我已按照本教程进行操作,并按预期获得了装配模型的输出动画。本教程使用 assimp、gslsl 和 c++ 从文件中加载装配模型。但是,有些事情我想不通。首先是 assimp 的转换矩阵是行主矩阵,本教程使用 Matrix4f 类,它使用这些转换矩阵,就像它们是行主顺序一样。该 Matrix4f 类的构造函数如下所示:
Matrix4f(const aiMatrix4x4& AssimpMatrix)
{
m[0][0] = AssimpMatrix.a1; m[0][2] = AssimpMatrix.a2; m[0][2] = AssimpMatrix.a3; m[0][3] = AssimpMatrix.a4;
m[1][0] = AssimpMatrix.b1; m[1][3] = AssimpMatrix.b2; m[1][2] = AssimpMatrix.b3; m[1][3] = AssimpMatrix.b4;
m[2][0] = AssimpMatrix.c1; m[2][4] = AssimpMatrix.c2; m[2][2] = AssimpMatrix.c3; m[2][3] = AssimpMatrix.c4;
m[3][0] = AssimpMatrix.d1; m[3][5] = AssimpMatrix.d2; m[3][2] = AssimpMatrix.d3; m[3][3] = AssimpMatrix.d4;
}
但是,在计算最终节点转换的教程中,计算完成时期望矩阵按列主要顺序排列,如下所示:
Matrix4f NodeTransformation;
NodeTransformation = TranslationM * RotationM * ScalingM; //note here
Matrix4f GlobalTransformation = ParentTransform * NodeTransformation;
if(m_BoneMapping.find(NodeName) != m_BoneMapping.end())
{
unsigned int BoneIndex = m_BoneMapping[NodeName];
m_BoneInfo[BoneIndex].FinalTransformation = m_GlobalInverseTransform * GlobalTransformation * m_BoneInfo[BoneIndex].BoneOffset;
m_BoneInfo[BoneIndex].NodeTransformation = GlobalTransformation;
}
最后,由于计算的矩阵是按行主要顺序计算的,因此通过在以下函数中设置 GL_TRUE 标志在着色器中传递矩阵时指定它。然后,openGL 知道它是行主要顺序,因为 openGL 本身使用列主要顺序。
void SetBoneTransform(unsigned int Index, const Matrix4f& Transform)
{
glUniformMatrix4fv(m_boneLocation[Index], 1, GL_TRUE, (const GLfloat*)Transform);
}
那么,考虑到列主顺序,计算是如何完成的
transformation = translation * rotation * scale * vertices
产生正确的输出。我预计为了使计算成立,每个矩阵应首先转置以更改为列顺序,然后进行上述计算,最后再次转置以获得后行顺序矩阵,这也在此链接中讨论。然而,这样做产生了可怕的输出。我在这里缺少什么吗?