Phase 5 Stage C: item floor plan — all 9 kinds now at Stage C
Item is the last Stage A-only kind to gain def.floorplan. Closes Stage C
across every registered kind.
Files added:
- nodes/src/item/floorplan.ts: buildItemFloorplan inlines a self-
contained parent-chain transform walker using `ctx.resolve`. Mirrors
the legacy `getItemFloorplanTransform` math from editor/lib/floorplan/
items.ts:
* Wall parent: rotate item.position by wall's angle, anchor at
wall.start, handle wall-side attachTo via wall.thickness offset.
* Item parent (nested): recurse for parent's transform.
* Level / slab / ceiling parent: item.position is level-local.
Returns a rotated width × depth rectangle. asset.floorPlanUrl image
overlay deferred for Phase 5 follow-up.
Files changed:
- nodes/src/item/definition.ts: wires `floorplan: buildItemFloorplan`.
- floorplan-panel.tsx: floorplanItemEntries useMemo short-circuits to
[] when nodeRegistry.has('item'). Phase 6 deletes the entire useMemo.
Stage C coverage (all 9 registered kinds):
shelf ✅ spawn ✅ fence ✅ slab ✅ ceiling ✅ wall ✅ door ✅ window ✅ item ✅
Next sessions: Stage B for door / window / wall (each large geometry
extraction), Stage D per kind (DragAction affordance ports), Stage E
(drop legacy panels), Phase 6 Stage F cleanup.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
9bcb25d0aa
commit
9aec943740
@@ -1,4 +1,5 @@
|
||||
import type { ItemNode as ItemNodeType, NodeDefinition } from '@pascal-app/core'
|
||||
import { buildItemFloorplan } from './floorplan'
|
||||
import { itemParametrics } from './parametrics'
|
||||
import { ItemNode } from './schema'
|
||||
|
||||
@@ -18,25 +19,17 @@ import { ItemNode } from './schema'
|
||||
* placement. The smooth generic mover can't express that. Legacy
|
||||
* mover keeps running via capability-driven dispatch.
|
||||
* - `selectable`, `duplicable`, `deletable` standard.
|
||||
* - Items have a catalog-defined `surface.height` (some items act as
|
||||
* tables — they expose a surface other items stack on). For Stage A
|
||||
* we don't surface this via `capabilities.surfaces.top` yet —
|
||||
* legacy ItemSystem computes the stack y via spatial-grid lookups.
|
||||
* Phase 5+ may surface it.
|
||||
*
|
||||
* Stages:
|
||||
* - A: registered.
|
||||
* - B: N/A — def.renderer escape hatch (GLB / useGLTF).
|
||||
* - C: `def.floorplan` resolves parent chain via `ctx.resolve`,
|
||||
* returns a rotated rectangle (width × depth). Mirrors the legacy
|
||||
* `getItemFloorplanTransform` math. Legacy `floorplanItemEntries`
|
||||
* short-circuits when item is registered.
|
||||
*
|
||||
* `toolHints`: matches the legacy ItemHelper UI (mouse / R / T / Shift /
|
||||
* Esc) — same panel the user sees during placement. Once item registers,
|
||||
* `HelperManager` consults `def.toolHints` and renders the
|
||||
* `RegisteredToolHelper` for placement (the legacy ItemHelper still
|
||||
* renders for movingNode state — that's a generic "you're moving
|
||||
* something" panel, not item-specific; Phase 5+ may deprecate it).
|
||||
*
|
||||
* Renderer + system: wrap-export of legacy ItemRenderer + bundle of
|
||||
* ItemSystem + ItemLightSystem.
|
||||
*
|
||||
* Tool field absent: catalog UI + item-tool placement flow stays on
|
||||
* editor state. Phase 5+ may port to `DragAction` once the registry's
|
||||
* catalog-aware affordances exist.
|
||||
* Esc) — registry-driven placement panel.
|
||||
*/
|
||||
export const itemDefinition: NodeDefinition<typeof ItemNode> = {
|
||||
kind: 'item',
|
||||
@@ -86,6 +79,9 @@ export const itemDefinition: NodeDefinition<typeof ItemNode> = {
|
||||
// Same priority as the legacy ItemSystem.
|
||||
priority: 2,
|
||||
},
|
||||
// Stage C: floor-plan polygon. ctx.resolve walks the parent chain
|
||||
// (wall / nested item / level) to compute the world-space transform.
|
||||
floorplan: buildItemFloorplan,
|
||||
|
||||
toolHints: [
|
||||
{ key: 'Left click', label: 'Place item' },
|
||||
|
||||
Reference in New Issue
Block a user