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/sact/SACTSubtype.py
|
||||||
hecl/srea/__init__.py
|
hecl/srea/__init__.py
|
||||||
hecl/swld/__init__.py
|
hecl/swld/__init__.py
|
||||||
|
hecl/armature.py
|
||||||
hecl/mapa.py
|
hecl/mapa.py
|
||||||
hecl/mapu.py
|
hecl/mapu.py
|
||||||
hecl/frme.py
|
hecl/frme.py
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
# Node Grid Arranger Class
|
# Node Grid Arranger Class
|
||||||
NODE_PADDING = 80
|
NODE_PADDING = 80
|
||||||
FRAME_NAMES = ['Textures','Output']
|
FRAME_NAMES = ['Textures','Output','Blend']
|
||||||
FRAME_WIDTHS = [400, 180]
|
FRAME_WIDTHS = [400, 180, 180]
|
||||||
TOTAL_WIDTH = 0.0
|
TOTAL_WIDTH = 0.0
|
||||||
for width in FRAME_WIDTHS:
|
for width in FRAME_WIDTHS:
|
||||||
TOTAL_WIDTH += width + NODE_PADDING
|
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:
|
class Nodegrid:
|
||||||
|
|
||||||
def __init__(self, nodetree, cycles=False):
|
def __init__(self, nodetree, cycles=False):
|
||||||
|
|
|
@ -9,7 +9,7 @@ bl_info = {
|
||||||
"category": "System"}
|
"category": "System"}
|
||||||
|
|
||||||
# Package import
|
# 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
|
Nodegrid = Nodegrid.Nodegrid
|
||||||
parent_armature = sact.SACTSubtype.parent_armature
|
parent_armature = sact.SACTSubtype.parent_armature
|
||||||
import bpy, os, sys, struct, math
|
import bpy, os, sys, struct, math
|
||||||
|
@ -20,6 +20,7 @@ hecl_typeS = [
|
||||||
('NONE', "None", "Active scene not using HECL", None),
|
('NONE', "None", "Active scene not using HECL", None),
|
||||||
('MESH', "Mesh", "Active scene represents an HMDL Mesh", hmdl.draw),
|
('MESH', "Mesh", "Active scene represents an HMDL Mesh", hmdl.draw),
|
||||||
('CMESH', "Collision Mesh", "Active scene represents a Collision Mesh", None),
|
('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),
|
('ACTOR', "Actor", "Active scene represents a HECL Actor", sact.draw),
|
||||||
('AREA', "Area", "Active scene represents a HECL Area", srea.draw),
|
('AREA', "Area", "Active scene represents a HECL Area", srea.draw),
|
||||||
('WORLD', "World", "Active scene represents a HECL World", swld.draw),
|
('WORLD', "World", "Active scene represents a HECL World", swld.draw),
|
||||||
|
@ -141,8 +142,9 @@ from bpy.app.handlers import persistent
|
||||||
@persistent
|
@persistent
|
||||||
def scene_loaded(dummy):
|
def scene_loaded(dummy):
|
||||||
# Hide everything from an external library
|
# Hide everything from an external library
|
||||||
|
if bpy.context.scene.hecl_type != 'FRAME':
|
||||||
for o in bpy.context.scene.objects:
|
for o in bpy.context.scene.objects:
|
||||||
if o.library:
|
if o.library or (o.data and o.data.library):
|
||||||
o.hide_set(True)
|
o.hide_set(True)
|
||||||
|
|
||||||
# Show PATH library objects as wireframes
|
# Show PATH library objects as wireframes
|
||||||
|
@ -208,6 +210,7 @@ def register():
|
||||||
mapa.register()
|
mapa.register()
|
||||||
mapu.register()
|
mapu.register()
|
||||||
path.register()
|
path.register()
|
||||||
|
armature.register()
|
||||||
bpy.utils.register_class(hecl_scene_panel)
|
bpy.utils.register_class(hecl_scene_panel)
|
||||||
bpy.utils.register_class(hecl_light_panel)
|
bpy.utils.register_class(hecl_light_panel)
|
||||||
bpy.types.Scene.hecl_auto_select = bpy.props.BoolProperty(name='HECL Auto Select', default=True)
|
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
|
import struct, bpy, bmesh
|
||||||
from . import HMDLShader, HMDLMesh
|
from . import HMDLShader, HMDLMesh
|
||||||
|
|
||||||
|
BLEND_TYPES = {
|
||||||
|
'HECLAdditiveOutput': 2,
|
||||||
|
'HECLBlendOutput': 1,
|
||||||
|
'HECLOpaqueOutput': 0,
|
||||||
|
}
|
||||||
|
|
||||||
def write_out_material(writebuf, mat, mesh_obj):
|
def write_out_material(writebuf, mat, mesh_obj):
|
||||||
writebuf(struct.pack('I', len(mat.name)))
|
writebuf(struct.pack('I', len(mat.name)))
|
||||||
writebuf(mat.name.encode())
|
writebuf(mat.name.encode())
|
||||||
|
@ -20,12 +26,10 @@ def write_out_material(writebuf, mat, mesh_obj):
|
||||||
writebuf(prop[0].encode())
|
writebuf(prop[0].encode())
|
||||||
writebuf(struct.pack('i', prop[1]))
|
writebuf(struct.pack('i', prop[1]))
|
||||||
|
|
||||||
blend = 0
|
blend_node = mat.node_tree.nodes['Blend']
|
||||||
if mat.blend_method == 'BLEND':
|
if blend_node.node_tree.name not in BLEND_TYPES:
|
||||||
blend = 1
|
raise RuntimeError("HMDL *requires* one of the HMDL*Output group nodes for the 'Blend' node")
|
||||||
elif mat.blend_method == 'ADD':
|
writebuf(struct.pack('I', BLEND_TYPES[blend_node.node_tree.name]))
|
||||||
blend = 2
|
|
||||||
writebuf(struct.pack('I', blend))
|
|
||||||
|
|
||||||
# Takes a Blender 'Mesh' object (not the datablock)
|
# Takes a Blender 'Mesh' object (not the datablock)
|
||||||
# and performs a one-shot conversion process to HMDL
|
# 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]
|
obj = context.scene.objects[context.scene.hecl_mesh_obj]
|
||||||
if obj.type != 'MESH':
|
if obj.type != 'MESH':
|
||||||
layout.label(text="'"+context.scene.hecl_mesh_obj+"' not a 'MESH'", icon='ERROR')
|
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_active_material')
|
||||||
layout.prop(obj.data, 'hecl_material_count')
|
layout.prop(obj.data, 'hecl_material_count')
|
||||||
|
|
||||||
|
@ -297,6 +302,7 @@ def register():
|
||||||
bpy.types.Scene.hecl_actor_obj = bpy.props.StringProperty(
|
bpy.types.Scene.hecl_actor_obj = bpy.props.StringProperty(
|
||||||
name='HECL Actor Object',
|
name='HECL Actor Object',
|
||||||
description='Blender Empty Object to export during HECL\'s cook process')
|
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_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.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)
|
bpy.utils.register_class(hecl_mesh_operator)
|
||||||
|
|
|
@ -52,6 +52,7 @@ def draw(layout, context):
|
||||||
else:
|
else:
|
||||||
#layout.prop(linked_action, 'hecl_index', text="Index")
|
#layout.prop(linked_action, 'hecl_index', text="Index")
|
||||||
#layout.prop(linked_action, 'hecl_anim_props', text="Props")
|
#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")
|
layout.prop(linked_action, 'hecl_fps', text="Frame Rate")
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
row.prop(context.scene, 'hecl_auto_remap', text="60-fps Remap")
|
row.prop(context.scene, 'hecl_auto_remap', text="60-fps Remap")
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from . import SACTSubtype, SACTAction, ANIM
|
from . import SACTSubtype, SACTAction, ANIM
|
||||||
|
from .. import armature
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
import bpy.path
|
import bpy.path
|
||||||
|
@ -207,21 +208,14 @@ def _out_armatures(sact_data, writebuf):
|
||||||
writebuf(struct.pack('I', len(arm.name)))
|
writebuf(struct.pack('I', len(arm.name)))
|
||||||
writebuf(arm.name.encode())
|
writebuf(arm.name.encode())
|
||||||
|
|
||||||
writebuf(struct.pack('I', len(arm.bones)))
|
if arm.library:
|
||||||
for bone in arm.bones:
|
arm_path = bpy.path.abspath(arm.library.filepath)
|
||||||
writebuf(struct.pack('I', len(bone.name)))
|
writebuf(struct.pack('I', len(arm_path)))
|
||||||
writebuf(bone.name.encode())
|
writebuf(arm_path.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:
|
else:
|
||||||
writebuf(struct.pack('i', -1))
|
writebuf(struct.pack('I', 0))
|
||||||
|
|
||||||
writebuf(struct.pack('I', len(bone.children)))
|
armature.cook(writebuf, arm)
|
||||||
for child in bone.children:
|
|
||||||
writebuf(struct.pack('i', arm.bones.find(child.name)))
|
|
||||||
|
|
||||||
def _out_subtypes(sact_data, writebuf):
|
def _out_subtypes(sact_data, writebuf):
|
||||||
writebuf(struct.pack('I', len(sact_data.subtypes)))
|
writebuf(struct.pack('I', len(sact_data.subtypes)))
|
||||||
|
@ -232,9 +226,14 @@ def _out_subtypes(sact_data, writebuf):
|
||||||
mesh = None
|
mesh = None
|
||||||
if subtype.linked_mesh in bpy.data.objects:
|
if subtype.linked_mesh in bpy.data.objects:
|
||||||
mesh = bpy.data.objects[subtype.linked_mesh]
|
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:
|
if mesh and mesh.data.library:
|
||||||
mesh_path = bpy.path.abspath(mesh.library.filepath)
|
mesh_path = bpy.path.abspath(mesh.data.library.filepath)
|
||||||
writebuf(struct.pack('I', len(mesh_path)))
|
writebuf(struct.pack('I', len(mesh_path)))
|
||||||
writebuf(mesh_path.encode())
|
writebuf(mesh_path.encode())
|
||||||
else:
|
else:
|
||||||
|
@ -257,9 +256,14 @@ def _out_subtypes(sact_data, writebuf):
|
||||||
mesh = None
|
mesh = None
|
||||||
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]
|
||||||
|
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:
|
if mesh and mesh.data.library:
|
||||||
mesh_path = bpy.path.abspath(mesh.library.filepath)
|
mesh_path = bpy.path.abspath(mesh.data.library.filepath)
|
||||||
writebuf(struct.pack('I', len(mesh_path)))
|
writebuf(struct.pack('I', len(mesh_path)))
|
||||||
writebuf(mesh_path.encode())
|
writebuf(mesh_path.encode())
|
||||||
else:
|
else:
|
||||||
|
@ -274,9 +278,14 @@ def _out_attachments(sact_data, writebuf):
|
||||||
mesh = None
|
mesh = None
|
||||||
if attachment.linked_mesh in bpy.data.objects:
|
if attachment.linked_mesh in bpy.data.objects:
|
||||||
mesh = bpy.data.objects[attachment.linked_mesh]
|
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:
|
if mesh and mesh.data.library:
|
||||||
mesh_path = bpy.path.abspath(mesh.library.filepath)
|
mesh_path = bpy.path.abspath(mesh.data.library.filepath)
|
||||||
writebuf(struct.pack('I', len(mesh_path)))
|
writebuf(struct.pack('I', len(mesh_path)))
|
||||||
writebuf(mesh_path.encode())
|
writebuf(mesh_path.encode())
|
||||||
else:
|
else:
|
||||||
|
@ -302,6 +311,9 @@ def _out_actions(sact_data, writebuf):
|
||||||
bact = None
|
bact = None
|
||||||
if action.name in bpy.data.actions:
|
if action.name in bpy.data.actions:
|
||||||
bact = bpy.data.actions[action.name]
|
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:
|
if not bact:
|
||||||
raise RuntimeError('action %s not found' % action.name)
|
raise RuntimeError('action %s not found' % action.name)
|
||||||
|
|
||||||
|
@ -334,6 +346,9 @@ def _out_action_no_subtypes(sact_data, writebuf, action_name):
|
||||||
bact = None
|
bact = None
|
||||||
if action.name in bpy.data.actions:
|
if action.name in bpy.data.actions:
|
||||||
bact = bpy.data.actions[action.name]
|
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:
|
if not bact:
|
||||||
raise RuntimeError('action %s not found' % action.name)
|
raise RuntimeError('action %s not found' % action.name)
|
||||||
|
|
||||||
|
@ -386,14 +401,6 @@ def cook_action_channels_only(writebuf, action_name):
|
||||||
# Output action without AABBs
|
# Output action without AABBs
|
||||||
_out_action_no_subtypes(sact_data, writebuf, action_name)
|
_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
|
# Access actor's contained subtype names
|
||||||
def get_subtype_names(writebuf):
|
def get_subtype_names(writebuf):
|
||||||
sact_data = bpy.context.scene.hecl_sact_data
|
sact_data = bpy.context.scene.hecl_sact_data
|
||||||
|
@ -402,6 +409,10 @@ def get_subtype_names(writebuf):
|
||||||
subtype = sact_data.subtypes[sub_idx]
|
subtype = sact_data.subtypes[sub_idx]
|
||||||
writebuf(struct.pack('I', len(subtype.name)))
|
writebuf(struct.pack('I', len(subtype.name)))
|
||||||
writebuf(subtype.name.encode())
|
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
|
# Access subtype's contained overlay names
|
||||||
def get_subtype_overlay_names(writebuf, subtypeName):
|
def get_subtype_overlay_names(writebuf, subtypeName):
|
||||||
|
@ -413,6 +424,10 @@ def get_subtype_overlay_names(writebuf, subtypeName):
|
||||||
for overlay in subtype.overlays:
|
for overlay in subtype.overlays:
|
||||||
writebuf(struct.pack('I', len(overlay.name)))
|
writebuf(struct.pack('I', len(overlay.name)))
|
||||||
writebuf(overlay.name.encode())
|
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
|
return
|
||||||
writebuf(struct.pack('I', 0))
|
writebuf(struct.pack('I', 0))
|
||||||
|
|
||||||
|
@ -424,6 +439,10 @@ def get_attachment_names(writebuf):
|
||||||
attachment = sact_data.attachments[att_idx]
|
attachment = sact_data.attachments[att_idx]
|
||||||
writebuf(struct.pack('I', len(attachment.name)))
|
writebuf(struct.pack('I', len(attachment.name)))
|
||||||
writebuf(attachment.name.encode())
|
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
|
# Access actor's contained action names
|
||||||
def get_action_names(writebuf):
|
def get_action_names(writebuf):
|
||||||
|
@ -433,6 +452,9 @@ def get_action_names(writebuf):
|
||||||
action = sact_data.actions[action_idx]
|
action = sact_data.actions[action_idx]
|
||||||
writebuf(struct.pack('I', len(action.name)))
|
writebuf(struct.pack('I', len(action.name)))
|
||||||
writebuf(action.name.encode())
|
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
|
# Panel draw
|
||||||
def draw(layout, context):
|
def draw(layout, context):
|
||||||
|
@ -452,6 +474,7 @@ def register():
|
||||||
SACTAction.register()
|
SACTAction.register()
|
||||||
bpy.utils.register_class(SACTData)
|
bpy.utils.register_class(SACTData)
|
||||||
bpy.types.Scene.hecl_sact_data = bpy.props.PointerProperty(type=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_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_additive = bpy.props.BoolProperty(name='HECL Additive Action', default=False)
|
||||||
bpy.types.Action.hecl_looping = bpy.props.BoolProperty(name='HECL Looping 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):
|
def hashpath32(self, path):
|
||||||
writepipestr(path.encode())
|
writepipestr(path.encode())
|
||||||
read_str = readpipestr()
|
read_str = readpipestr()
|
||||||
if len(read_str) >= 16:
|
return int(read_str[0:8], 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
|
|
||||||
|
|
||||||
# Ensure Blender 2.8 is being used
|
# Ensure Blender 2.8 is being used
|
||||||
if bpy.app.version < (2, 80, 0):
|
if bpy.app.version < (2, 80, 0):
|
||||||
|
@ -226,21 +216,21 @@ def dataout_loop():
|
||||||
elif cmdargs[0] == 'MESHLIST':
|
elif cmdargs[0] == 'MESHLIST':
|
||||||
meshCount = 0
|
meshCount = 0
|
||||||
for meshobj in bpy.data.objects:
|
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
|
meshCount += 1
|
||||||
writepipebuf(struct.pack('I', meshCount))
|
writepipebuf(struct.pack('I', meshCount))
|
||||||
for meshobj in bpy.data.objects:
|
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())
|
writepipestr(meshobj.name.encode())
|
||||||
|
|
||||||
elif cmdargs[0] == 'LIGHTLIST':
|
elif cmdargs[0] == 'LIGHTLIST':
|
||||||
lightCount = 0
|
lightCount = 0
|
||||||
for obj in bpy.context.scene.objects:
|
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
|
lightCount += 1
|
||||||
writepipebuf(struct.pack('I', lightCount))
|
writepipebuf(struct.pack('I', lightCount))
|
||||||
for obj in bpy.context.scene.objects:
|
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())
|
writepipestr(obj.name.encode())
|
||||||
|
|
||||||
elif cmdargs[0] == 'MESHAABB':
|
elif cmdargs[0] == 'MESHAABB':
|
||||||
|
@ -256,6 +246,15 @@ def dataout_loop():
|
||||||
writepipestr(b'OK')
|
writepipestr(b'OK')
|
||||||
hecl.hmdl.cook(writepipebuf, bpy.data.objects[meshName])
|
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':
|
elif cmdargs[0] == 'MESHCOMPILENAME':
|
||||||
meshName = cmdargs[1]
|
meshName = cmdargs[1]
|
||||||
useLuv = int(cmdargs[2])
|
useLuv = int(cmdargs[2])
|
||||||
|
@ -281,13 +280,13 @@ def dataout_loop():
|
||||||
writepipestr(b'OK')
|
writepipestr(b'OK')
|
||||||
colCount = 0
|
colCount = 0
|
||||||
for obj in bpy.context.scene.objects:
|
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
|
colCount += 1
|
||||||
|
|
||||||
writepipebuf(struct.pack('I', colCount))
|
writepipebuf(struct.pack('I', colCount))
|
||||||
|
|
||||||
for obj in bpy.context.scene.objects:
|
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)
|
hecl.hmdl.cookcol(writepipebuf, obj)
|
||||||
|
|
||||||
elif cmdargs[0] == 'MESHCOMPILEPATH':
|
elif cmdargs[0] == 'MESHCOMPILEPATH':
|
||||||
|
@ -384,10 +383,6 @@ def dataout_loop():
|
||||||
writepipestr(b'OK')
|
writepipestr(b'OK')
|
||||||
hecl.sact.cook_action_channels_only(writepipebuf, actionName)
|
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':
|
elif cmdargs[0] == 'GETSUBTYPENAMES':
|
||||||
writepipestr(b'OK')
|
writepipestr(b'OK')
|
||||||
hecl.sact.get_subtype_names(writepipebuf)
|
hecl.sact.get_subtype_names(writepipebuf)
|
||||||
|
|
|
@ -26,7 +26,7 @@ public:
|
||||||
for (const hecl::SystemString& arg : info.args) {
|
for (const hecl::SystemString& arg : info.args) {
|
||||||
if (arg.empty())
|
if (arg.empty())
|
||||||
continue;
|
continue;
|
||||||
else if (!arg.compare(_SYS_STR("--fast"))) {
|
else if (arg == _SYS_STR("--fast")) {
|
||||||
m_fast = true;
|
m_fast = true;
|
||||||
continue;
|
continue;
|
||||||
} else if (arg.size() >= 8 && !arg.compare(0, 7, _SYS_STR("--spec="))) {
|
} 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) {
|
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);
|
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) {
|
void FindSelectedItems(const hecl::ProjectPath& path, bool checkGeneral) {
|
||||||
|
@ -70,7 +65,7 @@ public:
|
||||||
for (const hecl::SystemString& arg : info.args) {
|
for (const hecl::SystemString& arg : info.args) {
|
||||||
if (arg.empty())
|
if (arg.empty())
|
||||||
continue;
|
continue;
|
||||||
else if (!arg.compare(_SYS_STR("--fast"))) {
|
else if (arg == _SYS_STR("--fast")) {
|
||||||
m_fast = true;
|
m_fast = true;
|
||||||
continue;
|
continue;
|
||||||
} else if (arg.size() >= 8 && !arg.compare(0, 7, _SYS_STR("--spec="))) {
|
} else if (arg.size() >= 8 && !arg.compare(0, 7, _SYS_STR("--spec="))) {
|
||||||
|
|
|
@ -19,9 +19,9 @@ public:
|
||||||
hecl::SystemString firstArg = info.args.front();
|
hecl::SystemString firstArg = info.args.front();
|
||||||
hecl::ToLower(firstArg);
|
hecl::ToLower(firstArg);
|
||||||
|
|
||||||
if (!firstArg.compare(_SYS_STR("enable")))
|
if (firstArg == _SYS_STR("enable"))
|
||||||
mode = MENABLE;
|
mode = MENABLE;
|
||||||
else if (!firstArg.compare(_SYS_STR("disable")))
|
else if (firstArg == _SYS_STR("disable"))
|
||||||
mode = MDISABLE;
|
mode = MDISABLE;
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
@ -112,7 +112,7 @@ public:
|
||||||
for (auto& spec : specs) {
|
for (auto& spec : specs) {
|
||||||
hecl::SystemString compName(spec.spec.m_name);
|
hecl::SystemString compName(spec.spec.m_name);
|
||||||
hecl::ToLower(compName);
|
hecl::ToLower(compName);
|
||||||
if (!itName.compare(compName)) {
|
if (itName == compName) {
|
||||||
opSpecs.emplace_back(spec.spec.m_name);
|
opSpecs.emplace_back(spec.spec.m_name);
|
||||||
break;
|
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(PyOutStream& parent, bool deleteOnError) : m_parent(parent), m_deleteOnError(deleteOnError) {}
|
||||||
StreamBuf(const StreamBuf& other) = delete;
|
StreamBuf(const StreamBuf& other) = delete;
|
||||||
StreamBuf(StreamBuf&& other) = default;
|
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;
|
} m_sbuf;
|
||||||
PyOutStream(Connection* parent, bool deleteOnError);
|
PyOutStream(Connection* parent, bool deleteOnError);
|
||||||
|
|
||||||
|
@ -94,8 +95,10 @@ public:
|
||||||
void close();
|
void close();
|
||||||
template <typename S, typename... Args, typename Char = fmt::char_t<S>>
|
template <typename S, typename... Args, typename Char = fmt::char_t<S>>
|
||||||
void format(const S& format, Args&&... args);
|
void format(const S& format, Args&&... args);
|
||||||
void linkBlend(const char* target, const char* objName, bool link = true);
|
void linkBlend(std::string_view target, std::string_view objName, bool link = true);
|
||||||
void linkBackground(const char* target, const char* sceneName = nullptr);
|
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 AABBToBMesh(const atVec3f& min, const atVec3f& max);
|
||||||
void centerView();
|
void centerView();
|
||||||
|
|
||||||
|
@ -498,15 +501,15 @@ struct Light {
|
||||||
|
|
||||||
/** Intermediate MapArea representation */
|
/** Intermediate MapArea representation */
|
||||||
struct MapArea {
|
struct MapArea {
|
||||||
Index visType;
|
uint32_t visType;
|
||||||
std::vector<Vector3f> verts;
|
std::vector<Vector3f> verts;
|
||||||
std::vector<Index> indices;
|
std::vector<uint32_t> indices;
|
||||||
struct Surface {
|
struct Surface {
|
||||||
Vector3f normal;
|
Vector3f normal;
|
||||||
Vector3f centerOfMass;
|
Vector3f centerOfMass;
|
||||||
Index start;
|
uint32_t start;
|
||||||
Index count;
|
uint32_t count;
|
||||||
std::vector<std::pair<Index, Index>> borders;
|
std::vector<std::pair<uint32_t, uint32_t>> borders;
|
||||||
Surface(Connection& conn);
|
Surface(Connection& conn);
|
||||||
};
|
};
|
||||||
std::vector<Surface> surfaces;
|
std::vector<Surface> surfaces;
|
||||||
|
@ -547,7 +550,6 @@ struct Bone {
|
||||||
|
|
||||||
/** Intermediate armature representation used in Actor */
|
/** Intermediate armature representation used in Actor */
|
||||||
struct Armature {
|
struct Armature {
|
||||||
std::string name;
|
|
||||||
std::vector<Bone> bones;
|
std::vector<Bone> bones;
|
||||||
const Bone* lookupBone(const char* name) const;
|
const Bone* lookupBone(const char* name) const;
|
||||||
const Bone* getParent(const Bone* bone) const;
|
const Bone* getParent(const Bone* bone) const;
|
||||||
|
@ -559,6 +561,7 @@ struct Armature {
|
||||||
/** Intermediate action representation used in Actor */
|
/** Intermediate action representation used in Actor */
|
||||||
struct Action {
|
struct Action {
|
||||||
std::string name;
|
std::string name;
|
||||||
|
std::string animId;
|
||||||
float interval;
|
float interval;
|
||||||
bool additive;
|
bool additive;
|
||||||
bool looping;
|
bool looping;
|
||||||
|
@ -582,18 +585,32 @@ struct Action {
|
||||||
|
|
||||||
/** Intermediate actor representation prepared by blender from a single HECL actor blend */
|
/** Intermediate actor representation prepared by blender from a single HECL actor blend */
|
||||||
struct Actor {
|
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 {
|
struct Subtype {
|
||||||
std::string name;
|
std::string name;
|
||||||
|
std::string cskrId;
|
||||||
ProjectPath mesh;
|
ProjectPath mesh;
|
||||||
int32_t armature = -1;
|
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);
|
Subtype(Connection& conn);
|
||||||
};
|
};
|
||||||
std::vector<Subtype> subtypes;
|
std::vector<Subtype> subtypes;
|
||||||
struct Attachment {
|
struct Attachment {
|
||||||
std::string name;
|
std::string name;
|
||||||
|
std::string cskrId;
|
||||||
ProjectPath mesh;
|
ProjectPath mesh;
|
||||||
int32_t armature = -1;
|
int32_t armature = -1;
|
||||||
Attachment(Connection& conn);
|
Attachment(Connection& conn);
|
||||||
|
@ -654,12 +671,12 @@ public:
|
||||||
|
|
||||||
Actor compileActor();
|
Actor compileActor();
|
||||||
Actor compileActorCharacterOnly();
|
Actor compileActorCharacterOnly();
|
||||||
|
Armature compileArmature();
|
||||||
Action compileActionChannelsOnly(std::string_view name);
|
Action compileActionChannelsOnly(std::string_view name);
|
||||||
std::vector<std::string> getArmatureNames();
|
std::vector<std::pair<std::string, std::string>> getSubtypeNames();
|
||||||
std::vector<std::string> getSubtypeNames();
|
std::vector<std::pair<std::string, std::string>> getActionNames();
|
||||||
std::vector<std::string> getActionNames();
|
std::vector<std::pair<std::string, std::string>> getSubtypeOverlayNames(std::string_view name);
|
||||||
std::vector<std::string> getSubtypeOverlayNames(std::string_view name);
|
std::vector<std::pair<std::string, std::string>> getAttachmentNames();
|
||||||
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);
|
||||||
|
|
||||||
|
@ -695,6 +712,7 @@ class Connection {
|
||||||
friend struct Vector3f;
|
friend struct Vector3f;
|
||||||
friend struct Vector4f;
|
friend struct Vector4f;
|
||||||
friend struct World;
|
friend struct World;
|
||||||
|
friend class MeshOptimizer;
|
||||||
|
|
||||||
std::atomic_bool m_lock = {false};
|
std::atomic_bool m_lock = {false};
|
||||||
bool m_pyStreamActive = false;
|
bool m_pyStreamActive = false;
|
||||||
|
@ -718,6 +736,80 @@ class Connection {
|
||||||
uint32_t _writeStr(std::string_view view) { return _writeStr(view.data(), view.size()); }
|
uint32_t _writeStr(std::string_view view) { return _writeStr(view.data(), view.size()); }
|
||||||
size_t _readBuf(void* buf, size_t len);
|
size_t _readBuf(void* buf, size_t len);
|
||||||
size_t _writeBuf(const 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 _closePipe();
|
||||||
void _blenderDied();
|
void _blenderDied();
|
||||||
|
|
||||||
|
@ -764,8 +856,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename S, typename... Args, typename Char>
|
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)
|
if (!m_parent || !m_parent->m_lock)
|
||||||
BlenderLog.report(logvisor::Fatal, fmt("lock not held for PyOutStream::format()"));
|
BlenderLog.report(logvisor::Fatal, fmt("lock not held for PyOutStream::format()"));
|
||||||
fmt::print(*this, format, std::forward<Args>(args)...);
|
fmt::print(*this, format, std::forward<Args>(args)...);
|
||||||
|
|
|
@ -15,8 +15,6 @@
|
||||||
|
|
||||||
#include "hecl.hpp"
|
#include "hecl.hpp"
|
||||||
|
|
||||||
#define RUNTIME_ORIGINAL_IDS 0
|
|
||||||
|
|
||||||
namespace hecl {
|
namespace hecl {
|
||||||
class ClientProcess;
|
class ClientProcess;
|
||||||
|
|
||||||
|
|
|
@ -72,12 +72,12 @@ inline void DNAFourCC::Enumerate<BigDNA::Write>(Write::StreamT& w) {
|
||||||
}
|
}
|
||||||
template <>
|
template <>
|
||||||
inline void DNAFourCC::Enumerate<BigDNA::ReadYaml>(ReadYaml::StreamT& r) {
|
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));
|
rs.copy(fcc, std::size(fcc));
|
||||||
}
|
}
|
||||||
template <>
|
template <>
|
||||||
inline void DNAFourCC::Enumerate<BigDNA::WriteYaml>(WriteYaml::StreamT& w) {
|
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 <>
|
template <>
|
||||||
inline void DNAFourCC::Enumerate<BigDNA::BinarySize>(BinarySize::StreamT& s) {
|
inline void DNAFourCC::Enumerate<BigDNA::BinarySize>(BinarySize::StreamT& s) {
|
||||||
|
|
|
@ -204,7 +204,7 @@ template <> \
|
||||||
template <> \
|
template <> \
|
||||||
inline void hecl::TypedVariantBigDNA<__VA_ARGS__>::Enumerate<athena::io::DNA<athena::Big>::Read>(typename Read::StreamT & r) { \
|
inline void hecl::TypedVariantBigDNA<__VA_ARGS__>::Enumerate<athena::io::DNA<athena::Big>::Read>(typename Read::StreamT & r) { \
|
||||||
EnumType variant_type = {}; \
|
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); \
|
static_cast<TypedVariant<__VA_ARGS__>&>(*this) = Build(variant_type); \
|
||||||
visit([&](auto& var) { var.read(r); }); \
|
visit([&](auto& var) { var.read(r); }); \
|
||||||
} \
|
} \
|
||||||
|
@ -215,7 +215,7 @@ inline void hecl::TypedVariantBigDNA<__VA_ARGS__>::Enumerate<athena::io::DNA<ath
|
||||||
visit([&](auto& var) { \
|
visit([&](auto& var) { \
|
||||||
using T = std::decay_t<decltype(var)>; \
|
using T = std::decay_t<decltype(var)>; \
|
||||||
EnumType variant_type = T::variant_type(); \
|
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); \
|
var.write(w); \
|
||||||
}); \
|
}); \
|
||||||
} \
|
} \
|
||||||
|
@ -226,13 +226,13 @@ inline void hecl::TypedVariantBigDNA<__VA_ARGS__>::Enumerate<athena::io::DNA<ath
|
||||||
visit([&](auto& var) { \
|
visit([&](auto& var) { \
|
||||||
using T = std::decay_t<decltype(var)>; \
|
using T = std::decay_t<decltype(var)>; \
|
||||||
EnumType variant_type = T::variant_type(); \
|
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); \
|
var.binarySize(sz); \
|
||||||
}); \
|
}); \
|
||||||
} \
|
} \
|
||||||
template <> \
|
template <> \
|
||||||
inline const char* hecl::TypedVariantBigDNA<__VA_ARGS__>::DNAType() { \
|
inline std::string_view hecl::TypedVariantBigDNA<__VA_ARGS__>::DNAType() { \
|
||||||
return "hecl::TypedVariantBigDNA<" #__VA_ARGS__ ">"; \
|
return "hecl::TypedVariantBigDNA<" #__VA_ARGS__ ">"sv; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define AT_SPECIALIZE_TYPED_VARIANT_BIGDNA_YAML(...) \
|
#define AT_SPECIALIZE_TYPED_VARIANT_BIGDNA_YAML(...) \
|
||||||
|
@ -241,7 +241,7 @@ template <> \
|
||||||
template <> \
|
template <> \
|
||||||
inline void hecl::TypedVariantBigDNA<__VA_ARGS__>::Enumerate<athena::io::DNA<athena::Big>::ReadYaml>(typename ReadYaml::StreamT & r) { \
|
inline void hecl::TypedVariantBigDNA<__VA_ARGS__>::Enumerate<athena::io::DNA<athena::Big>::ReadYaml>(typename ReadYaml::StreamT & r) { \
|
||||||
EnumType variant_type = {}; \
|
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); \
|
static_cast<TypedVariant<__VA_ARGS__>&>(*this) = Build(variant_type); \
|
||||||
visit([&](auto& var) { var.read(r); }); \
|
visit([&](auto& var) { var.read(r); }); \
|
||||||
} \
|
} \
|
||||||
|
@ -252,7 +252,7 @@ inline void hecl::TypedVariantBigDNA<__VA_ARGS__>::Enumerate<athena::io::DNA<ath
|
||||||
visit([&](auto& var) { \
|
visit([&](auto& var) { \
|
||||||
using T = std::decay_t<decltype(var)>; \
|
using T = std::decay_t<decltype(var)>; \
|
||||||
EnumType variant_type = T::variant_type(); \
|
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); \
|
var.write(w); \
|
||||||
}); \
|
}); \
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,8 @@ struct DataSpecEntry;
|
||||||
} // namespace Database
|
} // namespace Database
|
||||||
|
|
||||||
namespace blender {
|
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 Connection;
|
||||||
class Token;
|
class Token;
|
||||||
|
@ -137,6 +138,8 @@ public:
|
||||||
return std::wstring(lhs).append(rhs.m_sys);
|
return std::wstring(lhs).append(rhs.m_sys);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline hecl::SystemString UTF8StringToSysString(std::string_view src) { return UTF8ToWide(src); }
|
||||||
#else
|
#else
|
||||||
class SystemUTF8Conv {
|
class SystemUTF8Conv {
|
||||||
std::string_view m_utf8;
|
std::string_view m_utf8;
|
||||||
|
@ -171,6 +174,8 @@ public:
|
||||||
return std::string(lhs).append(rhs.m_sys);
|
return std::string(lhs).append(rhs.m_sys);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline hecl::SystemString UTF8StringToSysString(std::string src) { return src; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void SanitizePath(std::string& path);
|
void SanitizePath(std::string& path);
|
||||||
|
@ -423,7 +428,9 @@ class MultiProgressPrinter;
|
||||||
class ProjectRootPath;
|
class ProjectRootPath;
|
||||||
|
|
||||||
using SystemRegex = std::basic_regex<SystemChar>;
|
using SystemRegex = std::basic_regex<SystemChar>;
|
||||||
|
using SystemRegexIterator = std::regex_iterator<SystemString::const_iterator>;
|
||||||
using SystemRegexMatch = std::match_results<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>;
|
using SystemRegexTokenIterator = std::regex_token_iterator<SystemString::const_iterator>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -929,6 +936,36 @@ public:
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
* @brief Type of path
|
||||||
*/
|
*/
|
||||||
|
@ -1053,6 +1090,8 @@ public:
|
||||||
Hash hash() const noexcept { return m_hash; }
|
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 m_hash == other.m_hash; }
|
||||||
bool operator!=(const ProjectPath& other) const noexcept { return !operator==(other); }
|
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
|
} // 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 {
|
namespace std {
|
||||||
template <>
|
template <>
|
||||||
struct hash<hecl::ProjectPath> {
|
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) {
|
MeshOptimizer::Vertex::Vertex(Connection& conn) {
|
||||||
co.read(conn);
|
co.read(conn);
|
||||||
Index skin_count(conn);
|
uint32_t skin_count;
|
||||||
if (skin_count.val > MaxSkinEntries)
|
conn._readValue(skin_count);
|
||||||
Log.report(logvisor::Fatal, fmt("Skin entry overflow {}/{}"), skin_count.val, MaxSkinEntries);
|
if (skin_count > MaxSkinEntries)
|
||||||
for (uint32_t i = 0; i < skin_count.val; ++i)
|
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);
|
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);
|
colors[i].read(conn);
|
||||||
for (uint32_t i = 0; i < uv_count; ++i)
|
for (uint32_t i = 0; i < uv_count; ++i)
|
||||||
uvs[i].read(conn);
|
uvs[i].read(conn);
|
||||||
vert = Index(conn).val;
|
conn._readValue(vert);
|
||||||
edge = Index(conn).val;
|
conn._readValue(edge);
|
||||||
face = Index(conn).val;
|
conn._readValue(face);
|
||||||
link_loop_next = Index(conn).val;
|
conn._readValue(link_loop_next);
|
||||||
link_loop_prev = Index(conn).val;
|
conn._readValue(link_loop_prev);
|
||||||
link_loop_radial_next = Index(conn).val;
|
conn._readValue(link_loop_radial_next);
|
||||||
link_loop_radial_prev = Index(conn).val;
|
conn._readValue(link_loop_radial_prev);
|
||||||
}
|
}
|
||||||
|
|
||||||
MeshOptimizer::Edge::Edge(Connection& conn) {
|
MeshOptimizer::Edge::Edge(Connection& conn) {
|
||||||
for (uint32_t i = 0; i < 2; ++i)
|
for (uint32_t i = 0; i < 2; ++i)
|
||||||
verts[i] = Index(conn).val;
|
conn._readValue(verts[i]);
|
||||||
Index face_count(conn);
|
uint32_t face_count;
|
||||||
|
conn._readValue(face_count);
|
||||||
if (face_count > MaxLinkFaces)
|
if (face_count > MaxLinkFaces)
|
||||||
Log.report(logvisor::Fatal, fmt("Face overflow {}/{}"), face_count.val, MaxLinkFaces);
|
Log.report(logvisor::Fatal, fmt("Face overflow {}/{}"), face_count, MaxLinkFaces);
|
||||||
for (uint32_t i = 0; i < face_count.val; ++i)
|
for (uint32_t i = 0; i < face_count; ++i)
|
||||||
link_faces[i] = Index(conn).val;
|
conn._readValue(link_faces[i]);
|
||||||
is_contiguous = Boolean(conn).val;
|
conn._readValue(is_contiguous);
|
||||||
}
|
}
|
||||||
|
|
||||||
MeshOptimizer::Face::Face(Connection& conn) {
|
MeshOptimizer::Face::Face(Connection& conn) {
|
||||||
normal.read(conn);
|
normal.read(conn);
|
||||||
centroid.read(conn);
|
centroid.read(conn);
|
||||||
material_index = Index(conn).val;
|
conn._readValue(material_index);
|
||||||
for (uint32_t i = 0; i < 3; ++i)
|
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 {
|
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)
|
MeshOptimizer::MeshOptimizer(Connection& conn, const std::vector<Material>& materials, bool use_luvs)
|
||||||
: materials(materials), use_luvs(use_luvs) {
|
: materials(materials), use_luvs(use_luvs) {
|
||||||
color_count = Index(conn).val;
|
conn._readValue(color_count);
|
||||||
if (color_count > MaxColorLayers)
|
if (color_count > MaxColorLayers)
|
||||||
Log.report(logvisor::Fatal, fmt("Color layer overflow {}/{}"), 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)
|
if (uv_count > MaxUVLayers)
|
||||||
Log.report(logvisor::Fatal, fmt("UV layer overflow {}/{}"), uv_count, MaxUVLayers);
|
Log.report(logvisor::Fatal, fmt("UV layer overflow {}/{}"), uv_count, MaxUVLayers);
|
||||||
|
|
||||||
/* Simultaneously load topology objects and build unique mapping indices */
|
/* Simultaneously load topology objects and build unique mapping indices */
|
||||||
|
|
||||||
Index vert_count(conn);
|
uint32_t vert_count;
|
||||||
verts.reserve(vert_count.val);
|
conn._readValue(vert_count);
|
||||||
b_pos.reserve(vert_count.val);
|
verts.reserve(vert_count);
|
||||||
b_skin.reserve(vert_count.val * 4);
|
b_pos.reserve(vert_count);
|
||||||
for (uint32_t i = 0; i < vert_count.val; ++i) {
|
b_skin.reserve(vert_count * 4);
|
||||||
|
for (uint32_t i = 0; i < vert_count; ++i) {
|
||||||
verts.emplace_back(conn);
|
verts.emplace_back(conn);
|
||||||
insert_unique_attr(b_pos, verts.back().co);
|
insert_unique_attr(b_pos, verts.back().co);
|
||||||
if (verts.back().skin_ents[0].valid())
|
if (verts.back().skin_ents[0].valid())
|
||||||
insert_unique_attr(b_skin, verts.back().skin_ents);
|
insert_unique_attr(b_skin, verts.back().skin_ents);
|
||||||
}
|
}
|
||||||
|
|
||||||
Index loop_count(conn);
|
uint32_t loop_count;
|
||||||
loops.reserve(loop_count.val);
|
conn._readValue(loop_count);
|
||||||
b_norm.reserve(loop_count.val);
|
loops.reserve(loop_count);
|
||||||
|
b_norm.reserve(loop_count);
|
||||||
if (use_luvs) {
|
if (use_luvs) {
|
||||||
b_uv.reserve(std::max(int(loop_count.val) - 1, 0) * uv_count);
|
b_uv.reserve(std::max(int(loop_count) - 1, 0) * uv_count);
|
||||||
b_luv.reserve(loop_count.val);
|
b_luv.reserve(loop_count);
|
||||||
} else {
|
} 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);
|
loops.emplace_back(conn, color_count, uv_count);
|
||||||
insert_unique_attr(b_norm, loops.back().normal);
|
insert_unique_attr(b_norm, loops.back().normal);
|
||||||
for (const auto& c : loops.back().colors)
|
for (const auto& c : loops.back().colors)
|
||||||
|
@ -420,15 +424,8 @@ MeshOptimizer::MeshOptimizer(Connection& conn, const std::vector<Material>& mate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Index edge_count(conn);
|
conn._readVector(edges);
|
||||||
edges.reserve(edge_count.val);
|
conn._readVector(faces);
|
||||||
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);
|
|
||||||
|
|
||||||
/* Cache edges that should block tristrip traversal */
|
/* Cache edges that should block tristrip traversal */
|
||||||
for (auto& e : edges)
|
for (auto& e : edges)
|
||||||
|
|
|
@ -29,7 +29,7 @@ const SDNABlock::SDNAStruct::SDNAField* SDNABlock::SDNAStruct::lookupField(const
|
||||||
if (bracket != std::string::npos) {
|
if (bracket != std::string::npos) {
|
||||||
if (!name.compare(0, bracket, n))
|
if (!name.compare(0, bracket, n))
|
||||||
return &field;
|
return &field;
|
||||||
} else if (!name.compare(n))
|
} else if (name == n)
|
||||||
return &field;
|
return &field;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -39,7 +39,7 @@ const SDNABlock::SDNAStruct* SDNABlock::lookupStruct(const char* n, atUint32& id
|
||||||
idx = 0;
|
idx = 0;
|
||||||
for (const SDNAStruct& strc : strcs) {
|
for (const SDNAStruct& strc : strcs) {
|
||||||
const auto& name = types[strc.type];
|
const auto& name = types[strc.type];
|
||||||
if (!name.compare(n))
|
if (name == n)
|
||||||
return &strc;
|
return &strc;
|
||||||
++idx;
|
++idx;
|
||||||
}
|
}
|
||||||
|
|
|
@ -165,11 +165,11 @@ bool CVar::toBoolean(bool* isValid) const {
|
||||||
std::string tmp = m_value;
|
std::string tmp = m_value;
|
||||||
athena::utility::tolower(tmp);
|
athena::utility::tolower(tmp);
|
||||||
|
|
||||||
if (!tmp.compare("yes") || !tmp.compare("true") || !tmp.compare("1")) {
|
if (tmp == "yes" || tmp == "true" || tmp == "1") {
|
||||||
if (isValid)
|
if (isValid)
|
||||||
*isValid = true;
|
*isValid = true;
|
||||||
return true;
|
return true;
|
||||||
} else if (!tmp.compare("no") || !tmp.compare("false") || !tmp.compare("0")) {
|
} else if (tmp == "no" || tmp == "false" || tmp == "0") {
|
||||||
if (isValid)
|
if (isValid)
|
||||||
*isValid = true;
|
*isValid = true;
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -181,7 +181,7 @@ void CVarManager::serialize() {
|
||||||
filename += _SYS_STR(".yaml");
|
filename += _SYS_STR(".yaml");
|
||||||
|
|
||||||
athena::io::FileReader r(filename);
|
athena::io::FileReader r(filename);
|
||||||
athena::io::YAMLDocWriter docWriter(nullptr, r.isOpen() ? &r : nullptr);
|
athena::io::YAMLDocWriter docWriter(r.isOpen() ? &r : nullptr);
|
||||||
r.close();
|
r.close();
|
||||||
|
|
||||||
docWriter.setStyle(athena::io::YAMLNodeStyle::Block);
|
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();) {
|
for (auto it = m_lines.begin(); it != m_lines.end();) {
|
||||||
if (!(*it).compare(refLine)) {
|
if (*it == refLine) {
|
||||||
it = m_lines.erase(it);
|
it = m_lines.erase(it);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ bool Project::ConfigFile::checkForLine(std::string_view refLine) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const std::string& line : m_lines)
|
for (const std::string& line : m_lines)
|
||||||
if (!line.compare(refLine))
|
if (line == refLine)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,9 +14,9 @@ static SystemString CanonRelPath(SystemStringView path) {
|
||||||
SanitizePath(in);
|
SanitizePath(in);
|
||||||
for (; std::regex_search(in, matches, regPATHCOMP); in = matches.suffix().str()) {
|
for (; std::regex_search(in, matches, regPATHCOMP); in = matches.suffix().str()) {
|
||||||
hecl::SystemRegexMatch::const_reference match = matches[1];
|
hecl::SystemRegexMatch::const_reference match = matches[1];
|
||||||
if (!match.compare(_SYS_STR(".")))
|
if (match == _SYS_STR("."))
|
||||||
continue;
|
continue;
|
||||||
else if (!match.compare(_SYS_STR(".."))) {
|
else if (match == _SYS_STR("..")) {
|
||||||
if (comps.empty()) {
|
if (comps.empty()) {
|
||||||
/* Unable to resolve outside project */
|
/* Unable to resolve outside project */
|
||||||
LogModule.report(logvisor::Fatal, fmt(_SYS_STR("Unable to resolve outside project root in {}")), path);
|
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 {
|
ProjectPath::Type ProjectPath::getPathType() const {
|
||||||
|
if (m_absPath.empty())
|
||||||
|
return Type::None;
|
||||||
if (m_absPath.find(_SYS_STR('*')) != SystemString::npos)
|
if (m_absPath.find(_SYS_STR('*')) != SystemString::npos)
|
||||||
return Type::Glob;
|
return Type::Glob;
|
||||||
Sstat theStat;
|
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('/'));
|
_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 SearchForProject(SystemStringView path) {
|
||||||
ProjectRootPath testRoot(path);
|
ProjectRootPath testRoot(path);
|
||||||
auto begin = testRoot.getAbsolutePath().begin();
|
auto begin = testRoot.getAbsolutePath().begin();
|
||||||
|
|
|
@ -30,11 +30,13 @@
|
||||||
|
|
||||||
#include <logvisor/logvisor.hpp>
|
#include <logvisor/logvisor.hpp>
|
||||||
|
|
||||||
|
using namespace std::literals;
|
||||||
|
|
||||||
namespace hecl {
|
namespace hecl {
|
||||||
unsigned VerbosityLevel = 0;
|
unsigned VerbosityLevel = 0;
|
||||||
bool GuiMode = false;
|
bool GuiMode = false;
|
||||||
logvisor::Module LogModule("hecl");
|
logvisor::Module LogModule("hecl");
|
||||||
constexpr std::string_view Illegals{"<>?\""};
|
constexpr std::string_view Illegals = "<>?\""sv;
|
||||||
|
|
||||||
void SanitizePath(std::string& path) {
|
void SanitizePath(std::string& path) {
|
||||||
if (path.empty())
|
if (path.empty())
|
||||||
|
@ -64,7 +66,7 @@ void SanitizePath(std::string& path) {
|
||||||
path.pop_back();
|
path.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr std::wstring_view WIllegals{L"<>?\""};
|
constexpr std::wstring_view WIllegals = L"<>?\""sv;
|
||||||
|
|
||||||
void SanitizePath(std::wstring& path) {
|
void SanitizePath(std::wstring& path) {
|
||||||
if (path.empty())
|
if (path.empty())
|
||||||
|
@ -174,9 +176,8 @@ bool IsPathPNG(const hecl::ProjectPath& path) {
|
||||||
|
|
||||||
bool IsPathBlend(const hecl::ProjectPath& path) {
|
bool IsPathBlend(const hecl::ProjectPath& path) {
|
||||||
const auto lastCompExt = path.getLastComponentExt();
|
const auto lastCompExt = path.getLastComponentExt();
|
||||||
if (lastCompExt.empty() || hecl::StrCmp(lastCompExt.data(), _SYS_STR("blend"))) {
|
if (lastCompExt.empty() || lastCompExt != _SYS_STR("blend"))
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
const auto fp = hecl::FopenUnique(path.getAbsolutePath().data(), _SYS_STR("rb"));
|
const auto fp = hecl::FopenUnique(path.getAbsolutePath().data(), _SYS_STR("rb"));
|
||||||
if (fp == nullptr) {
|
if (fp == nullptr) {
|
||||||
|
@ -193,14 +194,15 @@ bool IsPathBlend(const hecl::ProjectPath& path) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsPathYAML(const hecl::ProjectPath& path) {
|
bool IsPathYAML(const hecl::ProjectPath& path) {
|
||||||
if (!hecl::StrCmp(path.getLastComponent().data(), _SYS_STR("!catalog.yaml")))
|
auto lastComp = path.getLastComponent();
|
||||||
return false; /* !catalog.yaml is exempt from general use */
|
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();
|
auto lastCompExt = path.getLastComponentExt();
|
||||||
if (lastCompExt.empty())
|
if (lastCompExt.empty())
|
||||||
return false;
|
return false;
|
||||||
if (!hecl::StrCmp(lastCompExt.data(), _SYS_STR("yaml")) || !hecl::StrCmp(lastCompExt.data(), _SYS_STR("yml")))
|
return lastCompExt == _SYS_STR("yaml") || lastCompExt == _SYS_STR("yml");
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hecl::DirectoryEnumerator::DirectoryEnumerator(SystemStringView path, Mode mode, bool sizeSort, bool reverse,
|
hecl::DirectoryEnumerator::DirectoryEnumerator(SystemStringView path, Mode mode, bool sizeSort, bool reverse,
|
||||||
|
|
Loading…
Reference in New Issue