IK-FK matching conception

I have 3 joint chains system on my rig:

And I’m trying to write a script which will match FK to IK and vice versa.
In addition to joint chains there are IK and FK curve controls on each of them exept for bound joint chain.

The script will be consist of 4 blocks of code:

1) Control and Attribute names identity check part
I suppose to use long names of controls with retrieving full DAG path because it can be situations where you
will have 2 or more characters in your scene with the same rig and identical control names. The use of unique
namespaces for different characters would be a nice solution as well. I have seen many IKFK match code examples
without identity check at all. I have no idea how they will work for example in complex scenes with a file
referencing and much more than one character onboard.

2) FK -> IK part
Matching FK to IK can be easy – if the joints share the same base orientation, all you need to do is copy the
rotation values from IK joints to their FK counterparts using the xform command. You have to copy
from IK joints to FK joints or FK controls?
If copy to FK joints then it is not clear because they already
constrained to FK controls and can not be moved.

3) IK -> FK part
Matching IK to FK is where things get interesting. Technically all you need to do is snap the IK handle to the
FK wrist/foot, and the pole vector to the elbow/knee. Ok this is clear in theory, but what the algorithm in a practice?
The matter is that my IK handle is already parented to the IK control. So it can not be moved or rotated directly in itself.
The same applies to the pole vector it is constrained to my elbowIK control with the Pole Vector Contraint.

4) Set keyframe part
I do not quite understand this part at all. Why you have to key all your controls and IKFK switching attribute
with the setKeyframe command. In what keyframe you have to do this (current or previous)? What if
autoKeyframe option is on/off by the user? And why you should set keyframe with a script if the animator which
will be using your rig can do it manually through the Maya UI?

PS. And in conclusion I have to say that I like TSM2 (The Setup Machine) by Anzovin Studio very much. I wonder
how they are implemented the FKIK snapping because I don’t see any xform or setAttr copying and pasting
rotation values operations in their code. I’ve attached their FKIK MEL script in a case you might be interested in.

> 1) Control and Attribute names identity check part

I would look into connecting nodes with message attributes, that way you stay independent from names.

[QUOTE=tokejepsen;27931]> 1) Control and Attribute names identity check part

I would look into connecting nodes with message attributes, that way you stay independent from names.[/QUOTE]

hmm… yes this solution is also suitable.

To match IK to FK, there’s a two-step solution.

First you need to get the IK effector in your IK chain to the world space position you want. This may or may not be identical with the position of the last joint in the FK chain, depending on how you’ve done your setups you may have an offset so it’s best to provide a marker in the FK chain which lines up precisely with the IK effector in the FK chain in the rest pose. If you have that you can need to snap the IK control to that marker’s position and orientation (it helps if the pivot of final IK control object also lines up with the marker).

The second snap is to calculate a good pole vector position. That’s the tricky bit: the math is not to hard but it produces an infinite set of valid solutions, so you need to find one that makes things painless for you. Generically there are a couple of things you need to do:
A) get the world space positions of you chain: eg, the world space positions of the shoulder, elbow and wrist (for chains with more than 2 bones there’s a bit of roll your own here)
B) get a matrix which represents the plane of the pole vector. This takes a few steps
1) Get the vector from shoulder to wrist and the vector from shoulder to elbow.
2) Get the cross vector of those two. Normalize it: That will becomes the ‘up’ vector of your pole plane.
3) the ‘forward’ vector of the matrix is the shoulder-wrist vector normalized
4) the ‘right’ vector of the matrix is the cross vector of (2) and (3)
5) make a matrix where (3) is the first row, (2) is the second row, and (4) is the third row. I usually use the world space position of the shoulder as the 4th row
c) Now any position in that matrix with a y value of zero will give you a valid pole vector for the iK chain. You’ll need to pick some consistent place on that plane to snap your PV: I usually do something like (1,0,1) * the distance from shoulder to wrist.

Ok, Theodox! Thanks for the reply. I’ve found much more easier solution without math at all:

  1. Create a simple locator.
  2. Position and orient it to your IK pole vector control.
  3. Parent constrain this locator to your shoulder FK joint.
  4. Now you can always match the position of IK pole vector to this locator.

But the math you have described is nice and as you mentioned it really produces an infinite set of another valid solutions.

I have one question that I suppose ambiguous -
What do you think is the most appropriate control to place FKIK Switch attribute?
At first glance, it is more logical to place FKIK Arm Switch attribute at the IK arm control for example.
But when you switch to FK mode IK arm control visibility will be equal to zero. That is why I’ve place it
on my character global control. I’m not sure about this choice, is it the best or not.

[QUOTE=zzz7net;28010]
What do you think is the most appropriate control to place FKIK Switch attribute?
At first glance, it is more logical to place FKIK Arm Switch attribute at the IK arm control for example.
But when you switch to FK mode IK arm control visibility will be equal to zero. That is why I’ve place it
on my character global control. I’m not sure about this choice, is it the best or not.[/QUOTE]

If you put the IK attribute on a shape node (I usually use something like a volume sphere) you can instance that shape around to multiple parents and they will all see it it in the channel box. The downside is that the attribute is on the shape, so it shows up in the second pane of the channel box along with other shape stuff – a place many animators just ignore out of habit.

[QUOTE=zzz7net;28010]Ok, Theodox! Thanks for the reply. I’ve found much more easier solution without math at all:

  1. Create a simple locator.
  2. Position and orient it to your IK pole vector control.
  3. Parent constrain this locator to your shoulder FK joint.
  4. Now you can always match the position of IK pole vector to this locator.

But the math you have described is nice and as you mentioned it really produces an infinite set of another valid solutions.

I have one question that I suppose ambiguous -
What do you think is the most appropriate control to place FKIK Switch attribute?
At first glance, it is more logical to place FKIK Arm Switch attribute at the IK arm control for example.
But when you switch to FK mode IK arm control visibility will be equal to zero. That is why I’ve place it
on my character global control. I’m not sure about this choice, is it the best or not.[/QUOTE]

I use a setup like this, but ran into a limitation where the bones in the arm chain had to be planar or else the pole vector wouldn’t snap to the correct position, resulting in my arm chain rotating a little bit every time I switched from FK back to IK. Did you encounter anything like this in your setup, and if so how did you solve it?

Here is a video that includes a demonstration of this idea

I’m almost done with the matching script. Working fine with the arms,

if ($currentMode == 1) //we're in IK mode
{
	//query current rotations
	float $shldr_jntRot[] = `xform -q -ws -ro $shldr_jnt[0]`;
	float $elbow_jntRot[] = `xform -q -ws -ro $elbow_jnt[0]`;
	float $wrist_jntRot[] = `xform -q -ws -ro $wrist_jnt[0]`;				
				
	//switches to FK mode
	setAttr $userswitch 0;
				
	//matches to IK joint chain transforms
	xform -ws -ro $shldr_jntRot[0] $shldr_jntRot[1] $shldr_jntRot[2] $shldr_ctrl[0];
	xform -ws -ro $elbow_jntRot[0] $elbow_jntRot[1] $elbow_jntRot[2] $elbowFK_ctrl[0];
	xform -ws -ro $wrist_jntRot[0] $wrist_jntRot[1] $wrist_jntRot[2] $wristFK_ctrl[0];				
				
	//holds the new position
	setKeyframe ...
}
else //we're in FK mode
{
	//query current transforms
	float $pvArm_locPos[] = `xform -q -ws -t  $pvArm_loc[0]`;
	float $wrist_jntPos[] = `xform -q -ws -t  $wrist_jnt[0]`;
	float $wrist_jntRot[] = `xform -q -ws -ro $wrist_jnt[0]`;				
				
	//switches to IK mode
	setAttr $userswitch 1;
				
	//matches to FK joint chain transforms
	xform -ws -t  $pvArm_locPos[0] $pvArm_locPos[1] $pvArm_locPos[2] $elbowIK_ctrl[0];
	xform -ws -t  $wrist_jntPos[0] $wrist_jntPos[1] $wrist_jntPos[2] $handIK_ctrl[0];
	xform -ws -ro $wrist_jntRot[0] $wrist_jntRot[1] $wrist_jntRot[2] $handIK_ctrl[0];
				
	//holds the new position
	setKeyframe ...
}

but as regards to the legs it’s not. This is driving me crazy.
The point is that as opposed to the wrist, footFK and footIK have a different initial world rotation values
because of need to lift up the boot precisely towards world Y axis (up) in IK mode.

This cause “broken leg” effect during FK to IK match:

All over the Internet there is information only about arms matching but there are no examples for legs.
Is anybody has an idea about the solution of that?