from . import SACTEvent import bpy # Action update (if anything important changes) def active_action_update(self, context): if not bpy.app.background: if context.scene.hecl_type == 'ACTOR' and context.scene.hecl_auto_select: if SACTAction_load.poll(context): bpy.ops.scene.SACTAction_load() # Action type update def action_type_update(self, context): if not bpy.app.background: actor_data = context.scene.hecl_sact_data active_action_update(self, context) # Actor action class class SACTAction(bpy.types.PropertyGroup): name = bpy.props.StringProperty(name="Action Name") action = bpy.props.StringProperty(name="Blender Action") # Panel draw def draw(layout, context): actor_data = context.scene.hecl_sact_data row = layout.row(align=True) row.alignment = 'LEFT' row.prop(actor_data, 'show_actions', text="Actions", icon='ACTION', emboss=False) if actor_data.show_actions: row = layout.row() row.template_list("UI_UL_list", "SCENE_UL_SACTActions", actor_data, 'actions', actor_data, 'active_action') col = row.column(align=True) col.operator("scene.sactaction_add", icon="ZOOMIN", text="") col.operator("scene.sactaction_remove", icon="ZOOMOUT", text="") if len(actor_data.actions) and actor_data.active_action >= 0: action = actor_data.actions[actor_data.active_action] # Load action operator if not bpy.context.scene.hecl_auto_select: layout.operator("scene.sactaction_load", icon='FILE_TICK', text="Load Action") # Name edit field layout.prop(action, 'name', text="Name") layout.prop_search(action, 'action', bpy.data, 'actions', text="Action") linked_action = None if bpy.data.actions.find(action.action) != -1: linked_action = bpy.data.actions[action.action] # Validate if linked_action is None: layout.label("Source action not set", icon='ERROR') else: layout.prop(linked_action, 'hecl_index', text="Index") layout.prop(linked_action, 'hecl_anim_props', text="Props") layout.prop(linked_action, 'hecl_fps', text="Frame Rate") layout.prop(context.scene, 'hecl_auto_remap', text="60-fps Remap") # Action 'add' operator class SACTAction_add(bpy.types.Operator): bl_idname = "scene.sactaction_add" bl_label = "New HECL Actor Action" bl_description = "Add New HECL Actor Action to active scene" @classmethod def poll(cls, context): return (context.scene is not None and not context.scene.library and context.scene.hecl_type == 'ACTOR') def execute(self, context): actor_data = context.scene.hecl_sact_data action_name = 'ActorAction' if action_name in actor_data.actions: action_name = 'ActorAction.001' action_idx = 1 while action_name in actor_data.actions: action_idx += 1 action_name = 'ActorAction.{:0>3}'.format(action_idx) action = actor_data.actions.add() action.name = action_name actor_data.active_action = len(actor_data.actions)-1 return {'FINISHED'} # Action 'remove' operator class SACTAction_remove(bpy.types.Operator): bl_idname = "scene.sactaction_remove" bl_label = "Remove HECL Actor Action" bl_description = "Remove HECL Actor Action from active scene" @classmethod def poll(cls, context): actor_data = context.scene.hecl_sact_data return (context.scene is not None and not context.scene.library and context.scene.hecl_type == 'ACTOR' and actor_data.active_action >= 0 and len(actor_data.actions)) def execute(self, context): actor_data = context.scene.hecl_sact_data actor_data.actions.remove(actor_data.active_action) actor_data.active_action -= 1 if actor_data.active_action == -1: actor_data.active_action = 0 return {'FINISHED'} # Action 'load' operator class SACTAction_load(bpy.types.Operator): bl_idname = "scene.sactaction_load" bl_label = "Load HECL Actor Action" bl_description = "Loads Action for playback in active scene" @classmethod def poll(cls, context): return (context.scene is not None and context.scene.hecl_type == 'ACTOR' and len(context.scene.hecl_sact_data.actions) and context.scene.hecl_sact_data.active_action >= 0) def execute(self, context): actor_data = context.scene.hecl_sact_data if actor_data.active_action not in range(len(actor_data.actions)): return {'CANCELLED'} if actor_data.active_subtype not in range(len(actor_data.subtypes)): return {'CANCELLED'} action_data = actor_data.actions[actor_data.active_action] subtype = actor_data.subtypes[actor_data.active_subtype] # Refresh event markers actor_event.clear_event_markers(actor_data, context) actor_event.update_action_events(None) actor_event.active_event_update(None, context) # Clear animation data for all subtypes for s in range(len(actor_data.subtypes)): st = actor_data.subtypes[s] if st.linked_armature in bpy.data.objects: am = bpy.data.objects[st.linked_armature] am.animation_data_clear() # Set single action into armature if subtype.linked_armature in bpy.data.objects: armature_obj = bpy.data.objects[subtype.linked_armature] if action_data.action in bpy.data.actions: action_obj =\ bpy.data.actions[action_data.action] armature_obj.animation_data_clear() armature_obj.animation_data_create() armature_obj.animation_data.action = action_obj # Time remapping if context.scene.hecl_auto_remap: bpy.context.scene.render.fps = 60 bpy.context.scene.render.frame_map_old = action_obj.hecl_fps bpy.context.scene.render.frame_map_new = 60 bpy.context.scene.frame_start = 2 bpy.context.scene.frame_end = action_obj.frame_range[1] * (60 / action_obj.hecl_fps) else: bpy.context.scene.render.fps = action_obj.hecl_fps bpy.context.scene.render.frame_map_old = action_obj.hecl_fps bpy.context.scene.render.frame_map_new = action_obj.hecl_fps bpy.context.scene.frame_start = 1 bpy.context.scene.frame_end = action_obj.frame_range[1] # Events #actor_event.clear_action_events(self, context, actor_data) #actor_event.load_action_events(self, context, action_obj, 0) return {'FINISHED'} else: armature_obj.animation_data_clear() self.report({'WARNING'}, "Unable to load action; check HECL panel") return {'FINISHED'} else: self.report({'WARNING'}, "Unable to load armature; check HECL panel") return {'FINISHED'} # Registration def register(): bpy.types.Action.hecl_fps = bpy.props.IntProperty(name="HECL Actor Sub-action Frame-rate", description="Frame-rate at which action is authored; to be interpolated at 60-fps by runtime", min=1, max=60, default=30, update=active_action_update) bpy.types.Action.hecl_anim_props = bpy.props.StringProperty(name="Animation Metadata") bpy.types.Action.hecl_index = bpy.props.IntProperty(name="HECL Actor Action Index") bpy.utils.register_class(SACTAction) bpy.utils.register_class(SACTAction_add) bpy.utils.register_class(SACTAction_load) bpy.utils.register_class(SACTAction_remove) def unregister(): bpy.utils.unregister_class(SACTAction) bpy.utils.unregister_class(SACTAction_add) bpy.utils.unregister_class(SACTAction_load) bpy.utils.unregister_class(SACTAction_remove)