BS-PR-703 - Skeletal animation import, preview, and authoring workflow #46

Closed
opened 2026-07-10 04:04:44 -04:00 by Rbanh · 5 comments
Owner

Summary

Promote animation/skinning metadata from import warnings to a usable production workflow.

Scope

  • Normalize skeleton, skin, clip, and animation-event artifacts for supported glTF/FBX inputs.
  • Add animated actor components with stable asset references and hydration.
  • Asset Browser clip/skeleton inspection, thumbnail or scrub preview, loop/range controls, and drag placement.
  • Minimal animation graph/state-machine authoring suitable for gameplay integration.
  • Retargeting policy and diagnostics for mismatched skeletons.

Acceptance criteria

  • A skinned model and its clips import, preview, save, hydrate, and play in PIE.
  • Clip references survive asset moves through stable IDs.
  • Missing/mismatched skeletons produce actionable diagnostics.
  • Animation state changes can be driven by a game extension API.
  • Sample fixture and automated import/round-trip coverage ship.
## Summary Promote animation/skinning metadata from import warnings to a usable production workflow. ## Scope - Normalize skeleton, skin, clip, and animation-event artifacts for supported glTF/FBX inputs. - Add animated actor components with stable asset references and hydration. - Asset Browser clip/skeleton inspection, thumbnail or scrub preview, loop/range controls, and drag placement. - Minimal animation graph/state-machine authoring suitable for gameplay integration. - Retargeting policy and diagnostics for mismatched skeletons. ## Acceptance criteria - [ ] A skinned model and its clips import, preview, save, hydrate, and play in PIE. - [ ] Clip references survive asset moves through stable IDs. - [ ] Missing/mismatched skeletons produce actionable diagnostics. - [ ] Animation state changes can be driven by a game extension API. - [ ] Sample fixture and automated import/round-trip coverage ship.
Rbanh added this to the M7 - Content production and shipping milestone 2026-07-10 04:04:44 -04:00
Rbanh added the
type:architecture
priority:P1
roadmap:production
area:animation
labels 2026-07-10 04:04:44 -04:00
Author
Owner

Implemented and production-accepted in pushed commit 0553a85 (with prerequisite editor workflow fixes in cc1fa6e).

Acceptance evidence:

  • Automated: cargo test -p editor -p game -p scene -p shared --lib passed with 155 editor, 30 game, 50 scene (1 migration test intentionally ignored), and 67 shared tests.
  • Static checks: cargo fmt --all -- --check, git diff --check, and strict cargo clippy -p editor -p game -p scene -p shared --lib -- -D warnings passed.
  • Project validation: cargo validate-levels resolved 34 runtime dependencies with 0 blocking errors.
  • Import/browser: committed RobotExpressive GLB imported as stable model UUID 339488ab-16a6-47c4-a0ea-0f97ff7a6393; schema-v2 manifest exposed 2 rigs and 14 clips. Expanded skeleton/clip shelf stayed stable, including safe full-scene thumbnails for skinned primitives.
  • Authoring: dragging Walking created and selected one hydrated imported-model actor with an Animation Controller. Play, pause, and scrub reached 0.91/0.96s without dirtying authored data.
  • Persistence: saved scene retained the stable model UUID and animation:clip:10:walking; clean reload hydrated the actor correctly.
  • PIE: entering play clears paused edit-mode preview state; authored animation advanced in PIE with 11,514 changed pixels between captured robot-region frames and no runtime/render errors.
  • Move resilience: moving the source to assets/models/characters/robot_expressive.glb preserved UUID 339488ab-16a6-47c4-a0ea-0f97ff7a6393, regenerated manifests at the new path, rehydrated the saved actor, and validated with 0 blockers.
  • Package/runtime: development package contained the moved GLB, generated static/animation manifests, stable scene references, binary, and metadata. Standalone startup loaded the default scene cleanly; two frames 0.5s apart differed by 372,821 pixels, visibly confirming skeletal playback.
  • Unsupported/mismatch paths have focused coverage for animated/skinned FBX guidance, multi-root sources, exact rig signatures, missing manifests/clips, and stale runtime graph cleanup.

All BS-PR-703 acceptance gates are satisfied.

Implemented and production-accepted in pushed commit `0553a85` (with prerequisite editor workflow fixes in `cc1fa6e`). Acceptance evidence: - Automated: `cargo test -p editor -p game -p scene -p shared --lib` passed with 155 editor, 30 game, 50 scene (1 migration test intentionally ignored), and 67 shared tests. - Static checks: `cargo fmt --all -- --check`, `git diff --check`, and strict `cargo clippy -p editor -p game -p scene -p shared --lib -- -D warnings` passed. - Project validation: `cargo validate-levels` resolved 34 runtime dependencies with 0 blocking errors. - Import/browser: committed RobotExpressive GLB imported as stable model UUID `339488ab-16a6-47c4-a0ea-0f97ff7a6393`; schema-v2 manifest exposed 2 rigs and 14 clips. Expanded skeleton/clip shelf stayed stable, including safe full-scene thumbnails for skinned primitives. - Authoring: dragging Walking created and selected one hydrated imported-model actor with an Animation Controller. Play, pause, and scrub reached 0.91/0.96s without dirtying authored data. - Persistence: saved scene retained the stable model UUID and `animation:clip:10:walking`; clean reload hydrated the actor correctly. - PIE: entering play clears paused edit-mode preview state; authored animation advanced in PIE with 11,514 changed pixels between captured robot-region frames and no runtime/render errors. - Move resilience: moving the source to `assets/models/characters/robot_expressive.glb` preserved UUID `339488ab-16a6-47c4-a0ea-0f97ff7a6393`, regenerated manifests at the new path, rehydrated the saved actor, and validated with 0 blockers. - Package/runtime: development package contained the moved GLB, generated static/animation manifests, stable scene references, binary, and metadata. Standalone startup loaded the default scene cleanly; two frames 0.5s apart differed by 372,821 pixels, visibly confirming skeletal playback. - Unsupported/mismatch paths have focused coverage for animated/skinned FBX guidance, multi-root sources, exact rig signatures, missing manifests/clips, and stale runtime graph cleanup. All BS-PR-703 acceptance gates are satisfied.
Rbanh added reference main 2026-07-11 12:42:16 -04:00
Rbanh closed this issue 2026-07-11 12:42:18 -04:00
Author
Owner

Corrective architecture follow-up — dedicated skinned renderer (2026-07-11)

The accepted animation workflow remains closed. This follow-up corrects the renderer boundary so rigged, skinned, or animated geometry is no longer represented or hydrated through static-mesh components.

RobotExpressive placed through the dedicated Skinned Mesh Renderer

Implemented

  • Added authored SkinnedMeshRenderer and a dedicated HydratedSkinnedMeshRoot; the runtime path preserves the imported joint hierarchy, inverse bind poses, and Bevy SkinnedMesh bindings.
  • Model, skinned-primitive, and animation-clip placement now route animated/skinned sources through the skinned renderer instead of StaticMeshRenderer or generic static slots.
  • Static-mesh manifest schema v2 excludes skin-bound primitives and all animated-source geometry from static placement.
  • Scene schema v3 migrates legacy animated ModelRef actors to SkinnedMeshRenderer.
  • Editor inspection and validation now surface the renderer split explicitly and diagnose static-renderer use for animated/skinned sources.

The live editor evidence above shows RobotExpressive as a SkinnedMesh actor, the dedicated Skinned Mesh Renderer inspector card, and the Asset Browser source annotation Skinned | dedicated renderer.

Documentation

  • ADR 0033 — Dedicated skinned mesh renderer
  • Repository docs updated locally: README.md, docs/README.md, docs/editor/README.md, docs/editor/animation-authoring.md, docs/editor/architecture.md, and the authoring/hydration ADR links.

Verification

  • cargo test --workspace passed.
  • cargo fmt --all -- --check, git diff --check, workspace checks, and strict clippy with warnings denied passed.
  • Live editor smoke test: RobotExpressive was placed from a marked skinned primitive and hydrated as one selected SkinnedMesh actor with the dedicated renderer card.

Status: implemented and verified in the local worktree; this corrective slice has not yet been committed or pushed. No change to this issue's closed state.

## Corrective architecture follow-up — dedicated skinned renderer (2026-07-11) The accepted animation workflow remains closed. This follow-up corrects the renderer boundary so rigged, skinned, or animated geometry is no longer represented or hydrated through static-mesh components. ![RobotExpressive placed through the dedicated Skinned Mesh Renderer](https://git.spacetrainclubhouse.com/attachments/96585466-9f31-4617-ae28-563b74f57745) ### Implemented - Added authored `SkinnedMeshRenderer` and a dedicated `HydratedSkinnedMeshRoot`; the runtime path preserves the imported joint hierarchy, inverse bind poses, and Bevy `SkinnedMesh` bindings. - Model, skinned-primitive, and animation-clip placement now route animated/skinned sources through the skinned renderer instead of `StaticMeshRenderer` or generic static slots. - Static-mesh manifest schema v2 excludes skin-bound primitives and all animated-source geometry from static placement. - Scene schema v3 migrates legacy animated `ModelRef` actors to `SkinnedMeshRenderer`. - Editor inspection and validation now surface the renderer split explicitly and diagnose static-renderer use for animated/skinned sources. The live editor evidence above shows RobotExpressive as a `SkinnedMesh` actor, the dedicated **Skinned Mesh Renderer** inspector card, and the Asset Browser source annotation **Skinned | dedicated renderer**. ### Documentation - [ADR 0033 — Dedicated skinned mesh renderer](https://git.spacetrainclubhouse.com/attachments/145bda7f-93fc-4f41-9d6b-124be79b616d) - Repository docs updated locally: `README.md`, `docs/README.md`, `docs/editor/README.md`, `docs/editor/animation-authoring.md`, `docs/editor/architecture.md`, and the authoring/hydration ADR links. ### Verification - `cargo test --workspace` passed. - `cargo fmt --all -- --check`, `git diff --check`, workspace checks, and strict clippy with warnings denied passed. - Live editor smoke test: RobotExpressive was placed from a marked skinned primitive and hydrated as one selected `SkinnedMesh` actor with the dedicated renderer card. Status: implemented and verified in the local worktree; this corrective slice has not yet been committed or pushed. No change to this issue's closed state.
Rbanh reopened this issue 2026-07-11 18:50:02 -04:00
Author
Owner

Reopened: default-pose and stop/restore regression

This issue is reopened because the current skinned actor workflow does not yet satisfy the original preview/hydration acceptance criteria.

The RobotExpressive fixture was reproduced outside the editor: its authored default node pose shows the same crouched/disconnected-looking result, while its imported rest/bind pose is coherent. The dedicated skinned renderer is preserving the source hierarchy; the missing product contract is an explicit edit-time pose lifecycle. A second regression is also confirmed: stopping preview clears playback but does not restore the sampled descendant Transform and MorphWeights values.

Corrective acceptance:

  • Add an optional model import setting that stores an exact stable default clip subasset ID; never guess the first clip or retarget a stale ID by display label.
  • Capture imported descendant transforms and morph weights once the scene instance is ready and before animation evaluation.
  • With a valid explicit default clip, sample its configured edit-rest pose; without one, display the captured imported rest pose.
  • Stop, PIE exit, controller removal, and preview reset restore the captured baseline exactly before any configured edit-rest sample is reapplied.
  • Validate each skin independently: inverse-bind data exists, joint count matches inverse-bind count, and every joint belongs to the instantiated hierarchy. Shared joints are captured once without conflating distinct skins.
  • Material-only edits from #51 leave hierarchy, joints, baseline, animation players, and pose unchanged.
  • RobotExpressive regression coverage includes all 19 imported draw bindings, both skin records, explicit Standing edit-rest configuration, transform restoration, morph-weight restoration, and save/hydrate/PIE round trips.
  • Link updated animation workflow documentation, automated results, and a committed evaluation screenshot before closure.

Implementation and acceptance evidence are pending; the prior screenshot/ADR attachments remain historical evidence of the dedicated-renderer refactor, not proof that this corrective lifecycle is complete.

### Reopened: default-pose and stop/restore regression This issue is reopened because the current skinned actor workflow does not yet satisfy the original preview/hydration acceptance criteria. The RobotExpressive fixture was reproduced outside the editor: its authored default node pose shows the same crouched/disconnected-looking result, while its imported rest/bind pose is coherent. The dedicated skinned renderer is preserving the source hierarchy; the missing product contract is an explicit edit-time pose lifecycle. A second regression is also confirmed: stopping preview clears playback but does not restore the sampled descendant `Transform` and `MorphWeights` values. Corrective acceptance: - [ ] Add an optional model import setting that stores an exact stable default clip subasset ID; never guess the first clip or retarget a stale ID by display label. - [ ] Capture imported descendant transforms and morph weights once the scene instance is ready and before animation evaluation. - [ ] With a valid explicit default clip, sample its configured edit-rest pose; without one, display the captured imported rest pose. - [ ] Stop, PIE exit, controller removal, and preview reset restore the captured baseline exactly before any configured edit-rest sample is reapplied. - [ ] Validate each skin independently: inverse-bind data exists, joint count matches inverse-bind count, and every joint belongs to the instantiated hierarchy. Shared joints are captured once without conflating distinct skins. - [ ] Material-only edits from #51 leave hierarchy, joints, baseline, animation players, and pose unchanged. - [ ] RobotExpressive regression coverage includes all 19 imported draw bindings, both skin records, explicit Standing edit-rest configuration, transform restoration, morph-weight restoration, and save/hydrate/PIE round trips. - [ ] Link updated animation workflow documentation, automated results, and a committed evaluation screenshot before closure. Implementation and acceptance evidence are pending; the prior screenshot/ADR attachments remain historical evidence of the dedicated-renderer refactor, not proof that this corrective lifecycle is complete.
Author
Owner

Corrective pose lifecycle implemented locally

The regression acceptance added in comment 863 is now implemented and verified on codex/renderer-material-component-foundation:

  • one explicit stable default clip ID (RobotExpressive uses Standing), never first-clip guessing;
  • descendant Transform and MorphWeights baselines captured before evaluation;
  • exact restore on stop, controller removal, preview reset, and PIE exit;
  • independent validation for both skin records and all 19 draw bindings;
  • material-only edits patch the dedicated skinned hierarchy without changing joints, players, baseline, or pose;
  • live evidence shows the coherent edit pose plus the dedicated renderer/material slots.

Full test counts, documentation paths, screenshots, and the honest Solari deformation boundary are recorded on #51 comment 865.

This issue stays open until the local branch and committed evaluation screenshot are published; no pushed-state claim is being made.

### Corrective pose lifecycle implemented locally The regression acceptance added in [comment 863](https://git.spacetrainclubhouse.com/Falling-Metal-Interactive/Blacksite/issues/46#issuecomment-863) is now implemented and verified on `codex/renderer-material-component-foundation`: - one explicit stable default clip ID (RobotExpressive uses Standing), never first-clip guessing; - descendant `Transform` and `MorphWeights` baselines captured before evaluation; - exact restore on stop, controller removal, preview reset, and PIE exit; - independent validation for both skin records and all 19 draw bindings; - material-only edits patch the dedicated skinned hierarchy without changing joints, players, baseline, or pose; - live evidence shows the coherent edit pose plus the dedicated renderer/material slots. Full test counts, documentation paths, screenshots, and the honest Solari deformation boundary are recorded on [#51 comment 865](https://git.spacetrainclubhouse.com/Falling-Metal-Interactive/Blacksite/issues/51#issuecomment-865). This issue stays open until the local branch and committed evaluation screenshot are published; no pushed-state claim is being made.
Author
Owner

Corrective pose-lifecycle acceptance is now published in commit 0798aa5d5724115b198d5ec2a2df57e051b49f60 on codex/renderer-material-component-foundation.

Evidence:

The explicit stable default clip, imported transform/morph baselines, exact stop/reset/PIE restoration, independent two-skin validation, 19 draw bindings, material-only pose preservation, and save/hydrate/PIE regression coverage are all implemented and published. Closing BS-PR-703.

Corrective pose-lifecycle acceptance is now published in commit `0798aa5d5724115b198d5ec2a2df57e051b49f60` on `codex/renderer-material-component-foundation`. Evidence: - [Animation/material/component evaluation record](https://git.spacetrainclubhouse.com/Falling-Metal-Interactive/Blacksite/src/commit/0798aa5d5724115b198d5ec2a2df57e051b49f60/docs/editor/evaluations/material-renderer-foundation/README.md) - [Dedicated skinned renderer and stable slots](https://git.spacetrainclubhouse.com/attachments/fb4a04e7-88ac-4946-a81a-ef3d3ba26140) - Full automated and live acceptance details are recorded in #51 comment 865, with publication links in #51 comment 878. The explicit stable default clip, imported transform/morph baselines, exact stop/reset/PIE restoration, independent two-skin validation, 19 draw bindings, material-only pose preservation, and save/hydrate/PIE regression coverage are all implemented and published. Closing BS-PR-703.
Rbanh closed this issue 2026-07-12 02:36:15 -04:00
Sign in to join this conversation.
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: Falling-Metal-Interactive/Blacksite#46
No description provided.