Skip to content

Skel: Slice A — Bone CRUD (create / remove / rename / duplicate) #555

@fernandotonon

Description

@fernandotonon

Parent epic: #554

Goal

Direct bone-level CRUD on the skeleton of a selected entity: create a new bone (under a chosen parent), remove a bone (with optional weight transfer to parent), rename, duplicate. The user-requested foundation that every other slice depends on.

Scope

  • New singleton SkeletonEditor (src/SkeletonEditor.{h,cpp}) — main-thread, getSingleton/kill, signals boneCreated(name), boneRemoved(name), boneRenamed(old,new).
  • Create bone:
    • Pick parent bone in the inspector or right-click on a bone in the viewport.
    • Default placement: at parent's tail, oriented along parent's axis. User can drag with TransformOperator immediately after creation.
    • Auto-name: Bone, Bone.001, Bone.002 (Blender convention).
  • Remove bone:
    • Confirmation prompt if the bone has children (offer "remove with children" vs "promote children to parent").
    • Weight transfer: any vertex weighted to the removed bone gets its weight reassigned to the parent (renormalized). Toggle for "transfer to parent" vs "drop weight".
    • Refresh every SubMesh::getBoneAssignments referencing the removed handle.
  • Rename bone: inline edit in the outliner or context menu. Must propagate to:
    • Every animation track in every clip that references the bone (AnimationMerger-style renaming).
    • Every VertexBoneAssignment (handle stays the same; only the name field changes — Ogre stores by handle).
    • The QML inspector / weight overlay caches.
  • Duplicate bone: clones name (with .001 suffix), TRS, parent. Does not clone children (different operation; covered in Slice B's "split chain").
  • Undo: new commands CreateBoneCommand, RemoveBoneCommand, RenameBoneCommand, DuplicateBoneCommand. Each rebuilds the affected vertex assignments + animation tracks atomically.
  • Ogre quirk: there's no Skeleton::removeBone. Bone deletion walks the bone list, rebuilds handles via Skeleton::_buildMapBoneByHandle, then rewrites every SubMesh::clearBoneAssignments / addBoneAssignment referencing the moved handles. Treat as the most complex op in this slice.

Acceptance Criteria

  • Create-bone-from-parent produces a bone visible in the outliner and SkeletonDebug overlay; drag with the gizmo works.
  • Remove-bone with "transfer to parent" leaves the mesh deforming correctly with the parent absorbing the removed bone's influence.
  • Rename-bone propagates to every animation clip and the bone shows up under the new name in dope sheet / curve editor.
  • Duplicate-bone creates a sibling with .001 suffix.
  • Every operation is undoable end-to-end (including weight transfers and clip renames).
  • No regression in BoneDragRelease's drag-with-auto-key path.
  • Sentry breadcrumbs scene.skel.bone.create, .remove, .rename, .duplicate.
  • Headless-CI tests cover each op on a 2-bone fixture skeleton.

Effort

~9 days. Bone removal's handle-rebuild is the schedule risk.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestskeletonSkeleton & rigging: bones, weights, IK, constraints, envelopes

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions