2016-03-12 43 views
1

我目前正在使用ASSIMP庫在我的3D OpenGL遊戲引擎中實現骨架動畫,但不幸的是它並不是那麼棒。 我目前面臨的問題是,只有一個父變換時,連接的骨骼變換(骨骼之間的父子關係)才能正確運行。Assimp Skinning Global Transforms

會發生什麼事是,thigh's bone transformation is carried out on global axes instead of the pelvis' local axes.

這裏是我的骨架類:

class Skeleton 
{ 
public: 
    Skeleton(); 

    unsigned int numBones; 
    std::vector<std::string> names; 
    std::vector<glm::mat4> offsets; 


    std::vector<glm::mat4> transforms; 
    std::vector<int> parents; 

    std::string GetName(int bone); 
    glm::mat4 GetWorldTransform(int bone); 
    int GetID(std::string bone_name); 
}; 

,這裏是我用來計算世界變換每個骨骼的功能:

glm::mat4 Skeleton::GetWorldTransform(int bone) 
{ 
int p = parents[bone]; 
glm::mat4 result = glm::mat4(1.0); 

result *= glm::inverse(offsets[bone]); 
    result *= transforms[bone]; 
result *= offsets[bone]; 

while(p >= 0) //The root bone has a parent of -1 
{ 
    result *= glm::inverse(offsets[p]); 
     result *= transforms[p]; //Apply The Parent's Transform 
    result *= offsets[p]; 

    p = parents[p]; 
} 
return result; 
} 

在我的網格類中,我有這個函數UpdateSkeleton():

void Mesh::UpdateSkeleton(unsigned int shaderID) 
{ 
std::vector<glm::mat4> mats; 

for(int i = 0; i < skeleton->numBones; i++) 
{ 
    glm::mat4 matrix = glm::mat4(1.0); 
     matrix *= skeleton->GetWorldTransform(i); 
    mats.push_back(matrix); 
} 

if(mats.size() > 0) 
    glUniformMatrix4fv(glGetUniformLocation(shaderID,"gBones"),mats.size(),GL_FALSE,glm::value_ptr(mats[0])); 
} 

謝謝!

回答

0

所以我修好了。

https://www.youtube.com/playlist?list=PLi9hkiiZDonvUcT_FRD8rJtuuGltL3xys

基本問題是,串連被以相反的順序正在做,我正在做他們喜歡這個原本:

void Bone::UpdateParentTransform() 
{ 
    parent_transform = glm::mat4(1.0); 

    Node* node_id = parent_node; 

    while(node_id != nullptr) 
    { 
     Bone* bone = mesh->FindBone(node_id->name); 

     if(bone != nullptr) 
     { 
      parent_transform *= glm::inverse(bone->offset_matrix); 
       parent_transform *= node_id->transformation; 
      parent_transform *= (bone->offset_matrix); 
      node_id = bone->parent_node; 
     } 
     else 
      node_id = nullptr; 
    } 
} 

現在我做到了,使他們在反向進行秩序,像這樣:

void Bone::UpdateParentTransform() 
{ 
    parent_transform = glm::mat4(1.0); 

    Node* node_id = node; 

    std::vector<Bone*> bones; 
    std::vector<Node*> parents; 

    while(node_id != nullptr) 
    { 
     Bone* bone = mesh->FindBone(node_id->name); 

     if(bone != nullptr) 
     { 
      bones.push_back(bone); 
      parents.push_back(node_id); 

      node_id = bone->parent_node; 
     } 
     else 
      node_id = nullptr; 
    } 


    for(int i = parents.size()-1; i > 0; i--) 
    { 
     parent_transform *= glm::inverse(bones.at(i)->offset_matrix); 
      parent_transform *= parents.at(i)->transformation; 
     parent_transform *= (bones.at(i)->offset_matrix); 
    } 

} 

如果你有關於這個或任何其他關於使用ASSIMP請做骨骼動畫有任何疑問不要猶豫,問我,你可以在這裏或我的YouTube頻道與我聯繫:RealityMultiplied

我要開始製作關於如何使用ASSIMP進行骨骼動畫的教程系列,所以我希望今晚有第一個視頻。

我希望能夠讓這是一個容易理解的話題,因爲這看起來令人望而生畏,而且總體上可怕。

編輯: 所以我開始研究這些教程,但我現在經歷了很多艱難的事情,我認爲我不能完成它們。 我希望他們至少有一點幫助,我很抱歉我不能做更多。

http://realitymultiplied.blogspot.mx/