@pascal-app/viewer 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/error-boundary.d.ts +7 -3
- package/dist/components/error-boundary.d.ts.map +1 -1
- package/dist/components/error-boundary.js +3 -1
- package/dist/components/renderers/ceiling/ceiling-renderer.d.ts.map +1 -1
- package/dist/components/renderers/ceiling/ceiling-renderer.js +19 -3
- package/dist/components/renderers/column/column-renderer.d.ts +5 -0
- package/dist/components/renderers/column/column-renderer.d.ts.map +1 -0
- package/dist/components/renderers/column/column-renderer.js +594 -0
- package/dist/components/renderers/door/door-renderer.d.ts.map +1 -1
- package/dist/components/renderers/door/door-renderer.js +4 -9
- package/dist/components/renderers/fence/fence-renderer.d.ts.map +1 -1
- package/dist/components/renderers/guide/guide-renderer.js +1 -1
- package/dist/components/renderers/item/item-renderer.d.ts.map +1 -1
- package/dist/components/renderers/item/item-renderer.js +2 -1
- package/dist/components/renderers/node-renderer.d.ts.map +1 -1
- package/dist/components/renderers/node-renderer.js +3 -1
- package/dist/components/renderers/roof/roof-renderer.d.ts.map +1 -1
- package/dist/components/renderers/roof/roof-renderer.js +1 -13
- package/dist/components/renderers/roof-segment/roof-segment-renderer.d.ts.map +1 -1
- package/dist/components/renderers/roof-segment/roof-segment-renderer.js +5 -20
- package/dist/components/renderers/slab/slab-renderer.d.ts.map +1 -1
- package/dist/components/renderers/slab/slab-renderer.js +39 -27
- package/dist/components/renderers/spawn/spawn-renderer.d.ts +5 -0
- package/dist/components/renderers/spawn/spawn-renderer.d.ts.map +1 -0
- package/dist/components/renderers/spawn/spawn-renderer.js +32 -0
- package/dist/components/renderers/stair/stair-renderer.d.ts.map +1 -1
- package/dist/components/renderers/stair/stair-renderer.js +5 -23
- package/dist/components/renderers/stair-segment/stair-segment-renderer.d.ts.map +1 -1
- package/dist/components/renderers/stair-segment/stair-segment-renderer.js +5 -22
- package/dist/components/viewer/index.d.ts +2 -0
- package/dist/components/viewer/index.d.ts.map +1 -1
- package/dist/components/viewer/index.js +88 -18
- package/dist/components/viewer/post-processing.d.ts +13 -1
- package/dist/components/viewer/post-processing.d.ts.map +1 -1
- package/dist/components/viewer/post-processing.js +71 -14
- package/dist/components/viewer/selection-manager.d.ts.map +1 -1
- package/dist/components/viewer/selection-manager.js +19 -2
- package/dist/hooks/use-node-events.d.ts +9 -1
- package/dist/hooks/use-node-events.d.ts.map +1 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/dist/lib/materials.d.ts +3 -0
- package/dist/lib/materials.d.ts.map +1 -1
- package/dist/lib/materials.js +14 -0
- package/dist/lib/merged-outline-node.d.ts +2 -0
- package/dist/lib/merged-outline-node.d.ts.map +1 -1
- package/dist/lib/merged-outline-node.js +25 -5
- package/dist/store/use-viewer.d.ts +4 -4
- package/dist/store/use-viewer.d.ts.map +1 -1
- package/dist/store/use-viewer.js +2 -2
- package/dist/systems/ceiling/ceiling-system.d.ts +8 -0
- package/dist/systems/ceiling/ceiling-system.d.ts.map +1 -0
- package/dist/systems/ceiling/ceiling-system.js +91 -0
- package/dist/systems/column/column-geometry.d.ts +22 -0
- package/dist/systems/column/column-geometry.d.ts.map +1 -0
- package/dist/systems/column/column-geometry.js +108 -0
- package/dist/systems/door/door-animation-system.d.ts +2 -0
- package/dist/systems/door/door-animation-system.d.ts.map +1 -0
- package/dist/systems/door/door-animation-system.js +53 -0
- package/dist/systems/door/door-system.d.ts +2 -0
- package/dist/systems/door/door-system.d.ts.map +1 -0
- package/dist/systems/door/door-system.js +867 -0
- package/dist/systems/fence/fence-system.d.ts +2 -0
- package/dist/systems/fence/fence-system.d.ts.map +1 -0
- package/dist/systems/fence/fence-system.js +185 -0
- package/dist/systems/item/item-system.d.ts +2 -0
- package/dist/systems/item/item-system.d.ts.map +1 -0
- package/dist/systems/item/item-system.js +44 -0
- package/dist/systems/item-mesh-metadata/compute-item-mesh-metadata.d.ts +14 -0
- package/dist/systems/item-mesh-metadata/compute-item-mesh-metadata.d.ts.map +1 -0
- package/dist/systems/item-mesh-metadata/compute-item-mesh-metadata.js +155 -0
- package/dist/systems/item-mesh-metadata/item-mesh-metadata-system.d.ts +6 -0
- package/dist/systems/item-mesh-metadata/item-mesh-metadata-system.d.ts.map +1 -0
- package/dist/systems/item-mesh-metadata/item-mesh-metadata-system.js +75 -0
- package/dist/systems/item-mesh-metadata/sync-request.d.ts +7 -0
- package/dist/systems/item-mesh-metadata/sync-request.d.ts.map +1 -0
- package/dist/systems/item-mesh-metadata/sync-request.js +25 -0
- package/dist/systems/roof/roof-materials.d.ts.map +1 -1
- package/dist/systems/roof/roof-materials.js +18 -1
- package/dist/systems/roof/roof-system.d.ts +16 -0
- package/dist/systems/roof/roof-system.d.ts.map +1 -0
- package/dist/systems/roof/roof-system.js +797 -0
- package/dist/systems/slab/slab-system.d.ts +8 -0
- package/dist/systems/slab/slab-system.d.ts.map +1 -0
- package/dist/systems/slab/slab-system.js +155 -0
- package/dist/systems/stair/stair-materials.d.ts.map +1 -1
- package/dist/systems/stair/stair-materials.js +25 -2
- package/dist/systems/stair/stair-system.d.ts +2 -0
- package/dist/systems/stair/stair-system.d.ts.map +1 -0
- package/dist/systems/stair/stair-system.js +772 -0
- package/dist/systems/wall/wall-materials.d.ts.map +1 -1
- package/dist/systems/wall/wall-materials.js +2 -2
- package/dist/systems/wall/wall-system.d.ts +11 -0
- package/dist/systems/wall/wall-system.d.ts.map +1 -0
- package/dist/systems/wall/wall-system.js +592 -0
- package/dist/systems/window/window-animation-system.d.ts +2 -0
- package/dist/systems/window/window-animation-system.d.ts.map +1 -0
- package/dist/systems/window/window-animation-system.js +135 -0
- package/dist/systems/window/window-system.d.ts +12 -0
- package/dist/systems/window/window-system.d.ts.map +1 -0
- package/dist/systems/window/window-system.js +1430 -0
- package/package.json +4 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { useInteractive, useRegistry, useScene, } from '@pascal-app/core';
|
|
3
3
|
import { useAnimations } from '@react-three/drei';
|
|
4
4
|
import { Clone } from '@react-three/drei/core/Clone';
|
|
5
5
|
import { useGLTF } from '@react-three/drei/core/Gltf';
|
|
@@ -10,6 +10,7 @@ import { positionLocal, smoothstep, time } from 'three/tsl';
|
|
|
10
10
|
import { MeshStandardNodeMaterial } from 'three/webgpu';
|
|
11
11
|
import { useNodeEvents } from '../../../hooks/use-node-events';
|
|
12
12
|
import { resolveCdnUrl } from '../../../lib/asset-url';
|
|
13
|
+
import { baseMaterial, glassMaterial } from '../../../lib/materials';
|
|
13
14
|
import { useItemLightPool } from '../../../store/use-item-light-pool';
|
|
14
15
|
import { ErrorBoundary } from '../../error-boundary';
|
|
15
16
|
import { NodeRenderer } from '../node-renderer';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-renderer.d.ts","sourceRoot":"","sources":["../../../src/components/renderers/node-renderer.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,OAAO,EAAY,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"node-renderer.d.ts","sourceRoot":"","sources":["../../../src/components/renderers/node-renderer.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,OAAO,EAAY,MAAM,kBAAkB,CAAA;AAqBzD,eAAO,MAAM,YAAY,GAAI,YAAY;IAAE,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,mDA4BjE,CAAA"}
|
|
@@ -3,6 +3,7 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
|
|
|
3
3
|
import { useScene } from '@pascal-app/core';
|
|
4
4
|
import { BuildingRenderer } from './building/building-renderer';
|
|
5
5
|
import { CeilingRenderer } from './ceiling/ceiling-renderer';
|
|
6
|
+
import { ColumnRenderer } from './column/column-renderer';
|
|
6
7
|
import { DoorRenderer } from './door/door-renderer';
|
|
7
8
|
import { FenceRenderer } from './fence/fence-renderer';
|
|
8
9
|
import { GuideRenderer } from './guide/guide-renderer';
|
|
@@ -13,6 +14,7 @@ import { RoofSegmentRenderer } from './roof-segment/roof-segment-renderer';
|
|
|
13
14
|
import { ScanRenderer } from './scan/scan-renderer';
|
|
14
15
|
import { SiteRenderer } from './site/site-renderer';
|
|
15
16
|
import { SlabRenderer } from './slab/slab-renderer';
|
|
17
|
+
import { SpawnRenderer } from './spawn/spawn-renderer';
|
|
16
18
|
import { StairRenderer } from './stair/stair-renderer';
|
|
17
19
|
import { StairSegmentRenderer } from './stair-segment/stair-segment-renderer';
|
|
18
20
|
import { WallRenderer } from './wall/wall-renderer';
|
|
@@ -22,5 +24,5 @@ export const NodeRenderer = ({ nodeId }) => {
|
|
|
22
24
|
const node = useScene((state) => state.nodes[nodeId]);
|
|
23
25
|
if (!node)
|
|
24
26
|
return null;
|
|
25
|
-
return (_jsxs(_Fragment, { children: [node.type === 'site' && _jsx(SiteRenderer, { node: node }), node.type === 'building' && _jsx(BuildingRenderer, { node: node }), node.type === 'ceiling' && _jsx(CeilingRenderer, { node: node }), node.type === 'level' && _jsx(LevelRenderer, { node: node }), node.type === 'item' && _jsx(ItemRenderer, { node: node }), node.type === 'slab' && _jsx(SlabRenderer, { node: node }), node.type === 'wall' && _jsx(WallRenderer, { node: node }), node.type === 'fence' && _jsx(FenceRenderer, { node: node }), node.type === 'door' && _jsx(DoorRenderer, { node: node }), node.type === 'window' && _jsx(WindowRenderer, { node: node }), node.type === 'zone' && _jsx(ZoneRenderer, { node: node }), node.type === 'roof' && _jsx(RoofRenderer, { node: node }), node.type === 'roof-segment' && _jsx(RoofSegmentRenderer, { node: node }), node.type === 'stair' && _jsx(StairRenderer, { node: node }), node.type === 'stair-segment' && _jsx(StairSegmentRenderer, { node: node }), node.type === 'scan' && _jsx(ScanRenderer, { node: node }), node.type === 'guide' && _jsx(GuideRenderer, { node: node })] }));
|
|
27
|
+
return (_jsxs(_Fragment, { children: [node.type === 'site' && _jsx(SiteRenderer, { node: node }), node.type === 'building' && _jsx(BuildingRenderer, { node: node }), node.type === 'ceiling' && _jsx(CeilingRenderer, { node: node }), node.type === 'column' && _jsx(ColumnRenderer, { node: node }), node.type === 'level' && _jsx(LevelRenderer, { node: node }), node.type === 'item' && _jsx(ItemRenderer, { node: node }), node.type === 'slab' && _jsx(SlabRenderer, { node: node }), node.type === 'spawn' && _jsx(SpawnRenderer, { node: node }), node.type === 'wall' && _jsx(WallRenderer, { node: node }), node.type === 'fence' && _jsx(FenceRenderer, { node: node }), node.type === 'door' && _jsx(DoorRenderer, { node: node }), node.type === 'window' && _jsx(WindowRenderer, { node: node }), node.type === 'zone' && _jsx(ZoneRenderer, { node: node }), node.type === 'roof' && _jsx(RoofRenderer, { node: node }), node.type === 'roof-segment' && _jsx(RoofSegmentRenderer, { node: node }), node.type === 'stair' && _jsx(StairRenderer, { node: node }), node.type === 'stair-segment' && _jsx(StairSegmentRenderer, { node: node }), node.type === 'scan' && _jsx(ScanRenderer, { node: node }), node.type === 'guide' && _jsx(GuideRenderer, { node: node })] }));
|
|
26
28
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roof-renderer.d.ts","sourceRoot":"","sources":["../../../../src/components/renderers/roof/roof-renderer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAe,MAAM,kBAAkB,CAAA;AAS7D,eAAO,MAAM,YAAY,GAAI,UAAU;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,
|
|
1
|
+
{"version":3,"file":"roof-renderer.d.ts","sourceRoot":"","sources":["../../../../src/components/renderers/roof/roof-renderer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAe,MAAM,kBAAkB,CAAA;AAS7D,eAAO,MAAM,YAAY,GAAI,UAAU;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,4CAiDxD,CAAA"}
|
|
@@ -21,19 +21,7 @@ export const RoofRenderer = ({ node }) => {
|
|
|
21
21
|
geometry.addGroup(0, 0, 3);
|
|
22
22
|
return geometry;
|
|
23
23
|
}, []);
|
|
24
|
-
const customMaterial = useMemo(() => getRoofMaterialArray(node), [
|
|
25
|
-
node.materialPreset,
|
|
26
|
-
node.material,
|
|
27
|
-
node.material?.preset,
|
|
28
|
-
node.material?.properties,
|
|
29
|
-
node.material?.texture,
|
|
30
|
-
node.topMaterial,
|
|
31
|
-
node.topMaterialPreset,
|
|
32
|
-
node.edgeMaterial,
|
|
33
|
-
node.edgeMaterialPreset,
|
|
34
|
-
node.wallMaterial,
|
|
35
|
-
node.wallMaterialPreset,
|
|
36
|
-
]);
|
|
24
|
+
const customMaterial = useMemo(() => getRoofMaterialArray(node), [node]);
|
|
37
25
|
const material = debugColors ? roofDebugMaterials : customMaterial || roofMaterials;
|
|
38
26
|
useEffect(() => {
|
|
39
27
|
return () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roof-segment-renderer.d.ts","sourceRoot":"","sources":["../../../../src/components/renderers/roof-segment/roof-segment-renderer.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"roof-segment-renderer.d.ts","sourceRoot":"","sources":["../../../../src/components/renderers/roof-segment/roof-segment-renderer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,eAAe,EAGrB,MAAM,kBAAkB,CAAA;AAQzB,eAAO,MAAM,mBAAmB,GAAI,UAAU;IAAE,IAAI,EAAE,eAAe,CAAA;CAAE,4CAgDtE,CAAA"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useRegistry, useScene } from '@pascal-app/core';
|
|
2
|
+
import { useRegistry, useScene, } from '@pascal-app/core';
|
|
3
3
|
import { useEffect, useMemo, useRef } from 'react';
|
|
4
4
|
import * as THREE from 'three';
|
|
5
5
|
import { useNodeEvents } from '../../../hooks/use-node-events';
|
|
@@ -12,7 +12,9 @@ export const RoofSegmentRenderer = ({ node }) => {
|
|
|
12
12
|
useRegistry(node.id, 'roof-segment', ref);
|
|
13
13
|
const handlers = useNodeEvents(node, 'roof-segment');
|
|
14
14
|
const debugColors = useViewer((s) => s.debugColors);
|
|
15
|
-
const parentNode = node.parentId
|
|
15
|
+
const parentNode = node.parentId
|
|
16
|
+
? nodes[node.parentId]
|
|
17
|
+
: undefined;
|
|
16
18
|
const placeholderGeometry = useMemo(() => {
|
|
17
19
|
const geometry = new THREE.BufferGeometry();
|
|
18
20
|
geometry.setAttribute('position', new THREE.Float32BufferAttribute([], 3));
|
|
@@ -27,24 +29,7 @@ export const RoofSegmentRenderer = ({ node }) => {
|
|
|
27
29
|
return null;
|
|
28
30
|
}
|
|
29
31
|
return parentNode ? getRoofMaterialArray(parentNode) : null;
|
|
30
|
-
}, [
|
|
31
|
-
node.materialPreset,
|
|
32
|
-
node.material,
|
|
33
|
-
node.material?.preset,
|
|
34
|
-
node.material?.properties,
|
|
35
|
-
node.material?.texture,
|
|
36
|
-
parentNode?.materialPreset,
|
|
37
|
-
parentNode?.material,
|
|
38
|
-
parentNode?.material?.preset,
|
|
39
|
-
parentNode?.material?.properties,
|
|
40
|
-
parentNode?.material?.texture,
|
|
41
|
-
parentNode?.topMaterial,
|
|
42
|
-
parentNode?.topMaterialPreset,
|
|
43
|
-
parentNode?.edgeMaterial,
|
|
44
|
-
parentNode?.edgeMaterialPreset,
|
|
45
|
-
parentNode?.wallMaterial,
|
|
46
|
-
parentNode?.wallMaterialPreset,
|
|
47
|
-
]);
|
|
32
|
+
}, [node, parentNode]);
|
|
48
33
|
const material = debugColors ? roofDebugMaterials : customMaterial || roofMaterials;
|
|
49
34
|
useEffect(() => {
|
|
50
35
|
return () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slab-renderer.d.ts","sourceRoot":"","sources":["../../../../src/components/renderers/slab/slab-renderer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA0B,KAAK,QAAQ,EAAe,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"slab-renderer.d.ts","sourceRoot":"","sources":["../../../../src/components/renderers/slab/slab-renderer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA0B,KAAK,QAAQ,EAAe,MAAM,kBAAkB,CAAA;AA+CrF,eAAO,MAAM,YAAY,GAAI,UAAU;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,4CAuCxD,CAAA"}
|
|
@@ -1,35 +1,52 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { getMaterialPresetByRef, useRegistry } from '@pascal-app/core';
|
|
3
|
-
import {
|
|
3
|
+
import { useMemo, useRef } from 'react';
|
|
4
4
|
import * as THREE from 'three';
|
|
5
5
|
import { useNodeEvents } from '../../../hooks/use-node-events';
|
|
6
6
|
import { applyMaterialPresetToMaterials, createMaterial, DEFAULT_SLAB_MATERIAL, } from '../../../lib/materials';
|
|
7
|
+
const slabMaterialCache = new Map();
|
|
8
|
+
function getSlabMaterial(cacheKey, params) {
|
|
9
|
+
const cached = slabMaterialCache.get(cacheKey);
|
|
10
|
+
if (cached)
|
|
11
|
+
return cached;
|
|
12
|
+
const preset = getMaterialPresetByRef(params.materialPreset);
|
|
13
|
+
const slabMaterial = preset
|
|
14
|
+
? new THREE.MeshStandardMaterial()
|
|
15
|
+
: params.material
|
|
16
|
+
? createMaterial(params.material).clone()
|
|
17
|
+
: DEFAULT_SLAB_MATERIAL.clone();
|
|
18
|
+
if (preset) {
|
|
19
|
+
// Apply the preset to the slab-owned material so async texture loads update
|
|
20
|
+
// the instance we actually render after refresh as well.
|
|
21
|
+
applyMaterialPresetToMaterials(slabMaterial, preset);
|
|
22
|
+
}
|
|
23
|
+
// Slabs participate in the WebGPU MRT scene pass. Keeping them opaque avoids
|
|
24
|
+
// pipeline variants that can fail when geometry is regenerated while a
|
|
25
|
+
// transparent/custom material is attached.
|
|
26
|
+
slabMaterial.transparent = false;
|
|
27
|
+
slabMaterial.opacity = 1;
|
|
28
|
+
slabMaterial.alphaMap = null;
|
|
29
|
+
slabMaterial.side = THREE.DoubleSide;
|
|
30
|
+
slabMaterial.depthWrite = true;
|
|
31
|
+
slabMaterial.needsUpdate = true;
|
|
32
|
+
slabMaterialCache.set(cacheKey, slabMaterial);
|
|
33
|
+
return slabMaterial;
|
|
34
|
+
}
|
|
7
35
|
export const SlabRenderer = ({ node }) => {
|
|
8
36
|
const ref = useRef(null);
|
|
9
37
|
useRegistry(node.id, 'slab', ref);
|
|
10
38
|
const handlers = useNodeEvents(node, 'slab');
|
|
11
39
|
const material = useMemo(() => {
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
:
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
23
|
-
// Slabs participate in the WebGPU MRT scene pass. Keeping them opaque avoids
|
|
24
|
-
// pipeline variants that can fail when geometry is regenerated while a
|
|
25
|
-
// transparent/custom material is attached.
|
|
26
|
-
slabMaterial.transparent = false;
|
|
27
|
-
slabMaterial.opacity = 1;
|
|
28
|
-
slabMaterial.alphaMap = null;
|
|
29
|
-
slabMaterial.side = THREE.DoubleSide;
|
|
30
|
-
slabMaterial.depthWrite = true;
|
|
31
|
-
slabMaterial.needsUpdate = true;
|
|
32
|
-
return slabMaterial;
|
|
40
|
+
const resolvedMaterial = node.material;
|
|
41
|
+
const resolvedMaterialPreset = node.materialPreset;
|
|
42
|
+
const cacheKey = JSON.stringify({
|
|
43
|
+
material: resolvedMaterial ?? null,
|
|
44
|
+
materialPreset: resolvedMaterialPreset ?? null,
|
|
45
|
+
});
|
|
46
|
+
return getSlabMaterial(cacheKey, {
|
|
47
|
+
material: resolvedMaterial,
|
|
48
|
+
materialPreset: resolvedMaterialPreset,
|
|
49
|
+
});
|
|
33
50
|
}, [
|
|
34
51
|
node.material,
|
|
35
52
|
node.material?.preset,
|
|
@@ -37,10 +54,5 @@ export const SlabRenderer = ({ node }) => {
|
|
|
37
54
|
node.material?.texture,
|
|
38
55
|
node.materialPreset,
|
|
39
56
|
]);
|
|
40
|
-
useEffect(() => {
|
|
41
|
-
return () => {
|
|
42
|
-
material.dispose();
|
|
43
|
-
};
|
|
44
|
-
}, [material]);
|
|
45
57
|
return (_jsx("mesh", { castShadow: true, receiveShadow: true, ref: ref, ...handlers, material: material, visible: node.visible, children: _jsx("boxGeometry", { args: [0, 0, 0] }) }));
|
|
46
58
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spawn-renderer.d.ts","sourceRoot":"","sources":["../../../../src/components/renderers/spawn/spawn-renderer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAkC,MAAM,kBAAkB,CAAA;AASjF,eAAO,MAAM,aAAa,GAAI,UAAU;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,4CA0D1D,CAAA"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useLiveTransforms, useRegistry } from '@pascal-app/core';
|
|
3
|
+
import { useMemo, useRef } from 'react';
|
|
4
|
+
import { Color, Shape } from 'three';
|
|
5
|
+
import { useNodeEvents } from '../../../hooks/use-node-events';
|
|
6
|
+
import useViewer from '../../../store/use-viewer';
|
|
7
|
+
const SPAWN_COLOR = new Color('#22c55e');
|
|
8
|
+
export const SpawnRenderer = ({ node }) => {
|
|
9
|
+
const ref = useRef(null);
|
|
10
|
+
const handlers = useNodeEvents(node, 'spawn');
|
|
11
|
+
const liveTransform = useLiveTransforms((state) => state.get(node.id));
|
|
12
|
+
const walkthroughMode = useViewer((state) => state.walkthroughMode);
|
|
13
|
+
useRegistry(node.id, 'spawn', ref);
|
|
14
|
+
const materialProps = useMemo(() => ({
|
|
15
|
+
color: SPAWN_COLOR,
|
|
16
|
+
emissive: SPAWN_COLOR,
|
|
17
|
+
emissiveIntensity: 0.08,
|
|
18
|
+
metalness: 0.03,
|
|
19
|
+
roughness: 0.42,
|
|
20
|
+
}), []);
|
|
21
|
+
const arrowShape = useMemo(() => {
|
|
22
|
+
const shape = new Shape();
|
|
23
|
+
// Positive local Y becomes negative world Z after the -90deg X rotation below,
|
|
24
|
+
// so this tip points "forward" for the player/spawn direction.
|
|
25
|
+
shape.moveTo(0, 0.24);
|
|
26
|
+
shape.lineTo(-0.18, -0.14);
|
|
27
|
+
shape.lineTo(0.18, -0.14);
|
|
28
|
+
shape.closePath();
|
|
29
|
+
return shape;
|
|
30
|
+
}, []);
|
|
31
|
+
return (_jsxs("group", { position: liveTransform?.position ?? node.position, ref: ref, rotation: [0, liveTransform?.rotation ?? node.rotation, 0], visible: !walkthroughMode, children: [_jsxs("mesh", { position: [0, 0.09, 0], rotation: [-Math.PI / 2, 0, 0], ...handlers, children: [_jsx("ringGeometry", { args: [0.34, 0.48, 48] }), _jsx("meshStandardMaterial", { ...materialProps })] }), _jsxs("mesh", { position: [0, 0.1, -0.52], rotation: [-Math.PI / 2, 0, 0], ...handlers, children: [_jsx("shapeGeometry", { args: [arrowShape] }), _jsx("meshStandardMaterial", { ...materialProps })] }), _jsxs("mesh", { position: [0, 0.41, 0], ...handlers, children: [_jsx("boxGeometry", { args: [0.3, 0.54, 0.16] }), _jsx("meshStandardMaterial", { ...materialProps })] }), _jsxs("mesh", { position: [0, 0.83, 0], ...handlers, children: [_jsx("boxGeometry", { args: [0.18, 0.18, 0.18] }), _jsx("meshStandardMaterial", { ...materialProps })] })] }));
|
|
32
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stair-renderer.d.ts","sourceRoot":"","sources":["../../../../src/components/renderers/stair/stair-renderer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,SAAS,EAIf,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"stair-renderer.d.ts","sourceRoot":"","sources":["../../../../src/components/renderers/stair/stair-renderer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,SAAS,EAIf,MAAM,kBAAkB,CAAA;AA8CzB,eAAO,MAAM,aAAa,GAAI,UAAU;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,4CA2E1D,CAAA"}
|
|
@@ -3,8 +3,8 @@ import { useRegistry, useScene, } from '@pascal-app/core';
|
|
|
3
3
|
import { useEffect, useLayoutEffect, useMemo, useRef } from 'react';
|
|
4
4
|
import * as THREE from 'three';
|
|
5
5
|
import { useNodeEvents } from '../../../hooks/use-node-events';
|
|
6
|
-
import { createMaterial, createMaterialFromPresetRef, DEFAULT_STAIR_MATERIAL } from '../../../lib/materials';
|
|
7
|
-
import {
|
|
6
|
+
import { createMaterial, createMaterialFromPresetRef, DEFAULT_STAIR_MATERIAL, } from '../../../lib/materials';
|
|
7
|
+
import { getStairBodyMaterials, getStairRailingMaterial, } from '../../../systems/stair/stair-materials';
|
|
8
8
|
import { NodeRenderer } from '../node-renderer';
|
|
9
9
|
export const StairRenderer = ({ node }) => {
|
|
10
10
|
const ref = useRef(null);
|
|
@@ -29,26 +29,8 @@ export const StairRenderer = ({ node }) => {
|
|
|
29
29
|
node.material?.properties,
|
|
30
30
|
node.material?.texture,
|
|
31
31
|
]);
|
|
32
|
-
const straightBodyMaterials = useMemo(() => getStairBodyMaterials(node), [
|
|
33
|
-
|
|
34
|
-
node.materialPreset,
|
|
35
|
-
node.railingMaterial,
|
|
36
|
-
node.railingMaterialPreset,
|
|
37
|
-
node.sideMaterial,
|
|
38
|
-
node.sideMaterialPreset,
|
|
39
|
-
node.treadMaterial,
|
|
40
|
-
node.treadMaterialPreset,
|
|
41
|
-
]);
|
|
42
|
-
const railingMaterial = useMemo(() => getStairRailingMaterial(node), [
|
|
43
|
-
node.material,
|
|
44
|
-
node.materialPreset,
|
|
45
|
-
node.railingMaterial,
|
|
46
|
-
node.railingMaterialPreset,
|
|
47
|
-
node.sideMaterial,
|
|
48
|
-
node.sideMaterialPreset,
|
|
49
|
-
node.treadMaterial,
|
|
50
|
-
node.treadMaterialPreset,
|
|
51
|
-
]);
|
|
32
|
+
const straightBodyMaterials = useMemo(() => getStairBodyMaterials(node), [node]);
|
|
33
|
+
const railingMaterial = useMemo(() => getStairRailingMaterial(node), [node]);
|
|
52
34
|
const straightPlaceholderGeometry = useMemo(() => {
|
|
53
35
|
const geometry = new THREE.BufferGeometry();
|
|
54
36
|
geometry.setAttribute('position', new THREE.Float32BufferAttribute([], 3));
|
|
@@ -61,7 +43,7 @@ export const StairRenderer = ({ node }) => {
|
|
|
61
43
|
straightPlaceholderGeometry.dispose();
|
|
62
44
|
};
|
|
63
45
|
}, [straightPlaceholderGeometry]);
|
|
64
|
-
return (_jsxs("group", { "position-x": node.position[0], "position-z": node.position[2], ref: ref, "rotation-y": node.rotation, visible: node.visible, ...handlers, children: [isSegmentBasedStair ? (_jsx("mesh", { castShadow: true, geometry: straightPlaceholderGeometry, material: straightBodyMaterials, name: "merged-stair", receiveShadow: true })) : null, !isSegmentBasedStair ? _jsx(CurvedStairBody, { bodyMaterials: straightBodyMaterials, stair: node }) : null, _jsx(StairRailings, { material: railingMaterial, stair: node }), isSegmentBasedStair ? (_jsx("group", { name: "segments-wrapper", visible: false, children: (node.children ?? []).map((childId) => (_jsx(NodeRenderer, { nodeId: childId }, childId))) })) : null] }));
|
|
46
|
+
return (_jsxs("group", { "position-x": node.position[0], "position-z": node.position[2], ref: ref, "rotation-y": node.rotation, visible: node.visible, ...handlers, children: [isSegmentBasedStair ? (_jsx("mesh", { castShadow: true, geometry: straightPlaceholderGeometry, material: straightBodyMaterials, name: "merged-stair", receiveShadow: true })) : null, !isSegmentBasedStair ? (_jsx(CurvedStairBody, { bodyMaterials: straightBodyMaterials, stair: node })) : null, _jsx(StairRailings, { material: railingMaterial, stair: node }), isSegmentBasedStair ? (_jsx("group", { name: "segments-wrapper", visible: false, children: (node.children ?? []).map((childId) => (_jsx(NodeRenderer, { nodeId: childId }, childId))) })) : null] }));
|
|
65
47
|
};
|
|
66
48
|
function StairRailings({ stair, material }) {
|
|
67
49
|
const nodes = useScene((state) => state.nodes);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stair-segment-renderer.d.ts","sourceRoot":"","sources":["../../../../src/components/renderers/stair-segment/stair-segment-renderer.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"stair-segment-renderer.d.ts","sourceRoot":"","sources":["../../../../src/components/renderers/stair-segment/stair-segment-renderer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,gBAAgB,EAGtB,MAAM,kBAAkB,CAAA;AAMzB,eAAO,MAAM,oBAAoB,GAAI,UAAU;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,4CA4CxE,CAAA"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useRegistry, useScene } from '@pascal-app/core';
|
|
2
|
+
import { useRegistry, useScene, } from '@pascal-app/core';
|
|
3
3
|
import { useEffect, useLayoutEffect, useMemo, useRef } from 'react';
|
|
4
4
|
import * as THREE from 'three';
|
|
5
5
|
import { useNodeEvents } from '../../../hooks/use-node-events';
|
|
@@ -12,27 +12,10 @@ export const StairSegmentRenderer = ({ node }) => {
|
|
|
12
12
|
useScene.getState().markDirty(node.id);
|
|
13
13
|
}, [node.id]);
|
|
14
14
|
const handlers = useNodeEvents(node, 'stair-segment');
|
|
15
|
-
const parentNode = node.parentId
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
node.materialPreset,
|
|
20
|
-
node.material,
|
|
21
|
-
node.material?.preset,
|
|
22
|
-
node.material?.properties,
|
|
23
|
-
node.material?.texture,
|
|
24
|
-
parentNode?.materialPreset,
|
|
25
|
-
parentNode?.material,
|
|
26
|
-
parentNode?.material?.preset,
|
|
27
|
-
parentNode?.material?.properties,
|
|
28
|
-
parentNode?.material?.texture,
|
|
29
|
-
parentNode?.railingMaterialPreset,
|
|
30
|
-
parentNode?.railingMaterial,
|
|
31
|
-
parentNode?.sideMaterialPreset,
|
|
32
|
-
parentNode?.sideMaterial,
|
|
33
|
-
parentNode?.treadMaterialPreset,
|
|
34
|
-
parentNode?.treadMaterial,
|
|
35
|
-
]);
|
|
15
|
+
const parentNode = node.parentId
|
|
16
|
+
? nodes[node.parentId]
|
|
17
|
+
: undefined;
|
|
18
|
+
const material = useMemo(() => getStraightStairSegmentBodyMaterials(node, parentNode), [node, parentNode]);
|
|
36
19
|
const placeholderGeometry = useMemo(() => {
|
|
37
20
|
const geometry = new THREE.BufferGeometry();
|
|
38
21
|
geometry.setAttribute('position', new THREE.Float32BufferAttribute([], 3));
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { type ThreeToJSXElements } from '@react-three/fiber';
|
|
2
2
|
import * as THREE from 'three/webgpu';
|
|
3
|
+
import { type HoverStyles } from './post-processing';
|
|
3
4
|
declare module '@react-three/fiber' {
|
|
4
5
|
interface ThreeElements extends ThreeToJSXElements<typeof THREE> {
|
|
5
6
|
}
|
|
6
7
|
}
|
|
7
8
|
interface ViewerProps {
|
|
8
9
|
children?: React.ReactNode;
|
|
10
|
+
hoverStyles?: HoverStyles;
|
|
9
11
|
selectionManager?: 'default' | 'custom';
|
|
10
12
|
perf?: boolean;
|
|
11
13
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/index.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAkB,KAAK,kBAAkB,EAAsB,MAAM,oBAAoB,CAAA;AAEhG,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AAwBrC,OAAuB,EAAwB,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAA;AA+B1F,OAAO,QAAQ,oBAAoB,CAAC;IAClC,UAAU,aAAc,SAAQ,kBAAkB,CAAC,OAAO,KAAK,CAAC;KAAG;CACpE;AAkFD,UAAU,WAAW;IACnB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC1B,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,gBAAgB,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAA;IACvC,IAAI,CAAC,EAAE,OAAO,CAAA;CACf;AAED,QAAA,MAAM,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CAmGjC,CAAA;AASD,eAAe,MAAM,CAAA"}
|
|
@@ -1,22 +1,33 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { CeilingSystem, DoorSystem, FenceSystem, ItemSystem, RoofSystem, SlabSystem, StairSystem, WallSystem, WindowSystem, } from '@pascal-app/core';
|
|
4
3
|
import { Bvh } from '@react-three/drei';
|
|
5
4
|
import { Canvas, extend, useFrame, useThree } from '@react-three/fiber';
|
|
6
5
|
import { useEffect, useMemo, useRef } from 'react';
|
|
7
6
|
import * as THREE from 'three/webgpu';
|
|
8
7
|
import useViewer from '../../store/use-viewer';
|
|
8
|
+
import { CeilingSystem } from '../../systems/ceiling/ceiling-system';
|
|
9
|
+
import { DoorAnimationSystem } from '../../systems/door/door-animation-system';
|
|
10
|
+
import { DoorSystem } from '../../systems/door/door-system';
|
|
11
|
+
import { FenceSystem } from '../../systems/fence/fence-system';
|
|
9
12
|
import { GuideSystem } from '../../systems/guide/guide-system';
|
|
13
|
+
import { ItemSystem } from '../../systems/item/item-system';
|
|
10
14
|
import { ItemLightSystem } from '../../systems/item-light/item-light-system';
|
|
11
15
|
import { LevelSystem } from '../../systems/level/level-system';
|
|
16
|
+
import { RoofSystem } from '../../systems/roof/roof-system';
|
|
12
17
|
import { ScanSystem } from '../../systems/scan/scan-system';
|
|
18
|
+
import { SlabSystem } from '../../systems/slab/slab-system';
|
|
19
|
+
import { StairSystem } from '../../systems/stair/stair-system';
|
|
13
20
|
import { WallCutout } from '../../systems/wall/wall-cutout';
|
|
21
|
+
import { WallSystem } from '../../systems/wall/wall-system';
|
|
22
|
+
import { WindowAnimationSystem } from '../../systems/window/window-animation-system';
|
|
23
|
+
import { WindowSystem } from '../../systems/window/window-system';
|
|
14
24
|
import { ZoneSystem } from '../../systems/zone/zone-system';
|
|
25
|
+
import { ErrorBoundary } from '../error-boundary';
|
|
15
26
|
import { SceneRenderer } from '../renderers/scene-renderer';
|
|
16
27
|
import FrameLimiter from './frame-limiter';
|
|
17
28
|
import { Lights } from './lights';
|
|
18
29
|
import { PerfMonitor } from './perf-monitor';
|
|
19
|
-
import PostProcessing from './post-processing';
|
|
30
|
+
import PostProcessing, { DEFAULT_HOVER_STYLES } from './post-processing';
|
|
20
31
|
import { SelectionManager } from './selection-manager';
|
|
21
32
|
import { ViewerCamera } from './viewer-camera';
|
|
22
33
|
function AnimatedBackground({ isDark }) {
|
|
@@ -41,40 +52,99 @@ function AnimatedBackground({ isDark }) {
|
|
|
41
52
|
return null;
|
|
42
53
|
}
|
|
43
54
|
extend(THREE);
|
|
55
|
+
// R3F's <Canvas> useLayoutEffect has no deps, so any re-render (theme switch,
|
|
56
|
+
// parent re-render, StrictMode double-mount) re-invokes `configure()`. With a
|
|
57
|
+
// sync `gl` factory that's harmless — the renderer is created once and reused.
|
|
58
|
+
// With an async factory (WebGPURenderer needs `await init()`), two configure
|
|
59
|
+
// calls can race: both see `state.gl == null` and both create a renderer. The
|
|
60
|
+
// first to resolve gets `setSize`/`setDpr` called on it; the second overwrites
|
|
61
|
+
// `state.gl` but R3F's store already holds the new size/dpr, so the new
|
|
62
|
+
// renderer is never resized and stays at the canvas's 300×150 default.
|
|
63
|
+
//
|
|
64
|
+
// Caching by canvas guarantees both branches return the same instance, so
|
|
65
|
+
// "duplicate" configure calls become no-ops on an already-sized renderer.
|
|
66
|
+
// We cache the in-flight Promise (not just the resolved renderer) so two
|
|
67
|
+
// concurrent configure() calls await the same init instead of creating two
|
|
68
|
+
// renderers in parallel and only caching the second.
|
|
69
|
+
const WEBGPU_RENDERER_CACHE = new WeakMap();
|
|
44
70
|
function GPUDeviceWatcher() {
|
|
45
71
|
const gl = useThree((s) => s.gl);
|
|
46
72
|
useEffect(() => {
|
|
47
73
|
const backend = gl.backend;
|
|
48
74
|
const device = backend?.device;
|
|
49
|
-
if (!device)
|
|
75
|
+
if (!device) {
|
|
76
|
+
console.warn('[viewer] No WebGPU device on backend — running on a fallback renderer.', {
|
|
77
|
+
backend: backend?.constructor?.name ?? 'unknown',
|
|
78
|
+
rendererType: gl.constructor?.name ?? 'unknown',
|
|
79
|
+
});
|
|
50
80
|
return;
|
|
81
|
+
}
|
|
82
|
+
console.log('[viewer] WebGPU device ready', {
|
|
83
|
+
label: device.label,
|
|
84
|
+
features: device.features ? Array.from(device.features) : [],
|
|
85
|
+
});
|
|
51
86
|
device.lost.then((info) => {
|
|
52
87
|
console.error(`[viewer] WebGPU device lost: reason="${info.reason ?? 'unknown'}", message="${info.message ?? ''}". ` +
|
|
53
88
|
'The page must be reloaded to recover the GPU context.');
|
|
54
89
|
});
|
|
90
|
+
// Uncaptured errors are normally silent (only console-warned by Chrome at
|
|
91
|
+
// best). Pipe them to console.error so silent mobile crashes show up.
|
|
92
|
+
const onUncapturedError = (event) => {
|
|
93
|
+
console.error('[viewer] WebGPU uncaptured error:', event?.error?.message, event?.error);
|
|
94
|
+
};
|
|
95
|
+
device.addEventListener?.('uncapturederror', onUncapturedError);
|
|
96
|
+
return () => {
|
|
97
|
+
device.removeEventListener?.('uncapturederror', onUncapturedError);
|
|
98
|
+
};
|
|
55
99
|
}, [gl]);
|
|
56
100
|
return null;
|
|
57
101
|
}
|
|
58
|
-
const Viewer = ({ children, selectionManager = 'default', perf = false, }) => {
|
|
102
|
+
const Viewer = ({ children, hoverStyles = DEFAULT_HOVER_STYLES, selectionManager = 'default', perf = false, }) => {
|
|
59
103
|
const theme = useViewer((state) => state.theme);
|
|
60
|
-
return (_jsxs(Canvas, { camera: { position: [50, 50, 50], fov: 50 }, className: `transition-colors duration-700 ${theme === 'dark' ? 'bg-[#1f2433]' : 'bg-[#fafafa]'}`, dpr: [1, 1.5], frameloop: "never", gl:
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
//
|
|
66
|
-
//
|
|
67
|
-
//
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
104
|
+
return (_jsxs(Canvas, { camera: { position: [50, 50, 50], fov: 50 }, className: `transition-colors duration-700 ${theme === 'dark' ? 'bg-[#1f2433]' : 'bg-[#fafafa]'}`, dpr: [1, 1.5], frameloop: "never", gl: ((props) => {
|
|
105
|
+
const canvas = props.canvas;
|
|
106
|
+
const cached = canvas ? WEBGPU_RENDERER_CACHE.get(canvas) : undefined;
|
|
107
|
+
if (cached)
|
|
108
|
+
return cached;
|
|
109
|
+
// Surface the env we're about to ask WebGPU for — catches "no
|
|
110
|
+
// navigator.gpu" / "adapter request failed" silently failing in
|
|
111
|
+
// mobile WebViews where WebGPU is gated behind flags.
|
|
112
|
+
const hasGpu = typeof navigator !== 'undefined' && 'gpu' in navigator;
|
|
113
|
+
console.log('[viewer] Creating WebGPURenderer', {
|
|
114
|
+
hasNavigatorGPU: hasGpu,
|
|
115
|
+
ua: typeof navigator !== 'undefined' ? navigator.userAgent : 'n/a',
|
|
116
|
+
});
|
|
117
|
+
const promise = (async () => {
|
|
118
|
+
try {
|
|
119
|
+
const renderer = new THREE.WebGPURenderer(props);
|
|
120
|
+
renderer.toneMapping = THREE.ACESFilmicToneMapping;
|
|
121
|
+
renderer.toneMappingExposure = 0.9;
|
|
122
|
+
await renderer.init();
|
|
123
|
+
console.log('[viewer] WebGPURenderer ready', {
|
|
124
|
+
backend: renderer.backend?.constructor?.name,
|
|
125
|
+
isWebGPU: renderer.isWebGPURenderer === true,
|
|
126
|
+
});
|
|
127
|
+
return renderer;
|
|
128
|
+
}
|
|
129
|
+
catch (err) {
|
|
130
|
+
// Drop the failed promise from the cache so a future Canvas
|
|
131
|
+
// mount on the same DOM can retry instead of inheriting the
|
|
132
|
+
// rejection forever.
|
|
133
|
+
if (canvas)
|
|
134
|
+
WEBGPU_RENDERER_CACHE.delete(canvas);
|
|
135
|
+
console.error('[viewer] WebGPURenderer init failed', err);
|
|
136
|
+
throw err;
|
|
137
|
+
}
|
|
138
|
+
})();
|
|
139
|
+
if (canvas)
|
|
140
|
+
WEBGPU_RENDERER_CACHE.set(canvas, promise);
|
|
141
|
+
return promise;
|
|
142
|
+
}), resize: {
|
|
73
143
|
debounce: 100,
|
|
74
144
|
}, shadows: {
|
|
75
145
|
type: THREE.PCFShadowMap,
|
|
76
146
|
enabled: true,
|
|
77
|
-
}, children: [_jsx(FrameLimiter, { fps: 50 }), _jsx(ViewerCamera, {}), _jsx(Lights, {}), _jsx(Bvh, { children: _jsx(SceneRenderer, {}) }), _jsx(LevelSystem, {}), _jsx(GuideSystem, {}), _jsx(ScanSystem, {}), _jsx(WallCutout, {}), _jsx(CeilingSystem, {}), _jsx(DoorSystem, {}), _jsx(FenceSystem, {}), _jsx(ItemSystem, {}), _jsx(RoofSystem, {}), _jsx(SlabSystem, {}), _jsx(StairSystem, {}), _jsx(WallSystem, {}), _jsx(WindowSystem, {}), _jsx(ZoneSystem, {}), _jsx(PostProcessing, {
|
|
147
|
+
}, children: [_jsx(FrameLimiter, { fps: 50 }), _jsx(ViewerCamera, {}), _jsx(GPUDeviceWatcher, {}), _jsxs(ErrorBoundary, { fallback: null, scope: "viewer-scene", children: [_jsx(Lights, {}), _jsx(Bvh, { children: _jsx(SceneRenderer, {}) }), _jsx(LevelSystem, {}), _jsx(GuideSystem, {}), _jsx(ScanSystem, {}), _jsx(WallCutout, {}), _jsx(CeilingSystem, {}), _jsx(DoorAnimationSystem, {}), _jsx(WindowAnimationSystem, {}), _jsx(DoorSystem, {}), _jsx(FenceSystem, {}), _jsx(ItemSystem, {}), _jsx(RoofSystem, {}), _jsx(SlabSystem, {}), _jsx(StairSystem, {}), _jsx(WallSystem, {}), _jsx(WindowSystem, {}), _jsx(ZoneSystem, {}), _jsx(PostProcessing, { hoverStyles: hoverStyles }), _jsx(ItemLightSystem, {}), selectionManager === 'default' && _jsx(SelectionManager, {}), perf && _jsx(PerfMonitor, {}), children] })] }));
|
|
78
148
|
};
|
|
79
149
|
const DebugRenderer = () => {
|
|
80
150
|
useFrame(({ gl, scene, camera }) => {
|
|
@@ -12,6 +12,18 @@ export declare const SSGI_PARAMS: {
|
|
|
12
12
|
useScreenSpaceSampling: boolean;
|
|
13
13
|
useTemporalFiltering: boolean;
|
|
14
14
|
};
|
|
15
|
-
|
|
15
|
+
export type HoverStyle = {
|
|
16
|
+
visibleColor: number;
|
|
17
|
+
hiddenColor: number;
|
|
18
|
+
strength: number;
|
|
19
|
+
pulse: boolean;
|
|
20
|
+
};
|
|
21
|
+
export type HoverStyles = {
|
|
22
|
+
default: HoverStyle;
|
|
23
|
+
} & Record<string, HoverStyle>;
|
|
24
|
+
export declare const DEFAULT_HOVER_STYLES: HoverStyles;
|
|
25
|
+
declare const PostProcessingPasses: ({ hoverStyles, }: {
|
|
26
|
+
hoverStyles?: HoverStyles;
|
|
27
|
+
}) => null;
|
|
16
28
|
export default PostProcessingPasses;
|
|
17
29
|
//# sourceMappingURL=post-processing.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"post-processing.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/post-processing.tsx"],"names":[],"mappings":"AA4BA,eAAO,MAAM,WAAW;;;;;;;;;;;;;CAavB,CAAA;
|
|
1
|
+
{"version":3,"file":"post-processing.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/post-processing.tsx"],"names":[],"mappings":"AA4BA,eAAO,MAAM,WAAW;;;;;;;;;;;;;CAavB,CAAA;AAQD,MAAM,MAAM,UAAU,GAAG;IACvB,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,OAAO,CAAA;CACf,CAAA;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,EAAE,UAAU,CAAA;CACpB,GAAG,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;AAS9B,eAAO,MAAM,oBAAoB,EAAE,WAElC,CAAA;AAiBD,QAAA,MAAM,oBAAoB,GAAI,kBAE3B;IACD,WAAW,CAAC,EAAE,WAAW,CAAA;CAC1B,SAkVA,CAAA;AAED,eAAe,oBAAoB,CAAA"}
|