In our Character Rigging series, we showed you how to build a robust bipedal character rig,
tailored specifically for animation.
In this movie, we'll build on that foundation by developing a system
to snap FK joints to IK joint positions.
So far, we have a rig that works great in IK or FK mode.
All the controls respond as they should,
and play nice with the other IK/FK controls of other body parts.
However, the IK and FK solutions, particularly for the arms and legs,
are quite independent of each other.
Imagine animating a sequence that involved both,
like pushing up from a school desk to stretch like so.
We'd use IK to animate the initial pushing part, since the hands need to be planted...
...and then we'd want to switch in mid-animation to FK mode to take care of the stretching motion.
However, look what happens when we switch from IK to FK mode...
...the arm snaps back to the FK position!
This is kind of annoying as it means every time we want to switch between modes,
an animator would have to manually pose the other limb to match the current one.
Not only that, but because it's unlikely we'd be able to match the limbs
in precisely the same position, we'd also have to animate a blend from one mode to the other,
otherwise we'd get some unsightly popping right at the moment of the switch.
This is a lot of work just to switch from IK to FK
and can actually set animators back days or even weeks in total time spent.
Thankfully there is a solution to this. With just a few extra joints and a script,
we can build a tool that will allow us to snap IK joints directly to their FK position and vice versa.
Let's explore the basic concept of how our matching script will work.
Ideally, we'd like to match each joint to the location and orientation
of the opposing kinematic limb.
Even better would be matching the IK/FK joints to the result joints.
This would guarantee that whatever mode we were switching to
would precisely match the rig we're currently looking at.
Unfortunately, one thing blocking us from doing that is that the IK controls, FK controls,
and result joints all live in different spaces.
They don't all have the same local rotation axes or points of reference.
However, what if we were able to set up an extra object on the result arm
that DID live in each of the FK and IK arm spaces?
Then we'd be able to match to those instead!
Let's test out our theory on the left arm.
Start by opening the file "01-0- Character_Rigging_AppendixA_part1_start.mb".
First, make sure the FK arm is visible.
Now make a copy of the leftUpperArm_FK_CTRL and rename it "leftUpperArm_FK_snap_JNT".
Delete everything below it including the shape node.
Before we can re-parent to the result joint,
we'll have to unlock its Translate attributes via the Channel Control editor.
nce you've done that, re-parent it to the leftUpperArm_result_JNT.
Now we have a joint to snap to, we just need a way to snap to it.
Open the script editor.
We're going to start by matching the FK upper arm's rotation to the snap joint's rotation.
To do that, we'll use the xform command.
xform is a Maya command that allows you to query where an object is in the scene,
but also allows you to position one as well.
Let's do a simple xform command to try it out.
Type the command "xform --query --worldSpace -- rotation leftUpperArm_FK_snap_JNT".
You'll notice our command is outfitted with several flags.
These are options that determine what we want from the xform command.
-query signifies we're asking, not setting, where this object is.
-worldSpace signifies we want its absolute position in the world,
not its relative position to its parent (very important).
-rotation obviously signifies we're asking for the rotation.
Now run the command using the "Execute All" button.
Maya returns the world space position of the snap joint.
You may try to double-check this value by selecting the snap joint
and looking at its rotation values in the Channel Box.
But it says here the Rotation is 0, 0, 0!
Fear not. Remember that we queried the world space rotation.
What the "Rotation" attribute is showing you is the object space.
Sure enough, if you were to change the -- worldSpace flag in the command
to an --objectSpace flag, the Script Editor returns 0 0 0.
So now that we have the rotation, what do we do with it?
Remember, we want to use that value to drive the rotation of the FK upper arm.
That means first we'll need to store the rotation of the snap joint,
then apply that stored value to the actual FK joint.
Add the line "$r_upperArm =" before the xform command.
This indicates we want to store the value of the xform rotation query
in a variable called "$r_upperArm".
In order for Maya to understand this, we'll also need to insert a set of tildes
around the xform command.
This is so Maya knows where the command starts and where it ends.
The tilde key is located right next to the "1" on your keyboard.
It's not the same as the apostrophe.
You can confirm that $r_upperArm has the right value by using the command "print $r_upperArm"
to write the value of the variable in the upper window.
Notice when writing multiple lines like this, we need to include a semicolon after every line
so Maya knows where one ends and the next begins.
To apply this rotation value to the FK arm, we'll just run the xform command again,
but without the --query flag.
Notice how we're individually inputting the $r_upperArm values
one by one with these square brackets.
This is because the variable stores the values of the rotation as an array,
where index 0 is the X rotation, 1 is the Y rotation, and 2 is the Z rotation.
Finally, we're applying this rotation to the leftUpperArm _FK_CTRL.
Now let's test our script.
Go to IK mode and position the arm however you like.
Now run your script.
Switch back to FK mode.
Sure enough, the FK upper arm's rotation matches the IK arm's rotation.
Now we can do that for the rest of the arm.
Just like before, make duplicates of the FK forearm and FK hand joints.
Rename them appropriately, then delete all their children.
Unlock their "Translate" attributes and then re- parent them under their respective result joints.
Now copy and paste the script work you did for the upper arm
and alter it for the forearm and hand joints.
Now try posing the IK arm again.
Run your script and then switch to FK mode.
The FK arm matches perfectly.
One thing we haven't taken into consideration yet is the gimbal control.
It's impossible to really assign it a meaningful value
since its usefulness is determined on a pose-by- pose basis.
Thus, we'll set all its rotations to 0 before an FK match.
Finally, as a precautionary measure, hide the snap joints.
This is a good start, and as you can see the concept isn't actually too difficult.
You can repeat the entire process for the right arm.
In the next movie, we'll match the IK arm using the same technique.