core: one tunnel for two strates with landing chambers (L151, owner design; v238, grade open)

Each passage records upper and lower landing chambers (floor, gradient, radius, 4.5 m clear height) composed with the
tunnel shell; cave route endpoints bind to the chambers; envelope audit permits only the named chamber joints.
Seed 2: 0 solid in 319,579 passage+chamber capsule samples, 0 shell violations, 0 envelope conflicts, controls fire.
Open: tunnel-to-chamber floor blend leaves 19.1/19.0 deg grades (limit 15); sweeps/timing not run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016dhxM43dnWvUu2B5Ph1iG1
This commit is contained in:
Fr0zkaandClaude Opus 5.5 committed 2026-11-01 18:41:40 +01:00
1 parent 9ac60d5d18
commit 5bd158d4eb
21 files changed
+1949 -105

No files matched your search

@@ -0,0 +1,318 @@
#!/usr/bin/env python3
"""Audit cave primitive bounds against passage envelopes, allowing chamber joints only."""
from __future__ import annotations
import math
from typing import Any
INFLUENCE_REACH_M = 1.053334
SHELL_THICKNESS_M = 0.75
def _point(control: dict[str, Any], scale: float) -> tuple[float, float, float, float]:
x, y, z = control["position_q"]
return (x * scale, y * scale, z * scale, control["radius_q"] * scale)
def _knot_span(a, b) -> float:
return max(1.0e-6, math.sqrt(math.sqrt((b[0] - a[0]) ** 2 + (b[1] - a[1]) ** 2)))
def _evaluate(controls, span: int, t: float):
p1, p2 = controls[span], controls[span + 1]
p0 = controls[span - 1] if span else controls[0]
p3 = controls[min(span + 2, len(controls) - 1)]
dt0, dt1, dt2 = _knot_span(p0, p1), _knot_span(p1, p2), _knot_span(p2, p3)
t2, t3 = t * t, t * t * t
result = []
for axis in (0, 1, 3):
m1 = dt1 * ((p1[axis] - p0[axis]) / dt0
- (p2[axis] - p0[axis]) / (dt0 + dt1)
+ (p2[axis] - p1[axis]) / dt1)
m2 = dt1 * ((p2[axis] - p1[axis]) / dt1
- (p3[axis] - p1[axis]) / (dt1 + dt2)
+ (p3[axis] - p2[axis]) / dt2)
value = ((2 * t3 - 3 * t2 + 1) * p1[axis]
+ (-2 * t3 + 3 * t2) * p2[axis]
+ (t3 - 2 * t2 + t) * m1 + (t3 - t2) * m2)
result.append(value)
radius = min(max(result[2], min(p1[3], p2[3])), max(p1[3], p2[3]))
return result[0], result[1], p1[2] + (p2[2] - p1[2]) * t, radius
def _segments(passage: dict[str, Any], scale: float):
controls = [_point(row, scale) for row in passage["control_points"]]
route_end = min(max(1, int(passage.get("lower_mouth_control_index", len(controls) - 1))),
len(controls) - 1)
along = 0.0
for span in range(route_end):
a, b = controls[span], controls[span + 1]
chord = math.hypot(b[0] - a[0], b[1] - a[1])
steps = max(1, math.ceil(chord / 2.0))
prior = _evaluate(controls, span, 0.0)
for step in range(1, steps + 1):
current = _evaluate(controls, span, step / steps)
length = math.dist(prior[:3], current[:3])
yield prior, current, along, max(prior[3], current[3]) + INFLUENCE_REACH_M
along += length
prior = current
def _distance_squared(a, b, bounds, t: float) -> float:
total = 0.0
for axis in range(3):
pos = a[axis] + (b[axis] - a[axis]) * t
lo, hi = bounds[axis]
gap = lo - pos if pos < lo else pos - hi if pos > hi else 0.0
total += gap * gap
return total
def _overlap_interval(a, b, bounds, radius: float):
cuts = {0.0, 1.0}
for axis in range(3):
delta = b[axis] - a[axis]
if abs(delta) < 1.0e-15:
continue
for edge in bounds[axis]:
t = (edge - a[axis]) / delta
if 0.0 < t < 1.0:
cuts.add(t)
cuts = sorted(cuts)
best_t, best_d2 = 0.0, math.inf
for lo, hi in zip(cuts, cuts[1:]):
mid = (lo + hi) * 0.5
quadratic = linear = 0.0
for axis in range(3):
delta = b[axis] - a[axis]
pos = a[axis] + delta * mid
low, high = bounds[axis]
edge = low if pos < low else high if pos > high else None
if edge is not None:
quadratic += delta * delta
linear += delta * (a[axis] - edge)
candidate = min(hi, max(lo, -linear / quadratic)) if quadratic else lo
d2 = _distance_squared(a, b, bounds, candidate)
if d2 < best_d2:
best_t, best_d2 = candidate, d2
for t in (0.0, 1.0):
d2 = _distance_squared(a, b, bounds, t)
if d2 < best_d2:
best_t, best_d2 = t, d2
if best_d2 > radius * radius:
return None
radius2 = radius * radius
if _distance_squared(a, b, bounds, 0.0) <= radius2:
left = 0.0
else:
low, high = 0.0, best_t
for _ in range(42):
mid = (low + high) * 0.5
if _distance_squared(a, b, bounds, mid) <= radius2:
high = mid
else:
low = mid
left = high
if _distance_squared(a, b, bounds, 1.0) <= radius2:
right = 1.0
else:
low, high = best_t, 1.0
for _ in range(42):
mid = (low + high) * 0.5
if _distance_squared(a, b, bounds, mid) <= radius2:
low = mid
else:
high = mid
right = low
return left, right, best_t
def _inside_chamber(point, chamber: dict[str, Any], scale: float) -> bool:
cx, cy, cz = (value * scale for value in chamber["floor_center_q"])
radius = chamber["radius_q"] * scale
clear = chamber["clear_height_q"] * scale
gx, gy = (value / 65536.0 for value in chamber["floor_gradient_q16"])
floor = cz + gx * (point[0] - cx) + gy * (point[1] - cy)
chamber_distance = max(math.hypot(point[0] - cx, point[1] - cy) - radius,
floor - point[2], point[2] - (floor + clear))
return chamber_distance <= SHELL_THICKNESS_M
def _primitive_bounds(row: dict[str, Any]):
return tuple((row["bounds_min_um"][i] / 1.0e6,
row["bounds_max_um"][i] / 1.0e6) for i in range(3))
def _bezier(points, t: float):
u = 1.0 - t
return tuple(u**3 * points[0][axis] + 3*u*u*t * points[1][axis]
+ 3*u*t*t * points[2][axis] + t**3 * points[3][axis]
for axis in range(3))
def _distance_to_ellipse(radial: float, vertical: float,
radius: float, height: float) -> float:
"""Euclidean distance to the edge bore's horizontal/vertical ellipse."""
radial = abs(radial)
vertical = abs(vertical)
if (radial / radius) ** 2 + (vertical / height) ** 2 <= 1.0:
return 0.0
lo, hi = 0.0, math.pi / 2.0
ratio = (math.sqrt(5.0) - 1.0) / 2.0
def squared_distance(angle: float) -> float:
return ((radial - radius * math.cos(angle)) ** 2
+ (vertical - height * math.sin(angle)) ** 2)
left = hi - ratio * (hi - lo)
right = lo + ratio * (hi - lo)
left_value, right_value = squared_distance(left), squared_distance(right)
for _ in range(48):
if left_value < right_value:
hi, right, right_value = right, left, left_value
left = hi - ratio * (hi - lo)
left_value = squared_distance(left)
else:
lo, left, left_value = left, right, right_value
right = lo + ratio * (hi - lo)
right_value = squared_distance(right)
return math.sqrt(min(left_value, right_value))
def _actual_edge_clearance(passage, edge, scale: float,
chamber: dict[str, Any]) -> float:
"""Return minimum true tube clearance outside the landing chamber.
The route edge is a swept ellipse, with its recorded polyline as the axis.
Comparing the tunnel tube to that ellipse avoids the false clashes caused by
intersecting two enclosing boxes.
"""
controls = [tuple(value / 1.0e6 for value in point)
for point in edge["control_points_um"]]
axis = [tuple(value / 1.0e6 for value in point)
for point in edge.get("polyline_um", [])]
if len(axis) < 2:
axis = [_bezier(controls, index / 64.0) for index in range(65)]
edge_radius = (edge["bore_radius_um"]
+ edge["irregularity_amplitude_um"]) / 1.0e6
edge_height = (edge["bore_height_um"]
+ edge["irregularity_amplitude_um"]) / 1.0e6
passage_segments = passage.get("_audit_segments") or tuple(_segments(passage, scale))
minimum_clearance = math.inf
for a, b, _, passage_radius in passage_segments:
length = math.dist(a[:3], b[:3])
steps = max(1, math.ceil(length / 0.05))
for step in range(steps + 1):
t = step / steps
point = tuple(a[i] + (b[i] - a[i]) * t for i in range(3))
if _inside_chamber(point, chamber, scale):
continue
tunnel_radius = (a[3] + (b[3] - a[3]) * t
+ INFLUENCE_REACH_M)
for start, end in zip(axis, axis[1:]):
delta = tuple(end[i] - start[i] for i in range(3))
length_squared = sum(value * value for value in delta)
projection = (sum((point[i] - start[i]) * delta[i]
for i in range(3)) / length_squared
if length_squared else 0.0)
projection = min(1.0, max(0.0, projection))
center = tuple(start[i] + projection * delta[i] for i in range(3))
radial = math.hypot(point[0] - center[0], point[1] - center[1])
vertical = abs(point[2] - center[2])
clearance = (_distance_to_ellipse(radial, vertical,
edge_radius, edge_height)
- tunnel_radius)
minimum_clearance = min(minimum_clearance, clearance)
return minimum_clearance
def _test_bounds(bounds, strate_index: int, passages, scale: float,
*, allow_chamber: bool = True):
for passage in passages:
if strate_index not in (passage["upper_strate_index"], passage["lower_strate_index"]):
continue
chamber_key = ("upper_landing_chamber" if strate_index == passage["upper_strate_index"]
else "lower_landing_chamber")
chamber = passage[chamber_key]
segments = passage.get("_audit_segments")
if segments is None:
segments = tuple(_segments(passage, scale))
for a, b, along, radius in segments:
expanded = [(a[i] - radius, b[i] + radius) if a[i] <= b[i]
else (b[i] - radius, a[i] + radius) for i in range(3)]
if any(expanded[i][1] < bounds[i][0] or expanded[i][0] > bounds[i][1]
for i in range(3)):
continue
overlap = _overlap_interval(a, b, bounds, radius)
if overlap is None:
continue
first, last, closest = overlap
if allow_chamber:
points = [tuple(a[i] + (b[i] - a[i]) * t for i in range(3))
for t in (first, closest, last)]
if all(_inside_chamber(point, chamber, scale) for point in points):
continue
point = tuple(a[i] + (b[i] - a[i]) * closest for i in range(3))
return passage["stable_id"], along + closest * math.dist(a[:3], b[:3]), point
return None
def audit_layout(layout: dict[str, Any]) -> dict[str, Any]:
scale = layout["core_voxel_size_um"] / (256.0 * 1.0e6)
passages = [dict(row, _audit_segments=tuple(_segments(row, scale)))
for row in layout.get("passages", [])]
primitives = [*layout.get("cavern_rooms", []), *layout.get("cavern_edges", [])]
checked = conflicts = chamber_joints = bounds_candidates = refined_false_positives = 0
first_conflict = None
for primitive in primitives:
bounds = _primitive_bounds(primitive)
checked += 1
primitive_conflicted = False
for passage in passages:
found = _test_bounds(bounds, primitive["strate_index"], [passage], scale)
if not found:
continue
bounds_candidates += 1
passage_id, station, point = found
if "control_points_um" in primitive:
side = ("upper_landing_chamber"
if primitive["strate_index"] == passage["upper_strate_index"]
else "lower_landing_chamber")
clearance = _actual_edge_clearance(passage, primitive, scale,
passage[side])
if clearance >= 0.0:
refined_false_positives += 1
continue
primitive_conflicted = True
conflicts += 1
if first_conflict is None:
first_conflict = {"primitive": primitive["stable_id"],
"passage": passage_id, "station_m": round(station, 3),
"center_m": [round(value, 3) for value in point]}
break
if not primitive_conflicted:
# Count the edge's named landing association as a confirmed joint.
anchor = primitive.get("start_anchor_stable_id", "")
if anchor.endswith(("/upper-landing-chamber", "/lower-landing-chamber")):
chamber_joints += 1
negative_controls = 0
long_passage = max(passages, key=lambda row: len(row["control_points"]), default=None)
if long_passage:
controls = [_point(row, scale) for row in long_passage["control_points"]]
index = min(max(1, len(controls) // 2), len(controls) - 2)
center = controls[index]
bounds = tuple((center[axis] - 0.25, center[axis] + 0.25) for axis in range(3))
# Select the side whose chamber is farther from this forced tunnel overlap.
strate = long_passage["lower_strate_index"]
if _test_bounds(bounds, strate, [long_passage], scale, allow_chamber=False):
negative_controls = 1
return {"primitives_checked": checked, "bounds_candidates": bounds_candidates,
"refined_edge_false_positives": refined_false_positives,
"outside_chamber_conflicts": conflicts,
"chamber_joints": chamber_joints, "negative_controls": negative_controls,
"negative_controls_expected": 1, "first_conflict": first_conflict,
"passed": conflicts == 0 and negative_controls == 1}
@@ -0,0 +1,39 @@
# L151 — One tunnel for two strata
| Landing chamber | Before (L150) | After (L151) |
|---|---|---|
| passage/0-1/0 · upper | ![L150 upper landing, passage 0-1](captures/before-l150-0-1-0-upper-landing.jpg) | ![L151 upper landing, passage 0-1](captures/after-l151-0-1-0-upper-landing.jpg) |
| passage/0-1/0 · lower | ![L150 lower landing, passage 0-1](captures/before-l150-0-1-0-lower-landing.jpg) | ![L151 lower landing, passage 0-1](captures/after-l151-0-1-0-lower-landing.jpg) |
| passage/1-2/0 · upper | ![L150 upper landing, passage 1-2](captures/before-l150-1-2-0-upper-landing.jpg) | ![L151 upper landing, passage 1-2](captures/after-l151-1-2-0-upper-landing.jpg) |
| passage/1-2/0 · lower | ![L150 lower landing, passage 1-2](captures/before-l150-1-2-0-lower-landing.jpg) | ![L151 lower landing, passage 1-2](captures/after-l151-1-2-0-lower-landing.jpg) |
| passage/2-3/0 · upper | ![L150 upper landing, passage 2-3](captures/before-l150-2-3-0-upper-landing.jpg) | ![L151 upper landing, passage 2-3](captures/after-l151-2-3-0-upper-landing.jpg) |
| passage/2-3/0 · lower | ![L150 lower landing, passage 2-3](captures/before-l150-2-3-0-lower-landing.jpg) | ![L151 lower landing, passage 2-3](captures/after-l151-2-3-0-lower-landing.jpg) |
Seed 0 camera poses are matched at eye height. All 12 images passed the capture quality check. The L150 build stamp is `c6b8a100355e271ddc40eb5973569d2ff4e2ba8d9c628c72f8e0af2493f0609f`; L151 is `1ca3b84f6d35f7f355ec0f72dabd3b87a455ea02e5789fea611916962e5db8e5`. The [capture index](captures/INDEX.md) and [manifest](captures/manifest.json) record the poses and files.
## Result
**L151 is not promotion-ready.** The resolved layout now records one passage spline with an upper and lower landing chamber, and the evaluator version is 238. The best tested floor blend still leaves two walk segments above the 15° limit: 19.077° on passage 0-1 and 19.033° on passage 2-3. The three-variant stop rule was reached; I stopped without a fourth geometry attempt. No owner baselines were promoted.
## What changed
- Added serialized and validated landing chamber records with floor center, floor gradient, radius, and 4.5 m clear height. The shared passage field composes each chamber with the tunnel shell and floor.
- Cave route endpoints now bind to the passage's landing chamber anchors. The passage floor blends to chamber floors over the tested 12 m transition.
- Extended passage audits for chamber capsule clearance, floor and wall shell, and blocked-world negative controls. Added a geometric cave-primitive envelope audit that permits the named chamber joints and refines conservative edge-box candidates against the swept bore.
- Retained the L135 mouth profile, L147 interior-air gate, and L148 envelope allowance.
## Measurements and checks
- **Focused owner-world run:** one seed-2 W8 run, source stamp above. Three interfaces were audited. Passage and chamber interiors together had 0 solid samples across 319,579 capsule samples; all six chambers had 0 solid samples. Passage floor, wall, and interior shell violations were all zero. Naturalness, mouth profile, ripple, and all three layer route audits passed. Tunnel-network, vertical-shaft, and blocked-passage negative controls were detected (1/1, 1/1, and 3/3). The combined passage summary failed because only one of three interfaces met walkability.
- **Chamber envelope audit:** 549 primitives checked; 2 conservative bounds candidates were refined as false positives; 0 conflicts remained outside chambers; 3 named chamber joints and the negative control passed (1/1). Result: [JSON](../../../../Saved/Linux/l151/passage-envelope-audit.json).
- **Blend attempts:** 12 m retained two grades at 19.077° and 19.033°. Extending the blend to 24 m produced 436 solid interior capsule samples and one wall violation, as well as grades of 15.282° and 17.406° on passage 0-1. Restricting the external blend to 0 m kept interior and shell checks clear but left a 22.226° grade on passage 0-1. The 12 m variant is the final source state.
- **Build and snapshots:** Clang 19 build passed for stamp `1ca3b84f…`; the explicit seed-0 resolved-layout snapshot round trip passed. Python capture and envelope audit scripts ran successfully. `git diff --check` passed for the tracked diff; the report's whitespace and image references were checked separately.
- **Seams:** the saved seed-2 log has no `[PassageTileSeamAudit]` result, so seam status is unverified.
## Not run
The three-failure stop was reached before the fast tier, the 16-seed Tunnel Network and Vertical Shafts sweeps, Clang/GCC W1/W8/W12, and L80 timing for all four layers. No timing claim is made. No owner-world baseline files were updated because the composed walkability gate failed. The only modified `Source/` file is `Standalone/Source/StreamBenchmarkPipeline.h`; no Unreal `Source/` files changed.
## Remaining risk
The tunnel-to-chamber floor transition still creates local grades above 15° in two interfaces. The envelope audit and geometry evidence cover seed 2 only; multi-seed composed behavior, seams, compiler/worker determinism, the fast tier, and L80 performance remain unverified.
@@ -0,0 +1,206 @@
#!/usr/bin/env python3
"""Capture matched eye-height views from both ends of every owner tunnel."""
from __future__ import annotations
import json
import math
import os
from pathlib import Path
import re
import subprocess
import sys
ROOT = Path(__file__).resolve().parents[4]
DATA = ROOT / "Standalone/data/owner_world.json"
OUT = ROOT / "Saved/Linux/l151/captures"
LAYOUT = OUT / "after-resolved-layout.json"
ARTIFACTS = ROOT / "Standalone/Research/WorldAssemblerM3/Linux151/captures"
LIMIT = ["taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--"]
VERSIONS = {
"before-l150": {
"headless": ROOT / "Standalone/bin/linux/VoxelForgeCoreHeadless-l150-head-clang",
"renderer": ROOT / "Standalone/bin/linux/VoxelForgeOffscreenCapture-l150-head-clang",
"stamp": "c6b8a100355e271ddc40eb5973569d2ff4e2ba8d9c628c72f8e0af2493f0609f",
},
"after-l151": {
"headless": ROOT / "Standalone/bin/linux/VoxelForgeCoreHeadless-l151-clang",
"renderer": ROOT / "Standalone/bin/linux/VoxelForgeOffscreenCapture-l151-clang",
"stamp": "1ca3b84f6d35f7f355ec0f72dabd3b87a455ea02e5789fea611916962e5db8e5",
},
}
STAMP_RE = re.compile(r"^\[VoxelForgeSourceStamp\] sha256=([0-9a-f]{64})$", re.M)
def fmt(values) -> str:
return ",".join(f"{value:.6f}" for value in values)
def angles(camera, target) -> tuple[float, float]:
dx, dy, dz = (target[index] - camera[index] for index in range(3))
return math.degrees(math.atan2(dx, dy)), math.degrees(
math.atan2(dz, math.hypot(dx, dy)))
def point_q(layout: dict, values) -> tuple[float, float, float]:
scale = layout["core_voxel_size_um"] / (256.0 * 1_000_000.0)
return tuple(value * scale for value in values)
def chamber_views(layout: dict) -> list[dict]:
result = []
for passage in layout["passages"]:
controls = passage["control_points"]
for side, endpoint, neighbor in (
("upper", controls[0], controls[1]),
("lower", controls[-1], controls[-2])):
chamber = passage[f"{side}_landing_chamber"]
center = point_q(layout, chamber["floor_center_q"])
a = point_q(layout, neighbor["position_q"])
b = point_q(layout, endpoint["position_q"])
dx, dy = a[0] - b[0], a[1] - b[1]
length = math.hypot(dx, dy)
if length <= 1.0e-9:
raise ValueError(f"degenerate {side} tunnel tangent: {passage['stable_id']}")
dx, dy = dx / length, dy / length
eye_z = center[2] + 1.45
distance = 9.0
target = (center[0] + dx * distance, center[1] + dy * distance,
eye_z + (chamber["floor_gradient_q16"][0] / 65536.0 * dx
+ chamber["floor_gradient_q16"][1] / 65536.0 * dy)
* distance)
camera = (center[0], center[1], eye_z)
slug = passage["stable_id"].replace("passage/", "").replace("/", "-")
result.append({"name": f"{slug}-{side}-landing", "passage": passage["stable_id"],
"side": side, "camera": camera, "target": target,
"focus": (center[0], center[1], eye_z, 18.0)})
return result
def stamped_run(name: str, command: list[object], log: Path, expected_stamp: str,
env: dict[str, str]) -> str:
binary = Path(str(command[0]))
probe = subprocess.run([*LIMIT, "timeout", "15s", str(binary), "--print-source-stamp"],
cwd=ROOT, env=env, text=True, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, check=False, timeout=20)
match = STAMP_RE.search(probe.stdout or "")
if probe.returncode or not match or match.group(1) != expected_stamp:
raise RuntimeError(f"{name}: source stamp mismatch for {binary}")
log.parent.mkdir(parents=True, exist_ok=True)
with log.open("w", encoding="utf-8") as stream:
result = subprocess.run([*LIMIT, "timeout", "1740s", *map(str, command)],
cwd=ROOT, env=env, stdout=stream, stderr=subprocess.STDOUT,
timeout=1745, check=False)
output = log.read_text(encoding="utf-8", errors="replace")
emitted = STAMP_RE.search(output)
if result.returncode or not emitted or emitted.group(1) != expected_stamp:
raise RuntimeError(f"{name}: export or render failed; see {log}")
return output
def resolve_layout(env: dict[str, str]) -> dict:
config = VERSIONS["after-l151"]
command = [config["headless"], DATA, "--world-assembler-prototype",
"--stream-benchmark", "--stream-pipeline", "--workers=12",
"--clip-radius=6", "--max-clip-level=0", "--max-level=0",
"--force-generate", "--seed=0", "--recipe=surface-world", "--resolved-layout-only",
f"--resolved-layout-output={LAYOUT}"]
stamped_run("after-l151-resolve-layout", list(map(str, command)),
OUT / "after-l151-resolved-layout.log", config["stamp"], env)
layout = json.loads(LAYOUT.read_text(encoding="utf-8"))
if len(layout.get("passages", [])) != 3:
raise RuntimeError("owner layout did not resolve the expected three tunnels")
return layout
def main() -> int:
if not DATA.is_file():
raise SystemExit("missing owner fixture")
OUT.mkdir(parents=True, exist_ok=True)
ARTIFACTS.mkdir(parents=True, exist_ok=True)
env = os.environ.copy()
env["LP_NUM_THREADS"] = "12"
env["XDG_CACHE_HOME"] = str(OUT / "xdg-cache")
layout = resolve_layout(env)
views = chamber_views(layout)
quality_tool = ROOT / "Standalone/Tools/verify/capture_quality.py"
manifest = []
failures = []
for version, config in VERSIONS.items():
for view in views:
camera, target = view["camera"], view["target"]
yaw, pitch = angles(camera, target)
mesh_dir = OUT / "meshes" / version
mesh_dir.mkdir(parents=True, exist_ok=True)
mesh = mesh_dir / f"{view['name']}.vfmesh"
capture_layout = mesh_dir / f"{view['name']}-layout.json"
export = [config["headless"], DATA, "--world-assembler-prototype",
"--stream-benchmark", "--stream-pipeline", "--workers=12",
"--clip-radius=6", "--max-clip-level=0", "--max-level=0",
"--force-generate", "--seed=0", "--recipe=surface-world",
"--render-distance-chunks=0",
f"--camera={fmt((*camera, yaw, pitch))}",
f"--resolved-layout-output={capture_layout}", f"--mesh-export={mesh}"]
stamped_run(f"{version}-{view['name']}-export", list(map(str, export)),
OUT / f"{version}-{view['name']}-export.log", config["stamp"], env)
if not mesh.is_file() or mesh.stat().st_size == 0:
raise RuntimeError(f"{version}-{view['name']}: empty mesh export")
png = OUT / f"{version}-{view['name']}.png"
jpg = ARTIFACTS / f"{version}-{view['name']}.jpg"
render = [config["renderer"], mesh, png, "--size=1280x720",
"--fov-deg=78.0", f"--camera-m={fmt(camera)}",
f"--yaw-deg={yaw:.6f}", f"--pitch-deg={pitch:.6f}",
"--tile-skirts=off", "--shade=readable", "--headlamp=on",
"--height-tint=on", "--height-center-m=-950", "--height-range-m=60",
"--tile-edges=off", f"--focus-region={fmt(view['focus'])}"]
stamped_run(f"{version}-{view['name']}-render", list(map(str, render)),
OUT / f"{version}-{view['name']}-render.log", config["stamp"], env)
subprocess.run([*LIMIT, "timeout", "120s", "ffmpeg", "-nostdin",
"-hide_banner", "-loglevel", "error", "-y", "-i", png,
"-frames:v", "1", "-q:v", "4", jpg], cwd=ROOT, env=env,
check=True, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT,
timeout=125)
check = subprocess.run([*LIMIT, "timeout", "120s", sys.executable,
quality_tool, jpg], cwd=ROOT, env=env, text=True,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
check=False, timeout=125)
quality_ok = check.returncode == 0 and "status=PASS" in check.stdout
if not quality_ok:
failures.append(f"{version}-{view['name']}")
quality_line = (check.stdout.strip().splitlines()[-1]
if check.stdout.strip() else f"quality exit={check.returncode}")
manifest.append({"version": version, "view": view["name"],
"passage": view["passage"], "side": view["side"],
"file": str(jpg.relative_to(ROOT)), "camera_m": camera,
"target_m": target, "yaw_deg": yaw, "pitch_deg": pitch,
"source_stamp": config["stamp"],
"pose_layout_identity": layout.get("stable_identity"),
"quality_status": "PASS" if quality_ok else "FAIL",
"quality": quality_line})
print(f"[L151Capture] version={version} view={view['name']} "
f"quality={'PASS' if quality_ok else 'FAIL'} "
f"file={jpg.relative_to(ROOT)}", flush=True)
(ARTIFACTS / "manifest.json").write_text(
json.dumps(manifest, indent=2) + "\n", encoding="utf-8")
with (ARTIFACTS / "INDEX.md").open("w", encoding="utf-8") as index:
index.write("# L151 matched owner tunnel landing captures\n\n"
"Seed 0 camera poses resolved from the L151 owner layout and reused for both "
"versions. Each view is at eye height at one of the three tunnel landing "
"chambers. Before uses the L150 head build; after uses L151 source stamp "
f"`{VERSIONS['after-l151']['stamp']}`.\n\n")
for view in views:
index.write(f"## {view['passage']} / {view['side']} landing\n\n"
f"- Before: [image](before-l150-{view['name']}.jpg)\n"
f"- After: [image](after-l151-{view['name']}.jpg)\n\n")
index.write(f"Capture quality failures: {len(failures)}/{len(manifest)}.\n")
print(f"[L151CaptureSummary] chamber_views={len(views)} "
f"images={len(manifest)} quality_failures={len(failures)}", flush=True)
return 0 if not failures else 1
if __name__ == "__main__":
try:
raise SystemExit(main())
except Exception as error:
print(f"[L151CaptureFailure] {error}", file=sys.stderr, flush=True)
raise SystemExit(1)
@@ -0,0 +1,35 @@
# L151 matched owner tunnel landing captures
Seed 0 camera poses resolved from the L151 owner layout and reused for both versions. Each view is at eye height at one of the three tunnel landing chambers. Before uses the L150 head build; after uses L151 source stamp `1ca3b84f6d35f7f355ec0f72dabd3b87a455ea02e5789fea611916962e5db8e5`.
## passage/0-1/0 / upper landing
- Before: [image](before-l150-0-1-0-upper-landing.jpg)
- After: [image](after-l151-0-1-0-upper-landing.jpg)
## passage/0-1/0 / lower landing
- Before: [image](before-l150-0-1-0-lower-landing.jpg)
- After: [image](after-l151-0-1-0-lower-landing.jpg)
## passage/1-2/0 / upper landing
- Before: [image](before-l150-1-2-0-upper-landing.jpg)
- After: [image](after-l151-1-2-0-upper-landing.jpg)
## passage/1-2/0 / lower landing
- Before: [image](before-l150-1-2-0-lower-landing.jpg)
- After: [image](after-l151-1-2-0-lower-landing.jpg)
## passage/2-3/0 / upper landing
- Before: [image](before-l150-2-3-0-upper-landing.jpg)
- After: [image](after-l151-2-3-0-upper-landing.jpg)
## passage/2-3/0 / lower landing
- Before: [image](before-l150-2-3-0-lower-landing.jpg)
- After: [image](after-l151-2-3-0-lower-landing.jpg)
Capture quality failures: 0/12.
Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

@@ -0,0 +1,278 @@
[
{
"version": "before-l150",
"view": "0-1-0-upper-landing",
"passage": "passage/0-1/0",
"side": "upper",
"file": "Standalone/Research/WorldAssemblerM3/Linux151/captures/before-l150-0-1-0-upper-landing.jpg",
"camera_m": [
37.0,
-5.25,
-372.3810546875
],
"target_m": [
28.40474992442715,
-7.918646874047773,
-372.325197471535
],
"yaw_deg": -107.24848481126237,
"pitch_deg": 0.3555935154874107,
"source_stamp": "c6b8a100355e271ddc40eb5973569d2ff4e2ba8d9c628c72f8e0af2493f0609f",
"pose_layout_identity": "resolved-layout-v3-fnv64:ed02312296ac2003",
"quality_status": "PASS",
"quality": "[CaptureQuality] image=/home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Research/WorldAssemblerM3/Linux151/captures/before-l150-0-1-0-upper-landing.jpg pixels=921600 mean_luma=113.553 stddev_luma=8.807 coverage_luma_gt12=1.00000 thresholds=(stddev>=2.0,coverage>=0.001) status=PASS"
},
{
"version": "before-l150",
"view": "0-1-0-lower-landing",
"passage": "passage/0-1/0",
"side": "lower",
"file": "Standalone/Research/WorldAssemblerM3/Linux151/captures/before-l150-0-1-0-lower-landing.jpg",
"camera_m": [
25.8369140625,
3.19921875,
-736.6798828125
],
"target_m": [
17.97380590951016,
-1.1793118453464206,
-734.970169262755
],
"yaw_deg": -119.11101808688004,
"pitch_deg": 10.756207017349817,
"source_stamp": "c6b8a100355e271ddc40eb5973569d2ff4e2ba8d9c628c72f8e0af2493f0609f",
"pose_layout_identity": "resolved-layout-v3-fnv64:ed02312296ac2003",
"quality_status": "PASS",
"quality": "[CaptureQuality] image=/home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Research/WorldAssemblerM3/Linux151/captures/before-l150-0-1-0-lower-landing.jpg pixels=921600 mean_luma=106.418 stddev_luma=2.881 coverage_luma_gt12=1.00000 thresholds=(stddev>=2.0,coverage>=0.001) status=PASS"
},
{
"version": "before-l150",
"view": "1-2-0-upper-landing",
"passage": "passage/1-2/0",
"side": "upper",
"file": "Standalone/Research/WorldAssemblerM3/Linux151/captures/before-l150-1-2-0-upper-landing.jpg",
"camera_m": [
19.166015625,
-14.2001953125,
-731.8810546875
],
"target_m": [
10.35825176774404,
-16.050410390488395,
-733.216132282697
],
"yaw_deg": -101.86342177874246,
"pitch_deg": -8.437834550031965,
"source_stamp": "c6b8a100355e271ddc40eb5973569d2ff4e2ba8d9c628c72f8e0af2493f0609f",
"pose_layout_identity": "resolved-layout-v3-fnv64:ed02312296ac2003",
"quality_status": "PASS",
"quality": "[CaptureQuality] image=/home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Research/WorldAssemblerM3/Linux151/captures/before-l150-1-2-0-upper-landing.jpg pixels=921600 mean_luma=108.420 stddev_luma=2.873 coverage_luma_gt12=1.00000 thresholds=(stddev>=2.0,coverage>=0.001) status=PASS"
},
{
"version": "before-l150",
"view": "1-2-0-lower-landing",
"passage": "passage/1-2/0",
"side": "lower",
"file": "Standalone/Research/WorldAssemblerM3/Linux151/captures/before-l150-1-2-0-lower-landing.jpg",
"camera_m": [
19.166015625,
-14.2001953125,
-753.05390625
],
"target_m": [
10.48848361510052,
-16.587754362485967,
-751.7193175939389
],
"yaw_deg": -105.38384894032598,
"pitch_deg": 8.434788863627224,
"source_stamp": "c6b8a100355e271ddc40eb5973569d2ff4e2ba8d9c628c72f8e0af2493f0609f",
"pose_layout_identity": "resolved-layout-v3-fnv64:ed02312296ac2003",
"quality_status": "PASS",
"quality": "[CaptureQuality] image=/home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Research/WorldAssemblerM3/Linux151/captures/before-l150-1-2-0-lower-landing.jpg pixels=921600 mean_luma=113.918 stddev_luma=10.489 coverage_luma_gt12=1.00000 thresholds=(stddev>=2.0,coverage>=0.001) status=PASS"
},
{
"version": "before-l150",
"view": "2-3-0-upper-landing",
"passage": "passage/2-3/0",
"side": "upper",
"file": "Standalone/Research/WorldAssemblerM3/Linux151/captures/before-l150-2-3-0-upper-landing.jpg",
"camera_m": [
-20.0625,
-5.068359375,
-812.075390625
],
"target_m": [
-13.604954164712868,
-11.337338700629157,
-813.6662645746064
],
"yaw_deg": 134.15112141809087,
"pitch_deg": -10.024269857937275,
"source_stamp": "c6b8a100355e271ddc40eb5973569d2ff4e2ba8d9c628c72f8e0af2493f0609f",
"pose_layout_identity": "resolved-layout-v3-fnv64:ed02312296ac2003",
"quality_status": "PASS",
"quality": "[CaptureQuality] image=/home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Research/WorldAssemblerM3/Linux151/captures/before-l150-2-3-0-upper-landing.jpg pixels=921600 mean_luma=108.739 stddev_luma=2.947 coverage_luma_gt12=1.00000 thresholds=(stddev>=2.0,coverage>=0.001) status=PASS"
},
{
"version": "before-l150",
"view": "2-3-0-lower-landing",
"passage": "passage/2-3/0",
"side": "lower",
"file": "Standalone/Research/WorldAssemblerM3/Linux151/captures/before-l150-2-3-0-lower-landing.jpg",
"camera_m": [
-20.0625,
-5.068359375,
-900.0333984375
],
"target_m": [
-14.865342978484083,
-12.416118141706198,
-898.4427583280197
],
"yaw_deg": 144.72777711381306,
"pitch_deg": 10.022826283920647,
"source_stamp": "c6b8a100355e271ddc40eb5973569d2ff4e2ba8d9c628c72f8e0af2493f0609f",
"pose_layout_identity": "resolved-layout-v3-fnv64:ed02312296ac2003",
"quality_status": "PASS",
"quality": "[CaptureQuality] image=/home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Research/WorldAssemblerM3/Linux151/captures/before-l150-2-3-0-lower-landing.jpg pixels=921600 mean_luma=112.176 stddev_luma=9.871 coverage_luma_gt12=1.00000 thresholds=(stddev>=2.0,coverage>=0.001) status=PASS"
},
{
"version": "after-l151",
"view": "0-1-0-upper-landing",
"passage": "passage/0-1/0",
"side": "upper",
"file": "Standalone/Research/WorldAssemblerM3/Linux151/captures/after-l151-0-1-0-upper-landing.jpg",
"camera_m": [
37.0,
-5.25,
-372.3810546875
],
"target_m": [
28.40474992442715,
-7.918646874047773,
-372.325197471535
],
"yaw_deg": -107.24848481126237,
"pitch_deg": 0.3555935154874107,
"source_stamp": "1ca3b84f6d35f7f355ec0f72dabd3b87a455ea02e5789fea611916962e5db8e5",
"pose_layout_identity": "resolved-layout-v3-fnv64:ed02312296ac2003",
"quality_status": "PASS",
"quality": "[CaptureQuality] image=/home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Research/WorldAssemblerM3/Linux151/captures/after-l151-0-1-0-upper-landing.jpg pixels=921600 mean_luma=118.392 stddev_luma=15.921 coverage_luma_gt12=1.00000 thresholds=(stddev>=2.0,coverage>=0.001) status=PASS"
},
{
"version": "after-l151",
"view": "0-1-0-lower-landing",
"passage": "passage/0-1/0",
"side": "lower",
"file": "Standalone/Research/WorldAssemblerM3/Linux151/captures/after-l151-0-1-0-lower-landing.jpg",
"camera_m": [
25.8369140625,
3.19921875,
-736.6798828125
],
"target_m": [
17.97380590951016,
-1.1793118453464206,
-734.970169262755
],
"yaw_deg": -119.11101808688004,
"pitch_deg": 10.756207017349817,
"source_stamp": "1ca3b84f6d35f7f355ec0f72dabd3b87a455ea02e5789fea611916962e5db8e5",
"pose_layout_identity": "resolved-layout-v3-fnv64:ed02312296ac2003",
"quality_status": "PASS",
"quality": "[CaptureQuality] image=/home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Research/WorldAssemblerM3/Linux151/captures/after-l151-0-1-0-lower-landing.jpg pixels=921600 mean_luma=111.426 stddev_luma=12.411 coverage_luma_gt12=1.00000 thresholds=(stddev>=2.0,coverage>=0.001) status=PASS"
},
{
"version": "after-l151",
"view": "1-2-0-upper-landing",
"passage": "passage/1-2/0",
"side": "upper",
"file": "Standalone/Research/WorldAssemblerM3/Linux151/captures/after-l151-1-2-0-upper-landing.jpg",
"camera_m": [
19.166015625,
-14.2001953125,
-731.8810546875
],
"target_m": [
10.35825176774404,
-16.050410390488395,
-733.216132282697
],
"yaw_deg": -101.86342177874246,
"pitch_deg": -8.437834550031965,
"source_stamp": "1ca3b84f6d35f7f355ec0f72dabd3b87a455ea02e5789fea611916962e5db8e5",
"pose_layout_identity": "resolved-layout-v3-fnv64:ed02312296ac2003",
"quality_status": "PASS",
"quality": "[CaptureQuality] image=/home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Research/WorldAssemblerM3/Linux151/captures/after-l151-1-2-0-upper-landing.jpg pixels=921600 mean_luma=117.134 stddev_luma=15.664 coverage_luma_gt12=1.00000 thresholds=(stddev>=2.0,coverage>=0.001) status=PASS"
},
{
"version": "after-l151",
"view": "1-2-0-lower-landing",
"passage": "passage/1-2/0",
"side": "lower",
"file": "Standalone/Research/WorldAssemblerM3/Linux151/captures/after-l151-1-2-0-lower-landing.jpg",
"camera_m": [
19.166015625,
-14.2001953125,
-753.05390625
],
"target_m": [
10.48848361510052,
-16.587754362485967,
-751.7193175939389
],
"yaw_deg": -105.38384894032598,
"pitch_deg": 8.434788863627224,
"source_stamp": "1ca3b84f6d35f7f355ec0f72dabd3b87a455ea02e5789fea611916962e5db8e5",
"pose_layout_identity": "resolved-layout-v3-fnv64:ed02312296ac2003",
"quality_status": "PASS",
"quality": "[CaptureQuality] image=/home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Research/WorldAssemblerM3/Linux151/captures/after-l151-1-2-0-lower-landing.jpg pixels=921600 mean_luma=119.710 stddev_luma=14.975 coverage_luma_gt12=1.00000 thresholds=(stddev>=2.0,coverage>=0.001) status=PASS"
},
{
"version": "after-l151",
"view": "2-3-0-upper-landing",
"passage": "passage/2-3/0",
"side": "upper",
"file": "Standalone/Research/WorldAssemblerM3/Linux151/captures/after-l151-2-3-0-upper-landing.jpg",
"camera_m": [
-20.0625,
-5.068359375,
-812.075390625
],
"target_m": [
-13.604954164712868,
-11.337338700629157,
-813.6662645746064
],
"yaw_deg": 134.15112141809087,
"pitch_deg": -10.024269857937275,
"source_stamp": "1ca3b84f6d35f7f355ec0f72dabd3b87a455ea02e5789fea611916962e5db8e5",
"pose_layout_identity": "resolved-layout-v3-fnv64:ed02312296ac2003",
"quality_status": "PASS",
"quality": "[CaptureQuality] image=/home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Research/WorldAssemblerM3/Linux151/captures/after-l151-2-3-0-upper-landing.jpg pixels=921600 mean_luma=118.198 stddev_luma=15.882 coverage_luma_gt12=1.00000 thresholds=(stddev>=2.0,coverage>=0.001) status=PASS"
},
{
"version": "after-l151",
"view": "2-3-0-lower-landing",
"passage": "passage/2-3/0",
"side": "lower",
"file": "Standalone/Research/WorldAssemblerM3/Linux151/captures/after-l151-2-3-0-lower-landing.jpg",
"camera_m": [
-20.0625,
-5.068359375,
-900.0333984375
],
"target_m": [
-14.865342978484083,
-12.416118141706198,
-898.4427583280197
],
"yaw_deg": 144.72777711381306,
"pitch_deg": 10.022826283920647,
"source_stamp": "1ca3b84f6d35f7f355ec0f72dabd3b87a455ea02e5789fea611916962e5db8e5",
"pose_layout_identity": "resolved-layout-v3-fnv64:ed02312296ac2003",
"quality_status": "PASS",
"quality": "[CaptureQuality] image=/home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Research/WorldAssemblerM3/Linux151/captures/after-l151-2-3-0-lower-landing.jpg pixels=921600 mean_luma=121.734 stddev_luma=16.193 coverage_luma_gt12=1.00000 thresholds=(stddev>=2.0,coverage>=0.001) status=PASS"
}
]