2

我正在尝试将 *.x 文件导入我的引擎并使用 OpenGL 为它们设置动画(目前没有着色器,但现在这并不重要)。我在 MSDN 上找到了格式参考,但对问题没有多大帮助。

所以 - 基本上 - 我创建了一个文件,其中包含一个类似恶魔的简单动画,它有 7 根骨头(主要,2 根尾巴,4 根腿),其中只有 2 根(右腿)目前是动画的。我已经在 DXViewer 中测试了网格,它似乎在那里工作得很好,所以问题一定出在我的代码方面。

当我导出网格时,我得到一个包含大量信息的文件,其中有 3 个重要的位置用于骨骼动画(以下所有矩阵都用于 RLeg2 骨骼):

  1. SkinWeights - matrixOffset

    -0.361238,  -0.932141, -0.024957,  0.000000,
     0.081428,  -0.004872, -0.996669,  0.000000,
     0.928913,  -0.362066,  0.077663,  0.000000,
     0.139213,  -0.057892, -0.009323,  1.000000
    
  2. 帧变换矩阵

    0.913144,  0.000000, -0.407637,  0.000000,
    0.069999,  0.985146,  0.156804,  0.000000,
    0.401582, -0.171719,  0.899580,  0.000000,
    0.000000, -0.000000,  0.398344,  1.000000
    
  3. 绑定姿势中的 AnimationKey 矩阵

    0.913144,  0.000000, -0.407637,  0.000000, 
    0.069999,  0.985146,  0.156804,  0.000000,
    0.401582, -0.171719,  0.899580,  0.000000,
    0.000000, -0.000000,  0.398344,  1.000000
    

我的问题是——我究竟该如何处理这些矩阵?我在纽卡斯尔大学网站 ( http://research.ncl.ac.uk/game/mastersdegree/graphicsforgames/skeletalanimation/ ) 上找到了一个方程式,但那里只有 1 个矩阵。问题是 -如何组合这些矩阵以获得顶点变换矩阵

4

2 回答 2

6

这篇文章不是假装是一个完整的答案,而是一组有用的链接。

如何获取动画所需的所有信息

问题是如何导入网格,以及为什么要这样做。您可以与.x网格战斗几个月,但这没有任何意义,因为这.x是一种非常基本、陈旧且确实不够好的格式。您在 StackOverflow 上找不到很多.x格式爱好者。=)

.x文件以一种棘手的方式存储动画数据。它旨在通过一组D3DX*()功能加载。但是,要手动从中获取骨骼和权重,您必须预处理加载的数据。很多东西要编码。这是一篇大文章,解释了如何:

在没有 DirectX 的情况下加载和显示 .X 文件

做事的好方法就是切换到一些网格加载库。最流行和普遍的一个是Assimp。至少,请查看他们的文档和/或源代码,了解他们如何处理加载和预处理,以及输出有什么乳清。另外,这里有一个很好的解释:

教程 38 - 使用 Assimp 的骨骼动画

因此,使用 assimp,您可以立即停止战斗并开始制作动画。也许稍后,当您对它的工作原理有所了解时,您可以编写自己的加载程序。

当您获得动画所需的所有信息时

骨骼动画是一个基本的话题,在网络上都有详细的解释。

希望能帮助到你!

于 2013-10-12T09:59:15.070 回答
0

由于Drop提供了讨论问题的链接,并提供了如何解决问题的线索,但并没有提供简单的答案,所以我觉得有必要将解决方案留在这里,以防其他人偶然发现同样的问题。

在“绑定姿势”中获取新的顶点位置

v'(i) = v(i)*Σ(transform(bone)*W(bone,i))

其中: v'(i)- 新顶点位置, v(i)- 旧顶点位置,以及 W(bone,i)- 变换的权重。(当然 Σ 是从 0 到骨骼中骨骼数量的总和)

transform(bone)等于sw(bone) * cM(bone),其中是swSkinWeights 标签内的矩阵使用cM(bone)递归函数计算:

cM(bone)
{
  if(bone->parent)
    return localTransform*cM(bone->parent);
  else
    return localTransform;
}

localTransform是位于FrameTransformMatrix标记内的矩阵。

获取某个动画帧中的新顶点位置

执行与上述完全相同的操作,但使用相应AnimationKey标记内的矩阵之一,而不是FrameTransformMatrix中的矩阵。请注意,播放动画时,FrameTransformMatrix标签内的矩阵变为未使用。这意味着,您可能最终会在大多数情况下忽略它。

于 2013-10-13T02:16:31.103 回答