このチュートリアルに従って、リグモデルの出力アニメーションを期待どおりに取得しました。このチュートリアルでは、assimp、glsl、および 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
正しい出力を生成します。計算が成り立つためには、各行列を最初に転置して列の順序に変更し、次に上記の計算を行い、最後に再度転置して逆行順序の行列を取得する必要があると予想しました。これについては、このリンクでも説明しています。しかし、そうすると恐ろしい出力が生成されました。ここに欠けているものはありますか?