【问题标题】:Bones rotate around parent - OpenGL Animation/Skinning骨骼围绕父级旋转 - OpenGL 动画/蒙皮
【发布时间】:2021-12-16 14:59:42
【问题描述】:

我的骨骼蒙皮存在问题,我的骨骼不是围绕其本地原点旋转,而是围绕其父节点旋转。 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 是推送到着色器的数组。

在我的网格/动画解析器中,我有这段代码可以计算反向绑定姿势矩阵(使用 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() 函数也是如此)。

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

【问题讨论】:

    标签: c++ animation opengl glm-math skeletal-animation


    【解决方案1】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-07-23
      • 2012-02-12
      • 2013-07-20
      • 2017-05-03
      • 2017-05-05
      • 2022-11-21
      • 2015-05-24
      相关资源
      最近更新 更多