Clear the firefighter helmet brim from the brow

The face pass added a brow ridge; lift the helmet mesh 2 cm so the brim sits
above the eyes. Cap and hood were rendered on their characters and leave the
brow/ears and face readable. Rebuild and re-bake the helmet; Python 87/87.
This commit is contained in:
zwitschi committed 2026-11-01 18:02:38 +01:00
1 parent 702f54ae53
commit a478bfbf35
6 files changed
+15 -5

No files matched your search

+4 -1
View File
@@ -15,7 +15,10 @@ Session memory for durable decisions, state, and gotchas. Keep concise, remove o
(7 match / 4 review / 0 diff); `--model` remains available. (7 match / 4 review / 0 diff); `--model` remains available.
- `capture_realism.gd` parses `--portrait-type=N`; it was documented but ignored before the gear - `capture_realism.gd` parses `--portrait-type=N`; it was documented but ignored before the gear
pass. Portrait captures need the requested NPC type to have spawned, otherwise the stage can pass. Portrait captures need the requested NPC type to have spawned, otherwise the stage can
finish with an empty frame; use the Blender `npc_coat` preview for a deterministic gear check. finish with an empty frame; use the Blender character previews (`render --only npc_coat`) for
deterministic gear checks.
- Headgear: the firefighter helmet was lifted 2 cm after the brow/face pass; cap and hood were
visually checked on `npc_vest`/`npc_hoodie`. The beanie is unused and shares the cap shell.
- Gear fit is measured with `python3 tools/blender_assets.py fit` (stdlib, reads the GLBs): - Gear fit is measured with `python3 tools/blender_assets.py fit` (stdlib, reads the GLBs):
head width uses skin vertices weighted to Head in y 1.55–1.81; clothing radius is the cloth head width uses skin vertices weighted to Head in y 1.55–1.81; clothing radius is the cloth
skirt in y 0.30–0.52 with a pants hip fallback. The command reports per-character gear boxes, skirt in y 0.30–0.52 with a pants hip fallback. The command reports per-character gear boxes,
+5 -2
View File
@@ -25,8 +25,11 @@ live in `tools/blender_assets.py` (`_build_gear()`), the contract in `docs/blend
moved it outboard (centre x=0.292); the body's inner face is now 0.262 m, clearing the coat moved it outboard (centre x=0.292); the body's inner face is now 0.262 m, clearing the coat
(0.225) by 0.037 m and the dress (0.260) by 0.002 m. The strap's lower attach points sit on (0.225) by 0.037 m and the dress (0.260) by 0.002 m. The strap's lower attach points sit on
the same outboard line. `fit` now measures the bag body separately from the torso strap. the same outboard line. `fit` now measures the bag body separately from the torso strap.
- [ ] Same pass for `cap`/`beanie`/`hood`/`firefighter_helmet`: they must not clip the new - [x] Same pass for `cap`/`beanie`/`hood`/`firefighter_helmet`: rendered the cap (vest), hood
brow/ear geometry, and `hood` must still leave the face readable for hoodie avatars. (hoodie), and firefighter helmet on their characters. Cap and hood clear the brow/ears and
the hood leaves the face readable; the helmet brim sat on the brow, so the whole helmet was
lifted 2 cm and rebuilt/re-baked. Beanie uses the same capped-shell sizing as the cap and is
currently unused; it is covered by the upcoming headgear regression check.
- [ ] Rebuild the gear (`build`) and re-bake AO (`tools/bake_ao.py`), then - [ ] Rebuild the gear (`build`) and re-bake AO (`tools/bake_ao.py`), then
`godot --headless --path . --import`. `godot --headless --path . --import`.
- [ ] Add a regression test: `tools/test_blender_assets.py` checks the glasses width against the - [ ] Add a regression test: `tools/test_blender_assets.py` checks the glasses width against the
+2 -2
View File
@@ -287,12 +287,12 @@
"bounds_godot": { "bounds_godot": {
"max": [ "max": [
0.26, 0.26,
0.225, 0.245,
0.26 0.26
], ],
"min": [ "min": [
-0.26, -0.26,
0.015, 0.035,
-0.351 -0.351
] ]
}, },
Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

+4
View File
@@ -996,6 +996,10 @@ def build_gear(name):
scale=(1.0, 1.08, 1.0))) scale=(1.0, 1.08, 1.0)))
p.append(box("Ridge", (0.03, 0.34, 0.05), (0, 0.0, 0.2), M("helmet"), bevel=0.01)) p.append(box("Ridge", (0.03, 0.34, 0.05), (0, 0.0, 0.2), M("helmet"), bevel=0.01))
p.append(box("Shield", (0.09, 0.012, 0.09), (0, -0.2, 0.11), M("brass"), bevel=0.01)) p.append(box("Shield", (0.09, 0.012, 0.09), (0, -0.2, 0.11), M("brass"), bevel=0.01))
# The 2026-11-01 face pass added a brow ridge; lift the helmet 2 cm so
# the brim sits above the eyes instead of cutting into the brow.
for obj in p:
obj.data.transform(Matrix.Translation((0, 0, 0.02)))
# Back gear: origin = spine centre (Godot 0, 1.10, 0); +Y Blender = behind. # Back gear: origin = spine centre (Godot 0, 1.10, 0); +Y Blender = behind.
elif name == "backpack": elif name == "backpack":
p.append(box("Pack", (0.30, 0.15, 0.40), (0, 0.20, 0.08), M("pack_nylon"), p.append(box("Pack", (0.30, 0.15, 0.40), (0, 0.20, 0.08), M("pack_nylon"),