Maya based FK to IK matching script issue

128 views Asked by At

It's been a while since I last asked a question here, however, I've once again come back to these forums with an issue regarding code with DCC software math logic.

I will post my code below, however, due to the nature of rigging-related issues being highly dependent on what my setup is, I thought I'd give context and be specific. I'm not looking necessarily for an actual code correction, but more along the lines of what I might be doing wrong.

So I have a rig, that contains an FK chain (made of FK joints) and an IK chain (made of IK joints). The FK joints use FK controllers with parent constraints and the IK chain joints use an IK solver (single-chain) with a single controller constraining the handle. So pretty simple setup. However, I have one thing: a single-hand controller. The hand controller moves the IKHandle in IK mode, and in FK mode, acts as an FK controller.

To give more context, I am only currently interested in the matching from FK -> IK (so mapping FK control matrices to IK joint matrices while in my FK mode.) by calculating rotation offsets. Not IK to FK. Feel free to point out if that in itself would be causing the issue, however, I highly doubt it as currently, my script whenever its run, gets all the current FK and IK information and performs the match.

My issue is this: I am getting strange behaviour/ unexpected results when matching. I wondered if it might be something to do with the single-hand control setup.

Furthermore, When I'm in IK mode, and I move my hand control, that then moves the IK chain and switch to FK mode:

The FK joints are obviously still in their original position (before matching) however, the hand ctrl has moved to the new position. However, when in FK mode, and having switched to IK and moved my hand ctrl, thus moving the IK chain and then switch back to FK mode, the strange offset does not occur anymore. The hand snaps between IK position and FK position. (The same hand ctrl).

Apologies for the long-winded context. Anyway regarding the code:

def computeRotationalOffset(fk_joint, fk_ctrl, ik_joint, hand_ctrl):

"""

Args:
    fk_joint(MDagPath): Our FK joint.
    fk_ctrl(MDagPath): Our FK control.
    ik_joint(MDagPath): Our IK joint.

Returns:

"""

fk_jnt_mat = getWorldMatrix(fk_joint)

fk_ctrl_mat = getWorldMatrix(fk_ctrl)

ik_joint_mat = getWorldMatrix(ik_joint)

constraint_matrix = fk_jnt_mat * fk_ctrl_mat.inverse()

target_rot_ctrl = om.MTransformationMatrix(
    constraint_matrix.inverse() * ik_joint_mat,
)

mQuaternion = target_rot_ctrl.rotation(asQuaternion=True)

eulerRot = mQuaternion.asEulerRotation()

return [math.degrees(angle)
        for angle in (eulerRot.x, eulerRot.y, eulerRot.z)
        ]

The above code gets called three times to work out the rotation offset for each FK ctrl. Its arguments are the FK ctrl DAGPath, FK jnt DAGPath and the IK joint DAGPath. We gets its world matrix and do the above.

So yeah. That's basically it. Any solutions to my problem would be greatly appreciated:

Some of the stuff I've tried so far:

  1. Take the hand ctrl position in IK mode, switch to FK, take its position now and then perform above calculation but instead using new position as target

  2. Thought about potentially storing the translation offset of the hand ctrl when in FK mode (as FK only deals with rotation).

Thanks!

0

There are 0 answers