Awesome Spine Setup

•October 8, 2008 • 31 Comments

“Awesome Spine” Setup

A few people have showed interest in how I create what I call the Awesome Spine. So here is my tutorial. I hope you enjoy it. Click on the images to make them larger.
  1. Create a spine with 5 joints like Figure 1. and orient the joints correctly.



  2. Name the joints to avoid future confusion. I named the first set Spine_#_ik, replace the hash with a number. Duplicate the all the joints and rename them Spine_#_bind. See Figure 2.
  3. Duplicate the spine_1_ik and duplicate it again so you have two joints. Name them hip_joint, shoulder_joint respectively. Snap the shoulder_joint to the top spine joint.
  4. Now create an splineIK from spine_1_ik to spine_6_ik, with the attributes in Figure 3.
  5. Now select the spine_curve, hip_joint, and shoulder_joint. We are going to smooth bind these joints to the splineIK curve. Skin->Bind Skin->Smooth Bind. Use the selected joints and default settings for the rest. The hip and shoulder joints now control the spine. This is awesome because now we have independent control of the shoulder and hips. By rotating either joint we can get nice curves quickly. The only thing it can’t do yet is twist down the length of the spine. This is what we are going to spend the rest of the tutorial setting up.
  6. Create ikRPSolver for each joint in the spine_#_bind joints. A quick way of doing this is to go to Skeleton->IK Handle Tool-> optionBox and selecting the spine_1_bind, then shift-select spine_2_bind. Repeat for the rest of the joints. Figure 4 shows an ikRPSolver at each joint. The reason for applying the ikSolvers at each joint is so that we can have individual control of the twist at each joint.



  7. Parent each ikHandle to the respective parent + 1. what I mean by this is look at where the first ikHandle is. It located at the second joint in the bind chain, so parent the first ikHandle to Spine_2_ik, and so on. Also, you will need to point constraint the spine_1_bind to the spine_1_ik. so select spine_1_ik and shift-select spine_1_bind and click point constraint. Now if you move the hip or shoulder joints the spine_#_bind spine will follow.
  8. Create 5 locators. Exactly the number of ikHandles we have. Snap them to each joint, except the last one, and move it a few units from the spine. See Figure 4
  9. Create an empty group and snap it to the first joint in spine_#_bind. Then Parent the first locator to


    the group. Do this for the rest of the locators. Now if you rotate the group along the twist axis of the spine it will rotate the locator around the spine. This is exactly the behavior we want. See Figure 5 for a snap-shot of what the locators and groups look like.

  10. Now select the first locator, and shift_select the first IKhandle and click pole vector constraint. Do this for all the locators and ikHandles. This is what will control the twist of the spine.
  11. Once all the locators are grouped parent the groups to the corresponding spine_#_ik joint. Now since the twist axis of the spine joints is the X-Axis, we need to select the all the groups we just parented


    and Freeze Transformations. Now the groups will rotate about X and orbit the locators around the spine. You can see this better if you select all the spine_#_bind joints and turn on the Local Rotation Axis, Display->Transform Display->Local Rotation Axis. Figure 6.

  12. Now we are going to distribute the twist equally along the spine. Open up the HyperShade. And drag the hip_joint, shoulder_joint, and the locator groups into the HyperShade. This part might get kind of confusing, that’s why I am including a large picture of my HyperShade (figure 7) so you can see how I connect the nodes. But I will still try my best explain.
  13. I first created a plusMinusAverage node, known from now on as a pma. Name it spine_3_pma. With the attribute editor I changed it from Sum to Average. I connected the rotateX of the hip_joint to the


    input1D[0] of the pma. Then I connected the rotateX of the shoulder_joint to the input1D[1] of the pma. I connected the output1D of the pma to the locator3_grp.rotateX. Now if you rotate the shoulder_joint 100 degress in rotateX, locator3_grp will have rotated 50 degrees.

  14. Now move on to locator2_grp. Create another pma. Name it spine_2_pma. Connect the output1D of spine_3_pma to the input1D[0] of spine_2_pma. Then connect the hip_joint.rotateX to the input1D[1] of spine_2_pma. Connect the output1D of spine_2_pma to locator2_grp.rotateX. With the shoulder_joint still rotated 100 degrees, the locator2_grp will now be rotated 25 degrees.
  15. Create another pma, name it spine_1_pma. Connect the hip_joint.rotateX to spine_1_pma.input1D[0].


    Connect the spine_1_pma.output1D to locator1_grp.rotateX. We want locator1_grp to only get its rotation from the hip_joint. This seems like a waste of a utility node, but I included it for organization and so the HyperShade would make more sense.

  16. Create another pma, name it spine_4_pma. Connect the spine_3_pma.output1D to the spine_4_pma.input1D[0]. Connect shoulder_joint.rotateX to spine_4_pma.input1D[1]. Connect the spine_4_pma.output1D to locator4_grp.rotateX.The locator4_grp should now have a 75 degree rotation.
  17. Create another pma, and name it spine_5_pma. Connect the shoulder_joint.rotateX to the spine_5_pma.input1D[0]. Connect the
    The HyperShade setup for the twist.


    spine_5_pma.output1D to locator5_grp.rotateX. Don’t forget to



    change each plusMinusAverage node to “Average” instead of “Sum”.

  18. If we did everything right this is what it should look like Figure 8. Twist both the hip and shoulder_joint around to see how it works. It definitely twists past 180 without flipping.
  19. Now to add a few controls for easy selection and to finish it off. Create a NURBS circle, name it hip_ctrl. Duplicate it and name it shoulder_ctrl. Snap the shoulder_ctrl to the top of the spine. Select hip_ctrl and hip_joint and parent constraint it. Select the shoulder_ctrl and shoulder_joint and parent constraint it. Figure 9 shows the controls and the spine twisted and manipulated.
  20. I really hope this tutorial is helpful. If you have questions, comments, or critiques feel free to state


    them. Let me know if there are errors and i’ll fix them as soon as i can. If enough people are interested I can show how to make the spine squash and stretchy. Its not that hard just takes a bit more work. Let me know and I’ll add an addendum to this post.

Side 90 and twist 180

Side 90 and twist 180

Here is a link to the file, change the .doc extension to .ma. It is a 2008 file, but you can change the header to work for your version of maya. awesomespine1

Maya – No Flip Knees with Local Global Switching

•February 13, 2008 • 4 Comments

This method of creating no flip knees with local and global switch for the ankle is a compilation of ideas that were inspired by Aaron Holly.  Also there were some limitations I found with this way of creating No Flip knees, the animator no long had a control object to move that controls the knee rotations, also the animators want to have the control to rotate the knees with the rotation of the ankle or to turn that feature off. So I created this method as follows.

So I start off with a basic IK leg setup, I am not going to address IK/FK switching in this post, but it is easy to integrate into a switch system. basic setup As you can see from the picture that it has an IK chain running from the thigh to the ankle and the ik handle is parented to a control object. Very basic. So what we are going to do now is setup the pole vector constraint, this so the animators can have an iconic representation of the knee control. I created a NURBS cone and aligned it to the knee joint then selected the cone and shift-selected the ik_handle and click the poleVector constraint. So now the cone controls were the knee points. But if you move the foot control or the root control the knee control doesn’t move. And if you move the foot control up in Y it will flip when it passes the pelvis line. Flipping Knee We will now fix this problem.

Start by creating 4 locators I named them as follows: _l_knee01_pos , _l_knee01_aim , _l_knee01_up , _l_knee01_tgt . I use Aaron Holly’s naming scheme so it might look familiar. The _aim and the _up are parented to the _pos locator. Point and orient constrain the _tgt to the thigh joint. Then point-constrain the _pos locator to the foot control. Move the _up out a bit form the _aim locator on the X-axis. The _up locator will be used to define the up vector for the aim-constraint we will setup. Select the _tgt and shift-Select the _aim locator and go to the animation menu constrain->aim->[option box]. For the aim vector I used 1 for Y, so it would aim in the Y-direction. For up vector I used 1 for X, so that it would point toward the _up locator. For world up type I used Object Up and then in World Up Object I typed the name of my _up locator: _l_knee01_up. The orientation of the _aim locator should be relatively the same if some axis flipped try entering a -1 for the aim or up vector.

Once that is setup the _aim locator should always point to look at the _tgt locator constrained to the hip. This is exactly the behavior we want for the knee control. If you haven’t grouped the knee control to zero out the transformations do it now. If you don’t what I mean look here. Now all you have to do is parent the knee control group node to the _aim locator.

Now if you move the foot control up past the pelvis it doesn’t flip but rotates perfectly around. As you can see the knee control follows the movement of the foot control as well as the root control. NoFlip

Now on to the Local Global Switching. Sometimes animators want to be able to have the knee rotation follow the ankle rotation and sometimes they don’t want this behavior, so we are going to create a way to do both.

Right now if you select the foot control and rotate it the ankle moves independent of the knee. This is one of the behaviors we are after now we need the other. Create another locator and call it _c_bodyGlobal01_loc. You can move it off to the side just don’t rotate it. Right now it’s orientated to the world. Select the foot control and shift-select the _pos locator go to the constrain menu and click the parent option box. uncheck translate so it only adds a parent constraint for the rotation values. This will be our Local rotations inherited from the foot control. Now select the bodyGlobal locator and shift-select the _pos locator and do the same parent constraint. This is our Global rotations inherited from the bodyGlobal rotation.

So if you go into the hyperGraph and select the parent-Contraint node underneath the _pos locator, in the channel box you will see two weights. Set the first weight to 1 and the second to 0. Now if you rotate the foot control the knee rotates with the ankle. If you swap the weight values W0 = 0, W1 = 1, then you when you rotate the foot control the knee does not rotate with the ankle.

If your handy with MEL script you could easily make a GUI that will do this switching at the click of a button. You will notice that if you have it in Local mode, rotate the ankle, then switch to Global mode, the knee will pop back to its original position is this expected. To really fix it you will need to use MEL script. But basically what you do is before the local global switch unparent the knee control from the knee_control_group, do the local global switch, then parent back to the group.

That is basically it for the No Flip Knees with Local Global Switching. Please post any comments, questions, or corrections. There are probably mistakes, just let me know and I will fix them.

No Flip Knee File– Just change the extension to .ma

Maya – mGroup, zero out transformations

•February 13, 2008 • 1 Comment

To zero out the transformations of an object without using the freezeTransforms method. This is a very common method which I have seen on many websites. Here is what I do:

Create a locator and move it away from the origin and rotate it some arbitrary amount. If you look in the channel box it will have values for the translations and rotations. Sometimes you want to zero this but keep the relative position. Now create an empty group. Its world space location will be at the origin. Select the locator and shift-select the group probably by way of the outliner or hyperGraph since it isn’t visible. point and orient-constrain the group to the locator. Now the group has the exact position and rotation as the locator. Delete the point and orient-constraints from the group, and parent the locator to the group. If you look in the channel box it will have all zero’s. Thats it fairly easy.

Here is some code I wrote that will automate the process:

global proc mGroup()
string $selected[] = `ls -sl`;
for($obj in $selected)
string $group = `group -em -name ($obj+”_grp”)`;
select -r $obj;
select -tgl $group;
delete `pointConstraint -offset 0 0 0 -weight 1`;
delete `orientConstraint -offset 0 0 0 -weight 1`;
string $objParent[] = `listRelatives -p $obj`;
if(size($objParent) != 0)
parent $group $objParent;
parent $obj $group;
}else { parent $obj $group; }


Syntax Highlighted picture: