About Me

Tuesday, July 6, 2010

Trax, Character Sets and Referencing

Whilst this stuff is fresh in my mind I wanted to put it down, more for my reference but who knows, it may be useful to others.

How Does Referencing work with Character Sets?
As per previous posts, referencing is nothing more than an import of data from one scene into your current, followed by an edit list applied afterwards. The thing is that the refEdits are all based on full Dag node paths, so if you change the name of a node in the master file, or reparent it, your referencing for that edit fails. Namespaces go some way to eliviate clash issues but other than that, it's all name based. In fact, you really need to think of Maya's scene hieracrhy not as a nested scene graph, but as a flat, dag name based database.

So How Do CharacterSets help?
Unlike normal referencing, all connections to objects that are members of a CharacterSet are based NOT on name, but on the membership index of that set. This means that as long as you carefully maintain the internal order of the chSet, you can rename and regroup at will, the connections for your animations will be maintained.

A Little Deaper:
The CharacterSet in Maya is actually mapped in a totally different way internally to that which the users sees. Rather than using names to pass animations to channels it uses characterMapping and characterAlias's. It's actually split down into 3 main internal arrays,

  • Map 0 : unitlessValues : animCurveTU - attrs like user defined and scales
  • Map 1 : linearValues : animCurveTL - transform data
  • Map 2 : angularValues : animCurveTA- rotational data
in your Master Rig file (.ma) that contains the characterSet you see a block that looks something like this:
setAttr ".rm" -type "characterMapping" 206 "RIG:Shoulders_Ctr.SpineBias"
0 1 "RIG:Shoulders_Ctr.rotateZ" 2 1 "RIG:Shoulders_Ctr.rotateY"
2 2 "RIG:Shoulders_Ctr.rotateX" 2 3 "RIG:Shoulders_Ctr.translateZ"
1 1 "RIG:Shoulders_Ctr.translateY" 1 2 "RIG:Shoulders_Ctr.translateX"
1 3 "RIG:Hips_Ctr.rotateZ" 2 4 "RIG:Hips_Ctr.rotateY"

Here the characterSet has 206 members (channels), "RIG:Shoulders_Ctr.SpineBias 0 1" indictates that this is a unitlessValue (Map 0) and it's unitlessValue[1]. "RIG:Hips_Ctr.rotateZ" 2 4 indicates it's an angularValue (Map 2) and angularValue[4].... and so on....

The channels within the ChSet are mapped to these arrays in the order they're found within the ChSet, but going from bottom to top. It's this mapping thats then used to reConnect channels and animCurves when you load or reference the scene.
In the referenceEdits you'll see the connections from animCurves to these lists, which will give you an idea of just how the data is mapped internally on a real scene.

The key thing here is that because it's all based on order, should you switch your reference to a rig whos chSet mapping is different the whole thing falls apart. Say you had a refEdit :
connectAttr animCurveTL4545 LinearValue[4] 
that connected the translateX of the Wrist to it's animCurve, this edit would still just blindly go and remake this connection, even though LinearValue[4] may now be a completely different object. Now in Maya2011 they try and resolve this issue in a post load script that runs after file load, but's it's better to know about than rely on it.

So the key is, maintain the chSets, order is king.