# Lane 0: dump the mixamorig armature (names + rest pose) from character_kit → ground truth. # Run: Blender --background --python spec/dump_bones.py import bpy, json, os, sys GLB = os.path.expanduser("~/Documents/character_kit/female/female_game.glb") OUT = os.path.join(os.path.dirname(os.path.abspath(__file__)), "mixamorig_bones.json") bpy.ops.wm.read_factory_settings(use_empty=True) bpy.ops.import_scene.gltf(filepath=GLB) arm = next((o for o in bpy.data.objects if o.type == "ARMATURE"), None) if arm is None: sys.exit("no armature in " + GLB) def v(x): # round rest coords, they're the reference not gospel return [round(c, 6) for c in x] bones = [{ "name": b.name, "parent": b.parent.name if b.parent else None, "head": v(b.head_local), # armature-space rest pose "tail": v(b.tail_local), } for b in arm.data.bones] json.dump({ "source": os.path.relpath(GLB, os.path.expanduser("~/Documents")), "armature": arm.name, "count": len(bones), "units": "metres, Y-up (Blender Z-up native; glTF import applies +90X)", "joint_order": [b["name"] for b in bones], "bones": bones, }, open(OUT, "w"), indent=1) print("===DUMP=== %d bones -> %s" % (len(bones), OUT))