我的骨骼蒙皮存在问题,我的骨骼不是围绕它们的本地原点旋转,而是围绕它们的父节点旋转。左 - 我的引擎。右 - 搅拌机
我怀疑管道中有两个位置有问题,但我不知道它到底在哪里。首先,我有一段代码可以实际计算骨骼矩阵:
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 是推送到着色器的数组。
在我的网格/动画解析器中,我有计算反向绑定姿势矩阵的代码(使用 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 函数在本地空间中获取项目。
以及上面引用的 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() 函数也是如此)。
所以我的问题是,为什么会这样?此外,在网格蒙皮中这种类型的事情的一些原因是什么?我的翻译是本地的,但轮换不是。