Я пишу инструмент для извлечения необходимых данных из файла .fbx для записи в пользовательский файл и загрузки в игровой движок.У меня есть сетки, суставы и скелетные анимации, которые работают и отображаются правильно, но я не могу заставить его работать, когда я включаю скиннинг.
Я отображаю скелетные анимации путем рекурсивного преобразования исходной точки черезКлючевой кадр костяного дерева трансформируется и рисует линии между ними:
Скелетная анимация
Я почти уверен, что логически сузил его до неправильного получения матрицы поз обратной привязки связыванияиз файла, поскольку скелетная анимация выглядит точной.
Вот так я получаю позу обратного связывания:
// Find the joint associated with this cluster
FbxCluster *fbx_cluster = fbx_skin->GetCluster(i_cluster);
std::string joint_name = fbx_cluster->GetLink()->GetName();
auto joint = std::find(model.m_skeleton.m_joints.begin(), model.m_skeleton.m_joints.end(), joint_name);
FbxAMatrix transform_matrix;
FbxAMatrix transform_link_matrix;
FbxAMatrix parent_transform_link_matrix;
// Calculate bind pose matrix, which is the starting transformation matrix
fbx_cluster->GetTransformMatrix(transform_matrix);
fbx_cluster->GetTransformLinkMatrix(transform_link_matrix);
const FbxVector4 lT = fbx_cluster->GetLink()->GetGeometricTranslation(FbxNode::eSourcePivot);
const FbxVector4 lR = fbx_cluster->GetLink()->GetGeometricRotation(FbxNode::eSourcePivot);
const FbxVector4 lS = fbx_cluster->GetLink()->GetGeometricScaling(FbxNode::eSourcePivot);
FbxAMatrix geom(lT, lR, lS);
joint->m_jointNode = fbx_cluster->GetLink();
joint->m_inverseBindPose = transform_link_matrix.Inverse() * transform_matrix * geom;
joint->m_isBindPoseSet = true;
Согласно различным онлайн-статьям, "transform_matrix" и "geom"Существуют ли они для совместимости с другим программным обеспечением и, как правило, представляют собой просто матрицу идентификации, и я подтвердил, что это именно такПоэтому я в основном вызываю GetTransformLinkMatrix и инвертирую его.Затем для соединений, у которых нет кластера, связанного с ним, я делаю это:
// If the joint didn't have a cluster, it wasn't a part of binding, and therefore
// doesn't have an inverse bind pose. We have to make one here
if (!joint.m_isBindPoseSet) {
joint.m_isBindPoseSet = true;
joint.m_globalBindPoseMatrix = joint.m_jointNode->EvaluateLocalTransform().Inverse() * model.m_skeleton.m_joints[joint.m_parentIndex].m_inverseBindPoseMatrix;
}
То есть, просто получая локальное преобразование соединения и умножая его на обратную позицию связывания его родителя.Я пробовал это с 3 различными анимированными ригами, и ни одна из них не работает.Вот пример того, как это выглядит:
Скиннинг
Мне кажется, что я провел много исследований по этому вопросу, но я не знаю, чтонеправильно.Я использую DirectX 11, если это вообще актуально.Я также использую fbx-файлы, экспортированные из Maya, созданные некоторыми друзьями-художниками.(И один файл майя, который я нашел в интернете, который я сам экспортировал).Заранее спасибо!