1
$\begingroup$

I have two slightly different rigs (two armatures from different sources) and trying to transfer rotations between corresponding bones, from one armature to another (retarget current pose at some degree). Everything is fine except one thing - some bones has different rolls in edit mode, and simple cloning of rotation_quaternion shifts final positions.

The quiestion is: How i can account for roll difference, when applying rotation_quaternion from donor bone to target one? I don`t wish to reset roll on target bones, instead i with to recalculate quaternion for different roll, so target roll will stay the same, but quaternion will account for the difference instead. Imho this is possible, since rotation_quaternion is able to completely define bone rotation, but... how? How i can translate quaternion from one bone-local coordinate system to another?

I already tryed to calculate something like this: "donor rotation_quaternion" - "donor roll" + "target roll" to get "target rotation_quaternion". For example i tryed to create "donor roll" - "target roll" rotation matrix and apply it to rotate quaternion around target bone Z axis (to undo roll difference), but no luck.

So... How roll is applyed to final bone orientation? Is there the way to remove/undo it from rotation_quaternion?

Any help really appreciated

$\endgroup$
  • $\begingroup$ After some digging into Blender sources i started to think this is not possible (to overcome bone roll via rotation quaternion). Armature deformation math can be found here (just one of blender fork around the net): searchcode.com/file/131130197/blender/source/blender/blenkernel/… And it looks like Rest Matrices are calculated in slightly "separate tree" from pose matrices, so there is no direct way to "undo" roll part of the equation. Because roll affect rest matrices of child bones completely by itself, in "logical paralel" with pose calculation :( $\endgroup$ – IPv6 Aug 11 '17 at 11:40
0
$\begingroup$

I managed to overcome roll differences by resetting roll on all bones to zero without affect final pose (much). Procedure is little hackish but it works:

  • create armature clone in same place as donor one
  • add rotation constraint in WORLD coordinates on each bone of clone
  • reset roll to 0 on all edit bones of clone (bones will do thier best to stay intact due constraint)
  • execute "Apply Visual Transform to Pose" - bpy.ops.pose.visual_transform_apply() - on clone bones to flush contraints into real bone properties
  • remember clone rotation_quaternions and delete clone
  • set roll=0 and rotation_quaternion to remembered values on original armature.

That is all. After that we have almost the same pose, but all roll values on each bone are zeroed out

Code: https://gist.github.com/IPv6/0209f6ff4e013c575ca69ef0fbc0fe14

$\endgroup$

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.