mirror of https://github.com/AxioDL/metaforce.git
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
|
||||
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")
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit bba2486c15498a307eb1c009edba09ec10a10294
|
||||
Subproject commit f917d154b2ff38a5cbeea8c536c91e7813be060d
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
namespace hecl::Backend
|
||||
{
|
||||
struct ExtensionSlot;
|
||||
|
||||
using IR = Frontend::IR;
|
||||
using Diagnostics = Frontend::Diagnostics;
|
||||
|
@ -159,6 +160,9 @@ public:
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
boo::AdditionalPipelineInfo additionalInfo(const ExtensionSlot& ext,
|
||||
std::pair<BlendFactor, BlendFactor> blendFactors) const;
|
||||
};
|
||||
|
||||
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
|
||||
|
|
|
@ -504,6 +504,14 @@ struct Actor
|
|||
Subtype(Connection& conn);
|
||||
};
|
||||
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;
|
||||
|
||||
Actor(Connection& conn);
|
||||
|
@ -572,6 +580,7 @@ public:
|
|||
std::vector<std::string> getSubtypeNames();
|
||||
std::vector<std::string> getActionNames();
|
||||
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);
|
||||
|
||||
|
|
|
@ -83,6 +83,9 @@ public:
|
|||
m_extension.texCount, m_extension.texs);
|
||||
}
|
||||
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>
|
||||
|
@ -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_vtxFmtData = in.getTag().vertexFormat();
|
||||
m_vtxFmt = boo::VertexFormatInfo(m_vtxFmtData.size(), m_vtxFmtData.data());
|
||||
m_additionalInfo = in.getTag().additionalInfo(in.extension(), in.blendFactors());
|
||||
MakeHash();
|
||||
}
|
||||
|
||||
|
|
|
@ -66,9 +66,7 @@ public:
|
|||
uint64_t Hash() const { return m_hash; }
|
||||
|
||||
explicit StageSourceText(std::string_view text)
|
||||
{
|
||||
m_hash = XXH64(m_text.data(), m_text.size(), 0);
|
||||
}
|
||||
: m_text(text), m_hash(XXH64(m_text.data(), m_text.size(), 0)) {}
|
||||
std::string_view text() const { return m_text; }
|
||||
};
|
||||
|
||||
|
|
|
@ -834,37 +834,7 @@ public:
|
|||
* @param replace remove existing extension (if any) before appending new extension
|
||||
* @return new path with extension
|
||||
*/
|
||||
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;
|
||||
}
|
||||
ProjectPath getWithExtension(const SystemChar* ext, bool replace=false) const;
|
||||
|
||||
/**
|
||||
* @brief Access fully-canonicalized absolute path
|
||||
|
@ -1063,7 +1033,10 @@ public:
|
|||
*/
|
||||
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
|
||||
|
|
|
@ -1546,6 +1546,12 @@ Actor::Actor(Connection& conn)
|
|||
for (uint32_t i=0 ; i<subtypeCount ; ++i)
|
||||
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;
|
||||
conn._readBuf(&actionCount, 4);
|
||||
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)
|
||||
{
|
||||
uint32_t bufSz;
|
||||
|
@ -2234,6 +2263,37 @@ std::vector<std::string> DataStream::getSubtypeOverlayNames(std::string_view nam
|
|||
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>
|
||||
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;
|
||||
SanitizePath(m_relPath);
|
||||
SanitizePath(m_absPath);
|
||||
|
||||
|
||||
ComputeHash();
|
||||
}
|
||||
|
||||
|
@ -119,6 +119,38 @@ void ProjectPath::assign(const ProjectPath& parentPath, std::string_view path)
|
|||
}
|
||||
#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 woExt = getWithExtension(nullptr, true);
|
||||
|
|
Loading…
Reference in New Issue