Advanced Rigging

Arm with Forearm Twist and IK/FK Switch

Introduction

This tutorial is a custom tutorial based on the classic IK/FK switch and forearm twist desribed in The Art of Rigging Volume 1 and the master class tutorial led by Jason Schleifer for SIGGRAPH 2006. The mesh segmentation and controls are based on Animator Friendly Rigging, however we will not be implementing the stretch (which limits the complexity). Instead of the stretch, we will be using a method similar to the one described in The Art of Rigging. If you would like to learn more about creating an IK/FK switch or auto forearm twist, and further understand the concepts behind this tutorial, please view the origonal text: Animator Friendly Rigging Part 3 and The Art of Rigging Volume 1 pages 21 through 24 (available for purchase at CG Toolkit or you can ask Kendal nicely to borrow hers).

Tutorial

  1. Unhide l_arm_geo and l_gloves_geo
  2. Segment the geometry into 5 pieces, cut just after the shoulder, at the elbow, at the middle of the lower arm (forearm) and at the wrist. You can use Mesh > Extract to separate the faces.
  3. Name the segments l_shldr_geo, l_upArm_geo, l_lowArm_geo, l_foreArm_geo, and l_glove_geo.
  4. Create a joint that starts between l_shldr_geo and l_upArm_geo, another at the elbow, another at the forearm, and another at the wrist and then the end of the joint chain right before the knuckles.
  5. Name the joints l_upArm_joint, l_lowArm_joint, l_foreArm_joint, l_hand_joint, and l_handEnd_joint.
  6. Change the joint orientation such that the positive Y axis points forward. You can do this with the Skeleton > Orient Joint > Options. The orientation can be XYZ with the second axis as the positive z, set this for each joint in the arm.
  7. Now fix the rotation order by using the Change Rotation Order script in the Rigging shelf. Here is what the rotation orders should be:
            l_upArm = xyz
            l_lowArm = xzy
            l_foreArm = zyx
            l_hand = zyx
  8. Create another joint that is not in the joint chain (just a free floating joint). The joint will be straight in from the l_upArm_joint and below the colar of the mime's shirt. It would technically be in the center of the colar bone and is not a real joint in the body, but this is where the shoulder rotations are going to origonate from. Name the joint l_clavicle_joint.
  9. Duplicate l_upArm_joint. Delete all of its children. Name the joint l_clavicleEnd_joint, and parent it to l_clavicle_joint.
  10. Parent the l_shldr_geo to the l_clavicle_joint. Hide l_clavicle_joint so that we can finish it up later.
  11. Select l_fk_upArm_joint and click the "grep rename" button on the Rigging Shelf. Search for "l_" and replace with "l_fk", make sure that the Duplicate then rename box is checked (so that you create a duplicate of the control skeleton you just made).
  12. Select l_fk_upArm_joint and click the "grep rename" button on the Rigging Shelf. Search for "fk_" and replace with "ik_", make sure that the Duplicate then rename box is checked (so that you create a duplicate of the fk skeleton you just made).
  13. Parent the geometry to the correct joints. parent l_upArm_geo to l_upArm_joint, l_lowArm_geo to l_lowArm_joint, and l_glove_geo to l_hand_joint.
  14. Under the all_anim settings_grp, click on settings_anim. RMB in the channel box and add an click attributes > add attribute. The long name should be l_arm_state, it should be of type Enum, and the enum names should be fk and ik. Click ok when you are done.
  15. The following will walk you throuhg blending ik and fk manually. This is what the blend script does, the same effect can be achieved through constraints rather than using a blend node (we are going to set up a blend node). If you understand how to use the blend script, feel free to use it like you hooked up the leg, however if you want to learn more, you should follow these steps.
  16. Load the hypergraph by selecting l_up_arm, l_fk_up_arm, and l_ik_up_arm then choose Window > Hypergarph: Connections
  17. Create a blendColors node by choosing Rendering > Create Render Node (this is a menu in the Hypergraph Window) Click on the Blend Colors button under the utilities tab.
  18. Middle mouse click on the right side of the l_fk_upArm_joint and drag it onto the left side of the blendColors1 node. Select rotate. The connection Editor should open. Click on rotate on the left side (for the l_fk_upArm_joint) and click on color2 on the right side. (for the blendColors1 node).
  19. Middle mouse click on the right side of the l_ik_upArm_joint and drag it onto the left side of the blendColors1 node. Select rotate. The connection Editor should open. Click on rotate on the left side (for the l_ik_upArm_joint) and click on color1 on the right side. (for the blendColors1 node).
  20. Middle mouse click on the right side of the blendColors1 node and drag it onto the left side of the l_upArm_joint. Select rotate.
  21. Click on the blendColors1 node, ctrl click on settings_anim in the outliner (so that both blendColors1 and settings_anim are selected). Click the input and output connections button in the hypergraph (click help > help on hypergraph in the hypergraph window if you don't know what button that is).
  22. Middle mouse click on the right side of settings_anim and select other. Now the connection editor will open. Click on blendColors1 and click reload right in the connection editor. Click on l_arm_state in the left side, connect it to the blender by clicking on the blender on the right side. Now when you toggle between ik and fk on the l_arm_state, the l_upArm_joint should be controlled by either the l_ik_upArm_joint or the l_fk_upArm_joint.
  23. Now lets do the rest the easy way. Click on the blend button on the Rigging shelf. Set the following options: Object 1 l_fk_lowArm_joint, Object 2 l_ik_lowArm_joint, Target Obj l_lowArm_joint, Attribute rotate, Driver settings_anim.l_arm_state. Click Go.
  24. Change the attribute from rotate to translate. Click Go again.
  25. Click on the blend button on the Rigging shelf. Set the following options: Object 1 l_fk_foreArm_joint, Object 2 l_ik_foreArm_joint, Target Obj l_foreArm_joint, Attribute rotate, Driver settings_anim.l_arm_state. Click Go..
  26. Change the attribute from rotate to translate. Click Go again.
  27. Connect the hand translate and rotate with the Connect Blend UI still up, set the following values: Object1 l_fk_hand_joint, Object2 l_ik_hand_joint, Target Obj l_hand_joint, Attribute rotate, Driversettings_anim.l_arm_state
  28. Now change rotate to translate and click Go again. Now you have the fk/ik switch working.
  29. Now we can create the FK controls. Hide l_ik_upArm_joint and then add l_upArm_joint to the doNotTouch_layer. Create 3 nurbs circles, use the shape script in the Rigging shelf to attach the shapes to the l_fk_upArm_joint and l_fk_lowArm_joint. The control for the lowArm joint should span from the elbow to the wrist.
  30. Do not attach the last circle shape. Instead move the circle to the hand, snap the control to the hand joint. Use F8 to move the cvs to a more appropriate spot. Modify > Freeze transformations on the circle.
  31. Delete the first two circles that are floating in space (leaving the controls on the arm). Rename the control around the hand to l_wrist_anim
  32. Parent l_wrist_anim to l_fk_hand_joint and freeze transformation, this will make l_wrist_anim orient itself to l_fk_hand_joint. Group the l_wrist_anim to itself by selecting it and hitting crtl+g. Name the group l_wrist_anim_grp. Now unparent the group.
  33. Open the connection editor in Window > General Editors > Connection Editor. Click on l_wrist_anim and click reload left. Click on l_fk_hand_joint and click reload right. Rotate the l_fk_hand_joint to see which axes rotate the joint up and down, and side to side. We only want to connect those directions, twisting the wrist should be done from the forearm joint. If you have your joints set up correctly then you should click rotate y both sides of the connection editor and then rotate z on both sides.
  34. Click on the l_fk_forearm_joint and then reload right in the connection editor. Connect the rotate x on both sides of the connection editor. Now when you rotate your wrist, the forearm should twist. Make sure that the rotation order on the attribute editor is the same for both the joint and the control.
  35. Rename l_fk_upArm_joint to l_fk_upArm_anim. Rename l_fk_lowArm_joint to l_fk_lowArm_anim.
  36. Now hide your fk arm and unhide your ik arm.
  37. Click on your l_ik_lowArm_joint and set the prefered angle to 50 for the z direction in the attribute editor.
  38. Create an IK Handle from l_ik_upArm_joint to l_ik_foreArm_joint, it should be an RP solver (not an SC solver, RP solvers are for when we have pole vectors associated with the ikHandle). Rename it l_arm_ikHandle.
  39. Select the effector for the l_arm_ikHandle, press insert to move the pivot. Snap the pivot to the wrist joint and press insert again. You should be able to see the ikHandle move with the effector to the wrist.
  40. Import \\ntdfs\cs\unix\projects\instr\production2\rigging_files\control_library\circleArrowThree.mb. Move it to the location of the wrist. Rename it l_arm_anim.
  41. Parent l_arm_anim and l_arm_ikHandle to l_ik_hand_joint and freeze transformation on l_arm_anim, this will make l_arm_anim and l_arm_ikHandle orient to l_ik_hand_joint. Group the l_arm_anim and l_arm_ikHandle together by selecting it and hitting crtl+g. Name the group l_arm_anim_grp. Now unparent the group. Don't freak out, this is a cyclic dependancy, but you will unparent it! This just needs to happen because we want the axes of the joint to match the axes of the control and ik handle.
  42. Now point constrain l_arm_ikHandle to l_arm_anim by clicking Constrain>point.
  43. Create another ikHandle from l_ik_hand_joint to l_ik_handEnd_joint, parent constrain it to l_arm_anim (so that l_arm anim is the one controling the ik).
  44. Click on l_arm_anim and then l_ik_hand_joint and create an orient constraint on only the y and z axes.
  45. Click on l_arm_anim and then l_ik_foreArm_joint and create an orient constraint on only the x axis.
  46. Create a pole vector for the ikHandle like in the previous rigging tutorial (create a square and move it behind the elbow, click on the control (named l_elbow_anim) and then the l_arm_ikHandle and create a pole constraint.
  47. Hide the ikHandles.
  48. Select l_arm_anim_grp, l_wrist_anim_grp and l_elbow_anim and group them together in a group called l_arm_all_anim_grp.
  49. Select l_ik_upArm_joint, l_fk_upArm_anim, l_hand_ikHandle and l_upArm_joint. Group them together in a group called l_arm_grp
  50. Duplicate the l_arm_grp, delete all children and rename to l_arm_grp_p.  Move pivot to l_clavicleEnd_joint.
  51. Point constraint the l_arm_grp to the l_arm_grp_pos.
  52. Move the l_arm_grp_pos underneath l_clavicleEnd_joint
  53. Create a nurbsCirlce to control the shoulder. Use the shape script in the shelf to transfer the shape to the l_clavicle_joint. Rename l_clavicle_joint to l_clavicle_anim.
  54. Move l_arm_grp and l_arm_all_anim_grp underneath anim_grp.
  55. Move l_clavicle_anim underneath shldr_anim (parent it). Lock the translate, scale and visibility on l_clavicle_anim.
  56. As you may, or may not, have noticed, l_wrist_anim doesn't follow the other fk controls. To fix this. Select l_wrist_anim_grp and duplicate it. Rename the duplicate group l_wrist_anim_grp_pos and delete all of its children.
  57. Parent l_wrist_anim_grp_pos to l_lowArm_anim
  58. Click on l_wrist_anim_grp_pos and then l_wrist_anim_grp and create a parent contraint.
  59. Lock and hide other attributes on the appropriate controls.
  60. Done!