Cosmetic changes to UI. Also, added option to mark which bones should be planted...
authorBenjy Cook <benjycook@hotmail.com>
Wed, 6 Jul 2011 13:31:13 +0000 (13:31 +0000)
committerBenjy Cook <benjycook@hotmail.com>
Wed, 6 Jul 2011 13:31:13 +0000 (13:31 +0000)
release/scripts/modules/retarget.py
release/scripts/startup/ui_mocap.py

index b875b15e6e5b5cf1674fe6a44601ba07068c9ad1..dca3556f2c09e950f09aee7e7d19aff67e2812ee 100644 (file)
@@ -33,14 +33,15 @@ from math import radians, acos
 # be created from a more comfortable UI in the future
 
 
-def createDictionary(perf_arm):
+def createDictionary(perf_arm,end_arm):
     bonemap = {}
+    #Bonemap: performer to enduser
     for bone in perf_arm.bones:
         bonemap[bone.name] = bone.map
-    #root is the root of the enduser
-    root = "root"
+    
     # creation of a reverse map
     # multiple keys get mapped to list values
+    #Bonemapr: enduser to performer
     bonemapr = {}
     for key, value in bonemap.items():
         if not value in bonemapr:
@@ -51,7 +52,10 @@ def createDictionary(perf_arm):
                 bonemapr[bonemap[key]] = [key]
         else:
             bonemapr[bonemap[key]].append(key)
-    return bonemap, bonemapr, root
+    #root is the root of the enduser
+    root = end_arm.bones[0].name
+    feetBones = [bone.name for bone in perf_arm.bones if bone.foot]
+    return bonemap, bonemapr, feetBones, root
 # list of empties created to keep track of "original"
 # position data
 # in final product, these locations can be stored as custom props
@@ -210,12 +214,15 @@ 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):
-    endFeet = [bonemap[perfBone] for perfBone in perfFeet]
-    perfRoot = bonemapr[root][0]
-    locDictKeys = perfFeet + endFeet + [perfRoot]
+    
     perf_bones = performer_obj.pose.bones
     end_bones = enduser_obj.pose.bones
 
+    perfRoot = bonemapr[root][0]
+    endFeet = [bonemap[perfBone] for perfBone in perfFeet]
+    locDictKeys = perfFeet + endFeet + [perfRoot]
+    
+        
     def tailLoc(bone):
         return bone.center + (bone.vector / 2)
 
@@ -364,12 +371,12 @@ def totalRetarget():
     scene = bpy.context.scene
     s_frame = scene.frame_start
     e_frame = scene.frame_end
-    bonemap, bonemapr, root = createDictionary(perf_arm)
+    bonemap, bonemapr, feetBones, root = createDictionary(perf_arm,end_arm)
     perf_obj_mat, enduser_obj_mat = cleanAndStoreObjMat(performer_obj, enduser_obj)
     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)
-    stride_bone = copyTranslation(performer_obj, enduser_obj, ["RightFoot", "LeftFoot"], bonemap, bonemapr, root, s_frame, e_frame, scene, enduser_obj_mat)
+    stride_bone = copyTranslation(performer_obj, enduser_obj, feetBones, bonemap, bonemapr, root, s_frame, e_frame, scene, enduser_obj_mat)
     IKRetarget(bonemap, bonemapr, performer_obj, enduser_obj, s_frame, e_frame, scene)
     restoreObjMat(performer_obj, enduser_obj, perf_obj_mat, enduser_obj_mat, stride_bone)
     bpy.ops.object.mode_set(mode='OBJECT')
index e6c7529be990682f5e1dd052f27d049b1687ee32..737f3fcfa56ec922eb52d74edc10f94cb7dada24 100644 (file)
@@ -149,6 +149,9 @@ def toggleIKBone(self, context):
                     bone.IKRetarget = False
 
 bpy.types.Bone.map = bpy.props.StringProperty()
+bpy.types.Bone.foot = bpy.props.BoolProperty(name="Foot",
+    description="Marks this bone as a 'foot', which determines retargeted animation's translation",
+    default=False)
 bpy.types.PoseBone.IKRetarget = bpy.props.BoolProperty(name="IK",
     description="Toggles IK Retargeting method for given bone",
     update=toggleIKBone, default=False)
@@ -189,6 +192,7 @@ class MocapPanel(bpy.types.Panel):
         row.alignment = 'EXPAND'
         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')
         row2 = self.layout.row(align=True)
         row2.operator("mocap.looper", text='Loop animation')
         row2.operator("mocap.limitdof", text='Constrain Rig')
@@ -198,7 +202,6 @@ class MocapPanel(bpy.types.Panel):
         column1.label("Performer Rig")
         column2 = row3.column(align=True)
         column2.label("Enduser Rig")
-        self.layout.label("Hierarchy mapping")
         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:
@@ -212,6 +215,7 @@ class MocapPanel(bpy.types.Panel):
                     perf_pose_bones = enduser_obj.pose.bones
                     for bone in perf.bones:
                         row = self.layout.row()
+                        row.prop(data=bone, property='foot', text='', icon='POSE_DATA')
                         row.label(bone.name)
                         row.prop_search(bone, "map", enduser_arm, "bones")
                         label_mod = "FK"
@@ -222,7 +226,11 @@ class MocapPanel(bpy.types.Panel):
                             if hasIKConstraint(pose_bone):
                                 label_mod = "ik end"
                             row.prop(pose_bone, 'IKRetarget')
-                        row.label(label_mod)
+                            row.label(label_mod)
+                        else:
+                            row.label(" ")
+                            row.label(" ")
+                        
 
                     self.layout.operator("mocap.retarget", text='RETARGET!')
 
@@ -320,6 +328,17 @@ class OBJECT_OT_LimitDOFButton(bpy.types.Operator):
     def execute(self, context):
         return {"FINISHED"}
 
+class OBJECT_OT_RotateFixArmature(bpy.types.Operator):
+    bl_idname = "mocap.rotate_fix"
+    bl_label = "Rotates selected armature 90 degrees (fix for bvh import)"
+
+    def execute(self, context):
+        mocap_tools.rotate_fix_armature(context.active_object.data)
+        return {"FINISHED"}
+    
+    #def poll(self, context):
+      #  return context.active_object.data in bpy.data.armatures
+
 
 class OBJECT_OT_AddMocapConstraint(bpy.types.Operator):
     bl_idname = "mocap.addconstraint"