不正确的骨骼旋转,基于编辑模式下的骨骼结构
Incorrect bone rotations, based on bone structure in edit mode
我有一个关于 assimp 和 blender 导出的 trouble/question。我将模型从搅拌机导出到 gltf 二进制文件 (.glb),并且一切正常,除非搅拌机内的骨骼不是在姿势模式内旋转(在编辑模式下创建和旋转)我很好奇问题是否可以在内部解决代码,或者我必须修改搅拌机的导出来修复它。
如您所见,在第一次比较中,一个骨骼骨骼朝上,而在第二次比较中,它在编辑模式下旋转,导致其旋转不正确。
这是我计算动画矩阵的 C++ 代码
class Bone
{
public:
int Id;
glm::mat4 Transform;
Bone* BoneParent;
std::vector<Bone*> BoneChild;
glm::mat4 NodeTran;
glm::mat4 MTran;
std::vector<glm::vec3> LocFrames;
std::vector<glm::quat> RotFrames;
std::vector<glm::vec3> ScaleFrames;
glm::mat4 Offset;
glm::mat4 getLocalTransform()
{
float Factor= 1.0;
glm::vec3 T= this->LocFrames[1]+ (Factor * (this->LocFrames[1] - this->LocFrames[0]));
glm::mat4 TR = glm::translate(glm::mat4(1.0f), T);
glm::quat R = glm::normalize(glm::mix(this->RotFrames[0],this->RotFrames[1],Factor));
glm::mat4 RT = glm::toMat4(R);
return TR*RT ;
}
glm::mat4 getParentTransform()
{
if (this->BoneParent){
return BoneParent->NodeTran;
}
else {
return glm::mat4(1.0f);
}
}
class Skeleton
{
public:
std::vector<Bone> BoneList;
Bone *Root;
glm::mat4 inverse;
aiMatrix4x4 inverseai;
void Calc(Bone* bone = NULL)
{
bone->NodeTran = bone->getParentTransform()* // parent
bone->getLocalTransform(); // T*R
bone->Transform = inverse * // ai inverse
bone->MTran* // node->mTransformation of bone
bone->NodeTran*
bone->Offset; // bone->mOffsetMatrix
for (int i = 0; i < bone->BoneChild.size(); i++) {
Calc(bone->BoneChild[i]);
}
}
};
//...
//...
ObjModel->ModelSkeleton.Calc(ObjModel->ModelSkeleton.Root);
for(int i=0; i<ObjModel->ModelSkeleton.BoneList.size();i++){
glm::mat4 matrix = ObjModel->ModelSkeleton.BoneList[i].Transform;
glUniformMatrix4fv(glGetUniformLocation(ActiveShader->ID, "Anim[0]")+i, 1, GL_FALSE, glm::value_ptr(matrix );
}
通过调试各种东西,我发现 blender/assimp gltf2 导入器将骨骼平移(旋转、位置、大小)和节点(静态骨骼)的偏移量放在 location/rotation/scale 帧中,我解决了:
- 创建 'unanimated' 序列,顾名思义,包含非动画骨骼
- 保存非动画 loc/rot/scale 帧
- 用非动画帧减去所有动画帧
我知道这是一个“hackfix”,但这超出了我的理解范围,因为错误在 blender 或 assimp import 中
我有一个关于 assimp 和 blender 导出的 trouble/question。我将模型从搅拌机导出到 gltf 二进制文件 (.glb),并且一切正常,除非搅拌机内的骨骼不是在姿势模式内旋转(在编辑模式下创建和旋转)我很好奇问题是否可以在内部解决代码,或者我必须修改搅拌机的导出来修复它。
如您所见,在第一次比较中,一个骨骼骨骼朝上,而在第二次比较中,它在编辑模式下旋转,导致其旋转不正确。
这是我计算动画矩阵的 C++ 代码
class Bone
{
public:
int Id;
glm::mat4 Transform;
Bone* BoneParent;
std::vector<Bone*> BoneChild;
glm::mat4 NodeTran;
glm::mat4 MTran;
std::vector<glm::vec3> LocFrames;
std::vector<glm::quat> RotFrames;
std::vector<glm::vec3> ScaleFrames;
glm::mat4 Offset;
glm::mat4 getLocalTransform()
{
float Factor= 1.0;
glm::vec3 T= this->LocFrames[1]+ (Factor * (this->LocFrames[1] - this->LocFrames[0]));
glm::mat4 TR = glm::translate(glm::mat4(1.0f), T);
glm::quat R = glm::normalize(glm::mix(this->RotFrames[0],this->RotFrames[1],Factor));
glm::mat4 RT = glm::toMat4(R);
return TR*RT ;
}
glm::mat4 getParentTransform()
{
if (this->BoneParent){
return BoneParent->NodeTran;
}
else {
return glm::mat4(1.0f);
}
}
class Skeleton
{
public:
std::vector<Bone> BoneList;
Bone *Root;
glm::mat4 inverse;
aiMatrix4x4 inverseai;
void Calc(Bone* bone = NULL)
{
bone->NodeTran = bone->getParentTransform()* // parent
bone->getLocalTransform(); // T*R
bone->Transform = inverse * // ai inverse
bone->MTran* // node->mTransformation of bone
bone->NodeTran*
bone->Offset; // bone->mOffsetMatrix
for (int i = 0; i < bone->BoneChild.size(); i++) {
Calc(bone->BoneChild[i]);
}
}
};
//...
//...
ObjModel->ModelSkeleton.Calc(ObjModel->ModelSkeleton.Root);
for(int i=0; i<ObjModel->ModelSkeleton.BoneList.size();i++){
glm::mat4 matrix = ObjModel->ModelSkeleton.BoneList[i].Transform;
glUniformMatrix4fv(glGetUniformLocation(ActiveShader->ID, "Anim[0]")+i, 1, GL_FALSE, glm::value_ptr(matrix );
}
通过调试各种东西,我发现 blender/assimp gltf2 导入器将骨骼平移(旋转、位置、大小)和节点(静态骨骼)的偏移量放在 location/rotation/scale 帧中,我解决了:
- 创建 'unanimated' 序列,顾名思义,包含非动画骨骼
- 保存非动画 loc/rot/scale 帧
- 用非动画帧减去所有动画帧
我知道这是一个“hackfix”,但这超出了我的理解范围,因为错误在 blender 或 assimp import 中