You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
SceneOps: Slice F — Move entity to different scene node + improved node-reparent UX #629
The other half of the user's hierarchy request: move a whole mesh (entity) into a different scene node, and tighten the existing scene-node reparent (already present via SceneTreeModel::reparentNode) so users can actually find and use it.
Scope
Entity move
New helper SubMeshOps::moveEntityToNode(entity, targetNode, transformMode) -> bool where transformMode ∈ { keepWorld, keepLocal }.
Keep world (default): recomputes the entity's scene node's local TRS so the world transform is preserved.
Keep local: TRS unchanged; the entity visibly jumps to the new parent's space.
Multi-select: dragging multiple entities to a new parent preserves each one's world transform individually.
Undo: MoveEntityCommand stores the original parent + local TRS.
Node reparent UX polish
SceneTreeModel::reparentNode is already implemented but invisible to most users. Surface it:
Drag-and-drop a scene node onto another node in qml/SceneTreeNode.qml triggers reparent (with the same keep-world / keep-local picker on first use; remembered as a session default).
Right-click context menu: "Set parent…" picker dialog as a fallback.
Drag onto empty space (or onto the "Scene Root" entry at the top) detaches the node to root.
Validation feedback: the existing canReparent is used to highlight valid drop targets in green / invalid in red during drag, with a tooltip explaining "circular parent rejected" / "already a child" cases.
Group affordance: if multiple nodes are selected and the user picks "Group selected" from the context menu, route through the existing Manager::groupNodes so the new affordance shares the proven group-node path.
Ungroup affordance: right-click on a group node → "Ungroup" via existing Manager::ungroupNode.
Visual indicator for group nodes vs regular nodes in the tree (small icon distinguishing them).
Combined
Drag protocol: the scene tree learns a tiny drop-target taxonomy:
Multiple SceneNodes dragged onto empty space → group (this slice via Manager::groupNodes).
The drop handler dispatches by source/target type.
Acceptance Criteria
Dragging an entity onto a different scene node moves it, with keep-world preserving the visual position.
Keep-local toggles the entity's apparent position correctly.
Multi-entity reparent preserves each entity's world transform.
Dragging a scene node onto another reparents via SceneTreeModel::reparentNode, with canReparent validation surfaced as drop-target highlight + tooltip.
Drop on root (empty space or "Scene Root" entry) detaches.
Group / Ungroup affordances surface in the right-click menu and route through Manager::groupNodes/ungroupNode.
Drop taxonomy correctly dispatches SubEntity / Entity / SceneNode drops.
Undo works for entity-move; existing undo for node reparent is verified.
Project save / load round-trips the new hierarchy.
Parent epic: #623
Goal
The other half of the user's hierarchy request: move a whole mesh (entity) into a different scene node, and tighten the existing scene-node reparent (already present via
SceneTreeModel::reparentNode) so users can actually find and use it.Scope
Entity move
SubMeshOps::moveEntityToNode(entity, targetNode, transformMode) -> boolwheretransformMode ∈ { keepWorld, keepLocal }.MoveEntityCommandstores the original parent + local TRS.Node reparent UX polish
SceneTreeModel::reparentNodeis already implemented but invisible to most users. Surface it:qml/SceneTreeNode.qmltriggers reparent (with the same keep-world / keep-local picker on first use; remembered as a session default).canReparentis used to highlight valid drop targets in green / invalid in red during drag, with a tooltip explaining "circular parent rejected" / "already a child" cases.Manager::groupNodesso the new affordance shares the proven group-node path.Manager::ungroupNode.Combined
Manager::groupNodes).Acceptance Criteria
SceneTreeModel::reparentNode, withcanReparentvalidation surfaced as drop-target highlight + tooltip.Manager::groupNodes/ungroupNode.scene.tree.entity_move,scene.tree.node_reparent,scene.tree.group,scene.tree.ungroup.Effort
~5 days.