I'm setting up IK FK matching for a rig - if I match the FK on top of the IK, it works fine because I'm just taking the rotation of the joints and applying it to the controllers. But if I match the IK on top of the FK it's always ever so slightly off - just enough to see the pop, enough that it's not good enough to use in production.
I even completely rerigged all the legs just because of this, and the second time around it happens too. There is no popping when switching IK/FK in a zero'd pose - they do line up appropriately. It only pops if I rotate the hip joint on anything but Z. Using ONLY Z works fine.
I'd prefer to avoid posting my scene file as it's for someone else, I could remove everything and just leave a leg in there or what not maybe, if it's necessary.
I want to stress that all rotation orders are the same and all joint chains are identical except for the unnoticeable rotations the IK gets from IK handles. The knee joint can ONLY rotate on one axis for all 3 chains. Also it's important to note that the pole vector controller is perfectly aligned to the ik handle plane.
I'll talk through what I've done so far.
1. I position a locator directly onto the leg's pole vector control and parent it under the FK hip.
2. I position a locator directly onto the FK ankle and parent it under the FK ankle.
3. I xform to get the transforms of the pole vector locator
4. Since the pole vector is point constrained to the foot, I get the translation values of the group node above the pole vector that actually contains the constraint.
5. I subtract the values from #4 from #3 (the xform)
6. I apply the result to the pole vector and it snaps perfectly on top of the locator
7. I xform the position of the ankle locator and move the leg IK controller on top of it
I'll post my code too if it helps, I've made it so it looks at what leg switch (the controller that switches between IK FK) you have selected, as well as whether it's in FK or IK, and automatically decides what action to take.
This is a four legged creature, hence the naming L_F_ or R_B_ (for left front or right back).
import maya.cmds as cmds ''' This script will match IK to FK and FK to IK for the Predator Creature If you are in IK, it will match the IK to the FK and vice versa. HOW TO USE: Select the x_x_legSwitch_CTRL and run the script, it identifies with which switch control is selected to determine the leg to match. by Jared Taylor ''' try: if cmds.ls(sl = True) == '': cmds.error('Nothing Selected!') if cmds.ls(sl = True) == 'L_F_legSwitch_CTRL': leg = 'L_F_' elif cmds.ls(sl = True) == 'L_B_legSwitch_CTRL': leg = 'L_B_' elif cmds.ls(sl = True) == 'R_F_legSwitch_CTRL': leg = 'R_F_' elif cmds.ls(sl = True) == 'R_B_legSwitch_CTRL': leg = 'R_B_' else: cmds.error("-----Wrong Selection! - Please select a leg switch control object!") except IndexError: cmds.error("-----Wrong Selection! - Please select a leg switch control object!") switch = cmds.ls(sl = True) #match IK onto the FK if cmds.getAttr(switch + '.ikFkSwitch') == 1: #match elbow polevector aimTrans = cmds.xform(leg + 'dummyAim_LOC', t = True, ws = True, q = True) #subtract point constraint on PV movements subX = cmds.getAttr(leg + 'kneeIK_CTRL_GRP.translateX') subY = cmds.getAttr(leg + 'kneeIK_CTRL_GRP.translateY') subZ = cmds.getAttr(leg + 'kneeIK_CTRL_GRP.translateZ') tranX = aimTrans - subX tranY = aimTrans - subY tranZ = aimTrans - subZ cmds.setAttr(leg + 'kneeIK_CTRL.translateX', tranX) cmds.setAttr(leg + 'kneeIK_CTRL.translateY', tranY) cmds.setAttr(leg + 'kneeIK_CTRL.translateZ', tranZ) #match arm IK control dummyTrans = cmds.xform(leg + 'dummy_LOC', t = True, ws = True, q = True) cmds.setAttr(leg + 'footIK_CTRL.translateX', dummyTrans) cmds.setAttr(leg + 'footIK_CTRL.translateY', dummyTrans) cmds.setAttr(leg + 'footIK_CTRL.translateZ', dummyTrans) #match FK onto the IK if cmds.getAttr(switch + '.ikFkSwitch') == 0: #get rotation of IK joints hipRX = cmds.getAttr(leg + 'hip_IK.rotateX') hipRY = cmds.getAttr(leg + 'hip_IK.rotateY') hipRZ = cmds.getAttr(leg + 'hip_IK.rotateZ') kneeRZ = cmds.getAttr(leg + 'knee_IK.rotateZ') cmds.setAttr(leg + 'hipFK_CTRL.rotateX', hipRX) cmds.setAttr(leg + 'hipFK_CTRL.rotateY', hipRY) cmds.setAttr(leg + 'hipFK_CTRL.rotateZ', hipRZ) cmds.setAttr(leg + 'kneeFK_CTRL.rotateZ', kneeRZ)