16 Commits

Author SHA1 Message Date
Wassim SAMAD
773b58ccd4 Floor-plan: registry-driven action menu + cursor-driven move overlay
Two new files in packages/editor/src/components/editor-2d/ keep the
work out of the 18k-line floorplan-panel.tsx monolith. The panel
itself gets only four tiny additions (two imports, two component
mounts, one data attribute).

<FloorplanRegistryActionMenu>
 - Reads useViewer.selection — when a registered kind is selected and
   we're not in a move state, queries the rendered [data-node-id] <g>
   for its bounding rect (polled via rAF for pan/zoom/move reactivity).
 - Portals an HTML overlay above the bounding box with the existing
   <NodeActionMenu>. Buttons gated by def.capabilities:
     * Move → setMovingNode(node)
     * Duplicate → structuredClone + schema.parse + createNode + set
       movingNode (placement cursor) — matches 3D duplicate UX.
     * Delete → deleteNode(id) + clear selection.
 - Same visual styling as the legacy <FloorplanActionMenuLayer> per
   kind, but driven by registry data.

<FloorplanRegistryMoveOverlay>
 - Activates when useEditor.movingNode is a kind with def.floorplan.
 - Listens on window for pointermove (to track cursor in floor plan
   meters via the scene <g>'s getScreenCTM — matches the legacy
   getSvgPointFromClientPoint coordinate path so cursor → meters
   accounts for pan/zoom/building rotation).
 - Renders a 50%-opacity ghost via portal into the floor-plan scene
   <g>. Builder reused from def.floorplan — no per-kind ghost code.
 - Click commits via updateNode({ position: [cx, oldY, cz] }) and
   clears movingNode. Clears `isNew` metadata on duplicates so they
   don't loop. Esc cancels.

floorplan-panel.tsx touches:
 - Two imports (action menu + move overlay).
 - data-floorplan-scene="" attribute on the floorplanSceneRef <g>
   so the overlay can find the scene without sharing a ref.
 - <FloorplanRegistryActionMenu /> mounted alongside the legacy
   action menu layer.
 - <FloorplanRegistryMoveOverlay /> mounted inside the SVG tree
   alongside the registry render layer.

FloorplanRegistryLayer: also stopPropagation on click events so the
outer SVG's onClick={handleBackgroundClick} doesn't deselect right
after our pointerDown sets selection. Fixes "click-in-2D doesn't
select" bug.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 11:18:45 -04:00
Wassim SAMAD
a3fb5bd622 FloorplanRegistryLayer: strip drag-to-move, keep click-to-select
The drag-with-grab-cursor model was wrong design — 3D doesn't drag,
it uses select → inspector "Move" button → click-to-place. Floor
plan should match. Drag also had a coord-conversion bug (used outer
<svg> CTM instead of the floorplanSceneRef <g>, so screen→meter
conversion didn't account for the floor plan's pan/zoom/building-
rotation transforms).

Strips the drag pointerdown/move/up handlers, the imperative
transform override, the temporal pause bracketing, and the global
window listeners. Cursor goes back to 'pointer'. Only click-to-
select remains.

The right pattern (move via inspector / action menu + cursor-driven
placement) needs:
 - Registry-aware FloorplanActionMenuLayer path
 - Generic movingNode handler in floor-plan-panel for any registered
   kind with capabilities.movable
 - Shared floorplanSceneRef for accurate coord conversion
Both flagged in the plan as Phase 4 follow-on gaps with their
acceptance criteria. 3D-realtime-sync-while-moving is documented as
deferred (legacy doesn't do it for any kind either; design + ship
in a dedicated PR later).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 11:02:44 -04:00
Wassim SAMAD
d10d7f8deb Phase 4 follow-on: floor-plan interaction + def.toolHints + spawn floorplan builder
Three additions on top of the floor-plan registry contract:

1. def.toolHints + RegisteredToolHelper (registry contract for the
   shortcut hint panel)

   - New ToolHint type in core: { key, label } static array.
   - Added `def.toolHints?: ToolHint[]` to NodeDefinition.
   - New <RegisteredToolHelper hints={...}> in editor — same visual
     styling as WallHelper / ItemHelper but data-driven.
   - HelperManager: registry-first check before falling through to the
     hand-written per-tool switch. Per-tool helper files get deleted
     as their kind migrates `toolHints` in.
   - Shelf + spawn definitions ship toolHints today; wall ports in
     Phase 3 Milestone C alongside its tool/affordance port.

2. Floor-plan interaction layer (selection + drag-to-move)

   - <FloorplanRegistryLayer> now wraps each entry in an interactive
     <g>:
       * Click → useViewer.setSelection({ selectedIds: [id] }).
         Selection visual is a thicker accent-colored stroke applied
         via withSelectionStyle() recursion through the FloorplanGeometry
         tree — kinds don't author selection decoration.
       * Drag → imperative SVG transform during the gesture, single
         updateNode commit on pointerup. Same "smooth move" pattern as
         MoveRegistryNodeTool for 3D drag: no per-tick store update,
         no React re-render storm, no zundo bloat. Coordinate
         conversion via svg.getScreenCTM().inverse().
       * useScene.temporal.pause/resume brackets the gesture so one
         drag = one undo step.
   - Global pointermove / pointerup listeners so the gesture survives
     the cursor leaving the entry's bounding box (matches the legacy
     elevator-resize-drag and item-drag patterns in floorplan-panel).

3. Spawn floor-plan builder (deferred wiring)

   - buildSpawnFloorplan written but NOT wired on the definition —
     spawn already renders in the legacy floorplan-panel.tsx via
     `floorplanSpawnEntries`, and wiring def.floorplan now would
     double-render. The pure builder lives in nodes/src/spawn/
     floorplan.ts ready to wire when the legacy inline branch is
     removed (Phase 5 spawn-floorplan migration PR — same shape as
     wall's feature flag, but per kind inside the legacy panel).

Plan updated: floor-plan interaction section locks the click/drag
contract in, wall-floor-plan-as-legacy note flags everything advanced
the user sees today as legacy that ports alongside Milestone C.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 10:51:22 -04:00
Wassim SAMAD
ac36297e7e Phase 4 follow-on: registry-driven floor-plan rendering + shelf port
Adds the floor-plan side of the three-checkbox composition model
documented in wiki/architecture/node-definitions.md. Mirrors the 3D
side (def.geometry → <GeometrySystem> → <ParametricNodeRenderer>) but
emits SVG primitives instead of three.js Object3Ds, and runs inside
the floor-plan panel.

Type-side (packages/core/src/registry/types.ts):
 - New FloorplanGeometry tagged union covering path / polygon /
   polyline / rect / circle / line / group. FloorplanStyle props map
   straight to SVG attributes. Coordinates are level-local meters;
   rotations are radians (three.js convention).
 - New `def.floorplan?: (node, ctx) => FloorplanGeometry | null` field
   on NodeDefinition, independent of `geometry` and `renderer`. Re-
   exported via packages/core/src/registry/index.ts.

Runtime (packages/editor):
 - <FloorplanGeometryRenderer> walks the FloorplanGeometry tree and
   emits the matching React-SVG elements. Pure data → DOM; no per-kind
   logic.
 - <FloorplanRegistryLayer> reads the active levelId, walks the level
   subtree, looks up each node's def.floorplan, builds a
   GeometryContext, calls the builder, and renders the output via
   FloorplanGeometryRenderer.
 - Mounted in floorplan-panel.tsx just before <FloorplanMarqueeLayer>
   so registry-driven kinds layer above legacy inline content.

Shelf migration (proof port):
 - New nodes/src/shelf/floorplan.ts — buildShelfFloorplan(node) emits
   a group with the rotation/translation transform and a width × depth
   rectangle in the shelf's color. Brackets omitted (hidden under top
   board from above).
 - Wired to shelfDefinition.floorplan. Shelf now appears in the floor
   plan view for the first time (was missing from the legacy panel's
   inline switch).

Pattern proven; every future kind migrating in Phase 5 follows the
same shape: a pure (node, ctx) => FloorplanGeometry function. As kinds
register their floor-plan builders, the corresponding inline branches
in floorplan-panel.tsx become dead code and can be deleted in the
same PR.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 10:34:42 -04:00
sudhir
b782ce9cf2 Merge branch 'main' into feat/elevator-system
# Conflicts:
#	packages/editor/src/components/tools/item/move-tool.tsx
#	packages/editor/src/components/tools/tool-manager.tsx
#	packages/editor/src/components/ui/panels/panel-manager.tsx
#	packages/editor/src/store/use-editor.tsx
#	packages/viewer/src/components/renderers/site/site-renderer.tsx
#	packages/viewer/src/components/viewer/ground-occluder.tsx
#	packages/viewer/src/components/viewer/index.tsx
#	packages/viewer/src/components/viewer/post-processing.tsx
2026-05-13 01:38:55 +05:30
sudhir
70c85d7760 Refine wall move previews and expose auto-slab planning 2026-05-12 12:15:45 +05:30
sudhir
909f96ef09 Improve elevator floorplan resize and drag controls 2026-05-10 12:20:53 +05:30
Wawa
e618175bba Reset core/viewer/editor/mcp packages and apps/editor from private-editor
Wholesale swap of packages/{core,viewer,editor,mcp} and apps/editor with the
versions from the private editor repo, which is the production source of truth.

Setup changes:
- packages/{core,viewer,editor} versions held at 0.7.0 baseline (matching
  the most recent published release) so a bump=minor publishes 0.8.0
- packages/mcp held at 0.1.1 (never published; first publish will go through
  the new release.yml flow)
- peerDependencies and devDependencies for inter-package @pascal-app/*
  references pinned to ^0.7.0 instead of '*' / 'workspace:*' so they are
  valid for npm consumers
- Root package.json: TypeScript bumped to 6.0.2, added overrides for
  @types/react, @types/react-dom, @types/three to prevent JSX namespace
  fragmentation across the workspace
- release.yml extended to also publish editor and mcp; 'both' option renamed
  to 'all'; added a sync step that updates inter-package peerDeps/devDeps to
  match the new versions on every bump (so viewer/editor/mcp tarballs always
  reference the version of core they were built against)
- Root scripts gained release:editor and release:mcp shortcuts

Verification:
- bun install --frozen-lockfile is consistent
- packages/{core,viewer,mcp} build cleanly, dist/index.d.ts emitted
- packages/editor check-types reports 21 pre-existing errors, identical to
  what private-editor currently reports

Open PRs against editor-v2 will need rebasing/conflict resolution.
2026-05-09 20:52:26 +00:00
sudhir
70933adf9d Fix floorplan player move and action menu anchoring 2026-05-06 13:54:05 +05:30
sudhir
411ae2e905 Refine 2D door swing rendering 2026-04-29 17:51:58 +05:30
sudhir
3ae8d6d0fa Extract floorplan placement and hit-testing helpers 2026-04-27 12:18:27 +05:30
sudhir
e4f42e0ee5 Use bbox anchors for item dimension measurements 2026-04-27 10:49:20 +05:30
sudhir
45f0867a74 Extract floorplan render logic into editor 2D modules 2026-04-26 23:02:03 +05:30
sudhir
83e1c9d1fd Align floorplan drawing with local build coordinates 2026-04-24 12:39:36 +05:30
sudhir
1492e5bd0c Add roof drag controls to the 2D floorplan 2026-04-22 17:24:58 +05:30
sudhir
a69591670d Refactor floorplan wall visuals and shared plan helpers 2026-04-22 15:34:22 +05:30