@terraware/web-components 5.0.1 → 5.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 (36) hide show
  1. package/components/VirtualWalkthrough/SplatModel.js +2 -1
  2. package/components/VirtualWalkthrough/SplatRevealRain.d.ts +3 -1
  3. package/components/VirtualWalkthrough/SplatRevealRain.d.ts.map +1 -1
  4. package/components/VirtualWalkthrough/SplatRevealRain.js +15 -8
  5. package/components/VirtualWalkthrough/VirtualWalkthroughViewer.d.ts +12 -1
  6. package/components/VirtualWalkthrough/VirtualWalkthroughViewer.d.ts.map +1 -1
  7. package/components/VirtualWalkthrough/VirtualWalkthroughViewer.js +42 -5
  8. package/components/VirtualWalkthrough/useRestartOnVr.d.ts +16 -0
  9. package/components/VirtualWalkthrough/useRestartOnVr.d.ts.map +1 -0
  10. package/components/VirtualWalkthrough/useRestartOnVr.js +38 -0
  11. package/components/VirtualWalkthrough/xr-annotation-candidate-buffer.d.ts +32 -0
  12. package/components/VirtualWalkthrough/xr-annotation-candidate-buffer.d.ts.map +1 -0
  13. package/components/VirtualWalkthrough/xr-annotation-candidate-buffer.js +88 -0
  14. package/components/VirtualWalkthrough/xr-annotation-candidates.d.ts +8 -12
  15. package/components/VirtualWalkthrough/xr-annotation-candidates.d.ts.map +1 -1
  16. package/components/VirtualWalkthrough/xr-annotation-candidates.js +11 -32
  17. package/components/VirtualWalkthrough/xr-annotation-targeting.d.ts.map +1 -1
  18. package/components/VirtualWalkthrough/xr-annotation-targeting.js +9 -4
  19. package/components/VirtualWalkthrough/xr-exit-button-mask.d.ts +11 -0
  20. package/components/VirtualWalkthrough/xr-exit-button-mask.d.ts.map +1 -0
  21. package/components/VirtualWalkthrough/xr-exit-button-mask.js +41 -0
  22. package/components/VirtualWalkthrough/xr-exit-button.d.ts +3 -16
  23. package/components/VirtualWalkthrough/xr-exit-button.d.ts.map +1 -1
  24. package/components/VirtualWalkthrough/xr-exit-button.js +30 -93
  25. package/components/VirtualWalkthrough/xr-gaze-dwell.d.ts +14 -9
  26. package/components/VirtualWalkthrough/xr-gaze-dwell.d.ts.map +1 -1
  27. package/components/VirtualWalkthrough/xr-gaze-dwell.js +72 -90
  28. package/components/VirtualWalkthrough/xr-progress-pie-material.d.ts +24 -0
  29. package/components/VirtualWalkthrough/xr-progress-pie-material.d.ts.map +1 -0
  30. package/components/VirtualWalkthrough/xr-progress-pie-material.js +174 -0
  31. package/components/VirtualWalkthrough/xr-progress-pie.d.ts +7 -7
  32. package/components/VirtualWalkthrough/xr-progress-pie.d.ts.map +1 -1
  33. package/components/VirtualWalkthrough/xr-progress-pie.js +8 -29
  34. package/hooks/useXr.d.ts.map +1 -1
  35. package/hooks/useXr.js +6 -4
  36. package/package.json +1 -1
@@ -76,7 +76,8 @@ const SplatModel = ({
76
76
  aabbMax: cropAabbMax,
77
77
  edgeScaleFactor: cropEdgeScaleFactor
78
78
  })), /*#__PURE__*/jsx(SplatRevealRain, {
79
- enabled: revealRain
79
+ enabled: revealRain,
80
+ scaleFactor: scaleFactor
80
81
  })]
81
82
  });
82
83
  };
@@ -1,5 +1,7 @@
1
1
  interface SplatRevealRainProps {
2
2
  enabled?: boolean;
3
+ restartOnVr?: boolean;
4
+ scaleFactor?: number;
3
5
  center?: [number, number, number];
4
6
  distance?: number;
5
7
  speed?: number;
@@ -13,6 +15,6 @@ interface SplatRevealRainProps {
13
15
  hitDuration?: number;
14
16
  endRadius?: number;
15
17
  }
16
- declare const SplatRevealRain: ({ enabled, center, distance, speed, acceleration, flightTime, rainSize, rotation, fallTint, fallTintIntensity, hitTint, hitDuration, endRadius, }: SplatRevealRainProps) => import("react/jsx-runtime").JSX.Element;
18
+ declare const SplatRevealRain: ({ enabled, restartOnVr, scaleFactor, center, distance, speed, acceleration, flightTime, rainSize, rotation, fallTint, fallTintIntensity, hitTint, hitDuration, endRadius, }: SplatRevealRainProps) => import("react/jsx-runtime").JSX.Element;
17
19
  export default SplatRevealRain;
18
20
  //# sourceMappingURL=SplatRevealRain.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SplatRevealRain.d.ts","sourceRoot":"","sources":["../../../src/components/VirtualWalkthrough/SplatRevealRain.tsx"],"names":[],"mappings":"AAMA,UAAU,oBAAoB;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,QAAA,MAAM,eAAe,GAAI,mJActB,oBAAoB,4CAmBtB,CAAC;AAEF,eAAe,eAAe,CAAC"}
1
+ {"version":3,"file":"SplatRevealRain.d.ts","sourceRoot":"","sources":["../../../src/components/VirtualWalkthrough/SplatRevealRain.tsx"],"names":[],"mappings":"AAQA,UAAU,oBAAoB;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,QAAA,MAAM,eAAe,GAAI,6KAgBtB,oBAAoB,4CAyBtB,CAAC;AAEF,eAAe,eAAe,CAAC"}
@@ -1,14 +1,17 @@
1
- import 'react';
1
+ import { useRef } from 'react';
2
2
  import { Script } from '@playcanvas/react/components';
3
3
  import { Color, Vec3 } from 'playcanvas';
4
4
  import { GSplatRevealRain } from 'playcanvas/scripts/esm/gsplat/reveal-rain.mjs';
5
+ import useRestartOnVr from './useRestartOnVr.js';
5
6
  import { jsx } from 'react/jsx-runtime';
6
7
 
7
8
  const SplatRevealRain = ({
8
9
  enabled = true,
10
+ restartOnVr = true,
11
+ scaleFactor = 1,
9
12
  center = [0, 0, 0],
10
13
  distance = 3,
11
- speed = 10,
14
+ speed = 1,
12
15
  acceleration = 5,
13
16
  flightTime = 0.25,
14
17
  rainSize = 0.0,
@@ -19,21 +22,25 @@ const SplatRevealRain = ({
19
22
  hitDuration = 0,
20
23
  endRadius = 5
21
24
  }) => {
25
+ const scale = value => value * scaleFactor;
26
+ const scriptRef = useRef(null);
27
+ useRestartOnVr(scriptRef, enabled && restartOnVr);
22
28
  return /*#__PURE__*/jsx(Script, {
29
+ ref: scriptRef,
23
30
  script: GSplatRevealRain,
24
31
  enabled: enabled,
25
- center: new Vec3(...center),
26
- distance: distance,
27
- speed: speed,
28
- acceleration: acceleration,
32
+ center: new Vec3(...center).mulScalar(scaleFactor),
33
+ distance: scale(distance),
34
+ speed: scale(speed),
35
+ acceleration: scale(acceleration),
29
36
  flightTime: flightTime,
30
- rainSize: rainSize,
37
+ rainSize: scale(rainSize),
31
38
  rotation: rotation,
32
39
  fallTint: new Color(...fallTint),
33
40
  fallTintIntensity: fallTintIntensity,
34
41
  hitTint: new Color(...hitTint),
35
42
  hitDuration: hitDuration,
36
- endRadius: endRadius
43
+ endRadius: scale(endRadius)
37
44
  });
38
45
  };
39
46
 
@@ -37,6 +37,17 @@ export interface VirtualWalkthroughViewerProps {
37
37
  * `rotation`, `scaleFactor` and `revealRain` — take precedence over anything set here.
38
38
  */
39
39
  splatModelProps?: Partial<SplatModelProps>;
40
+ /**
41
+ * Requests a VR session when this goes from false to true, and when the viewer mounts with it
42
+ * already true. Never re-requests on its own, so exiting VR leaves the user out. Browsers only
43
+ * grant an immersive session inside a user gesture, so the caller must raise this from a click.
44
+ */
45
+ autoStartVr?: boolean;
46
+ /**
47
+ * Called whenever the viewer ends up out of XR: when a session ends, and when one was requested
48
+ * but couldn't be started, in which case the error says why.
49
+ */
50
+ onXrExit?: (error?: Error) => void;
40
51
  annotations: AnnotationProps[];
41
52
  onSaveAnnotations: (annotations: AnnotationProps[]) => void | Promise<void>;
42
53
  editable?: boolean;
@@ -45,6 +56,6 @@ export interface VirtualWalkthroughViewerProps {
45
56
  onToggleFullScreen?: () => void;
46
57
  maxImagesPerAnnotation?: number;
47
58
  }
48
- declare const VirtualWalkthroughViewer: ({ splatSrc, splatFormat, origin, cameraPosition, sceneBounds, groundPlane: groundPlaneProp, skyColor, groundColor, averageCameraHeight, scaleFactor, splatModelProps, annotations, onSaveAnnotations, editable, showFreeFly, isFullScreen, onToggleFullScreen, maxImagesPerAnnotation, }: VirtualWalkthroughViewerProps) => import("react/jsx-runtime").JSX.Element;
59
+ declare const VirtualWalkthroughViewer: ({ splatSrc, splatFormat, origin, cameraPosition, sceneBounds, groundPlane: groundPlaneProp, skyColor, groundColor, averageCameraHeight, scaleFactor, splatModelProps, autoStartVr, onXrExit, annotations, onSaveAnnotations, editable, showFreeFly, isFullScreen, onToggleFullScreen, maxImagesPerAnnotation, }: VirtualWalkthroughViewerProps) => import("react/jsx-runtime").JSX.Element;
49
60
  export default VirtualWalkthroughViewer;
50
61
  //# sourceMappingURL=VirtualWalkthroughViewer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"VirtualWalkthroughViewer.d.ts","sourceRoot":"","sources":["../../../src/components/VirtualWalkthrough/VirtualWalkthroughViewer.tsx"],"names":[],"mappings":"AAYA,OAAmB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAO3D,OAAmB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAS3D,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAmB5C;;;;GAIG;AACH,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,6CAA6C;IAC7C,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,8CAA8C;IAC9C,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,2FAA2F;IAC3F,WAAW,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7D,uEAAuE;IACvE,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6CAA6C;IAC7C,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;IAC3C,WAAW,EAAE,eAAe,EAAE,CAAC;IAC/B,iBAAiB,EAAE,CAAC,WAAW,EAAE,eAAe,EAAE,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5E,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;IAChC,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,QAAA,MAAM,wBAAwB,GAAI,0RAmB/B,6BAA6B,4CAgY/B,CAAC;AAEF,eAAe,wBAAwB,CAAC"}
1
+ {"version":3,"file":"VirtualWalkthroughViewer.d.ts","sourceRoot":"","sources":["../../../src/components/VirtualWalkthrough/VirtualWalkthroughViewer.tsx"],"names":[],"mappings":"AAYA,OAAmB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAO3D,OAAmB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAS3D,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAmB5C;;;;GAIG;AACH,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,6CAA6C;IAC7C,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,8CAA8C;IAC9C,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,2FAA2F;IAC3F,WAAW,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7D,uEAAuE;IACvE,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6CAA6C;IAC7C,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;IAC3C;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;OAGG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,KAAK,IAAI,CAAC;IACnC,WAAW,EAAE,eAAe,EAAE,CAAC;IAC/B,iBAAiB,EAAE,CAAC,WAAW,EAAE,eAAe,EAAE,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5E,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;IAChC,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,QAAA,MAAM,wBAAwB,GAAI,iTAqB/B,6BAA6B,4CAqa/B,CAAC;AAEF,eAAe,wBAAwB,CAAC"}
@@ -1,4 +1,4 @@
1
- import { useState, useMemo, useEffect, useCallback } from 'react';
1
+ import { useState, useCallback, useRef, useEffect, useMemo } from 'react';
2
2
  import { useTheme } from '@mui/material';
3
3
  import { Entity } from '@playcanvas/react';
4
4
  import { Camera, Script } from '@playcanvas/react/components';
@@ -61,6 +61,8 @@ const VirtualWalkthroughViewer = ({
61
61
  averageCameraHeight = 0,
62
62
  scaleFactor = 1,
63
63
  splatModelProps,
64
+ autoStartVr = false,
65
+ onXrExit,
64
66
  annotations,
65
67
  onSaveAnnotations,
66
68
  editable = false,
@@ -87,12 +89,46 @@ const VirtualWalkthroughViewer = ({
87
89
  const [viewingAnnotation, setViewingAnnotation] = useState(null);
88
90
  const [viewingAnnotationIndex, setViewingAnnotationIndex] = useState(-1);
89
91
  const [viewedScreenPos, setViewedScreenPos] = useState(null);
92
+ const reportXrError = useCallback(error => {
93
+ console.warn(error.message, error);
94
+ onXrExit?.(error);
95
+ }, [onXrExit]);
90
96
  const {
91
97
  isCurrentlyInXr,
92
98
  isCurrentlyInVr,
93
- isCurrentlyInAr
94
- } = useXr();
99
+ isCurrentlyInAr,
100
+ isXrAvailable,
101
+ startXr
102
+ } = useXr({
103
+ onError: reportXrError
104
+ });
95
105
  useXrRenderTuning();
106
+ const autoStartRequested = useRef(false);
107
+
108
+ // Edge-triggered so that ending a session doesn't pull the user straight back into one. The ref
109
+ // is written before the early returns, so lowering the prop re-arms the next rising edge.
110
+ useEffect(() => {
111
+ const isRisingEdge = autoStartVr && !autoStartRequested.current;
112
+ autoStartRequested.current = autoStartVr;
113
+ if (!isRisingEdge || isCurrentlyInXr) {
114
+ return;
115
+ }
116
+ if (!isXrAvailable('VR')) {
117
+ reportXrError(new Error('A VR session was requested, but this device reports no immersive VR support'));
118
+ return;
119
+ }
120
+ startXr('VR');
121
+ }, [autoStartVr, isCurrentlyInXr, isXrAvailable, startXr, reportXrError]);
122
+ const wasInXr = useRef(false);
123
+
124
+ // Edge-detected rather than reported whenever the viewer is out of XR, which would fire on mount
125
+ // and tell a caller a session had ended before one ever began.
126
+ useEffect(() => {
127
+ if (wasInXr.current && !isCurrentlyInXr) {
128
+ onXrExit?.();
129
+ }
130
+ wasInXr.current = isCurrentlyInXr;
131
+ }, [isCurrentlyInXr, onXrExit]);
96
132
  const sceneBoundsRadius = useMemo(() => {
97
133
  if (sceneBounds?.m !== undefined) {
98
134
  return sceneBounds.m;
@@ -287,7 +323,7 @@ const VirtualWalkthroughViewer = ({
287
323
  }), /*#__PURE__*/jsx(XrPointerRay, {}), isCurrentlyInVr && viewingAnnotation && /*#__PURE__*/jsx(VrAnnotationPanel, {
288
324
  annotation: viewingAnnotation,
289
325
  annotationIndex: viewingAnnotationIndex
290
- }, viewingAnnotationIndex), isCurrentlyInXr && /*#__PURE__*/jsx(XrGazeDwell, {
326
+ }, viewingAnnotationIndex), /*#__PURE__*/jsx(XrGazeDwell, {
291
327
  activeIndex: viewingAnnotationIndex
292
328
  }), /*#__PURE__*/jsx(Script, {
293
329
  script: XrStartPose,
@@ -370,7 +406,8 @@ const VirtualWalkthroughViewer = ({
370
406
  onToggleFullScreen: onToggleFullScreen,
371
407
  isFreeFly: isFreeFly,
372
408
  onToggleFreeFly: handleToggleFreeFly,
373
- showFreeFly: showFreeFly
409
+ showFreeFly: showFreeFly,
410
+ onError: reportXrError
374
411
  }), /*#__PURE__*/jsx(AnnotationPanel, {
375
412
  annotation: viewingAnnotation,
376
413
  hotspotPosition: viewedScreenPos,
@@ -0,0 +1,16 @@
1
+ import { RefObject } from 'react';
2
+ import { Script } from 'playcanvas';
3
+ /**
4
+ * Replays a one-shot script effect at the start of every VR session.
5
+ *
6
+ * `GSplatShaderEffect` zeroes its timeline on the script's `enable` event and switches itself off
7
+ * once the animation has played out, so re-enabling a finished effect runs it again. The `enabled`
8
+ * setter only fires the event on a change of state, which is why an effect still mid-play is taken
9
+ * back through disabled first.
10
+ *
11
+ * @param scriptRef - The script instance to replay, as handed back by `Script`'s ref.
12
+ * @param enabled - Whether the effect is in use at all. No session is watched while false.
13
+ */
14
+ export declare const useRestartOnVr: (scriptRef: RefObject<Script | null>, enabled: boolean) => void;
15
+ export default useRestartOnVr;
16
+ //# sourceMappingURL=useRestartOnVr.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useRestartOnVr.d.ts","sourceRoot":"","sources":["../../../src/components/VirtualWalkthrough/useRestartOnVr.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAa,MAAM,OAAO,CAAC;AAG7C,OAAO,EAAE,MAAM,EAAa,MAAM,YAAY,CAAC;AAE/C;;;;;;;;;;GAUG;AACH,eAAO,MAAM,cAAc,GAAI,WAAW,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,SAAS,OAAO,SAwBnF,CAAC;AAEF,eAAe,cAAc,CAAC"}
@@ -0,0 +1,38 @@
1
+ import { useEffect } from 'react';
2
+ import { useApp } from '@playcanvas/react/hooks';
3
+ import { XRTYPE_VR } from 'playcanvas';
4
+
5
+ /**
6
+ * Replays a one-shot script effect at the start of every VR session.
7
+ *
8
+ * `GSplatShaderEffect` zeroes its timeline on the script's `enable` event and switches itself off
9
+ * once the animation has played out, so re-enabling a finished effect runs it again. The `enabled`
10
+ * setter only fires the event on a change of state, which is why an effect still mid-play is taken
11
+ * back through disabled first.
12
+ *
13
+ * @param scriptRef - The script instance to replay, as handed back by `Script`'s ref.
14
+ * @param enabled - Whether the effect is in use at all. No session is watched while false.
15
+ */
16
+ const useRestartOnVr = (scriptRef, enabled) => {
17
+ const app = useApp();
18
+ useEffect(() => {
19
+ const xr = app?.xr;
20
+ if (!xr || !enabled) {
21
+ return;
22
+ }
23
+ const restart = () => {
24
+ const script = scriptRef.current;
25
+ if (!script || xr.type !== XRTYPE_VR) {
26
+ return;
27
+ }
28
+ script.enabled = false;
29
+ script.enabled = true;
30
+ };
31
+ xr.on('start', restart);
32
+ return () => {
33
+ xr.off('start', restart);
34
+ };
35
+ }, [app, enabled, scriptRef]);
36
+ };
37
+
38
+ export { useRestartOnVr as default, useRestartOnVr };
@@ -0,0 +1,32 @@
1
+ import { Vec3 } from 'playcanvas';
2
+ /** Local half-extent of the unit-plane hotspot quad. */
3
+ export declare const HOTSPOT_HALF_EXTENT = 0.5;
4
+ export interface AnnotationCandidate {
5
+ entity: any;
6
+ script: any;
7
+ position: Vec3;
8
+ radius: number;
9
+ }
10
+ /** Pulls the stock annotation script off a hotspot entity, or undefined if it carries none. */
11
+ export type AnnotationScriptLookup = (entity: any) => any;
12
+ /**
13
+ * Collects world-space hit candidates for the openable annotation hotspots into a buffer it owns and
14
+ * reuses, so a caller running every frame allocates nothing. The returned array and the candidate
15
+ * objects inside it are overwritten by the next `collect`, which is why each caller holds its own
16
+ * buffer rather than sharing one.
17
+ *
18
+ * Positions and radii are re-read on every call, so hotspots that move or resize stay targetable.
19
+ * That read is cheap; it is the allocation around it that a per-frame caller cannot afford.
20
+ */
21
+ export declare class AnnotationCandidateBuffer {
22
+ private readonly _getScript;
23
+ private readonly _candidates;
24
+ private _root;
25
+ constructor(_getScript: AnnotationScriptLookup);
26
+ /**
27
+ * Hit candidates for every openable hotspot except `excludeName`, with hit spheres derived from
28
+ * each hotspot's rendered world size and padded by `radiusPad` for easier aiming.
29
+ */
30
+ collect(app: any, radiusPad: number, excludeName?: string): AnnotationCandidate[];
31
+ }
32
+ //# sourceMappingURL=xr-annotation-candidate-buffer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"xr-annotation-candidate-buffer.d.ts","sourceRoot":"","sources":["../../../src/components/VirtualWalkthrough/xr-annotation-candidate-buffer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAElC,wDAAwD;AACxD,eAAO,MAAM,mBAAmB,MAAM,CAAC;AAEvC,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,GAAG,CAAC;IACZ,MAAM,EAAE,GAAG,CAAC;IACZ,QAAQ,EAAE,IAAI,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,+FAA+F;AAC/F,MAAM,MAAM,sBAAsB,GAAG,CAAC,MAAM,EAAE,GAAG,KAAK,GAAG,CAAC;AAmB1D;;;;;;;;GAQG;AACH,qBAAa,yBAAyB;IAIxB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAHvC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA6B;IACzD,OAAO,CAAC,KAAK,CAAa;gBAEG,UAAU,EAAE,sBAAsB;IAE/D;;;OAGG;IACH,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,mBAAmB,EAAE;CA6ClF"}
@@ -0,0 +1,88 @@
1
+ import { Vec3 } from 'playcanvas';
2
+
3
+ /** Local half-extent of the unit-plane hotspot quad. */
4
+ const HOTSPOT_HALF_EXTENT = 0.5;
5
+
6
+ /** Pulls the stock annotation script off a hotspot entity, or undefined if it carries none. */
7
+
8
+ const scratchScale = new Vec3();
9
+
10
+ /**
11
+ * Whether `node` still hangs beneath `sceneRoot`. An entity that has been removed from the scene
12
+ * keeps its own `children` array - a destroyed one keeps it as an empty array - so only a walk back
13
+ * up the parent chain tells a live root apart from a detached one.
14
+ */
15
+ const isInScene = (node, sceneRoot) => {
16
+ for (let current = node; current; current = current.parent) {
17
+ if (current === sceneRoot) {
18
+ return true;
19
+ }
20
+ }
21
+ return false;
22
+ };
23
+
24
+ /**
25
+ * Collects world-space hit candidates for the openable annotation hotspots into a buffer it owns and
26
+ * reuses, so a caller running every frame allocates nothing. The returned array and the candidate
27
+ * objects inside it are overwritten by the next `collect`, which is why each caller holds its own
28
+ * buffer rather than sharing one.
29
+ *
30
+ * Positions and radii are re-read on every call, so hotspots that move or resize stay targetable.
31
+ * That read is cheap; it is the allocation around it that a per-frame caller cannot afford.
32
+ */
33
+ class AnnotationCandidateBuffer {
34
+ _candidates = [];
35
+ _root = null;
36
+ constructor(_getScript) {
37
+ this._getScript = _getScript;
38
+ }
39
+
40
+ /**
41
+ * Hit candidates for every openable hotspot except `excludeName`, with hit spheres derived from
42
+ * each hotspot's rendered world size and padded by `radiusPad` for easier aiming.
43
+ */
44
+ collect(app, radiusPad, excludeName) {
45
+ // The root is looked up by a walk of the whole scene graph, so it is held onto between frames.
46
+ // It is re-resolved whenever it leaves the scene: annotations mount after the scene does, and
47
+ // the root is torn down and built afresh every time the annotation list empties and refills.
48
+ if (!isInScene(this._root, app.root)) {
49
+ this._root = app.root.findByName('annotations-root');
50
+ }
51
+ const children = this._root?.children;
52
+ if (!children) {
53
+ this._candidates.length = 0;
54
+ return this._candidates;
55
+ }
56
+ let count = 0;
57
+ for (const entity of children) {
58
+ if (excludeName !== undefined && entity.name === excludeName) {
59
+ continue;
60
+ }
61
+ const script = this._getScript(entity);
62
+ if (!script || script.enabled === false || typeof script.onVrOpenCallback !== 'function') {
63
+ continue;
64
+ }
65
+ entity.getWorldTransform().getScale(scratchScale);
66
+ const radius = HOTSPOT_HALF_EXTENT * scratchScale.x * radiusPad;
67
+ const existing = this._candidates[count];
68
+ if (existing) {
69
+ existing.entity = entity;
70
+ existing.script = script;
71
+ existing.position = entity.getPosition();
72
+ existing.radius = radius;
73
+ } else {
74
+ this._candidates.push({
75
+ entity,
76
+ script,
77
+ position: entity.getPosition(),
78
+ radius
79
+ });
80
+ }
81
+ count++;
82
+ }
83
+ this._candidates.length = count;
84
+ return this._candidates;
85
+ }
86
+ }
87
+
88
+ export { AnnotationCandidateBuffer, HOTSPOT_HALF_EXTENT };
@@ -1,18 +1,14 @@
1
- import { Vec3 } from 'playcanvas';
2
- /** Local half-extent of the unit-plane hotspot quad. */
3
- export declare const HOTSPOT_HALF_EXTENT = 0.5;
1
+ import { AnnotationCandidate, AnnotationCandidateBuffer, HOTSPOT_HALF_EXTENT } from './xr-annotation-candidate-buffer';
2
+ export { HOTSPOT_HALF_EXTENT };
3
+ export type { AnnotationCandidate };
4
4
  /** Multiplier on the hotspot's world radius to make controller targeting forgiving. */
5
5
  export declare const HIT_RADIUS_PAD = 2.5;
6
- export interface AnnotationCandidate {
7
- entity: any;
8
- script: any;
9
- position: Vec3;
10
- radius: number;
11
- }
6
+ /** A buffer wired to the stock annotation script. Callers that collect every frame hold one of
7
+ * these; its results are overwritten on the next collect, so one buffer cannot be shared. */
8
+ export declare const createAnnotationCandidateBuffer: () => AnnotationCandidateBuffer;
12
9
  /**
13
- * World-space hit candidates for every openable annotation hotspot: its entity, its stock
14
- * annotation script (which carries `onVrOpenCallback`), its world position, and a hit-sphere
15
- * radius derived from the hotspot's rendered world size, padded by `radiusPad` for easier aiming.
10
+ * One-shot collection for callers that run on an input event rather than every frame, and so have no
11
+ * reason to hold a buffer of their own.
16
12
  */
17
13
  export declare const collectAnnotationHitCandidates: (app: any, radiusPad: number) => AnnotationCandidate[];
18
14
  //# sourceMappingURL=xr-annotation-candidates.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"xr-annotation-candidates.d.ts","sourceRoot":"","sources":["../../../src/components/VirtualWalkthrough/xr-annotation-candidates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAGlC,wDAAwD;AACxD,eAAO,MAAM,mBAAmB,MAAM,CAAC;AAEvC,uFAAuF;AACvF,eAAO,MAAM,cAAc,MAAM,CAAC;AAElC,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,GAAG,CAAC;IACZ,MAAM,EAAE,GAAG,CAAC;IACZ,QAAQ,EAAE,IAAI,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAID;;;;GAIG;AACH,eAAO,MAAM,8BAA8B,GAAI,KAAK,GAAG,EAAE,WAAW,MAAM,KAAG,mBAAmB,EAmB/F,CAAC"}
1
+ {"version":3,"file":"xr-annotation-candidates.d.ts","sourceRoot":"","sources":["../../../src/components/VirtualWalkthrough/xr-annotation-candidates.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAEvH,OAAO,EAAE,mBAAmB,EAAE,CAAC;AAC/B,YAAY,EAAE,mBAAmB,EAAE,CAAC;AAEpC,uFAAuF;AACvF,eAAO,MAAM,cAAc,MAAM,CAAC;AAIlC;6FAC6F;AAC7F,eAAO,MAAM,+BAA+B,QAAO,yBACA,CAAC;AAEpD;;;GAGG;AACH,eAAO,MAAM,8BAA8B,GAAI,KAAK,GAAG,EAAE,WAAW,MAAM,KAAG,mBAAmB,EACrC,CAAC"}
@@ -1,40 +1,19 @@
1
- import { Vec3 } from 'playcanvas';
2
1
  import { Annotation } from 'playcanvas/scripts/esm/annotations.mjs';
3
-
4
- /** Local half-extent of the unit-plane hotspot quad. */
5
- const HOTSPOT_HALF_EXTENT = 0.5;
2
+ import { AnnotationCandidateBuffer } from './xr-annotation-candidate-buffer.js';
3
+ export { HOTSPOT_HALF_EXTENT } from './xr-annotation-candidate-buffer.js';
6
4
 
7
5
  /** Multiplier on the hotspot's world radius to make controller targeting forgiving. */
8
6
  const HIT_RADIUS_PAD = 2.5;
9
- const scratchScale = new Vec3();
7
+ const annotationScriptOf = entity => entity.script?.get(Annotation.scriptName);
8
+
9
+ /** A buffer wired to the stock annotation script. Callers that collect every frame hold one of
10
+ * these; its results are overwritten on the next collect, so one buffer cannot be shared. */
11
+ const createAnnotationCandidateBuffer = () => new AnnotationCandidateBuffer(annotationScriptOf);
10
12
 
11
13
  /**
12
- * World-space hit candidates for every openable annotation hotspot: its entity, its stock
13
- * annotation script (which carries `onVrOpenCallback`), its world position, and a hit-sphere
14
- * radius derived from the hotspot's rendered world size, padded by `radiusPad` for easier aiming.
14
+ * One-shot collection for callers that run on an input event rather than every frame, and so have no
15
+ * reason to hold a buffer of their own.
15
16
  */
16
- const collectAnnotationHitCandidates = (app, radiusPad) => {
17
- const root = app.root.findByName('annotations-root');
18
- if (!root) {
19
- return [];
20
- }
21
- return root.children.map(entity => ({
22
- entity,
23
- script: entity.script?.get(Annotation.scriptName)
24
- })).filter(({
25
- script
26
- }) => script && script.enabled !== false && typeof script.onVrOpenCallback === 'function').map(({
27
- entity,
28
- script
29
- }) => {
30
- entity.getWorldTransform().getScale(scratchScale);
31
- return {
32
- entity,
33
- script,
34
- position: entity.getPosition(),
35
- radius: HOTSPOT_HALF_EXTENT * scratchScale.x * radiusPad
36
- };
37
- });
38
- };
17
+ const collectAnnotationHitCandidates = (app, radiusPad) => createAnnotationCandidateBuffer().collect(app, radiusPad);
39
18
 
40
- export { HIT_RADIUS_PAD, HOTSPOT_HALF_EXTENT, collectAnnotationHitCandidates };
19
+ export { HIT_RADIUS_PAD, collectAnnotationHitCandidates, createAnnotationCandidateBuffer };
@@ -1 +1 @@
1
- {"version":3,"file":"xr-annotation-targeting.d.ts","sourceRoot":"","sources":["../../../src/components/VirtualWalkthrough/xr-annotation-targeting.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAElC,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,IAAI,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAsBD;;GAEG;AACH,eAAO,MAAM,oBAAoB,GAC/B,QAAQ,IAAI,EACZ,WAAW,IAAI,EACf,YAAY,sBAAsB,EAAE,KACnC,MAAM,GAAG,IAcX,CAAC"}
1
+ {"version":3,"file":"xr-annotation-targeting.d.ts","sourceRoot":"","sources":["../../../src/components/VirtualWalkthrough/xr-annotation-targeting.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAElC,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,IAAI,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AA0BD;;GAEG;AACH,eAAO,MAAM,oBAAoB,GAC/B,QAAQ,IAAI,EACZ,WAAW,IAAI,EACf,YAAY,sBAAsB,EAAE,KACnC,MAAM,GAAG,IAeX,CAAC"}
@@ -1,11 +1,15 @@
1
1
  import { Vec3 } from 'playcanvas';
2
2
 
3
+ // Reused across calls: this runs per candidate per frame, where fresh vectors would be steady GC churn.
4
+ const scratchDir = new Vec3();
5
+ const scratchToCenter = new Vec3();
6
+
3
7
  /**
4
8
  * Distance along a (normalized) ray to where it first enters the sphere, or null if it never does.
5
9
  * A ray starting inside the sphere returns 0.
6
10
  */
7
11
  const raySphereEntryDistance = (origin, dir, center, radius) => {
8
- const m = new Vec3().sub2(origin, center);
12
+ const m = scratchToCenter.sub2(origin, center);
9
13
  const b = m.dot(dir);
10
14
  const c = m.dot(m) - radius * radius;
11
15
  if (c > 0 && b > 0) {
@@ -23,16 +27,17 @@ const raySphereEntryDistance = (origin, dir, center, radius) => {
23
27
  * Index of the closest candidate sphere the ray enters, or null if it hits none.
24
28
  */
25
29
  const nearestAnnotationHit = (origin, direction, candidates) => {
26
- const dir = direction.clone().normalize();
30
+ const dir = scratchDir.copy(direction).normalize();
27
31
  let bestIndex = null;
28
32
  let bestDistance = Infinity;
29
- candidates.forEach((candidate, index) => {
33
+ for (let index = 0; index < candidates.length; index++) {
34
+ const candidate = candidates[index];
30
35
  const distance = raySphereEntryDistance(origin, dir, candidate.position, candidate.radius);
31
36
  if (distance !== null && distance < bestDistance) {
32
37
  bestDistance = distance;
33
38
  bestIndex = index;
34
39
  }
35
- });
40
+ }
36
41
  return bestIndex;
37
42
  };
38
43
 
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Bakes the exit button's static artwork into a two-channel mask: red covers the backing disc, green
3
+ * the X glyph. The shader composites the progress sweep between the two, which is what keeps the
4
+ * glyph legible over the fill.
5
+ *
6
+ * The channels have to stay independent, so the glyph is drawn additively rather than over the disc,
7
+ * and an opaque base goes down first. Uniform full alpha means the mask survives the texture upload
8
+ * whether or not alpha ends up premultiplied, and antialiased edges keep their coverage.
9
+ */
10
+ export declare const drawExitButtonMask: (ctx: CanvasRenderingContext2D, size: number) => void;
11
+ //# sourceMappingURL=xr-exit-button-mask.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"xr-exit-button-mask.d.ts","sourceRoot":"","sources":["../../../src/components/VirtualWalkthrough/xr-exit-button-mask.ts"],"names":[],"mappings":"AAOA;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,GAAI,KAAK,wBAAwB,EAAE,MAAM,MAAM,SA4B7E,CAAC"}
@@ -0,0 +1,41 @@
1
+ /** Backing disc radius as a fraction of the button's half-size. Matches the shader's pie radius. */
2
+ const DISC_RADIUS = 0.92;
3
+
4
+ /** Glyph arm reach and stroke width, as fractions of the drawn size. */
5
+ const GLYPH_ARM = 0.24;
6
+ const GLYPH_WIDTH = 0.09;
7
+
8
+ /**
9
+ * Bakes the exit button's static artwork into a two-channel mask: red covers the backing disc, green
10
+ * the X glyph. The shader composites the progress sweep between the two, which is what keeps the
11
+ * glyph legible over the fill.
12
+ *
13
+ * The channels have to stay independent, so the glyph is drawn additively rather than over the disc,
14
+ * and an opaque base goes down first. Uniform full alpha means the mask survives the texture upload
15
+ * whether or not alpha ends up premultiplied, and antialiased edges keep their coverage.
16
+ */
17
+ const drawExitButtonMask = (ctx, size) => {
18
+ const c = size / 2;
19
+ ctx.save();
20
+ ctx.globalCompositeOperation = 'source-over';
21
+ ctx.fillStyle = '#000000';
22
+ ctx.fillRect(0, 0, size, size);
23
+ ctx.globalCompositeOperation = 'lighter';
24
+ ctx.fillStyle = '#ff0000';
25
+ ctx.beginPath();
26
+ ctx.arc(c, c, c * DISC_RADIUS, 0, Math.PI * 2);
27
+ ctx.fill();
28
+ const arm = size * GLYPH_ARM;
29
+ ctx.strokeStyle = '#00ff00';
30
+ ctx.lineWidth = size * GLYPH_WIDTH;
31
+ ctx.lineCap = 'round';
32
+ ctx.beginPath();
33
+ ctx.moveTo(c - arm, c - arm);
34
+ ctx.lineTo(c + arm, c + arm);
35
+ ctx.moveTo(c + arm, c - arm);
36
+ ctx.lineTo(c - arm, c + arm);
37
+ ctx.stroke();
38
+ ctx.restore();
39
+ };
40
+
41
+ export { drawExitButtonMask };
@@ -20,9 +20,6 @@ export declare class XrExitButton extends Script {
20
20
  private _headRotation;
21
21
  private _worldOffset;
22
22
  private _faceButtons;
23
- private _canvas?;
24
- private _context?;
25
- private _drawnProgress;
26
23
  private _hold;
27
24
  private _arming;
28
25
  private _isVrActive;
@@ -31,20 +28,10 @@ export declare class XrExitButton extends Script {
31
28
  private _onSelect;
32
29
  /** True when the ray points at the button's hit sphere. False while the button entity is disabled. */
33
30
  rayHitsButton(origin: Vec3, direction: Vec3): boolean;
34
- private _createCanvas;
35
- private _createTexture;
36
- /**
37
- * Repaints the button: dark disc, then the hold progress wedge, then the X arms on top so the
38
- * glyph stays legible over the fill. The pie is skipped entirely at zero progress so the idle
39
- * button doesn't wear the pie's faint track. Returns whether it painted, so callers can tell a
40
- * missing context from a successful repaint.
41
- */
42
- private _drawButton;
43
- /** Repaints only when the drawn wedge would visibly move. Only records the paint on success, so a
44
- * missing context doesn't fool the dedupe cache into thinking a repaint already happened. */
45
- private _setProgress;
31
+ /** The button's static artwork, painted once. Only the sweep changes per frame, and that lives in
32
+ * the shader. */
33
+ private _createMaskTexture;
46
34
  private _resetProgress;
47
- private _createMesh;
48
35
  initialize(): void;
49
36
  update(dt: number): void;
50
37
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"xr-exit-button.d.ts","sourceRoot":"","sources":["../../../src/components/VirtualWalkthrough/xr-exit-button.ts"],"names":[],"mappings":"AAAA,OAAO,EAUL,MAAM,EAGN,IAAI,EAGL,MAAM,YAAY,CAAC;AAOpB;;;GAGG;AACH,eAAO,MAAM,kBAAkB,GAAI,QAAQ,IAAI,EAAE,WAAW,IAAI,EAAE,QAAQ,IAAI,EAAE,QAAQ,MAAM,KAAG,OAUhG,CAAC;AAOF,qBAAa,YAAa,SAAQ,MAAM;IACtC,MAAM,CAAC,UAAU,SAAkB;IAEnC,yGAAyG;IACzG,MAAM,OAA8B;IAEpC,oFAAoF;IACpF,QAAQ,SAAQ;IAEhB,sGAAsG;IACtG,SAAS,SAAQ;IAEjB,OAAO,CAAC,SAAS,CAAC,CAAmB;IACrC,OAAO,CAAC,QAAQ,CAAC,CAAU;IAC3B,OAAO,CAAC,KAAK,CAAC,CAAO;IACrB,OAAO,CAAC,QAAQ,CAAS;IAEzB,OAAO,CAAC,aAAa,CAAc;IACnC,OAAO,CAAC,aAAa,CAAc;IACnC,OAAO,CAAC,YAAY,CAAc;IAClC,OAAO,CAAC,YAAY,CAAgC;IAEpD,OAAO,CAAC,OAAO,CAAC,CAAoB;IACpC,OAAO,CAAC,QAAQ,CAAC,CAA2B;IAC5C,OAAO,CAAC,cAAc,CAAM;IAC5B,OAAO,CAAC,KAAK,CAAiC;IAC9C,OAAO,CAAC,OAAO,CAA2B;IAE1C,OAAO,CAAC,WAAW,CAAyE;IAE5F,OAAO,CAAC,UAAU,CAGhB;IAEF,OAAO,CAAC,QAAQ,CASd;IAEF,OAAO,CAAC,SAAS,CAOf;IAEF,sGAAsG;IACtG,aAAa,CAAC,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,GAAG,OAAO;IAQrD,OAAO,CAAC,aAAa;IAQrB,OAAO,CAAC,cAAc;IAgBtB;;;;;OAKG;IACH,OAAO,CAAC,WAAW;IAiCnB;iGAC6F;IAC7F,OAAO,CAAC,YAAY;IAUpB,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,WAAW;IAYnB,UAAU;IAgCV,MAAM,CAAC,EAAE,EAAE,MAAM;IAoDjB;;;;;OAKG;IACH,OAAO,CAAC,UAAU;IAuBlB,OAAO;CAgBR"}
1
+ {"version":3,"file":"xr-exit-button.d.ts","sourceRoot":"","sources":["../../../src/components/VirtualWalkthrough/xr-exit-button.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,MAAM,EAGN,IAAI,EAGL,MAAM,YAAY,CAAC;AASpB;;;GAGG;AACH,eAAO,MAAM,kBAAkB,GAAI,QAAQ,IAAI,EAAE,WAAW,IAAI,EAAE,QAAQ,IAAI,EAAE,QAAQ,MAAM,KAAG,OAUhG,CAAC;AAUF,qBAAa,YAAa,SAAQ,MAAM;IACtC,MAAM,CAAC,UAAU,SAAkB;IAEnC,yGAAyG;IACzG,MAAM,OAA8B;IAEpC,oFAAoF;IACpF,QAAQ,SAAQ;IAEhB,sGAAsG;IACtG,SAAS,SAAQ;IAEjB,OAAO,CAAC,SAAS,CAAC,CAAiB;IACnC,OAAO,CAAC,QAAQ,CAAC,CAAU;IAC3B,OAAO,CAAC,KAAK,CAAC,CAAO;IACrB,OAAO,CAAC,QAAQ,CAAS;IAEzB,OAAO,CAAC,aAAa,CAAc;IACnC,OAAO,CAAC,aAAa,CAAc;IACnC,OAAO,CAAC,YAAY,CAAc;IAClC,OAAO,CAAC,YAAY,CAAgC;IAEpD,OAAO,CAAC,KAAK,CAAiC;IAC9C,OAAO,CAAC,OAAO,CAA2B;IAE1C,OAAO,CAAC,WAAW,CAAyE;IAE5F,OAAO,CAAC,UAAU,CAGhB;IAEF,OAAO,CAAC,QAAQ,CAMd;IAEF,OAAO,CAAC,SAAS,CAOf;IAEF,sGAAsG;IACtG,aAAa,CAAC,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,GAAG,OAAO;IAQrD;qBACiB;IACjB,OAAO,CAAC,kBAAkB;IAyB1B,OAAO,CAAC,cAAc;IAKtB,UAAU;IAwBV,MAAM,CAAC,EAAE,EAAE,MAAM;IAiDjB;;;;;OAKG;IACH,OAAO,CAAC,UAAU;IAuBlB,OAAO;CAcR"}