SOURCE / PINNED RELEASE
Made of little things.
Outbreak: Soycoon City
- Release
- db7750b1d009…
- Author-recorded commit
- 3ee3f5fd27a6…
- License
- LICENSE
- Author’s source reference
- nostr://npub182jczunncwe0jn6frpqwq3e0qjws7yqqnc3auccqv9nte2dnd63scjm4rf/wss%3A%2F%2Fgit.napplet.soy%2F/n-b87c04571a9
Archive hash verified: dbebdc772b142a1c…. The source-to-build association is the author’s claim; it has not been independently rebuilt.
"""Export artist-edited .blend files without regenerating their meshes/actions.
blender --background --factory-startup --python-exit-code 1 --python scripts/export-characters.py
"""
import bpy, json, hashlib
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
manifest_path = ROOT / 'models/manifest.json'
manifest = json.loads(manifest_path.read_text())
for item in manifest['models']:
bpy.ops.wm.open_mainfile(filepath=str(ROOT / item['source']))
rig = next(o for o in bpy.context.scene.objects if o.type == 'ARMATURE')
meshes = [o for o in bpy.context.scene.objects if o.type == 'MESH' and any(m.type == 'ARMATURE' and m.object == rig for m in o.modifiers)]
bpy.ops.object.select_all(action='DESELECT')
rig.select_set(True)
for mesh in meshes:
mesh.select_set(True)
bpy.context.view_layer.objects.active = rig
target = ROOT / item['path']
bpy.ops.export_scene.gltf(filepath=str(target), export_format='GLB', use_selection=True,
export_animations=True, export_animation_mode='ACTIONS', export_anim_single_armature=True,
export_skins=True, export_yup=True, export_apply=False, export_extras=True)
binary = target.read_bytes()
item['size'] = len(binary)
item['sha256'] = hashlib.sha256(binary).hexdigest()
item['bones'] = [bone.name for bone in rig.data.bones]
item['triangles'] = sum(len(p.vertices)-2 for mesh in meshes for p in mesh.data.polygons)
manifest_path.write_text(json.dumps(manifest, indent=2)+'\n')
print('Exported artist-edited character sources; run pnpm test:polish to validate clips and rigs.')
