如何从 2018 FBX SDK 中获取反向绑定姿势矩阵?

Posted

技术标签:

【中文标题】如何从 2018 FBX SDK 中获取反向绑定姿势矩阵?【英文标题】:How do I get the inverse bind pose matrix from the 2018 FBX SDK? 【发布时间】:2019-05-21 11:21:14 【问题描述】:

我正在编写一个工具来从 .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】:

试试这个:

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

【讨论】:

感谢您的回复,但我忘了提到我已经尝试过了。这是我得到的:imgur.com/MsdB7Bf 第一帧最终更接近原始绑定姿势。

以上是关于如何从 2018 FBX SDK 中获取反向绑定姿势矩阵?的主要内容,如果未能解决你的问题,请参考以下文章

使用 FBX SDK 获取索引

FBX SDK - 从角色的 ENodeId 获取 FbxNode

使用 fbx sdk c++ 从 fbx 读取纹理文件名

如何使用 FBX SDK 在 fbx 文件中加载嵌入的纹理? [关闭]

FBX SDK - 将 fbx 文件的所有内容转换为文本

FBX SDK 如何检索用户定义的对象属性