<%@LANGUAGE="JAVASCRIPT" CODEPAGE="1252"%> MAXTD - MAX, TD, Character Rigging
 

ARM IK: Ok. First, before assigning any IK to the arms, we need to go over a few things. First, let me explain a bit about the architecture behind my rig. The arm rig uses some complex controls and behaviours to control both IK behaviour, and inheritances. Take for example, a character doing pushups. You'd like to animate the rotations on the hips and spine, without worrying about the hands sliding all over the place. I've set some inheritance controls so that the wrists can or cannot inherit the arms movement and rotations. It is, however, not as simple (I wish) as setting standard inheritances. I achieved this by using two goals in the arm, and using weighted constraints on the wrists, so that you could alternate between an 'inherit' object, and a 'no-inherit' object. The constraint's weights are controller through a custom attribute I set on my arm control object. This object, which is the one you'll use to move the arm, also has some other custom controls to drive finger curling, IK swivel angles, wrist rotations, etc. That way, I can animate almost anything in my arm rig from this object, without having to select other objects, animate them, re-select the arm control object, etc. This makes animating characters a breeze. Therefore, there are some things we need to do prior to creating anything here, so that the whole thing will work perfectly. Let's get to it.

First, select the last bone in the arm chain (in my case, it'd be the 'Bone_ikterminator_arm' small bone). In the hierarchy panel, pivot tab, turn on the 'Don't affect children' button. Move the bone so that it's pivot point meets exactly the pivot points of the bones that start the hand assembly. This is crucial, or the hand will slide when the torso moves. Ok.

Select the arm bone (not the forearm one). Now, in your perspective view, really zoom in onto the ikterminator bone. Switch to a wireframe view if necesary (the hand bones are most likely getting in the way). Now, with the arm bone still selected, go into the animation menu (I have a toolbar for most of these operations), and select IK Solvers - HI Solver. Now, select the ikterminator bone. You'll see a blue cross at the ikterminator's pivot, and a line running from the cross to the pivot of the arm bone. The line is the IK solver. The blue cross is the goal. Whenever you move the goal, the IK solver will try to rotate the bones encompassed by it in order to meet the goal. These rotations are dependant on something called the rotation plane. You can't see it, but it's there. It's a plane that serves as a 'grond plane' to the IK chain, and it's originally parallel to the bones in the chain (that's why it's very important that the bones are aligned). This plane is controller by something called the swivel angle. By modifying this angle, you rotate the plane, thus rotating the bone chain, using the goal as a pivot. It's very much like moving your elbows while having your hands placed at your waist.

Now that we've gone over some IK basic concepts. Let's rig our arm.

Let's create some nodes we'll need for our arm rig. I used one spline object (just like the rotator, but pointy), and two point objects. Align them to the ikterminator bone (pos and orientation).Ok. Here we go.

Select the rotator (mine is colored purple). Link it to the forearm bone (not the ikterminator bone). In the hierarchies panel, link info tab, turn off the rotate inheritances in all axes. Name it NoInherit_arm.

Select the first point helper. Name it HandOrient. Link it to the NoInherit_arm spline object. Turn off the rotation inheritances. Now, apply an orientation constraint to it. Selec the forearm bone as a first target, and the NoInherit spline obj as a second target. For now, set the forearm's weight at 100, and the NoInherit object's to 0.

Select the second point object. Name it WristControl.Link this one to the HandOrient point object. Now, select each root bone in the arm and link it to the WirstControl obj. Here's a shot of my schematic view.


FIG 12

Create a new point helper object. Name it Control_arm, and align it with the IK WirstControl obj. Now, add the following custom attributes to it:

Name: Thumb Curl. Type: Float spinner. From -15 to 70, default 0. Object's base level.

Name: Index Curl. Same params as before.

Name: Mid Curl. Same params as before.

Name: Pinky Curl. Same params as before.

Name: Finger spread. Type: Float spinner. From -15 to 15, default 0. Object's base level.

Name: Inherit Arm. Type: Float slider. From 0 to 100, default 0. 4 ticks. Object's base level.

Name: Swivel Angle. Type: Float spinner. From -360 to 360 default 0. Object's base level.

As you might have guessed, most of these are hand-related controls. You'll see how easy is to animate both the arm and hand with these controls. Link the IK chain you created to it.


FIG 13

First, we'll wire the Swivel Angle parameter to the chain's swivel angle. Just select the point object (A_Control_arm), go to Animation/Wire Paramters/Wire Parameter, and select the IK chain (my point object has the cross option turned off so the IK chain underneath can be selected. I used instead the Axis Tripod option). The wire parameters dialogue will appear. Wire the point's object Swivel Angle Parameter to the IK chain's swivel angle parameter. Set the direction from the point object (driver) to the IK chain (driven). In the expression textbox, enclose the current expression in parenthesis, and add the following to the beggining of it... 'degtorad'. This tells the expression to convert the value from degrees to radians. This is necessary to have the results you expect.


FIG 14

Ok. Now comes a lot of repetitive work, so I'll just explain it once, and you repeat it as needed. We'll be wiring the finger controls to the fingers. We'll take the Index Curl parameter, for example. But first, let's prep the fingers. Select all of the finger bones, and assign a list controller to each of their Y rotations tracks (I use local euler controllers on them). Now, select the bones that would be the first bone in each finger (say, A_Bone_index_root), and assign to them another list controller to their Z rotation track. Ready. Re-select the control_arm point object, and open up the wire parameters dialogue box. Make sure that in the wire paramters dialogue, you are seeing the control_arm node in one side, and in the other the Bone_index_root node. Select the index curl parameter track in the control_arm side. Select the track marked as 'availble' in the Index_root's Y rotation list controller. Wire from the index_curl parameter to the Y avalible track. In the expression window, add the degtorad expression to it.


FIG 15

Without leaving the wire parameters dialogue, navigate to the next bone in the chain, in this case, A_Bone_index_mid. Repeat the wiring from the index_curl parameter to the bone's avalible controller in it's local Y rotation tracks. Finally, repeat for the last bone in the index finger chain.

To test if everything is working ok, grab the control_arm object and in the modify panel play with the index curl spinner. The index finger will bend forward and backwards.


FIG 16

Now, you'll need to do the same for the rest of the fingers, wiring them to their proper parameter in the control_arm object (pinky fingers to the pinky curl parameter).

To finish wiring the fingers, let's wire the Finger spread parameter. This parameter goes wired to each of the root bones of the fingers. Specifically, to their available Z rotation track. There is, however, one detail. Since this parameter spreads the fingers (open or close), the expresion value will have to be positive for either the index or pinky finger, and negative for the other. The middle finger needs to remain still (in the case of normal 5-fingered characters, both the mid finger and the ring finger would need to spread a bit). To make one of the values negative, you'd need to add a minus sign before the degtorad expression. In my case, I added it to the index finger, leaving the pinky as it was.


FIG 17

And lastly, the Inherit Arm slider. This slider is intended to make the hand inherit or not the arm's movements and rotations. This is so that you can pin the hand to anything else (a wall or the floor) and remain statick while the rest of the character moves. What this slider does is control automatically the oriantation constraints placed earilier on the HandOrient point object. But we'll use expressions to drive this one.

Select the HandOrient node, and in the motion panel create two expression controllers, one for each weight track in the orientation constraint controller. Open one of the expression controller for the weight0 track, create a scalar variable, and assign it to the Control_Arm's Inherit Arm track. Enter the variable's name you just created as the expression. Do the same for the second expression, but in the expression window enter the following expression... 100-variable.


FIG 18

This way, the slider will automatically drive the weight on both constraint controllers, interpolating correctly from 0 to 100 and 100 to 0.

Lastly, so you can control everything from the Control arm Node, wire its x,y and z rotation's to the WristControl x,y and z rotations. This way, you can rotate the arm control object, and the wrist will rotate (so you won't have to worry about having another node tim animate). If one of the rotations is reversed, enter a minus sign before the expression in the wire parameters dialogue (test by rotating the Control Arm node).

There you go. Your arm should be fully functional and working properly.

Leg IK

smucino@maxtd.com