错误的骨骼会变形Assimp

时间:2020-04-27 18:21:52

标签: c++ opengl glm-math assimp

我在创建骨骼动画时遇到麻烦,我的模型转换不正确

    void Animation(glm::mat4 a[])
    {
        float Factor= fmod(glfwGetTime(),1.0);
        for(int b=0;b<BoneList.size();b++)
        {
    
            Bone *BoneT = &BoneList[b];
            aiMatrix4x4 temp = inverse;
            while(BoneT)
            {
    
                    aiVector3D sc= BoneT->ScaleFrame[0] + (Factor * (BoneT->ScaleFrame[1] - BoneT->ScaleFrame[0]));
                    aiMatrix4x4 S=aiMatrix4x4();
                    S[0][0]=sc.x;
                    S[1][1]=sc.y;
                    S[2][2]=sc.z; 

                    aiVector3D tr= BoneT->LocFrame[0] + (Factor * (BoneT->LocFrame[1] - BoneT->LocFrame[0]));
                    aiMatrix4x4 T=aiMatrix4x4();
                    T[0][3]=tr.x;
                    T[1][3]=tr.y;
                    T[2][3]=tr.z;

                    aiQuaternion R;
                    aiQuaternion::Interpolate(R, BoneT->RotFrame[0], BoneT->RotFrame[1], Factor);
                    R = R.Normalize();

                    temp*=BoneT->NodeTransform*(T* aiMatrix4x4(R.GetMatrix()) * S );
                    BoneT=BoneT->BoneParent;
                
            }
            temp*=BoneList[b].offset;
            temp.Transpose();
            ai_to_glm(temp,a[b]);
        }
    }

im创建一个Temp aiMatrix4x4来保留asimp矩阵的乘法顺序,然后使用函数将aiMatrix4x4转换为glm :: mat4:

     void ai_to_glm(const aiMatrix4x4 &from, glm::mat4 &to)
{
    to[0][0] = from[0][0];
    to[0][1] = from[0][1];
    to[0][2] = from[0][2];
    to[0][3] = from[0][3];

    to[1][0] = from[1][0];
    to[1][1] = from[1][1];
    to[1][2] = from[1][2];
    to[1][3] = from[1][3];

    to[2][0] = from[2][0];
    to[2][1] = from[2][1];
    to[2][2] = from[2][2];
    to[2][3] = from[2][3];

    to[3][0] = from[3][0];
    to[3][1] = from[3][1];
    to[3][2] = from[3][2];
    to[3][3] = from[3][3];
}

然而,模型的最终框架如下:blender and program comparision

我注意到,如果我从函数中删除了翻译矩阵,则模型看起来应该更接近enter image description here

蒙皮是在着色器中完成的

layout (location = 0) in vec3 aPos; 
layout (location = 1) in vec2 Tpos;
layout (location = 2) in ivec4 Bones;
layout (location = 3) in vec4 Weight;
uniform mat4 view;
uniform mat4 proj;
uniform mat4 LocRot;
uniform mat4 Test[8];
out vec3 vertexColor;
out vec2 TextCoord;

void main()
{
    mat4 BoneTransform = Test[Bones.x]* Weight.x;
    BoneTransform += Test[Bones.y] * Weight.y;
  BoneTransform += Test[Bones.z] * Weight.z;
   BoneTransform += Test[Bones.w] * Weight.w;
    gl_Position = proj * view *LocRot* BoneTransform *vec4(aPos, 1.0);
    vertexColor = vec3(1,1,1);
    TextCoord = Tpos;
}

并且需要制服

    for(int i=0; i<4;i++)
    {
        glUniformMatrix4fv(glGetUniformLocation(ActiveShader->ID, "Test[0]")+i, 1, GL_FALSE, glm::value_ptr(AnimMatrix[i]));
    }

我知道的是: -逆矩阵是恒等矩阵,它现在对该模型没有任何作用。

-某些权重之和不等于1.0,但我认为这不是问题

-更改矩阵乘法顺序无法解决

模型已创建并在Blender中导出

链接到模型https://send.firefox.com/download/fe0b85d3f4581630/#6S0Vr9EIjgLNN03rerMW0w

我敢打赌,ai_to_glm函数在这里有问题,但我不确定。

编辑:我注意到旋转也发生了翻转,如图所示,但是将其乘以inverseai(倒置的根骨转换)则无济于事。

更新:我在转换之前先转换了asimp矩阵,它解决了大多数问题,但是偏移量和父代继承被错误了

1 个答案:

答案 0 :(得分:0)

在没有任何怀疑之前,我不知道我的帐户在堆栈溢出时,我从我的真实帐户中回答了这个问题

要解决此问题,它需要执行多项操作:

  1. 迭代骨骼和分配孩子/父母使用不稳定的指针并被破坏,在解决它之后,它修复了主要问题

  2. 我已使用问题Matrix calculations for gpu skinning

    中的编码冒险答案
  3. 我的ai_to_glm错误,并用

    替换后

    glm :: mat4 ai_to_glm(aiMatrix4x4 *从) { glm :: mat4到= glm :: mat4(1.0f); 到[0] [0] =(GLfloat)从-> a1;到[0] [1] =(GLfloat)从-> b1;到[0] [2] =(GLfloat)从-> c1;到[0] [3] =(GLfloat)从-> d1; 到[1] [0] =(GLfloat)从-> a2;到[1] [1] =(GLfloat)从-> b2;到[1] [2] =(GLfloat)从-> c2到[1] [3] =(GLfloat)从-> d2; 到[2] [0] =(GLfloat)从-> a3;到[2] [1] =(GLfloat)从-> b3; to [2] [2] =(GLfloat)from-> c3; to [2] [3] =(GLfloat)from-> d3; 到[3] [0] =(GLfloat)从-> a4;到[3] [1] =(GLfloat)从-> b4; to [3] [2] =(GLfloat)from-> c4;到[3] [3] =(GLfloat)从-> d4; 还给; };

这样做之后,它就固定了

相关问题