Audit NPC body proportions against a shared guide
Measure all eight exported characters and record the stylized proportion bands. All variants pass; no skeleton or mesh rescale was needed.
This commit is contained in:
1 parent
7c1a4bfd69
commit
ab9c67d266
10 files changed
+329
-3
No files matched your search
@@ -12,6 +12,7 @@ This folder holds the project documentation, visual references and generated QA
|
||||
- [`getting-started.md`](getting-started.md) — setup, run/test commands and controls
|
||||
- [`asset-tooling.md`](asset-tooling.md) — image/model pipelines and screenshot gates
|
||||
- [`npc-visual-review.md`](npc-visual-review.md) — NPC visual baseline, acceptance criteria and ranked gaps
|
||||
- [`npc-proportion-audit.md`](npc-proportion-audit.md) — NPC proportion ratios and stylized guide results
|
||||
- [`development-status.md`](development-status.md) — implemented features and current gaps
|
||||
- [`smoke-checklist.md`](smoke-checklist.md) — manual verification
|
||||
- [`ui-copy.md`](ui-copy.md) — screen, copy and button inventory
|
||||
|
||||
@@ -213,6 +213,11 @@ and firefighter helmet so the badge clears the jacket and the brim does not sit
|
||||
over the eyes; these are `NpcAvatar.GEAR_OFFSETS`, not changes to the gear
|
||||
contract.
|
||||
|
||||
`tools/npc_proportions.py` checks the eight character GLBs against the shared
|
||||
height/head/shoulder/hip/torso/leg/arm/foot guide; the current results are in
|
||||
[`npc-proportion-audit.md`](npc-proportion-audit.md). It reads the exported GLBs
|
||||
and does not require Blender.
|
||||
|
||||
`capture_npc_baseline.gd` is the 0.9.4 neutral baseline: eight characters ×
|
||||
front/three-quarter/profile/back/full-body/crowd = 48 frames with a fixed
|
||||
camera, studio lighting and no venue/HUD/animation. The raw PNGs stay in
|
||||
|
||||
@@ -39,6 +39,7 @@ Implemented so far:
|
||||
- Aim-free selection pass (v0.3.0 work, [ADR-0011](adr/0011-aim-free-selection-and-precision-walk.md)): the focus cone ranks candidates by angle then distance, `Tab` and the mouse wheel cycle nearby people nearest-first and pin the selection, right click clears focus with a short re-acquire grace, the HUD reports how many people are in the ring, and holding `Shift` walks at half speed for close work
|
||||
|
||||
- Visual alignment: start/venue menu, pause, settings, shift review, radio, wand, inspection, timeline, HUD target chip/escalation bar, and radial menu now use or match their AI references in `assets/images/ui/`. The runtime art loader (`src/game/ui/art.gd`) falls back cleanly when a file is missing. The wand panel lists the guest's carried items, and multiline HUD/wand strings render real line breaks.
|
||||
- NPC proportion audit (0.9.4 work): `tools/npc_proportions.py` measures all eight GLBs against a stylized height/head/shoulder/hip/torso/leg/arm/foot guide. All variants pass; the head and broad-build silhouettes are the nearest upper bounds. Results are in [`npc-proportion-audit.md`](npc-proportion-audit.md).
|
||||
- NPC P1 portrait fixes (0.9.4 work): tourists now hide their photo-pose camera bag outside `photo`/`film` poses, removing the duplicate-backpack silhouette; the backpack gear was rebuilt with flattened, forward chest straps and a fresh AO map. The before/after sheet is [`blender_previews/sheet_npc_baseline_compare-p1.jpg`](blender_previews/sheet_npc_baseline_compare-p1.jpg); the face and remaining clothing/hand work stay open.
|
||||
- NPC visual baseline (0.9.4 work): `src/test/capture_npc_baseline.gd` captures all eight library characters from front, three-quarter, profile, back, full-body and crowd views in a neutral studio (48 frames). The criteria, measurements and ranked gaps are in [`npc-visual-review.md`](npc-visual-review.md); the committed sheet is [`blender_previews/sheet_npc_baseline.jpg`](blender_previews/sheet_npc_baseline.jpg). No model changes were made in this baseline step.
|
||||
- UI-state capture pass (0.9.3 work): `src/test/capture_ui_states.gd` adds committed captures 14–21 for the start menu, pause, settings, shift review, emergency radio, action wheel, crowd panic and responder arrival. Every one of the 21 catalogue entries now has a current-build capture; `tools/check_screenshots.sh` reports 21 good / 0 bad and the automatic judge reports 21/21 match, 0 diff. Crowd panic and responder arrival are staged presentation frames, not gameplay changes.
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
# NPC proportion audit
|
||||
|
||||
Status: audited 2026-11-02. All eight library variants are inside the stylized
|
||||
proportion guide; no geometry correction was required in this pass. The report
|
||||
is repeatable from the exported GLBs:
|
||||
|
||||
```bash
|
||||
python3 tools/npc_proportions.py report
|
||||
python3 tools/npc_proportions.py report --json
|
||||
```
|
||||
|
||||
## Method
|
||||
|
||||
`tools/npc_proportions.py` reads the GLB meshes and rest-pose joint hierarchy:
|
||||
|
||||
- height from the full mesh bounds;
|
||||
- head height, width and aspect from `Head`/`skin` vertices (hair excluded so
|
||||
long hairstyles do not change the head measurement);
|
||||
- shoulder silhouette from vertices in the upper-chest band around the
|
||||
shoulder joint;
|
||||
- hip width from `HipL`/`HipR` pants vertices;
|
||||
- torso length from the Spine joint to the shoulder joint;
|
||||
- leg length from the Spine joint to the lowest vertex;
|
||||
- arm length from the shoulder joint to the Hand joint;
|
||||
- foot length from the forward extent of the KneeL/KneeR shoe vertices.
|
||||
|
||||
All ratios are divided by total standing height except `head_aspect`
|
||||
(width / head height).
|
||||
|
||||
## Guide
|
||||
|
||||
These are stylized-but-credible bands for the game's low-poly adults, not
|
||||
photoreal anatomy. The broad build is allowed a larger shoulder/hip silhouette
|
||||
than the slim build.
|
||||
|
||||
| Ratio | Target | Notes |
|
||||
| --- | ---: | --- |
|
||||
| `head_height` | 0.16–0.22 | deliberately larger than a realistic 0.13–0.15 |
|
||||
| `head_aspect` | 0.70–1.00 | width / height; rounded heads are acceptable |
|
||||
| `shoulder_width` | 0.28–0.38 | silhouette includes sleeves and build scaling |
|
||||
| `hip_width` | 0.17–0.23 | pants-only width, not skirt/coat flare |
|
||||
| `torso_length` | 0.28–0.38 | Spine joint to shoulder |
|
||||
| `leg_length` | 0.40–0.48 | Spine joint to ground |
|
||||
| `arm_length` | 0.28–0.38 | shoulder to hand |
|
||||
| `foot_length` | 0.12–0.18 | shoe forward extent |
|
||||
|
||||
## Result
|
||||
|
||||
| Character | Height | Head | Aspect | Shoulder | Hip | Torso | Leg | Arm | Foot | Result |
|
||||
| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | --- |
|
||||
| `npc_casual` | 1.824 m | 0.190 | 0.907 | 0.320 | 0.209 | 0.307 | 0.449 | 0.329 | 0.144 | PASS |
|
||||
| `npc_jacket` | 1.824 m | 0.190 | 0.907 | 0.325 | 0.209 | 0.307 | 0.449 | 0.329 | 0.144 | PASS |
|
||||
| `npc_coat` | 1.824 m | 0.190 | 0.907 | 0.329 | 0.209 | 0.307 | 0.449 | 0.329 | 0.144 | PASS |
|
||||
| `npc_vest` | 1.819 m | 0.191 | 0.907 | 0.321 | 0.210 | 0.308 | 0.451 | 0.330 | 0.144 | PASS |
|
||||
| `npc_dress` | 1.825 m | 0.190 | 0.907 | 0.287 | 0.191 | 0.307 | 0.449 | 0.329 | 0.144 | PASS |
|
||||
| `npc_hoodie` | 1.856 m | 0.187 | 0.907 | 0.320 | 0.205 | 0.302 | 0.442 | 0.323 | 0.141 | PASS |
|
||||
| `npc_firefighter` | 1.819 m | 0.191 | 0.907 | 0.356 | 0.225 | 0.308 | 0.451 | 0.330 | 0.148 | PASS |
|
||||
| `npc_guard` | 1.819 m | 0.191 | 0.907 | 0.370 | 0.219 | 0.308 | 0.451 | 0.330 | 0.144 | PASS |
|
||||
|
||||
No variant is outside a band, so the body pass does not need a global skeleton
|
||||
or mesh rescale. The values closest to a boundary are:
|
||||
|
||||
- **head height 0.190** against the 0.22 upper bound, and **head aspect 0.907**
|
||||
against 1.00 — the head is deliberately large. Any head-size change must be
|
||||
coordinated with the face/headgear pass and its gear-fit measurements.
|
||||
- **guard shoulder 0.370** and **firefighter hip 0.225** against the broad-build
|
||||
upper bounds — these are the intended uniform/turnout silhouettes, not
|
||||
outliers.
|
||||
- **leg length 0.449** and **torso 0.307** sit inside the guide for all variants;
|
||||
the earlier short-leg impression came from the hip joint position, not the
|
||||
visible pelvis line.
|
||||
|
||||
## Follow-up
|
||||
|
||||
The proportion audit does not replace the visual criteria in
|
||||
[`npc-visual-review.md`](npc-visual-review.md): neck/shoulder/hip transitions,
|
||||
face depth, hand grips, clothing hems and shoes still need the appearance pass.
|
||||
Re-run the audit after any body mesh or skeleton change and record the new
|
||||
ratios here.
|
||||
@@ -84,6 +84,14 @@ silhouette (normal for a backpack, suspicious when it is a strap). Runtime
|
||||
`NpcAvatar.GEAR_OFFSETS` is applied after attachment and is not part of the GLB
|
||||
measurement.
|
||||
|
||||
## Proportion audit
|
||||
|
||||
The separate [`npc-proportion-audit.md`](npc-proportion-audit.md) measures
|
||||
height, head size, shoulder/hip width, torso, leg, arm and foot ratios for every
|
||||
variant with `tools/npc_proportions.py`. All eight pass the stylized guide; the
|
||||
head and broad-build shoulders sit nearest their upper bounds. No skeleton or
|
||||
mesh proportion change was needed in this pass.
|
||||
|
||||
## Baseline measurements
|
||||
|
||||
From `python3 tools/blender_assets.py fit` and the manifest:
|
||||
|
||||
Reference in new issue
Block a user