Maya Stretchy Spine

The objective of this tutorial is to create a Spine Chain that will stretch and Give you warning if stretch too far or Squash too much.

Creating the Spine

First lets strat with construction of the Spine. For this tutorial I will use a simple 4 joint chain. This will help keep things simple. You can create the joint chain in the side view and turn on the snap to grid button which is located across the Top menubar.

This is done so that we have a clean joint chain to start with. Once the joint chain is created you can declick the snap to joint.

Once you have the joint chain created you will need to apply the spine IK tool. Start with the bottom most joint and connect it to the top most joint.

This give us the basic Spine Spline IK. Now we are going to need to select the CVs of the Curve that was created with the Spine IK. In your panel uncheck Bones and IK Handles. This will make it easier to select the Curve CVs.

Select a CV, then in the Animation Menu Set, select Deform>Create Cluster

To repeat this command select a new CV and press the "g" key on your Keyboard. You will notice this creates a new cluster for the CV. You will need to create Clusters for Each of the CVs on the Curve.

The clusters allow you to select the Points in object mode and also allow you to constrain other objects to them.

With our clusters created, we will need to create a way to control the clusters more easily. We can do this with a simple control.

Create a NURBS circle, from the Modeling Menu Set select Create>NURBS Primative>Circle you will need a total of 4 circles. Don't worry if the circles are stacked on top of each other we will adjust this in a moment.

In the outliner Select the Custer1 First then Ctrl Select the NurbsCircle1 second. Then from the Animation Menu Set select Constrain>Point This will snap the Circle to the cluster. It also removes the issue of spending time to try and line up the Circle to the Cluster. You will need to repeat this for all of the clusters and circles.

With our control circles in the right spot, you can exapand the menu of the Nurbs circles and delete the Point Constraint from the circles.

With the circles in the right spot, we will want to Freeze Transforms, and Delete by type History. It is import to note that we are only deleting the history for the circle. Doing a Delete all by type History will cause problems. Especially if you have a skinned object.

To freeze transforms from any Menu Set select Modify> Freeze Transfomations (you may want to select the option box to reset your settings). Then you can select Edit>Delete by Type>History What this does is remove any remain references to the point constraint that might be lingering, it also resets the Translate, Rotate and Scale to 0 for the circles.

With the Circles reset to zero and snaped to the clusters position when can reverse the process for the point constraint. Select the Circle first and the Cluster second and create a point constraint. Now our circles drive the position of the clusters so we can move the clusters and the curve to move with them.

At this point you can go to your panel and check show all. Check the spine, at this point your controlers should be moving the position of the spine.

You can also select the Joint and the circle controler that are closest to each other. Select the Joint first and the circle second and apply a Orient Constraint. This will keep your control circles in line and pointing the same direction as your curve.

 

Make the Spine Stretch

With the Spine created and controls in place, we will need to now make it stretch. We can make the spine stretch while maintaining its original volume.

To do this we will need to open the Hypershader and maximize the workspace area. Add Joint1 to the Hypergraph (with Joint1 selected click Graph>Add Selected to Graph). Then in the Create Maya Nodes Panel scroll down to General Utilities and click Multiply/Divide. You will need to add 2 Multiply/Divide Nodes.

The first Multiply/Divide Node will need to be renamed Joint1Inverse and the Second will be renamed Joint1SquareRoot.

Attach the Outbound Scale.X from Joint1 to the inbound Input2X of Joint1Inverse. Then in the Attribute Editor set the operation to Divide and the Input1x to 1 and lock the value by right clicking on the value and selecting Lock Selected.

We will be adding in a control later to keep us from dividing by Zero. Which is always a bad thing to do.

Next we will attach the Outbound.X to the Input.1x of the Joint1SquareRoot Node.

In the Attribute Editor with the Joint1SquareRoot node selected set the Input2x value to 0.5 and lock the value, and set the operation to Power.

Then apply the Outbound X of the Joint1SquareRoot to ScaleY of Joint1, do this again for the ScaleZ value. This will have the value of Scale X drive the Values of Scale Y and Z via the Multiply/Divide nodes. The operation allow the Joint to maintain volume while scaling instead of just scaling in one axis.

You will need to repeat this process for all 4 of the joints.

Having created the stretch for the joint we want to control that stretch. We will be doing that by using the length of the curve.

In the Outliner select the Curve, then in the MEL Command Line enter arclen -ch 1; This turns on the construction history for the curve. More importantly it allows us to see the length of the cruve, measured in the current units.

Select the Curve and Joints 1-4 and add them to a new graph in the Hypershader. Seperate out the Curve Info node and the 4 joints. Then select the remaining nodes and remove them from the Graph (Graph>Remove Selected from Graph). Under no circumstance should you delete the nodes. This will cause the spine to stop working.

With our cleaned up graph we will be able to see and select the nodes we are using with a greater amount of ease.

 

Next we are going to add a Multiply/Divide node and name it ArcLengthRatio This is one of the nodes that is going to help us control the stretching of the spine.

In the Hypershader apply the arclength to the Inputer1x of the ArcLengthRatio Node.

Next with the ArcLengthRatio Node Selected open the Attribute Editor. Here you will see the arclegth being applied to the 1x value, in the 2x value copy the number and lock the value, and set the operation to Divide. This will now divide the two number and give you a number that will be either greater or less than 1.

 

With the arc length value figured out, we will now need some where to apply it. Rather than simply applying the value to the X scale we will create a new attribute for the stretch and link that to the X scale. The reason for this is so that we have a filter for the value. The purpose of the filter is so that we can avoid dividing by zero.

With Joint1 selected, open the channel box, and right click inside of it and to bring up the submenu and select Add Attribute.

Name the Attribute Stretch, make it a float and give it a minimum value of 0.1 and a default of 1. Do not worry about placing a maximum value in.

Repeat this step for all 4 joints.

With all of the joints now having a stretch attribute, we will need to have the attribute drive the scale X of the respective joint.

I have found that this is easily done with the Connection Editor. You can bring up the Connection Editor from any Menu Set then selecting Window>General Editors>Connection Editor

With Joint1 selected click Reload Left and then Reload Right. This loads the node into both sides. Make sure you are going From -> To so that you connect the right attributes. You may also want to uncheck Show Hidden and Show NonKeyable This will help to clean your window up. Then select the New Stretch attribute in the left hand side and then Scale X in the Right hand side. This associates the stretch value to the scaleX value.

Going back to Hypershader with our Joints and ArclengthRatio Node, we are now going to add a Condition Node to the Graph.

We are going to apply the Output X to the FirstTerm of the Condition Node.

Then we are going to open up the Connection Editor again and then with the Condition Node selected, Reload both Left and Right.

Select FirstTerm in the Left Hand side, and connect it to Color If True R and set the value of Color If False R to 1 and lock that value. Then set the operation to Greater than

This will now set up an condition that if the ratio is greater than 1 it will use the value of the ratio, but if it is less than 1 it will use 1 as the value.

 

With our Condition set, we will want to have some control over the value so that we can also turn the stretch on and off.

We will do this with a BlendColor Node. Once added to the graph apply the outbound ColorR to the Inbound Color.R1 of the Color Blend Node.

Then in the Channel Box set the attribute of 2R to 1 and lock that attribute. This way we will be able to Blend between the ratio value and 1, so that we can smooth the blend between stretching and not stretching.

Now apply the outbound R value to the Stretch value of each of the Joints. This is what will drive the all the joints to stretch at the same time.

Creating a Global Controler

Now with all the joints stretching at the same time we need some way to control the BlendColor Node.

Create a Nurbs Circle, scale it up move it to the bottom of the Joint chain and freeze the transforms on the circle.

Rename the circle GlobalControl and add a new attribute. Name it Stretch and set the Maximum and Default Values to 1, and Set the Minimum Value to 0.

 

Keeping the GlobalControl selected add it to the graph in the Hypershader.

Connect the Stretch Attribute of the GlobalControl to the Blender Attribute of the BlendColorNode.

This will allow you to Blend from stretchy to non stretchy IK from your GlobalControl.

In the Outliner you will want to parent the NurbsCircles, Joints, and IK Handle to the Global Controller. Leaving the Clusters, Curve and any geometry you might have outside of the GlobalControl.

The Reason for this, is that the controlers, joints and IK handle control the position of the cluster handles, curve and any geometry that you might have in the scene. Parenting them to the GlobalControl causes them to be offset from their point of origin.

Warning with Color

If you want to take this one step further, you can apply a color warning to the geometry so that the animator will know if he is stretching the rig too far.

We will acomplish this with a Blend Color Node, Multiply/Divide Node and a Lambert Material.

First we will need to create some geometry to apply the warning to. For this tutorial I created a Simple Polygon Cube with the same number of divisions as the joint chain. Then smooth bound the cube.

Then in the Hypershader I created a new Lambert material, you can certainly use any material that you want to.

Be sure to select the new material and add it to the graph. Also add a Multiply/Divide Node and a BlendColor Node.

Attach the outbound ColorR from the Condition Node to the Input1.x of the Multiply/Divide Node.

In the attribute Editor set the value of 2x to 0.5 and set the operation to Multiply, and lock the value.

If you want to set the Warning to be more sensitive set the multiplier to a higher number such as 0.6 or 0.75. If you want it to be less sensitive set the multiplier to a lower numer.

Connect the Output.X of the Multiply/Divide Node to the Input 1R of the BlendColor Node

In the Channel Box, lock the value of 2R to 0.

Now when you stretch the spine around you will see the geometry turn Red if its stretched too much and Blue if its Squashed too much.

 

Now we have a spine the squashes and stretches with the controlers. That can be turned on and off, that will warn us if we squash or stretch it too much.

Have fun.

 

Parts of this Tutorial are taken from the Book Inspired 3D advanced Rigging and Deformations by Brad Clark, John Hood, Joe Harkins.

Go buy the book, its a great reference tool. This was written to Expand on the Stretchy Spine IK in the Book. The rest of the Tutorial are my own ideas and concepts from working with Maya since Maya 2.

No part of this tutorial was plagerized from the book, the content presented here is all written by myself, I am simply taking the concepts and ideas presented in the book and rewritting the tutorial in long form with addition explainations and some additions, such as the GlobalControler.

Comments, suggestions can be sent to david@darksuit.com