forked from bartvdbraak/blender
Bugfixing for retargeting - unconnected bones now retarget alot better. Also some placeholder code for a fix scale operator
This commit is contained in:
parent
a6e2fba994
commit
0dcc7d05ab
@ -567,3 +567,13 @@ def rotate_fix_armature(arm_data):
|
|||||||
for bone in connectedBones:
|
for bone in connectedBones:
|
||||||
arm_data.edit_bones[bone].use_connect = True
|
arm_data.edit_bones[bone].use_connect = True
|
||||||
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
|
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
|
||||||
|
|
||||||
|
|
||||||
|
def scale_fix_armature(performer_obj, enduser_obj):
|
||||||
|
perf_bones = performer_obj.data.bones
|
||||||
|
end_bones = enduser_obj.data.bones
|
||||||
|
|
||||||
|
#perf_avg = performer_obj.dimensions
|
||||||
|
#end_avg = enduser_obj.dimensions
|
||||||
|
#print(perf_avg, end_avg)
|
||||||
|
#performer_obj.scale /= (perf_avg / end_avg)
|
||||||
|
@ -105,7 +105,12 @@ def createIntermediate(performer_obj, enduser_obj, root, s_frame, e_frame, scene
|
|||||||
else:
|
else:
|
||||||
perf_bone = performer_bones[perf_bone_name[0].name]
|
perf_bone = performer_bones[perf_bone_name[0].name]
|
||||||
inter_bone.matrix_basis = singleBoneRetarget(inter_bone, perf_bone)
|
inter_bone.matrix_basis = singleBoneRetarget(inter_bone, perf_bone)
|
||||||
|
elif inter_bone.parent:
|
||||||
|
if "Temp" in inter_bone.parent.name:
|
||||||
|
inter_bone.parent.bone.use_inherit_rotation = True
|
||||||
|
inter_bone.bone.use_inherit_rotation = True
|
||||||
|
else:
|
||||||
|
inter_bone.bone.use_inherit_rotation = True
|
||||||
inter_bone.keyframe_insert("rotation_quaternion")
|
inter_bone.keyframe_insert("rotation_quaternion")
|
||||||
for child in inter_bone.children:
|
for child in inter_bone.children:
|
||||||
retargetPerfToInter(child)
|
retargetPerfToInter(child)
|
||||||
@ -119,12 +124,14 @@ def createIntermediate(performer_obj, enduser_obj, root, s_frame, e_frame, scene
|
|||||||
bpy.ops.object.mode_set(mode='EDIT')
|
bpy.ops.object.mode_set(mode='EDIT')
|
||||||
#add some temporary connecting bones in case end user bones are not connected to their parents
|
#add some temporary connecting bones in case end user bones are not connected to their parents
|
||||||
for bone in inter_obj.data.edit_bones:
|
for bone in inter_obj.data.edit_bones:
|
||||||
if not bone.use_connect and bone.parent:
|
if not bone.use_connect and bone.parent and inter_obj.data.bones[bone.name].reverseMap:
|
||||||
newBone = inter_obj.data.edit_bones.new("Temp")
|
newBone = inter_obj.data.edit_bones.new("Temp")
|
||||||
newBone.head = bone.parent.head
|
newBone.head = bone.parent.tail
|
||||||
newBone.tail = bone.head
|
newBone.tail = bone.head
|
||||||
newBone.parent = bone.parent
|
newBone.parent = bone.parent
|
||||||
bone.parent = newBone
|
bone.parent = newBone
|
||||||
|
bone.use_connect = True
|
||||||
|
newBone.use_connect = True
|
||||||
#resets roll
|
#resets roll
|
||||||
bpy.ops.armature.calculate_roll(type='Z')
|
bpy.ops.armature.calculate_roll(type='Z')
|
||||||
bpy.ops.object.mode_set(mode="OBJECT")
|
bpy.ops.object.mode_set(mode="OBJECT")
|
||||||
@ -165,7 +172,7 @@ def retargetEnduser(inter_obj, enduser_obj, root, s_frame, e_frame, scene):
|
|||||||
|
|
||||||
if trg_bone.parent and trg_bone.bone.use_inherit_rotation:
|
if trg_bone.parent and trg_bone.bone.use_inherit_rotation:
|
||||||
srcParent = src_bone.parent
|
srcParent = src_bone.parent
|
||||||
if not trg_bone.bone.use_connect:
|
if "Temp" in srcParent.name:
|
||||||
srcParent = srcParent.parent
|
srcParent = srcParent.parent
|
||||||
parent_mat = srcParent.matrix
|
parent_mat = srcParent.matrix
|
||||||
parent_rest = trg_bone.parent.bone.matrix_local
|
parent_rest = trg_bone.parent.bone.matrix_local
|
||||||
@ -187,6 +194,8 @@ def retargetEnduser(inter_obj, enduser_obj, root, s_frame, e_frame, scene):
|
|||||||
end_bone.keyframe_insert("rotation_axis_angle")
|
end_bone.keyframe_insert("rotation_axis_angle")
|
||||||
else:
|
else:
|
||||||
end_bone.keyframe_insert("rotation_euler")
|
end_bone.keyframe_insert("rotation_euler")
|
||||||
|
if not end_bone.bone.use_connect:
|
||||||
|
end_bone.keyframe_insert("location")
|
||||||
|
|
||||||
for bone in end_bone.children:
|
for bone in end_bone.children:
|
||||||
bakeTransform(bone)
|
bakeTransform(bone)
|
||||||
@ -384,11 +393,16 @@ def NLASystemInitialize(enduser_obj, s_frame):
|
|||||||
def totalRetarget(performer_obj, enduser_obj, scene, s_frame, e_frame):
|
def totalRetarget(performer_obj, enduser_obj, scene, s_frame, e_frame):
|
||||||
perf_arm = performer_obj.data
|
perf_arm = performer_obj.data
|
||||||
end_arm = enduser_obj.data
|
end_arm = enduser_obj.data
|
||||||
|
print("creating Dictionary")
|
||||||
feetBones, root = createDictionary(perf_arm, end_arm)
|
feetBones, root = createDictionary(perf_arm, end_arm)
|
||||||
|
print("cleaning stuff up")
|
||||||
perf_obj_mat, enduser_obj_mat = cleanAndStoreObjMat(performer_obj, enduser_obj)
|
perf_obj_mat, enduser_obj_mat = cleanAndStoreObjMat(performer_obj, enduser_obj)
|
||||||
turnOffIK(enduser_obj)
|
turnOffIK(enduser_obj)
|
||||||
|
print("creating intermediate armature")
|
||||||
inter_obj = createIntermediate(performer_obj, enduser_obj, root, s_frame, e_frame, scene)
|
inter_obj = createIntermediate(performer_obj, enduser_obj, root, s_frame, e_frame, scene)
|
||||||
|
print("retargeting from intermediate to end user")
|
||||||
retargetEnduser(inter_obj, enduser_obj, root, s_frame, e_frame, scene)
|
retargetEnduser(inter_obj, enduser_obj, root, s_frame, e_frame, scene)
|
||||||
|
print("retargeting root translation and clean up")
|
||||||
stride_bone = copyTranslation(performer_obj, enduser_obj, feetBones, root, s_frame, e_frame, scene, enduser_obj_mat)
|
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)
|
restoreObjMat(performer_obj, enduser_obj, perf_obj_mat, enduser_obj_mat, stride_bone)
|
||||||
@ -396,6 +410,7 @@ def totalRetarget(performer_obj, enduser_obj, scene, s_frame, e_frame):
|
|||||||
bpy.ops.object.select_name(name=inter_obj.name, extend=False)
|
bpy.ops.object.select_name(name=inter_obj.name, extend=False)
|
||||||
bpy.ops.object.delete()
|
bpy.ops.object.delete()
|
||||||
NLASystemInitialize(enduser_obj, s_frame)
|
NLASystemInitialize(enduser_obj, s_frame)
|
||||||
|
print("retargeting done!")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@ -191,6 +191,7 @@ class MocapPanel(bpy.types.Panel):
|
|||||||
row.operator("mocap.samples", text='Samples to Beziers')
|
row.operator("mocap.samples", text='Samples to Beziers')
|
||||||
row.operator("mocap.denoise", text='Clean noise')
|
row.operator("mocap.denoise", text='Clean noise')
|
||||||
row.operator("mocap.rotate_fix", text='Fix BVH Axis Orientation')
|
row.operator("mocap.rotate_fix", text='Fix BVH Axis Orientation')
|
||||||
|
row.operator("mocap.scale_fix", text='Auto scale Performer')
|
||||||
row2 = self.layout.row(align=True)
|
row2 = self.layout.row(align=True)
|
||||||
row2.operator("mocap.looper", text='Loop animation')
|
row2.operator("mocap.looper", text='Loop animation')
|
||||||
row2.operator("mocap.limitdof", text='Constrain Rig')
|
row2.operator("mocap.limitdof", text='Constrain Rig')
|
||||||
@ -430,6 +431,27 @@ class OBJECT_OT_RotateFixArmature(bpy.types.Operator):
|
|||||||
return isinstance(context.active_object.data, bpy.types.Armature)
|
return isinstance(context.active_object.data, bpy.types.Armature)
|
||||||
|
|
||||||
|
|
||||||
|
class OBJECT_OT_ScaleFixArmature(bpy.types.Operator):
|
||||||
|
bl_idname = "mocap.scale_fix"
|
||||||
|
bl_label = "Scales performer armature to match target armature"
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
enduser_obj = bpy.context.active_object
|
||||||
|
performer_obj = [obj for obj in bpy.context.selected_objects if obj != enduser_obj][0]
|
||||||
|
mocap_tools.scale_fix_armature(performer_obj, enduser_obj)
|
||||||
|
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_AddMocapConstraint(bpy.types.Operator):
|
class OBJECT_OT_AddMocapConstraint(bpy.types.Operator):
|
||||||
bl_idname = "mocap.addconstraint"
|
bl_idname = "mocap.addconstraint"
|
||||||
bl_label = "Add constraint to target armature"
|
bl_label = "Add constraint to target armature"
|
||||||
|
Loading…
Reference in New Issue
Block a user