mirror of https://github.com/AxioDL/metaforce.git
Code style improvements
This commit is contained in:
parent
0b30fedef5
commit
8a73a8ee48
|
@ -10,6 +10,7 @@ list(APPEND PY_SOURCES
|
|||
hecl/sact/SACTSubtype.py
|
||||
hecl/srea/__init__.py
|
||||
hecl/swld/__init__.py
|
||||
hecl/armature.py
|
||||
hecl/mapa.py
|
||||
hecl/mapu.py
|
||||
hecl/frme.py
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
# Node Grid Arranger Class
|
||||
NODE_PADDING = 80
|
||||
FRAME_NAMES = ['Textures','Output']
|
||||
FRAME_WIDTHS = [400, 180]
|
||||
FRAME_NAMES = ['Textures','Output','Blend']
|
||||
FRAME_WIDTHS = [400, 180, 180]
|
||||
TOTAL_WIDTH = 0.0
|
||||
for width in FRAME_WIDTHS:
|
||||
TOTAL_WIDTH += width + NODE_PADDING
|
||||
FRAME_COLORS = [(0.6,0.48,0.44),(0.53,0.6,0.47)]
|
||||
FRAME_COLORS = [(0.6,0.48,0.44),(0.53,0.6,0.47),(0.56,0.46,0.90)]
|
||||
class Nodegrid:
|
||||
|
||||
def __init__(self, nodetree, cycles=False):
|
||||
|
|
|
@ -9,7 +9,7 @@ bl_info = {
|
|||
"category": "System"}
|
||||
|
||||
# Package import
|
||||
from . import hmdl, sact, srea, swld, mapa, mapu, frme, path, Nodegrid, Patching
|
||||
from . import hmdl, sact, srea, swld, armature, mapa, mapu, frme, path, Nodegrid, Patching
|
||||
Nodegrid = Nodegrid.Nodegrid
|
||||
parent_armature = sact.SACTSubtype.parent_armature
|
||||
import bpy, os, sys, struct, math
|
||||
|
@ -20,6 +20,7 @@ hecl_typeS = [
|
|||
('NONE', "None", "Active scene not using HECL", None),
|
||||
('MESH', "Mesh", "Active scene represents an HMDL Mesh", hmdl.draw),
|
||||
('CMESH', "Collision Mesh", "Active scene represents a Collision Mesh", None),
|
||||
('ARMATURE', "Armature", "Active scene represents an Armature", armature.draw),
|
||||
('ACTOR', "Actor", "Active scene represents a HECL Actor", sact.draw),
|
||||
('AREA', "Area", "Active scene represents a HECL Area", srea.draw),
|
||||
('WORLD', "World", "Active scene represents a HECL World", swld.draw),
|
||||
|
@ -141,8 +142,9 @@ from bpy.app.handlers import persistent
|
|||
@persistent
|
||||
def scene_loaded(dummy):
|
||||
# Hide everything from an external library
|
||||
if bpy.context.scene.hecl_type != 'FRAME':
|
||||
for o in bpy.context.scene.objects:
|
||||
if o.library:
|
||||
if o.library or (o.data and o.data.library):
|
||||
o.hide_set(True)
|
||||
|
||||
# Show PATH library objects as wireframes
|
||||
|
@ -208,6 +210,7 @@ def register():
|
|||
mapa.register()
|
||||
mapu.register()
|
||||
path.register()
|
||||
armature.register()
|
||||
bpy.utils.register_class(hecl_scene_panel)
|
||||
bpy.utils.register_class(hecl_light_panel)
|
||||
bpy.types.Scene.hecl_auto_select = bpy.props.BoolProperty(name='HECL Auto Select', default=True)
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
import struct
|
||||
|
||||
def cook(writebuf, arm):
|
||||
writebuf(struct.pack('I', len(arm.bones)))
|
||||
for bone in arm.bones:
|
||||
writebuf(struct.pack('I', len(bone.name)))
|
||||
writebuf(bone.name.encode())
|
||||
|
||||
writebuf(struct.pack('fff', bone.head_local[0], bone.head_local[1], bone.head_local[2]))
|
||||
|
||||
if bone.parent:
|
||||
writebuf(struct.pack('i', arm.bones.find(bone.parent.name)))
|
||||
else:
|
||||
writebuf(struct.pack('i', -1))
|
||||
|
||||
writebuf(struct.pack('I', len(bone.children)))
|
||||
for child in bone.children:
|
||||
writebuf(struct.pack('i', arm.bones.find(child.name)))
|
||||
|
||||
def draw(layout, context):
|
||||
layout.prop_search(context.scene, 'hecl_arm_obj', context.scene, 'objects')
|
||||
if not len(context.scene.hecl_arm_obj):
|
||||
layout.label(text="Armature not specified", icon='ERROR')
|
||||
elif context.scene.hecl_arm_obj not in context.scene.objects:
|
||||
layout.label(text="'"+context.scene.hecl_arm_obj+"' not in scene", icon='ERROR')
|
||||
else:
|
||||
obj = context.scene.objects[context.scene.hecl_arm_obj]
|
||||
if obj.type != 'ARMATURE':
|
||||
layout.label(text="'"+context.scene.hecl_arm_obj+"' not an 'ARMATURE'", icon='ERROR')
|
||||
|
||||
import bpy
|
||||
def register():
|
||||
bpy.types.Scene.hecl_arm_obj = bpy.props.StringProperty(
|
||||
name='HECL Armature Object',
|
||||
description='Blender Armature Object to export during HECL\'s cook process')
|
|
@ -1,6 +1,12 @@
|
|||
import struct, bpy, bmesh
|
||||
from . import HMDLShader, HMDLMesh
|
||||
|
||||
BLEND_TYPES = {
|
||||
'HECLAdditiveOutput': 2,
|
||||
'HECLBlendOutput': 1,
|
||||
'HECLOpaqueOutput': 0,
|
||||
}
|
||||
|
||||
def write_out_material(writebuf, mat, mesh_obj):
|
||||
writebuf(struct.pack('I', len(mat.name)))
|
||||
writebuf(mat.name.encode())
|
||||
|
@ -20,12 +26,10 @@ def write_out_material(writebuf, mat, mesh_obj):
|
|||
writebuf(prop[0].encode())
|
||||
writebuf(struct.pack('i', prop[1]))
|
||||
|
||||
blend = 0
|
||||
if mat.blend_method == 'BLEND':
|
||||
blend = 1
|
||||
elif mat.blend_method == 'ADD':
|
||||
blend = 2
|
||||
writebuf(struct.pack('I', blend))
|
||||
blend_node = mat.node_tree.nodes['Blend']
|
||||
if blend_node.node_tree.name not in BLEND_TYPES:
|
||||
raise RuntimeError("HMDL *requires* one of the HMDL*Output group nodes for the 'Blend' node")
|
||||
writebuf(struct.pack('I', BLEND_TYPES[blend_node.node_tree.name]))
|
||||
|
||||
# Takes a Blender 'Mesh' object (not the datablock)
|
||||
# and performs a one-shot conversion process to HMDL
|
||||
|
@ -256,6 +260,7 @@ def draw(layout, context):
|
|||
obj = context.scene.objects[context.scene.hecl_mesh_obj]
|
||||
if obj.type != 'MESH':
|
||||
layout.label(text="'"+context.scene.hecl_mesh_obj+"' not a 'MESH'", icon='ERROR')
|
||||
layout.prop(obj.data, 'cskr_id')
|
||||
layout.prop(obj.data, 'hecl_active_material')
|
||||
layout.prop(obj.data, 'hecl_material_count')
|
||||
|
||||
|
@ -297,6 +302,7 @@ def register():
|
|||
bpy.types.Scene.hecl_actor_obj = bpy.props.StringProperty(
|
||||
name='HECL Actor Object',
|
||||
description='Blender Empty Object to export during HECL\'s cook process')
|
||||
bpy.types.Mesh.cskr_id = bpy.props.StringProperty(name='Original CSKR ID')
|
||||
bpy.types.Mesh.hecl_material_count = bpy.props.IntProperty(name='HECL Material Count', default=0, min=0)
|
||||
bpy.types.Mesh.hecl_active_material = bpy.props.IntProperty(name='HECL Active Material', default=0, min=0, update=material_update)
|
||||
bpy.utils.register_class(hecl_mesh_operator)
|
||||
|
|
|
@ -52,6 +52,7 @@ def draw(layout, context):
|
|||
else:
|
||||
#layout.prop(linked_action, 'hecl_index', text="Index")
|
||||
#layout.prop(linked_action, 'hecl_anim_props', text="Props")
|
||||
layout.prop(linked_action, 'anim_id', text="ANIM ID")
|
||||
layout.prop(linked_action, 'hecl_fps', text="Frame Rate")
|
||||
row = layout.row()
|
||||
row.prop(context.scene, 'hecl_auto_remap', text="60-fps Remap")
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from . import SACTSubtype, SACTAction, ANIM
|
||||
from .. import armature
|
||||
|
||||
import bpy
|
||||
import bpy.path
|
||||
|
@ -207,21 +208,14 @@ def _out_armatures(sact_data, writebuf):
|
|||
writebuf(struct.pack('I', len(arm.name)))
|
||||
writebuf(arm.name.encode())
|
||||
|
||||
writebuf(struct.pack('I', len(arm.bones)))
|
||||
for bone in arm.bones:
|
||||
writebuf(struct.pack('I', len(bone.name)))
|
||||
writebuf(bone.name.encode())
|
||||
|
||||
writebuf(struct.pack('fff', bone.head_local[0], bone.head_local[1], bone.head_local[2]))
|
||||
|
||||
if bone.parent:
|
||||
writebuf(struct.pack('i', arm.bones.find(bone.parent.name)))
|
||||
if arm.library:
|
||||
arm_path = bpy.path.abspath(arm.library.filepath)
|
||||
writebuf(struct.pack('I', len(arm_path)))
|
||||
writebuf(arm_path.encode())
|
||||
else:
|
||||
writebuf(struct.pack('i', -1))
|
||||
writebuf(struct.pack('I', 0))
|
||||
|
||||
writebuf(struct.pack('I', len(bone.children)))
|
||||
for child in bone.children:
|
||||
writebuf(struct.pack('i', arm.bones.find(child.name)))
|
||||
armature.cook(writebuf, arm)
|
||||
|
||||
def _out_subtypes(sact_data, writebuf):
|
||||
writebuf(struct.pack('I', len(sact_data.subtypes)))
|
||||
|
@ -232,9 +226,14 @@ def _out_subtypes(sact_data, writebuf):
|
|||
mesh = None
|
||||
if subtype.linked_mesh in bpy.data.objects:
|
||||
mesh = bpy.data.objects[subtype.linked_mesh]
|
||||
cskr_id = mesh.data.cskr_id
|
||||
writebuf(struct.pack('I', len(cskr_id)))
|
||||
writebuf(cskr_id.encode())
|
||||
else:
|
||||
writebuf(struct.pack('I', 0))
|
||||
|
||||
if mesh and mesh.library:
|
||||
mesh_path = bpy.path.abspath(mesh.library.filepath)
|
||||
if mesh and mesh.data.library:
|
||||
mesh_path = bpy.path.abspath(mesh.data.library.filepath)
|
||||
writebuf(struct.pack('I', len(mesh_path)))
|
||||
writebuf(mesh_path.encode())
|
||||
else:
|
||||
|
@ -257,9 +256,14 @@ def _out_subtypes(sact_data, writebuf):
|
|||
mesh = None
|
||||
if overlay.linked_mesh in bpy.data.objects:
|
||||
mesh = bpy.data.objects[overlay.linked_mesh]
|
||||
cskr_id = mesh.data.cskr_id
|
||||
writebuf(struct.pack('I', len(cskr_id)))
|
||||
writebuf(cskr_id.encode())
|
||||
else:
|
||||
writebuf(struct.pack('I', 0))
|
||||
|
||||
if mesh and mesh.library:
|
||||
mesh_path = bpy.path.abspath(mesh.library.filepath)
|
||||
if mesh and mesh.data.library:
|
||||
mesh_path = bpy.path.abspath(mesh.data.library.filepath)
|
||||
writebuf(struct.pack('I', len(mesh_path)))
|
||||
writebuf(mesh_path.encode())
|
||||
else:
|
||||
|
@ -274,9 +278,14 @@ def _out_attachments(sact_data, writebuf):
|
|||
mesh = None
|
||||
if attachment.linked_mesh in bpy.data.objects:
|
||||
mesh = bpy.data.objects[attachment.linked_mesh]
|
||||
cskr_id = mesh.data.cskr_id
|
||||
writebuf(struct.pack('I', len(cskr_id)))
|
||||
writebuf(cskr_id.encode())
|
||||
else:
|
||||
writebuf(struct.pack('I', 0))
|
||||
|
||||
if mesh and mesh.library:
|
||||
mesh_path = bpy.path.abspath(mesh.library.filepath)
|
||||
if mesh and mesh.data.library:
|
||||
mesh_path = bpy.path.abspath(mesh.data.library.filepath)
|
||||
writebuf(struct.pack('I', len(mesh_path)))
|
||||
writebuf(mesh_path.encode())
|
||||
else:
|
||||
|
@ -302,6 +311,9 @@ def _out_actions(sact_data, writebuf):
|
|||
bact = None
|
||||
if action.name in bpy.data.actions:
|
||||
bact = bpy.data.actions[action.name]
|
||||
anim_id = bact.anim_id
|
||||
writebuf(struct.pack('I', len(anim_id)))
|
||||
writebuf(anim_id.encode())
|
||||
if not bact:
|
||||
raise RuntimeError('action %s not found' % action.name)
|
||||
|
||||
|
@ -334,6 +346,9 @@ def _out_action_no_subtypes(sact_data, writebuf, action_name):
|
|||
bact = None
|
||||
if action.name in bpy.data.actions:
|
||||
bact = bpy.data.actions[action.name]
|
||||
anim_id = bact.anim_id
|
||||
writebuf(struct.pack('I', len(anim_id)))
|
||||
writebuf(anim_id.encode())
|
||||
if not bact:
|
||||
raise RuntimeError('action %s not found' % action.name)
|
||||
|
||||
|
@ -386,14 +401,6 @@ def cook_action_channels_only(writebuf, action_name):
|
|||
# Output action without AABBs
|
||||
_out_action_no_subtypes(sact_data, writebuf, action_name)
|
||||
|
||||
|
||||
# Access actor's contained armature names
|
||||
def get_armature_names(writebuf):
|
||||
writebuf(struct.pack('I', len(bpy.data.armatures)))
|
||||
for arm in bpy.data.armatures:
|
||||
writebuf(struct.pack('I', len(arm.name)))
|
||||
writebuf(arm.name.encode())
|
||||
|
||||
# Access actor's contained subtype names
|
||||
def get_subtype_names(writebuf):
|
||||
sact_data = bpy.context.scene.hecl_sact_data
|
||||
|
@ -402,6 +409,10 @@ def get_subtype_names(writebuf):
|
|||
subtype = sact_data.subtypes[sub_idx]
|
||||
writebuf(struct.pack('I', len(subtype.name)))
|
||||
writebuf(subtype.name.encode())
|
||||
obj = bpy.data.objects[subtype.linked_mesh]
|
||||
cskr_id = obj.data.cskr_id
|
||||
writebuf(struct.pack('I', len(cskr_id)))
|
||||
writebuf(cskr_id.encode())
|
||||
|
||||
# Access subtype's contained overlay names
|
||||
def get_subtype_overlay_names(writebuf, subtypeName):
|
||||
|
@ -413,6 +424,10 @@ def get_subtype_overlay_names(writebuf, subtypeName):
|
|||
for overlay in subtype.overlays:
|
||||
writebuf(struct.pack('I', len(overlay.name)))
|
||||
writebuf(overlay.name.encode())
|
||||
obj = bpy.data.objects[overlay.linked_mesh]
|
||||
cskr_id = obj.data.cskr_id
|
||||
writebuf(struct.pack('I', len(cskr_id)))
|
||||
writebuf(cskr_id.encode())
|
||||
return
|
||||
writebuf(struct.pack('I', 0))
|
||||
|
||||
|
@ -424,6 +439,10 @@ def get_attachment_names(writebuf):
|
|||
attachment = sact_data.attachments[att_idx]
|
||||
writebuf(struct.pack('I', len(attachment.name)))
|
||||
writebuf(attachment.name.encode())
|
||||
obj = bpy.data.objects[attachment.linked_mesh]
|
||||
cskr_id = obj.data.cskr_id
|
||||
writebuf(struct.pack('I', len(cskr_id)))
|
||||
writebuf(cskr_id.encode())
|
||||
|
||||
# Access actor's contained action names
|
||||
def get_action_names(writebuf):
|
||||
|
@ -433,6 +452,9 @@ def get_action_names(writebuf):
|
|||
action = sact_data.actions[action_idx]
|
||||
writebuf(struct.pack('I', len(action.name)))
|
||||
writebuf(action.name.encode())
|
||||
anim_id = bpy.data.actions[action.name].anim_id
|
||||
writebuf(struct.pack('I', len(anim_id)))
|
||||
writebuf(anim_id.encode())
|
||||
|
||||
# Panel draw
|
||||
def draw(layout, context):
|
||||
|
@ -452,6 +474,7 @@ def register():
|
|||
SACTAction.register()
|
||||
bpy.utils.register_class(SACTData)
|
||||
bpy.types.Scene.hecl_sact_data = bpy.props.PointerProperty(type=SACTData)
|
||||
bpy.types.Action.anim_id = bpy.props.StringProperty(name='Original ANIM ID')
|
||||
bpy.types.Action.hecl_fps = bpy.props.IntProperty(name='HECL Action FPS', default=30)
|
||||
bpy.types.Action.hecl_additive = bpy.props.BoolProperty(name='HECL Additive Action', default=False)
|
||||
bpy.types.Action.hecl_looping = bpy.props.BoolProperty(name='HECL Looping Action', default=False)
|
||||
|
|
|
@ -55,17 +55,7 @@ class PathHasher:
|
|||
def hashpath32(self, path):
|
||||
writepipestr(path.encode())
|
||||
read_str = readpipestr()
|
||||
if len(read_str) >= 16:
|
||||
hash = int(read_str[0:16], 16)
|
||||
return (hash & 0xffffffff) ^ ((hash >> 32) & 0xffffffff)
|
||||
return 0
|
||||
|
||||
def hashpath64(self, path):
|
||||
writepipestr(path.encode())
|
||||
read_str = readpipestr()
|
||||
if len(read_str) >= 16:
|
||||
return int(read_str[0:16], 16)
|
||||
return 0
|
||||
return int(read_str[0:8], 16)
|
||||
|
||||
# Ensure Blender 2.8 is being used
|
||||
if bpy.app.version < (2, 80, 0):
|
||||
|
@ -226,21 +216,21 @@ def dataout_loop():
|
|||
elif cmdargs[0] == 'MESHLIST':
|
||||
meshCount = 0
|
||||
for meshobj in bpy.data.objects:
|
||||
if meshobj.type == 'MESH' and not meshobj.library:
|
||||
if meshobj.type == 'MESH' and not meshobj.data.library:
|
||||
meshCount += 1
|
||||
writepipebuf(struct.pack('I', meshCount))
|
||||
for meshobj in bpy.data.objects:
|
||||
if meshobj.type == 'MESH' and not meshobj.library:
|
||||
if meshobj.type == 'MESH' and not meshobj.data.library:
|
||||
writepipestr(meshobj.name.encode())
|
||||
|
||||
elif cmdargs[0] == 'LIGHTLIST':
|
||||
lightCount = 0
|
||||
for obj in bpy.context.scene.objects:
|
||||
if obj.type == 'LIGHT' and not obj.library:
|
||||
if obj.type == 'LIGHT' and not obj.data.library:
|
||||
lightCount += 1
|
||||
writepipebuf(struct.pack('I', lightCount))
|
||||
for obj in bpy.context.scene.objects:
|
||||
if obj.type == 'LIGHT' and not obj.library:
|
||||
if obj.type == 'LIGHT' and not obj.data.library:
|
||||
writepipestr(obj.name.encode())
|
||||
|
||||
elif cmdargs[0] == 'MESHAABB':
|
||||
|
@ -256,6 +246,15 @@ def dataout_loop():
|
|||
writepipestr(b'OK')
|
||||
hecl.hmdl.cook(writepipebuf, bpy.data.objects[meshName])
|
||||
|
||||
elif cmdargs[0] == 'ARMATURECOMPILE':
|
||||
armName = bpy.context.scene.hecl_arm_obj
|
||||
if armName not in bpy.data.objects:
|
||||
writepipestr(('armature %s not found' % armName).encode())
|
||||
continue
|
||||
|
||||
writepipestr(b'OK')
|
||||
hecl.armature.cook(writepipebuf, bpy.data.objects[armName].data)
|
||||
|
||||
elif cmdargs[0] == 'MESHCOMPILENAME':
|
||||
meshName = cmdargs[1]
|
||||
useLuv = int(cmdargs[2])
|
||||
|
@ -281,13 +280,13 @@ def dataout_loop():
|
|||
writepipestr(b'OK')
|
||||
colCount = 0
|
||||
for obj in bpy.context.scene.objects:
|
||||
if obj.type == 'MESH' and not obj.library:
|
||||
if obj.type == 'MESH' and not obj.data.library:
|
||||
colCount += 1
|
||||
|
||||
writepipebuf(struct.pack('I', colCount))
|
||||
|
||||
for obj in bpy.context.scene.objects:
|
||||
if obj.type == 'MESH' and not obj.library:
|
||||
if obj.type == 'MESH' and not obj.data.library:
|
||||
hecl.hmdl.cookcol(writepipebuf, obj)
|
||||
|
||||
elif cmdargs[0] == 'MESHCOMPILEPATH':
|
||||
|
@ -384,10 +383,6 @@ def dataout_loop():
|
|||
writepipestr(b'OK')
|
||||
hecl.sact.cook_action_channels_only(writepipebuf, actionName)
|
||||
|
||||
elif cmdargs[0] == 'GETARMATURENAMES':
|
||||
writepipestr(b'OK')
|
||||
hecl.sact.get_armature_names(writepipebuf)
|
||||
|
||||
elif cmdargs[0] == 'GETSUBTYPENAMES':
|
||||
writepipestr(b'OK')
|
||||
hecl.sact.get_subtype_names(writepipebuf)
|
||||
|
|
|
@ -26,7 +26,7 @@ public:
|
|||
for (const hecl::SystemString& arg : info.args) {
|
||||
if (arg.empty())
|
||||
continue;
|
||||
else if (!arg.compare(_SYS_STR("--fast"))) {
|
||||
else if (arg == _SYS_STR("--fast")) {
|
||||
m_fast = true;
|
||||
continue;
|
||||
} else if (arg.size() >= 8 && !arg.compare(0, 7, _SYS_STR("--spec="))) {
|
||||
|
|
|
@ -20,15 +20,10 @@ class ToolPackage final : public ToolBase {
|
|||
}
|
||||
|
||||
void CheckFile(const hecl::ProjectPath& path) {
|
||||
if (!hecl::StrCmp(path.getLastComponent().data(), _SYS_STR("!world.blend")))
|
||||
auto lastComp = path.getLastComponent();
|
||||
if (hecl::StringUtils::BeginsWith(lastComp, _SYS_STR("!world_")) &&
|
||||
hecl::StringUtils::EndsWith(lastComp, _SYS_STR(".blend")))
|
||||
AddSelectedItem(path);
|
||||
#if RUNTIME_ORIGINAL_IDS
|
||||
else if (!hecl::StrCmp(path.getLastComponent().data(), _SYS_STR("!original_ids.yaml"))) {
|
||||
auto pathComps = path.getPathComponents();
|
||||
if (pathComps.size() == 2 && pathComps[0] != _SYS_STR("out"))
|
||||
AddSelectedItem(path);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void FindSelectedItems(const hecl::ProjectPath& path, bool checkGeneral) {
|
||||
|
@ -70,7 +65,7 @@ public:
|
|||
for (const hecl::SystemString& arg : info.args) {
|
||||
if (arg.empty())
|
||||
continue;
|
||||
else if (!arg.compare(_SYS_STR("--fast"))) {
|
||||
else if (arg == _SYS_STR("--fast")) {
|
||||
m_fast = true;
|
||||
continue;
|
||||
} else if (arg.size() >= 8 && !arg.compare(0, 7, _SYS_STR("--spec="))) {
|
||||
|
|
|
@ -19,9 +19,9 @@ public:
|
|||
hecl::SystemString firstArg = info.args.front();
|
||||
hecl::ToLower(firstArg);
|
||||
|
||||
if (!firstArg.compare(_SYS_STR("enable")))
|
||||
if (firstArg == _SYS_STR("enable"))
|
||||
mode = MENABLE;
|
||||
else if (!firstArg.compare(_SYS_STR("disable")))
|
||||
else if (firstArg == _SYS_STR("disable"))
|
||||
mode = MDISABLE;
|
||||
else
|
||||
return;
|
||||
|
@ -112,7 +112,7 @@ public:
|
|||
for (auto& spec : specs) {
|
||||
hecl::SystemString compName(spec.spec.m_name);
|
||||
hecl::ToLower(compName);
|
||||
if (!itName.compare(compName)) {
|
||||
if (itName == compName) {
|
||||
opSpecs.emplace_back(spec.spec.m_name);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 132c7def65a78f5915e199de805abb672c291d98
|
||||
Subproject commit 42581c922a4574f4f34df134a454effa9f9cc8d0
|
|
@ -1 +1 @@
|
|||
Subproject commit 9b8ef4695f3f1d07b29580241fc266abc17dc29c
|
||||
Subproject commit 922fcbb3c23677b3ccc53737fd23ada165ccf9f3
|
|
@ -81,7 +81,8 @@ class PyOutStream : public std::ostream {
|
|||
StreamBuf(PyOutStream& parent, bool deleteOnError) : m_parent(parent), m_deleteOnError(deleteOnError) {}
|
||||
StreamBuf(const StreamBuf& other) = delete;
|
||||
StreamBuf(StreamBuf&& other) = default;
|
||||
int_type overflow(int_type ch) override;
|
||||
bool sendLine(std::string_view line);
|
||||
std::streamsize xsputn(const char_type* __s, std::streamsize __n) override;
|
||||
} m_sbuf;
|
||||
PyOutStream(Connection* parent, bool deleteOnError);
|
||||
|
||||
|
@ -94,8 +95,10 @@ public:
|
|||
void close();
|
||||
template <typename S, typename... Args, typename Char = fmt::char_t<S>>
|
||||
void format(const S& format, Args&&... args);
|
||||
void linkBlend(const char* target, const char* objName, bool link = true);
|
||||
void linkBackground(const char* target, const char* sceneName = nullptr);
|
||||
void linkBlend(std::string_view target, std::string_view objName, bool link = true);
|
||||
void linkArmature(std::string_view target, std::string_view armName);
|
||||
void linkMesh(std::string_view target, std::string_view meshName);
|
||||
void linkBackground(std::string_view target, std::string_view sceneName = {});
|
||||
void AABBToBMesh(const atVec3f& min, const atVec3f& max);
|
||||
void centerView();
|
||||
|
||||
|
@ -498,15 +501,15 @@ struct Light {
|
|||
|
||||
/** Intermediate MapArea representation */
|
||||
struct MapArea {
|
||||
Index visType;
|
||||
uint32_t visType;
|
||||
std::vector<Vector3f> verts;
|
||||
std::vector<Index> indices;
|
||||
std::vector<uint32_t> indices;
|
||||
struct Surface {
|
||||
Vector3f normal;
|
||||
Vector3f centerOfMass;
|
||||
Index start;
|
||||
Index count;
|
||||
std::vector<std::pair<Index, Index>> borders;
|
||||
uint32_t start;
|
||||
uint32_t count;
|
||||
std::vector<std::pair<uint32_t, uint32_t>> borders;
|
||||
Surface(Connection& conn);
|
||||
};
|
||||
std::vector<Surface> surfaces;
|
||||
|
@ -547,7 +550,6 @@ struct Bone {
|
|||
|
||||
/** Intermediate armature representation used in Actor */
|
||||
struct Armature {
|
||||
std::string name;
|
||||
std::vector<Bone> bones;
|
||||
const Bone* lookupBone(const char* name) const;
|
||||
const Bone* getParent(const Bone* bone) const;
|
||||
|
@ -559,6 +561,7 @@ struct Armature {
|
|||
/** Intermediate action representation used in Actor */
|
||||
struct Action {
|
||||
std::string name;
|
||||
std::string animId;
|
||||
float interval;
|
||||
bool additive;
|
||||
bool looping;
|
||||
|
@ -582,18 +585,32 @@ struct Action {
|
|||
|
||||
/** Intermediate actor representation prepared by blender from a single HECL actor blend */
|
||||
struct Actor {
|
||||
std::vector<Armature> armatures;
|
||||
struct ActorArmature {
|
||||
std::string name;
|
||||
ProjectPath path;
|
||||
std::optional<Armature> armature;
|
||||
ActorArmature(Connection& conn);
|
||||
};
|
||||
std::vector<ActorArmature> armatures;
|
||||
|
||||
struct Subtype {
|
||||
std::string name;
|
||||
std::string cskrId;
|
||||
ProjectPath mesh;
|
||||
int32_t armature = -1;
|
||||
std::vector<std::pair<std::string, ProjectPath>> overlayMeshes;
|
||||
struct OverlayMesh {
|
||||
std::string name;
|
||||
std::string cskrId;
|
||||
ProjectPath mesh;
|
||||
OverlayMesh(Connection& conn);
|
||||
};
|
||||
std::vector<OverlayMesh> overlayMeshes;
|
||||
Subtype(Connection& conn);
|
||||
};
|
||||
std::vector<Subtype> subtypes;
|
||||
struct Attachment {
|
||||
std::string name;
|
||||
std::string cskrId;
|
||||
ProjectPath mesh;
|
||||
int32_t armature = -1;
|
||||
Attachment(Connection& conn);
|
||||
|
@ -654,12 +671,12 @@ public:
|
|||
|
||||
Actor compileActor();
|
||||
Actor compileActorCharacterOnly();
|
||||
Armature compileArmature();
|
||||
Action compileActionChannelsOnly(std::string_view name);
|
||||
std::vector<std::string> getArmatureNames();
|
||||
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::vector<std::pair<std::string, std::string>> getSubtypeNames();
|
||||
std::vector<std::pair<std::string, std::string>> getActionNames();
|
||||
std::vector<std::pair<std::string, std::string>> getSubtypeOverlayNames(std::string_view name);
|
||||
std::vector<std::pair<std::string, std::string>> getAttachmentNames();
|
||||
|
||||
std::unordered_map<std::string, Matrix3f> getBoneMatrices(std::string_view name);
|
||||
|
||||
|
@ -695,6 +712,7 @@ class Connection {
|
|||
friend struct Vector3f;
|
||||
friend struct Vector4f;
|
||||
friend struct World;
|
||||
friend class MeshOptimizer;
|
||||
|
||||
std::atomic_bool m_lock = {false};
|
||||
bool m_pyStreamActive = false;
|
||||
|
@ -718,6 +736,80 @@ class Connection {
|
|||
uint32_t _writeStr(std::string_view view) { return _writeStr(view.data(), view.size()); }
|
||||
size_t _readBuf(void* buf, size_t len);
|
||||
size_t _writeBuf(const void* buf, size_t len);
|
||||
std::string _readStdString() {
|
||||
uint32_t bufSz;
|
||||
_readBuf(&bufSz, 4);
|
||||
std::string ret(bufSz, ' ');
|
||||
_readBuf(&ret[0], bufSz);
|
||||
return ret;
|
||||
}
|
||||
template<typename T, std::enable_if_t<std::disjunction_v<std::is_arithmetic<T>, std::is_enum<T>>, int> = 0>
|
||||
void _readValue(T& v) { _readBuf(&v, sizeof(T)); }
|
||||
template<typename T>
|
||||
void _readItems(T enumerator) {
|
||||
uint32_t nItems;
|
||||
_readBuf(&nItems, 4);
|
||||
for (uint32_t i = 0; i < nItems; ++i)
|
||||
enumerator(*this);
|
||||
}
|
||||
template<typename T, typename... Args, std::enable_if_t<
|
||||
!std::disjunction_v<std::is_arithmetic<T>, std::is_enum<T>, std::is_same<T, std::string>>, int> = 0>
|
||||
void _readVector(std::vector<T>& container, Args&&... args) {
|
||||
uint32_t nItems;
|
||||
_readBuf(&nItems, 4);
|
||||
container.clear();
|
||||
container.reserve(nItems);
|
||||
for (uint32_t i = 0; i < nItems; ++i)
|
||||
container.emplace_back(*this, std::forward<Args>(args)...);
|
||||
}
|
||||
template<typename T, std::enable_if_t<std::disjunction_v<std::is_arithmetic<T>, std::is_enum<T>>, int> = 0>
|
||||
void _readVector(std::vector<T>& container) {
|
||||
uint32_t nItems;
|
||||
_readBuf(&nItems, 4);
|
||||
container.clear();
|
||||
container.resize(nItems);
|
||||
_readBuf(&container[0], sizeof(T) * nItems);
|
||||
}
|
||||
void _readVector(std::vector<std::string>& container) {
|
||||
uint32_t nItems;
|
||||
_readBuf(&nItems, 4);
|
||||
container.clear();
|
||||
container.reserve(nItems);
|
||||
for (uint32_t i = 0; i < nItems; ++i) {
|
||||
uint32_t strSize;
|
||||
_readBuf(&strSize, 4);
|
||||
_readBuf(&container.emplace_back(strSize, ' ')[0], strSize);
|
||||
}
|
||||
}
|
||||
template<typename T, typename F>
|
||||
void _readVectorFunc(std::vector<T>& container, F func) {
|
||||
uint32_t nItems;
|
||||
_readBuf(&nItems, 4);
|
||||
container.clear();
|
||||
container.reserve(nItems);
|
||||
for (uint32_t i = 0; i < nItems; ++i)
|
||||
func();
|
||||
}
|
||||
ProjectPath _readPath();
|
||||
bool _isStatus(const char* status) {
|
||||
char readBuf[16];
|
||||
_readStr(readBuf, 16);
|
||||
return std::strcmp(readBuf, status) == 0;
|
||||
}
|
||||
bool _isOk() { return _isStatus("OK"); }
|
||||
bool _isFinished() { return _isStatus("FINISHED"); }
|
||||
bool _isTrue() { return _isStatus("TRUE"); }
|
||||
void _checkStatus(std::string_view action, std::string_view status) {
|
||||
char readBuf[16];
|
||||
_readStr(readBuf, 16);
|
||||
if (status != readBuf)
|
||||
BlenderLog.report(logvisor::Fatal, fmt("{}: {}: {}"), m_loadedBlend.getRelativePathUTF8(), action, readBuf);
|
||||
}
|
||||
void _checkReady(std::string_view action) { _checkStatus(action, "READY"sv); }
|
||||
void _checkDone(std::string_view action) { _checkStatus(action, "DONE"sv); }
|
||||
void _checkOk(std::string_view action) { _checkStatus(action, "OK"sv); }
|
||||
void _checkAnimReady(std::string_view action) { _checkStatus(action, "ANIMREADY"sv); }
|
||||
void _checkAnimDone(std::string_view action) { _checkStatus(action, "ANIMDONE"sv); }
|
||||
void _closePipe();
|
||||
void _blenderDied();
|
||||
|
||||
|
@ -764,8 +856,7 @@ public:
|
|||
};
|
||||
|
||||
template <typename S, typename... Args, typename Char>
|
||||
void PyOutStream::format(const S& format, Args&&... args)
|
||||
{
|
||||
void PyOutStream::format(const S& format, Args&&... args) {
|
||||
if (!m_parent || !m_parent->m_lock)
|
||||
BlenderLog.report(logvisor::Fatal, fmt("lock not held for PyOutStream::format()"));
|
||||
fmt::print(*this, format, std::forward<Args>(args)...);
|
||||
|
|
|
@ -15,8 +15,6 @@
|
|||
|
||||
#include "hecl.hpp"
|
||||
|
||||
#define RUNTIME_ORIGINAL_IDS 0
|
||||
|
||||
namespace hecl {
|
||||
class ClientProcess;
|
||||
|
||||
|
|
|
@ -72,12 +72,12 @@ inline void DNAFourCC::Enumerate<BigDNA::Write>(Write::StreamT& w) {
|
|||
}
|
||||
template <>
|
||||
inline void DNAFourCC::Enumerate<BigDNA::ReadYaml>(ReadYaml::StreamT& r) {
|
||||
const std::string rs = r.readString(nullptr);
|
||||
const std::string rs = r.readString();
|
||||
rs.copy(fcc, std::size(fcc));
|
||||
}
|
||||
template <>
|
||||
inline void DNAFourCC::Enumerate<BigDNA::WriteYaml>(WriteYaml::StreamT& w) {
|
||||
w.writeString(nullptr, std::string_view{fcc, std::size(fcc)});
|
||||
w.writeString(std::string_view{fcc, std::size(fcc)});
|
||||
}
|
||||
template <>
|
||||
inline void DNAFourCC::Enumerate<BigDNA::BinarySize>(BinarySize::StreamT& s) {
|
||||
|
|
|
@ -204,7 +204,7 @@ template <> \
|
|||
template <> \
|
||||
inline void hecl::TypedVariantBigDNA<__VA_ARGS__>::Enumerate<athena::io::DNA<athena::Big>::Read>(typename Read::StreamT & r) { \
|
||||
EnumType variant_type = {}; \
|
||||
Do<athena::io::DNA<athena::Big>::Read>(athena::io::PropId("variant_type"), variant_type, r); \
|
||||
Do<athena::io::DNA<athena::Big>::Read>(athena::io::PropId("variant_type"sv), variant_type, r); \
|
||||
static_cast<TypedVariant<__VA_ARGS__>&>(*this) = Build(variant_type); \
|
||||
visit([&](auto& var) { var.read(r); }); \
|
||||
} \
|
||||
|
@ -215,7 +215,7 @@ inline void hecl::TypedVariantBigDNA<__VA_ARGS__>::Enumerate<athena::io::DNA<ath
|
|||
visit([&](auto& var) { \
|
||||
using T = std::decay_t<decltype(var)>; \
|
||||
EnumType variant_type = T::variant_type(); \
|
||||
Do<athena::io::DNA<athena::Big>::Write>(athena::io::PropId("variant_type"), variant_type, w); \
|
||||
Do<athena::io::DNA<athena::Big>::Write>(athena::io::PropId("variant_type"sv), variant_type, w); \
|
||||
var.write(w); \
|
||||
}); \
|
||||
} \
|
||||
|
@ -226,13 +226,13 @@ inline void hecl::TypedVariantBigDNA<__VA_ARGS__>::Enumerate<athena::io::DNA<ath
|
|||
visit([&](auto& var) { \
|
||||
using T = std::decay_t<decltype(var)>; \
|
||||
EnumType variant_type = T::variant_type(); \
|
||||
Do<athena::io::DNA<athena::Big>::BinarySize>(athena::io::PropId("variant_type"), variant_type, sz); \
|
||||
Do<athena::io::DNA<athena::Big>::BinarySize>(athena::io::PropId("variant_type"sv), variant_type, sz); \
|
||||
var.binarySize(sz); \
|
||||
}); \
|
||||
} \
|
||||
template <> \
|
||||
inline const char* hecl::TypedVariantBigDNA<__VA_ARGS__>::DNAType() { \
|
||||
return "hecl::TypedVariantBigDNA<" #__VA_ARGS__ ">"; \
|
||||
inline std::string_view hecl::TypedVariantBigDNA<__VA_ARGS__>::DNAType() { \
|
||||
return "hecl::TypedVariantBigDNA<" #__VA_ARGS__ ">"sv; \
|
||||
}
|
||||
|
||||
#define AT_SPECIALIZE_TYPED_VARIANT_BIGDNA_YAML(...) \
|
||||
|
@ -241,7 +241,7 @@ template <> \
|
|||
template <> \
|
||||
inline void hecl::TypedVariantBigDNA<__VA_ARGS__>::Enumerate<athena::io::DNA<athena::Big>::ReadYaml>(typename ReadYaml::StreamT & r) { \
|
||||
EnumType variant_type = {}; \
|
||||
Do<athena::io::DNA<athena::Big>::ReadYaml>(athena::io::PropId("variant_type"), variant_type, r); \
|
||||
Do<athena::io::DNA<athena::Big>::ReadYaml>(athena::io::PropId("variant_type"sv), variant_type, r); \
|
||||
static_cast<TypedVariant<__VA_ARGS__>&>(*this) = Build(variant_type); \
|
||||
visit([&](auto& var) { var.read(r); }); \
|
||||
} \
|
||||
|
@ -252,7 +252,7 @@ inline void hecl::TypedVariantBigDNA<__VA_ARGS__>::Enumerate<athena::io::DNA<ath
|
|||
visit([&](auto& var) { \
|
||||
using T = std::decay_t<decltype(var)>; \
|
||||
EnumType variant_type = T::variant_type(); \
|
||||
Do<athena::io::DNA<athena::Big>::WriteYaml>(athena::io::PropId("variant_type"), variant_type, w); \
|
||||
Do<athena::io::DNA<athena::Big>::WriteYaml>(athena::io::PropId("variant_type"sv), variant_type, w); \
|
||||
var.write(w); \
|
||||
}); \
|
||||
}
|
||||
|
|
|
@ -60,7 +60,8 @@ struct DataSpecEntry;
|
|||
} // namespace Database
|
||||
|
||||
namespace blender {
|
||||
enum class BlendType { None, Mesh, ColMesh, Actor, Area, World, MapArea, MapUniverse, Frame, PathMesh };
|
||||
enum class BlendType { None, Mesh, ColMesh, Armature, Actor, Area,
|
||||
World, MapArea, MapUniverse, Frame, PathMesh };
|
||||
|
||||
class Connection;
|
||||
class Token;
|
||||
|
@ -137,6 +138,8 @@ public:
|
|||
return std::wstring(lhs).append(rhs.m_sys);
|
||||
}
|
||||
};
|
||||
|
||||
inline hecl::SystemString UTF8StringToSysString(std::string_view src) { return UTF8ToWide(src); }
|
||||
#else
|
||||
class SystemUTF8Conv {
|
||||
std::string_view m_utf8;
|
||||
|
@ -171,6 +174,8 @@ public:
|
|||
return std::string(lhs).append(rhs.m_sys);
|
||||
}
|
||||
};
|
||||
|
||||
inline hecl::SystemString UTF8StringToSysString(std::string src) { return src; }
|
||||
#endif
|
||||
|
||||
void SanitizePath(std::string& path);
|
||||
|
@ -423,7 +428,9 @@ class MultiProgressPrinter;
|
|||
class ProjectRootPath;
|
||||
|
||||
using SystemRegex = std::basic_regex<SystemChar>;
|
||||
using SystemRegexIterator = std::regex_iterator<SystemString::const_iterator>;
|
||||
using SystemRegexMatch = std::match_results<SystemString::const_iterator>;
|
||||
using SystemViewRegexMatch = std::match_results<SystemStringView::const_iterator>;
|
||||
using SystemRegexTokenIterator = std::regex_token_iterator<SystemString::const_iterator>;
|
||||
|
||||
/**
|
||||
|
@ -929,6 +936,36 @@ public:
|
|||
}
|
||||
#endif
|
||||
|
||||
template<typename StringT>
|
||||
class EncodableString {
|
||||
friend class ProjectPath;
|
||||
using EncStringView = std::basic_string_view<typename StringT::value_type>;
|
||||
StringT m_ownedString;
|
||||
EncStringView m_stringView;
|
||||
EncodableString(StringT s) : m_ownedString(std::move(s)), m_stringView(m_ownedString) {}
|
||||
EncodableString(EncStringView sv) : m_stringView(sv) {}
|
||||
EncodableString(const EncodableString&) = delete;
|
||||
EncodableString& operator=(const EncodableString&) = delete;
|
||||
EncodableString(EncodableString&&) = delete;
|
||||
EncodableString& operator=(EncodableString&&) = delete;
|
||||
public:
|
||||
operator EncStringView() const { return m_stringView; }
|
||||
};
|
||||
|
||||
EncodableString<SystemString> getEncodableString() const {
|
||||
if (!getAuxInfo().empty())
|
||||
return {SystemString(getRelativePath()) + _SYS_STR('|') + getAuxInfo().data()};
|
||||
else
|
||||
return {getRelativePath()};
|
||||
}
|
||||
|
||||
EncodableString<std::string> getEncodableStringUTF8() const {
|
||||
if (!getAuxInfo().empty())
|
||||
return {std::string(getRelativePathUTF8()) + '|' + getAuxInfoUTF8().data()};
|
||||
else
|
||||
return {getRelativePathUTF8()};
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Type of path
|
||||
*/
|
||||
|
@ -1053,6 +1090,8 @@ public:
|
|||
Hash hash() const noexcept { return m_hash; }
|
||||
bool operator==(const ProjectPath& other) const noexcept { return m_hash == other.m_hash; }
|
||||
bool operator!=(const ProjectPath& other) const noexcept { return !operator==(other); }
|
||||
|
||||
uint32_t parsedHash32() const;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1294,6 +1333,50 @@ constexpr void hash_combine_impl(SizeT& seed, SizeT value) noexcept {
|
|||
|
||||
} // namespace hecl
|
||||
|
||||
#define CHAINED_SIGNAL_HANDLER(name, signal) \
|
||||
class ChainedSignalHandler_##name { \
|
||||
typedef void(*sighandler_t)(int); \
|
||||
typedef void(*sigaction_t)(int, siginfo_t*, void*); \
|
||||
static std::atomic_bool m_isSetup; \
|
||||
static sighandler_t m_nextsh; \
|
||||
static sigaction_t m_nextsa; \
|
||||
static void my_sig_action(int sig, siginfo_t* si, void* ctx); \
|
||||
static void sig_action(int sig, siginfo_t* si, void* ctx) { \
|
||||
my_sig_action(sig, si, ctx); \
|
||||
if (m_nextsa) \
|
||||
m_nextsa(sig, si, ctx); \
|
||||
else if (m_nextsh) \
|
||||
m_nextsh(sig); \
|
||||
} \
|
||||
public: \
|
||||
static void setup() { \
|
||||
if (ChainedSignalHandler_##name::m_isSetup.exchange(true) == true) \
|
||||
return; \
|
||||
{ \
|
||||
struct sigaction sold; \
|
||||
if (sigaction(signal, nullptr, &sold) == 0) { \
|
||||
if (sold.sa_flags & SA_SIGINFO) \
|
||||
m_nextsa = sold.sa_sigaction; \
|
||||
else \
|
||||
m_nextsh = sold.sa_handler; \
|
||||
} \
|
||||
} \
|
||||
{ \
|
||||
struct sigaction snew = {}; \
|
||||
snew.sa_sigaction = sig_action; \
|
||||
snew.sa_flags = SA_RESTART | SA_NOCLDSTOP | SA_SIGINFO; \
|
||||
sigaction(signal, &snew, nullptr); \
|
||||
} \
|
||||
} \
|
||||
}; \
|
||||
std::atomic_bool ChainedSignalHandler_##name::m_isSetup = {false}; \
|
||||
ChainedSignalHandler_##name::sighandler_t ChainedSignalHandler_##name::m_nextsh = {}; \
|
||||
ChainedSignalHandler_##name::sigaction_t ChainedSignalHandler_##name::m_nextsa = {}; \
|
||||
inline void ChainedSignalHandler_##name::my_sig_action
|
||||
|
||||
#define SETUP_CHAINED_SIGNAL_HANDLER(name) \
|
||||
ChainedSignalHandler_##name::setup()
|
||||
|
||||
namespace std {
|
||||
template <>
|
||||
struct hash<hecl::ProjectPath> {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -43,10 +43,11 @@ static bool material_is_lightmapped(const Material& mat) {
|
|||
|
||||
MeshOptimizer::Vertex::Vertex(Connection& conn) {
|
||||
co.read(conn);
|
||||
Index skin_count(conn);
|
||||
if (skin_count.val > MaxSkinEntries)
|
||||
Log.report(logvisor::Fatal, fmt("Skin entry overflow {}/{}"), skin_count.val, MaxSkinEntries);
|
||||
for (uint32_t i = 0; i < skin_count.val; ++i)
|
||||
uint32_t skin_count;
|
||||
conn._readValue(skin_count);
|
||||
if (skin_count > MaxSkinEntries)
|
||||
Log.report(logvisor::Fatal, fmt("Skin entry overflow {}/{}"), skin_count, MaxSkinEntries);
|
||||
for (uint32_t i = 0; i < skin_count; ++i)
|
||||
skin_ents[i] = Mesh::SkinBind(conn);
|
||||
}
|
||||
|
||||
|
@ -56,32 +57,33 @@ MeshOptimizer::Loop::Loop(Connection& conn, uint32_t color_count, uint32_t uv_co
|
|||
colors[i].read(conn);
|
||||
for (uint32_t i = 0; i < uv_count; ++i)
|
||||
uvs[i].read(conn);
|
||||
vert = Index(conn).val;
|
||||
edge = Index(conn).val;
|
||||
face = Index(conn).val;
|
||||
link_loop_next = Index(conn).val;
|
||||
link_loop_prev = Index(conn).val;
|
||||
link_loop_radial_next = Index(conn).val;
|
||||
link_loop_radial_prev = Index(conn).val;
|
||||
conn._readValue(vert);
|
||||
conn._readValue(edge);
|
||||
conn._readValue(face);
|
||||
conn._readValue(link_loop_next);
|
||||
conn._readValue(link_loop_prev);
|
||||
conn._readValue(link_loop_radial_next);
|
||||
conn._readValue(link_loop_radial_prev);
|
||||
}
|
||||
|
||||
MeshOptimizer::Edge::Edge(Connection& conn) {
|
||||
for (uint32_t i = 0; i < 2; ++i)
|
||||
verts[i] = Index(conn).val;
|
||||
Index face_count(conn);
|
||||
conn._readValue(verts[i]);
|
||||
uint32_t face_count;
|
||||
conn._readValue(face_count);
|
||||
if (face_count > MaxLinkFaces)
|
||||
Log.report(logvisor::Fatal, fmt("Face overflow {}/{}"), face_count.val, MaxLinkFaces);
|
||||
for (uint32_t i = 0; i < face_count.val; ++i)
|
||||
link_faces[i] = Index(conn).val;
|
||||
is_contiguous = Boolean(conn).val;
|
||||
Log.report(logvisor::Fatal, fmt("Face overflow {}/{}"), face_count, MaxLinkFaces);
|
||||
for (uint32_t i = 0; i < face_count; ++i)
|
||||
conn._readValue(link_faces[i]);
|
||||
conn._readValue(is_contiguous);
|
||||
}
|
||||
|
||||
MeshOptimizer::Face::Face(Connection& conn) {
|
||||
normal.read(conn);
|
||||
centroid.read(conn);
|
||||
material_index = Index(conn).val;
|
||||
conn._readValue(material_index);
|
||||
for (uint32_t i = 0; i < 3; ++i)
|
||||
loops[i] = Index(conn).val;
|
||||
conn._readValue(loops[i]);
|
||||
}
|
||||
|
||||
uint32_t MeshOptimizer::get_pos_idx(const Vertex& v) const {
|
||||
|
@ -376,36 +378,38 @@ void MeshOptimizer::optimize(Mesh& mesh, int max_skin_banks) const {
|
|||
|
||||
MeshOptimizer::MeshOptimizer(Connection& conn, const std::vector<Material>& materials, bool use_luvs)
|
||||
: materials(materials), use_luvs(use_luvs) {
|
||||
color_count = Index(conn).val;
|
||||
conn._readValue(color_count);
|
||||
if (color_count > MaxColorLayers)
|
||||
Log.report(logvisor::Fatal, fmt("Color layer overflow {}/{}"), color_count, MaxColorLayers);
|
||||
uv_count = Index(conn).val;
|
||||
conn._readValue(uv_count);
|
||||
if (uv_count > MaxUVLayers)
|
||||
Log.report(logvisor::Fatal, fmt("UV layer overflow {}/{}"), uv_count, MaxUVLayers);
|
||||
|
||||
/* Simultaneously load topology objects and build unique mapping indices */
|
||||
|
||||
Index vert_count(conn);
|
||||
verts.reserve(vert_count.val);
|
||||
b_pos.reserve(vert_count.val);
|
||||
b_skin.reserve(vert_count.val * 4);
|
||||
for (uint32_t i = 0; i < vert_count.val; ++i) {
|
||||
uint32_t vert_count;
|
||||
conn._readValue(vert_count);
|
||||
verts.reserve(vert_count);
|
||||
b_pos.reserve(vert_count);
|
||||
b_skin.reserve(vert_count * 4);
|
||||
for (uint32_t i = 0; i < vert_count; ++i) {
|
||||
verts.emplace_back(conn);
|
||||
insert_unique_attr(b_pos, verts.back().co);
|
||||
if (verts.back().skin_ents[0].valid())
|
||||
insert_unique_attr(b_skin, verts.back().skin_ents);
|
||||
}
|
||||
|
||||
Index loop_count(conn);
|
||||
loops.reserve(loop_count.val);
|
||||
b_norm.reserve(loop_count.val);
|
||||
uint32_t loop_count;
|
||||
conn._readValue(loop_count);
|
||||
loops.reserve(loop_count);
|
||||
b_norm.reserve(loop_count);
|
||||
if (use_luvs) {
|
||||
b_uv.reserve(std::max(int(loop_count.val) - 1, 0) * uv_count);
|
||||
b_luv.reserve(loop_count.val);
|
||||
b_uv.reserve(std::max(int(loop_count) - 1, 0) * uv_count);
|
||||
b_luv.reserve(loop_count);
|
||||
} else {
|
||||
b_uv.reserve(loop_count.val * uv_count);
|
||||
b_uv.reserve(loop_count * uv_count);
|
||||
}
|
||||
for (uint32_t i = 0; i < loop_count.val; ++i) {
|
||||
for (uint32_t i = 0; i < loop_count; ++i) {
|
||||
loops.emplace_back(conn, color_count, uv_count);
|
||||
insert_unique_attr(b_norm, loops.back().normal);
|
||||
for (const auto& c : loops.back().colors)
|
||||
|
@ -420,15 +424,8 @@ MeshOptimizer::MeshOptimizer(Connection& conn, const std::vector<Material>& mate
|
|||
}
|
||||
}
|
||||
|
||||
Index edge_count(conn);
|
||||
edges.reserve(edge_count.val);
|
||||
for (uint32_t i = 0; i < edge_count.val; ++i)
|
||||
edges.emplace_back(conn);
|
||||
|
||||
Index face_count(conn);
|
||||
faces.reserve(face_count.val);
|
||||
for (uint32_t i = 0; i < face_count.val; ++i)
|
||||
faces.emplace_back(conn);
|
||||
conn._readVector(edges);
|
||||
conn._readVector(faces);
|
||||
|
||||
/* Cache edges that should block tristrip traversal */
|
||||
for (auto& e : edges)
|
||||
|
|
|
@ -29,7 +29,7 @@ const SDNABlock::SDNAStruct::SDNAField* SDNABlock::SDNAStruct::lookupField(const
|
|||
if (bracket != std::string::npos) {
|
||||
if (!name.compare(0, bracket, n))
|
||||
return &field;
|
||||
} else if (!name.compare(n))
|
||||
} else if (name == n)
|
||||
return &field;
|
||||
}
|
||||
return nullptr;
|
||||
|
@ -39,7 +39,7 @@ const SDNABlock::SDNAStruct* SDNABlock::lookupStruct(const char* n, atUint32& id
|
|||
idx = 0;
|
||||
for (const SDNAStruct& strc : strcs) {
|
||||
const auto& name = types[strc.type];
|
||||
if (!name.compare(n))
|
||||
if (name == n)
|
||||
return &strc;
|
||||
++idx;
|
||||
}
|
||||
|
|
|
@ -165,11 +165,11 @@ bool CVar::toBoolean(bool* isValid) const {
|
|||
std::string tmp = m_value;
|
||||
athena::utility::tolower(tmp);
|
||||
|
||||
if (!tmp.compare("yes") || !tmp.compare("true") || !tmp.compare("1")) {
|
||||
if (tmp == "yes" || tmp == "true" || tmp == "1") {
|
||||
if (isValid)
|
||||
*isValid = true;
|
||||
return true;
|
||||
} else if (!tmp.compare("no") || !tmp.compare("false") || !tmp.compare("0")) {
|
||||
} else if (tmp == "no" || tmp == "false" || tmp == "0") {
|
||||
if (isValid)
|
||||
*isValid = true;
|
||||
return false;
|
||||
|
|
|
@ -181,7 +181,7 @@ void CVarManager::serialize() {
|
|||
filename += _SYS_STR(".yaml");
|
||||
|
||||
athena::io::FileReader r(filename);
|
||||
athena::io::YAMLDocWriter docWriter(nullptr, r.isOpen() ? &r : nullptr);
|
||||
athena::io::YAMLDocWriter docWriter(r.isOpen() ? &r : nullptr);
|
||||
r.close();
|
||||
|
||||
docWriter.setStyle(athena::io::YAMLNodeStyle::Block);
|
||||
|
|
|
@ -91,7 +91,7 @@ void Project::ConfigFile::removeLine(std::string_view refLine) {
|
|||
}
|
||||
|
||||
for (auto it = m_lines.begin(); it != m_lines.end();) {
|
||||
if (!(*it).compare(refLine)) {
|
||||
if (*it == refLine) {
|
||||
it = m_lines.erase(it);
|
||||
continue;
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ bool Project::ConfigFile::checkForLine(std::string_view refLine) {
|
|||
}
|
||||
|
||||
for (const std::string& line : m_lines)
|
||||
if (!line.compare(refLine))
|
||||
if (line == refLine)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -14,9 +14,9 @@ static SystemString CanonRelPath(SystemStringView path) {
|
|||
SanitizePath(in);
|
||||
for (; std::regex_search(in, matches, regPATHCOMP); in = matches.suffix().str()) {
|
||||
hecl::SystemRegexMatch::const_reference match = matches[1];
|
||||
if (!match.compare(_SYS_STR(".")))
|
||||
if (match == _SYS_STR("."))
|
||||
continue;
|
||||
else if (!match.compare(_SYS_STR(".."))) {
|
||||
else if (match == _SYS_STR("..")) {
|
||||
if (comps.empty()) {
|
||||
/* Unable to resolve outside project */
|
||||
LogModule.report(logvisor::Fatal, fmt(_SYS_STR("Unable to resolve outside project root in {}")), path);
|
||||
|
@ -140,6 +140,8 @@ ProjectPath ProjectPath::getCookedPath(const Database::DataSpecEntry& spec) cons
|
|||
}
|
||||
|
||||
ProjectPath::Type ProjectPath::getPathType() const {
|
||||
if (m_absPath.empty())
|
||||
return Type::None;
|
||||
if (m_absPath.find(_SYS_STR('*')) != SystemString::npos)
|
||||
return Type::Glob;
|
||||
Sstat theStat;
|
||||
|
@ -246,6 +248,43 @@ void ProjectPath::getGlobResults(std::vector<ProjectPath>& outPaths) const {
|
|||
_recursiveGlob(*m_proj, outPaths, m_relPath, rootPath.data(), rootPath.back() != _SYS_STR('/'));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static bool RegexSearchLast(const T& str, std::match_results<typename T::const_iterator>& m,
|
||||
const std::basic_regex<typename T::value_type>& reg) {
|
||||
using Iterator = std::regex_iterator<typename T::const_iterator>;
|
||||
Iterator begin = Iterator(str.begin(), str.end(), reg);
|
||||
Iterator end = Iterator();
|
||||
if (begin == end)
|
||||
return false;
|
||||
Iterator last_it;
|
||||
for (auto it = begin; it != end; ++it)
|
||||
last_it = it;
|
||||
m = *last_it;
|
||||
return true;
|
||||
}
|
||||
|
||||
static const hecl::SystemRegex regParsedHash32(_SYS_STR(R"(_([0-9a-fA-F]{8}))"),
|
||||
std::regex::ECMAScript | std::regex::optimize);
|
||||
uint32_t ProjectPath::parsedHash32() const {
|
||||
{
|
||||
hecl::SystemRegexMatch match;
|
||||
if (RegexSearchLast(m_auxInfo, match, regParsedHash32)) {
|
||||
auto hexStr = match[1].str();
|
||||
if (auto val = hecl::StrToUl(hexStr.c_str(), nullptr, 16))
|
||||
return val;
|
||||
}
|
||||
}
|
||||
{
|
||||
hecl::SystemViewRegexMatch match;
|
||||
if (RegexSearchLast(getLastComponent(), match, regParsedHash32)) {
|
||||
auto hexStr = match[1].str();
|
||||
if (auto val = hecl::StrToUl(hexStr.c_str(), nullptr, 16))
|
||||
return val;
|
||||
}
|
||||
}
|
||||
return hash().val32();
|
||||
}
|
||||
|
||||
ProjectRootPath SearchForProject(SystemStringView path) {
|
||||
ProjectRootPath testRoot(path);
|
||||
auto begin = testRoot.getAbsolutePath().begin();
|
||||
|
|
|
@ -30,11 +30,13 @@
|
|||
|
||||
#include <logvisor/logvisor.hpp>
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
namespace hecl {
|
||||
unsigned VerbosityLevel = 0;
|
||||
bool GuiMode = false;
|
||||
logvisor::Module LogModule("hecl");
|
||||
constexpr std::string_view Illegals{"<>?\""};
|
||||
constexpr std::string_view Illegals = "<>?\""sv;
|
||||
|
||||
void SanitizePath(std::string& path) {
|
||||
if (path.empty())
|
||||
|
@ -64,7 +66,7 @@ void SanitizePath(std::string& path) {
|
|||
path.pop_back();
|
||||
}
|
||||
|
||||
constexpr std::wstring_view WIllegals{L"<>?\""};
|
||||
constexpr std::wstring_view WIllegals = L"<>?\""sv;
|
||||
|
||||
void SanitizePath(std::wstring& path) {
|
||||
if (path.empty())
|
||||
|
@ -174,9 +176,8 @@ bool IsPathPNG(const hecl::ProjectPath& path) {
|
|||
|
||||
bool IsPathBlend(const hecl::ProjectPath& path) {
|
||||
const auto lastCompExt = path.getLastComponentExt();
|
||||
if (lastCompExt.empty() || hecl::StrCmp(lastCompExt.data(), _SYS_STR("blend"))) {
|
||||
if (lastCompExt.empty() || lastCompExt != _SYS_STR("blend"))
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto fp = hecl::FopenUnique(path.getAbsolutePath().data(), _SYS_STR("rb"));
|
||||
if (fp == nullptr) {
|
||||
|
@ -193,14 +194,15 @@ bool IsPathBlend(const hecl::ProjectPath& path) {
|
|||
}
|
||||
|
||||
bool IsPathYAML(const hecl::ProjectPath& path) {
|
||||
if (!hecl::StrCmp(path.getLastComponent().data(), _SYS_STR("!catalog.yaml")))
|
||||
return false; /* !catalog.yaml is exempt from general use */
|
||||
auto lastComp = path.getLastComponent();
|
||||
if (lastComp == _SYS_STR("!catalog.yaml") ||
|
||||
lastComp == _SYS_STR("!memoryid.yaml") ||
|
||||
lastComp == _SYS_STR("!memoryrelays.yaml"))
|
||||
return false; /* !catalog.yaml, !memoryid.yaml, !memoryrelays.yaml are exempt from general use */
|
||||
auto lastCompExt = path.getLastComponentExt();
|
||||
if (lastCompExt.empty())
|
||||
return false;
|
||||
if (!hecl::StrCmp(lastCompExt.data(), _SYS_STR("yaml")) || !hecl::StrCmp(lastCompExt.data(), _SYS_STR("yml")))
|
||||
return true;
|
||||
return false;
|
||||
return lastCompExt == _SYS_STR("yaml") || lastCompExt == _SYS_STR("yml");
|
||||
}
|
||||
|
||||
hecl::DirectoryEnumerator::DirectoryEnumerator(SystemStringView path, Mode mode, bool sizeSort, bool reverse,
|
||||
|
|
Loading…
Reference in New Issue