Changed creation of original location targets to be created only if needed for IK (i.e. user's decision)

This commit is contained in:
2011-07-06 14:19:54 +00:00
parent 120e5a3417
commit 2367220108

View File

@@ -33,12 +33,12 @@ from math import radians, acos
# be created from a more comfortable UI in the future # be created from a more comfortable UI in the future
def createDictionary(perf_arm,end_arm): def createDictionary(perf_arm, end_arm):
bonemap = {} bonemap = {}
#Bonemap: performer to enduser #Bonemap: performer to enduser
for bone in perf_arm.bones: for bone in perf_arm.bones:
bonemap[bone.name] = bone.map bonemap[bone.name] = bone.map
# creation of a reverse map # creation of a reverse map
# multiple keys get mapped to list values # multiple keys get mapped to list values
#Bonemapr: enduser to performer #Bonemapr: enduser to performer
@@ -74,22 +74,6 @@ def createIntermediate(performer_obj, enduser_obj, bonemap, bonemapr, root, s_fr
#the original position of the tail bone #the original position of the tail bone
#useful for storing the important data in the original motion #useful for storing the important data in the original motion
#i.e. using this empty to IK the chain to that pos / DEBUG #i.e. using this empty to IK the chain to that pos / DEBUG
def locOfOriginal(inter_bone, perf_bone):
if not inter_bone.name + "Org" in bpy.data.objects:
bpy.ops.object.add()
empty = bpy.context.active_object
empty.name = inter_bone.name + "Org"
empty.empty_draw_size = 0.1
#empty.parent = enduser_obj
empty = bpy.data.objects[inter_bone.name + "Org"]
offset = perf_bone.vector
if inter_bone.length == 0 or perf_bone.length == 0:
scaling = 1
else:
scaling = perf_bone.length / inter_bone.length
offset /= scaling
empty.location = inter_bone.head + offset
empty.keyframe_insert("location")
#Simple 1to1 retarget of a bone #Simple 1to1 retarget of a bone
def singleBoneRetarget(inter_bone, perf_bone): def singleBoneRetarget(inter_bone, perf_bone):
@@ -116,21 +100,17 @@ def createIntermediate(performer_obj, enduser_obj, bonemap, bonemapr, root, s_fr
perf_bone_name = bonemapr[inter_bone.name] perf_bone_name = bonemapr[inter_bone.name]
#is it a 1 to many? #is it a 1 to many?
if isinstance(bonemap[perf_bone_name[0]], tuple): if isinstance(bonemap[perf_bone_name[0]], tuple):
perf_bone = performer_bones[perf_bone_name[0]] pass
if inter_bone.name == bonemap[perf_bone_name[0]][0]: # 1 to many not supported yet
locOfOriginal(inter_bone, perf_bone)
else: else:
# then its either a many to 1 or 1 to 1 # then its either a many to 1 or 1 to 1
if len(perf_bone_name) > 1: if len(perf_bone_name) > 1:
performer_bones_s = [performer_bones[name] for name in perf_bone_name] performer_bones_s = [performer_bones[name] for name in perf_bone_name]
#we need to map several performance bone to a single #we need to map several performance bone to a single
for perf_bone in performer_bones_s:
locOfOriginal(inter_bone, perf_bone)
inter_bone.matrix_basis = manyPerfToSingleInterRetarget(inter_bone, performer_bones_s) inter_bone.matrix_basis = manyPerfToSingleInterRetarget(inter_bone, performer_bones_s)
else: else:
perf_bone = performer_bones[perf_bone_name[0]] perf_bone = performer_bones[perf_bone_name[0]]
locOfOriginal(inter_bone, perf_bone)
inter_bone.matrix_basis = singleBoneRetarget(inter_bone, perf_bone) inter_bone.matrix_basis = singleBoneRetarget(inter_bone, perf_bone)
inter_bone.keyframe_insert("rotation_quaternion") inter_bone.keyframe_insert("rotation_quaternion")
@@ -214,15 +194,14 @@ def retargetEnduser(inter_obj, enduser_obj, root, s_frame, e_frame, scene):
def copyTranslation(performer_obj, enduser_obj, perfFeet, bonemap, bonemapr, root, s_frame, e_frame, scene, enduser_obj_mat): def copyTranslation(performer_obj, enduser_obj, perfFeet, bonemap, bonemapr, root, s_frame, e_frame, scene, enduser_obj_mat):
perf_bones = performer_obj.pose.bones perf_bones = performer_obj.pose.bones
end_bones = enduser_obj.pose.bones end_bones = enduser_obj.pose.bones
perfRoot = bonemapr[root][0] perfRoot = bonemapr[root][0]
endFeet = [bonemap[perfBone] for perfBone in perfFeet] endFeet = [bonemap[perfBone] for perfBone in perfFeet]
locDictKeys = perfFeet + endFeet + [perfRoot] locDictKeys = perfFeet + endFeet + [perfRoot]
def tailLoc(bone): def tailLoc(bone):
return bone.center + (bone.vector / 2) return bone.center + (bone.vector / 2)
@@ -293,32 +272,34 @@ def IKRetarget(bonemap, bonemapr, performer_obj, enduser_obj, s_frame, e_frame,
end_bones = enduser_obj.pose.bones end_bones = enduser_obj.pose.bones
for pose_bone in end_bones: for pose_bone in end_bones:
if "IK" in [constraint.type for constraint in pose_bone.constraints]: if "IK" in [constraint.type for constraint in pose_bone.constraints]:
target_is_bone = False
# set constraint target to corresponding empty if targetless, # set constraint target to corresponding empty if targetless,
# if not, keyframe current target to corresponding empty # if not, keyframe current target to corresponding empty
perf_bone = bonemapr[pose_bone.name] perf_bone = bonemapr[pose_bone.name]
if isinstance(perf_bone, list): if isinstance(perf_bone, list):
perf_bone = bonemapr[pose_bone.name][-1] perf_bone = bonemapr[pose_bone.name][-1]
end_empty = bpy.data.objects[pose_bone.name + "Org"] orgLocTrg = originalLocationTarget(pose_bone)
ik_constraint = [constraint for constraint in pose_bone.constraints if constraint.type == "IK"][0] ik_constraint = [constraint for constraint in pose_bone.constraints if constraint.type == "IK"][0]
if not ik_constraint.target: if not ik_constraint.target:
ik_constraint.target = end_empty ik_constraint.target = orgLocTrg
target = orgLocTrg
# There is a target now
if ik_constraint.subtarget:
target = ik_constraint.target.pose.bones[ik_constraint.subtarget]
target.bone.use_local_location = False
target_is_bone = True
else: else:
#Bone target target = ik_constraint.target
target_is_bone = False
if ik_constraint.subtarget: for t in range(s_frame, e_frame):
target = ik_constraint.target.pose.bones[ik_constraint.subtarget] scene.frame_set(t)
target.bone.use_local_location = False if target_is_bone:
target_is_bone = True final_loc = pose_bone.tail - target.bone.matrix_local.to_translation()
else: else:
target = ik_constraint.target final_loc = pose_bone.tail
for t in range(s_frame, e_frame): target.location = final_loc
scene.frame_set(t) target.keyframe_insert("location")
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 ik_constraint.mute = False
@@ -358,6 +339,17 @@ def restoreObjMat(performer_obj, enduser_obj, perf_obj_mat, enduser_obj_mat, str
enduser_obj.parent = stride_bone enduser_obj.parent = stride_bone
def originalLocationTarget(end_bone):
if not end_bone.name + "Org" in bpy.data.objects:
bpy.ops.object.add()
empty = bpy.context.active_object
empty.name = end_bone.name + "Org"
empty.empty_draw_size = 0.1
#empty.parent = enduser_obj
empty = bpy.data.objects[end_bone.name + "Org"]
return empty
def totalRetarget(): def totalRetarget():
print("retargeting...") print("retargeting...")
enduser_obj = bpy.context.active_object enduser_obj = bpy.context.active_object
@@ -371,7 +363,7 @@ def totalRetarget():
scene = bpy.context.scene scene = bpy.context.scene
s_frame = scene.frame_start s_frame = scene.frame_start
e_frame = scene.frame_end e_frame = scene.frame_end
bonemap, bonemapr, feetBones, root = createDictionary(perf_arm,end_arm) bonemap, bonemapr, feetBones, root = createDictionary(perf_arm, end_arm)
perf_obj_mat, enduser_obj_mat = cleanAndStoreObjMat(performer_obj, enduser_obj) perf_obj_mat, enduser_obj_mat = cleanAndStoreObjMat(performer_obj, enduser_obj)
turnOffIK(enduser_obj) turnOffIK(enduser_obj)
inter_obj, inter_arm = createIntermediate(performer_obj, enduser_obj, bonemap, bonemapr, root, s_frame, e_frame, scene) inter_obj, inter_arm = createIntermediate(performer_obj, enduser_obj, bonemap, bonemapr, root, s_frame, e_frame, scene)