Replace dasher-pack with unified animation-pack using original Blender bone names

This commit is contained in:
2026-06-15 14:28:26 +08:00
parent 9dd3c59edf
commit 844ec194cb
297 changed files with 28680 additions and 1884 deletions
+90
View File
@@ -0,0 +1,90 @@
#!/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('<I', f.read(4))[0]
f.read(4) # chunk type
json_data = f.read(chunk_len)
rest = f.read()
data = json.loads(json_data)
nodes = data.get('nodes', [])
idx = find_rig_node(nodes, old_name)
if idx < 0:
print(f' {os.path.basename(path)}: rig root "{old_name}" NOT FOUND, skipping')
return False
nodes[idx]['name'] = NEW_NAME
new_json = json.dumps(data, separators=(',', ':')).encode('utf-8')
new_chunk_len = len(new_json)
new_length = 12 + 8 + new_chunk_len + len(rest)
with open(path, 'wb') as f:
f.write(b'glTF')
f.write(struct.pack('<I', 2))
f.write(struct.pack('<I', new_length))
f.write(struct.pack('<I', new_chunk_len))
f.write(b'JSON')
f.write(new_json)
f.write(rest)
print(f' {os.path.basename(path)}: renamed {old_name} -> {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()