Arm Rig Setup For Seamless FK/IK Switching
This tutorial assumes that you have the following simple skeleton:
- A joint named L_shoulder_JNT
- A joint named L_elbow_JNT
- An arm IK control object called L_armIk_CON (to which the IK handle is going to be point-constrained)
- A pole-vector control object called L_armPole_CON
You can download the Maya (6.0) scene here: armRig_001.ma.
The purpose of this tutorial is to detail the setup of a simple arm rig that will allow you to switch from FK to IK and vice-versa without the joints popping, which is very useful to pose a character (among other things). Please note that this method uses a single skeleton (no blending between multiple arms/skeletons).
In this example, the arm IK and pole vector control objects are Nurbs curves, but they could be any type of object you’d like. You can download the basic setup with this (maya 6.0) scene: armRig_001.ma.
Please note that it is indispensable that those joints form a perfectly flat plane. Bending the elbow is OK, but no twisting!
1) Building the Rig using MEL:
Now that we’ve got a basic skeleton and some controls, time to setup the arm rig itself. The following code is basically a scripted “tweaking” of the above Maya file to allow for the FK / IK switching:
// 1) First lock the Y and Z rotations on the elbow joint (it will only bend like a real elbow).
setAttr "L_elbow_JNT.jointTypeY" 0;
setAttr "L_elbow_JNT.jointTypeZ" 0;
setAttr -lock true -keyable false "L_elbow_JNT.ry";
setAttr -lock true -keyable false "L_elbow_JNT.rz";
// 2) Create the IK handle.
ikHandle -sol ikRPsolver -sj L_shoulder_JNT -ee L_wrist_JNT -n L_arm_IK;
// 3) Set the armIk control in world space (default values won't be 0, but we don't care).
move -rpr 0 0 0 L_armIk_CON;
makeIdentity -a 1 -r 1 -t 1 -s 1 L_armIk_CON;
vector $wristPos = `xform -query -a -worldSpace -rp L_wrist_JNT`;
move -worldSpace -a ($wristPos.x) ($wristPos.y) ($wristPos.z) L_armIk_CON;
makeIdentity -a 1 -r 1 -t 1 -s 1 L_armIk_CON;
pointConstraint -w 1 -o 0 0 0 L_armIk_CON L_arm_IK;
// 4) Create the default position locator for the arm pole vector
// (we'll use it to position the pole-vector when switching from FK to IK).
spaceLocator -p 0 0 0 -n "L_armPoleDefault_LOC";
vector $elbowPos = `xform -query -a -worldSpace -rp L_elbow_JNT`;
move -a ($elbowPos.x) ($elbowPos.y) ($elbowPos.z) L_armPoleDefault_LOC;
// 5) Parent the locator to the shoulder joint and put the locator behind the elbow.
parent L_armPoleDefault_LOC L_shoulder_JNT;
move -r -ws -wd 0 0 -10 "L_armPoleDefault_LOC";
setAttr "L_armPoleDefault_LOC.visibility" 0;
// 6) Match the position between the pole vector and the locator.
pointConstraint -w 1 -o 0 0 0 L_armPoleDefault_LOC L_armPole_CON;
makeIdentity -apply true -t 1 -r 1 -s 1 -n 0 "L_armPole_CON";
// 7) Pole-constraint the IK handle to the pole-vector control.
poleVectorConstraint -w 1 L_armPole_CON L_arm_IK;
// 8) Connect the IK handle visibility to the wrist IK enable attribute.
addAttr -ln enableIk -at bool -k on -dv 0 L_armIk_CON;
connectAttr -f L_armIk_CON.enableIk L_arm_IK.ikBlend;
connectAttr -f L_armIk_CON.enableIk L_arm_IK.visibility;
connectAttr -f L_armIk_CON.enableIk L_armIk_CON.visibility;
// 9) Put the arm in FK by default.
setAttr "L_armIk_CON.enableIk" 0;
2) IK/FK switching:
Now we have a rig ready for some switching. If everything went well, the Ik control object just disappeared (!). That’s normal, since the rig is currently in FK. So you can animate the elbow and shoulder joints by selecting and rotating them.
The whole idea behind this simple rig is to only use one skeleton for the arm, both in FK and IK. The trick is achieved by parenting a locator to L_shoulder_JNT that will serve as a ‘solid’ reference anchor point to which we snap the L_armPole_CON each time we switch to IK.
One advantage is that the locator will always be at the ‘right place’ for the plane of the arm to be respected (since it IS part of the arm skeleton); Therefore there won’t be ANY wobbling/popping at all when switching.
The other advantage for the animators is that they won’t have to look for the pole vector object every time they switch to IK, since it will ALWAYS appear at the same place/distance from the elbow.
When you want to switch to IK, use the following script: IkFk_switch_002.mel. You can source it, or copy and paste it into the script editor, and then make a button out of it. To run the script, just type:
IkFk_switch( "", "L_", "arm" );
The switch procedure itself is a command which takes 3 arguments; the first being the namespace (since the rig’s not referenced we’ll use “”), the second being the arm’s side (“L_” or “R_”) and finally the limb (“arm” or “leg”; in this case the arm). The code is abundantly commented, so please have a look to see what happens under the hood.
You should now see the Ik control object, neatly placed on the wrist. Now you can move it (as well as the pole vector object) and the arm should follow along.
To toggle back to FK, simply call the same procedure again (with the same arguments).
There you go!
As always, drop me a line if something explodes that shouldn’t…