尝试使用Assimp GLM从MD5文件加载OpenGL中的动画

时间:2018-09-09 21:18:47

标签: c++ opengl glm-math assimp

我正在尝试遵循here ( at ogldev ) 中提到的in this answer的教程。

尽管我不太确定,但我面临一些我认为与Assimp的行主要订单与GLM的列主要订单有关的问题。

我已经尝试了一些变体和命令,以查看其中的任何一项是否奏效,但无济于事。

Here ( Gist )是用于加载完整MD5文件的类。还有我目前的结果。

而且,当我尝试更新骨骼转换矩阵时,这是我认为出错的部分。

void SkeletalModel::ReadNodeHierarchyAnimation(float _animationTime, const aiNode* _node,
        const glm::mat4& _parentTransform)
    {

        std::string node_name = _node->mName.data;

        const aiAnimation * p_animation = scene->mAnimations[0];

        glm::mat4 node_transformation(1.0f);

        convert_aimatrix_to_glm(node_transformation, _node->mTransformation);
        // Transpose it.
        node_transformation = glm::transpose(node_transformation);

        const aiNodeAnim * node_anim = FindNodeAnim(p_animation, node_name);

        if (node_anim) {

            //glm::mat4 transformation_matrix(1.0f);

            glm::mat4 translation_matrix(1.0f);
            glm::mat4 rotation_matrix(1.0f);
            glm::mat4 scaling_matrix(1.0f);

            aiVector3D translation;
            CalcInterpolatedPosition(translation, _animationTime, node_anim);

            translation_matrix = glm::translate(translation_matrix, glm::vec3(translation.x, translation.y, translation.z));

            aiQuaternion rotation;
            CalcInterpolatedRotation(rotation, _animationTime, node_anim);

            // Transpose the matrix after this.
            convert_aimatrix_to_glm(rotation_matrix, rotation.GetMatrix());
            //rotation_matrix = glm::transpose(rotation_matrix);

            aiVector3D scaling;
            CalcInterpolatedScaling(scaling, _animationTime, node_anim);
            scaling_matrix = glm::scale(scaling_matrix, glm::vec3(scaling.x, scaling.y, scaling.z));

            node_transformation = scaling_matrix * rotation_matrix * translation_matrix;
            //node_transformation = translation_matrix * rotation_matrix * scaling_matrix;

        }

        glm::mat4 global_transformation =  node_transformation * _parentTransform;

        if (boneMapping.find(node_name) != boneMapping.end()) {

            // Update the Global Transformation.
            auto bone_index = boneMapping[node_name];

            //boneInfoData[bone_index].finalTransformation = globalInverseTransform * global_transformation * boneInfoData[bone_index].boneOffset;
            boneInfoData[bone_index].finalTransformation = boneInfoData[bone_index].boneOffset * global_transformation * globalInverseTransform;
            //boneInfoData[bone_index].finalTransformation = globalInverseTransform;
        }

        for (auto i = 0; i < _node->mNumChildren; i++) {
            ReadNodeHierarchyAnimation(_animationTime, _node->mChildren[i], global_transformation);
        }

    }

我当前的输出:

Current Output

我尝试遍历代码中使用的每个矩阵,以检查是否应该转置它。是否更改矩阵乘法顺序。我找不到我的问题。

如果任何人都可以在这里指出我的错误或将我引导到可以帮助我加载动画的其他教程,那就太好了。

此外,我看到在学习此模型的初始阶段使用基本模型的建议。但是我被告知Obj格式不支持动画,在此之前我只使用过Obj。如本教程所示,我是否可以使用Blender导出的其他任何格式类似于MD5?

1 个答案:

答案 0 :(得分:1)

几年前,我基本上使用了这些教程,然后使用Assimp库构建了一个动画场景。 http://ogldev.atspace.co.uk/www/tutorial38/tutorial38.htmlhttp://sourceforge.net/projects/assimp/forums/forum/817654/topic/3880745

虽然我使用的是旧的X格式(blender可以使用X,但使用扩展名),但我可以肯定地确认您需要转置asimp动画矩阵以用于GML。

关于使用其他格式,您可以使用Blender(导入,编辑,导出)和Assimp支持的任何格式。更改格式时,请准备好进行反复尝试!

然后,我将尝试从您的工作系统中发布相关的片段,以显示您的代码,该片段显示了骨矩阵的计算。希望这对您有所帮助,因为我记得您遇到过同样的问题,并且花了一些时间来查找它。代码是普通的“ C”。

您可以在代码末尾看到转置发生的位置。

abc = node['abc']
def1 = node['def']
abc_sit = abc['sit']
def_sit = def1['sit']
%w{abc_sit def_sit}.each do | client |
  template "/etc/#{client}.sh" do
   source 'tunnel.erb'
   owner 'root'
   group 'root'
   variables ("#{client}") --> At this line I am getting error
 end
end