我是否需要为我的网格动画绑定姿势骨骼变换?

时间:2015-12-18 13:25:21

标签: c++ opengl animation graphics

  1. 我有一个手工网格,我想制作动画。

  2. 我有可以分层动画的Skeleton。

  3. 我的网格也在Blender中加权。因此每个顶点都有4个相关的骨骼受到影响。

  4. 当我将Skeleton的动画应用于网格时,正确应用了层次结构。 (因此网格的层次结构与骨架的层次结构相匹配)。

  5. 到目前为止很好,现在问题: 手指看起来被拉伸(就像被一扇沉重的门砸碎的手指)。为什么?

    注意:(我没有明确地应用绑定姿势骨骼转换矩阵,但我读到它并且我相信它的功能在那里,在我的骨架的分层转换中)。

    如果您需要更多说明步骤,请询问。

    vector<glm::mat4> Posture1Hand::HierarchyApplied(HandSkltn HNDSKs){
    
        vector <glm::mat4> Matrices; 
    Matrices.resize(HNDSKs.GetLimbNum());
    
        //non Hierarchical Matrices
        for (unsigned int i = 0; i < Matrices.size(); i++){
            Matrices[i] = newPose[i].getModelMatSkltn(HNDSKs.GetLimb(i).getLwCenter());
        }
    
    
        for (unsigned int i = 0; i < Matrices.size(); i++){
            vector<Limb*>childeren = HNDSKs.GetLimb(i).getChildren();
            for (unsigned int j = 0; j < childeren.size(); j++){
                Matrices[childeren[j]->getId()] = Matrices[i] * Matrices[childeren[j]->getId()];
            }
        }
        return Matrices;
    }
    

    这是我的getModelMatSkltn方法。

    inline glm::mat4 getModelMatSkltn(const glm::vec3& RotationCentre) const{//to apply the rotation on the whole heirarchy
        glm::mat4 posMatrix = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
        posMatrix = glm::translate(posMatrix, newPos);
    
        glm::mat4 trMatrix = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
        glm::mat4 OriginTranslate = glm::translate(trMatrix, -RotationCentre);
        glm::mat4 InverseTranslate = glm::translate(trMatrix, RotationCentre);
    
    
        glm::mat4 rotXMatrix = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
        rotXMatrix = glm::rotate(rotXMatrix, glm::radians(newRot.x), glm::vec3(1, 0, 0));
    
        glm::mat4 rotYMatrix = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
        rotYMatrix = glm::rotate(rotYMatrix, glm::radians(newRot.y), glm::vec3(0, 1, 0));
    
        glm::mat4 rotZMatrix = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
        rotZMatrix = glm::rotate(rotZMatrix, glm::radians(newRot.z), glm::vec3(0, 0, 1));
    
        glm::mat4 scaleMatric = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
        scaleMatric = glm::scale(scaleMatric, newScale);
    
        glm::mat4 rotMatrix = rotZMatrix*rotYMatrix*rotXMatrix;
    
        rotMatrix = InverseTranslate*rotMatrix*OriginTranslate;
    
        return posMatrix*rotMatrix*scaleMatric;
    }
    

    这就是我向GPU发送20个转换矩阵(因为手中有20个关节)的方式:

    void GLShader :: Update(const vector trMat,const GLCamera&amp; camera){

    vector<glm::mat4> MVP; MVP.resize(trMat.size());
    for (unsigned int i = 0; i < trMat.size(); i++){
        MVP[i] = camera.getViewProjection()* trMat[i];
    }
    glUniformMatrix4fv(newUniform[TRANSFORM_U], trMat.size(), GL_FALSE, &MVP[0][0][0]);//4 floating value
    

    }

    我想应该熟悉着色器中顶点位置的计算,以便能够回答问题,但我也发送了一部分顶点着色器。

    attribute vec3 position;
    attribute vec2 texCoord;
    attribute vec4 weight;
    attribute vec4 weightInd;
    
    
    uniform mat4 transform[20];//vector of uniform for 20 number of joints in my skleton
    
    void main(){
        mat4 WMat;//weighted matrix
        float w;
        int Index;
        for (int i=0; i<4; i++){
            Index=int(weightInd[i]);
            w=weight[i];
                WMat += w*transform[Index];
        }
        gl_Position= WMat*vec4(position, 1.0);
    }
    

0 个答案:

没有答案