Commit Graph

4 Commits

Author SHA1 Message Date
type-two
305fbf9447 Phase 5: the dressing room — thumbnails, a manifest, and the rig/LOD/dress bench on one page
The wardrobe had grown past the point where a list of filenames is usable: 20 bodies and a
garments list you had to read rather than look at. Three things close that.

THUMBNAILS. New `thumb` blender op — fixed front ortho camera, EEVEE, transparent film, bind
pose (a thumb caught mid-clip is unreadable), framed on the real mesh with helper widgets
excluded or a bone widget decides the crop. /thumb?p= renders lazily and caches on a hash of
the source path. 2D layers skip Blender entirely and downscale through PIL — 12ms vs a process
launch. First paint of a fresh grid is slow because every 3D card spawns a render; after that
they're cached. Worth knowing before it looks broken.

MANIFEST (library/index.json, written atomically so a half-write can't blank the wardrobe).
Canonical slots and a layer int that drives BOTH the 2D doll stack and 3D ordering, so a
garment sorts the same in either product. Slots are GUESSED from the filename as a convenience
and the guess is marked as such — the UI shows `head?` with a "confirm it" note, and setting a
slot explicitly clears the inferred flag. A guess presented as fact is how a library quietly
fills with wrong data. Props (boombox, camera, thermos) correctly come back unset rather than
being forced into a garment slot.

THE BENCH, in the order you actually work: fix units -> rig (MIRPAMO) -> LOD -> dress. LOD is
four preset buttons at the tiers the games budget for (hero 60k / npc 18k / crowd 6k / tiny 2k)
instead of typing tri counts. /api/rig shells out to MIRPAMO, and the UI states its real
limitation up front: 22 bones, no fingers — fine for locomotion, but a 65-bone donor garment
will leave cuffs under-driven, which is exactly the mismatch that bit us in Phase 4.

Grid, slot tabs with counts, search over name+tags, metadata editor, LOD presets and the bench
buttons all verified in-browser with no JS errors. nsfw tagging from the previous commit carries
through: tagged assets stay hidden behind the toggle and out of the grid.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-24 20:25:44 +10:00
type-two
037f6ef0af Fold NPCFACTORY in: vendor three.js, take the banks, and fix units without flattening body types
NPCFACTORY and wardrobegod were the same product — wardrobegod had already absorbed its reskin
engine, and keeping two benches means two half-libraries and two export paths. Folded, keeping
the wardrobegod name and codebase (370 lines there vs ~1,100 here).

· Vendored three.js r175 from NPCFACTORY, replacing the unpkg CDN importmap. This was real
  drift, not tidiness: a CDN import breaks offline and can't be lifted into a game build.
  NPCFACTORY lacked OrbitControls (it used PointerLock), so that one addon was fetched at the
  matching revision. Added a guarded /vendor/ static route. Verified in-browser: zero CDN
  requests, 5 vendor files, model still loads.
· Took the 17 rigged walk-animated NPCs and 6 parts. Bodies 4 -> 20.
· New `unitfix` op. Deliberately NOT scale-to-height: a 0.06m human is a UNIT error, but
  normalising everything to 1.72m would erase the small/medium/large/obese range the library is
  meant to carry. So it only corrects heights outside 0.5-3.0m — physically impossible for a
  human — and leaves real proportions alone as data. Verified both ways: hum_character 0.0576m
  -> 1.72m, tradie 1.000m left untouched.

Three bugs found while building it, two of them pre-existing:
· `is_helper`/`real_meshes`/`bbox_of` factored out. Material-less bone widgets (a radius-1
  42-vert Icosphere, so exactly 2.0 units tall) were being measured INSTEAD of the character —
  every body reported 2.000m. This poisoned the `scale` op too, which has been measuring
  widgets all along; NPCFACTORY's render_plates.py had independently worked around the same
  thing by framing on the dominant mesh.
· `transform_apply` under temp_override(selected_editable_objects=...) SEGFAULTS Blender 5.1.2
  on rigs with parented children. A segfault can't be caught, so it's avoided rather than
  handled: glTF encodes node scale natively, so setting the root transform is sufficient and
  every downstream measurement still reads correctly. Confirmed `scale` still round-trips
  (1.00m -> 1.72m, re-measured).
· My own bulk edit replaced only ONE of the two crash-prone call sites and reported "replaced 1"
  — I didn't check for a second, which is why `scale` worked while `unitfix` kept crashing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-24 19:36:03 +10:00
type-two
8119e2de4c Phase 4: donor harvest — real cloth that bends, plus three assemble bugs it exposed
harvest op: split a garment off an already-rigged clothed character by material. Blender's
mesh.separate(type='MATERIAL') carries the vertex groups onto the separated piece, so the
garment lands ALREADY skinned to the donor's skeleton — no fit, no weight transfer, and it
deforms correctly at the elbow because it was authored to. Unused groups are purged after.

Triaged all 43 clothed donors on ultra (headless Blender, run where the files are rather than
moving 3 GB). Measured what the LoRA bench could only guess at: only 11/43 (25%) are separable.
The rest bake skin and cloth onto one fused atlas and cannot be split at all. The best targets
are the Ready Player Me avatars (Wolf3D_Outfit_Top/Bottom/Footwear — a clean 3-way split) and
the Mixamo characters (Topmat/Bottommat/Shoesmat); most of the man_*/woman_* set is fused.
Triage also over-reported at first: the skin regex missed 'mouth', so mouth materials showed up
as garments. Widened.

Proving it end to end exposed three real bugs in `assemble`, none of which erred — they all
failed silently, which is why they had survived:
· Bone names are NOT uniform across the fleet, contrary to the "one skeleton" contract in the
  README. character_kit and NPCFACTORY use 'mixamorig:Hips'; Ready Player Me donors use bare
  'Hips'; Blender suffixes '.001' on any import collision. Vertex groups therefore pointed at
  bones that did not exist and the garment sat frozen in bind pose while the body animated.
  Now matched on the bare name, so a garment harvested off one rig drives another.
· Donors are not authored at a common scale. character_kit rigs are ~0.06 m tall, a Ready
  Player Me donor ~1.5 m, so the harvested top arrived 27.41x oversized and swallowed the
  scene. Rescaled by a shared hips->head bone span, the same trick character_kit's
  assemble.fit_part uses.
· Material-less bone-widget meshes (a 42-vert 'Icosphere' in character_kit rigs) rode along and
  wrecked the scene bbox, which drives both the HUD height and the viewer's auto-framing — one
  stray widget framed the camera on the widget and rendered the character as a speck.
  NPCFACTORY's render_plates.py had already worked around the same thing.

Verified: a garment harvested from a Ready Player Me donor, assembled onto character_kit's
hum_character, deforming correctly mid-stride through a Running clip. Honest caveat unchanged —
the garment inherits its donor's proportions, so it reads loose on a slimmer body and there is
no cloth sim to save it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-24 19:07:32 +10:00
type-two
58354d9b66 WARDROBEGOD v1 — wardrobe generator bench (bodies, fits, garment gen pipeline)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 20:53:43 +10:00