Я пытаюсь реализовать скелетную анимацию, используя OpenGL и C ++.
Кроме того, порядок матрицы является главным по столбцу (glm).
Мой Joint
выглядит так:
struct Joint {
u8 id;
u8 parentId;
mat4 invBindPose;
}
В частности, Joint::invBindPose
пришло из FBX, используя эти строки кода:
FbxAMatrix transformLinkMatrix{};
cluster->GetTransformLinkMatrix(transformLinkMatrix);
FbxAMatrix transformMatrix{};
cluster->GetTransformMatrix(transformMatrix);
// FbxAMatrix->glm::mat4
joint.invBindPose = makeMat4(transformLinkMatrix.Inverse() * transformMatrix);
А вот и хитрая часть, с которой я борюсь. Я использую 3 прохода для обновления матриц скина.
Сначала интерполируйте два кадра и сохраните в матрице скинов. Сустав сортируется по его идентификатору в порядке возрастания.
for (u8 i = 0; i < jointCount; ++i) {
// track stores keys and joint id that affects.
auto track = mCurrAnimation->track(i); // here, find track by joint id.
auto& currKey = track->key[mCurrKeyIndex];
auto& nextKey = track->key[mNextKeyIndex];
// interpolate translation(vector3)
auto t = glm::mix(currKey.t, nextKey.t, alpha);
// spherically interpolate rotation(quaternion)
auto q = glm::slerp(currKey.q, nextKey.q, alpha);
// compose translation, rotation, scaling
mat4 transform = Math::compose(t, q, vec3{1.0});
mSkinMatrices[i] = transform;
}
Второе, множественное родительское преобразование
// root joint is at 0 -> no need to calculate?
for (u8 i = 1; i < jointCount; ++i) {
const auto parentId = mSkeleton->joints[i].parentId;
mSkinMatrices[i] = mSkinMatrices[i] * mSkinMatrices[parentId];
}
В-третьих, умножить обратную позу связывания
for (u8 i = 0; i < jointCount; ++i) {
auto& joint = mSkeleton->joints[i];
mSkinMatrice[i] = joint.invBindPose * mSkinMatrices[i];
}
Более подробно, я использовал эти строки кода для получения ключа от FBX:
const auto transform = node->EvaluateLocalTransform(time);
key.t = makeVec3(transform.GetT()); // FbxVector4->glm::vec3
key.q = makeQuat(trasnform.GetQ()); // FbxQuaterion->glm::quat
Статическая сетка выглядит так:
Но когда я использую это mSkinMatrices
для снятия вершин, эта сетка разрывается и вращается:
Очевидно, что я делаю что-то не так, но сам не могу понять.
Можете ли вы, ребята, посоветовать мне?