Skip to content

RigPanel has no control to run a retarget: pick a clip, choose diagnostic vs write, read the measured proposal #6065

Description

@atomantic

The retarget lane shipped server-side in #5893 (POST /api/rigging/models/:id/retarget, GET /api/rigging/clips) but has no UI. client/src/components/media/RigPanel.jsx still only offers the auto-skin action, so the only way to animate a rigged character today is to call the endpoint by hand.

This is specifically the control that drives a retarget. #5894 covers the separate concern of making an already-animated record selectable and playable by the CoS and Eidoverse avatar surfaces.

Why the diagnostic/write split needs UI, not a default

mode defaults to diagnostic on purpose: the head-zone cleanup edits skin weights a human never reviewed, so a run measures the proposal first and the user opts into the edit second. Without UI that second step is unreachable — a user can never see "this would re-bind 340 of 12,000 vertices, cap is 240" and decide. Surfacing that number is the whole point of the two modes; a panel that just posts mode: 'write' throws the design away.

Scope

  • A clip picker in RigPanel.jsx fed by GET /api/rigging/clips, disabled with an explaining line when the library is empty (clips are user-dropped GLB files under data/rigging/clips/, so an empty roster is the normal first-run state — not an error).
  • An apiRigging.js wrapper pair (listRiggingClips, retargetImageTo3dModel) plus its client/src/services/README.md row.
  • Run the retarget in diagnostic mode, render the returned summary (proposedCleanupVertices / cleanupCapVertices / cleanupOverCap, clip, clipDuration, sampledFrames, maxJointTranslation), and offer an explicit "apply cleanup" action that re-runs in write mode. When cleanupOverCap is true, say so and explain that a write run will refuse rather than offering an action that cannot succeed.
  • Render the measured refusals verbatim — the server already returns the sentence naming the numbers (RIGGING_SKELETON_INCOMPATIBLE, RIGGING_RETARGET_GATE_FAILED), so the panel must not collapse them into a generic failure toast.
  • Persist nothing new: the record's retarget field already carries status/summary/error, so the panel reads it the way it reads rig today.
  • Show the published animation once ready (retarget.assetPath) rather than leaving the user to guess whether the run landed.

Acceptance criteria

  • With an empty clip library the retarget control explains why it is unavailable instead of rendering a dead picker.
  • A diagnostic run shows the proposed cleanup, the cap, and the motion numbers; nothing is written.
  • The write action is reachable only after a diagnostic run, and is refused-with-reason (not offered) when the proposal is over cap.
  • A gate refusal reaches the user as the server's own sentence.
  • Component tests cover the empty-library state, the diagnostic → write handoff, the over-cap branch, and the refusal rendering, following the existing RigPanel.test.jsx conventions.

Files/areas: client/src/components/media/RigPanel.jsx, client/src/services/apiRigging.js, client/src/services/README.md, related tests.

Related to #5893

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:mediaarea:uiUI components and stylingeffort:mediumEffort: mediumin-progressClaimed and being workedmodel:lightModel size: lightplanTracked by /do:replanplanner:opus-5Plan authored by the opus-5 modeluxProposed from a UX/design audit

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions