2

我已经实现了一个骨骼动画系统,我似乎遗漏了最后一个细节以使其正常工作。

我制作了一个动画,其中只有一部分角色有骨骼。在这张图片中,火柴人有一只挥动的手臂,但与火柴人的其余部分相比,手臂挥动的位置错误。(你几乎看不到他的腿之间)

动画火柴人

我将尝试概述我的矩阵计算的基础知识,看看我是否做错了什么。

计算骨骼特定的绝对和相对动画矩阵(基于我的关键帧矩阵数据):

        if (b == this->root) {
                b->absoluteMatrix = M;
            } else {
                b->absoluteMatrix = b->parent->absoluteMatrix * M;
            } 

            b->skinningMatrix = b->absoluteMatrix * inverse(b->offsetMatrix);       

            if (this->currentAnimationTime == 0) {
                cout << "Bone '" << b->name << "' skinningMatrix:\n";
                printMatrix(b->skinningMatrix);

                cout << "Bone '" << b->name << "' absoluteMatrix:\n";
                printMatrix(b->absoluteMatrix);

                cout << "Bone '" << b->name << "' offsetMatrix:\n";
                printMatrix(b->offsetMatrix);

                cout << "---------------------------------\n";
            }

我发送到 GPU 的 skinningMatrix。这将打印以下内容:

调试输出

其中 offsetMatrix 是在绑定姿势中从网格空间变换到骨骼空间的变换。

然后在我的着色器中:

layout(location = 0) in vec4 v; // normal vertex data
newVertex = (skinningMatrix[boneIndex.x] * v) * weights.x;
newVertex = (skinningMatrix[boneIndex.y] * v) * weights.y + newVertex;
newVertex = (skinningMatrix[boneIndex.z] * v) * weights.z + newVertex;

关于我的计算可能有什么问题的任何提示?

4

1 回答 1

0

我目前正在自己​​处理骨骼动画,我注意到的唯一可能是问题的是您如何使用 ASSIMP 中的偏移矩阵。所讨论的矩阵是“在绑定姿势中从网格空间转换到骨骼空间”的矩阵。

据我所知,该矩阵旨在“按原样”使用,它本质上会将您的顶点带入骨骼局部空间,然后您将乘以一个“新”全局关节姿势,该姿势会将顶点从骨骼空间带到模型空间。

当您反转矩阵时,您将顶点再次转换为模型空间,并且与当前动画帧的全局关节姿势相比,将顶点推得更远。

我相信您的解决方案将是删除偏移矩阵的反转,这将导致您的顶点从“模型-关节模型”移动。

于 2014-03-03T12:52:38.517 回答