Rotation Order\Joint Orient

Rotation Order

Rotation Orders (TD Matt)


Rotation orders are perhaps one of the most neglected areas of rigging and yet they have a major impact on the stability of the rig and usability for the animators. Setting the correct orders can save hours of work trying understand curves that make no sense and struggling to clean up wierd rotation pops in a single animation. Multiply that over all animations for a character, all characters in a project and suddenly the importance of getting this right becomes self evident.

He even includes a skel w/his preferred rotation orders..

Biped Cheat Sheet

Note: These are suggestions only, and may vary w/personal preference or based on the structure and range of motion needed by the character.

for Y-down (from TD Matt):

COG: zxy

Hip: zxy

leg joints: yzx

shoulder/clav: yxz

upper arm: zyx (or yzx)

lower arm: zyx (or yzx)

wrist: yzx

spine base: zxy

mid spine: yzx

chest: zxy

neck: yxz

head: yxz

for X-down

COG: zxy

Hip: zxy

leg joints: xzy

shoulder/clav: xyz

upper arm: zxy

lower arm: zxy

wrist: xyz (or yzx?)

fingers: yzx

spine base: zxy

mid spine: xzy

chest: zxy

neck: yxz

head: yxz


I'd like to add up all the child rotations of a hierarchy (with

different rotation orders) and output them to the euler rotations of

one node with a scripted python plugin.

It would be similar to decomposing a world matrix, however it would

take account of rotations over 180 degrees and different rotation

orders thereby giving a correct value for the total rotation of a

child rather than just a pointless world space orientation.

I can't find the source code in the devkit for the decomposeMatrix

plugin (unsupported?) but I did find:

'Find Euler rotation values of Maya matrix'

I'm currently looping through a dag path and incrementally adding

rotations with the xform command in an expression

Could someone please demonstrate, in scripted plugin code, how to add

rotations together that have different rotation orders like the xform

command does?

OK! Due to further research, it seems that matching rotations of

different rotation orders is a mathmatical imposibility;

So, the question now is;

What would be the scripted plugin code to do 'relative' additive

rotations on one transform from the rotation values of nodes in a


I'd like to use this class that supports rotations past 360 degrees

using "MTransformationMatrix::rotateBy"


You can match transformations with different rotation orders,

because internally the rotation order is irrelevant, it is only used

when calculating the input and the output ( given it is rotation ).

Internally the 4x4 matrix is just a bunch of vectors, that dont

know anything about rotation orders and how many times they spun around.

So I am not sure if the classic way will get you what you are looking for.

(j. berger)

My current mel script that I'd like to turn into a scripted plugin:

for ($obj in $hir){

string $type = `nodeType $obj`;

if (`gmatch joint $type`){

float $jo[] ={};

$jo[0] = `getAttr ($obj + ".jointOrientX")`;

$jo[1] = `getAttr ($obj + ".jointOrientY")`;

$jo[2] = `getAttr ($obj + ".jointOrientZ")`;

rotate -r -os $jo[0] $jo[1] $jo[2] c;


float $rot[] = `xform -q -os -ro $obj`;

rotate -r -os $rot[0] $rot[1] $rot[2] $target;


By "classic way" do you mean using the MMatrix class?

Because 'AK Eric' says in the above mentioned description that the

"MTransformationMatrix [class] will keep track of rotations past 360

degrees & rotation order of the node, while MMatrix objects will not.

It makes sense: A matrix itself stores orientations as vectors, which

have no concept how how far they’ve been ‘rotated’, so the MMatrix

object doesn’t track this data. But behind the scenes, the

MTransformationMatrix does track this info..."

The whole point of the plugin I want to create is to add up how many

times the source nodes have spun and incrementaly add the rotations

together and output it on to one node. It sounds like

"MTransformationMatrix::rotateBy" would allow me to do this?


The example in the blog just spits out what has

been put into the TransformationMatrix.

The question is whether when you add a rotation

this will be kept track of as well, right?

If I were you I would take the code from the blog

and add some rotation either with rotateBy

or addRotation and then see what it spits out.

Sorry I can not give you direct answers and/or write code ...

(j. berger)

Luckily I found out that you DID help someone last year with a similar



Maybe someone else could please suggest how to "just" add a line to

the following to use MTransformationMatrix::

  • rotateBy a value, if they

  • get the time


  • Somehow this:

  • rotate -r -os $rot[0] $rot[1] $rot[2] $target;

  • Equals this:

  • MTransformationMatrix::rotateBy ( const MEulerRotation & e,

  • MSpace::Space space, MStatus * ReturnStatus = NULL )

  • It would be much appreciated.


Rotation Order and Set Driven Keys

(ie., for armor, feathers or other sliding-plane animation)

Just keep in mind, if you use Driven Keys, that if you get into complex rotation, your driving axis could be a bit unpredictable. (talking about gimbal lock and euler rotation order.) You would want the driving axis to be the last letter in your joint's rotation order.

Assuming you are rotating in Z, you'd want your joint's rotation order to be xyz or yxz.

If this is an elbow (for example) and it is only rotating in one axis, this won't be a problem.


Gimbal Lock Prevention

What to do?

You can add in extra 'gimbal breaker' controls, and preferably hide them when not in use to avoid confusing those animators, OR..

check out this post (link thanks to Brad Clark)

Joint Orient

One of the most important things about rigging is making sure your joints are properly oriented.

badly oriented joints == endless pain.

- if you have rotations in any of your joint orient except for the channel you are using to bend (ie., z, if you are using x down), it will make it harder to do ik/fk switch, among other things.

-how to create proper joint orient?

If x is down the axis on the left-hand side, z is always facing fwd, and y axis is always to the left of z if you are looking straight down the axis

on the opposite side (-x), x is reversed and going up the axis, z faces backward and the y axis is still to the left of z if you are facing up.