@pascal-app/core 0.6.0 → 0.8.0

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 (120) hide show
  1. package/dist/events/bus.d.ts +45 -6
  2. package/dist/events/bus.d.ts.map +1 -1
  3. package/dist/events/bus.js +1 -1
  4. package/dist/hooks/scene-registry/scene-registry.d.ts +2 -0
  5. package/dist/hooks/scene-registry/scene-registry.d.ts.map +1 -1
  6. package/dist/hooks/scene-registry/scene-registry.js +2 -0
  7. package/dist/hooks/spatial-grid/spatial-grid-manager.d.ts.map +1 -1
  8. package/dist/hooks/spatial-grid/spatial-grid-manager.js +164 -6
  9. package/dist/index.d.ts +8 -15
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +7 -14
  12. package/dist/lib/door-operation.d.ts +7 -0
  13. package/dist/lib/door-operation.d.ts.map +1 -0
  14. package/dist/lib/door-operation.js +25 -0
  15. package/dist/lib/polygon-geometry.d.ts.map +1 -1
  16. package/dist/lib/slab-polygon.d.ts +3 -0
  17. package/dist/lib/slab-polygon.d.ts.map +1 -0
  18. package/dist/lib/slab-polygon.js +58 -0
  19. package/dist/lib/space-detection.d.ts.map +1 -1
  20. package/dist/lib/space-detection.js +10 -8
  21. package/dist/material-library.d.ts +5 -3
  22. package/dist/material-library.d.ts.map +1 -1
  23. package/dist/material-library.js +28 -32
  24. package/dist/schema/asset-url.d.ts +34 -0
  25. package/dist/schema/asset-url.d.ts.map +1 -0
  26. package/dist/schema/asset-url.js +79 -0
  27. package/dist/schema/asset-url.test.d.ts +2 -0
  28. package/dist/schema/asset-url.test.d.ts.map +1 -0
  29. package/dist/schema/asset-url.test.js +134 -0
  30. package/dist/schema/index.d.ts +7 -5
  31. package/dist/schema/index.d.ts.map +1 -1
  32. package/dist/schema/index.js +5 -3
  33. package/dist/schema/material.d.ts +1 -0
  34. package/dist/schema/material.d.ts.map +1 -1
  35. package/dist/schema/material.js +13 -11
  36. package/dist/schema/nodes/column.d.ts +520 -0
  37. package/dist/schema/nodes/column.d.ts.map +1 -0
  38. package/dist/schema/nodes/column.js +385 -0
  39. package/dist/schema/nodes/door.d.ts +72 -0
  40. package/dist/schema/nodes/door.d.ts.map +1 -1
  41. package/dist/schema/nodes/door.js +39 -2
  42. package/dist/schema/nodes/fence.d.ts +1 -1
  43. package/dist/schema/nodes/fence.js +2 -2
  44. package/dist/schema/nodes/guide.d.ts +17 -0
  45. package/dist/schema/nodes/guide.d.ts.map +1 -1
  46. package/dist/schema/nodes/guide.js +11 -1
  47. package/dist/schema/nodes/item.d.ts +20 -0
  48. package/dist/schema/nodes/item.d.ts.map +1 -1
  49. package/dist/schema/nodes/item.js +30 -1
  50. package/dist/schema/nodes/level.d.ts +1 -1
  51. package/dist/schema/nodes/level.d.ts.map +1 -1
  52. package/dist/schema/nodes/level.js +6 -0
  53. package/dist/schema/nodes/roof-segment.d.ts +2 -2
  54. package/dist/schema/nodes/roof.d.ts +2 -2
  55. package/dist/schema/nodes/roof.d.ts.map +1 -1
  56. package/dist/schema/nodes/roof.js +5 -5
  57. package/dist/schema/nodes/scan.d.ts.map +1 -1
  58. package/dist/schema/nodes/scan.js +2 -1
  59. package/dist/schema/nodes/site.d.ts +7 -0
  60. package/dist/schema/nodes/site.d.ts.map +1 -1
  61. package/dist/schema/nodes/spawn.d.ts +24 -0
  62. package/dist/schema/nodes/spawn.d.ts.map +1 -0
  63. package/dist/schema/nodes/spawn.js +8 -0
  64. package/dist/schema/nodes/stair.d.ts +6 -6
  65. package/dist/schema/nodes/stair.d.ts.map +1 -1
  66. package/dist/schema/nodes/stair.js +9 -7
  67. package/dist/schema/nodes/window.d.ts +55 -0
  68. package/dist/schema/nodes/window.d.ts.map +1 -1
  69. package/dist/schema/nodes/window.js +29 -0
  70. package/dist/schema/types.d.ts +320 -5
  71. package/dist/schema/types.d.ts.map +1 -1
  72. package/dist/schema/types.js +4 -0
  73. package/dist/store/actions/node-actions.d.ts.map +1 -1
  74. package/dist/store/actions/node-actions.js +13 -10
  75. package/dist/store/use-interactive.d.ts +43 -0
  76. package/dist/store/use-interactive.d.ts.map +1 -1
  77. package/dist/store/use-interactive.js +66 -0
  78. package/dist/store/use-scene.d.ts.map +1 -1
  79. package/dist/store/use-scene.js +69 -5
  80. package/dist/systems/stair/stair-opening-sync.d.ts.map +1 -1
  81. package/dist/systems/stair/stair-opening-sync.js +41 -7
  82. package/dist/systems/stair/stair-opening-sync.test.d.ts +2 -0
  83. package/dist/systems/stair/stair-opening-sync.test.d.ts.map +1 -0
  84. package/dist/systems/stair/stair-opening-sync.test.js +63 -0
  85. package/dist/systems/wall/wall-curve.d.ts +1 -1
  86. package/dist/systems/wall/wall-curve.d.ts.map +1 -1
  87. package/dist/systems/wall/wall-curve.js +1 -1
  88. package/dist/systems/wall/wall-mitering.d.ts.map +1 -1
  89. package/dist/systems/wall/wall-mitering.js +2 -6
  90. package/package.json +34 -5
  91. package/dist/materials.d.ts +0 -10
  92. package/dist/materials.d.ts.map +0 -1
  93. package/dist/materials.js +0 -22
  94. package/dist/systems/ceiling/ceiling-system.d.ts +0 -8
  95. package/dist/systems/ceiling/ceiling-system.d.ts.map +0 -1
  96. package/dist/systems/ceiling/ceiling-system.js +0 -92
  97. package/dist/systems/door/door-system.d.ts +0 -2
  98. package/dist/systems/door/door-system.d.ts.map +0 -1
  99. package/dist/systems/door/door-system.js +0 -195
  100. package/dist/systems/fence/fence-system.d.ts +0 -2
  101. package/dist/systems/fence/fence-system.d.ts.map +0 -1
  102. package/dist/systems/fence/fence-system.js +0 -187
  103. package/dist/systems/item/item-system.d.ts +0 -2
  104. package/dist/systems/item/item-system.d.ts.map +0 -1
  105. package/dist/systems/item/item-system.js +0 -48
  106. package/dist/systems/roof/roof-system.d.ts +0 -16
  107. package/dist/systems/roof/roof-system.d.ts.map +0 -1
  108. package/dist/systems/roof/roof-system.js +0 -797
  109. package/dist/systems/slab/slab-system.d.ts +0 -8
  110. package/dist/systems/slab/slab-system.d.ts.map +0 -1
  111. package/dist/systems/slab/slab-system.js +0 -214
  112. package/dist/systems/stair/stair-system.d.ts +0 -2
  113. package/dist/systems/stair/stair-system.d.ts.map +0 -1
  114. package/dist/systems/stair/stair-system.js +0 -776
  115. package/dist/systems/wall/wall-system.d.ts +0 -12
  116. package/dist/systems/wall/wall-system.d.ts.map +0 -1
  117. package/dist/systems/wall/wall-system.js +0 -455
  118. package/dist/systems/window/window-system.d.ts +0 -2
  119. package/dist/systems/window/window-system.d.ts.map +0 -1
  120. package/dist/systems/window/window-system.js +0 -131
@@ -76,6 +76,13 @@ export declare const AnyNode: z.ZodDiscriminatedUnion<[z.ZodObject<{
76
76
  category: z.ZodString;
77
77
  name: z.ZodString;
78
78
  thumbnail: z.ZodString;
79
+ floorPlanUrl: z.ZodOptional<z.ZodString>;
80
+ source: z.ZodDefault<z.ZodEnum<{
81
+ library: "library";
82
+ community: "community";
83
+ mine: "mine";
84
+ }>>;
85
+ isDraft: z.ZodOptional<z.ZodBoolean>;
79
86
  src: z.ZodString;
80
87
  dimensions: z.ZodDefault<z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>>;
81
88
  attachTo: z.ZodOptional<z.ZodEnum<{
@@ -175,8 +182,192 @@ export declare const AnyNode: z.ZodDiscriminatedUnion<[z.ZodObject<{
175
182
  metadata: z.ZodDefault<z.ZodOptional<z.ZodJSONSchema>>;
176
183
  id: z.ZodDefault<z.ZodTemplateLiteral<`level_${string}`>>;
177
184
  type: z.ZodDefault<z.ZodLiteral<"level">>;
178
- children: z.ZodDefault<z.ZodArray<z.ZodUnion<readonly [z.ZodDefault<z.ZodTemplateLiteral<`wall_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`fence_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`zone_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`slab_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`ceiling_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`roof_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`stair_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`scan_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`guide_${string}`>>]>>>;
185
+ children: z.ZodDefault<z.ZodArray<z.ZodUnion<readonly [z.ZodDefault<z.ZodTemplateLiteral<`wall_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`fence_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`column_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`item_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`zone_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`slab_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`ceiling_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`roof_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`stair_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`scan_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`guide_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`spawn_${string}`>>]>>>;
179
186
  level: z.ZodDefault<z.ZodNumber>;
187
+ }, z.core.$strip>, z.ZodObject<{
188
+ object: z.ZodDefault<z.ZodLiteral<"node">>;
189
+ name: z.ZodOptional<z.ZodString>;
190
+ parentId: z.ZodDefault<z.ZodNullable<z.ZodString>>;
191
+ visible: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
192
+ camera: z.ZodOptional<z.ZodObject<{
193
+ position: z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>;
194
+ target: z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>;
195
+ mode: z.ZodDefault<z.ZodEnum<{
196
+ perspective: "perspective";
197
+ orthographic: "orthographic";
198
+ }>>;
199
+ fov: z.ZodOptional<z.ZodNumber>;
200
+ zoom: z.ZodOptional<z.ZodNumber>;
201
+ }, z.core.$strip>>;
202
+ metadata: z.ZodDefault<z.ZodOptional<z.ZodJSONSchema>>;
203
+ id: z.ZodDefault<z.ZodTemplateLiteral<`column_${string}`>>;
204
+ type: z.ZodDefault<z.ZodLiteral<"column">>;
205
+ position: z.ZodDefault<z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>>;
206
+ rotation: z.ZodDefault<z.ZodNumber>;
207
+ style: z.ZodDefault<z.ZodEnum<{
208
+ plain: "plain";
209
+ faceted: "faceted";
210
+ fluted: "fluted";
211
+ "lathe-turned": "lathe-turned";
212
+ "dravidian-carved": "dravidian-carved";
213
+ cluster: "cluster";
214
+ }>>;
215
+ crossSection: z.ZodDefault<z.ZodEnum<{
216
+ round: "round";
217
+ square: "square";
218
+ rectangular: "rectangular";
219
+ octagonal: "octagonal";
220
+ "sixteen-sided": "sixteen-sided";
221
+ }>>;
222
+ height: z.ZodDefault<z.ZodNumber>;
223
+ radius: z.ZodDefault<z.ZodNumber>;
224
+ width: z.ZodDefault<z.ZodNumber>;
225
+ depth: z.ZodDefault<z.ZodNumber>;
226
+ edgeSoftness: z.ZodDefault<z.ZodNumber>;
227
+ baseHeight: z.ZodDefault<z.ZodNumber>;
228
+ capitalHeight: z.ZodDefault<z.ZodNumber>;
229
+ shaftProfile: z.ZodDefault<z.ZodEnum<{
230
+ straight: "straight";
231
+ tapered: "tapered";
232
+ bulged: "bulged";
233
+ baluster: "baluster";
234
+ hourglass: "hourglass";
235
+ }>>;
236
+ shaftTaper: z.ZodDefault<z.ZodNumber>;
237
+ shaftBulge: z.ZodDefault<z.ZodNumber>;
238
+ shaftStartScale: z.ZodDefault<z.ZodNumber>;
239
+ shaftEndScale: z.ZodDefault<z.ZodNumber>;
240
+ shaftSegmentCount: z.ZodDefault<z.ZodNumber>;
241
+ shaftTwistStep: z.ZodDefault<z.ZodNumber>;
242
+ shaftCornerRadius: z.ZodDefault<z.ZodNumber>;
243
+ shaftDetail: z.ZodDefault<z.ZodEnum<{
244
+ fluted: "fluted";
245
+ "lathe-turned": "lathe-turned";
246
+ none: "none";
247
+ spiral: "spiral";
248
+ panelled: "panelled";
249
+ }>>;
250
+ baseStyle: z.ZodDefault<z.ZodEnum<{
251
+ none: "none";
252
+ "simple-square": "simple-square";
253
+ "round-rings": "round-rings";
254
+ "square-plinth": "square-plinth";
255
+ "stepped-square": "stepped-square";
256
+ lotus: "lotus";
257
+ "ribbed-lotus": "ribbed-lotus";
258
+ "panelled-pedestal": "panelled-pedestal";
259
+ }>>;
260
+ baseWidthScale: z.ZodDefault<z.ZodNumber>;
261
+ baseDepthScale: z.ZodDefault<z.ZodNumber>;
262
+ baseTierCount: z.ZodDefault<z.ZodNumber>;
263
+ baseStepSpread: z.ZodDefault<z.ZodNumber>;
264
+ basePlinthHeightRatio: z.ZodDefault<z.ZodNumber>;
265
+ baseRoundBandScale: z.ZodDefault<z.ZodNumber>;
266
+ baseNeckScale: z.ZodDefault<z.ZodNumber>;
267
+ baseRoundBandCount: z.ZodDefault<z.ZodNumber>;
268
+ baseRibCount: z.ZodDefault<z.ZodNumber>;
269
+ baseCarvingLevel: z.ZodDefault<z.ZodNumber>;
270
+ basePanelInset: z.ZodDefault<z.ZodNumber>;
271
+ capitalStyle: z.ZodDefault<z.ZodEnum<{
272
+ none: "none";
273
+ simple: "simple";
274
+ "simple-slab": "simple-slab";
275
+ rounded: "rounded";
276
+ stepped: "stepped";
277
+ doric: "doric";
278
+ volute: "volute";
279
+ "ionic-volute": "ionic-volute";
280
+ "leaf-carved": "leaf-carved";
281
+ "corinthian-leaf": "corinthian-leaf";
282
+ "south-indian-bracket": "south-indian-bracket";
283
+ "wood-bracket": "wood-bracket";
284
+ }>>;
285
+ capitalWidthScale: z.ZodDefault<z.ZodNumber>;
286
+ capitalDepthScale: z.ZodDefault<z.ZodNumber>;
287
+ capitalTierCount: z.ZodDefault<z.ZodNumber>;
288
+ capitalStepSpread: z.ZodDefault<z.ZodNumber>;
289
+ capitalBandCount: z.ZodDefault<z.ZodNumber>;
290
+ voluteSize: z.ZodDefault<z.ZodNumber>;
291
+ voluteCount: z.ZodDefault<z.ZodNumber>;
292
+ leafCount: z.ZodDefault<z.ZodNumber>;
293
+ leafRows: z.ZodDefault<z.ZodNumber>;
294
+ bracketDepth: z.ZodDefault<z.ZodNumber>;
295
+ bracketTierCount: z.ZodDefault<z.ZodNumber>;
296
+ pendantCount: z.ZodDefault<z.ZodNumber>;
297
+ capitalCarvingLevel: z.ZodDefault<z.ZodNumber>;
298
+ ringCount: z.ZodDefault<z.ZodNumber>;
299
+ ringPlacement: z.ZodDefault<z.ZodEnum<{
300
+ ends: "ends";
301
+ even: "even";
302
+ top: "top";
303
+ bottom: "bottom";
304
+ }>>;
305
+ ringThickness: z.ZodDefault<z.ZodNumber>;
306
+ ringSpread: z.ZodDefault<z.ZodNumber>;
307
+ fluteCount: z.ZodDefault<z.ZodNumber>;
308
+ fluteDepth: z.ZodDefault<z.ZodNumber>;
309
+ fluteWidth: z.ZodDefault<z.ZodNumber>;
310
+ spiralTwist: z.ZodDefault<z.ZodNumber>;
311
+ spiralRibCount: z.ZodDefault<z.ZodNumber>;
312
+ panelCount: z.ZodDefault<z.ZodNumber>;
313
+ panelInsetDepth: z.ZodDefault<z.ZodNumber>;
314
+ panelShape: z.ZodDefault<z.ZodEnum<{
315
+ rectangle: "rectangle";
316
+ arched: "arched";
317
+ diamond: "diamond";
318
+ }>>;
319
+ latheRingCount: z.ZodDefault<z.ZodNumber>;
320
+ latheRingSpacing: z.ZodDefault<z.ZodEnum<{
321
+ ends: "ends";
322
+ even: "even";
323
+ top: "top";
324
+ bottom: "bottom";
325
+ }>>;
326
+ carvingLevel: z.ZodDefault<z.ZodNumber>;
327
+ carvingPlacement: z.ZodDefault<z.ZodEnum<{
328
+ shaft: "shaft";
329
+ base: "base";
330
+ capital: "capital";
331
+ all: "all";
332
+ }>>;
333
+ lowerBandEnabled: z.ZodDefault<z.ZodBoolean>;
334
+ lowerBandHeight: z.ZodDefault<z.ZodNumber>;
335
+ lowerBandCarvingLevel: z.ZodDefault<z.ZodNumber>;
336
+ dentilCount: z.ZodDefault<z.ZodNumber>;
337
+ beadCount: z.ZodDefault<z.ZodNumber>;
338
+ material: z.ZodOptional<z.ZodObject<{
339
+ id: z.ZodOptional<z.ZodString>;
340
+ preset: z.ZodOptional<z.ZodEnum<{
341
+ custom: "custom";
342
+ white: "white";
343
+ brick: "brick";
344
+ concrete: "concrete";
345
+ wood: "wood";
346
+ glass: "glass";
347
+ metal: "metal";
348
+ plaster: "plaster";
349
+ tile: "tile";
350
+ marble: "marble";
351
+ }>>;
352
+ properties: z.ZodOptional<z.ZodObject<{
353
+ color: z.ZodDefault<z.ZodString>;
354
+ roughness: z.ZodDefault<z.ZodNumber>;
355
+ metalness: z.ZodDefault<z.ZodNumber>;
356
+ opacity: z.ZodDefault<z.ZodNumber>;
357
+ transparent: z.ZodDefault<z.ZodBoolean>;
358
+ side: z.ZodDefault<z.ZodEnum<{
359
+ front: "front";
360
+ back: "back";
361
+ double: "double";
362
+ }>>;
363
+ }, z.core.$strip>>;
364
+ texture: z.ZodOptional<z.ZodObject<{
365
+ url: z.ZodString;
366
+ repeat: z.ZodOptional<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
367
+ scale: z.ZodOptional<z.ZodNumber>;
368
+ }, z.core.$strip>>;
369
+ }, z.core.$strip>>;
370
+ materialPreset: z.ZodOptional<z.ZodString>;
180
371
  }, z.core.$strip>, z.ZodObject<{
181
372
  object: z.ZodDefault<z.ZodLiteral<"node">>;
182
373
  name: z.ZodOptional<z.ZodString>;
@@ -363,9 +554,9 @@ export declare const AnyNode: z.ZodDiscriminatedUnion<[z.ZodObject<{
363
554
  materialPreset: z.ZodOptional<z.ZodString>;
364
555
  start: z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>;
365
556
  end: z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>;
366
- curveOffset: z.ZodOptional<z.ZodNumber>;
367
557
  height: z.ZodDefault<z.ZodNumber>;
368
558
  thickness: z.ZodDefault<z.ZodNumber>;
559
+ curveOffset: z.ZodOptional<z.ZodNumber>;
369
560
  baseHeight: z.ZodDefault<z.ZodNumber>;
370
561
  postSpacing: z.ZodDefault<z.ZodNumber>;
371
562
  postSize: z.ZodDefault<z.ZodNumber>;
@@ -416,6 +607,13 @@ export declare const AnyNode: z.ZodDiscriminatedUnion<[z.ZodObject<{
416
607
  category: z.ZodString;
417
608
  name: z.ZodString;
418
609
  thumbnail: z.ZodString;
610
+ floorPlanUrl: z.ZodOptional<z.ZodString>;
611
+ source: z.ZodDefault<z.ZodEnum<{
612
+ library: "library";
613
+ community: "community";
614
+ mine: "mine";
615
+ }>>;
616
+ isDraft: z.ZodOptional<z.ZodBoolean>;
419
617
  src: z.ZodString;
420
618
  dimensions: z.ZodDefault<z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>>;
421
619
  attachTo: z.ZodOptional<z.ZodEnum<{
@@ -827,13 +1025,13 @@ export declare const AnyNode: z.ZodDiscriminatedUnion<[z.ZodObject<{
827
1025
  position: z.ZodDefault<z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>>;
828
1026
  rotation: z.ZodDefault<z.ZodNumber>;
829
1027
  roofType: z.ZodDefault<z.ZodEnum<{
1028
+ flat: "flat";
830
1029
  hip: "hip";
831
1030
  gable: "gable";
832
1031
  shed: "shed";
833
1032
  gambrel: "gambrel";
834
1033
  dutch: "dutch";
835
1034
  mansard: "mansard";
836
- flat: "flat";
837
1035
  }>>;
838
1036
  width: z.ZodDefault<z.ZodNumber>;
839
1037
  depth: z.ZodDefault<z.ZodNumber>;
@@ -997,8 +1195,8 @@ export declare const AnyNode: z.ZodDiscriminatedUnion<[z.ZodObject<{
997
1195
  rotation: z.ZodDefault<z.ZodNumber>;
998
1196
  stairType: z.ZodDefault<z.ZodEnum<{
999
1197
  straight: "straight";
1000
- curved: "curved";
1001
1198
  spiral: "spiral";
1199
+ curved: "curved";
1002
1200
  }>>;
1003
1201
  fromLevelId: z.ZodDefault<z.ZodNullable<z.ZodString>>;
1004
1202
  toLevelId: z.ZodDefault<z.ZodNullable<z.ZodString>>;
@@ -1022,9 +1220,9 @@ export declare const AnyNode: z.ZodDiscriminatedUnion<[z.ZodObject<{
1022
1220
  showCenterColumn: z.ZodDefault<z.ZodBoolean>;
1023
1221
  showStepSupports: z.ZodDefault<z.ZodBoolean>;
1024
1222
  railingMode: z.ZodDefault<z.ZodEnum<{
1223
+ none: "none";
1025
1224
  left: "left";
1026
1225
  right: "right";
1027
- none: "none";
1028
1226
  both: "both";
1029
1227
  }>>;
1030
1228
  railingHeight: z.ZodDefault<z.ZodNumber>;
@@ -1143,6 +1341,34 @@ export declare const AnyNode: z.ZodDiscriminatedUnion<[z.ZodObject<{
1143
1341
  rotation: z.ZodDefault<z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>>;
1144
1342
  scale: z.ZodDefault<z.ZodNumber>;
1145
1343
  opacity: z.ZodDefault<z.ZodNumber>;
1344
+ scaleReference: z.ZodDefault<z.ZodNullable<z.ZodObject<{
1345
+ start: z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>;
1346
+ end: z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>;
1347
+ realLengthMeters: z.ZodNumber;
1348
+ measuredLengthUnits: z.ZodNumber;
1349
+ metersPerUnit: z.ZodNumber;
1350
+ label: z.ZodString;
1351
+ }, z.core.$strip>>>;
1352
+ }, z.core.$strip>, z.ZodObject<{
1353
+ object: z.ZodDefault<z.ZodLiteral<"node">>;
1354
+ name: z.ZodOptional<z.ZodString>;
1355
+ parentId: z.ZodDefault<z.ZodNullable<z.ZodString>>;
1356
+ visible: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
1357
+ camera: z.ZodOptional<z.ZodObject<{
1358
+ position: z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>;
1359
+ target: z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>;
1360
+ mode: z.ZodDefault<z.ZodEnum<{
1361
+ perspective: "perspective";
1362
+ orthographic: "orthographic";
1363
+ }>>;
1364
+ fov: z.ZodOptional<z.ZodNumber>;
1365
+ zoom: z.ZodOptional<z.ZodNumber>;
1366
+ }, z.core.$strip>>;
1367
+ metadata: z.ZodDefault<z.ZodOptional<z.ZodJSONSchema>>;
1368
+ id: z.ZodDefault<z.ZodTemplateLiteral<`spawn_${string}`>>;
1369
+ type: z.ZodDefault<z.ZodLiteral<"spawn">>;
1370
+ position: z.ZodDefault<z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>>;
1371
+ rotation: z.ZodDefault<z.ZodNumber>;
1146
1372
  }, z.core.$strip>, z.ZodObject<{
1147
1373
  object: z.ZodDefault<z.ZodLiteral<"node">>;
1148
1374
  name: z.ZodOptional<z.ZodString>;
@@ -1202,6 +1428,48 @@ export declare const AnyNode: z.ZodDiscriminatedUnion<[z.ZodObject<{
1202
1428
  wallId: z.ZodOptional<z.ZodString>;
1203
1429
  width: z.ZodDefault<z.ZodNumber>;
1204
1430
  height: z.ZodDefault<z.ZodNumber>;
1431
+ openingKind: z.ZodDefault<z.ZodEnum<{
1432
+ window: "window";
1433
+ opening: "opening";
1434
+ }>>;
1435
+ windowType: z.ZodDefault<z.ZodEnum<{
1436
+ sliding: "sliding";
1437
+ fixed: "fixed";
1438
+ casement: "casement";
1439
+ awning: "awning";
1440
+ hopper: "hopper";
1441
+ "single-hung": "single-hung";
1442
+ "double-hung": "double-hung";
1443
+ bay: "bay";
1444
+ bow: "bow";
1445
+ louvered: "louvered";
1446
+ }>>;
1447
+ operationState: z.ZodDefault<z.ZodNumber>;
1448
+ awningDirection: z.ZodDefault<z.ZodEnum<{
1449
+ up: "up";
1450
+ down: "down";
1451
+ }>>;
1452
+ casementStyle: z.ZodDefault<z.ZodEnum<{
1453
+ french: "french";
1454
+ single: "single";
1455
+ }>>;
1456
+ hingesSide: z.ZodDefault<z.ZodEnum<{
1457
+ left: "left";
1458
+ right: "right";
1459
+ }>>;
1460
+ openingShape: z.ZodDefault<z.ZodEnum<{
1461
+ rectangle: "rectangle";
1462
+ rounded: "rounded";
1463
+ arch: "arch";
1464
+ }>>;
1465
+ openingRadiusMode: z.ZodDefault<z.ZodEnum<{
1466
+ all: "all";
1467
+ individual: "individual";
1468
+ }>>;
1469
+ openingCornerRadii: z.ZodDefault<z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber, z.ZodNumber], null>>;
1470
+ cornerRadius: z.ZodDefault<z.ZodNumber>;
1471
+ archHeight: z.ZodDefault<z.ZodNumber>;
1472
+ openingRevealRadius: z.ZodDefault<z.ZodNumber>;
1205
1473
  frameThickness: z.ZodDefault<z.ZodNumber>;
1206
1474
  frameDepth: z.ZodDefault<z.ZodNumber>;
1207
1475
  columnRatios: z.ZodDefault<z.ZodArray<z.ZodNumber>>;
@@ -1270,6 +1538,52 @@ export declare const AnyNode: z.ZodDiscriminatedUnion<[z.ZodObject<{
1270
1538
  wallId: z.ZodOptional<z.ZodString>;
1271
1539
  width: z.ZodDefault<z.ZodNumber>;
1272
1540
  height: z.ZodDefault<z.ZodNumber>;
1541
+ doorCategory: z.ZodDefault<z.ZodEnum<{
1542
+ interior: "interior";
1543
+ garage: "garage";
1544
+ }>>;
1545
+ doorType: z.ZodDefault<z.ZodEnum<{
1546
+ double: "double";
1547
+ hinged: "hinged";
1548
+ french: "french";
1549
+ folding: "folding";
1550
+ pocket: "pocket";
1551
+ barn: "barn";
1552
+ sliding: "sliding";
1553
+ "garage-sectional": "garage-sectional";
1554
+ "garage-rollup": "garage-rollup";
1555
+ "garage-tiltup": "garage-tiltup";
1556
+ }>>;
1557
+ leafCount: z.ZodDefault<z.ZodUnion<readonly [z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<3>, z.ZodLiteral<4>]>>;
1558
+ operationState: z.ZodDefault<z.ZodNumber>;
1559
+ slideDirection: z.ZodDefault<z.ZodEnum<{
1560
+ left: "left";
1561
+ right: "right";
1562
+ }>>;
1563
+ trackStyle: z.ZodDefault<z.ZodEnum<{
1564
+ visible: "visible";
1565
+ none: "none";
1566
+ pocket: "pocket";
1567
+ overhead: "overhead";
1568
+ }>>;
1569
+ garagePanelCount: z.ZodDefault<z.ZodNumber>;
1570
+ openingKind: z.ZodDefault<z.ZodEnum<{
1571
+ door: "door";
1572
+ opening: "opening";
1573
+ }>>;
1574
+ openingShape: z.ZodDefault<z.ZodEnum<{
1575
+ rectangle: "rectangle";
1576
+ rounded: "rounded";
1577
+ arch: "arch";
1578
+ }>>;
1579
+ openingRadiusMode: z.ZodDefault<z.ZodEnum<{
1580
+ all: "all";
1581
+ individual: "individual";
1582
+ }>>;
1583
+ openingTopRadii: z.ZodDefault<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
1584
+ cornerRadius: z.ZodDefault<z.ZodNumber>;
1585
+ archHeight: z.ZodDefault<z.ZodNumber>;
1586
+ openingRevealRadius: z.ZodDefault<z.ZodNumber>;
1273
1587
  frameThickness: z.ZodDefault<z.ZodNumber>;
1274
1588
  frameDepth: z.ZodDefault<z.ZodNumber>;
1275
1589
  threshold: z.ZodDefault<z.ZodBoolean>;
@@ -1282,6 +1596,7 @@ export declare const AnyNode: z.ZodDiscriminatedUnion<[z.ZodObject<{
1282
1596
  inward: "inward";
1283
1597
  outward: "outward";
1284
1598
  }>>;
1599
+ swingAngle: z.ZodDefault<z.ZodNumber>;
1285
1600
  segments: z.ZodDefault<z.ZodArray<z.ZodObject<{
1286
1601
  type: z.ZodEnum<{
1287
1602
  glass: "glass";
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/schema/types.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,KAAK,CAAA;AAmBnB,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAkBlB,CAAA;AAEF,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,OAAO,CAAC,CAAA;AAC7C,MAAM,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;AACzC,MAAM,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/schema/types.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,KAAK,CAAA;AAqBnB,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAoBlB,CAAA;AAEF,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,OAAO,CAAC,CAAA;AAC7C,MAAM,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;AACzC,MAAM,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA"}
@@ -1,6 +1,7 @@
1
1
  import z from 'zod';
2
2
  import { BuildingNode } from './nodes/building';
3
3
  import { CeilingNode } from './nodes/ceiling';
4
+ import { ColumnNode } from './nodes/column';
4
5
  import { DoorNode } from './nodes/door';
5
6
  import { FenceNode } from './nodes/fence';
6
7
  import { GuideNode } from './nodes/guide';
@@ -11,6 +12,7 @@ import { RoofSegmentNode } from './nodes/roof-segment';
11
12
  import { ScanNode } from './nodes/scan';
12
13
  import { SiteNode } from './nodes/site';
13
14
  import { SlabNode } from './nodes/slab';
15
+ import { SpawnNode } from './nodes/spawn';
14
16
  import { StairNode } from './nodes/stair';
15
17
  import { StairSegmentNode } from './nodes/stair-segment';
16
18
  import { WallNode } from './nodes/wall';
@@ -20,6 +22,7 @@ export const AnyNode = z.discriminatedUnion('type', [
20
22
  SiteNode,
21
23
  BuildingNode,
22
24
  LevelNode,
25
+ ColumnNode,
23
26
  WallNode,
24
27
  FenceNode,
25
28
  ItemNode,
@@ -32,6 +35,7 @@ export const AnyNode = z.discriminatedUnion('type', [
32
35
  StairSegmentNode,
33
36
  ScanNode,
34
37
  GuideNode,
38
+ SpawnNode,
35
39
  WindowNode,
36
40
  DoorNode,
37
41
  ]);
@@ -1 +1 @@
1
- {"version":3,"file":"node-actions.d.ts","sourceRoot":"","sources":["../../../src/store/actions/node-actions.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,SAAS,EAIf,MAAM,cAAc,CAAA;AAErB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AA6N9C,eAAO,MAAM,iBAAiB,GAC5B,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,UAAU,CAAC,KAAK,IAAI,EAC7D,KAAK,MAAM,UAAU,EACrB,KAAK;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,SAAS,CAAA;CAAE,EAAE,SA4C/C,CAAA;AAED,eAAO,MAAM,iBAAiB,GAC5B,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,UAAU,CAAC,KAAK,IAAI,EAC7D,KAAK,MAAM,UAAU,EACrB,SAAS;IAAE,EAAE,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;CAAE,EAAE,SA+DrD,CAAA;AAED,eAAO,MAAM,iBAAiB,GAC5B,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,UAAU,CAAC,KAAK,IAAI,EAC7D,KAAK,MAAM,UAAU,EACrB,KAAK,SAAS,EAAE,SAsGjB,CAAA"}
1
+ {"version":3,"file":"node-actions.d.ts","sourceRoot":"","sources":["../../../src/store/actions/node-actions.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,SAAS,EAIf,MAAM,cAAc,CAAA;AAErB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AA+N9C,eAAO,MAAM,iBAAiB,GAC5B,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,UAAU,CAAC,KAAK,IAAI,EAC7D,KAAK,MAAM,UAAU,EACrB,KAAK;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,SAAS,CAAA;CAAE,EAAE,SA+C/C,CAAA;AAED,eAAO,MAAM,iBAAiB,GAC5B,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,UAAU,CAAC,KAAK,IAAI,EAC7D,KAAK,MAAM,UAAU,EACrB,SAAS;IAAE,EAAE,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;CAAE,EAAE,SA+DrD,CAAA;AAED,eAAO,MAAM,iBAAiB,GAC5B,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,UAAU,CAAC,KAAK,IAAI,EAC7D,KAAK,MAAM,UAAU,EACrB,KAAK,SAAS,EAAE,SAsGjB,CAAA"}
@@ -72,7 +72,7 @@ function buildMergedWallAttachmentUpdates(primary, secondary, mergedWallId, merg
72
72
  const wallChildren = [...(primary.children ?? []), ...(secondary.children ?? [])];
73
73
  for (const childId of wallChildren) {
74
74
  const child = nodes[childId];
75
- if (!child || !('position' in child) || !Array.isArray(child.position)) {
75
+ if (!(child && 'position' in child && Array.isArray(child.position))) {
76
76
  continue;
77
77
  }
78
78
  const sourceWall = child.parentId === secondary.id ? secondary : primary;
@@ -123,10 +123,10 @@ function buildWallMergePlans(nodes, idsToDelete) {
123
123
  return a.id.localeCompare(b.id);
124
124
  });
125
125
  const [primary, secondary] = sortedCandidates;
126
- if (!primary ||
127
- !secondary ||
128
- !areWallStylesCompatible(primary, secondary) ||
129
- !areWallsCollinearAcrossPoint(primary, secondary, junction)) {
126
+ if (!(primary &&
127
+ secondary &&
128
+ areWallStylesCompatible(primary, secondary) &&
129
+ areWallsCollinearAcrossPoint(primary, secondary, junction))) {
130
130
  continue;
131
131
  }
132
132
  const { start, end } = resolveMergedWallEndpoints(primary, secondary, junction);
@@ -153,25 +153,26 @@ export const createNodesAction = (set, get, ops) => {
153
153
  const nextNodes = { ...state.nodes };
154
154
  const nextRootIds = [...state.rootNodeIds];
155
155
  for (const { node, parentId } of ops) {
156
+ const effectiveParentId = parentId ?? node.parentId ?? null;
156
157
  // 1. Assign parentId to the child (Safe because BaseNode has parentId)
157
158
  const newNode = {
158
159
  ...node,
159
- parentId: parentId ?? null,
160
+ parentId: effectiveParentId,
160
161
  };
161
162
  nextNodes[newNode.id] = newNode;
162
163
  // 2. Update the Parent's children list
163
- if (parentId && nextNodes[parentId]) {
164
- const parent = nextNodes[parentId];
164
+ if (effectiveParentId && nextNodes[effectiveParentId]) {
165
+ const parent = nextNodes[effectiveParentId];
165
166
  // Type Guard: Check if the parent node is a container that supports children
166
167
  if ('children' in parent && Array.isArray(parent.children)) {
167
- nextNodes[parentId] = {
168
+ nextNodes[effectiveParentId] = {
168
169
  ...parent,
169
170
  // Use Set to prevent duplicate IDs if createNode is called twice
170
171
  children: Array.from(new Set([...parent.children, newNode.id])), // We don't verify child types here
171
172
  };
172
173
  }
173
174
  }
174
- else if (!parentId) {
175
+ else if (!effectiveParentId) {
175
176
  // 3. Handle Root nodes
176
177
  if (!nextRootIds.includes(newNode.id)) {
177
178
  nextRootIds.push(newNode.id);
@@ -185,6 +186,8 @@ export const createNodesAction = (set, get, ops) => {
185
186
  get().markDirty(node.id);
186
187
  if (parentId)
187
188
  get().markDirty(parentId);
189
+ else if (node.parentId)
190
+ get().markDirty(node.parentId);
188
191
  });
189
192
  };
190
193
  export const updateNodesAction = (set, get, updates) => {
@@ -4,14 +4,57 @@ export type ControlValue = boolean | number;
4
4
  export type ItemInteractiveState = {
5
5
  controlValues: ControlValue[];
6
6
  };
7
+ export type DoorInteractiveState = {
8
+ operationState?: number;
9
+ swingAngle?: number;
10
+ };
11
+ export type DoorAnimationState = {
12
+ field: keyof DoorInteractiveState;
13
+ from: number;
14
+ to: number;
15
+ startedAt: number | null;
16
+ durationMs: number;
17
+ persist: boolean;
18
+ };
19
+ export type WindowInteractiveState = {
20
+ operationState?: number;
21
+ };
22
+ export type WindowAnimationState = {
23
+ field: keyof WindowInteractiveState;
24
+ from: number;
25
+ to: number;
26
+ startedAt: number | null;
27
+ durationMs: number;
28
+ persist: boolean;
29
+ };
7
30
  type InteractiveStore = {
8
31
  items: Record<AnyNodeId, ItemInteractiveState>;
32
+ doors: Record<AnyNodeId, DoorInteractiveState>;
33
+ doorAnimations: Record<AnyNodeId, DoorAnimationState>;
34
+ windows: Record<AnyNodeId, WindowInteractiveState>;
35
+ windowAnimations: Record<AnyNodeId, WindowAnimationState>;
9
36
  /** Initialize a node's interactive state from its asset definition (idempotent) */
10
37
  initItem: (itemId: AnyNodeId, interactive: Interactive) => void;
11
38
  /** Set a single control value */
12
39
  setControlValue: (itemId: AnyNodeId, index: number, value: ControlValue) => void;
13
40
  /** Remove a node's state (e.g. on unmount) */
14
41
  removeItem: (itemId: AnyNodeId) => void;
42
+ /** Set transient door open state without committing it to the scene node */
43
+ setDoorOpenState: (doorId: AnyNodeId, value: DoorInteractiveState) => void;
44
+ /** Clear transient door open state */
45
+ removeDoorOpenState: (doorId: AnyNodeId) => void;
46
+ /** Queue a door animation for the viewer frame loop */
47
+ startDoorAnimation: (doorId: AnyNodeId, value: DoorAnimationState) => void;
48
+ /** Cancel a queued door animation */
49
+ cancelDoorAnimation: (doorId: AnyNodeId) => void;
50
+ /** Set transient window open state without committing it to the scene node */
51
+ setWindowOpenState: (windowId: AnyNodeId, value: WindowInteractiveState) => void;
52
+ /** Clear transient window open state */
53
+ removeWindowOpenState: (windowId: AnyNodeId) => void;
54
+ /** Queue a window animation for the viewer frame loop */
55
+ startWindowAnimation: (windowId: AnyNodeId, value: WindowAnimationState) => void;
56
+ /** Cancel a queued window animation */
57
+ cancelWindowAnimation: (windowId: AnyNodeId) => void;
15
58
  };
16
59
  export declare const useInteractive: import("zustand").UseBoundStore<import("zustand").StoreApi<InteractiveStore>>;
17
60
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"use-interactive.d.ts","sourceRoot":"","sources":["../../src/store/use-interactive.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AACvD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAGhD,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,MAAM,CAAA;AAE3C,MAAM,MAAM,oBAAoB,GAAG;IAEjC,aAAa,EAAE,YAAY,EAAE,CAAA;CAC9B,CAAA;AAED,KAAK,gBAAgB,GAAG;IACtB,KAAK,EAAE,MAAM,CAAC,SAAS,EAAE,oBAAoB,CAAC,CAAA;IAE9C,mFAAmF;IACnF,QAAQ,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,KAAK,IAAI,CAAA;IAE/D,iCAAiC;IACjC,eAAe,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,KAAK,IAAI,CAAA;IAEhF,8CAA8C;IAC9C,UAAU,EAAE,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI,CAAA;CACxC,CAAA;AAeD,eAAO,MAAM,cAAc,+EAoCxB,CAAA"}
1
+ {"version":3,"file":"use-interactive.d.ts","sourceRoot":"","sources":["../../src/store/use-interactive.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AACvD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAGhD,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,MAAM,CAAA;AAE3C,MAAM,MAAM,oBAAoB,GAAG;IAEjC,aAAa,EAAE,YAAY,EAAE,CAAA;CAC9B,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG;IACjC,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,MAAM,oBAAoB,CAAA;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,OAAO,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,sBAAsB,GAAG;IACnC,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,EAAE,MAAM,sBAAsB,CAAA;IACnC,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,OAAO,CAAA;CACjB,CAAA;AAED,KAAK,gBAAgB,GAAG;IACtB,KAAK,EAAE,MAAM,CAAC,SAAS,EAAE,oBAAoB,CAAC,CAAA;IAC9C,KAAK,EAAE,MAAM,CAAC,SAAS,EAAE,oBAAoB,CAAC,CAAA;IAC9C,cAAc,EAAE,MAAM,CAAC,SAAS,EAAE,kBAAkB,CAAC,CAAA;IACrD,OAAO,EAAE,MAAM,CAAC,SAAS,EAAE,sBAAsB,CAAC,CAAA;IAClD,gBAAgB,EAAE,MAAM,CAAC,SAAS,EAAE,oBAAoB,CAAC,CAAA;IAEzD,mFAAmF;IACnF,QAAQ,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,KAAK,IAAI,CAAA;IAE/D,iCAAiC;IACjC,eAAe,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,KAAK,IAAI,CAAA;IAEhF,8CAA8C;IAC9C,UAAU,EAAE,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI,CAAA;IAEvC,4EAA4E;IAC5E,gBAAgB,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,oBAAoB,KAAK,IAAI,CAAA;IAE1E,sCAAsC;IACtC,mBAAmB,EAAE,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI,CAAA;IAEhD,uDAAuD;IACvD,kBAAkB,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAA;IAE1E,qCAAqC;IACrC,mBAAmB,EAAE,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI,CAAA;IAEhD,8EAA8E;IAC9E,kBAAkB,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,sBAAsB,KAAK,IAAI,CAAA;IAEhF,wCAAwC;IACxC,qBAAqB,EAAE,CAAC,QAAQ,EAAE,SAAS,KAAK,IAAI,CAAA;IAEpD,yDAAyD;IACzD,oBAAoB,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,oBAAoB,KAAK,IAAI,CAAA;IAEhF,uCAAuC;IACvC,qBAAqB,EAAE,CAAC,QAAQ,EAAE,SAAS,KAAK,IAAI,CAAA;CACrD,CAAA;AAeD,eAAO,MAAM,cAAc,+EA8GxB,CAAA"}
@@ -15,6 +15,10 @@ const defaultControlValue = (interactive, index) => {
15
15
  };
16
16
  export const useInteractive = create((set, get) => ({
17
17
  items: {},
18
+ doors: {},
19
+ doorAnimations: {},
20
+ windows: {},
21
+ windowAnimations: {},
18
22
  initItem: (itemId, interactive) => {
19
23
  const { controls } = interactive;
20
24
  if (controls.length === 0)
@@ -47,4 +51,66 @@ export const useInteractive = create((set, get) => ({
47
51
  return { items: rest };
48
52
  });
49
53
  },
54
+ setDoorOpenState: (doorId, value) => {
55
+ set((state) => ({
56
+ doors: {
57
+ ...state.doors,
58
+ [doorId]: {
59
+ ...state.doors[doorId],
60
+ ...value,
61
+ },
62
+ },
63
+ }));
64
+ },
65
+ removeDoorOpenState: (doorId) => {
66
+ set((state) => {
67
+ const { [doorId]: _, ...rest } = state.doors;
68
+ return { doors: rest };
69
+ });
70
+ },
71
+ startDoorAnimation: (doorId, value) => {
72
+ set((state) => ({
73
+ doorAnimations: {
74
+ ...state.doorAnimations,
75
+ [doorId]: value,
76
+ },
77
+ }));
78
+ },
79
+ cancelDoorAnimation: (doorId) => {
80
+ set((state) => {
81
+ const { [doorId]: _, ...rest } = state.doorAnimations;
82
+ return { doorAnimations: rest };
83
+ });
84
+ },
85
+ setWindowOpenState: (windowId, value) => {
86
+ set((state) => ({
87
+ windows: {
88
+ ...state.windows,
89
+ [windowId]: {
90
+ ...state.windows[windowId],
91
+ ...value,
92
+ },
93
+ },
94
+ }));
95
+ },
96
+ removeWindowOpenState: (windowId) => {
97
+ set((state) => {
98
+ const { [windowId]: _, ...rest } = state.windows;
99
+ return { windows: rest };
100
+ });
101
+ },
102
+ startWindowAnimation: (windowId, value) => {
103
+ set((state) => ({
104
+ windowAnimations: {
105
+ ...state.windowAnimations,
106
+ [windowId]: value,
107
+ },
108
+ }));
109
+ },
110
+ cancelWindowAnimation: (windowId) => {
111
+ set((state) => {
112
+ const { [windowId]: _, ...rest } = state.windowAnimations;
113
+ return { windowAnimations: rest };
114
+ });
115
+ },
50
116
  }));