I am writing a custom model loader (to load IQE files). So far, things have been working well, but I’ve run into a snag when playing animations. When I load a skeleton, but don’t animate it at all, the skeleton takes the pose I expect it to, but as soon as I start running an animation, the orientation of the bones all change, so that the skeleton itself becomes rotated and then individual bones are rotated improperly relative to their parent bone. Other than that, the animation seems to be playing correctly. I am wondering how the rotation and translation values in a BoneTrack are interpreted (eg. are they relative to something?) by the engine, so that I can more easily debug this.
Can anyone provide me with any info, hints, or suggestions?
EDIT: The solution was that BoneTrack transforms are supposed to be relative to the binding pose, whereas the transforms I was adding were absolute. This was not that difficult to figure out. The hard part (for me) was calculating the correct rotation based on the absolute rotation and the binding pose rotation. The correct calculation turned out to be:
There’s this thing called a “binding pose” that makes animation a bit complicated. Every bone has a binding transform (usually just a rotation) relative to its parent. At every joint, the animation transforms from the bone track are applied on top of the binding pose.
I assume by “absolute rotation” you mean the bone’s orientation in the coordinate system of the skeletonized object. Correct?
The transforms in the bone track are relative to both the parent and the bind pose, so you’d have to undo both of those to get the correct answer. And of course the parent’s orientation is affected by its bind pose and local rotation, and so on back to the root bone. And of course the skeleton as a whole might be rotated.
And as you’ve discovered, with quaternions, A x B does not necessarily equal B x A.
Just some precision about this. This also guaranty correct rotation. if the rotation was accumulated from frame to frame we’ll end up with too much error in the end and the last frames would look wrong.
I don’t know the math logic behind this though, probably because we use quaternions and they don’t represent exactly the same rotation as a corresponding matrix…or… I’m full of shit… anyway just know that this is the reason behind this design
If there were an accumulation of errors, that would be caused by
floating-point arithmetic. It’s of particular concern since jME3
implements quaternions using single-precision. Avoiding
error accumulation is an important aspect of Numerical Methods.