Skip to content

fix(editor): wall-item placement & floorplan polish#450

Merged
wass08 merged 1 commit into
mainfrom
feat/placement-interaction-polish
Jun 29, 2026
Merged

fix(editor): wall-item placement & floorplan polish#450
wass08 merged 1 commit into
mainfrom
feat/placement-interaction-polish

Conversation

@wass08

@wass08 wass08 commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator

What does this PR do?

Polish pass on the placement/interaction overhaul (follow-up to #169). Five fixes across the placement coordinator, 2D floorplan, and keyboard handling:

  1. Item-on-item rotation box — when an item is stacked on another item and rotated, the green bounding/placement box diverged from the item by the host's rotation (floor items were fine). The box held the host-local yaw; it now derives world yaw from the mesh/host quaternion in both the R/T handler and the move-start sync.
  2. 2D floorplan move ignores snapping mode — the 2D item-move session hard-coded grid quantization + alignment, gated only by Shift/Alt. Now mode-driven like 3D: grid only in grid mode, alignment guides only in lines/magnetic mode. Also added the move "tick" SFX (fires on any resolved-position change, all modes — matching 3D).
  3. Wall-side item mirrored in 2D floorplan — the footprint depth offset (centerLocalZ) extended toward the wall instead of into the room, laying the box across the wall onto the far side. Flipped -depth/2+depth/2; also aligned the undefined-side anchor to the 3D convention.
  4. Wall item on wrong side during 3D placement — the placement preview bounds + base plane used an into-wall (-Z) convention, and the 2D live preview during a 3D wall placement consumed the 3D world cursor yaw (π off on a wall face), flipping the footprint to the far side. Preview now uses the into-room (+Z) convention and publishes the plan rotation.
  5. Cmd/Ctrl+R rotates the selected node instead of reloading — added a !metaKey && !ctrlKey guard to the global selected-node handler and the 2D move-overlay flip, so the browser reload comes through.

Each was validated live in the editor across several rounds before landing.

How to test

  1. bun dev, open a project with walls.
  2. Item-on-item: place an item on a table, rotate (R/T) and move it — the box hugs the item at every angle. Floor items unaffected.
  3. 2D move snapping: move an item in the 2D floorplan and cycle snapping modes — off = no snap, grid = grid only, lines = guides only. A move "tick" plays in every mode.
  4. Wall item 2D side: place a wall AC, confirm the 2D footprint sits on the same side as 3D (after placement and while moving in 2D).
  5. 3D placement preview: during a 3D wall placement the live 2D preview sits on the correct side (matches the committed result).
  6. Cmd/Ctrl+R: with a node selected, Cmd+R reloads (does not rotate/flip). Plain R still rotates.

Screenshots / screen recording

n/a — verified live; happy to record a clip if useful.

Checklist

  • I've tested this locally with bun dev
  • My code follows the existing code style (run bun check to verify)
  • I've updated relevant documentation (if applicable)
  • This PR targets the main branch

Follow-up (not in this PR)

Doors/windows share the same legacy 2D-move snapping path (door/window/floorplan-move.ts) and would benefit from the same mode-driven fix as #2 — left out to keep this scoped to the reported items.

🤖 Generated with Claude Code


Note

Medium Risk
Touches wall-side coordinate conventions and live transform math across placement, floorplan rendering, and move sessions; regressions could show wrong footprints or snapping, but scope is editor interaction rather than auth or persistence.

Overview
Follow-up polish on placement and 2D/3D parity: wall-side items now use an into-room +Z convention everywhere the plan footprint and 3D preview bounds are built (depth offset, front/back thickness sign, and placement wireframes), fixing mirrored 2D footprints and wrong-side live previews during 3D wall placement. The placement coordinator also publishes plan-space yaw for wall live transforms and derives world yaw for items on rotated hosts so green boxes track stacked/rotated items.

2D floorplan item moves respect the global snapping mode like 3D (grid vs magnetic alignment, not Shift/Alt-only), and the registry move overlay plays the grid-snap tick when the resolved position changes. Cmd/Ctrl+R is left to the browser in the global rotate handler and the 2D move flip handler instead of rotating/flipping the selection.

Reviewed by Cursor Bugbot for commit ba464ef. Bugbot is set up for automated code reviews on this repo. Configure here.

Polish pass on the placement/interaction overhaul. Five fixes:

- Item-on-item rotation box: the cursor box held the host-local yaw instead of
  world yaw, so it diverged from the item by the host's rotation when stacked on
  another item (fine on the floor). The box now derives world yaw from the
  mesh/host quaternion in both the R/T handler and the move-start sync.

- 2D floorplan move now respects the snapping mode (parity with 3D): grid
  quantization only in grid mode, alignment guides only in lines/magnetic mode;
  Shift/Alt no longer hard-bypass. Item move also plays the move "tick" SFX on
  any resolved-position change, like the 3D move.

- Wall-side item footprint side: the 2D footprint depth offset extended toward the
  wall (centerLocalZ -depth/2) instead of into the room, mirroring the item across
  the wall; flipped to +depth/2. Aligned the undefined-side anchor to the 3D
  convention (front +1 / else -1).

- 3D placement preview side: the wall-side preview bounds + base plane used a -Z
  (into-wall) convention; flipped to +Z (into-room) to match the body and the
  fixed 2D footprint. The 2D live preview during a 3D wall placement now publishes
  the plan rotation (wall angle + item yaw) instead of the world cursor yaw, which
  was pi off on a wall face and flipped the footprint to the far side.

- Cmd/Ctrl+R no longer rotates/flips the selected node (it reaches the browser
  reload); guard added to the global selected-node handler and the 2D move overlay.

Verified: core/editor/nodes tsc, biome, editor 162/0 + nodes 292/0 tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@wass08 wass08 merged commit 08731b5 into main Jun 29, 2026
3 checks passed

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit ba464ef. Configure here.

// The box lives in building-local space while the mesh is parented to the host
// item, so add the host's world yaw: the box must track the item's true
// orientation, not its host-local `rotation[1]`.
cursorGroupRef.current.rotation.y = newRotationY + surfaceWorldY

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Item-surface live yaw desync

Medium Severity

When placing items on other items, the 2D floorplan preview's rotation was out of sync with the 3D preview. The 3D box correctly incorporated the host item's world rotation, but useLiveTransforms published only the item's host-local rotation, causing the 2D footprint to appear mis-rotated until refreshed.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit ba464ef. Configure here.

@mintlify

mintlify Bot commented Jun 29, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
pascal 🔴 Failed Jun 29, 2026, 2:38 PM

💡 Tip: Enable Workflows to automatically generate PRs for you.

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.

1 participant