mirror of
https://github.com/DarklightGames/io_scene_psk_psa.git
synced 2024-11-15 02:37:39 +01:00
Action selection now works in the PSA exporter, and actions that likely correspond to the selected armature are deselected by default (will save a bit of time!)
This commit is contained in:
parent
d13cd881a4
commit
3001501006
@ -42,12 +42,15 @@ classes = [
|
|||||||
psa_operator.ActionListItem
|
psa_operator.ActionListItem
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def psk_menu_func(self, context):
|
def psk_menu_func(self, context):
|
||||||
self.layout.operator(psk_operator.PskExportOperator.bl_idname, text ='Unreal PSK (.psk)')
|
self.layout.operator(psk_operator.PskExportOperator.bl_idname, text ='Unreal PSK (.psk)')
|
||||||
|
|
||||||
|
|
||||||
def psa_menu_func(self, context):
|
def psa_menu_func(self, context):
|
||||||
self.layout.operator(psa_operator.PsaExportOperator.bl_idname, text='Unreal PSA (.psa)')
|
self.layout.operator(psa_operator.PsaExportOperator.bl_idname, text='Unreal PSA (.psa)')
|
||||||
|
|
||||||
|
|
||||||
def register():
|
def register():
|
||||||
from bpy.utils import register_class
|
from bpy.utils import register_class
|
||||||
for cls in classes:
|
for cls in classes:
|
||||||
@ -57,6 +60,7 @@ def register():
|
|||||||
bpy.types.Scene.psa_action_list = CollectionProperty(type=psa_operator.ActionListItem)
|
bpy.types.Scene.psa_action_list = CollectionProperty(type=psa_operator.ActionListItem)
|
||||||
bpy.types.Scene.psa_action_list_index = IntProperty(name='index for list??', default=0)
|
bpy.types.Scene.psa_action_list_index = IntProperty(name='index for list??', default=0)
|
||||||
|
|
||||||
|
|
||||||
def unregister():
|
def unregister():
|
||||||
del bpy.types.Scene.psa_action_list_index
|
del bpy.types.Scene.psa_action_list_index
|
||||||
del bpy.types.Scene.psa_action_list
|
del bpy.types.Scene.psa_action_list
|
||||||
@ -66,5 +70,6 @@ def unregister():
|
|||||||
for cls in reversed(classes):
|
for cls in reversed(classes):
|
||||||
unregister_class(cls)
|
unregister_class(cls)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
register()
|
register()
|
||||||
|
@ -3,13 +3,18 @@ import mathutils
|
|||||||
from .data import *
|
from .data import *
|
||||||
|
|
||||||
|
|
||||||
|
class PsaBuilderOptions(object):
|
||||||
|
def __init__(self):
|
||||||
|
self.actions = []
|
||||||
|
|
||||||
|
|
||||||
# https://git.cth451.me/cth451/blender-addons/blob/master/io_export_unreal_psk_psa.py
|
# https://git.cth451.me/cth451/blender-addons/blob/master/io_export_unreal_psk_psa.py
|
||||||
class PsaBuilder(object):
|
class PsaBuilder(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# TODO: add options in here (selected anims, eg.)
|
# TODO: add options in here (selected anims, eg.)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def build(self, context) -> Psa:
|
def build(self, context, options) -> Psa:
|
||||||
object = context.view_layer.objects.active
|
object = context.view_layer.objects.active
|
||||||
|
|
||||||
if object.type != 'ARMATURE':
|
if object.type != 'ARMATURE':
|
||||||
@ -70,7 +75,7 @@ class PsaBuilder(object):
|
|||||||
print('---- ACTIONS ----')
|
print('---- ACTIONS ----')
|
||||||
frame_start_index = 0
|
frame_start_index = 0
|
||||||
|
|
||||||
for action in bpy.data.actions:
|
for action in options.actions:
|
||||||
if len(action.fcurves) == 0:
|
if len(action.fcurves) == 0:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
from bpy.types import Operator, Action, UIList, PropertyGroup
|
from bpy.types import Operator, Action, UIList, PropertyGroup
|
||||||
from bpy_extras.io_utils import ExportHelper
|
from bpy_extras.io_utils import ExportHelper
|
||||||
from bpy.props import StringProperty, BoolProperty, FloatProperty, CollectionProperty, PointerProperty
|
from bpy.props import StringProperty, BoolProperty, FloatProperty, CollectionProperty, PointerProperty
|
||||||
from .builder import PsaBuilder
|
from .builder import PsaBuilder, PsaBuilderOptions
|
||||||
from .exporter import PsaExporter
|
from .exporter import PsaExporter
|
||||||
import bpy
|
import bpy
|
||||||
import re
|
import re
|
||||||
@ -20,7 +20,7 @@ class PSA_UL_ActionList(UIList):
|
|||||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
|
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
|
||||||
layout.alignment = 'LEFT'
|
layout.alignment = 'LEFT'
|
||||||
layout.prop(item, 'is_selected', icon_only=True)
|
layout.prop(item, 'is_selected', icon_only=True)
|
||||||
layout.label(text=item.action.name, icon='ACTION')
|
layout.label(text=item.action.name)
|
||||||
|
|
||||||
def filter_items(self, context, data, property):
|
def filter_items(self, context, data, property):
|
||||||
# TODO: returns two lists, apparently
|
# TODO: returns two lists, apparently
|
||||||
@ -44,30 +44,61 @@ class PsaExportOperator(Operator, ExportHelper):
|
|||||||
maxlen=1024,
|
maxlen=1024,
|
||||||
default='')
|
default='')
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.armature = None
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
scene = context.scene
|
scene = context.scene
|
||||||
row = layout.row()
|
box = layout.box()
|
||||||
row.label(text='Actions')
|
box.label(text='Actions', icon='ACTION')
|
||||||
row = layout.row()
|
row = box.row()
|
||||||
row.template_list('PSA_UL_ActionList', 'asd', scene, 'psa_action_list', scene, 'psa_action_list_index', rows=len(context.scene.psa_action_list))
|
row.template_list('PSA_UL_ActionList', 'asd', scene, 'psa_action_list', scene, 'psa_action_list_index', rows=len(context.scene.psa_action_list))
|
||||||
|
|
||||||
|
def is_action_for_armature(self, action):
|
||||||
|
bone_names = [x.name for x in self.armature.data.bones]
|
||||||
|
print(bone_names)
|
||||||
|
for fcurve in action.fcurves:
|
||||||
|
match = re.match('pose\.bones\["(.+)"\].\w+', fcurve.data_path)
|
||||||
|
if not match:
|
||||||
|
continue
|
||||||
|
bone_name = match.group(1)
|
||||||
|
if bone_name not in bone_names:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
if context.view_layer.objects.active.type != 'ARMATURE':
|
if context.view_layer.objects.active.type != 'ARMATURE':
|
||||||
self.report({'ERROR_INVALID_CONTEXT'}, 'The selected object must be an armature.')
|
self.report({'ERROR_INVALID_CONTEXT'}, 'The selected object must be an armature.')
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
|
|
||||||
|
self.armature = context.view_layer.objects.active
|
||||||
|
|
||||||
context.scene.psa_action_list.clear()
|
context.scene.psa_action_list.clear()
|
||||||
for action in bpy.data.actions:
|
for action in bpy.data.actions:
|
||||||
item = context.scene.psa_action_list.add()
|
item = context.scene.psa_action_list.add()
|
||||||
item.action = action
|
item.action = action
|
||||||
# TODO: add
|
if self.is_action_for_armature(action):
|
||||||
item.is_selected = True
|
item.is_selected = True
|
||||||
|
|
||||||
|
if len(context.scene.psa_action_list) == 0:
|
||||||
|
self.report({'ERROR_INVALID_CONTEXT'}, 'There are no actions to export.')
|
||||||
|
return {'CANCELLED'}
|
||||||
|
|
||||||
context.window_manager.fileselect_add(self)
|
context.window_manager.fileselect_add(self)
|
||||||
return {'RUNNING_MODAL'}
|
return {'RUNNING_MODAL'}
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
|
actions = [x.action for x in context.scene.psa_action_list if x.is_selected]
|
||||||
|
|
||||||
|
if len(actions) == 0:
|
||||||
|
self.report({'ERROR_INVALID_CONTEXT'}, 'No actions were selected for export.')
|
||||||
|
return {'CANCELLED'}
|
||||||
|
|
||||||
|
options = PsaBuilderOptions()
|
||||||
|
options.actions = actions
|
||||||
builder = PsaBuilder()
|
builder = PsaBuilder()
|
||||||
psk = builder.build(context)
|
psk = builder.build(context, options)
|
||||||
exporter = PsaExporter(psk)
|
exporter = PsaExporter(psk)
|
||||||
exporter.export(self.filepath)
|
exporter.export(self.filepath)
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
Loading…
Reference in New Issue
Block a user