Skip to main content

Overview

The ItemSystem is a React component that processes dirty item nodes and calculates their position based on attachment type:
  • Wall-side items: Offset by wall thickness with correct side orientation
  • Floor items: Elevated by slab height using spatial grid
  • Ceiling items: Positioned at ceiling height
  • Surface-placed items: Positioned on other items via hierarchy
The system runs in a useFrame hook at priority 2, ensuring items update after slabs but before walls.

Location

How It Works

Processing Pipeline

1

Monitor dirty nodes

The system watches the dirtyNodes set for nodes with type === 'item'.
2

Determine attachment type

Check the item’s asset.attachTo property:
  • 'wall-side': Wall-attached items (art, TVs, switches)
  • 'wall': Wall-embedded items (windows, doors)
  • 'ceiling': Ceiling-attached items (lights, fans)
  • undefined: Floor or surface-placed items
3

Calculate position

Based on attachment type:
  • Wall-side: Offset Z by (wallThickness / 2) * side
  • Floor: Query spatial grid for slab elevation
  • Surface: Let React Three Fiber hierarchy handle it
4

Clear dirty flag

Once the mesh is positioned, the node is removed from dirtyNodes.

Props

The ItemSystem component has no props. It reads state from the Zustand store:
Set<AnyNodeId>
Set of node IDs that need position updates
Record<AnyNodeId, AnyNode>
All nodes in the scene graph

Dependencies

ItemNode Schema

The system processes ItemNode objects with these properties:
string
required
Unique item identifier
[number, number, number]
default:"[0, 0, 0]"
Position in level (or parent) coordinates [x, y, z]
[number, number, number]
default:"[0, 0, 0]"
Euler rotation in radians [x, y, z]
[number, number, number]
default:"[1, 1, 1]"
Scale multiplier [x, y, z]
'front' | 'back'
Which side of the wall the item is on (for attachTo: 'wall-side')
string
Parent node ID (wall, ceiling, level, or another item)
Asset
required
Asset definition containing dimensions, model URL, and attachment type

Asset Schema

'wall' | 'wall-side' | 'ceiling' | undefined
How the item attaches to the scene:
  • 'wall-side': On wall surface (art, TVs)
  • 'wall': Embedded in wall (windows, doors)
  • 'ceiling': Hangs from ceiling (lights, fans)
  • undefined: Sits on floor or surface
[number, number, number]
Base dimensions in meters [width, height, depth]
{ height: number }
Optional surface definition for items that support placement on top

External Systems

  • Scene Registry (sceneRegistry.nodes): Maps node IDs to THREE.js meshes
  • Spatial Grid Manager (spatialGridManager): Provides slab elevation for floor items

Positioning Logic

Wall-Side Items

Items attached to wall surfaces are offset perpendicular to the wall:
  • Front side: z = +wallThickness/2 (outside wall)
  • Back side: z = -wallThickness/2 (inside wall)

Floor Items

Items placed on the floor query the spatial grid for slab elevation:
The spatial grid uses the item’s full footprint to determine which slab it sits on.

Surface-Placed Items

Items placed on surfaces (tables, desks) inherit position from their parent:

Slab Elevation Calculation

The spatial grid manager calculates slab elevation by:
  1. Transforming item footprint to world coordinates
  2. Querying spatial grid cells that overlap the footprint
  3. Finding highest slab that the item sits on
  4. Returning elevation (or 0 if no slab found)
This ensures items:
  • Sit on raised platforms
  • Don’t fall through floors
  • Rest on the correct slab when overlapping multiple floors

Usage Example

Coordinate Systems

Wall-Attached Items

Wall-local coordinates:
  • X-axis: Along wall length
  • Y-axis: Height (up)
  • Z-axis: Perpendicular to wall (thickness direction)

Floor Items

Level coordinates:
  • X-axis: Horizontal (left-right)
  • Y-axis: Vertical (height)
  • Z-axis: Horizontal (forward-back)

Ceiling Items

Ceiling-local coordinates:
  • X-axis: Horizontal (left-right)
  • Y-axis: Vertical (down from ceiling)
  • Z-axis: Horizontal (forward-back)

Surface Placement

Items with asset.surface can have other items placed on them:
The parent-child hierarchy in React Three Fiber automatically handles the transform.

Performance Notes

  • Only updates dirty items (not all items every frame)
  • Runs at priority 2 (after slabs update their geometry)
  • Uses cached spatial grid queries for slab elevation
  • No geometry generation (just position updates)

Integration with Other Systems

Wall System

Walls create cutouts for wall-attached items with a 'cutout' mesh using CSG subtraction.

Spatial Grid

The spatial grid tracks slab boundaries and elevations to correctly position floor items, even on complex multi-level floors.

Scene Registry

All item meshes are registered in sceneRegistry.nodes for quick lookup by ID.