OpenGL中DirectX文件的骨架动画

时间:2013-10-11 16:40:55

标签: c++ opengl animation directx

我正在尝试将* .x文件导入我的引擎并使用OpenGL动画它们(目前没有着色器,但现在这并不是真正相关)。我在MSDN上找到了格式参考,但它对这个问题没什么帮助。

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

当我导出网格时,我得到一个包含大量信息的文件,其中有三个重要的位置用于骨架动画(以下所有矩阵都用于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. FrameTransformMatrix

    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
    
  4. 我的问题是 - 我对这些矩阵做了什么?我在纽卡斯尔大学网站(http://research.ncl.ac.uk/game/mastersdegree/graphicsforgames/skeletalanimation/)找到了一个等式,但那里只有一个矩阵。问题是 - 如何组合这些矩阵来获得顶点变换矩阵

2 个答案:

答案 0 :(得分:6)

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

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

问题是如何导入网格,为什么要这样做。您可以使用.x网格对战一个月,但这没有任何意义,因为.x是一种非常基本的,旧的且非常不够好的格式。您在StackOverflow上找不到许多.x格式的粉丝。 =)

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

Loading and displaying .X files without DirectX

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

Tutorial 38 - Skeletal Animation With Assimp

所以,有了assimp你可以停止战斗并立即开始制作动画。也许以后,当你知道它是如何工作的时候,你可以编写自己的装载机。

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

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

希望它有所帮助!

答案 1 :(得分: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),其中sw是在 SkinWeights 标记内找到的矩阵,cM(bone)是使用递归函数:

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

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

获取特定动画帧中的新顶点位置

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