author Benjy Cook Thu, 11 Aug 2011 13:47:49 +0000 (13:47 +0000) committer Benjy Cook Thu, 11 Aug 2011 13:47:49 +0000 (13:47 +0000)

index 9415553d4ff4062f7238b2d11259754619ac4acf..88a5c3a620a297720d8ce0b52dff6526acb8bd28 100644 (file)
@@ -21,6 +21,7 @@
import bpy
from mathutils import *
+from bl_operators import nla
import cProfile

@@ -264,6 +265,7 @@ def copyTranslation(performer_obj, enduser_obj, perfFeet, root, s_frame, e_frame
v = locDeriv[key][i]
hipV = locDeriv[perfRoot][i]
endV = locDeriv[perf_bones[key].bone.map][i]
+            print(v.length,)
if (v.length < 0.1):
#this is a plant frame.
#lets see what the original hip delta is, and the corresponding
@@ -284,6 +286,7 @@ def copyTranslation(performer_obj, enduser_obj, perfFeet, root, s_frame, e_frame
stride_bone.name = "stride_bone"
print(stride_bone)
stride_bone.location = Vector((0, 0, 0))
+    print(linearAvg)
if linearAvg:
#determine the average change in scale needed
avg = sum(linearAvg) / len(linearAvg)
@@ -295,6 +298,8 @@ def copyTranslation(performer_obj, enduser_obj, perfFeet, root, s_frame, e_frame
newTranslation = (tailLoc(perf_bones[perfRoot]) / avg)
stride_bone.location = enduser_obj_mat * (newTranslation - initialPos)
stride_bone.keyframe_insert("location")
+    else:
+        stride_bone.keyframe_insert("location")
stride_bone.animation_data.action.name = ("Stride Bone " + action_name)

return stride_bone
@@ -439,10 +444,66 @@ def NLASystemInitialize(enduser_arm, context):#enduser_obj, name):
anim_data.action = None

+    createDictionary(performer_obj.data, enduser_obj.data)
+    bones = enduser_obj.pose.bones
+    map_bones = [bone for bone in bones if bone.bone.reverseMap]
+    for bone in map_bones:
+        perf_bone = bone.bone.reverseMap[0].name
+        if bone.bone.use_connect or not bone.constraints:
+            locks = bone.lock_location
+            if not (locks[0] or locks[1] or locks[2]):
+                cons = bone.constraints.new('COPY_LOCATION')
+                cons.name = "retargetTemp"
+                cons.use_x = not locks[0]
+                cons.use_y = not locks[1]
+                cons.use_z = not locks[2]
+                cons.target = performer_obj
+                cons.subtarget = perf_bone
+
+
+        cons2 = bone.constraints.new('COPY_ROTATION')
+        cons2.name = "retargetTemp"
+        locks = bone.lock_rotation
+        cons2.use_x = not locks[0]
+        cons2.use_y = not locks[1]
+        cons2.use_z = not locks[2]
+        cons2.target = performer_obj
+        cons2.subtarget = perf_bone
+
+            for constraint in bone.constraints:
+                if constraint.type == 'COPY_ROTATION':
+                    constraint.target_space = 'LOCAL'
+                    constraint.owner_space = 'LOCAL_WITH_PARENT'
+
+
+def prepareForBake(enduser_obj):
+    bones = enduser_obj.pose.bones
+    for bone in bones:
+        bone.bone.select = False
+    map_bones = [bone for bone in bones if bone.bone.reverseMap]
+    for bone in map_bones:
+        for cons in bone.constraints:
+            if "retargetTemp" in cons.name:
+                bone.bone.select = True
+
+def cleanTempConstraints(enduser_obj):
+    bones = enduser_obj.pose.bones
+    map_bones = [bone for bone in bones if bone.bone.reverseMap]
+    for bone in map_bones:
+        for cons in bone.constraints:
+            if "retargetTemp" in cons.name:
+                bone.constraints.remove(cons)
+
#Main function that runs the retargeting sequence.
def totalRetarget(performer_obj, enduser_obj, scene, s_frame, e_frame):
perf_arm = performer_obj.data
end_arm = enduser_obj.data

try:
enduser_obj.animation_data.action = bpy.data.actions.new("temp")
@@ -450,27 +511,33 @@ def totalRetarget(performer_obj, enduser_obj, scene, s_frame, e_frame):
except:
print("no need to create new action")

-
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 (for first pass)")
-    inter_obj = createIntermediate(performer_obj, enduser_obj, root, s_frame, e_frame, scene)
-    print("First pass: retargeting from intermediate to end user")
-
-
-    retargetEnduser(inter_obj, enduser_obj, root, s_frame, e_frame, scene)
+        turnOffIK(enduser_obj)
+        print("Creating intermediate armature (for first pass)")
+        inter_obj = createIntermediate(performer_obj, enduser_obj, root, s_frame, e_frame, scene)
+        print("First pass: retargeting from intermediate to end user")
+        retargetEnduser(inter_obj, enduser_obj, root, s_frame, e_frame, scene)
+    else:
+        prepareForBake(enduser_obj)
+        nla.bake(s_frame, e_frame, action=enduser_obj.animation_data.action, only_selected=True, do_pose=True, do_object=False)
name = performer_obj.animation_data.action.name
enduser_obj.animation_data.action.name = "Base " + name
print("Second pass: 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)
+        IKRetarget(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')
-    bpy.ops.object.select_name(name=inter_obj.name, extend=False)
-    bpy.ops.object.delete()
+        bpy.ops.object.select_name(name=inter_obj.name, extend=False)
+        bpy.ops.object.delete()
+    else:
+        cleanTempConstraints(enduser_obj)
bpy.ops.object.select_name(name=enduser_obj.name, extend=False)

if not name in [tracks.name for tracks in end_arm.mocapNLATracks]:
@@ -140,9 +140,26 @@ class MocapNLATracks(bpy.types.PropertyGroup):

bpy.utils.register_class(MocapNLATracks)

+
+    enduser_obj = context.active_object
+    performer_obj = [obj for obj in context.selected_objects if obj != enduser_obj]
+    if enduser_obj is None or len(performer_obj) != 1:
+        print("Need active and selected armatures")
+        return
+    else:
+        performer_obj = performer_obj[0]
+    else:
+        retarget.cleanTempConstraints(enduser_obj)
+
+
+
bpy.types.Armature.stitch_settings = bpy.props.PointerProperty(type=AnimationStitchSettings)
bpy.types.Armature.active_mocap =  bpy.props.StringProperty(update=retarget.NLASystemInitialize)
bpy.types.Armature.mocapNLATracks = bpy.props.CollectionProperty(type=MocapNLATracks)

#Update function for IK functionality. Is called when IK prop checkboxes are toggled.

@@ -189,7 +206,7 @@ def toggleIKBone(self, context):
for bone in cnstrn_bone.parent_recursive:
if not bone.is_in_ik_chain:
bone.IKRetarget = False
-
+

class MocapMapping(bpy.types.PropertyGroup):
name = bpy.props.StringProperty()
@@ -281,6 +298,7 @@ class MocapPanel(bpy.types.Panel):
mapRow.operator("mocap.savemapping", text='Save mapping')
self.layout.prop(data=performer_obj.animation_data.action, property='name', text='Action Name')
self.layout.operator("mocap.retarget", text='RETARGET!')

@@ -396,6 +414,35 @@ class OBJECT_OT_RetargetButton(bpy.types.Operator):
return activeIsArmature and isinstance(performer_obj[0].data, bpy.types.Armature)
else:
return False
+
+
+        #~ '''Prepare for advanced retargeting '''
+        #~ bl_idname = "mocap.preretarget"
+        #~ bl_label = "Prepares retarget of active action from Performer to Enduser"
+
+        #~ def execute(self, context):
+            #~ scene = context.scene
+            #~ s_frame = scene.frame_start
+            #~ e_frame = scene.frame_end
+            #~ enduser_obj = context.active_object
+            #~ performer_obj = [obj for obj in context.selected_objects if obj != enduser_obj]
+            #~ if enduser_obj is None or len(performer_obj) != 1:
+                #~ print("Need active and selected armatures")
+            #~ else:
+                #~ performer_obj = performer_obj[0]
+            #~ 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_SaveMappingButton(bpy.types.Operator):
@@ -715,7 +762,7 @@ class OBJECT_OT_AnimationStitchingButton(bpy.types.Operator):
stitch_settings = context.active_object.data.stitch_settings
return (stitch_settings.first_action and stitch_settings.second_action)
return False
-
+

def register():
bpy.utils.register_module(__name__)