Files
editor/packages/core
Thiago LöpesandGitHub afe14a8cc7 Fix: Restore floor drag/delete functionality for imported legacy JSON… (#413)
* Fix: Restore floor drag/delete functionality for imported legacy JSON files

Summary

Fixed an issue where floors became impossible to drag or delete after importing JSON configuration files created in versions prior to 0.9.1.

Root Cause

The migration process was executing elevator parent migration before all level nodes had their children fully normalized. As a result, imported scenes could end up with inconsistent parent-child relationships, causing floor management operations such as dragging and deletion to fail.

Changes Made
Refactored migrateNodes() into a two-pass migration process.
Added normalization for level nodes:
Ensures level values are valid finite numbers.
Removes references to missing child nodes.
Preserves only valid children during migration.
Moved elevator migration logic to a dedicated second pass:
Elevator parent migration now runs only after all level.children relationships have been stabilized.
Prevents invalid hierarchy reconstruction when importing legacy JSON files.
Result

Imported layouts from versions prior to 0.9.1 now correctly preserve floor hierarchy, allowing floors to be dragged, reordered, and deleted as expected.

* Update use-scene.ts
2026-06-24 16:00:43 -04:00
..
2026-02-05 08:22:19 +09:00

@pascal-app/core

Core library for Pascal 3D building editor.

Installation

npm install @pascal-app/core

Peer Dependencies

npm install react three @react-three/fiber @react-three/drei

What's Included

  • Node Schemas - Zod schemas for all building primitives (walls, slabs, items, etc.)
  • Scene State - Zustand store with IndexedDB persistence and undo/redo
  • Systems - Geometry generation for walls, floors, ceilings, roofs
  • Scene Registry - Fast lookup from node IDs to Three.js objects
  • Spatial Grid - Collision detection and placement validation
  • Event Bus - Typed event emitter for inter-component communication
  • Asset Storage - IndexedDB-based file storage for user-uploaded assets

Usage

import { useScene, WallNode, ItemNode } from '@pascal-app/core'

// Create a wall
const wall = WallNode.parse({
  points: [[0, 0], [5, 0]],
  height: 3,
  thickness: 0.2,
})

useScene.getState().createNode(wall, parentLevelId)

// Subscribe to scene changes
function MyComponent() {
  const nodes = useScene((state) => state.nodes)
  const walls = Object.values(nodes).filter(n => n.type === 'wall')

  return <div>Total walls: {walls.length}</div>
}

Node Types

  • SiteNode - Root container
  • BuildingNode - Building within a site
  • LevelNode - Floor level
  • WallNode - Vertical wall with optional openings
  • SlabNode - Floor slab
  • CeilingNode - Ceiling surface
  • RoofNode - Roof geometry
  • ZoneNode - Spatial zone/room
  • ItemNode - Furniture, fixtures, appliances
  • ScanNode - 3D scan reference
  • GuideNode - 2D guide image reference

Systems

Systems process dirty nodes each frame to update geometry:

  • WallSystem - Wall geometry with mitering and CSG cutouts
  • SlabSystem - Floor polygon generation
  • CeilingSystem - Ceiling geometry
  • RoofSystem - Roof generation
  • ItemSystem - Item positioning on walls/ceilings/floors

License

MIT