@pascal-app/viewer 0.8.0 → 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/error-boundary.d.ts +6 -0
- package/dist/components/error-boundary.d.ts.map +1 -1
- package/dist/components/error-boundary.js +6 -0
- package/dist/components/renderers/node-renderer.d.ts +6 -2
- package/dist/components/renderers/node-renderer.d.ts.map +1 -1
- package/dist/components/renderers/node-renderer.js +41 -22
- package/dist/components/renderers/parametric-node-renderer.d.ts +5 -0
- package/dist/components/renderers/parametric-node-renderer.d.ts.map +1 -0
- package/dist/components/renderers/parametric-node-renderer.js +37 -0
- package/dist/components/renderers/scene-renderer.d.ts +1 -1
- package/dist/components/renderers/scene-renderer.d.ts.map +1 -1
- package/dist/components/viewer/bvh-ecctrl.d.ts +77 -0
- package/dist/components/viewer/bvh-ecctrl.d.ts.map +1 -0
- package/dist/components/viewer/bvh-ecctrl.js +552 -0
- package/dist/components/viewer/frame-limiter.d.ts.map +1 -1
- package/dist/components/viewer/frame-limiter.js +39 -4
- package/dist/components/viewer/glb-interactive.d.ts +41 -0
- package/dist/components/viewer/glb-interactive.d.ts.map +1 -0
- package/dist/components/viewer/glb-interactive.js +394 -0
- package/dist/components/viewer/glb-reference-nodes.d.ts +29 -0
- package/dist/components/viewer/glb-reference-nodes.d.ts.map +1 -0
- package/dist/components/viewer/glb-reference-nodes.js +80 -0
- package/dist/components/viewer/glb-replace-instances.d.ts +18 -0
- package/dist/components/viewer/glb-replace-instances.d.ts.map +1 -0
- package/dist/components/viewer/glb-replace-instances.js +61 -0
- package/dist/components/viewer/glb-scene.d.ts +54 -0
- package/dist/components/viewer/glb-scene.d.ts.map +1 -0
- package/dist/components/viewer/glb-scene.js +920 -0
- package/dist/components/viewer/glb-walkthrough-controller.d.ts +12 -0
- package/dist/components/viewer/glb-walkthrough-controller.d.ts.map +1 -0
- package/dist/components/viewer/glb-walkthrough-controller.js +357 -0
- package/dist/components/viewer/index.d.ts +56 -3
- package/dist/components/viewer/index.d.ts.map +1 -1
- package/dist/components/viewer/index.js +280 -65
- package/dist/components/viewer/lights.d.ts +1 -1
- package/dist/components/viewer/lights.d.ts.map +1 -1
- package/dist/components/viewer/lights.js +201 -43
- package/dist/components/viewer/perf-monitor.d.ts +1 -1
- package/dist/components/viewer/perf-monitor.d.ts.map +1 -1
- package/dist/components/viewer/perf-monitor.js +115 -12
- package/dist/components/viewer/post-processing.d.ts +7 -1
- package/dist/components/viewer/post-processing.d.ts.map +1 -1
- package/dist/components/viewer/post-processing.js +395 -63
- package/dist/components/viewer/registered-systems.d.ts +12 -0
- package/dist/components/viewer/registered-systems.d.ts.map +1 -0
- package/dist/components/viewer/registered-systems.js +49 -0
- package/dist/components/viewer/scene-bvh.d.ts +18 -0
- package/dist/components/viewer/scene-bvh.d.ts.map +1 -0
- package/dist/components/viewer/scene-bvh.js +97 -0
- package/dist/components/viewer/scene-bvh.test.d.ts +2 -0
- package/dist/components/viewer/scene-bvh.test.d.ts.map +1 -0
- package/dist/components/viewer/scene-bvh.test.js +13 -0
- package/dist/components/viewer/scene-environment.d.ts +2 -0
- package/dist/components/viewer/scene-environment.d.ts.map +1 -0
- package/dist/components/viewer/scene-environment.js +79 -0
- package/dist/components/viewer/selection-manager.d.ts +1 -1
- package/dist/components/viewer/selection-manager.d.ts.map +1 -1
- package/dist/components/viewer/selection-manager.js +37 -14
- package/dist/components/viewer/viewer-camera.d.ts +1 -1
- package/dist/components/viewer/viewer-camera.d.ts.map +1 -1
- package/dist/components/viewer/walkthrough-controls.d.ts +2 -1
- package/dist/components/viewer/walkthrough-controls.d.ts.map +1 -1
- package/dist/components/viewer/walkthrough-controls.js +20 -0
- package/dist/hooks/use-gltf-ktx2.d.ts.map +1 -1
- package/dist/hooks/use-gltf-ktx2.js +3 -22
- package/dist/hooks/use-node-events.d.ts +6 -74
- package/dist/hooks/use-node-events.d.ts.map +1 -1
- package/dist/hooks/use-node-events.js +28 -8
- package/dist/index.d.ts +48 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +82 -4
- package/dist/lib/backdrop.d.ts +33 -0
- package/dist/lib/backdrop.d.ts.map +1 -0
- package/dist/lib/backdrop.js +92 -0
- package/dist/lib/box-uv.d.ts +13 -0
- package/dist/lib/box-uv.d.ts.map +1 -0
- package/dist/lib/box-uv.js +32 -0
- package/dist/lib/csg-utils.d.ts +10 -0
- package/dist/lib/csg-utils.d.ts.map +1 -0
- package/dist/lib/csg-utils.js +93 -0
- package/dist/lib/csg-utils.test.d.ts +2 -0
- package/dist/lib/csg-utils.test.d.ts.map +1 -0
- package/dist/lib/csg-utils.test.js +45 -0
- package/dist/lib/drawable-geometry.d.ts +21 -0
- package/dist/lib/drawable-geometry.d.ts.map +1 -0
- package/dist/lib/drawable-geometry.js +22 -0
- package/dist/lib/edge-style.d.ts +4 -0
- package/dist/lib/edge-style.d.ts.map +1 -0
- package/dist/lib/edge-style.js +31 -0
- package/dist/lib/gpu-perf.d.ts +4 -0
- package/dist/lib/gpu-perf.d.ts.map +1 -0
- package/dist/lib/gpu-perf.js +23 -0
- package/dist/lib/ink-edges.d.ts +9 -0
- package/dist/lib/ink-edges.d.ts.map +1 -0
- package/dist/lib/ink-edges.js +49 -0
- package/dist/lib/isolation.d.ts +39 -0
- package/dist/lib/isolation.d.ts.map +1 -0
- package/dist/lib/isolation.js +103 -0
- package/dist/lib/ktx2-loader.d.ts +43 -0
- package/dist/lib/ktx2-loader.d.ts.map +1 -0
- package/dist/lib/ktx2-loader.js +136 -0
- package/dist/lib/layers.d.ts +28 -0
- package/dist/lib/layers.d.ts.map +1 -1
- package/dist/lib/layers.js +28 -0
- package/dist/lib/materials.d.ts +38 -15
- package/dist/lib/materials.d.ts.map +1 -1
- package/dist/lib/materials.js +364 -72
- package/dist/lib/merged-outline-node.d.ts.map +1 -1
- package/dist/lib/merged-outline-node.js +7 -0
- package/dist/lib/polygon-union.d.ts +4 -0
- package/dist/lib/polygon-union.d.ts.map +1 -0
- package/dist/lib/polygon-union.js +289 -0
- package/dist/lib/polygon-union.test.d.ts +2 -0
- package/dist/lib/polygon-union.test.d.ts.map +1 -0
- package/dist/lib/polygon-union.test.js +105 -0
- package/dist/lib/scene-themes.d.ts +30 -0
- package/dist/lib/scene-themes.d.ts.map +1 -0
- package/dist/lib/scene-themes.js +202 -0
- package/dist/lib/shadow-only.d.ts +4 -0
- package/dist/lib/shadow-only.d.ts.map +1 -0
- package/dist/lib/shadow-only.js +36 -0
- package/dist/lib/tsl-compat.d.ts +12 -0
- package/dist/lib/tsl-compat.d.ts.map +1 -0
- package/dist/lib/tsl-compat.js +13 -0
- package/dist/store/use-viewer.d.ts +92 -12
- package/dist/store/use-viewer.d.ts.map +1 -1
- package/dist/store/use-viewer.js +201 -6
- package/dist/store/use-viewer.test.d.ts +2 -0
- package/dist/store/use-viewer.test.d.ts.map +1 -0
- package/dist/store/use-viewer.test.js +42 -0
- package/dist/systems/ceiling/ceiling-system.d.ts +6 -2
- package/dist/systems/ceiling/ceiling-system.d.ts.map +1 -1
- package/dist/systems/ceiling/ceiling-system.js +66 -13
- package/dist/systems/door/door-animation.test.d.ts +2 -0
- package/dist/systems/door/door-animation.test.d.ts.map +1 -0
- package/dist/systems/door/door-animation.test.js +51 -0
- package/dist/systems/door/door-floor-alignment.test.d.ts +2 -0
- package/dist/systems/door/door-floor-alignment.test.d.ts.map +1 -0
- package/dist/systems/door/door-floor-alignment.test.js +50 -0
- package/dist/systems/door/door-system.d.ts +24 -0
- package/dist/systems/door/door-system.d.ts.map +1 -1
- package/dist/systems/door/door-system.js +864 -180
- package/dist/systems/elevator/elevator-interaction-system.d.ts +2 -0
- package/dist/systems/elevator/elevator-interaction-system.d.ts.map +1 -0
- package/dist/systems/elevator/elevator-interaction-system.js +62 -0
- package/dist/systems/fence/fence-system.d.ts +20 -0
- package/dist/systems/fence/fence-system.d.ts.map +1 -1
- package/dist/systems/fence/fence-system.js +229 -57
- package/dist/systems/floor-elevation/floor-elevation-system.d.ts +20 -0
- package/dist/systems/floor-elevation/floor-elevation-system.d.ts.map +1 -0
- package/dist/systems/floor-elevation/floor-elevation-system.js +78 -0
- package/dist/systems/geometry/geometry-system.d.ts +41 -0
- package/dist/systems/geometry/geometry-system.d.ts.map +1 -0
- package/dist/systems/geometry/geometry-system.js +348 -0
- package/dist/systems/geometry/geometry-system.test.d.ts +2 -0
- package/dist/systems/geometry/geometry-system.test.d.ts.map +1 -0
- package/dist/systems/geometry/geometry-system.test.js +30 -0
- package/dist/systems/interactive/control-widget.d.ts +10 -0
- package/dist/systems/interactive/control-widget.d.ts.map +1 -0
- package/dist/systems/interactive/control-widget.js +35 -0
- package/dist/systems/interactive/interactive-system.d.ts +1 -1
- package/dist/systems/interactive/interactive-system.d.ts.map +1 -1
- package/dist/systems/interactive/interactive-system.js +55 -56
- package/dist/systems/item/item-system.d.ts +7 -0
- package/dist/systems/item/item-system.d.ts.map +1 -1
- package/dist/systems/item/item-system.js +28 -17
- 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 +18 -5
- package/dist/systems/level/level-system.d.ts.map +1 -1
- package/dist/systems/level/level-system.js +28 -4
- package/dist/systems/level/level-utils.d.ts +0 -3
- package/dist/systems/level/level-utils.d.ts.map +1 -1
- package/dist/systems/level/level-utils.js +2 -41
- package/dist/systems/roof/roof-materials.d.ts +3 -2
- package/dist/systems/roof/roof-materials.d.ts.map +1 -1
- package/dist/systems/roof/roof-materials.js +59 -14
- package/dist/systems/roof/roof-system.d.ts +46 -6
- package/dist/systems/roof/roof-system.d.ts.map +1 -1
- package/dist/systems/roof/roof-system.js +1365 -170
- package/dist/systems/slab/slab-system.d.ts +5 -3
- package/dist/systems/slab/slab-system.d.ts.map +1 -1
- package/dist/systems/slab/slab-system.js +204 -68
- package/dist/systems/slab/slab-system.test.d.ts +2 -0
- package/dist/systems/slab/slab-system.test.d.ts.map +1 -0
- package/dist/systems/slab/slab-system.test.js +63 -0
- package/dist/systems/stair/stair-materials.d.ts +4 -3
- package/dist/systems/stair/stair-materials.d.ts.map +1 -1
- package/dist/systems/stair/stair-materials.js +30 -15
- package/dist/systems/stair/stair-system.d.ts.map +1 -1
- package/dist/systems/stair/stair-system.js +55 -63
- package/dist/systems/surface-hole-geometry.d.ts +3 -0
- package/dist/systems/surface-hole-geometry.d.ts.map +1 -0
- package/dist/systems/surface-hole-geometry.js +4 -0
- package/dist/systems/wall/opening-cutout-geometry.d.ts +31 -0
- package/dist/systems/wall/opening-cutout-geometry.d.ts.map +1 -0
- package/dist/systems/wall/opening-cutout-geometry.js +167 -0
- package/dist/systems/wall/opening-cutout-geometry.test.d.ts +2 -0
- package/dist/systems/wall/opening-cutout-geometry.test.d.ts.map +1 -0
- package/dist/systems/wall/opening-cutout-geometry.test.js +172 -0
- package/dist/systems/wall/wall-cutout.d.ts.map +1 -1
- package/dist/systems/wall/wall-cutout.js +62 -17
- package/dist/systems/wall/wall-materials.d.ts +12 -7
- package/dist/systems/wall/wall-materials.d.ts.map +1 -1
- package/dist/systems/wall/wall-materials.js +279 -46
- package/dist/systems/wall/wall-opening-cutout.test.d.ts +2 -0
- package/dist/systems/wall/wall-opening-cutout.test.d.ts.map +1 -0
- package/dist/systems/wall/wall-opening-cutout.test.js +59 -0
- package/dist/systems/wall/wall-support-extension.test.d.ts +2 -0
- package/dist/systems/wall/wall-support-extension.test.d.ts.map +1 -0
- package/dist/systems/wall/wall-support-extension.test.js +48 -0
- package/dist/systems/wall/wall-system.d.ts +2 -2
- package/dist/systems/wall/wall-system.d.ts.map +1 -1
- package/dist/systems/wall/wall-system.js +493 -193
- package/dist/systems/window/window-animation-system.d.ts +12 -0
- package/dist/systems/window/window-animation-system.d.ts.map +1 -1
- package/dist/systems/window/window-animation-system.js +16 -5
- package/dist/systems/window/window-system.d.ts +7 -0
- package/dist/systems/window/window-system.d.ts.map +1 -1
- package/dist/systems/window/window-system.js +308 -18
- package/package.json +5 -6
- package/dist/components/renderers/building/building-renderer.d.ts +0 -5
- package/dist/components/renderers/building/building-renderer.d.ts.map +0 -1
- package/dist/components/renderers/building/building-renderer.js +0 -11
- package/dist/components/renderers/ceiling/ceiling-renderer.d.ts +0 -5
- package/dist/components/renderers/ceiling/ceiling-renderer.d.ts.map +0 -1
- package/dist/components/renderers/ceiling/ceiling-renderer.js +0 -58
- package/dist/components/renderers/column/column-renderer.d.ts +0 -5
- package/dist/components/renderers/column/column-renderer.d.ts.map +0 -1
- package/dist/components/renderers/column/column-renderer.js +0 -597
- package/dist/components/renderers/door/door-renderer.d.ts +0 -5
- package/dist/components/renderers/door/door-renderer.d.ts.map +0 -1
- package/dist/components/renderers/door/door-renderer.js +0 -16
- package/dist/components/renderers/fence/fence-renderer.d.ts +0 -5
- package/dist/components/renderers/fence/fence-renderer.d.ts.map +0 -1
- package/dist/components/renderers/fence/fence-renderer.js +0 -15
- package/dist/components/renderers/guide/guide-renderer.d.ts +0 -5
- package/dist/components/renderers/guide/guide-renderer.d.ts.map +0 -1
- package/dist/components/renderers/guide/guide-renderer.js +0 -38
- package/dist/components/renderers/item/item-renderer.d.ts +0 -5
- package/dist/components/renderers/item/item-renderer.d.ts.map +0 -1
- package/dist/components/renderers/item/item-renderer.js +0 -172
- package/dist/components/renderers/level/level-renderer.d.ts +0 -5
- package/dist/components/renderers/level/level-renderer.d.ts.map +0 -1
- package/dist/components/renderers/level/level-renderer.js +0 -11
- package/dist/components/renderers/roof/roof-materials.d.ts +0 -4
- package/dist/components/renderers/roof/roof-materials.d.ts.map +0 -1
- package/dist/components/renderers/roof/roof-materials.js +0 -16
- package/dist/components/renderers/roof/roof-renderer.d.ts +0 -5
- package/dist/components/renderers/roof/roof-renderer.d.ts.map +0 -1
- package/dist/components/renderers/roof/roof-renderer.js +0 -32
- package/dist/components/renderers/roof-segment/roof-segment-renderer.d.ts +0 -5
- package/dist/components/renderers/roof-segment/roof-segment-renderer.d.ts.map +0 -1
- package/dist/components/renderers/roof-segment/roof-segment-renderer.js +0 -40
- package/dist/components/renderers/scan/scan-renderer.d.ts +0 -5
- package/dist/components/renderers/scan/scan-renderer.d.ts.map +0 -1
- package/dist/components/renderers/scan/scan-renderer.js +0 -54
- package/dist/components/renderers/site/site-renderer.d.ts +0 -5
- package/dist/components/renderers/site/site-renderer.d.ts.map +0 -1
- package/dist/components/renderers/site/site-renderer.js +0 -106
- package/dist/components/renderers/slab/slab-renderer.d.ts +0 -5
- package/dist/components/renderers/slab/slab-renderer.d.ts.map +0 -1
- package/dist/components/renderers/slab/slab-renderer.js +0 -58
- package/dist/components/renderers/spawn/spawn-renderer.d.ts +0 -5
- package/dist/components/renderers/spawn/spawn-renderer.d.ts.map +0 -1
- package/dist/components/renderers/spawn/spawn-renderer.js +0 -32
- package/dist/components/renderers/stair/stair-renderer.d.ts +0 -5
- package/dist/components/renderers/stair/stair-renderer.d.ts.map +0 -1
- package/dist/components/renderers/stair/stair-renderer.js +0 -603
- package/dist/components/renderers/stair-segment/stair-segment-renderer.d.ts +0 -5
- package/dist/components/renderers/stair-segment/stair-segment-renderer.d.ts.map +0 -1
- package/dist/components/renderers/stair-segment/stair-segment-renderer.js +0 -51
- package/dist/components/renderers/wall/wall-renderer.d.ts +0 -5
- package/dist/components/renderers/wall/wall-renderer.d.ts.map +0 -1
- package/dist/components/renderers/wall/wall-renderer.js +0 -16
- package/dist/components/renderers/window/window-renderer.d.ts +0 -5
- package/dist/components/renderers/window/window-renderer.d.ts.map +0 -1
- package/dist/components/renderers/window/window-renderer.js +0 -21
- package/dist/components/renderers/zone/zone-renderer.d.ts +0 -5
- package/dist/components/renderers/zone/zone-renderer.d.ts.map +0 -1
- package/dist/components/renderers/zone/zone-renderer.js +0 -181
- package/dist/components/viewer/ground-occluder.d.ts +0 -2
- package/dist/components/viewer/ground-occluder.d.ts.map +0 -1
- package/dist/components/viewer/ground-occluder.js +0 -79
|
@@ -1,8 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { sceneRegistry, useScene, } from '@pascal-app/core';
|
|
2
2
|
import { useFrame } from '@react-three/fiber';
|
|
3
3
|
// ============================================================================
|
|
4
4
|
// ITEM SYSTEM
|
|
5
5
|
// ============================================================================
|
|
6
|
+
/**
|
|
7
|
+
* Per-frame wall-side offset for items mounted to wall faces. The slab-
|
|
8
|
+
* elevation lift for floor items lives in the generic
|
|
9
|
+
* `<FloorElevationSystem>` and runs at priority 1 — it has already
|
|
10
|
+
* landed `mesh.position.y` by the time this system clears the dirty
|
|
11
|
+
* mark at priority 2.
|
|
12
|
+
*/
|
|
6
13
|
export const ItemSystem = () => {
|
|
7
14
|
const dirtyNodes = useScene((state) => state.dirtyNodes);
|
|
8
15
|
const clearDirty = useScene((state) => state.clearDirty);
|
|
@@ -12,31 +19,35 @@ export const ItemSystem = () => {
|
|
|
12
19
|
const nodes = useScene.getState().nodes;
|
|
13
20
|
dirtyNodes.forEach((id) => {
|
|
14
21
|
const node = nodes[id];
|
|
15
|
-
if (
|
|
22
|
+
if (node?.type !== 'item')
|
|
16
23
|
return;
|
|
17
24
|
const item = node;
|
|
18
25
|
const mesh = sceneRegistry.nodes.get(id);
|
|
19
26
|
if (!mesh)
|
|
20
27
|
return;
|
|
21
28
|
if (item.asset.attachTo === 'wall-side') {
|
|
22
|
-
// Wall-attached item: offset Z by half the
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
29
|
+
// Wall-attached item: offset Z by half the host wall's thickness.
|
|
30
|
+
// Roof-segment wall faces share the convention — the face frame's
|
|
31
|
+
// z = 0 is the wall mid-plane, so the same push lands the item on
|
|
32
|
+
// the outer surface.
|
|
33
|
+
const parent = item.parentId ? nodes[item.parentId] : undefined;
|
|
34
|
+
const thickness = parent?.type === 'wall'
|
|
35
|
+
? (parent.thickness ?? 0.1)
|
|
36
|
+
: parent?.type === 'roof-segment'
|
|
37
|
+
? (parent.wallThickness ?? 0.1)
|
|
38
|
+
: undefined;
|
|
39
|
+
if (thickness !== undefined) {
|
|
26
40
|
const side = item.side === 'front' ? 1 : -1;
|
|
27
|
-
mesh.position.z = (
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
else if (!item.asset.attachTo) {
|
|
31
|
-
// If parented to another item (surface placement), R3F handles positioning via the hierarchy
|
|
32
|
-
const parentNode = item.parentId ? nodes[item.parentId] : undefined;
|
|
33
|
-
if (parentNode?.type !== 'item') {
|
|
34
|
-
// Floor item: elevate by slab height (using full footprint overlap)
|
|
35
|
-
const levelId = resolveLevelId(item, nodes);
|
|
36
|
-
const slabElevation = spatialGridManager.getSlabElevationForItem(levelId, item.position, getScaledDimensions(item), item.rotation);
|
|
37
|
-
mesh.position.y = slabElevation + item.position[1];
|
|
41
|
+
mesh.position.z = (thickness / 2) * side;
|
|
38
42
|
}
|
|
39
43
|
}
|
|
44
|
+
// Hold the mark until the model settles (loaded, terminally failed, or
|
|
45
|
+
// never expected — see ItemRenderer.markSettled). Registration alone
|
|
46
|
+
// isn't "built": clearing then would let scene-ready fire while GLBs are
|
|
47
|
+
// still downloading and a bake would export loading placeholders.
|
|
48
|
+
const settled = mesh.userData.itemModelSettled;
|
|
49
|
+
if (!settled)
|
|
50
|
+
return;
|
|
40
51
|
clearDirty(id);
|
|
41
52
|
});
|
|
42
53
|
}, 2);
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare function ItemLightSystem(): import("react
|
|
1
|
+
export declare function ItemLightSystem(): import("react").JSX.Element;
|
|
2
2
|
//# sourceMappingURL=item-light-system.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"item-light-system.d.ts","sourceRoot":"","sources":["../../../src/systems/item-light/item-light-system.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"item-light-system.d.ts","sourceRoot":"","sources":["../../../src/systems/item-light/item-light-system.tsx"],"names":[],"mappings":"AAuFA,wBAAgB,eAAe,gCA8N9B"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { sceneRegistry, useInteractive, useScene } from '@pascal-app/core';
|
|
2
|
+
import { findLevelAncestorId, sceneRegistry, useInteractive, useScene } from '@pascal-app/core';
|
|
3
3
|
import { useFrame } from '@react-three/fiber';
|
|
4
4
|
import { useRef } from 'react';
|
|
5
5
|
import { MathUtils, Vector3 } from 'three';
|
|
@@ -42,8 +42,7 @@ function scoreRegistration(reg, nodes, selectedLevelId, levelMode, interactiveSt
|
|
|
42
42
|
// Normalised distance component (assumes scenes < 200 units)
|
|
43
43
|
const dist = _camPos.distanceTo(_itemPos) / 200;
|
|
44
44
|
// ── Level factor ──────────────────────────────────────────────────────────
|
|
45
|
-
const
|
|
46
|
-
const itemLevelId = node?.parentId ?? null;
|
|
45
|
+
const itemLevelId = findLevelAncestorId(nodeId, nodes);
|
|
47
46
|
let levelPenalty = 0;
|
|
48
47
|
if (selectedLevelId) {
|
|
49
48
|
if (itemLevelId !== selectedLevelId) {
|
|
@@ -97,7 +96,10 @@ export function ItemLightSystem() {
|
|
|
97
96
|
}
|
|
98
97
|
scored.sort((a, b) => a.score - b.score);
|
|
99
98
|
// Build the desired assignment (top POOL_SIZE keys)
|
|
100
|
-
const desired = scored
|
|
99
|
+
const desired = scored
|
|
100
|
+
.filter((s) => Number.isFinite(s.score))
|
|
101
|
+
.slice(0, POOL_SIZE)
|
|
102
|
+
.map((s) => s.key);
|
|
101
103
|
// Build a map of currently-assigned keys → slot index for hysteresis
|
|
102
104
|
const currentlyAssigned = new Map();
|
|
103
105
|
for (let i = 0; i < POOL_SIZE; i++) {
|
|
@@ -181,9 +183,11 @@ export function ItemLightSystem() {
|
|
|
181
183
|
continue;
|
|
182
184
|
// Fade-out phase: lerp intensity → 0, then complete the transition
|
|
183
185
|
if (slot.isFadingOut) {
|
|
186
|
+
light.visible = true;
|
|
184
187
|
light.intensity = MathUtils.lerp(light.intensity, 0, dt * 12);
|
|
185
188
|
if (light.intensity < 0.01) {
|
|
186
189
|
light.intensity = 0;
|
|
190
|
+
light.visible = false;
|
|
187
191
|
slot.isFadingOut = false;
|
|
188
192
|
slot.key = slot.pendingKey;
|
|
189
193
|
slot.pendingKey = null;
|
|
@@ -200,12 +204,14 @@ export function ItemLightSystem() {
|
|
|
200
204
|
if (!slot.key) {
|
|
201
205
|
// Idle slot — keep dark
|
|
202
206
|
light.intensity = 0;
|
|
207
|
+
light.visible = false;
|
|
203
208
|
continue;
|
|
204
209
|
}
|
|
205
210
|
const reg = registrations.get(slot.key);
|
|
206
211
|
if (!reg) {
|
|
207
212
|
slot.key = null;
|
|
208
213
|
light.intensity = 0;
|
|
214
|
+
light.visible = false;
|
|
209
215
|
continue;
|
|
210
216
|
}
|
|
211
217
|
// Snap world position each frame
|
|
@@ -226,10 +232,17 @@ export function ItemLightSystem() {
|
|
|
226
232
|
const targetIntensity = isOn
|
|
227
233
|
? MathUtils.lerp(reg.effect.intensityRange[0], reg.effect.intensityRange[1], t)
|
|
228
234
|
: reg.effect.intensityRange[0];
|
|
235
|
+
if (targetIntensity > 0) {
|
|
236
|
+
light.visible = true;
|
|
237
|
+
}
|
|
229
238
|
light.intensity = MathUtils.lerp(light.intensity, targetIntensity, dt * 12);
|
|
239
|
+
if (targetIntensity <= 0 && light.intensity < 0.01) {
|
|
240
|
+
light.intensity = 0;
|
|
241
|
+
light.visible = false;
|
|
242
|
+
}
|
|
230
243
|
}
|
|
231
244
|
});
|
|
232
|
-
return (_jsx(_Fragment, { children: Array.from({ length: POOL_SIZE }, (_, i) => (_jsx("pointLight", { castShadow: false, intensity: 0, ref: (el) => {
|
|
245
|
+
return (_jsx(_Fragment, { children: Array.from({ length: POOL_SIZE }, (_, i) => (_jsx("pointLight", { castShadow: false, intensity: 0, visible: false, ref: (el) => {
|
|
233
246
|
lightRefs.current[i] = el;
|
|
234
247
|
} }, i))) }));
|
|
235
248
|
}
|
|
@@ -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":"AAeA,eAAO,MAAM,WAAW,YA6DvB,CAAA"}
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
import { sceneRegistry, useScene } from '@pascal-app/core';
|
|
1
|
+
import { getLevelHeight, sceneRegistry, useScene } from '@pascal-app/core';
|
|
2
2
|
import { useFrame } from '@react-three/fiber';
|
|
3
3
|
import { lerp } from 'three/src/math/MathUtils.js';
|
|
4
|
+
import { applyShadowOnly, clearShadowOnly } from '../../lib/shadow-only';
|
|
4
5
|
import useViewer from '../../store/use-viewer';
|
|
5
|
-
import { getLevelHeight } from './level-utils';
|
|
6
6
|
const EXPLODED_GAP = 5;
|
|
7
|
+
// Levels currently in shadow-caster-only mode (solo hides them from the color
|
|
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
12
|
export const LevelSystem = () => {
|
|
8
13
|
useFrame((_, delta) => {
|
|
9
14
|
const nodes = useScene.getState().nodes;
|
|
@@ -19,6 +24,9 @@ export const LevelSystem = () => {
|
|
|
19
24
|
});
|
|
20
25
|
entries.sort((a, b) => a.index - b.index);
|
|
21
26
|
// Walk sorted levels, accumulating base Y offsets
|
|
27
|
+
const selectedIndex = selectedLevel
|
|
28
|
+
? entries.find((e) => e.levelId === selectedLevel)?.index
|
|
29
|
+
: undefined;
|
|
22
30
|
let cumulativeY = 0;
|
|
23
31
|
for (const { levelId, index, obj } of entries) {
|
|
24
32
|
const level = nodes[levelId];
|
|
@@ -26,8 +34,24 @@ export const LevelSystem = () => {
|
|
|
26
34
|
const explodedExtra = levelMode === 'exploded' ? index * EXPLODED_GAP : 0;
|
|
27
35
|
const targetY = baseY + explodedExtra;
|
|
28
36
|
obj.position.y = lerp(obj.position.y, targetY, delta * 12); // Smoothly animate to new Y position
|
|
29
|
-
|
|
30
|
-
|
|
37
|
+
// Solo: hidden levels ABOVE the soloed one stay in the shadow map
|
|
38
|
+
// (shadow-caster-only) so the sun still shadows the soloed floor through
|
|
39
|
+
// them; levels below can't block the sun, so they plain-hide.
|
|
40
|
+
const hidden = levelMode === 'solo' && Boolean(selectedLevel) && level?.id !== selectedLevel;
|
|
41
|
+
const castsWhileHidden = hidden && selectedIndex !== undefined && index > selectedIndex;
|
|
42
|
+
if (castsWhileHidden) {
|
|
43
|
+
applyShadowOnly(obj);
|
|
44
|
+
shadowOnlyLevels.add(obj);
|
|
45
|
+
obj.visible = true;
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
if (shadowOnlyLevels.has(obj)) {
|
|
49
|
+
clearShadowOnly(obj);
|
|
50
|
+
shadowOnlyLevels.delete(obj);
|
|
51
|
+
}
|
|
52
|
+
obj.visible = !hidden;
|
|
53
|
+
}
|
|
54
|
+
cumulativeY += getLevelHeight(levelId, nodes, (wallId) => sceneRegistry.nodes.get(wallId)?.position.y);
|
|
31
55
|
}
|
|
32
56
|
}, 5); // Using a lower priority so it runs after transforms from other systems have settled
|
|
33
57
|
return null;
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import { useScene } from '@pascal-app/core';
|
|
2
|
-
export declare const DEFAULT_LEVEL_HEIGHT = 2.5;
|
|
3
|
-
export declare function getLevelHeight(levelId: string, nodes: ReturnType<typeof useScene.getState>['nodes']): number;
|
|
4
1
|
/**
|
|
5
2
|
* Instantly snaps all level Objects3D to their true stacked Y positions
|
|
6
3
|
* (ignores levelMode — always uses stacked, no exploded gap).
|
|
@@ -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":"AAEA;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,IAAI,CA6CtD"}
|
|
@@ -1,43 +1,4 @@
|
|
|
1
|
-
import { sceneRegistry, useScene
|
|
2
|
-
export const DEFAULT_LEVEL_HEIGHT = 2.5;
|
|
3
|
-
// Cache: levelId → computed height. Invalidated when the nodes reference changes.
|
|
4
|
-
// Zustand produces a new `nodes` object on every mutation, so reference equality
|
|
5
|
-
// is a zero-cost way to detect stale data without any subscription overhead.
|
|
6
|
-
const heightCache = new Map();
|
|
7
|
-
let lastNodesRef = null;
|
|
8
|
-
export function getLevelHeight(levelId, nodes) {
|
|
9
|
-
if (nodes !== lastNodesRef) {
|
|
10
|
-
heightCache.clear();
|
|
11
|
-
lastNodesRef = nodes;
|
|
12
|
-
}
|
|
13
|
-
if (heightCache.has(levelId))
|
|
14
|
-
return heightCache.get(levelId);
|
|
15
|
-
const level = nodes[levelId];
|
|
16
|
-
if (!level)
|
|
17
|
-
return DEFAULT_LEVEL_HEIGHT;
|
|
18
|
-
let maxTop = 0;
|
|
19
|
-
for (const childId of level.children) {
|
|
20
|
-
const child = nodes[childId];
|
|
21
|
-
if (!child)
|
|
22
|
-
continue;
|
|
23
|
-
if (child.type === 'ceiling') {
|
|
24
|
-
const ch = child.height ?? DEFAULT_LEVEL_HEIGHT;
|
|
25
|
-
if (ch > maxTop)
|
|
26
|
-
maxTop = ch;
|
|
27
|
-
}
|
|
28
|
-
else if (child.type === 'wall') {
|
|
29
|
-
let meshY = sceneRegistry.nodes.get(childId)?.position.y ?? 0;
|
|
30
|
-
if (meshY < 0)
|
|
31
|
-
meshY = 0;
|
|
32
|
-
const top = meshY + (child.height ?? DEFAULT_LEVEL_HEIGHT);
|
|
33
|
-
if (top > maxTop)
|
|
34
|
-
maxTop = top;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
const height = maxTop > 0 ? maxTop : DEFAULT_LEVEL_HEIGHT;
|
|
38
|
-
heightCache.set(levelId, height);
|
|
39
|
-
return height;
|
|
40
|
-
}
|
|
1
|
+
import { getLevelHeight, sceneRegistry, useScene } from '@pascal-app/core';
|
|
41
2
|
/**
|
|
42
3
|
* Instantly snaps all level Objects3D to their true stacked Y positions
|
|
43
4
|
* (ignores levelMode — always uses stacked, no exploded gap).
|
|
@@ -68,7 +29,7 @@ export function snapLevelsToTruePositions() {
|
|
|
68
29
|
for (const { levelId, obj } of entries) {
|
|
69
30
|
obj.position.y = cumulativeY;
|
|
70
31
|
obj.visible = true;
|
|
71
|
-
cumulativeY += getLevelHeight(levelId, nodes);
|
|
32
|
+
cumulativeY += getLevelHeight(levelId, nodes, (wallId) => sceneRegistry.nodes.get(wallId)?.position.y);
|
|
72
33
|
}
|
|
73
34
|
return () => {
|
|
74
35
|
for (const { levelId, obj } of entries) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type RoofNode } from '@pascal-app/core';
|
|
2
|
-
import * as THREE from 'three';
|
|
2
|
+
import type * as THREE from 'three';
|
|
3
|
+
import { type ColorPreset, type RenderShading } from '../../lib/materials';
|
|
3
4
|
export type RoofMaterialArray = [THREE.Material, THREE.Material, THREE.Material, THREE.Material];
|
|
4
|
-
export declare function getRoofMaterialArray(node: RoofNode): RoofMaterialArray | null;
|
|
5
|
+
export declare function getRoofMaterialArray(node: RoofNode, shading?: RenderShading, textures?: boolean, colorPreset?: ColorPreset, sceneTheme?: string): RoofMaterialArray | null;
|
|
5
6
|
//# 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,EAEL,KAAK,QAAQ,EAEd,MAAM,kBAAkB,CAAA;AACzB,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"roof-materials.d.ts","sourceRoot":"","sources":["../../../src/systems/roof/roof-materials.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,QAAQ,EAEd,MAAM,kBAAkB,CAAA;AACzB,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAA;AACnC,OAAO,EACL,KAAK,WAAW,EAIhB,KAAK,aAAa,EAEnB,MAAM,qBAAqB,CAAA;AAa5B,MAAM,MAAM,iBAAiB,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAA;AA6BhG,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,QAAQ,EACd,OAAO,GAAE,aAA0B,EACnC,QAAQ,UAAO,EACf,WAAW,GAAE,WAAoB,EACjC,UAAU,CAAC,EAAE,MAAM,GAClB,iBAAiB,GAAG,IAAI,CAsE1B"}
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import { getEffectiveRoofSurfaceMaterial, } from '@pascal-app/core';
|
|
2
|
-
import
|
|
3
|
-
|
|
2
|
+
import { createMaterial, createMaterialFromPresetRef, createSurfaceRoleMaterial, resolveSlotDefaultMaterial, } from '../../lib/materials';
|
|
3
|
+
// Declared catalog defaults for an unpainted roof, per the 4-slot layout
|
|
4
|
+
// (0 wall/trim · 1 deck · 2 interior soffit · 3 shingle top). The wall/trim
|
|
5
|
+
// band mirrors the wall kind's default (WALL_SLOT_DEFAULT = concrete-drywall)
|
|
6
|
+
// so a roof reads as continuous with the walls below it.
|
|
7
|
+
const ROOF_DEFAULT_REFS = [
|
|
8
|
+
'library:concrete-drywall',
|
|
9
|
+
'library:preset-softwhite',
|
|
10
|
+
'library:preset-softwhite',
|
|
11
|
+
'library:roof-terracottatiles',
|
|
12
|
+
];
|
|
4
13
|
const roofMaterialArrayCache = new Map();
|
|
5
14
|
function getSurfaceMaterialSignature(spec) {
|
|
6
15
|
return JSON.stringify({
|
|
@@ -8,20 +17,24 @@ function getSurfaceMaterialSignature(spec) {
|
|
|
8
17
|
materialPreset: spec.materialPreset ?? null,
|
|
9
18
|
});
|
|
10
19
|
}
|
|
11
|
-
function createResolvedMaterial(material, materialPreset) {
|
|
20
|
+
function createResolvedMaterial(material, materialPreset, shading) {
|
|
12
21
|
if (materialPreset) {
|
|
13
|
-
return createMaterialFromPresetRef(materialPreset);
|
|
22
|
+
return createMaterialFromPresetRef(materialPreset, shading);
|
|
14
23
|
}
|
|
15
24
|
if (material) {
|
|
16
|
-
return createMaterial(material);
|
|
25
|
+
return createMaterial(material, shading);
|
|
17
26
|
}
|
|
18
27
|
return null;
|
|
19
28
|
}
|
|
20
|
-
export function getRoofMaterialArray(node) {
|
|
29
|
+
export function getRoofMaterialArray(node, shading = 'rendered', textures = true, colorPreset = 'clay', sceneTheme) {
|
|
21
30
|
const top = getEffectiveRoofSurfaceMaterial(node, 'top');
|
|
22
31
|
const edge = getEffectiveRoofSurfaceMaterial(node, 'edge');
|
|
23
32
|
const wall = getEffectiveRoofSurfaceMaterial(node, 'wall');
|
|
24
33
|
const cacheKey = JSON.stringify({
|
|
34
|
+
shading,
|
|
35
|
+
textures,
|
|
36
|
+
colorPreset,
|
|
37
|
+
sceneTheme,
|
|
25
38
|
top: getSurfaceMaterialSignature(top),
|
|
26
39
|
edge: getSurfaceMaterialSignature(edge),
|
|
27
40
|
wall: getSurfaceMaterialSignature(wall),
|
|
@@ -29,17 +42,49 @@ export function getRoofMaterialArray(node) {
|
|
|
29
42
|
const cached = roofMaterialArrayCache.get(cacheKey);
|
|
30
43
|
if (cached)
|
|
31
44
|
return cached;
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
45
|
+
// Themed role colours: roof top/edge use the 'roof' role, the soffit/underside
|
|
46
|
+
// uses 'ceiling'. These also fill any untextured slot so an untextured roof is
|
|
47
|
+
// theme-coloured regardless of the textures toggle (no more white default).
|
|
48
|
+
const roofMaterial = createSurfaceRoleMaterial('roof', colorPreset, undefined, sceneTheme);
|
|
49
|
+
const ceilingMaterial = createSurfaceRoleMaterial('ceiling', colorPreset, undefined, sceneTheme);
|
|
50
|
+
const roleArray = [
|
|
51
|
+
roofMaterial,
|
|
52
|
+
ceilingMaterial,
|
|
53
|
+
ceilingMaterial,
|
|
54
|
+
roofMaterial,
|
|
55
|
+
];
|
|
56
|
+
// Textures-off (monochrome) is the guaranteed escape hatch: themed role
|
|
57
|
+
// colours, no catalog finishes.
|
|
58
|
+
if (!textures) {
|
|
59
|
+
roofMaterialArrayCache.set(cacheKey, roleArray);
|
|
60
|
+
return roleArray;
|
|
61
|
+
}
|
|
62
|
+
// Textures-on default appearance: catalog finishes per slot (terracotta
|
|
63
|
+
// shingle, soft-white deck/soffit, wall-coloured trim). Used both when the
|
|
64
|
+
// roof is unpainted and to fill any individual unpainted slot below.
|
|
65
|
+
const defaultArray = [
|
|
66
|
+
resolveSlotDefaultMaterial(ROOF_DEFAULT_REFS[0], shading),
|
|
67
|
+
resolveSlotDefaultMaterial(ROOF_DEFAULT_REFS[1], shading),
|
|
68
|
+
resolveSlotDefaultMaterial(ROOF_DEFAULT_REFS[2], shading),
|
|
69
|
+
resolveSlotDefaultMaterial(ROOF_DEFAULT_REFS[3], shading),
|
|
70
|
+
];
|
|
71
|
+
const topMaterial = createResolvedMaterial(top.material, top.materialPreset, shading);
|
|
72
|
+
const edgeMaterial = createResolvedMaterial(edge.material, edge.materialPreset, shading);
|
|
73
|
+
const wallMaterial = createResolvedMaterial(wall.material, wall.materialPreset, shading);
|
|
35
74
|
if (!(topMaterial || edgeMaterial || wallMaterial)) {
|
|
36
|
-
|
|
75
|
+
roofMaterialArrayCache.set(cacheKey, defaultArray);
|
|
76
|
+
return defaultArray;
|
|
37
77
|
}
|
|
78
|
+
// Each slot resolves to its own role only, then the declared default — never
|
|
79
|
+
// another role. Cross-role fallback here used to splatter a single painted
|
|
80
|
+
// surface (e.g. the edge) across the shingle and soffit slots. The legacy
|
|
81
|
+
// catch-all still fills every role because `getEffectiveRoofSurfaceMaterial`
|
|
82
|
+
// returns it for top/edge/wall alike.
|
|
38
83
|
const materialArray = [
|
|
39
|
-
edgeMaterial ??
|
|
40
|
-
wallMaterial ??
|
|
41
|
-
wallMaterial ??
|
|
42
|
-
topMaterial ??
|
|
84
|
+
edgeMaterial ?? defaultArray[0],
|
|
85
|
+
wallMaterial ?? defaultArray[1],
|
|
86
|
+
wallMaterial ?? defaultArray[2],
|
|
87
|
+
topMaterial ?? defaultArray[3],
|
|
43
88
|
];
|
|
44
89
|
roofMaterialArrayCache.set(cacheKey, materialArray);
|
|
45
90
|
return materialArray;
|
|
@@ -1,16 +1,56 @@
|
|
|
1
|
-
import { type RoofSegmentNode } from '@pascal-app/core';
|
|
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
4
|
export declare const RoofSystem: () => null;
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* Four dummy materials used as identity placeholders during CSG. Shared
|
|
7
|
+
* across every input brush so three-bvh-csg can preserve reference
|
|
8
|
+
* equality on the result and `mapRoofGroupMaterialIndex` can map result
|
|
9
|
+
* groups back to slots 0..3. Exposed so kinds that compose additional
|
|
10
|
+
* CSG ops on top of `getRoofSegmentBrushes` (e.g. dormer) use the same
|
|
11
|
+
* identity refs.
|
|
8
12
|
*/
|
|
9
|
-
export declare
|
|
13
|
+
export declare const roofCsgDummyMats: [
|
|
14
|
+
THREE.MeshBasicMaterial,
|
|
15
|
+
THREE.MeshBasicMaterial,
|
|
16
|
+
THREE.MeshBasicMaterial,
|
|
17
|
+
THREE.MeshBasicMaterial
|
|
18
|
+
];
|
|
19
|
+
export declare const ROOF_MATERIAL_SLOT_COUNT = 4;
|
|
20
|
+
type RoofSegmentBrushSet = {
|
|
10
21
|
deckSlab: Brush;
|
|
11
22
|
shinSlab: Brush;
|
|
12
23
|
wallBrush: Brush;
|
|
13
24
|
innerBrush: Brush;
|
|
14
|
-
|
|
15
|
-
|
|
25
|
+
rakeBoards: THREE.BufferGeometry | null;
|
|
26
|
+
};
|
|
27
|
+
export declare function mapRoofGroupMaterialIndex(groupMaterialIndex: number | undefined, csgMaterials: THREE.Material[], matToIndex: Map<THREE.Material, number>): number;
|
|
28
|
+
/**
|
|
29
|
+
* Subtract a segment's trim cuts from an arbitrary segment-local geometry,
|
|
30
|
+
* returning the clipped result. The input geometry is consumed (disposed) on
|
|
31
|
+
* each successful CSG pass — callers that need to keep the original must pass a
|
|
32
|
+
* clone. Returns the input untouched when the segment has no trim. Used
|
|
33
|
+
* internally for rake-board / end-slope attachments and exported so roof
|
|
34
|
+
* accessories (chimney, vents, skylight, …) can clip their own meshes by the
|
|
35
|
+
* same trim, in the same segment-local frame.
|
|
36
|
+
*/
|
|
37
|
+
export declare function clipGeometryBySegmentTrim(geometry: THREE.BufferGeometry | null, segment: RoofSegmentNode): THREE.BufferGeometry | null;
|
|
38
|
+
/**
|
|
39
|
+
* Generate complete hollow-shell geometry for a roof segment.
|
|
40
|
+
* Ports the prototype's CSG approach using three-bvh-csg.
|
|
41
|
+
*/
|
|
42
|
+
export declare function getRoofSegmentBrushes(node: RoofSegmentNode): RoofSegmentBrushSet | null;
|
|
43
|
+
export declare function generateRoofSegmentGeometry(node: RoofSegmentNode, nodes?: Record<string, AnyNode>): THREE.BufferGeometry;
|
|
44
|
+
export declare function remapRoofShellFaces(geometry: THREE.BufferGeometry, node: RoofSegmentNode): void;
|
|
45
|
+
export type SurfaceFrame = {
|
|
46
|
+
point: THREE.Vector3;
|
|
47
|
+
normal: THREE.Vector3;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Returns the outer roof surface frame (point + normal) at a given segment-local XZ.
|
|
51
|
+
* This is used for skylight placement + cut direction so cutouts remain perpendicular
|
|
52
|
+
* to the true roof surface even on multi-slope roofs (gambrel/mansard/dutch).
|
|
53
|
+
*/
|
|
54
|
+
export declare function getRoofOuterSurfaceFrameAtPoint(segment: RoofSegmentNode, lx: number, lz: number): SurfaceFrame;
|
|
55
|
+
export {};
|
|
16
56
|
//# sourceMappingURL=roof-system.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roof-system.d.ts","sourceRoot":"","sources":["../../../src/systems/roof/roof-system.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"roof-system.d.ts","sourceRoot":"","sources":["../../../src/systems/roof/roof-system.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EAcZ,KAAK,eAAe,EAKrB,MAAM,kBAAkB,CAAA;AAEzB,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAAY,KAAK,EAA0B,MAAM,eAAe,CAAA;AAwIvE,eAAO,MAAM,UAAU,YAuItB,CAAA;AAmXD;;;;;;;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;AA0FD,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;AAgUD;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,KAAK,CAAC,cAAc,GAAG,IAAI,EACrC,OAAO,EAAE,eAAe,GACvB,KAAK,CAAC,cAAc,GAAG,IAAI,CAyB7B;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,eAAe,GAAG,mBAAmB,GAAG,IAAI,CA+SvF;AAED,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,eAAe,EACrB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,KAAK,CAAC,cAAc,CAsFtB;AAsLD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,KAAK,CAAC,cAAc,EAAE,IAAI,EAAE,eAAe,QA2ExF;AAijBD,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"}
|