Friday, November 19, 2010

Audio Sound node - follow on

Following on from my previous post about audio:

In the Trax editor you can actually trim the sound directly. It's very hidden and there's no graphical hint at all, but if you LMB drag on the top left / right of the sound node, over the top time text, then you'll be able to trim the sound directly. If you're in the CamSequencer you can also, by doing a Shift MMB Drag, shift the audio itself within the sound track. All hidden features, but they work (only in 2011)

Wednesday, November 17, 2010

Hidden Audio functionality in Maya2011

New Audio Handling in Maya2011

I wanted to point out a couple of hidden features for Audio handling that aren't in the docs and that kind of slipped into Maya2011 via the CameraSequencer upgrades. The audio node in Maya used to just have 2 main attrs, path and offset, that was all you could do, point it to a wav and set the start time. If you now look at an audio node in 2011 there's a ton of new attributes to control the behaviour of the audio. Unfortunately most of this is hidden unless you're using the AttributeEditor or CameraSequencer, in which case RMB on a sound you'll get access to Mute, that's about it. In the Trax sound is still just a simple, poorly supported add-on..... or is it?



Firstly there's now a Mute attr, so you can mute out those audio's you don't want, this displays in both Sequencer and Trax, but for Trax you have to set the attr direct.  Now for the more complex stuff. If you're used to editing in Trax you're used to sliding the start and end times, trimming the clip etc. There's no UI support for Sound for any of this, BUT you can still do it via the attr's directly.



So, 2 sets of attrs work together. Offset and EndFrame, SourceStart and SourceEnd. The Offset is no longer what it used to be, this is the start of the clip nothing more. If like us you have tons of sound code designed to offset audio then it's all stuffed! you need to manage both Offset and EndFrame at the same time now in order to shift a sound node along time.

However, using the Source attrs you can now trim the audio, directly in Maya..... there's not a lot been mentioned about this and we only found it by accident.

 The 2 sound nodes here are the same bit of audio, but the lower has been offset to start at frm 120, because the source start has also been moved to frm120 the audio is still in sync with the original one, just trimmed to start later on. The end source has been moved in, trimming the audio to stop earlier. You can also add silence to the start of the sound if needed.

Thought I'd share that as it's actually going to be really useful, think I'll push for the UI  integration from Autodesk so that the sound node is treated like the clips are, about to be trimmed directly rather than having to set the attrs up manually.

Mark

Thursday, September 30, 2010

Maya 2011 Subscription Pack now available

Autodesk have just made the Maya2011 Subscription Advantage Pack available on the Subscription Center for download. Great another bug fix build and a few new toys to play with, then never use again.

BE WARNED: point release 2011.5
They've made this a full point release so it now makes a ...docs/maya/Maya2011.5 for your prefs. Ok, this is fine, our pipelines can easily cope with this but what they've also done is had the program install into:

\Autodesk\Maya 2011 Subscription Advantage Pack

Not only not following their own naming conventions, but also filling the path with WHITE SPACES! How the hell are large scale studio pipelines which need to support multiple versions of Apps meant to deal with that one in a consistent manner? We can no longer guarantee any naming conventions and that's going to make life really tough. Our pipeline installer adds a python sitecustomize.py file into the Python\lib\site-packages dir so we need to be able to find it.

Oh, and to make it even better `getApplicationVersionAsFloat` returns 2011 not 2011.5! Great, thanks guys not that really has scuppered us.

WHY... and if somebody from Autodesk uses the word "Interoperability" again to try and persuade me that moving between apps is a good idea, just because they own them all, I'm going to kill them then dance over their still burning embers!

Friday, September 10, 2010

Relative Namespaces in Maya2011

I just wanted to add a quick pointer to the namespace -rel flag in Maya 2011 and how it can make managing namespaces a whole lot easier. By default this is set to false, meaning that all namespaces are treated from the root space (":") When you look in the Reference editor what you see as the namespace is the actual ns that the file was imported into.

Lets say you had imported a file 3 times on itself, so ended up with nested namespaces:

THIS:IS:ATEST:Myfile.ma

Now if you look in the ref editor you'll see the namespace as ATEST. If you try and change it it'll say the namespace doesn't exist. This is because your by default in root (":") space. This is where the rel flag can really help, it makes the namespace handling RELATIVE to the current space your in.

So mel:
namespace -set "THIS:IS";
namespace -rel true;
file -e -ns "FIXED" "C:/Test_Rig.ma";
namespace -rel false; 
namespace -set ":";

So here were setting ourself into the namespace THIS:IS, making all namespace actions relative to this, setting the new namespace to FIXED and then returning ourselves to root sapce and tuirning off the rel falg. The result is you've now changed the namespace that it said couldn't be changed, ending up with

THIS:IS:FIXED

Mark

Monday, September 6, 2010

fileBrowserDialog is no more! Thankyou Pymel!

Anybody who's used the Maya fileBrowserDialog command will know what a pain in the arse it is, having to always pass in a function for it to use on the returned selection. Why the hell couldn't it just give you back the path.
import pymel.core as pCore
print 'Folder Selected : %s' % (pCore.promptForFolder())
import pymel.core as pCore
print 'File Selected : %s' % (pCore.promptForPath())
Well, no more, I might have guessed that Chad would have simplified this and bingo Pymel promptForFolder() and promptForPath() functions. At last, it opens the file prompt window and just gives you back the return.

Chad,Pymel thankyou!

Thursday, September 2, 2010

Exporting Simple Skeleton and Mesh data via FBX in Maya

Its something that you think should be really easy, taking your animated rig data and spitting out an nice clean fbx containing just the animated skeleton and mesh data, but in practice Fbx is such a beast it needs a little pre-setup to achieve. What you need to do is to first select the nodes you want to output. FBX has no concept of what it should, or shouldn't output, so use the export selected option from Maya.

If like most rigs you have a master bind skeleton, select it's root, then run something like this to select any joint and mesh data under it, you may need to shift select your skin, the key is to get what you want selected and nothing else:

import maya.cmds as cmds
meshes=[]
joints=cmds.ls(sl=True)

#find all joints
joints.extend(cmds.listRelatives(type='joint',allDescendents=True))

#find your Skinned Geo
for skin in cmds.listConnections(joints,type='skinCluster'):
    if skin:
        shape=cmds.skinCluster(skin,query=True,geometry=True)
        meshTransform=cmds.listRelatives(shape,parent=True)[0]
        if meshTransform not in meshes:
            meshes.append(meshTransform)

cmds.select(joints,meshes)

Right, now you have the nodes you actually want to go through for export. I should point out here that this only works from Maya2010 onwards, there was an FBX bug in older versions of the export selected.

Here's the key, in the FBX output options (use fbs not fbx_dae) you need to go to the Animation Options block and make sure that these 2 flags are set.

Bake-Animations = ON, InputConnections= OFF




That's it. You should end up with a nice clean fbx with JUST the data you wanted in it.

Friday, August 13, 2010

FBX Update Issues with Merge

Just thought I'd share an issue that's cropped up with the latest versions of the FBX plugins, from v2011.2 onwards.

In previous versions if you did an import and had the include set to 'Update scene elements' it would import onto nodes using a shortName match so that the path didn't get taken into account. This is NO LONGER the case, it now uses a full DAG path match.

Our main MoCap pipeline relies on the fact the we have data coming from MotionBuilder as such:

FBX_DATA_GameRoot
....>FBX_DATA_Root
........>FBX_DATA_Spine

But on our Maya binders we parent this hierarchy as we may need to scale the nodes to get a better remapping fit, so in Maya it looks like

ADJUSTER
....>FBX_DATA_GameRoot
........>FBX_DATA_Root
............>FBX_DATA_Spine

Now this has always worked, and it's been very successful, the animators just throw the fbx into the scene and they get a bound rig. But because it's now using a full dag path match the fbx will no longer bring any data in unless the entire paths match.

This is something that the FBX guys know about and hopefully will be resolved/roll-back to it's previous functionality soon.



UPDATE:
As of FBX version FBX 2011.3.1. the guys at Autodesk rolled the behaviour of this back to it's original, so nodes are updated based on node name NOT full Dag path. Thanks to Trevor Adams in the FBX team for this one.

Thursday, July 8, 2010

Adding Syntax Highlighing to Blogger

I was doing some digging around last night to see how people inset syntax highlighting to blog posts and came across a really nice demo for it here:

http://codingfreak.blogspot.com/2009/02/blogger-adding-syntax-highlighter-to.html

Means you can do things like:

import pymel.core as pm
def dummystuff():
     node=pm.selected()[0]
     node.name()

It also has syntax highting for most languages supported :)

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.

Maya Animation Layers

I've just spend the last few days moaning at the Animation Layer setups and how poor the merge functionality is in Maya. We had a cutscene here that was 4000frms of baked MoCap, 3 animLayers, which took 40 minutes to merge on a 64bit beast of a machine. I can't understand why Autodesk are running the standard Bake command when it's so slow over large timelines.

Answer, by-pass it and use Trax. Ended up writing a function that would take all the nodes in each layer and generate a clip with the animData in it. So for the above case we end up with 3 clips. Now the Trax merge is FAST. The results meant that the same bake process going via this method went from 40 minutes, to 20 secs :)

And people diss Trax! It may be a little excentric, and lacking in features, but at least it's fast and clean.

Thursday, July 1, 2010

Reference Edits

One crucial thing with referencing is that the Reference Edit List isn't just a macro that's run in the order you performed the actions. Instead it's grouped and more importantly applied by function types. If you open the refEdit List up you'll see the grouped calls:

: setAttr
: addAttr
: connectAttr
: disconnectAttr
: deleteAttr

To get to the edit List open the referenceEditor then File > List ReferenceEdits

This is a contentious issue and has been bought up on the Autodesk Beta forums many times. In Maya2011 there has been some fixes to this to make it more intelligent. Try the following in 2010 and then 2011.

Make a cube and reference it into a new scene, run the following and save this new scene. Now open the file again...
import maya.cmds as cmds
cube=cmds.ls(sl=True)[0]
cmds.addAttr(cube, ln='Test')
cmds.deleteAttr('%s.Test' % cube)
cmds.addAttr(cube, ln='Test')
So we've added an attribute 'Test', then deleted it, then added it again in a referenced file. Now this looks like a stupid thing to do, but lets say you're using attributes as markers in a function, maybe exportFlags etc. In 2010 if you look at the edits you'll see the addAttr, then under that the deleteAttr.... regardless of the fact that the last action was to add the attribute again. When the scene is saved the new attribute won't be there because the delete was the last thing in the editList. More over, unless you go and remove that deleteAttr from the editList itself, you'll never be able to remake it.

2011 has a fix for this case.

Maya Referencing

I've spent the last month or so updating our Referencing Pipeline in Maya and thought I'd share a few tips in light of changes in Maya 2011. This will probably be a multi-part post... too much for one.

Part1: Background and Workflows - Reference crash course

At work we run a fully referenced animation setup, carefully managed by custom character checkers, loaders and asset management systems all designed to by-pass bugs and limitations in Maya native referencing setups.

Where to begin.... How and what should you reference?

Firstly referencing is designed to make life easier, a change in a source file will automatically ripple into all your working files. So in the case of Character Rigs ideally you'd want to reference the modelGeo into a skin file, skin it, reference that into a rig file, rig it, reference that into an animation and animate it. GREAT, you change the mesh and ......BOOOOOOOM! oops wait all my animations broken.. WTF?. In the real world there are just too many unknowns and possible conflicts to go that far. Also you really want to isolate certain changes from stages of production. So point one:

Avoid nesting your references if you can.

We run a 2 stage reference setup, based around a Rig that carries the skinned master character around with it... basically the output skeleton and geo piggy-back the rig's internal skeleton. This means that the riggers can run rig files that have a reference to the characters skin file - a scene with the skeleton and geo skinned, basically the output file required for the game. What this means is that to generate a new animation rig all that's required is to open up the master rig file, switch the reference to the skin file to the new character and bingo, rig done. This is very fast and ensures consistency in the rig itself. The piggy backing also isolates any small changes in skeleton, making it possible to tweak the characters internal structure if really required without destroying all your animation files. This referenced rig is itself then referenced into a second level where the facial is added.

Now that gives you a working rig, and for a short period we used these files for animation. But referencing is based on macros, referenceEdits, and they're just not stable enough to cope with this level of complexity, it means production gets flaky and that comes back to you, the TD. So before passing the files to the animators dereference it. flatten those references out of the file isolating them from rig production.

Referencing the Rig - Naming conventions:
So now we have a production ready rig, no references in it, and most crucially, all nodes NAMED IDENTICALLY in all rigs.. or at least all the master controllers the animators will touch are all named generically. Why not name the rig nodes to match the characters, why not prefix things in the rig file eg BOND_Wrist_Ctr? You need to understand the way referencing is managed internally. Think of it like this, referencing just imports a scene and runs a macro on it which is NAME DEPENDENT, that's crucial and there are ways to by-pass it, we'll get to those later. So in the case above if you'd animated Bond_Wrist_Ctr and then switched reference to Odjob who's rig file had Odjob_Wrist_Ctr nothing would connect up and you'd be left with a broken scene... not good.

Namespaces:
These are the devils work, but required to make referencing in Maya work. The idea is that the generic rig has everything none specifically named, then when you make the reference you use namespaces to denote who the character is. So you'd end up with BOND:Wrist_Ctr. This is a crucial distinction to prefixing. Namespaces are handled by the reference command/file command, when you switch the reference to a rig all you're doing is pointing it to a new file, replacing the imported file nodes and then rerunning that refEdit macro. The namespace will remain as it was after the switch, but that's easily changed from inside the reference editor itself.

I'll explain the tech side of namespace management in the next part..

Wednesday, June 16, 2010