@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
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { createSceneApi, isNodeKindEnabled, nodeRegistry, useScene, } from '@pascal-app/core';
|
|
4
|
+
import { lazy, Suspense, useMemo } from 'react';
|
|
5
|
+
const DEFAULT_PRIORITY = 5;
|
|
6
|
+
const lazyCache = new WeakMap();
|
|
7
|
+
function loadSystem(def) {
|
|
8
|
+
if (!def.system)
|
|
9
|
+
return null;
|
|
10
|
+
const cached = lazyCache.get(def.system.module);
|
|
11
|
+
if (cached)
|
|
12
|
+
return cached;
|
|
13
|
+
const Comp = lazy(def.system.module);
|
|
14
|
+
lazyCache.set(def.system.module, Comp);
|
|
15
|
+
return Comp;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Mounts every registered node kind's system component, ordered by
|
|
19
|
+
* `system.priority` (default {@link DEFAULT_PRIORITY}).
|
|
20
|
+
*
|
|
21
|
+
* Today the registry is empty so this component mounts nothing — coexists
|
|
22
|
+
* with legacy `*-System` components in `<Viewer>`. Once kinds register via
|
|
23
|
+
* `@pascal-app/nodes`, each kind's registry-driven system takes over and
|
|
24
|
+
* its legacy counterpart short-circuits via the `nodeRegistry.has(kind)`
|
|
25
|
+
* guard added to each legacy system.
|
|
26
|
+
*/
|
|
27
|
+
export function RegisteredSystems() {
|
|
28
|
+
const sceneApi = useMemo(() => createSceneApi(useScene), []);
|
|
29
|
+
const installedPlugins = useScene((state) => state.installedPlugins);
|
|
30
|
+
const entries = useMemo(() => {
|
|
31
|
+
return Array.from(nodeRegistry.entries())
|
|
32
|
+
.filter(([, def]) => def.system != null)
|
|
33
|
+
.sort(([, a], [, b]) => {
|
|
34
|
+
const pa = a.system?.priority ?? DEFAULT_PRIORITY;
|
|
35
|
+
const pb = b.system?.priority ?? DEFAULT_PRIORITY;
|
|
36
|
+
return pa - pb;
|
|
37
|
+
});
|
|
38
|
+
}, []);
|
|
39
|
+
if (entries.length === 0)
|
|
40
|
+
return null;
|
|
41
|
+
return (_jsx(Suspense, { fallback: null, children: entries.map(([kind, def]) => {
|
|
42
|
+
if (!isNodeKindEnabled(kind, installedPlugins))
|
|
43
|
+
return null;
|
|
44
|
+
const Comp = loadSystem(def);
|
|
45
|
+
if (!Comp)
|
|
46
|
+
return null;
|
|
47
|
+
return _jsx(Comp, { sceneApi: sceneApi }, `registered-system:${kind}`);
|
|
48
|
+
}) }));
|
|
49
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import { type Group, Mesh } from 'three';
|
|
3
|
+
import { type SplitStrategy } from 'three-mesh-bvh';
|
|
4
|
+
type SceneBvhProps = {
|
|
5
|
+
children?: ReactNode;
|
|
6
|
+
enabled?: boolean;
|
|
7
|
+
firstHitOnly?: boolean;
|
|
8
|
+
strategy?: SplitStrategy;
|
|
9
|
+
verbose?: boolean;
|
|
10
|
+
setBoundingBox?: boolean;
|
|
11
|
+
maxDepth?: number;
|
|
12
|
+
maxLeafSize?: number;
|
|
13
|
+
indirect?: boolean;
|
|
14
|
+
};
|
|
15
|
+
export declare const isSceneBvhExcluded: (object: Mesh) => boolean;
|
|
16
|
+
export declare const SceneBvh: import("react").ForwardRefExoticComponent<SceneBvhProps & import("react").RefAttributes<Group<import("three").Object3DEventMap>>>;
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=scene-bvh.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scene-bvh.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/scene-bvh.tsx"],"names":[],"mappings":"AACA,OAAO,EAAc,KAAK,SAAS,EAA0C,MAAM,OAAO,CAAA;AAC1F,OAAO,EAAuB,KAAK,KAAK,EAAE,IAAI,EAAE,MAAM,OAAO,CAAA;AAC7D,OAAO,EAKL,KAAK,aAAa,EACnB,MAAM,gBAAgB,CAAA;AAEvB,KAAK,aAAa,GAAG;IACnB,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,QAAQ,CAAC,EAAE,aAAa,CAAA;IACxB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,CAAA;AAKD,eAAO,MAAM,kBAAkB,GAAI,QAAQ,IAAI,YAA4C,CAAA;AAY3F,eAAO,MAAM,QAAQ,mIAoGpB,CAAA"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useThree } from '@react-three/fiber';
|
|
3
|
+
import { forwardRef, useEffect, useImperativeHandle, useRef } from 'react';
|
|
4
|
+
import { Mesh } from 'three';
|
|
5
|
+
import { acceleratedRaycast, computeBoundsTree, disposeBoundsTree, SAH, } from 'three-mesh-bvh';
|
|
6
|
+
const isMesh = (object) => !!object && typeof object === 'object' && object.isMesh === true;
|
|
7
|
+
export const isSceneBvhExcluded = (object) => object.userData.excludeFromBvh === true;
|
|
8
|
+
const hasBvhCompatibleGeometry = (geometry) => {
|
|
9
|
+
if (!geometry)
|
|
10
|
+
return false;
|
|
11
|
+
const position = geometry.getAttribute('position');
|
|
12
|
+
if (!position)
|
|
13
|
+
return false;
|
|
14
|
+
const vertexCount = geometry.getIndex()?.count ?? position.count;
|
|
15
|
+
return vertexCount >= 3;
|
|
16
|
+
};
|
|
17
|
+
export const SceneBvh = forwardRef(({ children, enabled = true, firstHitOnly = false, strategy = SAH, verbose = false, setBoundingBox = true, maxDepth = 40, maxLeafSize = 10, indirect = false, }, forwardedRef) => {
|
|
18
|
+
const ref = useRef(null);
|
|
19
|
+
const raycaster = useThree((state) => state.raycaster);
|
|
20
|
+
useImperativeHandle(forwardedRef, () => ref.current, []);
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
if (!enabled || !ref.current)
|
|
23
|
+
return;
|
|
24
|
+
const options = {
|
|
25
|
+
strategy,
|
|
26
|
+
verbose,
|
|
27
|
+
setBoundingBox,
|
|
28
|
+
maxDepth,
|
|
29
|
+
maxLeafSize,
|
|
30
|
+
indirect,
|
|
31
|
+
};
|
|
32
|
+
const group = ref.current;
|
|
33
|
+
const acceleratedMeshes = new Set();
|
|
34
|
+
const computedGeometries = new Set();
|
|
35
|
+
raycaster.firstHitOnly = firstHitOnly;
|
|
36
|
+
group.traverse((child) => {
|
|
37
|
+
if (!isMesh(child))
|
|
38
|
+
return;
|
|
39
|
+
if (isSceneBvhExcluded(child))
|
|
40
|
+
return;
|
|
41
|
+
if (child.raycast === Mesh.prototype.raycast) {
|
|
42
|
+
child.raycast = acceleratedRaycast;
|
|
43
|
+
acceleratedMeshes.add(child);
|
|
44
|
+
}
|
|
45
|
+
if (child.raycast !== acceleratedRaycast)
|
|
46
|
+
return;
|
|
47
|
+
const geometry = child.geometry;
|
|
48
|
+
if (geometry.boundsTree || !hasBvhCompatibleGeometry(geometry))
|
|
49
|
+
return;
|
|
50
|
+
try {
|
|
51
|
+
// The three-mesh-bvh + @types/three combo doesn't agree on
|
|
52
|
+
// BVH option / class identity (ComputeBVHOptions vs
|
|
53
|
+
// MeshBVHOptions, GeometryBVH vs MeshBVH) — cast through
|
|
54
|
+
// `unknown` to bypass the structural mismatch. Runtime is
|
|
55
|
+
// fine; we're just calling the library's own helpers.
|
|
56
|
+
;
|
|
57
|
+
geometry.computeBoundsTree =
|
|
58
|
+
computeBoundsTree;
|
|
59
|
+
geometry.disposeBoundsTree =
|
|
60
|
+
disposeBoundsTree;
|
|
61
|
+
geometry.computeBoundsTree(options);
|
|
62
|
+
computedGeometries.add(geometry);
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
console.warn('[viewer] Skipping BVH for incompatible mesh geometry.', {
|
|
66
|
+
mesh: child.name || child.type,
|
|
67
|
+
error,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
return () => {
|
|
72
|
+
delete raycaster.firstHitOnly;
|
|
73
|
+
for (const geometry of computedGeometries) {
|
|
74
|
+
if (geometry.boundsTree) {
|
|
75
|
+
geometry.disposeBoundsTree();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
for (const mesh of acceleratedMeshes) {
|
|
79
|
+
if (mesh.raycast === acceleratedRaycast) {
|
|
80
|
+
mesh.raycast = Mesh.prototype.raycast;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
}, [
|
|
85
|
+
enabled,
|
|
86
|
+
firstHitOnly,
|
|
87
|
+
strategy,
|
|
88
|
+
verbose,
|
|
89
|
+
setBoundingBox,
|
|
90
|
+
maxDepth,
|
|
91
|
+
maxLeafSize,
|
|
92
|
+
indirect,
|
|
93
|
+
raycaster,
|
|
94
|
+
]);
|
|
95
|
+
return _jsx("group", { ref: ref, children: children });
|
|
96
|
+
});
|
|
97
|
+
SceneBvh.displayName = 'SceneBvh';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scene-bvh.test.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/scene-bvh.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// @ts-expect-error — bun:test is provided by the Bun runtime; viewer does not
|
|
2
|
+
// include Bun ambient types in its production declaration build.
|
|
3
|
+
import { describe, expect, test } from 'bun:test';
|
|
4
|
+
import { Mesh } from 'three';
|
|
5
|
+
import { isSceneBvhExcluded } from './scene-bvh';
|
|
6
|
+
describe('scene BVH exclusions', () => {
|
|
7
|
+
test('keeps annotation meshes on their normal raycast path', () => {
|
|
8
|
+
expect(isSceneBvhExcluded(new Mesh())).toBe(false);
|
|
9
|
+
const annotation = new Mesh();
|
|
10
|
+
annotation.userData.excludeFromBvh = true;
|
|
11
|
+
expect(isSceneBvhExcluded(annotation)).toBe(true);
|
|
12
|
+
});
|
|
13
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scene-environment.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/scene-environment.tsx"],"names":[],"mappings":"AAmEA,wBAAgB,gBAAgB,SAkB/B"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { useThree } from '@react-three/fiber';
|
|
3
|
+
import { useEffect, useMemo } from 'react';
|
|
4
|
+
import * as THREE from 'three/webgpu';
|
|
5
|
+
import { getSceneTheme } from '../../lib/scene-themes';
|
|
6
|
+
import useViewer from '../../store/use-viewer';
|
|
7
|
+
/**
|
|
8
|
+
* Scene IBL — a small procedural gradient sky (cool zenith → warm horizon →
|
|
9
|
+
* dim ground bounce) used purely as the environment light source. The visible
|
|
10
|
+
* backdrop stays the flat theme background (composited in post-processing);
|
|
11
|
+
* this texture is never shown. Replaces the old `venice_sunset_1k.hdr` fetch:
|
|
12
|
+
* no network dependency, and the vertical color split means upward-facing
|
|
13
|
+
* surfaces read cooler than vertical ones instead of everything getting the
|
|
14
|
+
* same directionless warm wash. Exported as an opt-in <Viewer> child so
|
|
15
|
+
* embed / thumbnail surfaces that don't want IBL simply don't mount it.
|
|
16
|
+
* Only affects `rendered` shading (Lambert ignores env maps).
|
|
17
|
+
*/
|
|
18
|
+
// Linear-space gradient stops.
|
|
19
|
+
const ZENITH = [0.4, 0.56, 0.78];
|
|
20
|
+
const HORIZON = [0.95, 0.84, 0.66];
|
|
21
|
+
const GROUND = [0.38, 0.35, 0.3];
|
|
22
|
+
const ENV_INTENSITY = 0.6;
|
|
23
|
+
// The gradient sky is a daylight source; dark themes only want a whisper of it.
|
|
24
|
+
const ENV_INTENSITY_DARK = 0.2;
|
|
25
|
+
const WIDTH = 64;
|
|
26
|
+
const HEIGHT = 32;
|
|
27
|
+
function buildGradientSky() {
|
|
28
|
+
const data = new Float32Array(WIDTH * HEIGHT * 4);
|
|
29
|
+
for (let y = 0; y < HEIGHT; y++) {
|
|
30
|
+
// Row 0 = v0 = nadir, top row = zenith (equirect v spans -90°..+90°).
|
|
31
|
+
const lat = ((y + 0.5) / HEIGHT) * 2 - 1;
|
|
32
|
+
let r;
|
|
33
|
+
let g;
|
|
34
|
+
let b;
|
|
35
|
+
if (lat <= 0) {
|
|
36
|
+
// Below the horizon: flat ground bounce, slightly darker toward nadir.
|
|
37
|
+
const k = 1 + lat * 0.35;
|
|
38
|
+
r = GROUND[0] * k;
|
|
39
|
+
g = GROUND[1] * k;
|
|
40
|
+
b = GROUND[2] * k;
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
// pow < 1 widens the warm horizon band.
|
|
44
|
+
const t = lat ** 0.65;
|
|
45
|
+
r = HORIZON[0] + (ZENITH[0] - HORIZON[0]) * t;
|
|
46
|
+
g = HORIZON[1] + (ZENITH[1] - HORIZON[1]) * t;
|
|
47
|
+
b = HORIZON[2] + (ZENITH[2] - HORIZON[2]) * t;
|
|
48
|
+
}
|
|
49
|
+
for (let x = 0; x < WIDTH; x++) {
|
|
50
|
+
const i = (y * WIDTH + x) * 4;
|
|
51
|
+
data[i] = r;
|
|
52
|
+
data[i + 1] = g;
|
|
53
|
+
data[i + 2] = b;
|
|
54
|
+
data[i + 3] = 1;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const texture = new THREE.DataTexture(data, WIDTH, HEIGHT, THREE.RGBAFormat, THREE.FloatType);
|
|
58
|
+
texture.mapping = THREE.EquirectangularReflectionMapping;
|
|
59
|
+
texture.colorSpace = THREE.LinearSRGBColorSpace;
|
|
60
|
+
texture.needsUpdate = true;
|
|
61
|
+
return texture;
|
|
62
|
+
}
|
|
63
|
+
export function SceneEnvironment() {
|
|
64
|
+
const scene = useThree((state) => state.scene);
|
|
65
|
+
const texture = useMemo(buildGradientSky, []);
|
|
66
|
+
const appearance = useViewer((state) => getSceneTheme(state.sceneTheme).appearance);
|
|
67
|
+
useEffect(() => {
|
|
68
|
+
const prevEnvironment = scene.environment;
|
|
69
|
+
const prevIntensity = scene.environmentIntensity;
|
|
70
|
+
scene.environment = texture;
|
|
71
|
+
scene.environmentIntensity = appearance === 'dark' ? ENV_INTENSITY_DARK : ENV_INTENSITY;
|
|
72
|
+
return () => {
|
|
73
|
+
scene.environment = prevEnvironment;
|
|
74
|
+
scene.environmentIntensity = prevIntensity;
|
|
75
|
+
texture.dispose();
|
|
76
|
+
};
|
|
77
|
+
}, [scene, texture, appearance]);
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const SelectionManager: () => import("react
|
|
1
|
+
export declare const SelectionManager: () => import("react").JSX.Element;
|
|
2
2
|
//# sourceMappingURL=selection-manager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selection-manager.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/selection-manager.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"selection-manager.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/selection-manager.tsx"],"names":[],"mappings":"AAiTA,eAAO,MAAM,gBAAgB,mCAqG5B,CAAA"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { emitter, pointInPolygon, sceneRegistry, useScene, } from '@pascal-app/core';
|
|
3
|
+
import { emitter, getSelectableKinds, pointInPolygon, resolveSelectionProxyId, sceneRegistry, useScene, } from '@pascal-app/core';
|
|
4
4
|
import { useThree } from '@react-three/fiber';
|
|
5
5
|
import { useEffect, useRef } from 'react';
|
|
6
6
|
import { Vector3 } from 'three';
|
|
@@ -122,16 +122,18 @@ const isNodeInZone = (node, levelId, zoneId) => {
|
|
|
122
122
|
};
|
|
123
123
|
const getStrategy = () => {
|
|
124
124
|
const { buildingId, levelId, zoneId } = useViewer.getState().selection;
|
|
125
|
-
const computeNextIds = (
|
|
125
|
+
const computeNextIds = (nodeId, selectedIds, event) => {
|
|
126
126
|
const isMeta = event?.metaKey || event?.nativeEvent?.metaKey;
|
|
127
127
|
const isCtrl = event?.ctrlKey || event?.nativeEvent?.ctrlKey;
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
128
|
+
// Shift toggles membership like Cmd/Ctrl.
|
|
129
|
+
const isShift = event?.shiftKey || event?.nativeEvent?.shiftKey;
|
|
130
|
+
if (isMeta || isCtrl || isShift) {
|
|
131
|
+
if (selectedIds.includes(nodeId)) {
|
|
132
|
+
return selectedIds.filter((id) => id !== nodeId);
|
|
131
133
|
}
|
|
132
|
-
return [...selectedIds,
|
|
134
|
+
return [...selectedIds, nodeId];
|
|
133
135
|
}
|
|
134
|
-
return [
|
|
136
|
+
return [nodeId];
|
|
135
137
|
};
|
|
136
138
|
// No building selected -> can select buildings
|
|
137
139
|
if (!buildingId) {
|
|
@@ -195,9 +197,10 @@ const getStrategy = () => {
|
|
|
195
197
|
}
|
|
196
198
|
}
|
|
197
199
|
const { selectedIds } = useViewer.getState().selection;
|
|
200
|
+
const proxyId = resolveSelectionProxyId(nodeToSelect, useScene.getState().nodes);
|
|
198
201
|
useViewer
|
|
199
202
|
.getState()
|
|
200
|
-
.setSelection({ selectedIds: computeNextIds(
|
|
203
|
+
.setSelection({ selectedIds: computeNextIds(proxyId, selectedIds, nativeEvent) });
|
|
201
204
|
},
|
|
202
205
|
handleDeselect: () => {
|
|
203
206
|
const { selectedIds } = useViewer.getState().selection;
|
|
@@ -236,28 +239,43 @@ export const SelectionManager = () => {
|
|
|
236
239
|
const strategy = getStrategy();
|
|
237
240
|
if (!strategy)
|
|
238
241
|
return;
|
|
242
|
+
// Ceilings are selected via their floor-plan helper and the
|
|
243
|
+
// boundary-editor vertex handles, never via a direct 3D click on
|
|
244
|
+
// the polygon. Skipping selection routing here means a click on a
|
|
245
|
+
// ceiling falls through to the item / wall / floor below it.
|
|
246
|
+
if (event.node.type === 'ceiling')
|
|
247
|
+
return;
|
|
239
248
|
if (strategy.isValid(event.node)) {
|
|
240
249
|
event.stopPropagation();
|
|
241
250
|
if (event.node.type === 'slab') {
|
|
242
251
|
useViewer.setState({ hoveredId: null });
|
|
243
252
|
return;
|
|
244
253
|
}
|
|
245
|
-
useViewer.setState({
|
|
254
|
+
useViewer.setState({
|
|
255
|
+
hoveredId: resolveSelectionProxyId(event.node, useScene.getState().nodes),
|
|
256
|
+
});
|
|
246
257
|
}
|
|
247
258
|
};
|
|
248
259
|
const onLeave = (event) => {
|
|
249
260
|
const strategy = getStrategy();
|
|
250
261
|
if (!strategy)
|
|
251
262
|
return;
|
|
263
|
+
if (event.node.type === 'ceiling')
|
|
264
|
+
return;
|
|
252
265
|
if (strategy.isValid(event.node)) {
|
|
253
266
|
event.stopPropagation();
|
|
254
|
-
|
|
267
|
+
const targetId = resolveSelectionProxyId(event.node, useScene.getState().nodes);
|
|
268
|
+
if (useViewer.getState().hoveredId === targetId) {
|
|
269
|
+
useViewer.setState({ hoveredId: null });
|
|
270
|
+
}
|
|
255
271
|
}
|
|
256
272
|
};
|
|
257
273
|
const onClick = (event) => {
|
|
258
274
|
const strategy = getStrategy();
|
|
259
275
|
if (!strategy)
|
|
260
276
|
return;
|
|
277
|
+
if (event.node.type === 'ceiling')
|
|
278
|
+
return;
|
|
261
279
|
if (!strategy.isValid(event.node))
|
|
262
280
|
return;
|
|
263
281
|
event.stopPropagation();
|
|
@@ -266,7 +284,9 @@ export const SelectionManager = () => {
|
|
|
266
284
|
// Clear hover immediately after clicking on building/level/zone
|
|
267
285
|
useViewer.setState({ hoveredId: null });
|
|
268
286
|
};
|
|
269
|
-
// Subscribe to all node types
|
|
287
|
+
// Subscribe to all node types. Hardcoded kinds + registry-supplied kinds
|
|
288
|
+
// (any NodeDefinition declaring `capabilities.selectable`). Phase 6
|
|
289
|
+
// collapses these into a single registry-driven list.
|
|
270
290
|
const allTypes = [
|
|
271
291
|
'building',
|
|
272
292
|
'level',
|
|
@@ -282,13 +302,15 @@ export const SelectionManager = () => {
|
|
|
282
302
|
'window',
|
|
283
303
|
'door',
|
|
284
304
|
];
|
|
285
|
-
|
|
305
|
+
const registryKinds = getSelectableKinds().filter((k) => !allTypes.includes(k));
|
|
306
|
+
const subscribedKinds = [...allTypes, ...registryKinds];
|
|
307
|
+
for (const type of subscribedKinds) {
|
|
286
308
|
emitter.on(`${type}:enter`, onEnter);
|
|
287
309
|
emitter.on(`${type}:leave`, onLeave);
|
|
288
310
|
emitter.on(`${type}:click`, onClick);
|
|
289
311
|
}
|
|
290
312
|
return () => {
|
|
291
|
-
for (const type of
|
|
313
|
+
for (const type of subscribedKinds) {
|
|
292
314
|
emitter.off(`${type}:enter`, onEnter);
|
|
293
315
|
emitter.off(`${type}:leave`, onLeave);
|
|
294
316
|
emitter.off(`${type}:click`, onClick);
|
|
@@ -302,7 +324,8 @@ const PointerMissedHandler = ({ clickHandledRef, }) => {
|
|
|
302
324
|
useEffect(() => {
|
|
303
325
|
const handleClick = (event) => {
|
|
304
326
|
// Only handle left clicks
|
|
305
|
-
|
|
327
|
+
const viewerState = useViewer.getState();
|
|
328
|
+
if (viewerState.cameraDragging || viewerState.inputDragging)
|
|
306
329
|
return;
|
|
307
330
|
if (event.button !== 0)
|
|
308
331
|
return;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const ViewerCamera: () => import("react
|
|
1
|
+
export declare const ViewerCamera: () => import("react").JSX.Element;
|
|
2
2
|
//# sourceMappingURL=viewer-camera.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"viewer-camera.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/viewer-camera.tsx"],"names":[],"mappings":"AAGA,eAAO,MAAM,YAAY
|
|
1
|
+
{"version":3,"file":"viewer-camera.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/viewer-camera.tsx"],"names":[],"mappings":"AAGA,eAAO,MAAM,YAAY,mCAQxB,CAAA"}
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
export declare const
|
|
1
|
+
export declare const WALKTHROUGH_FOV = 60;
|
|
2
|
+
export declare const WalkthroughControls: () => import("react").JSX.Element | null;
|
|
2
3
|
//# sourceMappingURL=walkthrough-controls.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"walkthrough-controls.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/walkthrough-controls.tsx"],"names":[],"mappings":"AAeA,eAAO,MAAM,mBAAmB,
|
|
1
|
+
{"version":3,"file":"walkthrough-controls.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/walkthrough-controls.tsx"],"names":[],"mappings":"AAeA,eAAO,MAAM,eAAe,KAAK,CAAA;AAMjC,eAAO,MAAM,mBAAmB,0CAsI/B,CAAA"}
|
|
@@ -7,6 +7,11 @@ import { Vector3 } from 'three';
|
|
|
7
7
|
import useViewer from '../../store/use-viewer';
|
|
8
8
|
const MOVE_SPEED = 5;
|
|
9
9
|
const EYE_HEIGHT = 1.6;
|
|
10
|
+
// First-person FOV. The orbit camera is 50° (set on the Canvas), which feels
|
|
11
|
+
// cramped on foot; ~60° vertical (~90° horizontal at 16:9) restores peripheral
|
|
12
|
+
// awareness without wide-angle distortion. Applied only while walking — both
|
|
13
|
+
// walkthrough controllers read this and restore the orbit FOV on exit.
|
|
14
|
+
export const WALKTHROUGH_FOV = 60;
|
|
10
15
|
const _direction = new Vector3();
|
|
11
16
|
const _forward = new Vector3();
|
|
12
17
|
const _right = new Vector3();
|
|
@@ -21,6 +26,21 @@ export const WalkthroughControls = () => {
|
|
|
21
26
|
camera.position.y = EYE_HEIGHT;
|
|
22
27
|
}
|
|
23
28
|
}, [walkthroughMode, camera]);
|
|
29
|
+
// Widen FOV while walking; restore the orbit FOV on exit.
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
if (!walkthroughMode)
|
|
32
|
+
return;
|
|
33
|
+
const cam = camera;
|
|
34
|
+
if (!cam.isPerspectiveCamera)
|
|
35
|
+
return;
|
|
36
|
+
const prevFov = cam.fov;
|
|
37
|
+
cam.fov = WALKTHROUGH_FOV;
|
|
38
|
+
cam.updateProjectionMatrix();
|
|
39
|
+
return () => {
|
|
40
|
+
cam.fov = prevFov;
|
|
41
|
+
cam.updateProjectionMatrix();
|
|
42
|
+
};
|
|
43
|
+
}, [walkthroughMode, camera]);
|
|
24
44
|
// Keyboard handlers
|
|
25
45
|
useEffect(() => {
|
|
26
46
|
if (!walkthroughMode)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-gltf-ktx2.d.ts","sourceRoot":"","sources":["../../src/hooks/use-gltf-ktx2.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"use-gltf-ktx2.d.ts","sourceRoot":"","sources":["../../src/hooks/use-gltf-ktx2.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAK3C,QAAA,MAAM,WAAW,GAAI,MAAM,MAAM,KAAG,UAAU,CAAC,OAAO,OAAO,CAU5D,CAAA;AAED,OAAO,EAAE,WAAW,EAAE,CAAA"}
|
|
@@ -1,32 +1,13 @@
|
|
|
1
1
|
import { useGLTF } from '@react-three/drei';
|
|
2
2
|
import { useThree } from '@react-three/fiber';
|
|
3
|
-
import { KTX2Loader } from 'three/examples/jsm/Addons.js';
|
|
4
3
|
import { MeshoptDecoder } from 'three/examples/jsm/libs/meshopt_decoder.module.js';
|
|
5
|
-
|
|
6
|
-
ktx2LoaderInstance.setTranscoderPath('https://cdn.jsdelivr.net/gh/pmndrs/drei-assets@master/basis/');
|
|
7
|
-
const ktx2ConfiguredRenderers = new WeakSet();
|
|
8
|
-
const ktx2WarningLoggedRenderers = new WeakSet();
|
|
4
|
+
import { ensureKtx2Support, ktx2Loader } from '../lib/ktx2-loader';
|
|
9
5
|
const useGLTFKTX2 = (path) => {
|
|
10
6
|
const gl = useThree((state) => state.gl);
|
|
11
7
|
return useGLTF(path, true, true, (loader) => {
|
|
12
|
-
|
|
13
|
-
if (!ktx2ConfiguredRenderers.has(renderer)) {
|
|
14
|
-
try {
|
|
15
|
-
ktx2LoaderInstance.detectSupport(gl);
|
|
16
|
-
ktx2ConfiguredRenderers.add(renderer);
|
|
17
|
-
}
|
|
18
|
-
catch (error) {
|
|
19
|
-
// Some WebGPU flows can transiently call this before backend init.
|
|
20
|
-
// Avoid crashing the whole scene; scans may render without KTX2 on this pass.
|
|
21
|
-
if (!ktx2WarningLoggedRenderers.has(renderer)) {
|
|
22
|
-
console.warn('[viewer] Skipping KTX2 support detection for now.', error);
|
|
23
|
-
ktx2WarningLoggedRenderers.add(renderer);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
if (ktx2ConfiguredRenderers.has(renderer)) {
|
|
8
|
+
if (ensureKtx2Support(gl)) {
|
|
28
9
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
29
|
-
loader.setKTX2Loader(
|
|
10
|
+
loader.setKTX2Loader(ktx2Loader);
|
|
30
11
|
}
|
|
31
12
|
loader.setMeshoptDecoder(MeshoptDecoder);
|
|
32
13
|
});
|
|
@@ -1,80 +1,12 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type AnyNode, type AnyNodeType } from '@pascal-app/core';
|
|
2
2
|
import type { ThreeEvent } from '@react-three/fiber';
|
|
3
|
-
type
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
};
|
|
8
|
-
item: {
|
|
9
|
-
node: ItemNode;
|
|
10
|
-
event: ItemEvent;
|
|
11
|
-
};
|
|
12
|
-
wall: {
|
|
13
|
-
node: WallNode;
|
|
14
|
-
event: WallEvent;
|
|
15
|
-
};
|
|
16
|
-
fence: {
|
|
17
|
-
node: FenceNode;
|
|
18
|
-
event: FenceEvent;
|
|
19
|
-
};
|
|
20
|
-
building: {
|
|
21
|
-
node: BuildingNode;
|
|
22
|
-
event: BuildingEvent;
|
|
23
|
-
};
|
|
24
|
-
level: {
|
|
25
|
-
node: LevelNode;
|
|
26
|
-
event: LevelEvent;
|
|
27
|
-
};
|
|
28
|
-
zone: {
|
|
29
|
-
node: ZoneNode;
|
|
30
|
-
event: ZoneEvent;
|
|
31
|
-
};
|
|
32
|
-
slab: {
|
|
33
|
-
node: SlabNode;
|
|
34
|
-
event: SlabEvent;
|
|
35
|
-
};
|
|
36
|
-
spawn: {
|
|
37
|
-
node: SpawnNode;
|
|
38
|
-
event: SpawnEvent;
|
|
39
|
-
};
|
|
40
|
-
ceiling: {
|
|
41
|
-
node: CeilingNode;
|
|
42
|
-
event: CeilingEvent;
|
|
43
|
-
};
|
|
44
|
-
column: {
|
|
45
|
-
node: ColumnNode;
|
|
46
|
-
event: ColumnEvent;
|
|
47
|
-
};
|
|
48
|
-
roof: {
|
|
49
|
-
node: RoofNode;
|
|
50
|
-
event: RoofEvent;
|
|
51
|
-
};
|
|
52
|
-
'roof-segment': {
|
|
53
|
-
node: RoofSegmentNode;
|
|
54
|
-
event: RoofSegmentEvent;
|
|
55
|
-
};
|
|
56
|
-
stair: {
|
|
57
|
-
node: StairNode;
|
|
58
|
-
event: StairEvent;
|
|
59
|
-
};
|
|
60
|
-
'stair-segment': {
|
|
61
|
-
node: StairSegmentNode;
|
|
62
|
-
event: StairSegmentEvent;
|
|
63
|
-
};
|
|
64
|
-
window: {
|
|
65
|
-
node: WindowNode;
|
|
66
|
-
event: WindowEvent;
|
|
67
|
-
};
|
|
68
|
-
door: {
|
|
69
|
-
node: DoorNode;
|
|
70
|
-
event: DoorEvent;
|
|
71
|
-
};
|
|
72
|
-
};
|
|
73
|
-
type NodeType = keyof NodeConfig;
|
|
74
|
-
export declare function useNodeEvents<T extends NodeType>(node: NodeConfig[T]['node'], type: T): {
|
|
3
|
+
type NodeByKind<K extends AnyNodeType> = Extract<AnyNode, {
|
|
4
|
+
type: K;
|
|
5
|
+
}>;
|
|
6
|
+
export declare function useNodeEvents<K extends AnyNodeType>(node: NodeByKind<K>, type: K): {
|
|
75
7
|
onPointerDown: (e: ThreeEvent<PointerEvent>) => void;
|
|
76
8
|
onPointerUp: (e: ThreeEvent<PointerEvent>) => void;
|
|
77
|
-
onClick: (
|
|
9
|
+
onClick: (_e: ThreeEvent<PointerEvent>) => void;
|
|
78
10
|
onPointerEnter: (e: ThreeEvent<PointerEvent>) => void;
|
|
79
11
|
onPointerLeave: (e: ThreeEvent<PointerEvent>) => void;
|
|
80
12
|
onPointerMove: (e: ThreeEvent<PointerEvent>) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-node-events.d.ts","sourceRoot":"","sources":["../../src/hooks/use-node-events.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,
|
|
1
|
+
{"version":3,"file":"use-node-events.d.ts","sourceRoot":"","sources":["../../src/hooks/use-node-events.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,WAAW,EAIjB,MAAM,kBAAkB,CAAA;AACzB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAQpD,KAAK,UAAU,CAAC,CAAC,SAAS,WAAW,IAAI,OAAO,CAAC,OAAO,EAAE;IAAE,IAAI,EAAE,CAAC,CAAA;CAAE,CAAC,CAAA;AAEtE,wBAAgB,aAAa,CAAC,CAAC,SAAS,WAAW,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;uBAwC1D,UAAU,CAAC,YAAY,CAAC;qBAK1B,UAAU,CAAC,YAAY,CAAC;kBAQ3B,UAAU,CAAC,YAAY,CAAC;wBAIlB,UAAU,CAAC,YAAY,CAAC;wBAIxB,UAAU,CAAC,YAAY,CAAC;uBAIzB,UAAU,CAAC,YAAY,CAAC;uBAIxB,UAAU,CAAC,YAAY,CAAC;uBAIxB,UAAU,CAAC,YAAY,CAAC;EAK9C"}
|