骨骼围绕父级旋转 - OpenGL Animation/Skinning

Bones rotate around parent - OpenGL Animation/Skinning

我的骨骼蒙皮有问题,我的骨骼不是围绕它们的本地原点旋转,而是围绕它们的父对象旋转。 Left - my engine. Right - blender

我怀疑管道中有两个位置有问题,但我无法说出具体位置。首先,我有这段实际计算骨骼矩阵的代码:

void CalculateBoneTransform(DSkeletonBone sb, dmat4x4f parentTransform, std::vector<DSkeletonBone> boneOverrides)
{
    if (boneDataIndex.count(sb.name) == 0) return;

    Transform transform = sb.localTransform;
    for (auto& bo : boneOverrides)
    {
        if (bo.name == sb.name)
        {
            transform = bo.localTransform;
        }
    }

    dmat4x4f globalTransform = dmat4x4f::Mul(parentTransform, transform.GetMatrix());

    dmat4x4f finalTransform = dmat4x4f::Mul(globalTransform, sb.inverseTransform);

    finalTransforms[boneDataIndex[sb.name]] = finalTransform;

    for (auto& pbC : sb.children)
    {
        CalculateBoneTransform(pbC, globalTransform, boneOverrides);
    }
}

boneOverrides 来自任何想要覆盖骨骼的东西(例如动画)。 finalTransforms 是被推送到着色器的数组。

在我的 mesh/anim 解析器中,我有这段代码计算反向绑定姿势矩阵(使用 OpenFBX,但这不相关):

            glm::mat4 local = glm::inverse(GetMatFromVecs(
                boneData[skin->getCluster(i)->name].pos,
                boneData[skin->getCluster(i)->name].rot,
                boneData[skin->getCluster(i)->name].scl));

            for (Object* parent = skin->getCluster(i)->getLink()->getParent(); parent != NULL; parent = parent->getParent())
            {
                glm::mat4 parentInverseTransform = glm::inverse(GetMatFromVecs(
                    parent->getLocalTranslation(),
                    parent->getLocalRotation(),
                    parent->getLocalScaling()));

                local = parentInverseTransform * local;
            }
            boneData[skin->getCluster(i)->name].offset = local;

getLocalXX 函数获取本地 space 中的项目。

以及上面引用的 GetMatFromVecs 函数:

    glm::mat4 GetMatFromVecs(Vec3 pos, Vec3 rot)
    {
        glm::mat4 m(1);
        m = glm::scale(m, glm::vec3(1,1,1));
        m = glm::rotate(m, (float)rot.x * 0.0174532925f, glm::vec3(1, 0, 0));
        m = glm::rotate(m, (float)rot.y * 0.0174532925f, glm::vec3(0, 1, 0));
        m = glm::rotate(m, (float)rot.z * 0.0174532925f, glm::vec3(0, 0, 1));
        m = glm::translate(m, glm::vec3(pos.x, pos.y, pos.z));
        return m;
    }

注意我先旋转,然后平移(顺便说一句,第一个代码片段中引用的 GetMatrix() 函数也是这种情况)。

所以我的问题是,为什么会这样?另外,网格蒙皮中出现这种情况的原因有哪些?我的翻译是本地的,但旋转不是。

我的问题是矩阵数学不好。我将我的 matrix::mul 函数换成 glm 并得到了预期的结果。