Commit Graph
5 Commits
Author SHA1 Message Date
Nicholas Butzke 922983429e big 2026-08-02 02:20:02 -04:00
Nicholas Butzke 374d9f9822 feat: implement automated 3D character pipeline with retargeting and rig management tools 2026-07-24 20:52:35 -04:00
Nicholas ButzkeandClaude Opus 4.8 afc954e129 fix: no limb vertex may carry opposite-leg weight — thigh collapse gone
The thighs going thin was never the knee bend. It was inner-thigh vertices
keeping ~20% of the weight of the OPPOSITE leg, so a split stride tore them
across the body. Printing the weight composition of the worst-collapsing
vertices is what finally showed it: a right-thigh vertex reading
DEF-thigh.R=0.58 DEF-shin.R=0.21 DEF-thigh.L=0.13 DEF-shin.L=0.08.

Every earlier pass had a guard that let these through. The below-knee pass does
not reach them; the above-knee pass demanded one leg chain be 1.25x nearer than
the other, which excludes everything near the centre line — precisely where the
damage was; and the limb-radius gates are measured from the bone AXIS, so a
vertex on the front or back of a thigh clears them easily.

SkinLegRepair now ends with an unconditional pass: any vertex within a generous
radius of either leg chain is forced onto the leg that actually drives it, at
any height. It runs last so none of the staged rules can reintroduce the
problem.

Measured per vertex, across jump, fall, run and dash:

                     before        after
  Body below 0.80      70            0
  Body worst          0.46         0.82
  ClothCAndW below 0.80  107          0
  ClothCAndW worst    0.66         0.85
  ClothB worst        0.81         0.87

No vertex anywhere on the legs now loses more than 18% of its thickness, down
from 54%. The skirt still deforms freely (0.87-0.88) — clothes flow, limbs hold.

Also fixed in SkinJointHelper along the way: it picked the FIRST joint chain
that matched a vertex rather than the one holding most of its weight, which
bound right-thigh vertices with stray left-leg weight to the LEFT knee's helpers
and dragged them across the body. It now picks the dominant joint and requires
the joint to own at least half the vertex.

Taila snaps 2021 vertices, Miku 659. FSM tests 11/11, spawn smoke test 0
failures.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-07-22 09:03:45 -04:00
Nicholas ButzkeandClaude Opus 4.8 d33f9cd812 docs: record why bone-scale volume preservation does not work here
Tried widening the helper bone to cancel the joint collapse. The geometry is
right — blending two rotations θ apart thins anything perpendicular to the bend
by exactly cos(θ/2), which is |q.w| of the pose rotation, so scaling the helper
across the bone by the reciprocal is the exact correction.

It does not work, because a BONE scale is the wrong granularity. It fattens
every vertex weighted to the helper whether or not that vertex was collapsing:
parts of the thigh ballooned to 167% while the worst-collapsing vertices, which
are not on the helper at all, stayed at 0.83. The idea needs per-vertex
correction and a bone cannot express it. Removed, with the reasoning kept in the
file so it is not retried.

Hip joints were also retested, since two other variables had changed since the
first attempt (one-joint-per-vertex, and the limb gate removed). Same verdict a
second time: upper thigh 0.90 -> 0.84, and the skirt 0.80 -> 0.72. Knees only.

Shipped state is unchanged from the previous commit; this is the reasoning and a
revert of an experiment.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-07-22 08:49:14 -04:00
Nicholas ButzkeandClaude Opus 4.8 1ab7e99231 fix: handle the knee bend with a joint, and record what made it worse
Renames SkinKneeHelper to SkinJointHelper and generalises it to a list of
[parent, child] joints, so the half-angle joint technique is stated once and can
be pointed at any joint. It stays pointed at the KNEES only, and the header now
says why, because "add more joints" is the obvious next idea and it is wrong
here.

Three things were tried this round and measured, on the thigh, per vertex,
against the rest transforms:

  * hip and ankle helpers as well as knees: the knee got WORSE, 0.80 -> 0.50,
    and the skirt went 0.80 -> 0.72. The hip mostly swings rather than folding,
    and linear-blend skinning handles a swing far better than a fold; the helper
    just added another blend for nothing. Reverted.
  * gating the re-weight to vertices near the leg bone chain, to keep the hip
    helper off the skirt: that also excludes the OUTSIDE of the knee, which sits
    further from the bone axis than the limb radius and is exactly the geometry
    that needs helping. Knee went back to 0.50. Removed — with knees only there
    is no skirt to protect against.
  * one joint per vertex (break after the first match): kept, since a second
    job would read the bones the first just rewrote.

Net result on the thigh, worst per height bucket during a jump:

  y=0.60  0.80 -> 0.83     y=0.75  0.84 -> 0.84
  y=0.65  0.81 -> 0.84     y=0.85  0.90 -> 0.90

and the skirt is untouched at 0.80/0.84, still free to move.

FSM tests 11/11, spawn smoke test 0 failures.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-07-22 08:43:56 -04:00