1
$\begingroup$

I'm trying to write an exporter for Blender, but i can't wrap my head around how to get the rotations straight. In the format I'm trying to export to, the initial orientation is always neutral relative to the pivot point (= bone position in world space). Rotations and translations are represented as relative to the parent (so basically, expressed in world space, since initial bone matrices are identity matrices). I'm using the OrientationHelper class to create a global_matrix, same as in most exporters - the resulting matrix in this case rotates 90 degrees around the Z axis. My idea was then to multiply each quaternion keyframe for each bone with this matrix in the export (global_matrix * rot), but this results in each bone contorting 90 degrees relative to its parent. My most successful attempt so far has been to do it like this:

for x, y, z, w in zip(xcurve.keyframe_points, ycurve.keyframe_points, zcurve.keyframe_points, wcurve.keyframe_points):
        rot = Quaternion((x.co[1], y.co[1], z.co[1], w.co[1]))
        rot = global_matrix.inverted().to_quaternion() * rot.inverted() * global_matrix.to_quaternion()
        rot.normalize()
        fw("\t\t%d: {%f, %f, %f, %f},\n" % (f2ms * int(x.co[0]), rnd(rot.x), rnd(rot.y), rnd(rot.z), rnd(rot.w)))

The result becomes 90% correct, but some joints still rotate the wrong way. I just came to this formula by randomly testing things and seeing what works. I have no idea why inverting the rotation makes it twist the right way. My intuition would say that the correct method would be to first multiply the keyframe quat with bone.matrix_local (bone space to armature space), then rotate it by global_matrix, and finally rotate it by bone.matrix_local.inverted() to get it back to bone space. This fails miserably though, and my character ends up as a curled ball. So, to summarize, i guess my question is:

  • What space are rotation (quaternion) keyframes for bones stored in?
  • What would be the proper way to apply an axis conversion matrix to a quaternion keyframe animation, if the (exported) rest state of each bone is always the identity matrix, and animations should be exported as being relative to their parent bone?

Note: to keep things simple, I'm not mixing in the armature's world matrix yet, since it's the identity matrix in this case. If anyone has a solution which includes this though, it would make me very happy.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.