#!/usr/bin/env python3 """Rename rig root node in character GLBs to 'Character' for consistent paths. This must run before Godot imports the GLBs. It modifies the .glb JSON to rename the rig root node (oldpop-rig, bob-rig, etc.) to 'Character' so all characters share the same skeleton path: Character/Skeleton3D:bone_name Backups are created as .glb.bak on first run. Re-runnable: if backup exists, restore from backup first to ensure idempotency. """ import json import os import struct import shutil import sys CHARACTERS = { 'Bob.glb': 'bob-rig', 'Oldpop.glb': 'oldpop-rig', 'Masbro.glb': 'masbro-tpose', 'Gatot.glb': 'gatot-tpose', } NEW_NAME = 'Character' CHARS_DIR = os.path.join(os.path.dirname(__file__), '..', 'assets', 'characters') def find_rig_node(nodes, old_name): for i, n in enumerate(nodes): if n.get('name') == old_name: return i return -1 def process_glb(path, old_name): backup = path + '.bak' if os.path.exists(backup): shutil.copy(backup, path) else: shutil.copy(path, backup) with open(path, 'rb') as f: f.read(12) # magic + version + length chunk_len = struct.unpack(' {NEW_NAME}') return True def main(): os.chdir(CHARS_DIR) print(f'Processing GLBs in {CHARS_DIR}') for glb, old_name in CHARACTERS.items(): path = os.path.join(CHARS_DIR, glb) if not os.path.exists(path): print(f' {glb}: not found, skipping') continue process_glb(path, old_name) print('Done.') if __name__ == '__main__': main()