2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-12-08 13:44:56 +00:00

Attachment model support in blender addon

This commit is contained in:
Jack Andersen
2018-10-11 10:48:13 -10:00
parent d1f0450401
commit aef455e1ab
12 changed files with 362 additions and 81 deletions

View File

@@ -149,44 +149,50 @@ class SACTAction_load(bpy.types.Operator):
# Set single action into armature
if subtype.linked_armature in bpy.data.objects:
armature_obj = bpy.data.objects[subtype.linked_armature]
armature_objs = [bpy.data.objects[subtype.linked_armature]]
for attachment in actor_data.attachments:
if attachment.linked_armature in bpy.data.objects:
attachment_armature = bpy.data.objects[attachment.linked_armature]
armature_objs.append(attachment_armature)
for bone in armature_obj.pose.bones:
bone.location = (0,0,0)
bone.rotation_quaternion = (1,0,0,0)
bone.scale = (1,1,1)
for armature_obj in armature_objs:
for bone in armature_obj.pose.bones:
bone.location = (0,0,0)
bone.rotation_quaternion = (1,0,0,0)
bone.scale = (1,1,1)
if action_data.name in bpy.data.actions:
action_obj =\
bpy.data.actions[action_data.name]
armature_obj.animation_data_clear()
armature_obj.animation_data_create()
armature_obj.animation_data.action = action_obj
if action_data.name in bpy.data.actions:
action_obj =\
bpy.data.actions[action_data.name]
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 = 0
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 = 0
bpy.context.scene.frame_end = action_obj.frame_range[1]
# Events
#SACTEvent.clear_action_events(self, context, actor_data)
#SACTEvent.load_action_events(self, context, action_obj, 0)
# 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 = 0
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 = 0
bpy.context.scene.frame_end = action_obj.frame_range[1]
armature_obj.animation_data_clear()
self.report({'WARNING'}, "Unable to load action; check HECL panel")
return {'FINISHED'}
# Events
#SACTEvent.clear_action_events(self, context, actor_data)
#SACTEvent.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'}
return {'FINISHED'}
else:
self.report({'WARNING'}, "Unable to load armature; check HECL panel")

View File

@@ -13,18 +13,25 @@ class SACTSubtypeOverlay(bpy.types.PropertyGroup):
linked_mesh = bpy.props.StringProperty(name="Linked Mesh Object Source", update=active_subtype_update)
show_overlay = bpy.props.BoolProperty(name="Show Overlay Mesh", update=active_subtype_update)
# Actor attachment class
class SACTAttachment(bpy.types.PropertyGroup):
name = bpy.props.StringProperty(name="Attachment Name")
linked_armature = bpy.props.StringProperty(name="Linked Armature Object Source", update=active_subtype_update)
linked_mesh = bpy.props.StringProperty(name="Linked Mesh Object Source", update=active_subtype_update)
show_attachment = bpy.props.BoolProperty(name="Show Attachment Mesh", update=active_subtype_update)
# Actor subtype class
class SACTSubtype(bpy.types.PropertyGroup):
name = bpy.props.StringProperty(name="Actor Mesh Name")
linked_armature = bpy.props.StringProperty(name="Linked Armature Object Source", update=active_subtype_update)
linked_mesh = bpy.props.StringProperty(name="Linked Mesh Object Source", update=active_subtype_update)
show_mesh = bpy.props.BoolProperty(name="Show Mesh", default=True, update=active_subtype_update)
overlays =\
bpy.props.CollectionProperty(type=SACTSubtypeOverlay, name="Subtype Overlay List")
active_overlay =\
bpy.props.IntProperty(name="Active Subtype Overlay", default=0, update=active_subtype_update)
# Panel draw
def draw(layout, context):
actor_data = context.scene.hecl_sact_data
@@ -70,6 +77,7 @@ def draw(layout, context):
linked_mesh = None
if subtype.linked_mesh in bpy.data.objects:
linked_mesh = bpy.data.objects[subtype.linked_mesh]
layout.prop(subtype, 'show_mesh', text="Show Mesh")
# Mesh overlays
layout.label("Overlay Meshes:")
@@ -84,12 +92,33 @@ def draw(layout, context):
if len(subtype.overlays) and subtype.active_overlay >= 0:
overlay = subtype.overlays[subtype.active_overlay]
layout.prop(overlay, 'name', text="Name")
overlay = subtype.overlays[subtype.active_overlay]
layout.prop_search(overlay, 'linked_mesh', bpy.data, 'objects', text="Mesh")
if overlay.linked_mesh in bpy.data.objects:
overlay_mesh = bpy.data.objects[overlay.linked_mesh]
layout.prop(overlay, 'show_overlay', text="Show Overlay")
# Mesh attachments
layout.label("Attachment Meshes:")
row = layout.row()
row.template_list("UI_UL_list", "SCENE_UL_SACTAttachments",
actor_data, 'attachments', actor_data, 'active_attachment')
col = row.column(align=True)
col.operator("scene.sactattachment_add", icon="ZOOMIN", text="")
col.operator("scene.sactattachment_remove", icon="ZOOMOUT", text="")
attachment_armature = linked_armature
attachment_mesh = None
if len(actor_data.attachments) and actor_data.active_attachment >= 0:
attachment = actor_data.attachments[actor_data.active_attachment]
layout.prop(attachment, 'name', text="Name")
layout.prop_search(attachment, 'linked_armature', bpy.data, 'objects', text="Armature")
if attachment.linked_armature in bpy.data.objects:
attachment_armature = bpy.data.objects[attachment.linked_armature]
layout.prop_search(attachment, 'linked_mesh', bpy.data, 'objects', text="Mesh")
if attachment.linked_mesh in bpy.data.objects:
attachment_mesh = bpy.data.objects[attachment.linked_mesh]
layout.prop(attachment, 'show_attachment', text="Show Attachment")
# Validate
if linked_mesh is None:
layout.label("Source mesh not set", icon='ERROR')
@@ -103,11 +132,17 @@ def draw(layout, context):
if overlay_mesh:
if overlay_mesh.type != 'MESH':
layout.label("Overlay mesh not 'MESH'", icon='ERROR')
elif linked_armature is not None and overlay_mesh not in linked_armature.children:
layout.label(overlay_mesh.name+" not a child of "+linked_armature.name, icon='ERROR')
elif overlay_mesh.parent_type != 'ARMATURE':
layout.label("Overlay mesh not 'ARMATURE' parent type", icon='ERROR')
if attachment_mesh:
if attachment_mesh.type != 'MESH':
layout.label("Attachment mesh not 'MESH'", icon='ERROR')
elif attachment_armature is not None and attachment_mesh not in attachment_armature.children:
layout.label(attachment_mesh.name+" not a child of "+attachment_armature.name, icon='ERROR')
elif attachment_mesh.parent_type != 'ARMATURE':
layout.label("Attachment mesh not 'ARMATURE' parent type", icon='ERROR')
# Subtype 'add' operator
class SACTSubtype_add(bpy.types.Operator):
@@ -190,28 +225,43 @@ class SACTSubtype_load(bpy.types.Operator):
object.hide = True
# Hide all meshes (incl overlays)
for mesh_name in actor_data.subtypes:
if mesh_name.linked_mesh in bpy.data.objects:
mesh = bpy.data.objects[mesh_name.linked_mesh]
for subtype_data in actor_data.subtypes:
if subtype_data.linked_mesh in bpy.data.objects:
mesh = bpy.data.objects[subtype_data.linked_mesh]
if mesh.name in context.scene.objects:
mesh.hide = True
for overlay in mesh_name.overlays:
for overlay in subtype_data.overlays:
if overlay.linked_mesh in bpy.data.objects:
mesh = bpy.data.objects[overlay.linked_mesh]
if mesh.name in context.scene.objects:
mesh.hide = True
# Hide/Show selected attachment meshes
for attachment in actor_data.attachments:
if attachment.linked_mesh in bpy.data.objects:
mesh_obj = bpy.data.objects[attachment.linked_mesh]
if mesh_obj.name in context.scene.objects:
mesh_obj.hide = not attachment.show_attachment
attachment_armature = linked_armature
if attachment.linked_armature in bpy.data.objects:
attachment_armature = bpy.data.objects[attachment.linked_armature]
if mesh_obj != attachment_armature:
mesh_obj.parent = attachment_armature
mesh_obj.parent_type = 'ARMATURE'
# Show only the chosen subtype (and selected overlays)
if subtype.linked_mesh in bpy.data.objects:
mesh_obj = bpy.data.objects[subtype.linked_mesh]
mesh_obj.hide = False
if subtype.show_mesh:
mesh_obj.hide = False
if mesh_obj != linked_armature:
mesh_obj.parent = linked_armature
mesh_obj.parent_type = 'ARMATURE'
for overlay in subtype.overlays:
if overlay.show_overlay and overlay.linked_mesh in bpy.data.objects:
if overlay.linked_mesh in bpy.data.objects:
mesh_obj = bpy.data.objects[overlay.linked_mesh]
mesh_obj.hide = False
if overlay.show_overlay:
mesh_obj.hide = False
if mesh_obj != linked_armature:
mesh_obj.parent = linked_armature
mesh_obj.parent_type = 'ARMATURE'
@@ -275,11 +325,65 @@ class SACTSubtypeOverlay_remove(bpy.types.Operator):
subtype.active_overlay = 0
return {'FINISHED'}
# Subtype overlay 'add' operator
class SACTAttachment_add(bpy.types.Operator):
bl_idname = "scene.sactattachment_add"
bl_label = "New HECL Actor Attachment"
bl_description = "Add New HECL Actor Attachment"
@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')
def execute(self, context):
actor_data = context.scene.hecl_sact_data
attachment_name = 'ActorAttachment'
if attachment_name in actor_data.attachments:
attachment_name = 'ActorAttachment.001'
attachment_idx = 1
while attachment_name in actor_data.attachments:
attachment_idx += 1
attachment_name = 'ActorAttachment.{:0>3}'.format(attachment_idx)
attachment = actor_data.attachments.add()
attachment.name = attachment_name
actor_data.active_attachment = len(actor_data.attachments)-1
return {'FINISHED'}
# Subtype overlay 'remove' operator
class SACTAttachment_remove(bpy.types.Operator):
bl_idname = "scene.sactattachment_remove"
bl_label = "Remove HECL Actor Attachment"
bl_description = "Remove HECL Actor Attachment"
@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_attachment >= 0 and
len(actor_data.attachments))
def execute(self, context):
actor_data = context.scene.hecl_sact_data
actor_data.attachments.remove(actor_data.active_attachment)
actor_data.active_attachment -= 1
if actor_data.active_attachment == -1:
actor_data.active_attachment = 0
return {'FINISHED'}
# Registration
def register():
bpy.utils.register_class(SACTSubtypeOverlay)
bpy.utils.register_class(SACTSubtypeOverlay_add)
bpy.utils.register_class(SACTSubtypeOverlay_remove)
bpy.utils.register_class(SACTAttachment)
bpy.utils.register_class(SACTAttachment_add)
bpy.utils.register_class(SACTAttachment_remove)
bpy.utils.register_class(SACTSubtype)
bpy.utils.register_class(SACTSubtype_add)
bpy.utils.register_class(SACTSubtype_remove)
@@ -290,6 +394,9 @@ def unregister():
bpy.utils.unregister_class(SACTSubtype_add)
bpy.utils.unregister_class(SACTSubtype_remove)
bpy.utils.unregister_class(SACTSubtype_load)
bpy.utils.unregister_class(SACTAttachment)
bpy.utils.unregister_class(SACTAttachment_add)
bpy.utils.unregister_class(SACTAttachment_remove)
bpy.utils.unregister_class(SACTSubtypeOverlay)
bpy.utils.unregister_class(SACTSubtypeOverlay_add)
bpy.utils.unregister_class(SACTSubtypeOverlay_remove)

View File

@@ -19,6 +19,11 @@ class SACTData(bpy.types.PropertyGroup):
show_subtypes =\
bpy.props.BoolProperty()
attachments = \
bpy.props.CollectionProperty(type=SACTSubtype.SACTAttachment, name="Attachment List")
active_attachment = \
bpy.props.IntProperty(name="Active Attachment", default=0, update=SACTSubtype.active_subtype_update)
actions =\
bpy.props.CollectionProperty(type=SACTAction.SACTAction, name="Actor Action List")
active_action =\
@@ -268,6 +273,32 @@ def _out_subtypes(sact_data, writebuf):
else:
writebuf(struct.pack('I', 0))
def _out_attachments(sact_data, writebuf):
writebuf(struct.pack('I', len(sact_data.attachments)))
for attachment in sact_data.attachments:
writebuf(struct.pack('I', len(attachment.name)))
writebuf(attachment.name.encode())
mesh = None
if attachment.linked_mesh in bpy.data.objects:
mesh = bpy.data.objects[attachment.linked_mesh]
if mesh and mesh.library:
mesh_path = bpy.path.abspath(mesh.library.filepath)
writebuf(struct.pack('I', len(mesh_path)))
writebuf(mesh_path.encode())
else:
writebuf(struct.pack('I', 0))
arm = None
if attachment.linked_armature in bpy.data.objects:
arm = bpy.data.objects[attachment.linked_armature]
arm_idx = -1
if arm:
arm_idx = bpy.data.armatures.find(arm.name)
writebuf(struct.pack('i', arm_idx))
def _out_actions(sact_data, writebuf):
writebuf(struct.pack('I', len(sact_data.actions)))
for action_idx in range(len(sact_data.actions)):
@@ -335,6 +366,9 @@ def cook(writebuf):
# Output subtypes
_out_subtypes(sact_data, writebuf)
# Output attachments
_out_attachments(sact_data, writebuf)
# Output actions
_out_actions(sact_data, writebuf)
@@ -348,6 +382,9 @@ def cook_character_only(writebuf):
# Output subtypes
_out_subtypes(sact_data, writebuf)
# Output attachments
_out_attachments(sact_data, writebuf)
# Output no actions
writebuf(struct.pack('I', 0))
@@ -387,6 +424,15 @@ def get_subtype_overlay_names(writebuf, subtypeName):
return
writebuf(struct.pack('I', 0))
# Access contained attachment names
def get_attachment_names(writebuf):
sact_data = bpy.context.scene.hecl_sact_data
writebuf(struct.pack('I', len(sact_data.attachments)))
for att_idx in range(len(sact_data.attachments)):
attachment = sact_data.attachments[att_idx]
writebuf(struct.pack('I', len(attachment.name)))
writebuf(attachment.name.encode())
# Access actor's contained action names
def get_action_names(writebuf):
sact_data = bpy.context.scene.hecl_sact_data

View File

@@ -419,6 +419,10 @@ def dataout_loop():
writepipestr(b'OK')
hecl.sact.get_subtype_overlay_names(writepipebuf, subtypeName)
elif cmdargs[0] == 'GETATTACHMENTNAMES':
writepipestr(b'OK')
hecl.sact.get_attachment_names(writepipebuf)
elif cmdargs[0] == 'GETACTIONNAMES':
writepipestr(b'OK')
hecl.sact.get_action_names(writepipebuf)