Files
blender-portable-repo/scripts/addons/rokoko-studio-live-blender-master/panels/objects.py
T
2026-03-17 14:58:51 -06:00

167 lines
5.9 KiB
Python

import bpy
from ..core import animations, animation_lists
from ..operators.actor import InitTPose, ResetTPose
from ..operators import detector
# Create a panel in the Object category of all objects
class ObjectsPanel(bpy.types.Panel):
bl_label = "Rokoko Studio Live Setup"
bl_idname = "OBJECT_PT_rsl_objects_v2"
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "object"
def draw(self, context):
layout = self.layout
obj = context.object
self.draw_tracker(context, layout)
if obj.type == 'MESH':
self.draw_face(context, layout)
elif obj.type == 'ARMATURE':
self.draw_actor(context, layout)
@staticmethod
def draw_tracker(context, layout):
obj = context.object
props_string = 'Prop or Tracker' if animations.live_data.version <= 2 else 'prop'
row = layout.row(align=True)
row.label(text=f'Attach to {props_string}:')
if not animations.live_data.trackers and not animations.live_data.props:
row = layout.row(align=True)
row.label(text=f'No {props_string.lower()} data available.', icon='INFO')
return
row = layout.row(align=True)
row.prop(context.object, 'rsl_animations_props_trackers')
if obj.rsl_animations_props_trackers and obj.rsl_animations_props_trackers != 'None':
row = layout.row(align=True)
row.prop(context.object, 'rsl_use_custom_scale')
if obj.rsl_use_custom_scale:
row.prop(context.object, 'rsl_custom_scene_scale', text='')
@staticmethod
def draw_face(context, layout):
obj = context.object
layout.separator()
row = layout.row(align=True)
row.label(text='Attach to Face:')
if not animations.live_data.faces:
row = layout.row(align=True)
row.label(text='No face data available.', icon='INFO')
row = layout.row(align=True)
row.scale_y = 0.1
return
row = layout.row(align=True)
row.prop(obj, 'rsl_animations_faces')
if obj.rsl_animations_faces and obj.rsl_animations_faces != 'None':
layout.separator()
row = layout.row(align=True)
row.label(text='Select Shapekeys:')
row.operator(detector.DetectFaceShapes.bl_idname)
if not hasattr(obj.data, 'shape_keys') or not hasattr(obj.data.shape_keys, 'key_blocks'):
row = layout.row(align=True)
row.label(text='This mesh has no shapekeys!', icon='INFO')
return
draw_import_export(layout, shapes=True)
for shape in animation_lists.face_shapes:
row = layout.row(align=True)
row.prop_search(obj, 'rsl_face_' + shape, obj.data.shape_keys, "key_blocks", text=shape)
@staticmethod
def draw_actor(context, layout):
obj = context.object
layout.separator()
row = layout.row(align=True)
row.label(text='Attach to Actor:')
if not animations.live_data.actors:
row = layout.row(align=True)
row.label(text='No actor data available.', icon='INFO')
else:
row = layout.row(align=True)
row.prop(context.object, 'rsl_animations_actors')
if obj.rsl_animations_actors and obj.rsl_animations_actors != 'None':
layout.separator()
split = layout.row(align=True)
row = split.split(factor=0.16, align=True)
row.label(text='Bones:')
row.operator(detector.DetectActorBones.bl_idname)
row.operator(InitTPose.bl_idname)
row.operator(ResetTPose.bl_idname)
# if obj.rsl_animations_actors and obj.rsl_animations_actors != 'None':
if not obj.get('CUSTOM') or not obj.get('CUSTOM').get('rsl_tpose_bones'):
row = layout.row(align=True)
row.label(text='T-Pose is not set yet!', icon='ERROR')
draw_import_export(layout)
col = layout.column()
show_gloves = True
for actor_bone in animation_lists.get_bones().keys():
if not show_gloves:
continue
split = col.row(align=True)
row = split.split(factor=0.32, align=True)
row.label(text=actor_bone + ':')
row.prop_search(obj, 'rsl_actor_' + actor_bone, obj.pose, "bones", text='')
# Make a split after right toe to separate hands
if actor_bone == 'rightToe':
if not animations.live_data.has_gloves(animations.live_data.get_actor_by_obj(obj)): # Stop showing glove bones if they are not supported by the JSON version
show_gloves = False
continue
col.separator()
row = col.row(align=True)
row.label(text='Gloves:', icon='VIEW_PAN')
if actor_bone == 'leftLittleDistal':
col.separator()
def draw_import_export(layout, shapes=False):
layout.separator()
row = layout.row(align=True)
row.label(text='Custom Naming Schemes:')
if shapes:
row.operator(detector.SaveCustomShapes.bl_idname, text='Save Current Naming Scheme')
else:
row.operator(detector.SaveCustomBones.bl_idname, text='Save Current Naming Scheme')
subrow = layout.row(align=True)
row = subrow.row(align=True)
row.scale_y = 0.9
row.operator(detector.ImportCustomBones.bl_idname, text='Import')
row.operator(detector.ExportCustomBones.bl_idname, text='Export')
row = subrow.row(align=True)
row.scale_y = 0.9
row.alignment = 'RIGHT'
if shapes:
row.operator(detector.ClearCustomShapes.bl_idname, text='', icon='X')
else:
row.operator(detector.ClearCustomBones.bl_idname, text='', icon='X')
layout.separator()