#!/usr/bin/env python3 """Single source of truth for where staged actors belong in the DemoMap. This exists because the same value was written in two places and they drifted: `ue_hero_facade_import.py` kept the pre-`0.1.0` position `(-12024.5, -1450)` while `ue_build_demo_map.py` staged the hero at `(-13336, 1307)`. Running the importer on its own therefore moved the hero **13 m east and onto the north side of the boulevard** — and nothing complained, because a displaced building still renders. The values are Unreal centimetres, absolute world space. Every one of them is verified against `Geo/verification/2026-11-06-el-capitan-block.md` and probed by `Tools/review/visual_loop.py --verify` (via the demo screenshot expectations) and by the world-span probes recorded in `MEMORY.md`. Keep this file boring: constants and one validator, no `unreal` import, so it can be unit-tested on the host. """ from __future__ import annotations # The hero façade sits INSIDE the frontage gap between 6902 (ends at -17749) and # the El Capitan Theatre (starts at -12082), so its actor origin is the measured # building line. The mesh is authored with its front plane 7 cm ahead of the actor # origin, which is why the X here is the frontage centre and Y is the building line. HERO_ACTOR = "Hero_Facade" HERO_LOCATION_CM = (-13336.0, 1307.0, 0.0) # Tolerance for the span probe: the verified footprints are within ~1 m. SPAN_TOLERANCE_CM = 100.0 # Expected world span per frontage actor (min X, max X), from the block # verification notes. Used to prove a staged building is on its own footprint # rather than merely present. FRONTAGE_SPANS_CM = { "6922": (-24276.0, -17700.0), "6902": (-17749.0, -14591.0), "hero": (-14644.0, -12028.0), "6838": (-12082.0, -8210.0), "6822": (-7854.0, -7252.0), "6806": (-6608.0, -3307.0), "6800": (-3320.0, -1437.0), } def span_error(name: str, observed_min: float, observed_max: float): """Return (expected_min, expected_max, ok) for an observed building span. `name` is a key of `FRONTAGE_SPANS_CM`; `ok` is False when either edge is more than `SPAN_TOLERANCE_CM` from the verified value. """ if name not in FRONTAGE_SPANS_CM: raise KeyError(f"unknown building {name!r}; known: {sorted(FRONTAGE_SPANS_CM)}") exp_min, exp_max = FRONTAGE_SPANS_CM[name] ok = (abs(observed_min - exp_min) <= SPAN_TOLERANCE_CM and abs(observed_max - exp_max) <= SPAN_TOLERANCE_CM) return exp_min, exp_max, ok def describe_span_failure(name: str, observed_min: float, observed_max: float) -> str: """A one-line message for a misplaced building, or "" when it is correct.""" exp_min, exp_max, ok = span_error(name, observed_min, observed_max) if ok: return "" return (f"{name}: span X {observed_min:.0f}..{observed_max:.0f} does not match the " f"verified {exp_min:.0f}..{exp_max:.0f} (±{SPAN_TOLERANCE_CM:.0f} cm)")