@pascal-app/viewer 1.0.3 → 1.0.4
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/components/renderers/node-renderer.d.ts.map +1 -1
- package/dist/components/renderers/node-renderer.js +8 -3
- package/dist/components/viewer/frame-limiter.d.ts +1 -0
- package/dist/components/viewer/frame-limiter.d.ts.map +1 -1
- package/dist/components/viewer/frame-limiter.js +22 -3
- package/dist/components/viewer/glb-interactive.d.ts +25 -1
- package/dist/components/viewer/glb-interactive.d.ts.map +1 -1
- package/dist/components/viewer/glb-interactive.js +252 -85
- package/dist/components/viewer/glb-mechanisms.d.ts +10 -0
- package/dist/components/viewer/glb-mechanisms.d.ts.map +1 -0
- package/dist/components/viewer/glb-mechanisms.js +19 -0
- package/dist/components/viewer/glb-scene.d.ts +45 -27
- package/dist/components/viewer/glb-scene.d.ts.map +1 -1
- package/dist/components/viewer/glb-scene.js +420 -506
- 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 +12 -1
- package/dist/components/viewer/index.d.ts +14 -0
- package/dist/components/viewer/index.d.ts.map +1 -1
- package/dist/components/viewer/index.js +84 -26
- package/dist/components/viewer/lights.d.ts.map +1 -1
- package/dist/components/viewer/lights.js +6 -1
- package/dist/components/viewer/perf-monitor.d.ts.map +1 -1
- package/dist/components/viewer/perf-monitor.js +6 -0
- package/dist/components/viewer/post-processing.d.ts.map +1 -1
- package/dist/components/viewer/post-processing.js +8 -3
- package/dist/components/viewer/registered-systems.d.ts.map +1 -1
- package/dist/components/viewer/registered-systems.js +16 -2
- package/dist/components/viewer/render-error.d.ts +18 -0
- package/dist/components/viewer/render-error.d.ts.map +1 -0
- package/dist/components/viewer/render-error.js +29 -0
- package/dist/components/viewer/scene-ground-replacement.d.ts +6 -0
- package/dist/components/viewer/scene-ground-replacement.d.ts.map +1 -1
- package/dist/components/viewer/scene-ground-replacement.js +15 -0
- package/dist/components/viewer/selection-manager.d.ts.map +1 -1
- package/dist/components/viewer/selection-manager.js +10 -0
- package/dist/components/viewer/viewer-camera.d.ts +4 -0
- package/dist/components/viewer/viewer-camera.d.ts.map +1 -1
- package/dist/components/viewer/viewer-camera.js +11 -1
- package/dist/index.d.ts +22 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -14
- package/dist/lib/asset-url.d.ts.map +1 -1
- package/dist/lib/asset-url.js +7 -1
- package/dist/lib/display-state.d.ts +25 -0
- package/dist/lib/display-state.d.ts.map +1 -0
- package/dist/lib/display-state.js +1 -0
- package/dist/lib/hero-pose.d.ts +12 -2
- package/dist/lib/hero-pose.d.ts.map +1 -1
- package/dist/lib/hero-pose.js +72 -5
- package/dist/lib/ink-edges.d.ts +4 -2
- package/dist/lib/ink-edges.d.ts.map +1 -1
- package/dist/lib/ink-edges.js +17 -7
- package/dist/lib/key-light-override.d.ts +11 -0
- package/dist/lib/key-light-override.d.ts.map +1 -0
- package/dist/lib/key-light-override.js +14 -0
- package/dist/lib/live-frame-hold.d.ts +14 -0
- package/dist/lib/live-frame-hold.d.ts.map +1 -0
- package/dist/lib/live-frame-hold.js +28 -0
- package/dist/lib/materials.d.ts +14 -7
- package/dist/lib/materials.d.ts.map +1 -1
- package/dist/lib/materials.js +31 -5
- package/dist/lib/node-top-surface-height.d.ts +6 -0
- package/dist/lib/node-top-surface-height.d.ts.map +1 -0
- package/dist/lib/node-top-surface-height.js +74 -0
- package/dist/lib/perf-probe-state.d.ts +39 -0
- package/dist/lib/perf-probe-state.d.ts.map +1 -0
- package/dist/lib/perf-probe-state.js +17 -0
- package/dist/lib/pointer-events.d.ts +8 -0
- package/dist/lib/pointer-events.d.ts.map +1 -1
- package/dist/lib/pointer-events.js +27 -4
- package/dist/lib/procedural-emission.d.ts +7 -0
- package/dist/lib/procedural-emission.d.ts.map +1 -0
- package/dist/lib/procedural-emission.js +54 -0
- package/dist/lib/scene-support-height.d.ts +4 -0
- package/dist/lib/scene-support-height.d.ts.map +1 -0
- package/dist/lib/scene-support-height.js +34 -0
- package/dist/lib/scene-visibility.d.ts +6 -0
- package/dist/lib/scene-visibility.d.ts.map +1 -1
- package/dist/lib/scene-visibility.js +15 -3
- package/dist/lib/scripted-opening.d.ts +11 -0
- package/dist/lib/scripted-opening.d.ts.map +1 -0
- package/dist/lib/scripted-opening.js +20 -0
- package/dist/lib/snapshot-pipeline.d.ts +32 -2
- package/dist/lib/snapshot-pipeline.d.ts.map +1 -1
- package/dist/lib/snapshot-pipeline.js +215 -105
- package/dist/lib/terrain-perimeter-fill.d.ts.map +1 -1
- package/dist/lib/terrain-perimeter-fill.js +22 -14
- package/dist/lib/zone-geometry.d.ts +11 -0
- package/dist/lib/zone-geometry.d.ts.map +1 -0
- package/dist/lib/zone-geometry.js +46 -0
- package/dist/store/use-item-light-pool.d.ts +14 -10
- package/dist/store/use-item-light-pool.d.ts.map +1 -1
- package/dist/store/use-item-light-pool.js +52 -26
- package/dist/store/use-viewer.d.ts +11 -0
- package/dist/store/use-viewer.d.ts.map +1 -1
- package/dist/store/use-viewer.js +13 -6
- package/dist/systems/ceiling/ceiling-system.d.ts +15 -1
- package/dist/systems/ceiling/ceiling-system.d.ts.map +1 -1
- package/dist/systems/ceiling/ceiling-system.js +86 -6
- package/dist/systems/door/door-system.d.ts.map +1 -1
- package/dist/systems/door/door-system.js +55 -17
- package/dist/systems/floor-elevation/floor-elevation-system.d.ts +3 -1
- package/dist/systems/floor-elevation/floor-elevation-system.d.ts.map +1 -1
- package/dist/systems/floor-elevation/floor-elevation-system.js +33 -5
- package/dist/systems/geometry/geometry-system.d.ts.map +1 -1
- package/dist/systems/geometry/geometry-system.js +71 -11
- package/dist/systems/interactive/interactive-system.d.ts.map +1 -1
- package/dist/systems/interactive/interactive-system.js +40 -15
- package/dist/systems/interactive/procedural-controls.d.ts +13 -0
- package/dist/systems/interactive/procedural-controls.d.ts.map +1 -0
- package/dist/systems/interactive/procedural-controls.js +17 -0
- package/dist/systems/interactive/scripted-clips.d.ts +19 -0
- package/dist/systems/interactive/scripted-clips.d.ts.map +1 -0
- package/dist/systems/interactive/scripted-clips.js +134 -0
- package/dist/systems/item/item-system.d.ts.map +1 -1
- package/dist/systems/item/item-system.js +9 -3
- package/dist/systems/item/object-cut-invalidation.d.ts +3 -0
- package/dist/systems/item/object-cut-invalidation.d.ts.map +1 -0
- package/dist/systems/item/object-cut-invalidation.js +68 -0
- package/dist/systems/item-light/item-light-system.d.ts +1 -1
- package/dist/systems/item-light/item-light-system.d.ts.map +1 -1
- package/dist/systems/item-light/item-light-system.js +47 -52
- package/dist/systems/level/level-system.d.ts.map +1 -1
- package/dist/systems/level/level-system.js +3 -5
- package/dist/systems/level/level-utils.d.ts +7 -4
- package/dist/systems/level/level-utils.d.ts.map +1 -1
- package/dist/systems/level/level-utils.js +17 -6
- package/dist/systems/level/shadow-only-levels.d.ts +9 -0
- package/dist/systems/level/shadow-only-levels.d.ts.map +1 -0
- package/dist/systems/level/shadow-only-levels.js +7 -0
- package/dist/systems/roof/roof-materials.d.ts +14 -2
- package/dist/systems/roof/roof-materials.d.ts.map +1 -1
- package/dist/systems/roof/roof-materials.js +54 -15
- package/dist/systems/roof/roof-system.d.ts +13 -3
- package/dist/systems/roof/roof-system.d.ts.map +1 -1
- package/dist/systems/roof/roof-system.js +188 -13
- package/dist/systems/slab/slab-system.d.ts +1 -1
- package/dist/systems/slab/slab-system.d.ts.map +1 -1
- package/dist/systems/slab/slab-system.js +49 -19
- package/dist/systems/stair/stair-system.d.ts.map +1 -1
- package/dist/systems/stair/stair-system.js +133 -354
- package/dist/systems/wall/wall-cutout-cache.d.ts +7 -0
- package/dist/systems/wall/wall-cutout-cache.d.ts.map +1 -1
- package/dist/systems/wall/wall-cutout-cache.js +46 -17
- package/dist/systems/wall/wall-cutout.d.ts +6 -0
- package/dist/systems/wall/wall-cutout.d.ts.map +1 -1
- package/dist/systems/wall/wall-cutout.js +42 -28
- package/dist/systems/wall/wall-finish-data.d.ts +22 -0
- package/dist/systems/wall/wall-finish-data.d.ts.map +1 -0
- package/dist/systems/wall/wall-finish-data.js +17 -0
- package/dist/systems/wall/wall-materials.d.ts +9 -4
- package/dist/systems/wall/wall-materials.d.ts.map +1 -1
- package/dist/systems/wall/wall-materials.js +99 -152
- package/dist/systems/wall/wall-system.d.ts +28 -2
- package/dist/systems/wall/wall-system.d.ts.map +1 -1
- package/dist/systems/wall/wall-system.js +582 -143
- package/dist/systems/window/window-system.d.ts +1 -1
- package/dist/systems/window/window-system.d.ts.map +1 -1
- package/dist/systems/window/window-system.js +41 -22
- package/package.json +5 -5
- package/dist/systems/fence/fence-system.d.ts +0 -22
- package/dist/systems/fence/fence-system.d.ts.map +0 -1
- package/dist/systems/fence/fence-system.js +0 -357
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { findLevelAncestorId, sceneRegistry,
|
|
3
|
-
import { useFrame } from '@react-three/fiber';
|
|
2
|
+
import { findLevelAncestorId, sceneRegistry, useScene } from '@pascal-app/core';
|
|
3
|
+
import { useFrame, useThree } from '@react-three/fiber';
|
|
4
4
|
import { useRef } from 'react';
|
|
5
5
|
import { MathUtils, Vector3 } from 'three';
|
|
6
|
+
import { SCENE_LAYER } from '../../lib/layers';
|
|
6
7
|
import { useItemLightPool } from '../../store/use-item-light-pool';
|
|
7
8
|
import useViewer from '../../store/use-viewer';
|
|
8
9
|
const POOL_SIZE = 12;
|
|
@@ -19,22 +20,30 @@ const _dir = new Vector3();
|
|
|
19
20
|
const _camPos = new Vector3();
|
|
20
21
|
const _camFwd = new Vector3();
|
|
21
22
|
const _itemPos = new Vector3();
|
|
22
|
-
function
|
|
23
|
-
|
|
24
|
-
if (
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
if (!
|
|
23
|
+
function isRendered(nodeId) {
|
|
24
|
+
let object = sceneRegistry.nodes.get(nodeId);
|
|
25
|
+
if (!object?.layers.isEnabled(SCENE_LAYER))
|
|
26
|
+
return false;
|
|
27
|
+
while (object) {
|
|
28
|
+
if (!object.visible)
|
|
29
|
+
return false;
|
|
30
|
+
object = object.parent;
|
|
31
|
+
}
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
function scoreRegistration(reg, nodes, selectedLevelId, levelMode, hideAbove) {
|
|
35
|
+
if (!reg.isEligible() || !isRendered(reg.nodeId) || !reg.getWorldPosition(_itemPos))
|
|
36
|
+
return Number.POSITIVE_INFINITY;
|
|
37
|
+
const { nodeId } = reg;
|
|
38
|
+
let current = nodes[nodeId];
|
|
39
|
+
while (current) {
|
|
40
|
+
if (current.type !== 'site' && current.visible === false)
|
|
28
41
|
return Number.POSITIVE_INFINITY;
|
|
42
|
+
current = current.parentId ? nodes[current.parentId] : undefined;
|
|
29
43
|
}
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
if (!obj)
|
|
44
|
+
const itemLevelId = findLevelAncestorId(nodeId, nodes);
|
|
45
|
+
if (selectedLevelId && itemLevelId !== selectedLevelId && levelMode === 'solo')
|
|
33
46
|
return Number.POSITIVE_INFINITY;
|
|
34
|
-
obj.getWorldPosition(_itemPos);
|
|
35
|
-
_itemPos.x += effect.offset[0];
|
|
36
|
-
_itemPos.y += effect.offset[1];
|
|
37
|
-
_itemPos.z += effect.offset[2];
|
|
38
47
|
_dir.copy(_itemPos).sub(_camPos).normalize();
|
|
39
48
|
const dot = _camFwd.dot(_dir); // 1 = ahead, -1 = behind
|
|
40
49
|
// Angular component (0 = dead ahead, 2 = directly behind)
|
|
@@ -42,12 +51,15 @@ function scoreRegistration(reg, nodes, selectedLevelId, levelMode, interactiveSt
|
|
|
42
51
|
// Normalised distance component (assumes scenes < 200 units)
|
|
43
52
|
const dist = _camPos.distanceTo(_itemPos) / 200;
|
|
44
53
|
// ── Level factor ──────────────────────────────────────────────────────────
|
|
45
|
-
const itemLevelId = findLevelAncestorId(nodeId, nodes);
|
|
46
54
|
let levelPenalty = 0;
|
|
47
55
|
if (selectedLevelId) {
|
|
48
56
|
if (itemLevelId !== selectedLevelId) {
|
|
49
|
-
//
|
|
50
|
-
|
|
57
|
+
// Items on hidden levels (every other one in solo, those above the
|
|
58
|
+
// selected one while editing) are invisible — deprioritize strongly
|
|
59
|
+
const itemIndex = nodes[itemLevelId]?.level ?? 0;
|
|
60
|
+
const selectedIndex = nodes[selectedLevelId]?.level ?? 0;
|
|
61
|
+
const hidden = levelMode === 'solo' || (hideAbove && itemIndex > selectedIndex);
|
|
62
|
+
levelPenalty = hidden ? 100 : 0.8;
|
|
51
63
|
}
|
|
52
64
|
}
|
|
53
65
|
else if (itemLevelId) {
|
|
@@ -60,6 +72,8 @@ function scoreRegistration(reg, nodes, selectedLevelId, levelMode, interactiveSt
|
|
|
60
72
|
return angular * 0.7 + dist * 0.3 + levelPenalty;
|
|
61
73
|
}
|
|
62
74
|
export function ItemLightSystem() {
|
|
75
|
+
const scene = useThree((state) => state.scene);
|
|
76
|
+
const bakedOwner = useItemLightPool((state) => state.bakedCanvases.has(scene));
|
|
63
77
|
const lightRefs = useRef(Array.from({ length: POOL_SIZE }, () => null));
|
|
64
78
|
const slots = useRef(Array.from({ length: POOL_SIZE }, () => ({ key: null, pendingKey: null, isFadingOut: false })));
|
|
65
79
|
const reassignTimer = useRef(0);
|
|
@@ -67,9 +81,10 @@ export function ItemLightSystem() {
|
|
|
67
81
|
const prevReassignCamPos = useRef(new Vector3());
|
|
68
82
|
const prevReassignCamFwd = useRef(new Vector3(0, 0, -1));
|
|
69
83
|
useFrame(({ camera }, delta) => {
|
|
84
|
+
if (bakedOwner)
|
|
85
|
+
return;
|
|
70
86
|
const dt = Math.min(delta, 0.1);
|
|
71
87
|
const { registrations } = useItemLightPool.getState();
|
|
72
|
-
const interactiveState = useInteractive.getState();
|
|
73
88
|
// ── 1. Throttled priority reassignment ──────────────────────────────────
|
|
74
89
|
camera.getWorldPosition(_camPos);
|
|
75
90
|
camera.getWorldDirection(_camFwd);
|
|
@@ -86,12 +101,13 @@ export function ItemLightSystem() {
|
|
|
86
101
|
const viewerState = useViewer.getState();
|
|
87
102
|
const selectedLevelId = viewerState.selection.levelId;
|
|
88
103
|
const levelMode = viewerState.levelMode;
|
|
104
|
+
const hideAbove = viewerState.hideLevelsAboveSelection;
|
|
89
105
|
// Score every registration
|
|
90
106
|
const scored = [];
|
|
91
107
|
for (const [key, reg] of registrations) {
|
|
92
108
|
scored.push({
|
|
93
109
|
key,
|
|
94
|
-
score: scoreRegistration(reg, nodes, selectedLevelId, levelMode,
|
|
110
|
+
score: scoreRegistration(reg, nodes, selectedLevelId, levelMode, hideAbove),
|
|
95
111
|
});
|
|
96
112
|
}
|
|
97
113
|
scored.sort((a, b) => a.score - b.score);
|
|
@@ -155,8 +171,8 @@ export function ItemLightSystem() {
|
|
|
155
171
|
const light = lightRefs.current[freeSlot];
|
|
156
172
|
const reg = registrations.get(key);
|
|
157
173
|
if (light && reg) {
|
|
158
|
-
light.color.set(reg.
|
|
159
|
-
light.distance = reg.
|
|
174
|
+
light.color.set(reg.color);
|
|
175
|
+
light.distance = reg.distance;
|
|
160
176
|
}
|
|
161
177
|
}
|
|
162
178
|
}
|
|
@@ -183,19 +199,17 @@ export function ItemLightSystem() {
|
|
|
183
199
|
continue;
|
|
184
200
|
// Fade-out phase: lerp intensity → 0, then complete the transition
|
|
185
201
|
if (slot.isFadingOut) {
|
|
186
|
-
light.visible = true;
|
|
187
202
|
light.intensity = MathUtils.lerp(light.intensity, 0, dt * 12);
|
|
188
203
|
if (light.intensity < 0.01) {
|
|
189
204
|
light.intensity = 0;
|
|
190
|
-
light.visible = false;
|
|
191
205
|
slot.isFadingOut = false;
|
|
192
206
|
slot.key = slot.pendingKey;
|
|
193
207
|
slot.pendingKey = null;
|
|
194
208
|
if (slot.key) {
|
|
195
209
|
const reg = registrations.get(slot.key);
|
|
196
210
|
if (reg) {
|
|
197
|
-
light.color.set(reg.
|
|
198
|
-
light.distance = reg.
|
|
211
|
+
light.color.set(reg.color);
|
|
212
|
+
light.distance = reg.distance;
|
|
199
213
|
}
|
|
200
214
|
}
|
|
201
215
|
}
|
|
@@ -204,45 +218,26 @@ export function ItemLightSystem() {
|
|
|
204
218
|
if (!slot.key) {
|
|
205
219
|
// Idle slot — keep dark
|
|
206
220
|
light.intensity = 0;
|
|
207
|
-
light.visible = false;
|
|
208
221
|
continue;
|
|
209
222
|
}
|
|
210
223
|
const reg = registrations.get(slot.key);
|
|
211
224
|
if (!reg) {
|
|
212
225
|
slot.key = null;
|
|
213
226
|
light.intensity = 0;
|
|
214
|
-
light.visible = false;
|
|
215
227
|
continue;
|
|
216
228
|
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
obj.getWorldPosition(_itemPos);
|
|
221
|
-
const [ox, oy, oz] = reg.effect.offset;
|
|
222
|
-
light.position.set(_itemPos.x + ox, _itemPos.y + oy, _itemPos.z + oz);
|
|
223
|
-
}
|
|
224
|
-
// Compute target intensity
|
|
225
|
-
const values = interactiveState.items[reg.nodeId]?.controlValues;
|
|
226
|
-
const isOn = reg.toggleIndex >= 0 ? Boolean(values?.[reg.toggleIndex]) : true;
|
|
227
|
-
let t = 1;
|
|
228
|
-
if (reg.hasSlider) {
|
|
229
|
-
const raw = values?.[reg.sliderIndex] ?? reg.sliderMin;
|
|
230
|
-
t = (raw - reg.sliderMin) / (reg.sliderMax - reg.sliderMin);
|
|
231
|
-
}
|
|
232
|
-
const targetIntensity = isOn
|
|
233
|
-
? MathUtils.lerp(reg.effect.intensityRange[0], reg.effect.intensityRange[1], t)
|
|
234
|
-
: reg.effect.intensityRange[0];
|
|
235
|
-
if (targetIntensity > 0) {
|
|
236
|
-
light.visible = true;
|
|
237
|
-
}
|
|
229
|
+
if (reg.getWorldPosition(_itemPos))
|
|
230
|
+
light.position.copy(_itemPos);
|
|
231
|
+
const targetIntensity = reg.isEligible() && isRendered(reg.nodeId) ? reg.getIntensity() : 0;
|
|
238
232
|
light.intensity = MathUtils.lerp(light.intensity, targetIntensity, dt * 12);
|
|
239
233
|
if (targetIntensity <= 0 && light.intensity < 0.01) {
|
|
240
234
|
light.intensity = 0;
|
|
241
|
-
light.visible = false;
|
|
242
235
|
}
|
|
243
236
|
}
|
|
244
|
-
});
|
|
245
|
-
|
|
237
|
+
}, 6);
|
|
238
|
+
if (bakedOwner)
|
|
239
|
+
return null;
|
|
240
|
+
return (_jsx(_Fragment, { children: Array.from({ length: POOL_SIZE }, (_, i) => (_jsx("pointLight", { castShadow: false, intensity: 0, visible: true, ref: (el) => {
|
|
246
241
|
lightRefs.current[i] = el;
|
|
247
242
|
} }, i))) }));
|
|
248
243
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"level-system.d.ts","sourceRoot":"","sources":["../../../src/systems/level/level-system.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"level-system.d.ts","sourceRoot":"","sources":["../../../src/systems/level/level-system.tsx"],"names":[],"mappings":"AAQA,eAAO,MAAM,WAAW,YA+DvB,CAAA"}
|
|
@@ -4,15 +4,12 @@ import { lerp } from 'three/src/math/MathUtils.js';
|
|
|
4
4
|
import { applyShadowOnly, clearShadowOnly } from '../../lib/shadow-only';
|
|
5
5
|
import useViewer from '../../store/use-viewer';
|
|
6
6
|
import { EXPLODED_GAP, resolveLevelVisibility } from './level-utils';
|
|
7
|
-
|
|
8
|
-
// passes but keeps their sun shadows). Tracked so we can restore layer masks
|
|
9
|
-
// exactly once on transition; apply re-runs every frame so meshes rebuilt
|
|
10
|
-
// while hidden (theme/texture changes) get re-hidden.
|
|
11
|
-
const shadowOnlyLevels = new WeakSet();
|
|
7
|
+
import { shadowOnlyLevels } from './shadow-only-levels';
|
|
12
8
|
export const LevelSystem = () => {
|
|
13
9
|
useFrame((_, delta) => {
|
|
14
10
|
const nodes = useScene.getState().nodes;
|
|
15
11
|
const levelMode = useViewer.getState().levelMode;
|
|
12
|
+
const hideAbove = useViewer.getState().hideLevelsAboveSelection;
|
|
16
13
|
const selectedLevel = useViewer.getState().selection.levelId;
|
|
17
14
|
const levelElevations = getLevelElevations(nodes);
|
|
18
15
|
const entries = [];
|
|
@@ -44,6 +41,7 @@ export const LevelSystem = () => {
|
|
|
44
41
|
obj.position.y = lerp(obj.position.y, targetY, Math.min(1, delta * 12));
|
|
45
42
|
const { visible, shadowOnly } = resolveLevelVisibility({
|
|
46
43
|
levelMode,
|
|
44
|
+
hideAbove,
|
|
47
45
|
hasSelectedLevel: Boolean(selectedLevel),
|
|
48
46
|
isSelected: level?.id === selectedLevel,
|
|
49
47
|
index,
|
|
@@ -12,14 +12,17 @@ export declare function getLevelPresentationY(levelId: string, nodes: Record<str
|
|
|
12
12
|
* shadow-caster only.
|
|
13
13
|
*
|
|
14
14
|
* Two unrelated things hide a level and they do not compose: the author's own
|
|
15
|
-
* `visible` flag (the sidebar eye), which hides the floor outright, and
|
|
16
|
-
* mode
|
|
17
|
-
*
|
|
15
|
+
* `visible` flag (the sidebar eye), which hides the floor outright, and
|
|
16
|
+
* presentation hiding — solo mode hides every level but the soloed one, and
|
|
17
|
+
* the editor's level display (`hideAbove`) hides the levels above the
|
|
18
|
+
* selected one. Presentation-hidden levels ABOVE the selected one stay in the
|
|
19
|
+
* shadow map so the sun still shadows the selected floor through them.
|
|
18
20
|
* A level the author hid never enters that shadow-caster branch: its shadows
|
|
19
21
|
* on the floor below would be exactly what hiding it was meant to remove.
|
|
20
22
|
*/
|
|
21
|
-
export declare function resolveLevelVisibility({ levelMode, hasSelectedLevel, isSelected, index, selectedIndex, nodeVisible, }: {
|
|
23
|
+
export declare function resolveLevelVisibility({ levelMode, hideAbove, hasSelectedLevel, isSelected, index, selectedIndex, nodeVisible, }: {
|
|
22
24
|
levelMode: 'stacked' | 'exploded' | 'solo' | 'manual';
|
|
25
|
+
hideAbove: boolean;
|
|
23
26
|
hasSelectedLevel: boolean;
|
|
24
27
|
isSelected: boolean;
|
|
25
28
|
index: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"level-utils.d.ts","sourceRoot":"","sources":["../../../src/systems/level/level-utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"level-utils.d.ts","sourceRoot":"","sources":["../../../src/systems/level/level-utils.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,YAAY,IAAI,CAAA;AAE7B;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,SAAS,EAAE,SAAS,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,GACpD,MAAM,CAKR;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,SAAS,EACT,SAAS,EACT,gBAAgB,EAChB,UAAU,EACV,KAAK,EACL,aAAa,EACb,WAAW,GACZ,EAAE;IACD,SAAS,EAAE,SAAS,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,CAAA;IACrD,SAAS,EAAE,OAAO,CAAA;IAClB,gBAAgB,EAAE,OAAO,CAAA;IACzB,UAAU,EAAE,OAAO,CAAA;IACnB,KAAK,EAAE,MAAM,CAAA;IACb,aAAa,EAAE,MAAM,GAAG,SAAS,CAAA;IACjC,WAAW,EAAE,OAAO,CAAA;CACrB,GAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,CAQ5C;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,IAAI,CA+CtD"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { getLevelElevations, sceneRegistry, useScene } from '@pascal-app/core';
|
|
2
|
+
import { applyShadowOnly, clearShadowOnly } from '../../lib/shadow-only';
|
|
3
|
+
import { shadowOnlyLevels } from './shadow-only-levels';
|
|
2
4
|
export const EXPLODED_GAP = 5;
|
|
3
5
|
/**
|
|
4
6
|
* The Y a level settles at under the given presentation mode — its stacked
|
|
@@ -18,16 +20,19 @@ export function getLevelPresentationY(levelId, nodes, levelMode) {
|
|
|
18
20
|
* shadow-caster only.
|
|
19
21
|
*
|
|
20
22
|
* Two unrelated things hide a level and they do not compose: the author's own
|
|
21
|
-
* `visible` flag (the sidebar eye), which hides the floor outright, and
|
|
22
|
-
* mode
|
|
23
|
-
*
|
|
23
|
+
* `visible` flag (the sidebar eye), which hides the floor outright, and
|
|
24
|
+
* presentation hiding — solo mode hides every level but the soloed one, and
|
|
25
|
+
* the editor's level display (`hideAbove`) hides the levels above the
|
|
26
|
+
* selected one. Presentation-hidden levels ABOVE the selected one stay in the
|
|
27
|
+
* shadow map so the sun still shadows the selected floor through them.
|
|
24
28
|
* A level the author hid never enters that shadow-caster branch: its shadows
|
|
25
29
|
* on the floor below would be exactly what hiding it was meant to remove.
|
|
26
30
|
*/
|
|
27
|
-
export function resolveLevelVisibility({ levelMode, hasSelectedLevel, isSelected, index, selectedIndex, nodeVisible, }) {
|
|
31
|
+
export function resolveLevelVisibility({ levelMode, hideAbove, hasSelectedLevel, isSelected, index, selectedIndex, nodeVisible, }) {
|
|
28
32
|
if (!nodeVisible)
|
|
29
33
|
return { visible: false, shadowOnly: false };
|
|
30
|
-
const hidden = levelMode === 'solo' && hasSelectedLevel && !isSelected
|
|
34
|
+
const hidden = (levelMode === 'solo' && hasSelectedLevel && !isSelected) ||
|
|
35
|
+
(hideAbove && selectedIndex !== undefined && index > selectedIndex);
|
|
31
36
|
const shadowOnly = hidden && selectedIndex !== undefined && index > selectedIndex;
|
|
32
37
|
return { visible: shadowOnly || !hidden, shadowOnly };
|
|
33
38
|
}
|
|
@@ -62,11 +67,15 @@ export function snapLevelsToTruePositions() {
|
|
|
62
67
|
const levelElevations = getLevelElevations(nodes);
|
|
63
68
|
// Snapshot current Y and visibility so we can restore them after the render
|
|
64
69
|
const snapshot = new Map(entries.map(({ levelId, obj }) => [levelId, { y: obj.position.y, visible: obj.visible }]));
|
|
65
|
-
// Snap to true stacked positions and undo presentation hiding
|
|
70
|
+
// Snap to true stacked positions and undo presentation hiding — including
|
|
71
|
+
// the levels kept shadow-caster-only above the selected level.
|
|
72
|
+
const shadowOnly = entries.filter(({ obj }) => shadowOnlyLevels.has(obj));
|
|
66
73
|
for (const { levelId, obj, nodeVisible } of entries) {
|
|
67
74
|
obj.position.y = levelElevations.get(levelId)?.baseY ?? 0;
|
|
68
75
|
obj.visible = nodeVisible;
|
|
69
76
|
}
|
|
77
|
+
for (const { obj } of shadowOnly)
|
|
78
|
+
clearShadowOnly(obj);
|
|
70
79
|
return () => {
|
|
71
80
|
for (const { levelId, obj } of entries) {
|
|
72
81
|
const saved = snapshot.get(levelId);
|
|
@@ -75,5 +84,7 @@ export function snapLevelsToTruePositions() {
|
|
|
75
84
|
obj.visible = saved.visible;
|
|
76
85
|
}
|
|
77
86
|
}
|
|
87
|
+
for (const { obj } of shadowOnly)
|
|
88
|
+
applyShadowOnly(obj);
|
|
78
89
|
};
|
|
79
90
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Object3D } from 'three';
|
|
2
|
+
/**
|
|
3
|
+
* Levels currently in shadow-caster-only mode (hidden above the selected level
|
|
4
|
+
* by solo or by the editor's level display). Tracked so layer masks are
|
|
5
|
+
* restored exactly once on transition, and so a full-building capture can
|
|
6
|
+
* show them for its one render.
|
|
7
|
+
*/
|
|
8
|
+
export declare const shadowOnlyLevels: WeakSet<Object3D<import("three").Object3DEventMap>>;
|
|
9
|
+
//# sourceMappingURL=shadow-only-levels.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shadow-only-levels.d.ts","sourceRoot":"","sources":["../../../src/systems/level/shadow-only-levels.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAErC;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,qDAA0B,CAAA"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Levels currently in shadow-caster-only mode (hidden above the selected level
|
|
3
|
+
* by solo or by the editor's level display). Tracked so layer masks are
|
|
4
|
+
* restored exactly once on transition, and so a full-building capture can
|
|
5
|
+
* show them for its one render.
|
|
6
|
+
*/
|
|
7
|
+
export const shadowOnlyLevels = new WeakSet();
|
|
@@ -1,6 +1,18 @@
|
|
|
1
|
-
import { type RoofNode } from '@pascal-app/core';
|
|
1
|
+
import { type AnyNode, type RoofNode, type SceneMaterial, type SceneMaterialId } from '@pascal-app/core';
|
|
2
2
|
import type * as THREE from 'three';
|
|
3
3
|
import { type ColorPreset, type RenderShading } from '../../lib/materials';
|
|
4
|
+
type SceneMaterials = Record<SceneMaterialId, SceneMaterial> | undefined;
|
|
4
5
|
export type RoofMaterialArray = [THREE.Material, THREE.Material, THREE.Material, THREE.Material];
|
|
5
|
-
|
|
6
|
+
/**
|
|
7
|
+
* The cladding the walls under a roof declare through their ASSEMBLIES
|
|
8
|
+
* (`wall.assembly.exterior.finish` → catalog ref), so the roof's gable band —
|
|
9
|
+
* the triangle of wall above the plate that the roof kind builds — is skinned
|
|
10
|
+
* like the walls it sits on instead of the bare drywall default. The most
|
|
11
|
+
* common ref among the level's walls wins; null when none declares one.
|
|
12
|
+
*/
|
|
13
|
+
export declare function levelWallCladdingRef(nodes: Readonly<Record<string, AnyNode | undefined>>, roof: Pick<RoofNode, 'parentId'>): string | null;
|
|
14
|
+
export declare function getRoofMaterialArray(node: RoofNode, shading?: RenderShading, textures?: boolean, colorPreset?: ColorPreset, sceneTheme?: string,
|
|
15
|
+
/** Catalog ref for the gable/trim band when unpainted — see `levelWallCladdingRef`. */
|
|
16
|
+
wallCladdingRef?: string | null, sceneMaterials?: SceneMaterials): RoofMaterialArray | null;
|
|
17
|
+
export {};
|
|
6
18
|
//# sourceMappingURL=roof-materials.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roof-materials.d.ts","sourceRoot":"","sources":["../../../src/systems/roof/roof-materials.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"roof-materials.d.ts","sourceRoot":"","sources":["../../../src/systems/roof/roof-materials.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EAGZ,KAAK,QAAQ,EAEb,KAAK,aAAa,EAClB,KAAK,eAAe,EAErB,MAAM,kBAAkB,CAAA;AACzB,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAA;AACnC,OAAO,EACL,KAAK,WAAW,EAGhB,KAAK,aAAa,EAGnB,MAAM,qBAAqB,CAAA;AAE5B,KAAK,cAAc,GAAG,MAAM,CAAC,eAAe,EAAE,aAAa,CAAC,GAAG,SAAS,CAAA;AAaxE,MAAM,MAAM,iBAAiB,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAA;AAqChG;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC,CAAC,EACpD,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,GAC/B,MAAM,GAAG,IAAI,CAkBf;AAED,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,QAAQ,EACd,OAAO,GAAE,aAA0B,EACnC,QAAQ,UAAO,EACf,WAAW,GAAE,WAAoB,EACjC,UAAU,CAAC,EAAE,MAAM;AACnB,uFAAuF;AACvF,eAAe,GAAE,MAAM,GAAG,IAAW,EACrC,cAAc,CAAC,EAAE,cAAc,GAC9B,iBAAiB,GAAG,IAAI,CAyE1B"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { getEffectiveRoofSurfaceMaterial, } from '@pascal-app/core';
|
|
2
|
-
import { createMaterial,
|
|
1
|
+
import { getEffectiveRoofSurfaceMaterial, parseMaterialRef, wallAssemblyFinishRef, } from '@pascal-app/core';
|
|
2
|
+
import { createMaterial, createSurfaceRoleMaterial, resolveMaterialRef, resolveSlotDefaultMaterial, } from '../../lib/materials';
|
|
3
3
|
// Declared catalog defaults for an unpainted roof, per the 4-slot layout
|
|
4
4
|
// (0 wall/trim · 1 deck · 2 interior soffit · 3 shingle top). The wall/trim
|
|
5
5
|
// band mirrors the wall kind's default (WALL_SLOT_DEFAULT = concrete-drywall)
|
|
@@ -11,22 +11,59 @@ const ROOF_DEFAULT_REFS = [
|
|
|
11
11
|
'library:roof-terracottatiles',
|
|
12
12
|
];
|
|
13
13
|
const roofMaterialArrayCache = new Map();
|
|
14
|
-
function getSurfaceMaterialSignature(spec) {
|
|
14
|
+
function getSurfaceMaterialSignature(spec, sceneMaterials) {
|
|
15
|
+
const ref = parseMaterialRef(spec.materialPreset);
|
|
15
16
|
return JSON.stringify({
|
|
16
17
|
material: spec.material ?? null,
|
|
17
18
|
materialPreset: spec.materialPreset ?? null,
|
|
19
|
+
sceneMaterial: ref?.kind === 'scene'
|
|
20
|
+
? (sceneMaterials?.[ref.id]?.material ?? null)
|
|
21
|
+
: null,
|
|
18
22
|
});
|
|
19
23
|
}
|
|
20
|
-
function createResolvedMaterial(material, materialPreset, shading) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
+
function createResolvedMaterial(material, materialPreset, sceneMaterials, shading) {
|
|
25
|
+
// An unknown or dangling ref resolves to nothing: fall through to the
|
|
26
|
+
// colour, then the slot default, as the segment renderer does.
|
|
27
|
+
const preset = resolveMaterialRef(materialPreset, sceneMaterials, shading);
|
|
28
|
+
if (preset)
|
|
29
|
+
return preset;
|
|
24
30
|
if (material) {
|
|
25
31
|
return createMaterial(material, shading);
|
|
26
32
|
}
|
|
27
33
|
return null;
|
|
28
34
|
}
|
|
29
|
-
|
|
35
|
+
/**
|
|
36
|
+
* The cladding the walls under a roof declare through their ASSEMBLIES
|
|
37
|
+
* (`wall.assembly.exterior.finish` → catalog ref), so the roof's gable band —
|
|
38
|
+
* the triangle of wall above the plate that the roof kind builds — is skinned
|
|
39
|
+
* like the walls it sits on instead of the bare drywall default. The most
|
|
40
|
+
* common ref among the level's walls wins; null when none declares one.
|
|
41
|
+
*/
|
|
42
|
+
export function levelWallCladdingRef(nodes, roof) {
|
|
43
|
+
const levelId = roof.parentId;
|
|
44
|
+
if (!levelId)
|
|
45
|
+
return null;
|
|
46
|
+
const counts = new Map();
|
|
47
|
+
for (const node of Object.values(nodes)) {
|
|
48
|
+
if (node?.type !== 'wall' || node.parentId !== levelId)
|
|
49
|
+
continue;
|
|
50
|
+
const ref = wallAssemblyFinishRef(node);
|
|
51
|
+
if (ref)
|
|
52
|
+
counts.set(ref, (counts.get(ref) ?? 0) + 1);
|
|
53
|
+
}
|
|
54
|
+
let best = null;
|
|
55
|
+
let bestCount = 0;
|
|
56
|
+
for (const [ref, count] of counts) {
|
|
57
|
+
if (count > bestCount) {
|
|
58
|
+
best = ref;
|
|
59
|
+
bestCount = count;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return best;
|
|
63
|
+
}
|
|
64
|
+
export function getRoofMaterialArray(node, shading = 'rendered', textures = true, colorPreset = 'clay', sceneTheme,
|
|
65
|
+
/** Catalog ref for the gable/trim band when unpainted — see `levelWallCladdingRef`. */
|
|
66
|
+
wallCladdingRef = null, sceneMaterials) {
|
|
30
67
|
const top = getEffectiveRoofSurfaceMaterial(node, 'top');
|
|
31
68
|
const edge = getEffectiveRoofSurfaceMaterial(node, 'edge');
|
|
32
69
|
const wall = getEffectiveRoofSurfaceMaterial(node, 'wall');
|
|
@@ -35,9 +72,10 @@ export function getRoofMaterialArray(node, shading = 'rendered', textures = true
|
|
|
35
72
|
textures,
|
|
36
73
|
colorPreset,
|
|
37
74
|
sceneTheme,
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
75
|
+
wallCladdingRef,
|
|
76
|
+
top: getSurfaceMaterialSignature(top, sceneMaterials),
|
|
77
|
+
edge: getSurfaceMaterialSignature(edge, sceneMaterials),
|
|
78
|
+
wall: getSurfaceMaterialSignature(wall, sceneMaterials),
|
|
41
79
|
});
|
|
42
80
|
const cached = roofMaterialArrayCache.get(cacheKey);
|
|
43
81
|
if (cached)
|
|
@@ -63,14 +101,15 @@ export function getRoofMaterialArray(node, shading = 'rendered', textures = true
|
|
|
63
101
|
// shingle, soft-white deck/soffit, wall-coloured trim). Used both when the
|
|
64
102
|
// roof is unpainted and to fill any individual unpainted slot below.
|
|
65
103
|
const defaultArray = [
|
|
66
|
-
resolveSlotDefaultMaterial(ROOF_DEFAULT_REFS[0], shading),
|
|
104
|
+
resolveSlotDefaultMaterial(wallCladdingRef ?? ROOF_DEFAULT_REFS[0], shading),
|
|
67
105
|
resolveSlotDefaultMaterial(ROOF_DEFAULT_REFS[1], shading),
|
|
68
106
|
resolveSlotDefaultMaterial(ROOF_DEFAULT_REFS[2], shading),
|
|
69
107
|
resolveSlotDefaultMaterial(ROOF_DEFAULT_REFS[3], shading),
|
|
70
108
|
];
|
|
71
|
-
const
|
|
72
|
-
const
|
|
73
|
-
const
|
|
109
|
+
const resolve = (spec) => createResolvedMaterial(spec.material, spec.materialPreset, sceneMaterials, shading);
|
|
110
|
+
const topMaterial = resolve(top);
|
|
111
|
+
const edgeMaterial = resolve(edge);
|
|
112
|
+
const wallMaterial = resolve(wall);
|
|
74
113
|
if (!(topMaterial || edgeMaterial || wallMaterial)) {
|
|
75
114
|
roofMaterialArrayCache.set(cacheKey, defaultArray);
|
|
76
115
|
return defaultArray;
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import { type AnyNode, type RoofSegmentNode } from '@pascal-app/core';
|
|
2
2
|
import * as THREE from 'three';
|
|
3
3
|
import { Brush } from 'three-bvh-csg';
|
|
4
|
+
/**
|
|
5
|
+
* Roofs whose merged shell is still to build: until it is, the roof shows its segments apart (or
|
|
6
|
+
* an old shell), and a capture would show that. Only roofs on screen count, a first merge (a
|
|
7
|
+
* mounted group with no shell yet) included: one never mounted stays queued and would hold every
|
|
8
|
+
* capture.
|
|
9
|
+
*/
|
|
10
|
+
export declare function getPendingRoofMergeCount(): number;
|
|
11
|
+
export declare function countPendingRoofShells(pending: Iterable<string>, mounted: (id: string) => THREE.Object3D | undefined): number;
|
|
4
12
|
export declare const RoofSystem: () => null;
|
|
5
13
|
/**
|
|
6
14
|
* Four dummy materials used as identity placeholders during CSG. Shared
|
|
@@ -36,10 +44,12 @@ export declare function mapRoofGroupMaterialIndex(groupMaterialIndex: number | u
|
|
|
36
44
|
*/
|
|
37
45
|
export declare function clipGeometryBySegmentTrim(geometry: THREE.BufferGeometry | null, segment: RoofSegmentNode): THREE.BufferGeometry | null;
|
|
38
46
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
47
|
+
* `fascia`: build the segment's fascia boards into its deck. Only the roof
|
|
48
|
+
* renderer asks; a dormer, a chimney or a sibling's clip takes the bare shell.
|
|
41
49
|
*/
|
|
42
|
-
export declare function getRoofSegmentBrushes(node: RoofSegmentNode
|
|
50
|
+
export declare function getRoofSegmentBrushes(node: RoofSegmentNode, options?: {
|
|
51
|
+
fascia?: boolean;
|
|
52
|
+
}): RoofSegmentBrushSet | null;
|
|
43
53
|
export declare function generateRoofSegmentGeometry(node: RoofSegmentNode, nodes?: Record<string, AnyNode>): THREE.BufferGeometry;
|
|
44
54
|
export declare function remapRoofShellFaces(geometry: THREE.BufferGeometry, node: RoofSegmentNode): void;
|
|
45
55
|
export type SurfaceFrame = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roof-system.d.ts","sourceRoot":"","sources":["../../../src/systems/roof/roof-system.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EAoBZ,KAAK,eAAe,EAQrB,MAAM,kBAAkB,CAAA;AAEzB,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAAY,KAAK,EAA0B,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"roof-system.d.ts","sourceRoot":"","sources":["../../../src/systems/roof/roof-system.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EAoBZ,KAAK,eAAe,EAQrB,MAAM,kBAAkB,CAAA;AAEzB,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAAY,KAAK,EAA0B,MAAM,eAAe,CAAA;AAqIvE;;;;;GAKG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,CAIjD;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,EACzB,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,KAAK,CAAC,QAAQ,GAAG,SAAS,GAClD,MAAM,CAIR;AA+DD,eAAO,MAAM,UAAU,YAwItB,CAAA;AAgbD;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,EAAE;IAC7B,KAAK,CAAC,iBAAiB;IACvB,KAAK,CAAC,iBAAiB;IACvB,KAAK,CAAC,iBAAiB;IACvB,KAAK,CAAC,iBAAiB;CAMxB,CAAA;AAID,eAAO,MAAM,wBAAwB,IAAI,CAAA;AAEzC,KAAK,mBAAmB,GAAG;IACzB,QAAQ,EAAE,KAAK,CAAA;IACf,QAAQ,EAAE,KAAK,CAAA;IACf,SAAS,EAAE,KAAK,CAAA;IAChB,UAAU,EAAE,KAAK,CAAA;IACjB,UAAU,EAAE,KAAK,CAAC,cAAc,GAAG,IAAI,CAAA;CACxC,CAAA;AA4FD,wBAAgB,yBAAyB,CACvC,kBAAkB,EAAE,MAAM,GAAG,SAAS,EACtC,YAAY,EAAE,KAAK,CAAC,QAAQ,EAAE,EAC9B,UAAU,EAAE,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,GACtC,MAAM,CAuBR;AAuXD;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,KAAK,CAAC,cAAc,GAAG,IAAI,EACrC,OAAO,EAAE,eAAe,GACvB,KAAK,CAAC,cAAc,GAAG,IAAI,CAyB7B;AAoHD;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,eAAe,EACrB,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GACjC,mBAAmB,GAAG,IAAI,CAyV5B;AAED,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,eAAe,EACrB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,KAAK,CAAC,cAAc,CA6GtB;AAuyCD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,KAAK,CAAC,cAAc,EAAE,IAAI,EAAE,eAAe,QA0ExF;AAirBD,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,EAAE,KAAK,CAAC,OAAO,CAAA;IACpB,MAAM,EAAE,KAAK,CAAC,OAAO,CAAA;CACtB,CAAA;AAED;;;;GAIG;AACH,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,eAAe,EACxB,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,GACT,YAAY,CAqLd"}
|