@pascal-app/core 0.5.1 → 0.7.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 (134) hide show
  1. package/dist/events/bus.d.ts +74 -4
  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/hooks/spatial-grid/spatial-grid.d.ts +2 -0
  10. package/dist/hooks/spatial-grid/spatial-grid.d.ts.map +1 -1
  11. package/dist/hooks/spatial-grid/spatial-grid.js +43 -20
  12. package/dist/index.d.ts +9 -13
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +7 -11
  15. package/dist/lib/door-operation.d.ts +7 -0
  16. package/dist/lib/door-operation.d.ts.map +1 -0
  17. package/dist/lib/door-operation.js +25 -0
  18. package/dist/lib/polygon-geometry.d.ts +3 -0
  19. package/dist/lib/polygon-geometry.d.ts.map +1 -0
  20. package/dist/lib/polygon-geometry.js +90 -0
  21. package/dist/lib/slab-polygon.d.ts +3 -0
  22. package/dist/lib/slab-polygon.d.ts.map +1 -0
  23. package/dist/lib/slab-polygon.js +58 -0
  24. package/dist/lib/space-detection.d.ts +10 -17
  25. package/dist/lib/space-detection.d.ts.map +1 -1
  26. package/dist/lib/space-detection.js +666 -453
  27. package/dist/material-library.d.ts +20 -0
  28. package/dist/material-library.d.ts.map +1 -0
  29. package/dist/material-library.js +580 -0
  30. package/dist/schema/asset-url.d.ts +34 -0
  31. package/dist/schema/asset-url.d.ts.map +1 -0
  32. package/dist/schema/asset-url.js +79 -0
  33. package/dist/schema/asset-url.test.d.ts +2 -0
  34. package/dist/schema/asset-url.test.d.ts.map +1 -0
  35. package/dist/schema/asset-url.test.js +138 -0
  36. package/dist/schema/index.d.ts +14 -7
  37. package/dist/schema/index.d.ts.map +1 -1
  38. package/dist/schema/index.js +10 -7
  39. package/dist/schema/material.d.ts +112 -2
  40. package/dist/schema/material.d.ts.map +1 -1
  41. package/dist/schema/material.js +55 -1
  42. package/dist/schema/nodes/ceiling.d.ts +11 -1
  43. package/dist/schema/nodes/ceiling.d.ts.map +1 -1
  44. package/dist/schema/nodes/ceiling.js +6 -0
  45. package/dist/schema/nodes/column.d.ts +520 -0
  46. package/dist/schema/nodes/column.d.ts.map +1 -0
  47. package/dist/schema/nodes/column.js +385 -0
  48. package/dist/schema/nodes/door.d.ts +74 -1
  49. package/dist/schema/nodes/door.d.ts.map +1 -1
  50. package/dist/schema/nodes/door.js +39 -2
  51. package/dist/schema/nodes/fence.d.ts +34 -0
  52. package/dist/schema/nodes/fence.d.ts.map +1 -1
  53. package/dist/schema/nodes/fence.js +5 -0
  54. package/dist/schema/nodes/guide.d.ts +17 -0
  55. package/dist/schema/nodes/guide.d.ts.map +1 -1
  56. package/dist/schema/nodes/guide.js +11 -1
  57. package/dist/schema/nodes/item.d.ts +10 -2
  58. package/dist/schema/nodes/item.d.ts.map +1 -1
  59. package/dist/schema/nodes/item.js +18 -1
  60. package/dist/schema/nodes/level.d.ts +1 -1
  61. package/dist/schema/nodes/level.d.ts.map +1 -1
  62. package/dist/schema/nodes/level.js +6 -0
  63. package/dist/schema/nodes/roof-segment.d.ts +3 -1
  64. package/dist/schema/nodes/roof-segment.d.ts.map +1 -1
  65. package/dist/schema/nodes/roof-segment.js +1 -0
  66. package/dist/schema/nodes/roof.d.ts +108 -0
  67. package/dist/schema/nodes/roof.d.ts.map +1 -1
  68. package/dist/schema/nodes/roof.js +58 -2
  69. package/dist/schema/nodes/scan.d.ts.map +1 -1
  70. package/dist/schema/nodes/scan.js +2 -1
  71. package/dist/schema/nodes/site.d.ts +2 -1
  72. package/dist/schema/nodes/site.d.ts.map +1 -1
  73. package/dist/schema/nodes/slab.d.ts +11 -1
  74. package/dist/schema/nodes/slab.d.ts.map +1 -1
  75. package/dist/schema/nodes/slab.js +7 -0
  76. package/dist/schema/nodes/spawn.d.ts +24 -0
  77. package/dist/schema/nodes/spawn.d.ts.map +1 -0
  78. package/dist/schema/nodes/spawn.js +8 -0
  79. package/dist/schema/nodes/stair-segment.d.ts +3 -1
  80. package/dist/schema/nodes/stair-segment.d.ts.map +1 -1
  81. package/dist/schema/nodes/stair-segment.js +1 -0
  82. package/dist/schema/nodes/stair.d.ts +122 -2
  83. package/dist/schema/nodes/stair.d.ts.map +1 -1
  84. package/dist/schema/nodes/stair.js +72 -2
  85. package/dist/schema/nodes/surface-hole-metadata.d.ts +10 -0
  86. package/dist/schema/nodes/surface-hole-metadata.d.ts.map +1 -0
  87. package/dist/schema/nodes/surface-hole-metadata.js +5 -0
  88. package/dist/schema/nodes/wall.d.ts +87 -1
  89. package/dist/schema/nodes/wall.d.ts.map +1 -1
  90. package/dist/schema/nodes/wall.js +45 -4
  91. package/dist/schema/nodes/window.d.ts +57 -1
  92. package/dist/schema/nodes/window.d.ts.map +1 -1
  93. package/dist/schema/nodes/window.js +29 -0
  94. package/dist/schema/types.d.ts +653 -12
  95. package/dist/schema/types.d.ts.map +1 -1
  96. package/dist/schema/types.js +4 -0
  97. package/dist/store/actions/node-actions.d.ts +1 -1
  98. package/dist/store/actions/node-actions.d.ts.map +1 -1
  99. package/dist/store/actions/node-actions.js +181 -5
  100. package/dist/store/history-control.d.ts +14 -0
  101. package/dist/store/history-control.d.ts.map +1 -0
  102. package/dist/store/history-control.js +22 -0
  103. package/dist/store/use-interactive.d.ts +43 -0
  104. package/dist/store/use-interactive.d.ts.map +1 -1
  105. package/dist/store/use-interactive.js +66 -0
  106. package/dist/store/use-scene.d.ts.map +1 -1
  107. package/dist/store/use-scene.js +307 -3
  108. package/dist/systems/ceiling/ceiling-system.d.ts.map +1 -1
  109. package/dist/systems/ceiling/ceiling-system.js +7 -0
  110. package/dist/systems/fence/fence-system.d.ts.map +1 -1
  111. package/dist/systems/fence/fence-system.js +106 -39
  112. package/dist/systems/roof/roof-system.d.ts.map +1 -1
  113. package/dist/systems/roof/roof-system.js +31 -1
  114. package/dist/systems/slab/slab-system.d.ts.map +1 -1
  115. package/dist/systems/slab/slab-system.js +45 -8
  116. package/dist/systems/stair/stair-opening-sync.d.ts +6 -0
  117. package/dist/systems/stair/stair-opening-sync.d.ts.map +1 -0
  118. package/dist/systems/stair/stair-opening-sync.js +576 -0
  119. package/dist/systems/stair/stair-opening-sync.test.d.ts +2 -0
  120. package/dist/systems/stair/stair-opening-sync.test.d.ts.map +1 -0
  121. package/dist/systems/stair/stair-opening-sync.test.js +65 -0
  122. package/dist/systems/stair/stair-system.d.ts.map +1 -1
  123. package/dist/systems/stair/stair-system.js +119 -2
  124. package/dist/systems/wall/wall-curve.d.ts +43 -0
  125. package/dist/systems/wall/wall-curve.d.ts.map +1 -0
  126. package/dist/systems/wall/wall-curve.js +176 -0
  127. package/dist/systems/wall/wall-footprint.d.ts.map +1 -1
  128. package/dist/systems/wall/wall-footprint.js +16 -2
  129. package/dist/systems/wall/wall-mitering.d.ts +7 -0
  130. package/dist/systems/wall/wall-mitering.d.ts.map +1 -1
  131. package/dist/systems/wall/wall-mitering.js +76 -3
  132. package/dist/systems/wall/wall-system.d.ts.map +1 -1
  133. package/dist/systems/wall/wall-system.js +202 -2
  134. package/package.json +33 -5
@@ -1,13 +1,15 @@
1
1
  import type { ThreeEvent } from '@react-three/fiber';
2
- import type { BuildingNode, CeilingNode, DoorNode, FenceNode, ItemNode, LevelNode, RoofNode, RoofSegmentNode, SiteNode, SlabNode, StairNode, StairSegmentNode, WallNode, WindowNode, ZoneNode } from '../schema';
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
4
  import type { AnyNode } from '../schema/types';
4
5
  export interface GridEvent {
5
6
  /** World-space intersection point on the grid plane. */
6
7
  position: [number, number, number];
7
8
  /**
8
- * Building-local intersection point relative to the currently selected building.
9
+ * Building-local intersection point, relative to the currently selected building.
9
10
  * Equals `position` when no building is selected.
10
- * Use this for placing/committing anything that lives inside a building (walls, slabs, items, etc.).
11
+ * Use this for placing or committing anything that lives inside a building
12
+ * (walls, slabs, items, etc.).
11
13
  */
12
14
  localPosition: [number, number, number];
13
15
  nativeEvent: ThreeEvent<PointerEvent>;
@@ -17,6 +19,8 @@ export interface NodeEvent<T extends AnyNode = AnyNode> {
17
19
  position: [number, number, number];
18
20
  localPosition: [number, number, number];
19
21
  normal?: [number, number, number];
22
+ faceIndex?: number;
23
+ object: Object3D;
20
24
  stopPropagation: () => void;
21
25
  nativeEvent: ThreeEvent<PointerEvent>;
22
26
  }
@@ -28,7 +32,9 @@ export type BuildingEvent = NodeEvent<BuildingNode>;
28
32
  export type LevelEvent = NodeEvent<LevelNode>;
29
33
  export type ZoneEvent = NodeEvent<ZoneNode>;
30
34
  export type SlabEvent = NodeEvent<SlabNode>;
35
+ export type SpawnEvent = NodeEvent<SpawnNode>;
31
36
  export type CeilingEvent = NodeEvent<CeilingNode>;
37
+ export type ColumnEvent = NodeEvent<ColumnNode>;
32
38
  export type RoofEvent = NodeEvent<RoofNode>;
33
39
  export type RoofSegmentEvent = NodeEvent<RoofSegmentNode>;
34
40
  export type StairEvent = NodeEvent<StairNode>;
@@ -48,6 +54,32 @@ export interface CameraControlEvent {
48
54
  }
49
55
  export interface ThumbnailGenerateEvent {
50
56
  projectId: string;
57
+ captureMode?: 'standard' | 'viewport' | 'area';
58
+ cropRegion?: {
59
+ x: number;
60
+ y: number;
61
+ width: number;
62
+ height: number;
63
+ };
64
+ /**
65
+ * When true, snap levels to their true positions before capturing (for a
66
+ * consistent auto-thumbnail angle) and defer the capture if the tab is
67
+ * hidden, the background auto-save path. Omit for user-driven captures
68
+ * that should fire immediately from the current camera pose.
69
+ */
70
+ snapLevels?: boolean;
71
+ }
72
+ export interface CameraControlFitSceneEvent {
73
+ /**
74
+ * XZ-plane axis-aligned bounds for camera framing. Omitted values let the
75
+ * listener choose its default framing pose.
76
+ */
77
+ bounds?: {
78
+ min: [number, number];
79
+ max: [number, number];
80
+ center: [number, number];
81
+ size: [number, number];
82
+ };
51
83
  }
52
84
  type CameraControlEvents = {
53
85
  'camera-controls:view': CameraControlEvent;
@@ -56,11 +88,33 @@ type CameraControlEvents = {
56
88
  'camera-controls:top-view': undefined;
57
89
  'camera-controls:orbit-cw': undefined;
58
90
  'camera-controls:orbit-ccw': undefined;
91
+ 'camera-controls:fit-scene': CameraControlFitSceneEvent;
59
92
  'camera-controls:generate-thumbnail': ThumbnailGenerateEvent;
60
93
  };
61
94
  type ToolEvents = {
62
95
  'tool:cancel': undefined;
63
96
  };
97
+ type GuideEvents = {
98
+ 'guide:set-reference-scale': {
99
+ guideId: GuideNode['id'];
100
+ };
101
+ 'guide:cancel-reference-scale': undefined;
102
+ 'guide:deleted': {
103
+ guideId: GuideNode['id'];
104
+ };
105
+ };
106
+ type DoorAnimationEvents = {
107
+ 'door:animation-completed': {
108
+ doorId: DoorNode['id'];
109
+ field: 'operationState' | 'swingAngle';
110
+ };
111
+ };
112
+ type WindowAnimationEvents = {
113
+ 'window:animation-completed': {
114
+ windowId: WindowNode['id'];
115
+ field: 'operationState';
116
+ };
117
+ };
64
118
  type PresetEvents = {
65
119
  'preset:generate-thumbnail': {
66
120
  presetId: string;
@@ -75,7 +129,23 @@ type ThumbnailEvents = {
75
129
  'thumbnail:before-capture': undefined;
76
130
  'thumbnail:after-capture': undefined;
77
131
  };
78
- 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<'ceiling', CeilingEvent> & NodeEvents<'roof', RoofEvent> & NodeEvents<'roof-segment', RoofSegmentEvent> & NodeEvents<'stair', StairEvent> & NodeEvents<'stair-segment', StairSegmentEvent> & NodeEvents<'window', WindowEvent> & NodeEvents<'door', DoorEvent> & CameraControlEvents & ToolEvents & PresetEvents & ThumbnailEvents;
132
+ type SnapshotEvents = {
133
+ 'snapshot:saved': undefined;
134
+ 'camera:go-to-position': {
135
+ position: [number, number, number];
136
+ target: [number, number, number];
137
+ };
138
+ };
139
+ type AIChatEvents = {
140
+ 'ai-chat:attach-images': {
141
+ images: {
142
+ url: string;
143
+ name: string;
144
+ kind: 'snapshot' | 'render';
145
+ }[];
146
+ };
147
+ };
148
+ 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;
79
149
  export declare const emitter: import("mitt").Emitter<EditorEvents>;
80
150
  export {};
81
151
  //# 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":"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"}
@@ -1,5 +1,5 @@
1
1
  import mitt from 'mitt';
2
- // Event suffixes - exported for use in hooks
2
+ // Event suffixes, exported for use in hooks
3
3
  export const eventSuffixes = [
4
4
  'click',
5
5
  'move',
@@ -5,11 +5,13 @@ export declare const sceneRegistry: {
5
5
  site: Set<string>;
6
6
  building: Set<string>;
7
7
  ceiling: Set<string>;
8
+ column: Set<string>;
8
9
  level: Set<string>;
9
10
  wall: Set<string>;
10
11
  fence: Set<string>;
11
12
  item: Set<string>;
12
13
  slab: Set<string>;
14
+ spawn: Set<string>;
13
15
  zone: Set<string>;
14
16
  roof: Set<string>;
15
17
  'roof-segment': Set<string>;
@@ -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;;;;;;;;;;;;;;;;;;;;;IA0BxB,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;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"}
@@ -9,11 +9,13 @@ export const sceneRegistry = {
9
9
  site: new Set(),
10
10
  building: new Set(),
11
11
  ceiling: new Set(),
12
+ column: new Set(),
12
13
  level: new Set(),
13
14
  wall: new Set(),
14
15
  fence: new Set(),
15
16
  item: new Set(),
16
17
  slab: new Set(),
18
+ spawn: new Set(),
17
19
  zone: new Set(),
18
20
  roof: new Set(),
19
21
  'roof-segment': new Set(),
@@ -1 +1 @@
1
- {"version":3,"file":"spatial-grid-manager.d.ts","sourceRoot":"","sources":["../../../src/hooks/spatial-grid/spatial-grid-manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"spatial-grid-manager.d.ts","sourceRoot":"","sources":["../../../src/hooks/spatial-grid/spatial-grid-manager.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
- import { getScaledDimensions } from '../../schema';
1
+ import { getScaledDimensions, isLowProfileItemSurface } from '../../schema';
2
+ import useScene from '../../store/use-scene';
2
3
  import { SpatialGrid } from './spatial-grid';
3
4
  import { WallSpatialGrid } from './wall-spatial-grid';
4
5
  // ============================================================================
@@ -37,6 +38,65 @@ function getItemFootprint(position, dimensions, rotation, inset = 0) {
37
38
  [x + (-halfW * cos - halfD * sin), z + (-halfW * sin + halfD * cos)],
38
39
  ];
39
40
  }
41
+ function getItemLocalBounds(item) {
42
+ const [width, height, depth] = getScaledDimensions(item);
43
+ const minZ = item.asset.attachTo === 'wall-side' ? -depth : -depth / 2;
44
+ const maxZ = item.asset.attachTo === 'wall-side' ? 0 : depth / 2;
45
+ return {
46
+ min: [-width / 2, 0, minZ],
47
+ max: [width / 2, height, maxZ],
48
+ };
49
+ }
50
+ function getItemParentAabb(item) {
51
+ const bounds = getItemLocalBounds(item);
52
+ const corners = [
53
+ [bounds.min[0], bounds.min[1], bounds.min[2]],
54
+ [bounds.min[0], bounds.min[1], bounds.max[2]],
55
+ [bounds.min[0], bounds.max[1], bounds.min[2]],
56
+ [bounds.min[0], bounds.max[1], bounds.max[2]],
57
+ [bounds.max[0], bounds.min[1], bounds.min[2]],
58
+ [bounds.max[0], bounds.min[1], bounds.max[2]],
59
+ [bounds.max[0], bounds.max[1], bounds.min[2]],
60
+ [bounds.max[0], bounds.max[1], bounds.max[2]],
61
+ ];
62
+ const yRot = item.rotation[1] ?? 0;
63
+ const cos = Math.cos(yRot);
64
+ const sin = Math.sin(yRot);
65
+ let minX = Number.POSITIVE_INFINITY;
66
+ let minY = Number.POSITIVE_INFINITY;
67
+ let minZ = Number.POSITIVE_INFINITY;
68
+ let maxX = Number.NEGATIVE_INFINITY;
69
+ let maxY = Number.NEGATIVE_INFINITY;
70
+ let maxZ = Number.NEGATIVE_INFINITY;
71
+ for (const [cx, cy, cz] of corners) {
72
+ const rotatedX = cx * cos + cz * sin;
73
+ const rotatedZ = -cx * sin + cz * cos;
74
+ const worldX = rotatedX + item.position[0];
75
+ const worldY = cy + item.position[1];
76
+ const worldZ = rotatedZ + item.position[2];
77
+ minX = Math.min(minX, worldX);
78
+ minY = Math.min(minY, worldY);
79
+ minZ = Math.min(minZ, worldZ);
80
+ maxX = Math.max(maxX, worldX);
81
+ maxY = Math.max(maxY, worldY);
82
+ maxZ = Math.max(maxZ, worldZ);
83
+ }
84
+ return { minX, maxX, minY, maxY, minZ, maxZ };
85
+ }
86
+ function intervalsOverlap(minA, maxA, minB, maxB, epsilon = 1e-4) {
87
+ return minA < maxB - epsilon && maxA > minB + epsilon;
88
+ }
89
+ function resolveNodeLevelId(node, nodes) {
90
+ if (node.type === 'level')
91
+ return node.id;
92
+ let current = node;
93
+ while (current) {
94
+ if (current.type === 'level')
95
+ return current.id;
96
+ current = current.parentId ? nodes[current.parentId] : undefined;
97
+ }
98
+ return 'default';
99
+ }
40
100
  /**
41
101
  * Test if two line segments (a1->a2) and (b1->b2) intersect.
42
102
  */
@@ -373,8 +433,40 @@ export class SpatialGridManager {
373
433
  }
374
434
  // Query methods
375
435
  canPlaceOnFloor(levelId, position, dimensions, rotation, ignoreIds) {
376
- const grid = this.getFloorGrid(levelId);
377
- return grid.canPlace(position, dimensions, rotation, ignoreIds);
436
+ const nodes = useScene.getState().nodes;
437
+ const ignoreSet = new Set(ignoreIds ?? []);
438
+ const [width, , depth] = dimensions;
439
+ const yRot = rotation[1];
440
+ const cos = Math.abs(Math.cos(yRot));
441
+ const sin = Math.abs(Math.sin(yRot));
442
+ const rotatedW = width * cos + depth * sin;
443
+ const rotatedD = width * sin + depth * cos;
444
+ const draftBounds = {
445
+ minX: position[0] - rotatedW / 2,
446
+ maxX: position[0] + rotatedW / 2,
447
+ minZ: position[2] - rotatedD / 2,
448
+ maxZ: position[2] + rotatedD / 2,
449
+ };
450
+ const conflicts = [];
451
+ for (const node of Object.values(nodes)) {
452
+ if (node.type !== 'item')
453
+ continue;
454
+ const item = node;
455
+ if (item.asset.attachTo)
456
+ continue;
457
+ if (isLowProfileItemSurface(item))
458
+ continue;
459
+ if (ignoreSet.has(item.id))
460
+ continue;
461
+ if (resolveNodeLevelId(item, nodes) !== levelId)
462
+ continue;
463
+ const bounds = getItemParentAabb(item);
464
+ if (intervalsOverlap(draftBounds.minX, draftBounds.maxX, bounds.minX, bounds.maxX) &&
465
+ intervalsOverlap(draftBounds.minZ, draftBounds.maxZ, bounds.minZ, bounds.maxZ)) {
466
+ conflicts.push(item.id);
467
+ }
468
+ }
469
+ return { valid: conflicts.length === 0, conflictIds: conflicts };
378
470
  }
379
471
  /**
380
472
  * Check if an item can be placed on a wall
@@ -396,7 +488,43 @@ export class SpatialGridManager {
396
488
  // Convert local X position to parametric t (0-1)
397
489
  const tCenter = localX / wallLength;
398
490
  const [itemWidth, itemHeight] = dimensions;
399
- return this.getWallGrid(levelId).canPlaceOnWall(wallId, wallLength, wallHeight, tCenter, itemWidth, localY, itemHeight, attachType, side, ignoreIds);
491
+ const baseResult = this.getWallGrid(levelId).canPlaceOnWall(wallId, wallLength, wallHeight, tCenter, itemWidth, localY, itemHeight, attachType, side, ignoreIds);
492
+ if (!baseResult.valid)
493
+ return baseResult;
494
+ const nodes = useScene.getState().nodes;
495
+ const ignoreSet = new Set(ignoreIds ?? []);
496
+ const draftBounds = {
497
+ minX: localX - itemWidth / 2,
498
+ maxX: localX + itemWidth / 2,
499
+ minY: baseResult.adjustedY,
500
+ maxY: baseResult.adjustedY + itemHeight,
501
+ };
502
+ const conflicts = [];
503
+ for (const node of Object.values(nodes)) {
504
+ if (node.type !== 'item')
505
+ continue;
506
+ const item = node;
507
+ if (!(item.asset.attachTo === 'wall' || item.asset.attachTo === 'wall-side'))
508
+ continue;
509
+ if (ignoreSet.has(item.id))
510
+ continue;
511
+ if (item.parentId !== wallId)
512
+ continue;
513
+ if (attachType === 'wall-side' && item.asset.attachTo === 'wall-side' && side && item.side) {
514
+ if (side !== item.side)
515
+ continue;
516
+ }
517
+ const bounds = getItemParentAabb(item);
518
+ if (intervalsOverlap(draftBounds.minX, draftBounds.maxX, bounds.minX, bounds.maxX) &&
519
+ intervalsOverlap(draftBounds.minY, draftBounds.maxY, bounds.minY, bounds.maxY)) {
520
+ conflicts.push(item.id);
521
+ }
522
+ }
523
+ return {
524
+ ...baseResult,
525
+ valid: conflicts.length === 0,
526
+ conflictIds: conflicts,
527
+ };
400
528
  }
401
529
  getWallForItem(levelId, itemId) {
402
530
  return this.getWallGrid(levelId).getWallForItem(itemId);
@@ -541,8 +669,38 @@ export class SpatialGridManager {
541
669
  return { valid: false, conflictIds: [] };
542
670
  }
543
671
  }
544
- // Check for overlaps with other ceiling items
545
- return this.getCeilingGrid(ceilingId).canPlace(position, dimensions, rotation, ignoreIds);
672
+ const nodes = useScene.getState().nodes;
673
+ const ignoreSet = new Set(ignoreIds ?? []);
674
+ const [width, , depth] = dimensions;
675
+ const yRot = rotation[1];
676
+ const cos = Math.abs(Math.cos(yRot));
677
+ const sin = Math.abs(Math.sin(yRot));
678
+ const rotatedW = width * cos + depth * sin;
679
+ const rotatedD = width * sin + depth * cos;
680
+ const draftBounds = {
681
+ minX: position[0] - rotatedW / 2,
682
+ maxX: position[0] + rotatedW / 2,
683
+ minZ: position[2] - rotatedD / 2,
684
+ maxZ: position[2] + rotatedD / 2,
685
+ };
686
+ const conflicts = [];
687
+ for (const node of Object.values(nodes)) {
688
+ if (node.type !== 'item')
689
+ continue;
690
+ const item = node;
691
+ if (item.asset.attachTo !== 'ceiling')
692
+ continue;
693
+ if (ignoreSet.has(item.id))
694
+ continue;
695
+ if (item.parentId !== ceilingId)
696
+ continue;
697
+ const bounds = getItemParentAabb(item);
698
+ if (intervalsOverlap(draftBounds.minX, draftBounds.maxX, bounds.minX, bounds.maxX) &&
699
+ intervalsOverlap(draftBounds.minZ, draftBounds.maxZ, bounds.minZ, bounds.maxZ)) {
700
+ conflicts.push(item.id);
701
+ }
702
+ }
703
+ return { valid: conflicts.length === 0, conflictIds: conflicts };
546
704
  }
547
705
  clearLevel(levelId) {
548
706
  this.floorGrids.delete(levelId);
@@ -4,10 +4,12 @@ interface SpatialGridConfig {
4
4
  export declare class SpatialGrid {
5
5
  private readonly cells;
6
6
  private readonly itemCells;
7
+ private readonly itemBounds;
7
8
  private readonly config;
8
9
  constructor(config: SpatialGridConfig);
9
10
  private posToCell;
10
11
  private cellKey;
12
+ private getAABB;
11
13
  private getItemCells;
12
14
  insert(itemId: string, position: [number, number, number], dimensions: [number, number, number], rotation: [number, number, number]): void;
13
15
  remove(itemId: string): void;
@@ -1 +1 @@
1
- {"version":3,"file":"spatial-grid.d.ts","sourceRoot":"","sources":["../../../src/hooks/spatial-grid/spatial-grid.ts"],"names":[],"mappings":"AAMA,UAAU,iBAAiB;IACzB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA+B;IACrD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAkC;IAE5D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;gBAE9B,MAAM,EAAE,iBAAiB;IAIrC,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,OAAO;IAKf,OAAO,CAAC,YAAY;IAsCpB,MAAM,CACJ,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAClC,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EACpC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;IAepC,MAAM,CAAC,MAAM,EAAE,MAAM;IAiBrB,MAAM,CACJ,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAClC,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EACpC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;IAOpC,QAAQ,CACN,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAClC,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EACpC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAClC,SAAS,GAAE,MAAM,EAAO,GACvB;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,WAAW,EAAE,MAAM,EAAE,CAAA;KAAE;IAuB5C,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE;IAkB3D,YAAY,IAAI,MAAM;CAGvB"}
1
+ {"version":3,"file":"spatial-grid.d.ts","sourceRoot":"","sources":["../../../src/hooks/spatial-grid/spatial-grid.ts"],"names":[],"mappings":"AAaA,UAAU,iBAAiB;IACzB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA+B;IACrD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAkC;IAC5D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAgC;IAE3D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;gBAE9B,MAAM,EAAE,iBAAiB;IAIrC,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,OAAO;IAKf,OAAO,CAAC,OAAO;IAuBf,OAAO,CAAC,YAAY;IAgBpB,MAAM,CACJ,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAClC,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EACpC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;IAiBpC,MAAM,CAAC,MAAM,EAAE,MAAM;IAkBrB,MAAM,CACJ,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAClC,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EACpC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;IASpC,QAAQ,CACN,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAClC,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EACpC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAClC,SAAS,GAAE,MAAM,EAAO,GACvB;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,WAAW,EAAE,MAAM,EAAE,CAAA;KAAE;IA0C5C,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE;IAkB3D,YAAY,IAAI,MAAM;CAGvB"}
@@ -1,6 +1,7 @@
1
1
  export class SpatialGrid {
2
2
  cells = new Map();
3
3
  itemCells = new Map(); // reverse lookup
4
+ itemBounds = new Map(); // actual AABB for narrow-phase
4
5
  config;
5
6
  constructor(config) {
6
7
  this.config = config;
@@ -11,27 +12,27 @@ export class SpatialGrid {
11
12
  cellKey(cx, cz) {
12
13
  return `${cx},${cz}`;
13
14
  }
14
- // Get all cells an item occupies based on its AABB
15
- getItemCells(position, dimensions, rotation) {
16
- // Simplified: axis-aligned bounding box
17
- // For full rotation support, compute rotated corners
15
+ // Compute the axis-aligned bounding box for a rotated item
16
+ getAABB(position, dimensions, rotation) {
18
17
  const [x, , z] = position;
19
18
  const [w, , d] = dimensions;
20
- const yRot = rotation[1]; // Y-axis rotation
21
- // Compute rotated footprint (simplified for 90° increments)
19
+ const yRot = rotation[1];
22
20
  const cos = Math.abs(Math.cos(yRot));
23
21
  const sin = Math.abs(Math.sin(yRot));
24
22
  const rotatedW = w * cos + d * sin;
25
23
  const rotatedD = w * sin + d * cos;
26
- const minX = x - rotatedW / 2;
27
- const maxX = x + rotatedW / 2;
28
- const minZ = z - rotatedD / 2;
29
- const maxZ = z + rotatedD / 2;
24
+ return {
25
+ minX: x - rotatedW / 2,
26
+ maxX: x + rotatedW / 2,
27
+ minZ: z - rotatedD / 2,
28
+ maxZ: z + rotatedD / 2,
29
+ };
30
+ }
31
+ // Get all cells an item occupies based on its AABB
32
+ getItemCells(bounds) {
33
+ const { minX, maxX, minZ, maxZ } = bounds;
30
34
  const [minCx, minCz] = this.posToCell(minX, minZ);
31
- // Use exclusive upper bound: subtract epsilon so exact boundaries don't overlap
32
- // This allows adjacent items (touching but not overlapping) to not conflict
33
- const epsilon = 1e-6;
34
- const [maxCx, maxCz] = this.posToCell(maxX - epsilon, maxZ - epsilon);
35
+ const [maxCx, maxCz] = this.posToCell(maxX, maxZ);
35
36
  const keys = [];
36
37
  for (let cx = minCx; cx <= maxCx; cx++) {
37
38
  for (let cz = minCz; cz <= maxCz; cz++) {
@@ -42,8 +43,10 @@ export class SpatialGrid {
42
43
  }
43
44
  // Register an item
44
45
  insert(itemId, position, dimensions, rotation) {
45
- const cellKeys = this.getItemCells(position, dimensions, rotation);
46
+ const bounds = this.getAABB(position, dimensions, rotation);
47
+ const cellKeys = this.getItemCells(bounds);
46
48
  this.itemCells.set(itemId, new Set(cellKeys));
49
+ this.itemBounds.set(itemId, bounds);
47
50
  for (const key of cellKeys) {
48
51
  if (!this.cells.has(key)) {
49
52
  this.cells.set(key, { itemIds: new Set() });
@@ -66,6 +69,7 @@ export class SpatialGrid {
66
69
  }
67
70
  }
68
71
  this.itemCells.delete(itemId);
72
+ this.itemBounds.delete(itemId);
69
73
  }
70
74
  // Update = remove + insert
71
75
  update(itemId, position, dimensions, rotation) {
@@ -73,23 +77,42 @@ export class SpatialGrid {
73
77
  this.insert(itemId, position, dimensions, rotation);
74
78
  }
75
79
  // Query: is this placement valid?
80
+ // Uses cells as broad-phase, then checks actual AABB overlap (narrow-phase)
81
+ // to avoid false positives when adjacent items share a cell but don't overlap.
76
82
  canPlace(position, dimensions, rotation, ignoreIds = []) {
77
- const cellKeys = this.getItemCells(position, dimensions, rotation);
83
+ const bounds = this.getAABB(position, dimensions, rotation);
84
+ const cellKeys = this.getItemCells(bounds);
78
85
  const ignoreSet = new Set(ignoreIds);
79
- const conflicts = new Set();
86
+ // Broad phase: collect candidate items from overlapping cells
87
+ const candidates = new Set();
80
88
  for (const key of cellKeys) {
81
89
  const cell = this.cells.get(key);
82
90
  if (cell) {
83
91
  for (const id of cell.itemIds) {
84
92
  if (!ignoreSet.has(id)) {
85
- conflicts.add(id);
93
+ candidates.add(id);
86
94
  }
87
95
  }
88
96
  }
89
97
  }
98
+ // Narrow phase: check actual AABB overlap
99
+ // Items that merely touch (share an edge) are allowed; only true overlap conflicts.
100
+ const EPSILON = 1e-4; // tolerance to allow touching
101
+ const conflicts = [];
102
+ for (const id of candidates) {
103
+ const other = this.itemBounds.get(id);
104
+ if (!other)
105
+ continue;
106
+ if (bounds.minX < other.maxX - EPSILON &&
107
+ bounds.maxX > other.minX + EPSILON &&
108
+ bounds.minZ < other.maxZ - EPSILON &&
109
+ bounds.maxZ > other.minZ + EPSILON) {
110
+ conflicts.push(id);
111
+ }
112
+ }
90
113
  return {
91
- valid: conflicts.size === 0,
92
- conflictIds: [...conflicts],
114
+ valid: conflicts.length === 0,
115
+ conflictIds: conflicts,
93
116
  };
94
117
  }
95
118
  // Query: get all items near a point (for snapping, selection, etc.)
package/dist/index.d.ts CHANGED
@@ -1,27 +1,23 @@
1
- export type { BuildingEvent, CameraControlEvent, CeilingEvent, DoorEvent, EventSuffix, FenceEvent, GridEvent, ItemEvent, LevelEvent, NodeEvent, RoofEvent, RoofSegmentEvent, SiteEvent, SlabEvent, StairEvent, StairSegmentEvent, WallEvent, WindowEvent, ZoneEvent, } from './events/bus';
1
+ export type { BuildingEvent, CameraControlEvent, CameraControlFitSceneEvent, CeilingEvent, ColumnEvent, DoorEvent, EventSuffix, FenceEvent, GridEvent, ItemEvent, LevelEvent, NodeEvent, RoofEvent, RoofSegmentEvent, SiteEvent, SlabEvent, SpawnEvent, StairEvent, StairSegmentEvent, WallEvent, WindowEvent, ZoneEvent, } from './events/bus';
2
2
  export { emitter, eventSuffixes } from './events/bus';
3
3
  export { sceneRegistry, useRegistry, } from './hooks/scene-registry/scene-registry';
4
4
  export { pointInPolygon, spatialGridManager } from './hooks/spatial-grid/spatial-grid-manager';
5
5
  export { initSpatialGridSync, resolveLevelId, } from './hooks/spatial-grid/spatial-grid-sync';
6
6
  export { useSpatialQuery } from './hooks/spatial-grid/use-spatial-query';
7
7
  export { loadAssetUrl, saveAsset } from './lib/asset-storage';
8
+ export { clampDoorOperationState, getDoorRenderOpenAmount, getGarageVisibleOpeningRatio, isOperationDoorType, SECTIONAL_GARAGE_RENDER_OPEN_SCALE, } from './lib/door-operation';
9
+ export { getRenderableSlabPolygon } from './lib/slab-polygon';
8
10
  export { detectSpacesForLevel, initSpaceDetectionSync, type Space, wallTouchesOthers, } from './lib/space-detection';
9
- export { baseMaterial, glassMaterial } from './materials';
11
+ export { getCatalogMaterialById, getLibraryMaterialIdFromRef, getMaterialPresetByRef, getMaterialsForCategory, LIBRARY_MATERIAL_REF_PREFIX, MATERIAL_CATALOG, MATERIAL_CATEGORIES, type MaterialCatalogItem, type MaterialCategory, toLibraryMaterialRef, } from './material-library';
10
12
  export * from './schema';
11
- export { type ControlValue, type ItemInteractiveState, useInteractive, } from './store/use-interactive';
13
+ export { getSceneHistoryPauseDepth, pauseSceneHistory, resetSceneHistoryPauseDepth, resumeSceneHistory, } from './store/history-control';
14
+ export { type ControlValue, type DoorAnimationState, type DoorInteractiveState, type ItemInteractiveState, useInteractive, type WindowAnimationState, type WindowInteractiveState, } from './store/use-interactive';
12
15
  export { default as useLiveTransforms, type LiveTransform } from './store/use-live-transforms';
13
- export { FenceSystem } from './systems/fence/fence-system';
14
16
  export { clearSceneHistory, default as useScene } from './store/use-scene';
15
- export { CeilingSystem } from './systems/ceiling/ceiling-system';
16
- export { DoorSystem } from './systems/door/door-system';
17
- export { ItemSystem } from './systems/item/item-system';
18
- export { RoofSystem } from './systems/roof/roof-system';
19
- export { SlabSystem } from './systems/slab/slab-system';
20
- export { StairSystem } from './systems/stair/stair-system';
17
+ export { syncAutoStairOpenings } from './systems/stair/stair-opening-sync';
18
+ export { getClampedWallCurveOffset, getMaxWallCurveOffset, getWallChordFrame, getWallCurveFrameAt, getWallCurveLength, getWallMidpointHandlePoint, getWallStraightSnapOffset, getWallSurfacePolygon, isCurvedWall, normalizeWallCurveOffset, sampleWallCenterline, } from './systems/wall/wall-curve';
21
19
  export { DEFAULT_WALL_HEIGHT, DEFAULT_WALL_THICKNESS, getWallPlanFootprint, getWallThickness, } from './systems/wall/wall-footprint';
22
- export { calculateLevelMiters, type Point2D, pointToKey, type WallMiterData, } from './systems/wall/wall-mitering';
23
- export { WallSystem } from './systems/wall/wall-system';
24
- export { WindowSystem } from './systems/window/window-system';
20
+ export { calculateLevelMiters, getAdjacentWallIds, getWallMiterBoundaryPoints, type Point2D, pointToKey, type WallMiterBoundaryPoints, type WallMiterData, } from './systems/wall/wall-mitering';
25
21
  export type { SceneGraph } from './utils/clone-scene-graph';
26
22
  export { cloneLevelSubtree, cloneSceneGraph, forkSceneGraph } from './utils/clone-scene-graph';
27
23
  export { isObject } from './utils/types';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,aAAa,EACb,kBAAkB,EAClB,YAAY,EACZ,SAAS,EACT,WAAW,EACX,UAAU,EACV,SAAS,EACT,SAAS,EACT,UAAU,EACV,SAAS,EACT,SAAS,EACT,gBAAgB,EAChB,SAAS,EACT,SAAS,EACT,UAAU,EACV,iBAAiB,EACjB,SAAS,EACT,WAAW,EACX,SAAS,GACV,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AACrD,OAAO,EACL,aAAa,EACb,WAAW,GACZ,MAAM,uCAAuC,CAAA;AAC9C,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,2CAA2C,CAAA;AAC9F,OAAO,EACL,mBAAmB,EACnB,cAAc,GACf,MAAM,wCAAwC,CAAA;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,wCAAwC,CAAA;AACxE,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAC7D,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,KAAK,KAAK,EACV,iBAAiB,GAClB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AACzD,cAAc,UAAU,CAAA;AACxB,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,oBAAoB,EACzB,cAAc,GACf,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,KAAK,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAC9F,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAA;AAC1D,OAAO,EAAE,iBAAiB,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAC1E,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAA;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAA;AAC1D,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,+BAA+B,CAAA;AACtC,OAAO,EACL,oBAAoB,EACpB,KAAK,OAAO,EACZ,UAAU,EACV,KAAK,aAAa,GACnB,MAAM,8BAA8B,CAAA;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAA;AAC7D,YAAY,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAA;AAC3D,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAC9F,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,aAAa,EACb,kBAAkB,EAClB,0BAA0B,EAC1B,YAAY,EACZ,WAAW,EACX,SAAS,EACT,WAAW,EACX,UAAU,EACV,SAAS,EACT,SAAS,EACT,UAAU,EACV,SAAS,EACT,SAAS,EACT,gBAAgB,EAChB,SAAS,EACT,SAAS,EACT,UAAU,EACV,UAAU,EACV,iBAAiB,EACjB,SAAS,EACT,WAAW,EACX,SAAS,GACV,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AACrD,OAAO,EACL,aAAa,EACb,WAAW,GACZ,MAAM,uCAAuC,CAAA;AAC9C,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,2CAA2C,CAAA;AAC9F,OAAO,EACL,mBAAmB,EACnB,cAAc,GACf,MAAM,wCAAwC,CAAA;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,wCAAwC,CAAA;AACxE,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAC7D,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,4BAA4B,EAC5B,mBAAmB,EACnB,kCAAkC,GACnC,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAA;AAC7D,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,KAAK,KAAK,EACV,iBAAiB,GAClB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACL,sBAAsB,EACtB,2BAA2B,EAC3B,sBAAsB,EACtB,uBAAuB,EACvB,2BAA2B,EAC3B,gBAAgB,EAChB,mBAAmB,EACnB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,oBAAoB,GACrB,MAAM,oBAAoB,CAAA;AAC3B,cAAc,UAAU,CAAA;AACxB,OAAO,EACL,yBAAyB,EACzB,iBAAiB,EACjB,2BAA2B,EAC3B,kBAAkB,GACnB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,cAAc,EACd,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,GAC5B,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,KAAK,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAC9F,OAAO,EAAE,iBAAiB,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAC1E,OAAO,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAA;AAC1E,OAAO,EACL,yBAAyB,EACzB,qBAAqB,EACrB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,0BAA0B,EAC1B,yBAAyB,EACzB,qBAAqB,EACrB,YAAY,EACZ,wBAAwB,EACxB,oBAAoB,GACrB,MAAM,2BAA2B,CAAA;AAClC,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,+BAA+B,CAAA;AACtC,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,0BAA0B,EAC1B,KAAK,OAAO,EACZ,UAAU,EACV,KAAK,uBAAuB,EAC5B,KAAK,aAAa,GACnB,MAAM,8BAA8B,CAAA;AACrC,YAAY,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAA;AAC3D,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAC9F,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA"}
package/dist/index.js CHANGED
@@ -4,22 +4,18 @@ export { pointInPolygon, spatialGridManager } from './hooks/spatial-grid/spatial
4
4
  export { initSpatialGridSync, resolveLevelId, } from './hooks/spatial-grid/spatial-grid-sync';
5
5
  export { useSpatialQuery } from './hooks/spatial-grid/use-spatial-query';
6
6
  export { loadAssetUrl, saveAsset } from './lib/asset-storage';
7
+ export { clampDoorOperationState, getDoorRenderOpenAmount, getGarageVisibleOpeningRatio, isOperationDoorType, SECTIONAL_GARAGE_RENDER_OPEN_SCALE, } from './lib/door-operation';
8
+ export { getRenderableSlabPolygon } from './lib/slab-polygon';
7
9
  export { detectSpacesForLevel, initSpaceDetectionSync, wallTouchesOthers, } from './lib/space-detection';
8
- export { baseMaterial, glassMaterial } from './materials';
10
+ export { getCatalogMaterialById, getLibraryMaterialIdFromRef, getMaterialPresetByRef, getMaterialsForCategory, LIBRARY_MATERIAL_REF_PREFIX, MATERIAL_CATALOG, MATERIAL_CATEGORIES, toLibraryMaterialRef, } from './material-library';
9
11
  export * from './schema';
12
+ export { getSceneHistoryPauseDepth, pauseSceneHistory, resetSceneHistoryPauseDepth, resumeSceneHistory, } from './store/history-control';
10
13
  export { useInteractive, } from './store/use-interactive';
11
14
  export { default as useLiveTransforms } from './store/use-live-transforms';
12
- export { FenceSystem } from './systems/fence/fence-system';
13
15
  export { clearSceneHistory, default as useScene } from './store/use-scene';
14
- export { CeilingSystem } from './systems/ceiling/ceiling-system';
15
- export { DoorSystem } from './systems/door/door-system';
16
- export { ItemSystem } from './systems/item/item-system';
17
- export { RoofSystem } from './systems/roof/roof-system';
18
- export { SlabSystem } from './systems/slab/slab-system';
19
- export { StairSystem } from './systems/stair/stair-system';
16
+ export { syncAutoStairOpenings } from './systems/stair/stair-opening-sync';
17
+ export { getClampedWallCurveOffset, getMaxWallCurveOffset, getWallChordFrame, getWallCurveFrameAt, getWallCurveLength, getWallMidpointHandlePoint, getWallStraightSnapOffset, getWallSurfacePolygon, isCurvedWall, normalizeWallCurveOffset, sampleWallCenterline, } from './systems/wall/wall-curve';
20
18
  export { DEFAULT_WALL_HEIGHT, DEFAULT_WALL_THICKNESS, getWallPlanFootprint, getWallThickness, } from './systems/wall/wall-footprint';
21
- export { calculateLevelMiters, pointToKey, } from './systems/wall/wall-mitering';
22
- export { WallSystem } from './systems/wall/wall-system';
23
- export { WindowSystem } from './systems/window/window-system';
19
+ export { calculateLevelMiters, getAdjacentWallIds, getWallMiterBoundaryPoints, pointToKey, } from './systems/wall/wall-mitering';
24
20
  export { cloneLevelSubtree, cloneSceneGraph, forkSceneGraph } from './utils/clone-scene-graph';
25
21
  export { isObject } from './utils/types';