Skip to content

feat(art): skin the Synty mesh to our rig — closer, still not shippable#34

Merged
ralyodio merged 1 commit into
mainfrom
feat/synty-skinning
Jul 27, 2026
Merged

feat(art): skin the Synty mesh to our rig — closer, still not shippable#34
ralyodio merged 1 commit into
mainfrom
feat/synty-skinning

Conversation

@ralyodio

Copy link
Copy Markdown
Contributor

Second approach to getting a Synty character animated, following the last pass's recommendation: stop moving animation between skeletons and bind the Synty mesh to the rig that already has working clips. No retarget, because no second skeleton.

Where it got to

Five clips exported under their own names
Height matched to our rig ✅ within 2%
Torso, legs, head animate
Arms ❌ one locks straight out, the other crumples into the chest

Confirmed by render, not by measurement alone.

What's established, so a third attempt doesn't re-derive it

  • The pose step is correct. Every mapped arm bone reaches its target direction to within 0.0°, verified bone by bone against wanted world directions. The arms are provably down before the mesh is baked — and the baked mesh still measures 1.16 m across against our rig's 0.69 m. So the mesh isn't following its own skeleton and the fault is downstream of the pose, most likely in the ARMATURE_AUTO bind.
  • POSE_MAP is arms-only, measured. Including the pelvis and spine collapsed the figure from 1.79 m to 0.49 m: those bones don't share a direction convention between an Unreal skeleton and ours.
  • The extreme vertices are fingertips weighted to indexFinger_03_l/r, bones this script never poses. Whether they're parented under Hand_* in the FBX is unconfirmed and is the first thing to check.

It also solves an old mystery

The "stray Icosphere" from the last PR is COL_character — the collision hull shipped inside character.glb — at 1.9 × 2.0 × 2.8 against a body of 0.69 × 0.62 × 1.75. Measuring the two together is what produced the bogus "the retarget splays the limbs" reading that stood in the handoff for months. The script now excludes collision proxies and refuses any height correction outside 0.75–1.35×, so a mangled pose fails loudly instead of being quietly scaled back to a plausible height.

Scope

No asset changes, script not wired into the build, committed characters untouched, bots still use the generated one. I'm not shipping a fighter with one arm out sideways.

The handoff now recommends a different route: get clips authored for the Synty skeleton via auto-rigging, rather than a third attempt at moving animation between these two rigs. Both directions have now cost more than they're worth.

249 tests pass; lint and format clean.

🤖 Generated with Claude Code

Second approach to getting a Synty character animated, per the recommendation
in the last pass: stop moving animation between skeletons and instead bind the
Synty mesh to the rig we already have working clips on. There is no retarget
because there is no longer a second skeleton.

It gets much further than `import_synty.py`. The export carries all five clips,
the height matches our rig to within 2%, and the torso, legs and head animate
correctly. The arms do not survive the bind: one locks straight out at shoulder
height and the other crumples into the chest, confirmed by render rather than
by measurement alone.

What is established, so a third attempt does not re-derive it:

- The pose step is correct. Every mapped arm bone reaches its target direction
  to within 0.0 degrees, verified by comparing achieved against wanted world
  directions bone by bone. The arms are provably down before the mesh is baked,
  and the baked mesh still measures 1.16 m across against our rig's 0.69 m — so
  the mesh is not following its own skeleton, and the fault is downstream of
  the pose.
- `POSE_MAP` is arms-only, measured: including the pelvis and spine collapsed
  the figure from 1.79 m tall to 0.49 m, because those bones do not share a
  direction convention between an Unreal skeleton and ours.
- The extreme vertices are fingertips weighted to `indexFinger_03_l/r`, bones
  this script never poses.

It also resolves the "stray Icosphere" noted last time: that is `COL_character`,
the collision hull shipped inside `character.glb`, at 1.9 x 2.0 x 2.8 against a
body of 0.69 x 0.62 x 1.75. Measuring the two together is what produced the
bogus "the retarget splays the limbs" reading that stood in the handoff for so
long. The script excludes collision proxies and refuses any height correction
outside 0.75-1.35x, so a mangled pose fails loudly instead of being scaled back
to a plausible-looking height.

No asset changes, and the script is not wired into the build. The committed
characters are untouched and the bots keep using the generated one.

The handoff now recommends a different route entirely: get clips authored *for*
the Synty skeleton via auto-rigging, rather than a third attempt at moving
animation between these two rigs.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

vu1nz Security Review

0 finding(s) in PR #?

No security issues found.

@ralyodio
ralyodio merged commit 89ecfe3 into main Jul 27, 2026
6 checks passed
@ralyodio
ralyodio deleted the feat/synty-skinning branch July 27, 2026 00:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant