In the previous movie, we added FK controls to our rig
to give us more precision in controlling our proxy character’s torso.
In this movie, we’re going to add some squash/stretchability to the joints.
Start by opening the file “5-0- Character_rigging_part5_start.mb”
or by using your own file from the previous lesson.
If we grab the shoulder_CTRL node and try to move it around,
notice that the torso doesn’t follow past a certain point.
This is because the spine_result joints are of a fixed length
and cannot scale to reach the world position of the IK control.
Even if you were to just rotate the shoulders an extreme amount,
notice how the joints can’t match the control’s position.
We’d like it if the spine could stretch to meet our control no matter where it was,
and we can achieve this by modifying the dependency graph.
First, let’s think about the math of how this should work.
If we pull the shoulder control away from the body, notice how the spine_CRV stretches.
What we want to do is scale the attached joints and geometry alongside the curve.
Thus, if we could just determine the length of the curve and divide it by its normal “at rest” length,
we’d have a percentage of how much longer or shorter it is from its normal state.
Then we can just apply that same percentage to the underlying joints
to scale them up or down identically.
So how do we go about getting the curve length? We can use something called a “curveInfo” node.
A curveInfo node is a special node in Maya that provides all sorts of information about a curve.
To create this node, select spine_CRV and open the Node Editor.
Click the “Input and ouput connections” button to display the node’s dependency graph.
Whenever objects rely on each other for input or output of attribute values,
that link (or “dependency”) exists in the DG.
For example, you can see here how the spine_HDL node relies on spine_CRVShape.
Now we want to create a curveInfo node that will also depend on spine_CRVShape.
Press ‘Tab’ to create a new node and type “curveInfo”.
Press ‘Enter’ to create a new curveInfo node.
Rename this node “spineInfo”.
In the Attribute Editor, notice the "Arc Length" attribute.
This is the attribute that is supposed to give us the current length of the curve.
But right now it reads 0!
This is because the spineInfo node isn’t connected to anything yet.
We need to pipe information about the spine_CRVShape node
into the spineInfo node for this attribute to actually give us the data we want.
Click the output of spine_CRVShape and select the "worldSpace[0]" attribute,
representing the entirety of the curve itself.
The cursor turns into a small crosshair, indicating Maya is ready to connect this node to something.
Click on the input of spineInfo and choose the "inputCurve" attribute.
Maya creates a connection from spine_CRVShape to the spineInfo node,
signified by this line.
In the Attribute Editor, spineInfo’s "Arc Lengh" attribute
now displays the resting length of the curve.
Click Copy Tab to create a modeless copy of the Attribute Editor.
If you translate the shoulder control, the "Arc Length" attribute’s value changes, as we’d expect.
So now we know how to get the arc length value of our spine,
which also gives us its resting length.
We just need to find the percentage of the curve’s length increase/decrease
by taking its current length and dividing by its resting length.
We can do this math using a “Multiply Divide” render node.
Press 'Tab' and enter MultiplyDivide. Press 'Enter' to create the node.
Selecting the Multiply Divide node, you can see that it has two inputs and an "Operation" attribute.
As you’d expect, the node works by performing the chosen operation on Input 1 and 2.
Our first input will be the "Arc Length" attribute from the spineInfo node.
We want to attach it to "Inpu t1", but there's three values here.
This is because "Input 1" is set up to adapt to 3D positions or color values.
Since the "Arc Length" attribute is just a single value, we’ll slot it into the "Input 1X" attribute only.
Now if you move the shoulder_CTRL again, it not only affects the "Arc Length" value
in the spineInfo node, but also the "Input 1X" value of the multiplyDivide node.
Next, we just need to divide this "Input 1X" value by the curve’s default length
to get its scale percentage.
Type the number into the "Input 2X" attribute.
Also remember that we’re dividing these, not multiplying them.
Perfect. Now the output of this node is the percentage we’re looking for.
At this point we can connect the output of this node to each of our spine_result joints.
Select all the spine result joints and middle drag them from the Outliner into the Node Editor.
Use the Layout button to lay the nodes out neatly and make them easier to see.
Our output is the multiplyDivide node’s "OutputX" attribute,
which holds the result value to our equation.
The only question is, which attributes should we connect it to?
Recall that based on how we set our current joint orientation in part 2,
the X axis moves up along the joint.
This is precisely the direction we’d like to scale in,
so we'll connect the output to the "Scale X" values.
Since we want to scale every joint evenly,
you'll need to connect it to the scale value of each spine joint.
When you’re done, your DG should look like this.
Notice that we’re not scaling spine7. This is because there’s no other joints parented under it,
so scaling it wouldn’t serve much purpose.
Just to keep things neat and tidy, let’s rename the multiplyDivide node “spine_stretchPercent_DIV”.
Now minimize the Node Editor and use the Move Tool to play with your shoulder or hip controls.
It stretches and squashes.
This works great, but notice how the entire body scales exactly the same.
We’re missing some volume preservation.
When the torso stretches up in one axis, it should also squash inward on its other two axes
and vice versa.
Thus, we want to affect the other two axes inversely to the one being stretched.
Since X is being stretched in this case,
we’re going to scale Y and Z by 1 over the square root of X.
In case you’re curious where these numbers came from,
this is the generally accepted equation for volume preservation in three spaces.
Go back to the Node Editor and create another Multiply Divide node.
Rename it “spine_sqrtStretch_POW”.
Connect the X output of our "spine_stretchPercent_DIV" node
to the "Input 1" of our spine_sqrtStretch_POW node.
To get the square root of this value, we’ll set the "Operation" to "Power", and "Input 2" to "0.5".
Now to create this inverse, we need to divide 1 by this value.
Create one more Multiply Divide node and rename it “spine_stretchInvert_DIV”.
Plug the X output of our spine_sqrtStretch_POW node
to the "Input 2X" attribute of our spine_stretchInvert_DIV node.
Set "Operation" to "Divide" and the "Input 1X" value to "1".
The X output of our spine_stretchInvert_DIV node now outputs the 1/sqrt value,
so we can plug the X output of the spine_stretchInvert_DIV node
into all your spine_result joints’ Y and Z scale attributes.
You can make this a little easier for yourself by selecting all the involved nodes
and viewing them in Full Mode to see all the inputs and outputs at once.
When making the connections, hover the mouse over the "Scale" attribute
to expand it automatically into its X, Y, and Z constituents.
Now you can close the Node Editor and try stretching your rig again.
This time the body squashes inward as it stretches upward and vice versa.
You’ll notice that the FK controls aren’t following along, but don’t panic, this is actually expected.
Remember that the IK shoulder and hip controls
depend on the FK controls to tell them where to go, but the opposite is not true.
Thus, the FK controls are, in a sense,
“unaware” of the shoulder and hip controls' movements within itself.
So far we’ve got our torso moving in just about every way we want.
That means it’s time to start thinking about how to incorporate it into the body rig as a whole.
In the next movie, we’ll look at how to do that,
as well as how to clean up some of the loose ends we may have missed.