C++ 如何计算COLLADA文件';父对象和子对象的关节变换?
尝试实施索具:C++ 如何计算COLLADA文件';父对象和子对象的关节变换?,c++,opengl,matrix,collada,skeletal-animation,C++,Opengl,Matrix,Collada,Skeletal Animation,尝试实施索具: 使用Blender创建了一个简单的操纵蛇测试,并导出了COLLADA文件 我已正确加载顶点位置、权重和关节ID 我已经为每个骨骼加载了骨骼关节层次和这些变换(我加载了矩阵,将所有的浮点值放入一个浮点值[16],然后我使用glm::make_mat4(tmpFloatArray),然后我将其转置,不确定这是否是正确的方法): 1 0 0 0 0 0 1 0 0 -1 0 0 0 0 0 1 0.3299372 0.944003-1.78814e-70-4.76837e-70-
- 使用Blender创建了一个简单的操纵蛇测试,并导出了COLLADA文件
- 我已正确加载顶点位置、权重和关节ID
- 我已经为每个骨骼加载了骨骼关节层次和这些变换(我加载了矩阵,将所有的浮点值放入一个浮点值[16],然后我使用glm::make_mat4(tmpFloatArray),然后我将其转置,不确定这是否是正确的方法):
1 0 0 0 0 0 1 0 0 -1 0 0 0 0 0 1
0.3299372 0.944003-1.78814e-70-4.76837e-70-10-0.944003 0.3299374 3.8743e-7 0 0 1
0.886344-0.4630275 3.31894e-7 2.98023e-8 0.4630274 0.886344-1.86307e-7 1.239941-2.07907e-7 3.18808e-7 1-2.84217e-14 0 0 1
0.9669114 0.2551119-1.83038e-7-1.19209e-7-0.2551119 0.9669115 1.29195e-7 1.219687 2.09941e-7-7.82246e-8 1 0 0 0 1
0.8538353 0.5205433 1.0139e-7-1.19209e-7-0.5205433 0.8538353 2.4693e-7 1.815649 4.19671e-8-2.63615e-7 1 5.68434e-14 0 0 1
现在,如果我将每个骨骼的矩阵设置为glm::mat4(1),则得到以下结果:
但是,如果我尝试乘以关节父变换,就像在瘦矩阵装配教程中一样,我会得到非常奇怪的结果:
void SkelManager::setTposeTransforms(std::vector<Joint>& _reference)
{
for (int child = 0; child < _reference.size(); child++)
{
if (_reference[child].parent == -1)
{
//_reference[child].tPose = glm::mat4(1);
_reference[child].tPose = _reference[child].transform;
}
for (int parent = 0; parent < _reference.size(); parent++)
if (_reference[child].parent == parent)
{
//_reference[child].tPose = glm::mat4(1);
_reference[child].tPose = _reference[parent].tPose * _reference[child].transform;
}
}
}
void SkelManager::setTposeTransforms(std::vector&\u引用)
{
对于(int child=0;child<_reference.size();child++)
{
if(_引用[child].parent==-1)
{
//_引用[child].tPose=glm::mat4(1);
_引用[child].tPose=\u引用[child].transform;
}
对于(int parent=0;parent<_reference.size();parent++)
if(_引用[child].parent==parent)
{
//_引用[child].tPose=glm::mat4(1);
_引用[child]。tPose=_引用[parent]。tPose*_引用[child]。转换;
}
}
}
请帮帮我,我已经在这上面呆了几个星期了,但我没有成功,无论我多么努力地在网上搜索,我都找不到任何有用的东西,有没有关于我可能做错什么的想法
我使用glm::make_mat4(tmpFloatArray),然后转置它,不确定
如果这是正确的方法):
请参见COLLADA规范中关于矩阵的部分:
COLLADA中的矩阵是数学意义上的列矩阵。
这些矩阵是按行顺序写的,以帮助人类
读者。参见示例
所以,是的,你需要转换它
加载COLLADA的骨骼动画并不难。遵循以下步骤:
进口商方面:
FinalJointTrans4x4=JointTransform*InvBindPose*BindShapeMatrix
JointTransform是与父项相乘的变换
InvBindPose(或InvBindMatrix)是从蒙皮->关节->INV_BIND_矩阵中为每个关节读取的变换
BindShapeMatrix是从skin->bind\u shape\u矩阵读取的变换
PS:有一个名为AssetKit()的库,如果您愿意,可以使用它加载COLLADA文件。非常感谢您的回答!我试着慢慢来,现在,我想得到默认姿势,我猜我需要为每个关节得到一个矩阵,没有旋转或平移,但有偏移,对吗?当我变换其中一个关节矩阵时,子节点会正确地移动,但它会在错误的点上旋转。也找不到INV_BIND_矩阵,不管我读了多少遍,我都不明白,因为这些新术语。但是非常感谢你的回答!如果您可以指定如何计算偏移量,我想我可以管理其余的。Thx!。您必须能够以
的形式找到INV\u BIND\u矩阵。之所以需要,是因为需要将网格从对象空间变换到骨骼空间。然后,如果变换骨骼/关节,则网格将随之变换。按照上面的步骤创建FinalJointTrans4x4
matrix,就像我提到的那样。教程你可以按照recp,我100%详细地阅读了你说的教程,现在它工作得更好了,但仍然不是100%好,如果你有一分钟的时间,你能像猴子一样解释一下吗,把这个从collada文件中取出来,乘以collada文件中的其他东西,然后在更新中做这个和这个,请,这会有很大帮助,我在这里呆了很长时间
void SkelManager::setTposeTransforms(std::vector<Joint>& _reference)
{
for (int child = 0; child < _reference.size(); child++)
{
if (_reference[child].parent == -1)
{
//_reference[child].tPose = glm::mat4(1);
_reference[child].tPose = _reference[child].transform;
}
for (int parent = 0; parent < _reference.size(); parent++)
if (_reference[child].parent == parent)
{
//_reference[child].tPose = glm::mat4(1);
_reference[child].tPose = _reference[parent].tPose * _reference[child].transform;
}
}
}
...
mat4 skinMat;
skinMat = uJoints[JOINTS.x] * WEIGHTS.x
+ uJoints[JOINTS.y] * WEIGHTS.y
+ uJoints[JOINTS.z] * WEIGHTS.z
+ uJoints[JOINTS.w] * WEIGHTS.w;
pos4 = skinMat * pos4;
norm4 = skinMat * norm4;
...
#ifdef JOINT_COUNT
gl_Position = VP * pos4;
#else
gl_Position = MVP * pos4;
#endif
...