scene starting with site and not with building anymore

This commit is contained in:
wass08
2026-02-05 14:42:46 +09:00
parent 875cf277e0
commit 39f9f595d8
8 changed files with 84 additions and 15 deletions
+3 -1
View File
@@ -1,6 +1,6 @@
import type { ThreeEvent } from '@react-three/fiber'
import mitt from 'mitt'
import type { BuildingNode, CeilingNode, ItemNode, LevelNode, RoofNode, SlabNode, WallNode, ZoneNode } from '../schema'
import type { BuildingNode, CeilingNode, ItemNode, LevelNode, RoofNode, SiteNode, SlabNode, WallNode, ZoneNode } from '../schema'
import type { AnyNode } from '../schema/types'
// Base event interfaces
@@ -20,6 +20,7 @@ export interface NodeEvent<T extends AnyNode = AnyNode> {
export type WallEvent = NodeEvent<WallNode>
export type ItemEvent = NodeEvent<ItemNode>
export type SiteEvent = NodeEvent<SiteNode>
export type BuildingEvent = NodeEvent<BuildingNode>
export type LevelEvent = NodeEvent<LevelNode>
export type ZoneEvent = NodeEvent<ZoneNode>
@@ -64,6 +65,7 @@ type CameraControlEvents = {
type EditorEvents = GridEvents &
NodeEvents<'wall', WallEvent> &
NodeEvents<'item', ItemEvent> &
NodeEvents<'site', SiteEvent> &
NodeEvents<'building', BuildingEvent> &
NodeEvents<'level', LevelEvent> &
NodeEvents<'zone', ZoneEvent> &
@@ -8,6 +8,7 @@ export const sceneRegistry = {
// Categorized lookups: Type -> Set of IDs
// Using a Set is faster for adding/deleting than an Array
byType: {
site: new Set<string>(),
building: new Set<string>(),
ceiling: new Set<string>(),
level: new Set<string>(),
+1
View File
@@ -8,6 +8,7 @@ export type {
ItemEvent,
LevelEvent,
NodeEvent,
SiteEvent,
SlabEvent,
WallEvent,
ZoneEvent,
+46 -10
View File
@@ -6,6 +6,7 @@ import { create, type StoreApi, type UseBoundStore } from 'zustand'
import { persist } from 'zustand/middleware'
import { BuildingNode } from '../schema'
import { LevelNode } from '../schema/nodes/level'
import { SiteNode } from '../schema/nodes/site'
import type { AnyNode, AnyNodeId } from '../schema/types'
import { isObject } from '../utils/types'
import * as nodeActions from './actions/node-actions'
@@ -87,25 +88,29 @@ const useScene: UseSceneStore = create<SceneState>()(
return // Scene already loaded
}
const building = BuildingNode.parse({
children: [],
})
// Create hierarchy: Site → Building → Level
const level0 = LevelNode.parse({
level: 0,
children: [],
})
building.children.push(level0.id)
const building = BuildingNode.parse({
children: [level0.id],
})
const site = SiteNode.parse({
children: [building],
})
// Define all nodes flat
const nodes: Record<AnyNodeId, AnyNode> = {
[site.id]: site,
[building.id]: building,
[level0.id]: level0,
}
// Root nodes are the levels
const rootNodeIds = [building.id]
// Site is the root
const rootNodeIds = [site.id]
set({ nodes, rootNodeIds })
},
@@ -155,13 +160,44 @@ const useScene: UseSceneStore = create<SceneState>()(
onRehydrateStorage: (state) => {
console.log('hydrating...')
// optional
return (state, error) => {
if (error) {
console.log('an error happened during hydration', error)
} else {
console.log('hydration finished')
return
}
if (!state) {
console.log('hydration finished - no state')
return
}
// Migration: Wrap old scenes (where root is not a SiteNode) in a SiteNode
const rootId = state.rootNodeIds?.[0]
const rootNode = rootId ? state.nodes[rootId] : null
if (rootNode && rootNode.type !== 'site') {
console.log('Migrating old scene: wrapping in SiteNode')
// Collect existing root nodes (should be BuildingNode or ItemNode)
const existingRoots = (state.rootNodeIds || [])
.map(id => state.nodes[id])
.filter(node => node?.type === 'building' || node?.type === 'item')
// Create a new SiteNode with existing roots as children
const site = SiteNode.parse({
children: existingRoots,
})
// Add site to nodes
state.nodes[site.id] = site
// Update root to be the site
state.rootNodeIds = [site.id]
console.log('Migration complete: scene now has SiteNode as root')
}
console.log('hydration finished')
}
},
},