Skip to content

Tutorial: Ik/Fk Arm · Sep 30, 2:31am

By Ian Jones and Matt Ornstein

Step 1: Creating bind joint chain

For this example we are going to use a simple joint chain, clavicle to hand like this:

The _b represents that they are ‘bind’ joints and will be used for skinning. Joints not used for skinning are branded *_j. Be sure to set joint rotation order and clean up after you’re done. (If that just went in one ear and out the other please reference Paul Thuriot’s HyperReel Body Series as he does a wonderful job covering that topic in great detail)

Step 2: Create control arm

Duplicate shoulder_b ( duplicate -rr -renameChildren -un; ) and parent it to the world(unparent – shift+ P). Rename fkShoulder, fkElbow, fkWrist and delete anything below the wrist. These will become the fk controls shortly.

Now we’re going to replace the current shapes of the control arm with nurbs curves to ease selection/understanding. I’ll walk you through the process once manually – then I’ll show you how to repeat the process using ijUtils to speed up the process.

Create a nurbs curve control shape

Go ahead and create any control curve for the fkArm (I highly advise making it a single shape – I’ll be using a sphere created with the following mel:

curve -d 3 -p 0 0 -1 -p -0.5 0 -1 -p -1 0 -0.5 -p -1 0 0 -p -1 0 0.5 -p -0.5 0 1 -p 0 0 1 -p 0.5 0 1 -p 1 0 0.5 -p 1 0 0 -p 1 0 -0.5 -p 0.5 0 -1 -p 0 0 -1 -p 0 0 -1 -p 0 0.5 -1 -p 0 1 -0.5 -p 0 1 0 -p 0 1 0.5 -p 0 0.5 1 -p 0 0 1 -p 0 -0.5 1 -p 0 -1 0.5 -p 0 -1 0 -p 0 -1 -0.5 -p 0 -0.5 -1 -p 0 0 -1 -p 0 0 -1 -p 0 0.5 -1 -p 0 1 -0.5 -p 0 1 0 -p 0 1 0 -p -0.5 1 0 -p -1 0.5 0 -p -1 0 0 -p -1 -0.5 0 -p -0.5 -1 0 -p 0 -1 0 -p 0.5 -1 0 -p 1 -0.5 0 -p 1 0 0 -p 1 0.5 0 -p 0.5 1 0 -p 0 1 0 -p 0 1 0 -k 0 -k 0 -k 0 -k 1 -k 2 -k 3 -k 4 -k 5 -k 6 -k 7 -k 8 -k 9 -k 10 -k 11 -k 12 -k 13 -k 14 -k 15 -k 16 -k 17 -k 18 -k 19 -k 20 -k 21 -k 22 -k 23 -k 24 -k 25 -k 26 -k 27 -k 28 -k 29 -k 30 -k 31 -k 32 -k 33 -k 34 -k 35 -k 36 -k 37 -k 38 -k 39 -k 40 -k 41 -k 41 -k 41 ;

Don’t worry about naming this as it simply won’t be around long. Once your control curve is created open the outliner and be sure to enable the showing of shapes. Then select the curve’s shape and then the joint’s transform you’re interested making the control. For example: I would select curveShape1 then shift select fkShoulder. Then enter the command: ‘parent -r -s;’

Before ‘parent -r -s;’:

After ‘parent -r -s;’:

Notes about this methodology

Turn off shapes in the outliner – notice the fkShoulder now appears to be a nurbs curve – but if you examine the attribute editor the fkShoulder remains a joint. The immediate benifts to this method is that your control system can be an exact copy of your skeleton chain. This allows the control system to make use of joint only things like inverseScale so we can isolate scale between parts of the rig extremely easily. It also ensures that we can use direct connections to drive the skeleton over constraints.

Clean Up parent -r -s; command

You’ll notice the transform that the curveShape used to be associate with is now empty and appears like group in the outliner, delete it as it’s not longer needed.

Repeat for elbow to ensure understanding of the technique

Repeat method for fkElbow to practice

Using mel to ease the process for the wrist and beyond

Okay now create one final curve for the fkWrist but instead of repeating the above process you can use this script: ijParentShape (part of ijUtils found here)
Load ijUtils with the following command: ‘ijUtils;’ This time all you have to do is select the curve transform and then the fkWrist transform and press the button. In other words just select the curve/fkWrist in the viewport and press the ijParentShape.

Step 3: Layer IK ontop of the FK

Create an ikHandle (ikRPSolver) from the fkShoulder to the fkWrist. Rename it to: IkLimb. Create a control shape and attach it to the ikhandle. BE SURE TO MOVE THE CURVE TO THE WRIST. Only joints require the controls to be at the origin. Other nodes, like the ikHandle, require the shapes to be in their desired final location before using the script. I use a cube created with:

curve -d 1 -p 1 0 -1 -p -1 0 -1 -p -1 0 1 -p 1 0 1 -p 1 0 -1 -p 1 2 -1 -p -1 2 -1 -p -1 0 -1 -p -1 0 1 -p -1 2 1 -p -1 2 -1 -p 1 2 -1 -p 1 2 1 -p -1 2 1 -p 1 2 1 -p 1 0 1 -k 0 -k 1 -k 2 -k 3 -k 4 -k 5 -k 6 -k 7 -k 8 -k 9 -k 10 -k 11 -k 12 -k 13 -k 14 -k 15 ;CenterPivot;

Create a ‘poleVector’ control as you normally would and create a poleVector constraint between the IKLimb and your newly created poleVector.

Step 4: Hand Orientation

Select the fkWrist, IkLimb, and wrist_b; Open the hypershade and map the connections. Create a conditional node named `wristOri_cond`. Connect ikBlend to firstTerm and rotate to color if true from IkLimb -> wristOri_cond. Then from the fkWrist connect rotation to color if false and set the second term to 1; Then connect outColor to wrist_b rotation.

I used the following code:

shadingNode -asUtility condition -name wristOri_cond;
//IkLimb -> wristOri_cond
connectAttr -f IkLimb.ikBlend wristOri_cond.firstTerm;
connectAttr -f IkLimb.rotate wristOri_cond.colorIfTrue;
//fkWrist -> wristOri_cond
connectAttr -f fkWrist.rotate wristOri_cond.colorIfFalse;
setAttr “wristOri_cond.secondTerm” 1;
//wristOri_cond -> wrist_b
connectAttr -f wristOri_cond.outColor wrist_b.rotate;

Click to enlarge to visulize the flow of connections.

Step 5: Connect the controls to the bind joints

Connect fkShoulder.rotate to shoulder_b.rotate. Connect fkElbow.rotate to wrist_b.rotate.

Step 6: Visibility toggles

Use SDK to turn the visibility of the fkShoulder on/off based on the ikBlend value of IkLimb. Also, connect IkLimb.ikBlend to the visibility of the poleVector to finish setting up the toggle.

Step 7: Clean Up

Lock/Hide translateX/Y/Z, scaleX/Y/Z, and visiblity on the fk controls. Lock/Hide scaleX/Y/Z, poleVectorX/Y/Z, visibility, offset, and roll from the IkLimb. Lock/Hide offsetX/Y/Z, PoleVectorW0 from the poleVector constraint (Found under the shapes section of the channel box with the IkLimb selected). Lock/Hide rotateX/Y/Z, scaleX/Y/Z, and visibility on poleVector.

Ensure that the translation/rotation/scale on the controls is equal to zero at bind, especially the IkLimb and poleVector. To zero a control, create an empty group move it to the same location as the concerned control. Rename to ‘<>_ZeroSpace’, parent to the controls parent and then parent the control to the space. This process can be simplified greatly with GroupToSelf (part of ijUtils). Be sure to set the preferred angle on the fkElbow to improve the ikSolver.

Download the example maya file here.

previous entry | next entry