Bugfixing for retargeting - unconnected bones now retarget alot better. Also some...
authorBenjy Cook <benjycook@hotmail.com>
Mon, 18 Jul 2011 18:44:54 +0000 (18:44 +0000)
committerBenjy Cook <benjycook@hotmail.com>
Mon, 18 Jul 2011 18:44:54 +0000 (18:44 +0000)
release/scripts/modules/mocap_tools.py
release/scripts/modules/retarget.py
release/scripts/startup/ui_mocap.py

index 33e9105201c7d8ba859ac94b35719df929bf0027..1ce76dfbe6f99646855bae0db087a4c52f940859 100644 (file)
@@ -567,3 +567,13 @@ def rotate_fix_armature(arm_data):
     for bone in connectedBones:
         arm_data.edit_bones[bone].use_connect = True
     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)
index 0b694453865ef0b87028e84f712885d493985502..e8c9f3e25aa80e72551be7e50ebdd74ff6108565 100644 (file)
@@ -105,7 +105,12 @@ def createIntermediate(performer_obj, enduser_obj, root, s_frame, e_frame, scene
             else:
                 perf_bone = performer_bones[perf_bone_name[0].name]
                 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")
         for child in inter_bone.children:
             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')
     #add some temporary connecting bones in case end user bones are not connected to their parents
     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.head = bone.parent.head
+            newBone.head = bone.parent.tail
             newBone.tail = bone.head
             newBone.parent = bone.parent
             bone.parent = newBone
+            bone.use_connect = True
+            newBone.use_connect = True
     #resets roll
     bpy.ops.armature.calculate_roll(type='Z')
     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:
             srcParent = src_bone.parent
-            if not trg_bone.bone.use_connect:
+            if "Temp" in srcParent.name:
                 srcParent = srcParent.parent
             parent_mat = srcParent.matrix
             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")
         else:
             end_bone.keyframe_insert("rotation_euler")
+        if not end_bone.bone.use_connect:
+            end_bone.keyframe_insert("location")
 
         for bone in end_bone.children:
             bakeTransform(bone)
@@ -384,11 +393,16 @@ def NLASystemInitialize(enduser_obj, s_frame):
 def totalRetarget(performer_obj, enduser_obj, scene, s_frame, e_frame):
     perf_arm = performer_obj.data
     end_arm = enduser_obj.data
+    print("creating Dictionary")
     feetBones, root = createDictionary(perf_arm, end_arm)
+    print("cleaning stuff up")
     perf_obj_mat, enduser_obj_mat = cleanAndStoreObjMat(performer_obj, enduser_obj)
     turnOffIK(enduser_obj)
+    print("creating intermediate armature")
     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)
+    print("retargeting root translation and clean up")
     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)
     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.delete()
     NLASystemInitialize(enduser_obj, s_frame)
+    print("retargeting done!")
 
 
 if __name__ == "__main__":
index 356de00e8eec2c9f2ca9b352e18824d4992f31f6..0e623f44d9a927b39b8eee64751c1c278fdb898e 100644 (file)
@@ -191,6 +191,7 @@ class MocapPanel(bpy.types.Panel):
         row.operator("mocap.samples", text='Samples to Beziers')
         row.operator("mocap.denoise", text='Clean noise')
         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.operator("mocap.looper", text='Loop animation')
         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)
 
 
+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):
     bl_idname = "mocap.addconstraint"
     bl_label = "Add constraint to target armature"