Overview
TheWindowSystem is a React component that processes dirty window nodes and generates 3D window geometry. It supports:
- Parametric window geometry with configurable pane grids
- CSG cutouts in parent walls for window openings
- Multi-pane layouts with independent row and column divisions
- Optional sill with configurable depth and thickness
- Flexible divider spacing for custom pane arrangements
useFrame hook at priority 3, ensuring windows 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 === 'window'.2
Update window geometry
For each dirty window:
- Generate new geometry from window parameters
- Create frame members (top, bottom, left, right)
- Build pane grid with column and row dividers
- Add glass panes for each grid cell
- Add optional sill
- Update the invisible cutout mesh for wall CSG
3
Mark parent wall dirty
Trigger parent wall rebuild so its CSG cutout reflects the updated window geometry.
4
Clear dirty flag
Once the mesh is updated, the node is removed from
dirtyNodes.Geometry Generation
TheupdateWindowMesh() function builds window geometry in these steps:
- Create invisible hitbox (root mesh for selection)
- Build frame members (top, bottom, left, right)
- Calculate pane grid layout from
columnRatiosandrowRatios - Add column dividers (full inner height)
- Add row dividers (per column width to avoid overlap)
- Add glass panes for each grid cell
- Add optional sill (protrudes from front face)
- Update cutout mesh (always full window dimensions, 1m deep for wall CSG)
Props
TheWindowSystem 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
WindowNode Schema
The system processesWindowNode objects with these properties:
string
required
Unique window identifier
[number, number, number]
default:"[0, 0, 0]"
Center of the window in wall-local coordinates
[x, y, z][number, number, number]
default:"[0, 0, 0]"
Euler rotation in radians
[x, y, z]number
default:"1.5"
Overall window width in meters
number
default:"1.5"
Overall window 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)
number[]
default:"[1]"
Relative width proportions for columns (e.g.,
[1, 1] = two equal columns)number[]
default:"[1]"
Relative height proportions for rows (e.g.,
[1, 2] = bottom row twice as tall)number
default:"0.03"
Thickness of vertical dividers in meters
number
default:"0.03"
Thickness of horizontal dividers in meters
boolean
default:"true"
Whether to show window sill
number
default:"0.08"
Depth of sill protrusion in meters
number
default:"0.03"
Thickness of sill in meters
string
Parent wall ID
External Systems
- Scene Registry (
sceneRegistry.nodes): Maps node IDs to THREE.js meshes - Wall System (
WallSystem): Applies CSG subtraction using window’s cutout mesh
Window Geometry Details
Frame Construction
The frame consists of four members:- Top bar: Full width,
frameThicknesstall - Bottom bar: Full width,
frameThicknesstall - Left post: Inner height (to avoid corner overlap),
frameThicknesswide - Right post: Inner height (to avoid corner overlap),
frameThicknesswide
Pane Grid Layout
The inner area is divided bycolumnRatios and rowRatios:
1
Calculate usable dimensions
Subtract divider thicknesses from inner dimensions:
2
Distribute by ratios
Divide usable space proportionally:
3
Calculate cell centers
Compute X and Y centers for each grid cell accounting for dividers.
Divider Placement (window-system.tsx:133-150)
Column dividers span full inner height:Glass Panes (window-system.tsx:152-158)
Each grid cell gets a thin glass pane:Sill (window-system.tsx:160-166)
Optional sill protrudes from the front face:CSG Cutouts
The window creates a cutout in its parent wall using Constructive Solid Geometry:1
Create cutout mesh
Invisible mesh named
'cutout' with full window 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 window changes
Whenever a window is updated, its parent wall is marked dirty to trigger CSG recalculation.
Usage in Viewer
- Monitors the
dirtyNodesstore - Updates windows when they’re marked dirty
- Triggers parent wall CSG updates
Common Window Configurations
Single-Hung Window
Double-Hung Window
Bay Window Center
Picture Window
Casement Pair
Materials
The system uses three materials:Performance Notes
- Only updates dirty windows (not all windows every frame)
- Reuses shared material instances across all windows
- 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
Windows use wall-local coordinates:- X-axis: Along wall length
- Y-axis: Height (up)
- Z-axis: Perpendicular to wall (through thickness)
position is its center in wall-local space.
Integration with Other Systems
Wall System
Walls query child window nodes to:- Collect cutout meshes named
'cutout' - Apply CSG subtraction to create window openings
- Maintain wall structural integrity around openings
Scene Registry
All window meshes are registered insceneRegistry.nodes for quick lookup by ID and selection.
Related
- WallSystem - Applies CSG cutouts for windows
- DoorSystem - Similar CSG-based opening system
- ItemSystem - Can position window treatments