Files
Fr0zkaandClaude Opus 5.5 dcf0763ec5 wip(assembler): round L18 -- FloatingIslands false floors removed; shared strate ceiling
FI geometry v3 drops the all-XY lower boundary seal that created false floors (3.5/8 m); the
ceiling comes from the shared VF_ApplyUpperBoundarySeal and AppendStratumBoundaryCeilings path
for every generator, at each strate's own configured upper boundary (owner: every strate has a
ceiling). Far-LOD ceiling continuity: 0 gaps at LOD4-8. SurfaceWorld bit-identical to L14
(14 configs + 24 m crossing); FI deterministic (28-row matrix); route parity and proofs pass.
Unreal: FI geometryVersion 2->3 and the shared upper-seal helper extracted (UBT compile needed on
the owner PC). Open: small ceiling holes; lower-stratum LOD ring steps seen through the FI void.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CSFYgsdW8ejZSyiMf4qRSX
2026-10-20 07:55:53 +02:00

101 lines
4.2 KiB
Python

#!/usr/bin/env python3
"""Summarize exported tile geometry and upward-facing ground for L17."""
import array
import collections
import math
import struct
import sys
def read_exact(stream, size):
data = stream.read(size)
if len(data) != size:
raise EOFError(f"wanted {size} bytes, got {len(data)}")
return data
path = sys.argv[1]
with open(path, "rb") as stream:
if read_exact(stream, 8) != b"VFMSH001":
raise SystemExit("bad VFMSH001 header")
version, voxel_um, tile_count = struct.unpack("<3I", read_exact(stream, 12))
camera = struct.unpack("<3d", read_exact(stream, 24))
yaw, pitch = struct.unpack("<2d", read_exact(stream, 16))
per_lod = collections.defaultdict(lambda: {"tiles": 0, "vertices": 0,
"triangles": 0, "surface_triangles": 0, "up_triangles": 0,
"up_centroids": [], "tile_spans": [], "empty": 0})
tile_rows = []
for _ in range(tile_count):
key = struct.unpack("<4i", read_exact(stream, 16))
surf_vertices, skirt_count, vertex_count, index_count, mask_count = struct.unpack(
"<5I", read_exact(stream, 20))
p = array.array("f")
p.frombytes(read_exact(stream, vertex_count * 12))
n = array.array("f")
n.frombytes(read_exact(stream, vertex_count * 12))
if sys.byteorder != "little":
p.byteswap(); n.byteswap()
indices = array.array("I")
indices.frombytes(read_exact(stream, index_count * 4))
masks = read_exact(stream, mask_count)
if sys.byteorder != "little":
indices.byteswap()
lod = key[3]
row = per_lod[lod]
row["tiles"] += 1
row["vertices"] += vertex_count
row["triangles"] += index_count // 3
row["surface_triangles"] += index_count // 3 - skirt_count
up = []
for tri in range(index_count // 3):
if masks and masks[tri] != 0:
continue
a, b, c = indices[tri * 3:tri * 3 + 3]
if max(a, b, c) >= surf_vertices:
continue
if (n[a * 3 + 2] + n[b * 3 + 2] + n[c * 3 + 2]) / 3.0 < 0.65:
continue
up.append((p[a * 3 + 2] + p[b * 3 + 2] + p[c * 3 + 2]) / 3.0)
row["up_triangles"] += len(up)
row["up_centroids"].extend(up)
if up:
up.sort()
span = up[math.floor(0.95 * (len(up) - 1))] - up[math.floor(0.05 * (len(up) - 1))]
row["tile_spans"].append(span)
tile_rows.append((key, vertex_count, index_count // 3, skirt_count,
len(up), up[0], up[len(up) // 2], up[-1], span))
else:
row["empty"] += 1
tile_rows.append((key, vertex_count, index_count // 3, skirt_count,
0, math.nan, math.nan, math.nan, math.nan))
print(f"version={version} voxel_um={voxel_um} tiles={tile_count} camera_m={camera} yaw={yaw} pitch={pitch}")
print("lod tiles mesh_tiles vertices triangles skirt_triangles upward_surface_triangles "
"upward_centroid_z_m_p05/median/p95 tile_up_z_span_m_p50/p95/max")
for lod in sorted(per_lod):
r = per_lod[lod]
z = sorted(r["up_centroids"])
s = sorted(r["tile_spans"])
def q(values, fraction):
return values[math.floor(fraction * (len(values) - 1))] if values else math.nan
print(f"{lod} {r['tiles']} {r['tiles']-r['empty']} {r['vertices']} {r['triangles']} "
f"{sum(row[3] for row in tile_rows if row[0][3] == lod)} {r['up_triangles']} "
f"{q(z,.05):.4f}/{q(z,.5):.4f}/{q(z,.95):.4f} "
f"{q(s,.5):.4f}/{q(s,.95):.4f}/{max(s) if s else math.nan:.4f}")
print("near_camera_up_tiles (sorted by XY tile-centre distance):")
near = []
for row in tile_rows:
key = row[0]
lod = key[3]
extent = 32 * (1 << lod) * voxel_um / 1_000_000.0
cx = (key[0] + 0.5) * extent
cy = (key[1] + 0.5) * extent
near.append((math.hypot(cx-camera[0], cy-camera[1]), row))
for distance, row in sorted(near)[:30]:
key, verts, tris, skirts, ups, lo, med, hi, span = row
if ups:
print(f"key={key} xy_distance_m={distance:.2f} vertices={verts} triangles={tris} "
f"skirt_triangles={skirts} upward_triangles={ups} z_m={lo:.3f}/{med:.3f}/{hi:.3f} "
f"tile_span_p05_p95_m={span:.3f}")