如何从2018 FBX SDK获取逆绑定姿势矩阵?

时间:2018-12-20 22:51:36

标签: animation graphics maya fbx

我正在编写一个工具,用于从.fbx文件中提取必要的数据,然后将其写入自定义文件并加载到游戏引擎中。我的网格,关节和骨架动画可以正常工作并显示,但是当我合并蒙皮后,似乎无法使其正常工作。

我通过骨骼树的关键帧变换并在它们之间画线来递归变换原点,从而显示骨骼动画:

Skeleton Animation

我很确定我已经从逻辑上将其范围缩小到从文件正确获取逆绑定姿势矩阵,因为骨骼动画看起来很准确。

这是我获得反向绑定姿势的方式:

            // 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种不同的动画装备进行尝试,并且它们的蒙皮均无效。这是一个看起来像的例子:

Skinning

我觉得我对此进行了大量研究,但我不知道这是怎么回事。如果完全相关,我正在使用DirectX 11。我还使用了一些艺术家朋友从Maya导出的fbx文件。 (我从网上找到了一个Maya文件,我将其导出)。预先感谢!

1 个答案:

答案 0 :(得分:0)

尝试一下:

FbxAMatrix inverse_bindpose = joint->EvaluateGlobalTransform().Inverse();