import struct, math
data = open("content/VIDEO/GEO/TSPHERE.BGF","rb").read()
print("file bytes:", len(data))

TAGS = {0x0003:"HEADER",0x0005:"BIZ_DONE",0x0040:"OBJECT",0x0041:"LOD",0x0042:"PATCH",
0x0046:"PMESH",0x0047:"CONN",0x0048:"SPHERE_LIST",0x004d:"PCONN",0x0070:"BOUND",
0x0080:"V_XYZ",0x0081:"V_XYZ_N",0x0082:"V_XYZ_RGBA",0x0088:"V_XYZ_UV",0x0089:"V_XYZ_N_UV",
0x008A:"V_XYZ_RGBA_UV",0x2030:"SV_MATERIAL",0x2037:"SV_SPECIAL",0x2008:"NAME"}
CONTAINER={0x0003,0x0070,0x0040,0x0041,0x0042,0x0046,0x0048,0x0010,0x0020,0x0030}

verts=[]  # (x,y,z,u,v)
def parse(p,end,depth):
    while p+3<=end:
        tagword=struct.unpack_from("<H",data,p)[0]; p+=2
        cid=tagword&0x2fff
        lw=4 if (tagword&0x8000) else (2 if (tagword&0x4000) else 1)
        if p+lw>end: return
        ln=data[p] if lw==1 else (struct.unpack_from("<H",data,p)[0] if lw==2 else struct.unpack_from("<I",data,p)[0])
        p+=lw
        if p+ln>end: return
        name=TAGS.get(cid,hex(cid))
        if cid in (0x0088,0x0089,0x008A,0x0080,0x0081,0x0082):
            # vertex list
            stride={0x0080:12,0x0081:24,0x0082:28,0x0088:20,0x0089:32,0x008A:36}[cid]
            n=ln//stride
            print("  "*depth+f"{name} verts={n} stride={stride} len={ln}")
            for i in range(n):
                off=p+i*stride
                x,y,z=struct.unpack_from("<fff",data,off)
                u=v=0.0
                if cid==0x0089: u,v=struct.unpack_from("<ff",data,off+24)
                elif cid==0x0088: u,v=struct.unpack_from("<ff",data,off+12)
                elif cid==0x008A: u,v=struct.unpack_from("<ff",data,off+28)
                verts.append((x,y,z,u,v))
        else:
            print("  "*depth+f"{name} id={hex(cid)} len={ln}")
        if cid in CONTAINER:
            parse(p,p+ln,depth+1)
        p+=ln
        if cid==0x0005: break
parse(8,len(data),0)

if verts:
    xs=[v[0] for v in verts]; ys=[v[1] for v in verts]; zs=[v[2] for v in verts]
    us=[v[3] for v in verts]; vs=[v[4] for v in verts]
    print("\n=== GEOMETRY ===")
    print(f"nverts={len(verts)}")
    print(f"x [{min(xs):.2f},{max(xs):.2f}]  y [{min(ys):.2f},{max(ys):.2f}]  z [{min(zs):.2f},{max(zs):.2f}]")
    print(f"u [{min(us):.3f},{max(us):.3f}]  v [{min(vs):.3f},{max(vs):.3f}]")
    # radius from axis (0,8.25,z) per z, to see cone vs sphere vs cylinder
    print("\n=== per-vertex: z, radius_from_yaxis(@8.25), u, v (first 40) ===")
    for (x,y,z,u,v) in verts[:40]:
        dy=y-8.25; r=math.sqrt(x*x+dy*dy)
        print(f"  z={z:7.2f} r={r:7.2f} u={u:7.3f} v={v:7.3f}  (x={x:6.2f} y={y:6.2f})")
