Using matrices to mirror animation in Maya 2012

I’m fairly new to scripting, so please bear with me. I’ve never used PyMel or API before, just Maya cmds.

I’m trying to make a simple animation mirroring script for Maya 2012 (I know I can just use the bonus tools in Maya, but I’d really like to make my own). I want it to be able to mirror bone animation as well as rig animation in the end. I realize that by trying to mirror bone animation, I’m making more work for myself (the joint orients will probably get messed up), but I’d like to try.

From my research, it seems that the majority of people use matrices for this sort of thing(though I don’t fully understand why).

As a way to test mirroring one object’s transform to another object, I wrote this script:


import maya.cmds as cmds
import pymel.core as pm
import pymel.core.datatypes as dt


currentSelection1= pm.ls(selection=True)[0]
currentSelection2= pm.ls(selection=True)[1]

currentMatrix = currentSelection1.getMatrix(worldSpace=True)
print currentMatrix.formated()

reflectionMatrix_YZ = dt.Matrix(-1.0,0.0,0.0,0.0, 0.0,1.0,0.0,0.0, 0.0,0.0,1.0,0.0, 0.0,0.0,0.0,1.0)

newMatrix = currentMatrix * reflectionMatrix_YZ

currentSelection2.setMatrix(newMatrix , worldSpace=True)
newReflectedMatrix  = currentSelection2.getMatrix(worldSpace=True)
print newReflectedMatrix .formated()


On first look, it SEEMS like it works. However, the “currentSelection2” object ends up with -1 scale in Z.

My question(s) is: How can I mirror something, using matrices, without getting negative scale? Is there a better way to do this? Do I even need to use matrices?

Thank you in advance.

When you mirror something with matrices, you always get a negative scale on some axis.
I could be wrong, but I think that’s just how the math works.

to mirror without the scaling, you must actually map Right side joints to Left side joints and swap rotation values
even then it won’t be bullet proof. (not sure what you do with the spine, for example)
And of course the joints has to be oriented in a way that supports such value swapping.

I our game we require mirroring on many characters, and we use matrices to do it.
For symmetrical characters it is not an issue (we just make sure to flip the normals & normal map where needed)
For asymmetrical characters we actually build a second mirrored mesh -“pre-reversed” so to speak.

Depending on your platform / engine you may have other options as well.
Unity’s Mecanim Humanoid rigs have a mirror attribute that can be toggled, for example.

This is what we do when we need to mirror an animation when authoring inside Maya.
Each control knows what it’s mirror is, and which curves to swap. (I think we use message attrs for this)
For things like the spine, we do some math on the curves to flip them. (Mostly some * -1)

Orientation is rather crucial for this to work, we had one rig that somehow got tiny orientation values added to the hierarchy, threw the whole system off. The problem was subtle because near origin you couldn’t really tell, but we had a few root driven animations that needed to be mirrored, and the further out from origin the more bizarre the mirrored version would look.

Thank you both so much for the clarification and explanation! It’s really helped me to understand mirroring a lot better. I feel like I’ll be able to make my tool now. Thanks again!