@pascal-app/viewer 1.1.0 → 1.1.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/README.md +157 -0
- package/dist/components/viewer/drone-controller.d.ts.map +1 -1
- package/dist/components/viewer/drone-controller.js +1 -5
- package/dist/components/viewer/first-person/build-collider-world.d.ts +14 -0
- package/dist/components/viewer/first-person/build-collider-world.d.ts.map +1 -0
- package/dist/components/viewer/first-person/build-collider-world.js +426 -0
- package/dist/components/viewer/first-person/ground-holes.d.ts +22 -0
- package/dist/components/viewer/first-person/ground-holes.d.ts.map +1 -0
- package/dist/components/viewer/first-person/ground-holes.js +116 -0
- package/dist/components/viewer/first-person/mechanism-targets.d.ts +27 -0
- package/dist/components/viewer/first-person/mechanism-targets.d.ts.map +1 -0
- package/dist/components/viewer/first-person/mechanism-targets.js +79 -0
- package/dist/components/viewer/first-person/terrain-collider.d.ts +32 -0
- package/dist/components/viewer/first-person/terrain-collider.d.ts.map +1 -0
- package/dist/components/viewer/first-person/terrain-collider.js +175 -0
- package/dist/components/viewer/glb-walkthrough-controller.d.ts +1 -1
- package/dist/components/viewer/glb-walkthrough-controller.d.ts.map +1 -1
- package/dist/components/viewer/glb-walkthrough-controller.js +3 -4
- package/dist/components/viewer/live-walkthrough-controller.d.ts +17 -0
- package/dist/components/viewer/live-walkthrough-controller.d.ts.map +1 -0
- package/dist/components/viewer/live-walkthrough-controller.js +1449 -0
- package/dist/components/viewer/post-processing.d.ts.map +1 -1
- package/dist/components/viewer/post-processing.js +22 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/lib/daylight/room-map.d.ts +29 -4
- package/dist/lib/daylight/room-map.d.ts.map +1 -1
- package/dist/lib/daylight/room-map.js +219 -36
- package/dist/lib/daylight/room-scene.d.ts.map +1 -1
- package/dist/lib/daylight/room-scene.js +9 -3
- package/dist/lib/daylight/rooms.d.ts +15 -6
- package/dist/lib/daylight/rooms.d.ts.map +1 -1
- package/dist/lib/daylight/rooms.js +49 -9
- package/dist/lib/measurement-presentation.d.ts +2 -0
- package/dist/lib/measurement-presentation.d.ts.map +1 -1
- package/dist/lib/measurement-presentation.js +6 -0
- package/dist/lib/typing-target.d.ts +2 -0
- package/dist/lib/typing-target.d.ts.map +1 -0
- package/dist/lib/typing-target.js +7 -0
- package/dist/lib/viewer-config.d.ts +6 -0
- package/dist/lib/viewer-config.d.ts.map +1 -1
- package/dist/lib/viewer-config.js +2 -0
- package/dist/sfx/audio-settings.d.ts +81 -0
- package/dist/sfx/audio-settings.d.ts.map +1 -0
- package/dist/sfx/audio-settings.js +166 -0
- package/dist/sfx/index.d.ts +6 -0
- package/dist/sfx/index.d.ts.map +1 -0
- package/dist/sfx/index.js +5 -0
- package/dist/sfx/interaction-sounds.d.ts +7 -0
- package/dist/sfx/interaction-sounds.d.ts.map +1 -0
- package/dist/sfx/interaction-sounds.js +39 -0
- package/dist/sfx/player.d.ts +31 -0
- package/dist/sfx/player.d.ts.map +1 -0
- package/dist/sfx/player.js +255 -0
- package/dist/sfx/sounds.d.ts +60 -0
- package/dist/sfx/sounds.d.ts.map +1 -0
- package/dist/sfx/sounds.js +25 -0
- package/dist/sfx/use-viewer-ui-sounds.d.ts +8 -0
- package/dist/sfx/use-viewer-ui-sounds.d.ts.map +1 -0
- package/dist/sfx/use-viewer-ui-sounds.js +42 -0
- package/dist/store/use-first-person-hud.d.ts +13 -0
- package/dist/store/use-first-person-hud.d.ts.map +1 -0
- package/dist/store/use-first-person-hud.js +21 -0
- package/dist/systems/roof/roof-system.d.ts.map +1 -1
- package/dist/systems/roof/roof-system.js +27 -13
- package/dist/ui/components/action-button.d.ts +14 -0
- package/dist/ui/components/action-button.d.ts.map +1 -0
- package/dist/ui/components/action-button.js +21 -0
- package/dist/ui/components/action-menu-placement.d.ts +7 -0
- package/dist/ui/components/action-menu-placement.d.ts.map +1 -0
- package/dist/ui/components/action-menu-placement.js +10 -0
- package/dist/ui/components/floorplan-compass-button.d.ts +10 -0
- package/dist/ui/components/floorplan-compass-button.d.ts.map +1 -0
- package/dist/ui/components/floorplan-compass-button.js +22 -0
- package/dist/ui/components/follow-pascal-toggle.d.ts +6 -0
- package/dist/ui/components/follow-pascal-toggle.d.ts.map +1 -0
- package/dist/ui/components/follow-pascal-toggle.js +21 -0
- package/dist/ui/components/localized-html.d.ts +9 -0
- package/dist/ui/components/localized-html.d.ts.map +1 -0
- package/dist/ui/components/localized-html.js +16 -0
- package/dist/ui/components/render-settings-menu.d.ts +9 -0
- package/dist/ui/components/render-settings-menu.d.ts.map +1 -0
- package/dist/ui/components/render-settings-menu.js +145 -0
- package/dist/ui/components/rooms/room-highlight.d.ts +10 -0
- package/dist/ui/components/rooms/room-highlight.d.ts.map +1 -0
- package/dist/ui/components/rooms/room-highlight.js +56 -0
- package/dist/ui/components/rooms/room-labels.d.ts +278 -0
- package/dist/ui/components/rooms/room-labels.d.ts.map +1 -0
- package/dist/ui/components/rooms/room-labels.js +1295 -0
- package/dist/ui/components/rooms/viewer-rooms.d.ts +14 -0
- package/dist/ui/components/rooms/viewer-rooms.d.ts.map +1 -0
- package/dist/ui/components/rooms/viewer-rooms.js +123 -0
- package/dist/ui/components/scene-loader.d.ts +18 -0
- package/dist/ui/components/scene-loader.d.ts.map +1 -0
- package/dist/ui/components/scene-loader.js +29 -0
- package/dist/ui/components/sky-control.d.ts +37 -0
- package/dist/ui/components/sky-control.d.ts.map +1 -0
- package/dist/ui/components/sky-control.js +382 -0
- package/dist/ui/components/use-viewer-camera-navigation-sync.d.ts +4 -0
- package/dist/ui/components/use-viewer-camera-navigation-sync.d.ts.map +1 -0
- package/dist/ui/components/use-viewer-camera-navigation-sync.js +117 -0
- package/dist/ui/components/viewer-controls-bar.d.ts +20 -0
- package/dist/ui/components/viewer-controls-bar.d.ts.map +1 -0
- package/dist/ui/components/viewer-controls-bar.js +130 -0
- package/dist/ui/components/viewer-hover-label.d.ts +14 -0
- package/dist/ui/components/viewer-hover-label.d.ts.map +1 -0
- package/dist/ui/components/viewer-hover-label.js +28 -0
- package/dist/ui/components/viewer-scene-header.d.ts +34 -0
- package/dist/ui/components/viewer-scene-header.d.ts.map +1 -0
- package/dist/ui/components/viewer-scene-header.js +92 -0
- package/dist/ui/components/viewer-selection-manager.d.ts +7 -0
- package/dist/ui/components/viewer-selection-manager.d.ts.map +1 -0
- package/dist/ui/components/viewer-selection-manager.js +116 -0
- package/dist/ui/components/viewer-stage-modes.d.ts +7 -0
- package/dist/ui/components/viewer-stage-modes.d.ts.map +1 -0
- package/dist/ui/components/viewer-stage-modes.js +42 -0
- package/dist/ui/components/viewer-stage-switcher.d.ts +10 -0
- package/dist/ui/components/viewer-stage-switcher.d.ts.map +1 -0
- package/dist/ui/components/viewer-stage-switcher.js +16 -0
- package/dist/ui/components/viewer-stage.d.ts +25 -0
- package/dist/ui/components/viewer-stage.d.ts.map +1 -0
- package/dist/ui/components/viewer-stage.js +107 -0
- package/dist/ui/components/walkthrough-hud.d.ts +29 -0
- package/dist/ui/components/walkthrough-hud.d.ts.map +1 -0
- package/dist/ui/components/walkthrough-hud.js +55 -0
- package/dist/ui/floorplan/floorplan-camera-sync.d.ts +22 -0
- package/dist/ui/floorplan/floorplan-camera-sync.d.ts.map +1 -0
- package/dist/ui/floorplan/floorplan-camera-sync.js +157 -0
- package/dist/ui/floorplan/floorplan-dimension-renderer.d.ts +61 -0
- package/dist/ui/floorplan/floorplan-dimension-renderer.d.ts.map +1 -0
- package/dist/ui/floorplan/floorplan-dimension-renderer.js +280 -0
- package/dist/ui/floorplan/floorplan-geometry-renderer.d.ts +54 -0
- package/dist/ui/floorplan/floorplan-geometry-renderer.d.ts.map +1 -0
- package/dist/ui/floorplan/floorplan-geometry-renderer.js +317 -0
- package/dist/ui/floorplan/floorplan-label-angle.d.ts +24 -0
- package/dist/ui/floorplan/floorplan-label-angle.d.ts.map +1 -0
- package/dist/ui/floorplan/floorplan-label-angle.js +60 -0
- package/dist/ui/floorplan/floorplan-navigation-sync.d.ts +18 -0
- package/dist/ui/floorplan/floorplan-navigation-sync.d.ts.map +1 -0
- package/dist/ui/floorplan/floorplan-navigation-sync.js +41 -0
- package/dist/ui/floorplan/floorplan-preview-geometry.d.ts +26 -0
- package/dist/ui/floorplan/floorplan-preview-geometry.d.ts.map +1 -0
- package/dist/ui/floorplan/floorplan-preview-geometry.js +173 -0
- package/dist/ui/floorplan/floorplan-preview-navigation.d.ts +22 -0
- package/dist/ui/floorplan/floorplan-preview-navigation.d.ts.map +1 -0
- package/dist/ui/floorplan/floorplan-preview-navigation.js +41 -0
- package/dist/ui/floorplan/floorplan-preview-visibility.d.ts +8 -0
- package/dist/ui/floorplan/floorplan-preview-visibility.d.ts.map +1 -0
- package/dist/ui/floorplan/floorplan-preview-visibility.js +21 -0
- package/dist/ui/floorplan/floorplan-preview.d.ts +19 -0
- package/dist/ui/floorplan/floorplan-preview.d.ts.map +1 -0
- package/dist/ui/floorplan/floorplan-preview.js +700 -0
- package/dist/ui/hooks/use-mobile.d.ts +2 -0
- package/dist/ui/hooks/use-mobile.d.ts.map +1 -0
- package/dist/ui/hooks/use-mobile.js +14 -0
- package/dist/ui/index.d.ts +49 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +48 -0
- package/dist/ui/lib/below-grade.d.ts +38 -0
- package/dist/ui/lib/below-grade.d.ts.map +1 -0
- package/dist/ui/lib/below-grade.js +102 -0
- package/dist/ui/lib/camera-pose.d.ts +19 -0
- package/dist/ui/lib/camera-pose.d.ts.map +1 -0
- package/dist/ui/lib/camera-pose.js +113 -0
- package/dist/ui/lib/cn.d.ts +3 -0
- package/dist/ui/lib/cn.d.ts.map +1 -0
- package/dist/ui/lib/cn.js +5 -0
- package/dist/ui/lib/level-name.d.ts +10 -0
- package/dist/ui/lib/level-name.d.ts.map +1 -0
- package/dist/ui/lib/level-name.js +33 -0
- package/dist/ui/lib/node-display-label.d.ts +8 -0
- package/dist/ui/lib/node-display-label.d.ts.map +1 -0
- package/dist/ui/lib/node-display-label.js +36 -0
- package/dist/ui/lib/room-area.d.ts +3 -0
- package/dist/ui/lib/room-area.d.ts.map +1 -0
- package/dist/ui/lib/room-area.js +8 -0
- package/dist/ui/lib/room-assembly-overlay.d.ts +46 -0
- package/dist/ui/lib/room-assembly-overlay.d.ts.map +1 -0
- package/dist/ui/lib/room-assembly-overlay.js +222 -0
- package/dist/ui/lib/room-name-messages.d.ts +28 -0
- package/dist/ui/lib/room-name-messages.d.ts.map +1 -0
- package/dist/ui/lib/room-name-messages.js +112 -0
- package/dist/ui/lib/room-selection.d.ts +58 -0
- package/dist/ui/lib/room-selection.d.ts.map +1 -0
- package/dist/ui/lib/room-selection.js +297 -0
- package/dist/ui/lib/scene-theme-name.d.ts +4 -0
- package/dist/ui/lib/scene-theme-name.d.ts.map +1 -0
- package/dist/ui/lib/scene-theme-name.js +22 -0
- package/dist/ui/lib/selection-modifiers.d.ts +20 -0
- package/dist/ui/lib/selection-modifiers.d.ts.map +1 -0
- package/dist/ui/lib/selection-modifiers.js +15 -0
- package/dist/ui/lib/viewer-selection.d.ts +132 -0
- package/dist/ui/lib/viewer-selection.d.ts.map +1 -0
- package/dist/ui/lib/viewer-selection.js +462 -0
- package/dist/ui/lib/zone-content.d.ts +6 -0
- package/dist/ui/lib/zone-content.d.ts.map +1 -0
- package/dist/ui/lib/zone-content.js +96 -0
- package/dist/ui/primitives/button.d.ts +11 -0
- package/dist/ui/primitives/button.d.ts.map +1 -0
- package/dist/ui/primitives/button.js +35 -0
- package/dist/ui/primitives/dropdown-menu.d.ts +26 -0
- package/dist/ui/primitives/dropdown-menu.d.ts.map +1 -0
- package/dist/ui/primitives/dropdown-menu.js +53 -0
- package/dist/ui/primitives/popover.d.ts +8 -0
- package/dist/ui/primitives/popover.d.ts.map +1 -0
- package/dist/ui/primitives/popover.js +17 -0
- package/dist/ui/primitives/switch.d.ts +5 -0
- package/dist/ui/primitives/switch.d.ts.map +1 -0
- package/dist/ui/primitives/switch.js +8 -0
- package/dist/ui/primitives/tooltip.d.ts +8 -0
- package/dist/ui/primitives/tooltip.d.ts.map +1 -0
- package/dist/ui/primitives/tooltip.js +17 -0
- package/dist/ui/store/camera-pose-store.d.ts +17 -0
- package/dist/ui/store/camera-pose-store.d.ts.map +1 -0
- package/dist/ui/store/camera-pose-store.js +15 -0
- package/dist/ui/store/navigation-sync-pose-store.d.ts +26 -0
- package/dist/ui/store/navigation-sync-pose-store.d.ts.map +1 -0
- package/dist/ui/store/navigation-sync-pose-store.js +16 -0
- package/dist/ui/store/use-follow-pascal.d.ts +30 -0
- package/dist/ui/store/use-follow-pascal.d.ts.map +1 -0
- package/dist/ui/store/use-follow-pascal.js +28 -0
- package/dist/ui/theme.css +339 -0
- package/package.json +34 -7
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
import { area, containsPoint, createRoomTopologyIndex, getWallArcData, getWallFaceOffsets, roomClearPolygon, } from '@pascal-app/core';
|
|
2
|
+
import { polygonMatchesZoneFootprint } from './zone-content';
|
|
3
|
+
export function sameRoom(a, b) {
|
|
4
|
+
return a === b || (!!a && !!b && a.levelId === b.levelId && a.zoneId === b.zoneId);
|
|
5
|
+
}
|
|
6
|
+
export function shouldSelectRoom(selected, hit, modifiers) {
|
|
7
|
+
return (!!hit &&
|
|
8
|
+
!sameRoom(selected, hit) &&
|
|
9
|
+
!(modifiers.alt || modifiers.shift || modifiers.ctrl || modifiers.meta));
|
|
10
|
+
}
|
|
11
|
+
function describeRoomGeometry(levelId, room, zone) {
|
|
12
|
+
const clearPolygon = roomClearPolygon(room);
|
|
13
|
+
return {
|
|
14
|
+
...room,
|
|
15
|
+
key: { levelId, zoneId: zone.id },
|
|
16
|
+
boundaryWallIds: [
|
|
17
|
+
...new Set(room.spans.filter((span) => span.kind === 'wall').map((span) => span.boundaryId)),
|
|
18
|
+
],
|
|
19
|
+
clearPolygon,
|
|
20
|
+
area: area([{ outer: zone.polygon, holes: zone.holes }]),
|
|
21
|
+
hitPolygon: [{ outer: room.polygon, holes: room.holes }],
|
|
22
|
+
mezzanine: null,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export function isMezzanineZone(node) {
|
|
26
|
+
return node?.type === 'zone' && node.floor?.support === 'open';
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* A mezzanine as a selectable room. It has no walls of its own: its outline is
|
|
30
|
+
* the zone's polygon, its floor the zone's own plate, and it bounds nothing.
|
|
31
|
+
*/
|
|
32
|
+
function describeMezzanineGeometry(levelId, zone, context) {
|
|
33
|
+
const polygon = zone.polygon.map(([x, z]) => [x, z]);
|
|
34
|
+
const holes = (zone.holes ?? []).map((ring) => ring.map(([x, z]) => [x, z]));
|
|
35
|
+
const outline = [{ outer: polygon, holes }];
|
|
36
|
+
return {
|
|
37
|
+
id: `mezzanine:${zone.id}`,
|
|
38
|
+
polygon,
|
|
39
|
+
holes,
|
|
40
|
+
spans: [],
|
|
41
|
+
context,
|
|
42
|
+
key: { levelId, zoneId: zone.id },
|
|
43
|
+
boundaryWallIds: [],
|
|
44
|
+
clearPolygon: outline,
|
|
45
|
+
area: area(outline),
|
|
46
|
+
hitPolygon: outline,
|
|
47
|
+
mezzanine: { hostZoneId: zone.hostZoneId ?? '' },
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
const NO_WALLS = {
|
|
51
|
+
revision: -1,
|
|
52
|
+
walls: new Map(),
|
|
53
|
+
wallFootprints: new Map(),
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* A zone that bounds no room (a drawn area), outlined the way a room is: its
|
|
57
|
+
* polygon as the floor, no walls of its own.
|
|
58
|
+
*/
|
|
59
|
+
export function describeZoneOutline(levelId, zone) {
|
|
60
|
+
const geometry = {
|
|
61
|
+
...describeMezzanineGeometry(levelId, zone, NO_WALLS),
|
|
62
|
+
id: `zone:${zone.id}`,
|
|
63
|
+
mezzanine: null,
|
|
64
|
+
};
|
|
65
|
+
return {
|
|
66
|
+
...geometry,
|
|
67
|
+
geometry,
|
|
68
|
+
name: zone.name || 'Zone',
|
|
69
|
+
zoneId: zone.id,
|
|
70
|
+
slabId: null,
|
|
71
|
+
slabName: null,
|
|
72
|
+
ceilingId: null,
|
|
73
|
+
ceilingName: null,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
function describeRoom(geometry, candidates) {
|
|
77
|
+
const { clearPolygon } = geometry;
|
|
78
|
+
const matches = (node) => (node.type === 'zone' || node.type === 'slab' || node.type === 'ceiling') &&
|
|
79
|
+
(polygonMatchesZoneFootprint(node.polygon, geometry.polygon) ||
|
|
80
|
+
clearPolygon.some(({ outer }) => polygonMatchesZoneFootprint(node.polygon, outer)));
|
|
81
|
+
const slab = geometry.mezzanine
|
|
82
|
+
? candidates.find((node) => node.type === 'slab' &&
|
|
83
|
+
node.support === 'open' &&
|
|
84
|
+
!!node.zoneIds?.includes(geometry.key.zoneId))
|
|
85
|
+
: candidates.find((node) => node.type === 'slab' && node.support !== 'open' && node.autoFromWalls && matches(node));
|
|
86
|
+
const ceiling = candidates.find((node) => node.type === 'ceiling' && node.zoneId === geometry.key.zoneId);
|
|
87
|
+
const zone = candidates.find((node) => node.type === 'zone' && node.id === geometry.key.zoneId);
|
|
88
|
+
return {
|
|
89
|
+
...geometry,
|
|
90
|
+
geometry,
|
|
91
|
+
name: zone.name || 'Room',
|
|
92
|
+
area: area([{ outer: zone.polygon, holes: zone.holes }]),
|
|
93
|
+
zoneId: zone.id,
|
|
94
|
+
slabId: slab?.id ?? null,
|
|
95
|
+
slabName: slab ? slab.name || 'Slab' : null,
|
|
96
|
+
ceilingId: ceiling?.id ?? null,
|
|
97
|
+
ceilingName: ceiling ? ceiling.name || 'Ceiling' : null,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
const wallFrames = new WeakMap();
|
|
101
|
+
function wallHitFrame(wall) {
|
|
102
|
+
const dx = wall.end[0] - wall.start[0];
|
|
103
|
+
const dz = wall.end[1] - wall.start[1];
|
|
104
|
+
const length = Math.hypot(dx, dz);
|
|
105
|
+
const offsets = getWallFaceOffsets(wall);
|
|
106
|
+
return {
|
|
107
|
+
dx,
|
|
108
|
+
dz,
|
|
109
|
+
lengthSq: length * length,
|
|
110
|
+
nx: -dz / length,
|
|
111
|
+
nz: dx / length,
|
|
112
|
+
arc: getWallArcData(wall),
|
|
113
|
+
center: (offsets.a + offsets.b) / 2,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
export function resolveRoomHit(index, levelId, node, point, view = '2d') {
|
|
117
|
+
// A mezzanine's plate (railing included) and ceiling name their own room; the
|
|
118
|
+
// host floor under it and every other surface resolve by the point, which
|
|
119
|
+
// never lands in a mezzanine.
|
|
120
|
+
if (node?.type === 'slab' && node.support === 'open')
|
|
121
|
+
return index.roomForZone?.(levelId, node.zoneIds?.[0] ?? '') ?? null;
|
|
122
|
+
if (node?.type === 'ceiling' && node.zoneId) {
|
|
123
|
+
const own = index.roomForZone?.(levelId, node.zoneId);
|
|
124
|
+
if (own)
|
|
125
|
+
return own;
|
|
126
|
+
}
|
|
127
|
+
if (!node || node.type === 'slab' || node.type === 'ceiling')
|
|
128
|
+
return index.roomAtPoint(levelId, point);
|
|
129
|
+
if (node.type !== 'wall')
|
|
130
|
+
return null;
|
|
131
|
+
let frame = wallFrames.get(node);
|
|
132
|
+
if (!frame) {
|
|
133
|
+
frame = wallHitFrame(node);
|
|
134
|
+
wallFrames.set(node, frame);
|
|
135
|
+
}
|
|
136
|
+
const { dx, dz, lengthSq, arc } = frame;
|
|
137
|
+
if (!lengthSq)
|
|
138
|
+
return null;
|
|
139
|
+
const station = Math.max(0, Math.min(1, ((point[0] - node.start[0]) * dx + (point[1] - node.start[1]) * dz) / lengthSq));
|
|
140
|
+
let x = node.start[0] + station * dx;
|
|
141
|
+
let z = node.start[1] + station * dz;
|
|
142
|
+
let nx = frame.nx;
|
|
143
|
+
let nz = frame.nz;
|
|
144
|
+
if (arc) {
|
|
145
|
+
const angle = Math.atan2(point[1] - arc.center.y, point[0] - arc.center.x);
|
|
146
|
+
const delta = Math.atan2(Math.sin(angle - arc.startAngle), Math.cos(angle - arc.startAngle));
|
|
147
|
+
const t = Math.max(0, Math.min(1, delta / arc.delta));
|
|
148
|
+
const theta = arc.startAngle + arc.delta * t;
|
|
149
|
+
const cos = Math.cos(theta);
|
|
150
|
+
const sin = Math.sin(theta);
|
|
151
|
+
x = arc.center.x + cos * arc.radius;
|
|
152
|
+
z = arc.center.y + sin * arc.radius;
|
|
153
|
+
nx = -cos * arc.direction;
|
|
154
|
+
nz = -sin * arc.direction;
|
|
155
|
+
}
|
|
156
|
+
const localZ = (point[0] - x) * nx + (point[1] - z) * nz;
|
|
157
|
+
// Justified bodies can lie entirely on one side of the reference line.
|
|
158
|
+
const center = view === '3d' ? frame.center : 0;
|
|
159
|
+
const face = localZ >= center ? 'a' : 'b';
|
|
160
|
+
// Room first: a face with no room behind it (the exterior) still resolves
|
|
161
|
+
// to the room on the other face, or to the wall's only room; only walls
|
|
162
|
+
// bounding no room reach the wall itself.
|
|
163
|
+
return (index.roomForWallHit(levelId, node.id, face, station) ??
|
|
164
|
+
index.roomForWallHit(levelId, node.id, face === 'a' ? 'b' : 'a', station) ??
|
|
165
|
+
soleWallRoom(index, levelId, node.id));
|
|
166
|
+
}
|
|
167
|
+
function soleWallRoom(index, levelId, wallId) {
|
|
168
|
+
let sole = null;
|
|
169
|
+
for (const span of index.spansForWall(levelId, wallId)) {
|
|
170
|
+
if (sole && sole.roomId !== span.roomId)
|
|
171
|
+
return null;
|
|
172
|
+
sole ??= span;
|
|
173
|
+
}
|
|
174
|
+
return sole && index.roomForWallHit(levelId, wallId, sole.face, (sole.t0 + sole.t1) / 2);
|
|
175
|
+
}
|
|
176
|
+
function isBoundary(node) {
|
|
177
|
+
return node.type === 'wall' || node.type === 'separator';
|
|
178
|
+
}
|
|
179
|
+
function sameBoundary(a, b) {
|
|
180
|
+
return (!!b &&
|
|
181
|
+
isBoundary(b) &&
|
|
182
|
+
a.type === b.type &&
|
|
183
|
+
a.parentId === b.parentId &&
|
|
184
|
+
a.start[0] === b.start[0] &&
|
|
185
|
+
a.start[1] === b.start[1] &&
|
|
186
|
+
a.end[0] === b.end[0] &&
|
|
187
|
+
a.end[1] === b.end[1] &&
|
|
188
|
+
(a.type === 'separator' ||
|
|
189
|
+
(b.type === 'wall' &&
|
|
190
|
+
a.curveOffset === b.curveOffset &&
|
|
191
|
+
a.thickness === b.thickness &&
|
|
192
|
+
a.justification === b.justification)));
|
|
193
|
+
}
|
|
194
|
+
export class RoomSelectionIndex {
|
|
195
|
+
levelId;
|
|
196
|
+
topology = createRoomTopologyIndex();
|
|
197
|
+
nodes = null;
|
|
198
|
+
records = [];
|
|
199
|
+
geometry = [];
|
|
200
|
+
candidates = [];
|
|
201
|
+
revision = -1;
|
|
202
|
+
roomsById = new Map();
|
|
203
|
+
roomAtPoint(_levelId, point) {
|
|
204
|
+
for (const room of this.geometry)
|
|
205
|
+
if (!room.mezzanine && containsPoint(room.hitPolygon, point))
|
|
206
|
+
return room;
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
roomForZone(_levelId, zoneId) {
|
|
210
|
+
return this.geometry.find((room) => room.key.zoneId === zoneId) ?? null;
|
|
211
|
+
}
|
|
212
|
+
roomForWallHit(levelId, wallId, face, t) {
|
|
213
|
+
const spans = this.topology.getLevelTopology(levelId)?.spansByBoundary.get(wallId);
|
|
214
|
+
if (!spans)
|
|
215
|
+
return null;
|
|
216
|
+
for (const span of spans) {
|
|
217
|
+
if (span.face === face && t >= span.t0 && (t < span.t1 || (t === 1 && span.t1 === 1)))
|
|
218
|
+
return this.roomsById.get(span.roomId) ?? null;
|
|
219
|
+
}
|
|
220
|
+
return null;
|
|
221
|
+
}
|
|
222
|
+
spansForWall(levelId, wallId) {
|
|
223
|
+
return this.topology.spansForWall(levelId, wallId);
|
|
224
|
+
}
|
|
225
|
+
constructor(levelId) {
|
|
226
|
+
this.levelId = levelId;
|
|
227
|
+
}
|
|
228
|
+
update(nodes) {
|
|
229
|
+
if (nodes === this.nodes)
|
|
230
|
+
return this.records;
|
|
231
|
+
if (!this.nodes)
|
|
232
|
+
this.topology.rebuildLevel(this.levelId, nodes);
|
|
233
|
+
else {
|
|
234
|
+
const changed = new Set();
|
|
235
|
+
for (const snapshot of [this.nodes, nodes]) {
|
|
236
|
+
for (const node of Object.values(snapshot)) {
|
|
237
|
+
if (isBoundary(node) &&
|
|
238
|
+
node.parentId === this.levelId &&
|
|
239
|
+
!sameBoundary(node, snapshot === nodes ? this.nodes[node.id] : nodes[node.id]))
|
|
240
|
+
changed.add(node.id);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
if (changed.size)
|
|
244
|
+
this.topology.applyWallDelta(this.levelId, changed, this.nodes, nodes);
|
|
245
|
+
}
|
|
246
|
+
this.nodes = nodes;
|
|
247
|
+
const topology = this.topology.getLevelTopology(this.levelId);
|
|
248
|
+
const geometryChanged = topology?.revision !== this.revision;
|
|
249
|
+
const candidates = Object.values(nodes).filter((node) => node.parentId === this.levelId &&
|
|
250
|
+
(node.type === 'slab' || node.type === 'ceiling' || node.type === 'zone'));
|
|
251
|
+
const candidatesChanged = candidates.length !== this.candidates.length ||
|
|
252
|
+
candidates.some((node, i) => node !== this.candidates[i]);
|
|
253
|
+
if (!geometryChanged && !candidatesChanged)
|
|
254
|
+
return this.records;
|
|
255
|
+
if (geometryChanged || candidatesChanged) {
|
|
256
|
+
this.revision = topology?.revision ?? -1;
|
|
257
|
+
const previous = new Map(this.geometry.map((room) => [room.key.zoneId, room]));
|
|
258
|
+
const matched = new Set();
|
|
259
|
+
const zones = candidates
|
|
260
|
+
.filter((node) => node.type === 'zone' &&
|
|
261
|
+
node.spaceRole === 'room' &&
|
|
262
|
+
node.enclosureStatus !== 'open' &&
|
|
263
|
+
!isMezzanineZone(node))
|
|
264
|
+
.sort((a, b) => a.id.localeCompare(b.id));
|
|
265
|
+
this.geometry = (topology?.rooms ?? []).flatMap((room) => {
|
|
266
|
+
const boundaryIds = [...new Set(room.spans.map((span) => span.boundaryId))].sort().join('|');
|
|
267
|
+
const available = zones.filter((zone) => !matched.has(zone.id));
|
|
268
|
+
const zone = available.find((node) => [...node.boundaryWallIds, ...node.boundarySeparatorIds].sort().join('|') ===
|
|
269
|
+
boundaryIds) ??
|
|
270
|
+
available.find((node) => !!node.seed && containsPoint([{ outer: room.polygon, holes: room.holes }], node.seed));
|
|
271
|
+
if (!zone)
|
|
272
|
+
return [];
|
|
273
|
+
matched.add(zone.id);
|
|
274
|
+
return [
|
|
275
|
+
(!geometryChanged && previous.get(zone.id)) ||
|
|
276
|
+
describeRoomGeometry(this.levelId, room, zone),
|
|
277
|
+
];
|
|
278
|
+
});
|
|
279
|
+
const context = topology?.rooms[0]?.context;
|
|
280
|
+
if (context)
|
|
281
|
+
for (const zone of candidates) {
|
|
282
|
+
if (!isMezzanineZone(zone) || zone.spaceRole !== 'room')
|
|
283
|
+
continue;
|
|
284
|
+
const hosted = zone.hostZoneId && this.geometry.some((room) => room.key.zoneId === zone.hostZoneId);
|
|
285
|
+
if (!hosted)
|
|
286
|
+
continue;
|
|
287
|
+
this.geometry.push(describeMezzanineGeometry(this.levelId, zone, context));
|
|
288
|
+
}
|
|
289
|
+
this.roomsById.clear();
|
|
290
|
+
for (const room of this.geometry)
|
|
291
|
+
this.roomsById.set(room.id, room);
|
|
292
|
+
}
|
|
293
|
+
this.candidates = candidates;
|
|
294
|
+
this.records = this.geometry.map((room) => describeRoom(room, candidates));
|
|
295
|
+
return this.records;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { PascalI18n } from '@pascal-app/core';
|
|
2
|
+
/** Display name of a built-in scene theme; unknown (plugin) themes keep their own name. */
|
|
3
|
+
export declare function sceneThemeName(id: string, fallback: string, i18n: PascalI18n): string;
|
|
4
|
+
//# sourceMappingURL=scene-theme-name.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scene-theme-name.d.ts","sourceRoot":"","sources":["../../../src/ui/lib/scene-theme-name.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAElD,2FAA2F;AAC3F,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,MAAM,CAYrF"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** Display name of a built-in scene theme; unknown (plugin) themes keep their own name. */
|
|
2
|
+
export function sceneThemeName(id, fallback, i18n) {
|
|
3
|
+
if (id === 'studio')
|
|
4
|
+
return i18n._({ id: 'viewer.theme.studio', message: 'Studio' });
|
|
5
|
+
if (id === 'paper')
|
|
6
|
+
return i18n._({ id: 'viewer.theme.paper', message: 'Paper' });
|
|
7
|
+
if (id === 'sunset')
|
|
8
|
+
return i18n._({ id: 'viewer.theme.sunset', message: 'Sunset' });
|
|
9
|
+
if (id === 'overcast')
|
|
10
|
+
return i18n._({ id: 'viewer.theme.overcast', message: 'Overcast' });
|
|
11
|
+
if (id === 'blueprint')
|
|
12
|
+
return i18n._({ id: 'viewer.theme.blueprint', message: 'Blueprint' });
|
|
13
|
+
if (id === 'mediterranean')
|
|
14
|
+
return i18n._({ id: 'viewer.theme.mediterranean', message: 'Mediterranean' });
|
|
15
|
+
if (id === 'twilight')
|
|
16
|
+
return i18n._({ id: 'viewer.theme.twilight', message: 'Twilight' });
|
|
17
|
+
if (id === 'night')
|
|
18
|
+
return i18n._({ id: 'viewer.theme.night', message: 'Night' });
|
|
19
|
+
if (id === 'verdant')
|
|
20
|
+
return i18n._({ id: 'viewer.theme.verdant', message: 'Verdant' });
|
|
21
|
+
return fallback;
|
|
22
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type SelectionModifierKeys = {
|
|
2
|
+
meta: boolean;
|
|
3
|
+
ctrl: boolean;
|
|
4
|
+
shift: boolean;
|
|
5
|
+
/** Alt alone: select one session-group member without expanding. */
|
|
6
|
+
alt: boolean;
|
|
7
|
+
};
|
|
8
|
+
export declare function selectionModifiersFromEvent(event?: {
|
|
9
|
+
metaKey?: boolean;
|
|
10
|
+
ctrlKey?: boolean;
|
|
11
|
+
shiftKey?: boolean;
|
|
12
|
+
altKey?: boolean;
|
|
13
|
+
nativeEvent?: {
|
|
14
|
+
metaKey?: boolean;
|
|
15
|
+
ctrlKey?: boolean;
|
|
16
|
+
shiftKey?: boolean;
|
|
17
|
+
altKey?: boolean;
|
|
18
|
+
};
|
|
19
|
+
} | null, fallback?: Partial<SelectionModifierKeys>): SelectionModifierKeys;
|
|
20
|
+
//# sourceMappingURL=selection-modifiers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selection-modifiers.d.ts","sourceRoot":"","sources":["../../../src/ui/lib/selection-modifiers.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,qBAAqB,GAAG;IAClC,IAAI,EAAE,OAAO,CAAA;IACb,IAAI,EAAE,OAAO,CAAA;IACb,KAAK,EAAE,OAAO,CAAA;IACd,oEAAoE;IACpE,GAAG,EAAE,OAAO,CAAA;CACb,CAAA;AAED,wBAAgB,2BAA2B,CACzC,KAAK,CAAC,EAAE;IACN,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,WAAW,CAAC,EAAE;QACZ,OAAO,CAAC,EAAE,OAAO,CAAA;QACjB,OAAO,CAAC,EAAE,OAAO,CAAA;QACjB,QAAQ,CAAC,EAAE,OAAO,CAAA;QAClB,MAAM,CAAC,EAAE,OAAO,CAAA;KACjB,CAAA;CACF,GAAG,IAAI,EACR,QAAQ,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,GACxC,qBAAqB,CAgBvB"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export function selectionModifiersFromEvent(event, fallback) {
|
|
2
|
+
const fromEvent = (key, eventKey) => {
|
|
3
|
+
if (typeof event?.[eventKey] === 'boolean')
|
|
4
|
+
return event[eventKey];
|
|
5
|
+
if (typeof event?.nativeEvent?.[eventKey] === 'boolean')
|
|
6
|
+
return event.nativeEvent[eventKey];
|
|
7
|
+
return Boolean(fallback?.[key]);
|
|
8
|
+
};
|
|
9
|
+
return {
|
|
10
|
+
meta: fromEvent('meta', 'metaKey'),
|
|
11
|
+
ctrl: fromEvent('ctrl', 'ctrlKey'),
|
|
12
|
+
shift: fromEvent('shift', 'shiftKey'),
|
|
13
|
+
alt: fromEvent('alt', 'altKey'),
|
|
14
|
+
};
|
|
15
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { type AnyNode, type BuildingNode, type CameraControlFrameEvent, type LevelNode, type NodeEvent, type ZoneNode } from '@pascal-app/core';
|
|
2
|
+
import type { CameraControlsImpl } from '@react-three/drei';
|
|
3
|
+
import { type Camera, type Object3D } from 'three';
|
|
4
|
+
import { type DescriptorTranslator } from './room-name-messages';
|
|
5
|
+
import { type RoomSelectionRecord } from './room-selection';
|
|
6
|
+
import type { SelectionModifierKeys } from './selection-modifiers';
|
|
7
|
+
export type ViewerNodes = Readonly<Record<string, AnyNode>>;
|
|
8
|
+
/** The scene a viewer surface shows: its graph, and the 3D object standing for an id. */
|
|
9
|
+
export type ViewerSource = {
|
|
10
|
+
nodes: ViewerNodes;
|
|
11
|
+
objectFor: (id: string) => Object3D | undefined;
|
|
12
|
+
};
|
|
13
|
+
/** A pointer hit, whichever renderer took it: the node and the hit in its level's local XZ. */
|
|
14
|
+
export type ViewerPick = {
|
|
15
|
+
nodeId: string;
|
|
16
|
+
point: readonly [number, number] | null;
|
|
17
|
+
};
|
|
18
|
+
export type ViewerSelection = {
|
|
19
|
+
buildingId: BuildingNode['id'] | null;
|
|
20
|
+
levelId: LevelNode['id'] | null;
|
|
21
|
+
zoneId: ZoneNode['id'] | null;
|
|
22
|
+
selectedIds: string[];
|
|
23
|
+
};
|
|
24
|
+
type ViewerTarget = {
|
|
25
|
+
kind: 'room';
|
|
26
|
+
levelId: string;
|
|
27
|
+
zoneId: string;
|
|
28
|
+
} | {
|
|
29
|
+
kind: 'node';
|
|
30
|
+
levelId: string | null;
|
|
31
|
+
nodeId: string;
|
|
32
|
+
zoneId: string | null;
|
|
33
|
+
};
|
|
34
|
+
/** Kinds a viewer click never lands on: they pass the pointer to what lies behind. */
|
|
35
|
+
export declare const VIEWER_PASS_THROUGH_KINDS: ReadonlySet<string>;
|
|
36
|
+
/** The rooms the walls of a level close, as the editor detects them. */
|
|
37
|
+
export declare function viewerRooms(levelId: string, nodes: ViewerNodes): RoomSelectionRecord[];
|
|
38
|
+
export declare function levelOfNode(nodeId: string, nodes: ViewerNodes): string | null;
|
|
39
|
+
/**
|
|
40
|
+
* The parametric hit source: a node event as a pick, with the hit in its
|
|
41
|
+
* level's local XZ. A hit on a hidden floor, or on a kind a click passes
|
|
42
|
+
* through, is no pick: the pointer goes on to what lies behind it.
|
|
43
|
+
*/
|
|
44
|
+
export declare function viewerPickFromNodeEvent(event: NodeEvent, nodes: ViewerNodes): ViewerPick | null;
|
|
45
|
+
/**
|
|
46
|
+
* What a pick acts on. A wall, floor or ceiling picks the room it bounds;
|
|
47
|
+
* once that room is selected, its own surfaces are picked as themselves.
|
|
48
|
+
* Anything else (an item, a door, a stair) is picked directly. Alt, Shift,
|
|
49
|
+
* Ctrl and Meta skip the room, as in the editor.
|
|
50
|
+
*/
|
|
51
|
+
export declare function resolveViewerTarget(selection: Pick<ViewerSelection, 'zoneId'>, pick: ViewerPick, nodes: ViewerNodes, modifiers?: SelectionModifierKeys): ViewerTarget | null;
|
|
52
|
+
/**
|
|
53
|
+
* The selection a click makes. Empty space clears the room and the element
|
|
54
|
+
* and keeps the floor; nothing pops the user up a level.
|
|
55
|
+
*/
|
|
56
|
+
export declare function resolveViewerClick(selection: ViewerSelection, pick: ViewerPick | null, nodes: ViewerNodes, modifiers?: SelectionModifierKeys): ViewerSelection;
|
|
57
|
+
/** What a hover would select: a room's id (its highlight) or the element's (its outline). */
|
|
58
|
+
export declare function resolveViewerHover(selection: Pick<ViewerSelection, 'zoneId'>, pick: ViewerPick | null, nodes: ViewerNodes): string | null;
|
|
59
|
+
/**
|
|
60
|
+
* The current floor reads as the editor shows it: the levels above it step
|
|
61
|
+
* aside (in the stacked display) so its rooms are in view and in reach, and the
|
|
62
|
+
* ground is veiled over it when it lies below grade. Mount it in the surface's DOM tree,
|
|
63
|
+
* beside the editor's own level display, so one hands the flag to the other in
|
|
64
|
+
* order.
|
|
65
|
+
*/
|
|
66
|
+
export declare function useViewerFloorDisplay(): void;
|
|
67
|
+
export declare function applyViewerClick(pick: ViewerPick | null, nodes: ViewerNodes, modifiers?: SelectionModifierKeys): void;
|
|
68
|
+
export declare function applyViewerHover(pick: ViewerPick | null, nodes: ViewerNodes): void;
|
|
69
|
+
/** A floor from the floor list: the floor alone, framed. */
|
|
70
|
+
export declare function selectViewerLevel(levelId: string, source: ViewerSource): void;
|
|
71
|
+
/** The whole building again, framed. */
|
|
72
|
+
export declare function selectViewerBuilding(source: ViewerSource): void;
|
|
73
|
+
/** A room or zone from its pill, the bar or the sidebar: selected on its floor, framed. */
|
|
74
|
+
export declare function selectViewerRoom(zoneId: string, source: ViewerSource): void;
|
|
75
|
+
/**
|
|
76
|
+
* A unit from the sidebar: its rooms highlighted and framed. The floor stays
|
|
77
|
+
* when it holds one of the unit's rooms, else the unit's lowest floor shows.
|
|
78
|
+
*/
|
|
79
|
+
export declare function selectViewerUnit(unitId: string, source: ViewerSource): void;
|
|
80
|
+
/** Framing glides to its pose, or jumps there when the person asks for reduced motion. */
|
|
81
|
+
export declare function framingAnimates(): boolean;
|
|
82
|
+
export declare function frameViewerNode(id: string, source: ViewerSource): void;
|
|
83
|
+
type Vec3 = [number, number, number];
|
|
84
|
+
/**
|
|
85
|
+
* Where a camera frames a box: about 45° above it, far enough for the box to
|
|
86
|
+
* fill the view, along the heading the camera already has so the scene does
|
|
87
|
+
* not swing round.
|
|
88
|
+
*/
|
|
89
|
+
export declare function framedLookAt(event: CameraControlFrameEvent, from: {
|
|
90
|
+
position: Vec3;
|
|
91
|
+
target: Vec3;
|
|
92
|
+
}, fovDegrees?: number): {
|
|
93
|
+
position: Vec3;
|
|
94
|
+
target: Vec3;
|
|
95
|
+
} | null;
|
|
96
|
+
/** Apply the shared framing pose, fitting the orthographic viewport as well. */
|
|
97
|
+
export declare function frameViewerCamera(control: CameraControlsImpl, camera: Camera, event: CameraControlFrameEvent): void;
|
|
98
|
+
export type ViewerCrumb = {
|
|
99
|
+
kind: 'building' | 'level' | 'unit' | 'room' | 'node';
|
|
100
|
+
id: string;
|
|
101
|
+
label: string;
|
|
102
|
+
};
|
|
103
|
+
/**
|
|
104
|
+
* The viewer chrome's name for a zone, in the editor's UI language (the scene
|
|
105
|
+
* keeps its stored name). `i18n` is the caller's scoped `usePascalI18n()`.
|
|
106
|
+
*/
|
|
107
|
+
export declare function zoneLabel(zone: ZoneNode, i18n: DescriptorTranslator): string;
|
|
108
|
+
/**
|
|
109
|
+
* The bar: building › floor › room › element. An element inside a room shows
|
|
110
|
+
* that room (`roomOf`) without selecting it; a focused unit stands where the
|
|
111
|
+
* room would.
|
|
112
|
+
*/
|
|
113
|
+
export declare function viewerBreadcrumb(selection: ViewerSelection, focusedUnitId: string | null, nodes: ViewerNodes, i18n: DescriptorTranslator, roomOf?: (nodeId: string, levelId: string) => string | null): ViewerCrumb[];
|
|
114
|
+
/** The room an element stands in, from where its object sits on its floor. */
|
|
115
|
+
export declare function roomOfObject(nodeId: string, levelId: string, source: ViewerSource): string | null;
|
|
116
|
+
export type ViewerSidebarRow = {
|
|
117
|
+
id: string;
|
|
118
|
+
label: string;
|
|
119
|
+
color: string;
|
|
120
|
+
areaM2: number;
|
|
121
|
+
};
|
|
122
|
+
export type ViewerSidebarSection = {
|
|
123
|
+
kind: 'units' | 'rooms' | 'zones';
|
|
124
|
+
rows: ViewerSidebarRow[];
|
|
125
|
+
};
|
|
126
|
+
/**
|
|
127
|
+
* What sits under the current floor: its units, its rooms, its other zones.
|
|
128
|
+
* An empty section is left out.
|
|
129
|
+
*/
|
|
130
|
+
export declare function viewerSidebarSections(levelId: string, nodes: ViewerNodes, i18n: DescriptorTranslator): ViewerSidebarSection[];
|
|
131
|
+
export {};
|
|
132
|
+
//# sourceMappingURL=viewer-selection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viewer-selection.d.ts","sourceRoot":"","sources":["../../../src/ui/lib/viewer-selection.ts"],"names":[],"mappings":"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"}
|