diff options
Diffstat (limited to 'release/scripts')
-rw-r--r-- | release/scripts/modules/retarget.py | 25 | ||||
-rw-r--r-- | release/scripts/startup/ui_mocap.py | 23 |
2 files changed, 37 insertions, 11 deletions
diff --git a/release/scripts/modules/retarget.py b/release/scripts/modules/retarget.py index b875b15e6e5..dca3556f2c0 100644 --- a/release/scripts/modules/retarget.py +++ b/release/scripts/modules/retarget.py @@ -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') diff --git a/release/scripts/startup/ui_mocap.py b/release/scripts/startup/ui_mocap.py index e6c7529be99..737f3fcfa56 100644 --- a/release/scripts/startup/ui_mocap.py +++ b/release/scripts/startup/ui_mocap.py @@ -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" |