Tyler Thornock - Character TD
Rigs Scripts Tutorials Demo Reel Resume

Dog Hind Leg Tutorial
By, Tyler Thornock

This tutorial will help you setup a dog/animal's hind leg with a single control to make it easier for the animator to move.  This basically artificially sets up a spring ik.  So if you have Maya 7, you may want to use it, though this setup does give you more control in the end.  This setup may be confusing for some, but the stuff you learn can be applied to many other areas.

Well, the first part of this tutorial is "borrowed" from the Inspired 3D Advanced Rigging and Deformations book, however the book does not setup the rotation of the second part of the leg to be driven automatically which is a pain because the animator would have to rotate it appropriately every time they move the leg.  With this setup, the animator can control the rotation or leave it automatic, unlike using a spring ik.

Initial Setup:
- Start out with a four joint chain.  Name them Hip, Knee, Ankle, Wrist with the extension _ikfull.
- Now duplicate the chain and replace _ikfull1 with _ik, this is going to be the main ik chain, if you were setting up an ik/fk switch, this is the chain you would blend.
- Next, add an ikhandle from the Hip_ikfull to the Wrist_ikfull and name it Leg_ikhandle.
- Next, add an ikhandle from the Hip_ik to the Ankle_ik and name it Ankle_ikhandle.
- Finally, add an ikhandle from the Ankle_ik to the Wrist_ik and name it Wrist_ikhandle.

parenting
- Now that is setup, time for parenting.  Parent the Ankle_ikhandle to the Wrist_ik and the Wrist_ikhandle to the Ankle_ik and freeze transformations on both of the ikhandles.
- You can now drag around the Leg_ikhandle and have the other chain follow it.  If you rotate the Wrist_ikfull joint it would move the leg appropriately.  Now we need to set it up so it automatically figures out how much rotation to apply.
- Next create a distance dimension node and snap one end to the Hip and the other to the Wrist.  Parent the one at the wrist to Leg_ikhandle and parent the other to the Hip_ik (if you have cyclecheck issues, parent it to the hip pivot or "clavicle" when finished and leave unparented for now)

Savor the one and only screenshot!

Nodes and Mel!:
- Now we have to get the current value of the distance node so we know how much closer the wrist is to the hip when being moved then it was at default position. .... I used a getAttr mel command to do it to make sure I got all the trailing numbers (ex. 5.34233229)   mel code:  getAttr distanceDimensionShape1.distance;

setting up the plusMinusAverage node
- Next, we have to subtract the starting distance value from the one that is constantly changing.  So create a plusMinusAverage node named Leg_AutoWristRot_pma;
- Select the distanceDimension1 node and add an attribute called "starting distance" and set it to whatever you got from above.
- Open up the connection editor and load the distanceDimension1 node as the output and Leg_AutoWristRot_pma as the input.  Connect the starting distance to Input1 D[0];
- Now load up distanceDimensionShape1 as the output and connect the distance to Input1 D[1];  But oh no! There is no Input1 D[1] to connect it to!  You could use the hypergraph and not have this problem, but I prefer the connection editor.  You have to open up the script editor and find the line like this (connectAttr -f distanceDimension1.startingDistance Leg_AutoWristRot_pma.input1D[0];
) copy the line into the bottom part of the script editor and change that 0 to a 1 and run the command.  Now if you left the connection editor open you have an Input1 D[1] which you can connect the distanceDimensionShape1's distance to.
- Lastly, select the plusMinusAveraege node, open up the attribute editor and change the operation to subtrace.

setting up the condition node
- Now create a condition node named "Leg_AutoWristRot_con"      mel code:  createNode condition -n Leg_AutoWristRot_con;
- Plug in the Output1D value from the plusMinusAverage node above into the condition node's First Term (using the connection editor).
- Now select the condition node and open the attribute editor.  Set the operation to Greater Than and for all the Color If False values enter in 0.

setting up the multiplyDivide node
- Almost there.  Create a multiplyDivide node named "Leg_AutoWristRot_mult"      mel code:  createNode multiplyDivide -n Leg_AutoWristRot_mult;
- Plug in the Output1D value from the plusMinusAverage node above into the multiplyDivide node's input1X (using the connection editor).
- Now connect the OutputX of the multiplyDivide node to the condition node's colorIfTrueR attribute.
- Now, connect the condition node's outColorR to the Wrist_ikfull's rotateZ (it may be a different rotate depending on your orients).

Wrap Up:
- Next, create a control for the leg, snap it to the Wrist, freeze its transforms and point constraint the ikHandle to the control (select the control, then ikhandle, and then point constrain);
- Add an attribute to the control called ankleBendAdjust and set the min value to -30, max to 30 and default to 5 or 10.
- Now connect the ankleBendAdjust to the multiplyDivide node's input2X.
- If you did it right and my tutorial is void of typos you can now grab the box and move the leg around with the _ik chain moving correctly!
- TIP: If you want to add a control for the animator to be able to manually rotate the ankle and avoid the auto all together, simply create another plusMinusAverage node that adds up the outColorR of the condition node and another custom attribute and then connect the plusMinusAverage's Output1D value to the rotate instead of the condition's outColorR.

NOTE:  Before you bind the joints or continue with adding a footroll, you will need to create another joint called something like Foot_ik, snap it to the Wrist_ik and parent it to the Ankle_ik.  The reason for this is that the actual Wrist_ik joint is being rotated in order move the leg properly and would screw up the footroll if it was the joint all the toes were parented to.  The sample file has the footroll implemented into the setup.

Sample File from tutorial.