Files
animation/.agents/plans/rig-graft-lane-2026-08-04.md
T
jeremy 3d8825f5a9 reorg(characters): ship-time folders — lena_base_v01 ships, lane moves to work/lena
REGISTRY rewritten around the central rule: a character folder is born only
when a body ships to ariki-game (<character>_base_v<NN> = ship ordinal).
lena_nude dissolves accordingly:
- characters/female/lena_base_v01/ — SHIPPED 2026-08-10: AccuRig GLB carrier,
  T-pose/rig FBX + JSON, previews, frozen README
- characters/work/lena/ — the live lane: recipes 01-47 (incl. new 36-47:
  refill/sheets/clay/despeckle/musculature/spin/AccuRig export/graft/pose QC),
  masters (athletic_v04 blend + textures, accurig blend), lane-history README
- hires_claude/hires_work intermediates (blends, logs, probes) pruned

Supporting docs: AGENTS.md, working-files rule, rig-graft plan addendum,
originals README, prune_lane.py.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-12 07:17:15 -07:00

142 lines
8.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Rig-graft lane — AccuRig skeleton onto pristine Tripo GLBs (PLAN, not executed)
**Repo home:** this plan and its tools moved from ariki-game into the animation repo
2026-08-06 — the lane authors characters, so `characters/REGISTRY.md` governs it (see
`.agents/wiki/ARCHITECTURE.md` "Which repo does a non-gameplay tool belong to"). Paths
below are animation-repo-relative unless prefixed `ariki-game/`.
**Status 2026-08-04: PLAN ONLY. Jeremy has explicitly held execution — no model
files are to be created or modified until the naming convention is decided.**
## Goal
Rig Ozlem's two unrigged Tripo bodies without the FBX→GLB quality loss the male
lane hit in July (mangled textures, bad hand skinning). The move: FBX is only a
**disposable rig carrier** through AccuRig; the **GLB is the sole source of truth**
for mesh + materials and only ever *gains* bones and weights.
## Source files (curated 2026-08-04)
Byte-identical copies live in both repos: `characters/originals/` here (checksummed in
`characters/REGISTRY.md`) and `ariki-game/assets/models/characters/race-sources/`. Read
from this repo's copies.
| file | verts | tris | height | feet @ Z0 | axis | textures |
|---|---|---|---|---|---|---|
| `female_lena_tripo.glb` | 974,478 | 1,907,931 | 0.979 m | yes (0.0) | upright, rot 0, scale 1 | 3 packed 4K (basecolor/normal/rm) |
| `female_lena_tripo.fbx` | 953,968 | 1,907,931 | 0.979 m | — | upright | 5 external JPEGs (.fbm removed; git-recoverable) |
| `male_base_bald_tripo_v1.glb` | 969,881 | 1,901,449 | 0.980 m | yes (0.0) | upright, rot 0, scale 1 | 3 packed 4K, clean |
| `male_base_bald_tripo_v1.fbx` | 950,729 | 1,901,449 | 0.980 m | — | **lying down (bad axis)** | 6 packed, all mislabeled "Diffuse Texture.NNN", duplicated basecolor |
Census facts that shape the plan:
- **No bones anywhere** — all four files are truly unrigged, so no rig standard is
imposed by the sources. The 65-bone Quaternius game standard is unaffected.
- **Identical surfaces per pair** (tri counts match exactly); vertex counts differ
~2% from format-specific UV-seam splitting → index-exact weight copy is off the
table, nearest-surface transfer is the mechanism (surfaces coincide, so it is
near-exact everywhere except close-packed fingers — see step 4).
- The male FBX's axis + texture mangling is the July failure mode reproduced in
data — never source visual data from FBX.
## Decisions (Jeremy, 2026-08-04)
1. **NO scaling to standard height.** Bodies stay at Tripo's native ~0.98 m.
(Any scale handling happens later, downstream, not in this lane.)
2. **Axis check + ground the feet** — wanted, and the probe shows both GLBs
already pass (rot 0 / scale 1 / min-Z exactly 0.0). These become verify-only
gates, mutating nothing unless a future source fails them.
3. **HOLD before decimation** until the naming convention for derived files is
agreed. Nothing below the line runs until then.
## The lane (each step gated on the one before)
1. **Verify** (read-only, DONE for the two current GLBs): upright axis, unit
scale, feet at Z=0, centered X, packed textures present.
2. **Rig bait** *(HELD — naming)*: from the GLB, decimate a disposable copy and
export FBX for AccuRig. **Confirmed 2026-08-04: AccuRig refuses the raw
1.9 M-tri FBX outright** (Jeremy tried; July hit the same wall). Use the
`ariki-game/tools/male_mesh_decimate.py` precedent: region budgets body 24k / head 14k /
**hands 10k as their own protected region** (global-ratio decimation webs the
fingers — half of the historic hand-mangling happened here, pre-AccuRig).
Apply the July male-lane traps: Dummy-export quirk, the 4 cm offset.
No scale change on the GLB — but if AccuRig misplaces joints on a 0.98 m
body, scale the DISPOSABLE BAIT up 2× and scale the returned skeleton back
down in the graft; the GLB never changes size.
3. **AccuRig** (manual, Jeremy/Ozlem): rig the bait FBX. Export rigged FBX.
4. **Graft** (headless Blender): import rigged bait FBX + pristine GLB; snap rest
poses; transfer skeleton + skin weights decimated→full-res by nearest-surface
with tight max-distance. Export GLB: original mesh + original packed
textures + new rig. FBX artifacts are discarded.
**Hands are no longer part of this step — see "Hands" below.**
5. **QC**: pose sweep incl. finger curls; then (if/when destined for game) the
existing AccuRig→Quaternius conversion (`ariki-game/tools/make_male_ib_quatskin_accurig.py`
lineage) picks it up.
## Hands: transplanted, not solved (RESOLVED 2026-08-07)
The hands come off the bait entirely and are transplanted from a body that already
ships working ones — `tools/graft_hands.py`, wrist-aligned. Three measurements
decided this:
- **There is nothing to solve.** The nude lane never touched the hands: hand-region
displacement from the Tripo original is mean **0.010 mm**, p50 exactly 0.000, only
0.06% beyond 1 mm (the 12.6% vertex churn there is micron jitter from the v03
despeckle pass). A donor's hand weights fit this mesh as-is.
- **A mitten rig would cost real animation.** Fingers move *relative to each other*
by up to **89°** over a clip (fertility 89.4°, taming 77.6°, nd_01 46.7°,
canoedismount 26.4°); only `war_dance_01` and `hakadance1_static` hold them still.
So four of six dances would visibly flatten. Rejected.
- **The bone list is not negotiable anyway.** 40 of the 65 joints are hands, every
clip carries tracks for all 40, and `tools/verify_body_variant.py` gates on "65
joints in identical order". A mitten could only ever have been a *skinning* choice.
`graft_hands.py` edits the glTF node graph directly rather than round-tripping the
armature through Blender, because Blender re-derives bone rest orientation from
edit-bone head/tail — the exact failure `ariki-game/tools/rig_pose_gate.py` exists to
catch. Validated: two self-tests (identity, and a 0.55× + 7° similarity) place every
hand joint to **5e-16 u** and recover 100% of donor weights; output passes
`verify_body_variant.py`; and `rig_pose_gate.py` reports **max error 0.000° over 260
(bone, clip, sample) comparisons** under the two most finger-heavy dances.
Two self-inflicted bugs the similarity test caught, worth not re-introducing: the
wrist scale gets applied **twice** if you compose the target's wrist matrix without
stripping its own scale first (the forearm ratio was measured in that same scaled
space), and the weight transfer must convert donor-local → world → target-local, not
compare raw POSITION arrays across two files.
**Still open on hands:** if AccuRig returns no wrist joint at all once the hands are
cut from the bait, `graft_hands.py` aborts — the `--wrist-from-forearm` fallback is
specified but not implemented, because what AccuRig actually returns is unknown until
step 3 runs.
## Naming + step 2 status (RESOLVED 2026-08-04, later same day)
Jeremy raised the hands budget and released the bait step. Built with
`tools/rigbait_decimate.py` (parameterized successor to male_mesh_decimate.py —
no scale/recenter, bbox-relative region cuts, budgets body 24k / head 14k /
**hands 40k**):
- `characters/rig-work/lena_tripo_rigbait.fbx` — 77,999 tris, QA'd
- `characters/rig-work/mako_tripo_rigbait.fbx` — 78,000 tris, QA'd
- `characters/rig-work/` is exempt from the naming grammar (REGISTRY.md rule 11) —
disposable carriers, no registry rows. In the game repo it had needed a `.gdignore`
to stop Godot importing it, which was the tell that it lived in the wrong repo.
- QA renders alongside (`*_qa_front.png`, `*_qa_hand.png`) — fingers fully
distinct at 40k, no webbing.
- Baits are geometry-only (~3.5 MB; the GLB's packed textures don't survive FBX
embed) — AccuRig shows a grey model, which is fine for rigging. It does mean
the July "Dummy001 export" check can't use textures: **verify AccuRig's output
by mesh name + ~78k tri count instead.**
**AccuRig exports must be saved as** (same folder):
- `characters/rig-work/lena_tripo_accurig.fbx`
- `characters/rig-work/mako_tripo_accurig.fbx`
## Open before execution
- Step 3 (AccuRig) — manual, waiting on Jeremy/Ozlem.
- Step 4 graft script — build once a rigged FBX exists to test against.
- Whether to restore the female FBX's `.fbm` texture folder from git (only needed
if the FBX is ever used for more than rigging; the lane says it shouldn't be).