使用 ASSIMP 的骨骼动画

Posted

技术标签:

【中文标题】使用 ASSIMP 的骨骼动画【英文标题】:Skeletal animation with ASSIMP 【发布时间】:2017-07-22 20:15:01 【问题描述】:

我一直在尝试在自己的 3D openGL/c++ 游戏引擎中使用 ASSIMP 导入模型来实现骨骼动画。

我认为问题是由骨骼矩阵的计算引起的,骨骼矩阵作为统一变量加载到着色器中,因为如果我将它们分配给身份,网格将以其绑定姿势加载。

这些是我用来初始化和计算准备好的骨骼矩阵的函数:

    void Joint::AddToSceneGraph(GameObject* root)
    
        GameObject* parent = root->FindChild(m_name);
        //m_globalInverseMatrix = inverse(root->GetTransform().GetMatrix());
        parent->AddComponent(this);
        while (parent->GetParent() != root)
            parent = parent->GetParent();

        parent->GetTransform().SetParent(NULL); (1)
    

    mat4 Joint::GetMatrix()
    
        mat4 ans = /*m_globalInverseMatrix*/GetTransform().GetMatrix()*m_offsetMatrix;
        return ans;
    

由于我试图以绑定姿势渲染模型,因此我不会向您提供计算动画矩阵的代码。

一些说明 - 我有一个 Transform 类,它有 Transform* 父级,它的 GetMatrix() 方法从父级计算矩阵,缩放和平移 vec3s 和旋转四元数,因此考虑了父子之间的关系。我假设根关节的父级变换必须为 NULL,因此它的矩阵 - 恒等式,这是 (1) 的目的。虽然我不确定这个假设,但我确信具有骨架根的节点和包含网格的节点是兄弟节点。

我也不确定我应该使用m_globalInverseMatrix 以及它的用途到底是什么。

总的来说,我认为我的主要问题是误解了 ASSIMP 如何计算 offset matrix 或所谓的 inverse bind pose matrix 以及如何反转其效果。这个问题导致模型本身看起来“打包”:

【问题讨论】:

【参考方案1】:

根据 Assimp 中的文档,骨骼的偏移矩阵从网格空间转换为骨骼空间。

我设法使用与您的相似的层次结构渲染绑定位置(如果我没有误解,您有一个带有两个子节点的根节点,一个生成骨架层次结构,另一个生成网格)。您需要做的是将m_globalInverseMatrix 设置为包含网格的节点的逆变换。那么,每个骨骼的变换为:

boneTransform = m_globalInverseMatrix * boneHierarchyTransforms * boneOffsetMatrix

boneHierarchyTransform 来自于遍历树直到每个骨骼节点,boneOffsetMatrix 是您提到的,我在第一段中提到。

【讨论】:

以上是关于使用 ASSIMP 的骨骼动画的主要内容,如果未能解决你的问题,请参考以下文章

Skeleton with Assimp 骨骼动画解析

CSharpGL(50)使用Assimp加载骨骼动画

DirectX 12 中 Assimp 的骨骼动画错误

一步步学OpenGL(38) -《Assimp库实现骨骼蒙皮动画》

一步步学OpenGL(38) -《Assimp库实现骨骼蒙皮动画》

在 Assimp 中获取骨骼动画的变换矩阵