@pascal-app/core 0.1.12 → 0.2.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.
- package/dist/events/bus.d.ts +22 -2
- package/dist/events/bus.d.ts.map +1 -1
- package/dist/hooks/scene-registry/scene-registry.d.ts +6 -1
- package/dist/hooks/scene-registry/scene-registry.d.ts.map +1 -1
- package/dist/hooks/scene-registry/scene-registry.js +11 -1
- package/dist/hooks/spatial-grid/spatial-grid-manager.d.ts +17 -12
- package/dist/hooks/spatial-grid/spatial-grid-manager.d.ts.map +1 -1
- package/dist/hooks/spatial-grid/spatial-grid-manager.js +135 -38
- package/dist/hooks/spatial-grid/spatial-grid-sync.d.ts +1 -1
- package/dist/hooks/spatial-grid/spatial-grid-sync.d.ts.map +1 -1
- package/dist/hooks/spatial-grid/spatial-grid-sync.js +16 -8
- package/dist/hooks/spatial-grid/spatial-grid.d.ts +3 -3
- package/dist/hooks/spatial-grid/spatial-grid.d.ts.map +1 -1
- package/dist/hooks/spatial-grid/spatial-grid.js +2 -2
- package/dist/hooks/spatial-grid/use-spatial-query.d.ts +5 -0
- package/dist/hooks/spatial-grid/use-spatial-query.d.ts.map +1 -1
- package/dist/hooks/spatial-grid/wall-spatial-grid.d.ts +6 -3
- package/dist/hooks/spatial-grid/wall-spatial-grid.d.ts.map +1 -1
- package/dist/hooks/spatial-grid/wall-spatial-grid.js +35 -10
- package/dist/index.d.ts +8 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -6
- package/dist/lib/space-detection.d.ts.map +1 -1
- package/dist/lib/space-detection.js +1 -1
- package/dist/schema/collections.d.ts +11 -0
- package/dist/schema/collections.d.ts.map +1 -0
- package/dist/schema/collections.js +2 -0
- package/dist/schema/index.d.ts +11 -7
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +11 -6
- package/dist/schema/nodes/ceiling.d.ts +1 -0
- package/dist/schema/nodes/ceiling.d.ts.map +1 -1
- package/dist/schema/nodes/ceiling.js +2 -0
- package/dist/schema/nodes/door.d.ts +78 -0
- package/dist/schema/nodes/door.d.ts.map +1 -0
- package/dist/schema/nodes/door.js +67 -0
- package/dist/schema/nodes/item.d.ts +245 -2
- package/dist/schema/nodes/item.d.ts.map +1 -1
- package/dist/schema/nodes/item.js +72 -0
- package/dist/schema/nodes/level.d.ts.map +1 -1
- package/dist/schema/nodes/level.js +11 -1
- package/dist/schema/nodes/roof-segment.d.ts +51 -0
- package/dist/schema/nodes/roof-segment.d.ts.map +1 -0
- package/dist/schema/nodes/roof-segment.js +36 -0
- package/dist/schema/nodes/roof.d.ts +1 -4
- package/dist/schema/nodes/roof.d.ts.map +1 -1
- package/dist/schema/nodes/roof.js +9 -16
- package/dist/schema/nodes/site.d.ts +52 -1
- package/dist/schema/nodes/site.d.ts.map +1 -1
- package/dist/schema/nodes/slab.d.ts +1 -0
- package/dist/schema/nodes/slab.d.ts.map +1 -1
- package/dist/schema/nodes/slab.js +1 -0
- package/dist/schema/nodes/window.d.ts +40 -0
- package/dist/schema/nodes/window.d.ts.map +1 -0
- package/dist/schema/nodes/window.js +38 -0
- package/dist/schema/types.d.ts +241 -6
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/schema/types.js +6 -0
- package/dist/store/actions/node-actions.d.ts.map +1 -1
- package/dist/store/actions/node-actions.js +23 -4
- package/dist/store/use-interactive.d.ts +18 -0
- package/dist/store/use-interactive.d.ts.map +1 -0
- package/dist/store/use-interactive.js +50 -0
- package/dist/store/use-scene.d.ts +10 -1
- package/dist/store/use-scene.d.ts.map +1 -1
- package/dist/store/use-scene.js +180 -57
- package/dist/systems/ceiling/ceiling-system.d.ts.map +1 -1
- package/dist/systems/ceiling/ceiling-system.js +20 -0
- package/dist/systems/door/door-system.d.ts +2 -0
- package/dist/systems/door/door-system.d.ts.map +1 -0
- package/dist/systems/door/door-system.js +211 -0
- package/dist/systems/item/item-system.d.ts.map +1 -1
- package/dist/systems/item/item-system.js +10 -5
- package/dist/systems/roof/roof-system.d.ts +11 -3
- package/dist/systems/roof/roof-system.d.ts.map +1 -1
- package/dist/systems/roof/roof-system.js +705 -210
- package/dist/systems/slab/slab-system.d.ts.map +1 -1
- package/dist/systems/slab/slab-system.js +18 -3
- package/dist/systems/wall/wall-mitering.js +2 -2
- package/dist/systems/wall/wall-system.d.ts.map +1 -1
- package/dist/systems/wall/wall-system.js +11 -13
- package/dist/systems/window/window-system.d.ts +2 -0
- package/dist/systems/window/window-system.d.ts.map +1 -0
- package/dist/systems/window/window-system.js +147 -0
- package/package.json +10 -8
|
@@ -7,6 +7,11 @@ export declare function useSpatialQuery(): {
|
|
|
7
7
|
canPlaceOnWall: (levelId: LevelNode["id"], wallId: WallNode["id"], localX: number, localY: number, dimensions: [number, number, number], attachType?: "wall" | "wall-side", side?: "front" | "back", ignoreIds?: string[]) => {
|
|
8
8
|
valid: boolean;
|
|
9
9
|
conflictIds: string[];
|
|
10
|
+
adjustedY: number;
|
|
11
|
+
wasAdjusted: boolean;
|
|
12
|
+
} | {
|
|
13
|
+
valid: boolean;
|
|
14
|
+
conflictIds: never[];
|
|
10
15
|
};
|
|
11
16
|
canPlaceOnCeiling: (ceilingId: CeilingNode["id"], position: [number, number, number], dimensions: [number, number, number], rotation: [number, number, number], ignoreIds?: string[]) => {
|
|
12
17
|
valid: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-spatial-query.d.ts","sourceRoot":"","sources":["../../../src/hooks/spatial-grid/use-spatial-query.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAGpE,wBAAgB,eAAe;+BAGhB,SAAS,CAAC,IAAI,CAAC,YACd,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,cACtB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,YAC1B,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,cACtB,MAAM,EAAE;;;;8BASX,SAAS,CAAC,IAAI,CAAC,UAChB,QAAQ,CAAC,IAAI,CAAC,UACd,MAAM,UACN,MAAM,cACF,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,eACxB,MAAM,GAAG,WAAW,SACzB,OAAO,GAAG,MAAM,cACX,MAAM,EAAE
|
|
1
|
+
{"version":3,"file":"use-spatial-query.d.ts","sourceRoot":"","sources":["../../../src/hooks/spatial-grid/use-spatial-query.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAGpE,wBAAgB,eAAe;+BAGhB,SAAS,CAAC,IAAI,CAAC,YACd,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,cACtB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,YAC1B,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,cACtB,MAAM,EAAE;;;;8BASX,SAAS,CAAC,IAAI,CAAC,UAChB,QAAQ,CAAC,IAAI,CAAC,UACd,MAAM,UACN,MAAM,cACF,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,eACxB,MAAM,GAAG,WAAW,SACzB,OAAO,GAAG,MAAM,cACX,MAAM,EAAE;;;;;;;;;mCAkBT,WAAW,CAAC,IAAI,CAAC,YAClB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,cACtB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,YAC1B,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,cACtB,MAAM,EAAE;;;;EAczB"}
|
|
@@ -11,10 +11,10 @@ interface WallItemPlacement {
|
|
|
11
11
|
side?: WallSide;
|
|
12
12
|
}
|
|
13
13
|
export declare class WallSpatialGrid {
|
|
14
|
-
private wallItems;
|
|
15
|
-
private itemToWall;
|
|
14
|
+
private readonly wallItems;
|
|
15
|
+
private readonly itemToWall;
|
|
16
16
|
/**
|
|
17
|
-
* Check if an item can be placed on a wall
|
|
17
|
+
* Check if an item can be placed on a wall with auto-adjustment for vertical position
|
|
18
18
|
* @param wallId - The wall to place on
|
|
19
19
|
* @param wallLength - Length of the wall
|
|
20
20
|
* @param wallHeight - Height of the wall
|
|
@@ -25,10 +25,13 @@ export declare class WallSpatialGrid {
|
|
|
25
25
|
* @param attachType - 'wall' (blocks both sides) or 'wall-side' (blocks one side)
|
|
26
26
|
* @param side - Which side for 'wall-side' items
|
|
27
27
|
* @param ignoreIds - Item IDs to ignore in conflict check
|
|
28
|
+
* @returns Validation result with auto-adjusted Y position if needed
|
|
28
29
|
*/
|
|
29
30
|
canPlaceOnWall(wallId: string, wallLength: number, wallHeight: number, tCenter: number, itemWidth: number, yBottom: number, itemHeight: number, attachType?: AttachType, side?: WallSide, ignoreIds?: string[]): {
|
|
30
31
|
valid: boolean;
|
|
31
32
|
conflictIds: string[];
|
|
33
|
+
adjustedY: number;
|
|
34
|
+
wasAdjusted: boolean;
|
|
32
35
|
};
|
|
33
36
|
/**
|
|
34
37
|
* Check if two items conflict based on their attach types and sides
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wall-spatial-grid.d.ts","sourceRoot":"","sources":["../../../src/hooks/spatial-grid/wall-spatial-grid.ts"],"names":[],"mappings":"AAAA,KAAK,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAA;AAChC,KAAK,UAAU,GAAG,MAAM,GAAG,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"wall-spatial-grid.d.ts","sourceRoot":"","sources":["../../../src/hooks/spatial-grid/wall-spatial-grid.ts"],"names":[],"mappings":"AAAA,KAAK,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAA;AAChC,KAAK,UAAU,GAAG,MAAM,GAAG,WAAW,CAAA;AAQtC,UAAU,iBAAiB;IACzB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,CAAC,EAAE,UAAU,CAAA;IACvB,IAAI,CAAC,EAAE,QAAQ,CAAA;CAChB;AAgCD,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyC;IACnE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA4B;IAEvD;;;;;;;;;;;;;OAaG;IACH,cAAc,CACZ,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,UAAU,GAAE,UAAmB,EAC/B,IAAI,CAAC,EAAE,QAAQ,EACf,SAAS,GAAE,MAAM,EAAO,GACvB;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,WAAW,EAAE,MAAM,EAAE,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,OAAO,CAAA;KAAE;IAsCrF;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IA0BzB,MAAM,CAAC,SAAS,EAAE,iBAAiB;IAUnC,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IASrC,cAAc,CAAC,MAAM,EAAE,MAAM;IAQ7B,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE;IAapC,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAIlD,KAAK;CAIN"}
|
|
@@ -1,10 +1,33 @@
|
|
|
1
1
|
// Small tolerance for floating point comparison to allow adjacent items
|
|
2
2
|
const EPSILON = 0.001;
|
|
3
|
+
// Margin from ceiling/floor when auto-snapping items
|
|
4
|
+
const AUTO_SNAP_MARGIN = 0.05;
|
|
5
|
+
/**
|
|
6
|
+
* Auto-adjust Y position to fit item within wall bounds
|
|
7
|
+
* Returns the adjusted Y position (bottom of item)
|
|
8
|
+
*/
|
|
9
|
+
function autoAdjustYPosition(yBottom, itemHeight, wallHeight) {
|
|
10
|
+
const yTop = yBottom + itemHeight;
|
|
11
|
+
// If fits perfectly, no adjustment needed
|
|
12
|
+
if (yBottom >= 0 && yTop <= wallHeight) {
|
|
13
|
+
return { adjustedY: yBottom, wasAdjusted: false };
|
|
14
|
+
}
|
|
15
|
+
// If too high (top exceeds wall height), snap down from ceiling
|
|
16
|
+
if (yTop > wallHeight) {
|
|
17
|
+
const adjustedY = wallHeight - itemHeight - AUTO_SNAP_MARGIN;
|
|
18
|
+
return { adjustedY: Math.max(0, adjustedY), wasAdjusted: true };
|
|
19
|
+
}
|
|
20
|
+
// If too low (bottom below floor), snap up from floor
|
|
21
|
+
if (yBottom < 0) {
|
|
22
|
+
return { adjustedY: AUTO_SNAP_MARGIN, wasAdjusted: true };
|
|
23
|
+
}
|
|
24
|
+
return { adjustedY: yBottom, wasAdjusted: false };
|
|
25
|
+
}
|
|
3
26
|
export class WallSpatialGrid {
|
|
4
27
|
wallItems = new Map(); // wallId -> placements
|
|
5
28
|
itemToWall = new Map(); // itemId -> wallId (reverse lookup)
|
|
6
29
|
/**
|
|
7
|
-
* Check if an item can be placed on a wall
|
|
30
|
+
* Check if an item can be placed on a wall with auto-adjustment for vertical position
|
|
8
31
|
* @param wallId - The wall to place on
|
|
9
32
|
* @param wallLength - Length of the wall
|
|
10
33
|
* @param wallHeight - Height of the wall
|
|
@@ -15,18 +38,20 @@ export class WallSpatialGrid {
|
|
|
15
38
|
* @param attachType - 'wall' (blocks both sides) or 'wall-side' (blocks one side)
|
|
16
39
|
* @param side - Which side for 'wall-side' items
|
|
17
40
|
* @param ignoreIds - Item IDs to ignore in conflict check
|
|
41
|
+
* @returns Validation result with auto-adjusted Y position if needed
|
|
18
42
|
*/
|
|
19
43
|
canPlaceOnWall(wallId, wallLength, wallHeight, tCenter, itemWidth, yBottom, itemHeight, attachType = 'wall', side, ignoreIds = []) {
|
|
20
44
|
const halfW = itemWidth / wallLength / 2;
|
|
21
45
|
const tStart = tCenter - halfW;
|
|
22
46
|
const tEnd = tCenter + halfW;
|
|
23
|
-
//
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
// Check wall boundaries
|
|
27
|
-
if (tStart < 0 || tEnd > 1 || yStart < 0 || yEnd > wallHeight) {
|
|
28
|
-
return { valid: false, conflictIds: [] };
|
|
47
|
+
// Check horizontal boundaries (still reject if item exceeds wall width)
|
|
48
|
+
if (tStart < 0 || tEnd > 1) {
|
|
49
|
+
return { valid: false, conflictIds: [], adjustedY: yBottom, wasAdjusted: false };
|
|
29
50
|
}
|
|
51
|
+
// Auto-adjust vertical position to fit within wall bounds
|
|
52
|
+
const { adjustedY, wasAdjusted } = autoAdjustYPosition(yBottom, itemHeight, wallHeight);
|
|
53
|
+
const yStart = adjustedY;
|
|
54
|
+
const yEnd = adjustedY + itemHeight;
|
|
30
55
|
const existing = this.wallItems.get(wallId) ?? [];
|
|
31
56
|
const ignoreSet = new Set(ignoreIds);
|
|
32
57
|
const conflicts = [];
|
|
@@ -44,7 +69,7 @@ export class WallSpatialGrid {
|
|
|
44
69
|
}
|
|
45
70
|
}
|
|
46
71
|
}
|
|
47
|
-
return { valid: conflicts.length === 0, conflictIds: conflicts };
|
|
72
|
+
return { valid: conflicts.length === 0, conflictIds: conflicts, adjustedY, wasAdjusted };
|
|
48
73
|
}
|
|
49
74
|
/**
|
|
50
75
|
* Check if two items conflict based on their attach types and sides
|
|
@@ -64,7 +89,7 @@ export class WallSpatialGrid {
|
|
|
64
89
|
}
|
|
65
90
|
// Both are 'wall-side' - only conflict if they're on the same side
|
|
66
91
|
// If either side is undefined, be conservative and assume conflict
|
|
67
|
-
if (!newSide
|
|
92
|
+
if (!(newSide && existing.side)) {
|
|
68
93
|
return true;
|
|
69
94
|
}
|
|
70
95
|
return newSide === existing.side;
|
|
@@ -74,7 +99,7 @@ export class WallSpatialGrid {
|
|
|
74
99
|
if (!this.wallItems.has(wallId)) {
|
|
75
100
|
this.wallItems.set(wallId, []);
|
|
76
101
|
}
|
|
77
|
-
this.wallItems.get(wallId)
|
|
102
|
+
this.wallItems.get(wallId)?.push(placement);
|
|
78
103
|
this.itemToWall.set(itemId, wallId);
|
|
79
104
|
}
|
|
80
105
|
remove(wallId, itemId) {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
|
-
export type { BuildingEvent, CameraControlEvent, EventSuffix, GridEvent, ItemEvent, LevelEvent, NodeEvent, SiteEvent, SlabEvent, WallEvent,
|
|
1
|
+
export type { BuildingEvent, CameraControlEvent, CeilingEvent, DoorEvent, EventSuffix, GridEvent, ItemEvent, LevelEvent, NodeEvent, RoofEvent, RoofSegmentEvent, SiteEvent, SlabEvent, 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
|
+
export { pointInPolygon, spatialGridManager } from './hooks/spatial-grid/spatial-grid-manager';
|
|
4
5
|
export { initSpatialGridSync, resolveLevelId, } from './hooks/spatial-grid/spatial-grid-sync';
|
|
5
6
|
export { useSpatialQuery } from './hooks/spatial-grid/use-spatial-query';
|
|
6
|
-
export {
|
|
7
|
+
export { loadAssetUrl, saveAsset } from './lib/asset-storage';
|
|
8
|
+
export { detectSpacesForLevel, initSpaceDetectionSync, type Space, wallTouchesOthers, } from './lib/space-detection';
|
|
7
9
|
export * from './schema';
|
|
8
|
-
export {
|
|
10
|
+
export { type ControlValue, type ItemInteractiveState, useInteractive, } from './store/use-interactive';
|
|
11
|
+
export { clearSceneHistory, default as useScene } from './store/use-scene';
|
|
9
12
|
export { CeilingSystem } from './systems/ceiling/ceiling-system';
|
|
13
|
+
export { DoorSystem } from './systems/door/door-system';
|
|
10
14
|
export { ItemSystem } from './systems/item/item-system';
|
|
11
15
|
export { RoofSystem } from './systems/roof/roof-system';
|
|
12
16
|
export { SlabSystem } from './systems/slab/slab-system';
|
|
13
17
|
export { WallSystem } from './systems/wall/wall-system';
|
|
18
|
+
export { WindowSystem } from './systems/window/window-system';
|
|
14
19
|
export { isObject } from './utils/types';
|
|
15
|
-
export { saveAsset, loadAssetUrl } from './lib/asset-storage';
|
|
16
|
-
export { detectSpacesForLevel, wallTouchesOthers, initSpaceDetectionSync, type Space } from './lib/space-detection';
|
|
17
20
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,YAAY,EACV,aAAa,EACb,kBAAkB,EAClB,WAAW,EACX,SAAS,EACT,SAAS,EACT,UAAU,EACV,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,EACT,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,YAAY,EACV,aAAa,EACb,kBAAkB,EAClB,YAAY,EACZ,SAAS,EACT,WAAW,EACX,SAAS,EACT,SAAS,EACT,UAAU,EACV,SAAS,EACT,SAAS,EACT,gBAAgB,EAChB,SAAS,EACT,SAAS,EACT,SAAS,EACT,WAAW,EACX,SAAS,GACV,MAAM,cAAc,CAAA;AAErB,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAErD,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;AAExE,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAE7D,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,KAAK,KAAK,EACV,iBAAiB,GAClB,MAAM,uBAAuB,CAAA;AAE9B,cAAc,UAAU,CAAA;AACxB,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,oBAAoB,EACzB,cAAc,GACf,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,iBAAiB,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAE1E,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,UAAU,EAAE,MAAM,4BAA4B,CAAA;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAA;AAC7D,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -3,20 +3,23 @@
|
|
|
3
3
|
export { emitter, eventSuffixes } from './events/bus';
|
|
4
4
|
// Hooks
|
|
5
5
|
export { sceneRegistry, useRegistry, } from './hooks/scene-registry/scene-registry';
|
|
6
|
+
export { pointInPolygon, spatialGridManager } from './hooks/spatial-grid/spatial-grid-manager';
|
|
6
7
|
export { initSpatialGridSync, resolveLevelId, } from './hooks/spatial-grid/spatial-grid-sync';
|
|
7
8
|
export { useSpatialQuery } from './hooks/spatial-grid/use-spatial-query';
|
|
8
|
-
|
|
9
|
+
// Asset storage
|
|
10
|
+
export { loadAssetUrl, saveAsset } from './lib/asset-storage';
|
|
11
|
+
// Space detection
|
|
12
|
+
export { detectSpacesForLevel, initSpaceDetectionSync, wallTouchesOthers, } from './lib/space-detection';
|
|
9
13
|
// Schema
|
|
10
14
|
export * from './schema';
|
|
11
|
-
export {
|
|
15
|
+
export { useInteractive, } from './store/use-interactive';
|
|
16
|
+
export { clearSceneHistory, default as useScene } from './store/use-scene';
|
|
12
17
|
// Systems
|
|
13
18
|
export { CeilingSystem } from './systems/ceiling/ceiling-system';
|
|
19
|
+
export { DoorSystem } from './systems/door/door-system';
|
|
14
20
|
export { ItemSystem } from './systems/item/item-system';
|
|
15
21
|
export { RoofSystem } from './systems/roof/roof-system';
|
|
16
22
|
export { SlabSystem } from './systems/slab/slab-system';
|
|
17
23
|
export { WallSystem } from './systems/wall/wall-system';
|
|
24
|
+
export { WindowSystem } from './systems/window/window-system';
|
|
18
25
|
export { isObject } from './utils/types';
|
|
19
|
-
// Asset storage
|
|
20
|
-
export { saveAsset, loadAssetUrl } from './lib/asset-storage';
|
|
21
|
-
// Space detection
|
|
22
|
-
export { detectSpacesForLevel, wallTouchesOthers, initSpaceDetectionSync } from './lib/space-detection';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"space-detection.d.ts","sourceRoot":"","sources":["../../src/lib/space-detection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAMzC,MAAM,MAAM,KAAK,GAAG;IAClB,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IAChC,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,UAAU,EAAE,OAAO,CAAA;CACpB,CAAA;AAMD;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,GAAG,EAAE,iBAAiB;AAClC,WAAW,EAAE,GAAG,GACf,MAAM,IAAI,CAgGZ;AA+DD,KAAK,cAAc,GAAG;IACpB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,UAAU,GAAG,UAAU,GAAG,SAAS,CAAA;IAC9C,QAAQ,EAAE,UAAU,GAAG,UAAU,GAAG,SAAS,CAAA;CAC9C,CAAA;AAMD;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,QAAQ,EAAE,EACjB,cAAc,
|
|
1
|
+
{"version":3,"file":"space-detection.d.ts","sourceRoot":"","sources":["../../src/lib/space-detection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAMzC,MAAM,MAAM,KAAK,GAAG;IAClB,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IAChC,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,UAAU,EAAE,OAAO,CAAA;CACpB,CAAA;AAMD;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,GAAG,EAAE,iBAAiB;AAClC,WAAW,EAAE,GAAG,GACf,MAAM,IAAI,CAgGZ;AA+DD,KAAK,cAAc,GAAG;IACpB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,UAAU,GAAG,UAAU,GAAG,SAAS,CAAA;IAC9C,QAAQ,EAAE,UAAU,GAAG,UAAU,GAAG,SAAS,CAAA;CAC9C,CAAA;AAMD;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,QAAQ,EAAE,EACjB,cAAc,SAAM,GACnB;IACD,WAAW,EAAE,cAAc,EAAE,CAAA;IAC7B,MAAM,EAAE,KAAK,EAAE,CAAA;CAChB,CAqBA;AAsWD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,OAAO,CAkBjF"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { AnyNodeId } from './types';
|
|
2
|
+
export type CollectionId = `collection_${string}`;
|
|
3
|
+
export type Collection = {
|
|
4
|
+
id: CollectionId;
|
|
5
|
+
name: string;
|
|
6
|
+
color?: string;
|
|
7
|
+
nodeIds: AnyNodeId[];
|
|
8
|
+
controlNodeId?: AnyNodeId;
|
|
9
|
+
};
|
|
10
|
+
export declare const generateCollectionId: () => CollectionId;
|
|
11
|
+
//# sourceMappingURL=collections.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collections.d.ts","sourceRoot":"","sources":["../../src/schema/collections.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAExC,MAAM,MAAM,YAAY,GAAG,cAAc,MAAM,EAAE,CAAA;AAEjD,MAAM,MAAM,UAAU,GAAG;IACvB,EAAE,EAAE,YAAY,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,SAAS,EAAE,CAAA;IACpB,aAAa,CAAC,EAAE,SAAS,CAAA;CAC1B,CAAA;AAED,eAAO,MAAM,oBAAoB,QAAO,YAAwC,CAAA"}
|
package/dist/schema/index.d.ts
CHANGED
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
export { BaseNode, generateId, Material, nodeType, objectId } from './base';
|
|
2
2
|
export { CameraSchema } from './camera';
|
|
3
|
-
export type
|
|
4
|
-
export {
|
|
3
|
+
export { type Collection, type CollectionId, generateCollectionId } from './collections';
|
|
4
|
+
export { BuildingNode } from './nodes/building';
|
|
5
|
+
export { CeilingNode } from './nodes/ceiling';
|
|
6
|
+
export { DoorNode, DoorSegment } from './nodes/door';
|
|
7
|
+
export { GuideNode } from './nodes/guide';
|
|
8
|
+
export type { AnimationEffect, Asset, AssetInput, Control, Effect, Interactive, LightEffect, SliderControl, TemperatureControl, ToggleControl, } from './nodes/item';
|
|
9
|
+
export { getScaledDimensions, ItemNode } from './nodes/item';
|
|
5
10
|
export { LevelNode } from './nodes/level';
|
|
11
|
+
export { RoofNode } from './nodes/roof';
|
|
12
|
+
export { RoofSegmentNode, RoofType } from './nodes/roof-segment';
|
|
13
|
+
export { ScanNode } from './nodes/scan';
|
|
6
14
|
export { SiteNode } from './nodes/site';
|
|
7
15
|
export { SlabNode } from './nodes/slab';
|
|
8
16
|
export { WallNode } from './nodes/wall';
|
|
9
|
-
export {
|
|
10
|
-
export { CeilingNode } from './nodes/ceiling';
|
|
17
|
+
export { WindowNode } from './nodes/window';
|
|
11
18
|
export { ZoneNode } from './nodes/zone';
|
|
12
|
-
export { RoofNode } from './nodes/roof';
|
|
13
|
-
export { ScanNode } from './nodes/scan';
|
|
14
|
-
export { GuideNode } from './nodes/guide';
|
|
15
19
|
export type { AnyNodeId, AnyNodeType } from './types';
|
|
16
20
|
export { AnyNode } from './types';
|
|
17
21
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schema/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAE3E,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schema/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAE3E,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAEvC,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,YAAY,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAA;AACxF,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAC7C,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AACzC,YAAY,EACV,eAAe,EACf,KAAK,EACL,UAAU,EACV,OAAO,EACP,MAAM,EACN,WAAW,EACX,WAAW,EACX,aAAa,EACb,kBAAkB,EAClB,aAAa,GACd,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AACvC,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAChE,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAEvC,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AACvC,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAErD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA"}
|
package/dist/schema/index.js
CHANGED
|
@@ -2,17 +2,22 @@
|
|
|
2
2
|
export { BaseNode, generateId, Material, nodeType, objectId } from './base';
|
|
3
3
|
// Camera
|
|
4
4
|
export { CameraSchema } from './camera';
|
|
5
|
-
|
|
5
|
+
// Collections
|
|
6
|
+
export { generateCollectionId } from './collections';
|
|
7
|
+
export { BuildingNode } from './nodes/building';
|
|
8
|
+
export { CeilingNode } from './nodes/ceiling';
|
|
9
|
+
export { DoorNode, DoorSegment } from './nodes/door';
|
|
10
|
+
export { GuideNode } from './nodes/guide';
|
|
11
|
+
export { getScaledDimensions, ItemNode } from './nodes/item';
|
|
6
12
|
export { LevelNode } from './nodes/level';
|
|
13
|
+
export { RoofNode } from './nodes/roof';
|
|
14
|
+
export { RoofSegmentNode, RoofType } from './nodes/roof-segment';
|
|
15
|
+
export { ScanNode } from './nodes/scan';
|
|
7
16
|
// Nodes
|
|
8
17
|
export { SiteNode } from './nodes/site';
|
|
9
18
|
export { SlabNode } from './nodes/slab';
|
|
10
19
|
export { WallNode } from './nodes/wall';
|
|
11
|
-
export {
|
|
12
|
-
export { CeilingNode } from './nodes/ceiling';
|
|
20
|
+
export { WindowNode } from './nodes/window';
|
|
13
21
|
export { ZoneNode } from './nodes/zone';
|
|
14
|
-
export { RoofNode } from './nodes/roof';
|
|
15
|
-
export { ScanNode } from './nodes/scan';
|
|
16
|
-
export { GuideNode } from './nodes/guide';
|
|
17
22
|
// Union types
|
|
18
23
|
export { AnyNode } from './types';
|
|
@@ -19,6 +19,7 @@ export declare const CeilingNode: z.ZodObject<{
|
|
|
19
19
|
type: z.ZodDefault<z.ZodLiteral<"ceiling">>;
|
|
20
20
|
children: z.ZodDefault<z.ZodArray<z.ZodDefault<z.ZodTemplateLiteral<`item_${string}`>>>>;
|
|
21
21
|
polygon: z.ZodArray<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
|
|
22
|
+
holes: z.ZodDefault<z.ZodArray<z.ZodArray<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>>>;
|
|
22
23
|
height: z.ZodDefault<z.ZodNumber>;
|
|
23
24
|
}, z.core.$strip>;
|
|
24
25
|
export type CeilingNode = z.infer<typeof CeilingNode>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ceiling.d.ts","sourceRoot":"","sources":["../../../src/schema/nodes/ceiling.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,eAAO,MAAM,WAAW
|
|
1
|
+
{"version":3,"file":"ceiling.d.ts","sourceRoot":"","sources":["../../../src/schema/nodes/ceiling.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;iBAevB,CAAA;AAED,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAA"}
|
|
@@ -9,8 +9,10 @@ export const CeilingNode = BaseNode.extend({
|
|
|
9
9
|
// Specific props
|
|
10
10
|
// Polygon boundary - array of [x, z] coordinates defining the ceiling
|
|
11
11
|
polygon: z.array(z.tuple([z.number(), z.number()])),
|
|
12
|
+
holes: z.array(z.array(z.tuple([z.number(), z.number()]))).default([]),
|
|
12
13
|
height: z.number().default(2.5), // Height in meters
|
|
13
14
|
}).describe(dedent `
|
|
14
15
|
Ceiling node - used to represent a ceiling in the building
|
|
15
16
|
- polygon: array of [x, z] points defining the ceiling boundary
|
|
17
|
+
- holes: array of polygons representing holes in the ceiling
|
|
16
18
|
`);
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const DoorSegment: z.ZodObject<{
|
|
3
|
+
type: z.ZodEnum<{
|
|
4
|
+
panel: "panel";
|
|
5
|
+
glass: "glass";
|
|
6
|
+
empty: "empty";
|
|
7
|
+
}>;
|
|
8
|
+
heightRatio: z.ZodNumber;
|
|
9
|
+
columnRatios: z.ZodDefault<z.ZodArray<z.ZodNumber>>;
|
|
10
|
+
dividerThickness: z.ZodDefault<z.ZodNumber>;
|
|
11
|
+
panelDepth: z.ZodDefault<z.ZodNumber>;
|
|
12
|
+
panelInset: z.ZodDefault<z.ZodNumber>;
|
|
13
|
+
}, z.core.$strip>;
|
|
14
|
+
export type DoorSegment = z.infer<typeof DoorSegment>;
|
|
15
|
+
export declare const DoorNode: z.ZodObject<{
|
|
16
|
+
object: z.ZodDefault<z.ZodLiteral<"node">>;
|
|
17
|
+
name: z.ZodOptional<z.ZodString>;
|
|
18
|
+
parentId: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
19
|
+
visible: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
20
|
+
camera: z.ZodOptional<z.ZodObject<{
|
|
21
|
+
position: z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>;
|
|
22
|
+
target: z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>;
|
|
23
|
+
mode: z.ZodDefault<z.ZodEnum<{
|
|
24
|
+
perspective: "perspective";
|
|
25
|
+
orthographic: "orthographic";
|
|
26
|
+
}>>;
|
|
27
|
+
fov: z.ZodOptional<z.ZodNumber>;
|
|
28
|
+
zoom: z.ZodOptional<z.ZodNumber>;
|
|
29
|
+
}, z.core.$strip>>;
|
|
30
|
+
metadata: z.ZodDefault<z.ZodOptional<z.ZodJSONSchema>>;
|
|
31
|
+
id: z.ZodDefault<z.ZodTemplateLiteral<`door_${string}`>>;
|
|
32
|
+
type: z.ZodDefault<z.ZodLiteral<"door">>;
|
|
33
|
+
position: z.ZodDefault<z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>>;
|
|
34
|
+
rotation: z.ZodDefault<z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>>;
|
|
35
|
+
side: z.ZodOptional<z.ZodEnum<{
|
|
36
|
+
front: "front";
|
|
37
|
+
back: "back";
|
|
38
|
+
}>>;
|
|
39
|
+
wallId: z.ZodOptional<z.ZodString>;
|
|
40
|
+
width: z.ZodDefault<z.ZodNumber>;
|
|
41
|
+
height: z.ZodDefault<z.ZodNumber>;
|
|
42
|
+
frameThickness: z.ZodDefault<z.ZodNumber>;
|
|
43
|
+
frameDepth: z.ZodDefault<z.ZodNumber>;
|
|
44
|
+
threshold: z.ZodDefault<z.ZodBoolean>;
|
|
45
|
+
thresholdHeight: z.ZodDefault<z.ZodNumber>;
|
|
46
|
+
hingesSide: z.ZodDefault<z.ZodEnum<{
|
|
47
|
+
left: "left";
|
|
48
|
+
right: "right";
|
|
49
|
+
}>>;
|
|
50
|
+
swingDirection: z.ZodDefault<z.ZodEnum<{
|
|
51
|
+
inward: "inward";
|
|
52
|
+
outward: "outward";
|
|
53
|
+
}>>;
|
|
54
|
+
segments: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
55
|
+
type: z.ZodEnum<{
|
|
56
|
+
panel: "panel";
|
|
57
|
+
glass: "glass";
|
|
58
|
+
empty: "empty";
|
|
59
|
+
}>;
|
|
60
|
+
heightRatio: z.ZodNumber;
|
|
61
|
+
columnRatios: z.ZodDefault<z.ZodArray<z.ZodNumber>>;
|
|
62
|
+
dividerThickness: z.ZodDefault<z.ZodNumber>;
|
|
63
|
+
panelDepth: z.ZodDefault<z.ZodNumber>;
|
|
64
|
+
panelInset: z.ZodDefault<z.ZodNumber>;
|
|
65
|
+
}, z.core.$strip>>>;
|
|
66
|
+
handle: z.ZodDefault<z.ZodBoolean>;
|
|
67
|
+
handleHeight: z.ZodDefault<z.ZodNumber>;
|
|
68
|
+
handleSide: z.ZodDefault<z.ZodEnum<{
|
|
69
|
+
left: "left";
|
|
70
|
+
right: "right";
|
|
71
|
+
}>>;
|
|
72
|
+
contentPadding: z.ZodDefault<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
|
|
73
|
+
doorCloser: z.ZodDefault<z.ZodBoolean>;
|
|
74
|
+
panicBar: z.ZodDefault<z.ZodBoolean>;
|
|
75
|
+
panicBarHeight: z.ZodDefault<z.ZodNumber>;
|
|
76
|
+
}, z.core.$strip>;
|
|
77
|
+
export type DoorNode = z.infer<typeof DoorNode>;
|
|
78
|
+
//# sourceMappingURL=door.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"door.d.ts","sourceRoot":"","sources":["../../../src/schema/nodes/door.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB,eAAO,MAAM,WAAW;;;;;;;;;;;iBAWtB,CAAA;AAEF,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAA;AAErD,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA6DnB,CAAA;AAEF,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,QAAQ,CAAC,CAAA"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import dedent from 'dedent';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { BaseNode, nodeType, objectId } from '../base';
|
|
4
|
+
export const DoorSegment = z.object({
|
|
5
|
+
type: z.enum(['panel', 'glass', 'empty']),
|
|
6
|
+
heightRatio: z.number(),
|
|
7
|
+
// Each segment controls its own column split
|
|
8
|
+
columnRatios: z.array(z.number()).default([1]),
|
|
9
|
+
dividerThickness: z.number().default(0.03),
|
|
10
|
+
// panel-specific
|
|
11
|
+
panelDepth: z.number().default(0.01), // + raised, - recessed
|
|
12
|
+
panelInset: z.number().default(0.04),
|
|
13
|
+
});
|
|
14
|
+
export const DoorNode = BaseNode.extend({
|
|
15
|
+
id: objectId('door'),
|
|
16
|
+
type: nodeType('door'),
|
|
17
|
+
position: z.tuple([z.number(), z.number(), z.number()]).default([0, 0, 0]),
|
|
18
|
+
rotation: z.tuple([z.number(), z.number(), z.number()]).default([0, 0, 0]),
|
|
19
|
+
side: z.enum(['front', 'back']).optional(),
|
|
20
|
+
wallId: z.string().optional(),
|
|
21
|
+
// Overall dimensions
|
|
22
|
+
width: z.number().default(0.9),
|
|
23
|
+
height: z.number().default(2.1),
|
|
24
|
+
// Frame
|
|
25
|
+
frameThickness: z.number().default(0.05),
|
|
26
|
+
frameDepth: z.number().default(0.07),
|
|
27
|
+
threshold: z.boolean().default(true),
|
|
28
|
+
thresholdHeight: z.number().default(0.02),
|
|
29
|
+
// Swing
|
|
30
|
+
hingesSide: z.enum(['left', 'right']).default('left'),
|
|
31
|
+
swingDirection: z.enum(['inward', 'outward']).default('inward'),
|
|
32
|
+
// Leaf segments — stacked top to bottom, each with its own column split
|
|
33
|
+
segments: z.array(DoorSegment).default([
|
|
34
|
+
{
|
|
35
|
+
type: 'panel',
|
|
36
|
+
heightRatio: 0.4,
|
|
37
|
+
columnRatios: [1],
|
|
38
|
+
dividerThickness: 0.03,
|
|
39
|
+
panelDepth: 0.01,
|
|
40
|
+
panelInset: 0.04,
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
type: 'panel',
|
|
44
|
+
heightRatio: 0.6,
|
|
45
|
+
columnRatios: [1],
|
|
46
|
+
dividerThickness: 0.03,
|
|
47
|
+
panelDepth: 0.01,
|
|
48
|
+
panelInset: 0.04,
|
|
49
|
+
},
|
|
50
|
+
]),
|
|
51
|
+
// Handle
|
|
52
|
+
handle: z.boolean().default(true),
|
|
53
|
+
handleHeight: z.number().default(1.05),
|
|
54
|
+
handleSide: z.enum(['left', 'right']).default('right'),
|
|
55
|
+
// Leaf inner margin — space between leaf edge and segment content area [x, y]
|
|
56
|
+
contentPadding: z.tuple([z.number(), z.number()]).default([0.04, 0.04]),
|
|
57
|
+
// Emergency / commercial hardware
|
|
58
|
+
doorCloser: z.boolean().default(false),
|
|
59
|
+
panicBar: z.boolean().default(false),
|
|
60
|
+
panicBarHeight: z.number().default(1.0),
|
|
61
|
+
}).describe(dedent `Door node - a parametric door placed on a wall
|
|
62
|
+
- position: center of the door in wall-local coordinate system (Y = height/2, always at floor)
|
|
63
|
+
- segments: rows stacked top to bottom, each defining its own columnRatios
|
|
64
|
+
- type 'empty' = flush flat fill, 'panel' = raised/recessed panel, 'glass' = glazed
|
|
65
|
+
- hingesSide/swingDirection: which way the door opens
|
|
66
|
+
- doorCloser/panicBar: commercial and emergency hardware options
|
|
67
|
+
`);
|