diff --git a/mocap/__init__.py b/mocap/__init__.py index 55d8bdb7443e06df114c4da43c6535c2a18e7f68..d26937bef8843a3948aa19148d3275025a02f312 100644 --- a/mocap/__init__.py +++ b/mocap/__init__.py @@ -53,11 +53,19 @@ else: from . import mocap_constraints from . import retarget from . import mocap_tools + # MocapConstraint class # Defines MocapConstraint datatype, used to add and configute mocap constraints # Attached to Armature data +def hasIKConstraint(pose_bone): + #utility function / predicate, returns True if given bone has IK constraint + ik = [constraint for constraint in pose_bone.constraints if constraint.type == "IK"] + if ik: + return ik[0] + else: + return False class MocapConstraint(bpy.types.PropertyGroup): name = StringProperty(name="Name", diff --git a/mocap/retarget.py b/mocap/retarget.py index f599120044d49f3584fffec71d3abd82c72b40fe..e7f4bc1170b86d8114bd4685162d1c1d464363fb 100644 --- a/mocap/retarget.py +++ b/mocap/retarget.py @@ -21,7 +21,7 @@ import bpy from mathutils import Vector, Matrix from math import radians -from bl_operators import nla +from bpy_extras.anim_utils import bake_action def hasIKConstraint(pose_bone): @@ -292,15 +292,15 @@ def copyTranslation(performer_obj, enduser_obj, perfFeet, root, s_frame, e_frame if linearAvg: #determine the average change in scale needed avg = sum(linearAvg) / len(linearAvg) - scene.frame_set(s_frame) - initialPos = (tailLoc(perf_bones[perfRoot]) / avg) - for t in range(s_frame, e_frame): - scene.frame_set(t) - #calculate the new position, by dividing by the found ratio between performer and enduser - newTranslation = (tailLoc(perf_bones[perfRoot]) / avg) - stride_bone.location = enduser_obj_mat * (newTranslation - initialPos) - stride_bone.keyframe_insert("location") else: + avg = 1 + scene.frame_set(s_frame) + initialPos = (tailLoc(perf_bones[perfRoot]) / avg) + for t in range(s_frame, e_frame): + scene.frame_set(t) + #calculate the new position, by dividing by the found ratio between performer and enduser + newTranslation = (tailLoc(perf_bones[perfRoot]) / avg) + stride_bone.location = enduser_obj_mat * (newTranslation - initialPos) stride_bone.keyframe_insert("location") stride_bone.animation_data.action.name = ("Stride Bone " + action_name) @@ -520,8 +520,9 @@ def totalRetarget(performer_obj, enduser_obj, scene, s_frame, e_frame): else: prepareForBake(enduser_obj) print("Retargeting pose (Advanced Retarget)") - nla.bake(s_frame, e_frame, action=enduser_obj.animation_data.action, only_selected=True, do_pose=True, do_object=False, step=step) - name = performer_obj.animation_data.action.name + bake_action(s_frame, e_frame, action=enduser_obj.animation_data.action, only_selected=True, do_pose=True, do_object=False, step=step) + name = performer_obj.animation_data.action.name[:10] + #We trim the name down to 10 chars because of Action Name length maximum 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)