【发布时间】:2015-05-25 07:51:02
【问题描述】:
我已按照this 教程进行操作,并按预期获得了装配模型的输出动画。本教程使用 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
产生正确的输出。我预计要使计算成立,首先应将每个矩阵转置为列顺序,然后进行上述计算,最后再次转置以获得后行顺序矩阵,这也在link中进行了讨论。然而,这样做产生了可怕的输出。我在这里有什么遗漏吗?
【问题讨论】:
-
fyi,您从 a2、b2、c2 和 d2 进行的更新确实有些奇怪。向下看他们的第二列,它计数为 2,3,4,5——我认为它们都应该是 1。
标签: c++ opengl matrix glsl assimp