Skip to content

feat: spring bones#3373

Open
RocioCM wants to merge 17 commits intofeat/use-unity-wearable-previewfrom
feat/spring-bones
Open

feat: spring bones#3373
RocioCM wants to merge 17 commits intofeat/use-unity-wearable-previewfrom
feat/spring-bones

Conversation

@RocioCM
Copy link
Copy Markdown
Member

@RocioCM RocioCM commented Mar 24, 2026

Add Spring Bones Editor for Wearables

Related PRs:

Context and Problem Statement

Wearable creators need the ability to configure spring bone physics parameters (stiffness, gravity, drag force, etc.) directly within the Builder's item editor. Currently, there is no UI to parse, view, or edit spring bone data embedded in GLB/glTF wearable files, requiring creators to use raw blender custom properties.

Solution

Implement a full spring bones editing workflow: parsing spring bone data from GLB files, providing an interactive UI to tweak physics parameters, live-previewing changes in the wearable preview, and patching the GLB binary on save.

Key changes:

  • GLB parsing layer (glbUtils.ts, parseSpringBones.ts): Extracts and parses spring bone nodes and their extras parameters from GLB/glTF JSON chunks, supporting both binary GLB and plain glTF formats
  • GLB patching layer (patchGltfSpringBones.ts): Re-serializes modified spring bone parameters back into the GLB binary (JSON chunk replacement with proper 4-byte alignment), preserving the BIN chunk verbatim
  • Redux state management: New editor state (bones, springBoneParams, originalSpringBoneParams) with actions for set/add/delete/reset params and selectors for dirty-checking
  • Spring Bones UI (SpringBonesSection): Collapsible bone cards with sliders for stiffness/gravity/drag, vec3 input for gravity direction, bone hierarchy picker popover for center node selection, and copy/paste params between bones
  • Live preview integration (editor sagas): Debounced (1s) push of params to the wearable preview controller via controller.physics.setSpringBonesParams, with immediate push on preview load and emote play
  • Save flow (item sagas): On save, patches the GLB for the active body shape representation (or all representations if they share the same model), re-hashes the patched file, and uploads the updated contents
  • ItemProvider integration: Parses spring bones on item load and body shape change, clearing/resetting state appropriately

Testing

Spring Bones Section:

  • Load a wearable with existing spring bone nodes — verify the "Spring Bones" section appears on the bottom of right panel.
  • Load a wearable with no spring bones — verify the "Spring Bones" section does not appear
  • Load an emote — verify the "Spring Bones" section does not appear
  • Add a new spring bone via "Add a Bone" button and bone hierarchy picker (only spring bones should be selectable on the bone hierarchy)
  • Remove a spring bone via the card menu — verify it disappears from the list
  • Copy/paste parameters between spring bone cards. Once copied, you should be able to paste params multiple times.
  • Click Reset — verify spring bones parameters revert to the last saved state
  • Save the item — verify the spring bones parameters are saved correctly (reload the page or re-download the model and inspect to confirm params persisted)

Preview:

  • Adjust stiffness, gravity power, drag force sliders — verify live preview updates after ~1s debounce
  • Edit stiffness, gravity power, drag force sliders or gravity direction values using the inputs (not the sliders) — verify the values commit on blur. Ensure min-max range from sliders is enforced. verify live preview updates after ~1s debounce
  • Use the center node dropdown to assign/clear a center bone from the hierarchy picker

Body shapes:

  • On a wearable with the same model for both body shapes (male & female), switch body shapes — verify spring bones settings share the same values for both representations
  • Test with separate male/female GLB models — verify only the active body shape's GLB spring bones params are persisted on save (spring bones settings for the other representation should be untouched)

Screenshots

[Pending]

Pending tasks

  • When schemas PR is merged & released, install the new @dcl/schemas version.
  • When UI2 PR is merged & released, install the new decentraland-ui2 version.

@RocioCM RocioCM self-assigned this Mar 24, 2026
@vercel
Copy link
Copy Markdown

vercel bot commented Mar 24, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
builder Ready Ready Preview, Comment Mar 27, 2026 6:28pm

Request Review

@coveralls
Copy link
Copy Markdown

coveralls commented Mar 25, 2026

Pull Request Test Coverage Report for Build 23661386337

Details

  • 192 of 232 (82.76%) changed or added relevant lines in 10 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage increased (+0.6%) to 50.453%

Changes Missing Coverage Covered Lines Changed/Added Lines %
src/modules/editor/types.ts 1 2 50.0%
src/modules/editor/sagas.ts 4 16 25.0%
src/modules/item/sagas.ts 6 33 18.18%
Totals Coverage Status
Change from base Build 23518592275: 0.6%
Covered Lines: 6845
Relevant Lines: 12320

💛 - Coveralls

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds the Spring Bones editing workflow to the Builder item editor, including parsing spring bone data from wearable GLBs, exposing editable parameters in the Right Panel, pushing updates to the preview, and persisting changes by patching the GLB on save.

Changes:

  • Introduces GLB/glTF parsing + patching utilities for spring bone extras (read + write).
  • Adds editor state/actions/selectors/sagas to manage spring bone params, dirty-checking, and preview pushing.
  • Implements the Spring Bones UI section (bone picker, sliders/inputs, center selection, copy/paste) and wires it into load/reset/save flows.

Reviewed changes

Copilot reviewed 36 out of 37 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/modules/translation/languages/en.json Adds Spring Bones UI translations (EN).
src/modules/translation/languages/es.json Adds Spring Bones UI translations (ES).
src/modules/translation/languages/zh.json Adds Spring Bones UI translations (ZH) and formats invalid_video.
src/modules/item/utils.ts Adds helper to find a body-shape representation mainFile.
src/modules/item/utils.spec.ts Unit tests for getRepresentationMainFile.
src/modules/item/sagas.ts Patches GLBs on save when spring bone params changed, re-hashes contents.
src/modules/item/sagas.spec.ts Updates existing save tests to account for new selector usage.
src/modules/editor/types.ts Exposes SpringBoneParams and defines BoneNode.
src/modules/editor/selectors.ts Adds bones/params selectors and “dirty” detection.
src/modules/editor/selectors.spec.ts Adds tests for new editor selectors.
src/modules/editor/sagas.ts Pushes spring bone params to preview (debounced + immediate).
src/modules/editor/reducer.ts Stores bones/params in editor state; supports add/delete/reset; updates “original” on save success.
src/modules/editor/reducer.spec.ts Tests for the new spring bone reducer behavior.
src/modules/editor/actions.ts Adds spring bones actions (set bones/params, add/delete/reset, push).
src/modules/editor/actions.spec.ts Tests for the new spring bones actions.
src/lib/glbUtils.ts Adds GLB/glTF JSON extraction and GLB builder.
src/lib/glbUtils.spec.ts Tests for GLB/glTF extraction and GLB building.
src/lib/parseSpringBones.ts Parses nodes and spring bone params from GLB/glTF JSON.
src/lib/parseSpringBones.spec.ts Tests for parsing + defaults/formatting/center validation.
src/lib/patchGltfSpringBones.ts Patches spring bone params into GLB/glTF JSON (and rebuilds GLB).
src/lib/patchGltfSpringBones.spec.ts Tests for patching correctness, padding, and BIN preservation.
src/components/ItemProvider/ItemProvider.types.ts Adds bodyShape + callbacks to manage spring bone state.
src/components/ItemProvider/ItemProvider.tsx Loads/clears/parses spring bones on item/bodyShape changes.
src/components/ItemProvider/ItemProvider.container.tsx Wires bodyShape + spring bone actions to ItemProvider.
src/components/ItemEditorPage/RightPanel/SpringBonesSection/index.ts Exports SpringBonesSection.
src/components/ItemEditorPage/RightPanel/SpringBonesSection/SpringBonesSection.types.ts Props typing for SpringBonesSection.
src/components/ItemEditorPage/RightPanel/SpringBonesSection/SpringBonesSection.tsx Implements Spring Bones editor UI and bone pickers.
src/components/ItemEditorPage/RightPanel/SpringBonesSection/SpringBonesSection.css Styles for Spring Bones section and picker.
src/components/ItemEditorPage/RightPanel/RightPanel.types.ts Adds spring bones props/actions to RightPanel types.
src/components/ItemEditorPage/RightPanel/RightPanel.tsx Renders SpringBonesSection; includes spring-bone dirty state in Save/Reset.
src/components/ItemEditorPage/RightPanel/RightPanel.css Adds padding to accommodate floating help button.
src/components/ItemEditorPage/RightPanel/RightPanel.container.tsx Connects spring bones state/actions to RightPanel.
src/components/ItemEditorPage/CenterPanel/CenterPanel.types.ts Adds onPushSpringBoneParams prop.
src/components/ItemEditorPage/CenterPanel/CenterPanel.tsx Triggers immediate push on preview load and emote play.
src/components/ItemEditorPage/CenterPanel/CenterPanel.container.tsx Wires pushSpringBoneParams dispatch.
package.json Pins @dcl/schemas to a branch tgz and adds an override.
package-lock.json Updates lockfile to match the new @dcl/schemas source.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@RocioCM RocioCM changed the title feat: spring bones [WIP] feat: spring bones Mar 26, 2026
"CONTENTFUL_ADMIN_ENTITY_ID": "7FJAHnPOiCEHMJhrZ3sRmG",
"CREDITS_SERVER_URL": "https://credits.decentraland.zone",
"WEARABLE_PREVIEW_URL": "https://wearable-preview-git-feat-builder-mode-support-decentraland1.vercel.app/",
"WEARABLE_PREVIEW_URL": "https://wearable-preview-git-feat-spring-bones-decentraland1.vercel.app",
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

once the wearable-preview is deployed to .zone, could we update this to https://wearable-preview.decentraland.zone?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, of course. I'm waiting for this PR #3275 to be completed and merged first (depends on some aang changes that are pending)


// When there are separate male/female GLB models, only patch the one
// matching the currently previewed body shape. When all representations
// share the same model (same content hash), patch all of them.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this mean that I have to do 2 item saves?

what if I change the bodyShape preview before saving?

Copy link
Copy Markdown
Member Author

@RocioCM RocioCM Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. If you submitted 2 different models for male & female: yes, you have to save twice, as both models may have different spring bones. You have to configure the spring bones for one model, save, change body shape and then repeat for the other model.
    If you submitted only 1 model for both male & female: no, you save once and it applies for both male & female.

  2. You will loose your changes if you change body shape before saving 😅

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.

4 participants