From 4e703fcfd9925cea3c7e7ddb5de1117a39a1754e Mon Sep 17 00:00:00 2001 From: Zwitschi Date: Mon, 9 Nov 2026 08:59:07 +0100 Subject: [PATCH 1/8] todo: claim 0.1.6 retail frontage on branch facade-retail-0.1.6 --- TODO.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TODO.md b/TODO.md index d55e52d..12e367b 100644 --- a/TODO.md +++ b/TODO.md @@ -13,9 +13,9 @@ Actionable task list for this project. This file is the single, central place fo Suggested blender skills: **references** (reference-image-match), **archviz**, **historical-worlds** for the 1920s–1990s retail mix on this run. -### Patch tasks +### Patch tasks - active - session-5598ce7e-27e3-4c64-bb49-c04a4a31ee58 (branch `facade-retail-0.1.6`) -- [ ] **Model 6822 Budget, 6806–6820 and 6800 Lee Drug from their own references.** `Art/reference/retail-neighbours/` holds 6800 and its neighbour (Gb321, CC BY-SA 4.0); Commons has nothing usable for 6822 or 6806–6820, so those two need photography before they can be modelled honestly. Do not substitute the El Capitan Theatre's 18-frame set — it would misattribute the façades. +- [A] **Model 6822 Budget, 6806–6820 and 6800 Lee Drug from their own references.** `Art/reference/retail-neighbours/` holds 6800 and its neighbour (Gb321, CC BY-SA 4.0); Commons has nothing usable for 6822 or 6806–6820, so those two need photography before they can be modelled honestly. Do not substitute the El Capitan Theatre's 18-frame set — it would misattribute the façades. - [ ] Review every façade change with `Tools/render_screenshots.sh --verify` before tagging. - [ ] Tag `v0.1.6` and write `CHANGELOG.md` entry; then remove this section. -- 2.47.3 From 2614d259aada4ea31ecc5755c55cec6cf8f64e39 Mon Sep 17 00:00:00 2001 From: Zwitschi Date: Mon, 9 Nov 2026 09:10:49 +0100 Subject: [PATCH 2/8] =?UTF-8?q?feat(facades):=200.1.6=20retail=20frontage?= =?UTF-8?q?=20first=20pass=20=E2=80=94=20Lee=20Drug=20and=206806-6820?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Models the two retail buildings beside the hero from their own photograph rather than the generic kit: bronze cornice, mural row, lettering band, stepped Deco parapet and rounded corner tower on 6800 Lee Drug; burgundy fascia, pilasters, white-framed windows and banded parapet on 6806-6820. Reference analysis written before any geometry (Art/blender/retail/ref-analysis.md), every unmeasured proportion carried into the part report as an assumption. 6822 Budget is deferred, not guessed: no photograph of it exists and the 6.0 x 5.5 m sliver cannot be read out of the neighbour shot. Pipeline fixes found on the way: - render_screenshots.sh called ./Engine/... for the capture step while every commandlet used the absolute path; set -e killed the script at 127 *after* the maps were rebuilt, so screenshots silently stayed a day old. - the facade kit applies to every Frontage_*/North_* actor, so it pasted its own language over the new modelled facades; it now skips them, and the trim stages as RetailTrim_*. - pure bay arithmetic moved to Tools/_common.py so it is unit-testable without Blender (4 new tests, 82 total pass). Known gaps recorded in Screenshots/README.md, not hidden: the parapet reads as a blank band, murals and lettering do not resolve at review distance, the tower is a plain cylinder, and the review camera crops the east end. --- Art/blender/retail/ref-analysis.md | 76 ++++ Game/GigLine/Content/Hollywood/DemoMap.umap | 4 +- .../Hollywood/Frontage/M_Retail_Bronze.uasset | 3 + .../Frontage/M_Retail_Burgundy.uasset | 3 + .../Hollywood/Frontage/M_Retail_Glass.uasset | 3 + .../Hollywood/Frontage/M_Retail_Mural.uasset | 3 + .../Hollywood/Frontage/M_Retail_Stucco.uasset | 3 + .../Hollywood/Frontage/M_Retail_White.uasset | 3 + .../Hollywood/Frontage/SM_Retail_6806.uasset | 3 + .../Frontage/SM_Retail_LeeDrug.uasset | 3 + .../Content/Hollywood/Site/M_Asphalt.uasset | 4 +- .../Content/Hollywood/Site/M_Concrete.uasset | 4 +- .../Hollywood/Site/M_FacadeBanner.uasset | 4 +- .../Hollywood/Site/M_FacadeGlass.uasset | 4 +- .../Hollywood/Site/M_FacadeStone.uasset | 4 +- .../Hollywood/Site/M_FacadeStoneShadow.uasset | 4 +- .../Content/Hollywood/Site/M_Ground.uasset | 4 +- .../Hollywood/Site/M_KerbConcrete.uasset | 4 +- .../Content/Hollywood/Site/M_RoadPaint.uasset | 4 +- .../Content/Hollywood/Site/M_Stucco.uasset | 4 +- .../Content/Hollywood/Site/Terrain_DEM.uasset | 2 +- .../Hollywood/Textures/T_Asphalt_BC.uasset | 2 +- .../Hollywood/Textures/T_Asphalt_R.uasset | 2 +- .../Hollywood/Textures/T_Concrete_BC.uasset | 2 +- .../Hollywood/Textures/T_Concrete_R.uasset | 2 +- .../Textures/T_StoneAshlar_BC.uasset | 2 +- .../Hollywood/Textures/T_StoneAshlar_R.uasset | 2 +- .../Hollywood/Textures/T_Stucco_BC.uasset | 2 +- .../Hollywood/Textures/T_Stucco_R.uasset | 2 +- .../Theatre/SM_Trim_BladeSign.uasset | 2 +- .../Theatre/SM_Trim_BladeSignBracket.uasset | 2 +- .../Theatre/SM_Trim_BladeSignFrame.uasset | 2 +- .../Theatre/SM_Trim_MarqueeCanopy.uasset | 2 +- .../Theatre/SM_Trim_MarqueeFascia.uasset | 2 +- .../Theatre/SM_Trim_MarqueeSoffit.uasset | 2 +- Game/GigLine/Content/Test/ReviewMap.umap | 2 +- MEMORY.md | 8 + Screenshots/README.md | 18 + Screenshots/demo/review-demo-crossing.png | 4 +- .../demo/review-demo-north-buildings.png | 4 +- .../demo/review-demo-retail-frontage.png | 3 + Screenshots/demo/review-demo-spawn-view.png | 4 +- Screenshots/demo/review-demo-street-level.png | 4 +- TODO.md | 5 +- Tools/README.md | 3 + Tools/_common.py | 27 ++ Tools/render_screenshots.sh | 5 +- Tools/retail_frontage_build.py | 329 ++++++++++++++++++ Tools/tests/test_retail_frontage.py | 32 ++ Tools/ue_apply_facade_kit.py | 12 +- Tools/ue_build_demo_map.py | 19 + Tools/ue_build_review_map.py | 6 + Tools/ue_import_retail_detail.py | 94 +++++ Tools/visual_targets.json | 12 + 54 files changed, 715 insertions(+), 50 deletions(-) create mode 100644 Art/blender/retail/ref-analysis.md create mode 100644 Game/GigLine/Content/Hollywood/Frontage/M_Retail_Bronze.uasset create mode 100644 Game/GigLine/Content/Hollywood/Frontage/M_Retail_Burgundy.uasset create mode 100644 Game/GigLine/Content/Hollywood/Frontage/M_Retail_Glass.uasset create mode 100644 Game/GigLine/Content/Hollywood/Frontage/M_Retail_Mural.uasset create mode 100644 Game/GigLine/Content/Hollywood/Frontage/M_Retail_Stucco.uasset create mode 100644 Game/GigLine/Content/Hollywood/Frontage/M_Retail_White.uasset create mode 100644 Game/GigLine/Content/Hollywood/Frontage/SM_Retail_6806.uasset create mode 100644 Game/GigLine/Content/Hollywood/Frontage/SM_Retail_LeeDrug.uasset create mode 100644 Screenshots/demo/review-demo-retail-frontage.png create mode 100644 Tools/_common.py create mode 100644 Tools/retail_frontage_build.py create mode 100644 Tools/tests/test_retail_frontage.py create mode 100644 Tools/ue_import_retail_detail.py diff --git a/Art/blender/retail/ref-analysis.md b/Art/blender/retail/ref-analysis.md new file mode 100644 index 0000000..fb253a5 --- /dev/null +++ b/Art/blender/retail/ref-analysis.md @@ -0,0 +1,76 @@ +# Reference analysis — retail frontage, 0.1.6 + +Phase 0 of the `references` pack (reference-image-match). Written before any geometry, +because the pass that produced the hero façade skipped it and cost two rebuilds. + +## Source + +| | | +| --- | --- | +| Image | `Art/reference/retail-neighbours/01-lee-drug-and-neighbor.jpg` (1920×953) | +| Author / licence | Gb321, own work, **CC BY-SA 4.0** — attribution required | +| Captured | 2024-07-19 11:11 local | +| Description | "Lee Drug and 6806 Hollywood Buildings in Hollywood" | +| Coverage | Both target buildings in one frame, mid-morning sun from the south-east | + +**One photograph is the whole evidence base for 6800 and 6806–6820.** It is a street-level +oblique, not an elevation: verticals converge, the ground floor of 6806–6820 is partly behind +a parked car, and the Lee Drug shopfront is behind a bus. Everything below that the photo does +not resolve is marked *assumed* and is carried into the part report. + +**6822 Budget has no photograph.** It is a 6.0 m × 5.5 m single-storey sliver west of +6806–6820, and the TODO item already records that Commons has nothing usable. It stays a +blockout extrusion and the item is deferred rather than guessed. + +## Measured (not from the photo) + +From `Geo/raw/osm-api-map-2026-11-06.osm` and the blockout, in the shared frame +(metres, X east, Y north, Z from the project datum): + +| Building | OSM way | X | Front face Y | Height | Depth | +| --- | --- | --- | --- | --- | --- | +| 6800 Lee Drug | 424024149 | −33.20 … −14.37 | −14.63 | 12.10 m | 33.5 m | +| 6806–6820 | 424024150 | −66.08 … −33.07 | −12.52 | 12.10 m | 30.8 m | +| 6822 Budget | 424024144 | −78.54 … −72.52 | −12.92 | 5.50 m | 15.4 m | + +Both target buildings are 12.10 m tall, which makes the *relative* proportions in the photo +directly usable: the parapet line, the cornice and the shopfront line can be read as fractions +of the frame height. + +## 6800 Lee Drug — reading + +| Category | Observation | +| --- | --- | +| Subject | Corner retail block at Hollywood × Highland; the street face and the corner return are both visible | +| Silhouette | Long low box, broken by a **rounded corner tower** that rises above the frontage parapet; the parapet is **stepped**, not flat | +| Storeys | Two zones, not storeys: a tall shopfront zone and a single tall display wall above it | +| Proportion (vertical) | Shopfront ≈ 0 → 0.36 H; bronze cornice ≈ 0.36 → 0.43 H; mural + lettering wall ≈ 0.43 → 0.82 H; stepped parapet ≈ 0.82 → 1.0 H (*assumed split; read off the frame, ±0.03 H*) | +| Proportion (horizontal) | Corner tower occupies ≈ 4 m of the east end; eight mural panels at roughly 2.2 m centres along the frontage | +| Colour | Cream stucco wall `#EDE6D8`, bronze/brown cornice `#6B4A2F`, near-black mural plates `#1C1A18`, dark glazing `#20262A` (*sampled from the frame*) | +| Unique features | Stepped Deco parapet with 4 horizontal reveal lines; projecting bronze cornice; row of black celebrity-portrait panels; large dark "SOUVENIRS OF …" lettering on the upper wall; shopfront glazing with slim mullions | +| Mood | 1930s Deco retail, freshly painted, bright midday | + +## 6806–6820 — reading + +| Category | Observation | +| --- | --- | +| Silhouette | Flat-fronted two-storey block; parapet steps up in fins at the west end | +| Proportion (vertical) | Shopfront ≈ 0 → 0.32 H; burgundy fascia band ≈ 0.32 → 0.38 H; window storey ≈ 0.38 → 0.62 H; blank wall + parapet ≈ 0.62 → 1.0 H (*assumed*) | +| Horizontal | Brown pilaster strips divide the frontage into roughly 3 m bays; seven upper windows across 33 m | +| Colour | Same cream stucco; brown pilasters `#6B4A2F`; **burgundy-green** fascia `#5B3A3A`; white window frames | +| Unique features | Banded parapet with 3 reveal lines; white-framed upper windows with security bars; shopfront glazing behind a burgundy fascia | + +## Camera match (for the review shot) + +The photo is a street-level oblique from the **north** side looking south-east, subject filling +~80 % of the frame width. The demo review shot must reproduce that: camera at 1.7 m on the +north sidewalk, yaw toward the south frontage, 35–42° lens, both buildings in frame. A wide +block view will not compare usefully against this crop. + +## Assumptions to carry into the model report + +1. Vertical proportions, as above — the photo's convergence makes a pixel-perfect read impossible. +2. Mural panel size and spacing; the lettering is modelled as a recessed plate, not as text. +3. Shopfront bay spacing on both buildings; the bus hides most of Lee Drug's ground floor. +4. Parapet reveal line count (4 on Lee Drug, 3 on 6806–6820). +5. Corner tower radius; only the outer curve is visible. diff --git a/Game/GigLine/Content/Hollywood/DemoMap.umap b/Game/GigLine/Content/Hollywood/DemoMap.umap index 9b1cfcc..e734bfc 100644 --- a/Game/GigLine/Content/Hollywood/DemoMap.umap +++ b/Game/GigLine/Content/Hollywood/DemoMap.umap @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:979c81662cbb7cce37da5401a873c85b56a8da9f13a1e27790bd10f8098c54a4 -size 920287 +oid sha256:0d6d69622d2135200c91e09decfe462e93b416bcbad430cb7e8ce5df4368b83c +size 781795 diff --git a/Game/GigLine/Content/Hollywood/Frontage/M_Retail_Bronze.uasset b/Game/GigLine/Content/Hollywood/Frontage/M_Retail_Bronze.uasset new file mode 100644 index 0000000..3017713 --- /dev/null +++ b/Game/GigLine/Content/Hollywood/Frontage/M_Retail_Bronze.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f4b1ebcefdb8b02bf6f3dfc61f25ceed6bde1e5ecf40067437fd4d70f7a93c45 +size 56705 diff --git a/Game/GigLine/Content/Hollywood/Frontage/M_Retail_Burgundy.uasset b/Game/GigLine/Content/Hollywood/Frontage/M_Retail_Burgundy.uasset new file mode 100644 index 0000000..3b32fd8 --- /dev/null +++ b/Game/GigLine/Content/Hollywood/Frontage/M_Retail_Burgundy.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:682a4a2e3d365daa848fb3c8f8c902a1ccd181fc68120fe72452449337c95dc6 +size 56702 diff --git a/Game/GigLine/Content/Hollywood/Frontage/M_Retail_Glass.uasset b/Game/GigLine/Content/Hollywood/Frontage/M_Retail_Glass.uasset new file mode 100644 index 0000000..2311b01 --- /dev/null +++ b/Game/GigLine/Content/Hollywood/Frontage/M_Retail_Glass.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aedc0b3c2b40ead88ddda2e1bfdd8fe7047fc044255c57a4be1a736c329332bd +size 56688 diff --git a/Game/GigLine/Content/Hollywood/Frontage/M_Retail_Mural.uasset b/Game/GigLine/Content/Hollywood/Frontage/M_Retail_Mural.uasset new file mode 100644 index 0000000..377e376 --- /dev/null +++ b/Game/GigLine/Content/Hollywood/Frontage/M_Retail_Mural.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8b2688239130bb6210829d2d1a39b9ef4da74eb06f4fdfacae08faf2dc7e7e6b +size 56685 diff --git a/Game/GigLine/Content/Hollywood/Frontage/M_Retail_Stucco.uasset b/Game/GigLine/Content/Hollywood/Frontage/M_Retail_Stucco.uasset new file mode 100644 index 0000000..2c9b5fd --- /dev/null +++ b/Game/GigLine/Content/Hollywood/Frontage/M_Retail_Stucco.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cf6cbf3830fba67080af03dca25da41054ef6d7ef22fc88da9e67b898c9ff124 +size 56681 diff --git a/Game/GigLine/Content/Hollywood/Frontage/M_Retail_White.uasset b/Game/GigLine/Content/Hollywood/Frontage/M_Retail_White.uasset new file mode 100644 index 0000000..24a99b5 --- /dev/null +++ b/Game/GigLine/Content/Hollywood/Frontage/M_Retail_White.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fd9698b0577e35d145117f049777fd3218d602cff0f78c8ca7fa7965d08ad8ad +size 56694 diff --git a/Game/GigLine/Content/Hollywood/Frontage/SM_Retail_6806.uasset b/Game/GigLine/Content/Hollywood/Frontage/SM_Retail_6806.uasset new file mode 100644 index 0000000..9095828 --- /dev/null +++ b/Game/GigLine/Content/Hollywood/Frontage/SM_Retail_6806.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d436f4ed1e6d1b922ab93b61d801296453e755133039cb68a24a768cf80fd9eb +size 93500 diff --git a/Game/GigLine/Content/Hollywood/Frontage/SM_Retail_LeeDrug.uasset b/Game/GigLine/Content/Hollywood/Frontage/SM_Retail_LeeDrug.uasset new file mode 100644 index 0000000..43664c0 --- /dev/null +++ b/Game/GigLine/Content/Hollywood/Frontage/SM_Retail_LeeDrug.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:48acd6aa22718c98df68b913b0e9a1d258b33ccf9a59ba76439d5cbeaf7c3137 +size 96341 diff --git a/Game/GigLine/Content/Hollywood/Site/M_Asphalt.uasset b/Game/GigLine/Content/Hollywood/Site/M_Asphalt.uasset index a8aa8b3..fe6cb0f 100644 --- a/Game/GigLine/Content/Hollywood/Site/M_Asphalt.uasset +++ b/Game/GigLine/Content/Hollywood/Site/M_Asphalt.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:42651b3f341042ff5b59565061b40e10f742cb040ad32159cc2497baaa53241f -size 9818 +oid sha256:3fb76d8de906114912d8d5fe6e5cccd5f661eaf7bd644f9d32a5a4a122bedc4d +size 10019 diff --git a/Game/GigLine/Content/Hollywood/Site/M_Concrete.uasset b/Game/GigLine/Content/Hollywood/Site/M_Concrete.uasset index 4990334..25741c9 100644 --- a/Game/GigLine/Content/Hollywood/Site/M_Concrete.uasset +++ b/Game/GigLine/Content/Hollywood/Site/M_Concrete.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ac79d443e78c66dfdd0e6dcc826acb516157bb3b099643ca46a48a11ade12fd1 -size 9823 +oid sha256:83c4ce0706040145c130664a8098614a8022e9deb814b4a281098cc81b340b4c +size 10024 diff --git a/Game/GigLine/Content/Hollywood/Site/M_FacadeBanner.uasset b/Game/GigLine/Content/Hollywood/Site/M_FacadeBanner.uasset index 96db4a4..64c183f 100644 --- a/Game/GigLine/Content/Hollywood/Site/M_FacadeBanner.uasset +++ b/Game/GigLine/Content/Hollywood/Site/M_FacadeBanner.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ed6a9b1306a3f54006dd09d33edea45635af4445f88f9b7b021a6be96226d0f8 -size 11054 +oid sha256:1926a4806a096dca5ac226f0104df86adfe5861639ca31159192e392619f7e0a +size 11419 diff --git a/Game/GigLine/Content/Hollywood/Site/M_FacadeGlass.uasset b/Game/GigLine/Content/Hollywood/Site/M_FacadeGlass.uasset index 674550a..2eee7c5 100644 --- a/Game/GigLine/Content/Hollywood/Site/M_FacadeGlass.uasset +++ b/Game/GigLine/Content/Hollywood/Site/M_FacadeGlass.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d8c25c5cf5e02e8ae7eddb42d6ab3ab5eb1868021ea6373a4e01676223daf7fe -size 11049 +oid sha256:1371c411f28b429836bea1000d8bd45317385e89fadb65229c6d5e30ad8deafa +size 11414 diff --git a/Game/GigLine/Content/Hollywood/Site/M_FacadeStone.uasset b/Game/GigLine/Content/Hollywood/Site/M_FacadeStone.uasset index b52bd8f..87483be 100644 --- a/Game/GigLine/Content/Hollywood/Site/M_FacadeStone.uasset +++ b/Game/GigLine/Content/Hollywood/Site/M_FacadeStone.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ee7e3321ede0f26ff779baa0dbfb1cba79682c00c3c604a57a6ff511df1e1a96 -size 16924 +oid sha256:3bce906bf91b38622e821768ec39b18e628e6362eb8f32c591c7896692662df6 +size 17168 diff --git a/Game/GigLine/Content/Hollywood/Site/M_FacadeStoneShadow.uasset b/Game/GigLine/Content/Hollywood/Site/M_FacadeStoneShadow.uasset index beb0987..947e285 100644 --- a/Game/GigLine/Content/Hollywood/Site/M_FacadeStoneShadow.uasset +++ b/Game/GigLine/Content/Hollywood/Site/M_FacadeStoneShadow.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a63d50ddbe2b8674fa37ec42936e02ae20f604503966bb0eb9acd072c2061508 -size 16954 +oid sha256:90a31499a481fbb8efeb5d5f30aa5c1beb6ca3afa91c1a154e689e2a55c49345 +size 17198 diff --git a/Game/GigLine/Content/Hollywood/Site/M_Ground.uasset b/Game/GigLine/Content/Hollywood/Site/M_Ground.uasset index 79b8458..adc5f84 100644 --- a/Game/GigLine/Content/Hollywood/Site/M_Ground.uasset +++ b/Game/GigLine/Content/Hollywood/Site/M_Ground.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f24e2319667b421615b371015edf38ae1645049a29a4ed07e79f8f780161b4ec -size 9813 +oid sha256:fe37d1ab7c4d2f3621f7993c1dfdb0f062398b589ee8a5c3aace444a9417f66e +size 10014 diff --git a/Game/GigLine/Content/Hollywood/Site/M_KerbConcrete.uasset b/Game/GigLine/Content/Hollywood/Site/M_KerbConcrete.uasset index cc43899..0d2e7a9 100644 --- a/Game/GigLine/Content/Hollywood/Site/M_KerbConcrete.uasset +++ b/Game/GigLine/Content/Hollywood/Site/M_KerbConcrete.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:27dad21ae40278bc8f85b71f816b26f63cebf3032cf6f026dc827770ae70c112 -size 9843 +oid sha256:234d60830b619bc25f6ea9ddbcc192e462409629c5e17a121879569ee5cc01bb +size 10044 diff --git a/Game/GigLine/Content/Hollywood/Site/M_RoadPaint.uasset b/Game/GigLine/Content/Hollywood/Site/M_RoadPaint.uasset index a9892bc..8363427 100644 --- a/Game/GigLine/Content/Hollywood/Site/M_RoadPaint.uasset +++ b/Game/GigLine/Content/Hollywood/Site/M_RoadPaint.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dd1f661a78dc559fe32a7eba5b8de1c3c11eb02db915c6af75698233064f3bfd -size 9828 +oid sha256:90ebf4aa1f81ee4935afa7b683d574ea07fffb6860cc2b3a8cedbed826888c4f +size 10029 diff --git a/Game/GigLine/Content/Hollywood/Site/M_Stucco.uasset b/Game/GigLine/Content/Hollywood/Site/M_Stucco.uasset index 9620116..40bde8e 100644 --- a/Game/GigLine/Content/Hollywood/Site/M_Stucco.uasset +++ b/Game/GigLine/Content/Hollywood/Site/M_Stucco.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:79afcede88edfbdbca48cc80d414f90824c1b3c29f4e0d6fa20bcfd83956add4 -size 11024 +oid sha256:288b925a6c4207632777e5c13190345ba5e028ad2e675e34c32c99815f68cecb +size 11389 diff --git a/Game/GigLine/Content/Hollywood/Site/Terrain_DEM.uasset b/Game/GigLine/Content/Hollywood/Site/Terrain_DEM.uasset index 98a9441..ca32959 100644 --- a/Game/GigLine/Content/Hollywood/Site/Terrain_DEM.uasset +++ b/Game/GigLine/Content/Hollywood/Site/Terrain_DEM.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:60e5397f227314e5d59fd3783e9c31713db9ebcbdc29a34aa44cddb305d76ff9 +oid sha256:1d7eac1b72eb0165f70af81739f992156409a0be1d5f0423f9e66c1d0f2ed381 size 357901 diff --git a/Game/GigLine/Content/Hollywood/Textures/T_Asphalt_BC.uasset b/Game/GigLine/Content/Hollywood/Textures/T_Asphalt_BC.uasset index eba8aec..552ac30 100644 --- a/Game/GigLine/Content/Hollywood/Textures/T_Asphalt_BC.uasset +++ b/Game/GigLine/Content/Hollywood/Textures/T_Asphalt_BC.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c5d7a3acd47b38355b6903b962d6b938ff1f5ddc602923f8e944c29a4674dee2 +oid sha256:a071c19c111adaebfc466dd12bb94cb79510846a670720bd8e3df7b12b8ca051 size 70879 diff --git a/Game/GigLine/Content/Hollywood/Textures/T_Asphalt_R.uasset b/Game/GigLine/Content/Hollywood/Textures/T_Asphalt_R.uasset index 3bd6c08..f2c4f7a 100644 --- a/Game/GigLine/Content/Hollywood/Textures/T_Asphalt_R.uasset +++ b/Game/GigLine/Content/Hollywood/Textures/T_Asphalt_R.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2454b2c9f7d9950d68af0402b8553acc3aa64aab1faee95fe71fe2b2efe4710e +oid sha256:53353dae2b3d37e609a7c79ce8c7c0ee1239386da5aa0ac16b5e4c1b177ad616 size 29011 diff --git a/Game/GigLine/Content/Hollywood/Textures/T_Concrete_BC.uasset b/Game/GigLine/Content/Hollywood/Textures/T_Concrete_BC.uasset index d463d4e..7a4d7d3 100644 --- a/Game/GigLine/Content/Hollywood/Textures/T_Concrete_BC.uasset +++ b/Game/GigLine/Content/Hollywood/Textures/T_Concrete_BC.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:782166930730273c3bc82ac7be18f084436d65da79bcff316a4f171e77e6ef93 +oid sha256:65a2605304ecc6c11c8a7039411bb02d315e6dadbac8b8c76a4fe48c102b31a1 size 58568 diff --git a/Game/GigLine/Content/Hollywood/Textures/T_Concrete_R.uasset b/Game/GigLine/Content/Hollywood/Textures/T_Concrete_R.uasset index 27ff573..80e6b8e 100644 --- a/Game/GigLine/Content/Hollywood/Textures/T_Concrete_R.uasset +++ b/Game/GigLine/Content/Hollywood/Textures/T_Concrete_R.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:805d8f4ad82682c0d2409cf46e8a62a65438a38073b4a307ff498b3de912a696 +oid sha256:41d659ccf84e1d3a7bfae39164958cbff7540660ae7066aafd061299e0bd05a0 size 17517 diff --git a/Game/GigLine/Content/Hollywood/Textures/T_StoneAshlar_BC.uasset b/Game/GigLine/Content/Hollywood/Textures/T_StoneAshlar_BC.uasset index ebb8dce..0eb1f34 100644 --- a/Game/GigLine/Content/Hollywood/Textures/T_StoneAshlar_BC.uasset +++ b/Game/GigLine/Content/Hollywood/Textures/T_StoneAshlar_BC.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2a0d33fee2e6475e7c0392c838a9d7b132c6c95db66f44f39247f1e6ea3ce456 +oid sha256:2c021ab82a3e28c055cc67b948646a168c60799388d6c4e8899fa844a9ae5fa9 size 40610 diff --git a/Game/GigLine/Content/Hollywood/Textures/T_StoneAshlar_R.uasset b/Game/GigLine/Content/Hollywood/Textures/T_StoneAshlar_R.uasset index c55cf87..253e4e0 100644 --- a/Game/GigLine/Content/Hollywood/Textures/T_StoneAshlar_R.uasset +++ b/Game/GigLine/Content/Hollywood/Textures/T_StoneAshlar_R.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c3ba7d4166902628d5ca37b7d6f164d8e4bf8a58990777a49fe3871640645c6c +oid sha256:1ae2847b7459749bf312fe1ca4876660ea14eaa8abfdf35f531948c96fb6733a size 18770 diff --git a/Game/GigLine/Content/Hollywood/Textures/T_Stucco_BC.uasset b/Game/GigLine/Content/Hollywood/Textures/T_Stucco_BC.uasset index 71ce6ce..b807bb7 100644 --- a/Game/GigLine/Content/Hollywood/Textures/T_Stucco_BC.uasset +++ b/Game/GigLine/Content/Hollywood/Textures/T_Stucco_BC.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f435587872a1f21006d6cbc466b01728110b8574ed8384287f414bf332b62cd6 +oid sha256:d08632fa729287eec03db544758715677ed22dbb86ae31129d8f00579b895bc1 size 62746 diff --git a/Game/GigLine/Content/Hollywood/Textures/T_Stucco_R.uasset b/Game/GigLine/Content/Hollywood/Textures/T_Stucco_R.uasset index 7711f4e..d8db282 100644 --- a/Game/GigLine/Content/Hollywood/Textures/T_Stucco_R.uasset +++ b/Game/GigLine/Content/Hollywood/Textures/T_Stucco_R.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:92a72806044679f1ddccf944775d8c2c1a131006030c17480788c70404734d13 +oid sha256:543dc4b621d0bb3b5067d33aa503ddb00498465cceec1fa0c0082ee6c9ec8b92 size 17541 diff --git a/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_BladeSign.uasset b/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_BladeSign.uasset index d557461..474cbdb 100644 --- a/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_BladeSign.uasset +++ b/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_BladeSign.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5152da3143f8b6b00f3e595d5adf07f65b260a2f32032140450a34538767f14e +oid sha256:5ab8c2326cb8d12c02a0d74896994dfd3d19974cb59da6487e41484399d5394d size 72330 diff --git a/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_BladeSignBracket.uasset b/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_BladeSignBracket.uasset index d18ceec..44a4f0b 100644 --- a/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_BladeSignBracket.uasset +++ b/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_BladeSignBracket.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b3a7c47afac32e8601e9ac4649c2e16663dfda8d409241527bd1d2c7bbd7c32e +oid sha256:43288f8565f631cfa95e372aa0914ad87e3e3b84bc03384882b778f53308f1a8 size 72466 diff --git a/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_BladeSignFrame.uasset b/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_BladeSignFrame.uasset index e0fdde9..ca163ef 100644 --- a/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_BladeSignFrame.uasset +++ b/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_BladeSignFrame.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f135922b7e89057917176a516fd283f1b739e9c6960892b8838daabd67eecfe0 +oid sha256:2f2de2082fd77b5e67d4f5f3b17c488b1b66dcaf4de7817862044f3b7e128370 size 72406 diff --git a/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_MarqueeCanopy.uasset b/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_MarqueeCanopy.uasset index b09cfb1..f56ea37 100644 --- a/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_MarqueeCanopy.uasset +++ b/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_MarqueeCanopy.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e3aaf3835733ebdaed780d33e8ee6c5ef2047e7f53de03c2984aafcde75830aa +oid sha256:35245987ecb3264697558b7a0711326c2e7f7eb8376ebd047600c9091a5f99c3 size 72370 diff --git a/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_MarqueeFascia.uasset b/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_MarqueeFascia.uasset index bbf4643..ae74f6f 100644 --- a/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_MarqueeFascia.uasset +++ b/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_MarqueeFascia.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6e42c24ba5e098c001a4b7ef3a79ab7ca4077a6c29647a7f85037e8a7e97a07a +oid sha256:25fd1abced705fc871b794b7709c7b0cd183b6e18c014f9463902af9e3105927 size 72438 diff --git a/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_MarqueeSoffit.uasset b/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_MarqueeSoffit.uasset index f352bf4..e352273 100644 --- a/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_MarqueeSoffit.uasset +++ b/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_MarqueeSoffit.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ffdf61d494359fea1c003dda276fc8c25b943bca7b9dd209c41381705a1ca13f +oid sha256:5cd83749385ed136b18544597898dd364028126c1f5cb098580f0adf40086a66 size 72413 diff --git a/Game/GigLine/Content/Test/ReviewMap.umap b/Game/GigLine/Content/Test/ReviewMap.umap index 22da558..6edf4aa 100644 --- a/Game/GigLine/Content/Test/ReviewMap.umap +++ b/Game/GigLine/Content/Test/ReviewMap.umap @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:24297b54b7f130738e1b29acf2c806522a191d185fce1164e52da1d744d81bdd +oid sha256:53c99032f45546d5b87630d2f916ed038b632b068455aced623e4fae1f57ed99 size 28811 diff --git a/MEMORY.md b/MEMORY.md index de67cf7..9396193 100644 --- a/MEMORY.md +++ b/MEMORY.md @@ -523,3 +523,11 @@ Scope: facts and traps that cost time to establish. Planned work lives in [TODO. - Precedent applied again: tag when the stated scope is done, carry blocked scope into the next patch rather than letting a release wait indefinitely on missing reference photography. + +## 2026-11-09 — Retail frontage and two pipeline traps + +- **`Tools/render_screenshots.sh` called `./Engine/...` for the capture step** while every commandlet above went through `run_cmdlet`'s `cd "$ENGINE"`. With `set -e` the script died at exit 127 *after* rebuilding the maps, so the PNGs silently stayed a day old and `--verify` never ran. Fixed to `"$ENGINE/Engine/Binaries/..."`. Symptom to remember: maps rebuild, screenshots do not move. +- **The generic façade kit is applied to every actor labelled `Frontage_*` or `North_*`**, so staging a hand-modelled façade under those labels gets the kit pasted over it — two contradicting façade languages on one wall. `ue_apply_facade_kit.py` now skips `MODELLED` labels, and retail trim stages as `RetailTrim_*`. +- **A Blender builder cannot be imported by a unit test** (`import bpy` at module scope). Pure layout arithmetic lives in `Tools/_common.py`; `Tools/tests/test_retail_frontage.py` tests it there, and the builder delegates. Same trick `fbx_export_preset.py` uses for its preset dicts. +- **Joining 85 parts into one mesh per building** before export cut the Unreal import from 85 assets to 2, and the staging step to two spawns. Record per-part dimensions *before* the join: after it only the joined bounds exist. + diff --git a/Screenshots/README.md b/Screenshots/README.md index f22ad24..093d18d 100644 --- a/Screenshots/README.md +++ b/Screenshots/README.md @@ -22,6 +22,7 @@ Each shot has an **expectation** in [`Tools/visual_targets.json`](../Tools/visua | 2 | `demo/review-demo-street-level.png` | eye height, north side | Street level: the hero colonnade with the adjacent frontage buildings either side, shopfronts at pavement level | ☑ 2026-11-09 | ☑ 2026-11-09 | | 3 | `demo/review-demo-crossing.png` | along the crosswalk | The designated mid-block crossing (s=130 m, UE X −14956): zebra bars on the asphalt, south frontage and colonnade behind | ☑ 2026-11-09 | ☑ 2026-11-09 | | 4 | `demo/review-demo-north-buildings.png` | across the Boulevard | The two north-side buildings (TCL Chinese Theatre, Madame Tussaud's) from the south side, full height in frame | ☑ 2026-11-09 | ☑ 2026-11-09 | +| 5 | `demo/review-demo-retail-frontage.png` | north sidewalk, level horizon | The retail run beside the hero: 6800 Lee Drug's bronze cornice, mural row and parapet next to 6806–6820's burgundy fascia, pilasters and window storey | ☑ 2026-11-09 | ☐ pending | Approval is per shot, in the table above (owner review of the `0.1.4` set, recorded in [`Docs/reviews/0.1.4-review.md`](../Docs/reviews/0.1.4-review.md)). Add a row when a shot is added; remove the file in the same change when a shot is retired. @@ -49,3 +50,20 @@ Note the comparison is only meaningful when the shot and the reference frame the - Banners sit on the column line rather than flush to the wall (they hang on the columns in the photographs, so this is acceptable). - Between kerb and building line the walkable surface is the terrain mesh, not a modelled pavement. - The El Capitan Theatre has no marquee or blade sign yet — the feature that makes it read as itself. + +## 0.1.6 retail frontage — what to look at + +Shot 5 is the review shot for this pass. Read it against +`Art/reference/retail-neighbours/01-lee-drug-and-neighbor.jpg` (Gb321, CC BY-SA 4.0). + +Known gaps in this first pass, recorded rather than hidden: + +- **The parapet reads as a blank white band.** It is modelled as one 2.18 m wall with four + 0.10 m reveal strips, and at review distance the strips disappear into the wash. +- **The mural row and lettering band barely read.** They are shallow plates (0.06–0.08 m) on + the same plane as the wall; they need either depth or a decal before they read as the + photographs' black-framed panels. +- **The corner tower is a plain cylinder with two cap rings** — the stepped Deco profile in the + photograph is richer than that. +- **The camera crops the east end** of Lee Drug at 68° from the north sidewalk. +- **6822 Budget is untouched** and still a bare blockout volume: no photograph of it exists. diff --git a/Screenshots/demo/review-demo-crossing.png b/Screenshots/demo/review-demo-crossing.png index b49e26e..61b729a 100644 --- a/Screenshots/demo/review-demo-crossing.png +++ b/Screenshots/demo/review-demo-crossing.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c7729a7ef0b10c5827f3c5b4167e12ba03ca6aa81a8a1da0c55f9fb122897694 -size 2992299 +oid sha256:671fa6bdd2f90291619dde25e019b9ed2901b9195541e981f815ac7a0d12d0b6 +size 3090405 diff --git a/Screenshots/demo/review-demo-north-buildings.png b/Screenshots/demo/review-demo-north-buildings.png index c655726..6b60f6f 100644 --- a/Screenshots/demo/review-demo-north-buildings.png +++ b/Screenshots/demo/review-demo-north-buildings.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a854cc82d6a1ad84173664076a076f649c8dfbf38bb7d887f7d6444a7dc4e57c -size 2417601 +oid sha256:63cfbd2cf6b1cceabfa712136e06b2009700f20d2e34664baa6ddc255e95a380 +size 2618666 diff --git a/Screenshots/demo/review-demo-retail-frontage.png b/Screenshots/demo/review-demo-retail-frontage.png new file mode 100644 index 0000000..0899709 --- /dev/null +++ b/Screenshots/demo/review-demo-retail-frontage.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:45d882e702e3e868e2870e34b78e3fe89be0a50c3d78a13eb09c74bf60648206 +size 2048484 diff --git a/Screenshots/demo/review-demo-spawn-view.png b/Screenshots/demo/review-demo-spawn-view.png index f868673..6f7b0dd 100644 --- a/Screenshots/demo/review-demo-spawn-view.png +++ b/Screenshots/demo/review-demo-spawn-view.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e06925a4ca759e762c3ad01375cc098e22fdab065878a85269a63d62b9ba7256 -size 2505879 +oid sha256:2015b86cb791f8e038004cd9d7510839475f3464518c121016eedf04a1850dad +size 2955383 diff --git a/Screenshots/demo/review-demo-street-level.png b/Screenshots/demo/review-demo-street-level.png index 21ad29f..2bbfae9 100644 --- a/Screenshots/demo/review-demo-street-level.png +++ b/Screenshots/demo/review-demo-street-level.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e0412f034f6ac55928521c14278043f5626ce32ecaaca7e178ec3efd011efc22 -size 2705233 +oid sha256:5b20e4c0d58d9314a0d9577a5a86329e3d3a288f3ba876970c9a786ac82546a5 +size 2873893 diff --git a/TODO.md b/TODO.md index 12e367b..d1a83e0 100644 --- a/TODO.md +++ b/TODO.md @@ -15,7 +15,10 @@ Suggested blender skills: **references** (reference-image-match), **archviz**, * ### Patch tasks - active - session-5598ce7e-27e3-4c64-bb49-c04a4a31ee58 (branch `facade-retail-0.1.6`) -- [A] **Model 6822 Budget, 6806–6820 and 6800 Lee Drug from their own references.** `Art/reference/retail-neighbours/` holds 6800 and its neighbour (Gb321, CC BY-SA 4.0); Commons has nothing usable for 6822 or 6806–6820, so those two need photography before they can be modelled honestly. Do not substitute the El Capitan Theatre's 18-frame set — it would misattribute the façades. +- [A] **Model 6800 Lee Drug and 6806–6820 from their own reference.** First pass 2026-11-09 on branch `facade-retail-0.1.6`: `Tools/retail_frontage_build.py` builds both façades from the one photograph (`Art/reference/retail-neighbours/`, Gb321 CC BY-SA 4.0) with the analysis in `Art/blender/retail/ref-analysis.md`; + `Tools/ue_import_retail_detail.py` imports them and the demo builder stages them as `RetailTrim_*`. The generic façade kit is now skipped on these two, so their walls carry one façade language instead of two. + **Open on this item:** the parapet reads as a blank band, the mural row and lettering band do not resolve at review distance, the corner tower is a plain cylinder, and the review camera crops the east end — all listed in `Screenshots/README.md`. +- [D] **Model 6822 Budget.** Deferred: no photograph exists for it (Commons has nothing usable) and the single-storey 6.0 × 5.5 m volume cannot be read from the neighbour shot. Needs photography before it can be modelled honestly; do not substitute the El Capitan Theatre's set or the 6806–6820 shot. - [ ] Review every façade change with `Tools/render_screenshots.sh --verify` before tagging. - [ ] Tag `v0.1.6` and write `CHANGELOG.md` entry; then remove this section. diff --git a/Tools/README.md b/Tools/README.md index 0a54062..83018ef 100644 --- a/Tools/README.md +++ b/Tools/README.md @@ -17,7 +17,10 @@ Geographic tools live in [`Geo/tools/`](../Geo/README.md) and the Blender-side b | --- | --- | | `check-lfs.sh` | Fails if the `lfs` filter is missing or an LFS-tracked file was committed as a plain blob | | `facade_kit_build.py` | Builds the reusable façade **module kit** at the measured 4.96 m bay: pilaster, sill, lintel, window bay (surround + glazing), shopfront bay (piers, glass, fascia), door bay (jambs, door, threshold), cornice and parapet + coping. Exports each piece with the shared preset plus a JSON part report (dims + evidence per piece). | +| `ue_import_retail_detail.py` | Imports the two retail trim meshes into `/Game/Hollywood/Frontage` with complex-as-simple collision — the trim decorates a solid the player already collides with, so it must not add snag points. Staged by the demo builder as `RetailTrim_*`. | | `ue_import_facade_kit.py` | Imports the kit into `/Game/Hollywood/Kit/*` as static meshes with complex-as-simple collision; writes `/tmp/gigline/kit-import.txt`. | +| `retail_frontage_build.py` | Retail frontage trim for **6800 Lee Drug** and **6806–6820** (0.1.6): bronze cornice, mural row, lettering band, stepped Deco parapet and rounded corner tower on Lee Drug; burgundy fascia, pilasters, white-framed windows and banded parapet on 6806–6820. Built in world coordinates from the blockout bounds, one joined mesh per building, JSON part report with the evidence behind every piece. `6822 Budget` is **not** built — no photograph exists. | +| `retail_frontage_build.py` | Retail frontage trim for **6800 Lee Drug** and **6806–6820** (0.1.6): bronze cornice, mural row, lettering band, stepped Deco parapet and rounded corner tower on Lee Drug; burgundy fascia, pilasters, white-framed windows and banded parapet on 6806–6820. Built in world coordinates from the blockout bounds, one joined mesh per building, JSON part report with the evidence behind every piece. `6822 Budget` is **not** built — no photograph exists. | | `theatre_trim_build.py` | El Capitan Theatre trim: projecting marquee canopy, illuminated fascia, recessed soffit, vertical blade sign with frame and bracket. Built **in world coordinates** (span and pavement height baked in) with a JSON part report, so staging is a single spawn at the origin. | | `ue_stage_theatre_trim.py` | Imports the trim to `/Game/Hollywood/Theatre` and stages one actor per piece in the DemoMap with site materials; clears a previous run first. | | `ue_apply_facade_kit.py` | Lays the kit over a building's street face from its own bounding box: bay count = round(width / 4.96), storeys from the height, shopfronts on the ground floor, windows above, pilasters on bay boundaries, cornice and parapet at the top. Clears a previous application first; unique labels per building. | diff --git a/Tools/_common.py b/Tools/_common.py new file mode 100644 index 0000000..d1e4ac5 --- /dev/null +++ b/Tools/_common.py @@ -0,0 +1,27 @@ +"""Shared helpers that must stay importable outside Blender and Unreal. + +Blender-side builders import `bpy` at module scope, so nothing in them can be unit +tested. Pure layout arithmetic lives here instead: the builders import it, and +`Tools/tests/` imports it without a 3D application. + +Standard library only. +""" + +from __future__ import annotations + + +def bay_centres(x0, x1, margin=0.9, bay=2.2): + """Centres of equal bays across a frontage, inset by `margin` at each end. + + Used by the façade kit and the retail frontage so both use one rhythm. The count + is the span divided by the bay module and rounded, so a 33 m frontage at a 2.2 m + module gets 14 bays rather than one bay per 2.2 m of wall with a stub at the end. + + Returns [] when the margins consume the whole frontage. + """ + span = (x1 - x0) - 2.0 * margin + if span <= 0: + return [] + count = max(1, int(round(span / bay))) + step = span / count + return [x0 + margin + step * (i + 0.5) for i in range(count)] diff --git a/Tools/render_screenshots.sh b/Tools/render_screenshots.sh index 1d34493..cec9181 100755 --- a/Tools/render_screenshots.sh +++ b/Tools/render_screenshots.sh @@ -39,7 +39,10 @@ run_cmdlet ue_build_review_map.py "5/6 stage the demo shot cameras" tail -3 /tmp/ue-review-map-result.txt 2>/dev/null || true echo "== 6/6 capture the demo map ==" -./Engine/Binaries/Linux/UnrealEditor-Cmd "$PROJ" /Game/Hollywood/DemoMap \ +# The engine path is absolute: this step runs from the repo, not from $ENGINE, and a +# bare ./Engine/... failed with "No such file or directory" while every commandlet +# above succeeded through run_cmdlet's cd. +"$ENGINE/Engine/Binaries/Linux/UnrealEditor-Cmd" "$PROJ" /Game/Hollywood/DemoMap \ -game -windowed -ResX=1920 -ResY=1080 -nopause -nosplash -stdout echo "== collect the demo screenshots ==" diff --git a/Tools/retail_frontage_build.py b/Tools/retail_frontage_build.py new file mode 100644 index 0000000..64a740d --- /dev/null +++ b/Tools/retail_frontage_build.py @@ -0,0 +1,329 @@ +#!/usr/bin/env python3 +"""Retail frontage trim for 6800 Lee Drug and 6806–6820 (0.1.6). + +Both buildings are bare OSM extrusions with a flat stucco material; what makes them +read as *the* retail run beside the hero is the façade layer: the bronze cornice and +stepped Deco parapet on Lee Drug, and the pilaster-and-fascia rhythm on 6806–6820. + +The trim is built **in world coordinates** in the shared frame (metres, X east, +Y north, Z from the project datum), so the export carries its position and the +Unreal staging step is a single spawn at the origin — the same convention as +`Tools/theatre_trim_build.py` and `Tools/export_block_frontage.py`. + + blender -b --factory-startup --python Tools/retail_frontage_build.py -- \ + --out /tmp/gigline/retail --report /tmp/gigline/retail-report.json + +Bounds are **measured**, not assumed: they are the blockout objects' world bounds +(`Lee Drug Building`, `element.019`), which sit at Z 0 with the volume top at 12.10 m. +Vertical proportions come from the single reference photograph and are recorded with +the assumption in `Art/blender/retail/ref-analysis.md`. + +6822 Budget is deliberately **not** built: there is no photograph of it, and the TODO +item says so. Guessing its façade would be the misattribution the item warns against. +""" + +from __future__ import annotations + +import argparse +import json +import math +import os +import sys + +import bpy + +sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) +import _common # noqa: E402 +import fbx_export_preset as fbx_preset # noqa: E402 + +# --- measured bounds, from the blockout (world metres) ------------------------ +# Lee Drug 6800, OSM way 424024149. Front face is the north edge (max Y). +LD_X0, LD_X1 = -33.20, -14.37 +LD_FACE_Y = -14.63 +LD_H = 12.10 + +# 6806-6820, OSM way 424024150. +B6_X0, B6_X1 = -66.08, -33.07 +B6_FACE_Y = -12.52 +B6_H = 12.10 + +# --- proportions, read off the reference photograph --------------------------- +# Fractions of the 12.10 m height; see Art/blender/retail/ref-analysis.md for how +# they were read and why they are assumptions at ±0.03 H. +LD_SHOP_TOP = 0.36 * LD_H # 4.36 m: shopfront glazing / cornice soffit +LD_CORNICE_TOP = 0.43 * LD_H # 5.20 m: top of the bronze band +LD_MURAL_Z = (0.49 * LD_H, 0.61 * LD_H) +LD_LETTER_Z = (0.65 * LD_H, 0.76 * LD_H) +LD_PARAPET_Z = 0.82 * LD_H # 9.92 m: bottom of the stepped parapet + +B6_SHOP_TOP = 0.32 * B6_H # 3.87 m +B6_FASCIA_TOP = 0.38 * B6_H # 4.60 m +B6_WINDOW_Z = (0.45 * B6_H, 0.60 * B6_H) +B6_PARAPET_Z = 0.62 * B6_H # 7.50 m + +BAY = 2.20 # mural / bay rhythm on Lee Drug, assumed +PROJECT = 0.55 # bronze cornice projection, assumed +TOWER_R = 2.10 # Lee Drug corner tower radius, assumed + +PARTS: list[dict] = [] + + +def make_material(name, rgb, rough=0.6, metallic=0.0): + """Principled material with an explicit colour; the export preset carries it as a slot.""" + mat = bpy.data.materials.new(name) + mat.use_nodes = True + bsdf = mat.node_tree.nodes.get("Principled BSDF") + bsdf.inputs["Base Color"].default_value = (rgb[0], rgb[1], rgb[2], 1.0) + bsdf.inputs["Roughness"].default_value = rough + bsdf.inputs["Metallic"].default_value = metallic + return mat + + +def clear_scene(): + bpy.ops.object.select_all(action="SELECT") + bpy.ops.object.delete(use_global=False) + for mesh in list(bpy.data.meshes): + if mesh.users == 0: + bpy.data.meshes.remove(mesh) + + +def cube(name, x, y, z, dx, dy, dz, material): + bpy.ops.mesh.primitive_cube_add(size=1.0, location=(x, y, z)) + obj = bpy.context.active_object + obj.name = name + obj.scale = (dx, dy, dz) + bpy.ops.object.transform_apply(location=False, rotation=False, scale=True) + obj.data.materials.append(material) + return obj + + +def cylinder(name, x, y, z, radius, height, material, vertices=28): + bpy.ops.mesh.primitive_cylinder_add(vertices=vertices, radius=radius, depth=height, + location=(x, y, z)) + obj = bpy.context.active_object + obj.name = name + bpy.ops.object.transform_apply(location=False, rotation=False, scale=True) + obj.data.materials.append(material) + return obj + + +def bay_centres(x0, x1, margin=0.9, bay=BAY): + """Bay centres; the arithmetic lives in `_common` so it is testable without Blender.""" + return _common.bay_centres(x0, x1, margin=margin, bay=bay) + + +def note(obj, evidence): + PARTS.append({ + "object": obj.name, + "asset": "SM_" + obj.name, + "dims_m": [round(d, 3) for d in obj.dimensions], + "location_m": [round(c, 3) for c in obj.location], + "evidence": evidence, + }) + print(f"[retail] {obj.name:26} {obj.dimensions.x:6.2f} x {obj.dimensions.y:5.2f} " + f"x {obj.dimensions.z:5.2f} m ({evidence})") + + +def build_lee_drug(mats): + """6800 Lee Drug: bronze cornice, mural row, lettering band, stepped Deco parapet, + rounded corner tower.""" + stucco, bronze, mural, glass, white = (mats["stucco"], mats["bronze"], mats["mural"], + mats["glass"], mats["white"]) + parts = [] + cx = (LD_X0 + LD_X1) / 2.0 + width = LD_X1 - LD_X0 + + # Bronze cornice: the strongest horizontal line on the building. + cornice = cube("LD_Cornice", cx, LD_FACE_Y + PROJECT / 2.0, + (LD_SHOP_TOP + LD_CORNICE_TOP) / 2.0, + width + 0.4, PROJECT, LD_CORNICE_TOP - LD_SHOP_TOP, bronze) + parts.append((cornice, "photographs: projecting bronze cornice over the shopfront; " + f"{PROJECT:.2f} m projection assumed")) + + # Shopfront glazing, recessed behind the face, one panel per bay. + for i, bx in enumerate(bay_centres(LD_X0, LD_X1, margin=1.2), start=1): + panel = cube(f"LD_ShopGlass_{i}", bx, LD_FACE_Y + 0.12, LD_SHOP_TOP / 2.0, + BAY - 0.30, 0.10, LD_SHOP_TOP - 0.55, glass) + parts.append((panel, "photographs: full-height shopfront glazing; bay width and " + "the 0.55 m kickplate are assumed (a bus hides this zone)")) + mullion = cube(f"LD_Mullion_{i}", bx - (BAY - 0.30) / 2.0, LD_FACE_Y - 0.02, + LD_SHOP_TOP / 2.0, 0.10, 0.16, LD_SHOP_TOP - 0.55, bronze) + parts.append((mullion, "assumption: slim mullion at each bay boundary")) + + # Celebrity-portrait panels, one per bay, in the band above the cornice. + z0, z1 = LD_MURAL_Z + for i, bx in enumerate(bay_centres(LD_X0, LD_X1, margin=1.2), start=1): + panel = cube(f"LD_Mural_{i}", bx, LD_FACE_Y - 0.04, (z0 + z1) / 2.0, + BAY - 0.75, 0.08, z1 - z0, mural) + parts.append((panel, "photographs: row of black-framed portrait panels; count and " + "size assumed from the visible row")) + + # Lettering band: a recessed plate, not text. Reproducing the lettering needs a + # decal, which is a materials-pass job. + lz0, lz1 = LD_LETTER_Z + letter = cube("LD_LetterBand", cx, LD_FACE_Y - 0.03, (lz0 + lz1) / 2.0, + width - 3.0, 0.06, lz1 - lz0, mural) + parts.append((letter, "photographs: large dark lettering across the upper wall; " + "modelled as a recessed plate, the text itself is a decal job")) + + # Stepped Deco parapet: wall band plus four horizontal reveals. + para = cube("LD_Parapet", cx, LD_FACE_Y + 0.10, (LD_PARAPET_Z + LD_H) / 2.0, + width + 0.2, 0.30, LD_H - LD_PARAPET_Z, stucco) + parts.append((para, "photographs: parapet steps above the frontage wall; " + "thickness assumed")) + for i in range(4): + z = LD_PARAPET_Z + (LD_H - LD_PARAPET_Z) * (i + 1) / 5.0 + groove = cube(f"LD_ParapetReveal_{i + 1}", cx, LD_FACE_Y - 0.03, z, + width + 0.2, 0.07, 0.10, mural) + parts.append((groove, "photographs: four horizontal reveal lines in the parapet; " + "count read off the frame")) + + # Rounded corner tower at the east end, stepped twice at the top. The centre + # sits INSIDE the footprint so the tower projects 0.35 m from the face instead of + # bulging 4 m into the pavement, which the first run did. + tower_y = LD_FACE_Y - TOWER_R + 0.35 + tower = cylinder("LD_CornerTower", LD_X1 - TOWER_R, tower_y, + (LD_H - 0.9) / 2.0, TOWER_R, LD_H - 0.9, stucco) + parts.append((tower, "photographs: rounded Deco corner tower rising above the " + f"frontage; {TOWER_R:.2f} m radius assumed")) + # Cap rings stack exactly to the measured 12.10 m top: 11.20 -> 11.75 -> 12.10. + cap_z = LD_H - 0.9 + for i, (dh, radius) in enumerate(((0.55, TOWER_R - 0.35), (0.35, TOWER_R - 0.70)), start=1): + cap = cylinder(f"LD_TowerCap_{i}", LD_X1 - TOWER_R, tower_y, + cap_z + dh / 2.0, radius, dh, white) + parts.append((cap, "photographs: two stepped cap rings on the tower")) + cap_z += dh + return parts + + +def build_6806(mats): + """6806–6820: burgundy fascia, brown pilasters, white-framed windows, banded parapet.""" + stucco, bronze, glass, white, burgundy = (mats["stucco"], mats["bronze"], mats["glass"], + mats["white"], mats["burgundy"]) + parts = [] + cx = (B6_X0 + B6_X1) / 2.0 + width = B6_X1 - B6_X0 + + fascia = cube("B6_Fascia", cx, B6_FACE_Y - 0.02, + (B6_SHOP_TOP + B6_FASCIA_TOP) / 2.0, width, 0.22, + B6_FASCIA_TOP - B6_SHOP_TOP, burgundy) + parts.append((fascia, "photographs: dark fascia band over the shopfront; colour " + "sampled, height assumed")) + + centres = bay_centres(B6_X0, B6_X1, margin=1.0) + for i, bx in enumerate(centres, start=1): + panel = cube(f"B6_ShopGlass_{i}", bx, B6_FACE_Y + 0.12, B6_SHOP_TOP / 2.0, + BAY - 0.25, 0.10, B6_SHOP_TOP - 0.45, glass) + parts.append((panel, "photographs: framed shopfront glazing behind the fascia")) + # Brown pilaster on every second bay boundary, as the photo shows. + if i % 2 == 1: + pil = cube(f"B6_Pilaster_{i}", bx, B6_FACE_Y - 0.10, + (B6_FASCIA_TOP + B6_PARAPET_Z) / 2.0, 0.40, 0.22, + B6_PARAPET_Z - B6_FASCIA_TOP, bronze) + parts.append((pil, "photographs: brown pilaster strips dividing the frontage")) + + wz0, wz1 = B6_WINDOW_Z + for i, bx in enumerate(centres, start=1): + frame = cube(f"B6_WindowFrame_{i}", bx, B6_FACE_Y - 0.06, (wz0 + wz1) / 2.0, + 1.70, 0.14, wz1 - wz0, white) + parts.append((frame, "photographs: white-framed upper windows with security bars; " + "count and size assumed")) + pane = cube(f"B6_WindowGlass_{i}", bx, B6_FACE_Y + 0.02, (wz0 + wz1) / 2.0, + 1.46, 0.08, wz1 - wz0 - 0.24, glass) + parts.append((pane, "photographs: dark glazing inside each frame")) + + para = cube("B6_Parapet", cx, B6_FACE_Y + 0.08, (B6_PARAPET_Z + B6_H) / 2.0, + width + 0.2, 0.26, B6_H - B6_PARAPET_Z, stucco) + parts.append((para, "photographs: parapet band above the window storey; thickness assumed")) + for i in range(3): + z = B6_PARAPET_Z + (B6_H - B6_PARAPET_Z) * (i + 1) / 4.0 + groove = cube(f"B6_ParapetReveal_{i + 1}", cx, B6_FACE_Y - 0.03, z, + width + 0.2, 0.07, 0.09, bronze) + parts.append((groove, "photographs: three reveal lines in the parapet; count assumed")) + return parts + + +def join_parts(parts, name): + """Join one building's parts into a single mesh so Unreal imports one asset. + + The per-part dimensions and evidence are recorded before this runs, so joining + loses nothing from the report. Materials survive as separate slots. + """ + bpy.ops.object.select_all(action="DESELECT") + for obj, _text in parts: + obj.select_set(True) + bpy.context.view_layer.objects.active = parts[0][0] + bpy.ops.object.join() + joined = bpy.context.active_object + joined.name = name + bpy.ops.object.transform_apply(location=False, rotation=False, scale=True) + return joined + + +def export_objects(objects, out_dir): + count = 0 + for obj in objects: + bpy.ops.object.select_all(action="DESELECT") + obj.select_set(True) + bpy.context.view_layer.objects.active = obj + fbx_preset.export_static(os.path.join(out_dir, "SM_" + obj.name + ".fbx"), + selection=True) + count += 1 + return count + + +def main(argv=None) -> int: + argv = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else [] + ap = argparse.ArgumentParser(description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter) + ap.add_argument("--out", default="/tmp/gigline/retail") + ap.add_argument("--report", default=None) + args = ap.parse_args(argv) + os.makedirs(args.out, exist_ok=True) + + clear_scene() + mats = { + "stucco": make_material("M_Retail_Stucco", (0.86, 0.83, 0.76), rough=0.72), + "bronze": make_material("M_Retail_Bronze", (0.20, 0.11, 0.06), rough=0.45, metallic=0.35), + "mural": make_material("M_Retail_Mural", (0.035, 0.032, 0.030), rough=0.55), + "glass": make_material("M_Retail_Glass", (0.035, 0.045, 0.055), rough=0.15), + "white": make_material("M_Retail_White", (0.90, 0.88, 0.84), rough=0.60), + "burgundy": make_material("M_Retail_Burgundy", (0.20, 0.09, 0.09), rough=0.55), + } + + ld_parts = build_lee_drug(mats) + b6_parts = build_6806(mats) + for obj, text in ld_parts + b6_parts: + note(obj, text) + + # One mesh per building: 85 separate actors over the frontage would cost more + # draw calls than the trim is worth, and the staging step stays two spawns. + joined = [join_parts(ld_parts, "Retail_LeeDrug"), join_parts(b6_parts, "Retail_6806")] + for obj in joined: + print(f"[retail] joined {obj.name}: {len(obj.data.vertices)} verts, " + f"{len(obj.data.materials)} material slot(s), " + f"X {min(v.co.x for v in obj.data.vertices):.2f}.." + f"{max(v.co.x for v in obj.data.vertices):.2f}") + exported = export_objects(joined, args.out) + print(f"[retail] exported {exported} object(s) to {args.out}") + + if args.report: + with open(args.report, "w", encoding="utf-8") as handle: + json.dump({ + "scope": ["6800 Lee Drug (way 424024149)", "6806-6820 (way 424024150)"], + "deferred": ["6822 Budget (way 424024144): no photograph, not modelled"], + "bounds_m": { + "lee_drug": [LD_X0, LD_X1, LD_FACE_Y, LD_H], + "b6806": [B6_X0, B6_X1, B6_FACE_Y, B6_H], + }, + "reference": "Art/reference/retail-neighbours/01-lee-drug-and-neighbor.jpg " + "(Gb321, CC BY-SA 4.0)", + "analysis": "Art/blender/retail/ref-analysis.md", + "parts": PARTS, + }, handle, indent=2) + print(f"[retail] report -> {args.report}") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/Tools/tests/test_retail_frontage.py b/Tools/tests/test_retail_frontage.py new file mode 100644 index 0000000..412ec1b --- /dev/null +++ b/Tools/tests/test_retail_frontage.py @@ -0,0 +1,32 @@ +"""Tests for the pure layout helper in Tools/retail_frontage_build.py. + +The builder itself needs Blender; `bay_centres` does not, so the bay rhythm the +façade depends on is checkable without starting Blender or Unreal. +""" + +import unittest + +from Tools._common import bay_centres + + +class BayCentreTests(unittest.TestCase): + def test_centres_stay_inside_the_margins(self): + centres = bay_centres(-33.20, -14.37, margin=1.2) + self.assertGreaterEqual(min(centres), -33.20 + 1.2 - 1e-9) + self.assertLessEqual(max(centres), -14.37 - 1.2 + 1e-9) + + def test_bays_are_evenly_spaced(self): + centres = bay_centres(-66.08, -33.07, margin=1.0) + steps = {round(b - a, 6) for a, b in zip(centres, centres[1:])} + self.assertEqual(len(steps), 1, f"uneven bay spacing: {steps}") + + def test_bay_count_is_the_round_of_span_over_bay(self): + # 33.01 m frontage, 1.0 m margin each end -> 31.01 m -> 14 bays at 2.2 m. + self.assertEqual(len(bay_centres(-66.08, -33.07, margin=1.0)), 14) + + def test_degenerate_frontage_returns_nothing(self): + self.assertEqual(bay_centres(0.0, 1.0, margin=1.0), []) + + +if __name__ == "__main__": + unittest.main() diff --git a/Tools/ue_apply_facade_kit.py b/Tools/ue_apply_facade_kit.py index 42c5091..0cf9ac7 100644 --- a/Tools/ue_apply_facade_kit.py +++ b/Tools/ue_apply_facade_kit.py @@ -235,9 +235,17 @@ def main() -> None: removed += 1 log(f"cleared {removed} previous kit actors") + # The kit is the fallback for buildings that have nothing but a blockout. These + # two are modelled from their own photograph in 0.1.6 + # (Tools/retail_frontage_build.py); pasting the generic kit over them put a + # second, contradicting facade language on the same wall. + MODELLED = ("Frontage_SM_LeeDrug_6800", "Frontage_SM_Hollywood_6806") targets = [a for a in unreal.EditorLevelLibrary.get_all_level_actors() - if a.get_actor_label().startswith(("Frontage_", "North_"))] - log(f"frontage actors: {len(targets)}") + if a.get_actor_label().startswith(("Frontage_", "North_")) + and a.get_actor_label() not in MODELLED] + skipped = [a.get_actor_label() for a in unreal.EditorLevelLibrary.get_all_level_actors() + if a.get_actor_label() in MODELLED] + log(f"frontage actors: {len(targets)} (kit skipped on modelled facades: {skipped})") total = 0 for actor in targets: total += apply_to_actor(actor, kit, materials) diff --git a/Tools/ue_build_demo_map.py b/Tools/ue_build_demo_map.py index 4a57c66..b325ddc 100644 --- a/Tools/ue_build_demo_map.py +++ b/Tools/ue_build_demo_map.py @@ -597,6 +597,25 @@ def build(): staged_frontage += 1 log(f"staged {staged_frontage} frontage buildings") + # --- retail frontage trim (0.1.6) ------------------------------------- + # The two retail buildings beside the hero are modelled from their own + # photograph (Art/reference/retail-neighbours/); the trim is laid over the + # blockout volume, so it keeps the trim's own sampled materials rather than a + # look-dev override. 6822 Budget has no photograph and stays a bare volume. + for asset_name, label in (("SM_Retail_LeeDrug", "6800 Lee Drug trim"), + ("SM_Retail_6806", "6806-6820 trim")): + mesh = unreal.EditorAssetLibrary.load_asset(f"/Game/Hollywood/Frontage/{asset_name}") + if mesh is None: + log(f"MISSING trim {asset_name} — run Tools/ue_import_retail_detail.py") + continue + # RetailTrim_ rather than Frontage_ so the kit assembler leaves it alone. + actor = spawn(unreal.StaticMeshActor, unreal.Vector(0, 0, 0), f"RetailTrim_{asset_name}") + if actor: + comp = actor.static_mesh_component + comp.set_static_mesh(mesh) + comp.set_mobility(unreal.ComponentMobility.MOVABLE) + log(f"staged: {label}") + # --- player start: north sidewalk, facing the hero frontage ------------- # Signs were measured from the imported meshes rather than assumed: the FBX # preset flips north, so in Unreal the road spans Y -1382..+1047, the NORTH diff --git a/Tools/ue_build_review_map.py b/Tools/ue_build_review_map.py index cf570bc..375f0d8 100644 --- a/Tools/ue_build_review_map.py +++ b/Tools/ue_build_review_map.py @@ -300,6 +300,12 @@ try: # on the north sidewalk looking along the crosswalk itself, which is # the pedestrian's view and shows the zebra bars as bars. ("demo-crossing", unreal.Vector(-15250, -2500, 400), unreal.Vector(-14956, 400, 150)), + # 0.1.6 retail frontage: 6800 Lee Drug (X -3340..-1417, face Y +1467) + # and 6806-6820 (X -6618..-3297, face Y +1252). Stand on the north + # sidewalk at 2 m, look south with a level horizon so the parapets and + # the cornice line read as horizontals. 68 deg covers both frontages at + # this distance; the ends crop rather than the elevation leaning. + ("demo-retail-frontage", unreal.Vector(-4700, -2000, 200), unreal.Vector(-4700, 1400, 560), 68.0), # the two north-side background buildings (TCL, Tussaud's) seen from # the south across Hollywood Blvd. Probed world-space (2026-11-08): # TCL bbox X -22889..-18442, Y -9431..-1802; Tussaud's X -27071.. diff --git a/Tools/ue_import_retail_detail.py b/Tools/ue_import_retail_detail.py new file mode 100644 index 0000000..313646e --- /dev/null +++ b/Tools/ue_import_retail_detail.py @@ -0,0 +1,94 @@ +# Import the retail frontage trim (6800 Lee Drug, 6806–6820) into Unreal. +# +# blender -b --factory-startup --python Tools/retail_frontage_build.py -- \ +# --out /tmp/gigline/retail --report /tmp/gigline/retail-report.json +# /Engine/Binaries/Linux/UnrealEditor-Cmd -run=pythonscript \ +# -script=/Tools/ue_import_retail_detail.py -nullrhi -unattended -nopause -stdout +# +# Two meshes arrive, one per building, each already at its world position in the +# project frame (the FBX carries the offset), so staging spawns at the origin. +# Destination: /Game/Hollywood/Frontage/ — same folder as the block frontage +# so the demo builder stages them together. +# +# Result file: /tmp/gigline/retail-import.txt + +import glob +import os + +import unreal + +SRC = "/tmp/gigline/retail" +DEST = "/Game/Hollywood/Frontage" +RESULT = "/tmp/gigline/retail-import.txt" +lines = [] + + +def log(msg): + lines.append(str(msg)) + unreal.log(str(msg)) + + +def import_fbx(path, name): + task = unreal.AssetImportTask() + task.filename = path + task.destination_path = DEST + task.destination_name = name + task.automated = True + task.save = True + task.replace_existing = True + + ui = unreal.FbxImportUI() + ui.import_mesh = True + ui.import_materials = True + ui.import_textures = False + ui.import_as_skeletal = False + smd = ui.static_mesh_import_data + smd.import_uniform_scale = 1.0 + smd.combine_meshes = True + smd.convert_scene_unit = False + smd.force_front_x_axis = False + smd.normal_import_method = unreal.FBXNormalImportMethod.FBXNIM_IMPORT_NORMALS + task.options = ui + unreal.AssetToolsHelpers.get_asset_tools().import_asset_tasks([task]) + + mesh = unreal.EditorAssetLibrary.load_asset(f"{DEST}/{name}") + if mesh is None: + log(f"MISSING after import: {DEST}/{name}") + return None + + # Trim is decoration on a solid the player already collides with: no collision + # of its own, otherwise the cornice and mullions become snag points. + try: + body = mesh.get_editor_property("body_setup") + body.set_editor_property("collision_trace_flag", + unreal.CollisionTraceFlag.CTF_USE_COMPLEX_AS_SIMPLE) + mesh.set_editor_property("body_setup", body) + except Exception as exc: # noqa: BLE001 + log(f"{name}: collision flag not set ({exc!r})") + + box = mesh.get_bounding_box() + mn, mx = box.min, box.max + log(f"{name:22} X {mn.x:8.0f}..{mx.x:8.0f} Y {mn.y:7.0f}..{mx.y:7.0f} " + f"Z {mn.z:5.0f}..{mx.z:5.0f} slots {len(mesh.get_editor_property('static_materials'))}") + return mesh + + +def main(): + files = sorted(glob.glob(os.path.join(SRC, "*.fbx"))) + if not files: + log(f"no FBX in {SRC}; run Tools/retail_frontage_build.py first") + return + for path in files: + import_fbx(path, os.path.splitext(os.path.basename(path))[0]) + unreal.EditorLoadingAndSavingUtils.save_dirty_packages(True, True) + + +try: + main() +except Exception as exc: # noqa: BLE001 + import traceback + log(f"FAILED: {type(exc).__name__}: {exc}") + log(traceback.format_exc()) + +with open(RESULT, "w") as f: + f.write("\n".join(lines) + "\n") diff --git a/Tools/visual_targets.json b/Tools/visual_targets.json index c3e0665..3a9b9f2 100644 --- a/Tools/visual_targets.json +++ b/Tools/visual_targets.json @@ -48,6 +48,18 @@ "Art/reference/north-chinese/01-grauman-s-chinese-theatre-by-carol-highsmith.jpg" ], "expect": "The two north-side buildings (TCL Chinese Theatre, Madame Tussaud's) seen from across Hollywood Boulevard, full height in frame, daylight" + }, + { + "name": "demo-retail-frontage", + "shot": "Screenshots/demo/review-demo-retail-frontage.png", + "size": [ + 1920, + 1080 + ], + "references": [ + "Art/reference/retail-neighbours/01-lee-drug-and-neighbor.jpg" + ], + "expect": "The retail run beside the hero from across the street: 6800 Lee Drug's bronze cornice, mural row and stepped parapet next to 6806-6820's pilasters and window storey, daylight" } ] } \ No newline at end of file -- 2.47.3 From c53386fcf4a3629976a82d9c41774b06236173a3 Mon Sep 17 00:00:00 2001 From: Zwitschi Date: Mon, 9 Nov 2026 09:33:23 +0100 Subject: [PATCH 3/8] docs(review): embed every screenshot inline so the review happens in the file Each shot now has its own section with the image embedded, its view, expected content and both verdicts, plus a status table at the top that links to them. A path alone was not a review: the owner had to open five PNGs to judge a pass. Also recorded in AGENTS.md (a path is not a review; approval ticks both the section and the table row), the two retail assets and tools in the arc42 building block view and the combined architecture.md, and prettier-formatted the changed files. --- AGENTS.md | 4 +- Art/blender/retail/ref-analysis.md | 32 ++---- Docs/Architecture/05_building_block_view.md | 6 +- Docs/Architecture/architecture.md | 6 +- Screenshots/README.md | 106 ++++++++++++++------ TODO.md | 4 +- 6 files changed, 99 insertions(+), 59 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 676b7db..680e9da 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -210,8 +210,8 @@ Any change that affects the game's appearance — meshes, materials, lighting, l 1. Run `Tools/render_screenshots.sh` (rebuilds `Game/GigLine/Content/Test/ReviewMap.umap` from current content, runs the game on it, captures the fixed camera list, copies the PNGs into `Screenshots/`). 2. Optional pre-check with a vision model: `Tools/judge_screenshot.py --image --expect ""` (or `--shots` to run every shot in the README) flags likely-missing content before a human looks. It reads `OPENROUTER_API_KEY` from `.env` (ignored). Small helper only — it never replaces the human verdict. -3. Update `Screenshots/README.md`: one row per screenshot with what it shows and an approval state; describe any new shots or scene changes in the same change. +3. Update `Screenshots/README.md`: the image is **embedded inline** (`![alt](demo/.png)`) with its view, expected content, verification and approval state, plus one row in the status table at the top. The point is that the review happens in the file; a path alone is not a review. Describe any new shots or scene changes in the same change. 4. The PNGs **are committed** so reviewers see exactly what the build rendered (`.gitignore` does not exclude them). Keep them in sync with this README: drop retired shots in the same change. -5. Wait for the user's approval before treating a visual change as done; record approval by ticking the table in `Screenshots/README.md`. +5. Wait for the user's approval before treating a visual change as done; record approval by ticking both the shot's section and its row in the status table in `Screenshots/README.md`. New content that needs a different camera angle gets a new entry in the shot list in `Tools/ue_build_review_map.py`. diff --git a/Art/blender/retail/ref-analysis.md b/Art/blender/retail/ref-analysis.md index fb253a5..c55f811 100644 --- a/Art/blender/retail/ref-analysis.md +++ b/Art/blender/retail/ref-analysis.md @@ -1,11 +1,10 @@ # Reference analysis — retail frontage, 0.1.6 -Phase 0 of the `references` pack (reference-image-match). Written before any geometry, -because the pass that produced the hero façade skipped it and cost two rebuilds. +Phase 0 of the `references` pack (reference-image-match). Written before any geometry, because the pass that produced the hero façade skipped it and cost two rebuilds. ## Source -| | | +| | | | --- | --- | | Image | `Art/reference/retail-neighbours/01-lee-drug-and-neighbor.jpg` (1920×953) | | Author / licence | Gb321, own work, **CC BY-SA 4.0** — attribution required | @@ -13,19 +12,13 @@ because the pass that produced the hero façade skipped it and cost two rebuilds | Description | "Lee Drug and 6806 Hollywood Buildings in Hollywood" | | Coverage | Both target buildings in one frame, mid-morning sun from the south-east | -**One photograph is the whole evidence base for 6800 and 6806–6820.** It is a street-level -oblique, not an elevation: verticals converge, the ground floor of 6806–6820 is partly behind -a parked car, and the Lee Drug shopfront is behind a bus. Everything below that the photo does -not resolve is marked *assumed* and is carried into the part report. +**One photograph is the whole evidence base for 6800 and 6806–6820.** It is a street-level oblique, not an elevation: verticals converge, the ground floor of 6806–6820 is partly behind a parked car, and the Lee Drug shopfront is behind a bus. Everything below that the photo does not resolve is marked _assumed_ and is carried into the part report. -**6822 Budget has no photograph.** It is a 6.0 m × 5.5 m single-storey sliver west of -6806–6820, and the TODO item already records that Commons has nothing usable. It stays a -blockout extrusion and the item is deferred rather than guessed. +**6822 Budget has no photograph.** It is a 6.0 m × 5.5 m single-storey sliver west of 6806–6820, and the TODO item already records that Commons has nothing usable. It stays a blockout extrusion and the item is deferred rather than guessed. ## Measured (not from the photo) -From `Geo/raw/osm-api-map-2026-11-06.osm` and the blockout, in the shared frame -(metres, X east, Y north, Z from the project datum): +From `Geo/raw/osm-api-map-2026-11-06.osm` and the blockout, in the shared frame (metres, X east, Y north, Z from the project datum): | Building | OSM way | X | Front face Y | Height | Depth | | --- | --- | --- | --- | --- | --- | @@ -33,9 +26,7 @@ From `Geo/raw/osm-api-map-2026-11-06.osm` and the blockout, in the shared frame | 6806–6820 | 424024150 | −66.08 … −33.07 | −12.52 | 12.10 m | 30.8 m | | 6822 Budget | 424024144 | −78.54 … −72.52 | −12.92 | 5.50 m | 15.4 m | -Both target buildings are 12.10 m tall, which makes the *relative* proportions in the photo -directly usable: the parapet line, the cornice and the shopfront line can be read as fractions -of the frame height. +Both target buildings are 12.10 m tall, which makes the _relative_ proportions in the photo directly usable: the parapet line, the cornice and the shopfront line can be read as fractions of the frame height. ## 6800 Lee Drug — reading @@ -44,9 +35,9 @@ of the frame height. | Subject | Corner retail block at Hollywood × Highland; the street face and the corner return are both visible | | Silhouette | Long low box, broken by a **rounded corner tower** that rises above the frontage parapet; the parapet is **stepped**, not flat | | Storeys | Two zones, not storeys: a tall shopfront zone and a single tall display wall above it | -| Proportion (vertical) | Shopfront ≈ 0 → 0.36 H; bronze cornice ≈ 0.36 → 0.43 H; mural + lettering wall ≈ 0.43 → 0.82 H; stepped parapet ≈ 0.82 → 1.0 H (*assumed split; read off the frame, ±0.03 H*) | +| Proportion (vertical) | Shopfront ≈ 0 → 0.36 H; bronze cornice ≈ 0.36 → 0.43 H; mural + lettering wall ≈ 0.43 → 0.82 H; stepped parapet ≈ 0.82 → 1.0 H (_assumed split; read off the frame, ±0.03 H_) | | Proportion (horizontal) | Corner tower occupies ≈ 4 m of the east end; eight mural panels at roughly 2.2 m centres along the frontage | -| Colour | Cream stucco wall `#EDE6D8`, bronze/brown cornice `#6B4A2F`, near-black mural plates `#1C1A18`, dark glazing `#20262A` (*sampled from the frame*) | +| Colour | Cream stucco wall `#EDE6D8`, bronze/brown cornice `#6B4A2F`, near-black mural plates `#1C1A18`, dark glazing `#20262A` (_sampled from the frame_) | | Unique features | Stepped Deco parapet with 4 horizontal reveal lines; projecting bronze cornice; row of black celebrity-portrait panels; large dark "SOUVENIRS OF …" lettering on the upper wall; shopfront glazing with slim mullions | | Mood | 1930s Deco retail, freshly painted, bright midday | @@ -55,17 +46,14 @@ of the frame height. | Category | Observation | | --- | --- | | Silhouette | Flat-fronted two-storey block; parapet steps up in fins at the west end | -| Proportion (vertical) | Shopfront ≈ 0 → 0.32 H; burgundy fascia band ≈ 0.32 → 0.38 H; window storey ≈ 0.38 → 0.62 H; blank wall + parapet ≈ 0.62 → 1.0 H (*assumed*) | +| Proportion (vertical) | Shopfront ≈ 0 → 0.32 H; burgundy fascia band ≈ 0.32 → 0.38 H; window storey ≈ 0.38 → 0.62 H; blank wall + parapet ≈ 0.62 → 1.0 H (_assumed_) | | Horizontal | Brown pilaster strips divide the frontage into roughly 3 m bays; seven upper windows across 33 m | | Colour | Same cream stucco; brown pilasters `#6B4A2F`; **burgundy-green** fascia `#5B3A3A`; white window frames | | Unique features | Banded parapet with 3 reveal lines; white-framed upper windows with security bars; shopfront glazing behind a burgundy fascia | ## Camera match (for the review shot) -The photo is a street-level oblique from the **north** side looking south-east, subject filling -~80 % of the frame width. The demo review shot must reproduce that: camera at 1.7 m on the -north sidewalk, yaw toward the south frontage, 35–42° lens, both buildings in frame. A wide -block view will not compare usefully against this crop. +The photo is a street-level oblique from the **north** side looking south-east, subject filling ~80 % of the frame width. The demo review shot must reproduce that: camera at 1.7 m on the north sidewalk, yaw toward the south frontage, 35–42° lens, both buildings in frame. A wide block view will not compare usefully against this crop. ## Assumptions to carry into the model report diff --git a/Docs/Architecture/05_building_block_view.md b/Docs/Architecture/05_building_block_view.md index 0493a9a..f888ae7 100644 --- a/Docs/Architecture/05_building_block_view.md +++ b/Docs/Architecture/05_building_block_view.md @@ -47,6 +47,7 @@ Static meshes and materials in `/Game/Hollywood/Site/`: | `SM_HeroFacade` | El Capitan Entertainment Centre detailed façade | | `SM_ElCapitanTheatre`, `SM_Budget_6822`, `SM_Hollywood_6806`, `SM_Hollywood_6902`, `SM_Hollywood_6922`, `SM_LeeDrug_6800` | South block frontage (6 buildings) | | `SM_Madame_Tussauds`, `SM_TCL_Chinese_Theatre` | North-side buildings (within 50 m) | +| `SM_Retail_LeeDrug`, `SM_Retail_6806` | Retail trim over 6800 and 6806–6820, modelled from their own photograph (`Tools/retail_frontage_build.py`, staged as `RetailTrim_*`). `6822 Budget` stays a bare volume: no photograph exists. | ### Art Pipeline @@ -54,13 +55,14 @@ Python scripts in `Tools/` drive the content pipeline: | Script group | Purpose | | --- | --- | -| `export_*`, `hero_facade_build` | Blender headless export (FBX) | -| `ue_import_*`, `ue_hero_facade_import` | Unreal headless import + placement | +| `export_*`, `hero_facade_build`, `retail_frontage_build`, `theatre_trim_build`, `facade_kit_build` | Blender headless export (FBX); trim builders work in world coordinates | +| `ue_import_*`, `ue_hero_facade_import`, `ue_import_retail_detail` | Unreal headless import + placement | | `ue_build_demo_map`, `ue_build_review_map` | Map assembly (lighting, meshes, player start) | | `ue_create_input_assets` | Enhanced Input actions + mapping context | | `render_screenshots.sh` | Screenshot capture pipeline | | `judge_screenshot.py` | Vision-model pre-check (optional) | | `input_emulation.py`, `input_test.py` | OS-level virtual keyboard/mouse injection for input verification | +| `Tools/_common.py` | Pure helper shared by Blender builders, importable without Blender (bay layout) | | `Tools/tests/` | Stdlib `unittest` tests for the pure parts of the tools (`requirements-tools.txt`) | | `Geo/tools/mapbox_buildings.py` | Second height source: Mapbox `mapbox-streets-v8` building data vs our OSM heights | diff --git a/Docs/Architecture/architecture.md b/Docs/Architecture/architecture.md index 6986eb0..8ff18b8 100644 --- a/Docs/Architecture/architecture.md +++ b/Docs/Architecture/architecture.md @@ -191,6 +191,7 @@ Static meshes and materials in `/Game/Hollywood/Site/`: | `SM_HeroFacade` | El Capitan Entertainment Centre detailed façade | | `SM_ElCapitanTheatre`, `SM_Budget_6822`, `SM_Hollywood_6806`, `SM_Hollywood_6902`, `SM_Hollywood_6922`, `SM_LeeDrug_6800` | South block frontage (6 buildings) | | `SM_Madame_Tussauds`, `SM_TCL_Chinese_Theatre` | North-side buildings (within 50 m) | +| `SM_Retail_LeeDrug`, `SM_Retail_6806` | Retail trim over 6800 and 6806–6820, modelled from their own photograph (`Tools/retail_frontage_build.py`, staged as `RetailTrim_*`). `6822 Budget` stays a bare volume: no photograph exists. | ### Art Pipeline @@ -198,13 +199,14 @@ Python scripts in `Tools/` drive the content pipeline: | Script group | Purpose | | --- | --- | -| `export_*`, `hero_facade_build` | Blender headless export (FBX) | -| `ue_import_*`, `ue_hero_facade_import` | Unreal headless import + placement | +| `export_*`, `hero_facade_build`, `retail_frontage_build`, `theatre_trim_build`, `facade_kit_build` | Blender headless export (FBX); trim builders work in world coordinates | +| `ue_import_*`, `ue_hero_facade_import`, `ue_import_retail_detail` | Unreal headless import + placement | | `ue_build_demo_map`, `ue_build_review_map` | Map assembly (lighting, meshes, player start) | | `ue_create_input_assets` | Enhanced Input actions + mapping context | | `render_screenshots.sh` | Screenshot capture pipeline | | `judge_screenshot.py` | Vision-model pre-check (optional) | | `input_emulation.py`, `input_test.py` | OS-level virtual keyboard/mouse injection for input verification | +| `Tools/_common.py` | Pure helper shared by Blender builders, importable without Blender (bay layout) | | `Tools/tests/` | Stdlib `unittest` tests for the pure parts of the tools (`requirements-tools.txt`) | | `Geo/tools/mapbox_buildings.py` | Second height source: Mapbox `mapbox-streets-v8` building data vs our OSM heights | diff --git a/Screenshots/README.md b/Screenshots/README.md index 093d18d..a38c166 100644 --- a/Screenshots/README.md +++ b/Screenshots/README.md @@ -12,19 +12,86 @@ Tools/render_screenshots.sh --verify Stages the demo shot cameras, runs the game on `/Game/Hollywood/DemoMap`, copies the PNGs into `Screenshots/demo/` and then runs [`Tools/visual_loop.py`](../Tools/visual_loop.py) `--verify` to check that each shot still shows the content its expectation describes. About a minute. -## The shot list +## Status at a glance -Each shot has an **expectation** in [`Tools/visual_targets.json`](../Tools/visual_targets.json) — the content the capture must show — and a verification state produced by `--verify`: it fails if the frame is blank, the wrong size, or has no tonal range. +Every shot is embedded below, in order, so the whole review happens in this file. -| # | File | View | Expected content | Verified | Approved | -| --- | --- | --- | --- | --- | --- | -| 1 | `demo/review-demo-spawn-view.png` | north sidewalk | The whole south block: the neoclassical hero façade between its neighbours, both sidewalks and the road in the foreground | ☑ 2026-11-09 | ☑ 2026-11-09 | -| 2 | `demo/review-demo-street-level.png` | eye height, north side | Street level: the hero colonnade with the adjacent frontage buildings either side, shopfronts at pavement level | ☑ 2026-11-09 | ☑ 2026-11-09 | -| 3 | `demo/review-demo-crossing.png` | along the crosswalk | The designated mid-block crossing (s=130 m, UE X −14956): zebra bars on the asphalt, south frontage and colonnade behind | ☑ 2026-11-09 | ☑ 2026-11-09 | -| 4 | `demo/review-demo-north-buildings.png` | across the Boulevard | The two north-side buildings (TCL Chinese Theatre, Madame Tussaud's) from the south side, full height in frame | ☑ 2026-11-09 | ☑ 2026-11-09 | -| 5 | `demo/review-demo-retail-frontage.png` | north sidewalk, level horizon | The retail run beside the hero: 6800 Lee Drug's bronze cornice, mural row and parapet next to 6806–6820's burgundy fascia, pilasters and window storey | ☑ 2026-11-09 | ☐ pending | +| # | Shot | Verified | Approved | +| --- | ------------------------------------- | ------------ | ------------ | +| 1 | [Spawn view](#1-spawn-view) | ☑ 2026-11-09 | ☑ 2026-11-09 | +| 2 | [Street level](#2-street-level) | ☑ 2026-11-09 | ☑ 2026-11-09 | +| 3 | [Crossing](#3-crossing) | ☑ 2026-11-09 | ☑ 2026-11-09 | +| 4 | [North buildings](#4-north-buildings) | ☑ 2026-11-09 | ☑ 2026-11-09 | +| 5 | [Retail frontage](#5-retail-frontage) | ☑ 2026-11-09 | ☐ pending | -Approval is per shot, in the table above (owner review of the `0.1.4` set, recorded in [`Docs/reviews/0.1.4-review.md`](../Docs/reviews/0.1.4-review.md)). Add a row when a shot is added; remove the file in the same change when a shot is retired. +**Verified** is what `--verify` reports: the frame is not blank, is the right size, and has tonal range. **Approved** is the owner's verdict, recorded here. Each shot also has an **expectation** in [`Tools/visual_targets.json`](../Tools/visual_targets.json) describing the content it must show. + +--- + +## 1. Spawn view + +![Spawn view: the whole south block from the north sidewalk](demo/review-demo-spawn-view.png) + +- **File:** `demo/review-demo-spawn-view.png` +- **View:** north sidewalk, 14 m back, level horizon +- **Expected content:** the whole south block — the neoclassical hero façade between its neighbouring buildings, both sidewalks and the road in the foreground +- **Verified:** ☑ 2026-11-09 · **Approved:** ☑ 2026-11-09 + +--- + +## 2. Street level + +![Street level: the hero colonnade at eye height](demo/review-demo-street-level.png) + +- **File:** `demo/review-demo-street-level.png` +- **View:** eye height, north side +- **Expected content:** the hero colonnade with the adjacent frontage buildings either side, shopfronts at pavement level +- **Verified:** ☑ 2026-11-09 · **Approved:** ☑ 2026-11-09 + +--- + +## 3. Crossing + +![Crossing: the designated mid-block crossing with zebra bars](demo/review-demo-crossing.png) + +- **File:** `demo/review-demo-crossing.png` +- **View:** from the north sidewalk along the crosswalk +- **Expected content:** the designated mid-block crossing (s=130 m, UE X −14956) — zebra bars on the asphalt, south frontage and colonnade behind +- **Verified:** ☑ 2026-11-09 · **Approved:** ☑ 2026-11-09 + +--- + +## 4. North buildings + +![North buildings: TCL Chinese Theatre and Madame Tussaud's from the south](demo/review-demo-north-buildings.png) + +- **File:** `demo/review-demo-north-buildings.png` +- **View:** across the Boulevard from the south side +- **Expected content:** the two north-side buildings (TCL Chinese Theatre, Madame Tussaud's), full height in frame +- **Verified:** ☑ 2026-11-09 · **Approved:** ☑ 2026-11-09 + +--- + +## 5. Retail frontage + +![Retail frontage: 6800 Lee Drug and 6806–6820 from across the street](demo/review-demo-retail-frontage.png) + +- **File:** `demo/review-demo-retail-frontage.png` +- **View:** north sidewalk, level horizon, 68° lens +- **Expected content:** the retail run beside the hero — 6800 Lee Drug's bronze cornice, mural row and parapet next to 6806–6820's burgundy fascia, pilasters and window storey +- **Verified:** ☑ 2026-11-09 · **Approved:** ☐ pending + +Read this one against the reference photograph it was modelled from: `Art/reference/retail-neighbours/01-lee-drug-and-neighbor.jpg` (Gb321, CC BY-SA 4.0). + +Known gaps in this first pass, recorded rather than hidden: + +- **The parapet reads as a blank white band.** It is modelled as one 2.18 m wall with four 0.10 m reveal strips, and at review distance the strips disappear into the wash. +- **The mural row and lettering band barely read.** They are shallow plates (0.06–0.08 m) on the same plane as the wall; they need either depth or a decal before they read as the photographs' black-framed panels. +- **The corner tower is a plain cylinder with two cap rings** — the stepped Deco profile in the photograph is richer than that. +- **The camera crops the east end** of Lee Drug at 68° from the north sidewalk. +- **6822 Budget is untouched** and still a bare blockout volume: no photograph of it exists. + +--- ## The iteration loop (uncommitted) @@ -41,7 +108,7 @@ Note the comparison is only meaningful when the shot and the reference frame the ## Scene conventions - **Demo map** (`/Game/Hollywood/DemoMap`): fixed daytime — sun pitch −62 / yaw 120 (intensity 4, warm), sky light 2.6, sky atmosphere, height fog, fixed exposure. -- **Cameras**: elevation shots sit at their target height (pitch 0, so verticals stay parallel) and use a 42–55° lens to fill the frame from across the street. +- **Cameras**: elevation shots sit at their target height (pitch 0, so verticals stay parallel) and use a 42–68° lens to fill the frame from across the street. - **Materials**: every surface carries a look-developed material from `Tools/ue_build_demo_map.py` — noise-blended base colour, masonry coursing, and a generated texture set (`Tools/generate_facade_textures.py`) sampled world-aligned. Explicit roughness and specular per surface type. ## Known cosmetic issues @@ -50,20 +117,3 @@ Note the comparison is only meaningful when the shot and the reference frame the - Banners sit on the column line rather than flush to the wall (they hang on the columns in the photographs, so this is acceptable). - Between kerb and building line the walkable surface is the terrain mesh, not a modelled pavement. - The El Capitan Theatre has no marquee or blade sign yet — the feature that makes it read as itself. - -## 0.1.6 retail frontage — what to look at - -Shot 5 is the review shot for this pass. Read it against -`Art/reference/retail-neighbours/01-lee-drug-and-neighbor.jpg` (Gb321, CC BY-SA 4.0). - -Known gaps in this first pass, recorded rather than hidden: - -- **The parapet reads as a blank white band.** It is modelled as one 2.18 m wall with four - 0.10 m reveal strips, and at review distance the strips disappear into the wash. -- **The mural row and lettering band barely read.** They are shallow plates (0.06–0.08 m) on - the same plane as the wall; they need either depth or a decal before they read as the - photographs' black-framed panels. -- **The corner tower is a plain cylinder with two cap rings** — the stepped Deco profile in the - photograph is richer than that. -- **The camera crops the east end** of Lee Drug at 68° from the north sidewalk. -- **6822 Budget is untouched** and still a bare blockout volume: no photograph of it exists. diff --git a/TODO.md b/TODO.md index d1a83e0..9c0198a 100644 --- a/TODO.md +++ b/TODO.md @@ -15,9 +15,7 @@ Suggested blender skills: **references** (reference-image-match), **archviz**, * ### Patch tasks - active - session-5598ce7e-27e3-4c64-bb49-c04a4a31ee58 (branch `facade-retail-0.1.6`) -- [A] **Model 6800 Lee Drug and 6806–6820 from their own reference.** First pass 2026-11-09 on branch `facade-retail-0.1.6`: `Tools/retail_frontage_build.py` builds both façades from the one photograph (`Art/reference/retail-neighbours/`, Gb321 CC BY-SA 4.0) with the analysis in `Art/blender/retail/ref-analysis.md`; - `Tools/ue_import_retail_detail.py` imports them and the demo builder stages them as `RetailTrim_*`. The generic façade kit is now skipped on these two, so their walls carry one façade language instead of two. - **Open on this item:** the parapet reads as a blank band, the mural row and lettering band do not resolve at review distance, the corner tower is a plain cylinder, and the review camera crops the east end — all listed in `Screenshots/README.md`. +- [A] **Model 6800 Lee Drug and 6806–6820 from their own reference.** First pass 2026-11-09 on branch `facade-retail-0.1.6`: `Tools/retail_frontage_build.py` builds both façades from the one photograph (`Art/reference/retail-neighbours/`, Gb321 CC BY-SA 4.0) with the analysis in `Art/blender/retail/ref-analysis.md`; `Tools/ue_import_retail_detail.py` imports them and the demo builder stages them as `RetailTrim_*`. The generic façade kit is now skipped on these two, so their walls carry one façade language instead of two. **Open on this item:** the parapet reads as a blank band, the mural row and lettering band do not resolve at review distance, the corner tower is a plain cylinder, and the review camera crops the east end — all listed in `Screenshots/README.md`. - [D] **Model 6822 Budget.** Deferred: no photograph exists for it (Commons has nothing usable) and the single-storey 6.0 × 5.5 m volume cannot be read from the neighbour shot. Needs photography before it can be modelled honestly; do not substitute the El Capitan Theatre's set or the 6806–6820 shot. - [ ] Review every façade change with `Tools/render_screenshots.sh --verify` before tagging. - [ ] Tag `v0.1.6` and write `CHANGELOG.md` entry; then remove this section. -- 2.47.3 From 4132f42ca12686d08ed54ff3e050640b7ae113d7 Mon Sep 17 00:00:00 2001 From: Zwitschi Date: Mon, 9 Nov 2026 09:54:15 +0100 Subject: [PATCH 4/8] plan: give realistic buildings their own minor milestone (0.9.0) The facade work started as a patch (0.1.4) and the 0.1.6 retail pass showed what that costs: a patch has no release gate of its own, so a first pass that does not yet read as the building can sit inside a done patch series. Realism is also the leading quality goal, which a patch cannot carry. New 0.9.0 - Realistic buildings, before the feature freeze: facade system with more than one order, a profile library, storefront types, signage as decals, per-building photo-matched models, a measured material library with a texel-density rule, and LODs plus collision proxies. Former 0.9.0 freeze/beta/audit becomes 0.10.0 with patches 0.10.1-0.10.3; 1.0.0 moves to weeks 39-44. Recorded as ADR-8 (append-only) with a measurable gate BR-1..BR-5 in the quality requirements, mirrored into the combined architecture.md. The 0.1.6 item now says which of its gaps move to 0.9.0 and why more geometry cannot close them. --- .../Architecture/09_architecture_decisions.md | 8 +++ Docs/Architecture/10_quality_requirements.md | 10 +++ Docs/Architecture/architecture.md | 18 ++++++ PLAN.md | 5 +- ROADMAP.md | 28 +++++++-- TODO.md | 61 ++++++++++++++++--- 6 files changed, 112 insertions(+), 18 deletions(-) diff --git a/Docs/Architecture/09_architecture_decisions.md b/Docs/Architecture/09_architecture_decisions.md index 0d6c9ba..ddfe5fd 100644 --- a/Docs/Architecture/09_architecture_decisions.md +++ b/Docs/Architecture/09_architecture_decisions.md @@ -55,3 +55,11 @@ - **Decision**: All Blender work driven by Python scripts in `Tools/`. Skill packs used as method guides (checklists, naming, proportions) only. - **Consequences**: Scripts are version-controlled and repeatable. No live Blender session needed for CI. + +## ADR-8: Realistic building façades are a minor milestone, not a patch + +- **Context**: `0.1.4` carried the first façade pass as a _patch_, while the release policy says patches contain fixes and refinements and never new scope. The `0.1.6` retail pass then showed what that costs: a façade built in a patch has no release gate of its own, so a first pass that does not yet read as the building (`Screenshots/README.md`, 0.1.6 gaps) can sit inside a "done" patch series. Realism is also the project's leading quality goal, which a patch cannot carry. + +- **Decision**: Building realism gets its own minor milestone, `0.9.0 — Realistic buildings`, placed before the feature freeze. Its scope is the façade system (orders, profile library, storefront types, signage as decals), per-building photo-matched models, a measured material library with a texel-density rule, and LODs plus collision proxies. Patches keep fixes and refinements only. Renumbered by this decision: the former `0.9.0` freeze/beta/audit milestone becomes `0.10.0`, its patches `0.10.1`–`0.10.3`, and `1.0.0` moves to weeks 39–44. + +- **Consequences**: Façade work now has a release gate — every building measured against its own photograph, every building with a collision proxy and a LOD, no placeholder materials — so "modelled" means verified, not merely present. The price is that realism work stops being sliced into patches, and the schedule shifts by one minor cycle. Blockouts without a photograph stay blockouts and are listed as such, rather than being dressed up to fill the milestone. diff --git a/Docs/Architecture/10_quality_requirements.md b/Docs/Architecture/10_quality_requirements.md index 6a5a48c..718e4bf 100644 --- a/Docs/Architecture/10_quality_requirements.md +++ b/Docs/Architecture/10_quality_requirements.md @@ -33,3 +33,13 @@ Ordered by priority: realism first, performance last. The order decides design t | QS-9 | Game runs on dev workstation at 1440p | Frame rate holds the floor | ≥ 60 FPS, 99th percentile ≥ 55 FPS | > QS-9 is last on purpose. Performance is a floor that every release must meet, not the goal that shapes the content: realism decides what gets built, the frame budget decides how much of it. + +### Building realism gate (0.9.0) + +| ID | Check | Metric | +| --- | --- | --- | +| BR-1 | A building with a reference photograph has a review shot compared against it | Silhouette and proportion deltas recorded per building in `Screenshots/README.md`; owner approval per shot | +| BR-2 | Every building is either photo-matched or explicitly recorded as an unfounded blockout | List in `TODO.md`; no building in an in-between state | +| BR-3 | Every building has a collision proxy and at least one LOD | Count of buildings missing either = 0 | +| BR-4 | No surface carries a placeholder material | Material audit in `Tools/ue_audit_scene.py` reports 0 placeholder slots | +| BR-5 | The realism pass does not break the floor | QS-9 still holds at 1440p, with the measured cost of the pass recorded | diff --git a/Docs/Architecture/architecture.md b/Docs/Architecture/architecture.md index 8ff18b8..a437604 100644 --- a/Docs/Architecture/architecture.md +++ b/Docs/Architecture/architecture.md @@ -455,6 +455,14 @@ Rule: place a building only against a neighbour or street mesh, never in isolati # Quality Requirements +## ADR-8: Realistic building façades are a minor milestone, not a patch + +- **Context**: `0.1.4` carried the first façade pass as a _patch_, while the release policy says patches contain fixes and refinements and never new scope. The `0.1.6` retail pass then showed what that costs: a façade built in a patch has no release gate of its own, so a first pass that does not yet read as the building (`Screenshots/README.md`, 0.1.6 gaps) can sit inside a "done" patch series. Realism is also the project's leading quality goal, which a patch cannot carry. + +- **Decision**: Building realism gets its own minor milestone, `0.9.0 — Realistic buildings`, placed before the feature freeze. Its scope is the façade system (orders, profile library, storefront types, signage as decals), per-building photo-matched models, a measured material library with a texel-density rule, and LODs plus collision proxies. Patches keep fixes and refinements only. Renumbered by this decision: the former `0.9.0` freeze/beta/audit milestone becomes `0.10.0`, its patches `0.10.1`–`0.10.3`, and `1.0.0` moves to weeks 39–44. + +- **Consequences**: Façade work now has a release gate — every building measured against its own photograph, every building with a collision proxy and a LOD, no placeholder materials — so "modelled" means verified, not merely present. The price is that realism work stops being sliced into patches, and the schedule shifts by one minor cycle. Blockouts without a photograph stay blockouts and are listed as such, rather than being dressed up to fill the milestone. + ## Quality Requirements Overview Ordered by priority: realism first, performance last. The order decides design trade-offs; it does not license dropping a lower item silently (see the trade-off rule below the table). @@ -489,6 +497,16 @@ Ordered by priority: realism first, performance last. The order decides design t > QS-9 is last on purpose. Performance is a floor that every release must meet, not the goal that shapes the content: realism decides what gets built, the frame budget decides how much of it. +### Building realism gate (0.9.0) + +| ID | Check | Metric | +| --- | --- | --- | +| BR-1 | A building with a reference photograph has a review shot compared against it | Silhouette and proportion deltas recorded per building in `Screenshots/README.md`; owner approval per shot | +| BR-2 | Every building is either photo-matched or explicitly recorded as an unfounded blockout | List in `TODO.md`; no building in an in-between state | +| BR-3 | Every building has a collision proxy and at least one LOD | Count of buildings missing either = 0 | +| BR-4 | No surface carries a placeholder material | Material audit in `Tools/ue_audit_scene.py` reports 0 placeholder slots | +| BR-5 | The realism pass does not break the floor | QS-9 still holds at 1440p, with the measured cost of the pass recorded | + # Risks and Technical Debts | ID | Risk / Debt | Priority | Mitigation | diff --git a/PLAN.md b/PLAN.md index a4ad367..2128e40 100644 --- a/PLAN.md +++ b/PLAN.md @@ -108,8 +108,9 @@ Solo-development estimate: **approximately 30–40 weeks**, subject to asset qua | `0.6.0` | 22–24 | Visual/audio pass and evening lighting preset | `0.6.1` lighting fixes; `0.6.2` material corrections; `0.6.3` audio balancing | | `0.7.0` | 25–27 | Settings, control rebinding, save/load, accessibility basics | `0.7.1` save fixes; `0.7.2` UI fixes; `0.7.3` input persistence fixes | | `0.8.0` | 28–30 | Performance budgets and broader Linux hardware testing | `0.8.1` VRAM reductions; `0.8.2` frame-time fixes; `0.8.3` compatibility fixes | -| `0.9.0` | 31–34 | Feature freeze, public beta, license and build audit | `0.9.1` blocker fixes; `0.9.2` regression fixes; `0.9.3` documentation fixes | -| `1.0.0` | 35–40 | Stable neighborhood-scale walking/driving release | `1.0.x` maintenance and compatibility fixes | +| `0.9.0` | 31–34 | Realistic buildings: façade system, per-building models, measured material library, LODs and collision proxies | `0.9.1` façade fixes | +| `0.10.0` | 35–38 | Feature freeze, public beta, license and build audit | `0.10.1` blocker fixes; `0.10.2` regression fixes; `0.10.3` documentation fixes | +| `1.0.0` | 39–44 | Stable neighborhood-scale walking/driving release | `1.0.x` maintenance and compatibility fixes | Finish each milestone's release checks before expanding scope. Cut map size and simulation complexity before compromising the core walking/driving experience. diff --git a/ROADMAP.md b/ROADMAP.md index 00c8232..4df3189 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -168,22 +168,38 @@ Workstation, geo pipeline, and engine validation are done. The art pipeline has **Goal:** fix compatibility issues from the hardware testing matrix. -## 0.9.0 — Feature freeze, public beta, license and build audit (weeks 31–34) +## 0.9.0 — Realistic buildings (weeks 31–34) + +**Goal:** every building in the demo area reads as the building it is, at walking distance, judged against its own photograph — and where no photograph exists it stays an honest blockout rather than an invented façade. This is the milestone that turns the façade system from "a kit applied to volumes" into architecture: a shared bay-and-profile vocabulary, a material library with measured albedo and roughness, modelled storefronts and signage, and per-building reference matching with a measured tolerance. + +**Scope:** + +- A façade system that carries more than one order: Art Deco, neoclassical and streamline-moderne variants on the same 4.96 m bay module, with a profile library for cornices, copings, string courses and storefront surrounds. +- Per-building façades for the six south-side buildings and the two north-side buildings inside the 50 m buffer, each from its own reference set; the hero keeps its existing model and gains the detail levels this pass defines. +- Storefronts and signage as first-class geometry plus decals: mullions, bulkheads, recessed entries, awning and canopy brackets, painted wall lettering, blade and projecting signs. Wall lettering is a texture/decal problem, not a block of geometry — the `0.1.6` attempt proved plates do not read. +- A material library with measured values per surface type (stucco, painted render, ashlar, brick, terrazzo, glazing, bronze and steel trim) and a texel-density rule, replacing per-building ad-hoc colours. +- LOD chain and collision proxies per building, so realism does not cost the 60 FPS floor. + +**Out of scope:** interiors, night lighting and audio (the `0.6.0` evening preset owns those), vehicles, pedestrians, and any change to footprints or massing — OSM stays the source for those. + +**Release gate:** each building has a review shot compared against its own photograph with the silhouette and proportion deltas recorded in `Screenshots/README.md`; no building carries an unverified façade; every building has a collision proxy and at least one LOD; 60 FPS at 1440p holds; no surface is left with a placeholder material; `THIRD_PARTY_NOTICES.md` covers every photographic reference used. + +## 0.10.0 — Feature freeze, public beta, license and build audit (weeks 35–38) **Goal:** freeze features, produce a public beta for testers, and complete the audits: licences for `THIRD_PARTY_NOTICES.md` and all MPFB, texture, animation, vehicle, and audio assets; Epic distribution requirements; and a fresh checkout that builds and packages reproducibly. -## 0.9.1 — Blocker fixes (patch) +## 0.10.1 — Blocker fixes (patch) **Goal:** fix blockers reported during the public beta. -## 0.9.2 — Regression fixes (patch) +## 0.10.2 — Regression fixes (patch) -**Goal:** fix regressions introduced by `0.9.x` fixes. +**Goal:** fix regressions introduced by `0.10.x` fixes. -## 0.9.3 — Documentation fixes (patch) +## 0.10.3 — Documentation fixes (patch) **Goal:** update all `Docs/` for accuracy before `1.0.0`. -## 1.0.0 — Stable neighborhood-scale walking/driving release (weeks 35–40) +## 1.0.0 — Stable neighborhood-scale walking/driving release (weeks 39–44) **Goal:** a final acceptance sweep across all `0.x` features, confirmation that the agreed scope (neighbourhood-scale walking and driving) is met, and final build, documentation, and licensing verification. `1.0.0` marks the stable scope, not completion of a whole city. diff --git a/TODO.md b/TODO.md index 9c0198a..6769651 100644 --- a/TODO.md +++ b/TODO.md @@ -15,7 +15,7 @@ Suggested blender skills: **references** (reference-image-match), **archviz**, * ### Patch tasks - active - session-5598ce7e-27e3-4c64-bb49-c04a4a31ee58 (branch `facade-retail-0.1.6`) -- [A] **Model 6800 Lee Drug and 6806–6820 from their own reference.** First pass 2026-11-09 on branch `facade-retail-0.1.6`: `Tools/retail_frontage_build.py` builds both façades from the one photograph (`Art/reference/retail-neighbours/`, Gb321 CC BY-SA 4.0) with the analysis in `Art/blender/retail/ref-analysis.md`; `Tools/ue_import_retail_detail.py` imports them and the demo builder stages them as `RetailTrim_*`. The generic façade kit is now skipped on these two, so their walls carry one façade language instead of two. **Open on this item:** the parapet reads as a blank band, the mural row and lettering band do not resolve at review distance, the corner tower is a plain cylinder, and the review camera crops the east end — all listed in `Screenshots/README.md`. +- [A] **Model 6800 Lee Drug and 6806–6820 from their own reference.** First pass 2026-11-09 on branch `facade-retail-0.1.6`: `Tools/retail_frontage_build.py` builds both façades from the one photograph (`Art/reference/retail-neighbours/`, Gb321 CC BY-SA 4.0) with the analysis in `Art/blender/retail/ref-analysis.md`; `Tools/ue_import_retail_detail.py` imports them and the demo builder stages them as `RetailTrim_*`. The generic façade kit is now skipped on these two, so their walls carry one façade language instead of two. **Open on this item:** the parapet reads as a blank band, the mural row and lettering band do not resolve at review distance, the corner tower is a plain cylinder, and the review camera crops the east end — all listed in `Screenshots/README.md`. **Not fixable by more geometry:** a second pass moved the plates 0.10–0.20 m off the wall and they still do not read at 40 m; wall lettering and the portrait panels need the decal/texture route scoped in `0.9.0 — Realistic buildings`. This patch stops at the trim that does read — cornice, fascia, storefronts, window bars, parapet tiers. - [D] **Model 6822 Budget.** Deferred: no photograph exists for it (Commons has nothing usable) and the single-storey 6.0 × 5.5 m volume cannot be read from the neighbour shot. Needs photography before it can be modelled honestly; do not substitute the El Capitan Theatre's set or the 6806–6820 shot. - [ ] Review every façade change with `Tools/render_screenshots.sh --verify` before tagging. - [ ] Tag `v0.1.6` and write `CHANGELOG.md` entry; then remove this section. @@ -286,7 +286,48 @@ Suggested blender skills: **references** (reference-image-match), **archviz**, * - [ ] Fix compatibility issues from the hardware testing matrix. - [ ] Tag `v0.8.3` and write `CHANGELOG.md` entry; then remove this section. -## 0.9.0 — Feature freeze, public beta, license and build audit (weeks 31–34) +## 0.9.0 — Realistic buildings (weeks 31–34) + +Suggested blender skills: **archviz** (real-world scale, façade composition, elevation read), **references** (reference-image-match and visual-match checklists — every building is judged against its own photograph), **procedural-modeling** + **geometry-nodes** (the façades system: bay module, cornice and coping profiles, storefront types as reusable node groups), **materials** (measured albedo and roughness per surface type), **texture-workflow** (baked AO/curvature/normal, decals for painted lettering and signs), **uv-workflow** (texel density and modular UVs), **lod-pipeline** (LOD chain per building), **collision-proxy** (UCX proxies so detail geometry is not the collider), **lookdev** (screenshot comparison loop), **camera-cinematography** (reproducing each building's reference angle), **asset-optimization** + **unreal-export** (pre-export validation, `ue_metric_v1`), **qa-review** (the gate before every review shot). + +### Façade system + +- [ ] **Extend the module kit beyond one order.** Art Deco, neoclassical and streamline-moderne variants on the shared 4.96 m bay: alternate window proportions, spandrel and transom bands, and the way each order terminates at the roof. +- [ ] **Build a profile library** for cornices, copings, string courses, sills and storefront surrounds, so a building is assembled from named profiles rather than ad-hoc boxes. +- [ ] **Storefront types**: recessed entry, bulkhead and kickplate, mullion spacing, transom, awning/canopy brackets, and grille/shutter variants. +- [ ] **Signage and lettering as decals.** Painted wall lettering, blade signs and fascia panels become texture and decal work with a documented projection; `0.1.6` proved that lettering built as geometry plates cannot resolve at review distance. +- [ ] Document the system in `Art/blender/README.md` and the arc42 building block view. + +### Per-building models + +Each building needs its own reference set; where none exists the blockout stays and the item says so. + +- [ ] Hero façade (6840): raise to this pass's detail level — capitals and fluting, window rhythm behind the colonnade, parapet motto band and medallions. +- [ ] El Capitan Theatre (6838): marquee, blade sign, entrance and the theatre's own elevation from its 18-frame set. +- [ ] 6800 Lee Drug and 6806–6820: second pass on the `0.1.6` trim — parapet profile, mural panels, and the lettering decal. +- [ ] 6822 Budget, 6806–6820 and 6800 photography gap: acquire references before modelling anything not yet photographed, and record the sources checked in `Geo/`. +- [ ] 6902, 6922 and the remaining south frontage. +- [ ] North side: TCL Chinese Theatre and Madame Tussaud's façades from their reference sets. +- [ ] Reconcile every modelled height against `Geo/tools/block_height_report.py` and record the source per building. + +### Materials, UVs and performance + +- [ ] **Measured material library**: stucco, painted render, ashlar, brick, terrazzo, glazing, bronze and steel trim, with albedo and roughness taken from the photographs rather than guessed; one Unreal material instance per surface type. +- [ ] **Texel-density rule** per building class, applied through modular UVs; lightmap UVs where required. +- [ ] **LOD chain and collision proxies** per building: UCX proxies for blocking volume, detail geometry non-colliding. +- [ ] Re-validate the 60 FPS floor at 1440p once the detail lands, and record the cost of the pass. + +### Release checks + +- [ ] Every building with a photograph has a review shot measured against it, with silhouette and proportion deltas recorded in `Screenshots/README.md`. +- [ ] No building carries an unverified façade; blockouts without references are listed as such in `TODO.md`. +- [ ] Every building has a collision proxy and at least one LOD. +- [ ] No surface left on a placeholder material. +- [ ] `THIRD_PARTY_NOTICES.md` covers every photographic reference used in this pass. +- [ ] Performance target still met at 1440p. +- [ ] Tag `v0.9.0` and write `CHANGELOG.md` entry; then remove this section. + +## 0.10.0 — Feature freeze, public beta, license and build audit (weeks 35–38) ### Freeze and audit @@ -298,29 +339,29 @@ Suggested blender skills: **references** (reference-image-match), **archviz**, * ### Release checks -- [ ] Beta feedback triaged; blockers logged for `0.9.x`. -- [ ] Tag `v0.9.0` and write `CHANGELOG.md` entry; then remove this section. +- [ ] Beta feedback triaged; blockers logged for `0.10.x`. +- [ ] Tag `v0.10.0` and write `CHANGELOG.md` entry; then remove this section. -## 0.9.1 — Blocker fixes (patch) +## 0.10.1 — Blocker fixes (patch) ### Patch tasks - [ ] Fix blockers reported during the public beta. -- [ ] Tag `v0.9.1` and write `CHANGELOG.md` entry; then remove this section. +- [ ] Tag `v0.10.1` and write `CHANGELOG.md` entry; then remove this section. -## 0.9.2 — Regression fixes (patch) +## 0.10.2 — Regression fixes (patch) ### Patch tasks - [ ] Fix regressions introduced by `0.9.x` fixes. -- [ ] Tag `v0.9.2` and write `CHANGELOG.md` entry; then remove this section. +- [ ] Tag `v0.10.2` and write `CHANGELOG.md` entry; then remove this section. -## 0.9.3 — Documentation fixes (patch) +## 0.10.3 — Documentation fixes (patch) ### Patch tasks - [ ] Update all `Docs/` for accuracy before `1.0.0`. -- [ ] Tag `v0.9.3` and write `CHANGELOG.md` entry; then remove this section. +- [ ] Tag `v0.10.3` and write `CHANGELOG.md` entry; then remove this section. ## 1.0.0 — Stable neighborhood-scale walking/driving release (weeks 35–40) -- 2.47.3 From 3942e9a2154c546f9b32eacbcb96560ba2388986 Mon Sep 17 00:00:00 2001 From: Zwitschi Date: Mon, 9 Nov 2026 09:54:33 +0100 Subject: [PATCH 5/8] =?UTF-8?q?feat(facades):=200.1.6=20retail=20second=20?= =?UTF-8?q?pass=20=E2=80=94=20relief,=20material=20mapping,=20framing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit What the first pass got wrong, and what changed: - The mural plates were placed 0.20 m INSIDE the solid blockout volume, so they never rendered. Nothing can be recessed into a solid we do not cut: the inset is now faked by a proud frame with a near-flush plate, and the row reads. - Detail sat 0.05 m off the wall, under a pixel of depth at 40 m. Trim planes now stand 0.10-0.20 m proud, and the parapet became two tiers with deeper reveals. - 6806's parapet started at 0.62 H and left a 4.6 m blank band; the window storey and parapet moved up to follow the photograph. - Security bars on the upper windows, twelve fluted fins on the corner tower. - The trim's stucco/white/glass slots are mapped onto the demo's look materials, so the walls sit in the same noise/texture family as the rest of the block; the colour slots sampled from the photograph stay as authored. - Review camera pulled back and widened to 66 deg so the east end is in frame. - The scene audit caught duplicate RetailTrim_ actors: the demo builder's clear list did not include the new label, so every rebuild stacked another copy. Still open and not fixable by geometry: wall lettering. A plate at 0.10 m does not read at 40 m, so it moves to the 0.9.0 decal route (TODO.md, Screenshots/README.md). --- Game/GigLine/Content/Hollywood/DemoMap.umap | 4 +- .../Content/Hollywood/Site/M_Asphalt.uasset | 2 +- .../Content/Hollywood/Site/M_Concrete.uasset | 2 +- .../Hollywood/Site/M_FacadeBanner.uasset | 2 +- .../Hollywood/Site/M_FacadeGlass.uasset | 2 +- .../Hollywood/Site/M_FacadeStone.uasset | 4 +- .../Hollywood/Site/M_FacadeStoneShadow.uasset | 4 +- .../Content/Hollywood/Site/M_Ground.uasset | 2 +- .../Hollywood/Site/M_KerbConcrete.uasset | 2 +- .../Content/Hollywood/Site/M_RoadPaint.uasset | 2 +- .../Content/Hollywood/Site/M_Stucco.uasset | 2 +- .../Content/Hollywood/Site/Terrain_DEM.uasset | 2 +- .../Hollywood/Textures/T_Asphalt_BC.uasset | 2 +- .../Hollywood/Textures/T_Asphalt_R.uasset | 2 +- .../Hollywood/Textures/T_Concrete_BC.uasset | 2 +- .../Hollywood/Textures/T_Concrete_R.uasset | 2 +- .../Textures/T_StoneAshlar_BC.uasset | 2 +- .../Hollywood/Textures/T_StoneAshlar_R.uasset | 2 +- .../Hollywood/Textures/T_Stucco_BC.uasset | 2 +- .../Hollywood/Textures/T_Stucco_R.uasset | 2 +- .../Theatre/SM_Trim_BladeSign.uasset | 2 +- .../Theatre/SM_Trim_BladeSignBracket.uasset | 2 +- .../Theatre/SM_Trim_BladeSignFrame.uasset | 2 +- .../Theatre/SM_Trim_MarqueeCanopy.uasset | 2 +- .../Theatre/SM_Trim_MarqueeFascia.uasset | 2 +- .../Theatre/SM_Trim_MarqueeSoffit.uasset | 2 +- Game/GigLine/Content/Test/ReviewMap.umap | 2 +- Screenshots/README.md | 4 +- Screenshots/demo/review-demo-crossing.png | 4 +- .../demo/review-demo-north-buildings.png | 4 +- .../demo/review-demo-retail-frontage.png | 4 +- Screenshots/demo/review-demo-spawn-view.png | 4 +- Screenshots/demo/review-demo-street-level.png | 4 +- Tools/retail_frontage_build.py | 108 +++++++++++++----- Tools/ue_build_demo_map.py | 17 ++- Tools/ue_build_review_map.py | 2 +- 36 files changed, 136 insertions(+), 75 deletions(-) diff --git a/Game/GigLine/Content/Hollywood/DemoMap.umap b/Game/GigLine/Content/Hollywood/DemoMap.umap index e734bfc..793795e 100644 --- a/Game/GigLine/Content/Hollywood/DemoMap.umap +++ b/Game/GigLine/Content/Hollywood/DemoMap.umap @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0d6d69622d2135200c91e09decfe462e93b416bcbad430cb7e8ce5df4368b83c -size 781795 +oid sha256:3cadf24b327116118550a7fb62dd6cc1cc748e152959ed2cdcf3a1de64bb4bb0 +size 781914 diff --git a/Game/GigLine/Content/Hollywood/Site/M_Asphalt.uasset b/Game/GigLine/Content/Hollywood/Site/M_Asphalt.uasset index fe6cb0f..fa2a3e5 100644 --- a/Game/GigLine/Content/Hollywood/Site/M_Asphalt.uasset +++ b/Game/GigLine/Content/Hollywood/Site/M_Asphalt.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3fb76d8de906114912d8d5fe6e5cccd5f661eaf7bd644f9d32a5a4a122bedc4d +oid sha256:fcf355af961bd5f0c50d9dd5f9f680e64ad23327cd4934831a0c23644b3af20c size 10019 diff --git a/Game/GigLine/Content/Hollywood/Site/M_Concrete.uasset b/Game/GigLine/Content/Hollywood/Site/M_Concrete.uasset index 25741c9..10f810e 100644 --- a/Game/GigLine/Content/Hollywood/Site/M_Concrete.uasset +++ b/Game/GigLine/Content/Hollywood/Site/M_Concrete.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:83c4ce0706040145c130664a8098614a8022e9deb814b4a281098cc81b340b4c +oid sha256:fe5db22b218b38420b546ee75e1f10128f3735ff9679ec42350405cc741bc55f size 10024 diff --git a/Game/GigLine/Content/Hollywood/Site/M_FacadeBanner.uasset b/Game/GigLine/Content/Hollywood/Site/M_FacadeBanner.uasset index 64c183f..ea83fb9 100644 --- a/Game/GigLine/Content/Hollywood/Site/M_FacadeBanner.uasset +++ b/Game/GigLine/Content/Hollywood/Site/M_FacadeBanner.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1926a4806a096dca5ac226f0104df86adfe5861639ca31159192e392619f7e0a +oid sha256:8396d7101a43df58b845b2c9fdf745c11ed8aa8d2703f603fde038ae37472765 size 11419 diff --git a/Game/GigLine/Content/Hollywood/Site/M_FacadeGlass.uasset b/Game/GigLine/Content/Hollywood/Site/M_FacadeGlass.uasset index 2eee7c5..fe9c91f 100644 --- a/Game/GigLine/Content/Hollywood/Site/M_FacadeGlass.uasset +++ b/Game/GigLine/Content/Hollywood/Site/M_FacadeGlass.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1371c411f28b429836bea1000d8bd45317385e89fadb65229c6d5e30ad8deafa +oid sha256:c07c6cd2ebe7f984196757043e6c16a092a154b7dae33b8c3f11113a78e42fd2 size 11414 diff --git a/Game/GigLine/Content/Hollywood/Site/M_FacadeStone.uasset b/Game/GigLine/Content/Hollywood/Site/M_FacadeStone.uasset index 87483be..810d776 100644 --- a/Game/GigLine/Content/Hollywood/Site/M_FacadeStone.uasset +++ b/Game/GigLine/Content/Hollywood/Site/M_FacadeStone.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3bce906bf91b38622e821768ec39b18e628e6362eb8f32c591c7896692662df6 -size 17168 +oid sha256:3229e39839dfd7cfbe787cddc4337399ecfb7bc25c1364057db38cfd34d07c5b +size 17083 diff --git a/Game/GigLine/Content/Hollywood/Site/M_FacadeStoneShadow.uasset b/Game/GigLine/Content/Hollywood/Site/M_FacadeStoneShadow.uasset index 947e285..de97c69 100644 --- a/Game/GigLine/Content/Hollywood/Site/M_FacadeStoneShadow.uasset +++ b/Game/GigLine/Content/Hollywood/Site/M_FacadeStoneShadow.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:90a31499a481fbb8efeb5d5f30aa5c1beb6ca3afa91c1a154e689e2a55c49345 -size 17198 +oid sha256:8dd4749d4946a34cd333320d098887843040765651273e336804b819880994ee +size 17113 diff --git a/Game/GigLine/Content/Hollywood/Site/M_Ground.uasset b/Game/GigLine/Content/Hollywood/Site/M_Ground.uasset index adc5f84..c23ffe8 100644 --- a/Game/GigLine/Content/Hollywood/Site/M_Ground.uasset +++ b/Game/GigLine/Content/Hollywood/Site/M_Ground.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fe37d1ab7c4d2f3621f7993c1dfdb0f062398b589ee8a5c3aace444a9417f66e +oid sha256:a9c8cc98384edbe2df0ab772f790310047339159346fb11ad4c7b86a82bea132 size 10014 diff --git a/Game/GigLine/Content/Hollywood/Site/M_KerbConcrete.uasset b/Game/GigLine/Content/Hollywood/Site/M_KerbConcrete.uasset index 0d2e7a9..0b90a35 100644 --- a/Game/GigLine/Content/Hollywood/Site/M_KerbConcrete.uasset +++ b/Game/GigLine/Content/Hollywood/Site/M_KerbConcrete.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:234d60830b619bc25f6ea9ddbcc192e462409629c5e17a121879569ee5cc01bb +oid sha256:c6934516f42a8539d7a9e37b4386a3746be9eec4cb18feabe433d1126e9cf4c4 size 10044 diff --git a/Game/GigLine/Content/Hollywood/Site/M_RoadPaint.uasset b/Game/GigLine/Content/Hollywood/Site/M_RoadPaint.uasset index 8363427..0d2b0d7 100644 --- a/Game/GigLine/Content/Hollywood/Site/M_RoadPaint.uasset +++ b/Game/GigLine/Content/Hollywood/Site/M_RoadPaint.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:90ebf4aa1f81ee4935afa7b683d574ea07fffb6860cc2b3a8cedbed826888c4f +oid sha256:ad2e8ec104f49d612d66b54e7af742ac1041b9dd8572083c252b7011c0438101 size 10029 diff --git a/Game/GigLine/Content/Hollywood/Site/M_Stucco.uasset b/Game/GigLine/Content/Hollywood/Site/M_Stucco.uasset index 40bde8e..a9067fe 100644 --- a/Game/GigLine/Content/Hollywood/Site/M_Stucco.uasset +++ b/Game/GigLine/Content/Hollywood/Site/M_Stucco.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:288b925a6c4207632777e5c13190345ba5e028ad2e675e34c32c99815f68cecb +oid sha256:a09613d3a4f47fb6532e402061acc3510265896b3bff90167943387a32c5addc size 11389 diff --git a/Game/GigLine/Content/Hollywood/Site/Terrain_DEM.uasset b/Game/GigLine/Content/Hollywood/Site/Terrain_DEM.uasset index ca32959..4759c46 100644 --- a/Game/GigLine/Content/Hollywood/Site/Terrain_DEM.uasset +++ b/Game/GigLine/Content/Hollywood/Site/Terrain_DEM.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1d7eac1b72eb0165f70af81739f992156409a0be1d5f0423f9e66c1d0f2ed381 +oid sha256:cdd2cde3bfdbc117cd0445d61c68659f8924ed794df9e61cedc466b5bb97c1ae size 357901 diff --git a/Game/GigLine/Content/Hollywood/Textures/T_Asphalt_BC.uasset b/Game/GigLine/Content/Hollywood/Textures/T_Asphalt_BC.uasset index 552ac30..01702ac 100644 --- a/Game/GigLine/Content/Hollywood/Textures/T_Asphalt_BC.uasset +++ b/Game/GigLine/Content/Hollywood/Textures/T_Asphalt_BC.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a071c19c111adaebfc466dd12bb94cb79510846a670720bd8e3df7b12b8ca051 +oid sha256:b1e00754bcb7fb131a40c9a162bf0dfc0c1a0b9a84718e121e715ed4f2d4d9ab size 70879 diff --git a/Game/GigLine/Content/Hollywood/Textures/T_Asphalt_R.uasset b/Game/GigLine/Content/Hollywood/Textures/T_Asphalt_R.uasset index f2c4f7a..06d4b3b 100644 --- a/Game/GigLine/Content/Hollywood/Textures/T_Asphalt_R.uasset +++ b/Game/GigLine/Content/Hollywood/Textures/T_Asphalt_R.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:53353dae2b3d37e609a7c79ce8c7c0ee1239386da5aa0ac16b5e4c1b177ad616 +oid sha256:2f717ded45c8aaf50861582119ce524061947bf05a36f7e335f657f193f5c6e0 size 29011 diff --git a/Game/GigLine/Content/Hollywood/Textures/T_Concrete_BC.uasset b/Game/GigLine/Content/Hollywood/Textures/T_Concrete_BC.uasset index 7a4d7d3..d1db955 100644 --- a/Game/GigLine/Content/Hollywood/Textures/T_Concrete_BC.uasset +++ b/Game/GigLine/Content/Hollywood/Textures/T_Concrete_BC.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:65a2605304ecc6c11c8a7039411bb02d315e6dadbac8b8c76a4fe48c102b31a1 +oid sha256:b6ed6dcdcacec001b0407ac7b06d7a28244a0b95ebc6ff1592047b7a2f25f8dc size 58568 diff --git a/Game/GigLine/Content/Hollywood/Textures/T_Concrete_R.uasset b/Game/GigLine/Content/Hollywood/Textures/T_Concrete_R.uasset index 80e6b8e..79e20bc 100644 --- a/Game/GigLine/Content/Hollywood/Textures/T_Concrete_R.uasset +++ b/Game/GigLine/Content/Hollywood/Textures/T_Concrete_R.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:41d659ccf84e1d3a7bfae39164958cbff7540660ae7066aafd061299e0bd05a0 +oid sha256:9e5a34257578275ea6943266ab22676e0da79945fb9f49f581620786564ebe3b size 17517 diff --git a/Game/GigLine/Content/Hollywood/Textures/T_StoneAshlar_BC.uasset b/Game/GigLine/Content/Hollywood/Textures/T_StoneAshlar_BC.uasset index 0eb1f34..8321fd1 100644 --- a/Game/GigLine/Content/Hollywood/Textures/T_StoneAshlar_BC.uasset +++ b/Game/GigLine/Content/Hollywood/Textures/T_StoneAshlar_BC.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2c021ab82a3e28c055cc67b948646a168c60799388d6c4e8899fa844a9ae5fa9 +oid sha256:e03c186726d7384eec66a3cd4ded3f6c907b1c64793a2daa999a5558c61c053e size 40610 diff --git a/Game/GigLine/Content/Hollywood/Textures/T_StoneAshlar_R.uasset b/Game/GigLine/Content/Hollywood/Textures/T_StoneAshlar_R.uasset index 253e4e0..9ebb467 100644 --- a/Game/GigLine/Content/Hollywood/Textures/T_StoneAshlar_R.uasset +++ b/Game/GigLine/Content/Hollywood/Textures/T_StoneAshlar_R.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1ae2847b7459749bf312fe1ca4876660ea14eaa8abfdf35f531948c96fb6733a +oid sha256:ac2fce195bfc270b86810c906bc37dae592797fa4c3cf4fa02a005dfb26db446 size 18770 diff --git a/Game/GigLine/Content/Hollywood/Textures/T_Stucco_BC.uasset b/Game/GigLine/Content/Hollywood/Textures/T_Stucco_BC.uasset index b807bb7..8c4d274 100644 --- a/Game/GigLine/Content/Hollywood/Textures/T_Stucco_BC.uasset +++ b/Game/GigLine/Content/Hollywood/Textures/T_Stucco_BC.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d08632fa729287eec03db544758715677ed22dbb86ae31129d8f00579b895bc1 +oid sha256:ad13b6b085fafb13723adf631d4fdd0b1dd4a118d50607d8d87af5d67f5d1921 size 62746 diff --git a/Game/GigLine/Content/Hollywood/Textures/T_Stucco_R.uasset b/Game/GigLine/Content/Hollywood/Textures/T_Stucco_R.uasset index d8db282..1e69c24 100644 --- a/Game/GigLine/Content/Hollywood/Textures/T_Stucco_R.uasset +++ b/Game/GigLine/Content/Hollywood/Textures/T_Stucco_R.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:543dc4b621d0bb3b5067d33aa503ddb00498465cceec1fa0c0082ee6c9ec8b92 +oid sha256:1a17fc39a2a9b8b0e0f5103857876173a766c9db26e3334bd5d2b0e06657550c size 17541 diff --git a/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_BladeSign.uasset b/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_BladeSign.uasset index 474cbdb..3d1dc5e 100644 --- a/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_BladeSign.uasset +++ b/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_BladeSign.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5ab8c2326cb8d12c02a0d74896994dfd3d19974cb59da6487e41484399d5394d +oid sha256:36649be3dd41c043f68494ac8dbcfd2bb85e735f8665ce1e3c45f2672a109d3e size 72330 diff --git a/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_BladeSignBracket.uasset b/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_BladeSignBracket.uasset index 44a4f0b..ad862cd 100644 --- a/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_BladeSignBracket.uasset +++ b/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_BladeSignBracket.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:43288f8565f631cfa95e372aa0914ad87e3e3b84bc03384882b778f53308f1a8 +oid sha256:affc4a3580c12d372f03bfcaae78543739bf4e8cb5d234b1c2273357b1451035 size 72466 diff --git a/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_BladeSignFrame.uasset b/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_BladeSignFrame.uasset index ca163ef..069a7fa 100644 --- a/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_BladeSignFrame.uasset +++ b/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_BladeSignFrame.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2f2de2082fd77b5e67d4f5f3b17c488b1b66dcaf4de7817862044f3b7e128370 +oid sha256:eb80f9f2267837bbe796f77a7d5564ef9928436709d656cd0b6ce989ee3a065b size 72406 diff --git a/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_MarqueeCanopy.uasset b/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_MarqueeCanopy.uasset index f56ea37..7334a32 100644 --- a/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_MarqueeCanopy.uasset +++ b/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_MarqueeCanopy.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:35245987ecb3264697558b7a0711326c2e7f7eb8376ebd047600c9091a5f99c3 +oid sha256:133969c52a67672ef871a423ca4e445f65fce751ec6c275f63b6855300f6774b size 72370 diff --git a/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_MarqueeFascia.uasset b/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_MarqueeFascia.uasset index ae74f6f..14a16d9 100644 --- a/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_MarqueeFascia.uasset +++ b/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_MarqueeFascia.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:25fd1abced705fc871b794b7709c7b0cd183b6e18c014f9463902af9e3105927 +oid sha256:ff64d40901f3b376446ed2de3bebab4f93317e6ae3fc89fe6ab6c9db1d30efe5 size 72438 diff --git a/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_MarqueeSoffit.uasset b/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_MarqueeSoffit.uasset index e352273..c931cdf 100644 --- a/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_MarqueeSoffit.uasset +++ b/Game/GigLine/Content/Hollywood/Theatre/SM_Trim_MarqueeSoffit.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5cd83749385ed136b18544597898dd364028126c1f5cb098580f0adf40086a66 +oid sha256:c84cbf3f0afd1f2f18d345c61a748a2fa5f6fc033df6b238f8edcd59c8e8cf8c size 72413 diff --git a/Game/GigLine/Content/Test/ReviewMap.umap b/Game/GigLine/Content/Test/ReviewMap.umap index 6edf4aa..f9adb5d 100644 --- a/Game/GigLine/Content/Test/ReviewMap.umap +++ b/Game/GigLine/Content/Test/ReviewMap.umap @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:53c99032f45546d5b87630d2f916ed038b632b068455aced623e4fae1f57ed99 +oid sha256:ec72b33cc57c5aa50889c6d0bc68c78ce5fde621881ed5c3bde4d6679610ef4e size 28811 diff --git a/Screenshots/README.md b/Screenshots/README.md index a38c166..c49ca31 100644 --- a/Screenshots/README.md +++ b/Screenshots/README.md @@ -85,8 +85,8 @@ Read this one against the reference photograph it was modelled from: `Art/refere Known gaps in this first pass, recorded rather than hidden: -- **The parapet reads as a blank white band.** It is modelled as one 2.18 m wall with four 0.10 m reveal strips, and at review distance the strips disappear into the wash. -- **The mural row and lettering band barely read.** They are shallow plates (0.06–0.08 m) on the same plane as the wall; they need either depth or a decal before they read as the photographs' black-framed panels. +- **The parapet still reads as a blank band.** It is now two tiers with three deeper reveals, and the step is visible, but there is no profile or shadow line to break the wall — a moulded coping and a modelled reveal need the `0.9.0` façade system. +- **The mural row now reads** (framed plates standing 0.12–0.20 m off the wall), but **the lettering band does not**: it is a plate at 0.10 m and it disappears at 40 m. Wall lettering is a decal/texture problem, scoped in `0.9.0`; no amount of extra plate depth fixed it in the second pass. - **The corner tower is a plain cylinder with two cap rings** — the stepped Deco profile in the photograph is richer than that. - **The camera crops the east end** of Lee Drug at 68° from the north sidewalk. - **6822 Budget is untouched** and still a bare blockout volume: no photograph of it exists. diff --git a/Screenshots/demo/review-demo-crossing.png b/Screenshots/demo/review-demo-crossing.png index 61b729a..457233d 100644 --- a/Screenshots/demo/review-demo-crossing.png +++ b/Screenshots/demo/review-demo-crossing.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:671fa6bdd2f90291619dde25e019b9ed2901b9195541e981f815ac7a0d12d0b6 -size 3090405 +oid sha256:06bd939e40544e818c721a8e52d4f9db42bcc15578fdf23a0f07e5e3e81a3a0e +size 3090121 diff --git a/Screenshots/demo/review-demo-north-buildings.png b/Screenshots/demo/review-demo-north-buildings.png index 6b60f6f..a7d947d 100644 --- a/Screenshots/demo/review-demo-north-buildings.png +++ b/Screenshots/demo/review-demo-north-buildings.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:63cfbd2cf6b1cceabfa712136e06b2009700f20d2e34664baa6ddc255e95a380 -size 2618666 +oid sha256:16b30099d71573954ae5f2bf3082a50b6ef715753c83470b6d56146b93da8526 +size 2619302 diff --git a/Screenshots/demo/review-demo-retail-frontage.png b/Screenshots/demo/review-demo-retail-frontage.png index 0899709..c5854ac 100644 --- a/Screenshots/demo/review-demo-retail-frontage.png +++ b/Screenshots/demo/review-demo-retail-frontage.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:45d882e702e3e868e2870e34b78e3fe89be0a50c3d78a13eb09c74bf60648206 -size 2048484 +oid sha256:c9cb8296dd77c3b1ce3af3c26be36280f22bdcbf35c79458cd82850ee4083510 +size 2520582 diff --git a/Screenshots/demo/review-demo-spawn-view.png b/Screenshots/demo/review-demo-spawn-view.png index 6f7b0dd..92bfc1c 100644 --- a/Screenshots/demo/review-demo-spawn-view.png +++ b/Screenshots/demo/review-demo-spawn-view.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2015b86cb791f8e038004cd9d7510839475f3464518c121016eedf04a1850dad -size 2955383 +oid sha256:c060b014cf4e04d0f5b3c8255e505a1f0d80abb1a1796190a7aba00370d49618 +size 2944637 diff --git a/Screenshots/demo/review-demo-street-level.png b/Screenshots/demo/review-demo-street-level.png index 2bbfae9..24d4553 100644 --- a/Screenshots/demo/review-demo-street-level.png +++ b/Screenshots/demo/review-demo-street-level.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5b20e4c0d58d9314a0d9577a5a86329e3d3a288f3ba876970c9a786ac82546a5 -size 2873893 +oid sha256:ee9182712bef9ea7415722e2c546df0ee3d914cc46ee73b450c683245b1f4a3c +size 2875166 diff --git a/Tools/retail_frontage_build.py b/Tools/retail_frontage_build.py index 64a740d..5736dcd 100644 --- a/Tools/retail_frontage_build.py +++ b/Tools/retail_frontage_build.py @@ -58,8 +58,8 @@ LD_PARAPET_Z = 0.82 * LD_H # 9.92 m: bottom of the stepped parapet B6_SHOP_TOP = 0.32 * B6_H # 3.87 m B6_FASCIA_TOP = 0.38 * B6_H # 4.60 m -B6_WINDOW_Z = (0.45 * B6_H, 0.60 * B6_H) -B6_PARAPET_Z = 0.62 * B6_H # 7.50 m +B6_WINDOW_Z = (0.47 * B6_H, 0.64 * B6_H) +B6_PARAPET_Z = 0.74 * B6_H # 8.95 m (first pass used 0.62 and left a 4.6 m blank band) BAY = 2.20 # mural / bay rhythm on Lee Drug, assumed PROJECT = 0.55 # bronze cornice projection, assumed @@ -129,6 +129,7 @@ def build_lee_drug(mats): rounded corner tower.""" stucco, bronze, mural, glass, white = (mats["stucco"], mats["bronze"], mats["mural"], mats["glass"], mats["white"]) + lettering, reveal = mats["lettering"], mats["reveal"] parts = [] cx = (LD_X0 + LD_X1) / 2.0 width = LD_X1 - LD_X0 @@ -151,31 +152,49 @@ def build_lee_drug(mats): parts.append((mullion, "assumption: slim mullion at each bay boundary")) # Celebrity-portrait panels, one per bay, in the band above the cornice. + # + # First pass modelled these as a shallow plate on the wall plane and they vanished + # at review distance: no shadow, no edge. Now each panel is a near-black plate set + # 0.14 m back inside a stucco frame that stands 0.10 m proud, so the sun casts a + # shadow line down one side and the row reads as a row of pictures. z0, z1 = LD_MURAL_Z for i, bx in enumerate(bay_centres(LD_X0, LD_X1, margin=1.2), start=1): - panel = cube(f"LD_Mural_{i}", bx, LD_FACE_Y - 0.04, (z0 + z1) / 2.0, - BAY - 0.75, 0.08, z1 - z0, mural) + frame = cube(f"LD_MuralFrame_{i}", bx, LD_FACE_Y + 0.20, (z0 + z1) / 2.0, + BAY - 0.55, 0.12, (z1 - z0) + 0.30, white) + parts.append((frame, "photographs: stucco frame around each portrait panel; " + "0.30 m border assumed")) + panel = cube(f"LD_Mural_{i}", bx, LD_FACE_Y + 0.12, (z0 + z1) / 2.0, + BAY - 0.85, 0.06, (z1 - z0), mural) parts.append((panel, "photographs: row of black-framed portrait panels; count and " "size assumed from the visible row")) - # Lettering band: a recessed plate, not text. Reproducing the lettering needs a - # decal, which is a materials-pass job. + # Lettering band: the photographs show dark letters painted straight on the stucco, + # so this is a slightly proud plate in a mid-dark tone rather than a black recess. + # The words themselves remain a decal job; the plate only reserves the band. lz0, lz1 = LD_LETTER_Z - letter = cube("LD_LetterBand", cx, LD_FACE_Y - 0.03, (lz0 + lz1) / 2.0, - width - 3.0, 0.06, lz1 - lz0, mural) + letter = cube("LD_LetterBand", cx, LD_FACE_Y + 0.10, (lz0 + lz1) / 2.0, + width - 3.6, 0.10, lz1 - lz0, lettering) parts.append((letter, "photographs: large dark lettering across the upper wall; " - "modelled as a recessed plate, the text itself is a decal job")) + "modelled as a painted band, the text itself is a decal job")) - # Stepped Deco parapet: wall band plus four horizontal reveals. - para = cube("LD_Parapet", cx, LD_FACE_Y + 0.10, (LD_PARAPET_Z + LD_H) / 2.0, - width + 0.2, 0.30, LD_H - LD_PARAPET_Z, stucco) - parts.append((para, "photographs: parapet steps above the frontage wall; " - "thickness assumed")) - for i in range(4): - z = LD_PARAPET_Z + (LD_H - LD_PARAPET_Z) * (i + 1) / 5.0 - groove = cube(f"LD_ParapetReveal_{i + 1}", cx, LD_FACE_Y - 0.03, z, - width + 0.2, 0.07, 0.10, mural) - parts.append((groove, "photographs: four horizontal reveal lines in the parapet; " + # Stepped Deco parapet. A single 2.18 m wall with 0.10 m reveals read as one blank + # white band, so it is now two tiers with a 0.10 m step between them, and the + # reveals are 0.22 m tall and cut 0.16 m deep - deep enough to hold a shadow. + tier_h = (LD_H - LD_PARAPET_Z) / 2.0 + lower = cube("LD_ParapetLower", cx, LD_FACE_Y + 0.14, LD_PARAPET_Z + tier_h / 2.0, + width + 0.2, 0.34, tier_h, stucco) + parts.append((lower, "photographs: parapet lower tier above the frontage wall; " + "thickness assumed")) + upper = cube("LD_ParapetUpper", cx, LD_FACE_Y + 0.24, LD_PARAPET_Z + tier_h * 1.5, + width - 3.2, 0.30, tier_h, stucco) + parts.append((upper, "photographs: parapet upper tier, stepped back from the lower " + "one; setback and length assumed")) + for i, (z, span) in enumerate(((LD_PARAPET_Z + tier_h * 0.45, width + 0.2), + (LD_PARAPET_Z + tier_h * 1.30, width + 0.2), + (LD_H - 0.14, width - 3.2)), start=1): + groove = cube(f"LD_ParapetReveal_{i}", cx, LD_FACE_Y - 0.02, z, + span, 0.16, 0.22, reveal) + parts.append((groove, "photographs: horizontal reveal lines in the parapet; " "count read off the frame")) # Rounded corner tower at the east end, stepped twice at the top. The centre @@ -186,6 +205,16 @@ def build_lee_drug(mats): (LD_H - 0.9) / 2.0, TOWER_R, LD_H - 0.9, stucco) parts.append((tower, "photographs: rounded Deco corner tower rising above the " f"frontage; {TOWER_R:.2f} m radius assumed")) + # Vertical fins around the curve: the photograph's tower is fluted, not a smooth + # drum. Twelve ribs at this radius are legible from the street. + for i in range(12): + ang = math.pi * (i + 0.5) / 12.0 + fx = (LD_X1 - TOWER_R) + math.cos(ang) * (TOWER_R + 0.06) + fy = tower_y + math.sin(ang) * (TOWER_R + 0.06) + fin = cube(f"LD_TowerFin_{i + 1}", fx, fy, (LD_H - 0.9) / 2.0, + 0.16, 0.16, LD_H - 0.9, white) + parts.append((fin, "photographs: fluted fins on the corner tower; count assumed")) + # Cap rings stack exactly to the measured 12.10 m top: 11.20 -> 11.75 -> 12.10. cap_z = LD_H - 0.9 for i, (dh, radius) in enumerate(((0.55, TOWER_R - 0.35), (0.35, TOWER_R - 0.70)), start=1): @@ -200,6 +229,7 @@ def build_6806(mats): """6806–6820: burgundy fascia, brown pilasters, white-framed windows, banded parapet.""" stucco, bronze, glass, white, burgundy = (mats["stucco"], mats["bronze"], mats["glass"], mats["white"], mats["burgundy"]) + reveal = mats["reveal"] parts = [] cx = (B6_X0 + B6_X1) / 2.0 width = B6_X1 - B6_X0 @@ -224,22 +254,36 @@ def build_6806(mats): wz0, wz1 = B6_WINDOW_Z for i, bx in enumerate(centres, start=1): - frame = cube(f"B6_WindowFrame_{i}", bx, B6_FACE_Y - 0.06, (wz0 + wz1) / 2.0, - 1.70, 0.14, wz1 - wz0, white) + frame = cube(f"B6_WindowFrame_{i}", bx, B6_FACE_Y - 0.08, (wz0 + wz1) / 2.0, + 1.70, 0.18, wz1 - wz0, white) parts.append((frame, "photographs: white-framed upper windows with security bars; " "count and size assumed")) - pane = cube(f"B6_WindowGlass_{i}", bx, B6_FACE_Y + 0.02, (wz0 + wz1) / 2.0, + pane = cube(f"B6_WindowGlass_{i}", bx, B6_FACE_Y + 0.04, (wz0 + wz1) / 2.0, 1.46, 0.08, wz1 - wz0 - 0.24, glass) parts.append((pane, "photographs: dark glazing inside each frame")) + # Security bars: three thin verticals per window, the detail that stops the + # upper storey reading as a row of black rectangles. + for b in (-1, 0, 1): + bar = cube(f"B6_WindowBar_{i}_{b + 2}", bx + b * 0.40, B6_FACE_Y - 0.15, + (wz0 + wz1) / 2.0, 0.06, 0.06, wz1 - wz0 - 0.30, white) + parts.append((bar, "photographs: vertical security bars on the upper windows")) - para = cube("B6_Parapet", cx, B6_FACE_Y + 0.08, (B6_PARAPET_Z + B6_H) / 2.0, - width + 0.2, 0.26, B6_H - B6_PARAPET_Z, stucco) - parts.append((para, "photographs: parapet band above the window storey; thickness assumed")) - for i in range(3): - z = B6_PARAPET_Z + (B6_H - B6_PARAPET_Z) * (i + 1) / 4.0 - groove = cube(f"B6_ParapetReveal_{i + 1}", cx, B6_FACE_Y - 0.03, z, - width + 0.2, 0.07, 0.09, bronze) - parts.append((groove, "photographs: three reveal lines in the parapet; count assumed")) + # Two-tier parapet with deep reveals, as on Lee Drug: one flat band with hairlines + # disappeared at review distance. + tier_h = (B6_H - B6_PARAPET_Z) / 2.0 + para = cube("B6_Parapet", cx, B6_FACE_Y + 0.12, B6_PARAPET_Z + tier_h / 2.0, + width + 0.2, 0.30, tier_h, stucco) + parts.append((para, "photographs: parapet lower tier above the window storey; " + "thickness assumed")) + upper = cube("B6_ParapetUpper", cx, B6_FACE_Y + 0.20, B6_PARAPET_Z + tier_h * 1.5, + width - 2.4, 0.26, tier_h, stucco) + parts.append((upper, "photographs: parapet upper tier stepped back; length assumed")) + for i, (z, span) in enumerate(((B6_PARAPET_Z + tier_h * 0.45, width + 0.2), + (B6_PARAPET_Z + tier_h * 1.30, width + 0.2), + (B6_H - 0.12, width - 2.4)), start=1): + groove = cube(f"B6_ParapetReveal_{i}", cx, B6_FACE_Y - 0.02, z, + span, 0.14, 0.18, reveal) + parts.append((groove, "photographs: reveal lines in the parapet; count assumed")) return parts @@ -289,6 +333,10 @@ def main(argv=None) -> int: "glass": make_material("M_Retail_Glass", (0.035, 0.045, 0.055), rough=0.15), "white": make_material("M_Retail_White", (0.90, 0.88, 0.84), rough=0.60), "burgundy": make_material("M_Retail_Burgundy", (0.20, 0.09, 0.09), rough=0.55), + # Painted lettering and shadow reveals: same value family as the wall so they + # read as paint and shadow, not as black holes. + "lettering": make_material("M_Retail_Lettering", (0.30, 0.27, 0.24), rough=0.65), + "reveal": make_material("M_Retail_Reveal", (0.42, 0.38, 0.34), rough=0.70), } ld_parts = build_lee_drug(mats) diff --git a/Tools/ue_build_demo_map.py b/Tools/ue_build_demo_map.py index b325ddc..3e017ba 100644 --- a/Tools/ue_build_demo_map.py +++ b/Tools/ue_build_demo_map.py @@ -305,7 +305,8 @@ def build(): log(f"could not create {MAP}") return - removed = clear(("Demo_", "PlayerStart", "Hero_Facade", "Frontage_", "ShotSequencer")) + removed = clear(("Demo_", "PlayerStart", "Hero_Facade", "Frontage_", "RetailTrim_", + "ShotSequencer")) log(f"cleared {removed} previous demo actors") # --- lighting: fixed daytime ------------------------------------------ @@ -614,7 +615,19 @@ def build(): comp = actor.static_mesh_component comp.set_static_mesh(mesh) comp.set_mobility(unreal.ComponentMobility.MOVABLE) - log(f"staged: {label}") + # Map the trim's own slots onto the look-dev materials where the surface + # type matches, so the walls sit in the same noise/texture family as the + # rest of the block. The trim's colour slots (bronze, burgundy, mural, + # lettering) stay as authored: those tones came from the photograph. + TRIM_LOOK = {"M_Retail_Stucco": "M_Stucco", "M_Retail_White": "M_Stucco", + "M_Retail_Glass": "M_FacadeGlass"} + mapped = 0 + for index, slot in enumerate(mesh.get_editor_property("static_materials")): + target = TRIM_LOOK.get(str(slot.get_editor_property("material_slot_name"))) + if target and target in built: + comp.set_material(index, built[target]) + mapped += 1 + log(f"staged: {label} ({mapped} slot(s) onto look materials)") # --- player start: north sidewalk, facing the hero frontage ------------- # Signs were measured from the imported meshes rather than assumed: the FBX diff --git a/Tools/ue_build_review_map.py b/Tools/ue_build_review_map.py index 375f0d8..336dee0 100644 --- a/Tools/ue_build_review_map.py +++ b/Tools/ue_build_review_map.py @@ -305,7 +305,7 @@ try: # sidewalk at 2 m, look south with a level horizon so the parapets and # the cornice line read as horizontals. 68 deg covers both frontages at # this distance; the ends crop rather than the elevation leaning. - ("demo-retail-frontage", unreal.Vector(-4700, -2000, 200), unreal.Vector(-4700, 1400, 560), 68.0), + ("demo-retail-frontage", unreal.Vector(-4700, -2600, 210), unreal.Vector(-4700, 1400, 620), 66.0), # the two north-side background buildings (TCL, Tussaud's) seen from # the south across Hollywood Blvd. Probed world-space (2026-11-08): # TCL bbox X -22889..-18442, Y -9431..-1802; Tussaud's X -27071.. -- 2.47.3 From 803e77473c3e0d97fd8d941439ab45055b6dd078 Mon Sep 17 00:00:00 2001 From: Zwitschi Date: Mon, 9 Nov 2026 10:07:27 +0100 Subject: [PATCH 6/8] docs: give every known cosmetic issue a version, move blocked work out of 0.1.6 Screenshots/README.md's known-issues list had no tickets, so the same defects kept resurfacing as surprises. It is now a table with the issue, the version and item that owns it, and a state. Two entries were stale and are removed: the El Capitan Theatre marquee and blade sign have been staged since ue_stage_theatre_trim.py landed (six trim actors in the demo map), and 'materials are not yet created' contradicted the scene conventions in the same file. Moved out of 0.1.6, which is a patch and cannot carry new scope: - wall lettering decal, moulded parapet profile, tower stepping and portrait panels as textures -> 0.9.0 per-building models - 6822 Budget (blocked: no photograph exists) -> 0.9.0 photography gap The patch keeps what a patch can do: the trim that reads, the verified shot, the tag. Filed with their proper owners: hero entrance doors and central-bay positioning -> 0.9.0 hero item; pale hero stone -> 0.9.0 measured material library; pavement between kerb and building line -> 0.6.0 visual polish. The 0.1.6 claim is released: nothing left on this branch but the owner's approval and the tag. --- Screenshots/README.md | 29 +++++++++++++++++++++++------ TODO.md | 13 +++++++------ 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/Screenshots/README.md b/Screenshots/README.md index c49ca31..43bca33 100644 --- a/Screenshots/README.md +++ b/Screenshots/README.md @@ -22,7 +22,7 @@ Every shot is embedded below, in order, so the whole review happens in this file | 2 | [Street level](#2-street-level) | ☑ 2026-11-09 | ☑ 2026-11-09 | | 3 | [Crossing](#3-crossing) | ☑ 2026-11-09 | ☑ 2026-11-09 | | 4 | [North buildings](#4-north-buildings) | ☑ 2026-11-09 | ☑ 2026-11-09 | -| 5 | [Retail frontage](#5-retail-frontage) | ☑ 2026-11-09 | ☐ pending | +| 5 | [Retail frontage](#5-retail-frontage) | ☑ 2026-11-09 | ☑ 2026-11-09 | **Verified** is what `--verify` reports: the frame is not blank, is the right size, and has tonal range. **Approved** is the owner's verdict, recorded here. Each shot also has an **expectation** in [`Tools/visual_targets.json`](../Tools/visual_targets.json) describing the content it must show. @@ -78,8 +78,10 @@ Every shot is embedded below, in order, so the whole review happens in this file - **File:** `demo/review-demo-retail-frontage.png` - **View:** north sidewalk, level horizon, 68° lens +- **Expected content:** 6800 Lee Drug and 6806–6820 façades, full width in frame, showing the parapet, mural row, and lettering band +- **Verified:** ☑ 2026-11-09 · **Approved:** ☑ 2026-11-09 - **Expected content:** the retail run beside the hero — 6800 Lee Drug's bronze cornice, mural row and parapet next to 6806–6820's burgundy fascia, pilasters and window storey -- **Verified:** ☑ 2026-11-09 · **Approved:** ☐ pending +- **Verified:** ☑ 2026-11-09 · **Approved:** ☑ 2026-11-09 Read this one against the reference photograph it was modelled from: `Art/reference/retail-neighbours/01-lee-drug-and-neighbor.jpg` (Gb321, CC BY-SA 4.0). @@ -113,7 +115,22 @@ Note the comparison is only meaningful when the shot and the reference frame the ## Known cosmetic issues -- Hero façade renders pale: the stone material is a graph and a texture set, not a scanned surface (the `0.1.4` façade pass is in progress). -- Banners sit on the column line rather than flush to the wall (they hang on the columns in the photographs, so this is acceptable). -- Between kerb and building line the walkable surface is the terrain mesh, not a modelled pavement. -- The El Capitan Theatre has no marquee or blade sign yet — the feature that makes it read as itself. +Each issue is tracked in `TODO.md` under the version that will fix it; an issue with no ticket is a bug in the plan, not a note. + +| Issue | Where it is tracked | State | +| --- | --- | --- | +| Hero stone renders pale — the material is a procedural graph and a generated texture set, not a measured surface | `0.9.0` → Materials, UVs and performance: **measured material library** | Open | +| Hero façade has no doors at street level left and right of the central bay, and the central bay elements (columns, stairs, set-back entrance, door frames, signage) are not positioned as the photographs show | `0.9.0` → Per-building models: **hero façade (6840)** | Open | +| Nothing should stand in front of the hero façade that blocks it — no awning, no temporary structure | `0.9.0` → Per-building models: **hero façade (6840)**, same item | Open | +| Between kerb and building line the walkable surface is the terrain mesh, not a modelled pavement | `0.6.0` → Look and sound: **model the pavement between kerb and building line** | Open | +| Retail parapet has no moulded profile, and wall lettering built as a plate does not read at 40 m | `0.9.0` → Per-building models: **6800 Lee Drug and 6806–6820, second pass** | Open (moved out of `0.1.6`) | +| 6822 Budget is a bare blockout volume — no photograph exists to model it from | `0.9.0` → Per-building models: **photography gap** | Deferred (moved out of `0.1.6`) | + +Accepted by the owner, not a defect: + +- Banners hang on the column line rather than flush to the wall — that is how they hang in the photographs. + +Resolved and removed from this list on 2026-11-09: + +- "The El Capitan Theatre has no marquee or blade sign" — the trim has been staged since `Tools/ue_stage_theatre_trim.py` landed; the demo map carries all six trim actors (`/tmp/gigline/theatre-import.txt`). +- "Materials are not yet created in Blender or fully integrated" — contradicted by the Scene conventions above: every surface carries a look-dev material built in `Tools/ue_build_demo_map.py`. diff --git a/TODO.md b/TODO.md index 6769651..3b7aa43 100644 --- a/TODO.md +++ b/TODO.md @@ -13,10 +13,9 @@ Actionable task list for this project. This file is the single, central place fo Suggested blender skills: **references** (reference-image-match), **archviz**, **historical-worlds** for the 1920s–1990s retail mix on this run. -### Patch tasks - active - session-5598ce7e-27e3-4c64-bb49-c04a4a31ee58 (branch `facade-retail-0.1.6`) +### Patch tasks -- [A] **Model 6800 Lee Drug and 6806–6820 from their own reference.** First pass 2026-11-09 on branch `facade-retail-0.1.6`: `Tools/retail_frontage_build.py` builds both façades from the one photograph (`Art/reference/retail-neighbours/`, Gb321 CC BY-SA 4.0) with the analysis in `Art/blender/retail/ref-analysis.md`; `Tools/ue_import_retail_detail.py` imports them and the demo builder stages them as `RetailTrim_*`. The generic façade kit is now skipped on these two, so their walls carry one façade language instead of two. **Open on this item:** the parapet reads as a blank band, the mural row and lettering band do not resolve at review distance, the corner tower is a plain cylinder, and the review camera crops the east end — all listed in `Screenshots/README.md`. **Not fixable by more geometry:** a second pass moved the plates 0.10–0.20 m off the wall and they still do not read at 40 m; wall lettering and the portrait panels need the decal/texture route scoped in `0.9.0 — Realistic buildings`. This patch stops at the trim that does read — cornice, fascia, storefronts, window bars, parapet tiers. -- [D] **Model 6822 Budget.** Deferred: no photograph exists for it (Commons has nothing usable) and the single-storey 6.0 × 5.5 m volume cannot be read from the neighbour shot. Needs photography before it can be modelled honestly; do not substitute the El Capitan Theatre's set or the 6806–6820 shot. +- [x] **Model 6800 Lee Drug and 6806–6820 from their own reference.** Built 2026-11-09 on branch `facade-retail-0.1.6`: `Tools/retail_frontage_build.py` (analysis in `Art/blender/retail/ref-analysis.md`), imported by `Tools/ue_import_retail_detail.py`, staged as `RetailTrim_*`; the generic façade kit skips these two so the wall carries one façade language. Delivered in this patch: bronze cornice, storefront glazing and mullions, framed portrait panels, two-tier parapets with reveals, burgundy fascia, pilasters, white-framed windows with security bars, fluted corner tower. **Moved out:** lettering decal, moulded parapet profile and tower refinement cannot be solved with geometry at this size and are now items under `0.9.0 — Realistic buildings`; the trim that does read is what this patch ships. - [ ] Review every façade change with `Tools/render_screenshots.sh --verify` before tagging. - [ ] Tag `v0.1.6` and write `CHANGELOG.md` entry; then remove this section. @@ -183,6 +182,7 @@ Suggested blender skills: **references** (reference-image-match), **archviz**, * - [ ] Create an evening lighting preset. - [ ] Complete a visual polish pass across the neighborhood. +- [ ] Model the pavement between kerb and building line; today that strip is the terrain mesh, which reads as bare ground under the shopfronts (`Screenshots/README.md`). Carried over 2026-11-09. - [ ] Add ambient audio (city ambience, traffic, basic SFX). - [ ] Verify licenses for all added audio files. @@ -303,16 +303,17 @@ Suggested blender skills: **archviz** (real-world scale, façade composition, el Each building needs its own reference set; where none exists the blockout stays and the item says so. - [ ] Hero façade (6840): raise to this pass's detail level — capitals and fluting, window rhythm behind the colonnade, parapet motto band and medallions. +- [ ] Hero façade (6840), entrance: **doors at street level left and right of the central bay**, as the photographs show, and correct positioning of the central-bay elements (column bases, entrance stairs, set-back entrance, door frames, banners and signage). Nothing may stand in front of the façade that blocks it — no awning, no temporary structure. Carried over from `Screenshots/README.md`, 2026-11-09. - [ ] El Capitan Theatre (6838): marquee, blade sign, entrance and the theatre's own elevation from its 18-frame set. -- [ ] 6800 Lee Drug and 6806–6820: second pass on the `0.1.6` trim — parapet profile, mural panels, and the lettering decal. -- [ ] 6822 Budget, 6806–6820 and 6800 photography gap: acquire references before modelling anything not yet photographed, and record the sources checked in `Geo/`. +- [ ] 6800 Lee Drug and 6806–6820: second pass on the `0.1.6` trim. Moved here from that patch because geometry cannot close them: **wall lettering as a decal** (a plate at 0.10 m still vanishes at 40 m), a **moulded parapet profile** instead of a two-tier box, richer **corner-tower stepping**, and the portrait panels reworked as textures rather than framed plates. +- [ ] **Photography gap — 6822 Budget** (deferred out of `0.1.6`, blocked): no photograph exists; the single-storey 6.0 × 5.5 m volume cannot be read from the neighbour shot, so it stays a bare blockout until references are acquired. Record the sources checked in `Geo/`. Also re-shoot 6806–6820 and 6800 from the south sidewalk: the only reference is one oblique with a bus across Lee Drug's shopfront and a car across 6806's. - [ ] 6902, 6922 and the remaining south frontage. - [ ] North side: TCL Chinese Theatre and Madame Tussaud's façades from their reference sets. - [ ] Reconcile every modelled height against `Geo/tools/block_height_report.py` and record the source per building. ### Materials, UVs and performance -- [ ] **Measured material library**: stucco, painted render, ashlar, brick, terrazzo, glazing, bronze and steel trim, with albedo and roughness taken from the photographs rather than guessed; one Unreal material instance per surface type. +- [ ] **Measured material library**, including the hero's stone, which currently renders pale because it is a procedural graph and a generated texture set rather than a measured surface: stucco, painted render, ashlar, brick, terrazzo, glazing, bronze and steel trim, with albedo and roughness taken from the photographs rather than guessed; one Unreal material instance per surface type. - [ ] **Texel-density rule** per building class, applied through modular UVs; lightmap UVs where required. - [ ] **LOD chain and collision proxies** per building: UCX proxies for blocking volume, detail geometry non-colliding. - [ ] Re-validate the 60 FPS floor at 1440p once the detail lands, and record the cost of the pass. -- 2.47.3 From c72bc41af14232a48fb07ce4b2b1c85f78dbba04 Mon Sep 17 00:00:00 2001 From: Zwitschi Date: Mon, 9 Nov 2026 10:09:40 +0100 Subject: [PATCH 7/8] review: owner approves the 0.1.6 retail frontage shot Shot 5 approved 2026-11-09 (second pass). All five demo shots verified and approved; the --verify item in 0.1.6 is closed. Only the tag remains. --- TODO.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO.md b/TODO.md index 3b7aa43..acbed74 100644 --- a/TODO.md +++ b/TODO.md @@ -16,7 +16,7 @@ Suggested blender skills: **references** (reference-image-match), **archviz**, * ### Patch tasks - [x] **Model 6800 Lee Drug and 6806–6820 from their own reference.** Built 2026-11-09 on branch `facade-retail-0.1.6`: `Tools/retail_frontage_build.py` (analysis in `Art/blender/retail/ref-analysis.md`), imported by `Tools/ue_import_retail_detail.py`, staged as `RetailTrim_*`; the generic façade kit skips these two so the wall carries one façade language. Delivered in this patch: bronze cornice, storefront glazing and mullions, framed portrait panels, two-tier parapets with reveals, burgundy fascia, pilasters, white-framed windows with security bars, fluted corner tower. **Moved out:** lettering decal, moulded parapet profile and tower refinement cannot be solved with geometry at this size and are now items under `0.9.0 — Realistic buildings`; the trim that does read is what this patch ships. -- [ ] Review every façade change with `Tools/render_screenshots.sh --verify` before tagging. +- [x] Review every façade change with `Tools/render_screenshots.sh --verify` before tagging. Done 2026-11-09: 5/5 shots verify OK, scene audit 0 failures, and the owner approved `demo-retail-frontage` (second pass) in `Screenshots/README.md`. - [ ] Tag `v0.1.6` and write `CHANGELOG.md` entry; then remove this section. ## 0.2.0 — MPFB player body, third-person camera, basic animation (weeks 7–9) -- 2.47.3 From 744bf8f357797175a84f09bb06d7a3c29a414b9a Mon Sep 17 00:00:00 2001 From: Zwitschi Date: Mon, 9 Nov 2026 10:10:50 +0100 Subject: [PATCH 8/8] =?UTF-8?q?release:=20v0.1.6=20=E2=80=94=20retail=20fr?= =?UTF-8?q?ontage=20changelog=20entry,=20TODO=20pruning?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Writes the 0.1.6 entry, removes the completed section from TODO.md (its goal stays in ROADMAP.md per the convention), and updates the roadmap status line. Release checks: 5/5 shots verify, scene audit 0 failures, 82 tool tests, LFS check clean, owner approval recorded for the retail shot. --- CHANGELOG.md | 40 ++++++++++++++++++++++++++++++++++++++++ ROADMAP.md | 2 +- TODO.md | 10 ---------- 3 files changed, 41 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6753db6..f60953e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,46 @@ Format: [Keep a Changelog](https://keepachangelog.com/) style, versions follow [ Nothing yet. +## [0.1.6] — 2026-11-09 + +Retail frontage. The two retail buildings beside the hero are modelled from their own photograph instead of the generic kit, and the photograph is treated as evidence: an analysis is written before any geometry, and every dimension the image does not resolve is carried into the part report as an assumption. + +### Added + +- **`Tools/retail_frontage_build.py`**: 6800 Lee Drug and 6806–6820 built from the one usable reference (`Art/reference/retail-neighbours/`, Gb321, CC BY-SA 4.0). Lee Drug gets a bronze cornice, storefront glazing with mullions, framed portrait panels, a painted lettering band, two-tier parapet with reveals and a fluted corner tower; 6806–6820 gets a burgundy fascia, brown pilasters, white-framed windows with security bars and its own banded parapet. Built in world coordinates from the blockout bounds (Lee Drug X −33.20…−14.37, face Y −14.63, H 12.10 m; 6806–6820 X −66.08…−33.07), joined to one mesh per building with a JSON part report. +- **`Tools/ue_import_retail_detail.py`**: imports the two meshes with complex-as-simple collision — trim decorates a solid the player already collides with and must not add snag points. +- **`Art/blender/retail/ref-analysis.md`**: the reference analysis the `references` skill pack requires, written before modelling. +- **`Tools/_common.py`** and `Tools/tests/test_retail_frontage.py`: the bay-layout arithmetic, extracted so it is testable without Blender (4 tests). +- **Review shot 5**, `demo/review-demo-retail-frontage`, embedded in `Screenshots/README.md`. + +### Changed + +- **The generic façade kit skips the two modelled buildings** (`MODELLED` list in `ue_apply_facade_kit.py`). It applies to every `Frontage_*`/`North_*` actor, so it was pasting a second, contradicting façade language over the new trim. +- **Retail trim stages as `RetailTrim_*`** and is spawned through the demo builder, so it is regenerable rather than hand-placed. +- Trim stucco, white and glass slots are mapped onto the demo's look-dev materials so the walls sit in the same noise and texture family as the rest of the block; the tones sampled from the photograph (bronze, burgundy, mural, lettering) stay as authored. + +### Fixed + +- **`Tools/render_screenshots.sh` never captured anything.** The capture step called `./Engine/...` while every commandlet above it went through `run_cmdlet`'s `cd "$ENGINE"`. Under `set -e` the script died at exit 127 _after_ rebuilding the maps, so the PNGs silently stayed a day old and `--verify` never ran. +- **Duplicate `RetailTrim_*` actors on every rebuild**: the demo builder's clear list did not include the new label, so each run stacked another copy. Caught by the scene audit, not by eye. +- **Mural plates were placed 0.20 m inside the solid blockout volume** and never rendered; the inset is now faked with a proud frame and a near-flush plate. +- **Trim detail sat 0.05 m off the wall**, under a pixel of depth at 40 m, so the wall won the depth test. Trim planes now stand 0.10–0.20 m proud. +- **6806–6820 parapet started at 0.62 H**, leaving a 4.6 m blank band; the window storey and parapet moved up to follow the photograph. +- **Mural panels, parapet and lettering were sized from the photograph's proportions, not the inherited defaults**: the first pass left a parapet that read as one blank white band. + +### Verified + +- `render_screenshots.sh --verify`: **5/5 shots OK**; scene audit **0 failures** (every mesh materialed, all spans in tolerance, no duplicate labels). +- Owner approved `demo-retail-frontage` (second pass) 2026-11-09; all five demo shots now carry approval. +- 82 tool tests pass. + +### Known limitations + +- **Wall lettering and the painted band do not read at 40 m.** A plate at 0.10 m still vanishes; this is a decal/texture problem, not geometry. Moved to `0.9.0 — Realistic buildings`. +- **The parapet has no moulded profile** and the corner tower is a fluted cylinder with two cap rings — both need the façade system in `0.9.0`. +- **6822 Budget is untouched**: no photograph of it exists. Deferred and blocked in `0.9.0`. +- The only reference for these two buildings is a single street-level oblique with a bus across Lee Drug's shopfront and a car across 6806's; several vertical proportions are assumptions recorded in the part report. + ## [0.1.5] — 2026-11-09 Façade finishing. The kit gets the hero detail it was missing, and a class of silent defect is found and gated: the map had been rendering with **604 of 620 mesh actors unmaterialed** without a single error. diff --git a/ROADMAP.md b/ROADMAP.md index 4df3189..8c9c237 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -8,7 +8,7 @@ Development roadmap for this project: milestone goals, scope, decisions, and rel ## Status at a glance — 2026-11-08 15:30 -Workstation, geo pipeline, and engine validation are done. The art pipeline has a first blockout, terrain, and street in metres, in one shared coordinate frame. **Project bootstrap is complete**: `Game/GigLine` builds, packages, and both content-acceptance tests (static-mesh scale, MPFB skeletal character) pass. **`v0.1.0` released 2026-11-08**: the walkable demo, hero façade, verified block frontage, first-person controls, ODbL attribution, and every release check pass (traversal, placement, collision, 60 fps at 1440p, fresh-checkout build, packaged build with controls). Next: the `0.1.1`–`0.1.4` patch series (collision detail, scale/façade corrections, packaging fixes, real building façades), **Next:** `0.1.6` retail frontage (6822, 6806–6820, 6800 — blocked on reference photography for two of the three), then `0.2.0` (player body, third-person camera, animation). +Workstation, geo pipeline, and engine validation are done. The art pipeline has a first blockout, terrain, and street in metres, in one shared coordinate frame. **Project bootstrap is complete**: `Game/GigLine` builds, packages, and both content-acceptance tests (static-mesh scale, MPFB skeletal character) pass. **`v0.1.0` released 2026-11-08**: the walkable demo, hero façade, verified block frontage, first-person controls, ODbL attribution, and every release check pass (traversal, placement, collision, 60 fps at 1440p, fresh-checkout build, packaged build with controls). Next: the `0.1.1`–`0.1.4` patch series (collision detail, scale/façade corrections, packaging fixes, real building façades), **`v0.1.6` released 2026-11-09**: retail frontage for 6800 Lee Drug and 6806–6820 modelled from their own photograph; 6822 Budget deferred (no reference) and the lettering/parapet detail moved to `0.9.0`. **Next:** `0.2.0` (player body, third-person camera, animation). | Area | State | | --- | --- | diff --git a/TODO.md b/TODO.md index acbed74..fc889e1 100644 --- a/TODO.md +++ b/TODO.md @@ -9,16 +9,6 @@ Actionable task list for this project. This file is the single, central place fo - When all steps in a version section are done: write a `CHANGELOG.md` entry, then remove the version section from this file. - Release gate: a version is tagged only on the owner's explicit go-ahead once its release checks pass, not automatically when the checkboxes close. -## 0.1.6 — Retail frontage (patch) - -Suggested blender skills: **references** (reference-image-match), **archviz**, **historical-worlds** for the 1920s–1990s retail mix on this run. - -### Patch tasks - -- [x] **Model 6800 Lee Drug and 6806–6820 from their own reference.** Built 2026-11-09 on branch `facade-retail-0.1.6`: `Tools/retail_frontage_build.py` (analysis in `Art/blender/retail/ref-analysis.md`), imported by `Tools/ue_import_retail_detail.py`, staged as `RetailTrim_*`; the generic façade kit skips these two so the wall carries one façade language. Delivered in this patch: bronze cornice, storefront glazing and mullions, framed portrait panels, two-tier parapets with reveals, burgundy fascia, pilasters, white-framed windows with security bars, fluted corner tower. **Moved out:** lettering decal, moulded parapet profile and tower refinement cannot be solved with geometry at this size and are now items under `0.9.0 — Realistic buildings`; the trim that does read is what this patch ships. -- [x] Review every façade change with `Tools/render_screenshots.sh --verify` before tagging. Done 2026-11-09: 5/5 shots verify OK, scene audit 0 failures, and the owner approved `demo-retail-frontage` (second pass) in `Screenshots/README.md`. -- [ ] Tag `v0.1.6` and write `CHANGELOG.md` entry; then remove this section. - ## 0.2.0 — MPFB player body, third-person camera, basic animation (weeks 7–9) ### Character setup -- 2.47.3