В настоящее время я реализую скелетную анимацию в своем 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]));
}
Спасибо!