不正确的骨骼旋转,基于编辑模式下的骨骼结构

Posted

技术标签:

【中文标题】不正确的骨骼旋转,基于编辑模式下的骨骼结构【英文标题】:Incorrect bone rotations, based on bone structure in edit mode 【发布时间】:2021-01-12 11:06:15 【问题描述】:

我遇到了关于 assimp 和 blender 导出的问题/问题。我将模型从搅拌机导出到 gltf 二进制文件(.glb),一切正常,除非搅拌机内的骨骼不在姿势模式内旋转(在编辑模式内创建和旋转)我很好奇问题是否可以在内部解决代码,或者我必须修改搅拌机的导出来修复它。

如您所见,在第一次比较中,一个骨骼骨骼朝上,第二次在编辑模式下旋转,导致其旋转不正确。

这是我计算动画矩阵的 C++ 代码

class Bone

    public:
    int Id;
    glm::mat4 Transform;
    Bone* BoneParent;
    std::vector<Bone*> BoneChild;
    glm::mat4 NodeTran;
    glm::mat4 MTran;
    
    std::vector<glm::vec3> LocFrames;
    std::vector<glm::quat> RotFrames;
    std::vector<glm::vec3> ScaleFrames;
    glm::mat4 Offset;

    
    
    glm::mat4 getLocalTransform()
    
        float Factor= 1.0;

                    glm::vec3 T= this->LocFrames[1]+ (Factor * (this->LocFrames[1] - this->LocFrames[0]));
                    glm::mat4 TR = glm::translate(glm::mat4(1.0f), T);
                    
                    
                    glm::quat R = glm::normalize(glm::mix(this->RotFrames[0],this->RotFrames[1],Factor));
                    glm::mat4 RT = glm::toMat4(R);
                    
                    return TR*RT ;
        
    
    
    
    glm::mat4 getParentTransform()

    if (this->BoneParent)
        return BoneParent->NodeTran;
        
        
    
    else 
        return glm::mat4(1.0f);
        
    


    class Skeleton

    public:
    std::vector<Bone> BoneList;
    Bone *Root;
    glm::mat4 inverse;
    aiMatrix4x4 inverseai;
    void Calc(Bone* bone = NULL)
    
    

    
    bone->NodeTran = bone->getParentTransform()* // parent
    bone->getLocalTransform(); // T*R

    bone->Transform = inverse * // ai inverse
    bone->MTran* // node->mTransformation of bone
    bone->NodeTran*
    bone->Offset; // bone->mOffsetMatrix
    for (int i = 0; i < bone->BoneChild.size(); i++) 

       Calc(bone->BoneChild[i]);
    
    
    

    ;

//...
//...
ObjModel->ModelSkeleton.Calc(ObjModel->ModelSkeleton.Root);
for(int i=0; i<ObjModel->ModelSkeleton.BoneList.size();i++)
glm::mat4 matrix = ObjModel->ModelSkeleton.BoneList[i].Transform;
        glUniformMatrix4fv(glGetUniformLocation(ActiveShader->ID, "Anim[0]")+i, 1, GL_FALSE, glm::value_ptr(matrix );

【问题讨论】:

哦,对不起,我没明白bone-&gt;Transform = inverse * // ai inverse bone-&gt;MTran* // node-&gt;mTransformation of bone bone-&gt;NodeTran* bone-&gt;Offset; // bone-&gt;mOffsetMatrix 是一个单一的声明。 @Scheff 是的。 如果Calc() 与它的默认值一起使用(也就是用Calc() 调用它),那么bone-&gt; 的第一次出现将导致一个seg。错误(或其他 U.B.)我不会这样做(或在访问之前检查 bone 是否不是 nullptr)。 【参考方案1】:

通过调试各种事情,我发现搅拌机/assimp gltf2 导入器将骨骼平移(旋转、位置、大小)和节点的偏移(静态骨骼)放在位置/旋转/缩放框架中,我通过以下方式解决了这个问题:

    创建“无动画”序列,顾名思义,其中包含无动画骨骼 保存未设置动画的 loc/rot/scale 帧 用非动画帧减去所有动画帧

我知道这是一个“hackfix”,但这超出了我的理解范围,因为错误在搅拌机或 assimp 导入中

【讨论】:

以上是关于不正确的骨骼旋转,基于编辑模式下的骨骼结构的主要内容,如果未能解决你的问题,请参考以下文章

Blender 编辑骨骼动画,重复动作,并导出动画为视频

骨骼动画编辑器——Spine

max骨骼脚尖踩不住

Three.js:FBX 骨骼正确旋转,而 GLTF 骨骼奇怪地旋转

Blender 快捷键总结,一些子问题

unity新手求助,关于多个模型共享骨骼动画的问题