Upload
sierra-patel
View
52
Download
0
Tags:
Embed Size (px)
DESCRIPTION
Utility Nodes in an Animation Pipeline. Joe Harkins Creature Technical Director Tippett Studio. Definition: node A construct that holds specific information, along with the actions associated with that information. WHAT IS A UTILITY NODE?. Definition: utility node - PowerPoint PPT Presentation
Citation preview
Utility Nodes in an Animation Pipeline
Joe HarkinsCreature Technical DirectorTippett Studio
WHAT IS A
UTILITY NODE? Definition: node
A construct that holds specific information, along with the actions associated with that information.
WHAT IS A
UTILITY NODE?
Definition: utility node
A node that allows the creation of specific shading effects, most commonly used in shading networks. They are sometimes referred to as “math nodes”.
WHAT IS A
UTILITY NODE?
Definition: attributes
a slot in a node that can hold a value or a connection to another node. Attributes control how a node works.
NODE
Attribute Attribute
WHAT IS A
UTILITY NODE?
Definition: Input
two types of numerical inputs: static, dynamic.
dynamic input updates in real-time as the upstream connection changes.
static input does not change and is not connected to any other nodes
WHAT IS A
UTILITY NODE?
Definition: Operator
operation: mathematical function
Usually determined by the type of node you have created. The process of combining inputs and performing a mathematical function.
WHAT IS A
UTILITY NODE?
Definition: Output
output: dynamic result of the operation
An output attribute's job is to hold the result of the operation from the utility node. The real-time capability means that the output attribute is always accurate.
WHAT IS A
UTILITY NODE?
Definition: Compute
compute: hidden function
Each node in Maya must take the attributes associated with it and compute them to give you an output. The output is the dynamic result of the operation, but the operation is the result of a computation that must be made within Maya.
output operator
input
compute
input
operator
output
Advantages &
Disadvantages
disadvantage: no string inputs
No MEL commands
No text data
No variable storage
advantage: reliable evaluation
Updates with the dependency graph in real-time.Evaluation is reliable to upstream connections.
Advantages &
Disadvantages
advantage: evaluation speed
using an expression with commands like "getAttr" and "setAttr" is going to be slower than using a utility node with direct connections to perform the same operation.
Expressions take longer to evaluate because they contain code. That code must then by parsed and evaluated by the processor. A node is a simple mathematical operation that has a specific function and requires no preprocessing.
Advantages &
Disadvantages
disadvantage: MEL dependency
most utility nodes must be created manually using MEL.
Some nodes can be created within the Hypershade window.
Advantages &
Disadvantages
advantage: flexibility
Utility nodes can be quickly edited with MEL.
advantage: technical control
Utility nodes can essentially be locked down and require a certain amount of effort to change.
Advantages &
Disadvantages
disadvantage: archaic naming
What if you don't know what kind of node you need? Why is it called “addDoubleLinear”?
Why are there so many different nodes?
When in doubt - press F1
Advantages &
Disadvantages
advantage: functionality
advantage: not name dependant
Unaffected by referencing, namespaces, script errors, or variables changes.
advantage: keyable dynamic attributes
Any input from a utility node can accept keyframe animation.
Utility Nodes
and MEL
Utility Node Creation
MEL Commands you need to know…
createNode
the "createNode" command will allow you to create any type of node in Maya, for example, to create an "addDoubleLinear" type node, you would type the following into the script editor:
createNode "addDoubleLinear";
It would be better to name the node something besides the default name Maya gives it, add the -n flag as follows:
createNode "addDoubleLinear" -n "add1";
connectAttr
This command would connect objectA's translation in the X axis to the first input of the "add1" utility node that was created using the createNode command above:
connectAttr "objectA.translateX" "add1.input1";
setAttr
If the attribute is static you only need to set it initially at time of creation. Do this with the setAttr command on the utility node as follows:
setAttr "add1.input2" 5;
Utility Nodes
and MEL
MEL Flow Control
for loops
MEL offers a very convenient way to parse through the selection list by using for loops to break the list of objects (ie: a string array) down to per-item manipulation.
$listOfThingsSelected=`ls -sl`;// Note that if listOfThingsSelected hasn't been declared yet,// it will be dynamically typed based on the result of the "ls" command.for ($i=0; $i < size($listOfThingsSelected); ++$i)
{ print $listOfThingsSelected[$i]; }
Alternatively, this does the exact same thing:
string $listOfThingsSelected[] =`ls -sl`;for ($thing in $listOfThingsSelected)
{ print $thing; }
Utility Nodes
and MEL
MEL Flow Control
What is an array?
A list that can hold more than one value. The array assigns each value its own place in line which will allow you to call individual items from the array with ease.
string $listOfThingsSelected[] =`ls -sl`;for ($thing in $listOfThingsSelected)
{ createNode addDoubleLinear -n ($thing + "addMe"); }
Utility Nodes
and MEL
MEL Flow Control
To connect the attributes for each item in the array to the node and vice versa let’s take the loop one step further:
string $listOfThingsSelected[] =`ls -sl`;for ($thing in $listOfThingsSelected)
{ createNode addDoubleLinear -n ($thing + "addMe");
connectAttr ($thing + ".translateX") ($thing + "addMe.input1");connectAttr ($thing + ".translateY") ($thing + "addMe.input2");connectAttr ($thing + "addMe.output") ($thing + ".translateZ"); }
select $listOfThingsSelected;
A procedure is a collection of MEL commands that can be accessed by executing the name of that procedure (and any associated arguments) .
proc createAddNode (){string $listOfThingsSelected[] =`ls -sl`;for ($thing in $listOfThingsSelected)
{ createNode addDoubleLinear -n ($thing + "addMe");
connectAttr ($thing + ".translateX") ($thing + "addMe.input1");connectAttr ($thing + ".translateY") ($thing + "addMe.input2");connectAttr ($thing + "addMe.output") ($thing + ".translateZ"); }
select $listOfThingsSelected;}
Utility Nodes
and MEL
MEL Flow Control
If/else statements
Conditional statements allow you to choose which items in the array will be affected by the procedure.
proc createAddNode () {string $listOfThingsSelected[] =`ls -sl`;for ($thing in $listOfThingsSelected)
{if(`nodeType $thing` == "joint")
{ createNode addDoubleLinear -n ($thing + "addMe");
connectAttr ($thing + ".translateX") ($thing + "addMe.input1");connectAttr ($thing + ".translateY") ($thing + "addMe.input2");
connectAttr ($thing + "addMe.output") ($thing + ".translateZ"); }else print ($thing + " is not a joint, skipping! \n"); }
select $listOfThingsSelected; }
Utility Nodes
and MEL
GUI Implementation
Combining commands
There are only three MEL commands needed to control the nodes during creation. Worry about the methodology used to create the nodes themselves.Goal is to have a script with procedures that are robust, easy to understand, and offer flexibility during use.
Interactive window
Avoid name specific scripting.Use input data from fields to define variables.Name all of your fields appropriately for querying data within the procedure.
Utility Nodes
and MEL
GUI Implementation
Extracting data from the GUI
global proc createAddNode () {string $listOfThingsSelected[] =`ls -sl`;
string $input1 = `textField -q -tx adl_input1`;string $input2 = `textField -q -tx adl_input2`;string $output = `textField -q -tx adl_output`;
for ($thing in $listOfThingsSelected) {if(`nodeType $thing` == "joint")
{ createNode addDoubleLinear -n ($thing + "addMe");
connectAttr ($thing + "." + $input1) ($thing + "addMe.input1");connectAttr ($thing + "." + $input2) ($thing + "addMe.input2");
connectAttr ($thing + "addMe.output") ($thing + "." + $output); } else print ($thing + " is not a joint, skipping! \n"); }
select $listOfThingsSelected; }
Utility Nodes
and MEL
Utility Creator MEL Script
GUI to help with the creation of utility nodes.Uses for loops and if/else statements.no MEL needed - create connections visually
Utility Nodes
addDoubleLinear: Adds the value from both of its inputs:
output = input(0) + input(1)
blendTwoAttr:
Blends the values of the input(0) and input(1)attributes of the node using a blending attribute:
output = (1 - attributesBlender) * input(0) + attributesBlender * input(1) multDoubleLinear: Multiplies the values from both of its inputs: output = input(0) * input(1)
reverse: used to reverse node attributes.
output = 1 – input
Defining Areas
of Use
Rigging Solutions
Expression Replacement
An example of an expression that could be replaced with a utility node:
objectA.translateX = objectB.translateX * .75;
MEL code to create a multDoubleLinear node doing the equivelent would be:
string $mdl = `createNode multDoubleLinear`;connectAttr "objectB.translateX" ($mdl + ".input1");setAttr ($mdl + ".input2") .75;
This is another example, only slightly more complex; first the expression:
float $tx = `getAttr objectB.translateX`;float $ty = `getAttr objectB.translateY`;objectA.translateX = ($tx + $ty)* .75;
The MEL code for utility node conversion would be:
string $adl = `createNode addDoubleLinear`;string $mdl = `createNode multDoubleLinear`;connectAttr "objectB.translateX" ($adl + ".input1");connectAttr "objectB.translateY" ($adl + ".input2");connectAttr ($adl + ".output") ($mdl + ".input1") ;setAttr ($mdl + ".input2") .75;connectAttr ($mdl + ".output") "objectA.translateX";
Defining Areas
of Use
Rigging Solutions
Joint Dampening – multDoubleLinear node
Joint’s rotation is multiplied by a driving joint for a final output.Output is then input to the hierarchy above the driven joint for indirect manipulation.Can be gradually dialed on, or turned off to have no effect.
Defining Areas
of Use
Rigging Solutions
Joint Averaging
query the distance between two locators, then divide the distance by the number of joints and input into each joint’s translation using a multiplyDivide node.
joint.translate = locator.translate / number of joints
linearJointCreator MEL Script
1. input how many joints you want to create
2. multiplyDivide node gets translation inputs from the locator, then it divides that by the number of joints in the chain, and finally feeds the output to each joint's translation.
3. operator for the multiplyDivide node is set to "2", or divide, which will do the following operation:
multiplyDivide.outputX = multiplyDivide.input1x / multiplyDivide.input2x
Defining Areas
of Use
Rigging Solutions
Custom Driven Attributes
Useful for driving blendShapes or changing the range of an existing attribute for greater control.
Output = Min + (((Value-OldMin)/(OldMax-OldMin)) * (Max-Min))
customAttributeDriver MEL Script
1. Uses a setRange node
2. Input driving node name, custom attribute that will Drive selected attribute will live on this node.
3. Min and max range must be set. Query the range of the attribute selected if it has a hard range or set it manually.
4. Set a new range that you would like the attribute to have by inputting the values into to fhe fields.
Defining Areas
of Use
Rigging Solutions
FK/IK Switching
Requires 3 separate chains: driven, FK, IK
Connecting the driven skeleton to the driving FK and IK skeletons usinga blendTwoAttr node will allow animation blending between the two chains.
Use a custom attribute, connected to the attributeBlender of the node, as a driver.
blendTwoAttr
Blends the values of the input(0) and input(1)attributes of the node using a blending attribute:
output = (1 - attributesBlender) * input(0) + attributesBlender * input(1)
Defining Areas
of Use
Rigging Solutions
FK/IK Switching
string $arms[] = `ls -sl`;string $fk, $ik, $driven, $arm, $blendAttr;$blendAttr = "blendObject.blendAttribute";
for ($arm in $arms){if (`gmatch $arm "*FK*"`) $fk = $arm;if (`gmatch $arm "*IK*"`) $ik = $arm;if (`gmatch $arm "*Driven*"`) $driven = $arm;}print ("this is the FK arm: " + $fk + "\n");print ("this is the IK arm: " + $ik + "\n");print ("this is the DRIVEN arm: " + $driven + "\n");
string $rot[] = {".rx",".ry",".rz"};string $r;
for ($r in $rot){string $bta = `createNode blendTwoAttr`;connectAttr ($fk + $r) ($bta + ".i[0]");connectAttr ($ik + $r) ($bta + ".i[1]");connectAttr $blendAttr ($bta + ".ab");connectAttr ($bta + ".o") ($driven + $r);}
Defining Areas
of Use
Animation Solutions
Animation Blending
Able to be added nondestructively.
blendColors node is a good choice for this simple operation.
can take up to six inputs, two for each channel, R, G and B respectively. It also has one input called “blender”, which can be connected to a user added attribute to control the blending.
Here’s the code you would need to create the connections for channels that exist on selected objects:
string $all[] = `ls -sl`; string $each; string $blender = "blendObject.blendAttribute"; for ($each in $all) {string $blendColors = `createNode blendColors`; connectAttr $blender ($blendColors + ".blender"); connectAttr ($each + ".rx") ($blendColors + ".c1r"); connectAttr ($each + ".ry") ($blendColors + ".c2r"); connectAttr ($blendColors + ".opr") ($each + ".rz"); }
Here is the formula used for color blending:
output[i] = Color1[i] * Blender[i] + Color2[i] * (1.0 - Blender[i])
Defining Areas
of Use
Animation Solutions
Noise Animation
Able to be added nondestructively.unlike blending - is mulitplied in an additive fashion.Uses a hierarchy based system to avoid locking off channels.
multDoubleLinear gives us ( A * B = C )A = noiseCurve (driving animation curve)B = noiseMult (to control input of noiseCurve)
C = output to an identical channel one node above in the hierarchy.
string $all[] = `ls -sl`;for ($each in $all){string $noiseNodes[] = `listRelatives -p -pa $each`;string $noiseNode = $noiseNodes[0];string $mdl = `createNode multDoubleLinear`;string $inChan[] = `channelBox -q -sma mainChannelBox`;for ($channel in $inChan){catch (`addAttr -ln ($channel + "_noiseCurve") -k 1 $each`);catch (`addAttr -ln ($channel + "_noiseMult") -k 1 $each`);connectAttr ($each+ "." + $channel + "_noiseCurve") ($mdl + ".i1");connectAttr ($each+ "." + $channel + "_noiseMult") ($mdl + ".i2");setAttr ($each+ "." + $channel + "_noiseMult") 1;connectAttr ($mdl + ".output") ($noiseNode + "." + $channel);}}
Defining Areas
of Use
Animation Solutions
Noise Animation - noiseMaker MEL Script
node
noise
parent
Defining Areas
of Use
Animation Solutions
Noise Animation - noiseMaker MEL Script
Randomly generated noise animation
for($frame=$start;$frame<=$end;$frame+=$step){currentTime $frame; $rand = `rand $min $max`;setAttr ($obj + "." + $channel + "_noiseCurve") $rand;$noise = `getAttr ($obj + "." + $channel + "_noiseCurve")`;setKeyframe -v $noise -at ($channel + "_noiseCurve") $obj; }
checks to see if you want the generated curve to cycle infintely and if you want it to be locked so you can't accidently set new keyframes on it:
if ($cycle == 1) setInfinity -poi cycle -at ($channel + "_noiseCurve") $obj;if ($lock == 1)setAttr ($obj + "." + $channel + "_noiseCurve") -lock 1;
Complex
Situations
Cyclic Animation
Animation Cycles - noiseMaker MEL Script
if ($copy == 1){if (!`isConnected ($bta + ".output")($obj + "." + $channel) `)
{copyKey -attribute $channel -option curve $obj; CBdeleteConnection ($obj + "." + $channel);pasteKey -attribute ($channel + "_noiseCurve") $obj;}
}
You could combine the result with other cycles by using the blendColors or blendTwoAttr node, allowing you to blend between cycles quickly. The advantage, again, is the nondestructive additive nature of the multiplying and blending. Since we are not actively locking any attributes you can continue to animate normally.
If you are connecting two rigs together via constraints then the noise added to a loRes rig would transfer to the highRes rig without the need to add extra nodes to the highRes rig.
Complex
Situations
Cyclic Animation
Offseting the Cycle - noiseMaker MEL Script
add time + user input to animation curve
addDoubleLinear.output = offsetAttr + time1.outTimeaddDoubleLinear.output is connected to driverAttrdriverAttr <-> animCurve.inputmultDoubleLinear.output = animCurve * noiseMultipliermultDoubleLinear.output <--> final result
Connection must be forced in Maya
The –f flag tells Maya to break any connection to the defined attribute and then force it to connect to the one we want:
connectAttr -f objectA.driver objectA _animCurve.input;
Complex
Situations
Advanced MEL Discussion
Custom attribute noiseNon-hierarchy based noise animation
noiseMaker will check any user defined attributes on the loaded objects to find out if the loaded attribute is custom and needs a special setup. If the custom attribute query returns true then the script will copy your animation curve, if any exists, onto an attribute named "custom attribute name + old" which can be used to blend between the old animation and the noise curve.
Here's how it breaks down:
customAttrA_blendDriver = customAttrA_noiseCurve * customAttrA_noiseMultcustomAttrA_oldCurve is a copy of any existing animation on customAttrAcustomAttrA_oldCurve and blendDriver are then blended together with thecustomAttrA_blendOld attribute and finally output back to customAttrA
Here’s the code to show what’s going on in the script:
$mdl1 = `createNode multDoubleLinear`;$bta = `createNode blendTwoAttr`;addAttr -ln ($attr + "_oldCurve") -k 1 $obj;addAttr -ln ($attr + "_blendOld") -k 1 $obj;addAttr -ln ($attr + "_blendDriver") -k 1 $obj;catch (`copyKey -attribute $attr -option curve $obj`);catch (`CBdeleteConnection ($obj + "." + $attr)`);catch (`pasteKey -attribute ($attr + "_oldCurve") $obj`);connectAttr ($mdl1 + ".output") ($obj + "." + $attr + "_blendDriver");connectAttr ($obj + "." + $attr + "_blendDriver") ($bta + ".input[0]");connectAttr ($obj + "." + $attr + "_oldCurve") ($bta + ".input[1]");connectAttr ($obj + "." + $attr + "_blendOld") ($bta + ".ab");connectAttr ($bta + ".output") ($obj + "." + $attr);
Complex
Situations
Advanced MEL Discussion
Replacing Math CyclesAdvanced expression replacement
1. Evaluate what the expression is doing
breathroot1.scaleX=1+cos(time/breathcontrol.translateY)/10;breathroot2.scaleX=1+cos(time/breathcontrol.translateY)/10;
In this case the expression is using the COS function to create rythmatic breathing by using inputs from translation of a locator.
2. Determine whether or not the function is cyclic
3. If cyclic returns true, create the cycle with an animation curve
4. Setup cycle animation with utility nodes to mimic math function
string $multDivide = `createNode multiplyDivide`;setAttr ($multDivide + ".operation") 2;connectAttr "time1.outTime" "breathCurve.time";connectAttr "breathCurve.time" ($multDivide + ".i1x");connectAttr "breathcontrol.translateY" ($multDivide + ".i2x");connectAttr -f ($multDivide + ".outputX") "breathCurve_scaleCurve.input";
string $mdl = `createNode multDoubleLinear`;string $adl = `createNode addDoubleLinear`;
connectAttr "breathCurve.scaleCurve" ($mdl + ".i1");setAttr ($mdl + ".i2") .1;connectAttr ($mdl + ".output") ($adl + ".i1");setAttr ($adl + ".i2") 1;connectAttr ($adl + ".output") "breathroot1.scaleX";connectAttr ($adl + ".output") "breathroot2.scaleX";
Utility Nodes in an Animation Pipeline
Thank You!