Skip to main content

@pascal-app/core

The @pascal-app/core package provides the foundational scene graph management, state store, and spatial systems for Pascal. It handles the hierarchical node structure, undo/redo, persistence, and collision detection.

Installation

npm install @pascal-app/core

Package Exports

Store

  • useScene - Main Zustand store for scene state management

Events

  • emitter - Event bus for scene interactions (based on mitt)
  • eventSuffixes - Available event suffixes: click, move, enter, leave, pointerdown, pointerup, context-menu, double-click
Event Types:
  • BuildingEvent - Building interaction events
  • CameraControlEvent - Camera control events
  • CeilingEvent - Ceiling interaction events
  • DoorEvent - Door interaction events
  • EventSuffix - Type for event suffix strings
  • GridEvent - Grid interaction events
  • ItemEvent - Item interaction events
  • LevelEvent - Level interaction events
  • NodeEvent - Generic node events
  • RoofEvent - Roof interaction events
  • SiteEvent - Site interaction events
  • SlabEvent - Slab interaction events
  • WallEvent - Wall interaction events
  • WindowEvent - Window interaction events
  • ZoneEvent - Zone interaction events

Hooks & Registry

  • sceneRegistry - Global registry mapping node IDs to Three.js Object3D instances
  • useRegistry - React hook to register Three.js objects with the scene registry

Spatial Grid

  • spatialGridManager - Singleton for spatial queries and collision detection
  • useSpatialQuery - Hook for querying spatial grid (floor, wall, ceiling placement)
  • initSpatialGridSync - Initialize spatial grid synchronization with scene store
  • resolveLevelId - Resolve level ID from any node by walking up the parent chain

Schema

Node Types:
  • SiteNode - Root container for buildings
  • BuildingNode - Contains levels
  • LevelNode - Contains walls, slabs, items
  • WallNode - Wall geometry
  • SlabNode - Floor/ceiling slab
  • CeilingNode - Ceiling geometry
  • ItemNode - 3D object/furniture
  • ZoneNode - Spatial zone
  • RoofNode - Roof geometry
  • ScanNode - Scan data
  • GuideNode - Guide/helper object
  • WindowNode - Window in wall
  • DoorNode - Door in wall
Schema Utilities:
  • generateId - Generate unique node IDs with prefix (e.g., wall_abc123)
  • objectId - Zod schema for object IDs with default generation
  • nodeType - Zod schema for node type literals
  • Material - Zod schema for material preset name references
  • getScaledDimensions - Get item dimensions with scale applied
Type Utilities:
  • BaseNode - Base node schema
  • CameraSchema - Camera configuration schema
  • AnyNode - Union type of all node types
  • AnyNodeId - Any node ID type
  • AnyNodeType - Any node type string

Systems

Systems are React components that run physics/validation logic each frame:
  • CeilingSystem - Ceiling validation and updates
  • DoorSystem - Door placement and validation
  • ItemSystem - Item collision detection
  • RoofSystem - Roof geometry updates
  • SlabSystem - Slab elevation and validation
  • WallSystem - Wall mitering and CSG operations
  • WindowSystem - Window placement validation

Space Detection

  • detectSpacesForLevel - Detect enclosed spaces in a level
  • initSpaceDetectionSync - Initialize space detection synchronization
  • wallTouchesOthers - Check if wall connects to other walls
  • Space - Space detection result type

Asset Storage

  • loadAssetUrl - Load asset URL from storage
  • saveAsset - Save asset to storage

Utilities

Type Guards:
  • isObject - Type guard to check if value is a plain object (not null or array)
Geometry:
  • pointInPolygon - Point-in-polygon test using ray casting algorithm

Architecture

Scene Graph

The scene is a hierarchical tree structure:
SiteNode (root)
└─ BuildingNode
   └─ LevelNode
      ├─ WallNode
      │  ├─ WindowNode
      │  ├─ DoorNode
      │  └─ ItemNode (wall-attached)
      ├─ SlabNode
      ├─ CeilingNode
      │  └─ ItemNode (ceiling-attached)
      ├─ RoofNode
      ├─ ZoneNode
      └─ ItemNode (floor items)

State Management

The useScene store is built with:
  • Zustand - State management
  • Zundo - Undo/redo (temporal middleware)
  • Persist - LocalStorage persistence

Spatial Systems

The spatialGridManager provides:
  • Floor grid for item placement
  • Wall grid for wall-mounted items
  • Ceiling grid for ceiling items
  • Slab elevation queries
  • Collision detection

Usage Example

import useScene from '@pascal-app/core'
import { spatialGridManager, sceneRegistry } from '@pascal-app/core'

// Access scene state
function MyComponent() {
  const nodes = useScene((state) => state.nodes)
  const createNode = useScene((state) => state.createNode)
  
  // Create a new item
  const handleCreate = () => {
    const itemNode = ItemNode.parse({
      asset: { id: 'chair-01', attachTo: null },
      position: [0, 0, 0],
      rotation: [0, 0, 0],
      scale: [1, 1, 1],
    })
    createNode(itemNode, levelId)
  }
  
  // Check if placement is valid
  const canPlace = spatialGridManager.canPlaceOnFloor(
    levelId,
    [x, y, z],
    [width, height, depth],
    [0, 0, 0]
  )
  
  return <div>{/* ... */}</div>
}

Next Steps

Build docs developers (and LLMs) love