2016-03-12 2 views
1

В настоящее время я реализую скелетную анимацию в своем 3D-игровом движке OpenGL с использованием библиотеки ASSIMP, к сожалению, все идет не так уж хорошо. Проблема, с которой я столкнулся сейчас, состоит в том, что преобразование конкатенированных костей (отношения между родителями и дочерними элементами) действует только тогда, когда трансформируется только один родитель.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; 
} 

И в моем классе Mesh у меня есть эта функция 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 прямо сейчас, поэтому я надеюсь, что есть первое видео до сегодняшнего вечера.

Я надеюсь, что это станет понятной для тех, кто только начинает, потому что это может показаться сложным и просто ужасным.

EDIT: Итак, я начал работать над учебниками, но сейчас я переживаю много жесткого дерьма в своей жизни, и я не думаю, что смогу их закончить. Надеюсь, они помогут хотя бы немного, я сожалею, что больше не мог.

http://realitymultiplied.blogspot.mx/