Overview
TheDoorSystem is a React component that processes dirty door nodes and generates 3D door geometry. It supports:
- Parametric door geometry with configurable segments (panels, glass, empty)
- CSG cutouts in parent walls for door openings
- Commercial hardware (door closers, panic bars)
- Multi-segment layouts with independent column divisions per segment
- Threshold, handle, and hinge customization
useFrame hook at priority 3, ensuring doors update after items and slabs but before wall CSG operations.
Location
How It Works
Processing Pipeline
1
Monitor dirty nodes
The system watches the
dirtyNodes set for nodes with type === 'door'.2
Update door geometry
For each dirty door:
- Generate new geometry from door parameters
- Create frame members (left post, right post, head)
- Build leaf segments (panels, glass, or empty)
- Add hardware (handle, hinges, closer, panic bar)
- Update the invisible cutout mesh for wall CSG
3
Mark parent wall dirty
Trigger parent wall rebuild so its CSG cutout reflects the updated door geometry.
4
Clear dirty flag
Once the mesh is updated, the node is removed from
dirtyNodes.Geometry Generation
TheupdateDoorMesh() function builds door geometry in these steps:
- Create invisible hitbox (root mesh for selection)
- Build frame members (left post, right post, head)
- Add threshold if enabled
- Build leaf segments with content padding border strips
- Generate segment content (panels with raised details, glass panes, or empty fill)
- Add hardware (handle, door closer, panic bar, hinges)
- Update cutout mesh (always full door dimensions, 1m deep for wall CSG)
Props
TheDoorSystem component has no props. It reads state from the Zustand store:
Set<AnyNodeId>
Set of node IDs that need geometry updates
Record<AnyNodeId, AnyNode>
All nodes in the scene graph
Dependencies
DoorNode Schema
The system processesDoorNode objects with these properties:
string
required
Unique door identifier
[number, number, number]
default:"[0, 0, 0]"
Center of the door in wall-local coordinates
[x, y, z][number, number, number]
default:"[0, 0, 0]"
Euler rotation in radians
[x, y, z]number
default:"0.9"
Overall door width in meters
number
default:"2.1"
Overall door height in meters
number
default:"0.05"
Width of frame members in meters
number
default:"0.07"
Depth of frame in meters (perpendicular to wall)
boolean
default:"true"
Whether to show threshold at door base
number
default:"0.02"
Height of threshold in meters
'left' | 'right'
default:"'left'"
Which side the hinges are on
'inward' | 'outward'
default:"'inward'"
Direction the door swings
DoorSegment[]
required
Array of segments stacked top to bottom, each defining its own column layout
boolean
default:"true"
Whether to show door handle
number
default:"1.05"
Height of handle from floor in meters
'left' | 'right'
default:"'right'"
Which side the handle is on
[number, number]
default:"[0.04, 0.04]"
Leaf inner margin
[x, y] in metersboolean
default:"false"
Whether to show commercial door closer hardware
boolean
default:"false"
Whether to show panic bar (emergency exit hardware)
number
default:"1.0"
Height of panic bar from floor in meters
string
Parent wall ID
DoorSegment Schema
Each segment in thesegments array has:
'panel' | 'glass' | 'empty'
required
'panel': Opaque with raised/recessed panel detail'glass': Transparent glazed pane'empty': Flat opaque fill
number
required
Relative height proportion (segments are stacked top to bottom)
number[]
default:"[1]"
Relative width proportions for columns within this segment
number
default:"0.03"
Thickness of column dividers in meters
number
default:"0.01"
Depth of raised panel (positive = raised, negative = recessed)
number
default:"0.04"
Inset from segment edges to panel detail in meters
External Systems
- Scene Registry (
sceneRegistry.nodes): Maps node IDs to THREE.js meshes - Wall System (
WallSystem): Applies CSG subtraction using door’s cutout mesh
Door Geometry Details
Frame Construction
The frame consists of three members:- Left post: Full height,
frameThicknesswide - Right post: Full height,
frameThicknesswide - Head (top bar): Full width,
frameThicknesstall
Leaf Layout
The leaf occupies the full opening with no bottom frame:Segment Processing
Segments are stacked top to bottom:1
Calculate segment heights
Divide content area by
heightRatio proportions.2
Divide into columns
For each segment, split width by
columnRatios with dividerThickness spacing.3
Generate content per column
- Panel: Opaque backing + raised panel detail
- Glass: Thin transparent pane (no opaque backing)
- Empty: Opaque backing only
Hardware
Hinges (door-system.tsx:227-241)
Three knuckle-style hinges positioned:- Bottom: 0.25m from floor
- Middle: Centered vertically
- Top: 0.25m from top
Handle (door-system.tsx:194-209)
Lever-style handle with backplate and grip, positioned on front face athandleHeight.
Door Closer (door-system.tsx:211-218)
Commercial closer with body and arm, mounted at top of leaf.Panic Bar (door-system.tsx:220-224)
Horizontal push bar atpanicBarHeight, spanning 72% of leaf width.
CSG Cutouts
The door creates a cutout in its parent wall using Constructive Solid Geometry:1
Create cutout mesh
Invisible mesh named
'cutout' with full door dimensions (width × height × 1.0m deep).2
Wall CSG subtraction
Parent wall system subtracts the cutout brush from wall geometry using
three-bvh-csg.3
Rebuild wall on door changes
Whenever a door is updated, its parent wall is marked dirty to trigger CSG recalculation.
Usage in Viewer
- Monitors the
dirtyNodesstore - Updates doors when they’re marked dirty
- Triggers parent wall CSG updates
Multi-Column Segments
Each segment can have independent column divisions:Materials
The system uses three materials:Performance Notes
- Only updates dirty doors (not all doors every frame)
- Reuses shared material instances across all doors
- Disposes old geometries to prevent memory leaks
- Root mesh is invisible hitbox; all visuals are child meshes
- Runs at priority
3(after items, before wall CSG)
Coordinate System
Doors use wall-local coordinates:- X-axis: Along wall length
- Y-axis: Height (up)
- Z-axis: Perpendicular to wall (through thickness)
position is its center, with Y = height/2 so the base sits at floor level.
Related
- WallSystem - Applies CSG cutouts for doors
- WindowSystem - Similar CSG-based opening system
- ItemSystem - Positions door hardware items