diff --git a/TODO.md b/TODO.md index 2c7c2e5..788ea9f 100644 --- a/TODO.md +++ b/TODO.md @@ -21,6 +21,12 @@ separate sources: licensed real-location photos, generated concept boards, and b is an unversioned development track: it must not change the `npc_base` contract, the renderer or the 0.10.0 release candidate. +**Sequencing (2026-11-03, owner):** the asset-review fixes (A–G, notably the character P0/P1 +rebuilds and the face/foliage prototypes) stay **blocked** until the full local map rebuild +(H–M) is done **and** a fresh 3D model review runs against the new maps. The measurements and +scorecard in `docs/3d-model-review.md` stand as the pre-rebuild baseline, not a go-ahead to start +character work now. Character development stays gated behind that second review. + Reference material is collected first (section A): local, gitignored, development-only photo research may use any source the owner authorises (DuckDuckGo image search, street-view frames, neighbouring properties, buildings across the street) **without the licence gate**. The licence @@ -96,7 +102,8 @@ licence-free zone only. `texels` and `inspect --json --out` were added to make the measurements repeatable. All 46 assets audit/inspect clean; texel density 64–122 px/m authored, 287–440 effective fabric.) - [ ] Review the scorecard with the project owner, rank the P0/P1 gaps and decide fix vs accept - per item; record the decision and the reason in the review document. + per item; record the decision and the reason in the review document. **Deferred until the + full map rebuild (H–M) lands and a fresh 3D review runs against the new maps.** ### C. Character re-evaluation (8 variants + fallback) @@ -142,7 +149,8 @@ licence-free zone only. plus stride scaling are the accepted approach; a baked cloth-sim pipeline would only be reconsidered if a later close-up shows visible hem/coat stiffness. - [ ] Fix only the ranked P0/P1s, one asset family per commit; refresh the comparison sheet and - re-run `inspect`, `audit`, `fit` and `npc_proportions.py` after each fix. + re-run `inspect`, `audit`, `fit` and `npc_proportions.py` after each fix. **Blocked until + the map rebuild + second 3D review (see the track's sequencing note).** - [ ] Build a licensed real-photo reference board for crowd variety (ages, builds, hair, outer layers) and record what was adopted; reference only, never traced or repainted. - [ ] Generate a face/hand concept board for the highest-ranked P1 and compare it with the 0.9.4 diff --git a/assets/models/blender/manifest.json b/assets/models/blender/manifest.json index 5823c26..51ca86e 100644 --- a/assets/models/blender/manifest.json +++ b/assets/models/blender/manifest.json @@ -48,28 +48,6 @@ "triangles": 380, "vertices": 408 }, - "beanie": { - "attach": "head", - "bounds_godot": { - "max": [ - 0.193, - 0.215, - 0.183 - ], - "min": [ - -0.193, - 0.014, - -0.203 - ] - }, - "category": "npc_gear", - "materials": [ - "plastic_grey" - ], - "path": "assets/models/blender/npc_gear/beanie.glb", - "triangles": 460, - "vertices": 403 - }, "bench": { "bounds_godot": { "max": [ @@ -1246,4 +1224,4 @@ "head": "Rig/Head marker (y = 1.62 m, head centre)" }, "generator": "tools/blender_assets.py" -} +} \ No newline at end of file diff --git a/assets/models/blender/npc_gear/beanie.glb b/assets/models/blender/npc_gear/beanie.glb deleted file mode 100644 index 47d336d..0000000 Binary files a/assets/models/blender/npc_gear/beanie.glb and /dev/null differ diff --git a/assets/models/blender/npc_gear/beanie_ao.png b/assets/models/blender/npc_gear/beanie_ao.png deleted file mode 100644 index 7eb6380..0000000 Binary files a/assets/models/blender/npc_gear/beanie_ao.png and /dev/null differ diff --git a/docs/3d-model-review.md b/docs/3d-model-review.md index 0d908b4..d277b5a 100644 --- a/docs/3d-model-review.md +++ b/docs/3d-model-review.md @@ -103,7 +103,6 @@ yet reviewed; this document is the place to fill it. | Gear | Attach | Tris | Verdict | | --- | --- | --- | --- | | `cap` | head | 328 | — (fit measured, visual pending) | -| `beanie` | head | 460 | — (unused by any character) | | `hood` | head | 804 | — | | `sunglasses` | head | 164 | accept (0.9.4 clearance) | | `firefighter_helmet` | head | 672 | accept (0.9.4 + 3 cm runtime offset) | @@ -130,7 +129,8 @@ head band at 0.64× head width. Three caveats worth recording, none of which cha measured against the **hip/skirt** radius, which is wider than the upper back where the bags actually sit; `cap` and `firefighter_helmet` report `band=OUTSIDE` because they sit on the crown above the 1.55–1.81 face/head band (expected); and the `lanyard` clip is corrected at runtime by -`GEAR_OFFSETS` (+4 cm forward). `beanie` is unused and remains a retire/reassign candidate. +`GEAR_OFFSETS` (+4 cm forward). The unused `beanie` was retired on 2026-11-03 (removed from +`GEAR`, its builder, `npc_avatar.gd` and the manifest). ### Props (20 library + 6 generated fallbacks) @@ -249,7 +249,7 @@ owner review decides. palm with `HAND_ITEM_FORWARD`; no finger bones exist, so a curl rig is a contract decision, not a modelling tidy-up. 7. **Gear never reviewed as silhouette language (P2).** 18 pieces pass fit/contract but have no - prop-artist verdict; `beanie` is unused and could be retired or reassigned. + prop-artist verdict (the unused `beanie` was retired 2026-11-03). 8. **Venue shape language (P2).** Hollywood and the Joke Shop have budget data but no `environment-artist`/`archviz` review; the TV Studio has no recorded map-budget number in this document yet. diff --git a/docs/blender-assets.md b/docs/blender-assets.md index 3be54a6..b12d4b4 100644 --- a/docs/blender-assets.md +++ b/docs/blender-assets.md @@ -21,7 +21,7 @@ captures in `docs/screenshots/`. - **People** (`targeting_npc`, `joke_shop_queue`, `studio_arrival`, `crowd_panic`, `responder_arrival`): ordinary adults in sweaters, jackets, - long coats, hoodies and beanies; a security guard in a dark uniform with a cap + long coats and hoodies; a security guard in a dark uniform with a cap and belt; a firefighter in a dark turnout coat with yellow reflective bands, a helmet and an SCBA tank. The current skinned `npc_base` is a set of boxes and cylinders with a flat face, so silhouette was the main gap. @@ -145,7 +145,7 @@ attach point: | Attach | Godot parent / position | Gear | | --- | --- | --- | -| `head` | `Rig/Head` marker (0, 1.62, 0) | cap, beanie, hood, sunglasses, firefighter_helmet | +| `head` | `Rig/Head` marker (0, 1.62, 0) | cap, hood, sunglasses, firefighter_helmet | | `back` | `Rig` at (0, 1.10, 0), spine centre; items sit behind the body (Blender +Y = Godot −Z) | backpack, shoulder_bag, scba_tank | | `chest` | `Rig` at (0, 1.30, 0), sternum | lanyard | | `hand` | Hand proxy (±0.27, 0.78, 0.02); grip 5 cm below the origin | phone, cup, clipboard, umbrella, camera, protest_sign, flashlight, wand, radio | diff --git a/docs/npc-visual-review.md b/docs/npc-visual-review.md index 1b2d61a..e326081 100644 --- a/docs/npc-visual-review.md +++ b/docs/npc-visual-review.md @@ -78,7 +78,7 @@ pass every applicable item before a library rebuild is accepted. the head volume has a readable jaw/cheek/chin transition; no face-plane seams, inverted normals or z-fighting. The face direction must remain unambiguous. 4. **Hair and headgear:** hair covers the scalp without gaps or scalp-through - seams; fringes, buns and beards keep their silhouette. Caps, beanies, hoods, + seams; fringes, buns and beards keep their silhouette. Caps, hoods, sunglasses and the firefighter helmet clear the brow, eyes and ears. Headgear may sit outside the 1.55–1.81 m face band, but its brim must not cover the eyes. diff --git a/src/game/npc_avatar.gd b/src/game/npc_avatar.gd index a34ac07..88301b1 100644 --- a/src/game/npc_avatar.gd +++ b/src/game/npc_avatar.gd @@ -185,7 +185,7 @@ const GEAR_OFFSETS := { ## item forward into the open palm. const HAND_ITEM_FORWARD := Vector3(0, 0, 0.04) const GEAR_ATTACH := { - "cap": "head", "beanie": "head", "hood": "head", "sunglasses": "head", + "cap": "head", "hood": "head", "sunglasses": "head", "firefighter_helmet": "head", "backpack": "back", "shoulder_bag": "back", "scba_tank": "back", "lanyard": "chest", diff --git a/tools/blender_assets.py b/tools/blender_assets.py index dd4e0de..2f8489f 100644 --- a/tools/blender_assets.py +++ b/tools/blender_assets.py @@ -123,7 +123,7 @@ FIT_HIP_BAND = (0.55, 0.95) # fallback body radius for trousers/vests # tell where the bag body starts. Measure the body-only y band for this fit. FIT_BODY_BANDS = {"shoulder_bag": (-0.34, -0.16)} GEAR = { - "cap": "head", "beanie": "head", "hood": "head", "sunglasses": "head", + "cap": "head", "hood": "head", "sunglasses": "head", "firefighter_helmet": "head", "backpack": "back", "shoulder_bag": "back", "scba_tank": "back", "lanyard": "chest", @@ -1060,10 +1060,6 @@ def build_gear(name): p.append(cyl("Brim", 0.11, 0.11, 0.012, (0, -0.17, 0.055), M("plastic_black"), seg=16, scale=(1.0, 0.8, 1.0), rot=(math.radians(-8), 0, 0))) p.append(sphere("Button", 0.014, (0, 0.01, 0.195), M("plastic_black"), seg=8, rings=4)) - elif name == "beanie": - p.append(sphere("Knit", 0.172, (0, 0.01, 0.04), M("plastic_grey"), seg=20, rings=12, - scale=(1.0, 1.04, 1.02), cut_below=-0.05)) - p.append(torus("Cuff", 0.163, 0.03, (0, 0.01, 0.04), M("plastic_grey"), seg=20)) elif name == "hood": p.append(_hood("Hood", M("plastic_grey"), (0, 0, 0.015))) elif name == "sunglasses":