@pascal-app/viewer 1.0.0 → 1.0.3

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.
Files changed (73) hide show
  1. package/README.md +12 -0
  2. package/dist/capture/capture-runtime.js +2 -32
  3. package/dist/capture/layers/device-motion-layer.d.ts.map +1 -1
  4. package/dist/capture/layers/device-motion-layer.js +5 -7
  5. package/dist/capture/stream-rendering.d.ts.map +1 -1
  6. package/dist/capture/stream-rendering.js +2 -1
  7. package/dist/capture/use-json-artifact.d.ts +2 -0
  8. package/dist/capture/use-json-artifact.d.ts.map +1 -0
  9. package/dist/capture/use-json-artifact.js +42 -0
  10. package/dist/components/viewer/glb-scene.d.ts.map +1 -1
  11. package/dist/components/viewer/glb-scene.js +3 -1
  12. package/dist/components/viewer/index.d.ts +12 -0
  13. package/dist/components/viewer/index.d.ts.map +1 -1
  14. package/dist/components/viewer/index.js +28 -7
  15. package/dist/components/viewer/post-processing.d.ts.map +1 -1
  16. package/dist/components/viewer/post-processing.js +6 -0
  17. package/dist/components/viewer/selection-manager.d.ts.map +1 -1
  18. package/dist/components/viewer/selection-manager.js +8 -16
  19. package/dist/components/viewer/viewer-camera.d.ts +15 -1
  20. package/dist/components/viewer/viewer-camera.d.ts.map +1 -1
  21. package/dist/components/viewer/viewer-camera.js +43 -5
  22. package/dist/index.d.ts +8 -6
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +8 -6
  25. package/dist/lib/csg-utils.d.ts +1 -1
  26. package/dist/lib/csg-utils.d.ts.map +1 -1
  27. package/dist/lib/csg-utils.js +1 -1
  28. package/dist/lib/isolation.d.ts +14 -30
  29. package/dist/lib/isolation.d.ts.map +1 -1
  30. package/dist/lib/isolation.js +62 -66
  31. package/dist/lib/materials.d.ts.map +1 -1
  32. package/dist/lib/materials.js +2 -1
  33. package/dist/lib/renderer-capability.d.ts +2 -1
  34. package/dist/lib/renderer-capability.d.ts.map +1 -1
  35. package/dist/lib/renderer-capability.js +2 -2
  36. package/dist/lib/scene-visibility.js +3 -1
  37. package/dist/lib/snapshot-pipeline.d.ts +3 -1
  38. package/dist/lib/snapshot-pipeline.d.ts.map +1 -1
  39. package/dist/lib/snapshot-pipeline.js +32 -16
  40. package/dist/store/use-viewer.d.ts +3 -1
  41. package/dist/store/use-viewer.d.ts.map +1 -1
  42. package/dist/store/use-viewer.js +2 -0
  43. package/dist/systems/door/door-system.d.ts.map +1 -1
  44. package/dist/systems/door/door-system.js +18 -5
  45. package/dist/systems/floor-elevation/floor-elevation-system.d.ts.map +1 -1
  46. package/dist/systems/floor-elevation/floor-elevation-system.js +122 -3
  47. package/dist/systems/geometry/geometry-system.d.ts.map +1 -1
  48. package/dist/systems/geometry/geometry-system.js +4 -0
  49. package/dist/systems/level/level-system.js +14 -14
  50. package/dist/systems/level/level-utils.d.ts +25 -1
  51. package/dist/systems/level/level-utils.d.ts.map +1 -1
  52. package/dist/systems/level/level-utils.js +25 -4
  53. package/dist/systems/wall/wall-cutout-cache.d.ts +4 -1
  54. package/dist/systems/wall/wall-cutout-cache.d.ts.map +1 -1
  55. package/dist/systems/wall/wall-cutout-cache.js +16 -7
  56. package/dist/systems/wall/wall-cutout.d.ts +3 -1
  57. package/dist/systems/wall/wall-cutout.d.ts.map +1 -1
  58. package/dist/systems/wall/wall-cutout.js +5 -5
  59. package/dist/systems/wall/wall-materials.d.ts +11 -2
  60. package/dist/systems/wall/wall-materials.d.ts.map +1 -1
  61. package/dist/systems/wall/wall-materials.js +24 -18
  62. package/dist/systems/wall/wall-system.d.ts +15 -2
  63. package/dist/systems/wall/wall-system.d.ts.map +1 -1
  64. package/dist/systems/wall/wall-system.js +20 -21
  65. package/dist/systems/window/window-system.d.ts +1 -1
  66. package/dist/systems/window/window-system.d.ts.map +1 -1
  67. package/dist/systems/window/window-system.js +3 -2
  68. package/dist/systems/zone/zone-system.d.ts.map +1 -1
  69. package/dist/systems/zone/zone-system.js +28 -2
  70. package/dist/xr/presentation-context.d.ts +7 -0
  71. package/dist/xr/presentation-context.d.ts.map +1 -0
  72. package/dist/xr/presentation-context.js +10 -0
  73. package/package.json +4 -4
package/README.md CHANGED
@@ -175,6 +175,18 @@ colors; dollhouse enables front-face rendering for surface previews and room mod
175
175
  inward-facing room surfaces from outside. It changes per-instance materials, not geometry or
176
176
  loader-cached materials. Omitting these options preserves the existing presentation.
177
177
 
178
+ ## Scene Snapshots
179
+
180
+ `createSnapshotPipeline` renders offscreen snapshots with the scene theme's backdrop by default.
181
+ Inside a `Viewer`, pass the source returned by `useSceneAtmosphere()` as `atmosphere` to capture
182
+ the active presentation's sky instead. Recreate the pipeline when that source changes; updates
183
+ to its existing uniforms do not require rebuilding it.
184
+
185
+ Use `applyEnvironment({ ..., transparent: true })` to retain scene alpha without compositing a
186
+ backdrop. The snapshot scene pass owns its transparent clear so intermediate post-processing
187
+ passes cannot turn empty sky into opaque pixels. Dispose the pipeline when it is replaced or
188
+ no longer needed.
189
+
178
190
  ## Viewer State
179
191
 
180
192
  ```typescript
@@ -7,7 +7,6 @@ import { Suspense, useCallback, useEffect, useMemo, useRef, useState, } from 're
7
7
  import { ErrorBoundary } from '../components/error-boundary';
8
8
  import { useNodeEvents } from '../hooks/use-node-events';
9
9
  import useViewer from '../store/use-viewer';
10
- import { rewriteLoopbackAssetUrl } from './asset-url';
11
10
  import { resolveCaptureFrameMatrix } from './frame';
12
11
  import { isCaptureSessionVisible, isCaptureStreamVisible } from './layer-visibility';
13
12
  import { CaptureDeviceMotionLayer } from './layers/device-motion-layer';
@@ -17,6 +16,7 @@ import { CaptureSurfaceMeshLayer } from './layers/surface-mesh-layer';
17
16
  import { useCaptureSource } from './source-state';
18
17
  import { captureModelFormat, isCaptureModelArtifact, isCapturePointCloudArtifact, isCaptureStreamRenderable, streamHydratesJsonPayload, } from './stream-rendering';
19
18
  import { parseDeviceTrajectoryPackets, parseDeviceTrajectoryPayload } from './trajectory';
19
+ import { useJsonArtifactPayload } from './use-json-artifact';
20
20
  const EMPTY_RENDERERS = {};
21
21
  const EMPTY_LAYER_VISIBILITY = {};
22
22
  export function CaptureRuntime({ defaultLayerVisibility = EMPTY_LAYER_VISIBILITY, maxPacketsPerStream = 32, onError, renderers = EMPTY_RENDERERS, resolveSource, retryKey = 0, }) {
@@ -135,7 +135,7 @@ export function CaptureStreamLayer({ descriptor, meshPresentation, packets, rend
135
135
  if (Renderer) {
136
136
  content = (_jsx(Renderer, { artifactUrl: artifactUrl, descriptor: descriptor, meshPresentation: meshPresentation, packets: packets, scan: scan, source: source, stream: stream, streamEpoch: streamEpoch }));
137
137
  }
138
- else if (layerKey === 'model' &&
138
+ else if ((layerKey === 'model' || layerKey === 'spaceformScene') &&
139
139
  isCaptureModelArtifact(stream.artifact) &&
140
140
  stream.artifact &&
141
141
  artifactUrl) {
@@ -154,36 +154,6 @@ export function CaptureStreamLayer({ descriptor, meshPresentation, packets, rend
154
154
  return content;
155
155
  return (_jsx("group", { matrix: frameMatrix, matrixAutoUpdate: false, children: content }));
156
156
  }
157
- function useJsonArtifactPayload(url) {
158
- const [error, setError] = useState(null);
159
- const [payload, setPayload] = useState(null);
160
- useEffect(() => {
161
- setError(null);
162
- setPayload(null);
163
- if (!url)
164
- return;
165
- const abort = new AbortController();
166
- void fetch(rewriteLoopbackAssetUrl(url), { signal: abort.signal })
167
- .then(async (response) => {
168
- if (!response.ok)
169
- throw new Error(`Could not load ${url}: ${response.status}`);
170
- return (await response.json());
171
- })
172
- .then((data) => {
173
- if (!abort.signal.aborted)
174
- setPayload(data);
175
- })
176
- .catch((cause) => {
177
- if (abort.signal.aborted)
178
- return;
179
- setError(cause instanceof Error ? cause : new Error(`Could not load ${url}.`));
180
- });
181
- return () => abort.abort();
182
- }, [url]);
183
- if (error)
184
- throw error;
185
- return payload;
186
- }
187
157
  function useResolvedArtifact(source, artifact) {
188
158
  const [error, setError] = useState(null);
189
159
  const [url, setUrl] = useState(null);
@@ -1 +1 @@
1
- {"version":3,"file":"device-motion-layer.d.ts","sourceRoot":"","sources":["../../../src/capture/layers/device-motion-layer.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAE,KAAK,gBAAgB,EAA0B,MAAM,eAAe,CAAA;AAE7E,eAAO,MAAM,4BAA4B,IAAI,CAAA;AAE7C,wBAAgB,wBAAwB,CAAC,EACvC,SAAe,EACf,UAAU,GACX,EAAE;IACD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,gBAAgB,CAAA;CAC7B,+BAiDA"}
1
+ {"version":3,"file":"device-motion-layer.d.ts","sourceRoot":"","sources":["../../../src/capture/layers/device-motion-layer.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAE,KAAK,gBAAgB,EAA0B,MAAM,eAAe,CAAA;AAE7E,eAAO,MAAM,4BAA4B,IAAI,CAAA;AAE7C,wBAAgB,wBAAwB,CAAC,EACvC,SAAe,EACf,UAAU,GACX,EAAE;IACD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,gBAAgB,CAAA;CAC7B,+BA2CA"}
@@ -36,7 +36,7 @@ export function CaptureDeviceMotionLayer({ lineWidth = 2.5, trajectory, }) {
36
36
  deviceRef.current.position.copy(position);
37
37
  deviceRef.current.quaternion.slerpQuaternions(fromQuaternion, toQuaternion, frame.alpha);
38
38
  });
39
- return (_jsxs("group", { children: [trajectorySegments.map(({ points, segment }) => (_jsx(CaptureLine, { color: "#222326", lineWidth: lineWidth, opacity: 0.78, points: points }, segment))), _jsx("group", { ref: deviceRef, children: _jsx(CameraFrustum, { lineWidth: lineWidth }) })] }));
39
+ return (_jsxs("group", { children: [trajectorySegments.map(({ points, segment }) => (_jsx(CaptureLine, { color: "#39ff14", lineWidth: lineWidth, points: points }, segment))), _jsx("group", { ref: deviceRef, children: _jsx(CameraFrustum, { lineWidth: lineWidth }) })] }));
40
40
  }
41
41
  function CameraFrustum({ lineWidth }) {
42
42
  const apex = [0, 0, 0];
@@ -52,24 +52,22 @@ function CameraFrustum({ lineWidth }) {
52
52
  [bottomLeft, bottomRight],
53
53
  [bottomRight, topRight],
54
54
  ].flat();
55
- return (_jsxs("group", { children: [_jsx(CaptureLine, { color: "#f5b900", lineWidth: lineWidth, points: points, segments: true }), _jsxs("mesh", { children: [_jsx("sphereGeometry", { args: [0.025, 12, 12] }), _jsx("meshBasicMaterial", { color: "#ffd84d" })] })] }));
55
+ return (_jsxs("group", { scale: 1.35, children: [_jsx(CaptureLine, { color: "#ffee00", lineWidth: lineWidth, points: points, segments: true }), _jsxs("mesh", { children: [_jsx("sphereGeometry", { args: [0.035, 12, 12] }), _jsx("meshBasicMaterial", { color: "#ffee00", toneMapped: false })] })] }));
56
56
  }
57
- function CaptureLine({ color, lineWidth, opacity = 1, points, segments = false, }) {
57
+ function CaptureLine({ color, lineWidth, points, segments = false, }) {
58
58
  const line = useMemo(() => {
59
59
  const geometry = new BufferGeometry().setFromPoints(points.map(([x, y, z]) => new Vector3(x, y, z)));
60
60
  const material = new LineBasicMaterial({
61
61
  color,
62
- depthWrite: opacity >= 1,
63
62
  linewidth: lineWidth,
64
- opacity,
65
- transparent: opacity < 1,
63
+ toneMapped: false,
66
64
  });
67
65
  const object = segments
68
66
  ? new LineSegments(geometry, material)
69
67
  : new ThreeLine(geometry, material);
70
68
  object.frustumCulled = false;
71
69
  return object;
72
- }, [color, lineWidth, opacity, points, segments]);
70
+ }, [color, lineWidth, points, segments]);
73
71
  useEffect(() => () => {
74
72
  line.geometry.dispose();
75
73
  line.material.dispose();
@@ -1 +1 @@
1
- {"version":3,"file":"stream-rendering.d.ts","sourceRoot":"","sources":["../../src/capture/stream-rendering.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,wBAAwB,EAC7B,KAAK,uBAAuB,EAK7B,MAAM,0BAA0B,CAAA;AAOjC,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,MAAM,CAAA;AAEhD,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,uBAAuB,EAC/B,kBAAkB,GAAE,WAAW,CAAC,MAAM,CAAa,GAClD,OAAO,CA0BT;AAID;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,uBAAuB,GAAG,OAAO,CAKlF;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,wBAAwB,GAAG,SAAS,GAAG,OAAO,CAE9F;AAED,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,wBAAwB,GAAG,SAAS,GAC7C,kBAAkB,GAAG,IAAI,CAS3B;AAED,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,wBAAwB,GAAG,SAAS,GAC7C,OAAO,CAGT"}
1
+ {"version":3,"file":"stream-rendering.d.ts","sourceRoot":"","sources":["../../src/capture/stream-rendering.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,wBAAwB,EAC7B,KAAK,uBAAuB,EAK7B,MAAM,0BAA0B,CAAA;AAOjC,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,MAAM,CAAA;AAEhD,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,uBAAuB,EAC/B,kBAAkB,GAAE,WAAW,CAAC,MAAM,CAAa,GAClD,OAAO,CA4BT;AAID;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,uBAAuB,GAAG,OAAO,CAKlF;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,wBAAwB,GAAG,SAAS,GAAG,OAAO,CAE9F;AAED,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,wBAAwB,GAAG,SAAS,GAC7C,kBAAkB,GAAG,IAAI,CAS3B;AAED,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,wBAAwB,GAAG,SAAS,GAC7C,OAAO,CAGT"}
@@ -9,8 +9,9 @@ export function isCaptureStreamRenderable(stream, customRendererKeys = new Set()
9
9
  const layerKey = captureLayerKey(stream);
10
10
  if (customRendererKeys.has(layerKey) || customRendererKeys.has(stream.kind))
11
11
  return true;
12
- if (layerKey === 'model')
12
+ if (layerKey === 'model' || layerKey === 'spaceformScene') {
13
13
  return isCaptureModelArtifact(stream.artifact);
14
+ }
14
15
  if (layerKey === 'deviceMotion') {
15
16
  return (stream.availability === 'live' ||
16
17
  streamHydratesJsonPayload(stream) ||
@@ -0,0 +1,2 @@
1
+ export declare function useJsonArtifactPayload(url: string | null): unknown;
2
+ //# sourceMappingURL=use-json-artifact.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-json-artifact.d.ts","sourceRoot":"","sources":["../../src/capture/use-json-artifact.ts"],"names":[],"mappings":"AAgBA,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAgClE"}
@@ -0,0 +1,42 @@
1
+ import { useEffect, useState } from 'react';
2
+ import { FileLoader } from 'three';
3
+ import { rewriteLoopbackAssetUrl } from './asset-url';
4
+ const requests = new Map();
5
+ function loadJsonArtifact(url) {
6
+ const cached = requests.get(url);
7
+ if (cached)
8
+ return cached;
9
+ const request = new FileLoader().setResponseType('json').loadAsync(url);
10
+ requests.set(url, request);
11
+ // Keep successful downloads across view switches, but let a remount retry failures.
12
+ void request.catch(() => requests.delete(url));
13
+ return request;
14
+ }
15
+ export function useJsonArtifactPayload(url) {
16
+ const resolvedUrl = url ? rewriteLoopbackAssetUrl(url) : null;
17
+ const [result, setResult] = useState(null);
18
+ useEffect(() => {
19
+ if (!resolvedUrl)
20
+ return;
21
+ let active = true;
22
+ void loadJsonArtifact(resolvedUrl).then((payload) => {
23
+ if (active)
24
+ setResult({ url: resolvedUrl, payload });
25
+ }, (cause) => {
26
+ if (active) {
27
+ setResult({
28
+ url: resolvedUrl,
29
+ error: cause instanceof Error ? cause : new Error('Could not load capture data.'),
30
+ });
31
+ }
32
+ });
33
+ return () => {
34
+ active = false;
35
+ };
36
+ }, [resolvedUrl]);
37
+ if (!result || result.url !== resolvedUrl)
38
+ return null;
39
+ if (result.error)
40
+ throw result.error;
41
+ return result.payload ?? null;
42
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"glb-scene.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/glb-scene.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,OAAO,EAAkC,MAAM,kBAAkB,CAAA;AAc/E,OAAO,EAAkB,KAAK,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AAqB3E,2EAA2E;AAC3E,MAAM,MAAM,QAAQ,GAAG;IAAE,EAAE,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAA;AAE/D,4EAA4E;AAC5E,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAAA;AAEzE,mFAAmF;AACnF,MAAM,MAAM,QAAQ,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAA;AAE7D;8EAC8E;AAC9E,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAA;CAChD,GAAG,IAAI,CAAA;AA8NR;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,EACvB,GAAG,EACH,gBAAgB,EAChB,cAAc,EACd,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,mBAAmB,GACpB,EAAE;IACD,GAAG,EAAE,MAAM,CAAA;IACX;oFACgF;IAChF,gBAAgB,CAAC,EAAE,kBAAkB,EAAE,CAAA;IACvC;mFAC+E;IAC/E,cAAc,CAAC,EAAE,OAAO,EAAE,CAAA;IAC1B;kFAC8E;IAC9E,YAAY,CAAC,EAAE,OAAO,EAAE,CAAA;IACxB,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,IAAI,CAAA;IAC7C,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,WAAW,KAAK,IAAI,CAAA;IAClD,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAA;IACzC,mBAAmB,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAA;CACtD,+BAgzBA"}
1
+ {"version":3,"file":"glb-scene.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/glb-scene.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,OAAO,EAAkC,MAAM,kBAAkB,CAAA;AAc/E,OAAO,EAAkB,KAAK,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AAqB3E,2EAA2E;AAC3E,MAAM,MAAM,QAAQ,GAAG;IAAE,EAAE,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAA;AAE/D,4EAA4E;AAC5E,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAAA;AAEzE,mFAAmF;AACnF,MAAM,MAAM,QAAQ,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAA;AAE7D;8EAC8E;AAC9E,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAA;CAChD,GAAG,IAAI,CAAA;AA8NR;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,EACvB,GAAG,EACH,gBAAgB,EAChB,cAAc,EACd,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,mBAAmB,GACpB,EAAE;IACD,GAAG,EAAE,MAAM,CAAA;IACX;oFACgF;IAChF,gBAAgB,CAAC,EAAE,kBAAkB,EAAE,CAAA;IACvC;mFAC+E;IAC/E,cAAc,CAAC,EAAE,OAAO,EAAE,CAAA;IAC1B;kFAC8E;IAC9E,YAAY,CAAC,EAAE,OAAO,EAAE,CAAA;IACxB,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,IAAI,CAAA;IAC7C,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,WAAW,KAAK,IAAI,CAAA;IAClD,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAA;IACzC,mBAAmB,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAA;CACtD,+BAkzBA"}
@@ -483,7 +483,9 @@ export function GlbScene({ url, interactiveItems, referenceNodes, replaceNodes,
483
483
  const targetY = baseY + (exploded ? index * EXPLODED_GAP : 0);
484
484
  // Snap (not lerp) in walkthrough so the first-person collider, built from
485
485
  // these world positions, matches the stacked building immediately.
486
- node.position.y = walkthroughMode ? targetY : lerp(node.position.y, targetY, delta * 12);
486
+ node.position.y = walkthroughMode
487
+ ? targetY
488
+ : lerp(node.position.y, targetY, Math.min(1, delta * 12));
487
489
  // Solo: hidden levels above the soloed one keep casting shadows
488
490
  // (shadow-caster-only); below-levels can't block the sun, so plain-hide.
489
491
  const hidden = !walkthroughMode && levelMode === 'solo' && Boolean(selectedLevel) && id !== selectedLevel;
@@ -1,5 +1,6 @@
1
1
  import { type AnyNodeId } from '@pascal-app/core';
2
2
  import { type ThreeElement } from '@react-three/fiber';
3
+ import { type ComponentType } from 'react';
3
4
  import * as THREE from 'three/webgpu';
4
5
  import type { ColorPreset, RenderShading } from '../../lib/materials';
5
6
  import { type RenderContext } from '../../store/use-viewer';
@@ -9,6 +10,15 @@ declare module '@react-three/fiber' {
9
10
  lineBasicNodeMaterial: ThreeElement<typeof THREE.LineBasicNodeMaterial>;
10
11
  }
11
12
  }
13
+ export interface ViewerImmersiveSession {
14
+ Session: ComponentType<{
15
+ children: React.ReactNode;
16
+ }>;
17
+ Scene: ComponentType<{
18
+ children: React.ReactNode;
19
+ }>;
20
+ onError?: (cause: unknown) => void;
21
+ }
12
22
  interface ViewerProps {
13
23
  children?: React.ReactNode;
14
24
  hoverStyles?: HoverStyles;
@@ -69,6 +79,8 @@ interface ViewerProps {
69
79
  disablePostFx?: boolean;
70
80
  /** Keep the mounted renderer/context warm without advancing scene frames. */
71
81
  renderPaused?: boolean;
82
+ /** Host-provided immersive XR session wrappers for the main scene. */
83
+ immersive?: ViewerImmersiveSession;
72
84
  }
73
85
  /** Imperative handle exposed via `ref` on `<Viewer>`. */
74
86
  export type ViewerHandle = {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/index.tsx"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,SAAS,EAMf,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAkB,KAAK,YAAY,EAAsB,MAAM,oBAAoB,CAAA;AAS1F,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AAKrC,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAKrE,OAAkB,EAAE,KAAK,aAAa,EAAE,MAAM,wBAAwB,CAAA;AAatE,OAAuB,EAAwB,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAY1F,OAAO,QAAQ,oBAAoB,CAAC;IAOlC,UAAU,aAAa;QACrB,qBAAqB,EAAE,YAAY,CAAC,OAAO,KAAK,CAAC,qBAAqB,CAAC,CAAA;KACxE;CACF;AA8QD,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;IACd,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,aAAa,CAAC,EAAE,aAAa,CAAA;IAC7B,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,aAAa,CAAC,EAAE;QACd,OAAO,CAAC,EAAE,aAAa,CAAA;QACvB,QAAQ,CAAC,EAAE,OAAO,CAAA;QAClB,WAAW,CAAC,EAAE,WAAW,CAAA;KAC1B,CAAA;IACD;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,SAAS,EAAE,GAAG,IAAI,CAAA;IAC5B;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IACtC,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;IAC7C;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,6EAA6E;IAC7E,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB;AAED,yDAAyD;AACzD,MAAM,MAAM,YAAY,GAAG;IACzB;;;;;OAKG;IACH,WAAW,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,IAAI,GAAG,IAAI,CAAA;CAC3C,CAAA;AAED,QAAA,MAAM,MAAM,sGA0PV,CAAA;AAEF,eAAe,MAAM,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/index.tsx"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,SAAS,EAMf,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAkB,KAAK,YAAY,EAAsB,MAAM,oBAAoB,CAAA;AAC1F,OAAO,EACL,KAAK,aAAa,EAOnB,MAAM,OAAO,CAAA;AACd,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AAKrC,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAKrE,OAAkB,EAAE,KAAK,aAAa,EAAE,MAAM,wBAAwB,CAAA;AActE,OAAuB,EAAwB,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAY1F,OAAO,QAAQ,oBAAoB,CAAC;IAOlC,UAAU,aAAa;QACrB,qBAAqB,EAAE,YAAY,CAAC,OAAO,KAAK,CAAC,qBAAqB,CAAC,CAAA;KACxE;CACF;AAoRD,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,aAAa,CAAC;QAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;KAAE,CAAC,CAAA;IACrD,KAAK,EAAE,aAAa,CAAC;QAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;KAAE,CAAC,CAAA;IACnD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;CACnC;AAED,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;IACd,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,aAAa,CAAC,EAAE,aAAa,CAAA;IAC7B,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,aAAa,CAAC,EAAE;QACd,OAAO,CAAC,EAAE,aAAa,CAAA;QACvB,QAAQ,CAAC,EAAE,OAAO,CAAA;QAClB,WAAW,CAAC,EAAE,WAAW,CAAA;KAC1B,CAAA;IACD;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,SAAS,EAAE,GAAG,IAAI,CAAA;IAC5B;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IACtC,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;IAC7C;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,6EAA6E;IAC7E,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,sEAAsE;IACtE,SAAS,CAAC,EAAE,sBAAsB,CAAA;CACnC;AAED,yDAAyD;AACzD,MAAM,MAAM,YAAY,GAAG;IACzB;;;;;OAKG;IACH,WAAW,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,IAAI,GAAG,IAAI,CAAA;CAC3C,CAAA;AAED,QAAA,MAAM,MAAM,sGAuPV,CAAA;AAyEF,eAAe,MAAM,CAAA"}
@@ -1,5 +1,5 @@
1
1
  'use client';
2
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { nodeRegistry, RoofElevationSystem, StairOpeningSystem, sceneRegistry, useScene, } from '@pascal-app/core';
4
4
  import { Canvas, extend, useFrame, useThree } from '@react-three/fiber';
5
5
  import { forwardRef, useEffect, useImperativeHandle, useLayoutEffect, useRef, useState, } from 'react';
@@ -17,6 +17,7 @@ import { FloorElevationSystem } from '../../systems/floor-elevation/floor-elevat
17
17
  import { GeometrySystem } from '../../systems/geometry/geometry-system';
18
18
  import { PerfActionSettleSystem } from '../../systems/perf-action-settle/perf-action-settle-system';
19
19
  import { subscribeWallBuildInteractions } from '../../systems/wall/wall-build-lifecycle';
20
+ import { ImmersiveXRPresentationProvider } from '../../xr/presentation-context';
20
21
  import { ErrorBoundary } from '../error-boundary';
21
22
  import { SceneRenderer } from '../renderers/scene-renderer';
22
23
  import { BATCH_SPIKE_ENABLED, BatchedMeshSpike } from './batched-mesh-spike';
@@ -94,7 +95,7 @@ function installEmptyDrawGuard(renderer) {
94
95
  renderer.renderObject(object, scene, camera, geometry, material, group, lightsNode, clippingContext, passId);
95
96
  });
96
97
  }
97
- function GPUDeviceWatcher() {
98
+ function GPUDeviceWatcher({ intentionalWebGL = false }) {
98
99
  const gl = useThree((s) => s.gl);
99
100
  useEffect(() => {
100
101
  // Detect KTX2 transcode support as soon as the renderer exists, so catalog
@@ -103,13 +104,15 @@ function GPUDeviceWatcher() {
103
104
  ensureKtx2Support(gl);
104
105
  const backend = gl.backend;
105
106
  const device = backend?.device;
106
- if (!device) {
107
+ if (!device && !intentionalWebGL) {
107
108
  console.warn('[viewer] No WebGPU device on backend — running on a fallback renderer.', {
108
109
  backend: backend?.constructor?.name ?? 'unknown',
109
110
  rendererType: gl.constructor?.name ?? 'unknown',
110
111
  });
111
112
  return;
112
113
  }
114
+ if (!device)
115
+ return;
113
116
  console.log('[viewer] WebGPU device ready', {
114
117
  label: device.label,
115
118
  features: Array.from(device.features ?? []),
@@ -127,7 +130,7 @@ function GPUDeviceWatcher() {
127
130
  return () => {
128
131
  device.removeEventListener?.('uncapturederror', onUncapturedError);
129
132
  };
130
- }, [gl]);
133
+ }, [gl, intentionalWebGL]);
131
134
  return null;
132
135
  }
133
136
  function ToneMappingExposure() {
@@ -148,6 +151,10 @@ function ToneMappingExposure() {
148
151
  }, -1);
149
152
  return null;
150
153
  }
154
+ function ImmersiveXRBackground() {
155
+ const background = useViewer((state) => getSceneTheme(state.sceneTheme).background);
156
+ return _jsx("color", { args: [background], attach: "background" });
157
+ }
151
158
  function hasPendingSceneBuildWork() {
152
159
  const { dirtyNodes, nodes, rootNodeIds } = useScene.getState();
153
160
  for (const id of dirtyNodes) {
@@ -226,7 +233,7 @@ function SceneReadyTracker({ onSceneReadyChange, sceneReadyKey, sceneReadyMaxWai
226
233
  }, 10);
227
234
  return null;
228
235
  }
229
- const Viewer = forwardRef(function Viewer({ children, hoverStyles = DEFAULT_HOVER_STYLES, selectionManager = 'default', perf = false, useBvh = true, renderContext = 'editor', transparent, defaultRender, isolate, sceneReadyKey, onSceneReadyChange, sceneReadyMaxWaitMs, maxFps = 50, disablePostFx = false, renderPaused = false, }, ref) {
236
+ const Viewer = forwardRef(function Viewer({ children, hoverStyles = DEFAULT_HOVER_STYLES, selectionManager = 'default', perf = false, useBvh = true, renderContext = 'editor', transparent, defaultRender, isolate, sceneReadyKey, onSceneReadyChange, sceneReadyMaxWaitMs, maxFps = 50, disablePostFx = false, renderPaused = false, immersive, }, ref) {
230
237
  useEffect(() => {
231
238
  if (nodeRegistry.size === 0) {
232
239
  console.warn('[viewer] Node registry is empty. Install @pascal-app/nodes and call await loadPlugin(builtinPlugin) before mounting <Viewer>.');
@@ -313,16 +320,25 @@ const Viewer = forwardRef(function Viewer({ children, hoverStyles = DEFAULT_HOVE
313
320
  if (showGpuFallback)
314
321
  onSceneReadyChange?.(true);
315
322
  }, [showGpuFallback, onSceneReadyChange]);
323
+ useEffect(() => {
324
+ if (!immersive)
325
+ return;
326
+ const timeout = window.setTimeout(() => window.dispatchEvent(new Event('resize')), 0);
327
+ return () => window.clearTimeout(timeout);
328
+ }, [immersive]);
329
+ const ImmersiveSession = immersive?.Session;
330
+ const immersiveActive = immersive != null;
316
331
  if (showGpuFallback) {
317
332
  return _jsx(UnsupportedGpuViewerFallback, {});
318
333
  }
319
- return (_jsxs(_Fragment, { children: [(perf || PERF_OVERLAY_ENABLED) && _jsx(PerfPanel, {}), _jsxs(Canvas, { ref: subscribeWallBuildInteractions, camera: { position: [50, 50, 50], fov: 50 }, className: `transition-colors duration-700 ${transparentBackground ? 'bg-transparent' : isDark ? 'bg-[#1f2433]' : 'bg-[#fafafa]'}`, dpr: [1, maxDpr], events: pointerEvents, frameloop: "never", gl: ((props) => {
334
+ return (_jsxs(_Fragment, { children: [(perf || PERF_OVERLAY_ENABLED) && _jsx(PerfPanel, {}), _jsx(Canvas, { ref: subscribeWallBuildInteractions, camera: { position: [50, 50, 50], fov: 50 }, className: `transition-colors duration-700 ${transparentBackground ? 'bg-transparent' : isDark ? 'bg-[#1f2433]' : 'bg-[#fafafa]'}`, dpr: [1, maxDpr], events: pointerEvents, frameloop: "never", gl: ((props) => {
320
335
  const canvas = props.canvas;
321
336
  const cached = canvas ? WEBGPU_RENDERER_CACHE.get(canvas) : undefined;
322
337
  if (cached)
323
338
  return cached;
324
339
  const promise = (async () => {
325
340
  const result = await initializeGpuRenderer({
341
+ forceWebGL: immersiveActive,
326
342
  // Supplying `device` makes three skip its own `requestAdapter`,
327
343
  // so R3F's `powerPreference` only reaches the GPU if we forward it.
328
344
  powerPreference: props.powerPreference,
@@ -366,6 +382,11 @@ const Viewer = forwardRef(function Viewer({ children, hoverStyles = DEFAULT_HOVE
366
382
  }, shadows: {
367
383
  type: THREE.PCFShadowMap,
368
384
  enabled: shadowsEnabled,
369
- }, children: [_jsx(FrameLimiter, { fps: maxFps, paused: renderPaused }), _jsx(ViewerCamera, {}), _jsx(PointerRaycastLayers, {}), _jsx(GPUDeviceWatcher, {}), _jsx(ToneMappingExposure, {}), _jsx(SceneReadyTracker, { onSceneReadyChange: onSceneReadyChange, sceneReadyKey: sceneReadyKey, sceneReadyMaxWaitMs: sceneReadyMaxWaitMs }), _jsxs(ErrorBoundary, { fallback: null, scope: "viewer-scene", children: [_jsx(Lights, {}), useBvh ? (_jsx(SceneBvh, { children: _jsx(SceneRenderer, {}) })) : (_jsx(SceneRenderer, {})), _jsx(FloorElevationSystem, {}), _jsx(GeometrySystem, {}), _jsx(StairOpeningSystem, {}), _jsx(RoofElevationSystem, {}), _jsx(RegisteredSystems, {}), _jsx(PostProcessing, { disablePostFx: disablePostFx, hoverStyles: hoverStyles }), selectionManager === 'default' && _jsx(SelectionManager, {}), (perf || PERF_OVERLAY_ENABLED) && _jsx(PerfMonitor, {}), (perf || PERF_OVERLAY_ENABLED) && _jsx(PerfActionSettleSystem, {}), BATCH_SPIKE_ENABLED && _jsx(BatchedMeshSpike, {}), children] })] })] }));
385
+ }, children: _jsx(ImmersiveXRPresentationProvider, { enabled: immersiveActive, children: ImmersiveSession ? (_jsx(ImmersiveSession, { children: _jsx(ViewerScene, { disablePostFx: true, hoverStyles: hoverStyles, immersiveXR: true, onRenderError: immersive.onError, onSceneReadyChange: onSceneReadyChange, perf: perf, sceneReadyKey: sceneReadyKey, sceneReadyMaxWaitMs: sceneReadyMaxWaitMs, selectionManager: selectionManager, useBvh: useBvh, SceneWrapper: immersive.Scene, children: children }) })) : (_jsxs(_Fragment, { children: [_jsx(FrameLimiter, { fps: maxFps, paused: renderPaused }), _jsx(ViewerScene, { disablePostFx: disablePostFx, hoverStyles: hoverStyles, onSceneReadyChange: onSceneReadyChange, perf: perf, sceneReadyKey: sceneReadyKey, sceneReadyMaxWaitMs: sceneReadyMaxWaitMs, selectionManager: selectionManager, useBvh: useBvh, children: children })] })) }) }, immersiveActive ? 'webgl-xr' : 'webgpu')] }));
370
386
  });
387
+ function ViewerScene({ children, disablePostFx, hoverStyles, immersiveXR = false, onRenderError, onSceneReadyChange, perf, sceneReadyKey, sceneReadyMaxWaitMs, selectionManager, useBvh, SceneWrapper, }) {
388
+ const renderedScene = useBvh ? (_jsx(SceneBvh, { children: _jsx(SceneRenderer, {}) })) : (_jsx(SceneRenderer, {}));
389
+ const spatialScene = (_jsxs(_Fragment, { children: [renderedScene, _jsx(FloorElevationSystem, {}), _jsx(GeometrySystem, {}), _jsx(StairOpeningSystem, {}), _jsx(RoofElevationSystem, {}), _jsx(RegisteredSystems, {}), BATCH_SPIKE_ENABLED && _jsx(BatchedMeshSpike, {}), children] }));
390
+ return (_jsxs(_Fragment, { children: [_jsx(ViewerCamera, { immersiveXR: immersiveXR }), immersiveXR && _jsx(ImmersiveXRBackground, {}), _jsx(PointerRaycastLayers, {}), _jsx(GPUDeviceWatcher, { intentionalWebGL: immersiveXR }), _jsx(ToneMappingExposure, {}), _jsx(SceneReadyTracker, { onSceneReadyChange: onSceneReadyChange, sceneReadyKey: sceneReadyKey, sceneReadyMaxWaitMs: sceneReadyMaxWaitMs }), _jsxs(ErrorBoundary, { fallback: null, onError: onRenderError, scope: "viewer-scene", children: [_jsx(Lights, {}), SceneWrapper ? _jsx(SceneWrapper, { children: spatialScene }) : spatialScene, !immersiveXR && _jsx(PostProcessing, { disablePostFx: disablePostFx, hoverStyles: hoverStyles }), selectionManager === 'default' && _jsx(SelectionManager, {}), (perf || PERF_OVERLAY_ENABLED) && _jsx(PerfMonitor, {}), (perf || PERF_OVERLAY_ENABLED) && _jsx(PerfActionSettleSystem, {})] })] }));
391
+ }
371
392
  export default Viewer;
@@ -1 +1 @@
1
- {"version":3,"file":"post-processing.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/post-processing.tsx"],"names":[],"mappings":"AA6CA,eAAO,MAAM,YAAY;;;CAGxB,CAAA;AAGD,eAAO,MAAM,WAAW;;;;;;;;;;;;;CAavB,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,GAAI,iCAG3B;IACD,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,6EAA6E;IAC7E,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB,SA+mBA,CAAA;AAED,eAAe,oBAAoB,CAAA"}
1
+ {"version":3,"file":"post-processing.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/post-processing.tsx"],"names":[],"mappings":"AA8CA,eAAO,MAAM,YAAY;;;CAGxB,CAAA;AAGD,eAAO,MAAM,WAAW;;;;;;;;;;;;;CAavB,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,GAAI,iCAG3B;IACD,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,6EAA6E;IAC7E,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB,SAmnBA,CAAA;AAED,eAAe,oBAAoB,CAAA"}
@@ -9,6 +9,7 @@ import { backdropGradient, deepSkyColor, horizonHazeColor } from '../../lib/back
9
9
  import { edgeColorFor, edgeOpacityScaleFor } from '../../lib/edge-style';
10
10
  import { PERF_OVERLAY_ENABLED } from '../../lib/gpu-perf';
11
11
  import { inkedEdges } from '../../lib/ink-edges';
12
+ import { refreshIsolation } from '../../lib/isolation';
12
13
  import { LayerPassIndex, LayerPassNode } from '../../lib/layer-pass';
13
14
  import { GRID_LAYER, OVERLAY_LAYER, SCENE_LAYER, ZONE_LAYER } from '../../lib/layers';
14
15
  import { mergedOutline } from '../../lib/merged-outline-node';
@@ -612,6 +613,7 @@ const PostProcessingPasses = ({ hoverStyles = DEFAULT_HOVER_STYLES, disablePostF
612
613
  inkColorUniform.current.value.set(edgeColorFor(bgHex));
613
614
  inkOpacityScaleUniform.current.value = edgeOpacityScaleFor(bgHex);
614
615
  const outliner = useViewer.getState().outliner;
616
+ const restoreAtmosphere = refreshIsolation(scene);
615
617
  sanitizeOutlineObjects(outliner.selectedObjects);
616
618
  sanitizeOutlineObjects(outliner.hoveredObjects);
617
619
  if (disablePostFx ||
@@ -644,6 +646,7 @@ const PostProcessingPasses = ({ hoverStyles = DEFAULT_HOVER_STYLES, disablePostF
644
646
  }
645
647
  finally {
646
648
  scene.backgroundNode = previousBackgroundNode;
649
+ restoreAtmosphere();
647
650
  }
648
651
  return;
649
652
  }
@@ -681,6 +684,9 @@ const PostProcessingPasses = ({ hoverStyles = DEFAULT_HOVER_STYLES, disablePostF
681
684
  console.error('[viewer/post-processing] Retries exhausted. Rendering without post FX for this session.');
682
685
  }
683
686
  }
687
+ finally {
688
+ restoreAtmosphere();
689
+ }
684
690
  }, 1);
685
691
  return null;
686
692
  };
@@ -1 +1 @@
1
- {"version":3,"file":"selection-manager.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/selection-manager.tsx"],"names":[],"mappings":"AAkTA,eAAO,MAAM,gBAAgB,mCA0G5B,CAAA"}
1
+ {"version":3,"file":"selection-manager.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/selection-manager.tsx"],"names":[],"mappings":"AAqSA,eAAO,MAAM,gBAAgB,mCA0G5B,CAAA"}
@@ -40,25 +40,15 @@ const pointInPolygonWithTolerance = (x, z, polygon) => {
40
40
  const expanded = expandPolygon(polygon, EDGE_TOLERANCE);
41
41
  return pointInPolygon(x, z, expanded);
42
42
  };
43
- // Check if a node belongs to the selected level (directly or via wall parent)
44
43
  const isNodeOnLevel = (node, levelId) => {
45
44
  const nodes = useScene.getState().nodes;
46
- // Direct child of level
47
- if (node.parentId === levelId)
48
- return true;
49
- // Wall-attached nodes (window/door/item): check if parent wall is on the level
50
- if ((node.type === 'item' || node.type === 'window' || node.type === 'door') && node.parentId) {
51
- const parentNode = nodes[node.parentId];
52
- if (parentNode?.type === 'wall' && parentNode.parentId === levelId) {
53
- return true;
54
- }
55
- // Ceiling/slab/roof-attached items: check if parent structure is on the level
56
- if ((parentNode?.type === 'ceiling' ||
57
- parentNode?.type === 'slab' ||
58
- parentNode?.type === 'roof') &&
59
- parentNode.parentId === levelId) {
45
+ const seen = new Set();
46
+ let parentId = node.parentId;
47
+ while (parentId && !seen.has(parentId)) {
48
+ if (parentId === levelId)
60
49
  return true;
61
- }
50
+ seen.add(parentId);
51
+ parentId = nodes[parentId]?.parentId ?? null;
62
52
  }
63
53
  return false;
64
54
  };
@@ -187,6 +177,7 @@ const getStrategy = () => {
187
177
  'roof-segment',
188
178
  'window',
189
179
  'door',
180
+ ...getSelectableKinds(),
190
181
  ],
191
182
  handleClick: (node, nativeEvent) => {
192
183
  let nodeToSelect = node;
@@ -224,6 +215,7 @@ const getStrategy = () => {
224
215
  'roof-segment',
225
216
  'window',
226
217
  'door',
218
+ ...getSelectableKinds(),
227
219
  ];
228
220
  if (!validTypes.includes(node.type))
229
221
  return false;
@@ -1,2 +1,16 @@
1
- export declare const ViewerCamera: () => import("react").JSX.Element;
1
+ import type { Layers } from 'three';
2
+ export declare function enableImmersiveXRViewLayers(cameraLayers: Layers, raycasterLayers: Layers): () => void;
3
+ export declare function viewerCameraClipping(immersiveXR: boolean): {
4
+ far: number;
5
+ near: number;
6
+ };
7
+ export declare function applyViewerCameraClipping(camera: {
8
+ far: number;
9
+ near: number;
10
+ updateProjectionMatrix(): void;
11
+ }, immersiveXR: boolean): void;
12
+ export declare function viewerUsesPerspectiveCamera(cameraMode: string, immersiveXR: boolean): boolean;
13
+ export declare const ViewerCamera: ({ immersiveXR }: {
14
+ immersiveXR?: boolean;
15
+ }) => import("react").JSX.Element;
2
16
  //# 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":"AAIA,eAAO,MAAM,YAAY,mCAUxB,CAAA"}
1
+ {"version":3,"file":"viewer-camera.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/viewer-camera.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,OAAO,CAAA;AAOnC,wBAAgB,2BAA2B,CAAC,YAAY,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,cAWxF;AAcD,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,OAAO;;;EAExD;AAED,wBAAgB,yBAAyB,CACvC,MAAM,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,sBAAsB,IAAI,IAAI,CAAA;CAAE,EACrE,WAAW,EAAE,OAAO,QAMrB;AAED,wBAAgB,2BAA2B,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,WAEnF;AAED,eAAO,MAAM,YAAY,GAAI,iBAAyB;IAAE,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE,gCAqB9E,CAAA"}
@@ -1,10 +1,48 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { OrthographicCamera, PerspectiveCamera } from '@react-three/drei';
3
+ import { useThree } from '@react-three/fiber';
4
+ import { useEffect } from 'react';
5
+ import { GRID_LAYER, OVERLAY_LAYER, ZONE_LAYER } from '../../lib/layers';
3
6
  import useViewer from '../../store/use-viewer';
4
7
  import { useSceneGroundReplacement } from './scene-ground-replacement';
5
- export const ViewerCamera = () => {
8
+ const IMMERSIVE_XR_VISIBLE_LAYERS = [OVERLAY_LAYER, ZONE_LAYER, GRID_LAYER];
9
+ export function enableImmersiveXRViewLayers(cameraLayers, raycasterLayers) {
10
+ const cameraMask = cameraLayers.mask;
11
+ const raycasterMask = raycasterLayers.mask;
12
+ for (const layer of IMMERSIVE_XR_VISIBLE_LAYERS) {
13
+ cameraLayers.enable(layer);
14
+ raycasterLayers.enable(layer);
15
+ }
16
+ return () => {
17
+ cameraLayers.mask = cameraMask;
18
+ raycasterLayers.mask = raycasterMask;
19
+ };
20
+ }
21
+ function ImmersiveXRViewLayers({ enabled }) {
22
+ const camera = useThree((state) => state.camera);
23
+ const raycaster = useThree((state) => state.raycaster);
24
+ useEffect(() => {
25
+ if (!enabled)
26
+ return;
27
+ return enableImmersiveXRViewLayers(camera.layers, raycaster.layers);
28
+ }, [camera, enabled, raycaster]);
29
+ return null;
30
+ }
31
+ export function viewerCameraClipping(immersiveXR) {
32
+ return immersiveXR ? { far: 10_000, near: 0.001 } : { far: 1000, near: 0.1 };
33
+ }
34
+ export function applyViewerCameraClipping(camera, immersiveXR) {
35
+ const clipping = viewerCameraClipping(immersiveXR);
36
+ camera.far = clipping.far;
37
+ camera.near = clipping.near;
38
+ camera.updateProjectionMatrix();
39
+ }
40
+ export function viewerUsesPerspectiveCamera(cameraMode, immersiveXR) {
41
+ return immersiveXR || cameraMode === 'perspective';
42
+ }
43
+ export const ViewerCamera = ({ immersiveXR = false }) => {
6
44
  const cameraMode = useViewer((state) => state.cameraMode);
7
- // Exterior ground can include a coarse ocean horizon beyond the local terrain.
8
- const far = useSceneGroundReplacement() ? 20_000 : 1000;
9
- return cameraMode === 'perspective' ? (_jsx(PerspectiveCamera, { far: far, fov: 50, makeDefault: true, near: 0.1, position: [10, 10, 10] })) : (_jsx(OrthographicCamera, { far: 1000, makeDefault: true, near: -1000, position: [10, 10, 10], zoom: 20 }));
45
+ const clipping = viewerCameraClipping(immersiveXR);
46
+ const far = useSceneGroundReplacement() ? 20_000 : clipping.far;
47
+ return (_jsxs(_Fragment, { children: [viewerUsesPerspectiveCamera(cameraMode, immersiveXR) ? (_jsx(PerspectiveCamera, { far: far, fov: 50, makeDefault: true, near: clipping.near, position: [10, 10, 10] })) : (_jsx(OrthographicCamera, { far: 1000, makeDefault: true, near: -1000, position: [10, 10, 10], zoom: 20 })), _jsx(ImmersiveXRViewLayers, { enabled: immersiveXR })] }));
10
48
  };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export type { SurfaceRole } from '@pascal-app/core';
2
2
  export { ErrorBoundary } from './components/error-boundary';
3
3
  export { NodeRenderer } from './components/renderers/node-renderer';
4
- export { default as Viewer, type ViewerHandle } from './components/viewer';
4
+ export { default as Viewer, type ViewerHandle, type ViewerImmersiveSession, } from './components/viewer';
5
5
  export { type BVHEcctrlApi, default as BVHEcctrl, type MovementInput, } from './components/viewer/bvh-ecctrl';
6
6
  export { buildGlbInteractiveItems, GlbInteractive, type GlbInteractiveItem, } from './components/viewer/glb-interactive';
7
7
  export { buildGlbReferenceNodes, buildGlbReplaceNodes, } from './components/viewer/glb-reference-nodes';
@@ -20,12 +20,12 @@ export { useNodeEvents } from './hooks/use-node-events';
20
20
  export { ASSETS_CDN_URL, resolveAssetUrl, resolveCdnUrl } from './lib/asset-url';
21
21
  export { backdropGradient, deepSkyColor, horizonHazeColor } from './lib/backdrop';
22
22
  export { applyWorldScaleBoxUVs } from './lib/box-uv';
23
- export { ADDITION, Brush, computeGeometryBoundsTree, csgEvaluator, csgGeometry, csgMaterials, INTERSECTION, prepareBrushForCSG, SUBTRACTION, } from './lib/csg-utils';
23
+ export { ADDITION, Brush, computeGeometryBoundsTree, csgEvaluator, csgGeometry, csgMaterials, Evaluator, ensureRenderableGeometryAttributes, INTERSECTION, prepareBrushForCSG, SUBTRACTION, } from './lib/csg-utils';
24
24
  export { disposeObject3DResources } from './lib/dispose-object3d';
25
25
  export type { EdgeMode } from './lib/edge-style';
26
26
  export { PERF_OVERLAY_ENABLED } from './lib/gpu-perf';
27
27
  export { computeHeroFraming, DEFAULT_FRAMING_EXCLUDED_TYPES, type HeroFraming, heroCameraPose, temporarilyHideNodeTypes, unionRegisteredNodeBounds, } from './lib/hero-pose';
28
- export { applyIsolation, clearIsolation, collectIsolationSubtree, isIsolationActive, } from './lib/isolation';
28
+ export { applyIsolation, clearIsolation, collectIsolationSubtree, isIsolationActive, refreshIsolation, } from './lib/isolation';
29
29
  export { configureKtx2Support, ensureKtx2Support } from './lib/ktx2-loader';
30
30
  export { LayerPassIndex } from './lib/layer-pass';
31
31
  export { BATCHED_LAYER, GRID_LAYER, OVERLAY_LAYER, SCENE_LAYER, SHADOW_ONLY_LAYER, setSurfaceRaycastLayers, ZONE_LAYER, } from './lib/layers';
@@ -63,11 +63,13 @@ export { ScanSystem } from './systems/scan/scan-system';
63
63
  export { generateSlabGeometry } from './systems/slab/slab-system';
64
64
  export { getStairBodyMaterials, getStairRailingMaterial, getStraightStairSegmentBodyMaterials, type StairBodyMaterials, } from './systems/stair/stair-materials';
65
65
  export { StairSystem } from './systems/stair/stair-system';
66
- export { buildOpeningCutoutGeometry, getOpeningCutoutBottomPadding, hasFlatOpeningCutoutBottom, } from './systems/wall/opening-cutout-geometry';
66
+ export { buildOpeningCutoutGeometry, buildOpeningCutoutShape, getOpeningCutoutBottomPadding, hasFlatOpeningCutoutBottom, } from './systems/wall/opening-cutout-geometry';
67
67
  export { getWallHideState, WallCutout } from './systems/wall/wall-cutout';
68
- export { getVisibleWallMaterials } from './systems/wall/wall-materials';
69
- export { drainRebuiltWalls, getPendingWallRebuildCount, isWallInitialBuildActive, WallSystem, } from './systems/wall/wall-system';
68
+ export { WallCutoutCache, type WallCutoutViewerState, type WallCutoutViewerStore, } from './systems/wall/wall-cutout-cache';
69
+ export { getMaterialsForWall, getVisibleWallMaterials, type WallMaterialOverride, type WallMaterials, type WallMaterialsResolver, } from './systems/wall/wall-materials';
70
+ export { drainRebuiltWalls, generateExtrudedWall, getPendingWallRebuildCount, isWallInitialBuildActive, runWallBuildFrame, type WallGeometryAdapter, type WallGeometryAdapterContext, WallSystem, } from './systems/wall/wall-system';
70
71
  export { poseWindowMovingParts, WindowAnimationSystem, } from './systems/window/window-animation-system';
71
72
  export { buildWindowPreviewMesh, WindowSystem } from './systems/window/window-system';
72
73
  export { ZoneSystem } from './systems/zone/zone-system';
74
+ export { useImmersiveXRPresentation } from './xr/presentation-context';
73
75
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}