Bugfixing for retargeting - unconnected bones now retarget alot better. Also some placeholder code for a fix scale operator

This commit is contained in:
Benjy Cook 2011-07-18 18:44:54 +00:00
parent a6e2fba994
commit 0dcc7d05ab
3 changed files with 51 additions and 4 deletions

@ -567,3 +567,13 @@ def rotate_fix_armature(arm_data):
for bone in connectedBones: for bone in connectedBones:
arm_data.edit_bones[bone].use_connect = True arm_data.edit_bones[bone].use_connect = True
bpy.ops.object.mode_set(mode='OBJECT', toggle=False) bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
def scale_fix_armature(performer_obj, enduser_obj):
perf_bones = performer_obj.data.bones
end_bones = enduser_obj.data.bones
#perf_avg = performer_obj.dimensions
#end_avg = enduser_obj.dimensions
#print(perf_avg, end_avg)
#performer_obj.scale /= (perf_avg / end_avg)

@ -105,7 +105,12 @@ def createIntermediate(performer_obj, enduser_obj, root, s_frame, e_frame, scene
else: else:
perf_bone = performer_bones[perf_bone_name[0].name] perf_bone = performer_bones[perf_bone_name[0].name]
inter_bone.matrix_basis = singleBoneRetarget(inter_bone, perf_bone) inter_bone.matrix_basis = singleBoneRetarget(inter_bone, perf_bone)
elif inter_bone.parent:
if "Temp" in inter_bone.parent.name:
inter_bone.parent.bone.use_inherit_rotation = True
inter_bone.bone.use_inherit_rotation = True
else:
inter_bone.bone.use_inherit_rotation = True
inter_bone.keyframe_insert("rotation_quaternion") inter_bone.keyframe_insert("rotation_quaternion")
for child in inter_bone.children: for child in inter_bone.children:
retargetPerfToInter(child) retargetPerfToInter(child)
@ -119,12 +124,14 @@ def createIntermediate(performer_obj, enduser_obj, root, s_frame, e_frame, scene
bpy.ops.object.mode_set(mode='EDIT') bpy.ops.object.mode_set(mode='EDIT')
#add some temporary connecting bones in case end user bones are not connected to their parents #add some temporary connecting bones in case end user bones are not connected to their parents
for bone in inter_obj.data.edit_bones: for bone in inter_obj.data.edit_bones:
if not bone.use_connect and bone.parent: if not bone.use_connect and bone.parent and inter_obj.data.bones[bone.name].reverseMap:
newBone = inter_obj.data.edit_bones.new("Temp") newBone = inter_obj.data.edit_bones.new("Temp")
newBone.head = bone.parent.head newBone.head = bone.parent.tail
newBone.tail = bone.head newBone.tail = bone.head
newBone.parent = bone.parent newBone.parent = bone.parent
bone.parent = newBone bone.parent = newBone
bone.use_connect = True
newBone.use_connect = True
#resets roll #resets roll
bpy.ops.armature.calculate_roll(type='Z') bpy.ops.armature.calculate_roll(type='Z')
bpy.ops.object.mode_set(mode="OBJECT") bpy.ops.object.mode_set(mode="OBJECT")
@ -165,7 +172,7 @@ def retargetEnduser(inter_obj, enduser_obj, root, s_frame, e_frame, scene):
if trg_bone.parent and trg_bone.bone.use_inherit_rotation: if trg_bone.parent and trg_bone.bone.use_inherit_rotation:
srcParent = src_bone.parent srcParent = src_bone.parent
if not trg_bone.bone.use_connect: if "Temp" in srcParent.name:
srcParent = srcParent.parent srcParent = srcParent.parent
parent_mat = srcParent.matrix parent_mat = srcParent.matrix
parent_rest = trg_bone.parent.bone.matrix_local parent_rest = trg_bone.parent.bone.matrix_local
@ -187,6 +194,8 @@ def retargetEnduser(inter_obj, enduser_obj, root, s_frame, e_frame, scene):
end_bone.keyframe_insert("rotation_axis_angle") end_bone.keyframe_insert("rotation_axis_angle")
else: else:
end_bone.keyframe_insert("rotation_euler") end_bone.keyframe_insert("rotation_euler")
if not end_bone.bone.use_connect:
end_bone.keyframe_insert("location")
for bone in end_bone.children: for bone in end_bone.children:
bakeTransform(bone) bakeTransform(bone)
@ -384,11 +393,16 @@ def NLASystemInitialize(enduser_obj, s_frame):
def totalRetarget(performer_obj, enduser_obj, scene, s_frame, e_frame): def totalRetarget(performer_obj, enduser_obj, scene, s_frame, e_frame):
perf_arm = performer_obj.data perf_arm = performer_obj.data
end_arm = enduser_obj.data end_arm = enduser_obj.data
print("creating Dictionary")
feetBones, root = createDictionary(perf_arm, end_arm) feetBones, root = createDictionary(perf_arm, end_arm)
print("cleaning stuff up")
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)
print("creating intermediate armature")
inter_obj = createIntermediate(performer_obj, enduser_obj, root, s_frame, e_frame, scene) inter_obj = createIntermediate(performer_obj, enduser_obj, root, s_frame, e_frame, scene)
print("retargeting from intermediate to end user")
retargetEnduser(inter_obj, enduser_obj, root, s_frame, e_frame, scene) retargetEnduser(inter_obj, enduser_obj, root, s_frame, e_frame, scene)
print("retargeting root translation and clean up")
stride_bone = copyTranslation(performer_obj, enduser_obj, feetBones, root, s_frame, e_frame, scene, enduser_obj_mat) stride_bone = copyTranslation(performer_obj, enduser_obj, feetBones, root, s_frame, e_frame, scene, enduser_obj_mat)
IKRetarget(performer_obj, enduser_obj, s_frame, e_frame, scene) IKRetarget(performer_obj, enduser_obj, s_frame, e_frame, scene)
restoreObjMat(performer_obj, enduser_obj, perf_obj_mat, enduser_obj_mat, stride_bone) restoreObjMat(performer_obj, enduser_obj, perf_obj_mat, enduser_obj_mat, stride_bone)
@ -396,6 +410,7 @@ def totalRetarget(performer_obj, enduser_obj, scene, s_frame, e_frame):
bpy.ops.object.select_name(name=inter_obj.name, extend=False) bpy.ops.object.select_name(name=inter_obj.name, extend=False)
bpy.ops.object.delete() bpy.ops.object.delete()
NLASystemInitialize(enduser_obj, s_frame) NLASystemInitialize(enduser_obj, s_frame)
print("retargeting done!")
if __name__ == "__main__": if __name__ == "__main__":

@ -191,6 +191,7 @@ class MocapPanel(bpy.types.Panel):
row.operator("mocap.samples", text='Samples to Beziers') row.operator("mocap.samples", text='Samples to Beziers')
row.operator("mocap.denoise", text='Clean noise') row.operator("mocap.denoise", text='Clean noise')
row.operator("mocap.rotate_fix", text='Fix BVH Axis Orientation') row.operator("mocap.rotate_fix", text='Fix BVH Axis Orientation')
row.operator("mocap.scale_fix", text='Auto scale Performer')
row2 = self.layout.row(align=True) row2 = self.layout.row(align=True)
row2.operator("mocap.looper", text='Loop animation') row2.operator("mocap.looper", text='Loop animation')
row2.operator("mocap.limitdof", text='Constrain Rig') row2.operator("mocap.limitdof", text='Constrain Rig')
@ -430,6 +431,27 @@ class OBJECT_OT_RotateFixArmature(bpy.types.Operator):
return isinstance(context.active_object.data, bpy.types.Armature) return isinstance(context.active_object.data, bpy.types.Armature)
class OBJECT_OT_ScaleFixArmature(bpy.types.Operator):
bl_idname = "mocap.scale_fix"
bl_label = "Scales performer armature to match target armature"
def execute(self, context):
enduser_obj = bpy.context.active_object
performer_obj = [obj for obj in bpy.context.selected_objects if obj != enduser_obj][0]
mocap_tools.scale_fix_armature(performer_obj, enduser_obj)
return {"FINISHED"}
@classmethod
def poll(cls, context):
if context.active_object:
activeIsArmature = isinstance(context.active_object.data, bpy.types.Armature)
performer_obj = [obj for obj in context.selected_objects if obj != context.active_object]
if performer_obj:
return activeIsArmature and isinstance(performer_obj[0].data, bpy.types.Armature)
else:
return False
class OBJECT_OT_AddMocapConstraint(bpy.types.Operator): class OBJECT_OT_AddMocapConstraint(bpy.types.Operator):
bl_idname = "mocap.addconstraint" bl_idname = "mocap.addconstraint"
bl_label = "Add constraint to target armature" bl_label = "Add constraint to target armature"