The 0.1.2 blockout regeneration ran without --origin, so Blosm centred on the
extract instead of fitting the project frame. The frontage shifted ~119 m in X and
~2.4 m in Y and the hero fell outside the 6902/6838 gap - the verified placement
was silently undone, while every render still looked like a plausible block.
- Blockout regenerated with --origin 34.101545,-118.338718 (affine residual 0.0 cm);
frontage and north buildings re-exported and re-imported.
- Verified spans restored: 6922 -24276..-17700, 6902 -17749..-14591, hero
-14644..-12028 between them, theatre -12082..-8210, TCL -22889..-18442,
Tussaud's -27071..-22799.
- ue_apply_facade_kit now uses get_actor_bounds() (world space). It had used the
static mesh bounding box, which is building-line-local, so every kit piece was
placed ~12 km east of its building in empty ground.
- ue_import_north_buildings.py was missing 'import sys' (NameError, exit 255,
import silently skipped) - the same trap as the hero importer.
- Kit re-applied: 625 pieces across eight buildings; packaged QA still PASS
(walk, transect 0 holes, wall probe 0/35, facade probe 0/9).
Geo/tools/ is now every geographic script, with Geo/README.md documenting each
one; the Blender-side builders moved beside their outputs in Art/blender/*/ and
import their helpers from Geo/tools/osm_common.py.
That module gains to_unreal_local() and to_blender_local(): the only place in the
repository that multiplies metres by 100, so a second silent scale cannot be
introduced. block_height_report.py adds height provenance for the block — 3 of
15 buildings have no height data and render at a placeholder 6.4 m.
asset_metadata.py writes and audits <asset>.geo.json sidecars; four now exist
(hero-facade, terrain, street, blockout) and the audit recomputes each centre from
the origin, failing anything that disagrees.
Tools/terrain_from_dem.py builds a 191x106 grid at 2 m over the block, Z being
NAVD88 minus the origin ground. Building footprints from the OSM extract are cut
out so rooftops never become terrain (72 footprints, 6310 cells). Spot checks
reproduce the measured profile: origin 0.00, Orange Dr +3.39, south gutter
+0.93, crown +1.38, north sidewalk +1.43.
Blosm projects with a sphere, not an ellipsoid, so its frame was ~0.4% oversized
and rotated by meridian convergence: about 2 m at the theatre. The blockout now
fits a six-parameter affine into EPSG:26911 on five control points (0.0 cm
residual) and transforms root objects only, since children inherit and double
transforming them read as a 2 m placement error.
Tools/blosm_blockout.py imports the committed extract in 3Dsimple mode and
reports per-building dimensions so a units failure is visible in the log. The
result (87 meshes) is committed as the blockout baseline: hero 25.68 x 54.88 x
14.50 m against 25.75 x 54.88 m of OSM geometry, so the import is 1:1 metres.
Two headless defects needed working around: the asset-directory check that
fires before mode is honoured, and an empty default-level table sending the
add-on down a broken relative import. Member fetching stays off so the import
does not depend on Overpass.