c++ - 使用 ASSIMP 进行骨骼动画

标签 c++ opengl assimp

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

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

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

    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;
    }

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

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

此外,我不确定我应该使用 m_globalInverseMatrix 以及它的确切用途。

总的来说,我认为我遇到的主要问题是误解 ASSIMP 如何计算偏移矩阵或所谓的逆绑定(bind)姿势矩阵以及如何反转其效果。此问题导致模型本身看起来“拥挤”:

this is maybe the most famous md5 model

最佳答案

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

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

boneTransform = m_globalInverseMatrix *】boneHierarchyTransforms *【boneOffsetMatrix】

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

关于c++ - 使用 ASSIMP 进行骨骼动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42566685/

相关文章:

opengl:非线性加色混合

c++ - 将标准库添加到 C++ eclipse 项目

c++ - 在运行时检测 C++ 中的堆碎片的可移植方法?

opengl - 创建 OpenGL 阴影

c - Assimp详细类型指的是typedef

c++ - 在同一个 .obj 模型文件上,Assimp 查看器比 Assimp C++ 导入器快得多

3d - Assimp 模型有纹理但没有纹理坐标

c++ - 打印整个文本文件而不显示空行,C++

c++ - 构造函数帮助 const C 字符串数组

opengl - 正确使用glCopyBufferSubData