mirror of
https://github.com/AxioDL/metaforce.git
synced 2025-06-06 15:53:28 +00:00
Attachment model support in blender addon
This commit is contained in:
parent
d1f0450401
commit
aef455e1ab
@ -149,44 +149,50 @@ class SACTAction_load(bpy.types.Operator):
|
|||||||
|
|
||||||
# Set single action into armature
|
# Set single action into armature
|
||||||
if subtype.linked_armature in bpy.data.objects:
|
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:
|
for armature_obj in armature_objs:
|
||||||
bone.location = (0,0,0)
|
for bone in armature_obj.pose.bones:
|
||||||
bone.rotation_quaternion = (1,0,0,0)
|
bone.location = (0,0,0)
|
||||||
bone.scale = (1,1,1)
|
bone.rotation_quaternion = (1,0,0,0)
|
||||||
|
bone.scale = (1,1,1)
|
||||||
|
|
||||||
if action_data.name in bpy.data.actions:
|
if action_data.name in bpy.data.actions:
|
||||||
action_obj =\
|
action_obj =\
|
||||||
bpy.data.actions[action_data.name]
|
bpy.data.actions[action_data.name]
|
||||||
armature_obj.animation_data_clear()
|
armature_obj.animation_data_clear()
|
||||||
armature_obj.animation_data_create()
|
armature_obj.animation_data_create()
|
||||||
armature_obj.animation_data.action = action_obj
|
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:
|
else:
|
||||||
bpy.context.scene.render.fps = action_obj.hecl_fps
|
armature_obj.animation_data_clear()
|
||||||
bpy.context.scene.render.frame_map_old = action_obj.hecl_fps
|
self.report({'WARNING'}, "Unable to load action; check HECL panel")
|
||||||
bpy.context.scene.render.frame_map_new = action_obj.hecl_fps
|
return {'FINISHED'}
|
||||||
bpy.context.scene.frame_start = 0
|
|
||||||
bpy.context.scene.frame_end = action_obj.frame_range[1]
|
|
||||||
|
|
||||||
# Events
|
return {'FINISHED'}
|
||||||
#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'}
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
self.report({'WARNING'}, "Unable to load armature; check HECL panel")
|
self.report({'WARNING'}, "Unable to load armature; check HECL panel")
|
||||||
|
@ -13,18 +13,25 @@ class SACTSubtypeOverlay(bpy.types.PropertyGroup):
|
|||||||
linked_mesh = bpy.props.StringProperty(name="Linked Mesh Object Source", update=active_subtype_update)
|
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)
|
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
|
# Actor subtype class
|
||||||
class SACTSubtype(bpy.types.PropertyGroup):
|
class SACTSubtype(bpy.types.PropertyGroup):
|
||||||
name = bpy.props.StringProperty(name="Actor Mesh Name")
|
name = bpy.props.StringProperty(name="Actor Mesh Name")
|
||||||
linked_armature = bpy.props.StringProperty(name="Linked Armature Object Source", update=active_subtype_update)
|
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)
|
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 =\
|
overlays =\
|
||||||
bpy.props.CollectionProperty(type=SACTSubtypeOverlay, name="Subtype Overlay List")
|
bpy.props.CollectionProperty(type=SACTSubtypeOverlay, name="Subtype Overlay List")
|
||||||
active_overlay =\
|
active_overlay =\
|
||||||
bpy.props.IntProperty(name="Active Subtype Overlay", default=0, update=active_subtype_update)
|
bpy.props.IntProperty(name="Active Subtype Overlay", default=0, update=active_subtype_update)
|
||||||
|
|
||||||
|
|
||||||
# Panel draw
|
# Panel draw
|
||||||
def draw(layout, context):
|
def draw(layout, context):
|
||||||
actor_data = context.scene.hecl_sact_data
|
actor_data = context.scene.hecl_sact_data
|
||||||
@ -70,6 +77,7 @@ def draw(layout, context):
|
|||||||
linked_mesh = None
|
linked_mesh = None
|
||||||
if subtype.linked_mesh in bpy.data.objects:
|
if subtype.linked_mesh in bpy.data.objects:
|
||||||
linked_mesh = bpy.data.objects[subtype.linked_mesh]
|
linked_mesh = bpy.data.objects[subtype.linked_mesh]
|
||||||
|
layout.prop(subtype, 'show_mesh', text="Show Mesh")
|
||||||
|
|
||||||
# Mesh overlays
|
# Mesh overlays
|
||||||
layout.label("Overlay Meshes:")
|
layout.label("Overlay Meshes:")
|
||||||
@ -84,12 +92,33 @@ def draw(layout, context):
|
|||||||
if len(subtype.overlays) and subtype.active_overlay >= 0:
|
if len(subtype.overlays) and subtype.active_overlay >= 0:
|
||||||
overlay = subtype.overlays[subtype.active_overlay]
|
overlay = subtype.overlays[subtype.active_overlay]
|
||||||
layout.prop(overlay, 'name', text="Name")
|
layout.prop(overlay, 'name', text="Name")
|
||||||
overlay = subtype.overlays[subtype.active_overlay]
|
|
||||||
layout.prop_search(overlay, 'linked_mesh', bpy.data, 'objects', text="Mesh")
|
layout.prop_search(overlay, 'linked_mesh', bpy.data, 'objects', text="Mesh")
|
||||||
if overlay.linked_mesh in bpy.data.objects:
|
if overlay.linked_mesh in bpy.data.objects:
|
||||||
overlay_mesh = bpy.data.objects[overlay.linked_mesh]
|
overlay_mesh = bpy.data.objects[overlay.linked_mesh]
|
||||||
layout.prop(overlay, 'show_overlay', text="Show Overlay")
|
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
|
# Validate
|
||||||
if linked_mesh is None:
|
if linked_mesh is None:
|
||||||
layout.label("Source mesh not set", icon='ERROR')
|
layout.label("Source mesh not set", icon='ERROR')
|
||||||
@ -103,11 +132,17 @@ def draw(layout, context):
|
|||||||
if overlay_mesh:
|
if overlay_mesh:
|
||||||
if overlay_mesh.type != 'MESH':
|
if overlay_mesh.type != 'MESH':
|
||||||
layout.label("Overlay mesh not 'MESH'", icon='ERROR')
|
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':
|
elif overlay_mesh.parent_type != 'ARMATURE':
|
||||||
layout.label("Overlay mesh not 'ARMATURE' parent type", icon='ERROR')
|
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
|
# Subtype 'add' operator
|
||||||
class SACTSubtype_add(bpy.types.Operator):
|
class SACTSubtype_add(bpy.types.Operator):
|
||||||
@ -190,28 +225,43 @@ class SACTSubtype_load(bpy.types.Operator):
|
|||||||
object.hide = True
|
object.hide = True
|
||||||
|
|
||||||
# Hide all meshes (incl overlays)
|
# Hide all meshes (incl overlays)
|
||||||
for mesh_name in actor_data.subtypes:
|
for subtype_data in actor_data.subtypes:
|
||||||
if mesh_name.linked_mesh in bpy.data.objects:
|
if subtype_data.linked_mesh in bpy.data.objects:
|
||||||
mesh = bpy.data.objects[mesh_name.linked_mesh]
|
mesh = bpy.data.objects[subtype_data.linked_mesh]
|
||||||
if mesh.name in context.scene.objects:
|
if mesh.name in context.scene.objects:
|
||||||
mesh.hide = True
|
mesh.hide = True
|
||||||
for overlay in mesh_name.overlays:
|
for overlay in subtype_data.overlays:
|
||||||
if overlay.linked_mesh in bpy.data.objects:
|
if overlay.linked_mesh in bpy.data.objects:
|
||||||
mesh = bpy.data.objects[overlay.linked_mesh]
|
mesh = bpy.data.objects[overlay.linked_mesh]
|
||||||
if mesh.name in context.scene.objects:
|
if mesh.name in context.scene.objects:
|
||||||
mesh.hide = True
|
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)
|
# Show only the chosen subtype (and selected overlays)
|
||||||
if subtype.linked_mesh in bpy.data.objects:
|
if subtype.linked_mesh in bpy.data.objects:
|
||||||
mesh_obj = bpy.data.objects[subtype.linked_mesh]
|
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:
|
if mesh_obj != linked_armature:
|
||||||
mesh_obj.parent = linked_armature
|
mesh_obj.parent = linked_armature
|
||||||
mesh_obj.parent_type = 'ARMATURE'
|
mesh_obj.parent_type = 'ARMATURE'
|
||||||
for overlay in subtype.overlays:
|
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 = bpy.data.objects[overlay.linked_mesh]
|
||||||
mesh_obj.hide = False
|
if overlay.show_overlay:
|
||||||
|
mesh_obj.hide = False
|
||||||
if mesh_obj != linked_armature:
|
if mesh_obj != linked_armature:
|
||||||
mesh_obj.parent = linked_armature
|
mesh_obj.parent = linked_armature
|
||||||
mesh_obj.parent_type = 'ARMATURE'
|
mesh_obj.parent_type = 'ARMATURE'
|
||||||
@ -275,11 +325,65 @@ class SACTSubtypeOverlay_remove(bpy.types.Operator):
|
|||||||
subtype.active_overlay = 0
|
subtype.active_overlay = 0
|
||||||
return {'FINISHED'}
|
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
|
# Registration
|
||||||
def register():
|
def register():
|
||||||
bpy.utils.register_class(SACTSubtypeOverlay)
|
bpy.utils.register_class(SACTSubtypeOverlay)
|
||||||
bpy.utils.register_class(SACTSubtypeOverlay_add)
|
bpy.utils.register_class(SACTSubtypeOverlay_add)
|
||||||
bpy.utils.register_class(SACTSubtypeOverlay_remove)
|
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)
|
||||||
bpy.utils.register_class(SACTSubtype_add)
|
bpy.utils.register_class(SACTSubtype_add)
|
||||||
bpy.utils.register_class(SACTSubtype_remove)
|
bpy.utils.register_class(SACTSubtype_remove)
|
||||||
@ -290,6 +394,9 @@ def unregister():
|
|||||||
bpy.utils.unregister_class(SACTSubtype_add)
|
bpy.utils.unregister_class(SACTSubtype_add)
|
||||||
bpy.utils.unregister_class(SACTSubtype_remove)
|
bpy.utils.unregister_class(SACTSubtype_remove)
|
||||||
bpy.utils.unregister_class(SACTSubtype_load)
|
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)
|
||||||
bpy.utils.unregister_class(SACTSubtypeOverlay_add)
|
bpy.utils.unregister_class(SACTSubtypeOverlay_add)
|
||||||
bpy.utils.unregister_class(SACTSubtypeOverlay_remove)
|
bpy.utils.unregister_class(SACTSubtypeOverlay_remove)
|
||||||
|
@ -19,6 +19,11 @@ class SACTData(bpy.types.PropertyGroup):
|
|||||||
show_subtypes =\
|
show_subtypes =\
|
||||||
bpy.props.BoolProperty()
|
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 =\
|
actions =\
|
||||||
bpy.props.CollectionProperty(type=SACTAction.SACTAction, name="Actor Action List")
|
bpy.props.CollectionProperty(type=SACTAction.SACTAction, name="Actor Action List")
|
||||||
active_action =\
|
active_action =\
|
||||||
@ -268,6 +273,32 @@ def _out_subtypes(sact_data, writebuf):
|
|||||||
else:
|
else:
|
||||||
writebuf(struct.pack('I', 0))
|
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):
|
def _out_actions(sact_data, writebuf):
|
||||||
writebuf(struct.pack('I', len(sact_data.actions)))
|
writebuf(struct.pack('I', len(sact_data.actions)))
|
||||||
for action_idx in range(len(sact_data.actions)):
|
for action_idx in range(len(sact_data.actions)):
|
||||||
@ -335,6 +366,9 @@ def cook(writebuf):
|
|||||||
# Output subtypes
|
# Output subtypes
|
||||||
_out_subtypes(sact_data, writebuf)
|
_out_subtypes(sact_data, writebuf)
|
||||||
|
|
||||||
|
# Output attachments
|
||||||
|
_out_attachments(sact_data, writebuf)
|
||||||
|
|
||||||
# Output actions
|
# Output actions
|
||||||
_out_actions(sact_data, writebuf)
|
_out_actions(sact_data, writebuf)
|
||||||
|
|
||||||
@ -348,6 +382,9 @@ def cook_character_only(writebuf):
|
|||||||
# Output subtypes
|
# Output subtypes
|
||||||
_out_subtypes(sact_data, writebuf)
|
_out_subtypes(sact_data, writebuf)
|
||||||
|
|
||||||
|
# Output attachments
|
||||||
|
_out_attachments(sact_data, writebuf)
|
||||||
|
|
||||||
# Output no actions
|
# Output no actions
|
||||||
writebuf(struct.pack('I', 0))
|
writebuf(struct.pack('I', 0))
|
||||||
|
|
||||||
@ -387,6 +424,15 @@ def get_subtype_overlay_names(writebuf, subtypeName):
|
|||||||
return
|
return
|
||||||
writebuf(struct.pack('I', 0))
|
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
|
# Access actor's contained action names
|
||||||
def get_action_names(writebuf):
|
def get_action_names(writebuf):
|
||||||
sact_data = bpy.context.scene.hecl_sact_data
|
sact_data = bpy.context.scene.hecl_sact_data
|
||||||
|
@ -419,6 +419,10 @@ def dataout_loop():
|
|||||||
writepipestr(b'OK')
|
writepipestr(b'OK')
|
||||||
hecl.sact.get_subtype_overlay_names(writepipebuf, subtypeName)
|
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':
|
elif cmdargs[0] == 'GETACTIONNAMES':
|
||||||
writepipestr(b'OK')
|
writepipestr(b'OK')
|
||||||
hecl.sact.get_action_names(writepipebuf)
|
hecl.sact.get_action_names(writepipebuf)
|
||||||
|
2
hecl/extern/boo
vendored
2
hecl/extern/boo
vendored
@ -1 +1 @@
|
|||||||
Subproject commit bba2486c15498a307eb1c009edba09ec10a10294
|
Subproject commit f917d154b2ff38a5cbeea8c536c91e7813be060d
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
namespace hecl::Backend
|
namespace hecl::Backend
|
||||||
{
|
{
|
||||||
|
struct ExtensionSlot;
|
||||||
|
|
||||||
using IR = Frontend::IR;
|
using IR = Frontend::IR;
|
||||||
using Diagnostics = Frontend::Diagnostics;
|
using Diagnostics = Frontend::Diagnostics;
|
||||||
@ -159,6 +160,9 @@ public:
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boo::AdditionalPipelineInfo additionalInfo(const ExtensionSlot& ext,
|
||||||
|
std::pair<BlendFactor, BlendFactor> blendFactors) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Function
|
struct Function
|
||||||
@ -226,6 +230,44 @@ struct ExtensionSlot
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline boo::AdditionalPipelineInfo ShaderTag::additionalInfo(const ExtensionSlot& ext,
|
||||||
|
std::pair<BlendFactor, BlendFactor> blendFactors) const
|
||||||
|
{
|
||||||
|
boo::ZTest zTest;
|
||||||
|
switch (ext.depthTest)
|
||||||
|
{
|
||||||
|
case hecl::Backend::ZTest::Original:
|
||||||
|
default:
|
||||||
|
zTest = getDepthTest() ? boo::ZTest::LEqual : boo::ZTest::None;
|
||||||
|
break;
|
||||||
|
case hecl::Backend::ZTest::None:
|
||||||
|
zTest = boo::ZTest::None;
|
||||||
|
break;
|
||||||
|
case hecl::Backend::ZTest::LEqual:
|
||||||
|
zTest = boo::ZTest::LEqual;
|
||||||
|
break;
|
||||||
|
case hecl::Backend::ZTest::Greater:
|
||||||
|
zTest = boo::ZTest::Greater;
|
||||||
|
break;
|
||||||
|
case hecl::Backend::ZTest::Equal:
|
||||||
|
zTest = boo::ZTest::Equal;
|
||||||
|
break;
|
||||||
|
case hecl::Backend::ZTest::GEqual:
|
||||||
|
zTest = boo::ZTest::GEqual;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
boo::BlendFactor((ext.srcFactor == BlendFactor::Original) ? blendFactors.first : ext.srcFactor),
|
||||||
|
boo::BlendFactor((ext.dstFactor == BlendFactor::Original) ? blendFactors.second : ext.dstFactor),
|
||||||
|
getPrimType(), zTest, ext.noDepthWrite ? false : getDepthWrite(),
|
||||||
|
!ext.noColorWrite, !ext.noAlphaWrite,
|
||||||
|
(ext.cullMode == hecl::Backend::CullMode::Original) ?
|
||||||
|
(getBackfaceCulling() ? boo::CullMode::Backface : boo::CullMode::None) :
|
||||||
|
boo::CullMode(ext.cullMode), !ext.noAlphaOverwrite
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace std
|
namespace std
|
||||||
|
@ -504,6 +504,14 @@ struct Actor
|
|||||||
Subtype(Connection& conn);
|
Subtype(Connection& conn);
|
||||||
};
|
};
|
||||||
std::vector<Subtype> subtypes;
|
std::vector<Subtype> subtypes;
|
||||||
|
struct Attachment
|
||||||
|
{
|
||||||
|
std::string name;
|
||||||
|
ProjectPath mesh;
|
||||||
|
int32_t armature = -1;
|
||||||
|
Attachment(Connection& conn);
|
||||||
|
};
|
||||||
|
std::vector<Attachment> attachments;
|
||||||
std::vector<Action> actions;
|
std::vector<Action> actions;
|
||||||
|
|
||||||
Actor(Connection& conn);
|
Actor(Connection& conn);
|
||||||
@ -572,6 +580,7 @@ public:
|
|||||||
std::vector<std::string> getSubtypeNames();
|
std::vector<std::string> getSubtypeNames();
|
||||||
std::vector<std::string> getActionNames();
|
std::vector<std::string> getActionNames();
|
||||||
std::vector<std::string> getSubtypeOverlayNames(std::string_view name);
|
std::vector<std::string> getSubtypeOverlayNames(std::string_view name);
|
||||||
|
std::vector<std::string> getAttachmentNames();
|
||||||
|
|
||||||
std::unordered_map<std::string, Matrix3f> getBoneMatrices(std::string_view name);
|
std::unordered_map<std::string, Matrix3f> getBoneMatrices(std::string_view name);
|
||||||
|
|
||||||
|
@ -83,6 +83,9 @@ public:
|
|||||||
m_extension.texCount, m_extension.texs);
|
m_extension.texCount, m_extension.texs);
|
||||||
}
|
}
|
||||||
const hecl::Backend::ShaderTag& getTag() const { return m_tag; }
|
const hecl::Backend::ShaderTag& getTag() const { return m_tag; }
|
||||||
|
const hecl::Backend::ExtensionSlot& extension() const { return m_extension; }
|
||||||
|
std::pair<hecl::Backend::BlendFactor, hecl::Backend::BlendFactor> blendFactors() const
|
||||||
|
{ return {m_backend.m_blendSrc, m_backend.m_blendDst}; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename P>
|
template<typename P>
|
||||||
@ -134,6 +137,7 @@ StageCollection<T<P, Rest...>>::StageCollection(PipelineConverter<P>& conv, Fact
|
|||||||
m_fragment = conv.getFragmentConverter().convert(ctx, StageSourceText<P, PipelineStage::Fragment>(in.makeFrag()));
|
m_fragment = conv.getFragmentConverter().convert(ctx, StageSourceText<P, PipelineStage::Fragment>(in.makeFrag()));
|
||||||
m_vtxFmtData = in.getTag().vertexFormat();
|
m_vtxFmtData = in.getTag().vertexFormat();
|
||||||
m_vtxFmt = boo::VertexFormatInfo(m_vtxFmtData.size(), m_vtxFmtData.data());
|
m_vtxFmt = boo::VertexFormatInfo(m_vtxFmtData.size(), m_vtxFmtData.data());
|
||||||
|
m_additionalInfo = in.getTag().additionalInfo(in.extension(), in.blendFactors());
|
||||||
MakeHash();
|
MakeHash();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,9 +66,7 @@ public:
|
|||||||
uint64_t Hash() const { return m_hash; }
|
uint64_t Hash() const { return m_hash; }
|
||||||
|
|
||||||
explicit StageSourceText(std::string_view text)
|
explicit StageSourceText(std::string_view text)
|
||||||
{
|
: m_text(text), m_hash(XXH64(m_text.data(), m_text.size(), 0)) {}
|
||||||
m_hash = XXH64(m_text.data(), m_text.size(), 0);
|
|
||||||
}
|
|
||||||
std::string_view text() const { return m_text; }
|
std::string_view text() const { return m_text; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -834,37 +834,7 @@ public:
|
|||||||
* @param replace remove existing extension (if any) before appending new extension
|
* @param replace remove existing extension (if any) before appending new extension
|
||||||
* @return new path with extension
|
* @return new path with extension
|
||||||
*/
|
*/
|
||||||
ProjectPath getWithExtension(const SystemChar* ext, bool replace=false) const
|
ProjectPath getWithExtension(const SystemChar* ext, bool replace=false) const;
|
||||||
{
|
|
||||||
ProjectPath pp(*this);
|
|
||||||
if (replace)
|
|
||||||
{
|
|
||||||
auto relIt = pp.m_relPath.end();
|
|
||||||
if (relIt != pp.m_relPath.begin())
|
|
||||||
--relIt;
|
|
||||||
auto absIt = pp.m_absPath.end();
|
|
||||||
if (absIt != pp.m_absPath.begin())
|
|
||||||
--absIt;
|
|
||||||
while (relIt != pp.m_relPath.begin() && *relIt != _S('.') && *relIt != _S('/'))
|
|
||||||
{
|
|
||||||
--relIt;
|
|
||||||
--absIt;
|
|
||||||
}
|
|
||||||
if (*relIt == _S('.') && relIt != pp.m_relPath.begin())
|
|
||||||
{
|
|
||||||
pp.m_relPath.resize(relIt - pp.m_relPath.begin());
|
|
||||||
pp.m_absPath.resize(absIt - pp.m_absPath.begin());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ext)
|
|
||||||
{
|
|
||||||
pp.m_relPath += ext;
|
|
||||||
pp.m_absPath += ext;
|
|
||||||
}
|
|
||||||
|
|
||||||
pp.ComputeHash();
|
|
||||||
return pp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Access fully-canonicalized absolute path
|
* @brief Access fully-canonicalized absolute path
|
||||||
@ -1063,7 +1033,10 @@ public:
|
|||||||
*/
|
*/
|
||||||
ProjectPath ensureAuxInfo(SystemStringView auxStr) const
|
ProjectPath ensureAuxInfo(SystemStringView auxStr) const
|
||||||
{
|
{
|
||||||
return ProjectPath(getProject(), SystemString(getRelativePath()) + _S('|') + auxStr.data());
|
if (auxStr.empty())
|
||||||
|
return ProjectPath(getProject(), getRelativePath());
|
||||||
|
else
|
||||||
|
return ProjectPath(getProject(), SystemString(getRelativePath()) + _S('|') + auxStr.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
#if HECL_UCS2
|
#if HECL_UCS2
|
||||||
|
@ -1546,6 +1546,12 @@ Actor::Actor(Connection& conn)
|
|||||||
for (uint32_t i=0 ; i<subtypeCount ; ++i)
|
for (uint32_t i=0 ; i<subtypeCount ; ++i)
|
||||||
subtypes.emplace_back(conn);
|
subtypes.emplace_back(conn);
|
||||||
|
|
||||||
|
uint32_t attachmentCount;
|
||||||
|
conn._readBuf(&attachmentCount, 4);
|
||||||
|
attachments.reserve(attachmentCount);
|
||||||
|
for (uint32_t i=0 ; i<attachmentCount ; ++i)
|
||||||
|
attachments.emplace_back(conn);
|
||||||
|
|
||||||
uint32_t actionCount;
|
uint32_t actionCount;
|
||||||
conn._readBuf(&actionCount, 4);
|
conn._readBuf(&actionCount, 4);
|
||||||
actions.reserve(actionCount);
|
actions.reserve(actionCount);
|
||||||
@ -1677,6 +1683,29 @@ Actor::Subtype::Subtype(Connection& conn)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Actor::Attachment::Attachment(Connection& conn)
|
||||||
|
{
|
||||||
|
uint32_t bufSz;
|
||||||
|
conn._readBuf(&bufSz, 4);
|
||||||
|
name.assign(bufSz, ' ');
|
||||||
|
conn._readBuf(&name[0], bufSz);
|
||||||
|
|
||||||
|
std::string meshPath;
|
||||||
|
conn._readBuf(&bufSz, 4);
|
||||||
|
if (bufSz)
|
||||||
|
{
|
||||||
|
meshPath.assign(bufSz, ' ');
|
||||||
|
conn._readBuf(&meshPath[0], bufSz);
|
||||||
|
SystemStringConv meshPathAbs(meshPath);
|
||||||
|
|
||||||
|
SystemString meshPathRel =
|
||||||
|
conn.getBlendPath().getProject().getProjectRootPath().getProjectRelativeFromAbsolute(meshPathAbs.sys_str());
|
||||||
|
mesh.assign(conn.getBlendPath().getProject().getProjectWorkingPath(), meshPathRel);
|
||||||
|
}
|
||||||
|
|
||||||
|
conn._readBuf(&armature, 4);
|
||||||
|
}
|
||||||
|
|
||||||
Action::Action(Connection& conn)
|
Action::Action(Connection& conn)
|
||||||
{
|
{
|
||||||
uint32_t bufSz;
|
uint32_t bufSz;
|
||||||
@ -2234,6 +2263,37 @@ std::vector<std::string> DataStream::getSubtypeOverlayNames(std::string_view nam
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> DataStream::getAttachmentNames()
|
||||||
|
{
|
||||||
|
if (m_parent->getBlendType() != BlendType::Actor)
|
||||||
|
BlenderLog.report(logvisor::Fatal, _S("%s is not an ACTOR blend"),
|
||||||
|
m_parent->getBlendPath().getAbsolutePath().data());
|
||||||
|
|
||||||
|
m_parent->_writeStr("GETATTACHMENTNAMES");
|
||||||
|
|
||||||
|
char readBuf[256];
|
||||||
|
m_parent->_readStr(readBuf, 256);
|
||||||
|
if (strcmp(readBuf, "OK"))
|
||||||
|
BlenderLog.report(logvisor::Fatal, "unable to get attachments of actor: %s", readBuf);
|
||||||
|
|
||||||
|
std::vector<std::string> ret;
|
||||||
|
|
||||||
|
uint32_t attCount;
|
||||||
|
m_parent->_readBuf(&attCount, 4);
|
||||||
|
ret.reserve(attCount);
|
||||||
|
for (uint32_t i=0 ; i<attCount ; ++i)
|
||||||
|
{
|
||||||
|
ret.emplace_back();
|
||||||
|
std::string& name = ret.back();
|
||||||
|
uint32_t bufSz;
|
||||||
|
m_parent->_readBuf(&bufSz, 4);
|
||||||
|
name.assign(bufSz, ' ');
|
||||||
|
m_parent->_readBuf(&name[0], bufSz);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
std::unordered_map<std::string, Matrix3f>
|
std::unordered_map<std::string, Matrix3f>
|
||||||
DataStream::getBoneMatrices(std::string_view name)
|
DataStream::getBoneMatrices(std::string_view name)
|
||||||
{
|
{
|
||||||
|
@ -77,7 +77,7 @@ void ProjectPath::assign(Database::Project& project, SystemStringView path)
|
|||||||
m_absPath = SystemString(project.getProjectRootPath().getAbsolutePath()) + _S('/') + m_relPath;
|
m_absPath = SystemString(project.getProjectRootPath().getAbsolutePath()) + _S('/') + m_relPath;
|
||||||
SanitizePath(m_relPath);
|
SanitizePath(m_relPath);
|
||||||
SanitizePath(m_absPath);
|
SanitizePath(m_absPath);
|
||||||
|
|
||||||
ComputeHash();
|
ComputeHash();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,6 +119,38 @@ void ProjectPath::assign(const ProjectPath& parentPath, std::string_view path)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
ProjectPath ProjectPath::getWithExtension(const SystemChar* ext, bool replace) const
|
||||||
|
{
|
||||||
|
ProjectPath pp(*this);
|
||||||
|
if (replace)
|
||||||
|
{
|
||||||
|
auto relIt = pp.m_relPath.end();
|
||||||
|
if (relIt != pp.m_relPath.begin())
|
||||||
|
--relIt;
|
||||||
|
auto absIt = pp.m_absPath.end();
|
||||||
|
if (absIt != pp.m_absPath.begin())
|
||||||
|
--absIt;
|
||||||
|
while (relIt != pp.m_relPath.begin() && *relIt != _S('.') && *relIt != _S('/'))
|
||||||
|
{
|
||||||
|
--relIt;
|
||||||
|
--absIt;
|
||||||
|
}
|
||||||
|
if (*relIt == _S('.') && relIt != pp.m_relPath.begin())
|
||||||
|
{
|
||||||
|
pp.m_relPath.resize(relIt - pp.m_relPath.begin());
|
||||||
|
pp.m_absPath.resize(absIt - pp.m_absPath.begin());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ext)
|
||||||
|
{
|
||||||
|
pp.m_relPath += ext;
|
||||||
|
pp.m_absPath += ext;
|
||||||
|
}
|
||||||
|
|
||||||
|
pp.ComputeHash();
|
||||||
|
return pp;
|
||||||
|
}
|
||||||
|
|
||||||
ProjectPath ProjectPath::getCookedPath(const Database::DataSpecEntry& spec) const
|
ProjectPath ProjectPath::getCookedPath(const Database::DataSpecEntry& spec) const
|
||||||
{
|
{
|
||||||
ProjectPath woExt = getWithExtension(nullptr, true);
|
ProjectPath woExt = getWithExtension(nullptr, true);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user