Files
VoxelForge/Standalone/Research/WorldAssemblerM3/Linux129/RunL129MouthCaptures.py
T
Fr0zkaandClaude Opus 5.5 0d1140c117 research: tunnel reach study (L129, no-go; found a units mismatch in v225 bounds)
BuildPassageSpatialIndices adds the 4.335 m reach in core-voxel units, so the broadphase reaches ~1.08 m while
the sweep cutoff says 4 m. Physically-correct 2 m bounds are larger than v225's and 4.9-9.9% slower; captures at
all L125 poses pixel-identical. Patch kept.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016dhxM43dnWvUu2B5Ph1iG1
2026-10-30 23:09:27 +01:00

94 lines
4.4 KiB
Python

#!/usr/bin/env python3
"""Render matching baseline and L129 close views of each tunnel mouth."""
from __future__ import annotations
import hashlib
import importlib.util
import json
import os
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
RESEARCH = Path(__file__).resolve().parent
CAPTURES = RESEARCH / "captures/L129-mouth"
SAVED = ROOT / "Saved/Linux/l129/captures/mouth-closeups"
BASE_LAYOUT = ROOT / "Saved/Linux/l125/hashes/owner4-surface-world-w12-clang.layout.json"
AFTER_LAYOUT = ROOT / "Saved/Linux/l129/hashes/owner4-surface-world-w12-clang.layout.json"
HELPER_PATH = ROOT / "Standalone/Research/WorldAssemblerM3/Linux113/RunL113Captures.py"
SPEC = importlib.util.spec_from_file_location("l113_capture_helpers", HELPER_PATH)
if SPEC is None or SPEC.loader is None:
raise SystemExit("cannot load verified capture helpers")
HELPERS = importlib.util.module_from_spec(SPEC)
SPEC.loader.exec_module(HELPERS)
HELPERS.RESEARCH = RESEARCH
HELPERS.CAPTURES = CAPTURES
HELPERS.SAVED = SAVED
HELPERS.BINARIES = {
"before": ROOT / "Saved/Linux/l125/bin/VoxelForgeCoreHeadless-l125-clang",
"after": ROOT / "Saved/Linux/l129/bin/VoxelForgeCoreHeadless-l129-clang",
}
HELPERS.RENDERERS = {
"before": ROOT / "Saved/Linux/l125/bin/VoxelForgeOffscreenCapture-l125-clang",
"after": ROOT / "Saved/Linux/l129/bin/VoxelForgeOffscreenCapture-l129-clang",
}
def main() -> int:
required = [BASE_LAYOUT, AFTER_LAYOUT, *HELPERS.BINARIES.values(),
*HELPERS.RENDERERS.values()]
if any(not path.is_file() for path in required):
raise SystemExit("missing baseline/candidate layout or capture binary")
before_layout = json.loads(BASE_LAYOUT.read_text(encoding="utf-8"))
after_layout = json.loads(AFTER_LAYOUT.read_text(encoding="utf-8"))
if before_layout["passages"] != after_layout["passages"]:
raise RuntimeError("baseline and candidate passage routes differ")
views = [view for view in HELPERS.make_views(before_layout, [],
use_derived_shape=True, use_spline=True, include_open_air=False)
if view["kind"] == "mouth"]
if len(views) != 2 * len(before_layout["passages"]):
raise RuntimeError("unexpected mouth camera count")
rows = []
CAPTURES.mkdir(parents=True, exist_ok=True)
SAVED.mkdir(parents=True, exist_ok=True)
for view in views:
for variant, layout in (("before", before_layout), ("after", after_layout)):
row = HELPERS.capture(variant, view, layout)
row["variant"] = "L125-v225" if variant == "before" else "L129-v226"
row["view"] = view["name"]
image = ROOT / "Standalone/Research/WorldAssemblerM3/Linux129" / row["capture"]
row["image_sha256"] = hashlib.sha256(image.read_bytes()).hexdigest()
rows.append(row)
index = CAPTURES / "capture-index.json"
index.write_text(json.dumps({"captures": rows}, indent=2) + "\n", encoding="utf-8")
old_rows = {row["view"]: row for row in rows if row["variant"] == "L125-v225"}
new_rows = {row["view"]: row for row in rows if row["variant"] == "L129-v226"}
html = ["<!doctype html><meta charset='utf-8'>",
"<title>L125 / L129 mouth close-ups</title>",
"<style>body{font:14px system-ui;margin:24px;background:#17191d;color:#eee}"
"section{margin:28px 0}div{display:grid;grid-template-columns:1fr 1fr;gap:12px}"
"img{width:100%;height:auto}p{color:#bbb}</style>",
"<h1>L125 v225 / L129 v226 tunnel mouths</h1>"]
for name in old_rows:
old, new = old_rows[name], new_rows[name]
old_path = os.path.relpath(RESEARCH / old["capture"], CAPTURES)
new_path = os.path.relpath(RESEARCH / new["capture"], CAPTURES)
equality = "pixel-identical" if old["image_sha256"] == new["image_sha256"] else "pixels differ"
html.extend(["<section>", f"<h2>{old['passage']} — {old['station']}</h2>",
f"<p>{equality}; {old['pixel_quality_status']} / {new['pixel_quality_status']}</p>",
"<div>", f"<figure><figcaption>L125 v225</figcaption><img src='{old_path}'></figure>",
f"<figure><figcaption>L129 v226</figcaption><img src='{new_path}'></figure>",
"</div>", "</section>"])
(CAPTURES / "COMPARE.html").write_text("\n".join(html) + "\n", encoding="utf-8")
print(f"[L129MouthCaptures] views={len(views)} paired={len(rows)//2} "
f"index={index.relative_to(ROOT)}", flush=True)
return 0
if __name__ == "__main__":
raise SystemExit(main())