I am writing a custom exporter to export from blender to my opengl program. To read the roatation, as well as convert from blender's cordinate system to my game's system, i use this code:

e = poseBone.rotation_quaternion.to_euler()
quat = Euler((e[1], e[2], e[0])).to_quaternion() #write this quat to file

Bones in blender, as demonstrated by this image, have their own local space: image I believe this difference in local bone space vs world space is the last thing causing incorrect rotations in my opengl program. How would convert bone.rotation_quaternion from local bone to world space prior to export? I have seen several similar questions, but none that helped me.

  • 2
    $\begingroup$ It is quite confusing that you take the rotation_quaternion and convert it to an euler and back to quaternion in an VERY roundabout method. $\endgroup$ – Mutant Bob Oct 25 '17 at 14:37
  • $\begingroup$ This is to convert from blender's coordinate system to my own. X->Z, Y->X Z->Y $\endgroup$ – user1812 Oct 25 '17 at 16:19

Based on some simple experiments it seems that

debone = Matrix([[1,0,0,0],[0,0,-1,0], [0,1,0,0],[0,0,0,1]]) #because bones are wacky
m = armature_object.matrix_world * poseBone.matrix * debone
o2.rotation_mode = 'QUATERNION'
o2.location, o2.rotation_quaternion, o2.scale = m.decompose()

will align o2 with poseBone (unless o2 has a parent causing its matrix_local to not be identical to matrix_world)

  • $\begingroup$ I am trying to convert rotation from bone space to object/world space. If i "roll" the pose bone 90 degrees along itself, poseBone.matrix.to_euler() or poseBone.rotation_quaternion.to_euler() says the rotation is around Y, becouse in bone space, "Y" is the axis that runs along the bone. However, unless the bone itself is aligned with world "Y", then the rotation will be wrong. For excample, if the bone is aligned with "X" then the rotation will bend the animation up/down instead of rolling it. $\endgroup$ – user1812 Oct 25 '17 at 16:40
  • $\begingroup$ OK, let's see if my edit to the answer gives you what you need. $\endgroup$ – Mutant Bob Oct 25 '17 at 17:51
  • $\begingroup$ with this code, rotation_quaternion.to_euler() gives a rotation of 90 for blender's 'X' and -90 for 'Z' when the bone is in its original position. $\endgroup$ – user1812 Oct 25 '17 at 21:17
  • $\begingroup$ Would a debone matrix of Matrix([[1,0,0,0],[0,0,1,0], [0,-1,0,0],[0,0,0,1]]) be better? I am having difficulty figuring out exactly what you want from the wording of your question. $\endgroup$ – Mutant Bob Oct 27 '17 at 1:51
  • $\begingroup$ I am just trying to get the rotation from resting position at a given key frame. armature.pose.bones[foo].matrix * armature.data.bones [foo].matrix_local.to_4x4().inverted() seems to be giving something along the correct lines, but I need to do more testing. $\endgroup$ – user1812 Oct 27 '17 at 3:48

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.