Skip to content

fix(art): repair the Synty retarget's real faults, and correct the diagnosis#33

Merged
ralyodio merged 1 commit into
mainfrom
fix/synty-retarget-diagnosis
Jul 26, 2026
Merged

fix(art): repair the Synty retarget's real faults, and correct the diagnosis#33
ralyodio merged 1 commit into
mainfrom
fix/synty-retarget-diagnosis

Conversation

@ralyodio

Copy link
Copy Markdown
Contributor

The character retarget did not work, and the reason recorded in docs/HANDOFF-synty.md was wrong — it said the maths was correct and the export was broken. Three faults were in play, and the first two hid the third.

1. BONE_MAP's source side matched no real bone

written actual
Hips, Abdomen, Torso hips, spine, chest
LowerArm.L, Wrist.L forearm.L, hand.L
UpperLeg.L, LowerLeg.L thigh.L, shin.L

The lookup skipped whatever it could not find, so zero bones mapped, zero keyframes were written, and all five actions came out empty — with nothing logged. Corrected against both armatures; an unmatched name is now fatal, because that silence is what let a bind-posed character look like an export bug.

2. export_bake_animation=True overrode the actions

With it on, the exporter emits one baked animation per object, named after the object, covering all 55 bones in T/R/S. That is exactly the reported symptom — "all five clips collapse into a single animation named target_rig". It was never action handling. Now off, with each action on its own NLA track, and a bake that yields no curves is fatal.

3. The "splayed limbs" measurement was an artefact

The scene carries a stray 42-vertex Icosphere that dominated the bounding box. Measured on the character mesh alone: 2.03 × 0.32 × 1.79 — right height, right depth. Nothing was ever splayed. (The sphere is still in the committed fighter_*.glb; tracked in the handoff.)

What's left, measured

All five clips now export under their own names and the legs animate correctly. The remaining blocker is a genuine rest-pose mismatch:

across
our source rig 0.69 m (arms down; no clip exceeds 0.72)
Synty bind 2.03 m (T-pose)

Rest-relative retargeting transfers deviation from rest, so the arms never leave the T-pose. Two fixes were tried and rejected on measurements, recorded so they aren't repeated:

  • Copy world orientation outright — discards the bone-axis conventions along with the rest difference; the figure lies down (2.14 × 0.52 × 0.39 for something 1.79 m tall).
  • Re-rest the target into the source's A-pose — corrections come out incoherent (169° on the left upper arm vs 11° on the right, where a mirror pair must be symmetric), so the two rest frames aren't being compared in a common basis.

Scope

No asset changes. The committed characters are untouched and the bots keep using the generated one, so nothing in the game moves — this is a repaired tool plus a correct diagnosis, not a shipped character. I'm not going to wire up a character whose arms are stuck out sideways.

The recommended next route, now in the handoff: stop retargeting and skin the Synty mesh to our existing rig, which already has all five clips working. That removes the skeleton-to-skeleton problem instead of solving it.

249 tests pass; lint, typecheck and build clean.

🤖 Generated with Claude Code

…agnosis

The character retarget did not work, and the reason recorded in
docs/HANDOFF-synty.md was wrong. It said the maths was correct and the glTF
export was broken. Three faults were in play, and the first two hid the third.

**1. `BONE_MAP`'s source side matched no real bone.** It listed `Hips`,
`Abdomen`, `Torso`, `LowerArm.L`, `Wrist.L`, `UpperLeg.L`; our rig has `hips`,
`spine`, `chest`, `forearm.L`, `hand.L`, `thigh.L`. The lookup skipped whatever
it could not find, so zero bones mapped, zero keyframes were written, and all
five actions came out empty — with nothing logged. The table is corrected
against both armatures, and an unmatched name is now fatal instead of skipped,
because that silence is what let a bind-posed character look like an export bug.

**2. `export_bake_animation=True` overrode the actions.** With it on the
exporter emits one baked animation per object, named after the object, covering
all 55 bones in T/R/S. That is exactly the reported symptom — "all five clips
collapse into a single animation named target_rig" — and it was never
action-handling at all. It is off, and each action now gets its own NLA track.
A bake that yields no curves is also fatal now.

**3. The "limbs splayed, 1.90 x 2.00 x 2.47 m" measurement was an artefact.**
The scene carries a stray 42-vertex Icosphere that dominated the bounding box.
Measured on the character mesh alone the figure is 2.03 x 0.32 x 1.79 — right
height, right depth. Nothing was ever splayed.

With those fixed, all five clips export under their own names and the legs
animate correctly. What is left is a real rest-pose mismatch, measured rather
than guessed: our source rig rests arms-down at 0.69 m across and no clip
exceeds 0.72, while Synty's bind is a T-pose 2.03 m across. Rest-relative
retargeting transfers deviation from rest, so the arms never leave the T-pose.

Two fixes were tried and rejected on measurements, and both are recorded so
they are not repeated: copying world orientation outright discards the
bone-axis conventions along with the rest difference and lays the figure down
(2.14 x 0.52 x 0.39); re-resting the target into the source's A-pose produces
incoherent corrections — 169 degrees on the left upper arm against 11 on the
right, where a mirror pair must be symmetric.

No asset changes. The committed characters are untouched and the bots keep
using the generated one, so nothing in the game moves. The recommended next
route, now in the handoff, is to stop retargeting and skin the Synty mesh to
our existing rig, which already has all five clips working.

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 eb006c5 into main Jul 26, 2026
6 checks passed
@ralyodio
ralyodio deleted the fix/synty-retarget-diagnosis branch July 26, 2026 23:50
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