我正在编写自己的 COLLADA 导入器。我已经走了很远,加载网格和材料等。但我在动画方面遇到了障碍,特别是:关节旋转。
我用于为网格蒙皮的公式很简单:
weighted;
for (i = 0; i < joint_influences; i++)
{
weighted +=
joint[joint_index[i]]->parent->local_matrix *
joint[joint_index[i]]->local_matrix *
skin->inverse_bind_pose[joint_index[i]] *
position *
skin->weight[j];
}
position = weighted;
就文献而言,这是正确的公式。现在,COLLADA 为关节指定了两种类型的旋转:局部和全局。您必须将旋转连接在一起以获得关节的局部变换。
COLLADA 文档没有区分关节的局部旋转和关节的全局旋转。但在我见过的大多数模型中,旋转的 id 可以是rotate
(全局)或jointOrient
(局部)。
当我忽略全局旋转而只使用局部旋转时,我得到了模型的绑定姿势。但是当我将全局旋转添加到关节的局部变换中时,奇怪的事情开始发生。
这是不使用全局旋转:
这是全局旋转:
在这两个屏幕截图中,我都使用线条来绘制骨架,但在第一个屏幕中它是不可见的,因为关节位于网格内部。在第二个屏幕截图中,顶点到处都是!
为了比较,这是第二个屏幕截图的样子:
很难看到,但您可以在第二个屏幕截图中看到关节处于正确位置。
但现在奇怪的事情。如果我忽略 COLLADA 指定的反向绑定姿势,而是取关节的父局部变换乘以关节的局部变换的倒数,我得到以下结果:
在这个屏幕截图中,我从每个顶点到有影响的关节画了一条线。我得到绑定姿势的事实并不奇怪,因为现在公式变成了:
world_matrix * inverse_world_matrix * position * weight
但这让我怀疑 COLLADA 的反向绑定姿势在错误的空间中。
所以我的问题是:COLLADA 在什么空间指定它的反向绑定姿势?以及如何将反向绑定姿势转换为我需要的空间?