@pascal-app/core 0.3.0 → 0.3.2
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.
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/schema/index.d.ts +2 -1
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +3 -1
- package/dist/schema/material.d.ts +62 -0
- package/dist/schema/material.d.ts.map +1 -0
- package/dist/schema/material.js +130 -0
- package/dist/schema/nodes/ceiling.d.ts +31 -0
- package/dist/schema/nodes/ceiling.d.ts.map +1 -1
- package/dist/schema/nodes/ceiling.js +2 -2
- package/dist/schema/nodes/door.d.ts +33 -2
- package/dist/schema/nodes/door.d.ts.map +1 -1
- package/dist/schema/nodes/door.js +2 -0
- package/dist/schema/nodes/roof-segment.d.ts +31 -0
- package/dist/schema/nodes/roof-segment.d.ts.map +1 -1
- package/dist/schema/nodes/roof-segment.js +2 -1
- package/dist/schema/nodes/roof.d.ts +31 -0
- package/dist/schema/nodes/roof.d.ts.map +1 -1
- package/dist/schema/nodes/roof.js +2 -1
- package/dist/schema/nodes/slab.d.ts +31 -0
- package/dist/schema/nodes/slab.d.ts.map +1 -1
- package/dist/schema/nodes/slab.js +2 -2
- package/dist/schema/nodes/wall.d.ts +31 -0
- package/dist/schema/nodes/wall.d.ts.map +1 -1
- package/dist/schema/nodes/wall.js +2 -1
- package/dist/schema/nodes/window.d.ts +31 -0
- package/dist/schema/nodes/window.d.ts.map +1 -1
- package/dist/schema/nodes/window.js +2 -1
- package/dist/schema/types.d.ts +218 -1
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/store/actions/node-actions.d.ts.map +1 -1
- package/dist/store/actions/node-actions.js +43 -12
- package/dist/store/use-scene.d.ts +5 -0
- package/dist/store/use-scene.d.ts.map +1 -1
- package/dist/store/use-scene.js +14 -2
- package/dist/systems/wall/wall-system.d.ts.map +1 -1
- package/dist/systems/wall/wall-system.js +0 -2
- package/dist/utils/clone-scene-graph.d.ts +18 -0
- package/dist/utils/clone-scene-graph.d.ts.map +1 -0
- package/dist/utils/clone-scene-graph.js +96 -0
- package/package.json +2 -2
|
@@ -17,6 +17,37 @@ export declare const WindowNode: z.ZodObject<{
|
|
|
17
17
|
metadata: z.ZodDefault<z.ZodOptional<z.ZodJSONSchema>>;
|
|
18
18
|
id: z.ZodDefault<z.ZodTemplateLiteral<`window_${string}`>>;
|
|
19
19
|
type: z.ZodDefault<z.ZodLiteral<"window">>;
|
|
20
|
+
material: z.ZodOptional<z.ZodObject<{
|
|
21
|
+
preset: z.ZodOptional<z.ZodEnum<{
|
|
22
|
+
custom: "custom";
|
|
23
|
+
white: "white";
|
|
24
|
+
brick: "brick";
|
|
25
|
+
concrete: "concrete";
|
|
26
|
+
wood: "wood";
|
|
27
|
+
glass: "glass";
|
|
28
|
+
metal: "metal";
|
|
29
|
+
plaster: "plaster";
|
|
30
|
+
tile: "tile";
|
|
31
|
+
marble: "marble";
|
|
32
|
+
}>>;
|
|
33
|
+
properties: z.ZodOptional<z.ZodObject<{
|
|
34
|
+
color: z.ZodDefault<z.ZodString>;
|
|
35
|
+
roughness: z.ZodDefault<z.ZodNumber>;
|
|
36
|
+
metalness: z.ZodDefault<z.ZodNumber>;
|
|
37
|
+
opacity: z.ZodDefault<z.ZodNumber>;
|
|
38
|
+
transparent: z.ZodDefault<z.ZodBoolean>;
|
|
39
|
+
side: z.ZodDefault<z.ZodEnum<{
|
|
40
|
+
front: "front";
|
|
41
|
+
back: "back";
|
|
42
|
+
double: "double";
|
|
43
|
+
}>>;
|
|
44
|
+
}, z.core.$strip>>;
|
|
45
|
+
texture: z.ZodOptional<z.ZodObject<{
|
|
46
|
+
url: z.ZodString;
|
|
47
|
+
repeat: z.ZodOptional<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
|
|
48
|
+
scale: z.ZodOptional<z.ZodNumber>;
|
|
49
|
+
}, z.core.$strip>>;
|
|
50
|
+
}, z.core.$strip>>;
|
|
20
51
|
position: z.ZodDefault<z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>>;
|
|
21
52
|
rotation: z.ZodDefault<z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>>;
|
|
22
53
|
side: z.ZodOptional<z.ZodEnum<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"window.d.ts","sourceRoot":"","sources":["../../../src/schema/nodes/window.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;
|
|
1
|
+
{"version":3,"file":"window.d.ts","sourceRoot":"","sources":["../../../src/schema/nodes/window.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAwCrB,CAAA;AAEF,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAA"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import dedent from 'dedent';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { BaseNode, nodeType, objectId } from '../base';
|
|
4
|
+
import { MaterialSchema } from '../material';
|
|
4
5
|
export const WindowNode = BaseNode.extend({
|
|
5
6
|
id: objectId('window'),
|
|
6
7
|
type: nodeType('window'),
|
|
7
|
-
|
|
8
|
+
material: MaterialSchema.optional(),
|
|
8
9
|
position: z.tuple([z.number(), z.number(), z.number()]).default([0, 0, 0]),
|
|
9
10
|
rotation: z.tuple([z.number(), z.number(), z.number()]).default([0, 0, 0]),
|
|
10
11
|
side: z.enum(['front', 'back']).optional(),
|
package/dist/schema/types.d.ts
CHANGED
|
@@ -196,6 +196,37 @@ export declare const AnyNode: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
196
196
|
id: z.ZodDefault<z.ZodTemplateLiteral<`wall_${string}`>>;
|
|
197
197
|
type: z.ZodDefault<z.ZodLiteral<"wall">>;
|
|
198
198
|
children: z.ZodDefault<z.ZodArray<z.ZodDefault<z.ZodTemplateLiteral<`item_${string}`>>>>;
|
|
199
|
+
material: z.ZodOptional<z.ZodObject<{
|
|
200
|
+
preset: z.ZodOptional<z.ZodEnum<{
|
|
201
|
+
custom: "custom";
|
|
202
|
+
white: "white";
|
|
203
|
+
brick: "brick";
|
|
204
|
+
concrete: "concrete";
|
|
205
|
+
wood: "wood";
|
|
206
|
+
glass: "glass";
|
|
207
|
+
metal: "metal";
|
|
208
|
+
plaster: "plaster";
|
|
209
|
+
tile: "tile";
|
|
210
|
+
marble: "marble";
|
|
211
|
+
}>>;
|
|
212
|
+
properties: z.ZodOptional<z.ZodObject<{
|
|
213
|
+
color: z.ZodDefault<z.ZodString>;
|
|
214
|
+
roughness: z.ZodDefault<z.ZodNumber>;
|
|
215
|
+
metalness: z.ZodDefault<z.ZodNumber>;
|
|
216
|
+
opacity: z.ZodDefault<z.ZodNumber>;
|
|
217
|
+
transparent: z.ZodDefault<z.ZodBoolean>;
|
|
218
|
+
side: z.ZodDefault<z.ZodEnum<{
|
|
219
|
+
front: "front";
|
|
220
|
+
back: "back";
|
|
221
|
+
double: "double";
|
|
222
|
+
}>>;
|
|
223
|
+
}, z.core.$strip>>;
|
|
224
|
+
texture: z.ZodOptional<z.ZodObject<{
|
|
225
|
+
url: z.ZodString;
|
|
226
|
+
repeat: z.ZodOptional<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
|
|
227
|
+
scale: z.ZodOptional<z.ZodNumber>;
|
|
228
|
+
}, z.core.$strip>>;
|
|
229
|
+
}, z.core.$strip>>;
|
|
199
230
|
thickness: z.ZodOptional<z.ZodNumber>;
|
|
200
231
|
height: z.ZodOptional<z.ZodNumber>;
|
|
201
232
|
start: z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>;
|
|
@@ -341,6 +372,37 @@ export declare const AnyNode: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
341
372
|
metadata: z.ZodDefault<z.ZodOptional<z.ZodJSONSchema>>;
|
|
342
373
|
id: z.ZodDefault<z.ZodTemplateLiteral<`slab_${string}`>>;
|
|
343
374
|
type: z.ZodDefault<z.ZodLiteral<"slab">>;
|
|
375
|
+
material: z.ZodOptional<z.ZodObject<{
|
|
376
|
+
preset: z.ZodOptional<z.ZodEnum<{
|
|
377
|
+
custom: "custom";
|
|
378
|
+
white: "white";
|
|
379
|
+
brick: "brick";
|
|
380
|
+
concrete: "concrete";
|
|
381
|
+
wood: "wood";
|
|
382
|
+
glass: "glass";
|
|
383
|
+
metal: "metal";
|
|
384
|
+
plaster: "plaster";
|
|
385
|
+
tile: "tile";
|
|
386
|
+
marble: "marble";
|
|
387
|
+
}>>;
|
|
388
|
+
properties: z.ZodOptional<z.ZodObject<{
|
|
389
|
+
color: z.ZodDefault<z.ZodString>;
|
|
390
|
+
roughness: z.ZodDefault<z.ZodNumber>;
|
|
391
|
+
metalness: z.ZodDefault<z.ZodNumber>;
|
|
392
|
+
opacity: z.ZodDefault<z.ZodNumber>;
|
|
393
|
+
transparent: z.ZodDefault<z.ZodBoolean>;
|
|
394
|
+
side: z.ZodDefault<z.ZodEnum<{
|
|
395
|
+
front: "front";
|
|
396
|
+
back: "back";
|
|
397
|
+
double: "double";
|
|
398
|
+
}>>;
|
|
399
|
+
}, z.core.$strip>>;
|
|
400
|
+
texture: z.ZodOptional<z.ZodObject<{
|
|
401
|
+
url: z.ZodString;
|
|
402
|
+
repeat: z.ZodOptional<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
|
|
403
|
+
scale: z.ZodOptional<z.ZodNumber>;
|
|
404
|
+
}, z.core.$strip>>;
|
|
405
|
+
}, z.core.$strip>>;
|
|
344
406
|
polygon: z.ZodArray<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
|
|
345
407
|
holes: z.ZodDefault<z.ZodArray<z.ZodArray<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>>>;
|
|
346
408
|
elevation: z.ZodDefault<z.ZodNumber>;
|
|
@@ -363,6 +425,37 @@ export declare const AnyNode: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
363
425
|
id: z.ZodDefault<z.ZodTemplateLiteral<`ceiling_${string}`>>;
|
|
364
426
|
type: z.ZodDefault<z.ZodLiteral<"ceiling">>;
|
|
365
427
|
children: z.ZodDefault<z.ZodArray<z.ZodDefault<z.ZodTemplateLiteral<`item_${string}`>>>>;
|
|
428
|
+
material: z.ZodOptional<z.ZodObject<{
|
|
429
|
+
preset: z.ZodOptional<z.ZodEnum<{
|
|
430
|
+
custom: "custom";
|
|
431
|
+
white: "white";
|
|
432
|
+
brick: "brick";
|
|
433
|
+
concrete: "concrete";
|
|
434
|
+
wood: "wood";
|
|
435
|
+
glass: "glass";
|
|
436
|
+
metal: "metal";
|
|
437
|
+
plaster: "plaster";
|
|
438
|
+
tile: "tile";
|
|
439
|
+
marble: "marble";
|
|
440
|
+
}>>;
|
|
441
|
+
properties: z.ZodOptional<z.ZodObject<{
|
|
442
|
+
color: z.ZodDefault<z.ZodString>;
|
|
443
|
+
roughness: z.ZodDefault<z.ZodNumber>;
|
|
444
|
+
metalness: z.ZodDefault<z.ZodNumber>;
|
|
445
|
+
opacity: z.ZodDefault<z.ZodNumber>;
|
|
446
|
+
transparent: z.ZodDefault<z.ZodBoolean>;
|
|
447
|
+
side: z.ZodDefault<z.ZodEnum<{
|
|
448
|
+
front: "front";
|
|
449
|
+
back: "back";
|
|
450
|
+
double: "double";
|
|
451
|
+
}>>;
|
|
452
|
+
}, z.core.$strip>>;
|
|
453
|
+
texture: z.ZodOptional<z.ZodObject<{
|
|
454
|
+
url: z.ZodString;
|
|
455
|
+
repeat: z.ZodOptional<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
|
|
456
|
+
scale: z.ZodOptional<z.ZodNumber>;
|
|
457
|
+
}, z.core.$strip>>;
|
|
458
|
+
}, z.core.$strip>>;
|
|
366
459
|
polygon: z.ZodArray<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
|
|
367
460
|
holes: z.ZodDefault<z.ZodArray<z.ZodArray<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>>>;
|
|
368
461
|
height: z.ZodDefault<z.ZodNumber>;
|
|
@@ -384,6 +477,37 @@ export declare const AnyNode: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
384
477
|
metadata: z.ZodDefault<z.ZodOptional<z.ZodJSONSchema>>;
|
|
385
478
|
id: z.ZodDefault<z.ZodTemplateLiteral<`roof_${string}`>>;
|
|
386
479
|
type: z.ZodDefault<z.ZodLiteral<"roof">>;
|
|
480
|
+
material: z.ZodOptional<z.ZodObject<{
|
|
481
|
+
preset: z.ZodOptional<z.ZodEnum<{
|
|
482
|
+
custom: "custom";
|
|
483
|
+
white: "white";
|
|
484
|
+
brick: "brick";
|
|
485
|
+
concrete: "concrete";
|
|
486
|
+
wood: "wood";
|
|
487
|
+
glass: "glass";
|
|
488
|
+
metal: "metal";
|
|
489
|
+
plaster: "plaster";
|
|
490
|
+
tile: "tile";
|
|
491
|
+
marble: "marble";
|
|
492
|
+
}>>;
|
|
493
|
+
properties: z.ZodOptional<z.ZodObject<{
|
|
494
|
+
color: z.ZodDefault<z.ZodString>;
|
|
495
|
+
roughness: z.ZodDefault<z.ZodNumber>;
|
|
496
|
+
metalness: z.ZodDefault<z.ZodNumber>;
|
|
497
|
+
opacity: z.ZodDefault<z.ZodNumber>;
|
|
498
|
+
transparent: z.ZodDefault<z.ZodBoolean>;
|
|
499
|
+
side: z.ZodDefault<z.ZodEnum<{
|
|
500
|
+
front: "front";
|
|
501
|
+
back: "back";
|
|
502
|
+
double: "double";
|
|
503
|
+
}>>;
|
|
504
|
+
}, z.core.$strip>>;
|
|
505
|
+
texture: z.ZodOptional<z.ZodObject<{
|
|
506
|
+
url: z.ZodString;
|
|
507
|
+
repeat: z.ZodOptional<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
|
|
508
|
+
scale: z.ZodOptional<z.ZodNumber>;
|
|
509
|
+
}, z.core.$strip>>;
|
|
510
|
+
}, z.core.$strip>>;
|
|
387
511
|
position: z.ZodDefault<z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>>;
|
|
388
512
|
rotation: z.ZodDefault<z.ZodNumber>;
|
|
389
513
|
children: z.ZodDefault<z.ZodArray<z.ZodDefault<z.ZodTemplateLiteral<`rseg_${string}`>>>>;
|
|
@@ -405,6 +529,37 @@ export declare const AnyNode: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
405
529
|
metadata: z.ZodDefault<z.ZodOptional<z.ZodJSONSchema>>;
|
|
406
530
|
id: z.ZodDefault<z.ZodTemplateLiteral<`rseg_${string}`>>;
|
|
407
531
|
type: z.ZodDefault<z.ZodLiteral<"roof-segment">>;
|
|
532
|
+
material: z.ZodOptional<z.ZodObject<{
|
|
533
|
+
preset: z.ZodOptional<z.ZodEnum<{
|
|
534
|
+
custom: "custom";
|
|
535
|
+
white: "white";
|
|
536
|
+
brick: "brick";
|
|
537
|
+
concrete: "concrete";
|
|
538
|
+
wood: "wood";
|
|
539
|
+
glass: "glass";
|
|
540
|
+
metal: "metal";
|
|
541
|
+
plaster: "plaster";
|
|
542
|
+
tile: "tile";
|
|
543
|
+
marble: "marble";
|
|
544
|
+
}>>;
|
|
545
|
+
properties: z.ZodOptional<z.ZodObject<{
|
|
546
|
+
color: z.ZodDefault<z.ZodString>;
|
|
547
|
+
roughness: z.ZodDefault<z.ZodNumber>;
|
|
548
|
+
metalness: z.ZodDefault<z.ZodNumber>;
|
|
549
|
+
opacity: z.ZodDefault<z.ZodNumber>;
|
|
550
|
+
transparent: z.ZodDefault<z.ZodBoolean>;
|
|
551
|
+
side: z.ZodDefault<z.ZodEnum<{
|
|
552
|
+
front: "front";
|
|
553
|
+
back: "back";
|
|
554
|
+
double: "double";
|
|
555
|
+
}>>;
|
|
556
|
+
}, z.core.$strip>>;
|
|
557
|
+
texture: z.ZodOptional<z.ZodObject<{
|
|
558
|
+
url: z.ZodString;
|
|
559
|
+
repeat: z.ZodOptional<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
|
|
560
|
+
scale: z.ZodOptional<z.ZodNumber>;
|
|
561
|
+
}, z.core.$strip>>;
|
|
562
|
+
}, z.core.$strip>>;
|
|
408
563
|
position: z.ZodDefault<z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>>;
|
|
409
564
|
rotation: z.ZodDefault<z.ZodNumber>;
|
|
410
565
|
roofType: z.ZodDefault<z.ZodEnum<{
|
|
@@ -488,6 +643,37 @@ export declare const AnyNode: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
488
643
|
metadata: z.ZodDefault<z.ZodOptional<z.ZodJSONSchema>>;
|
|
489
644
|
id: z.ZodDefault<z.ZodTemplateLiteral<`window_${string}`>>;
|
|
490
645
|
type: z.ZodDefault<z.ZodLiteral<"window">>;
|
|
646
|
+
material: z.ZodOptional<z.ZodObject<{
|
|
647
|
+
preset: z.ZodOptional<z.ZodEnum<{
|
|
648
|
+
custom: "custom";
|
|
649
|
+
white: "white";
|
|
650
|
+
brick: "brick";
|
|
651
|
+
concrete: "concrete";
|
|
652
|
+
wood: "wood";
|
|
653
|
+
glass: "glass";
|
|
654
|
+
metal: "metal";
|
|
655
|
+
plaster: "plaster";
|
|
656
|
+
tile: "tile";
|
|
657
|
+
marble: "marble";
|
|
658
|
+
}>>;
|
|
659
|
+
properties: z.ZodOptional<z.ZodObject<{
|
|
660
|
+
color: z.ZodDefault<z.ZodString>;
|
|
661
|
+
roughness: z.ZodDefault<z.ZodNumber>;
|
|
662
|
+
metalness: z.ZodDefault<z.ZodNumber>;
|
|
663
|
+
opacity: z.ZodDefault<z.ZodNumber>;
|
|
664
|
+
transparent: z.ZodDefault<z.ZodBoolean>;
|
|
665
|
+
side: z.ZodDefault<z.ZodEnum<{
|
|
666
|
+
front: "front";
|
|
667
|
+
back: "back";
|
|
668
|
+
double: "double";
|
|
669
|
+
}>>;
|
|
670
|
+
}, z.core.$strip>>;
|
|
671
|
+
texture: z.ZodOptional<z.ZodObject<{
|
|
672
|
+
url: z.ZodString;
|
|
673
|
+
repeat: z.ZodOptional<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
|
|
674
|
+
scale: z.ZodOptional<z.ZodNumber>;
|
|
675
|
+
}, z.core.$strip>>;
|
|
676
|
+
}, z.core.$strip>>;
|
|
491
677
|
position: z.ZodDefault<z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>>;
|
|
492
678
|
rotation: z.ZodDefault<z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>>;
|
|
493
679
|
side: z.ZodOptional<z.ZodEnum<{
|
|
@@ -524,6 +710,37 @@ export declare const AnyNode: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
524
710
|
metadata: z.ZodDefault<z.ZodOptional<z.ZodJSONSchema>>;
|
|
525
711
|
id: z.ZodDefault<z.ZodTemplateLiteral<`door_${string}`>>;
|
|
526
712
|
type: z.ZodDefault<z.ZodLiteral<"door">>;
|
|
713
|
+
material: z.ZodOptional<z.ZodObject<{
|
|
714
|
+
preset: z.ZodOptional<z.ZodEnum<{
|
|
715
|
+
custom: "custom";
|
|
716
|
+
white: "white";
|
|
717
|
+
brick: "brick";
|
|
718
|
+
concrete: "concrete";
|
|
719
|
+
wood: "wood";
|
|
720
|
+
glass: "glass";
|
|
721
|
+
metal: "metal";
|
|
722
|
+
plaster: "plaster";
|
|
723
|
+
tile: "tile";
|
|
724
|
+
marble: "marble";
|
|
725
|
+
}>>;
|
|
726
|
+
properties: z.ZodOptional<z.ZodObject<{
|
|
727
|
+
color: z.ZodDefault<z.ZodString>;
|
|
728
|
+
roughness: z.ZodDefault<z.ZodNumber>;
|
|
729
|
+
metalness: z.ZodDefault<z.ZodNumber>;
|
|
730
|
+
opacity: z.ZodDefault<z.ZodNumber>;
|
|
731
|
+
transparent: z.ZodDefault<z.ZodBoolean>;
|
|
732
|
+
side: z.ZodDefault<z.ZodEnum<{
|
|
733
|
+
front: "front";
|
|
734
|
+
back: "back";
|
|
735
|
+
double: "double";
|
|
736
|
+
}>>;
|
|
737
|
+
}, z.core.$strip>>;
|
|
738
|
+
texture: z.ZodOptional<z.ZodObject<{
|
|
739
|
+
url: z.ZodString;
|
|
740
|
+
repeat: z.ZodOptional<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
|
|
741
|
+
scale: z.ZodOptional<z.ZodNumber>;
|
|
742
|
+
}, z.core.$strip>>;
|
|
743
|
+
}, z.core.$strip>>;
|
|
527
744
|
position: z.ZodDefault<z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>>;
|
|
528
745
|
rotation: z.ZodDefault<z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>>;
|
|
529
746
|
side: z.ZodOptional<z.ZodEnum<{
|
|
@@ -547,8 +764,8 @@ export declare const AnyNode: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
547
764
|
}>>;
|
|
548
765
|
segments: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
549
766
|
type: z.ZodEnum<{
|
|
550
|
-
panel: "panel";
|
|
551
767
|
glass: "glass";
|
|
768
|
+
panel: "panel";
|
|
552
769
|
empty: "empty";
|
|
553
770
|
}>;
|
|
554
771
|
heightRatio: z.ZodNumber;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/schema/types.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,KAAK,CAAA;AAgBnB,eAAO,MAAM,OAAO
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/schema/types.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,KAAK,CAAA;AAgBnB,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAelB,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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-actions.d.ts","sourceRoot":"","sources":["../../../src/store/actions/node-actions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAEtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"node-actions.d.ts","sourceRoot":"","sources":["../../../src/store/actions/node-actions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAEtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAQ9C,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,SA2C/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,SAsErD,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,SA4EjB,CAAA"}
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
// Track pending RAF for updateNodesAction to prevent multiple queued callbacks
|
|
2
|
+
let pendingRafId = null;
|
|
3
|
+
let pendingUpdates = new Set();
|
|
1
4
|
export const createNodesAction = (set, get, ops) => {
|
|
2
5
|
set((state) => {
|
|
3
6
|
const nextNodes = { ...state.nodes };
|
|
@@ -39,6 +42,7 @@ export const createNodesAction = (set, get, ops) => {
|
|
|
39
42
|
};
|
|
40
43
|
export const updateNodesAction = (set, get, updates) => {
|
|
41
44
|
const parentsToUpdate = new Set();
|
|
45
|
+
const idsToMarkDirty = new Set();
|
|
42
46
|
set((state) => {
|
|
43
47
|
const nextNodes = { ...state.nodes };
|
|
44
48
|
for (const { id, data } of updates) {
|
|
@@ -73,14 +77,28 @@ export const updateNodesAction = (set, get, updates) => {
|
|
|
73
77
|
}
|
|
74
78
|
return { nodes: nextNodes };
|
|
75
79
|
});
|
|
76
|
-
//
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
80
|
+
// Collect all IDs that need to be marked dirty
|
|
81
|
+
for (const u of updates) {
|
|
82
|
+
idsToMarkDirty.add(u.id);
|
|
83
|
+
}
|
|
84
|
+
for (const pId of parentsToUpdate) {
|
|
85
|
+
idsToMarkDirty.add(pId);
|
|
86
|
+
}
|
|
87
|
+
// Add to pending updates set
|
|
88
|
+
for (const id of idsToMarkDirty) {
|
|
89
|
+
pendingUpdates.add(id);
|
|
90
|
+
}
|
|
91
|
+
// Cancel any pending RAF and schedule a new one
|
|
92
|
+
if (pendingRafId !== null) {
|
|
93
|
+
cancelAnimationFrame(pendingRafId);
|
|
94
|
+
}
|
|
95
|
+
pendingRafId = requestAnimationFrame(() => {
|
|
96
|
+
// Mark all pending updates as dirty
|
|
97
|
+
pendingUpdates.forEach((id) => {
|
|
98
|
+
get().markDirty(id);
|
|
83
99
|
});
|
|
100
|
+
pendingUpdates.clear();
|
|
101
|
+
pendingRafId = null;
|
|
84
102
|
});
|
|
85
103
|
};
|
|
86
104
|
export const deleteNodesAction = (set, get, ids) => {
|
|
@@ -89,7 +107,25 @@ export const deleteNodesAction = (set, get, ids) => {
|
|
|
89
107
|
const nextNodes = { ...state.nodes };
|
|
90
108
|
const nextCollections = { ...state.collections };
|
|
91
109
|
let nextRootIds = [...state.rootNodeIds];
|
|
110
|
+
// Collect all IDs to delete (including descendants) in a first pass
|
|
111
|
+
// This avoids issues with recursive calls during state mutation
|
|
112
|
+
const allIdsToDelete = new Set();
|
|
113
|
+
const collectDescendants = (id) => {
|
|
114
|
+
const node = nextNodes[id];
|
|
115
|
+
if (!node)
|
|
116
|
+
return;
|
|
117
|
+
allIdsToDelete.add(id);
|
|
118
|
+
if ('children' in node && node.children) {
|
|
119
|
+
for (const childId of node.children) {
|
|
120
|
+
collectDescendants(childId);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
};
|
|
92
124
|
for (const id of ids) {
|
|
125
|
+
collectDescendants(id);
|
|
126
|
+
}
|
|
127
|
+
// Now process all nodes for deletion
|
|
128
|
+
for (const id of allIdsToDelete) {
|
|
93
129
|
const node = nextNodes[id];
|
|
94
130
|
if (!node)
|
|
95
131
|
continue;
|
|
@@ -118,11 +154,6 @@ export const deleteNodesAction = (set, get, ids) => {
|
|
|
118
154
|
}
|
|
119
155
|
// 4. Delete the node itself
|
|
120
156
|
delete nextNodes[id];
|
|
121
|
-
// Inside the deleteNodes loop
|
|
122
|
-
if ('children' in node && node.children.length > 0) {
|
|
123
|
-
// Recursively delete all children first
|
|
124
|
-
get().deleteNodes(node.children);
|
|
125
|
-
}
|
|
126
157
|
}
|
|
127
158
|
return { nodes: nextNodes, rootNodeIds: nextRootIds, collections: nextCollections };
|
|
128
159
|
});
|
|
@@ -36,5 +36,10 @@ type UseSceneStore = UseBoundStore<StoreApi<SceneState>> & {
|
|
|
36
36
|
};
|
|
37
37
|
declare const useScene: UseSceneStore;
|
|
38
38
|
export default useScene;
|
|
39
|
+
/**
|
|
40
|
+
* Clears temporal history tracking variables to prevent memory leaks.
|
|
41
|
+
* Should be called when unloading a scene to release node references.
|
|
42
|
+
*/
|
|
43
|
+
export declare function clearTemporalTracking(): void;
|
|
39
44
|
export declare function clearSceneHistory(): void;
|
|
40
45
|
//# sourceMappingURL=use-scene.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-scene.d.ts","sourceRoot":"","sources":["../../src/store/use-scene.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAE1C,OAAO,EAAU,KAAK,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,SAAS,CAAA;AAEnE,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAIrE,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AA8CzD,MAAM,MAAM,UAAU,GAAG;IAEvB,KAAK,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;IAGjC,WAAW,EAAE,SAAS,EAAE,CAAA;IAGxB,UAAU,EAAE,GAAG,CAAC,SAAS,CAAC,CAAA;IAG1B,WAAW,EAAE,MAAM,CAAC,YAAY,EAAE,UAAU,CAAC,CAAA;IAG7C,SAAS,EAAE,MAAM,IAAI,CAAA;IACrB,UAAU,EAAE,MAAM,IAAI,CAAA;IACtB,WAAW,EAAE,MAAM,IAAI,CAAA;IACvB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,WAAW,EAAE,SAAS,EAAE,KAAK,IAAI,CAAA;IAE/E,SAAS,EAAE,CAAC,EAAE,EAAE,SAAS,KAAK,IAAI,CAAA;IAClC,UAAU,EAAE,CAAC,EAAE,EAAE,SAAS,KAAK,IAAI,CAAA;IAEnC,UAAU,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,SAAS,KAAK,IAAI,CAAA;IACzD,WAAW,EAAE,CAAC,GAAG,EAAE;QAAE,IAAI,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,SAAS,CAAA;KAAE,EAAE,KAAK,IAAI,CAAA;IAErE,UAAU,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,IAAI,CAAA;IAC3D,WAAW,EAAE,CAAC,OAAO,EAAE;QAAE,EAAE,EAAE,SAAS,CAAC;QAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;KAAE,EAAE,KAAK,IAAI,CAAA;IAE3E,UAAU,EAAE,CAAC,EAAE,EAAE,SAAS,KAAK,IAAI,CAAA;IACnC,WAAW,EAAE,CAAC,GAAG,EAAE,SAAS,EAAE,KAAK,IAAI,CAAA;IAGvC,gBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,EAAE,KAAK,YAAY,CAAA;IACvE,gBAAgB,EAAE,CAAC,EAAE,EAAE,YAAY,KAAK,IAAI,CAAA;IAC5C,gBAAgB,EAAE,CAAC,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,KAAK,IAAI,CAAA;IACnF,eAAe,EAAE,CAAC,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,KAAK,IAAI,CAAA;IAC9D,oBAAoB,EAAE,CAAC,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,KAAK,IAAI,CAAA;CACpE,CAAA;AAID,KAAK,aAAa,GAAG,aAAa,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,GAAG;IACzD,QAAQ,EAAE,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,GAAG,aAAa,GAAG,aAAa,CAAC,CAAC,CAAC,CAAA;CAC7F,CAAA;AAED,QAAA,MAAM,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"use-scene.d.ts","sourceRoot":"","sources":["../../src/store/use-scene.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAE1C,OAAO,EAAU,KAAK,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,SAAS,CAAA;AAEnE,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAIrE,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AA8CzD,MAAM,MAAM,UAAU,GAAG;IAEvB,KAAK,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;IAGjC,WAAW,EAAE,SAAS,EAAE,CAAA;IAGxB,UAAU,EAAE,GAAG,CAAC,SAAS,CAAC,CAAA;IAG1B,WAAW,EAAE,MAAM,CAAC,YAAY,EAAE,UAAU,CAAC,CAAA;IAG7C,SAAS,EAAE,MAAM,IAAI,CAAA;IACrB,UAAU,EAAE,MAAM,IAAI,CAAA;IACtB,WAAW,EAAE,MAAM,IAAI,CAAA;IACvB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,WAAW,EAAE,SAAS,EAAE,KAAK,IAAI,CAAA;IAE/E,SAAS,EAAE,CAAC,EAAE,EAAE,SAAS,KAAK,IAAI,CAAA;IAClC,UAAU,EAAE,CAAC,EAAE,EAAE,SAAS,KAAK,IAAI,CAAA;IAEnC,UAAU,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,SAAS,KAAK,IAAI,CAAA;IACzD,WAAW,EAAE,CAAC,GAAG,EAAE;QAAE,IAAI,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,SAAS,CAAA;KAAE,EAAE,KAAK,IAAI,CAAA;IAErE,UAAU,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,IAAI,CAAA;IAC3D,WAAW,EAAE,CAAC,OAAO,EAAE;QAAE,EAAE,EAAE,SAAS,CAAC;QAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;KAAE,EAAE,KAAK,IAAI,CAAA;IAE3E,UAAU,EAAE,CAAC,EAAE,EAAE,SAAS,KAAK,IAAI,CAAA;IACnC,WAAW,EAAE,CAAC,GAAG,EAAE,SAAS,EAAE,KAAK,IAAI,CAAA;IAGvC,gBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,EAAE,KAAK,YAAY,CAAA;IACvE,gBAAgB,EAAE,CAAC,EAAE,EAAE,YAAY,KAAK,IAAI,CAAA;IAC5C,gBAAgB,EAAE,CAAC,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,KAAK,IAAI,CAAA;IACnF,eAAe,EAAE,CAAC,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,KAAK,IAAI,CAAA;IAC9D,oBAAoB,EAAE,CAAC,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,KAAK,IAAI,CAAA;CACpE,CAAA;AAID,KAAK,aAAa,GAAG,aAAa,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,GAAG;IACzD,QAAQ,EAAE,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,GAAG,aAAa,GAAG,aAAa,CAAC,CAAC,CAAC,CAAA;CAC7F,CAAA;AAED,QAAA,MAAM,QAAQ,EAAE,aA2Mf,CAAA;AAED,eAAe,QAAQ,CAAA;AAOvB;;;GAGG;AACH,wBAAgB,qBAAqB,SAIpC;AAED,wBAAgB,iBAAiB,SAGhC"}
|
package/dist/store/use-scene.js
CHANGED
|
@@ -56,6 +56,10 @@ const useScene = create()(temporal((set, get) => ({
|
|
|
56
56
|
// 4. Collections
|
|
57
57
|
collections: {},
|
|
58
58
|
unloadScene: () => {
|
|
59
|
+
// Clear temporal tracking to prevent memory leaks from stale node references
|
|
60
|
+
prevPastLength = 0;
|
|
61
|
+
prevFutureLength = 0;
|
|
62
|
+
prevNodesSnapshot = null;
|
|
59
63
|
set({
|
|
60
64
|
nodes: {},
|
|
61
65
|
rootNodeIds: [],
|
|
@@ -74,6 +78,7 @@ const useScene = create()(temporal((set, get) => ({
|
|
|
74
78
|
nodes: patchedNodes,
|
|
75
79
|
rootNodeIds,
|
|
76
80
|
dirtyNodes: new Set(),
|
|
81
|
+
collections: {},
|
|
77
82
|
});
|
|
78
83
|
// Mark all nodes as dirty to trigger re-validation
|
|
79
84
|
Object.values(patchedNodes).forEach((node) => {
|
|
@@ -222,12 +227,19 @@ export default useScene;
|
|
|
222
227
|
let prevPastLength = 0;
|
|
223
228
|
let prevFutureLength = 0;
|
|
224
229
|
let prevNodesSnapshot = null;
|
|
225
|
-
|
|
226
|
-
|
|
230
|
+
/**
|
|
231
|
+
* Clears temporal history tracking variables to prevent memory leaks.
|
|
232
|
+
* Should be called when unloading a scene to release node references.
|
|
233
|
+
*/
|
|
234
|
+
export function clearTemporalTracking() {
|
|
227
235
|
prevPastLength = 0;
|
|
228
236
|
prevFutureLength = 0;
|
|
229
237
|
prevNodesSnapshot = null;
|
|
230
238
|
}
|
|
239
|
+
export function clearSceneHistory() {
|
|
240
|
+
useScene.temporal.getState().clear();
|
|
241
|
+
clearTemporalTracking();
|
|
242
|
+
}
|
|
231
243
|
// Subscribe to the temporal store (Undo/Redo events)
|
|
232
244
|
useScene.temporal.subscribe((state) => {
|
|
233
245
|
const currentPastLength = state.pastStates.length;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wall-system.d.ts","sourceRoot":"","sources":["../../../src/systems/wall/wall-system.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAM9B,OAAO,KAAK,EAAE,OAAO,EAAa,QAAQ,EAAE,MAAM,cAAc,CAAA;AAGhE,OAAO,EAIL,KAAK,aAAa,EACnB,MAAM,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"wall-system.d.ts","sourceRoot":"","sources":["../../../src/systems/wall/wall-system.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAM9B,OAAO,KAAK,EAAE,OAAO,EAAa,QAAQ,EAAE,MAAM,cAAc,CAAA;AAGhE,OAAO,EAIL,KAAK,aAAa,EACnB,MAAM,iBAAiB,CAAA;AASxB,eAAO,MAAM,UAAU,YAsDtB,CAAA;AA0DD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,QAAQ,EAClB,aAAa,EAAE,OAAO,EAAE,EACxB,SAAS,EAAE,aAAa,EACxB,aAAa,SAAI,oFA+FlB"}
|
|
@@ -13,7 +13,6 @@ const csgEvaluator = new Evaluator();
|
|
|
13
13
|
// ============================================================================
|
|
14
14
|
// WALL SYSTEM
|
|
15
15
|
// ============================================================================
|
|
16
|
-
let useFrameNb = 0;
|
|
17
16
|
export const WallSystem = () => {
|
|
18
17
|
const dirtyNodes = useScene((state) => state.dirtyNodes);
|
|
19
18
|
const clearDirty = useScene((state) => state.clearDirty);
|
|
@@ -23,7 +22,6 @@ export const WallSystem = () => {
|
|
|
23
22
|
const nodes = useScene.getState().nodes;
|
|
24
23
|
// Collect dirty walls and their levels
|
|
25
24
|
const dirtyWallsByLevel = new Map();
|
|
26
|
-
useFrameNb += 1;
|
|
27
25
|
dirtyNodes.forEach((id) => {
|
|
28
26
|
const node = nodes[id];
|
|
29
27
|
if (!node || node.type !== 'wall')
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { AnyNode, AnyNodeId } from '../schema';
|
|
2
|
+
import type { Collection, CollectionId } from '../schema/collections';
|
|
3
|
+
export type SceneGraph = {
|
|
4
|
+
nodes: Record<AnyNodeId, AnyNode>;
|
|
5
|
+
rootNodeIds: AnyNodeId[];
|
|
6
|
+
collections?: Record<CollectionId, Collection>;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Deep clones a scene graph with all node IDs regenerated while preserving
|
|
10
|
+
* parent-child relationships and other internal references.
|
|
11
|
+
*
|
|
12
|
+
* This is useful for:
|
|
13
|
+
* - Copying nodes between different projects
|
|
14
|
+
* - Duplicating a subset of a scene within the same project
|
|
15
|
+
* - Multi-scene in-memory scenarios
|
|
16
|
+
*/
|
|
17
|
+
export declare function cloneSceneGraph(sceneGraph: SceneGraph): SceneGraph;
|
|
18
|
+
//# sourceMappingURL=clone-scene-graph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clone-scene-graph.d.ts","sourceRoot":"","sources":["../../src/utils/clone-scene-graph.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAEnD,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAErE,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;IACjC,WAAW,EAAE,SAAS,EAAE,CAAA;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC,YAAY,EAAE,UAAU,CAAC,CAAA;CAC/C,CAAA;AAUD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,UAAU,GAAG,UAAU,CA4FlE"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { generateId } from '../schema/base';
|
|
2
|
+
/**
|
|
3
|
+
* Extracts the type prefix from a node ID (e.g., "wall_abc123" -> "wall")
|
|
4
|
+
*/
|
|
5
|
+
function extractIdPrefix(id) {
|
|
6
|
+
const underscoreIndex = id.indexOf('_');
|
|
7
|
+
return underscoreIndex === -1 ? 'node' : id.slice(0, underscoreIndex);
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Deep clones a scene graph with all node IDs regenerated while preserving
|
|
11
|
+
* parent-child relationships and other internal references.
|
|
12
|
+
*
|
|
13
|
+
* This is useful for:
|
|
14
|
+
* - Copying nodes between different projects
|
|
15
|
+
* - Duplicating a subset of a scene within the same project
|
|
16
|
+
* - Multi-scene in-memory scenarios
|
|
17
|
+
*/
|
|
18
|
+
export function cloneSceneGraph(sceneGraph) {
|
|
19
|
+
const { nodes, rootNodeIds, collections } = sceneGraph;
|
|
20
|
+
// Build ID mapping: old ID -> new ID
|
|
21
|
+
const idMap = new Map();
|
|
22
|
+
// Pass 1: Generate new IDs for all nodes
|
|
23
|
+
for (const nodeId of Object.keys(nodes)) {
|
|
24
|
+
const prefix = extractIdPrefix(nodeId);
|
|
25
|
+
idMap.set(nodeId, generateId(prefix));
|
|
26
|
+
}
|
|
27
|
+
// Pass 2: Deep clone nodes with remapped references
|
|
28
|
+
const clonedNodes = {};
|
|
29
|
+
for (const [oldId, node] of Object.entries(nodes)) {
|
|
30
|
+
const newId = idMap.get(oldId);
|
|
31
|
+
// structuredClone to avoid shared references between original and clone
|
|
32
|
+
const clonedNode = structuredClone({ ...node, id: newId });
|
|
33
|
+
// Remap parentId
|
|
34
|
+
if (clonedNode.parentId && typeof clonedNode.parentId === 'string') {
|
|
35
|
+
clonedNode.parentId = (idMap.get(clonedNode.parentId) ?? null);
|
|
36
|
+
}
|
|
37
|
+
// Remap children array (walls, levels, buildings, sites, items can have children)
|
|
38
|
+
if ('children' in clonedNode && Array.isArray(clonedNode.children)) {
|
|
39
|
+
;
|
|
40
|
+
clonedNode.children = clonedNode.children
|
|
41
|
+
.map((childId) => idMap.get(childId))
|
|
42
|
+
.filter((id) => id !== undefined);
|
|
43
|
+
}
|
|
44
|
+
// Remap wallId (items/doors/windows attached to walls)
|
|
45
|
+
if ('wallId' in clonedNode && typeof clonedNode.wallId === 'string') {
|
|
46
|
+
;
|
|
47
|
+
clonedNode.wallId = idMap.get(clonedNode.wallId);
|
|
48
|
+
}
|
|
49
|
+
clonedNodes[newId] = clonedNode;
|
|
50
|
+
}
|
|
51
|
+
// Remap root node IDs
|
|
52
|
+
const clonedRootNodeIds = rootNodeIds
|
|
53
|
+
.map((id) => idMap.get(id))
|
|
54
|
+
.filter((id) => id !== undefined);
|
|
55
|
+
// Clone and remap collections if present
|
|
56
|
+
let clonedCollections;
|
|
57
|
+
if (collections) {
|
|
58
|
+
clonedCollections = {};
|
|
59
|
+
const collectionIdMap = new Map();
|
|
60
|
+
// Generate new collection IDs
|
|
61
|
+
for (const collectionId of Object.keys(collections)) {
|
|
62
|
+
collectionIdMap.set(collectionId, generateId('collection'));
|
|
63
|
+
}
|
|
64
|
+
for (const [oldCollectionId, collection] of Object.entries(collections)) {
|
|
65
|
+
const newCollectionId = collectionIdMap.get(oldCollectionId);
|
|
66
|
+
clonedCollections[newCollectionId] = {
|
|
67
|
+
...collection,
|
|
68
|
+
id: newCollectionId,
|
|
69
|
+
nodeIds: collection.nodeIds
|
|
70
|
+
.map((nodeId) => idMap.get(nodeId))
|
|
71
|
+
.filter((id) => id !== undefined),
|
|
72
|
+
controlNodeId: collection.controlNodeId
|
|
73
|
+
? idMap.get(collection.controlNodeId)
|
|
74
|
+
: undefined,
|
|
75
|
+
};
|
|
76
|
+
// Update collectionIds on nodes that reference this collection
|
|
77
|
+
for (const oldNodeId of collection.nodeIds) {
|
|
78
|
+
const newNodeId = idMap.get(oldNodeId);
|
|
79
|
+
if (newNodeId && clonedNodes[newNodeId]) {
|
|
80
|
+
const node = clonedNodes[newNodeId];
|
|
81
|
+
if ('collectionIds' in node && Array.isArray(node.collectionIds)) {
|
|
82
|
+
const oldColIds = node.collectionIds;
|
|
83
|
+
node.collectionIds = oldColIds
|
|
84
|
+
.map((cid) => collectionIdMap.get(cid))
|
|
85
|
+
.filter((id) => id !== undefined);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
nodes: clonedNodes,
|
|
93
|
+
rootNodeIds: clonedRootNodeIds,
|
|
94
|
+
...(clonedCollections && { collections: clonedCollections }),
|
|
95
|
+
};
|
|
96
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pascal-app/core",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "Core library for Pascal 3D building editor",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"@react-three/drei": "^10",
|
|
26
26
|
"@react-three/fiber": "^9",
|
|
27
27
|
"react": "^18 || ^19",
|
|
28
|
-
"three": "^0.
|
|
28
|
+
"three": "^0.182"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"dedent": "^1.7.1",
|