@pascal-app/core 0.8.0 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (272) hide show
  1. package/dist/events/bus.d.ts +39 -13
  2. package/dist/events/bus.d.ts.map +1 -1
  3. package/dist/hooks/scene-registry/scene-registry.d.ts +6 -22
  4. package/dist/hooks/scene-registry/scene-registry.d.ts.map +1 -1
  5. package/dist/hooks/scene-registry/scene-registry.js +33 -26
  6. package/dist/hooks/spatial-grid/floor-placed-elevation.d.ts +14 -0
  7. package/dist/hooks/spatial-grid/floor-placed-elevation.d.ts.map +1 -0
  8. package/dist/hooks/spatial-grid/floor-placed-elevation.js +51 -0
  9. package/dist/hooks/spatial-grid/floor-placed-elevation.test.d.ts +2 -0
  10. package/dist/hooks/spatial-grid/floor-placed-elevation.test.d.ts.map +1 -0
  11. package/dist/hooks/spatial-grid/floor-placed-elevation.test.js +273 -0
  12. package/dist/hooks/spatial-grid/spatial-grid-manager.d.ts +13 -2
  13. package/dist/hooks/spatial-grid/spatial-grid-manager.d.ts.map +1 -1
  14. package/dist/hooks/spatial-grid/spatial-grid-manager.js +95 -9
  15. package/dist/hooks/spatial-grid/spatial-grid-sync.d.ts +28 -1
  16. package/dist/hooks/spatial-grid/spatial-grid-sync.d.ts.map +1 -1
  17. package/dist/hooks/spatial-grid/spatial-grid-sync.js +91 -18
  18. package/dist/index.d.ts +22 -4
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +19 -2
  21. package/dist/lib/polygon-relations.d.ts +10 -0
  22. package/dist/lib/polygon-relations.d.ts.map +1 -0
  23. package/dist/lib/polygon-relations.js +73 -0
  24. package/dist/lib/space-detection-pause.test.d.ts +2 -0
  25. package/dist/lib/space-detection-pause.test.d.ts.map +1 -0
  26. package/dist/lib/space-detection-pause.test.js +42 -0
  27. package/dist/lib/space-detection.d.ts +30 -1
  28. package/dist/lib/space-detection.d.ts.map +1 -1
  29. package/dist/lib/space-detection.js +215 -36
  30. package/dist/lib/space-detection.test.d.ts +2 -0
  31. package/dist/lib/space-detection.test.d.ts.map +1 -0
  32. package/dist/lib/space-detection.test.js +77 -0
  33. package/dist/material-library.d.ts +1 -1
  34. package/dist/material-library.d.ts.map +1 -1
  35. package/dist/material-library.js +1940 -143
  36. package/dist/registry/__bench__/relations-resolver.bench.d.ts +15 -0
  37. package/dist/registry/__bench__/relations-resolver.bench.d.ts.map +1 -0
  38. package/dist/registry/__bench__/relations-resolver.bench.js +170 -0
  39. package/dist/registry/handles.d.ts +321 -0
  40. package/dist/registry/handles.d.ts.map +1 -0
  41. package/dist/registry/handles.js +24 -0
  42. package/dist/registry/index.d.ts +7 -0
  43. package/dist/registry/index.d.ts.map +1 -0
  44. package/dist/registry/index.js +4 -0
  45. package/dist/registry/registry.d.ts +93 -0
  46. package/dist/registry/registry.d.ts.map +1 -0
  47. package/dist/registry/registry.js +201 -0
  48. package/dist/registry/registry.test.d.ts +2 -0
  49. package/dist/registry/registry.test.d.ts.map +1 -0
  50. package/dist/registry/registry.test.js +183 -0
  51. package/dist/registry/relations-resolver.d.ts +42 -0
  52. package/dist/registry/relations-resolver.d.ts.map +1 -0
  53. package/dist/registry/relations-resolver.js +77 -0
  54. package/dist/registry/relations-resolver.test.d.ts +2 -0
  55. package/dist/registry/relations-resolver.test.d.ts.map +1 -0
  56. package/dist/registry/relations-resolver.test.js +183 -0
  57. package/dist/registry/scene-api.d.ts +44 -0
  58. package/dist/registry/scene-api.d.ts.map +1 -0
  59. package/dist/registry/scene-api.js +111 -0
  60. package/dist/registry/scene-api.test.d.ts +2 -0
  61. package/dist/registry/scene-api.test.d.ts.map +1 -0
  62. package/dist/registry/scene-api.test.js +183 -0
  63. package/dist/registry/subtree.d.ts +67 -0
  64. package/dist/registry/subtree.d.ts.map +1 -0
  65. package/dist/registry/subtree.js +119 -0
  66. package/dist/registry/subtree.test.d.ts +2 -0
  67. package/dist/registry/subtree.test.d.ts.map +1 -0
  68. package/dist/registry/subtree.test.js +133 -0
  69. package/dist/registry/types.d.ts +1420 -0
  70. package/dist/registry/types.d.ts.map +1 -0
  71. package/dist/registry/types.js +1 -0
  72. package/dist/schema/index.d.ts +17 -2
  73. package/dist/schema/index.d.ts.map +1 -1
  74. package/dist/schema/index.js +17 -3
  75. package/dist/schema/material.d.ts +10 -0
  76. package/dist/schema/material.d.ts.map +1 -1
  77. package/dist/schema/material.js +10 -0
  78. package/dist/schema/nodes/box-vent.d.ts +74 -0
  79. package/dist/schema/nodes/box-vent.d.ts.map +1 -0
  80. package/dist/schema/nodes/box-vent.js +63 -0
  81. package/dist/schema/nodes/building.d.ts +1 -1
  82. package/dist/schema/nodes/building.d.ts.map +1 -1
  83. package/dist/schema/nodes/building.js +3 -2
  84. package/dist/schema/nodes/ceiling.d.ts +2 -0
  85. package/dist/schema/nodes/ceiling.d.ts.map +1 -1
  86. package/dist/schema/nodes/ceiling.js +1 -1
  87. package/dist/schema/nodes/chimney.d.ts +158 -0
  88. package/dist/schema/nodes/chimney.d.ts.map +1 -0
  89. package/dist/schema/nodes/chimney.js +67 -0
  90. package/dist/schema/nodes/column.d.ts +597 -5
  91. package/dist/schema/nodes/column.d.ts.map +1 -1
  92. package/dist/schema/nodes/column.js +586 -6
  93. package/dist/schema/nodes/cupola.d.ts +66 -0
  94. package/dist/schema/nodes/cupola.d.ts.map +1 -0
  95. package/dist/schema/nodes/cupola.js +28 -0
  96. package/dist/schema/nodes/dormer.d.ts +228 -0
  97. package/dist/schema/nodes/dormer.d.ts.map +1 -0
  98. package/dist/schema/nodes/dormer.js +119 -0
  99. package/dist/schema/nodes/downspout.d.ts +75 -0
  100. package/dist/schema/nodes/downspout.d.ts.map +1 -0
  101. package/dist/schema/nodes/downspout.js +63 -0
  102. package/dist/schema/nodes/elevator.d.ts +105 -0
  103. package/dist/schema/nodes/elevator.d.ts.map +1 -0
  104. package/dist/schema/nodes/elevator.js +54 -0
  105. package/dist/schema/nodes/eyebrow-vent.d.ts +68 -0
  106. package/dist/schema/nodes/eyebrow-vent.d.ts.map +1 -0
  107. package/dist/schema/nodes/eyebrow-vent.js +40 -0
  108. package/dist/schema/nodes/fence.d.ts +1 -0
  109. package/dist/schema/nodes/fence.d.ts.map +1 -1
  110. package/dist/schema/nodes/fence.js +2 -0
  111. package/dist/schema/nodes/gutter.d.ts +84 -0
  112. package/dist/schema/nodes/gutter.d.ts.map +1 -0
  113. package/dist/schema/nodes/gutter.js +76 -0
  114. package/dist/schema/nodes/item.d.ts +4 -0
  115. package/dist/schema/nodes/item.d.ts.map +1 -1
  116. package/dist/schema/nodes/item.js +9 -0
  117. package/dist/schema/nodes/level.d.ts +1 -1
  118. package/dist/schema/nodes/level.d.ts.map +1 -1
  119. package/dist/schema/nodes/level.js +2 -0
  120. package/dist/schema/nodes/ridge-vent.d.ts +67 -0
  121. package/dist/schema/nodes/ridge-vent.d.ts.map +1 -0
  122. package/dist/schema/nodes/ridge-vent.js +30 -0
  123. package/dist/schema/nodes/roof-segment.d.ts +195 -1
  124. package/dist/schema/nodes/roof-segment.d.ts.map +1 -1
  125. package/dist/schema/nodes/roof-segment.js +254 -3
  126. package/dist/schema/nodes/roof.d.ts.map +1 -1
  127. package/dist/schema/nodes/roof.js +4 -16
  128. package/dist/schema/nodes/shelf.d.ts +105 -0
  129. package/dist/schema/nodes/shelf.d.ts.map +1 -0
  130. package/dist/schema/nodes/shelf.js +84 -0
  131. package/dist/schema/nodes/site.d.ts +1 -122
  132. package/dist/schema/nodes/site.d.ts.map +1 -1
  133. package/dist/schema/nodes/site.js +2 -6
  134. package/dist/schema/nodes/skylight.d.ts +279 -0
  135. package/dist/schema/nodes/skylight.d.ts.map +1 -0
  136. package/dist/schema/nodes/skylight.js +152 -0
  137. package/dist/schema/nodes/slab.d.ts +2 -0
  138. package/dist/schema/nodes/slab.d.ts.map +1 -1
  139. package/dist/schema/nodes/slab.js +1 -1
  140. package/dist/schema/nodes/solar-panel.d.ts +117 -0
  141. package/dist/schema/nodes/solar-panel.d.ts.map +1 -0
  142. package/dist/schema/nodes/solar-panel.js +47 -0
  143. package/dist/schema/nodes/surface-hole-metadata.d.ts +2 -0
  144. package/dist/schema/nodes/surface-hole-metadata.d.ts.map +1 -1
  145. package/dist/schema/nodes/surface-hole-metadata.js +3 -1
  146. package/dist/schema/nodes/turbine-vent.d.ts +68 -0
  147. package/dist/schema/nodes/turbine-vent.d.ts.map +1 -0
  148. package/dist/schema/nodes/turbine-vent.js +41 -0
  149. package/dist/schema/types.d.ts +1325 -125
  150. package/dist/schema/types.d.ts.map +1 -1
  151. package/dist/schema/types.js +26 -0
  152. package/dist/services/alignment-anchors.d.ts +100 -0
  153. package/dist/services/alignment-anchors.d.ts.map +1 -0
  154. package/dist/services/alignment-anchors.js +283 -0
  155. package/dist/services/alignment-anchors.test.d.ts +2 -0
  156. package/dist/services/alignment-anchors.test.d.ts.map +1 -0
  157. package/dist/services/alignment-anchors.test.js +383 -0
  158. package/dist/services/alignment.d.ts +126 -0
  159. package/dist/services/alignment.d.ts.map +1 -0
  160. package/dist/services/alignment.js +169 -0
  161. package/dist/services/alignment.test.d.ts +2 -0
  162. package/dist/services/alignment.test.d.ts.map +1 -0
  163. package/dist/services/alignment.test.js +92 -0
  164. package/dist/services/drag-session.d.ts +47 -0
  165. package/dist/services/drag-session.d.ts.map +1 -0
  166. package/dist/services/drag-session.js +100 -0
  167. package/dist/services/drag-session.test.d.ts +2 -0
  168. package/dist/services/drag-session.test.d.ts.map +1 -0
  169. package/dist/services/drag-session.test.js +219 -0
  170. package/dist/services/hosting.d.ts +80 -0
  171. package/dist/services/hosting.d.ts.map +1 -0
  172. package/dist/services/hosting.js +122 -0
  173. package/dist/services/hosting.test.d.ts +2 -0
  174. package/dist/services/hosting.test.d.ts.map +1 -0
  175. package/dist/services/hosting.test.js +199 -0
  176. package/dist/services/index.d.ts +7 -0
  177. package/dist/services/index.d.ts.map +1 -0
  178. package/dist/services/index.js +6 -0
  179. package/dist/services/movement.d.ts +48 -0
  180. package/dist/services/movement.d.ts.map +1 -0
  181. package/dist/services/movement.js +65 -0
  182. package/dist/services/movement.test.d.ts +2 -0
  183. package/dist/services/movement.test.d.ts.map +1 -0
  184. package/dist/services/movement.test.js +133 -0
  185. package/dist/services/single-undo-dance.test.d.ts +2 -0
  186. package/dist/services/single-undo-dance.test.d.ts.map +1 -0
  187. package/dist/services/single-undo-dance.test.js +210 -0
  188. package/dist/services/snap.d.ts +72 -0
  189. package/dist/services/snap.d.ts.map +1 -0
  190. package/dist/services/snap.js +120 -0
  191. package/dist/services/snap.test.d.ts +2 -0
  192. package/dist/services/snap.test.d.ts.map +1 -0
  193. package/dist/services/snap.test.js +95 -0
  194. package/dist/solar-panel-presets.d.ts +17 -0
  195. package/dist/solar-panel-presets.d.ts.map +1 -0
  196. package/dist/solar-panel-presets.js +43 -0
  197. package/dist/store/actions/node-actions.d.ts +14 -2
  198. package/dist/store/actions/node-actions.d.ts.map +1 -1
  199. package/dist/store/actions/node-actions.js +492 -15
  200. package/dist/store/actions/node-mutation-sanitize.test.d.ts +2 -0
  201. package/dist/store/actions/node-mutation-sanitize.test.d.ts.map +1 -0
  202. package/dist/store/actions/node-mutation-sanitize.test.js +147 -0
  203. package/dist/store/actions/reparent.test.d.ts +2 -0
  204. package/dist/store/actions/reparent.test.d.ts.map +1 -0
  205. package/dist/store/actions/reparent.test.js +212 -0
  206. package/dist/store/use-interactive.d.ts +39 -0
  207. package/dist/store/use-interactive.d.ts.map +1 -1
  208. package/dist/store/use-interactive.js +75 -0
  209. package/dist/store/use-live-node-overrides.d.ts +22 -0
  210. package/dist/store/use-live-node-overrides.d.ts.map +1 -0
  211. package/dist/store/use-live-node-overrides.js +59 -0
  212. package/dist/store/use-scene-elevator-migration.test.d.ts +2 -0
  213. package/dist/store/use-scene-elevator-migration.test.d.ts.map +1 -0
  214. package/dist/store/use-scene-elevator-migration.test.js +109 -0
  215. package/dist/store/use-scene.d.ts +11 -0
  216. package/dist/store/use-scene.d.ts.map +1 -1
  217. package/dist/store/use-scene.js +196 -6
  218. package/dist/systems/elevator/elevator-dispatch.d.ts +12 -0
  219. package/dist/systems/elevator/elevator-dispatch.d.ts.map +1 -0
  220. package/dist/systems/elevator/elevator-dispatch.js +57 -0
  221. package/dist/systems/elevator/elevator-geometry.d.ts +15 -0
  222. package/dist/systems/elevator/elevator-geometry.d.ts.map +1 -0
  223. package/dist/systems/elevator/elevator-geometry.js +50 -0
  224. package/dist/systems/elevator/elevator-opening-sync.d.ts +6 -0
  225. package/dist/systems/elevator/elevator-opening-sync.d.ts.map +1 -0
  226. package/dist/systems/elevator/elevator-opening-sync.js +218 -0
  227. package/dist/systems/elevator/elevator-opening-sync.test.d.ts +2 -0
  228. package/dist/systems/elevator/elevator-opening-sync.test.d.ts.map +1 -0
  229. package/dist/systems/elevator/elevator-opening-sync.test.js +146 -0
  230. package/dist/systems/elevator/elevator-opening-system.d.ts +2 -0
  231. package/dist/systems/elevator/elevator-opening-system.d.ts.map +1 -0
  232. package/dist/systems/elevator/elevator-opening-system.js +48 -0
  233. package/dist/systems/elevator/elevator-runtime-system.d.ts +2 -0
  234. package/dist/systems/elevator/elevator-runtime-system.d.ts.map +1 -0
  235. package/dist/systems/elevator/elevator-runtime-system.js +8 -0
  236. package/dist/systems/elevator/elevator-runtime.d.ts +18 -0
  237. package/dist/systems/elevator/elevator-runtime.d.ts.map +1 -0
  238. package/dist/systems/elevator/elevator-runtime.js +225 -0
  239. package/dist/systems/elevator/elevator-runtime.test.d.ts +2 -0
  240. package/dist/systems/elevator/elevator-runtime.test.d.ts.map +1 -0
  241. package/dist/systems/elevator/elevator-runtime.test.js +64 -0
  242. package/dist/systems/elevator/elevator-service.d.ts +19 -0
  243. package/dist/systems/elevator/elevator-service.d.ts.map +1 -0
  244. package/dist/systems/elevator/elevator-service.js +111 -0
  245. package/dist/systems/stair/stair-footprint.d.ts +44 -0
  246. package/dist/systems/stair/stair-footprint.d.ts.map +1 -0
  247. package/dist/systems/stair/stair-footprint.js +168 -0
  248. package/dist/systems/stair/stair-opening-preview.d.ts +1777 -0
  249. package/dist/systems/stair/stair-opening-preview.d.ts.map +1 -0
  250. package/dist/systems/stair/stair-opening-preview.js +93 -0
  251. package/dist/systems/stair/stair-opening-preview.test.d.ts +2 -0
  252. package/dist/systems/stair/stair-opening-preview.test.d.ts.map +1 -0
  253. package/dist/systems/stair/stair-opening-preview.test.js +80 -0
  254. package/dist/systems/stair/stair-opening-sync.d.ts.map +1 -1
  255. package/dist/systems/stair/stair-opening-sync.js +172 -147
  256. package/dist/systems/stair/stair-opening-sync.test.js +385 -2
  257. package/dist/systems/stair/stair-opening-system.d.ts +2 -0
  258. package/dist/systems/stair/stair-opening-system.d.ts.map +1 -0
  259. package/dist/systems/stair/stair-opening-system.js +104 -0
  260. package/dist/systems/wall/wall-move.d.ts +48 -0
  261. package/dist/systems/wall/wall-move.d.ts.map +1 -0
  262. package/dist/systems/wall/wall-move.js +193 -0
  263. package/dist/utils/clone-scene-graph.d.ts +6 -4
  264. package/dist/utils/clone-scene-graph.d.ts.map +1 -1
  265. package/dist/utils/clone-scene-graph.js +6 -4
  266. package/dist/utils/clone-scene-graph.test.d.ts +2 -0
  267. package/dist/utils/clone-scene-graph.test.d.ts.map +1 -0
  268. package/dist/utils/clone-scene-graph.test.js +59 -0
  269. package/dist/validation/validate-build-json.d.ts +43 -0
  270. package/dist/validation/validate-build-json.d.ts.map +1 -0
  271. package/dist/validation/validate-build-json.js +227 -0
  272. package/package.json +9 -2
@@ -1,6 +1,6 @@
1
1
  import type { ThreeEvent } from '@react-three/fiber';
2
2
  import type { Object3D } from 'three';
3
- import type { BuildingNode, CeilingNode, ColumnNode, DoorNode, FenceNode, GuideNode, ItemNode, LevelNode, RoofNode, RoofSegmentNode, SiteNode, SlabNode, SpawnNode, StairNode, StairSegmentNode, WallNode, WindowNode, ZoneNode } from '../schema';
3
+ import type { BoxVentNode, BuildingNode, CeilingNode, ChimneyNode, ColumnNode, CupolaNode, DoorNode, DormerNode, DownspoutNode, ElevatorNode, EyebrowVentNode, FenceNode, GuideNode, GutterNode, ItemNode, LevelNode, RidgeVentNode, RoofNode, RoofSegmentNode, ScanNode, ShelfNode, SiteNode, SkylightNode, SlabNode, SolarPanelNode, SpawnNode, StairNode, StairSegmentNode, TurbineVentNode, WallNode, WindowNode, ZoneNode } from '../schema';
4
4
  import type { AnyNode } from '../schema/types';
5
5
  export interface GridEvent {
6
6
  /** World-space intersection point on the grid plane. */
@@ -12,7 +12,14 @@ export interface GridEvent {
12
12
  */
13
13
  localPosition: [number, number, number];
14
14
  faceIndex?: number;
15
- object: Object3D;
15
+ /**
16
+ * Optional: the hit Three.js object. Present when the grid event was
17
+ * synthesized from a R3F mesh hit (the legacy grid-plane mesh path);
18
+ * absent when emitted by the canvas-level raycaster in
19
+ * `use-grid-events.ts`, where there is no specific mesh to attribute
20
+ * the intersection to.
21
+ */
22
+ object?: Object3D;
16
23
  nativeEvent: ThreeEvent<PointerEvent>;
17
24
  }
18
25
  export interface NodeEvent<T extends AnyNode = AnyNode> {
@@ -24,6 +31,7 @@ export interface NodeEvent<T extends AnyNode = AnyNode> {
24
31
  object: Object3D;
25
32
  stopPropagation: () => void;
26
33
  nativeEvent: ThreeEvent<PointerEvent>;
34
+ viaHandle?: boolean;
27
35
  }
28
36
  export type WallEvent = NodeEvent<WallNode>;
29
37
  export type FenceEvent = NodeEvent<FenceNode>;
@@ -32,6 +40,7 @@ export type SiteEvent = NodeEvent<SiteNode>;
32
40
  export type BuildingEvent = NodeEvent<BuildingNode>;
33
41
  export type LevelEvent = NodeEvent<LevelNode>;
34
42
  export type ZoneEvent = NodeEvent<ZoneNode>;
43
+ export type ShelfEvent = NodeEvent<ShelfNode>;
35
44
  export type SlabEvent = NodeEvent<SlabNode>;
36
45
  export type SpawnEvent = NodeEvent<SpawnNode>;
37
46
  export type CeilingEvent = NodeEvent<CeilingNode>;
@@ -42,6 +51,20 @@ export type StairEvent = NodeEvent<StairNode>;
42
51
  export type StairSegmentEvent = NodeEvent<StairSegmentNode>;
43
52
  export type WindowEvent = NodeEvent<WindowNode>;
44
53
  export type DoorEvent = NodeEvent<DoorNode>;
54
+ export type ElevatorEvent = NodeEvent<ElevatorNode>;
55
+ export type ScanEvent = NodeEvent<ScanNode>;
56
+ export type GuideEvent = NodeEvent<GuideNode>;
57
+ export type BoxVentEvent = NodeEvent<BoxVentNode>;
58
+ export type RidgeVentEvent = NodeEvent<RidgeVentNode>;
59
+ export type TurbineVentEvent = NodeEvent<TurbineVentNode>;
60
+ export type CupolaEvent = NodeEvent<CupolaNode>;
61
+ export type EyebrowVentEvent = NodeEvent<EyebrowVentNode>;
62
+ export type GutterEvent = NodeEvent<GutterNode>;
63
+ export type ChimneyEvent = NodeEvent<ChimneyNode>;
64
+ export type SolarPanelEvent = NodeEvent<SolarPanelNode>;
65
+ export type SkylightEvent = NodeEvent<SkylightNode>;
66
+ export type DormerEvent = NodeEvent<DormerNode>;
67
+ export type DownspoutEvent = NodeEvent<DownspoutNode>;
45
68
  export declare const eventSuffixes: readonly ["click", "move", "enter", "leave", "pointerdown", "pointerup", "context-menu", "double-click"];
46
69
  export type EventSuffix = (typeof eventSuffixes)[number];
47
70
  type NodeEvents<T extends string, E> = {
@@ -69,6 +92,13 @@ export interface ThumbnailGenerateEvent {
69
92
  * that should fire immediately from the current camera pose.
70
93
  */
71
94
  snapLevels?: boolean;
95
+ /**
96
+ * When true, keep the rendered alpha channel — emits a transparent PNG
97
+ * without baking the scene background into the output. Used by the
98
+ * preset capture flow so saved preset thumbnails composite cleanly on
99
+ * any palette background.
100
+ */
101
+ transparent?: boolean;
72
102
  }
73
103
  export interface CameraControlFitSceneEvent {
74
104
  /**
@@ -118,16 +148,6 @@ type WindowAnimationEvents = {
118
148
  field: 'operationState';
119
149
  };
120
150
  };
121
- type PresetEvents = {
122
- 'preset:generate-thumbnail': {
123
- presetId: string;
124
- nodeId: string;
125
- };
126
- 'preset:thumbnail-updated': {
127
- presetId: string;
128
- thumbnailUrl: string;
129
- };
130
- };
131
151
  type ThumbnailEvents = {
132
152
  'thumbnail:before-capture': undefined;
133
153
  'thumbnail:after-capture': undefined;
@@ -148,7 +168,13 @@ type AIChatEvents = {
148
168
  }[];
149
169
  };
150
170
  };
151
- type EditorEvents = GridEvents & NodeEvents<'wall', WallEvent> & NodeEvents<'fence', FenceEvent> & NodeEvents<'item', ItemEvent> & NodeEvents<'site', SiteEvent> & NodeEvents<'building', BuildingEvent> & NodeEvents<'level', LevelEvent> & NodeEvents<'zone', ZoneEvent> & NodeEvents<'slab', SlabEvent> & NodeEvents<'spawn', SpawnEvent> & NodeEvents<'ceiling', CeilingEvent> & NodeEvents<'column', ColumnEvent> & NodeEvents<'roof', RoofEvent> & NodeEvents<'roof-segment', RoofSegmentEvent> & NodeEvents<'stair', StairEvent> & NodeEvents<'stair-segment', StairSegmentEvent> & NodeEvents<'window', WindowEvent> & NodeEvents<'door', DoorEvent> & CameraControlEvents & ToolEvents & GuideEvents & DoorAnimationEvents & WindowAnimationEvents & PresetEvents & ThumbnailEvents & SnapshotEvents & AIChatEvents;
171
+ export interface RoomPresetCreateEvent {
172
+ zoneId: ZoneNode['id'];
173
+ }
174
+ type RoomPresetEvents = {
175
+ 'room-preset:create': RoomPresetCreateEvent;
176
+ };
177
+ type EditorEvents = GridEvents & NodeEvents<'wall', WallEvent> & NodeEvents<'fence', FenceEvent> & NodeEvents<'item', ItemEvent> & NodeEvents<'site', SiteEvent> & NodeEvents<'building', BuildingEvent> & NodeEvents<'elevator', ElevatorEvent> & NodeEvents<'level', LevelEvent> & NodeEvents<'zone', ZoneEvent> & NodeEvents<'slab', SlabEvent> & NodeEvents<'shelf', ShelfEvent> & NodeEvents<'spawn', SpawnEvent> & NodeEvents<'ceiling', CeilingEvent> & NodeEvents<'column', ColumnEvent> & NodeEvents<'roof', RoofEvent> & NodeEvents<'roof-segment', RoofSegmentEvent> & NodeEvents<'stair', StairEvent> & NodeEvents<'stair-segment', StairSegmentEvent> & NodeEvents<'window', WindowEvent> & NodeEvents<'door', DoorEvent> & NodeEvents<'scan', ScanEvent> & NodeEvents<'guide', GuideEvent> & NodeEvents<'box-vent', BoxVentEvent> & NodeEvents<'ridge-vent', RidgeVentEvent> & NodeEvents<'turbine-vent', TurbineVentEvent> & NodeEvents<'cupola', CupolaEvent> & NodeEvents<'eyebrow-vent', EyebrowVentEvent> & NodeEvents<'gutter', GutterEvent> & NodeEvents<'chimney', ChimneyEvent> & NodeEvents<'solar-panel', SolarPanelEvent> & NodeEvents<'skylight', SkylightEvent> & NodeEvents<'dormer', DormerEvent> & NodeEvents<'downspout', DownspoutEvent> & CameraControlEvents & ToolEvents & GuideEvents & DoorAnimationEvents & WindowAnimationEvents & ThumbnailEvents & SnapshotEvents & AIChatEvents & RoomPresetEvents;
152
178
  export declare const emitter: import("mitt").Emitter<EditorEvents>;
153
179
  export {};
154
180
  //# sourceMappingURL=bus.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"bus.d.ts","sourceRoot":"","sources":["../../src/events/bus.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bus.d.ts","sourceRoot":"","sources":["../../src/events/bus.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAEpD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AACrC,OAAO,KAAK,EACV,WAAW,EACX,YAAY,EACZ,WAAW,EACX,WAAW,EACX,UAAU,EACV,UAAU,EACV,QAAQ,EACR,UAAU,EACV,aAAa,EACb,YAAY,EACZ,eAAe,EACf,SAAS,EACT,SAAS,EACT,UAAU,EACV,QAAQ,EACR,SAAS,EACT,aAAa,EACb,QAAQ,EACR,eAAe,EACf,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,YAAY,EACZ,QAAQ,EACR,cAAc,EACd,SAAS,EACT,SAAS,EACT,gBAAgB,EAChB,eAAe,EACf,QAAQ,EACR,UAAU,EACV,QAAQ,EACT,MAAM,WAAW,CAAA;AAClB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAG9C,MAAM,WAAW,SAAS;IACxB,wDAAwD;IACxD,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAClC;;;;OAIG;IACH,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IACvC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,QAAQ,CAAA;IACjB,WAAW,EAAE,UAAU,CAAC,YAAY,CAAC,CAAA;CACtC;AAED,MAAM,WAAW,SAAS,CAAC,CAAC,SAAS,OAAO,GAAG,OAAO;IACpD,IAAI,EAAE,CAAC,CAAA;IACP,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAClC,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IACvC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IACjC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,QAAQ,CAAA;IAChB,eAAe,EAAE,MAAM,IAAI,CAAA;IAC3B,WAAW,EAAE,UAAU,CAAC,YAAY,CAAC,CAAA;IAKrC,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB;AAED,MAAM,MAAM,SAAS,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAA;AAC3C,MAAM,MAAM,UAAU,GAAG,SAAS,CAAC,SAAS,CAAC,CAAA;AAC7C,MAAM,MAAM,SAAS,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAA;AAC3C,MAAM,MAAM,SAAS,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAA;AAC3C,MAAM,MAAM,aAAa,GAAG,SAAS,CAAC,YAAY,CAAC,CAAA;AACnD,MAAM,MAAM,UAAU,GAAG,SAAS,CAAC,SAAS,CAAC,CAAA;AAC7C,MAAM,MAAM,SAAS,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAA;AAC3C,MAAM,MAAM,UAAU,GAAG,SAAS,CAAC,SAAS,CAAC,CAAA;AAC7C,MAAM,MAAM,SAAS,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAA;AAC3C,MAAM,MAAM,UAAU,GAAG,SAAS,CAAC,SAAS,CAAC,CAAA;AAC7C,MAAM,MAAM,YAAY,GAAG,SAAS,CAAC,WAAW,CAAC,CAAA;AACjD,MAAM,MAAM,WAAW,GAAG,SAAS,CAAC,UAAU,CAAC,CAAA;AAC/C,MAAM,MAAM,SAAS,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAA;AAC3C,MAAM,MAAM,gBAAgB,GAAG,SAAS,CAAC,eAAe,CAAC,CAAA;AACzD,MAAM,MAAM,UAAU,GAAG,SAAS,CAAC,SAAS,CAAC,CAAA;AAC7C,MAAM,MAAM,iBAAiB,GAAG,SAAS,CAAC,gBAAgB,CAAC,CAAA;AAC3D,MAAM,MAAM,WAAW,GAAG,SAAS,CAAC,UAAU,CAAC,CAAA;AAC/C,MAAM,MAAM,SAAS,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAA;AAC3C,MAAM,MAAM,aAAa,GAAG,SAAS,CAAC,YAAY,CAAC,CAAA;AACnD,MAAM,MAAM,SAAS,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAA;AAC3C,MAAM,MAAM,UAAU,GAAG,SAAS,CAAC,SAAS,CAAC,CAAA;AAC7C,MAAM,MAAM,YAAY,GAAG,SAAS,CAAC,WAAW,CAAC,CAAA;AACjD,MAAM,MAAM,cAAc,GAAG,SAAS,CAAC,aAAa,CAAC,CAAA;AACrD,MAAM,MAAM,gBAAgB,GAAG,SAAS,CAAC,eAAe,CAAC,CAAA;AACzD,MAAM,MAAM,WAAW,GAAG,SAAS,CAAC,UAAU,CAAC,CAAA;AAC/C,MAAM,MAAM,gBAAgB,GAAG,SAAS,CAAC,eAAe,CAAC,CAAA;AACzD,MAAM,MAAM,WAAW,GAAG,SAAS,CAAC,UAAU,CAAC,CAAA;AAC/C,MAAM,MAAM,YAAY,GAAG,SAAS,CAAC,WAAW,CAAC,CAAA;AACjD,MAAM,MAAM,eAAe,GAAG,SAAS,CAAC,cAAc,CAAC,CAAA;AACvD,MAAM,MAAM,aAAa,GAAG,SAAS,CAAC,YAAY,CAAC,CAAA;AACnD,MAAM,MAAM,WAAW,GAAG,SAAS,CAAC,UAAU,CAAC,CAAA;AAC/C,MAAM,MAAM,cAAc,GAAG,SAAS,CAAC,aAAa,CAAC,CAAA;AAGrD,eAAO,MAAM,aAAa,0GAShB,CAAA;AAEV,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAA;AAExD,KAAK,UAAU,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,IAAI;KACpC,CAAC,IAAI,GAAG,CAAC,IAAI,WAAW,EAAE,GAAG,CAAC;CAChC,CAAA;AAED,KAAK,UAAU,GAAG;KACf,CAAC,IAAI,QAAQ,WAAW,EAAE,GAAG,SAAS;CACxC,CAAA;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;CACtB;AAED,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,UAAU,GAAG,UAAU,GAAG,MAAM,CAAA;IAC9C,UAAU,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;IACpE;;;;;OAKG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB;AAED,MAAM,WAAW,0BAA0B;IACzC;;;;;OAKG;IACH,MAAM,CAAC,EAAE;QACP,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QACrB,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QACrB,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QACxB,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KACvB,CAAA;CACF;AAED,KAAK,mBAAmB,GAAG;IACzB,sBAAsB,EAAE,kBAAkB,CAAA;IAC1C,uBAAuB,EAAE,kBAAkB,CAAA;IAC3C,yBAAyB,EAAE,kBAAkB,CAAA;IAC7C,0BAA0B,EAAE,SAAS,CAAA;IACrC,0BAA0B,EAAE,SAAS,CAAA;IACrC,2BAA2B,EAAE,SAAS,CAAA;IACtC,2BAA2B,EAAE,0BAA0B,CAAA;IACvD,oCAAoC,EAAE,sBAAsB,CAAA;CAC7D,CAAA;AAED,KAAK,UAAU,GAAG;IAChB,aAAa,EAAE,SAAS,CAAA;CACzB,CAAA;AAED,KAAK,WAAW,GAAG;IACjB,2BAA2B,EAAE;QAAE,OAAO,EAAE,SAAS,CAAC,IAAI,CAAC,CAAA;KAAE,CAAA;IACzD,8BAA8B,EAAE,SAAS,CAAA;IACzC,eAAe,EAAE;QAAE,OAAO,EAAE,SAAS,CAAC,IAAI,CAAC,CAAA;KAAE,CAAA;CAC9C,CAAA;AAED,KAAK,mBAAmB,GAAG;IACzB,0BAA0B,EAAE;QAC1B,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAA;QACtB,KAAK,EAAE,gBAAgB,GAAG,YAAY,CAAA;KACvC,CAAA;CACF,CAAA;AAED,KAAK,qBAAqB,GAAG;IAC3B,4BAA4B,EAAE;QAC5B,QAAQ,EAAE,UAAU,CAAC,IAAI,CAAC,CAAA;QAC1B,KAAK,EAAE,gBAAgB,CAAA;KACxB,CAAA;CACF,CAAA;AAED,KAAK,eAAe,GAAG;IACrB,0BAA0B,EAAE,SAAS,CAAA;IACrC,yBAAyB,EAAE,SAAS,CAAA;CACrC,CAAA;AAED,KAAK,cAAc,GAAG;IACpB,gBAAgB,EAAE,SAAS,CAAA;IAC3B,uBAAuB,EAAE;QAAE,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAA;CAClG,CAAA;AAED,KAAK,YAAY,GAAG;IAClB,uBAAuB,EAAE;QACvB,MAAM,EAAE;YAAE,GAAG,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,UAAU,GAAG,QAAQ,CAAA;SAAE,EAAE,CAAA;KACrE,CAAA;CACF,CAAA;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAA;CACvB;AAED,KAAK,gBAAgB,GAAG;IACtB,oBAAoB,EAAE,qBAAqB,CAAA;CAC5C,CAAA;AAED,KAAK,YAAY,GAAG,UAAU,GAC5B,UAAU,CAAC,MAAM,EAAE,SAAS,CAAC,GAC7B,UAAU,CAAC,OAAO,EAAE,UAAU,CAAC,GAC/B,UAAU,CAAC,MAAM,EAAE,SAAS,CAAC,GAC7B,UAAU,CAAC,MAAM,EAAE,SAAS,CAAC,GAC7B,UAAU,CAAC,UAAU,EAAE,aAAa,CAAC,GACrC,UAAU,CAAC,UAAU,EAAE,aAAa,CAAC,GACrC,UAAU,CAAC,OAAO,EAAE,UAAU,CAAC,GAC/B,UAAU,CAAC,MAAM,EAAE,SAAS,CAAC,GAC7B,UAAU,CAAC,MAAM,EAAE,SAAS,CAAC,GAC7B,UAAU,CAAC,OAAO,EAAE,UAAU,CAAC,GAC/B,UAAU,CAAC,OAAO,EAAE,UAAU,CAAC,GAC/B,UAAU,CAAC,SAAS,EAAE,YAAY,CAAC,GACnC,UAAU,CAAC,QAAQ,EAAE,WAAW,CAAC,GACjC,UAAU,CAAC,MAAM,EAAE,SAAS,CAAC,GAC7B,UAAU,CAAC,cAAc,EAAE,gBAAgB,CAAC,GAC5C,UAAU,CAAC,OAAO,EAAE,UAAU,CAAC,GAC/B,UAAU,CAAC,eAAe,EAAE,iBAAiB,CAAC,GAC9C,UAAU,CAAC,QAAQ,EAAE,WAAW,CAAC,GACjC,UAAU,CAAC,MAAM,EAAE,SAAS,CAAC,GAC7B,UAAU,CAAC,MAAM,EAAE,SAAS,CAAC,GAC7B,UAAU,CAAC,OAAO,EAAE,UAAU,CAAC,GAC/B,UAAU,CAAC,UAAU,EAAE,YAAY,CAAC,GACpC,UAAU,CAAC,YAAY,EAAE,cAAc,CAAC,GACxC,UAAU,CAAC,cAAc,EAAE,gBAAgB,CAAC,GAC5C,UAAU,CAAC,QAAQ,EAAE,WAAW,CAAC,GACjC,UAAU,CAAC,cAAc,EAAE,gBAAgB,CAAC,GAC5C,UAAU,CAAC,QAAQ,EAAE,WAAW,CAAC,GACjC,UAAU,CAAC,SAAS,EAAE,YAAY,CAAC,GACnC,UAAU,CAAC,aAAa,EAAE,eAAe,CAAC,GAC1C,UAAU,CAAC,UAAU,EAAE,aAAa,CAAC,GACrC,UAAU,CAAC,QAAQ,EAAE,WAAW,CAAC,GACjC,UAAU,CAAC,WAAW,EAAE,cAAc,CAAC,GACvC,mBAAmB,GACnB,UAAU,GACV,WAAW,GACX,mBAAmB,GACnB,qBAAqB,GACrB,eAAe,GACf,cAAc,GACd,YAAY,GACZ,gBAAgB,CAAA;AAElB,eAAO,MAAM,OAAO,sCAAuB,CAAA"}
@@ -1,29 +1,13 @@
1
1
  import type * as THREE from 'three';
2
+ type ByTypeMap = {
3
+ [kind: string]: Set<string>;
4
+ };
2
5
  export declare const sceneRegistry: {
3
6
  nodes: Map<string, THREE.Object3D<THREE.Object3DEventMap>>;
4
- byType: {
5
- site: Set<string>;
6
- building: Set<string>;
7
- ceiling: Set<string>;
8
- column: Set<string>;
9
- level: Set<string>;
10
- wall: Set<string>;
11
- fence: Set<string>;
12
- item: Set<string>;
13
- slab: Set<string>;
14
- spawn: Set<string>;
15
- zone: Set<string>;
16
- roof: Set<string>;
17
- 'roof-segment': Set<string>;
18
- stair: Set<string>;
19
- 'stair-segment': Set<string>;
20
- scan: Set<string>;
21
- guide: Set<string>;
22
- window: Set<string>;
23
- door: Set<string>;
24
- };
7
+ byType: ByTypeMap;
25
8
  /** Remove all entries. Call when unloading a scene to prevent stale 3D refs. */
26
9
  clear(): void;
27
10
  };
28
- export declare function useRegistry(id: string, type: keyof typeof sceneRegistry.byType, ref: React.RefObject<THREE.Object3D>): void;
11
+ export declare function useRegistry(id: string, type: string, ref: React.RefObject<THREE.Object3D>): void;
12
+ export {};
29
13
  //# sourceMappingURL=scene-registry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"scene-registry.d.ts","sourceRoot":"","sources":["../../../src/hooks/scene-registry/scene-registry.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAA;AAEnC,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;IA4BxB,gFAAgF;;CAOjF,CAAA;AAED,wBAAgB,WAAW,CACzB,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,OAAO,aAAa,CAAC,MAAM,EACvC,GAAG,EAAE,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,QAkBrC"}
1
+ {"version":3,"file":"scene-registry.d.ts","sourceRoot":"","sources":["../../../src/hooks/scene-registry/scene-registry.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAA;AAYnC,KAAK,SAAS,GAAG;IAAE,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAAA;CAAE,CAAA;AA2BhD,eAAO,MAAM,aAAa;;;IAQxB,gFAAgF;;CAOjF,CAAA;AAED,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,QAiBzF"}
@@ -1,35 +1,42 @@
1
1
  'use client';
2
2
  import { useLayoutEffect } from 'react';
3
+ const byTypeStore = new Map();
4
+ const byTypeProxy = new Proxy({}, {
5
+ get(_target, key) {
6
+ if (typeof key !== 'string')
7
+ return undefined;
8
+ let set = byTypeStore.get(key);
9
+ if (!set) {
10
+ set = new Set();
11
+ byTypeStore.set(key, set);
12
+ }
13
+ return set;
14
+ },
15
+ ownKeys() {
16
+ return Array.from(byTypeStore.keys());
17
+ },
18
+ has(_target, key) {
19
+ return typeof key === 'string' && byTypeStore.has(key);
20
+ },
21
+ getOwnPropertyDescriptor(_target, key) {
22
+ if (typeof key !== 'string')
23
+ return undefined;
24
+ const set = byTypeStore.get(key);
25
+ if (!set)
26
+ return undefined;
27
+ return { configurable: true, enumerable: true, value: set, writable: false };
28
+ },
29
+ });
3
30
  export const sceneRegistry = {
4
31
  // Master lookup: ID -> Object3D
5
32
  nodes: new Map(),
6
- // Categorized lookups: Type -> Set of IDs
7
- // Using a Set is faster for adding/deleting than an Array
8
- byType: {
9
- site: new Set(),
10
- building: new Set(),
11
- ceiling: new Set(),
12
- column: new Set(),
13
- level: new Set(),
14
- wall: new Set(),
15
- fence: new Set(),
16
- item: new Set(),
17
- slab: new Set(),
18
- spawn: new Set(),
19
- zone: new Set(),
20
- roof: new Set(),
21
- 'roof-segment': new Set(),
22
- stair: new Set(),
23
- 'stair-segment': new Set(),
24
- scan: new Set(),
25
- guide: new Set(),
26
- window: new Set(),
27
- door: new Set(),
28
- },
33
+ // Categorized lookups: Kind -> Set of IDs. Backed by a Proxy so any kind
34
+ // gets a Set on first touch no hardcoded list.
35
+ byType: byTypeProxy,
29
36
  /** Remove all entries. Call when unloading a scene to prevent stale 3D refs. */
30
37
  clear() {
31
38
  this.nodes.clear();
32
- for (const set of Object.values(this.byType)) {
39
+ for (const set of byTypeStore.values()) {
33
40
  set.clear();
34
41
  }
35
42
  },
@@ -41,9 +48,9 @@ export function useRegistry(id, type, ref) {
41
48
  return;
42
49
  // 1. Add to master map
43
50
  sceneRegistry.nodes.set(id, obj);
44
- // 2. Add to type-specific set
51
+ // 2. Add to type-specific set — Proxy auto-creates on first access.
45
52
  sceneRegistry.byType[type].add(id);
46
- // 4. Cleanup when component unmounts
53
+ // 3. Cleanup when component unmounts
47
54
  return () => {
48
55
  sceneRegistry.nodes.delete(id);
49
56
  sceneRegistry.byType[type].delete(id);
@@ -0,0 +1,14 @@
1
+ import type { FloorPlacedConfig, FloorPlacedFootprint, FloorPlacedFootprintContext, FloorPlacedFootprintsResolver } from '../../registry/types';
2
+ import type { AnyNode } from '../../schema';
3
+ export type FloorPlacedElevationArgs = {
4
+ node: AnyNode;
5
+ nodes: Record<string, AnyNode>;
6
+ position: [number, number, number];
7
+ rotation?: unknown;
8
+ levelId?: string | null;
9
+ };
10
+ export declare function getFloorPlacedFootprints(floorPlaced: FloorPlacedConfig, node: AnyNode, ctx?: FloorPlacedFootprintContext): FloorPlacedFootprint[];
11
+ export declare function getFloorPlacedElevation({ node, nodes, position, rotation, levelId, }: FloorPlacedElevationArgs): number;
12
+ export declare function getFloorStackedPosition(args: FloorPlacedElevationArgs): [number, number, number];
13
+ export type { FloorPlacedFootprint, FloorPlacedFootprintContext, FloorPlacedFootprintsResolver };
14
+ //# sourceMappingURL=floor-placed-elevation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"floor-placed-elevation.d.ts","sourceRoot":"","sources":["../../../src/hooks/spatial-grid/floor-placed-elevation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,iBAAiB,EACjB,oBAAoB,EACpB,2BAA2B,EAC3B,6BAA6B,EAC9B,MAAM,sBAAsB,CAAA;AAC7B,OAAO,KAAK,EAAE,OAAO,EAAa,MAAM,cAAc,CAAA;AAGtD,MAAM,MAAM,wBAAwB,GAAG;IACrC,IAAI,EAAE,OAAO,CAAA;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAClC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACxB,CAAA;AAkBD,wBAAgB,wBAAwB,CACtC,WAAW,EAAE,iBAAiB,EAC9B,IAAI,EAAE,OAAO,EACb,GAAG,CAAC,EAAE,2BAA2B,GAChC,oBAAoB,EAAE,CAMxB;AAED,wBAAgB,uBAAuB,CAAC,EACtC,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,OAAO,GACR,EAAE,wBAAwB,GAAG,MAAM,CAiCnC;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,wBAAwB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAGhG;AAED,YAAY,EAAE,oBAAoB,EAAE,2BAA2B,EAAE,6BAA6B,EAAE,CAAA"}
@@ -0,0 +1,51 @@
1
+ import { nodeRegistry } from '../../registry';
2
+ import { spatialGridManager } from './spatial-grid-manager';
3
+ function finiteSlabElevation(elevation) {
4
+ return Number.isFinite(elevation) ? elevation : 0;
5
+ }
6
+ function withPositionAndRotation({ node, position, rotation, }) {
7
+ return {
8
+ ...node,
9
+ position,
10
+ ...(rotation !== undefined ? { rotation } : {}),
11
+ };
12
+ }
13
+ export function getFloorPlacedFootprints(floorPlaced, node, ctx) {
14
+ const rawFootprints = floorPlaced.footprints?.(node, ctx);
15
+ if (rawFootprints)
16
+ return [...rawFootprints];
17
+ const footprint = floorPlaced.footprint?.(node, ctx);
18
+ return footprint ? [footprint] : [];
19
+ }
20
+ export function getFloorPlacedElevation({ node, nodes, position, rotation, levelId, }) {
21
+ const floorPlaced = nodeRegistry.get(node.type)?.capabilities?.floorPlaced;
22
+ if (!floorPlaced)
23
+ return 0;
24
+ const effectiveNode = withPositionAndRotation({ node, position, rotation });
25
+ if (floorPlaced.applies && !floorPlaced.applies(effectiveNode))
26
+ return 0;
27
+ const parentId = effectiveNode.parentId ?? null;
28
+ const parent = parentId ? nodes[parentId] : null;
29
+ if (parentId && !parent)
30
+ return 0;
31
+ if (parent && parent.type !== 'level')
32
+ return 0;
33
+ if (!parent && !levelId)
34
+ return 0;
35
+ const resolvedLevelId = parent?.type === 'level' ? parent.id : levelId;
36
+ if (!resolvedLevelId)
37
+ return 0;
38
+ let maxElevation = Number.NEGATIVE_INFINITY;
39
+ for (const footprint of getFloorPlacedFootprints(floorPlaced, effectiveNode, { nodes })) {
40
+ const footprintPosition = footprint.position ?? position;
41
+ const elevation = finiteSlabElevation(spatialGridManager.getSlabElevationForItem(resolvedLevelId, footprintPosition, footprint.dimensions, footprint.rotation));
42
+ if (elevation > maxElevation) {
43
+ maxElevation = elevation;
44
+ }
45
+ }
46
+ return maxElevation === Number.NEGATIVE_INFINITY ? 0 : maxElevation;
47
+ }
48
+ export function getFloorStackedPosition(args) {
49
+ const [x, y, z] = args.position;
50
+ return [x, y + getFloorPlacedElevation(args), z];
51
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=floor-placed-elevation.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"floor-placed-elevation.test.d.ts","sourceRoot":"","sources":["../../../src/hooks/spatial-grid/floor-placed-elevation.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,273 @@
1
+ import { beforeEach, describe, expect, test } from 'bun:test';
2
+ import { z } from 'zod';
3
+ import { nodeRegistry, registerNode } from '../../registry';
4
+ import { getFloorPlacedElevation, getFloorStackedPosition } from './floor-placed-elevation';
5
+ import { spatialGridManager } from './spatial-grid-manager';
6
+ const LEVEL_ID = 'level_test';
7
+ function makeDefinition(kind, capabilities = {}) {
8
+ return {
9
+ kind,
10
+ schemaVersion: 1,
11
+ schema: z.object({ type: z.literal(kind) }),
12
+ category: 'utility',
13
+ defaults: () => ({}),
14
+ capabilities,
15
+ };
16
+ }
17
+ function makeLevel() {
18
+ return {
19
+ id: LEVEL_ID,
20
+ type: 'level',
21
+ object: 'node',
22
+ parentId: null,
23
+ visible: true,
24
+ metadata: {},
25
+ children: [],
26
+ level: 0,
27
+ };
28
+ }
29
+ function makeFloorNode(overrides = {}) {
30
+ return {
31
+ id: 'item_test',
32
+ type: 'item',
33
+ object: 'node',
34
+ parentId: LEVEL_ID,
35
+ visible: true,
36
+ metadata: {},
37
+ children: [],
38
+ position: [0, 0, 0],
39
+ rotation: [0, 0, 0],
40
+ scale: [1, 1, 1],
41
+ asset: {
42
+ id: 'asset_test',
43
+ category: 'test',
44
+ name: 'Test',
45
+ thumbnail: '',
46
+ src: 'asset:test',
47
+ dimensions: [1, 1, 1],
48
+ source: 'library',
49
+ },
50
+ ...overrides,
51
+ };
52
+ }
53
+ function addSlab(polygon, elevation, id = `slab_${elevation}`) {
54
+ const slab = {
55
+ id,
56
+ type: 'slab',
57
+ object: 'node',
58
+ parentId: LEVEL_ID,
59
+ visible: true,
60
+ metadata: {},
61
+ children: [],
62
+ polygon,
63
+ holes: [],
64
+ holeMetadata: [],
65
+ elevation,
66
+ autoFromWalls: false,
67
+ };
68
+ spatialGridManager.handleNodeCreated(slab, LEVEL_ID);
69
+ }
70
+ function nodesFor(...nodes) {
71
+ return Object.fromEntries(nodes.map((node) => [node.id, node]));
72
+ }
73
+ describe('floor-placed elevation resolver', () => {
74
+ beforeEach(() => {
75
+ nodeRegistry._reset();
76
+ spatialGridManager.clear();
77
+ });
78
+ test('returns 0 without a floorPlaced capability', () => {
79
+ registerNode(makeDefinition('item'));
80
+ addSlab([
81
+ [-1, -1],
82
+ [1, -1],
83
+ [1, 1],
84
+ [-1, 1],
85
+ ], 0.4);
86
+ const level = makeLevel();
87
+ const node = makeFloorNode();
88
+ expect(getFloorPlacedElevation({
89
+ node,
90
+ nodes: nodesFor(level, node),
91
+ position: [0, 0, 0],
92
+ rotation: [0, 0, 0],
93
+ })).toBe(0);
94
+ });
95
+ test('returns 0 when applies returns false', () => {
96
+ registerNode(makeDefinition('item', {
97
+ floorPlaced: {
98
+ footprint: () => ({ dimensions: [1, 1, 1], rotation: [0, 0, 0] }),
99
+ applies: () => false,
100
+ },
101
+ }));
102
+ addSlab([
103
+ [-1, -1],
104
+ [1, -1],
105
+ [1, 1],
106
+ [-1, 1],
107
+ ], 0.4);
108
+ const level = makeLevel();
109
+ const node = makeFloorNode();
110
+ expect(getFloorPlacedElevation({
111
+ node,
112
+ nodes: nodesFor(level, node),
113
+ position: [0, 0, 0],
114
+ rotation: [0, 0, 0],
115
+ })).toBe(0);
116
+ });
117
+ test('clamps non-finite slab elevation to 0', () => {
118
+ registerNode(makeDefinition('item', {
119
+ floorPlaced: {
120
+ footprint: () => ({ dimensions: [1, 1, 1], rotation: [0, 0, 0] }),
121
+ },
122
+ }));
123
+ const original = spatialGridManager.getSlabElevationForItem;
124
+ spatialGridManager.getSlabElevationForItem = (() => Number.NaN);
125
+ try {
126
+ const level = makeLevel();
127
+ const node = makeFloorNode();
128
+ expect(getFloorPlacedElevation({
129
+ node,
130
+ nodes: nodesFor(level, node),
131
+ position: [0, 0, 0],
132
+ rotation: [0, 0, 0],
133
+ })).toBe(0);
134
+ }
135
+ finally {
136
+ spatialGridManager.getSlabElevationForItem = original;
137
+ }
138
+ });
139
+ test('returns 0 for a non-level direct parent', () => {
140
+ registerNode(makeDefinition('item', {
141
+ floorPlaced: {
142
+ footprint: () => ({ dimensions: [1, 1, 1], rotation: [0, 0, 0] }),
143
+ },
144
+ }));
145
+ addSlab([
146
+ [-1, -1],
147
+ [1, -1],
148
+ [1, 1],
149
+ [-1, 1],
150
+ ], 0.4);
151
+ const level = makeLevel();
152
+ const shelf = {
153
+ id: 'shelf_test',
154
+ type: 'shelf',
155
+ parentId: LEVEL_ID,
156
+ };
157
+ const node = makeFloorNode({ parentId: shelf.id });
158
+ expect(getFloorPlacedElevation({
159
+ node,
160
+ nodes: nodesFor(level, shelf, node),
161
+ position: [0, 0, 0],
162
+ rotation: [0, 0, 0],
163
+ })).toBe(0);
164
+ });
165
+ test('returns 0 when the declared parent is missing', () => {
166
+ registerNode(makeDefinition('item', {
167
+ floorPlaced: {
168
+ footprint: () => ({ dimensions: [1, 1, 1], rotation: [0, 0, 0] }),
169
+ },
170
+ }));
171
+ addSlab([
172
+ [-1, -1],
173
+ [1, -1],
174
+ [1, 1],
175
+ [-1, 1],
176
+ ], 0.4);
177
+ const node = makeFloorNode({ parentId: 'missing_level' });
178
+ expect(getFloorPlacedElevation({
179
+ node,
180
+ nodes: nodesFor(node),
181
+ position: [0, 0, 0],
182
+ rotation: [0, 0, 0],
183
+ levelId: LEVEL_ID,
184
+ })).toBe(0);
185
+ });
186
+ test('uses the pending rotated footprint', () => {
187
+ registerNode(makeDefinition('item', {
188
+ floorPlaced: {
189
+ footprint: (node) => ({
190
+ dimensions: [4, 1, 1],
191
+ rotation: node.rotation,
192
+ }),
193
+ },
194
+ }));
195
+ addSlab([
196
+ [-0.2, 1.2],
197
+ [0.2, 1.2],
198
+ [0.2, 1.8],
199
+ [-0.2, 1.8],
200
+ ], 0.45);
201
+ const level = makeLevel();
202
+ const node = makeFloorNode();
203
+ expect(getFloorPlacedElevation({
204
+ node,
205
+ nodes: nodesFor(level, node),
206
+ position: [0, 0, 0],
207
+ rotation: [0, Math.PI / 2, 0],
208
+ })).toBeCloseTo(0.45);
209
+ });
210
+ test('returns slab overlap elevation and stacks Y onto canonical position', () => {
211
+ registerNode(makeDefinition('item', {
212
+ floorPlaced: {
213
+ footprint: (node) => ({
214
+ dimensions: [1, 1, 1],
215
+ rotation: node.rotation,
216
+ }),
217
+ },
218
+ }));
219
+ addSlab([
220
+ [-1, -1],
221
+ [1, -1],
222
+ [1, 1],
223
+ [-1, 1],
224
+ ], 0.35);
225
+ const level = makeLevel();
226
+ const node = makeFloorNode();
227
+ expect(getFloorPlacedElevation({
228
+ node,
229
+ nodes: nodesFor(level, node),
230
+ position: [0, 0.1, 0],
231
+ rotation: [0, 0, 0],
232
+ })).toBeCloseTo(0.35);
233
+ const stacked = getFloorStackedPosition({
234
+ node,
235
+ nodes: nodesFor(level, node),
236
+ position: [0, 0.1, 0],
237
+ rotation: [0, 0, 0],
238
+ });
239
+ expect(stacked[0]).toBe(0);
240
+ expect(stacked[1]).toBeCloseTo(0.45);
241
+ expect(stacked[2]).toBe(0);
242
+ });
243
+ test('takes the max elevation across composite footprints', () => {
244
+ registerNode(makeDefinition('item', {
245
+ floorPlaced: {
246
+ footprints: () => [
247
+ { position: [0, 0, 0], dimensions: [1, 1, 1], rotation: [0, 0, 0] },
248
+ { position: [3, 0, 0], dimensions: [1, 1, 1], rotation: [0, 0, 0] },
249
+ ],
250
+ },
251
+ }));
252
+ addSlab([
253
+ [-1, -1],
254
+ [1, -1],
255
+ [1, 1],
256
+ [-1, 1],
257
+ ], 0.2, 'slab_low');
258
+ addSlab([
259
+ [2.5, -0.5],
260
+ [3.5, -0.5],
261
+ [3.5, 0.5],
262
+ [2.5, 0.5],
263
+ ], 0.8, 'slab_high');
264
+ const level = makeLevel();
265
+ const node = makeFloorNode();
266
+ expect(getFloorPlacedElevation({
267
+ node,
268
+ nodes: nodesFor(level, node),
269
+ position: [0, 0, 0],
270
+ rotation: [0, 0, 0],
271
+ })).toBeCloseTo(0.8);
272
+ });
273
+ });
@@ -8,17 +8,24 @@ export declare function pointInPolygon(px: number, pz: number, polygon: Array<[n
8
8
  * Checks: any item corner inside polygon, or any polygon vertex inside item AABB, or edges intersect.
9
9
  */
10
10
  export declare function itemOverlapsPolygon(position: [number, number, number], dimensions: [number, number, number], rotation: [number, number, number], polygon: Array<[number, number]>, inset?: number): boolean;
11
+ type WallOverlapInput = {
12
+ start: [number, number];
13
+ end: [number, number];
14
+ curveOffset?: number;
15
+ thickness?: number;
16
+ };
11
17
  /**
12
18
  * Test if a wall segment overlaps with a polygon.
13
19
  * A wall is considered to overlap if:
14
20
  * - Its midpoint is inside the polygon (wall crosses through)
15
21
  * - At least one endpoint is inside (wall partially or fully in slab)
16
22
  * - It's collinear with and overlaps a polygon edge (wall on slab boundary)
23
+ * - (curved walls) any sample along the centerline is inside
17
24
  *
18
25
  * Note: A wall with just one endpoint touching the edge but the rest outside
19
26
  * is NOT considered overlapping (adjacent only).
20
27
  */
21
- export declare function wallOverlapsPolygon(start: [number, number], end: [number, number], polygon: Array<[number, number]>): boolean;
28
+ export declare function wallOverlapsPolygon(startOrWall: [number, number] | WallOverlapInput, endOrPolygon: [number, number] | Array<[number, number]>, polygonArg?: Array<[number, number]>): boolean;
22
29
  export declare class SpatialGridManager {
23
30
  private readonly floorGrids;
24
31
  private readonly wallGrids;
@@ -78,8 +85,11 @@ export declare class SpatialGridManager {
78
85
  * Get the slab elevation for a wall by checking if it overlaps with any slab polygon (excluding holes).
79
86
  * Uses wallOverlapsPolygon which handles edge cases (points on boundary, collinear segments).
80
87
  * Returns the highest slab elevation found, or 0 if none.
88
+ *
89
+ * Accepts an optional `curveOffset` so curved walls evaluate overlap
90
+ * against their actual centerline samples, not just the chord.
81
91
  */
82
- getSlabElevationForWall(levelId: string, start: [number, number], end: [number, number]): number;
92
+ getSlabElevationForWall(levelId: string, start: [number, number], end: [number, number], curveOffset?: number, thickness?: number): number;
83
93
  /**
84
94
  * Check if an item can be placed on a ceiling.
85
95
  * Validates that the footprint is within the ceiling polygon (but not in any holes) and doesn't overlap other ceiling items.
@@ -92,4 +102,5 @@ export declare class SpatialGridManager {
92
102
  clear(): void;
93
103
  }
94
104
  export declare const spatialGridManager: SpatialGridManager;
105
+ export {};
95
106
  //# sourceMappingURL=spatial-grid-manager.d.ts.map