diff options
author | Benjy Cook <benjycook@hotmail.com> | 2011-06-09 16:30:24 +0400 |
---|---|---|
committer | Benjy Cook <benjycook@hotmail.com> | 2011-06-09 16:30:24 +0400 |
commit | e4500096a5a9650899966fee9fa86a190cf2af1f (patch) | |
tree | 64ae624b0684434d48e9067aa9f9d89bd5870259 /release | |
parent | b9abe6211f258c6f6f967ba2502f92cdc37867c9 (diff) |
retarget.py updated with function to complete the retarget to the end user, with inheritance and bone roll taken under account
Diffstat (limited to 'release')
-rw-r--r-- | release/scripts/modules/retarget.py | 66 |
1 files changed, 64 insertions, 2 deletions
diff --git a/release/scripts/modules/retarget.py b/release/scripts/modules/retarget.py index c7a482659ef..b081191d9a6 100644 --- a/release/scripts/modules/retarget.py +++ b/release/scripts/modules/retarget.py @@ -3,9 +3,18 @@ from mathutils import * from math import radians, acos performer_obj = bpy.data.objects["performer"] enduser_obj = bpy.data.objects["enduser"] +end_arm = bpy.data.armatures["enduser_arm"] scene = bpy.context.scene +#TODO: Only selected bones get retargeted. +# Selected Bones/chains get original pos empties, if ppl want IK instead of FK +# Some "magic" numbers - frame start and end, eulers of all orders instead of just quats keyframed + + + # dictionary of mapping +# this is currently manuall input'ed, but will +# be created from a more comfortable UI in the future bonemap = { "LeftFoot": ("DEF_Foot.L","DEF_Toes.L"), "LeftUpLeg": "DEF_Thigh.L", "Hips": "DEF_Hip", @@ -26,6 +35,7 @@ bonemap = { "LeftFoot": ("DEF_Foot.L","DEF_Toes.L"), "RightUpLeg": "DEF_Thigh.R", "RightLeg": "DEF_Shin.R", "LeftLeg": "DEF_Shin.L"} + # creation of a reverse map # multiple keys get mapped to list values bonemapr = {} @@ -42,9 +52,11 @@ for key in bonemap.keys(): # list of empties created to keep track of "original" # position data # in final product, these locations can be stored as custom props +# these help with constraining, etc. constraints = [] + #creation of intermediate armature # the intermediate armature has the hiearchy of the end user, # does not have rotation inheritence @@ -103,9 +115,12 @@ def createIntermediate(): if len(perf_bone_name) > 1: performer_bones_s = [performer_bones[name] for name in perf_bone_name] #we need to map several performance bone to a single + for perf_bone in performer_bones_s: + locOfOriginal(inter_bone,perf_bone) inter_bone.matrix_basis = manyPerfToSingleInterRetarget(inter_bone,performer_bones_s) else: perf_bone = performer_bones[perf_bone_name[0]] + locOfOriginal(inter_bone,perf_bone) inter_bone.matrix_basis = singleBoneRetarget(inter_bone,perf_bone) inter_bone.keyframe_insert("rotation_quaternion") @@ -121,6 +136,8 @@ def createIntermediate(): #resets roll bpy.ops.armature.calculate_roll(type='Z') bpy.ops.object.mode_set(mode="OBJECT") + inter_arm = bpy.data.armatures["enduser_arm.001"] + inter_arm.name = "inter_arm" performer_bones = performer_obj.pose.bones inter_bones = inter_obj.pose.bones @@ -132,5 +149,50 @@ def createIntermediate(): scene.frame_set(t) inter_bone = inter_bones["DEF_Hip"] retargetPerfToInter(inter_bone) - -createIntermediate()
\ No newline at end of file + + return inter_obj,inter_arm + +# this procedure copies the rotations over from the intermediate +# armature to the end user one. +# As the hierarchies are 1 to 1, this is a simple matter of +# copying the rotation, while keeping in mind bone roll, parenting, etc. +# TODO: Control Bones: If a certain bone is constrained in a way +# that its rotation is determined by another (a control bone) +# We should determine the right pos of the control bone. +# Scale: ? Should work but needs testing. +def retargetEnduser(): + inter_bones = inter_obj.pose.bones + end_bones = enduser_obj.pose.bones + + def bakeTransform(end_bone): + src_bone = inter_bones[end_bone.name] + trg_bone = end_bone + bake_matrix = src_bone.matrix + rest_matrix = trg_bone.bone.matrix_local + + if trg_bone.parent and trg_bone.bone.use_inherit_rotation: + parent_mat = src_bone.parent.matrix + parent_rest = trg_bone.parent.bone.matrix_local + parent_rest_inv = parent_rest.copy() + parent_rest_inv.invert() + parent_mat_inv = parent_mat.copy() + parent_mat_inv.invert() + bake_matrix = parent_mat_inv * bake_matrix + rest_matrix = parent_rest_inv * rest_matrix + + rest_matrix_inv = rest_matrix.copy() + rest_matrix_inv.invert() + bake_matrix = rest_matrix_inv * bake_matrix + trg_bone.matrix_basis = bake_matrix + end_bone.keyframe_insert("rotation_quaternion") + + for bone in end_bone.children: + bakeTransform(bone) + + for t in range(1,150): + scene.frame_set(t) + end_bone = end_bones["DEF_Hip"] + bakeTransform(end_bone) + +inter_obj, inter_arm = createIntermediate() +retargetEnduser()
\ No newline at end of file |