@ericchen1990/pano-view 3.9.0 → 3.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +99 -55
- package/README.zh-CN.md +76 -42
- package/dist/index.cjs +1476 -768
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +75 -4
- package/dist/index.d.ts +75 -4
- package/dist/index.mjs +1241 -528
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +8 -0
- package/dist/ui.cjs.map +1 -1
- package/dist/ui.d.mts +1 -1
- package/dist/ui.d.ts +1 -1
- package/dist/ui.mjs.map +1 -1
- package/docs/dialogs.md +51 -41
- package/docs/dialogs.zh-CN.md +51 -41
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1284,8 +1284,8 @@ var require_howler = __commonJS({
|
|
|
1284
1284
|
break;
|
|
1285
1285
|
}
|
|
1286
1286
|
}
|
|
1287
|
-
if (
|
|
1288
|
-
delete
|
|
1287
|
+
if (cache2 && remCache) {
|
|
1288
|
+
delete cache2[self._src];
|
|
1289
1289
|
}
|
|
1290
1290
|
Howler4.noAudio = false;
|
|
1291
1291
|
self._state = "unloaded";
|
|
@@ -1540,7 +1540,7 @@ var require_howler = __commonJS({
|
|
|
1540
1540
|
_refreshBuffer: function(sound) {
|
|
1541
1541
|
var self = this;
|
|
1542
1542
|
sound._node.bufferSource = Howler4.ctx.createBufferSource();
|
|
1543
|
-
sound._node.bufferSource.buffer =
|
|
1543
|
+
sound._node.bufferSource.buffer = cache2[self._src];
|
|
1544
1544
|
if (sound._panner) {
|
|
1545
1545
|
sound._node.bufferSource.connect(sound._panner);
|
|
1546
1546
|
} else {
|
|
@@ -1702,11 +1702,11 @@ var require_howler = __commonJS({
|
|
|
1702
1702
|
self._node.removeEventListener("ended", self._endFn, false);
|
|
1703
1703
|
}
|
|
1704
1704
|
};
|
|
1705
|
-
var
|
|
1705
|
+
var cache2 = {};
|
|
1706
1706
|
var loadBuffer = function(self) {
|
|
1707
1707
|
var url = self._src;
|
|
1708
|
-
if (
|
|
1709
|
-
self._duration =
|
|
1708
|
+
if (cache2[url]) {
|
|
1709
|
+
self._duration = cache2[url].duration;
|
|
1710
1710
|
loadSound(self);
|
|
1711
1711
|
return;
|
|
1712
1712
|
}
|
|
@@ -1740,7 +1740,7 @@ var require_howler = __commonJS({
|
|
|
1740
1740
|
self._html5 = true;
|
|
1741
1741
|
self._webAudio = false;
|
|
1742
1742
|
self._sounds = [];
|
|
1743
|
-
delete
|
|
1743
|
+
delete cache2[url];
|
|
1744
1744
|
self.load();
|
|
1745
1745
|
}
|
|
1746
1746
|
};
|
|
@@ -1760,7 +1760,7 @@ var require_howler = __commonJS({
|
|
|
1760
1760
|
};
|
|
1761
1761
|
var success = function(buffer) {
|
|
1762
1762
|
if (buffer && self._sounds.length > 0) {
|
|
1763
|
-
|
|
1763
|
+
cache2[self._src] = buffer;
|
|
1764
1764
|
loadSound(self, buffer);
|
|
1765
1765
|
} else {
|
|
1766
1766
|
error();
|
|
@@ -2308,12 +2308,12 @@ import { Canvas } from "@react-three/fiber";
|
|
|
2308
2308
|
import { createXRStore, XR } from "@react-three/xr";
|
|
2309
2309
|
import {
|
|
2310
2310
|
forwardRef as forwardRef2,
|
|
2311
|
-
useCallback as
|
|
2311
|
+
useCallback as useCallback7,
|
|
2312
2312
|
useContext as useContext16,
|
|
2313
2313
|
useEffect as useEffect14,
|
|
2314
2314
|
useImperativeHandle as useImperativeHandle2,
|
|
2315
2315
|
useMemo as useMemo8,
|
|
2316
|
-
useRef as
|
|
2316
|
+
useRef as useRef14,
|
|
2317
2317
|
useState as useState7,
|
|
2318
2318
|
useSyncExternalStore as useSyncExternalStore8
|
|
2319
2319
|
} from "react";
|
|
@@ -3875,6 +3875,18 @@ import { useSyncExternalStore } from "react";
|
|
|
3875
3875
|
// src/webvr/host.ts
|
|
3876
3876
|
import { createContext as createContext5 } from "react";
|
|
3877
3877
|
var WebVRRuntimeContext = createContext5(null);
|
|
3878
|
+
var EMPTY_WEBVR_STATE = Object.freeze({
|
|
3879
|
+
available: false,
|
|
3880
|
+
enabled: false,
|
|
3881
|
+
mode: null
|
|
3882
|
+
});
|
|
3883
|
+
function createWebVRState(available, mode) {
|
|
3884
|
+
return Object.freeze({
|
|
3885
|
+
available,
|
|
3886
|
+
enabled: mode !== null,
|
|
3887
|
+
mode
|
|
3888
|
+
});
|
|
3889
|
+
}
|
|
3878
3890
|
function createWebVRHost() {
|
|
3879
3891
|
return {
|
|
3880
3892
|
controller: null,
|
|
@@ -3884,18 +3896,28 @@ function createWebVRHost() {
|
|
|
3884
3896
|
chrome: true,
|
|
3885
3897
|
mode: null,
|
|
3886
3898
|
setupOpen: false,
|
|
3887
|
-
settings: { screensize: "auto", profileId: "cardboard-v1" }
|
|
3899
|
+
settings: { screensize: "auto", profileId: "cardboard-v1" },
|
|
3900
|
+
detectedScreensize: null
|
|
3888
3901
|
},
|
|
3902
|
+
state: EMPTY_WEBVR_STATE,
|
|
3889
3903
|
listeners: /* @__PURE__ */ new Set()
|
|
3890
3904
|
};
|
|
3891
3905
|
}
|
|
3892
3906
|
function updateWebVRHost(host, snapshot) {
|
|
3893
|
-
|
|
3907
|
+
const previous = host.snapshot;
|
|
3908
|
+
const next = { ...previous, ...snapshot };
|
|
3909
|
+
host.snapshot = next;
|
|
3894
3910
|
host.revision += 1;
|
|
3911
|
+
if (previous.available !== next.available || previous.mode !== next.mode) {
|
|
3912
|
+
host.state = createWebVRState(next.available, next.mode);
|
|
3913
|
+
}
|
|
3895
3914
|
for (const listener of host.listeners) {
|
|
3896
3915
|
listener();
|
|
3897
3916
|
}
|
|
3898
3917
|
}
|
|
3918
|
+
function getWebVRState(host) {
|
|
3919
|
+
return host.state;
|
|
3920
|
+
}
|
|
3899
3921
|
function subscribeWebVRHost(host, listener) {
|
|
3900
3922
|
host.listeners.add(listener);
|
|
3901
3923
|
return () => {
|
|
@@ -6151,6 +6173,52 @@ function createPanoModalHost() {
|
|
|
6151
6173
|
};
|
|
6152
6174
|
}
|
|
6153
6175
|
|
|
6176
|
+
// src/overlay/partition.ts
|
|
6177
|
+
import {
|
|
6178
|
+
Children,
|
|
6179
|
+
Fragment,
|
|
6180
|
+
isValidElement
|
|
6181
|
+
} from "react";
|
|
6182
|
+
var PANO_OVERLAY_TYPE = /* @__PURE__ */ Symbol.for("pano-view.PanoOverlay");
|
|
6183
|
+
function isPanoOverlayType(type) {
|
|
6184
|
+
return typeof type === "function" && type[PANO_OVERLAY_TYPE] === true;
|
|
6185
|
+
}
|
|
6186
|
+
function isPanoOverlayElement(node) {
|
|
6187
|
+
return isValidElement(node) && isPanoOverlayType(node.type);
|
|
6188
|
+
}
|
|
6189
|
+
function isFragmentElement(node) {
|
|
6190
|
+
return isValidElement(node) && node.type === Fragment;
|
|
6191
|
+
}
|
|
6192
|
+
function flattenViewerChildren(children) {
|
|
6193
|
+
const flat = [];
|
|
6194
|
+
for (const item of Children.toArray(children)) {
|
|
6195
|
+
if (isFragmentElement(item)) {
|
|
6196
|
+
flat.push(...flattenViewerChildren(item.props.children));
|
|
6197
|
+
} else {
|
|
6198
|
+
flat.push(item);
|
|
6199
|
+
}
|
|
6200
|
+
}
|
|
6201
|
+
return flat;
|
|
6202
|
+
}
|
|
6203
|
+
function partitionPanoOverlay(children) {
|
|
6204
|
+
const items = flattenViewerChildren(children);
|
|
6205
|
+
const overlayElements = [];
|
|
6206
|
+
const sceneItems = [];
|
|
6207
|
+
let found = false;
|
|
6208
|
+
for (const item of items) {
|
|
6209
|
+
if (isPanoOverlayElement(item)) {
|
|
6210
|
+
found = true;
|
|
6211
|
+
overlayElements.push(item);
|
|
6212
|
+
} else {
|
|
6213
|
+
sceneItems.push(item);
|
|
6214
|
+
}
|
|
6215
|
+
}
|
|
6216
|
+
if (!found) {
|
|
6217
|
+
return { sceneChildren: children, overlayElements: [] };
|
|
6218
|
+
}
|
|
6219
|
+
return { sceneChildren: sceneItems, overlayElements };
|
|
6220
|
+
}
|
|
6221
|
+
|
|
6154
6222
|
// src/overlay/pano-overlay.tsx
|
|
6155
6223
|
import {
|
|
6156
6224
|
createContext as createContext12,
|
|
@@ -6170,17 +6238,33 @@ function getOverlayVisibleRect(rect, viewport) {
|
|
|
6170
6238
|
}
|
|
6171
6239
|
|
|
6172
6240
|
// src/overlay/pano-overlay.tsx
|
|
6173
|
-
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
6241
|
+
import { Fragment as Fragment2, jsx as jsx5 } from "react/jsx-runtime";
|
|
6174
6242
|
var PanoOverlayContext = createContext12(null);
|
|
6175
6243
|
var PanoModalHostContext = createContext12(null);
|
|
6244
|
+
var PanoOverlayOutletContext = createContext12(false);
|
|
6245
|
+
function PanoOverlay({ children }) {
|
|
6246
|
+
const inOutlet = useContext11(PanoOverlayOutletContext);
|
|
6247
|
+
if (!inOutlet) {
|
|
6248
|
+
throw new Error(
|
|
6249
|
+
"PanoOverlay must be a direct child of PanoViewer (or of a Fragment under PanoViewer), not nested inside scene components."
|
|
6250
|
+
);
|
|
6251
|
+
}
|
|
6252
|
+
return /* @__PURE__ */ jsx5(Fragment2, { children });
|
|
6253
|
+
}
|
|
6254
|
+
PanoOverlay[PANO_OVERLAY_TYPE] = true;
|
|
6255
|
+
var OVERLAY_HOOK_SCOPE = "PanoOverlay or PanoViewer.renderOverlay";
|
|
6176
6256
|
function usePanoOverlay() {
|
|
6177
6257
|
const context = useContext11(PanoOverlayContext);
|
|
6178
|
-
if (!context)
|
|
6258
|
+
if (!context) {
|
|
6259
|
+
throw new Error(`usePanoOverlay must be used inside ${OVERLAY_HOOK_SCOPE}.`);
|
|
6260
|
+
}
|
|
6179
6261
|
return context;
|
|
6180
6262
|
}
|
|
6181
6263
|
function usePanoModal(open) {
|
|
6182
6264
|
const host = useContext11(PanoModalHostContext);
|
|
6183
|
-
if (!host)
|
|
6265
|
+
if (!host) {
|
|
6266
|
+
throw new Error(`usePanoModal must be used inside ${OVERLAY_HOOK_SCOPE}.`);
|
|
6267
|
+
}
|
|
6184
6268
|
useLayoutEffect3(() => open ? host.acquire() : void 0, [host, open]);
|
|
6185
6269
|
}
|
|
6186
6270
|
function PanoOverlayPortalProvider({
|
|
@@ -6931,7 +7015,7 @@ function cueText(cue) {
|
|
|
6931
7015
|
}
|
|
6932
7016
|
|
|
6933
7017
|
// src/video/pano-video-controls.tsx
|
|
6934
|
-
import { Fragment, jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
7018
|
+
import { Fragment as Fragment3, jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
6935
7019
|
var DEFAULT_PANO_VIDEO_CONTROLS_APPEARANCE = {
|
|
6936
7020
|
background: "rgba(16, 16, 16, 0.88)",
|
|
6937
7021
|
color: "#f4f4f4",
|
|
@@ -7165,7 +7249,7 @@ function CaptionsMenu({
|
|
|
7165
7249
|
id,
|
|
7166
7250
|
labelledBy,
|
|
7167
7251
|
role: "menu",
|
|
7168
|
-
children: panel === "tracks" ? /* @__PURE__ */ jsxs4(
|
|
7252
|
+
children: panel === "tracks" ? /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
7169
7253
|
/* @__PURE__ */ jsxs4("div", { className: "pano-video-chrome-menu-list", children: [
|
|
7170
7254
|
/* @__PURE__ */ jsx9(
|
|
7171
7255
|
ChromeMenuRadioItem,
|
|
@@ -7204,7 +7288,7 @@ function CaptionsMenu({
|
|
|
7204
7288
|
secondary: /* @__PURE__ */ jsx9("span", { "aria-hidden": true, children: "\u203A" })
|
|
7205
7289
|
}
|
|
7206
7290
|
)
|
|
7207
|
-
] }) : /* @__PURE__ */ jsxs4(
|
|
7291
|
+
] }) : /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
7208
7292
|
/* @__PURE__ */ jsx9(
|
|
7209
7293
|
ChromeMenuActionItem,
|
|
7210
7294
|
{
|
|
@@ -7870,7 +7954,7 @@ function PanoVideoControlsHud({
|
|
|
7870
7954
|
children: /* @__PURE__ */ jsx9(Icon, { path: "M3 8a1 1 0 1 0 2 0 1 1 0 1 0-2 0M7 8a1 1 0 1 0 2 0 1 1 0 1 0-2 0M11 8a1 1 0 1 0 2 0 1 1 0 1 0-2 0" })
|
|
7871
7955
|
}
|
|
7872
7956
|
)
|
|
7873
|
-
] }) : /* @__PURE__ */ jsxs4(
|
|
7957
|
+
] }) : /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
7874
7958
|
rateButton,
|
|
7875
7959
|
variantButton,
|
|
7876
7960
|
captionsButton
|
|
@@ -7900,7 +7984,7 @@ function PanoVideoControls({ appearance }) {
|
|
|
7900
7984
|
}
|
|
7901
7985
|
|
|
7902
7986
|
// src/video/pano-video-chrome-bridge.tsx
|
|
7903
|
-
import { Fragment as
|
|
7987
|
+
import { Fragment as Fragment4, jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
7904
7988
|
function PanoVideoChromeBridge({
|
|
7905
7989
|
fullscreen,
|
|
7906
7990
|
host,
|
|
@@ -7915,7 +7999,7 @@ function PanoVideoChromeBridge({
|
|
|
7915
7999
|
return null;
|
|
7916
8000
|
}
|
|
7917
8001
|
const showDefaultControls = host.controller !== null && host.controls !== false && host.controlClaims === 0;
|
|
7918
|
-
return /* @__PURE__ */ jsxs5(
|
|
8002
|
+
return /* @__PURE__ */ jsxs5(Fragment4, { children: [
|
|
7919
8003
|
showDefaultControls ? /* @__PURE__ */ jsx10(
|
|
7920
8004
|
PanoVideoControlsHud,
|
|
7921
8005
|
{
|
|
@@ -7930,7 +8014,13 @@ function PanoVideoChromeBridge({
|
|
|
7930
8014
|
}
|
|
7931
8015
|
|
|
7932
8016
|
// src/webvr/chrome.tsx
|
|
7933
|
-
import {
|
|
8017
|
+
import {
|
|
8018
|
+
useCallback as useCallback6,
|
|
8019
|
+
useEffect as useEffect13,
|
|
8020
|
+
useRef as useRef12,
|
|
8021
|
+
useState as useState6,
|
|
8022
|
+
useSyncExternalStore as useSyncExternalStore7
|
|
8023
|
+
} from "react";
|
|
7934
8024
|
|
|
7935
8025
|
// src/webvr/appearance.ts
|
|
7936
8026
|
var DEFAULT_WEBVR_CHROME_APPEARANCE = {
|
|
@@ -7996,6 +8086,7 @@ var WEBVR_PROFILES = {
|
|
|
7996
8086
|
fov: 80,
|
|
7997
8087
|
ipdMm: 60,
|
|
7998
8088
|
screenToLensMm: 42,
|
|
8089
|
+
trayDistanceMm: 0,
|
|
7999
8090
|
k1: 0,
|
|
8000
8091
|
k2: 0
|
|
8001
8092
|
},
|
|
@@ -8005,6 +8096,7 @@ var WEBVR_PROFILES = {
|
|
|
8005
8096
|
fov: 80,
|
|
8006
8097
|
ipdMm: 60,
|
|
8007
8098
|
screenToLensMm: 42,
|
|
8099
|
+
trayDistanceMm: 35,
|
|
8008
8100
|
k1: 0.441,
|
|
8009
8101
|
k2: 0.156
|
|
8010
8102
|
},
|
|
@@ -8014,6 +8106,7 @@ var WEBVR_PROFILES = {
|
|
|
8014
8106
|
fov: 90,
|
|
8015
8107
|
ipdMm: 64,
|
|
8016
8108
|
screenToLensMm: 39,
|
|
8109
|
+
trayDistanceMm: 0,
|
|
8017
8110
|
k1: 0.336,
|
|
8018
8111
|
k2: 0.553
|
|
8019
8112
|
},
|
|
@@ -8023,6 +8116,7 @@ var WEBVR_PROFILES = {
|
|
|
8023
8116
|
fov: 96,
|
|
8024
8117
|
ipdMm: 63.5,
|
|
8025
8118
|
screenToLensMm: 50,
|
|
8119
|
+
trayDistanceMm: 0,
|
|
8026
8120
|
k1: 0.215,
|
|
8027
8121
|
k2: 0.215
|
|
8028
8122
|
},
|
|
@@ -8032,6 +8126,7 @@ var WEBVR_PROFILES = {
|
|
|
8032
8126
|
fov: 90,
|
|
8033
8127
|
ipdMm: 61.5,
|
|
8034
8128
|
screenToLensMm: 44,
|
|
8129
|
+
trayDistanceMm: 0,
|
|
8035
8130
|
k1: 0.385,
|
|
8036
8131
|
k2: 0.593
|
|
8037
8132
|
}
|
|
@@ -8082,12 +8177,28 @@ function saveWebVRSettings(settings) {
|
|
|
8082
8177
|
} catch {
|
|
8083
8178
|
}
|
|
8084
8179
|
}
|
|
8180
|
+
function clearWebVRSettings() {
|
|
8181
|
+
if (typeof localStorage === "undefined") {
|
|
8182
|
+
return;
|
|
8183
|
+
}
|
|
8184
|
+
try {
|
|
8185
|
+
localStorage.removeItem(STORAGE_KEY);
|
|
8186
|
+
} catch {
|
|
8187
|
+
}
|
|
8188
|
+
}
|
|
8189
|
+
function resolveInitialWebVRSettings(screensize, profile) {
|
|
8190
|
+
return {
|
|
8191
|
+
screensize: screensize ?? DEFAULT_WEBVR_SETTINGS.screensize,
|
|
8192
|
+
profileId: typeof profile === "string" ? profile : DEFAULT_WEBVR_SETTINGS.profileId
|
|
8193
|
+
};
|
|
8194
|
+
}
|
|
8085
8195
|
function clamp2(value, min, max) {
|
|
8086
8196
|
return Math.max(min, Math.min(max, Number.isFinite(value) ? value : min));
|
|
8087
8197
|
}
|
|
8088
8198
|
|
|
8089
8199
|
// src/webvr/chrome.tsx
|
|
8090
|
-
import { Fragment as
|
|
8200
|
+
import { Fragment as Fragment5, jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
8201
|
+
var SESSION_CHROME_IDLE_MS = 3e3;
|
|
8091
8202
|
function resolveAppearance(value) {
|
|
8092
8203
|
return {
|
|
8093
8204
|
...DEFAULT_WEBVR_CHROME_APPEARANCE,
|
|
@@ -8115,8 +8226,15 @@ function ChromeButton2({
|
|
|
8115
8226
|
}
|
|
8116
8227
|
);
|
|
8117
8228
|
}
|
|
8229
|
+
function formatScreensizeLabel(settings, detectedScreensize) {
|
|
8230
|
+
if (settings.screensize === "auto") {
|
|
8231
|
+
return detectedScreensize === null ? "Auto" : `Auto \xB7 ${detectedScreensize.toFixed(1)}`;
|
|
8232
|
+
}
|
|
8233
|
+
return settings.screensize.toFixed(1);
|
|
8234
|
+
}
|
|
8118
8235
|
function SetupPanel({
|
|
8119
8236
|
appearance,
|
|
8237
|
+
detectedScreensize,
|
|
8120
8238
|
host,
|
|
8121
8239
|
settings
|
|
8122
8240
|
}) {
|
|
@@ -8160,7 +8278,7 @@ function SetupPanel({
|
|
|
8160
8278
|
children: "\u2039"
|
|
8161
8279
|
}
|
|
8162
8280
|
),
|
|
8163
|
-
/* @__PURE__ */ jsx11("strong", { className: "pano-webvr-setup-value", children: settings
|
|
8281
|
+
/* @__PURE__ */ jsx11("strong", { className: "pano-webvr-setup-value", children: formatScreensizeLabel(settings, detectedScreensize) }),
|
|
8164
8282
|
/* @__PURE__ */ jsx11(
|
|
8165
8283
|
"button",
|
|
8166
8284
|
{
|
|
@@ -8201,42 +8319,61 @@ function SetupPanel({
|
|
|
8201
8319
|
)
|
|
8202
8320
|
] })
|
|
8203
8321
|
] }),
|
|
8322
|
+
/* @__PURE__ */ jsxs6("div", { className: "pano-webvr-setup-row", children: [
|
|
8323
|
+
/* @__PURE__ */ jsx11(
|
|
8324
|
+
ChromeButton2,
|
|
8325
|
+
{
|
|
8326
|
+
appearance,
|
|
8327
|
+
onClick: () => controller?.resetSettings(),
|
|
8328
|
+
children: "Reset"
|
|
8329
|
+
}
|
|
8330
|
+
),
|
|
8331
|
+
/* @__PURE__ */ jsx11(
|
|
8332
|
+
ChromeButton2,
|
|
8333
|
+
{
|
|
8334
|
+
appearance,
|
|
8335
|
+
onClick: () => controller?.closeSetup(),
|
|
8336
|
+
children: "Close"
|
|
8337
|
+
}
|
|
8338
|
+
)
|
|
8339
|
+
] })
|
|
8340
|
+
]
|
|
8341
|
+
}
|
|
8342
|
+
);
|
|
8343
|
+
}
|
|
8344
|
+
function SessionActions({
|
|
8345
|
+
appearance,
|
|
8346
|
+
host,
|
|
8347
|
+
mode,
|
|
8348
|
+
visible
|
|
8349
|
+
}) {
|
|
8350
|
+
return /* @__PURE__ */ jsxs6(
|
|
8351
|
+
"div",
|
|
8352
|
+
{
|
|
8353
|
+
"aria-hidden": !visible,
|
|
8354
|
+
className: visible ? "pano-webvr-toolbar-actions" : "pano-webvr-toolbar-actions pano-webvr-toolbar-actions-hidden",
|
|
8355
|
+
inert: !visible ? true : void 0,
|
|
8356
|
+
children: [
|
|
8357
|
+
mode !== "webxr" ? /* @__PURE__ */ jsx11(
|
|
8358
|
+
ChromeButton2,
|
|
8359
|
+
{
|
|
8360
|
+
appearance,
|
|
8361
|
+
onClick: () => host.controller?.openSetup(),
|
|
8362
|
+
children: "VR Setup"
|
|
8363
|
+
}
|
|
8364
|
+
) : null,
|
|
8204
8365
|
/* @__PURE__ */ jsx11(
|
|
8205
8366
|
ChromeButton2,
|
|
8206
8367
|
{
|
|
8207
8368
|
appearance,
|
|
8208
|
-
onClick: () => controller?.
|
|
8209
|
-
children: "
|
|
8369
|
+
onClick: () => void host.controller?.exitVR(),
|
|
8370
|
+
children: "Exit VR"
|
|
8210
8371
|
}
|
|
8211
8372
|
)
|
|
8212
8373
|
]
|
|
8213
8374
|
}
|
|
8214
8375
|
);
|
|
8215
8376
|
}
|
|
8216
|
-
function SessionActions({
|
|
8217
|
-
appearance,
|
|
8218
|
-
host,
|
|
8219
|
-
mode
|
|
8220
|
-
}) {
|
|
8221
|
-
return /* @__PURE__ */ jsxs6("div", { className: "pano-webvr-toolbar-actions", children: [
|
|
8222
|
-
mode !== "webxr" ? /* @__PURE__ */ jsx11(
|
|
8223
|
-
ChromeButton2,
|
|
8224
|
-
{
|
|
8225
|
-
appearance,
|
|
8226
|
-
onClick: () => host.controller?.openSetup(),
|
|
8227
|
-
children: "VR Setup"
|
|
8228
|
-
}
|
|
8229
|
-
) : null,
|
|
8230
|
-
/* @__PURE__ */ jsx11(
|
|
8231
|
-
ChromeButton2,
|
|
8232
|
-
{
|
|
8233
|
-
appearance,
|
|
8234
|
-
onClick: () => void host.controller?.exitVR(),
|
|
8235
|
-
children: "Exit VR"
|
|
8236
|
-
}
|
|
8237
|
-
)
|
|
8238
|
-
] });
|
|
8239
|
-
}
|
|
8240
8377
|
function RotatePhoneIcon2() {
|
|
8241
8378
|
return /* @__PURE__ */ jsxs6(
|
|
8242
8379
|
"svg",
|
|
@@ -8267,6 +8404,51 @@ function PortraitPrompt() {
|
|
|
8267
8404
|
/* @__PURE__ */ jsx11("p", { className: "pano-webvr-portrait-text", children: "Rotate your phone to landscape" })
|
|
8268
8405
|
] });
|
|
8269
8406
|
}
|
|
8407
|
+
function useSessionChromeVisibility(active, keepVisible, viewer) {
|
|
8408
|
+
const [visible, setVisible] = useState6(true);
|
|
8409
|
+
const idleTimerRef = useRef12(0);
|
|
8410
|
+
const bump = useCallback6(() => {
|
|
8411
|
+
setVisible(true);
|
|
8412
|
+
window.clearTimeout(idleTimerRef.current);
|
|
8413
|
+
if (!active || keepVisible) {
|
|
8414
|
+
return;
|
|
8415
|
+
}
|
|
8416
|
+
idleTimerRef.current = window.setTimeout(() => {
|
|
8417
|
+
setVisible(false);
|
|
8418
|
+
}, SESSION_CHROME_IDLE_MS);
|
|
8419
|
+
}, [active, keepVisible]);
|
|
8420
|
+
useEffect13(() => {
|
|
8421
|
+
if (!active) {
|
|
8422
|
+
window.clearTimeout(idleTimerRef.current);
|
|
8423
|
+
setVisible(true);
|
|
8424
|
+
return;
|
|
8425
|
+
}
|
|
8426
|
+
bump();
|
|
8427
|
+
}, [active, bump, keepVisible]);
|
|
8428
|
+
useEffect13(() => {
|
|
8429
|
+
if (!active || !viewer) {
|
|
8430
|
+
return;
|
|
8431
|
+
}
|
|
8432
|
+
const reveal = () => {
|
|
8433
|
+
bump();
|
|
8434
|
+
};
|
|
8435
|
+
viewer.addEventListener("pointerdown", reveal);
|
|
8436
|
+
viewer.addEventListener("wheel", reveal, { passive: true });
|
|
8437
|
+
viewer.addEventListener("keydown", reveal);
|
|
8438
|
+
return () => {
|
|
8439
|
+
viewer.removeEventListener("pointerdown", reveal);
|
|
8440
|
+
viewer.removeEventListener("wheel", reveal);
|
|
8441
|
+
viewer.removeEventListener("keydown", reveal);
|
|
8442
|
+
};
|
|
8443
|
+
}, [active, bump, viewer]);
|
|
8444
|
+
useEffect13(
|
|
8445
|
+
() => () => {
|
|
8446
|
+
window.clearTimeout(idleTimerRef.current);
|
|
8447
|
+
},
|
|
8448
|
+
[]
|
|
8449
|
+
);
|
|
8450
|
+
return keepVisible || visible;
|
|
8451
|
+
}
|
|
8270
8452
|
function WebVRChromeBridge({ host }) {
|
|
8271
8453
|
useSyncExternalStore7(
|
|
8272
8454
|
(listener) => subscribeWebVRHost(host, listener),
|
|
@@ -8274,11 +8456,29 @@ function WebVRChromeBridge({ host }) {
|
|
|
8274
8456
|
() => host.revision
|
|
8275
8457
|
);
|
|
8276
8458
|
const portrait = usePortraitOrientation();
|
|
8277
|
-
const {
|
|
8459
|
+
const {
|
|
8460
|
+
chrome,
|
|
8461
|
+
detectedScreensize,
|
|
8462
|
+
mode,
|
|
8463
|
+
settings,
|
|
8464
|
+
setupOpen
|
|
8465
|
+
} = host.snapshot;
|
|
8278
8466
|
const [mounted, setMounted] = useState6(false);
|
|
8467
|
+
const [viewer, setViewer] = useState6(null);
|
|
8468
|
+
const toolbarRef = useRef12(null);
|
|
8279
8469
|
useEffect13(() => {
|
|
8280
8470
|
setMounted(true);
|
|
8281
8471
|
}, []);
|
|
8472
|
+
useEffect13(() => {
|
|
8473
|
+
const node = toolbarRef.current?.closest("[data-pano-viewer]") ?? null;
|
|
8474
|
+
setViewer(node);
|
|
8475
|
+
}, [mode]);
|
|
8476
|
+
const sessionActive = mode !== null;
|
|
8477
|
+
const chromeVisible = useSessionChromeVisibility(
|
|
8478
|
+
sessionActive,
|
|
8479
|
+
setupOpen,
|
|
8480
|
+
viewer
|
|
8481
|
+
);
|
|
8282
8482
|
if (chrome === false || !host.controller) {
|
|
8283
8483
|
return null;
|
|
8284
8484
|
}
|
|
@@ -8287,17 +8487,29 @@ function WebVRChromeBridge({ host }) {
|
|
|
8287
8487
|
if (showPortraitPrompt) {
|
|
8288
8488
|
return /* @__PURE__ */ jsx11(PortraitPrompt, {});
|
|
8289
8489
|
}
|
|
8290
|
-
|
|
8291
|
-
|
|
8292
|
-
|
|
8490
|
+
if (!mode) {
|
|
8491
|
+
return null;
|
|
8492
|
+
}
|
|
8493
|
+
return /* @__PURE__ */ jsxs6(Fragment5, { children: [
|
|
8494
|
+
/* @__PURE__ */ jsx11("div", { className: "pano-webvr-toolbar", ref: toolbarRef, children: /* @__PURE__ */ jsx11(
|
|
8495
|
+
SessionActions,
|
|
8293
8496
|
{
|
|
8294
8497
|
appearance,
|
|
8295
|
-
|
|
8296
|
-
|
|
8498
|
+
host,
|
|
8499
|
+
mode,
|
|
8500
|
+
visible: chromeVisible
|
|
8297
8501
|
}
|
|
8298
8502
|
) }),
|
|
8299
|
-
mode === "fake" ? /* @__PURE__ */ jsx11("p", { className: "pano-webvr-hint", style: { color: appearance.color }, children: "Simulated VR Mode \xB7 Click the view to lock the mouse, then move to look around. Use a headset or phone for real VR." }) : null,
|
|
8300
|
-
setupOpen ? /* @__PURE__ */ jsx11(
|
|
8503
|
+
mode === "fake" && chromeVisible ? /* @__PURE__ */ jsx11("p", { className: "pano-webvr-hint", style: { color: appearance.color }, children: "Simulated VR Mode \xB7 Click the view to lock the mouse, then move to look around. Use a headset or phone for real VR." }) : null,
|
|
8504
|
+
setupOpen ? /* @__PURE__ */ jsx11(
|
|
8505
|
+
SetupPanel,
|
|
8506
|
+
{
|
|
8507
|
+
appearance,
|
|
8508
|
+
detectedScreensize,
|
|
8509
|
+
host,
|
|
8510
|
+
settings
|
|
8511
|
+
}
|
|
8512
|
+
) : null
|
|
8301
8513
|
] });
|
|
8302
8514
|
}
|
|
8303
8515
|
|
|
@@ -8330,12 +8542,12 @@ function projectStereoHtmlPosition(el, camera, size, eye) {
|
|
|
8330
8542
|
// src/webvr/xr-origin.tsx
|
|
8331
8543
|
import { useFrame as useFrame7, useThree as useThree8 } from "@react-three/fiber";
|
|
8332
8544
|
import { useXR as useXR2, XROrigin } from "@react-three/xr";
|
|
8333
|
-
import { useRef as
|
|
8545
|
+
import { useRef as useRef13 } from "react";
|
|
8334
8546
|
import { Vector3 as Vector36 } from "three";
|
|
8335
8547
|
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
8336
8548
|
function PanoramaXROrigin() {
|
|
8337
|
-
const originRef =
|
|
8338
|
-
const localHeadPositionRef =
|
|
8549
|
+
const originRef = useRef13(null);
|
|
8550
|
+
const localHeadPositionRef = useRef13(new Vector36());
|
|
8339
8551
|
const session2 = useXR2((state) => state.session);
|
|
8340
8552
|
const gl = useThree8((state) => state.gl);
|
|
8341
8553
|
useFrame7(() => {
|
|
@@ -8450,11 +8662,11 @@ var PanoViewer = forwardRef2(
|
|
|
8450
8662
|
"aria-label": ariaLabel = "Panorama viewer",
|
|
8451
8663
|
...divProps
|
|
8452
8664
|
}, ref) {
|
|
8453
|
-
const rootRef =
|
|
8454
|
-
const controlsRef =
|
|
8665
|
+
const rootRef = useRef14(null);
|
|
8666
|
+
const controlsRef = useRef14(null);
|
|
8455
8667
|
const modalHost = useMemo8(() => createPanoModalHost(), []);
|
|
8456
8668
|
const modalOpen = useSyncExternalStore8(modalHost.subscribe, modalHost.getSnapshot, () => false);
|
|
8457
|
-
const setControlsRuntime =
|
|
8669
|
+
const setControlsRuntime = useCallback7((runtime) => {
|
|
8458
8670
|
controlsRef.current = runtime;
|
|
8459
8671
|
modalHost.connect(runtime);
|
|
8460
8672
|
}, [modalHost]);
|
|
@@ -8514,12 +8726,12 @@ var PanoViewer = forwardRef2(
|
|
|
8514
8726
|
}),
|
|
8515
8727
|
[bgmHost, videoHost]
|
|
8516
8728
|
);
|
|
8517
|
-
const runMediaActivation =
|
|
8729
|
+
const runMediaActivation = useCallback7(() => {
|
|
8518
8730
|
const resume = mediaActivationControls.resumeAudio();
|
|
8519
8731
|
mediaActivationOptions?.onActivate?.(mediaActivationControls);
|
|
8520
8732
|
return resume;
|
|
8521
8733
|
}, [mediaActivationControls, mediaActivationOptions]);
|
|
8522
|
-
const activateMedia =
|
|
8734
|
+
const activateMedia = useCallback7(() => {
|
|
8523
8735
|
setMediaActivated(true);
|
|
8524
8736
|
return runMediaActivation();
|
|
8525
8737
|
}, [runMediaActivation]);
|
|
@@ -8601,7 +8813,7 @@ var PanoViewer = forwardRef2(
|
|
|
8601
8813
|
]);
|
|
8602
8814
|
const limitsKey = JSON.stringify(viewLimits);
|
|
8603
8815
|
const parsedLimits = useMemo8(() => parseViewLimits(viewLimits), [limitsKey]);
|
|
8604
|
-
const fallbackViewRef =
|
|
8816
|
+
const fallbackViewRef = useRef14(DEFAULT_VIEW);
|
|
8605
8817
|
const normalizedMinFov = Math.max(1, Math.min(minFov, maxFov - 1));
|
|
8606
8818
|
const normalizedMaxFov = Math.min(
|
|
8607
8819
|
179,
|
|
@@ -8664,7 +8876,7 @@ var PanoViewer = forwardRef2(
|
|
|
8664
8876
|
}),
|
|
8665
8877
|
[controlOptions.keyboard]
|
|
8666
8878
|
);
|
|
8667
|
-
const enterFullscreen =
|
|
8879
|
+
const enterFullscreen = useCallback7(async () => {
|
|
8668
8880
|
if (typeof document === "undefined") {
|
|
8669
8881
|
return;
|
|
8670
8882
|
}
|
|
@@ -8683,7 +8895,7 @@ var PanoViewer = forwardRef2(
|
|
|
8683
8895
|
acquireIphoneLandscapeFullscreen(root, "viewer");
|
|
8684
8896
|
}
|
|
8685
8897
|
}, []);
|
|
8686
|
-
const exitFullscreen =
|
|
8898
|
+
const exitFullscreen = useCallback7(async () => {
|
|
8687
8899
|
if (typeof document === "undefined") {
|
|
8688
8900
|
return;
|
|
8689
8901
|
}
|
|
@@ -8695,7 +8907,7 @@ var PanoViewer = forwardRef2(
|
|
|
8695
8907
|
await exitElementFullscreen();
|
|
8696
8908
|
}
|
|
8697
8909
|
}, []);
|
|
8698
|
-
const toggleFullscreen =
|
|
8910
|
+
const toggleFullscreen = useCallback7(async () => {
|
|
8699
8911
|
if (typeof document === "undefined") {
|
|
8700
8912
|
return;
|
|
8701
8913
|
}
|
|
@@ -8711,6 +8923,10 @@ var PanoViewer = forwardRef2(
|
|
|
8711
8923
|
}, [enterFullscreen, exitFullscreen]);
|
|
8712
8924
|
const [isViewerFullscreen, setIsViewerFullscreen] = useState7(false);
|
|
8713
8925
|
const { context: overlayContext, setPortalContainer } = usePanoOverlayHost(isViewerFullscreen);
|
|
8926
|
+
const { sceneChildren, overlayElements } = useMemo8(
|
|
8927
|
+
() => partitionPanoOverlay(children),
|
|
8928
|
+
[children]
|
|
8929
|
+
);
|
|
8714
8930
|
const iphoneFullscreenAllowsScroll = useSyncExternalStore8(
|
|
8715
8931
|
subscribeIphoneLandscapeFullscreen,
|
|
8716
8932
|
() => getIphoneLandscapeFullscreenSnapshot().allowsDocumentScroll,
|
|
@@ -8794,7 +9010,7 @@ var PanoViewer = forwardRef2(
|
|
|
8794
9010
|
useEffect14(() => {
|
|
8795
9011
|
setLegacyAutoRotate(legacyAutoRotateOptions.autoRotate ?? false);
|
|
8796
9012
|
}, [legacyAutoRotateOptions.autoRotate]);
|
|
8797
|
-
const isFullscreenRef =
|
|
9013
|
+
const isFullscreenRef = useRef14(false);
|
|
8798
9014
|
isFullscreenRef.current = isViewerFullscreen;
|
|
8799
9015
|
useImperativeHandle2(
|
|
8800
9016
|
ref,
|
|
@@ -8834,6 +9050,8 @@ var PanoViewer = forwardRef2(
|
|
|
8834
9050
|
isVRAvailable: () => webVRHost.snapshot.available,
|
|
8835
9051
|
isVREnabled: () => webVRHost.snapshot.mode !== null,
|
|
8836
9052
|
getVRMode: () => webVRHost.snapshot.mode,
|
|
9053
|
+
getVRState: () => webVRHost.state,
|
|
9054
|
+
subscribeVR: (onStoreChange) => subscribeWebVRHost(webVRHost, onStoreChange),
|
|
8837
9055
|
requestVRPermission: () => webVRHost.controller?.requestPermission() ?? Promise.resolve(false),
|
|
8838
9056
|
// -- Video --
|
|
8839
9057
|
getVideo: () => videoHost.controller,
|
|
@@ -8966,7 +9184,7 @@ var PanoViewer = forwardRef2(
|
|
|
8966
9184
|
/* @__PURE__ */ jsx13(PanoramaEventSurface, {}),
|
|
8967
9185
|
contextMenuChannel.mount ? /* @__PURE__ */ jsx13(PanoContextMenu, { ...contextMenuChannel.props }) : null,
|
|
8968
9186
|
/* @__PURE__ */ jsxs7(ControlClaimsContext.Provider, { value: controlClaims, children: [
|
|
8969
|
-
|
|
9187
|
+
sceneChildren,
|
|
8970
9188
|
/* @__PURE__ */ jsx13(
|
|
8971
9189
|
DefaultControlChannels,
|
|
8972
9190
|
{
|
|
@@ -9011,15 +9229,18 @@ var PanoViewer = forwardRef2(
|
|
|
9011
9229
|
contextMenuOverlay,
|
|
9012
9230
|
hotspotAccessibilityControls
|
|
9013
9231
|
] }),
|
|
9014
|
-
/* @__PURE__ */ jsx13(PanoEventBusContext.Provider, { value: eventBus, children: /* @__PURE__ */ jsx13(PanoModalHostContext.Provider, { value: modalHost, children: /* @__PURE__ */ jsx13(PanoOverlayContext.Provider, { value: overlayContext, children: /* @__PURE__ */ jsx13(
|
|
9232
|
+
/* @__PURE__ */ jsx13(PanoEventBusContext.Provider, { value: eventBus, children: /* @__PURE__ */ jsx13(PanoModalHostContext.Provider, { value: modalHost, children: /* @__PURE__ */ jsx13(PanoOverlayContext.Provider, { value: overlayContext, children: /* @__PURE__ */ jsx13(PanoOverlayOutletContext.Provider, { value: true, children: /* @__PURE__ */ jsxs7(
|
|
9015
9233
|
"div",
|
|
9016
9234
|
{
|
|
9017
9235
|
"data-pano-overlay": "",
|
|
9018
9236
|
ref: setPortalContainer,
|
|
9019
9237
|
style: { position: "absolute", inset: 0, zIndex: 30, pointerEvents: "none" },
|
|
9020
|
-
children:
|
|
9238
|
+
children: [
|
|
9239
|
+
renderOverlay?.(overlayContext),
|
|
9240
|
+
overlayElements
|
|
9241
|
+
]
|
|
9021
9242
|
}
|
|
9022
|
-
) }) }) })
|
|
9243
|
+
) }) }) }) })
|
|
9023
9244
|
]
|
|
9024
9245
|
}
|
|
9025
9246
|
);
|
|
@@ -9121,17 +9342,17 @@ import {
|
|
|
9121
9342
|
// src/scenes.tsx
|
|
9122
9343
|
import { useFrame as useFrame13, useThree as useThree16 } from "@react-three/fiber";
|
|
9123
9344
|
import {
|
|
9124
|
-
Fragment as
|
|
9125
|
-
useCallback as
|
|
9345
|
+
Fragment as Fragment6,
|
|
9346
|
+
useCallback as useCallback9,
|
|
9126
9347
|
useContext as useContext19,
|
|
9127
9348
|
useEffect as useEffect23,
|
|
9128
9349
|
useMemo as useMemo17,
|
|
9129
|
-
useRef as
|
|
9350
|
+
useRef as useRef23,
|
|
9130
9351
|
useState as useState12
|
|
9131
9352
|
} from "react";
|
|
9132
9353
|
import {
|
|
9133
9354
|
LinearSRGBColorSpace,
|
|
9134
|
-
LinearFilter as
|
|
9355
|
+
LinearFilter as LinearFilter3,
|
|
9135
9356
|
WebGLRenderTarget
|
|
9136
9357
|
} from "three";
|
|
9137
9358
|
|
|
@@ -9204,7 +9425,7 @@ function isSnapshotTransition(preset) {
|
|
|
9204
9425
|
|
|
9205
9426
|
// src/scene-transitions/snapshot-hold.tsx
|
|
9206
9427
|
import { useFrame as useFrame8, useThree as useThree9 } from "@react-three/fiber";
|
|
9207
|
-
import { useEffect as useEffect15, useMemo as useMemo9, useRef as
|
|
9428
|
+
import { useEffect as useEffect15, useMemo as useMemo9, useRef as useRef15 } from "react";
|
|
9208
9429
|
import { Vector3 as Vector38 } from "three";
|
|
9209
9430
|
|
|
9210
9431
|
// src/scene-transitions/overlay-utils.ts
|
|
@@ -9540,8 +9761,8 @@ function createSnapshotMaterial(preset, texture) {
|
|
|
9540
9761
|
import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
9541
9762
|
function SnapshotHold({ snapshot }) {
|
|
9542
9763
|
const { camera, gl } = useThree9();
|
|
9543
|
-
const meshRef =
|
|
9544
|
-
const directionRef =
|
|
9764
|
+
const meshRef = useRef15(null);
|
|
9765
|
+
const directionRef = useRef15(new Vector38());
|
|
9545
9766
|
const material = useMemo9(
|
|
9546
9767
|
() => createSnapshotMaterial("crossfade", snapshot.texture),
|
|
9547
9768
|
[snapshot.texture]
|
|
@@ -9624,7 +9845,7 @@ function phaseAfterSnapshot(preset, hold) {
|
|
|
9624
9845
|
|
|
9625
9846
|
// src/scene-transitions/particle-overlay.tsx
|
|
9626
9847
|
import { useFrame as useFrame9, useThree as useThree10 } from "@react-three/fiber";
|
|
9627
|
-
import { useEffect as useEffect16, useMemo as useMemo10, useRef as
|
|
9848
|
+
import { useEffect as useEffect16, useMemo as useMemo10, useRef as useRef16 } from "react";
|
|
9628
9849
|
import {
|
|
9629
9850
|
DoubleSide as DoubleSide2,
|
|
9630
9851
|
InstancedBufferAttribute,
|
|
@@ -9711,10 +9932,10 @@ function ParticleOverlay({
|
|
|
9711
9932
|
onFinish
|
|
9712
9933
|
}) {
|
|
9713
9934
|
const { camera } = useThree10();
|
|
9714
|
-
const meshRef =
|
|
9715
|
-
const startRef =
|
|
9716
|
-
const finishedRef =
|
|
9717
|
-
const directionRef =
|
|
9935
|
+
const meshRef = useRef16(null);
|
|
9936
|
+
const startRef = useRef16(null);
|
|
9937
|
+
const finishedRef = useRef16(false);
|
|
9938
|
+
const directionRef = useRef16(new Vector39());
|
|
9718
9939
|
const geometry = useMemo10(() => createParticleGeometry(), []);
|
|
9719
9940
|
const material = useMemo10(
|
|
9720
9941
|
() => new ShaderMaterial2({
|
|
@@ -9770,7 +9991,7 @@ function ParticleOverlay({
|
|
|
9770
9991
|
|
|
9771
9992
|
// src/scene-transitions/snapshot-overlay.tsx
|
|
9772
9993
|
import { useFrame as useFrame10, useThree as useThree11 } from "@react-three/fiber";
|
|
9773
|
-
import { useEffect as useEffect17, useMemo as useMemo11, useRef as
|
|
9994
|
+
import { useEffect as useEffect17, useMemo as useMemo11, useRef as useRef17 } from "react";
|
|
9774
9995
|
import { Vector3 as Vector310 } from "three";
|
|
9775
9996
|
import { jsx as jsx16, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
9776
9997
|
function SnapshotOverlay({
|
|
@@ -9781,10 +10002,10 @@ function SnapshotOverlay({
|
|
|
9781
10002
|
onFinish
|
|
9782
10003
|
}) {
|
|
9783
10004
|
const { camera, gl } = useThree11();
|
|
9784
|
-
const meshRef =
|
|
9785
|
-
const startRef =
|
|
9786
|
-
const finishedRef =
|
|
9787
|
-
const directionRef =
|
|
10005
|
+
const meshRef = useRef17(null);
|
|
10006
|
+
const startRef = useRef17(null);
|
|
10007
|
+
const finishedRef = useRef17(false);
|
|
10008
|
+
const directionRef = useRef17(new Vector310());
|
|
9788
10009
|
const material = useMemo11(() => {
|
|
9789
10010
|
if (!isSnapshotTransition(transition.preset)) {
|
|
9790
10011
|
return null;
|
|
@@ -9874,7 +10095,7 @@ function TransitionOverlay(props) {
|
|
|
9874
10095
|
|
|
9875
10096
|
// src/sphere.tsx
|
|
9876
10097
|
import { useThree as useThree12 } from "@react-three/fiber";
|
|
9877
|
-
import { useEffect as useEffect18, useMemo as useMemo13, useRef as
|
|
10098
|
+
import { useEffect as useEffect18, useMemo as useMemo13, useRef as useRef19, useState as useState8 } from "react";
|
|
9878
10099
|
import {
|
|
9879
10100
|
BackSide as BackSide2,
|
|
9880
10101
|
LinearFilter,
|
|
@@ -9886,7 +10107,7 @@ import {
|
|
|
9886
10107
|
} from "three";
|
|
9887
10108
|
|
|
9888
10109
|
// src/pano-filter/pano-basic-material.tsx
|
|
9889
|
-
import { useLayoutEffect as useLayoutEffect4, useMemo as useMemo12, useRef as
|
|
10110
|
+
import { useLayoutEffect as useLayoutEffect4, useMemo as useMemo12, useRef as useRef18 } from "react";
|
|
9890
10111
|
import {
|
|
9891
10112
|
Matrix4,
|
|
9892
10113
|
Vector4
|
|
@@ -10086,9 +10307,9 @@ function PanoBasicMaterial({
|
|
|
10086
10307
|
const preset = snapshot.enabled && target === "panorama" ? snapshot.preset : "none";
|
|
10087
10308
|
const matrix = snapshot.enabled && (target === "panorama" || snapshot.colorMatrixScope === "all") ? snapshot.colorMatrix : null;
|
|
10088
10309
|
const hasMatrix = matrix !== null;
|
|
10089
|
-
const currentRef =
|
|
10310
|
+
const currentRef = useRef18({ matrix, intensity: snapshot.intensity });
|
|
10090
10311
|
currentRef.current = { matrix, intensity: snapshot.intensity };
|
|
10091
|
-
const shaderRef =
|
|
10312
|
+
const shaderRef = useRef18(null);
|
|
10092
10313
|
const onBeforeCompile = useMemo12(() => {
|
|
10093
10314
|
const compile = (shader) => {
|
|
10094
10315
|
shaderRef.current = shader;
|
|
@@ -10136,8 +10357,8 @@ function PanoBasicMaterial({
|
|
|
10136
10357
|
import { jsx as jsx19, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
10137
10358
|
function useEquirectTexture(url, anisotropy, generateMipmaps, onLoad, onError) {
|
|
10138
10359
|
const [texture, setTexture] = useState8(null);
|
|
10139
|
-
const onLoadRef =
|
|
10140
|
-
const onErrorRef =
|
|
10360
|
+
const onLoadRef = useRef19(onLoad);
|
|
10361
|
+
const onErrorRef = useRef19(onError);
|
|
10141
10362
|
onLoadRef.current = onLoad;
|
|
10142
10363
|
onErrorRef.current = onError;
|
|
10143
10364
|
useEffect18(() => {
|
|
@@ -10218,7 +10439,7 @@ function Sphere({
|
|
|
10218
10439
|
onPreviewError
|
|
10219
10440
|
);
|
|
10220
10441
|
const displayTexture = texture ?? previewTexture;
|
|
10221
|
-
const readyRef =
|
|
10442
|
+
const readyRef = useRef19(false);
|
|
10222
10443
|
const detailReporter = useSceneDetailReporter();
|
|
10223
10444
|
useEffect18(() => {
|
|
10224
10445
|
readyRef.current = false;
|
|
@@ -10264,13 +10485,14 @@ function Sphere({
|
|
|
10264
10485
|
|
|
10265
10486
|
// src/sphere-tile/sphere-tile.tsx
|
|
10266
10487
|
import { useFrame as useFrame11, useThree as useThree14 } from "@react-three/fiber";
|
|
10267
|
-
import { memo, useCallback as
|
|
10488
|
+
import { memo, useCallback as useCallback8, useEffect as useEffect21, useMemo as useMemo15, useRef as useRef21, useState as useState10 } from "react";
|
|
10268
10489
|
import { BackSide as BackSide3, Frustum, Matrix4 as Matrix42, PerspectiveCamera as PerspectiveCamera4 } from "three";
|
|
10269
10490
|
|
|
10270
10491
|
// src/tile/texture-manager.ts
|
|
10271
10492
|
import {
|
|
10272
10493
|
ClampToEdgeWrapping,
|
|
10273
10494
|
LinearFilter as LinearFilter2,
|
|
10495
|
+
LinearMipmapLinearFilter as LinearMipmapLinearFilter2,
|
|
10274
10496
|
SRGBColorSpace as SRGBColorSpace2,
|
|
10275
10497
|
TextureLoader as TextureLoader2
|
|
10276
10498
|
} from "three";
|
|
@@ -10279,6 +10501,20 @@ var EMPTY_TEXTURE_SNAPSHOT = {
|
|
|
10279
10501
|
texture: null,
|
|
10280
10502
|
error: null
|
|
10281
10503
|
};
|
|
10504
|
+
var MIPMAP_MEMORY_FACTOR = 4 / 3;
|
|
10505
|
+
function mipmappedTextureBytes(width, height) {
|
|
10506
|
+
return Math.ceil(width * height * 4 * MIPMAP_MEMORY_FACTOR);
|
|
10507
|
+
}
|
|
10508
|
+
function configureMipmappedTexture(texture, anisotropy) {
|
|
10509
|
+
texture.colorSpace = SRGBColorSpace2;
|
|
10510
|
+
texture.wrapS = ClampToEdgeWrapping;
|
|
10511
|
+
texture.wrapT = ClampToEdgeWrapping;
|
|
10512
|
+
texture.magFilter = LinearFilter2;
|
|
10513
|
+
texture.minFilter = LinearMipmapLinearFilter2;
|
|
10514
|
+
texture.generateMipmaps = true;
|
|
10515
|
+
texture.anisotropy = Math.max(1, anisotropy);
|
|
10516
|
+
texture.needsUpdate = true;
|
|
10517
|
+
}
|
|
10282
10518
|
var TileTextureManager = class {
|
|
10283
10519
|
constructor(options) {
|
|
10284
10520
|
this.loader = new TextureLoader2();
|
|
@@ -10430,7 +10666,10 @@ var TileTextureManager = class {
|
|
|
10430
10666
|
entry.texture = texture;
|
|
10431
10667
|
entry.status = "loaded";
|
|
10432
10668
|
entry.error = null;
|
|
10433
|
-
entry.bytes =
|
|
10669
|
+
entry.bytes = mipmappedTextureBytes(
|
|
10670
|
+
entry.address.width,
|
|
10671
|
+
entry.address.height
|
|
10672
|
+
);
|
|
10434
10673
|
entry.lastUsed = performance.now();
|
|
10435
10674
|
this.totalBytes += entry.bytes;
|
|
10436
10675
|
this.loaded += 1;
|
|
@@ -10453,14 +10692,7 @@ var TileTextureManager = class {
|
|
|
10453
10692
|
}
|
|
10454
10693
|
}
|
|
10455
10694
|
configureTexture(texture) {
|
|
10456
|
-
texture.
|
|
10457
|
-
texture.wrapS = ClampToEdgeWrapping;
|
|
10458
|
-
texture.wrapT = ClampToEdgeWrapping;
|
|
10459
|
-
texture.magFilter = LinearFilter2;
|
|
10460
|
-
texture.minFilter = LinearFilter2;
|
|
10461
|
-
texture.generateMipmaps = false;
|
|
10462
|
-
texture.anisotropy = Math.min(4, this.options.anisotropy);
|
|
10463
|
-
texture.needsUpdate = true;
|
|
10695
|
+
configureMipmappedTexture(texture, this.options.anisotropy);
|
|
10464
10696
|
}
|
|
10465
10697
|
evict() {
|
|
10466
10698
|
if (this.totalBytes <= this.options.maxBytes) {
|
|
@@ -10534,16 +10766,11 @@ function useSharedTileTextureManager() {
|
|
|
10534
10766
|
}
|
|
10535
10767
|
|
|
10536
10768
|
// src/tile/texture-hooks.ts
|
|
10537
|
-
import { useEffect as useEffect20, useRef as
|
|
10538
|
-
import {
|
|
10539
|
-
ClampToEdgeWrapping as ClampToEdgeWrapping2,
|
|
10540
|
-
LinearFilter as LinearFilter3,
|
|
10541
|
-
SRGBColorSpace as SRGBColorSpace3,
|
|
10542
|
-
TextureLoader as TextureLoader3
|
|
10543
|
-
} from "three";
|
|
10769
|
+
import { useEffect as useEffect20, useRef as useRef20, useState as useState9 } from "react";
|
|
10770
|
+
import { TextureLoader as TextureLoader3 } from "three";
|
|
10544
10771
|
function usePreviewTexture(url, anisotropy, onError) {
|
|
10545
10772
|
const [texture, setTexture] = useState9(null);
|
|
10546
|
-
const onErrorRef =
|
|
10773
|
+
const onErrorRef = useRef20(onError);
|
|
10547
10774
|
onErrorRef.current = onError;
|
|
10548
10775
|
useEffect20(() => {
|
|
10549
10776
|
if (!url) {
|
|
@@ -10560,14 +10787,7 @@ function usePreviewTexture(url, anisotropy, onError) {
|
|
|
10560
10787
|
loadedTexture.dispose();
|
|
10561
10788
|
return;
|
|
10562
10789
|
}
|
|
10563
|
-
loadedTexture
|
|
10564
|
-
loadedTexture.wrapS = ClampToEdgeWrapping2;
|
|
10565
|
-
loadedTexture.wrapT = ClampToEdgeWrapping2;
|
|
10566
|
-
loadedTexture.magFilter = LinearFilter3;
|
|
10567
|
-
loadedTexture.minFilter = LinearFilter3;
|
|
10568
|
-
loadedTexture.generateMipmaps = false;
|
|
10569
|
-
loadedTexture.anisotropy = Math.min(4, anisotropy);
|
|
10570
|
-
loadedTexture.needsUpdate = true;
|
|
10790
|
+
configureMipmappedTexture(loadedTexture, anisotropy);
|
|
10571
10791
|
setTexture(loadedTexture);
|
|
10572
10792
|
},
|
|
10573
10793
|
void 0,
|
|
@@ -10739,8 +10959,17 @@ function sphereTileGeometry(address, yawOffset2, radius = DEFAULT_PANORAMA_RADIU
|
|
|
10739
10959
|
geometry.computeBoundingSphere();
|
|
10740
10960
|
return geometry;
|
|
10741
10961
|
}
|
|
10742
|
-
function
|
|
10743
|
-
const
|
|
10962
|
+
function tanHalfFov(verticalFov) {
|
|
10963
|
+
const fov = Math.min(179, Math.max(1, verticalFov));
|
|
10964
|
+
return Math.tan(MathUtils6.degToRad(fov) * 0.5);
|
|
10965
|
+
}
|
|
10966
|
+
function preferredSphereLevel(levels, height, dpr, verticalFov, width = height) {
|
|
10967
|
+
const pixelHeight = Math.max(1, height) * dpr;
|
|
10968
|
+
const pixelWidth = Math.max(1, width) * dpr;
|
|
10969
|
+
const tanHalfV = tanHalfFov(verticalFov);
|
|
10970
|
+
const tanHalfH = pixelWidth / pixelHeight * tanHalfV;
|
|
10971
|
+
const edgeScale = 1 + Math.max(tanHalfV, tanHalfH) ** 2;
|
|
10972
|
+
const needed = pixelHeight * 0.5 / tanHalfV * Math.PI * edgeScale;
|
|
10744
10973
|
const index = levels.findIndex((level) => level.height >= needed);
|
|
10745
10974
|
return index < 0 ? levels.length - 1 : index;
|
|
10746
10975
|
}
|
|
@@ -10841,7 +11070,7 @@ function SphereTileSource({
|
|
|
10841
11070
|
anisotropy,
|
|
10842
11071
|
onPreviewError
|
|
10843
11072
|
);
|
|
10844
|
-
const callbacks =
|
|
11073
|
+
const callbacks = useRef21({
|
|
10845
11074
|
onReady,
|
|
10846
11075
|
onLoadProgress,
|
|
10847
11076
|
onTileError,
|
|
@@ -10874,8 +11103,8 @@ function SphereTileSource({
|
|
|
10874
11103
|
);
|
|
10875
11104
|
const manager = sharedManager ?? ownedManager;
|
|
10876
11105
|
const budget = manager.memoryBudgetBytes;
|
|
10877
|
-
const readyRef =
|
|
10878
|
-
const ready =
|
|
11106
|
+
const readyRef = useRef21(false);
|
|
11107
|
+
const ready = useCallback8(() => {
|
|
10879
11108
|
if (!readyRef.current) {
|
|
10880
11109
|
readyRef.current = true;
|
|
10881
11110
|
callbacks.current.onReady?.();
|
|
@@ -10916,10 +11145,10 @@ function SphereTileSource({
|
|
|
10916
11145
|
);
|
|
10917
11146
|
const [layers, setLayers] = useState10([]);
|
|
10918
11147
|
const detailReporter = useSceneDetailReporter();
|
|
10919
|
-
const detailReporterRef =
|
|
11148
|
+
const detailReporterRef = useRef21(detailReporter);
|
|
10920
11149
|
detailReporterRef.current = detailReporter;
|
|
10921
|
-
const detailTokenRef =
|
|
10922
|
-
const targetKeysRef =
|
|
11150
|
+
const detailTokenRef = useRef21("");
|
|
11151
|
+
const targetKeysRef = useRef21([]);
|
|
10923
11152
|
const scratch = useMemo15(
|
|
10924
11153
|
() => ({
|
|
10925
11154
|
camera: new PerspectiveCamera4(),
|
|
@@ -10968,7 +11197,13 @@ function SphereTileSource({
|
|
|
10968
11197
|
scratch.camera.matrixWorldInverse
|
|
10969
11198
|
);
|
|
10970
11199
|
scratch.frustum.setFromProjectionMatrix(scratch.matrix);
|
|
10971
|
-
let level = loadMode === "preview" ? -1 : loadMode === "base" ? 0 : preferredSphereLevel(
|
|
11200
|
+
let level = loadMode === "preview" ? -1 : loadMode === "base" ? 0 : preferredSphereLevel(
|
|
11201
|
+
config.levels,
|
|
11202
|
+
size.height,
|
|
11203
|
+
dpr,
|
|
11204
|
+
camera.fov,
|
|
11205
|
+
size.width
|
|
11206
|
+
);
|
|
10972
11207
|
const next = [];
|
|
10973
11208
|
let residentBytes = 0;
|
|
10974
11209
|
for (let index = 0; index <= level; index++) {
|
|
@@ -10976,7 +11211,7 @@ function SphereTileSource({
|
|
|
10976
11211
|
({ bounds }) => scratch.frustum.intersectsBox(bounds)
|
|
10977
11212
|
).map(({ address }) => address);
|
|
10978
11213
|
const bytes = addresses.reduce(
|
|
10979
|
-
(total, address) => total + address.width
|
|
11214
|
+
(total, address) => total + mipmappedTextureBytes(address.width, address.height),
|
|
10980
11215
|
0
|
|
10981
11216
|
);
|
|
10982
11217
|
if (residentBytes + bytes > budget) {
|
|
@@ -11042,7 +11277,7 @@ function SphereTile({ multires, ...props }) {
|
|
|
11042
11277
|
|
|
11043
11278
|
// src/tile/tile.tsx
|
|
11044
11279
|
import { useFrame as useFrame12, useThree as useThree15 } from "@react-three/fiber";
|
|
11045
|
-
import { memo as memo2, useEffect as useEffect22, useMemo as useMemo16, useRef as
|
|
11280
|
+
import { memo as memo2, useEffect as useEffect22, useMemo as useMemo16, useRef as useRef22, useState as useState11 } from "react";
|
|
11046
11281
|
import {
|
|
11047
11282
|
Frustum as Frustum2,
|
|
11048
11283
|
Matrix4 as Matrix43,
|
|
@@ -11055,6 +11290,7 @@ import {
|
|
|
11055
11290
|
import {
|
|
11056
11291
|
Box3 as Box32,
|
|
11057
11292
|
Euler as Euler4,
|
|
11293
|
+
MathUtils as MathUtils7,
|
|
11058
11294
|
Quaternion as Quaternion2,
|
|
11059
11295
|
Vector3 as Vector312
|
|
11060
11296
|
} from "three";
|
|
@@ -11149,8 +11385,19 @@ function makeTileAddress(face, level, faceSize, tileSize, col, row) {
|
|
|
11149
11385
|
function tileKey(address) {
|
|
11150
11386
|
return `${address.level}/${address.face}/${address.row}/${address.col}`;
|
|
11151
11387
|
}
|
|
11152
|
-
function
|
|
11153
|
-
const
|
|
11388
|
+
function tanHalfFov2(verticalFov) {
|
|
11389
|
+
const fov = Math.min(179, Math.max(1, verticalFov));
|
|
11390
|
+
return Math.tan(MathUtils7.degToRad(fov) * 0.5);
|
|
11391
|
+
}
|
|
11392
|
+
function getPreferredLevel(levels, viewportHeight, pixelRatio, verticalFov, currentLevel, viewportWidth = viewportHeight) {
|
|
11393
|
+
const height = Math.max(1, viewportHeight) * pixelRatio;
|
|
11394
|
+
const width = Math.max(1, viewportWidth) * pixelRatio;
|
|
11395
|
+
const tanHalfV = tanHalfFov2(verticalFov);
|
|
11396
|
+
const requiredFaceSize = Math.max(
|
|
11397
|
+
height / tanHalfV,
|
|
11398
|
+
height * tanHalfV,
|
|
11399
|
+
width * width * tanHalfV / height
|
|
11400
|
+
);
|
|
11154
11401
|
let preferredLevel = levels.length;
|
|
11155
11402
|
for (let index = 0; index < levels.length; index += 1) {
|
|
11156
11403
|
if (levels[index] >= requiredFaceSize) {
|
|
@@ -11481,9 +11728,9 @@ function Tile({
|
|
|
11481
11728
|
onPreviewError
|
|
11482
11729
|
);
|
|
11483
11730
|
const sharedManager = useSharedTileTextureManager();
|
|
11484
|
-
const progressRef =
|
|
11485
|
-
const errorRef =
|
|
11486
|
-
const levelChangeRef =
|
|
11731
|
+
const progressRef = useRef22(onLoadProgress);
|
|
11732
|
+
const errorRef = useRef22(onTileError);
|
|
11733
|
+
const levelChangeRef = useRef22(onLevelChange);
|
|
11487
11734
|
progressRef.current = onLoadProgress;
|
|
11488
11735
|
errorRef.current = onTileError;
|
|
11489
11736
|
levelChangeRef.current = onLevelChange;
|
|
@@ -11518,7 +11765,7 @@ function Tile({
|
|
|
11518
11765
|
queueMicrotask(() => manager.releaseUnused());
|
|
11519
11766
|
};
|
|
11520
11767
|
}, [manager, ownedManager]);
|
|
11521
|
-
const readyRef =
|
|
11768
|
+
const readyRef = useRef22(false);
|
|
11522
11769
|
useEffect22(() => {
|
|
11523
11770
|
readyRef.current = false;
|
|
11524
11771
|
}, [effectivePreviewUrl]);
|
|
@@ -11538,21 +11785,21 @@ function Tile({
|
|
|
11538
11785
|
[baseUrl, resolveTileUrl, template]
|
|
11539
11786
|
);
|
|
11540
11787
|
const [layers, setLayers] = useState11([]);
|
|
11541
|
-
const layerTokenRef =
|
|
11542
|
-
const currentLevelRef =
|
|
11543
|
-
const lastUpdateAtRef =
|
|
11544
|
-
const visibilityDirtyRef =
|
|
11545
|
-
const lastVisibilityQuaternionRef =
|
|
11546
|
-
const lastVisibilityFovRef =
|
|
11547
|
-
const lastViewportRef =
|
|
11548
|
-
const frustumRef =
|
|
11549
|
-
const projectionMatrixRef =
|
|
11550
|
-
const visibilityCameraRef =
|
|
11551
|
-
const trackedLoadModeRef =
|
|
11552
|
-
const targetKeysRef =
|
|
11553
|
-
const detailTokenRef =
|
|
11788
|
+
const layerTokenRef = useRef22("");
|
|
11789
|
+
const currentLevelRef = useRef22(1);
|
|
11790
|
+
const lastUpdateAtRef = useRef22(-Infinity);
|
|
11791
|
+
const visibilityDirtyRef = useRef22(true);
|
|
11792
|
+
const lastVisibilityQuaternionRef = useRef22(camera.quaternion.clone());
|
|
11793
|
+
const lastVisibilityFovRef = useRef22(Number.NaN);
|
|
11794
|
+
const lastViewportRef = useRef22({ width: 0, height: 0, dpr: 0 });
|
|
11795
|
+
const frustumRef = useRef22(new Frustum2());
|
|
11796
|
+
const projectionMatrixRef = useRef22(new Matrix43());
|
|
11797
|
+
const visibilityCameraRef = useRef22(new PerspectiveCamera5());
|
|
11798
|
+
const trackedLoadModeRef = useRef22(loadMode);
|
|
11799
|
+
const targetKeysRef = useRef22([]);
|
|
11800
|
+
const detailTokenRef = useRef22("");
|
|
11554
11801
|
const detailReporter = useSceneDetailReporter();
|
|
11555
|
-
const detailReporterRef =
|
|
11802
|
+
const detailReporterRef = useRef22(detailReporter);
|
|
11556
11803
|
detailReporterRef.current = detailReporter;
|
|
11557
11804
|
useEffect22(() => {
|
|
11558
11805
|
currentLevelRef.current = 1;
|
|
@@ -11610,7 +11857,8 @@ function Tile({
|
|
|
11610
11857
|
size.height,
|
|
11611
11858
|
pixelRatio,
|
|
11612
11859
|
camera.fov,
|
|
11613
|
-
currentLevelRef.current
|
|
11860
|
+
currentLevelRef.current,
|
|
11861
|
+
size.width
|
|
11614
11862
|
);
|
|
11615
11863
|
if (targetLevel !== currentLevelRef.current) {
|
|
11616
11864
|
currentLevelRef.current = targetLevel;
|
|
@@ -11736,8 +11984,8 @@ function SnapshotCapture({
|
|
|
11736
11984
|
onCaptured
|
|
11737
11985
|
}) {
|
|
11738
11986
|
const { camera, gl, scene, size } = useThree16();
|
|
11739
|
-
const capturedRequestRef =
|
|
11740
|
-
const renderTargetRef =
|
|
11987
|
+
const capturedRequestRef = useRef23(0);
|
|
11988
|
+
const renderTargetRef = useRef23(null);
|
|
11741
11989
|
useEffect23(
|
|
11742
11990
|
() => () => {
|
|
11743
11991
|
renderTargetRef.current?.dispose();
|
|
@@ -11761,8 +12009,8 @@ function SnapshotCapture({
|
|
|
11761
12009
|
});
|
|
11762
12010
|
nextTarget.texture.colorSpace = LinearSRGBColorSpace;
|
|
11763
12011
|
nextTarget.texture.generateMipmaps = false;
|
|
11764
|
-
nextTarget.texture.minFilter =
|
|
11765
|
-
nextTarget.texture.magFilter =
|
|
12012
|
+
nextTarget.texture.minFilter = LinearFilter3;
|
|
12013
|
+
nextTarget.texture.magFilter = LinearFilter3;
|
|
11766
12014
|
const previousTarget = gl.getRenderTarget();
|
|
11767
12015
|
gl.setRenderTarget(nextTarget);
|
|
11768
12016
|
gl.clear();
|
|
@@ -11819,20 +12067,20 @@ function ScenesController({
|
|
|
11819
12067
|
const [transitionRunId, setTransitionRunId] = useState12(0);
|
|
11820
12068
|
const [snapshot, setSnapshot] = useState12(null);
|
|
11821
12069
|
const [recoveryKey, setRecoveryKey] = useState12(0);
|
|
11822
|
-
const requestedSceneIdRef =
|
|
11823
|
-
const captureReasonRef =
|
|
11824
|
-
const interactionReleaseRef =
|
|
11825
|
-
const slotsRef =
|
|
11826
|
-
const phaseRef =
|
|
11827
|
-
const liveSlotRef =
|
|
11828
|
-
const transitionFromRef =
|
|
11829
|
-
const readySceneRef =
|
|
11830
|
-
const waitRef =
|
|
11831
|
-
const waitTimerRef =
|
|
11832
|
-
const detailGenerationRef =
|
|
12070
|
+
const requestedSceneIdRef = useRef23(activeSceneId);
|
|
12071
|
+
const captureReasonRef = useRef23("start");
|
|
12072
|
+
const interactionReleaseRef = useRef23(null);
|
|
12073
|
+
const slotsRef = useRef23(slots);
|
|
12074
|
+
const phaseRef = useRef23(phase);
|
|
12075
|
+
const liveSlotRef = useRef23(liveSlot);
|
|
12076
|
+
const transitionFromRef = useRef23(initialScene);
|
|
12077
|
+
const readySceneRef = useRef23(null);
|
|
12078
|
+
const waitRef = useRef23(null);
|
|
12079
|
+
const waitTimerRef = useRef23(null);
|
|
12080
|
+
const detailGenerationRef = useRef23(0);
|
|
11833
12081
|
const [detailGeneration, setDetailGeneration] = useState12(0);
|
|
11834
|
-
const mountedRef =
|
|
11835
|
-
const waitForDetailMsRef =
|
|
12082
|
+
const mountedRef = useRef23(true);
|
|
12083
|
+
const waitForDetailMsRef = useRef23(0);
|
|
11836
12084
|
waitForDetailMsRef.current = normalizeTransitionWaitMs(transitionWaitForDetailMs);
|
|
11837
12085
|
slotsRef.current = slots;
|
|
11838
12086
|
phaseRef.current = phase;
|
|
@@ -11847,14 +12095,14 @@ function ScenesController({
|
|
|
11847
12095
|
useEffect23(() => () => {
|
|
11848
12096
|
controlsRef?.current?.setSceneViewLimits(void 0);
|
|
11849
12097
|
}, [controlsRef]);
|
|
11850
|
-
const releaseInteraction =
|
|
12098
|
+
const releaseInteraction = useCallback9(() => {
|
|
11851
12099
|
interactionReleaseRef.current?.();
|
|
11852
12100
|
interactionReleaseRef.current = null;
|
|
11853
12101
|
}, []);
|
|
11854
|
-
const reportError =
|
|
12102
|
+
const reportError = useCallback9((sceneId, error) => {
|
|
11855
12103
|
onTransitionError?.({ sceneId, error });
|
|
11856
12104
|
}, [onTransitionError]);
|
|
11857
|
-
const clearDetailWait =
|
|
12105
|
+
const clearDetailWait = useCallback9((bumpGeneration) => {
|
|
11858
12106
|
if (waitTimerRef.current !== null) {
|
|
11859
12107
|
clearTimeout(waitTimerRef.current);
|
|
11860
12108
|
waitTimerRef.current = null;
|
|
@@ -11882,7 +12130,7 @@ function ScenesController({
|
|
|
11882
12130
|
clearDetailWait(false);
|
|
11883
12131
|
};
|
|
11884
12132
|
}, [clearDetailWait]);
|
|
11885
|
-
const startPreload =
|
|
12133
|
+
const startPreload = useCallback9((scene) => {
|
|
11886
12134
|
clearDetailWait(true);
|
|
11887
12135
|
const nextSlot = 1 - liveSlotRef.current;
|
|
11888
12136
|
requestedSceneIdRef.current = scene.id;
|
|
@@ -11920,13 +12168,13 @@ function ScenesController({
|
|
|
11920
12168
|
}
|
|
11921
12169
|
startPreload(requested);
|
|
11922
12170
|
}, [activeSceneId, clearDetailWait, pendingSlot, reportError, sceneMap, startPreload]);
|
|
11923
|
-
const notifySceneReady =
|
|
12171
|
+
const notifySceneReady = useCallback9((scene) => {
|
|
11924
12172
|
if (!scene || readySceneRef.current === scene) return;
|
|
11925
12173
|
readySceneRef.current = scene;
|
|
11926
12174
|
controlsRef?.current?.setSceneViewLimits(sceneMap.get(scene.id)?.viewLimits);
|
|
11927
12175
|
onSceneReady?.(scene.id);
|
|
11928
12176
|
}, [controlsRef, onSceneReady, sceneMap]);
|
|
11929
|
-
const handleReady =
|
|
12177
|
+
const handleReady = useCallback9((slot) => {
|
|
11930
12178
|
if (slot === liveSlotRef.current && pendingSlot === null && phaseRef.current === "idle") {
|
|
11931
12179
|
notifySceneReady(slotsRef.current[slot]);
|
|
11932
12180
|
return;
|
|
@@ -11962,7 +12210,7 @@ function ScenesController({
|
|
|
11962
12210
|
setPhase("capturing");
|
|
11963
12211
|
setCaptureRequestId((current) => current + 1);
|
|
11964
12212
|
}, [controlsRef, notifySceneReady, onTransitionEnd, pendingSlot, transition.preset]);
|
|
11965
|
-
const finishTransition =
|
|
12213
|
+
const finishTransition = useCallback9(() => {
|
|
11966
12214
|
const nextSlot = pendingSlot;
|
|
11967
12215
|
const previousScene = transitionFromRef.current;
|
|
11968
12216
|
const nextScene = nextSlot === null ? null : slotsRef.current[nextSlot];
|
|
@@ -11987,11 +12235,11 @@ function ScenesController({
|
|
|
11987
12235
|
});
|
|
11988
12236
|
}
|
|
11989
12237
|
}, [onTransitionEnd, pendingSlot, releaseInteraction, snapshot, transition.preset]);
|
|
11990
|
-
const finishTransitionRef =
|
|
12238
|
+
const finishTransitionRef = useRef23(finishTransition);
|
|
11991
12239
|
finishTransitionRef.current = finishTransition;
|
|
11992
|
-
const transitionRef =
|
|
12240
|
+
const transitionRef = useRef23(transition);
|
|
11993
12241
|
transitionRef.current = transition;
|
|
11994
|
-
const consumeDetailSignal =
|
|
12242
|
+
const consumeDetailSignal = useCallback9((signal) => {
|
|
11995
12243
|
const decision = acceptDetailWait(waitRef.current, signal);
|
|
11996
12244
|
waitRef.current = decision.wait;
|
|
11997
12245
|
if (!decision.start) {
|
|
@@ -12011,7 +12259,7 @@ function ScenesController({
|
|
|
12011
12259
|
setPhase("transitioning");
|
|
12012
12260
|
setTransitionRunId((current) => current + 1);
|
|
12013
12261
|
}, []);
|
|
12014
|
-
const handleCaptured =
|
|
12262
|
+
const handleCaptured = useCallback9((nextSnapshot) => {
|
|
12015
12263
|
if (captureReasonRef.current === "interrupt") {
|
|
12016
12264
|
setSnapshot((current) => {
|
|
12017
12265
|
current?.dispose();
|
|
@@ -12109,7 +12357,7 @@ function ScenesController({
|
|
|
12109
12357
|
startPreload,
|
|
12110
12358
|
transition.preset
|
|
12111
12359
|
]);
|
|
12112
|
-
const snapshotRef =
|
|
12360
|
+
const snapshotRef = useRef23(snapshot);
|
|
12113
12361
|
snapshotRef.current = snapshot;
|
|
12114
12362
|
useEffect23(() => () => {
|
|
12115
12363
|
releaseInteraction();
|
|
@@ -12162,7 +12410,7 @@ ${slots[1]?.id ?? ""}`;
|
|
|
12162
12410
|
}
|
|
12163
12411
|
}));
|
|
12164
12412
|
}, [consumeDetailSignal, detailGeneration, slotSceneKey]);
|
|
12165
|
-
return /* @__PURE__ */ jsxs13(
|
|
12413
|
+
return /* @__PURE__ */ jsxs13(Fragment6, { children: [
|
|
12166
12414
|
/* @__PURE__ */ jsx23(
|
|
12167
12415
|
SnapshotCapture,
|
|
12168
12416
|
{
|
|
@@ -12225,7 +12473,7 @@ function Scenes({
|
|
|
12225
12473
|
() => controlledId ?? defaultActiveSceneId ?? scenes[0]?.id ?? ""
|
|
12226
12474
|
);
|
|
12227
12475
|
const resolvedId = isControlled ? controlledId : internalId;
|
|
12228
|
-
const requestSceneChange =
|
|
12476
|
+
const requestSceneChange = useCallback9(
|
|
12229
12477
|
(id) => {
|
|
12230
12478
|
if (isControlled) {
|
|
12231
12479
|
onActiveSceneIdChange?.(id);
|
|
@@ -12235,12 +12483,12 @@ function Scenes({
|
|
|
12235
12483
|
},
|
|
12236
12484
|
[isControlled, onActiveSceneIdChange]
|
|
12237
12485
|
);
|
|
12238
|
-
const scenesRef =
|
|
12486
|
+
const scenesRef = useRef23(scenes);
|
|
12239
12487
|
scenesRef.current = scenes;
|
|
12240
|
-
const resolvedIdRef =
|
|
12488
|
+
const resolvedIdRef = useRef23(resolvedId);
|
|
12241
12489
|
resolvedIdRef.current = resolvedId;
|
|
12242
12490
|
const host = useContext19(ScenesHostContext);
|
|
12243
|
-
const phaseRef =
|
|
12491
|
+
const phaseRef = useRef23("idle");
|
|
12244
12492
|
useEffect23(() => {
|
|
12245
12493
|
if (!host) {
|
|
12246
12494
|
return;
|
|
@@ -12311,12 +12559,12 @@ function Scenes({
|
|
|
12311
12559
|
|
|
12312
12560
|
// src/hotspot/image-hotspot.tsx
|
|
12313
12561
|
import { useThree as useThree20 } from "@react-three/fiber";
|
|
12314
|
-
import { useEffect as useEffect26, useRef as
|
|
12562
|
+
import { useEffect as useEffect26, useRef as useRef27, useState as useState15 } from "react";
|
|
12315
12563
|
import {
|
|
12316
|
-
ClampToEdgeWrapping as
|
|
12317
|
-
LinearFilter as
|
|
12318
|
-
LinearMipmapLinearFilter as
|
|
12319
|
-
SRGBColorSpace as
|
|
12564
|
+
ClampToEdgeWrapping as ClampToEdgeWrapping2,
|
|
12565
|
+
LinearFilter as LinearFilter4,
|
|
12566
|
+
LinearMipmapLinearFilter as LinearMipmapLinearFilter3,
|
|
12567
|
+
SRGBColorSpace as SRGBColorSpace3,
|
|
12320
12568
|
TextureLoader as TextureLoader4
|
|
12321
12569
|
} from "three";
|
|
12322
12570
|
|
|
@@ -12327,13 +12575,13 @@ import {
|
|
|
12327
12575
|
useEffect as useEffect25,
|
|
12328
12576
|
useLayoutEffect as useLayoutEffect7,
|
|
12329
12577
|
useMemo as useMemo19,
|
|
12330
|
-
useRef as
|
|
12578
|
+
useRef as useRef26,
|
|
12331
12579
|
useState as useState14
|
|
12332
12580
|
} from "react";
|
|
12333
12581
|
import {
|
|
12334
12582
|
Box3 as Box34,
|
|
12335
12583
|
EdgesGeometry,
|
|
12336
|
-
MathUtils as
|
|
12584
|
+
MathUtils as MathUtils10,
|
|
12337
12585
|
Matrix4 as Matrix44,
|
|
12338
12586
|
PerspectiveCamera as PerspectiveCamera8,
|
|
12339
12587
|
Plane,
|
|
@@ -12441,12 +12689,12 @@ import { useFrame as useFrame14, useThree as useThree17 } from "@react-three/fib
|
|
|
12441
12689
|
import {
|
|
12442
12690
|
useContext as useContext20,
|
|
12443
12691
|
useLayoutEffect as useLayoutEffect5,
|
|
12444
|
-
useRef as
|
|
12692
|
+
useRef as useRef24,
|
|
12445
12693
|
useSyncExternalStore as useSyncExternalStore9
|
|
12446
12694
|
} from "react";
|
|
12447
12695
|
import { createRoot } from "react-dom/client";
|
|
12448
12696
|
import { Vector3 as Vector314 } from "three";
|
|
12449
|
-
import { Fragment as
|
|
12697
|
+
import { Fragment as Fragment7, jsx as jsx24, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
12450
12698
|
function useFallbackStereoView() {
|
|
12451
12699
|
const runtime = useContext20(WebVRRuntimeContext);
|
|
12452
12700
|
const host = runtime?.host ?? null;
|
|
@@ -12466,9 +12714,9 @@ function ProjectedHtml({
|
|
|
12466
12714
|
eye
|
|
12467
12715
|
}) {
|
|
12468
12716
|
const { camera, gl, events, size } = useThree17();
|
|
12469
|
-
const group =
|
|
12470
|
-
const overlay =
|
|
12471
|
-
const scratch =
|
|
12717
|
+
const group = useRef24(null);
|
|
12718
|
+
const overlay = useRef24(null);
|
|
12719
|
+
const scratch = useRef24(new Vector314());
|
|
12472
12720
|
const target = events.connected || gl.domElement.parentElement;
|
|
12473
12721
|
const updatePosition = () => {
|
|
12474
12722
|
const anchor = group.current;
|
|
@@ -12543,7 +12791,7 @@ function PanoHtml(props) {
|
|
|
12543
12791
|
if (mode === "mobilevr" && portrait) {
|
|
12544
12792
|
return null;
|
|
12545
12793
|
}
|
|
12546
|
-
return stereoView ? /* @__PURE__ */ jsxs14(
|
|
12794
|
+
return stereoView ? /* @__PURE__ */ jsxs14(Fragment7, { children: [
|
|
12547
12795
|
/* @__PURE__ */ jsx24(ProjectedHtml, { ...props, stereoView, eye: "left" }),
|
|
12548
12796
|
/* @__PURE__ */ jsx24(ProjectedHtml, { ...props, stereoView, eye: "right" })
|
|
12549
12797
|
] }) : /* @__PURE__ */ jsx24(ProjectedHtml, { ...props });
|
|
@@ -12680,7 +12928,7 @@ function HotspotTooltip({
|
|
|
12680
12928
|
|
|
12681
12929
|
// src/hotspot/transform.ts
|
|
12682
12930
|
import {
|
|
12683
|
-
MathUtils as
|
|
12931
|
+
MathUtils as MathUtils8,
|
|
12684
12932
|
PerspectiveCamera as PerspectiveCamera6,
|
|
12685
12933
|
Vector3 as Vector315
|
|
12686
12934
|
} from "three";
|
|
@@ -12692,7 +12940,7 @@ function applyHotspotTransform(group, camera, orientation2, surfaceQuaternion3,
|
|
|
12692
12940
|
} else {
|
|
12693
12941
|
group.quaternion.copy(surfaceQuaternion3);
|
|
12694
12942
|
}
|
|
12695
|
-
group.rotateOnAxis(LOCAL_FORWARD,
|
|
12943
|
+
group.rotateOnAxis(LOCAL_FORWARD, MathUtils8.degToRad(-rotation));
|
|
12696
12944
|
let scaleFactor = scaleMode === "fixed" && camera instanceof PerspectiveCamera6 ? fixedScaleFactor(camera.fov, referenceFov) : 1;
|
|
12697
12945
|
if (scaleMode === "fixed" && orientation2 === "billboard" && useAngularScale && camera instanceof PerspectiveCamera6) {
|
|
12698
12946
|
group.updateWorldMatrix(true, false);
|
|
@@ -12709,15 +12957,15 @@ function applyHotspotTransform(group, camera, orientation2, surfaceQuaternion3,
|
|
|
12709
12957
|
group.updateMatrixWorld();
|
|
12710
12958
|
}
|
|
12711
12959
|
function fixedScaleFactor(cameraFov, referenceFov) {
|
|
12712
|
-
const safeReferenceFov =
|
|
12713
|
-
return Math.tan(
|
|
12960
|
+
const safeReferenceFov = MathUtils8.clamp(referenceFov, 1, 179);
|
|
12961
|
+
return Math.tan(MathUtils8.degToRad(cameraFov) / 2) / Math.tan(MathUtils8.degToRad(safeReferenceFov) / 2);
|
|
12714
12962
|
}
|
|
12715
12963
|
function selectionFrameScale(worldScaleX, worldScaleY, cameraSpaceDepth, fovDegrees, viewportHeight, outsetPixels) {
|
|
12716
12964
|
const pixels = Number.isFinite(outsetPixels) && outsetPixels > 0 ? outsetPixels : 0;
|
|
12717
12965
|
const depth = Number.isFinite(cameraSpaceDepth) ? Math.max(cameraSpaceDepth, 1e-4) : 1e-4;
|
|
12718
12966
|
const height = Number.isFinite(viewportHeight) ? Math.max(viewportHeight, 1) : 1;
|
|
12719
|
-
const fov = Number.isFinite(fovDegrees) ?
|
|
12720
|
-
const pixelsPerWorldUnit = height / (2 * Math.tan(
|
|
12967
|
+
const fov = Number.isFinite(fovDegrees) ? MathUtils8.clamp(fovDegrees, 1, 179) : 75;
|
|
12968
|
+
const pixelsPerWorldUnit = height / (2 * Math.tan(MathUtils8.degToRad(fov) * 0.5) * depth);
|
|
12721
12969
|
const axis = (worldScale) => {
|
|
12722
12970
|
const pixelsPerLocalUnit = pixelsPerWorldUnit * Math.abs(worldScale);
|
|
12723
12971
|
if (pixelsPerLocalUnit < 1e-4) {
|
|
@@ -12731,9 +12979,9 @@ function selectionFrameScale(worldScaleX, worldScaleY, cameraSpaceDepth, fovDegr
|
|
|
12731
12979
|
// src/hotspot/hotspot-stroke-line.tsx
|
|
12732
12980
|
import { Line } from "@react-three/drei";
|
|
12733
12981
|
import { useFrame as useFrame15, useThree as useThree18 } from "@react-three/fiber";
|
|
12734
|
-
import { useLayoutEffect as useLayoutEffect6, useRef as
|
|
12982
|
+
import { useLayoutEffect as useLayoutEffect6, useRef as useRef25 } from "react";
|
|
12735
12983
|
import {
|
|
12736
|
-
MathUtils as
|
|
12984
|
+
MathUtils as MathUtils9,
|
|
12737
12985
|
PerspectiveCamera as PerspectiveCamera7,
|
|
12738
12986
|
Vector3 as Vector316
|
|
12739
12987
|
} from "three";
|
|
@@ -12747,7 +12995,7 @@ function applyScreenSpaceDashScale(object, camera, viewportHeight) {
|
|
|
12747
12995
|
object.getWorldPosition(LINE_WORLD_POSITION);
|
|
12748
12996
|
const depth = Math.max(camera.position.distanceTo(LINE_WORLD_POSITION), 1);
|
|
12749
12997
|
const fov = camera instanceof PerspectiveCamera7 ? camera.fov : 75;
|
|
12750
|
-
material.dashScale = viewportHeight / (2 * Math.tan(
|
|
12998
|
+
material.dashScale = viewportHeight / (2 * Math.tan(MathUtils9.degToRad(fov) * 0.5) * depth);
|
|
12751
12999
|
}
|
|
12752
13000
|
function resolveDash(dashSize, gapSize) {
|
|
12753
13001
|
if (dashSize === void 0 || !Number.isFinite(dashSize) || dashSize <= 0) {
|
|
@@ -12768,7 +13016,7 @@ function HotspotStrokeLine({
|
|
|
12768
13016
|
dashSize,
|
|
12769
13017
|
gapSize
|
|
12770
13018
|
}) {
|
|
12771
|
-
const lineRef =
|
|
13019
|
+
const lineRef = useRef25(null);
|
|
12772
13020
|
const { camera, size } = useThree18();
|
|
12773
13021
|
const dash = resolveDash(dashSize, gapSize);
|
|
12774
13022
|
useLayoutEffect6(() => {
|
|
@@ -12844,8 +13092,8 @@ var HOTSPOT_MODE_RENDERING = {
|
|
|
12844
13092
|
billboard: { orientation: "billboard", placement: "floating" }
|
|
12845
13093
|
};
|
|
12846
13094
|
function angularSizeToWorldSize(size, radius) {
|
|
12847
|
-
const safeSize = Number.isFinite(size) ?
|
|
12848
|
-
return 2 * radius * Math.tan(
|
|
13095
|
+
const safeSize = Number.isFinite(size) ? MathUtils10.clamp(Math.abs(size), MIN_ANGULAR_SIZE, MAX_ANGULAR_SIZE) : MIN_ANGULAR_SIZE;
|
|
13096
|
+
return 2 * radius * Math.tan(MathUtils10.degToRad(safeSize) / 2);
|
|
12849
13097
|
}
|
|
12850
13098
|
function resolveScale(scale) {
|
|
12851
13099
|
return Number.isFinite(scale) && scale > 0 ? scale : 1;
|
|
@@ -12858,31 +13106,31 @@ function resolveDistance(placement, distance, width, height) {
|
|
|
12858
13106
|
if (!Number.isFinite(distance)) {
|
|
12859
13107
|
return DEFAULT_FLOATING_DISTANCE;
|
|
12860
13108
|
}
|
|
12861
|
-
return
|
|
13109
|
+
return MathUtils10.clamp(Math.abs(distance), 0.1, maximumDistance);
|
|
12862
13110
|
}
|
|
12863
13111
|
function maximumHotspotDistance(width, height) {
|
|
12864
|
-
const safeWidth =
|
|
13112
|
+
const safeWidth = MathUtils10.clamp(
|
|
12865
13113
|
Math.abs(Number.isFinite(width) ? width : MIN_ANGULAR_SIZE),
|
|
12866
13114
|
MIN_ANGULAR_SIZE,
|
|
12867
13115
|
MAX_ANGULAR_SIZE
|
|
12868
13116
|
);
|
|
12869
|
-
const safeHeight =
|
|
13117
|
+
const safeHeight = MathUtils10.clamp(
|
|
12870
13118
|
Math.abs(Number.isFinite(height) ? height : MIN_ANGULAR_SIZE),
|
|
12871
13119
|
MIN_ANGULAR_SIZE,
|
|
12872
13120
|
MAX_ANGULAR_SIZE
|
|
12873
13121
|
);
|
|
12874
13122
|
const cornerFactor = Math.hypot(
|
|
12875
13123
|
1,
|
|
12876
|
-
Math.tan(
|
|
12877
|
-
Math.tan(
|
|
13124
|
+
Math.tan(MathUtils10.degToRad(safeWidth) / 2),
|
|
13125
|
+
Math.tan(MathUtils10.degToRad(safeHeight) / 2)
|
|
12878
13126
|
);
|
|
12879
13127
|
return (PANORAMA_RADIUS - PANORAMA_SURFACE_INSET) / cornerFactor;
|
|
12880
13128
|
}
|
|
12881
13129
|
function createSurfaceQuaternion(position) {
|
|
12882
13130
|
const outward = panoPositionToVector3(position).normalize();
|
|
12883
13131
|
const inward = outward.clone().negate();
|
|
12884
|
-
const pitch =
|
|
12885
|
-
const yaw =
|
|
13132
|
+
const pitch = MathUtils10.degToRad(position.pitch);
|
|
13133
|
+
const yaw = MathUtils10.degToRad(position.yaw);
|
|
12886
13134
|
const localUp = new Vector317(
|
|
12887
13135
|
-Math.sin(pitch) * Math.sin(yaw),
|
|
12888
13136
|
Math.cos(pitch),
|
|
@@ -12903,7 +13151,7 @@ function makeInteractionEvent(id, position, event) {
|
|
|
12903
13151
|
function angularDistance(a, b) {
|
|
12904
13152
|
const aVector = panoPositionToVector3(a);
|
|
12905
13153
|
const bVector = panoPositionToVector3(b);
|
|
12906
|
-
return
|
|
13154
|
+
return MathUtils10.radToDeg(aVector.angleTo(bVector));
|
|
12907
13155
|
}
|
|
12908
13156
|
var DRAG_POINTER = new Vector24();
|
|
12909
13157
|
var DRAG_RAYCASTER = new Raycaster2();
|
|
@@ -13186,13 +13434,13 @@ function HotspotAnchor({
|
|
|
13186
13434
|
const eventBus = useContext21(PanoEventBusContext);
|
|
13187
13435
|
const cursorApi = usePanoCursor();
|
|
13188
13436
|
const { camera, gl, size } = useThree19();
|
|
13189
|
-
const groupRef =
|
|
13190
|
-
const selectionFrameRef =
|
|
13191
|
-
const tooltipAnchorRef =
|
|
13192
|
-
const dragStateRef =
|
|
13193
|
-
const updateDragRef =
|
|
13194
|
-
const endDragRef =
|
|
13195
|
-
const suppressNextClickRef =
|
|
13437
|
+
const groupRef = useRef26(null);
|
|
13438
|
+
const selectionFrameRef = useRef26(null);
|
|
13439
|
+
const tooltipAnchorRef = useRef26(null);
|
|
13440
|
+
const dragStateRef = useRef26(null);
|
|
13441
|
+
const updateDragRef = useRef26(() => void 0);
|
|
13442
|
+
const endDragRef = useRef26(() => void 0);
|
|
13443
|
+
const suppressNextClickRef = useRef26(false);
|
|
13196
13444
|
const [hovered, setHovered] = useState14(false);
|
|
13197
13445
|
const [dragging, setDragging] = useState14(false);
|
|
13198
13446
|
const [pinned, setPinned] = useState14(false);
|
|
@@ -13234,7 +13482,7 @@ function HotspotAnchor({
|
|
|
13234
13482
|
planeGeometry.dispose();
|
|
13235
13483
|
return geometry;
|
|
13236
13484
|
}, []);
|
|
13237
|
-
const eventHovered =
|
|
13485
|
+
const eventHovered = useRef26(false);
|
|
13238
13486
|
useEffect25(() => {
|
|
13239
13487
|
if (!visible || !interactive || pointerEvents === "none") eventHovered.current = false;
|
|
13240
13488
|
}, [visible, interactive, pointerEvents]);
|
|
@@ -13752,8 +14000,8 @@ import { jsx as jsx29 } from "react/jsx-runtime";
|
|
|
13752
14000
|
function useHotspotImageTexture(src, onLoad, onError) {
|
|
13753
14001
|
const gl = useThree20((state) => state.gl);
|
|
13754
14002
|
const [texture, setTexture] = useState15(null);
|
|
13755
|
-
const onLoadRef =
|
|
13756
|
-
const onErrorRef =
|
|
14003
|
+
const onLoadRef = useRef27(onLoad);
|
|
14004
|
+
const onErrorRef = useRef27(onError);
|
|
13757
14005
|
onLoadRef.current = onLoad;
|
|
13758
14006
|
onErrorRef.current = onError;
|
|
13759
14007
|
useEffect26(() => {
|
|
@@ -13772,11 +14020,11 @@ function useHotspotImageTexture(src, onLoad, onError) {
|
|
|
13772
14020
|
loadedTexture.dispose();
|
|
13773
14021
|
return;
|
|
13774
14022
|
}
|
|
13775
|
-
loadedTexture.colorSpace =
|
|
13776
|
-
loadedTexture.wrapS =
|
|
13777
|
-
loadedTexture.wrapT =
|
|
13778
|
-
loadedTexture.magFilter =
|
|
13779
|
-
loadedTexture.minFilter =
|
|
14023
|
+
loadedTexture.colorSpace = SRGBColorSpace3;
|
|
14024
|
+
loadedTexture.wrapS = ClampToEdgeWrapping2;
|
|
14025
|
+
loadedTexture.wrapT = ClampToEdgeWrapping2;
|
|
14026
|
+
loadedTexture.magFilter = LinearFilter4;
|
|
14027
|
+
loadedTexture.minFilter = LinearMipmapLinearFilter3;
|
|
13780
14028
|
loadedTexture.generateMipmaps = true;
|
|
13781
14029
|
loadedTexture.anisotropy = gl.capabilities.getMaxAnisotropy();
|
|
13782
14030
|
loadedTexture.needsUpdate = true;
|
|
@@ -13816,13 +14064,13 @@ function ImageHotspot({
|
|
|
13816
14064
|
}
|
|
13817
14065
|
|
|
13818
14066
|
// src/hotspot/graphic-hotspot.tsx
|
|
13819
|
-
import { useEffect as useEffect27, useRef as
|
|
14067
|
+
import { useEffect as useEffect27, useRef as useRef28, useState as useState16 } from "react";
|
|
13820
14068
|
import {
|
|
13821
14069
|
CanvasTexture,
|
|
13822
|
-
ClampToEdgeWrapping as
|
|
13823
|
-
LinearFilter as
|
|
13824
|
-
LinearMipmapLinearFilter as
|
|
13825
|
-
SRGBColorSpace as
|
|
14070
|
+
ClampToEdgeWrapping as ClampToEdgeWrapping3,
|
|
14071
|
+
LinearFilter as LinearFilter5,
|
|
14072
|
+
LinearMipmapLinearFilter as LinearMipmapLinearFilter4,
|
|
14073
|
+
SRGBColorSpace as SRGBColorSpace4
|
|
13826
14074
|
} from "three";
|
|
13827
14075
|
import { jsx as jsx30 } from "react/jsx-runtime";
|
|
13828
14076
|
var GRAPHIC_TEXTURE_SIZE = 512;
|
|
@@ -14003,19 +14251,19 @@ function createGraphicTexture(graphic, aspectWidth, aspectHeight) {
|
|
|
14003
14251
|
}
|
|
14004
14252
|
drawGraphic(context, graphic, aspectWidth, aspectHeight);
|
|
14005
14253
|
const texture = new CanvasTexture(canvas);
|
|
14006
|
-
texture.colorSpace =
|
|
14007
|
-
texture.wrapS =
|
|
14008
|
-
texture.wrapT =
|
|
14009
|
-
texture.magFilter =
|
|
14010
|
-
texture.minFilter =
|
|
14254
|
+
texture.colorSpace = SRGBColorSpace4;
|
|
14255
|
+
texture.wrapS = ClampToEdgeWrapping3;
|
|
14256
|
+
texture.wrapT = ClampToEdgeWrapping3;
|
|
14257
|
+
texture.magFilter = LinearFilter5;
|
|
14258
|
+
texture.minFilter = LinearMipmapLinearFilter4;
|
|
14011
14259
|
texture.generateMipmaps = true;
|
|
14012
14260
|
texture.needsUpdate = true;
|
|
14013
14261
|
return texture;
|
|
14014
14262
|
}
|
|
14015
14263
|
function useGraphicTexture(graphic, aspectWidth, aspectHeight, onLoad, onError) {
|
|
14016
14264
|
const [texture, setTexture] = useState16(null);
|
|
14017
|
-
const onLoadRef =
|
|
14018
|
-
const onErrorRef =
|
|
14265
|
+
const onLoadRef = useRef28(onLoad);
|
|
14266
|
+
const onErrorRef = useRef28(onError);
|
|
14019
14267
|
onLoadRef.current = onLoad;
|
|
14020
14268
|
onErrorRef.current = onError;
|
|
14021
14269
|
useEffect27(() => {
|
|
@@ -14057,12 +14305,12 @@ function GraphicHotspot(props) {
|
|
|
14057
14305
|
|
|
14058
14306
|
// src/hotspot/sequence-hotspot.tsx
|
|
14059
14307
|
import { useFrame as useFrame17, useThree as useThree21 } from "@react-three/fiber";
|
|
14060
|
-
import { useEffect as useEffect28, useRef as
|
|
14308
|
+
import { useEffect as useEffect28, useRef as useRef29, useState as useState17 } from "react";
|
|
14061
14309
|
import {
|
|
14062
|
-
ClampToEdgeWrapping as
|
|
14063
|
-
LinearFilter as
|
|
14064
|
-
LinearMipmapLinearFilter as
|
|
14065
|
-
SRGBColorSpace as
|
|
14310
|
+
ClampToEdgeWrapping as ClampToEdgeWrapping4,
|
|
14311
|
+
LinearFilter as LinearFilter6,
|
|
14312
|
+
LinearMipmapLinearFilter as LinearMipmapLinearFilter5,
|
|
14313
|
+
SRGBColorSpace as SRGBColorSpace5,
|
|
14066
14314
|
TextureLoader as TextureLoader5
|
|
14067
14315
|
} from "three";
|
|
14068
14316
|
import { jsx as jsx31 } from "react/jsx-runtime";
|
|
@@ -14081,8 +14329,8 @@ function useSpriteTexture({
|
|
|
14081
14329
|
}) {
|
|
14082
14330
|
const gl = useThree21((state) => state.gl);
|
|
14083
14331
|
const [texture, setTexture] = useState17(null);
|
|
14084
|
-
const onErrorRef =
|
|
14085
|
-
const onLoadProgressRef =
|
|
14332
|
+
const onErrorRef = useRef29(onError);
|
|
14333
|
+
const onLoadProgressRef = useRef29(onLoadProgress);
|
|
14086
14334
|
onErrorRef.current = onError;
|
|
14087
14335
|
onLoadProgressRef.current = onLoadProgress;
|
|
14088
14336
|
useEffect28(() => {
|
|
@@ -14102,11 +14350,11 @@ function useSpriteTexture({
|
|
|
14102
14350
|
loadedTexture.dispose();
|
|
14103
14351
|
return;
|
|
14104
14352
|
}
|
|
14105
|
-
loadedTexture.colorSpace =
|
|
14106
|
-
loadedTexture.wrapS =
|
|
14107
|
-
loadedTexture.wrapT =
|
|
14108
|
-
loadedTexture.magFilter =
|
|
14109
|
-
loadedTexture.minFilter =
|
|
14353
|
+
loadedTexture.colorSpace = SRGBColorSpace5;
|
|
14354
|
+
loadedTexture.wrapS = ClampToEdgeWrapping4;
|
|
14355
|
+
loadedTexture.wrapT = ClampToEdgeWrapping4;
|
|
14356
|
+
loadedTexture.magFilter = LinearFilter6;
|
|
14357
|
+
loadedTexture.minFilter = LinearMipmapLinearFilter5;
|
|
14110
14358
|
loadedTexture.generateMipmaps = true;
|
|
14111
14359
|
loadedTexture.anisotropy = gl.capabilities.getMaxAnisotropy();
|
|
14112
14360
|
loadedTexture.needsUpdate = true;
|
|
@@ -14156,13 +14404,13 @@ function SequenceHotspot({
|
|
|
14156
14404
|
const frameCount = resolveFrameCount(requestedFrameCount);
|
|
14157
14405
|
const safeFps = resolveFps(fps);
|
|
14158
14406
|
const [frameIndex, setFrameIndex] = useState17(0);
|
|
14159
|
-
const elapsedRef =
|
|
14160
|
-
const frameIndexRef =
|
|
14161
|
-
const endedRef =
|
|
14162
|
-
const lastPlaybackStateRef =
|
|
14163
|
-
const onFrameChangeRef =
|
|
14164
|
-
const onPlaybackStateChangeRef =
|
|
14165
|
-
const onEndedRef =
|
|
14407
|
+
const elapsedRef = useRef29(0);
|
|
14408
|
+
const frameIndexRef = useRef29(0);
|
|
14409
|
+
const endedRef = useRef29(false);
|
|
14410
|
+
const lastPlaybackStateRef = useRef29(null);
|
|
14411
|
+
const onFrameChangeRef = useRef29(onFrameChange);
|
|
14412
|
+
const onPlaybackStateChangeRef = useRef29(onPlaybackStateChange);
|
|
14413
|
+
const onEndedRef = useRef29(onEnded);
|
|
14166
14414
|
onFrameChangeRef.current = onFrameChange;
|
|
14167
14415
|
onPlaybackStateChangeRef.current = onPlaybackStateChange;
|
|
14168
14416
|
onEndedRef.current = onEnded;
|
|
@@ -14246,12 +14494,12 @@ function SequenceHotspot({
|
|
|
14246
14494
|
|
|
14247
14495
|
// src/hotspot/video-hotspot.tsx
|
|
14248
14496
|
import { useThree as useThree22 } from "@react-three/fiber";
|
|
14249
|
-
import { useEffect as useEffect29, useLayoutEffect as useLayoutEffect8, useRef as
|
|
14497
|
+
import { useEffect as useEffect29, useLayoutEffect as useLayoutEffect8, useRef as useRef30, useState as useState18 } from "react";
|
|
14250
14498
|
import {
|
|
14251
|
-
ClampToEdgeWrapping as
|
|
14252
|
-
LinearFilter as
|
|
14253
|
-
LinearMipmapLinearFilter as
|
|
14254
|
-
SRGBColorSpace as
|
|
14499
|
+
ClampToEdgeWrapping as ClampToEdgeWrapping5,
|
|
14500
|
+
LinearFilter as LinearFilter7,
|
|
14501
|
+
LinearMipmapLinearFilter as LinearMipmapLinearFilter6,
|
|
14502
|
+
SRGBColorSpace as SRGBColorSpace6,
|
|
14255
14503
|
TextureLoader as TextureLoader6,
|
|
14256
14504
|
VideoTexture
|
|
14257
14505
|
} from "three";
|
|
@@ -14317,7 +14565,7 @@ function clampVolume2(volume) {
|
|
|
14317
14565
|
function usePosterTexture(id, poster, onError) {
|
|
14318
14566
|
const gl = useThree22((state) => state.gl);
|
|
14319
14567
|
const [texture, setTexture] = useState18(null);
|
|
14320
|
-
const onErrorRef =
|
|
14568
|
+
const onErrorRef = useRef30(onError);
|
|
14321
14569
|
onErrorRef.current = onError;
|
|
14322
14570
|
useEffect29(() => {
|
|
14323
14571
|
let active = true;
|
|
@@ -14335,11 +14583,11 @@ function usePosterTexture(id, poster, onError) {
|
|
|
14335
14583
|
loadedTexture.dispose();
|
|
14336
14584
|
return;
|
|
14337
14585
|
}
|
|
14338
|
-
loadedTexture.colorSpace =
|
|
14339
|
-
loadedTexture.wrapS =
|
|
14340
|
-
loadedTexture.wrapT =
|
|
14341
|
-
loadedTexture.magFilter =
|
|
14342
|
-
loadedTexture.minFilter =
|
|
14586
|
+
loadedTexture.colorSpace = SRGBColorSpace6;
|
|
14587
|
+
loadedTexture.wrapS = ClampToEdgeWrapping5;
|
|
14588
|
+
loadedTexture.wrapT = ClampToEdgeWrapping5;
|
|
14589
|
+
loadedTexture.magFilter = LinearFilter7;
|
|
14590
|
+
loadedTexture.minFilter = LinearMipmapLinearFilter6;
|
|
14343
14591
|
loadedTexture.generateMipmaps = true;
|
|
14344
14592
|
loadedTexture.anisotropy = gl.capabilities.getMaxAnisotropy();
|
|
14345
14593
|
loadedTexture.needsUpdate = true;
|
|
@@ -14376,9 +14624,9 @@ function useVideoResource({
|
|
|
14376
14624
|
}) {
|
|
14377
14625
|
const gl = useThree22((state) => state.gl);
|
|
14378
14626
|
const [resource, setResource] = useState18(null);
|
|
14379
|
-
const onEndedRef =
|
|
14380
|
-
const onErrorRef =
|
|
14381
|
-
const onPlaybackStateChangeRef =
|
|
14627
|
+
const onEndedRef = useRef30(onEnded);
|
|
14628
|
+
const onErrorRef = useRef30(onError);
|
|
14629
|
+
const onPlaybackStateChangeRef = useRef30(onPlaybackStateChange);
|
|
14382
14630
|
onEndedRef.current = onEnded;
|
|
14383
14631
|
onErrorRef.current = onError;
|
|
14384
14632
|
onPlaybackStateChangeRef.current = onPlaybackStateChange;
|
|
@@ -14395,11 +14643,11 @@ function useVideoResource({
|
|
|
14395
14643
|
applyInlineVideoPlayback(video, playsInline ?? true);
|
|
14396
14644
|
video.poster = poster ?? "";
|
|
14397
14645
|
const texture = new VideoTexture(video);
|
|
14398
|
-
texture.colorSpace =
|
|
14399
|
-
texture.wrapS =
|
|
14400
|
-
texture.wrapT =
|
|
14401
|
-
texture.magFilter =
|
|
14402
|
-
texture.minFilter =
|
|
14646
|
+
texture.colorSpace = SRGBColorSpace6;
|
|
14647
|
+
texture.wrapS = ClampToEdgeWrapping5;
|
|
14648
|
+
texture.wrapT = ClampToEdgeWrapping5;
|
|
14649
|
+
texture.magFilter = LinearFilter7;
|
|
14650
|
+
texture.minFilter = LinearFilter7;
|
|
14403
14651
|
texture.generateMipmaps = false;
|
|
14404
14652
|
const notifyState = (state) => {
|
|
14405
14653
|
if (active) {
|
|
@@ -14495,8 +14743,8 @@ function VideoHotspot({
|
|
|
14495
14743
|
src
|
|
14496
14744
|
});
|
|
14497
14745
|
const posterTexture = usePosterTexture(id, poster, onError);
|
|
14498
|
-
const onPlaybackErrorRef =
|
|
14499
|
-
const onPlaybackStateChangeRef =
|
|
14746
|
+
const onPlaybackErrorRef = useRef30(onPlaybackError);
|
|
14747
|
+
const onPlaybackStateChangeRef = useRef30(onPlaybackStateChange);
|
|
14500
14748
|
onPlaybackErrorRef.current = onPlaybackError;
|
|
14501
14749
|
onPlaybackStateChangeRef.current = onPlaybackStateChange;
|
|
14502
14750
|
useLayoutEffect8(() => {
|
|
@@ -14537,18 +14785,18 @@ function VideoHotspot({
|
|
|
14537
14785
|
|
|
14538
14786
|
// src/hotspot/audio-hotspot.tsx
|
|
14539
14787
|
import { useFrame as useFrame18, useThree as useThree23 } from "@react-three/fiber";
|
|
14540
|
-
import { useEffect as useEffect30, useRef as
|
|
14788
|
+
import { useEffect as useEffect30, useRef as useRef31, useState as useState19 } from "react";
|
|
14541
14789
|
import {
|
|
14542
14790
|
CanvasTexture as CanvasTexture2,
|
|
14543
|
-
ClampToEdgeWrapping as
|
|
14544
|
-
LinearFilter as
|
|
14545
|
-
LinearMipmapLinearFilter as
|
|
14546
|
-
SRGBColorSpace as
|
|
14791
|
+
ClampToEdgeWrapping as ClampToEdgeWrapping6,
|
|
14792
|
+
LinearFilter as LinearFilter8,
|
|
14793
|
+
LinearMipmapLinearFilter as LinearMipmapLinearFilter7,
|
|
14794
|
+
SRGBColorSpace as SRGBColorSpace7,
|
|
14547
14795
|
TextureLoader as TextureLoader7
|
|
14548
14796
|
} from "three";
|
|
14549
14797
|
|
|
14550
14798
|
// src/hotspot/audio-spatial.ts
|
|
14551
|
-
import { MathUtils as
|
|
14799
|
+
import { MathUtils as MathUtils11, Vector3 as Vector318 } from "three";
|
|
14552
14800
|
var LOOK_DIR = new Vector318();
|
|
14553
14801
|
var SOURCE_DIR = new Vector318();
|
|
14554
14802
|
var RIGHT_DIR = new Vector318();
|
|
@@ -14576,11 +14824,11 @@ function lookRangeGain(angleDegrees, range) {
|
|
|
14576
14824
|
function audioSpatialFromView(camera, position, range) {
|
|
14577
14825
|
camera.getWorldDirection(LOOK_DIR);
|
|
14578
14826
|
SOURCE_DIR.copy(panoPositionToVector3(position)).normalize();
|
|
14579
|
-
const angleDegrees =
|
|
14580
|
-
Math.acos(
|
|
14827
|
+
const angleDegrees = MathUtils11.radToDeg(
|
|
14828
|
+
Math.acos(MathUtils11.clamp(LOOK_DIR.dot(SOURCE_DIR), -1, 1))
|
|
14581
14829
|
);
|
|
14582
14830
|
RIGHT_DIR.set(1, 0, 0).applyQuaternion(camera.quaternion);
|
|
14583
|
-
const pan =
|
|
14831
|
+
const pan = MathUtils11.clamp(
|
|
14584
14832
|
Math.atan2(SOURCE_DIR.dot(RIGHT_DIR), SOURCE_DIR.dot(LOOK_DIR)) / (Math.PI / 2),
|
|
14585
14833
|
-1,
|
|
14586
14834
|
1
|
|
@@ -14646,11 +14894,11 @@ function createSpeakerTexture(state) {
|
|
|
14646
14894
|
}
|
|
14647
14895
|
}
|
|
14648
14896
|
const texture = new CanvasTexture2(canvas);
|
|
14649
|
-
texture.colorSpace =
|
|
14650
|
-
texture.wrapS =
|
|
14651
|
-
texture.wrapT =
|
|
14652
|
-
texture.magFilter =
|
|
14653
|
-
texture.minFilter =
|
|
14897
|
+
texture.colorSpace = SRGBColorSpace7;
|
|
14898
|
+
texture.wrapS = ClampToEdgeWrapping6;
|
|
14899
|
+
texture.wrapT = ClampToEdgeWrapping6;
|
|
14900
|
+
texture.magFilter = LinearFilter8;
|
|
14901
|
+
texture.minFilter = LinearMipmapLinearFilter7;
|
|
14654
14902
|
texture.generateMipmaps = true;
|
|
14655
14903
|
texture.needsUpdate = true;
|
|
14656
14904
|
return texture;
|
|
@@ -14675,7 +14923,7 @@ function useSpeakerTextures(enabled) {
|
|
|
14675
14923
|
function useIconTexture(icon, enabled, onError, id) {
|
|
14676
14924
|
const gl = useThree23((state) => state.gl);
|
|
14677
14925
|
const [texture, setTexture] = useState19(null);
|
|
14678
|
-
const onErrorRef =
|
|
14926
|
+
const onErrorRef = useRef31(onError);
|
|
14679
14927
|
onErrorRef.current = onError;
|
|
14680
14928
|
useEffect30(() => {
|
|
14681
14929
|
let active = true;
|
|
@@ -14693,11 +14941,11 @@ function useIconTexture(icon, enabled, onError, id) {
|
|
|
14693
14941
|
loadedTexture.dispose();
|
|
14694
14942
|
return;
|
|
14695
14943
|
}
|
|
14696
|
-
loadedTexture.colorSpace =
|
|
14697
|
-
loadedTexture.wrapS =
|
|
14698
|
-
loadedTexture.wrapT =
|
|
14699
|
-
loadedTexture.magFilter =
|
|
14700
|
-
loadedTexture.minFilter =
|
|
14944
|
+
loadedTexture.colorSpace = SRGBColorSpace7;
|
|
14945
|
+
loadedTexture.wrapS = ClampToEdgeWrapping6;
|
|
14946
|
+
loadedTexture.wrapT = ClampToEdgeWrapping6;
|
|
14947
|
+
loadedTexture.magFilter = LinearFilter8;
|
|
14948
|
+
loadedTexture.minFilter = LinearMipmapLinearFilter7;
|
|
14701
14949
|
loadedTexture.generateMipmaps = true;
|
|
14702
14950
|
loadedTexture.anisotropy = gl.capabilities.getMaxAnisotropy();
|
|
14703
14951
|
loadedTexture.needsUpdate = true;
|
|
@@ -14735,12 +14983,12 @@ function useAudioHowl({
|
|
|
14735
14983
|
format
|
|
14736
14984
|
}) {
|
|
14737
14985
|
const [howl, setHowl] = useState19(null);
|
|
14738
|
-
const playingRef =
|
|
14739
|
-
const loopRef =
|
|
14740
|
-
const onEndedRef =
|
|
14741
|
-
const onErrorRef =
|
|
14742
|
-
const onPlaybackErrorRef =
|
|
14743
|
-
const onPlaybackStateChangeRef =
|
|
14986
|
+
const playingRef = useRef31(playing);
|
|
14987
|
+
const loopRef = useRef31(loop ?? false);
|
|
14988
|
+
const onEndedRef = useRef31(onEnded);
|
|
14989
|
+
const onErrorRef = useRef31(onError);
|
|
14990
|
+
const onPlaybackErrorRef = useRef31(onPlaybackError);
|
|
14991
|
+
const onPlaybackStateChangeRef = useRef31(onPlaybackStateChange);
|
|
14744
14992
|
playingRef.current = playing;
|
|
14745
14993
|
loopRef.current = loop ?? false;
|
|
14746
14994
|
onEndedRef.current = onEnded;
|
|
@@ -14833,11 +15081,11 @@ function AudioHotspot({
|
|
|
14833
15081
|
const stoppedIconTexture = useIconTexture(icon, marker, onError, id);
|
|
14834
15082
|
const playingIconTexture = useIconTexture(playingIcon, marker, onError, id);
|
|
14835
15083
|
const markerTexture = playing ? playingIconTexture ?? stoppedIconTexture ?? speakerTextures.playing : stoppedIconTexture ?? speakerTextures.stopped;
|
|
14836
|
-
const playingRef =
|
|
15084
|
+
const playingRef = useRef31(playing);
|
|
14837
15085
|
playingRef.current = playing;
|
|
14838
|
-
const mutedRef =
|
|
14839
|
-
const volumeRef =
|
|
14840
|
-
const rangeRef =
|
|
15086
|
+
const mutedRef = useRef31(muted);
|
|
15087
|
+
const volumeRef = useRef31(volume);
|
|
15088
|
+
const rangeRef = useRef31(range);
|
|
14841
15089
|
mutedRef.current = muted;
|
|
14842
15090
|
volumeRef.current = volume;
|
|
14843
15091
|
rangeRef.current = range;
|
|
@@ -14886,15 +15134,15 @@ function AudioHotspot({
|
|
|
14886
15134
|
}
|
|
14887
15135
|
|
|
14888
15136
|
// src/hotspot/text-hotspot.tsx
|
|
14889
|
-
import { useEffect as useEffect31, useRef as
|
|
15137
|
+
import { useEffect as useEffect31, useRef as useRef32, useState as useState20 } from "react";
|
|
14890
15138
|
import { useFrame as useFrame19, useThree as useThree24 } from "@react-three/fiber";
|
|
14891
15139
|
import {
|
|
14892
15140
|
CanvasTexture as CanvasTexture3,
|
|
14893
|
-
ClampToEdgeWrapping as
|
|
14894
|
-
LinearFilter as
|
|
14895
|
-
MathUtils as
|
|
15141
|
+
ClampToEdgeWrapping as ClampToEdgeWrapping7,
|
|
15142
|
+
LinearFilter as LinearFilter9,
|
|
15143
|
+
MathUtils as MathUtils12,
|
|
14896
15144
|
PerspectiveCamera as PerspectiveCamera9,
|
|
14897
|
-
SRGBColorSpace as
|
|
15145
|
+
SRGBColorSpace as SRGBColorSpace8
|
|
14898
15146
|
} from "three";
|
|
14899
15147
|
import { jsx as jsx34 } from "react/jsx-runtime";
|
|
14900
15148
|
var TEXT_TEXTURE_LONG_SIDE = 1024;
|
|
@@ -14967,7 +15215,7 @@ function projectedDevicePixels(angleDeg, fovDeg, viewportHeight) {
|
|
|
14967
15215
|
}
|
|
14968
15216
|
const fov = Math.min(179, Math.max(1, resolvePositive(fovDeg, DEFAULT_REFERENCE_FOV2)));
|
|
14969
15217
|
const angle = Math.min(179, Math.max(0.01, Math.abs(angleDeg)));
|
|
14970
|
-
return Math.tan(
|
|
15218
|
+
return Math.tan(MathUtils12.degToRad(angle) / 2) / Math.tan(MathUtils12.degToRad(fov) / 2) * viewportHeight;
|
|
14971
15219
|
}
|
|
14972
15220
|
function snapRasterLongSide(screenLong, layoutLong) {
|
|
14973
15221
|
if (!(screenLong > 0)) {
|
|
@@ -15157,11 +15405,11 @@ function createTextTexture(text, width, height, style, rasterLong) {
|
|
|
15157
15405
|
);
|
|
15158
15406
|
drawTextHotspot(context, layout.canvasWidth, layout.canvasHeight, text, style);
|
|
15159
15407
|
const texture = new CanvasTexture3(canvas);
|
|
15160
|
-
texture.colorSpace =
|
|
15161
|
-
texture.wrapS =
|
|
15162
|
-
texture.wrapT =
|
|
15163
|
-
texture.magFilter =
|
|
15164
|
-
texture.minFilter =
|
|
15408
|
+
texture.colorSpace = SRGBColorSpace8;
|
|
15409
|
+
texture.wrapS = ClampToEdgeWrapping7;
|
|
15410
|
+
texture.wrapT = ClampToEdgeWrapping7;
|
|
15411
|
+
texture.magFilter = LinearFilter9;
|
|
15412
|
+
texture.minFilter = LinearFilter9;
|
|
15165
15413
|
texture.generateMipmaps = false;
|
|
15166
15414
|
texture.needsUpdate = true;
|
|
15167
15415
|
return texture;
|
|
@@ -15206,8 +15454,8 @@ function useRasterLongSide(width, height, scale, scaleMode, referenceFov) {
|
|
|
15206
15454
|
function useTextTexture(text, width, height, style, scale, scaleMode, referenceFov, onLoad, onError) {
|
|
15207
15455
|
const rasterLong = useRasterLongSide(width, height, scale, scaleMode, referenceFov);
|
|
15208
15456
|
const [texture, setTexture] = useState20(null);
|
|
15209
|
-
const onLoadRef =
|
|
15210
|
-
const onErrorRef =
|
|
15457
|
+
const onLoadRef = useRef32(onLoad);
|
|
15458
|
+
const onErrorRef = useRef32(onError);
|
|
15211
15459
|
onLoadRef.current = onLoad;
|
|
15212
15460
|
onErrorRef.current = onError;
|
|
15213
15461
|
useEffect31(() => {
|
|
@@ -15436,7 +15684,7 @@ function IframeHotspot({
|
|
|
15436
15684
|
}
|
|
15437
15685
|
|
|
15438
15686
|
// src/hotspot/polygon-hotspot.tsx
|
|
15439
|
-
import { useEffect as useEffect32, useMemo as useMemo20, useRef as
|
|
15687
|
+
import { useEffect as useEffect32, useMemo as useMemo20, useRef as useRef33 } from "react";
|
|
15440
15688
|
import {
|
|
15441
15689
|
BufferGeometry as BufferGeometry2,
|
|
15442
15690
|
DoubleSide as DoubleSide5,
|
|
@@ -15715,7 +15963,7 @@ function PolygonHotspot({
|
|
|
15715
15963
|
[center, valid, vertices]
|
|
15716
15964
|
);
|
|
15717
15965
|
const resolvedStrokeOpacity = Math.max(0, Math.min(strokeOpacity, 1));
|
|
15718
|
-
const startVerticesRef =
|
|
15966
|
+
const startVerticesRef = useRef33(null);
|
|
15719
15967
|
const issuesKey = issues.map((issue) => issue.code).join(",");
|
|
15720
15968
|
useEffect32(() => {
|
|
15721
15969
|
if (!valid) onInvalid?.(issues);
|
|
@@ -15800,9 +16048,9 @@ function PolygonHotspot({
|
|
|
15800
16048
|
}
|
|
15801
16049
|
|
|
15802
16050
|
// src/hotspot/polyline-hotspot.tsx
|
|
15803
|
-
import { useEffect as useEffect33, useMemo as useMemo21, useRef as
|
|
16051
|
+
import { useEffect as useEffect33, useMemo as useMemo21, useRef as useRef34 } from "react";
|
|
15804
16052
|
import {
|
|
15805
|
-
MathUtils as
|
|
16053
|
+
MathUtils as MathUtils13,
|
|
15806
16054
|
Matrix4 as Matrix46,
|
|
15807
16055
|
Quaternion as Quaternion6,
|
|
15808
16056
|
Vector3 as Vector320
|
|
@@ -15839,8 +16087,8 @@ function polylineCenter(vertices) {
|
|
|
15839
16087
|
function surfaceQuaternion2(position) {
|
|
15840
16088
|
const outward = panoPositionToVector3(position).normalize();
|
|
15841
16089
|
const inward = outward.clone().negate();
|
|
15842
|
-
const pitch =
|
|
15843
|
-
const yaw =
|
|
16090
|
+
const pitch = MathUtils13.degToRad(position.pitch);
|
|
16091
|
+
const yaw = MathUtils13.degToRad(position.yaw);
|
|
15844
16092
|
const localUp = new Vector320(
|
|
15845
16093
|
-Math.sin(pitch) * Math.sin(yaw),
|
|
15846
16094
|
Math.cos(pitch),
|
|
@@ -15869,7 +16117,7 @@ function subdivisionSteps(vertices) {
|
|
|
15869
16117
|
}
|
|
15870
16118
|
return Math.min(
|
|
15871
16119
|
8,
|
|
15872
|
-
Math.max(1, Math.ceil(
|
|
16120
|
+
Math.max(1, Math.ceil(MathUtils13.radToDeg(maxAngle) / MAX_SEGMENT_DEGREES))
|
|
15873
16121
|
);
|
|
15874
16122
|
}
|
|
15875
16123
|
function makeLinePositions(vertices, center) {
|
|
@@ -15932,7 +16180,7 @@ function PolylineHotspot({
|
|
|
15932
16180
|
[center, valid, vertices]
|
|
15933
16181
|
);
|
|
15934
16182
|
const opacity = Math.max(0, Math.min(strokeOpacity, 1));
|
|
15935
|
-
const startVerticesRef =
|
|
16183
|
+
const startVerticesRef = useRef34(null);
|
|
15936
16184
|
useEffect33(() => {
|
|
15937
16185
|
if (!valid) onInvalid?.(issues);
|
|
15938
16186
|
}, [issues, onInvalid, valid]);
|
|
@@ -16249,7 +16497,7 @@ function ProjectScenes({
|
|
|
16249
16497
|
}
|
|
16250
16498
|
|
|
16251
16499
|
// src/background-audio.tsx
|
|
16252
|
-
import { useContext as useContext23, useEffect as useEffect34, useMemo as useMemo23, useRef as
|
|
16500
|
+
import { useContext as useContext23, useEffect as useEffect34, useMemo as useMemo23, useRef as useRef35, useState as useState22 } from "react";
|
|
16253
16501
|
var DEFAULT_FADE_MS = 400;
|
|
16254
16502
|
function resolveFadeMs(value) {
|
|
16255
16503
|
if (!Number.isFinite(value)) {
|
|
@@ -16301,21 +16549,21 @@ function BackgroundAudio({
|
|
|
16301
16549
|
const urls = resolveBackgroundAudioUrls(src, sources, sceneId);
|
|
16302
16550
|
usePanoMediaActivationIntent(playing && urls.length > 0);
|
|
16303
16551
|
const trackKey = urls.join("\0");
|
|
16304
|
-
const currentRef =
|
|
16305
|
-
const outgoingRef =
|
|
16306
|
-
const fadingInRef =
|
|
16307
|
-
const isFirstTrackRef =
|
|
16308
|
-
const playingRef =
|
|
16309
|
-
const loopRef =
|
|
16310
|
-
const mutedRef =
|
|
16311
|
-
const volumeRef =
|
|
16312
|
-
const mutedPropRef =
|
|
16313
|
-
const volumePropRef =
|
|
16314
|
-
const fadeMsRef =
|
|
16315
|
-
const onPlaybackStateChangeRef =
|
|
16316
|
-
const onPlaybackErrorRef =
|
|
16317
|
-
const onEndedRef =
|
|
16318
|
-
const onErrorRef =
|
|
16552
|
+
const currentRef = useRef35(null);
|
|
16553
|
+
const outgoingRef = useRef35([]);
|
|
16554
|
+
const fadingInRef = useRef35(false);
|
|
16555
|
+
const isFirstTrackRef = useRef35(true);
|
|
16556
|
+
const playingRef = useRef35(playing);
|
|
16557
|
+
const loopRef = useRef35(loop);
|
|
16558
|
+
const mutedRef = useRef35(muted);
|
|
16559
|
+
const volumeRef = useRef35(volume);
|
|
16560
|
+
const mutedPropRef = useRef35(muted);
|
|
16561
|
+
const volumePropRef = useRef35(volume);
|
|
16562
|
+
const fadeMsRef = useRef35(resolveFadeMs(fadeMs));
|
|
16563
|
+
const onPlaybackStateChangeRef = useRef35(onPlaybackStateChange);
|
|
16564
|
+
const onPlaybackErrorRef = useRef35(onPlaybackError);
|
|
16565
|
+
const onEndedRef = useRef35(onEnded);
|
|
16566
|
+
const onErrorRef = useRef35(onError);
|
|
16319
16567
|
playingRef.current = playing;
|
|
16320
16568
|
loopRef.current = loop;
|
|
16321
16569
|
fadeMsRef.current = resolveFadeMs(fadeMs);
|
|
@@ -16331,7 +16579,7 @@ function BackgroundAudio({
|
|
|
16331
16579
|
onPlaybackErrorRef.current = onPlaybackError;
|
|
16332
16580
|
onEndedRef.current = onEnded;
|
|
16333
16581
|
onErrorRef.current = onError;
|
|
16334
|
-
const snapshotRef =
|
|
16582
|
+
const snapshotRef = useRef35({
|
|
16335
16583
|
ready: false,
|
|
16336
16584
|
playing: false,
|
|
16337
16585
|
blocked: false,
|
|
@@ -16339,7 +16587,7 @@ function BackgroundAudio({
|
|
|
16339
16587
|
muted,
|
|
16340
16588
|
volume
|
|
16341
16589
|
});
|
|
16342
|
-
const snapshotListenersRef =
|
|
16590
|
+
const snapshotListenersRef = useRef35(/* @__PURE__ */ new Set());
|
|
16343
16591
|
const notifySnapshot = (patch) => {
|
|
16344
16592
|
const prev = snapshotRef.current;
|
|
16345
16593
|
snapshotRef.current = { ...prev, ...patch };
|
|
@@ -16347,7 +16595,7 @@ function BackgroundAudio({
|
|
|
16347
16595
|
listener();
|
|
16348
16596
|
}
|
|
16349
16597
|
};
|
|
16350
|
-
const isControlledRef =
|
|
16598
|
+
const isControlledRef = useRef35(isControlled);
|
|
16351
16599
|
isControlledRef.current = isControlled;
|
|
16352
16600
|
const controller = useMemo23(
|
|
16353
16601
|
() => ({
|
|
@@ -16635,11 +16883,11 @@ function PanoFilter({
|
|
|
16635
16883
|
import { useFrame as useFrame20, useThree as useThree25 } from "@react-three/fiber";
|
|
16636
16884
|
import {
|
|
16637
16885
|
forwardRef as forwardRef3,
|
|
16638
|
-
useCallback as
|
|
16886
|
+
useCallback as useCallback10,
|
|
16639
16887
|
useContext as useContext25,
|
|
16640
16888
|
useEffect as useEffect36,
|
|
16641
16889
|
useImperativeHandle as useImperativeHandle3,
|
|
16642
|
-
useRef as
|
|
16890
|
+
useRef as useRef36,
|
|
16643
16891
|
useState as useState23
|
|
16644
16892
|
} from "react";
|
|
16645
16893
|
import { Quaternion as Quaternion7 } from "three";
|
|
@@ -16679,30 +16927,30 @@ var Gyro = forwardRef3(function Gyro2({
|
|
|
16679
16927
|
const { gl } = useThree25();
|
|
16680
16928
|
const [internallyDisabled, setInternallyDisabled] = useState23(false);
|
|
16681
16929
|
const [available, setAvailableState] = useState23(false);
|
|
16682
|
-
const availableRef =
|
|
16683
|
-
const availabilityReportedRef =
|
|
16684
|
-
const activeRef =
|
|
16685
|
-
const permissionRef =
|
|
16686
|
-
const absoluteEventSourceRef =
|
|
16687
|
-
const rawQuaternionRef =
|
|
16688
|
-
const hasRawQuaternionRef =
|
|
16689
|
-
const calibrationRef =
|
|
16690
|
-
const hasCalibrationRef =
|
|
16691
|
-
const calibratedQuaternionRef =
|
|
16692
|
-
const absoluteOffsetRef =
|
|
16693
|
-
const screenAngleRef =
|
|
16694
|
-
const startPoseRef =
|
|
16695
|
-
const enabledAtRef =
|
|
16696
|
-
const filteredPoseRef =
|
|
16697
|
-
const lastAppliedPoseRef =
|
|
16698
|
-
const lastSamplePoseRef =
|
|
16699
|
-
const lastSampleAtRef =
|
|
16700
|
-
const previousYawRef =
|
|
16701
|
-
const absoluteRef =
|
|
16702
|
-
const northRef =
|
|
16930
|
+
const availableRef = useRef36(false);
|
|
16931
|
+
const availabilityReportedRef = useRef36(null);
|
|
16932
|
+
const activeRef = useRef36(false);
|
|
16933
|
+
const permissionRef = useRef36(deviceOrientationPermissionState);
|
|
16934
|
+
const absoluteEventSourceRef = useRef36(null);
|
|
16935
|
+
const rawQuaternionRef = useRef36(new Quaternion7());
|
|
16936
|
+
const hasRawQuaternionRef = useRef36(false);
|
|
16937
|
+
const calibrationRef = useRef36(new Quaternion7());
|
|
16938
|
+
const hasCalibrationRef = useRef36(false);
|
|
16939
|
+
const calibratedQuaternionRef = useRef36(new Quaternion7());
|
|
16940
|
+
const absoluteOffsetRef = useRef36({ yaw: 0, pitch: 0 });
|
|
16941
|
+
const screenAngleRef = useRef36(getScreenOrientationAngle());
|
|
16942
|
+
const startPoseRef = useRef36(null);
|
|
16943
|
+
const enabledAtRef = useRef36(0);
|
|
16944
|
+
const filteredPoseRef = useRef36(null);
|
|
16945
|
+
const lastAppliedPoseRef = useRef36(null);
|
|
16946
|
+
const lastSamplePoseRef = useRef36(null);
|
|
16947
|
+
const lastSampleAtRef = useRef36(null);
|
|
16948
|
+
const previousYawRef = useRef36(void 0);
|
|
16949
|
+
const absoluteRef = useRef36(absolute);
|
|
16950
|
+
const northRef = useRef36(north);
|
|
16703
16951
|
absoluteRef.current = absolute;
|
|
16704
16952
|
northRef.current = north;
|
|
16705
|
-
const callbacksRef =
|
|
16953
|
+
const callbacksRef = useRef36({
|
|
16706
16954
|
onAvailable,
|
|
16707
16955
|
onUnavailable,
|
|
16708
16956
|
onEnable,
|
|
@@ -16719,7 +16967,7 @@ var Gyro = forwardRef3(function Gyro2({
|
|
|
16719
16967
|
if (!controlsRef) {
|
|
16720
16968
|
throw new Error("<Gyro> must be rendered inside <PanoViewer>.");
|
|
16721
16969
|
}
|
|
16722
|
-
const emit =
|
|
16970
|
+
const emit = useCallback10(
|
|
16723
16971
|
(type) => {
|
|
16724
16972
|
eventBus?.emit(type, void 0);
|
|
16725
16973
|
switch (type) {
|
|
@@ -16746,7 +16994,7 @@ var Gyro = forwardRef3(function Gyro2({
|
|
|
16746
16994
|
},
|
|
16747
16995
|
[eventBus]
|
|
16748
16996
|
);
|
|
16749
|
-
const setAvailable =
|
|
16997
|
+
const setAvailable = useCallback10(
|
|
16750
16998
|
(nextAvailable) => {
|
|
16751
16999
|
availableRef.current = nextAvailable;
|
|
16752
17000
|
setAvailableState(nextAvailable);
|
|
@@ -16758,7 +17006,7 @@ var Gyro = forwardRef3(function Gyro2({
|
|
|
16758
17006
|
},
|
|
16759
17007
|
[emit]
|
|
16760
17008
|
);
|
|
16761
|
-
const requestPermission =
|
|
17009
|
+
const requestPermission = useCallback10(async () => {
|
|
16762
17010
|
if (!availableRef.current) {
|
|
16763
17011
|
return false;
|
|
16764
17012
|
}
|
|
@@ -16791,7 +17039,7 @@ var Gyro = forwardRef3(function Gyro2({
|
|
|
16791
17039
|
emit("gyrodenied");
|
|
16792
17040
|
return false;
|
|
16793
17041
|
}, [emit, setAvailable]);
|
|
16794
|
-
const deactivate =
|
|
17042
|
+
const deactivate = useCallback10(() => {
|
|
16795
17043
|
if (activeRef.current) {
|
|
16796
17044
|
activeRef.current = false;
|
|
16797
17045
|
controlsRef.current?.setGyroActive(false);
|
|
@@ -16806,7 +17054,7 @@ var Gyro = forwardRef3(function Gyro2({
|
|
|
16806
17054
|
lastSampleAtRef.current = null;
|
|
16807
17055
|
previousYawRef.current = void 0;
|
|
16808
17056
|
}, [controlsRef, emit]);
|
|
16809
|
-
const anchorToView =
|
|
17057
|
+
const anchorToView = useCallback10(
|
|
16810
17058
|
(yaw, pitch) => {
|
|
16811
17059
|
if (!hasRawQuaternionRef.current) {
|
|
16812
17060
|
return;
|
|
@@ -16836,7 +17084,7 @@ var Gyro = forwardRef3(function Gyro2({
|
|
|
16836
17084
|
},
|
|
16837
17085
|
[]
|
|
16838
17086
|
);
|
|
16839
|
-
const resetSensor =
|
|
17087
|
+
const resetSensor = useCallback10(
|
|
16840
17088
|
(yaw, pitch) => {
|
|
16841
17089
|
if (!hasRawQuaternionRef.current) {
|
|
16842
17090
|
return;
|
|
@@ -17118,12 +17366,12 @@ var Gyro = forwardRef3(function Gyro2({
|
|
|
17118
17366
|
import { useThree as useThree28 } from "@react-three/fiber";
|
|
17119
17367
|
import {
|
|
17120
17368
|
forwardRef as forwardRef4,
|
|
17121
|
-
useCallback as
|
|
17369
|
+
useCallback as useCallback11,
|
|
17122
17370
|
useContext as useContext27,
|
|
17123
17371
|
useEffect as useEffect40,
|
|
17124
17372
|
useImperativeHandle as useImperativeHandle4,
|
|
17125
17373
|
useMemo as useMemo26,
|
|
17126
|
-
useRef as
|
|
17374
|
+
useRef as useRef40,
|
|
17127
17375
|
useState as useState24
|
|
17128
17376
|
} from "react";
|
|
17129
17377
|
|
|
@@ -17146,6 +17394,184 @@ async function detectWebVRCapabilities() {
|
|
|
17146
17394
|
return { webxr, mobile, sensor };
|
|
17147
17395
|
}
|
|
17148
17396
|
|
|
17397
|
+
// src/webvr/dpdb.ts
|
|
17398
|
+
var DEFAULT_WEBVR_DATABASE_URL = "https://storage.googleapis.com/cardboard-dpdb/dpdb.json";
|
|
17399
|
+
var SCREENSIZE_MIN = 3;
|
|
17400
|
+
var SCREENSIZE_MAX = 20;
|
|
17401
|
+
var cache = /* @__PURE__ */ new Map();
|
|
17402
|
+
function normalizeDatabaseUrl(value) {
|
|
17403
|
+
if (value === null || value === "") {
|
|
17404
|
+
return null;
|
|
17405
|
+
}
|
|
17406
|
+
if (value === void 0) {
|
|
17407
|
+
return DEFAULT_WEBVR_DATABASE_URL;
|
|
17408
|
+
}
|
|
17409
|
+
const trimmed = value.trim();
|
|
17410
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
17411
|
+
}
|
|
17412
|
+
function physicalResolution(screenWidth, screenHeight, devicePixelRatio) {
|
|
17413
|
+
const ratio = Number.isFinite(devicePixelRatio) && devicePixelRatio > 0 ? devicePixelRatio : 1;
|
|
17414
|
+
return [
|
|
17415
|
+
Math.round(Math.max(0, screenWidth) * ratio),
|
|
17416
|
+
Math.round(Math.max(0, screenHeight) * ratio)
|
|
17417
|
+
];
|
|
17418
|
+
}
|
|
17419
|
+
function resolutionsMatch(rule, physical) {
|
|
17420
|
+
const [rw, rh] = rule;
|
|
17421
|
+
const [pw, ph] = physical;
|
|
17422
|
+
return rw === pw && rh === ph || rw === ph && rh === pw;
|
|
17423
|
+
}
|
|
17424
|
+
function ruleMatches(rule, input, physical) {
|
|
17425
|
+
if (typeof rule.ua === "string") {
|
|
17426
|
+
return input.userAgent.includes(rule.ua);
|
|
17427
|
+
}
|
|
17428
|
+
if (Array.isArray(rule.res) && rule.res.length === 2 && typeof rule.res[0] === "number" && typeof rule.res[1] === "number") {
|
|
17429
|
+
return resolutionsMatch(
|
|
17430
|
+
[rule.res[0], rule.res[1]],
|
|
17431
|
+
physical
|
|
17432
|
+
);
|
|
17433
|
+
}
|
|
17434
|
+
return false;
|
|
17435
|
+
}
|
|
17436
|
+
function deviceMatches(device, input) {
|
|
17437
|
+
const rules = device.rules;
|
|
17438
|
+
if (!Array.isArray(rules) || rules.length === 0) {
|
|
17439
|
+
return false;
|
|
17440
|
+
}
|
|
17441
|
+
const physical = physicalResolution(
|
|
17442
|
+
input.screenWidth,
|
|
17443
|
+
input.screenHeight,
|
|
17444
|
+
input.devicePixelRatio
|
|
17445
|
+
);
|
|
17446
|
+
return rules.some(
|
|
17447
|
+
(rule) => rule !== null && typeof rule === "object" && ruleMatches(rule, input, physical)
|
|
17448
|
+
);
|
|
17449
|
+
}
|
|
17450
|
+
function diagonalInchesFromDpi(dpi, physicalWidth, physicalHeight) {
|
|
17451
|
+
const shortPx = Math.min(physicalWidth, physicalHeight);
|
|
17452
|
+
const longPx = Math.max(physicalWidth, physicalHeight);
|
|
17453
|
+
if (!(shortPx > 0 && longPx > 0)) {
|
|
17454
|
+
return null;
|
|
17455
|
+
}
|
|
17456
|
+
let dpiX;
|
|
17457
|
+
let dpiY;
|
|
17458
|
+
if (typeof dpi === "number") {
|
|
17459
|
+
if (!(Number.isFinite(dpi) && dpi > 0)) {
|
|
17460
|
+
return null;
|
|
17461
|
+
}
|
|
17462
|
+
dpiX = dpi;
|
|
17463
|
+
dpiY = dpi;
|
|
17464
|
+
} else if (Array.isArray(dpi) && dpi.length >= 1) {
|
|
17465
|
+
const first = dpi[0];
|
|
17466
|
+
const second = dpi.length >= 2 ? dpi[1] : first;
|
|
17467
|
+
if (typeof first !== "number" || typeof second !== "number" || !(Number.isFinite(first) && first > 0) || !(Number.isFinite(second) && second > 0)) {
|
|
17468
|
+
return null;
|
|
17469
|
+
}
|
|
17470
|
+
dpiX = first;
|
|
17471
|
+
dpiY = second;
|
|
17472
|
+
} else {
|
|
17473
|
+
return null;
|
|
17474
|
+
}
|
|
17475
|
+
const widthIn = shortPx / dpiX;
|
|
17476
|
+
const heightIn = longPx / dpiY;
|
|
17477
|
+
const diagonal = Math.sqrt(widthIn * widthIn + heightIn * heightIn);
|
|
17478
|
+
if (!Number.isFinite(diagonal) || diagonal < SCREENSIZE_MIN || diagonal > SCREENSIZE_MAX) {
|
|
17479
|
+
return null;
|
|
17480
|
+
}
|
|
17481
|
+
return Math.round(diagonal * 10) / 10;
|
|
17482
|
+
}
|
|
17483
|
+
function matchDpdbDevice(document2, input) {
|
|
17484
|
+
const devices = document2.devices;
|
|
17485
|
+
if (!Array.isArray(devices)) {
|
|
17486
|
+
return null;
|
|
17487
|
+
}
|
|
17488
|
+
const physical = physicalResolution(
|
|
17489
|
+
input.screenWidth,
|
|
17490
|
+
input.screenHeight,
|
|
17491
|
+
input.devicePixelRatio
|
|
17492
|
+
);
|
|
17493
|
+
for (const device of devices) {
|
|
17494
|
+
if (!deviceMatches(device, input)) {
|
|
17495
|
+
continue;
|
|
17496
|
+
}
|
|
17497
|
+
if (device.dpi === void 0) {
|
|
17498
|
+
continue;
|
|
17499
|
+
}
|
|
17500
|
+
const screensizeInches = diagonalInchesFromDpi(
|
|
17501
|
+
device.dpi,
|
|
17502
|
+
physical[0],
|
|
17503
|
+
physical[1]
|
|
17504
|
+
);
|
|
17505
|
+
if (screensizeInches === null) {
|
|
17506
|
+
continue;
|
|
17507
|
+
}
|
|
17508
|
+
return { device, screensizeInches };
|
|
17509
|
+
}
|
|
17510
|
+
return null;
|
|
17511
|
+
}
|
|
17512
|
+
function readDpdbMatchInput(globalObject = globalThis) {
|
|
17513
|
+
const navigatorObject = globalObject.navigator;
|
|
17514
|
+
const screenObject = globalObject.screen;
|
|
17515
|
+
if (!navigatorObject || !screenObject) {
|
|
17516
|
+
return null;
|
|
17517
|
+
}
|
|
17518
|
+
const width = screenObject.width;
|
|
17519
|
+
const height = screenObject.height;
|
|
17520
|
+
if (typeof width !== "number" || typeof height !== "number" || !(width > 0 && height > 0)) {
|
|
17521
|
+
return null;
|
|
17522
|
+
}
|
|
17523
|
+
const dpr = typeof globalObject.devicePixelRatio === "number" ? globalObject.devicePixelRatio : 1;
|
|
17524
|
+
return {
|
|
17525
|
+
userAgent: navigatorObject.userAgent ?? "",
|
|
17526
|
+
screenWidth: width,
|
|
17527
|
+
screenHeight: height,
|
|
17528
|
+
devicePixelRatio: dpr
|
|
17529
|
+
};
|
|
17530
|
+
}
|
|
17531
|
+
async function fetchDpdbDocument(url) {
|
|
17532
|
+
try {
|
|
17533
|
+
const response = await fetch(url, {
|
|
17534
|
+
credentials: "omit",
|
|
17535
|
+
mode: "cors"
|
|
17536
|
+
});
|
|
17537
|
+
if (!response.ok) {
|
|
17538
|
+
return null;
|
|
17539
|
+
}
|
|
17540
|
+
const data = await response.json();
|
|
17541
|
+
if (data === null || typeof data !== "object" || !("devices" in data) || !Array.isArray(data.devices)) {
|
|
17542
|
+
return null;
|
|
17543
|
+
}
|
|
17544
|
+
return data;
|
|
17545
|
+
} catch {
|
|
17546
|
+
return null;
|
|
17547
|
+
}
|
|
17548
|
+
}
|
|
17549
|
+
function loadDpdbDocument(url) {
|
|
17550
|
+
const existing = cache.get(url);
|
|
17551
|
+
if (existing) {
|
|
17552
|
+
return existing;
|
|
17553
|
+
}
|
|
17554
|
+
const pending = fetchDpdbDocument(url).then((document2) => {
|
|
17555
|
+
if (!document2) {
|
|
17556
|
+
cache.delete(url);
|
|
17557
|
+
}
|
|
17558
|
+
return document2;
|
|
17559
|
+
});
|
|
17560
|
+
cache.set(url, pending);
|
|
17561
|
+
return pending;
|
|
17562
|
+
}
|
|
17563
|
+
async function resolveScreensizeFromDpdb(databaseUrl, input = readDpdbMatchInput()) {
|
|
17564
|
+
const url = normalizeDatabaseUrl(databaseUrl);
|
|
17565
|
+
if (!url || !input) {
|
|
17566
|
+
return null;
|
|
17567
|
+
}
|
|
17568
|
+
const document2 = await loadDpdbDocument(url);
|
|
17569
|
+
if (!document2) {
|
|
17570
|
+
return null;
|
|
17571
|
+
}
|
|
17572
|
+
return matchDpdbDevice(document2, input)?.screensizeInches ?? null;
|
|
17573
|
+
}
|
|
17574
|
+
|
|
17149
17575
|
// src/webvr/presentation.ts
|
|
17150
17576
|
var PRESENTATION_PROPERTIES = [
|
|
17151
17577
|
"background",
|
|
@@ -17303,7 +17729,7 @@ function subscribeWebVRPresentationExit(element, onExit) {
|
|
|
17303
17729
|
|
|
17304
17730
|
// src/webvr/reticle.tsx
|
|
17305
17731
|
import { useFrame as useFrame21, useThree as useThree26 } from "@react-three/fiber";
|
|
17306
|
-
import { useRef as
|
|
17732
|
+
import { useRef as useRef37 } from "react";
|
|
17307
17733
|
import {
|
|
17308
17734
|
DoubleSide as DoubleSide6,
|
|
17309
17735
|
Raycaster as Raycaster4,
|
|
@@ -17396,13 +17822,13 @@ function WebVRReticle({
|
|
|
17396
17822
|
scale = RETICLE_SCALE,
|
|
17397
17823
|
visible
|
|
17398
17824
|
}) {
|
|
17399
|
-
const groupRef =
|
|
17400
|
-
const ringMeshRef =
|
|
17401
|
-
const directionRef =
|
|
17402
|
-
const raycasterRef =
|
|
17403
|
-
const hoveredRef =
|
|
17404
|
-
const dwellRef =
|
|
17405
|
-
const clickedRef =
|
|
17825
|
+
const groupRef = useRef37(null);
|
|
17826
|
+
const ringMeshRef = useRef37(null);
|
|
17827
|
+
const directionRef = useRef37(new Vector321());
|
|
17828
|
+
const raycasterRef = useRef37(new Raycaster4());
|
|
17829
|
+
const hoveredRef = useRef37(null);
|
|
17830
|
+
const dwellRef = useRef37(0);
|
|
17831
|
+
const clickedRef = useRef37(false);
|
|
17406
17832
|
const { camera, gl, scene } = useThree26();
|
|
17407
17833
|
useFrame21((_, deltaSeconds) => {
|
|
17408
17834
|
const group = groupRef.current;
|
|
@@ -17565,7 +17991,7 @@ function WebVRReticle({
|
|
|
17565
17991
|
|
|
17566
17992
|
// src/webvr/stereo.tsx
|
|
17567
17993
|
import { useFrame as useFrame22, useThree as useThree27 } from "@react-three/fiber";
|
|
17568
|
-
import { useContext as useContext26, useEffect as useEffect37, useMemo as useMemo25, useRef as
|
|
17994
|
+
import { useContext as useContext26, useEffect as useEffect37, useMemo as useMemo25, useRef as useRef38 } from "react";
|
|
17569
17995
|
import {
|
|
17570
17996
|
Matrix4 as Matrix47,
|
|
17571
17997
|
Mesh as Mesh6,
|
|
@@ -17580,6 +18006,40 @@ import {
|
|
|
17580
18006
|
WebGLRenderTarget as WebGLRenderTarget2
|
|
17581
18007
|
} from "three";
|
|
17582
18008
|
|
|
18009
|
+
// src/webvr/lens-center.ts
|
|
18010
|
+
function physicalScreenFromDiagonal(screensizeInches, displayAspect) {
|
|
18011
|
+
if (!(Number.isFinite(screensizeInches) && screensizeInches > 0 && Number.isFinite(displayAspect) && displayAspect > 0)) {
|
|
18012
|
+
return null;
|
|
18013
|
+
}
|
|
18014
|
+
const diagonalMm = screensizeInches * 25.4;
|
|
18015
|
+
const heightMm = diagonalMm / Math.sqrt(displayAspect * displayAspect + 1);
|
|
18016
|
+
const widthMm = heightMm * displayAspect;
|
|
18017
|
+
if (!(heightMm > 0 && widthMm > 0)) {
|
|
18018
|
+
return null;
|
|
18019
|
+
}
|
|
18020
|
+
return { widthMm, heightMm };
|
|
18021
|
+
}
|
|
18022
|
+
function computeStereoLensCenters(profile, screensize, displayAspect) {
|
|
18023
|
+
const zero = { left: { x: 0, y: 0 }, right: { x: 0, y: 0 } };
|
|
18024
|
+
if (screensize === "auto") {
|
|
18025
|
+
return zero;
|
|
18026
|
+
}
|
|
18027
|
+
const screen = physicalScreenFromDiagonal(screensize, displayAspect);
|
|
18028
|
+
if (!screen) {
|
|
18029
|
+
return zero;
|
|
18030
|
+
}
|
|
18031
|
+
const halfEyeWidthMm = screen.widthMm / 4;
|
|
18032
|
+
const ipdMm = Number.isFinite(profile.ipdMm) ? profile.ipdMm : 60;
|
|
18033
|
+
const x = halfEyeWidthMm > 0 ? (halfEyeWidthMm - ipdMm / 2) / halfEyeWidthMm : 0;
|
|
18034
|
+
const trayDistanceMm = typeof profile.trayDistanceMm === "number" && Number.isFinite(profile.trayDistanceMm) && profile.trayDistanceMm > 0 ? profile.trayDistanceMm : 0;
|
|
18035
|
+
const y = trayDistanceMm > 0 && screen.heightMm > 0 ? 2 * trayDistanceMm / screen.heightMm - 1 : 0;
|
|
18036
|
+
const clampUnit = (value) => Math.max(-1, Math.min(1, Number.isFinite(value) ? value : 0));
|
|
18037
|
+
return {
|
|
18038
|
+
left: { x: clampUnit(x), y: clampUnit(y) },
|
|
18039
|
+
right: { x: clampUnit(-x), y: clampUnit(y) }
|
|
18040
|
+
};
|
|
18041
|
+
}
|
|
18042
|
+
|
|
17583
18043
|
// src/webvr/stereo-disparity.ts
|
|
17584
18044
|
var WEBVR_PANORAMA_VIRTUAL_DISTANCE_M = 2;
|
|
17585
18045
|
function panoramaStereoHalfAngle(ipdMm, virtualDistanceM = WEBVR_PANORAMA_VIRTUAL_DISTANCE_M) {
|
|
@@ -17595,19 +18055,32 @@ function panoramaStereoToeInYaw(eye, halfAngleRad) {
|
|
|
17595
18055
|
}
|
|
17596
18056
|
|
|
17597
18057
|
// src/webvr/stereo-layout.ts
|
|
17598
|
-
|
|
18058
|
+
var DEFAULT_WEBVR_OVERSAMPLING = 1;
|
|
18059
|
+
var MIN_WEBVR_OVERSAMPLING = 0.5;
|
|
18060
|
+
var MAX_WEBVR_OVERSAMPLING = 2;
|
|
18061
|
+
function clampWebVROversampling(value) {
|
|
18062
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
18063
|
+
return DEFAULT_WEBVR_OVERSAMPLING;
|
|
18064
|
+
}
|
|
18065
|
+
return Math.max(
|
|
18066
|
+
MIN_WEBVR_OVERSAMPLING,
|
|
18067
|
+
Math.min(MAX_WEBVR_OVERSAMPLING, value)
|
|
18068
|
+
);
|
|
18069
|
+
}
|
|
18070
|
+
function computeStereoLayout(logicalWidth, logicalHeight, pixelRatio, oversampling = DEFAULT_WEBVR_OVERSAMPLING) {
|
|
17599
18071
|
const fullWidth = Math.max(2, Math.floor(logicalWidth));
|
|
17600
18072
|
const fullHeight = Math.max(1, Math.floor(logicalHeight));
|
|
17601
18073
|
const leftWidth = Math.max(1, Math.floor(fullWidth / 2));
|
|
17602
18074
|
const rightWidth = Math.max(1, fullWidth - leftWidth);
|
|
17603
18075
|
const ratio = Number.isFinite(pixelRatio) && pixelRatio > 0 ? pixelRatio : 1;
|
|
18076
|
+
const scale = clampWebVROversampling(oversampling);
|
|
17604
18077
|
return {
|
|
17605
18078
|
fullWidth,
|
|
17606
18079
|
fullHeight,
|
|
17607
18080
|
left: { width: leftWidth, height: fullHeight, offsetX: 0 },
|
|
17608
18081
|
right: { width: rightWidth, height: fullHeight, offsetX: leftWidth },
|
|
17609
|
-
renderTargetWidth: Math.max(1, Math.floor(leftWidth * ratio)),
|
|
17610
|
-
renderTargetHeight: Math.max(1, Math.floor(fullHeight * ratio)),
|
|
18082
|
+
renderTargetWidth: Math.max(1, Math.floor(leftWidth * ratio * scale)),
|
|
18083
|
+
renderTargetHeight: Math.max(1, Math.floor(fullHeight * ratio * scale)),
|
|
17611
18084
|
stereoAspect: leftWidth / fullWidth
|
|
17612
18085
|
};
|
|
17613
18086
|
}
|
|
@@ -17624,12 +18097,13 @@ void main() {
|
|
|
17624
18097
|
var fragmentShader = `
|
|
17625
18098
|
uniform sampler2D sourceTexture;
|
|
17626
18099
|
uniform vec2 distortion;
|
|
18100
|
+
uniform vec2 lensCenter;
|
|
17627
18101
|
varying vec2 vUv;
|
|
17628
18102
|
void main() {
|
|
17629
|
-
vec2 centered = vUv * 2.0 - 1.0;
|
|
18103
|
+
vec2 centered = vUv * 2.0 - 1.0 - lensCenter;
|
|
17630
18104
|
float radius2 = dot(centered, centered);
|
|
17631
18105
|
float scale = 1.0 + distortion.x * radius2 + distortion.y * radius2 * radius2;
|
|
17632
|
-
vec2 sourceUv = centered * scale * 0.5 + 0.5;
|
|
18106
|
+
vec2 sourceUv = (centered * scale + lensCenter) * 0.5 + 0.5;
|
|
17633
18107
|
if (sourceUv.x < 0.0 || sourceUv.x > 1.0 || sourceUv.y < 0.0 || sourceUv.y > 1.0) {
|
|
17634
18108
|
gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
|
|
17635
18109
|
} else {
|
|
@@ -17649,6 +18123,7 @@ function createDistortionResources() {
|
|
|
17649
18123
|
fragmentShader,
|
|
17650
18124
|
uniforms: {
|
|
17651
18125
|
distortion: { value: new Vector28() },
|
|
18126
|
+
lensCenter: { value: new Vector28() },
|
|
17652
18127
|
sourceTexture: { value: target.texture }
|
|
17653
18128
|
},
|
|
17654
18129
|
vertexShader
|
|
@@ -17665,12 +18140,27 @@ function createDistortionResources() {
|
|
|
17665
18140
|
target
|
|
17666
18141
|
};
|
|
17667
18142
|
}
|
|
17668
|
-
function
|
|
18143
|
+
function applyEyeViewOffset(eyeCamera, eye, center) {
|
|
18144
|
+
const fullWidth = eye.width;
|
|
18145
|
+
const fullHeight = eye.height;
|
|
18146
|
+
const offsetX = ((center.x + 1) / 2 - 0.5) * fullWidth;
|
|
18147
|
+
const offsetY = (0.5 - (center.y + 1) / 2) * fullHeight;
|
|
18148
|
+
eyeCamera.setViewOffset(
|
|
18149
|
+
fullWidth,
|
|
18150
|
+
fullHeight,
|
|
18151
|
+
offsetX,
|
|
18152
|
+
offsetY,
|
|
18153
|
+
fullWidth,
|
|
18154
|
+
fullHeight
|
|
18155
|
+
);
|
|
18156
|
+
}
|
|
18157
|
+
function syncStereoCameras(stereo, camera, profile, screensize, oversampling, size, gl) {
|
|
17669
18158
|
gl.getSize(size);
|
|
17670
18159
|
const layout = computeStereoLayout(
|
|
17671
18160
|
size.x,
|
|
17672
18161
|
size.y,
|
|
17673
|
-
gl.getPixelRatio()
|
|
18162
|
+
gl.getPixelRatio(),
|
|
18163
|
+
oversampling
|
|
17674
18164
|
);
|
|
17675
18165
|
const screenToLensMm = profile.screenToLensMm ?? 42;
|
|
17676
18166
|
const displayAspect = layout.fullWidth / layout.fullHeight;
|
|
@@ -17689,34 +18179,40 @@ function syncStereoCameras(stereo, camera, profile, screensize, size, gl) {
|
|
|
17689
18179
|
TOE_IN.makeRotationY(panoramaStereoToeInYaw("right", halfAngle));
|
|
17690
18180
|
stereo.cameraR.matrix.multiply(TOE_IN);
|
|
17691
18181
|
stereo.cameraR.matrixWorldNeedsUpdate = true;
|
|
18182
|
+
const centers = computeStereoLensCenters(profile, screensize, displayAspect);
|
|
18183
|
+
applyEyeViewOffset(stereo.cameraL, layout.left, centers.left);
|
|
18184
|
+
applyEyeViewOffset(stereo.cameraR, layout.right, centers.right);
|
|
17692
18185
|
stereo.cameraL.updateMatrixWorld(true);
|
|
17693
18186
|
stereo.cameraR.updateMatrixWorld(true);
|
|
17694
|
-
return layout;
|
|
18187
|
+
return { layout, centers };
|
|
17695
18188
|
}
|
|
17696
18189
|
function WebVRStereoRenderer({
|
|
17697
18190
|
mode,
|
|
18191
|
+
oversampling = 1,
|
|
17698
18192
|
profile,
|
|
17699
18193
|
screensize
|
|
17700
18194
|
}) {
|
|
17701
18195
|
const { camera, gl } = useThree27();
|
|
17702
18196
|
const runtime = useContext26(WebVRRuntimeContext);
|
|
17703
|
-
const fallbackStereoRef =
|
|
18197
|
+
const fallbackStereoRef = useRef38(null);
|
|
17704
18198
|
if (!fallbackStereoRef.current) {
|
|
17705
18199
|
fallbackStereoRef.current = new StereoCamera2();
|
|
17706
18200
|
}
|
|
17707
18201
|
const stereo = runtime?.stereoView.stereo ?? fallbackStereoRef.current;
|
|
17708
|
-
const stereoRef =
|
|
18202
|
+
const stereoRef = useRef38(stereo);
|
|
17709
18203
|
stereoRef.current = stereo;
|
|
17710
18204
|
const resources = useMemo25(createDistortionResources, []);
|
|
17711
|
-
const sizeRef =
|
|
17712
|
-
const viewportRef =
|
|
17713
|
-
const scissorRef =
|
|
17714
|
-
const originalFovRef =
|
|
17715
|
-
const stereoActiveRef =
|
|
17716
|
-
const profileRef =
|
|
17717
|
-
const screensizeRef =
|
|
18205
|
+
const sizeRef = useRef38(new Vector28());
|
|
18206
|
+
const viewportRef = useRef38(new Vector42());
|
|
18207
|
+
const scissorRef = useRef38(new Vector42());
|
|
18208
|
+
const originalFovRef = useRef38(null);
|
|
18209
|
+
const stereoActiveRef = useRef38(false);
|
|
18210
|
+
const profileRef = useRef38(profile);
|
|
18211
|
+
const screensizeRef = useRef38(screensize);
|
|
18212
|
+
const oversamplingRef = useRef38(clampWebVROversampling(oversampling));
|
|
17718
18213
|
profileRef.current = profile;
|
|
17719
18214
|
screensizeRef.current = screensize;
|
|
18215
|
+
oversamplingRef.current = clampWebVROversampling(oversampling);
|
|
17720
18216
|
useEffect37(
|
|
17721
18217
|
() => () => {
|
|
17722
18218
|
resources.geometry.dispose();
|
|
@@ -17737,11 +18233,12 @@ function WebVRStereoRenderer({
|
|
|
17737
18233
|
if (originalFovRef.current === null) {
|
|
17738
18234
|
originalFovRef.current = cameraToRender.fov;
|
|
17739
18235
|
}
|
|
17740
|
-
const layout = syncStereoCameras(
|
|
18236
|
+
const { layout, centers } = syncStereoCameras(
|
|
17741
18237
|
stereoRef.current,
|
|
17742
18238
|
cameraToRender,
|
|
17743
18239
|
currentProfile,
|
|
17744
18240
|
currentScreensize,
|
|
18241
|
+
oversamplingRef.current,
|
|
17745
18242
|
sizeRef.current,
|
|
17746
18243
|
gl
|
|
17747
18244
|
);
|
|
@@ -17753,7 +18250,7 @@ function WebVRStereoRenderer({
|
|
|
17753
18250
|
gl.getScissor(scissorRef.current);
|
|
17754
18251
|
gl.autoClear = true;
|
|
17755
18252
|
gl.setScissorTest(true);
|
|
17756
|
-
const renderEye = (eyeCamera, eye) => {
|
|
18253
|
+
const renderEye = (eyeCamera, eye, center) => {
|
|
17757
18254
|
if (hasDistortion) {
|
|
17758
18255
|
if (resources.target.width !== layout.renderTargetWidth || resources.target.height !== layout.renderTargetHeight) {
|
|
17759
18256
|
resources.target.setSize(
|
|
@@ -17770,6 +18267,7 @@ function WebVRStereoRenderer({
|
|
|
17770
18267
|
currentProfile.k1,
|
|
17771
18268
|
currentProfile.k2
|
|
17772
18269
|
);
|
|
18270
|
+
resources.material.uniforms.lensCenter?.value.set(center.x, center.y);
|
|
17773
18271
|
originalRender(resources.scene, resources.camera);
|
|
17774
18272
|
return;
|
|
17775
18273
|
}
|
|
@@ -17778,8 +18276,8 @@ function WebVRStereoRenderer({
|
|
|
17778
18276
|
gl.setScissor(eye.offsetX, 0, eye.width, eye.height);
|
|
17779
18277
|
originalRender(sceneToRender, eyeCamera);
|
|
17780
18278
|
};
|
|
17781
|
-
renderEye(stereoRef.current.cameraL, layout.left);
|
|
17782
|
-
renderEye(stereoRef.current.cameraR, layout.right);
|
|
18279
|
+
renderEye(stereoRef.current.cameraL, layout.left, centers.left);
|
|
18280
|
+
renderEye(stereoRef.current.cameraR, layout.right, centers.right);
|
|
17783
18281
|
gl.setRenderTarget(previousTarget);
|
|
17784
18282
|
gl.setViewport(viewportRef.current);
|
|
17785
18283
|
gl.setScissor(scissorRef.current);
|
|
@@ -17810,6 +18308,7 @@ function WebVRStereoRenderer({
|
|
|
17810
18308
|
camera,
|
|
17811
18309
|
profileRef.current,
|
|
17812
18310
|
screensizeRef.current,
|
|
18311
|
+
oversamplingRef.current,
|
|
17813
18312
|
sizeRef.current,
|
|
17814
18313
|
gl
|
|
17815
18314
|
);
|
|
@@ -17825,7 +18324,7 @@ function WebVRStereoRenderer({
|
|
|
17825
18324
|
}
|
|
17826
18325
|
|
|
17827
18326
|
// src/webvr/pointerlock.ts
|
|
17828
|
-
import { useEffect as useEffect38, useRef as
|
|
18327
|
+
import { useEffect as useEffect38, useRef as useRef39 } from "react";
|
|
17829
18328
|
var POINTER_LOCK_CURSOR_ID = "webvr:pointerlock";
|
|
17830
18329
|
async function requestWebVRPointerLock(element) {
|
|
17831
18330
|
if (typeof document === "undefined") {
|
|
@@ -17858,8 +18357,8 @@ function exitWebVRPointerLock(element) {
|
|
|
17858
18357
|
}
|
|
17859
18358
|
function useWebVRPointerLock(enabled, element) {
|
|
17860
18359
|
const cursor = usePanoCursor();
|
|
17861
|
-
const cursorRef =
|
|
17862
|
-
const enabledRef =
|
|
18360
|
+
const cursorRef = useRef39(cursor);
|
|
18361
|
+
const enabledRef = useRef39(enabled);
|
|
17863
18362
|
cursorRef.current = cursor;
|
|
17864
18363
|
enabledRef.current = enabled;
|
|
17865
18364
|
useEffect38(() => {
|
|
@@ -18039,8 +18538,44 @@ function useWebVRWakeLock(enabled) {
|
|
|
18039
18538
|
}, [enabled]);
|
|
18040
18539
|
}
|
|
18041
18540
|
|
|
18541
|
+
// src/webvr/xr-quality.ts
|
|
18542
|
+
function clampWebVRFoveation(value) {
|
|
18543
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
18544
|
+
return void 0;
|
|
18545
|
+
}
|
|
18546
|
+
return Math.max(0, Math.min(1, value));
|
|
18547
|
+
}
|
|
18548
|
+
function resolveWebVRFrameRateOption(frameRate) {
|
|
18549
|
+
if (frameRate === void 0) {
|
|
18550
|
+
return void 0;
|
|
18551
|
+
}
|
|
18552
|
+
if (frameRate === "low" || frameRate === "mid" || frameRate === "high") {
|
|
18553
|
+
return frameRate;
|
|
18554
|
+
}
|
|
18555
|
+
if (typeof frameRate !== "number" || !Number.isFinite(frameRate)) {
|
|
18556
|
+
return void 0;
|
|
18557
|
+
}
|
|
18558
|
+
const target = frameRate;
|
|
18559
|
+
return (rates) => {
|
|
18560
|
+
if (rates.length === 0) {
|
|
18561
|
+
return false;
|
|
18562
|
+
}
|
|
18563
|
+
let best = rates[0];
|
|
18564
|
+
let bestDelta = Math.abs(best - target);
|
|
18565
|
+
for (let i = 1; i < rates.length; i += 1) {
|
|
18566
|
+
const candidate = rates[i];
|
|
18567
|
+
const delta = Math.abs(candidate - target);
|
|
18568
|
+
if (delta < bestDelta) {
|
|
18569
|
+
best = candidate;
|
|
18570
|
+
bestDelta = delta;
|
|
18571
|
+
}
|
|
18572
|
+
}
|
|
18573
|
+
return best;
|
|
18574
|
+
};
|
|
18575
|
+
}
|
|
18576
|
+
|
|
18042
18577
|
// src/webvr/webvr.tsx
|
|
18043
|
-
import { Fragment as
|
|
18578
|
+
import { Fragment as Fragment8, jsx as jsx40, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
18044
18579
|
function initializeSettings(screensize, profile) {
|
|
18045
18580
|
const stored = loadWebVRSettings();
|
|
18046
18581
|
return {
|
|
@@ -18057,7 +18592,15 @@ var WebVR = forwardRef4(function WebVR2({
|
|
|
18057
18592
|
desktopSupport = false,
|
|
18058
18593
|
fakeSupport = true,
|
|
18059
18594
|
screensize,
|
|
18595
|
+
databaseUrl,
|
|
18060
18596
|
profile,
|
|
18597
|
+
absolute = false,
|
|
18598
|
+
north = 0,
|
|
18599
|
+
friction = 0,
|
|
18600
|
+
touchSupport = false,
|
|
18601
|
+
oversampling = 1,
|
|
18602
|
+
foveation,
|
|
18603
|
+
frameRate,
|
|
18061
18604
|
cursor = true,
|
|
18062
18605
|
cursorDwellMs = DEFAULT_WEBVR_CURSOR_DWELL_MS,
|
|
18063
18606
|
wakelock = true,
|
|
@@ -18073,20 +18616,36 @@ var WebVR = forwardRef4(function WebVR2({
|
|
|
18073
18616
|
const controlsRef = useContext27(PanoramaViewContext);
|
|
18074
18617
|
const eventBus = useContext27(PanoEventBusContext);
|
|
18075
18618
|
const gl = useThree28((state) => state.gl);
|
|
18076
|
-
const gyroRef =
|
|
18077
|
-
const capabilitiesRef =
|
|
18619
|
+
const gyroRef = useRef40(null);
|
|
18620
|
+
const capabilitiesRef = useRef40({
|
|
18078
18621
|
mobile: false,
|
|
18079
18622
|
sensor: false,
|
|
18080
18623
|
webxr: false
|
|
18081
18624
|
});
|
|
18082
|
-
const availableRef =
|
|
18083
|
-
const modeRef =
|
|
18084
|
-
const webXRSessionRef =
|
|
18625
|
+
const availableRef = useRef40(false);
|
|
18626
|
+
const modeRef = useRef40(null);
|
|
18627
|
+
const webXRSessionRef = useRef40(null);
|
|
18628
|
+
const dpdbRequestIdRef = useRef40(0);
|
|
18629
|
+
const databaseUrlRef = useRef40(databaseUrl);
|
|
18630
|
+
databaseUrlRef.current = databaseUrl;
|
|
18631
|
+
const oversamplingRef = useRef40(clampWebVROversampling(oversampling));
|
|
18632
|
+
oversamplingRef.current = clampWebVROversampling(oversampling);
|
|
18633
|
+
const foveationRef = useRef40(clampWebVRFoveation(foveation));
|
|
18634
|
+
foveationRef.current = clampWebVRFoveation(foveation);
|
|
18635
|
+
const frameRateRef = useRef40(frameRate);
|
|
18636
|
+
frameRateRef.current = frameRate;
|
|
18637
|
+
const screensizePropRef = useRef40(screensize);
|
|
18638
|
+
screensizePropRef.current = screensize;
|
|
18639
|
+
const profilePropRef = useRef40(profile);
|
|
18640
|
+
profilePropRef.current = profile;
|
|
18085
18641
|
const [mode, setMode] = useState24(null);
|
|
18086
18642
|
const [settings, setSettings] = useState24(
|
|
18087
18643
|
() => initializeSettings(screensize, profile)
|
|
18088
18644
|
);
|
|
18089
|
-
const
|
|
18645
|
+
const [detectedScreensize, setDetectedScreensize] = useState24(
|
|
18646
|
+
null
|
|
18647
|
+
);
|
|
18648
|
+
const callbacksRef = useRef40({
|
|
18090
18649
|
onAvailable,
|
|
18091
18650
|
onDenied,
|
|
18092
18651
|
onEnterVR,
|
|
@@ -18110,18 +18669,44 @@ var WebVR = forwardRef4(function WebVR2({
|
|
|
18110
18669
|
() => resolveWebVRProfile(profile, settings.profileId),
|
|
18111
18670
|
[profile, settings.profileId]
|
|
18112
18671
|
);
|
|
18113
|
-
const
|
|
18672
|
+
const effectiveScreensize = settings.screensize === "auto" ? detectedScreensize ?? "auto" : settings.screensize;
|
|
18673
|
+
const resolvedOversampling = clampWebVROversampling(oversampling);
|
|
18674
|
+
const reportDenied = useCallback11(
|
|
18114
18675
|
(error) => {
|
|
18115
18676
|
eventBus.emit("vrdenied", { error });
|
|
18116
18677
|
callbacksRef.current.onDenied?.(error);
|
|
18117
18678
|
},
|
|
18118
18679
|
[eventBus]
|
|
18119
18680
|
);
|
|
18120
|
-
const reportUnknownDevice =
|
|
18681
|
+
const reportUnknownDevice = useCallback11(() => {
|
|
18121
18682
|
eventBus.emit("vrunknowndevice", void 0);
|
|
18122
18683
|
callbacksRef.current.onUnknownDevice?.();
|
|
18123
18684
|
}, [eventBus]);
|
|
18124
|
-
const
|
|
18685
|
+
const clearDetectedScreensize = useCallback11(() => {
|
|
18686
|
+
dpdbRequestIdRef.current += 1;
|
|
18687
|
+
setDetectedScreensize(null);
|
|
18688
|
+
updateWebVRHost(host, { detectedScreensize: null });
|
|
18689
|
+
}, [host]);
|
|
18690
|
+
const resolveAutoScreensize = useCallback11(() => {
|
|
18691
|
+
const requestId = ++dpdbRequestIdRef.current;
|
|
18692
|
+
const url = normalizeDatabaseUrl(databaseUrlRef.current);
|
|
18693
|
+
if (!url) {
|
|
18694
|
+
reportUnknownDevice();
|
|
18695
|
+
return;
|
|
18696
|
+
}
|
|
18697
|
+
void resolveScreensizeFromDpdb(url).then((inches) => {
|
|
18698
|
+
if (requestId !== dpdbRequestIdRef.current) {
|
|
18699
|
+
return;
|
|
18700
|
+
}
|
|
18701
|
+
if (inches === null) {
|
|
18702
|
+
reportUnknownDevice();
|
|
18703
|
+
return;
|
|
18704
|
+
}
|
|
18705
|
+
setDetectedScreensize(inches);
|
|
18706
|
+
updateWebVRHost(host, { detectedScreensize: inches });
|
|
18707
|
+
});
|
|
18708
|
+
}, [host, reportUnknownDevice]);
|
|
18709
|
+
const activate = useCallback11(
|
|
18125
18710
|
(nextMode) => {
|
|
18126
18711
|
if (modeRef.current === nextMode) {
|
|
18127
18712
|
return;
|
|
@@ -18136,7 +18721,7 @@ var WebVR = forwardRef4(function WebVR2({
|
|
|
18136
18721
|
},
|
|
18137
18722
|
[controlsRef, eventBus]
|
|
18138
18723
|
);
|
|
18139
|
-
const deactivate =
|
|
18724
|
+
const deactivate = useCallback11(
|
|
18140
18725
|
(expectedMode) => {
|
|
18141
18726
|
const previousMode = modeRef.current;
|
|
18142
18727
|
if (!previousMode || expectedMode && previousMode !== expectedMode) {
|
|
@@ -18144,6 +18729,7 @@ var WebVR = forwardRef4(function WebVR2({
|
|
|
18144
18729
|
}
|
|
18145
18730
|
modeRef.current = null;
|
|
18146
18731
|
setMode(null);
|
|
18732
|
+
clearDetectedScreensize();
|
|
18147
18733
|
if (previousMode === "fake") {
|
|
18148
18734
|
controlsRef.current?.setGyroActive(false);
|
|
18149
18735
|
}
|
|
@@ -18151,24 +18737,42 @@ var WebVR = forwardRef4(function WebVR2({
|
|
|
18151
18737
|
eventBus.emit("vrexit", { mode: previousMode });
|
|
18152
18738
|
callbacksRef.current.onExitVR?.(previousMode);
|
|
18153
18739
|
},
|
|
18154
|
-
[controlsRef, eventBus, gl.domElement]
|
|
18740
|
+
[clearDetectedScreensize, controlsRef, eventBus, gl.domElement]
|
|
18155
18741
|
);
|
|
18156
|
-
const requestPermission =
|
|
18742
|
+
const requestPermission = useCallback11(async () => {
|
|
18157
18743
|
return await gyroRef.current?.requestPermission() ?? false;
|
|
18158
18744
|
}, []);
|
|
18159
|
-
const
|
|
18745
|
+
const applyWebXRQuality = useCallback11(() => {
|
|
18746
|
+
const scale = oversamplingRef.current;
|
|
18747
|
+
if (typeof gl.xr.setFramebufferScaleFactor === "function") {
|
|
18748
|
+
gl.xr.setFramebufferScaleFactor(scale);
|
|
18749
|
+
}
|
|
18750
|
+
const nextFoveation = foveationRef.current;
|
|
18751
|
+
if (nextFoveation !== void 0 && typeof gl.xr.setFoveation === "function") {
|
|
18752
|
+
gl.xr.setFoveation(nextFoveation);
|
|
18753
|
+
}
|
|
18754
|
+
const frameRateOption = resolveWebVRFrameRateOption(frameRateRef.current);
|
|
18755
|
+
if (frameRateOption !== void 0) {
|
|
18756
|
+
xrStore.setFrameRate(frameRateOption);
|
|
18757
|
+
}
|
|
18758
|
+
}, [gl.xr, xrStore]);
|
|
18759
|
+
const enterVR = useCallback11(async () => {
|
|
18160
18760
|
if (modeRef.current) {
|
|
18161
18761
|
return true;
|
|
18162
18762
|
}
|
|
18163
18763
|
const capabilities = capabilitiesRef.current;
|
|
18164
18764
|
if (capabilities.webxr) {
|
|
18165
18765
|
try {
|
|
18766
|
+
if (typeof gl.xr.setFramebufferScaleFactor === "function") {
|
|
18767
|
+
gl.xr.setFramebufferScaleFactor(oversamplingRef.current);
|
|
18768
|
+
}
|
|
18166
18769
|
await xrStore.enterVR();
|
|
18167
18770
|
const session2 = xrStore.getState().session;
|
|
18168
18771
|
if (!session2) {
|
|
18169
18772
|
throw new Error("The WebXR session did not start.");
|
|
18170
18773
|
}
|
|
18171
18774
|
webXRSessionRef.current = session2;
|
|
18775
|
+
applyWebXRQuality();
|
|
18172
18776
|
session2.addEventListener(
|
|
18173
18777
|
"end",
|
|
18174
18778
|
() => {
|
|
@@ -18198,10 +18802,10 @@ var WebVR = forwardRef4(function WebVR2({
|
|
|
18198
18802
|
reportDenied();
|
|
18199
18803
|
return false;
|
|
18200
18804
|
}
|
|
18805
|
+
activate("mobilevr");
|
|
18201
18806
|
if (settings.screensize === "auto") {
|
|
18202
|
-
|
|
18807
|
+
resolveAutoScreensize();
|
|
18203
18808
|
}
|
|
18204
|
-
activate("mobilevr");
|
|
18205
18809
|
return true;
|
|
18206
18810
|
}
|
|
18207
18811
|
if (fakeSupport) {
|
|
@@ -18220,21 +18824,23 @@ var WebVR = forwardRef4(function WebVR2({
|
|
|
18220
18824
|
return false;
|
|
18221
18825
|
}, [
|
|
18222
18826
|
activate,
|
|
18827
|
+
applyWebXRQuality,
|
|
18223
18828
|
deactivate,
|
|
18224
18829
|
desktopSupport,
|
|
18225
18830
|
eventBus,
|
|
18226
18831
|
fakeSupport,
|
|
18227
18832
|
gl.domElement,
|
|
18833
|
+
gl.xr,
|
|
18228
18834
|
mobileVr,
|
|
18229
18835
|
mousePointerLock,
|
|
18230
18836
|
reportDenied,
|
|
18231
|
-
reportUnknownDevice,
|
|
18232
18837
|
requestPermission,
|
|
18838
|
+
resolveAutoScreensize,
|
|
18233
18839
|
settings.screensize,
|
|
18234
18840
|
wakelock,
|
|
18235
18841
|
xrStore
|
|
18236
18842
|
]);
|
|
18237
|
-
const exitVR =
|
|
18843
|
+
const exitVR = useCallback11(async () => {
|
|
18238
18844
|
if (modeRef.current === "webxr") {
|
|
18239
18845
|
const session2 = webXRSessionRef.current ?? xrStore.getState().session ?? null;
|
|
18240
18846
|
if (session2) {
|
|
@@ -18247,21 +18853,52 @@ var WebVR = forwardRef4(function WebVR2({
|
|
|
18247
18853
|
deactivate();
|
|
18248
18854
|
leaveWebVRPresentation();
|
|
18249
18855
|
}, [deactivate, xrStore]);
|
|
18250
|
-
const toggleVR =
|
|
18856
|
+
const toggleVR = useCallback11(async () => {
|
|
18251
18857
|
if (modeRef.current) {
|
|
18252
18858
|
await exitVR();
|
|
18253
18859
|
return false;
|
|
18254
18860
|
}
|
|
18255
18861
|
return enterVR();
|
|
18256
18862
|
}, [enterVR, exitVR]);
|
|
18257
|
-
const updateSettings =
|
|
18258
|
-
|
|
18259
|
-
|
|
18260
|
-
|
|
18261
|
-
|
|
18262
|
-
|
|
18263
|
-
|
|
18264
|
-
|
|
18863
|
+
const updateSettings = useCallback11(
|
|
18864
|
+
(next) => {
|
|
18865
|
+
const normalized = {
|
|
18866
|
+
profileId: next.profileId,
|
|
18867
|
+
screensize: next.screensize === "auto" ? "auto" : Math.round(Math.max(3, Math.min(20, next.screensize)) * 10) / 10
|
|
18868
|
+
};
|
|
18869
|
+
setSettings(normalized);
|
|
18870
|
+
saveWebVRSettings(normalized);
|
|
18871
|
+
if (normalized.screensize === "auto") {
|
|
18872
|
+
if (modeRef.current === "mobilevr") {
|
|
18873
|
+
setDetectedScreensize(null);
|
|
18874
|
+
updateWebVRHost(host, { detectedScreensize: null });
|
|
18875
|
+
resolveAutoScreensize();
|
|
18876
|
+
}
|
|
18877
|
+
} else {
|
|
18878
|
+
clearDetectedScreensize();
|
|
18879
|
+
}
|
|
18880
|
+
},
|
|
18881
|
+
[clearDetectedScreensize, host, resolveAutoScreensize]
|
|
18882
|
+
);
|
|
18883
|
+
const resetSettings = useCallback11(() => {
|
|
18884
|
+
clearWebVRSettings();
|
|
18885
|
+
const next = resolveInitialWebVRSettings(
|
|
18886
|
+
screensizePropRef.current,
|
|
18887
|
+
profilePropRef.current
|
|
18888
|
+
);
|
|
18889
|
+
setSettings(next);
|
|
18890
|
+
if (next.screensize === "auto") {
|
|
18891
|
+
if (modeRef.current === "mobilevr") {
|
|
18892
|
+
setDetectedScreensize(null);
|
|
18893
|
+
updateWebVRHost(host, { detectedScreensize: null });
|
|
18894
|
+
resolveAutoScreensize();
|
|
18895
|
+
} else {
|
|
18896
|
+
clearDetectedScreensize();
|
|
18897
|
+
}
|
|
18898
|
+
} else {
|
|
18899
|
+
clearDetectedScreensize();
|
|
18900
|
+
}
|
|
18901
|
+
}, [clearDetectedScreensize, host, resolveAutoScreensize]);
|
|
18265
18902
|
const controller = useMemo26(
|
|
18266
18903
|
() => ({
|
|
18267
18904
|
closeSetup: () => updateWebVRHost(host, { setupOpen: false }),
|
|
@@ -18269,10 +18906,19 @@ var WebVR = forwardRef4(function WebVR2({
|
|
|
18269
18906
|
exitVR,
|
|
18270
18907
|
openSetup: () => updateWebVRHost(host, { setupOpen: true }),
|
|
18271
18908
|
requestPermission,
|
|
18909
|
+
resetSettings,
|
|
18272
18910
|
toggleVR,
|
|
18273
18911
|
updateSettings
|
|
18274
18912
|
}),
|
|
18275
|
-
[
|
|
18913
|
+
[
|
|
18914
|
+
enterVR,
|
|
18915
|
+
exitVR,
|
|
18916
|
+
host,
|
|
18917
|
+
requestPermission,
|
|
18918
|
+
resetSettings,
|
|
18919
|
+
toggleVR,
|
|
18920
|
+
updateSettings
|
|
18921
|
+
]
|
|
18276
18922
|
);
|
|
18277
18923
|
useImperativeHandle4(
|
|
18278
18924
|
ref,
|
|
@@ -18280,12 +18926,15 @@ var WebVR = forwardRef4(function WebVR2({
|
|
|
18280
18926
|
enterVR,
|
|
18281
18927
|
exitVR,
|
|
18282
18928
|
getMode: () => modeRef.current,
|
|
18929
|
+
getState: () => getWebVRState(host),
|
|
18283
18930
|
isAvailable: () => availableRef.current,
|
|
18284
18931
|
isEnabled: () => modeRef.current !== null,
|
|
18285
18932
|
requestPermission,
|
|
18933
|
+
resetSettings,
|
|
18934
|
+
subscribe: (onStoreChange) => subscribeWebVRHost(host, onStoreChange),
|
|
18286
18935
|
toggleVR
|
|
18287
18936
|
}),
|
|
18288
|
-
[enterVR, exitVR, requestPermission, toggleVR]
|
|
18937
|
+
[enterVR, exitVR, host, requestPermission, resetSettings, toggleVR]
|
|
18289
18938
|
);
|
|
18290
18939
|
useEffect40(() => {
|
|
18291
18940
|
let active = true;
|
|
@@ -18314,13 +18963,24 @@ var WebVR = forwardRef4(function WebVR2({
|
|
|
18314
18963
|
return () => {
|
|
18315
18964
|
if (host.controller === controller) {
|
|
18316
18965
|
host.controller = null;
|
|
18317
|
-
|
|
18966
|
+
dpdbRequestIdRef.current += 1;
|
|
18967
|
+
setDetectedScreensize(null);
|
|
18968
|
+
updateWebVRHost(host, {
|
|
18969
|
+
detectedScreensize: null,
|
|
18970
|
+
mode: null,
|
|
18971
|
+
setupOpen: false
|
|
18972
|
+
});
|
|
18318
18973
|
}
|
|
18319
18974
|
};
|
|
18320
18975
|
}, [controller, host]);
|
|
18321
18976
|
useEffect40(() => {
|
|
18322
|
-
updateWebVRHost(host, {
|
|
18323
|
-
|
|
18977
|
+
updateWebVRHost(host, {
|
|
18978
|
+
chrome,
|
|
18979
|
+
detectedScreensize,
|
|
18980
|
+
mode,
|
|
18981
|
+
settings
|
|
18982
|
+
});
|
|
18983
|
+
}, [chrome, detectedScreensize, host, mode, settings]);
|
|
18324
18984
|
useEffect40(() => {
|
|
18325
18985
|
if (mode !== "fake") {
|
|
18326
18986
|
return;
|
|
@@ -18369,6 +19029,23 @@ var WebVR = forwardRef4(function WebVR2({
|
|
|
18369
19029
|
void exitVR();
|
|
18370
19030
|
});
|
|
18371
19031
|
}, [exitVR, gl.domElement, mode]);
|
|
19032
|
+
useEffect40(() => {
|
|
19033
|
+
if (mode !== "webxr") {
|
|
19034
|
+
return;
|
|
19035
|
+
}
|
|
19036
|
+
const session2 = webXRSessionRef.current ?? xrStore.getState().session ?? null;
|
|
19037
|
+
if (!session2) {
|
|
19038
|
+
return;
|
|
19039
|
+
}
|
|
19040
|
+
const nextFoveation = foveationRef.current;
|
|
19041
|
+
if (nextFoveation !== void 0 && typeof gl.xr.setFoveation === "function") {
|
|
19042
|
+
gl.xr.setFoveation(nextFoveation);
|
|
19043
|
+
}
|
|
19044
|
+
const frameRateOption = resolveWebVRFrameRateOption(frameRateRef.current);
|
|
19045
|
+
if (frameRateOption !== void 0) {
|
|
19046
|
+
xrStore.setFrameRate(frameRateOption);
|
|
19047
|
+
}
|
|
19048
|
+
}, [foveation, frameRate, gl.xr, mode, xrStore]);
|
|
18372
19049
|
useWebVRPointerLock(
|
|
18373
19050
|
mousePointerLock && mode === "fake",
|
|
18374
19051
|
gl.domElement
|
|
@@ -18376,27 +19053,31 @@ var WebVR = forwardRef4(function WebVR2({
|
|
|
18376
19053
|
useWebVRWakeLock(
|
|
18377
19054
|
wakelock && (mode === "mobilevr" || mode === "fake")
|
|
18378
19055
|
);
|
|
18379
|
-
return /* @__PURE__ */ jsxs21(
|
|
19056
|
+
return /* @__PURE__ */ jsxs21(Fragment8, { children: [
|
|
18380
19057
|
/* @__PURE__ */ jsx40(
|
|
18381
19058
|
Gyro,
|
|
18382
19059
|
{
|
|
18383
19060
|
ref: gyroRef,
|
|
19061
|
+
absolute,
|
|
18384
19062
|
desktopSupport,
|
|
18385
19063
|
enabled: mode === "mobilevr",
|
|
19064
|
+
friction,
|
|
19065
|
+
north,
|
|
18386
19066
|
onDenied: () => {
|
|
18387
19067
|
reportDenied();
|
|
18388
19068
|
deactivate("mobilevr");
|
|
18389
19069
|
},
|
|
18390
19070
|
softstart: 0,
|
|
18391
|
-
touchMode: "off"
|
|
19071
|
+
touchMode: touchSupport ? "horizontaloffset" : "off"
|
|
18392
19072
|
}
|
|
18393
19073
|
),
|
|
18394
19074
|
/* @__PURE__ */ jsx40(
|
|
18395
19075
|
WebVRStereoRenderer,
|
|
18396
19076
|
{
|
|
18397
19077
|
mode,
|
|
19078
|
+
oversampling: resolvedOversampling,
|
|
18398
19079
|
profile: resolvedProfile,
|
|
18399
|
-
screensize:
|
|
19080
|
+
screensize: effectiveScreensize
|
|
18400
19081
|
}
|
|
18401
19082
|
),
|
|
18402
19083
|
/* @__PURE__ */ jsx40(
|
|
@@ -18412,12 +19093,12 @@ var WebVR = forwardRef4(function WebVR2({
|
|
|
18412
19093
|
|
|
18413
19094
|
// src/pano-scene-menu.tsx
|
|
18414
19095
|
import {
|
|
18415
|
-
useCallback as
|
|
19096
|
+
useCallback as useCallback12,
|
|
18416
19097
|
useEffect as useEffect41,
|
|
18417
19098
|
useId as useId3,
|
|
18418
19099
|
useLayoutEffect as useLayoutEffect9,
|
|
18419
19100
|
useMemo as useMemo27,
|
|
18420
|
-
useRef as
|
|
19101
|
+
useRef as useRef41,
|
|
18421
19102
|
useState as useState25
|
|
18422
19103
|
} from "react";
|
|
18423
19104
|
|
|
@@ -18804,9 +19485,9 @@ function PanoSceneMenu({
|
|
|
18804
19485
|
collapseLabel = "Hide scenes"
|
|
18805
19486
|
}) {
|
|
18806
19487
|
const listId = useId3();
|
|
18807
|
-
const listRef =
|
|
18808
|
-
const trackRef =
|
|
18809
|
-
const itemRefs =
|
|
19488
|
+
const listRef = useRef41(null);
|
|
19489
|
+
const trackRef = useRef41(null);
|
|
19490
|
+
const itemRefs = useRef41(/* @__PURE__ */ new Map());
|
|
18810
19491
|
const resolved = resolveAppearance2(appearance);
|
|
18811
19492
|
const resolvedInset = resolveInset(inset);
|
|
18812
19493
|
const horizontal = isHorizontal(placement);
|
|
@@ -18820,9 +19501,9 @@ function PanoSceneMenu({
|
|
|
18820
19501
|
const [offset, setOffset] = useState25(0);
|
|
18821
19502
|
const [viewportSize, setViewportSize] = useState25(0);
|
|
18822
19503
|
const [contentSize, setContentSize] = useState25(0);
|
|
18823
|
-
const offsetRef =
|
|
18824
|
-
const dragRef =
|
|
18825
|
-
const animRef =
|
|
19504
|
+
const offsetRef = useRef41(0);
|
|
19505
|
+
const dragRef = useRef41(null);
|
|
19506
|
+
const animRef = useRef41(null);
|
|
18826
19507
|
const maxOffset = Math.max(0, contentSize - viewportSize);
|
|
18827
19508
|
offsetRef.current = offset;
|
|
18828
19509
|
const activeIndex = useMemo27(() => {
|
|
@@ -18831,18 +19512,18 @@ function PanoSceneMenu({
|
|
|
18831
19512
|
}
|
|
18832
19513
|
return items.findIndex((item) => item.id === activeId);
|
|
18833
19514
|
}, [activeId, items]);
|
|
18834
|
-
const cancelScrollAnimation =
|
|
19515
|
+
const cancelScrollAnimation = useCallback12(() => {
|
|
18835
19516
|
const anim = animRef.current;
|
|
18836
19517
|
if (anim?.raf != null) {
|
|
18837
19518
|
cancelAnimationFrame(anim.raf);
|
|
18838
19519
|
}
|
|
18839
19520
|
animRef.current = null;
|
|
18840
19521
|
}, []);
|
|
18841
|
-
const clampOffset =
|
|
19522
|
+
const clampOffset = useCallback12(
|
|
18842
19523
|
(value) => Math.min(maxOffset, Math.max(0, value)),
|
|
18843
19524
|
[maxOffset]
|
|
18844
19525
|
);
|
|
18845
|
-
const startScrollAnimation =
|
|
19526
|
+
const startScrollAnimation = useCallback12(
|
|
18846
19527
|
(velocity) => {
|
|
18847
19528
|
cancelScrollAnimation();
|
|
18848
19529
|
const current = offsetRef.current;
|
|
@@ -19109,7 +19790,7 @@ function PanoSceneMenu({
|
|
|
19109
19790
|
setOffset((previous) => clampOffset(previous + event.deltaX));
|
|
19110
19791
|
};
|
|
19111
19792
|
const axisPoint = (event) => horizontal ? event.clientX : event.clientY;
|
|
19112
|
-
const endSuppressClickRef =
|
|
19793
|
+
const endSuppressClickRef = useRef41(false);
|
|
19113
19794
|
const beginListDrag = (event, captureTarget) => {
|
|
19114
19795
|
if (!customDrag || event.button !== 0) return;
|
|
19115
19796
|
cancelScrollAnimation();
|
|
@@ -19319,7 +20000,7 @@ function PanoSceneMenu({
|
|
|
19319
20000
|
}
|
|
19320
20001
|
|
|
19321
20002
|
// src/use-pano-viewer.ts
|
|
19322
|
-
import { useMemo as useMemo28, useRef as
|
|
20003
|
+
import { useMemo as useMemo28, useRef as useRef42 } from "react";
|
|
19323
20004
|
function createPanoViewerHandle(ref) {
|
|
19324
20005
|
return {
|
|
19325
20006
|
getView: () => ref.current?.getView() ?? { yaw: 0, pitch: 0, fov: 75 },
|
|
@@ -19350,6 +20031,36 @@ function createPanoViewerHandle(ref) {
|
|
|
19350
20031
|
isVRAvailable: () => ref.current?.isVRAvailable() ?? false,
|
|
19351
20032
|
isVREnabled: () => ref.current?.isVREnabled() ?? false,
|
|
19352
20033
|
getVRMode: () => ref.current?.getVRMode() ?? null,
|
|
20034
|
+
getVRState: () => ref.current?.getVRState() ?? EMPTY_WEBVR_STATE,
|
|
20035
|
+
subscribeVR: (onStoreChange) => {
|
|
20036
|
+
let disposed = false;
|
|
20037
|
+
let unsubscribe;
|
|
20038
|
+
const timers = [];
|
|
20039
|
+
const attach = () => {
|
|
20040
|
+
if (disposed || unsubscribe) {
|
|
20041
|
+
return;
|
|
20042
|
+
}
|
|
20043
|
+
const handle = ref.current;
|
|
20044
|
+
if (!handle) {
|
|
20045
|
+
return;
|
|
20046
|
+
}
|
|
20047
|
+
unsubscribe = handle.subscribeVR(onStoreChange);
|
|
20048
|
+
onStoreChange();
|
|
20049
|
+
};
|
|
20050
|
+
attach();
|
|
20051
|
+
if (typeof window !== "undefined") {
|
|
20052
|
+
for (const delay of [0, 16, 50, 100, 250]) {
|
|
20053
|
+
timers.push(window.setTimeout(attach, delay));
|
|
20054
|
+
}
|
|
20055
|
+
}
|
|
20056
|
+
return () => {
|
|
20057
|
+
disposed = true;
|
|
20058
|
+
for (const id of timers) {
|
|
20059
|
+
window.clearTimeout(id);
|
|
20060
|
+
}
|
|
20061
|
+
unsubscribe?.();
|
|
20062
|
+
};
|
|
20063
|
+
},
|
|
19353
20064
|
requestVRPermission: () => ref.current?.requestVRPermission() ?? Promise.resolve(false),
|
|
19354
20065
|
getVideo: () => ref.current?.getVideo() ?? null,
|
|
19355
20066
|
subscribeVideo: (onStoreChange) => ref.current?.subscribeVideo(onStoreChange) ?? (() => {
|
|
@@ -19401,7 +20112,7 @@ function createPanoViewerHandle(ref) {
|
|
|
19401
20112
|
};
|
|
19402
20113
|
}
|
|
19403
20114
|
function usePanoViewer() {
|
|
19404
|
-
const ref =
|
|
20115
|
+
const ref = useRef42(null);
|
|
19405
20116
|
const handle = useMemo28(() => createPanoViewerHandle(ref), []);
|
|
19406
20117
|
return useMemo28(() => ({ ref, ...handle }), [handle]);
|
|
19407
20118
|
}
|
|
@@ -19409,25 +20120,25 @@ function usePanoViewer() {
|
|
|
19409
20120
|
// src/video/pano-video.tsx
|
|
19410
20121
|
import { useThree as useThree29 } from "@react-three/fiber";
|
|
19411
20122
|
import {
|
|
19412
|
-
useCallback as
|
|
20123
|
+
useCallback as useCallback13,
|
|
19413
20124
|
useContext as useContext28,
|
|
19414
20125
|
useEffect as useEffect42,
|
|
19415
20126
|
useLayoutEffect as useLayoutEffect10,
|
|
19416
20127
|
useMemo as useMemo29,
|
|
19417
|
-
useRef as
|
|
20128
|
+
useRef as useRef43,
|
|
19418
20129
|
useState as useState26
|
|
19419
20130
|
} from "react";
|
|
19420
20131
|
import {
|
|
19421
20132
|
BackSide as BackSide4,
|
|
19422
|
-
LinearFilter as
|
|
19423
|
-
LinearMipmapLinearFilter as
|
|
19424
|
-
MathUtils as
|
|
20133
|
+
LinearFilter as LinearFilter10,
|
|
20134
|
+
LinearMipmapLinearFilter as LinearMipmapLinearFilter8,
|
|
20135
|
+
MathUtils as MathUtils14,
|
|
19425
20136
|
RepeatWrapping as RepeatWrapping2,
|
|
19426
|
-
SRGBColorSpace as
|
|
20137
|
+
SRGBColorSpace as SRGBColorSpace9,
|
|
19427
20138
|
TextureLoader as TextureLoader8,
|
|
19428
20139
|
VideoTexture as VideoTexture2
|
|
19429
20140
|
} from "three";
|
|
19430
|
-
import { Fragment as
|
|
20141
|
+
import { Fragment as Fragment9, jsx as jsx42, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
19431
20142
|
var EMPTY_TRACKS = [];
|
|
19432
20143
|
var EMPTY_RATES = DEFAULT_PANO_VIDEO_PLAYBACK_RATES;
|
|
19433
20144
|
function createEmptySnapshot() {
|
|
@@ -19503,7 +20214,7 @@ function findTextTrack(video, tracks, trackId) {
|
|
|
19503
20214
|
return list.length > 0 ? list[0] : null;
|
|
19504
20215
|
}
|
|
19505
20216
|
function applyEquirectangularLayout(texture, anisotropy) {
|
|
19506
|
-
texture.colorSpace =
|
|
20217
|
+
texture.colorSpace = SRGBColorSpace9;
|
|
19507
20218
|
texture.wrapS = RepeatWrapping2;
|
|
19508
20219
|
texture.repeat.x = -1;
|
|
19509
20220
|
texture.offset.x = 1;
|
|
@@ -19513,7 +20224,7 @@ function applyEquirectangularLayout(texture, anisotropy) {
|
|
|
19513
20224
|
function usePosterTexture2(poster, onError) {
|
|
19514
20225
|
const gl = useThree29((state) => state.gl);
|
|
19515
20226
|
const [texture, setTexture] = useState26(null);
|
|
19516
|
-
const onErrorRef =
|
|
20227
|
+
const onErrorRef = useRef43(onError);
|
|
19517
20228
|
onErrorRef.current = onError;
|
|
19518
20229
|
useEffect42(() => {
|
|
19519
20230
|
let active = true;
|
|
@@ -19536,8 +20247,8 @@ function usePosterTexture2(poster, onError) {
|
|
|
19536
20247
|
gl.capabilities.getMaxAnisotropy()
|
|
19537
20248
|
);
|
|
19538
20249
|
loadedTexture.wrapT = RepeatWrapping2;
|
|
19539
|
-
loadedTexture.magFilter =
|
|
19540
|
-
loadedTexture.minFilter =
|
|
20250
|
+
loadedTexture.magFilter = LinearFilter10;
|
|
20251
|
+
loadedTexture.minFilter = LinearMipmapLinearFilter8;
|
|
19541
20252
|
loadedTexture.generateMipmaps = true;
|
|
19542
20253
|
setTexture(loadedTexture);
|
|
19543
20254
|
},
|
|
@@ -19631,17 +20342,17 @@ function PanoVideo({
|
|
|
19631
20342
|
() => captionsEnabled ? defaultPanoVideoTrackId(tracks) : null
|
|
19632
20343
|
);
|
|
19633
20344
|
const [ready, setReady] = useState26(false);
|
|
19634
|
-
const autoPlayRef =
|
|
20345
|
+
const autoPlayRef = useRef43(autoPlay);
|
|
19635
20346
|
autoPlayRef.current = autoPlay;
|
|
19636
|
-
const blockedRef =
|
|
19637
|
-
const captionAppearanceOverrideRef =
|
|
20347
|
+
const blockedRef = useRef43(false);
|
|
20348
|
+
const captionAppearanceOverrideRef = useRef43(
|
|
19638
20349
|
{}
|
|
19639
20350
|
);
|
|
19640
|
-
const mediaCapabilitiesRef =
|
|
20351
|
+
const mediaCapabilitiesRef = useRef43({
|
|
19641
20352
|
volumeAdjustable: true,
|
|
19642
20353
|
playbackRates: [...DEFAULT_PANO_VIDEO_PLAYBACK_RATES]
|
|
19643
20354
|
});
|
|
19644
|
-
const storeRef =
|
|
20355
|
+
const storeRef = useRef43(null);
|
|
19645
20356
|
if (!storeRef.current) {
|
|
19646
20357
|
storeRef.current = {
|
|
19647
20358
|
snapshot: {
|
|
@@ -19651,7 +20362,7 @@ function PanoVideo({
|
|
|
19651
20362
|
listeners: /* @__PURE__ */ new Set()
|
|
19652
20363
|
};
|
|
19653
20364
|
}
|
|
19654
|
-
const actionsRef =
|
|
20365
|
+
const actionsRef = useRef43({
|
|
19655
20366
|
play: async () => {
|
|
19656
20367
|
},
|
|
19657
20368
|
pause: () => {
|
|
@@ -19671,12 +20382,12 @@ function PanoVideo({
|
|
|
19671
20382
|
setCaptionAppearance: (_appearance) => {
|
|
19672
20383
|
}
|
|
19673
20384
|
});
|
|
19674
|
-
const onLoadRef =
|
|
19675
|
-
const onErrorRef =
|
|
19676
|
-
const onPlaybackStateChangeRef =
|
|
19677
|
-
const onEndedRef =
|
|
19678
|
-
const onVariantChangeRef =
|
|
19679
|
-
const onTrackChangeRef =
|
|
20385
|
+
const onLoadRef = useRef43(onLoad);
|
|
20386
|
+
const onErrorRef = useRef43(onError);
|
|
20387
|
+
const onPlaybackStateChangeRef = useRef43(onPlaybackStateChange);
|
|
20388
|
+
const onEndedRef = useRef43(onEnded);
|
|
20389
|
+
const onVariantChangeRef = useRef43(onVariantChange);
|
|
20390
|
+
const onTrackChangeRef = useRef43(onTrackChange);
|
|
19680
20391
|
onLoadRef.current = onLoad;
|
|
19681
20392
|
onErrorRef.current = onError;
|
|
19682
20393
|
onPlaybackStateChangeRef.current = onPlaybackStateChange;
|
|
@@ -19693,8 +20404,8 @@ function PanoVideo({
|
|
|
19693
20404
|
video.preload = "metadata";
|
|
19694
20405
|
const texture = new VideoTexture2(video);
|
|
19695
20406
|
applyEquirectangularLayout(texture, 1);
|
|
19696
|
-
texture.magFilter =
|
|
19697
|
-
texture.minFilter =
|
|
20407
|
+
texture.magFilter = LinearFilter10;
|
|
20408
|
+
texture.minFilter = LinearFilter10;
|
|
19698
20409
|
texture.generateMipmaps = false;
|
|
19699
20410
|
return { video, texture };
|
|
19700
20411
|
}, []);
|
|
@@ -19735,7 +20446,7 @@ function PanoVideo({
|
|
|
19735
20446
|
activeVariant?.poster ?? poster,
|
|
19736
20447
|
onError
|
|
19737
20448
|
);
|
|
19738
|
-
const emitSnapshot =
|
|
20449
|
+
const emitSnapshot = useCallback13(
|
|
19739
20450
|
(patch) => {
|
|
19740
20451
|
const store = storeRef.current;
|
|
19741
20452
|
const video = resource?.video;
|
|
@@ -20126,11 +20837,11 @@ function PanoVideo({
|
|
|
20126
20837
|
if (variants.length === 0) {
|
|
20127
20838
|
return null;
|
|
20128
20839
|
}
|
|
20129
|
-
return /* @__PURE__ */ jsxs23(
|
|
20840
|
+
return /* @__PURE__ */ jsxs23(Fragment9, { children: [
|
|
20130
20841
|
activeTexture ? /* @__PURE__ */ jsxs23(
|
|
20131
20842
|
"mesh",
|
|
20132
20843
|
{
|
|
20133
|
-
rotation: [0,
|
|
20844
|
+
rotation: [0, MathUtils14.degToRad(90 + yawOffset2), 0],
|
|
20134
20845
|
visible,
|
|
20135
20846
|
children: [
|
|
20136
20847
|
/* @__PURE__ */ jsx42("sphereGeometry", { args: [DEFAULT_PANORAMA_RADIUS, 128, 64] }),
|
|
@@ -20151,12 +20862,12 @@ function PanoVideo({
|
|
|
20151
20862
|
|
|
20152
20863
|
// src/map/pano-map.tsx
|
|
20153
20864
|
import {
|
|
20154
|
-
useCallback as
|
|
20865
|
+
useCallback as useCallback14,
|
|
20155
20866
|
useEffect as useEffect44,
|
|
20156
20867
|
useId as useId4,
|
|
20157
20868
|
useLayoutEffect as useLayoutEffect11,
|
|
20158
20869
|
useMemo as useMemo30,
|
|
20159
|
-
useRef as
|
|
20870
|
+
useRef as useRef45,
|
|
20160
20871
|
useState as useState28
|
|
20161
20872
|
} from "react";
|
|
20162
20873
|
|
|
@@ -20218,12 +20929,12 @@ function normalizeDegrees(value) {
|
|
|
20218
20929
|
}
|
|
20219
20930
|
|
|
20220
20931
|
// src/map/use-map-view.ts
|
|
20221
|
-
import { useContext as useContext29, useEffect as useEffect43, useRef as
|
|
20932
|
+
import { useContext as useContext29, useEffect as useEffect43, useRef as useRef44, useState as useState27 } from "react";
|
|
20222
20933
|
var DEFAULT_VIEW2 = { yaw: 0, pitch: 0, fov: 75 };
|
|
20223
20934
|
function useMapView(controlled) {
|
|
20224
20935
|
const eventBus = useContext29(PanoEventBusContext);
|
|
20225
20936
|
const [view, setView] = useState27(controlled ?? DEFAULT_VIEW2);
|
|
20226
|
-
const controlledRef =
|
|
20937
|
+
const controlledRef = useRef44(controlled);
|
|
20227
20938
|
controlledRef.current = controlled;
|
|
20228
20939
|
useEffect43(() => {
|
|
20229
20940
|
if (controlled !== void 0) {
|
|
@@ -20240,7 +20951,7 @@ function useMapView(controlled) {
|
|
|
20240
20951
|
}
|
|
20241
20952
|
|
|
20242
20953
|
// src/map/pano-map.tsx
|
|
20243
|
-
import { Fragment as
|
|
20954
|
+
import { Fragment as Fragment10, jsx as jsx43, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
20244
20955
|
var DEFAULT_ICON_SIZE2 = 28;
|
|
20245
20956
|
var DEFAULT_SECTOR_COLOR = "#ffffff";
|
|
20246
20957
|
var DEFAULT_SECTOR_OPACITY = 0.55;
|
|
@@ -20377,20 +21088,20 @@ function PanoMap({
|
|
|
20377
21088
|
}) {
|
|
20378
21089
|
const reactId = useId4().replace(/:/g, "");
|
|
20379
21090
|
const view = useMapView(controlledView);
|
|
20380
|
-
const rootRef =
|
|
20381
|
-
const containerRef =
|
|
20382
|
-
const sectorNodeRef =
|
|
20383
|
-
const yawRef =
|
|
21091
|
+
const rootRef = useRef45(null);
|
|
21092
|
+
const containerRef = useRef45(null);
|
|
21093
|
+
const sectorNodeRef = useRef45(null);
|
|
21094
|
+
const yawRef = useRef45(view.yaw);
|
|
20384
21095
|
const [size, setSize] = useState28({ width: 0, height: 0 });
|
|
20385
21096
|
const [imageSize2, setImageSize] = useState28({ width: 0, height: 0 });
|
|
20386
21097
|
const [scale, setScale] = useState28(1);
|
|
20387
21098
|
const [pan, setPan] = useState28({ x: 0, y: 0 });
|
|
20388
21099
|
const [uncontrolledCollapsed, setUncontrolledCollapsed] = useState28(false);
|
|
20389
|
-
const dragRef =
|
|
20390
|
-
const panAnimRef =
|
|
20391
|
-
const panRef =
|
|
20392
|
-
const scaleRef =
|
|
20393
|
-
const initialViewKeyRef =
|
|
21100
|
+
const dragRef = useRef45(null);
|
|
21101
|
+
const panAnimRef = useRef45(null);
|
|
21102
|
+
const panRef = useRef45(pan);
|
|
21103
|
+
const scaleRef = useRef45(scale);
|
|
21104
|
+
const initialViewKeyRef = useRef45(null);
|
|
20394
21105
|
const spots = map.spots;
|
|
20395
21106
|
const iconSize = map.iconSize ?? DEFAULT_ICON_SIZE2;
|
|
20396
21107
|
const interaction = map.interaction ?? "fixed";
|
|
@@ -20450,7 +21161,7 @@ function PanoMap({
|
|
|
20450
21161
|
};
|
|
20451
21162
|
panRef.current = pan;
|
|
20452
21163
|
scaleRef.current = scale;
|
|
20453
|
-
const panBoundsFor =
|
|
21164
|
+
const panBoundsFor = useCallback14(
|
|
20454
21165
|
(nextScale) => {
|
|
20455
21166
|
const width = fit.width * nextScale;
|
|
20456
21167
|
const height = fit.height * nextScale;
|
|
@@ -20466,7 +21177,7 @@ function PanoMap({
|
|
|
20466
21177
|
},
|
|
20467
21178
|
[fit, size]
|
|
20468
21179
|
);
|
|
20469
|
-
const clampPan =
|
|
21180
|
+
const clampPan = useCallback14(
|
|
20470
21181
|
(nextScale, nextPan) => {
|
|
20471
21182
|
const bounds = panBoundsFor(nextScale);
|
|
20472
21183
|
return {
|
|
@@ -20476,14 +21187,14 @@ function PanoMap({
|
|
|
20476
21187
|
},
|
|
20477
21188
|
[panBoundsFor]
|
|
20478
21189
|
);
|
|
20479
|
-
const cancelPanAnimation =
|
|
21190
|
+
const cancelPanAnimation = useCallback14(() => {
|
|
20480
21191
|
const anim = panAnimRef.current;
|
|
20481
21192
|
if (anim?.raf != null) {
|
|
20482
21193
|
cancelAnimationFrame(anim.raf);
|
|
20483
21194
|
}
|
|
20484
21195
|
panAnimRef.current = null;
|
|
20485
21196
|
}, []);
|
|
20486
|
-
const startPanAnimation =
|
|
21197
|
+
const startPanAnimation = useCallback14(
|
|
20487
21198
|
(velocity) => {
|
|
20488
21199
|
cancelPanAnimation();
|
|
20489
21200
|
const current = panRef.current;
|
|
@@ -20589,7 +21300,7 @@ function PanoMap({
|
|
|
20589
21300
|
size.height,
|
|
20590
21301
|
size.width
|
|
20591
21302
|
]);
|
|
20592
|
-
const applyZoom =
|
|
21303
|
+
const applyZoom = useCallback14(
|
|
20593
21304
|
(nextScale, origin) => {
|
|
20594
21305
|
if (!gestureZoom) return;
|
|
20595
21306
|
cancelPanAnimation();
|
|
@@ -20801,7 +21512,7 @@ function PanoMap({
|
|
|
20801
21512
|
children: collapsed ? "\u25A3" : "\u25A2"
|
|
20802
21513
|
}
|
|
20803
21514
|
) : null,
|
|
20804
|
-
zoomControls && !collapsed ? /* @__PURE__ */ jsxs24(
|
|
21515
|
+
zoomControls && !collapsed ? /* @__PURE__ */ jsxs24(Fragment10, { children: [
|
|
20805
21516
|
/* @__PURE__ */ jsx43(
|
|
20806
21517
|
"button",
|
|
20807
21518
|
{
|
|
@@ -21043,10 +21754,10 @@ import {
|
|
|
21043
21754
|
useEffect as useEffect45,
|
|
21044
21755
|
useId as useId5,
|
|
21045
21756
|
useMemo as useMemo31,
|
|
21046
|
-
useRef as
|
|
21757
|
+
useRef as useRef46,
|
|
21047
21758
|
useState as useState29
|
|
21048
21759
|
} from "react";
|
|
21049
|
-
import { Fragment as
|
|
21760
|
+
import { Fragment as Fragment11, jsx as jsx44, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
21050
21761
|
var DEFAULT_DIALOG_WIDTH = 720;
|
|
21051
21762
|
var DEFAULT_DIALOG_HEIGHT = 520;
|
|
21052
21763
|
function dockedBox(corner, offsetX, offsetY, width, height) {
|
|
@@ -21066,8 +21777,8 @@ function PanoMapDialogShell({
|
|
|
21066
21777
|
usePanoModal(open);
|
|
21067
21778
|
const { size } = usePanoOverlay();
|
|
21068
21779
|
const titleId = useId5();
|
|
21069
|
-
const panelRef =
|
|
21070
|
-
const previouslyFocused =
|
|
21780
|
+
const panelRef = useRef46(null);
|
|
21781
|
+
const previouslyFocused = useRef46(null);
|
|
21071
21782
|
useEffect45(() => {
|
|
21072
21783
|
if (!open) return;
|
|
21073
21784
|
const active = panelRef.current?.ownerDocument.activeElement;
|
|
@@ -21096,7 +21807,7 @@ function PanoMapDialogShell({
|
|
|
21096
21807
|
const height = Math.min(preferredHeight, Math.max(0, size.height - 32));
|
|
21097
21808
|
const left = Math.max(0, (size.width - width) / 2);
|
|
21098
21809
|
const top = Math.max(0, (size.height - height) / 2);
|
|
21099
|
-
return /* @__PURE__ */ jsxs25(
|
|
21810
|
+
return /* @__PURE__ */ jsxs25(Fragment11, { children: [
|
|
21100
21811
|
/* @__PURE__ */ jsx44(
|
|
21101
21812
|
"div",
|
|
21102
21813
|
{
|
|
@@ -21330,6 +22041,7 @@ export {
|
|
|
21330
22041
|
DEFAULT_PANO_VIDEO_PLAYBACK_RATES,
|
|
21331
22042
|
DEFAULT_WEBVR_CHROME_APPEARANCE,
|
|
21332
22043
|
DEFAULT_WEBVR_CURSOR_DWELL_MS,
|
|
22044
|
+
EMPTY_WEBVR_STATE,
|
|
21333
22045
|
GraphicHotspot,
|
|
21334
22046
|
Gyro,
|
|
21335
22047
|
IframeHotspot,
|
|
@@ -21344,6 +22056,7 @@ export {
|
|
|
21344
22056
|
PanoFilter,
|
|
21345
22057
|
PanoMap,
|
|
21346
22058
|
PanoMapOverlay,
|
|
22059
|
+
PanoOverlay,
|
|
21347
22060
|
PanoOverlayPortalProvider,
|
|
21348
22061
|
PanoSceneMenu,
|
|
21349
22062
|
PanoVideo,
|