# glTF (+ .bin) → one .glb per model; textures shared in <dest>/_tex/ (referenced as ../_tex/<file>).
import sys, os, json, struct, shutil, re
src, dst, texsrc = sys.argv[1], sys.argv[2], sys.argv[3]
os.makedirs(os.path.join(dst, '_tex'), exist_ok=True)
used = set(); n = 0
for pack in sorted(os.listdir(src)):
    pdir = os.path.join(src, pack)
    if not os.path.isdir(pdir): continue
    os.makedirs(os.path.join(dst, pack), exist_ok=True)
    for f in sorted(os.listdir(pdir)):
        if not f.endswith('.gltf'): continue
        j = json.load(open(os.path.join(pdir, f)))
        bufs = j.get('buffers', [])
        if len(bufs) != 1: print('skip', f); continue
        binary = open(os.path.join(pdir, bufs[0]['uri']), 'rb').read()
        del bufs[0]['uri']
        for im in j.get('images', []):
            base = os.path.splitext(os.path.basename(im.get('uri', '')))[0]
            ext = 'png' if os.path.exists(os.path.join(texsrc, base + '.png')) else 'jpg'
            im['uri'] = '../_tex/' + base + '.' + ext
            im['mimeType'] = 'image/png' if ext == 'png' else 'image/jpeg'
            used.add(base + '.' + ext)
        js = json.dumps(j, separators=(',', ':')).encode(); js += b' ' * (-len(js) % 4)
        binary += b'\0' * (-len(binary) % 4)
        glb = b'glTF' + struct.pack('<II', 2, 28 + len(js) + len(binary)) + struct.pack('<I', len(js)) + b'JSON' + js + struct.pack('<I', len(binary)) + b'BIN\0' + binary
        open(os.path.join(dst, pack, f[:-5] + '.glb'), 'wb').write(glb); n += 1
for t in used: shutil.copy(os.path.join(texsrc, t), os.path.join(dst, '_tex', t))
print('packed', n, 'textures', sorted(used))
