Я следовал этому руководству и получил выходную анимацию для ригг-модели как ожидал. В учебнике используются 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
дать правильный вывод. Я ожидал, что для того, чтобы вычисление было верным, каждая матрица должна быть сначала транспонирована для изменения порядка столбцов, а затем приведенного выше вычисления и, наконец, снова транспонирована, чтобы получить матрицу обратного порядка строк, которая также обсуждается в этом ссылка. Однако это привело к ужасному результату. Есть ли что-то, чего мне здесь не хватает?