C++ OpenGL中DirectX文件的骨骼动画

C++ OpenGL中DirectX文件的骨骼动画,c++,opengl,animation,directx,C++,Opengl,Animation,Directx,我正在尝试将*.x文件导入到我的引擎中,并使用OpenGL设置它们的动画(目前还没有着色器,但这与现在的情况并不相关)。我在MSDN上找到了格式参考,但在这个问题上没有多大帮助 所以-基本上-我创建了一个文件,其中包含一个类似恶魔的生物的简单动画,有7块骨头(主骨,2块尾巴,4块腿),目前只有2块骨头(右腿的骨头)被设置动画。我已经在DXViewer中测试了网格,它似乎在那里工作得很好,所以问题一定出在我的代码方面 导出网格时,会得到一个包含大量信息的文件,其中有3个重要位置用于骨骼动画(以下所

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

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

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

  • 皮肤重量-矩阵偏移

    -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
    
  • 框架变换矩阵

    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
    
  • 绑定姿势中的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
    

  • 我的问题是-我该如何处理这些矩阵?我在纽卡斯尔大学网站()上找到了一个等式,但那里只有一个矩阵。问题是-如何组合这些矩阵以获得顶点变换矩阵?

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

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

    问题是如何导入网格,以及为什么要这样做。您可以使用
    .x
    网格进行长达数月的斗争,但这没有任何意义,因为
    .x
    是一种非常基本、陈旧且不够好的格式。你在StackOverflow上找不到很多
    .x
    格式的粉丝。=)

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

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

    因此,使用assimp,您可以停止战斗,立即开始制作动画。也许以后,当你们发现它是如何工作的时候,你们可以编写你们自己的加载器

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

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

    • 您可以在此处找到动画的基本顶点着色器:
    • 下面解释了所有函数的工作原理(但以固定函数样式实现):

    希望有帮助

    由于Drop提供了讨论问题的链接,并提供了解决问题的线索,但没有提供简单的答案,因此我觉得有必要将解决方案留在这里,以防其他人遇到同样的问题

    在“绑定姿势”中获取新顶点位置的步骤 其中:
    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标记内的矩阵将变为未使用的矩阵。这意味着,你可能会在大多数时候忽略它。

    你的目标是什么版本的OpenGL?我看不出这有什么关系(我不认为解决方案依赖于更新的OpenGL版本),但我的电脑上有3.3版。我在我的项目中也使用GLU、GLUT和GLEW。对于矩阵运算,我使用我自己的类来实现重载运算符、换位和一个反函数(都在样本矩阵上测试过,工作正常)。是的,我想知道你是否使用着色器(很多OpenGL新手都使用不推荐的东西,如矩阵堆栈和立即模式)。但现在我发现问题不是蒙皮的实现,而是网格数据本身。谢谢,我会在有时间的时候检查链接。我一直使用*.x格式tho,因为它是我的3D图形程序唯一可以导出到的格式,支持骨骼动画。我给进口商写了封信,它很有效。。。除了动画,它有点破碎(但仍在移动!)。现在迁移到库中是一种浪费,但我会检查他们的代码。
    cM(bone)
    {
      if(bone->parent)
        return localTransform*cM(bone->parent);
      else
        return localTransform;
    }