-2

我的骨骼蒙皮存在问题,我的骨骼不是围绕它们的本地原点旋转,而是围绕它们的父节点旋转。左 - 我的引擎。右 - 搅拌机

我怀疑管道中有两个位置有问题,但我不知道它到底在哪里。首先,我有一段代码可以实际计算骨骼矩阵:

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 是推送到着色器的数组。

在我的网格/动画解析器中,我有计算反向绑定姿势矩阵的代码(使用 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 函数在本地空间中获取项目。

以及上面引用的 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() 函数也是如此)。

所以我的问题是,为什么会这样?此外,在网格蒙皮中这种类型的事情的一些原因是什么?我的翻译是本地的,但轮换不是。

4

1 回答 1

0

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

于 2021-11-07T16:48:08.883 回答