Added IK functionality to retargeting. If rig contains an IK constraint, in addition to FK retarget it will place and keyframe the IK targets correctly

This commit is contained in:
2011-06-26 19:54:29 +00:00
parent 87f242fab0
commit 17da597cc8
2 changed files with 70 additions and 15 deletions

View File

@@ -269,13 +269,6 @@ def copyTranslation(performer_obj, enduser_obj, perfFeet, bonemap, bonemapr, roo
bpy.ops.object.add()
stride_bone = bpy.context.active_object
stride_bone.name = "stride_bone"
bpy.ops.object.select_name(name=stride_bone.name, extend=False)
bpy.ops.object.select_name(name=enduser_obj.name, extend=True)
bpy.ops.object.mode_set(mode='POSE')
bpy.ops.pose.select_all(action='DESELECT')
root_bone = end_bones[root]
root_bone.bone.select = True
bpy.ops.pose.constraint_add_with_targets(type='CHILD_OF')
for t in range(s_frame, e_frame):
scene.frame_set(t)
newTranslation = (tailLoc(perf_bones[perfRoot]) / avg)
@@ -283,7 +276,57 @@ def copyTranslation(performer_obj, enduser_obj, perfFeet, bonemap, bonemapr, roo
stride_bone.keyframe_insert("location")
def IKRetarget(bonemap, bonemapr, performer_obj, enduser_obj, s_frame, e_frame, scene):
end_bones = enduser_obj.pose.bones
for pose_bone in end_bones:
if "IK" in [constraint.type for constraint in pose_bone.constraints]:
# set constraint target to corresponding empty if targetless,
# if not, keyframe current target to corresponding empty
perf_bone = bonemapr[pose_bone.name]
if isinstance(perf_bone, list):
perf_bone = bonemapr[pose_bone.name][-1]
end_empty = bpy.data.objects[perf_bone + "Org"]
ik_constraint = [constraint for constraint in pose_bone.constraints if constraint.type == "IK"][0]
if not ik_constraint.target:
ik_constraint.target = end_empty
else:
#Bone target
target_is_bone = False
if ik_constraint.subtarget:
target = ik_constraint.target.pose.bones[ik_constraint.subtarget]
target.bone.use_local_location = False
target_is_bone = True
else:
target = ik_constraint.target
for t in range(s_frame, e_frame):
scene.frame_set(t)
if target_is_bone:
final_loc = end_empty.location - target.bone.matrix_local.to_translation()
else:
final_loc = end_empty.location
target.location = final_loc
target.keyframe_insert("location")
ik_constraint.mute = False
def turnOffIK(enduser_obj):
end_bones = enduser_obj.pose.bones
for pose_bone in end_bones:
if pose_bone.is_in_ik_chain:
pass
# TODO:
# set stiffness according to place on chain
# and values from analysis that is stored in the bone
#pose_bone.ik_stiffness_x = 0.5
#pose_bone.ik_stiffness_y = 0.5
#pose_bone.ik_stiffness_z = 0.5
if "IK" in [constraint.type for constraint in pose_bone.constraints]:
ik_constraint = [constraint for constraint in pose_bone.constraints if constraint.type == "IK"][0]
ik_constraint.mute = True
def totalRetarget():
print("retargeting...")
enduser_obj = bpy.context.active_object
performer_obj = [obj for obj in bpy.context.selected_objects if obj != enduser_obj]
if enduser_obj is None or len(performer_obj) != 1:
@@ -296,9 +339,11 @@ def totalRetarget():
s_frame = scene.frame_start
e_frame = scene.frame_end
bonemap, bonemapr, root = createDictionary(perf_arm)
turnOffIK(enduser_obj)
inter_obj, inter_arm = createIntermediate(performer_obj, enduser_obj, bonemap, bonemapr, root, s_frame, e_frame, scene)
retargetEnduser(inter_obj, enduser_obj, root, s_frame, e_frame, scene)
copyTranslation(performer_obj, enduser_obj, ["RightFoot", "LeftFoot"], bonemap, bonemapr, root, s_frame, e_frame, scene)
IKRetarget(bonemap, bonemapr, performer_obj, enduser_obj, s_frame, e_frame, scene)
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.select_name(name=inter_obj.name, extend=False)
bpy.ops.object.delete()