When making a back it is important that all of the joints are oriented correctly. You will want to make sure and use the jsOrientJointUI script. For this tutorial however we will already have the backbone created.
Download these Mel scripts and place them in the "My Documents\maya\5.0\scripts" directory. These scripts will then be loaded when you start up maya and are necessary for these tutorials. If you have already done this in a different tutorial disregard these steps.
Create a spline ik for the back.
Open the options for spline ik. Set the options as shown in the figure. Create spline ik from the 5th lumbar to the 1st cervical vertebrae (L_5 -> C_1). Hiding extra information in your scene may make it easier to select them.
Name the curve back_curve and the ik handle back_ikHandle. Hide the ik handle.
Create clusters using the points of the back_curve. Select the curve and go to component mode. Select each point on the curve individually and create a cluster for each one (deform->create cluster).
Creating stretch in the back
Select the back_curve. Type this into the command line: arclen -ch 1;
This creates a curve info node. Select the curve and open the Hypergraph. Select input output connections to see the connections going in and out of the curve.
TIP: You can simplify the display in the hypergraph by going to show->show selected types.
Open the hypershader. Create a multiplyDivide utility. Go to create->general utility->multiply divide. Select the back_curveShape, curveInfo1 and the multiplyDivide node in the hypershader. In the hypergraph, select show->show selected types. Middle Mouse (MM) Drag the multiplyDivide1 node over to the hypergraph.
Name the multiplyDivide1 node back_scale.
We want to connect the curveInfo1.arclength to the back_scale input1x. Right click on the right side of the node in the hypergraph. Select the arclength property. Right click again on the back_scale node and select input1->input1x.
Select the curveInfo1 node. Select the Arc Length and copy it into back_scale input2x of the multiplyDivide node.
Change the operation on back_scale to divide.
This is going to give you the scale of the curve. Current curve length will be divided by the original. So when the curve is at its original position it will be 1 and when it is half of its original it will be .5 and when it is twice as long it will be 2. These values will then be applied to the translate y of the back joints.
We want to start stretching from l_4. Starting from the l_5 joint will cause the joint to come of the curve.
Create another multiplyDivide node. Name it l_4_scale (since this will be used for the l_4 joint.)
Copy the l_4 translate y value into the l_4_scale input2x.
Connect the outputX of the back_scale to the l_4_scale.input1x. Right click on the right side of the back_scale node in the hypergraph. Select output->outputX. Right click on the l_4_scale node and select input->input1X.
Open the Outliner and select the l_4 joint along with the back_curve and the l_4_scale node (which are easier to select in the hypergraph). Select show->show select types in the hypergraph. Deselect the objects and then MM drag the l_4 joint from the Outliner down to the hypergraph. Connect the outputX of the l_4_scale node to the l_4.tranlateY.
TIP: These connections can also all be done using the connection editor. As with most things in Maya there are many ways to connect these nodes. Use which ever method is more comfortable.
Now try moving one of the clusters. Notice how the Lumbar joint on the back scales in the y direction.
Open up Jason Schleifer's script jsScaleJointsByCurve.mel
Select the back_curve and hit sel. Select the l_3 to the C_1 joints(because we have already made the adjustments to the l_4 joint) and 'add joint'. Select the 'scale joints' button.
Now move one of the clusters and watch how the back moves and scales.
Creating Shoulder and Hip controls.
This file has all of the controllers for an entire character. Find the rootcon and pull it out of the hierarchy. Delete or hide the other controllers. duplicate the rootcon twice. Make sure there are no children on either of these nodes.
Name one of these controllers hipCtrl and the other ShoulderCtrl.
Select the shoulderCtrl and center the pivot (modify->center pivot). Switch to the side view mode and hide polygons (show->polygons to uncheck them). Place ShoulderCtrl behind the back so that it is easy to select. Scale the controller if it needs it. Move its pivot directly over the c_1 joint (use insert to move the pivot and 'v' to snap it to the joint).
Do the same for the hipCtrl except center it around the root joint.
Parent the two top clusters under shoulderCtrl and the bottom two clusters under the hipCtrl. Notice how the root controls don't move under the hip control.
Use Jason Schleifer's jsConstObj.mel
script to constrain the root to the hip controller (open the script in the script editor then execute it. Select the hipCtrl then the root joint then type in jsConstObj in the script editor and hit the number pad enter).
The hipCtrl now moves the pelvis as well. Notice that the center cluster has not been parented to anything yet. This will be used as a stabilizer for the fk portion of this back.
Creating the FK Controls
Select the hipCtrl, the shoulderCtrl and the middle cluster in that order and run the jsConstObj script (it should already be loaded in memory after the last section so just type in jsConstObj in the command line or script editor).
Create the joints that will be used for the fk controllers. Start a joint at the base of the back (the l_5 joint) and place another a third of the way up and another two thirds of the way up and the final at the c_1 joint.
Orient the joints using jsOrientjointUI.mel
Name the joints torso_1, torso_2, torso_3, and torso_3_end.
Parent shoulderCtrl under torso_3_end.
Parent hipCtrl under torso_1.
Now make sure that the controllers transforms are zeroed out.
Unparent the children under shoulderCtrl. Select shoulderCtrl and freeze the transformation. Reparent the children.
For the hipCtrl it will be a little more difficult since if you freeze its transform it will not align properly with the world. Unparent the children for the hipCtrl. Group the hipCtrl to itself (which makes a group above it). Rename the group HipCtrlOrientGrp.
Select the torso_1 joint and open the attribute editor. Under the joint tab find the Joint Orient x value. What we are going to do is adjust the HipCtrlOrientGrp by the difference of 180 - joint orient x value.
Enter this code into the command line: setAttr HipCtrlOrientGrp.rx(180- `getAttr torso_1.jointOrientX`);
This subtracts the torso joint orient x from 180 and assigns the result to HipCtrlOrientGrp.rotateX. Make sure to use the ` tic which is usually on the ~ tilda key.
Select hipCtrl and free transformation. Select HipCtrlOrientGrp and copy the rotate x value and paste it into hipCtrl.rx then place a - before its value. setAttr hipCtrl.rx (-`getAttr HipCtrlOrientGrp.rx`); will do the same thing. Select hipCtrl and then freeze transform. Now the hipCtrl is zeroed out and the rotate orientation matches the world rotation. Reparent the children of the hipCtrl.
Create the topCtrl
This is the controller which will be used to move all the other controllers. Take the last controller and name it topCtrl. Center the pivot (modify->center pivot). Move the topCtrl to a position above the character and scale it up a little. Move the pivot point to the root joint.
Freeze transformation on topCtrl.
Parent torso_1 to topCtrl.
The back controls rotate however you are not able to twist the back. This section will add twist, however you will not be able to twist the back more that 180 degrees. Since a back generally can't rotate more than 180 degrees this is fine.
Create a set of joints that start at the root goes to the neck then the top of the head. Name the joints hip_orient, shoulder_orient, shoulder_orient_end.
to orient the joints.
Change the rotation order of all of the new joints so that they are xzy (select the joint, attribute editor, rotation order.)
Create a ikSCsolver from the hip_orient to the shoulder_orient. Name it orient_ikhandle.
Select shoulder_orient then Select shoulderCtrl and apply the jsConstObj
script to orient constrain them. Delete the point constraint created.
Create an expression that connects the shoulder_orient.ry to the back_ikhandle.twist (a direct connection will cause it to break so you need to use this expression). Select the back_ikHandle in the outliner.
Select the twist property in the channel box and right click on in. Select expression for the drop down. Add this line of code to the Expressions window: back_ikHandle.twist = shoulder_orient.rotateY;
pointConstrain the orient_ikHandle to shoulderCtrl.
Parent the orient_ikHandle and hip_Orient to the hipCtrl.
Adding Stretch Warning
At this point the controls are set up. The back allows for too much stretch. Instead of limiting what the animator can do set controls that warn the animator if the limits are being pushed.
Open the hypershader and select the bone shader.
Right click on the Incandescence R value and select Set Driven Key to bring up the window.
Select the back_curve in the hypergraph and click on the input output connections button.
Select the back_curve in the hypergraph and click on the input output connections button.
Select the back_curve_scale node and load it in as the driver in the set driven key window. Select outPutX as the Driver and incandescenceR as the driven.
Move the shoulderCtrl up until the back is stretched as much as it should be and then select the bone shader and set the incandescenceR to 1. Select key in the set driven key window. Now move the shoulderCtrl down until the back is as squished as much as it should and then set the incandescenceR on the boneShader to 1 again. Select key in the set driven key window.
Select the boneShader in the hyperShader. Open up the graph editor and select incandescenceR on the left side. The points of the curve can be edited here to change the keys set earlier.
Select all the objects you don't want the animator to touch and put them on a display layer called untouchables and set it to reference.
Create a layer for the torso controls and give it a easily recognizable color. Turn on the selection handles for the torso controls so the joint controls are easy to select.
Assign the back curve controls to a backCtrl layer.