135 lines
4.5 KiB
Python
135 lines
4.5 KiB
Python
import bpy
|
|
import copy
|
|
|
|
from . import receiver
|
|
|
|
|
|
class InitTPose(bpy.types.Operator):
|
|
bl_idname = "rsl.init_tpose"
|
|
bl_label = "Set as T-Pose"
|
|
bl_description = "Press this button if you have this armature in T-Pose"
|
|
bl_options = {'REGISTER', 'UNDO', 'INTERNAL'}
|
|
|
|
def execute(self, context):
|
|
obj = context.object
|
|
if obj.type != 'ARMATURE':
|
|
self.report({'ERROR'}, 'This is not an armature!')
|
|
return {'CANCELLED'}
|
|
|
|
bpy.ops.object.mode_set(mode='OBJECT')
|
|
|
|
# Get current custom data
|
|
custom_data = obj.get('CUSTOM')
|
|
if not custom_data:
|
|
custom_data = {}
|
|
|
|
bones = {}
|
|
|
|
# Save local and global space rotations and local and object space locations for each bone
|
|
for bone in obj.pose.bones:
|
|
# Save rotation mode
|
|
rotation_mode = bone.rotation_mode
|
|
|
|
# Save bone pose data
|
|
bone.rotation_mode = 'QUATERNION'
|
|
bones[bone.name] = {
|
|
'location_local': bone.location,
|
|
'location_object': bone.matrix @ bone.location,
|
|
'rotation_local': bone.rotation_quaternion,
|
|
'rotation_global': bone.matrix.to_quaternion(),
|
|
'inherit_rotation': obj.data.bones.get(bone.name).use_inherit_rotation,
|
|
}
|
|
|
|
# Load rotation mode
|
|
bone.rotation_mode = rotation_mode
|
|
|
|
# Save tpose data to custom data
|
|
custom_data['rsl_tpose_bones'] = copy.deepcopy(bones)
|
|
obj['CUSTOM'] = custom_data
|
|
|
|
self.report({'INFO'}, 'T-Pose successfully saved!')
|
|
return {'FINISHED'}
|
|
|
|
|
|
class ResetTPose(bpy.types.Operator):
|
|
bl_idname = "rsl.reset_tpose"
|
|
bl_label = "Reset to T-Pose"
|
|
bl_description = "Use this to reset the armature to it's T-Pose"
|
|
bl_options = {'REGISTER', 'UNDO', 'INTERNAL'}
|
|
|
|
def execute(self, context):
|
|
if receiver.receiver_enabled:
|
|
self.report({'ERROR'}, 'Receiver is currently running. Please stop it first.')
|
|
return {'CANCELLED'}
|
|
|
|
obj = context.object
|
|
if obj.type != 'ARMATURE':
|
|
self.report({'ERROR'}, 'This is not an armature!')
|
|
return {'CANCELLED'}
|
|
|
|
# Get current custom data
|
|
custom_data = obj.get('CUSTOM')
|
|
if not custom_data:
|
|
self.report({'ERROR'}, 'Please set the T-Pose first.')
|
|
return {'CANCELLED'}
|
|
|
|
# Get tpose data from custom data
|
|
tpose_bones = custom_data.get('rsl_tpose_bones')
|
|
if not tpose_bones:
|
|
self.report({'ERROR'}, 'Please set the T-Pose first.')
|
|
return {'CANCELLED'}
|
|
|
|
# Apply locations and rotations to bones
|
|
for bone_name, data in tpose_bones.items():
|
|
bone = obj.pose.bones.get(bone_name)
|
|
if bone:
|
|
# Save rotation mode
|
|
rotation_mode = bone.rotation_mode
|
|
if rotation_mode == 'QUATERNION':
|
|
rotation_mode = 'XYZ'
|
|
|
|
bone.rotation_mode = 'QUATERNION'
|
|
bone.rotation_quaternion = data['rotation_local']
|
|
bone.location = data['location_local']
|
|
obj.data.bones.get(bone_name).use_inherit_rotation = data['inherit_rotation']
|
|
|
|
# Load rotation mode
|
|
bone.rotation_mode = rotation_mode
|
|
|
|
self.report({'INFO'}, 'T-Pose successfully restored!')
|
|
return {'FINISHED'}
|
|
|
|
|
|
class PrintCurrentPose(bpy.types.Operator):
|
|
bl_idname = "rsl.print_current_pose"
|
|
bl_label = "Print"
|
|
bl_description = "Debugging. Prints world rotation of armature bones"
|
|
bl_options = {'REGISTER', 'UNDO', 'INTERNAL'}
|
|
|
|
def execute(self, context):
|
|
obj = context.object
|
|
if obj.type != 'ARMATURE':
|
|
self.report({'ERROR'}, 'This is not an armature!')
|
|
return {'CANCELLED'}
|
|
|
|
for bone in obj.pose.bones:
|
|
# Save rotation mode
|
|
rotation_mode = bone.rotation_mode
|
|
if rotation_mode == 'QUATERNION':
|
|
rotation_mode = 'XYZ'
|
|
|
|
bone.rotation_mode = 'QUATERNION'
|
|
rot = bone.matrix.to_euler().to_quaternion().copy()
|
|
i = 5
|
|
print('actor_bones[\'' + bone.name + '\'] = Quaternion(('
|
|
+ str(round(rot[0], i)) + ', '
|
|
+ str(round(rot[1], i)) + ', '
|
|
+ str(round(rot[2], i)) + ', '
|
|
+ str(round(rot[3], i))
|
|
+ '))')
|
|
|
|
# Load rotation mode
|
|
bone.rotation_mode = rotation_mode
|
|
|
|
return {'FINISHED'}
|