骨骼围绕父级旋转 - OpenGL Animation/Skinning
Bones rotate around parent - OpenGL Animation/Skinning
我的骨骼蒙皮有问题,我的骨骼不是围绕它们的本地原点旋转,而是围绕它们的父对象旋转。 Left - my engine. Right - blender
我怀疑管道中有两个位置有问题,但我无法说出具体位置。首先,我有这段实际计算骨骼矩阵的代码:
void CalculateBoneTransform(DSkeletonBone sb, dmat4x4f parentTransform, std::vector<DSkeletonBone> boneOverrides)
{
if (boneDataIndex.count(sb.name) == 0) return;
Transform transform = sb.localTransform;
for (auto& bo : boneOverrides)
{
if (bo.name == sb.name)
{
transform = bo.localTransform;
}
}
dmat4x4f globalTransform = dmat4x4f::Mul(parentTransform, transform.GetMatrix());
dmat4x4f finalTransform = dmat4x4f::Mul(globalTransform, sb.inverseTransform);
finalTransforms[boneDataIndex[sb.name]] = finalTransform;
for (auto& pbC : sb.children)
{
CalculateBoneTransform(pbC, globalTransform, boneOverrides);
}
}
boneOverrides 来自任何想要覆盖骨骼的东西(例如动画)。
finalTransforms 是被推送到着色器的数组。
在我的 mesh/anim 解析器中,我有这段代码计算反向绑定姿势矩阵(使用 OpenFBX,但这不相关):
glm::mat4 local = glm::inverse(GetMatFromVecs(
boneData[skin->getCluster(i)->name].pos,
boneData[skin->getCluster(i)->name].rot,
boneData[skin->getCluster(i)->name].scl));
for (Object* parent = skin->getCluster(i)->getLink()->getParent(); parent != NULL; parent = parent->getParent())
{
glm::mat4 parentInverseTransform = glm::inverse(GetMatFromVecs(
parent->getLocalTranslation(),
parent->getLocalRotation(),
parent->getLocalScaling()));
local = parentInverseTransform * local;
}
boneData[skin->getCluster(i)->name].offset = local;
getLocalXX 函数获取本地 space 中的项目。
以及上面引用的 GetMatFromVecs 函数:
glm::mat4 GetMatFromVecs(Vec3 pos, Vec3 rot)
{
glm::mat4 m(1);
m = glm::scale(m, glm::vec3(1,1,1));
m = glm::rotate(m, (float)rot.x * 0.0174532925f, glm::vec3(1, 0, 0));
m = glm::rotate(m, (float)rot.y * 0.0174532925f, glm::vec3(0, 1, 0));
m = glm::rotate(m, (float)rot.z * 0.0174532925f, glm::vec3(0, 0, 1));
m = glm::translate(m, glm::vec3(pos.x, pos.y, pos.z));
return m;
}
注意我先旋转,然后平移(顺便说一句,第一个代码片段中引用的 GetMatrix() 函数也是这种情况)。
所以我的问题是,为什么会这样?另外,网格蒙皮中出现这种情况的原因有哪些?我的翻译是本地的,但旋转不是。
我的问题是矩阵数学不好。我将我的 matrix::mul 函数换成 glm 并得到了预期的结果。
我的骨骼蒙皮有问题,我的骨骼不是围绕它们的本地原点旋转,而是围绕它们的父对象旋转。 Left - my engine. Right - blender
我怀疑管道中有两个位置有问题,但我无法说出具体位置。首先,我有这段实际计算骨骼矩阵的代码:
void CalculateBoneTransform(DSkeletonBone sb, dmat4x4f parentTransform, std::vector<DSkeletonBone> boneOverrides)
{
if (boneDataIndex.count(sb.name) == 0) return;
Transform transform = sb.localTransform;
for (auto& bo : boneOverrides)
{
if (bo.name == sb.name)
{
transform = bo.localTransform;
}
}
dmat4x4f globalTransform = dmat4x4f::Mul(parentTransform, transform.GetMatrix());
dmat4x4f finalTransform = dmat4x4f::Mul(globalTransform, sb.inverseTransform);
finalTransforms[boneDataIndex[sb.name]] = finalTransform;
for (auto& pbC : sb.children)
{
CalculateBoneTransform(pbC, globalTransform, boneOverrides);
}
}
boneOverrides 来自任何想要覆盖骨骼的东西(例如动画)。 finalTransforms 是被推送到着色器的数组。
在我的 mesh/anim 解析器中,我有这段代码计算反向绑定姿势矩阵(使用 OpenFBX,但这不相关):
glm::mat4 local = glm::inverse(GetMatFromVecs(
boneData[skin->getCluster(i)->name].pos,
boneData[skin->getCluster(i)->name].rot,
boneData[skin->getCluster(i)->name].scl));
for (Object* parent = skin->getCluster(i)->getLink()->getParent(); parent != NULL; parent = parent->getParent())
{
glm::mat4 parentInverseTransform = glm::inverse(GetMatFromVecs(
parent->getLocalTranslation(),
parent->getLocalRotation(),
parent->getLocalScaling()));
local = parentInverseTransform * local;
}
boneData[skin->getCluster(i)->name].offset = local;
getLocalXX 函数获取本地 space 中的项目。
以及上面引用的 GetMatFromVecs 函数:
glm::mat4 GetMatFromVecs(Vec3 pos, Vec3 rot)
{
glm::mat4 m(1);
m = glm::scale(m, glm::vec3(1,1,1));
m = glm::rotate(m, (float)rot.x * 0.0174532925f, glm::vec3(1, 0, 0));
m = glm::rotate(m, (float)rot.y * 0.0174532925f, glm::vec3(0, 1, 0));
m = glm::rotate(m, (float)rot.z * 0.0174532925f, glm::vec3(0, 0, 1));
m = glm::translate(m, glm::vec3(pos.x, pos.y, pos.z));
return m;
}
注意我先旋转,然后平移(顺便说一句,第一个代码片段中引用的 GetMatrix() 函数也是这种情况)。
所以我的问题是,为什么会这样?另外,网格蒙皮中出现这种情况的原因有哪些?我的翻译是本地的,但旋转不是。
我的问题是矩阵数学不好。我将我的 matrix::mul 函数换成 glm 并得到了预期的结果。