Phase 6.5 checkpoint

This commit is contained in:
2026-10-26 11:03:11 +03:00
parent 9e2d9fce59
commit adc4c91a2c
61 changed files with 10261 additions and 450 deletions
+48 -1
View File
@@ -187,7 +187,14 @@ def extra_linear(angle, offset):
mapping_blend_path = argv[0]
mapping_gltf_path = argv[1]
# Backward compat: support both 4-arg (blend, gltf, armature, outfile) and 5-arg (blend, gltf, objects, armature, outfile)
if len(argv) >= 5:
mapping_lods_path = ""
if len(argv) >= 6:
# 6-arg form: (blend, gltf, objects, armature, outfile, lods_blend)
mapping_objects = argv[2]
mapping_armature_name = argv[3]
mapping_outfile = argv[4]
mapping_lods_path = argv[5]
elif len(argv) >= 5:
mapping_objects = argv[2]
mapping_armature_name = argv[3]
mapping_outfile = argv[4]
@@ -480,6 +487,46 @@ for mapping in[CommandLineMapping()]:
with open(json_filepath, 'w') as f:
json.dump(save_data, f, indent=2)
# ---- Character LOD meshes (demo-taxi phase 6.C.3/6.C.4) ----
# Optional 6th CLI arg: the generate_lods.py output blend. Its
# objects ("<part>_lod1" variants and "charlod_<sex>_*" impostors)
# are appended AFTER auto-discovery/catalog-json writing so they
# never get body_part_*.json entries, re-parented to the scene
# armature (the one prepare_armature produced, which exports the
# shared skeleton) and exported with the main OGRE pass below, so
# the impostor meshes link the SAME skeleton resource as the body
# parts (the runtime shares skeleton instances between them).
lod_obj_names = []
if mapping_lods_path and os.path.exists(mapping_lods_path):
print("Appending character LOD objects from: " + mapping_lods_path)
with bpy.data.libraries.load(mapping_lods_path) as (data_from, data_to):
data_to.objects = [
n for n in data_from.objects
if n.startswith("charlod_") or n.endswith("_lod1")]
body_arm = bpy.data.objects.get(mapping.armature_name)
for obj in data_to.objects:
if obj is None:
continue
try:
bpy.context.collection.objects.link(obj)
except RuntimeError:
pass # Already linked
lod_obj_names.append(obj.name)
# Mesh data names get the sex prefix like the body parts
# (charlod_ names already carry it).
if not obj.name.startswith("charlod_"):
obj.data.name = prefix + obj.name
else:
obj.data.name = obj.name
if body_arm:
obj.parent = body_arm
obj.matrix_parent_inverse = body_arm.matrix_world.inverted()
for mod in obj.modifiers:
if mod.type == 'ARMATURE':
mod.object = body_arm
print(f" LOD object '{obj.name}' -> mesh '{obj.data.name}'")
# -------------------------------------------------------------
# Triangulate body part meshes before OGRE export to prevent the exporter's
# triangulation from producing mismatched split normals at seams.
# BodyTop and BodyBottom have different face topologies, so the exporter's