Commit Graph
9 Commits
Author SHA1 Message Date
zwitschi 70c6e322e2 feat(hero): Ionic base and abacus, medallions onto the parapet face
Detail pass on the hero, all verified by measuring the built mesh:

- Column base moulding: a 1.36 m wide, 0.22 m tall cylinder at each shaft foot
  (2.00-2.22 m). The shaft previously started straight off the square pedestal,
  so the base never read in silhouette.
- Abacus: a 1.30 m square, 0.14 m thick slab over each capital. It takes the top
  of the capital zone, so the colonnade still ends at 9.70 m and the 53.1 %
  proportion is unchanged.
- Medallions fixed: they were built with the Z-axis cylinder helper, so the two
  'discs' were pancakes lying flat on the parapet coping (1.1 x 1.1 x 0.02,
  z 14.02-14.04). New disc_on_wall() helper rotates the cylinder 90 deg about X;
  they now stand 1.1 m across on the parapet face (y -1.32..-1.28,
  z 13.05..14.15).

Hero rebuilt (95 parts, 2420 tris, still 14.50 m), re-imported, DemoMap rebuilt,
screenshot set re-rendered. Part report records the new dims and their assumption
notes. Screenshots README notes the detail pass.
2026-11-08 17:39:52 +01:00
zwitschi abace2ad05 feat(tools): AI detail plates from the reference photography; fix floating windows
Adds Tools/facade_detail_concepts.py: generates architectural detail plates from a
local reference photograph through OpenRouter's image models. Spec-driven (eight
studies: door recess, entrance, column order, entablature/cornice, parapet/motto,
window rhythm, street wall, banner), never overwrites (writes -vN), writes a
.refgen.json sidecar (model, prompt, source photo, SHA-256) per image, and keeps
all output under the gitignored Art/reference/facade-details/ - local only, never
shipped. Stdlib only; http 429/5xx back-off; refuses to write a sidecar containing
the token. 11 tests cover the study table, prompt assembly, next-free naming,
data-URL decoding (both response shapes plus a refusal) and the local-only rule.

Measurement pass on the plates: the hero window panes were at Y -1.98, i.e. 1.44 m
in FRONT of the wall (Y -0.50) and ahead of the column line, so the glazing floated
in the colonnade instead of reading as openings behind it. Moved to Y -0.56; hero
rebuilt, re-imported, DemoMap rebuilt, full screenshot set re-rendered.

Docs: Tools/README row, Screenshots README known-issues entry now records the fix.
2026-11-08 17:27:27 +01:00
zwitschi 8851b2272e fix(hero): lift the colonnade into the photographed 50-60% band
Measured from the built mesh, the colonnade (columns + capitals) was 6.90 m of the
14.50 m elevation = 47.6 %: the entablature (3.40 m) and parapet (2.20 m) were
using 5.60 m of the height. Thinned both to 3.00 m and 1.80 m in
hero_facade_build.py, which lifts the colonnade to 7.70 m = 53.1 % - inside the
50-60 % band - with the envelope, motto band and medallions unchanged relative to
the parapet.

Hero rebuilt, re-imported (bounds 2604 x 1257 x 1450 cm), DemoMap rebuilt and the
screenshot set re-rendered for review. Hero part report updated (columns 7.45 ->
8.25 m, entablature 3.40 -> 3.00 m).

TODO: colonnade item closed. MEMORY records the FBX-vs-blend --out gotcha.
2026-11-08 16:46:30 +01:00
zwitschi 5ffe62f6aa feat(geo): adopt Mapbox building calibration (3.1 m per level) (#26)
Merged PR #26: adopt Mapbox building calibration

Co-authored-by: Zwitschi <zwitschi82@gmail.com>
2026-11-08 16:38:28 +01:00
zwitschi e75e5500a7 fix(street): 0.1.1 collision patch — flush sidewalk edge, graded crossing ramps (#21)
Merged PR #21: 0.1.1 collision patch (flush sidewalk edge, graded ramps)

Co-authored-by: Zwitschi <zwitschi82@gmail.com>
2026-11-08 16:19:11 +01:00
zwitschi 52b1212cf3 qa: make the demo walkable — terrain collision root cause, spawn, scripted QA
The reported fall-through was a misdiagnosis: the player never fell. The
imported Terrain_DEM had only a bounding-box simple collision proxy, so a
downward trace anywhere in the block hit the terrain at Z 819 (the mesh
bbox max) and the street sat under an invisible 8 m lid. Standing on that
box looked plausible, which is why it read as working.

- add UGigLineAssetTools (C++): force CTF_UseComplexAsSimple on a static
  mesh. UE 5.8 dropped bUseComplexAsSimpleCollision and Python cannot set
  the flag; the builder also saves the asset, since the flag lives there
  and a map-only save silently reverts it.
- spawn (-13336, -1150, 600): inside the carved corridor (the cut is a
  10.7 m half-width around the road centreline), lands on the road at 456.
- fix ResetToStart returning to the mid-air PlayerStart captured in
  BeginPlay: StartLocation is now captured on the first grounded frame.
- HighResShot 1280x720 instead of "1280 720", which is a multiplier.
- add -qaselftest: scripted walk/reset/pause on a core ticker plus a
  swept ground transect. Results: walk 746 cm/2 s with Z steady, reset
  0 cm from spawn, pause/unpause 1/0, transect 84 samples 0 holes.
- rebase onto main, keeping the frontage materials and placement fixes.
2026-11-08 11:56:19 +01:00
zwitschi accf3a5306 lighting: fixed daytime rig, real surface materials, dynamic lights
Completes "Fixed daytime lighting and basic ambience" for 0.1.0. All 14
screenshots approved by the owner.

Lighting rig (Tools/ue_build_demo_map.py):
- Sun pitch -50 / yaw 120, intensity 4, warm (255/245/230), atmosphere sun light
- Sky light 2.6 with real-time capture, sky atmosphere, height fog (density 0.008)
- Unbound post-process volume with fixed exposure (min == max brightness) so a
  shot cannot wash out or crush to black depending on how much sky it frames
- Dynamic-only: r.AllowStaticLighting=False plus MOVABLE lights and mesh
  components, so the editor's "LIGHTING NEEDS TO BE REBUILT" warning no longer
  fires and nothing needs baking

Bugs found and fixed on the way:
- Blender diffuse colours do not survive the FBX -> Unreal import: every site
  material arrived white and the terrain arrived with WorldGridMaterial, which
  is what actually made the scene look blown out. The demo builder now creates
  and assigns M_Asphalt, M_Concrete, M_Ground and M_RoadPaint.
- Only one of the three crossings reached the game: each zebra band was its own
  object, so Blender renamed the duplicates .001/.002 and exact-name site
  assembly skipped them. All bands are now one Crossing_Markings mesh.
- Demo cameras: street-level sat inside the facade body (rendering its unlit
  back face) and the crossing camera aimed at the s=36.6 crossing instead of
  the designated s=130.1 (UE X -14956).
- The terrain had no material and imported as a bright default grid.
- Cleared a committed Android File Server SecurityToken (plugin disabled and
  shipping-excluded; the value must stay empty).

Docs:
- Screenshots/README.md: one consolidated table for all 14 shots with map,
  camera view and description; all approved.
- MEMORY.md: records the material-import, exposure, light_color struct,
  band-naming, camera-bounds and lighting-build traps.
- TODO.md: lighting item marked done.

Squash of branch gameplay-lighting-0.1.0 (PR #3).
2026-11-07 18:22:19 +01:00
zwitschi bc2e421d33 gameplay: designated street crossing — zebra markings, corridor cut, up-facing street
- street_mesh.py: continental zebra markings (0.5 m bars, 0.5 m gaps, 3 m
  band) at all three signalised crossings, triangles not quads (FBX SDK
  refuses to triangulate the crown-twisted quads), stripes +6 cm above the
  DEM so they stay above the road surface; winding flipped so every street
  surface faces up (road/sidewalks/markings were 100% down-facing and
  invisible in engine once the terrain stopped covering them).
- terrain_from_dem.py: cut a 10.7 m corridor around the Hollywood Blvd
  centreline so road, kerbs and sidewalks are not buried under the terrain;
  sidewalks themselves cover the transition band, walk-check stays at 0 holes.
- Blender builders save with a writability guard + fatal failure: *.blend
  is LFS-lockable and checks out read-only; a failed save previously left
  downstream steps building from stale files.
- ue_import_site.py: Crossing_Markings imports with no collision (paint on
  the road); ue_build_demo_map.py stages it and chmods the lockable .umap
  before saving (save_map silently returned False on read-only maps).
- ue_build_review_map.py: demo-crossing camera moved to the real crossing
  (s=130.1 m -> UE -24291,-1340) and fixed the ensure_writable path (was
  missing the .umap suffix, so the chmod never fired).
2026-11-07 15:46:45 +01:00
zwitschi cf392a02f7 gameplay: walkable demo map, reset and pause
Tools/ue_build_demo_map.py builds /Game/Hollywood/DemoMap: sun, sky, the hero
facade on the building line, six site meshes imported with collision, and a
player start on the north sidewalk. Tools/ue_import_site.py imports the site
FBXs; terrain, road and sidewalks use complex-as-simple so a simple hull cannot
ramp over the kerbs. Art/blender/site/export_site_fbx.py exports one FBX per
object so each can carry its own collision.

Reset (R) and pause (Escape) join the character and the input context: reset
restores the spawn transform and clears momentum, pause is a real game pause that
releases the cursor. DefaultInput.ini captures the mouse on launch.

Three placement defects found by measuring the imported actors rather than
trusting the plan: the spawn was on the wrong sidewalk because the FBX flip
inverts north, a mirror I added to the exporter double-corrected an already
correct sidewalk, and the street meshes only carry part of the north walk - the
rest is terrain.
2026-11-07 13:17:24 +01:00