Automated garment-under-animation QA: CharacterVisual composite with the garment's covered body segments overridden to flat unshaded magenta, cycled clips x frames x 4 yaws; PIL analyzer flags connected key-pixel blobs and emits report.json + highlighted failure frames. Capture scene lives under client/tools/garment_qa/ (res:// boundary; outside the gdUnit scan root), driver/analyzer/config under tooling/garment-qa/. Verified: 72 captures across peasant set x average_m/f x Walk/Sprint/ Crouch_Fwd. Finding: no true mid-cloth clip-through; flags are coverage-claim vs silhouette mismatch (sleeveless/short-sleeve exposure at collar/cuffs) — a two-pass garment-behind-pixel discriminator is the queued refinement. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
27 lines
1.5 KiB
Markdown
27 lines
1.5 KiB
Markdown
# garment-qa — chromakey garment-clipping QA (T-1089)
|
||
|
||
Automatically detects clothing clip-through. The capture scene paints the body
|
||
segments a garment *claims to cover* (coverage.json `hides`) flat **unshaded magenta**,
|
||
leaves the garment and uncovered segments (head/hands/etc.) normal, then cycles
|
||
animation clips × sampled frames × 4 camera yaws and saves a PNG per view. Any magenta
|
||
the camera sees = body poking through cloth. The analyzer counts connected magenta
|
||
pixels per capture and flags clips.
|
||
|
||
**Run:** `tooling/garment-qa/run-garment-qa [config.json]` (defaults to
|
||
`configs/peasant.json`). It launches Godot (`~/bin/godot4`, `opengl3`, `xvfb-run` when
|
||
headless) on the capture scene, then runs the analyzer.
|
||
|
||
**Config** (path passed to the scene via `GARMENT_QA_CONFIG`): `garments`
|
||
(`{item_id,slot}` catalogue items, or `{glb,slot,covers[]}` for a raw WIP garment),
|
||
`body_types`, `clips`, `frames_per_clip`, `yaws`, `head_id/hair_id/eyebrow_id/skin_tone`,
|
||
`out_dir`.
|
||
|
||
**Read the report:** `<out_dir>/report.json` — per-capture `key_pixels`,
|
||
`largest_component`, `fail`, plus a `by_group` (body__clip) roll-up; the same summary
|
||
prints to stdout. A capture FAILS when its largest connected magenta blob ≥ `--min-pixels`
|
||
(default 8, tolerating AA edges). Failing frames are copied to `<out_dir>/failures/` with
|
||
clip pixels recoloured lime and each blob boxed red.
|
||
|
||
**Note:** the Godot scene lives at `client/tools/garment_qa/chromakey_scene.gd` (not here)
|
||
because Godot `res://` paths cannot leave the client project root.
|