@pascal-app/viewer 1.0.3 → 1.0.5
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/capture/capture-runtime.js +1 -1
- package/dist/components/error-boundary.d.ts.map +1 -1
- package/dist/components/renderers/node-renderer.d.ts +1 -1
- package/dist/components/renderers/node-renderer.d.ts.map +1 -1
- package/dist/components/renderers/node-renderer.js +12 -4
- package/dist/components/renderers/parametric-node-renderer.d.ts.map +1 -1
- package/dist/components/viewer/bvh-ecctrl.d.ts.map +1 -1
- package/dist/components/viewer/frame-limiter.d.ts +1 -0
- package/dist/components/viewer/frame-limiter.d.ts.map +1 -1
- package/dist/components/viewer/frame-limiter.js +22 -3
- package/dist/components/viewer/glb-interactive.d.ts +25 -1
- package/dist/components/viewer/glb-interactive.d.ts.map +1 -1
- package/dist/components/viewer/glb-interactive.js +253 -86
- package/dist/components/viewer/glb-mechanisms.d.ts +10 -0
- package/dist/components/viewer/glb-mechanisms.d.ts.map +1 -0
- package/dist/components/viewer/glb-mechanisms.js +19 -0
- package/dist/components/viewer/glb-reference-nodes.js +1 -1
- package/dist/components/viewer/glb-replace-instances.js +1 -1
- package/dist/components/viewer/glb-scene.d.ts +45 -27
- package/dist/components/viewer/glb-scene.d.ts.map +1 -1
- package/dist/components/viewer/glb-scene.js +421 -508
- package/dist/components/viewer/glb-walkthrough-controller.d.ts +1 -1
- package/dist/components/viewer/glb-walkthrough-controller.d.ts.map +1 -1
- package/dist/components/viewer/glb-walkthrough-controller.js +13 -2
- package/dist/components/viewer/index.d.ts +24 -1
- package/dist/components/viewer/index.d.ts.map +1 -1
- package/dist/components/viewer/index.js +111 -37
- package/dist/components/viewer/lights.d.ts.map +1 -1
- package/dist/components/viewer/lights.js +113 -22
- package/dist/components/viewer/perf-monitor.d.ts.map +1 -1
- package/dist/components/viewer/perf-monitor.js +6 -0
- package/dist/components/viewer/perf-panel.d.ts.map +1 -1
- package/dist/components/viewer/perf-panel.js +1 -1
- package/dist/components/viewer/post-processing.d.ts.map +1 -1
- package/dist/components/viewer/post-processing.js +104 -36
- package/dist/components/viewer/registered-systems.d.ts.map +1 -1
- package/dist/components/viewer/registered-systems.js +17 -3
- package/dist/components/viewer/render-error.d.ts +18 -0
- package/dist/components/viewer/render-error.d.ts.map +1 -0
- package/dist/components/viewer/render-error.js +29 -0
- package/dist/components/viewer/scene-bvh.d.ts.map +1 -1
- package/dist/components/viewer/scene-bvh.js +1 -1
- package/dist/components/viewer/scene-environment.d.ts.map +1 -1
- package/dist/components/viewer/scene-environment.js +31 -11
- package/dist/components/viewer/scene-ground-replacement.d.ts +6 -0
- package/dist/components/viewer/scene-ground-replacement.d.ts.map +1 -1
- package/dist/components/viewer/scene-ground-replacement.js +15 -0
- package/dist/components/viewer/selection-manager.d.ts.map +1 -1
- package/dist/components/viewer/selection-manager.js +25 -7
- package/dist/components/viewer/underground-ambiance.d.ts +9 -0
- package/dist/components/viewer/underground-ambiance.d.ts.map +1 -0
- package/dist/components/viewer/underground-ambiance.js +105 -0
- package/dist/components/viewer/viewer-camera.d.ts +4 -0
- package/dist/components/viewer/viewer-camera.d.ts.map +1 -1
- package/dist/components/viewer/viewer-camera.js +12 -2
- package/dist/components/viewer/viewer-presentations.d.ts.map +1 -1
- package/dist/hooks/use-gltf-ktx2.d.ts.map +1 -1
- package/dist/hooks/use-gltf-ktx2.js +2 -0
- package/dist/hooks/use-node-events.d.ts.map +1 -1
- package/dist/index.d.ts +36 -16
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +34 -19
- package/dist/lib/asset-url.d.ts.map +1 -1
- package/dist/lib/asset-url.js +7 -1
- package/dist/lib/backdrop.d.ts +17 -0
- package/dist/lib/backdrop.d.ts.map +1 -1
- package/dist/lib/backdrop.js +18 -1
- package/dist/lib/construction-dust.d.ts +57 -0
- package/dist/lib/construction-dust.d.ts.map +1 -0
- package/dist/lib/construction-dust.js +187 -0
- package/dist/lib/csg-utils.js +1 -1
- package/dist/lib/display-state.d.ts +25 -0
- package/dist/lib/display-state.d.ts.map +1 -0
- package/dist/lib/display-state.js +1 -0
- package/dist/lib/foundation-materials.d.ts +26 -0
- package/dist/lib/foundation-materials.d.ts.map +1 -0
- package/dist/lib/foundation-materials.js +65 -0
- package/dist/lib/gltf-unlit.d.ts +10 -0
- package/dist/lib/gltf-unlit.d.ts.map +1 -0
- package/dist/lib/gltf-unlit.js +23 -0
- package/dist/lib/ground-window.d.ts +33 -0
- package/dist/lib/ground-window.d.ts.map +1 -0
- package/dist/lib/ground-window.js +114 -0
- package/dist/lib/hero-pose.d.ts +13 -3
- package/dist/lib/hero-pose.d.ts.map +1 -1
- package/dist/lib/hero-pose.js +72 -5
- package/dist/lib/ink-edges.d.ts +6 -3
- package/dist/lib/ink-edges.d.ts.map +1 -1
- package/dist/lib/ink-edges.js +17 -7
- package/dist/lib/key-light-override.d.ts +11 -0
- package/dist/lib/key-light-override.d.ts.map +1 -0
- package/dist/lib/key-light-override.js +14 -0
- package/dist/lib/ktx2-loader.d.ts +7 -0
- package/dist/lib/ktx2-loader.d.ts.map +1 -1
- package/dist/lib/ktx2-loader.js +35 -0
- package/dist/lib/layer-pass.d.ts.map +1 -1
- package/dist/lib/layers.d.ts +11 -7
- package/dist/lib/layers.d.ts.map +1 -1
- package/dist/lib/layers.js +16 -6
- package/dist/lib/live-frame-hold.d.ts +14 -0
- package/dist/lib/live-frame-hold.d.ts.map +1 -0
- package/dist/lib/live-frame-hold.js +28 -0
- package/dist/lib/materials.d.ts +19 -7
- package/dist/lib/materials.d.ts.map +1 -1
- package/dist/lib/materials.js +65 -9
- package/dist/lib/merged-outline-node.d.ts +5 -0
- package/dist/lib/merged-outline-node.d.ts.map +1 -1
- package/dist/lib/merged-outline-node.js +80 -2
- package/dist/lib/node-top-surface-height.d.ts +6 -0
- package/dist/lib/node-top-surface-height.d.ts.map +1 -0
- package/dist/lib/node-top-surface-height.js +74 -0
- package/dist/lib/perf-probe-state.d.ts +39 -0
- package/dist/lib/perf-probe-state.d.ts.map +1 -0
- package/dist/lib/perf-probe-state.js +17 -0
- package/dist/lib/pointer-events.d.ts +26 -2
- package/dist/lib/pointer-events.d.ts.map +1 -1
- package/dist/lib/pointer-events.js +99 -12
- package/dist/lib/post-processing-resources.d.ts.map +1 -1
- package/dist/lib/procedural-emission.d.ts +7 -0
- package/dist/lib/procedural-emission.d.ts.map +1 -0
- package/dist/lib/procedural-emission.js +54 -0
- package/dist/lib/reveal-candidates.d.ts +80 -0
- package/dist/lib/reveal-candidates.d.ts.map +1 -0
- package/dist/lib/reveal-candidates.js +524 -0
- package/dist/lib/reveal-ghost.d.ts +9 -0
- package/dist/lib/reveal-ghost.d.ts.map +1 -0
- package/dist/lib/reveal-ghost.js +62 -0
- package/dist/lib/reveal-pending.d.ts +12 -0
- package/dist/lib/reveal-pending.d.ts.map +1 -0
- package/dist/lib/reveal-pending.js +12 -0
- package/dist/lib/reveal-pose.d.ts +70 -0
- package/dist/lib/reveal-pose.d.ts.map +1 -0
- package/dist/lib/reveal-pose.js +248 -0
- package/dist/lib/reveal-schedule.d.ts +208 -0
- package/dist/lib/reveal-schedule.d.ts.map +1 -0
- package/dist/lib/reveal-schedule.js +410 -0
- package/dist/lib/reveal-texture-scale.d.ts +5 -0
- package/dist/lib/reveal-texture-scale.d.ts.map +1 -0
- package/dist/lib/reveal-texture-scale.js +113 -0
- package/dist/lib/reveal-windows.d.ts +23 -0
- package/dist/lib/reveal-windows.d.ts.map +1 -0
- package/dist/lib/reveal-windows.js +31 -0
- package/dist/lib/reveal-wipe.d.ts +71 -0
- package/dist/lib/reveal-wipe.d.ts.map +1 -0
- package/dist/lib/reveal-wipe.js +105 -0
- package/dist/lib/scene-pass-mrt.d.ts +12 -0
- package/dist/lib/scene-pass-mrt.d.ts.map +1 -0
- package/dist/lib/scene-pass-mrt.js +23 -0
- package/dist/lib/scene-support-height.d.ts +4 -0
- package/dist/lib/scene-support-height.d.ts.map +1 -0
- package/dist/lib/scene-support-height.js +34 -0
- package/dist/lib/scene-themes.d.ts +30 -8
- package/dist/lib/scene-themes.d.ts.map +1 -1
- package/dist/lib/scene-themes.js +36 -0
- package/dist/lib/scene-visibility.d.ts +17 -1
- package/dist/lib/scene-visibility.d.ts.map +1 -1
- package/dist/lib/scene-visibility.js +53 -3
- package/dist/lib/scripted-opening.d.ts +11 -0
- package/dist/lib/scripted-opening.d.ts.map +1 -0
- package/dist/lib/scripted-opening.js +20 -0
- package/dist/lib/site-surfaces.d.ts +32 -0
- package/dist/lib/site-surfaces.d.ts.map +1 -0
- package/dist/lib/site-surfaces.js +70 -0
- package/dist/lib/snapshot-pipeline.d.ts +34 -3
- package/dist/lib/snapshot-pipeline.d.ts.map +1 -1
- package/dist/lib/snapshot-pipeline.js +247 -117
- package/dist/lib/terrain-perimeter-fill.d.ts.map +1 -1
- package/dist/lib/terrain-perimeter-fill.js +22 -14
- package/dist/lib/tsl-compat.d.ts +2 -2
- package/dist/lib/tsl-compat.d.ts.map +1 -1
- package/dist/lib/underground-ambiance.d.ts +168 -0
- package/dist/lib/underground-ambiance.d.ts.map +1 -0
- package/dist/lib/underground-ambiance.js +334 -0
- package/dist/lib/zone-geometry.d.ts +11 -0
- package/dist/lib/zone-geometry.d.ts.map +1 -0
- package/dist/lib/zone-geometry.js +46 -0
- package/dist/store/use-item-light-pool.d.ts +14 -10
- package/dist/store/use-item-light-pool.d.ts.map +1 -1
- package/dist/store/use-item-light-pool.js +52 -26
- package/dist/store/use-viewer.d.ts +194 -26
- package/dist/store/use-viewer.d.ts.map +1 -1
- package/dist/store/use-viewer.js +164 -21
- package/dist/systems/ceiling/ceiling-system.d.ts +15 -1
- package/dist/systems/ceiling/ceiling-system.d.ts.map +1 -1
- package/dist/systems/ceiling/ceiling-system.js +88 -6
- package/dist/systems/construction-reveal/construction-dust.d.ts +16 -0
- package/dist/systems/construction-reveal/construction-dust.d.ts.map +1 -0
- package/dist/systems/construction-reveal/construction-dust.js +92 -0
- package/dist/systems/construction-reveal/construction-reveal.d.ts +276 -0
- package/dist/systems/construction-reveal/construction-reveal.d.ts.map +1 -0
- package/dist/systems/construction-reveal/construction-reveal.js +2383 -0
- package/dist/systems/construction-reveal/dust-material.d.ts +10 -0
- package/dist/systems/construction-reveal/dust-material.d.ts.map +1 -0
- package/dist/systems/construction-reveal/dust-material.js +17 -0
- package/dist/systems/construction-reveal/ghost-dress.d.ts +10 -0
- package/dist/systems/construction-reveal/ghost-dress.d.ts.map +1 -0
- package/dist/systems/construction-reveal/ghost-dress.js +24 -0
- package/dist/systems/door/door-system.d.ts.map +1 -1
- package/dist/systems/door/door-system.js +55 -17
- package/dist/systems/elevator/elevator-interaction-system.d.ts +7 -0
- package/dist/systems/elevator/elevator-interaction-system.d.ts.map +1 -1
- package/dist/systems/elevator/elevator-interaction-system.js +18 -1
- package/dist/systems/floor-elevation/floor-elevation-system.d.ts +3 -1
- package/dist/systems/floor-elevation/floor-elevation-system.d.ts.map +1 -1
- package/dist/systems/floor-elevation/floor-elevation-system.js +33 -5
- package/dist/systems/geometry/geometry-system.d.ts.map +1 -1
- package/dist/systems/geometry/geometry-system.js +71 -11
- package/dist/systems/interactive/control-widget.d.ts.map +1 -1
- package/dist/systems/interactive/interactive-system.d.ts.map +1 -1
- package/dist/systems/interactive/interactive-system.js +52 -17
- package/dist/systems/interactive/procedural-controls.d.ts +13 -0
- package/dist/systems/interactive/procedural-controls.d.ts.map +1 -0
- package/dist/systems/interactive/procedural-controls.js +17 -0
- package/dist/systems/interactive/scripted-clips.d.ts +19 -0
- package/dist/systems/interactive/scripted-clips.d.ts.map +1 -0
- package/dist/systems/interactive/scripted-clips.js +134 -0
- package/dist/systems/item/item-system.d.ts.map +1 -1
- package/dist/systems/item/item-system.js +9 -3
- package/dist/systems/item/object-cut-invalidation.d.ts +3 -0
- package/dist/systems/item/object-cut-invalidation.d.ts.map +1 -0
- package/dist/systems/item/object-cut-invalidation.js +68 -0
- package/dist/systems/item-light/item-light-system.d.ts +1 -1
- package/dist/systems/item-light/item-light-system.d.ts.map +1 -1
- package/dist/systems/item-light/item-light-system.js +48 -53
- package/dist/systems/level/level-hold.d.ts +4 -0
- package/dist/systems/level/level-hold.d.ts.map +1 -0
- package/dist/systems/level/level-hold.js +14 -0
- package/dist/systems/level/level-system.d.ts.map +1 -1
- package/dist/systems/level/level-system.js +19 -6
- package/dist/systems/level/level-utils.d.ts +19 -6
- package/dist/systems/level/level-utils.d.ts.map +1 -1
- package/dist/systems/level/level-utils.js +68 -9
- package/dist/systems/level/shadow-only-levels.d.ts +9 -0
- package/dist/systems/level/shadow-only-levels.d.ts.map +1 -0
- package/dist/systems/level/shadow-only-levels.js +7 -0
- package/dist/systems/roof/__fixtures__/roof-plane-cases.d.ts +103 -0
- package/dist/systems/roof/__fixtures__/roof-plane-cases.d.ts.map +1 -0
- package/dist/systems/roof/__fixtures__/roof-plane-cases.js +317 -0
- package/dist/systems/roof/roof-materials.d.ts +16 -2
- package/dist/systems/roof/roof-materials.d.ts.map +1 -1
- package/dist/systems/roof/roof-materials.js +64 -31
- package/dist/systems/roof/roof-system.d.ts +21 -4
- package/dist/systems/roof/roof-system.d.ts.map +1 -1
- package/dist/systems/roof/roof-system.js +374 -49
- package/dist/systems/slab/slab-system.d.ts +1 -1
- package/dist/systems/slab/slab-system.d.ts.map +1 -1
- package/dist/systems/slab/slab-system.js +49 -19
- package/dist/systems/stair/stair-system.d.ts.map +1 -1
- package/dist/systems/stair/stair-system.js +133 -354
- package/dist/systems/wall/wall-cutout-cache.d.ts +39 -3
- package/dist/systems/wall/wall-cutout-cache.d.ts.map +1 -1
- package/dist/systems/wall/wall-cutout-cache.js +141 -19
- package/dist/systems/wall/wall-cutout.d.ts +6 -0
- package/dist/systems/wall/wall-cutout.d.ts.map +1 -1
- package/dist/systems/wall/wall-cutout.js +42 -28
- package/dist/systems/wall/wall-finish-data.d.ts +22 -0
- package/dist/systems/wall/wall-finish-data.d.ts.map +1 -0
- package/dist/systems/wall/wall-finish-data.js +17 -0
- package/dist/systems/wall/wall-material-variant.d.ts.map +1 -1
- package/dist/systems/wall/wall-materials.d.ts +9 -4
- package/dist/systems/wall/wall-materials.d.ts.map +1 -1
- package/dist/systems/wall/wall-materials.js +135 -153
- package/dist/systems/wall/wall-placeholder-sweep.d.ts.map +1 -1
- package/dist/systems/wall/wall-system.d.ts +33 -2
- package/dist/systems/wall/wall-system.d.ts.map +1 -1
- package/dist/systems/wall/wall-system.js +621 -159
- package/dist/systems/window/corner-frame.d.ts +10 -0
- package/dist/systems/window/corner-frame.d.ts.map +1 -0
- package/dist/systems/window/corner-frame.js +17 -0
- package/dist/systems/window/window-system.d.ts +1 -1
- package/dist/systems/window/window-system.d.ts.map +1 -1
- package/dist/systems/window/window-system.js +71 -27
- package/package.json +10 -10
- package/dist/systems/fence/fence-system.d.ts +0 -22
- package/dist/systems/fence/fence-system.d.ts.map +0 -1
- package/dist/systems/fence/fence-system.js +0 -357
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import {
|
|
2
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
4
4
|
import { createPortal } from 'react-dom';
|
|
5
5
|
import { usePerfActionReceipts } from '../../lib/perf-actions';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"post-processing.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/post-processing.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"post-processing.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/post-processing.tsx"],"names":[],"mappings":"AA0DA,eAAO,MAAM,YAAY;IACvB,QAAQ;IACR,UAAU;CACX,CAAA;AAGD,eAAO,MAAM,WAAW;IACtB,OAAO;IACP,UAAU;IACV,SAAS;IACT,MAAM;IACN,SAAS;IACT,SAAS;IACT,gBAAgB;IAChB,WAAW;IACX,WAAW;IACX,kBAAkB;IAClB,sBAAsB;IACtB,oBAAoB;CACrB,CAAA;AAgED,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;AA+CD,QAAA,MAAM,oBAAoB,oCAGvB;IACD,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,6EAA6E;IAC7E,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB,SAwsBA,CAAA;eAEc,oBAAoB"}
|
|
@@ -3,25 +3,26 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
|
3
3
|
import { Color, Layers, Matrix4, Scene, UnsignedByteType } from 'three';
|
|
4
4
|
import { ssgi } from 'three/addons/tsl/display/SSGINode.js';
|
|
5
5
|
import { denoise } from 'three/examples/jsm/tsl/display/DenoiseNode.js';
|
|
6
|
-
import { add, diffuseColor, mix,
|
|
6
|
+
import { add, diffuseColor, mix, normalView, normalWorldGeometry, oscSine, output, pass, premultiplyAlpha, renderOutput, sample, saturation, screenUV, smoothstep, time, color as tslColor, float as tslFloat, uniform, vec3, vec4, } from 'three/tsl';
|
|
7
7
|
import { RenderPipeline, TimestampQuery } from 'three/webgpu';
|
|
8
|
-
import {
|
|
8
|
+
import { backdropColors, backdropGradient, flatBackdropOutput } from '../../lib/backdrop';
|
|
9
9
|
import { edgeColorFor, edgeOpacityScaleFor } from '../../lib/edge-style';
|
|
10
10
|
import { PERF_OVERLAY_ENABLED } from '../../lib/gpu-perf';
|
|
11
|
-
import { inkedEdges } from '../../lib/ink-edges';
|
|
11
|
+
import { createEdgeDepthSampler, inkedEdges } from '../../lib/ink-edges';
|
|
12
12
|
import { refreshIsolation } from '../../lib/isolation';
|
|
13
13
|
import { LayerPassIndex, LayerPassNode } from '../../lib/layer-pass';
|
|
14
|
-
import {
|
|
14
|
+
import { OVERLAY_LAYER, SCENE_LAYER, scenePassLayers, ZONE_LAYER } from '../../lib/layers';
|
|
15
|
+
import { isLiveFrameHeld } from '../../lib/live-frame-hold';
|
|
15
16
|
import { mergedOutline } from '../../lib/merged-outline-node';
|
|
16
17
|
import { recordPerfSample, timeSpan } from '../../lib/perf-tracks';
|
|
17
18
|
import { PostProcessingResources } from '../../lib/post-processing-resources';
|
|
18
|
-
import {
|
|
19
|
+
import { sceneLightingMask, scenePassMrt } from '../../lib/scene-pass-mrt';
|
|
19
20
|
import { packNormalToRGB, unpackRGBToNormal } from '../../lib/tsl-compat';
|
|
21
|
+
import { earthNow, UNDERGROUND_VIGNETTE, undergroundAmbianceNode, undergroundBackdrop, undergroundDissolve, undergroundDissolveGrain, undergroundEarthNode, undergroundFogAmount, undergroundVignette, worldPositionFromDepth, } from '../../lib/underground-ambiance';
|
|
20
22
|
import useViewer from '../../store/use-viewer';
|
|
21
23
|
import { useSceneAtmosphere } from './scene-atmosphere';
|
|
22
|
-
//
|
|
23
|
-
//
|
|
24
|
-
// contrast + saturation lift restores the punch. Rendered shading only.
|
|
24
|
+
// A mild mid-gray contrast and saturation lift separates surfaces before the
|
|
25
|
+
// output transform. Saved project looks can turn it off. Rendered shading only.
|
|
25
26
|
export const GRADE_PARAMS = {
|
|
26
27
|
contrast: 1.05,
|
|
27
28
|
saturation: 1.1,
|
|
@@ -142,29 +143,33 @@ const PostProcessingPasses = ({ hoverStyles = DEFAULT_HOVER_STYLES, disablePostF
|
|
|
142
143
|
const { gl: renderer, invalidate, scene, camera, size } = useThree();
|
|
143
144
|
const resourcesRef = useRef(null);
|
|
144
145
|
const atmosphere = useSceneAtmosphere();
|
|
145
|
-
|
|
146
|
+
// Under the ground the sky is the dark mode's: the same mix the pipeline's backdrop makes.
|
|
147
|
+
const directSkyNode = useMemo(() => atmosphere
|
|
148
|
+
? mix(atmosphere.skyRadiance(normalWorldGeometry), undergroundBackdrop(normalWorldGeometry.y), undergroundEarthNode())
|
|
149
|
+
: null, [atmosphere]);
|
|
146
150
|
const hasPipelineErrorRef = useRef(false);
|
|
147
151
|
const retryCountRef = useRef(0);
|
|
148
152
|
const rebuildTimeoutRef = useRef(null);
|
|
149
153
|
const skippedZeroSizeRef = useRef(false);
|
|
150
154
|
// Background color uniform — updated every frame via lerp, read by the TSL pipeline.
|
|
151
155
|
// Initialised from the current scene theme so there's no flash on first render.
|
|
152
|
-
const initTheme =
|
|
156
|
+
const initTheme = useViewer.getState().sceneAppearance;
|
|
157
|
+
const initBackdrop = backdropColors(initTheme);
|
|
153
158
|
const initBg = initTheme.background;
|
|
154
159
|
const bgUniform = useRef(uniform(new Color(initBg)));
|
|
155
160
|
const bgCurrent = useRef(new Color(initBg));
|
|
156
161
|
const bgTarget = useRef(new Color());
|
|
157
162
|
// Zenith colour of the backdrop gradient (falls back to the flat background).
|
|
158
|
-
const initSky =
|
|
163
|
+
const initSky = initBackdrop.sky;
|
|
159
164
|
const bgSkyUniform = useRef(uniform(new Color(initSky)));
|
|
160
165
|
const bgSkyCurrent = useRef(new Color(initSky));
|
|
161
166
|
const bgSkyTarget = useRef(new Color());
|
|
162
167
|
// Horizon haze band + deep zenith (derived — see lib/backdrop.ts).
|
|
163
|
-
const initHaze =
|
|
168
|
+
const initHaze = initBackdrop.haze;
|
|
164
169
|
const bgHazeUniform = useRef(uniform(new Color(initHaze)));
|
|
165
170
|
const bgHazeCurrent = useRef(new Color(initHaze));
|
|
166
171
|
const bgHazeTarget = useRef(new Color());
|
|
167
|
-
const initSkyDeep =
|
|
172
|
+
const initSkyDeep = initBackdrop.skyDeep;
|
|
168
173
|
const bgSkyDeepUniform = useRef(uniform(new Color(initSkyDeep)));
|
|
169
174
|
const bgSkyDeepCurrent = useRef(new Color(initSkyDeep));
|
|
170
175
|
const bgSkyDeepTarget = useRef(new Color());
|
|
@@ -173,6 +178,9 @@ const PostProcessingPasses = ({ hoverStyles = DEFAULT_HOVER_STYLES, disablePostF
|
|
|
173
178
|
// view ray from these to find the true horizon (dir.y = 0).
|
|
174
179
|
const camProjInvUniform = useRef(uniform(new Matrix4()));
|
|
175
180
|
const camWorldUniform = useRef(uniform(new Matrix4()));
|
|
181
|
+
// The clear colour of the no-pipeline fallback under the ground (scratch, and the dark mode's tone).
|
|
182
|
+
const fallbackClear = useRef(new Color());
|
|
183
|
+
const fallbackEarth = useRef(new Color(UNDERGROUND_VIGNETTE));
|
|
176
184
|
// Ink-line colour follows the scene-theme background luminance (dark lines on
|
|
177
185
|
// light scenes, light on dark), refreshed each frame like the background.
|
|
178
186
|
// Dark scenes also scale the ink opacity down (see edge-style.ts).
|
|
@@ -189,13 +197,10 @@ const PostProcessingPasses = ({ hoverStyles = DEFAULT_HOVER_STYLES, disablePostF
|
|
|
189
197
|
// picking), so without this the gizmos/handles/tool previews land in the
|
|
190
198
|
// depth+normal MRT and get inked / AO'd as if they were geometry. The grid is
|
|
191
199
|
// kept in here (not the overlay pass) so scene geometry depth-occludes it; it's
|
|
192
|
-
// a flat, depth-non-writing plane
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
l.enable(GRID_LAYER);
|
|
197
|
-
return l;
|
|
198
|
-
}, []);
|
|
200
|
+
// a flat, depth-non-writing plane. The dust shares the layer and writes alpha 0 to
|
|
201
|
+
// the normal and diffuse attachments, which `scenePassMrt` blends, so the ink
|
|
202
|
+
// never sees its quads.
|
|
203
|
+
const sceneOnlyLayers = useMemo(scenePassLayers, []);
|
|
199
204
|
// Editor overlays render in their own pass, composited on top after the ink
|
|
200
205
|
// and outlines so they read as crisp UI rather than scene geometry.
|
|
201
206
|
const overlayLayers = useMemo(() => {
|
|
@@ -203,7 +208,10 @@ const PostProcessingPasses = ({ hoverStyles = DEFAULT_HOVER_STYLES, disablePostF
|
|
|
203
208
|
l.set(OVERLAY_LAYER);
|
|
204
209
|
return l;
|
|
205
210
|
}, []);
|
|
206
|
-
const
|
|
211
|
+
const hoverMode = useViewer((s) => s.hoverHighlightMode);
|
|
212
|
+
// Elements a chat chip points at draw in the `point` style whatever the editor's hover mode is.
|
|
213
|
+
const hasPointedIds = useViewer((s) => s.pointedIds.length > 0);
|
|
214
|
+
const hoverHighlightMode = hasPointedIds ? 'point' : hoverMode;
|
|
207
215
|
const hoverVisibleColor = useMemo(() => uniform(new Color(DEFAULT_HOVER_STYLE.visibleColor)), []);
|
|
208
216
|
const hoverHiddenColor = useMemo(() => uniform(new Color(DEFAULT_HOVER_STYLE.hiddenColor)), []);
|
|
209
217
|
const hoverStrength = useMemo(() => uniform(DEFAULT_HOVER_STYLE.strength), []);
|
|
@@ -211,6 +219,9 @@ const PostProcessingPasses = ({ hoverStyles = DEFAULT_HOVER_STYLES, disablePostF
|
|
|
211
219
|
// Subscribe to projectId so the pipeline rebuilds on project switch
|
|
212
220
|
const projectId = useViewer((s) => s.projectId);
|
|
213
221
|
const shading = useViewer((s) => s.shading);
|
|
222
|
+
const ambientOcclusion = useViewer((s) => s.sceneAppearance.postprocessing?.ambientOcclusion !== false);
|
|
223
|
+
const colorGrading = useViewer((s) => s.sceneAppearance.postprocessing?.colorGrading !== false);
|
|
224
|
+
const flatBackground = useViewer((s) => s.sceneAppearance.backgroundSky === null);
|
|
214
225
|
const edges = useViewer((s) => s.edges);
|
|
215
226
|
const inkOpacityOverride = useViewer((s) => s.inkOpacity);
|
|
216
227
|
const transparentBackground = useViewer((s) => s.transparentBackground);
|
|
@@ -294,7 +305,7 @@ const PostProcessingPasses = ({ hoverStyles = DEFAULT_HOVER_STYLES, disablePostF
|
|
|
294
305
|
disposePipeline();
|
|
295
306
|
return;
|
|
296
307
|
}
|
|
297
|
-
const ssgiEnabled = shading === 'rendered' && SSGI_PARAMS.enabled && !perfDisable.ao;
|
|
308
|
+
const ssgiEnabled = shading === 'rendered' && ambientOcclusion && SSGI_PARAMS.enabled && !perfDisable.ao;
|
|
298
309
|
const denoiseEnabled = ssgiEnabled && !perfDisable.denoise;
|
|
299
310
|
const outlineEnabled = !perfDisable.outline;
|
|
300
311
|
const inkEnabled = edges !== 'off';
|
|
@@ -312,6 +323,8 @@ const PostProcessingPasses = ({ hoverStyles = DEFAULT_HOVER_STYLES, disablePostF
|
|
|
312
323
|
perfDisable,
|
|
313
324
|
projectId,
|
|
314
325
|
shading,
|
|
326
|
+
ambientOcclusion,
|
|
327
|
+
colorGrading,
|
|
315
328
|
transparentBackground,
|
|
316
329
|
rendererCtor: renderer.constructor?.name,
|
|
317
330
|
width,
|
|
@@ -371,18 +384,21 @@ const PostProcessingPasses = ({ hoverStyles = DEFAULT_HOVER_STYLES, disablePostF
|
|
|
371
384
|
// Scene depth is shared by SSGI, ink, and outlines.
|
|
372
385
|
// The normal MRT is only built when SSGI or ink needs it.
|
|
373
386
|
const scenePassDepth = scenePass.getTextureNode('depth');
|
|
387
|
+
const sampleEdgeDepth = createEdgeDepthSampler(scenePassDepth, camera);
|
|
374
388
|
let scenePassNormal = null;
|
|
375
389
|
if (needsNormalMRT) {
|
|
376
|
-
scenePass.setMRT(
|
|
390
|
+
scenePass.setMRT(scenePassMrt({
|
|
377
391
|
output,
|
|
378
392
|
diffuseColor,
|
|
379
393
|
normal: packNormalToRGB(normalView),
|
|
394
|
+
lighting: sceneLightingMask(),
|
|
380
395
|
}));
|
|
381
396
|
scenePassNormal = scenePass.getTextureNode('normal');
|
|
382
397
|
}
|
|
383
398
|
if (scenePassNormal) {
|
|
384
399
|
const normalTexture = scenePass.getTexture('normal');
|
|
385
400
|
normalTexture.type = UnsignedByteType;
|
|
401
|
+
scenePass.getTexture('lighting').type = UnsignedByteType;
|
|
386
402
|
}
|
|
387
403
|
// Extract normal from color-encoded texture (SSGI consumes the node form).
|
|
388
404
|
const normalNode = scenePassNormal;
|
|
@@ -428,10 +444,12 @@ const PostProcessingPasses = ({ hoverStyles = DEFAULT_HOVER_STYLES, disablePostF
|
|
|
428
444
|
// (same ≈150→350 m window as ink-edges' distanceFade) so the horizon
|
|
429
445
|
// disc and the geometry↔sky depth cliff never grow an AO band — that
|
|
430
446
|
// band read as a visible line along the horizon.
|
|
431
|
-
const aoFarFade = smoothstep(tslFloat(0.9994), tslFloat(0.9998),
|
|
447
|
+
const aoFarFade = smoothstep(tslFloat(0.9994), tslFloat(0.9998), sampleEdgeDepth(screenUV));
|
|
432
448
|
ao = mix(ao, tslFloat(1), aoFarFade);
|
|
449
|
+
const lightingWeight = scenePass.getTextureNode('lighting').r;
|
|
450
|
+
ao = mix(tslFloat(1), ao, lightingWeight);
|
|
433
451
|
// Composite: scene * AO + diffuse * GI
|
|
434
|
-
sceneColor = vec4(add(scenePassColor.rgb.mul(ao), add(zonePass.rgb, scenePassDiffuse.rgb.mul(gi))), contentAlpha);
|
|
452
|
+
sceneColor = vec4(add(scenePassColor.rgb.mul(ao), add(zonePass.rgb, scenePassDiffuse.rgb.mul(gi).mul(lightingWeight))), contentAlpha);
|
|
435
453
|
}
|
|
436
454
|
// Screen-space ink outline (SketchUp look) — depth/normal edge detection
|
|
437
455
|
// over the composited scene. Topology-agnostic, so it handles CSG-cut
|
|
@@ -439,7 +457,7 @@ const PostProcessingPasses = ({ hoverStyles = DEFAULT_HOVER_STYLES, disablePostF
|
|
|
439
457
|
if (inkEnabled && scenePassDepth && scenePassNormal) {
|
|
440
458
|
sceneColor = vec4(inkedEdges({
|
|
441
459
|
sceneRgb: sceneColor.rgb,
|
|
442
|
-
|
|
460
|
+
sampleDepth: sampleEdgeDepth,
|
|
443
461
|
normalTex: scenePassNormal,
|
|
444
462
|
inkColor: inkColorUniform.current,
|
|
445
463
|
radius: inkRadius,
|
|
@@ -452,7 +470,7 @@ const PostProcessingPasses = ({ hoverStyles = DEFAULT_HOVER_STYLES, disablePostF
|
|
|
452
470
|
// backdrop below so geometry that fades to the background colour (the
|
|
453
471
|
// horizon disc) matches it exactly.
|
|
454
472
|
const gradeRgb = (rgb) => saturation(rgb.div(0.18).pow(vec3(GRADE_PARAMS.contrast)).mul(0.18), GRADE_PARAMS.saturation);
|
|
455
|
-
if (shading === 'rendered') {
|
|
473
|
+
if (shading === 'rendered' && colorGrading) {
|
|
456
474
|
sceneColor = vec4(gradeRgb(sceneColor.rgb), sceneColor.a);
|
|
457
475
|
}
|
|
458
476
|
// Reused scene depth lets outlined groups occlude each other; materials
|
|
@@ -509,11 +527,37 @@ const PostProcessingPasses = ({ hoverStyles = DEFAULT_HOVER_STYLES, disablePostF
|
|
|
509
527
|
sky: bgSkyUniform.current,
|
|
510
528
|
skyDeep: bgSkyDeepUniform.current,
|
|
511
529
|
});
|
|
512
|
-
if (shading === 'rendered') {
|
|
530
|
+
if (shading === 'rendered' && colorGrading) {
|
|
513
531
|
bgGradient = gradeRgb(bgGradient);
|
|
514
532
|
}
|
|
515
|
-
|
|
516
|
-
|
|
533
|
+
let sceneComposite = compositeWithOutlines.rgb;
|
|
534
|
+
// Under the ground (the eye below the ground surface) the scene goes to its dark mode: the
|
|
535
|
+
// sky is the dark theme's backdrop, and what stands far from the shown level dissolves into
|
|
536
|
+
// it (distance outside the level's box, from the scene pass's own depth; backdrop and fog
|
|
537
|
+
// meet in one colour per pixel). A noise mask closes over the screen as the eye crosses,
|
|
538
|
+
// 0 everywhere above the ground, 1 everywhere below.
|
|
539
|
+
let dive = null;
|
|
540
|
+
if (!transparentBackground) {
|
|
541
|
+
const grain = undergroundDissolveGrain();
|
|
542
|
+
dive = undergroundDissolve(screenUV, undergroundAmbianceNode(), grain);
|
|
543
|
+
// The backdrop follows the earth factor, which is the dark mode's own in the overview and
|
|
544
|
+
// alone in the walkthrough (looking out of a basement window shows earth, the rooms keep
|
|
545
|
+
// their light: no fog, no vignette).
|
|
546
|
+
const earthDive = undergroundDissolve(screenUV, undergroundEarthNode(), grain);
|
|
547
|
+
const dark = undergroundBackdrop(worldDir.y);
|
|
548
|
+
// The day's backdrop leaves ahead of the blobs: it greys and dims over the first half of
|
|
549
|
+
// the crossing, so the anthracite spreads over a neutral grey picture, not a blue sky.
|
|
550
|
+
const leaving = smoothstep(tslFloat(0), tslFloat(0.5), undergroundEarthNode());
|
|
551
|
+
const day = saturation(bgGradient, tslFloat(1).sub(leaving)).mul(tslFloat(1).sub(leaving.mul(0.35)));
|
|
552
|
+
bgGradient = mix(day, dark, earthDive);
|
|
553
|
+
const worldPosition = worldPositionFromDepth(scenePassDepth.sample(screenUV).r, camProjInvUniform.current, camWorldUniform.current);
|
|
554
|
+
sceneComposite = mix(sceneComposite, dark, undergroundFogAmount(worldPosition).mul(dive));
|
|
555
|
+
}
|
|
556
|
+
let composited = mix(bgGradient, sceneComposite, contentAlpha);
|
|
557
|
+
// The screen's edges close in with it.
|
|
558
|
+
if (dive) {
|
|
559
|
+
composited = mix(composited, tslColor(UNDERGROUND_VIGNETTE), undergroundVignette().mul(dive));
|
|
560
|
+
}
|
|
517
561
|
// Editor overlays painted on top by their own alpha — they never get inked,
|
|
518
562
|
// AO'd, or outlined, and always read crisp regardless of scene depth.
|
|
519
563
|
const withOverlay = mix(composited, overlayColor.rgb, overlayColor.a);
|
|
@@ -527,9 +571,21 @@ const PostProcessingPasses = ({ hoverStyles = DEFAULT_HOVER_STYLES, disablePostF
|
|
|
527
571
|
.div(alpha.max(tslFloat(0.00001)));
|
|
528
572
|
finalOutput = premultiplyAlpha(renderOutput(vec4(straightRgb, alpha)));
|
|
529
573
|
}
|
|
574
|
+
else if (flatBackground && !atmosphere) {
|
|
575
|
+
const backdrop = flatBackdropOutput({
|
|
576
|
+
background: bgUniform.current,
|
|
577
|
+
foreground: sceneComposite,
|
|
578
|
+
alpha: contentAlpha,
|
|
579
|
+
toneMapping: renderer.toneMapping,
|
|
580
|
+
outputColorSpace: renderer.outputColorSpace,
|
|
581
|
+
});
|
|
582
|
+
const overlay = renderOutput(vec4(overlayColor.rgb, 1), renderer.toneMapping, renderer.outputColorSpace);
|
|
583
|
+
finalOutput = vec4(mix(backdrop.rgb, overlay.rgb, overlayColor.a), 1);
|
|
584
|
+
}
|
|
530
585
|
const renderPipeline = new RenderPipeline(renderer);
|
|
531
586
|
resources.pipeline = renderPipeline;
|
|
532
|
-
renderPipeline.outputColorTransform =
|
|
587
|
+
renderPipeline.outputColorTransform =
|
|
588
|
+
!transparentBackground && !(flatBackground && !atmosphere);
|
|
533
589
|
renderPipeline.outputNode = finalOutput;
|
|
534
590
|
retryCountRef.current = 0;
|
|
535
591
|
}
|
|
@@ -563,6 +619,9 @@ const PostProcessingPasses = ({ hoverStyles = DEFAULT_HOVER_STYLES, disablePostF
|
|
|
563
619
|
renderer,
|
|
564
620
|
scene,
|
|
565
621
|
shading,
|
|
622
|
+
ambientOcclusion,
|
|
623
|
+
colorGrading,
|
|
624
|
+
flatBackground,
|
|
566
625
|
transparentBackground,
|
|
567
626
|
size.height,
|
|
568
627
|
size.width,
|
|
@@ -574,6 +633,9 @@ const PostProcessingPasses = ({ hoverStyles = DEFAULT_HOVER_STYLES, disablePostF
|
|
|
574
633
|
if (size.width < 1 || size.height < 1) {
|
|
575
634
|
return;
|
|
576
635
|
}
|
|
636
|
+
// A capture is working on the shared scene: the canvas keeps its last frame.
|
|
637
|
+
if (isLiveFrameHeld())
|
|
638
|
+
return;
|
|
577
639
|
// `?disable=draw`: nothing downstream wants pixels — render an EMPTY scene
|
|
578
640
|
// instead of the real one. This is the only render call (positive-priority
|
|
579
641
|
// useFrame subscribers already disable R3F's automatic render), so the real
|
|
@@ -593,17 +655,18 @@ const PostProcessingPasses = ({ hoverStyles = DEFAULT_HOVER_STYLES, disablePostF
|
|
|
593
655
|
return;
|
|
594
656
|
}
|
|
595
657
|
// Animate background colour toward the current scene theme target (same lerp as AnimatedBackground)
|
|
596
|
-
const bgTheme =
|
|
658
|
+
const bgTheme = useViewer.getState().sceneAppearance;
|
|
659
|
+
const backdrop = backdropColors(bgTheme);
|
|
597
660
|
bgTarget.current.set(bgTheme.background);
|
|
598
661
|
bgCurrent.current.lerp(bgTarget.current, Math.min(delta, 0.1) * 4);
|
|
599
662
|
bgUniform.current.value.copy(bgCurrent.current);
|
|
600
|
-
bgSkyTarget.current.set(
|
|
663
|
+
bgSkyTarget.current.set(backdrop.sky);
|
|
601
664
|
bgSkyCurrent.current.lerp(bgSkyTarget.current, Math.min(delta, 0.1) * 4);
|
|
602
665
|
bgSkyUniform.current.value.copy(bgSkyCurrent.current);
|
|
603
|
-
bgHazeTarget.current.set(
|
|
666
|
+
bgHazeTarget.current.set(backdrop.haze);
|
|
604
667
|
bgHazeCurrent.current.lerp(bgHazeTarget.current, Math.min(delta, 0.1) * 4);
|
|
605
668
|
bgHazeUniform.current.value.copy(bgHazeCurrent.current);
|
|
606
|
-
bgSkyDeepTarget.current.set(
|
|
669
|
+
bgSkyDeepTarget.current.set(backdrop.skyDeep);
|
|
607
670
|
bgSkyDeepCurrent.current.lerp(bgSkyDeepTarget.current, Math.min(delta, 0.1) * 4);
|
|
608
671
|
bgSkyDeepUniform.current.value.copy(bgSkyDeepCurrent.current);
|
|
609
672
|
camProjInvUniform.current.value.copy(camera.projectionMatrixInverse);
|
|
@@ -625,9 +688,14 @@ const PostProcessingPasses = ({ hoverStyles = DEFAULT_HOVER_STYLES, disablePostF
|
|
|
625
688
|
scene.backgroundNode = directSkyNode;
|
|
626
689
|
try {
|
|
627
690
|
const clearAlpha = transparentBackground ? 0 : 1;
|
|
691
|
+
// Without the pipeline there is no fog and no vignette: the clear colour is the dark mode's.
|
|
692
|
+
const underground = transparentBackground ? 0 : earthNow();
|
|
693
|
+
const clearColor = underground > 0 ? fallbackClear.current.copy(bgCurrent.current) : bgCurrent.current;
|
|
694
|
+
if (underground > 0)
|
|
695
|
+
clearColor.lerp(fallbackEarth.current, underground);
|
|
628
696
|
if (renderer.setClearColor) {
|
|
629
697
|
;
|
|
630
|
-
renderer.setClearColor(
|
|
698
|
+
renderer.setClearColor(clearColor, clearAlpha);
|
|
631
699
|
}
|
|
632
700
|
else if (renderer.setClearAlpha) {
|
|
633
701
|
;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registered-systems.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/registered-systems.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"registered-systems.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/registered-systems.tsx"],"names":[],"mappings":"AAoDA;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,iBAAiB,uCAkChC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import {
|
|
2
|
+
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
3
3
|
import { createSceneApi, isNodeKindEnabled, nodeRegistry, useRegistryVersion, useScene, } from '@pascal-app/core';
|
|
4
|
-
import { lazy, Suspense, useMemo } from 'react';
|
|
4
|
+
import { Component, lazy, Suspense, useMemo } from 'react';
|
|
5
5
|
const DEFAULT_PRIORITY = 5;
|
|
6
6
|
const lazyCache = new WeakMap();
|
|
7
7
|
function loadSystem(def) {
|
|
@@ -14,6 +14,20 @@ function loadSystem(def) {
|
|
|
14
14
|
lazyCache.set(def.system.module, Comp);
|
|
15
15
|
return Comp;
|
|
16
16
|
}
|
|
17
|
+
class SystemErrorBoundary extends Component {
|
|
18
|
+
state = { failed: false };
|
|
19
|
+
static getDerivedStateFromError() {
|
|
20
|
+
return { failed: true };
|
|
21
|
+
}
|
|
22
|
+
componentDidCatch(error) {
|
|
23
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
24
|
+
console.error(`[viewer] Disabled system ${this.props.systemId}`, error);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
render() {
|
|
28
|
+
return this.state.failed ? null : this.props.children;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
17
31
|
/**
|
|
18
32
|
* Mounts every registered node kind's system component, ordered by
|
|
19
33
|
* `system.priority` (default {@link DEFAULT_PRIORITY}).
|
|
@@ -56,6 +70,6 @@ export function RegisteredSystems() {
|
|
|
56
70
|
const Comp = loadSystem(def);
|
|
57
71
|
if (!Comp)
|
|
58
72
|
return null;
|
|
59
|
-
return (_jsx(Suspense, { fallback: null, children: _jsx(Comp, { sceneApi: sceneApi }) }, `registered-system:${kind}`));
|
|
73
|
+
return (_jsx(SystemErrorBoundary, { systemId: kind, children: _jsx(Suspense, { fallback: null, children: _jsx(Comp, { sceneApi: sceneApi }) }) }, `registered-system:${kind}`));
|
|
60
74
|
}) }));
|
|
61
75
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
type RenderErrorHandler = ((cause: unknown) => void) | undefined;
|
|
3
|
+
/**
|
|
4
|
+
* One handler that notifies every given handler (the immersive session's and
|
|
5
|
+
* the host's), or undefined when there is none. A handler that throws is
|
|
6
|
+
* logged and does not stop the others.
|
|
7
|
+
*/
|
|
8
|
+
export declare function composeRenderErrorHandlers(...handlers: RenderErrorHandler[]): RenderErrorHandler;
|
|
9
|
+
/**
|
|
10
|
+
* The viewer-scene error boundary: a node renderer or system that throws while
|
|
11
|
+
* rendering renders nothing in its place, and every handler hears about it.
|
|
12
|
+
*/
|
|
13
|
+
export declare function SceneErrorBoundary({ handlers, children, }: {
|
|
14
|
+
handlers: RenderErrorHandler[];
|
|
15
|
+
children: ReactNode;
|
|
16
|
+
}): import("react").JSX.Element;
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=render-error.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-error.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/render-error.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGtC,KAAK,kBAAkB,GAAG,CAAC,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;AAEhE;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,GAAG,QAAQ,EAAE,kBAAkB,EAAE,GAAG,kBAAkB,CAYhG;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,QAAQ,EACR,QAAQ,GACT,EAAE;IACD,QAAQ,EAAE,kBAAkB,EAAE,CAAA;IAC9B,QAAQ,EAAE,SAAS,CAAA;CACpB,+BAUA"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { ErrorBoundary } from '../error-boundary';
|
|
3
|
+
/**
|
|
4
|
+
* One handler that notifies every given handler (the immersive session's and
|
|
5
|
+
* the host's), or undefined when there is none. A handler that throws is
|
|
6
|
+
* logged and does not stop the others.
|
|
7
|
+
*/
|
|
8
|
+
export function composeRenderErrorHandlers(...handlers) {
|
|
9
|
+
const present = handlers.filter((handler) => handler !== undefined);
|
|
10
|
+
if (present.length === 0)
|
|
11
|
+
return;
|
|
12
|
+
return (cause) => {
|
|
13
|
+
for (const handler of present) {
|
|
14
|
+
try {
|
|
15
|
+
handler(cause);
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
console.error('[viewer] a render-error handler threw', error);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* The viewer-scene error boundary: a node renderer or system that throws while
|
|
25
|
+
* rendering renders nothing in its place, and every handler hears about it.
|
|
26
|
+
*/
|
|
27
|
+
export function SceneErrorBoundary({ handlers, children, }) {
|
|
28
|
+
return (_jsx(ErrorBoundary, { fallback: null, onError: composeRenderErrorHandlers(...handlers), scope: "viewer-scene", children: children }));
|
|
29
|
+
}
|
|
@@ -1 +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,
|
|
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,WAAY,IAAI,YAA4C,CAAA;AAY3F,eAAO,MAAM,QAAQ,mIAoGpB,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scene-environment.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/scene-environment.tsx"],"names":[],"mappings":"AAoEA,wBAAgB,gBAAgB,
|
|
1
|
+
{"version":3,"file":"scene-environment.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/scene-environment.tsx"],"names":[],"mappings":"AAoEA,wBAAgB,gBAAgB,SA8C/B"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { useThree } from '@react-three/fiber';
|
|
3
|
-
import { useEffect,
|
|
3
|
+
import { useEffect, useRef } from 'react';
|
|
4
|
+
import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js';
|
|
4
5
|
import * as THREE from 'three/webgpu';
|
|
5
|
-
import { getSceneTheme } from '../../lib/scene-themes';
|
|
6
6
|
import useViewer from '../../store/use-viewer';
|
|
7
7
|
import { useSceneAtmosphere } from './scene-atmosphere';
|
|
8
8
|
/**
|
|
@@ -63,31 +63,51 @@ function buildGradientSky() {
|
|
|
63
63
|
}
|
|
64
64
|
export function SceneEnvironment() {
|
|
65
65
|
const scene = useThree((state) => state.scene);
|
|
66
|
-
const
|
|
67
|
-
const appearance = useViewer((state) =>
|
|
66
|
+
const renderer = useThree((state) => state.gl);
|
|
67
|
+
const appearance = useViewer((state) => state.sceneAppearance.appearance);
|
|
68
|
+
const environment = useViewer((state) => state.sceneAppearance.environment);
|
|
69
|
+
const source = environment?.source ?? 'gradient';
|
|
68
70
|
const atmosphere = useSceneAtmosphere();
|
|
69
71
|
const atmosphereRef = useRef(atmosphere);
|
|
70
72
|
atmosphereRef.current = atmosphere;
|
|
71
73
|
useEffect(() => {
|
|
72
74
|
const prevEnvironment = scene.environment;
|
|
73
|
-
|
|
75
|
+
let target;
|
|
76
|
+
let texture = null;
|
|
77
|
+
if (source === 'room') {
|
|
78
|
+
const room = new RoomEnvironment();
|
|
79
|
+
const generator = new THREE.PMREMGenerator(renderer);
|
|
80
|
+
target = generator.fromScene(room, 0.04);
|
|
81
|
+
texture = target.texture;
|
|
82
|
+
room.dispose();
|
|
83
|
+
generator.dispose();
|
|
84
|
+
}
|
|
85
|
+
else if (source === 'gradient')
|
|
86
|
+
texture = buildGradientSky();
|
|
74
87
|
scene.environment = texture;
|
|
75
88
|
return () => {
|
|
76
89
|
if (scene.environment === texture) {
|
|
77
90
|
scene.environment = prevEnvironment;
|
|
78
|
-
if (!atmosphereRef.current)
|
|
79
|
-
scene.environmentIntensity = prevIntensity;
|
|
80
91
|
}
|
|
81
|
-
|
|
92
|
+
if (target)
|
|
93
|
+
target.dispose();
|
|
94
|
+
else
|
|
95
|
+
texture?.dispose();
|
|
82
96
|
};
|
|
83
|
-
}, [scene,
|
|
97
|
+
}, [renderer, scene, source]);
|
|
84
98
|
useEffect(() => {
|
|
85
99
|
// An atmosphere owns environmentIntensity while its environmentNode is
|
|
86
100
|
// active. The gradient remains installed as the fallback texture and takes
|
|
87
101
|
// over immediately when the atmosphere restores scene ownership.
|
|
88
102
|
if (atmosphere)
|
|
89
103
|
return;
|
|
90
|
-
scene.environmentIntensity
|
|
91
|
-
|
|
104
|
+
const previous = scene.environmentIntensity;
|
|
105
|
+
scene.environmentIntensity =
|
|
106
|
+
environment?.intensity ?? (appearance === 'dark' ? ENV_INTENSITY_DARK : ENV_INTENSITY);
|
|
107
|
+
return () => {
|
|
108
|
+
if (!atmosphereRef.current)
|
|
109
|
+
scene.environmentIntensity = previous;
|
|
110
|
+
};
|
|
111
|
+
}, [appearance, atmosphere, scene, environment?.intensity]);
|
|
92
112
|
return null;
|
|
93
113
|
}
|
|
@@ -1,5 +1,11 @@
|
|
|
1
|
+
import type { Scene } from 'three';
|
|
1
2
|
/** Whether modeled exterior ground replaces this scene's fallback horizon disc. */
|
|
2
3
|
export declare function useSceneGroundReplacement(): boolean;
|
|
4
|
+
/**
|
|
5
|
+
* The same claim from outside React (a map layer that hangs its own meshes on
|
|
6
|
+
* the scene): returns the release. The last release restores the fallback.
|
|
7
|
+
*/
|
|
8
|
+
export declare function claimSceneGround(scene: Scene): () => void;
|
|
3
9
|
/** Mount alongside replacement ground. The last release restores the fallback. */
|
|
4
10
|
export declare function SceneGroundReplacement(): null;
|
|
5
11
|
//# sourceMappingURL=scene-ground-replacement.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scene-ground-replacement.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/scene-ground-replacement.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"scene-ground-replacement.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/scene-ground-replacement.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,OAAO,CAAA;AAgBlC,mFAAmF;AACnF,wBAAgB,yBAAyB,IAAI,OAAO,CAInD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,IAAI,CASzD;AAED,kFAAkF;AAClF,wBAAgB,sBAAsB,SAarC"}
|
|
@@ -18,6 +18,21 @@ export function useSceneGroundReplacement() {
|
|
|
18
18
|
const store = useMemo(() => groundStore(scene), [scene]);
|
|
19
19
|
return useStore(store, (state) => state.owners > 0);
|
|
20
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* The same claim from outside React (a map layer that hangs its own meshes on
|
|
23
|
+
* the scene): returns the release. The last release restores the fallback.
|
|
24
|
+
*/
|
|
25
|
+
export function claimSceneGround(scene) {
|
|
26
|
+
const store = groundStore(scene);
|
|
27
|
+
store.setState((state) => ({ owners: state.owners + 1 }));
|
|
28
|
+
let released = false;
|
|
29
|
+
return () => {
|
|
30
|
+
if (released)
|
|
31
|
+
return;
|
|
32
|
+
released = true;
|
|
33
|
+
store.setState((state) => ({ owners: Math.max(0, state.owners - 1) }));
|
|
34
|
+
};
|
|
35
|
+
}
|
|
21
36
|
/** Mount alongside replacement ground. The last release restores the fallback. */
|
|
22
37
|
export function SceneGroundReplacement() {
|
|
23
38
|
const scene = useThree((state) => state.scene);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selection-manager.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/selection-manager.tsx"],"names":[],"mappings":"AAqSA,eAAO,MAAM,gBAAgB,
|
|
1
|
+
{"version":3,"file":"selection-manager.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/selection-manager.tsx"],"names":[],"mappings":"AAqSA,eAAO,MAAM,gBAAgB,mCA+G5B,CAAA"}
|