计算骨骼动画的最终骨骼变换

时间:2019-09-13 19:13:14

标签: opengl opentk assimp skeletal-animation skeletal-mesh

我有一个简单的模型,它具有在Blender中制作的简单骨骼结构。外观如下:

img

这是搅拌器中的层次结构:

img

如您所见,它有两根骨头:一根在矩形框(“骨头”)的中间,完全固定。从中点一直延伸到顶部的另一个骨骼(“ Bone.001”)旋转。

我已经使用AssImpNet导入了网格,并从动画节点通道中提取了旋转,缩放和位置关键帧。当我将这些变换应用于网格时,得到以下结果(以骨骼重量着色):

img

运动/动画似乎正常播放,因此我相信这部分工作正常。现在这是我的理解开始崩溃的地方,但是我相信我缺少的关键部分是计算“反向绑定姿势”(我已经看到了几个名字),并将其应用于我所进行的骨骼转换也可以输入我的着色器。但是到目前为止,我还无法确切找到需要从AssImp格式中提取的内容,然后相乘以获得正确的最终转换。我只找到了关于遍历节点树和从每个父节点“撤消”转换的模糊解释。

这是我尝试过的方法,似乎不起作用:

i thought that, for the base bone ("Bone"), i would need:
- the global inverse transform
- the node transform of the node with name "Bone"
- the rotation/position/scale keys from the animation channel with name "Bone"
- the bone offset from Meshes.Bones.OffsetMatrix from the bone named "Bone"

,然后按该顺序将它们相乘。

similarly for "Bone.001":
- the global inverse transform
- the node transform of the node with name "Bone"
- the rotation/position/scale keys from the animation channel with name "Bone"
- the node transform of the node with name "Bone.001"
- the rotation/position/scale keys from the animation channel with name "Bone.001"
- the bone offset from Meshes.Bones.OffsetMatrix from the bone named "Bone.001"

我试图实现这一点(现在硬编码索引只是为了使事情正常工作),请注意,它使用的是C#/ AssImpNet,因此命名约定与C ++ / AssImp有点不同:

        // "Bone"
        public Matrix4 Bone0Transform(double time)
        {
            var bone0 = MathUtils.ConvertMatrix(Scene.RootNode.Children[1].Children[0].Transform);

            var frame0 = GetTransformedFrame(1, TimeToFrame(1, time));

            var global = MathUtils.ConvertMatrix(Scene.RootNode.Transform).Inverted();

            var offset0 = MathUtils.ConvertMatrix(Scene.Meshes[0].Bones[0].OffsetMatrix);

            var total = global * bone0 * frame0 * offset0;

            return total;
        }

        // "Bone.001"
        public Matrix4 Bone1Transform(double time)
        {
            var bone0 = MathUtils.ConvertMatrix(Scene.RootNode.Children[1].Children[0].Transform);

            var bone1 = MathUtils.ConvertMatrix(Scene.RootNode.Children[1].Children[0].Children[0].Transform);

            var frame0 = GetTransformedFrame(1, TimeToFrame(1, time));
            var frame1 = GetTransformedFrame(2, TimeToFrame(2, time));

            var global = MathUtils.ConvertMatrix(Scene.RootNode.Transform).Inverted();

            var offset1 = MathUtils.ConvertMatrix(Scene.Meshes[0].Bones[1].OffsetMatrix);

            var total = global * bone0 * frame0 * bone1 * frame1 * offset1;

            return total;
        }

GetTransformedFrame返回一个Matrix4,该矩阵结合了与当前时间相对应的帧的缩放,旋转和位置键,并单独给出了可以在gif中看到的结果,该框的颜色为红色/绿色。

这给了我一个明显不正确的结果:  img

所以我的问题是:我对如何计算最终骨骼变形的理解是否错误?如果是这样,正确的做法是什么?

0 个答案:

没有答案