IK FK setup - Bone position changes when dialing between Child Of constraints

I have kind of a faux IK/FK setup for the arms of a character.
I have two Child Of constraints for the hand IK control. One is a child of the chest, the other a child of the master for the character, and I have them inversely linked via a driver (Meaning when one Child Of constraint is 1, the other is 0, and vice versa).

The effect is this: When the IK control is influenced by the master, the control behaves as you’d expect an IK control to behave. However, when the IK control is influenced by the chest, it still retains the IK behavior, but also moves parented to the chest like FK. Best of both worlds.

Demo:

As you can see, the problem happens when I’m dialing the influence from one constraint to the other. Namely, the control shifts if the chest control has been altered.

Here’s my question: What can I do to make the end position the same?
One thing I tried is trying to copy visual location/rotation using the “Copy Attributes” addon, but I ran into a problem with that as well. [Link]

Blend file attached. Any help is much appreciated!

Attachments

IKparentChange.blend (5.82 MB)

1 Like

Bumping this as I’d like to figure this out ASAP. Any solutions (or even guesses) would be appreciated. Either for this, or the method I’m trying but failing with. Thanks!

Bumping this one more time. Really hoping someone in the Blender community can help.

Bear in mind, I’m not saying the position should be the same when I dial the influence, but I’d like to be able to match one position to the other.

The closest latest solution I have is by an extraction/modification of code from the Dynamic Parent addon. The following is what I have:

import bpy
import mathutils


def dp_keyframe_insert_pbone(arm, pbone):
    arm.keyframe_insert(data_path='pose.bones["'+pbone.name+'"].location')
    if pbone.rotation_mode == 'QUATERNION':
        arm.keyframe_insert(data_path='pose.bones["'+pbone.name+'"].rotation_quaternion')
    elif pbone.rotation_mode == 'AXIS_ANGLE':
        arm.keyframe_insert(data_path='pose.bones["'+pbone.name+'"].rotation_axis_angel')
    else:
        arm.keyframe_insert(data_path='pose.bones["'+pbone.name+'"].rotation_euler')
    arm.keyframe_insert(data_path='pose.bones["'+pbone.name+'"].scale') 
    
arm = bpy.context.active_object
pbone = bpy.context.active_pose_bone
scn = bpy.context.scene


current_frame = scn.frame_current
scn.frame_current = current_frame - 1
pbone.constraints["Torso"].influence = 1
arm.keyframe_insert(data_path='pose.bones["'+pbone.name+'"].constraints["Torso"].influence')
        
scn.frame_current = current_frame
pbone.constraints["Torso"].influence = 0
arm.keyframe_insert(data_path='pose.bones["'+pbone.name+'"].constraints["Torso"].influence')
        
final_matrix = pbone.matrix
        
current_frame = scn.frame_current
scn.frame_current = current_frame - 1
dp_keyframe_insert_pbone(arm, pbone)
        
scn.frame_current = current_frame
pbone.matrix = final_matrix
dp_keyframe_insert_pbone(arm, pbone)

But it only works when the “Torso” Child Of constraint is at the influence of “1”; it doesn’t work when I run the script with the influence at “0” (And changing the first “pbone.constraints[“Torso”].influence =” to 0, and second to 1).

I’m guessing scripting is going to have to end up being the solution, but not sure how to make this work.

That looks like expected behavior to me. When you switch constraints on/off, the bones will revert to positions minus the constraints.

What you are asking to do needs some python scripting. On a switchable IK/FK rig, this would be called IK/FK snapping. It’s not a trivial undertaking. Look at the rigify.ui.py script for some insight on how to do this. (It’s above my current skill level.)

A work around without scripting, is to always do a single frame switch on the animation. You’ll need to manually pose the armature so controls and character are in roughly the same pose before and after the switching. Animating most properties is best done with this one frame switch method.

I have a couple tutorials on rigging and animating weapons with parent switches on my youtube channel that explains this process.

Good luck!

Hey, DanPro, appreciate the response! Yeah, it is expected behavior. I wanted to see if anybody knows a way to somehow match end positions given that the positions change when dialing the Child Of constraints. Because, as you said, the only work around is to manually match the positions and keyframe one frame apart, but this gets tedious when you inevitably revise animations. =/