@ericchen1990/pano-view 3.9.0 → 4.0.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 +207 -95
- package/README.zh-CN.md +170 -75
- package/dist/data.cjs +64 -17
- package/dist/data.cjs.map +1 -1
- package/dist/data.d.mts +24 -12
- package/dist/data.d.ts +24 -12
- package/dist/data.mjs +64 -17
- package/dist/data.mjs.map +1 -1
- package/dist/index.cjs +1998 -1031
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +162 -48
- package/dist/index.d.ts +162 -48
- package/dist/index.mjs +1789 -822
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +87 -74
- 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 +52 -42
- package/docs/dialogs.zh-CN.md +52 -42
- 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
|
);
|
|
@@ -9111,107 +9332,440 @@ function hotspotAction(hotspot, trigger) {
|
|
|
9111
9332
|
return hotspot.events?.[trigger] ?? (trigger === "click" ? hotspot.action : void 0);
|
|
9112
9333
|
}
|
|
9113
9334
|
|
|
9114
|
-
// src/
|
|
9115
|
-
|
|
9116
|
-
|
|
9117
|
-
|
|
9118
|
-
|
|
9119
|
-
|
|
9120
|
-
|
|
9121
|
-
|
|
9122
|
-
|
|
9123
|
-
|
|
9124
|
-
|
|
9125
|
-
|
|
9126
|
-
|
|
9127
|
-
|
|
9128
|
-
|
|
9129
|
-
|
|
9130
|
-
|
|
9131
|
-
}
|
|
9132
|
-
|
|
9133
|
-
|
|
9134
|
-
LinearFilter as LinearFilter4,
|
|
9135
|
-
WebGLRenderTarget
|
|
9136
|
-
} from "three";
|
|
9137
|
-
|
|
9138
|
-
// src/scene-detail.tsx
|
|
9139
|
-
import { createContext as createContext16, useContext as useContext17 } from "react";
|
|
9140
|
-
var SceneDetailContext = createContext16(null);
|
|
9141
|
-
function useSceneDetailReporter() {
|
|
9142
|
-
return useContext17(SceneDetailContext);
|
|
9143
|
-
}
|
|
9144
|
-
function viewTilesAreDrawable(textures) {
|
|
9145
|
-
return textures.length > 0 && textures.every((texture) => texture != null);
|
|
9335
|
+
// src/overlay/align.ts
|
|
9336
|
+
var PANO_OVERLAY_ALIGNS = [
|
|
9337
|
+
"top",
|
|
9338
|
+
"bottom",
|
|
9339
|
+
"left",
|
|
9340
|
+
"right",
|
|
9341
|
+
"top-left",
|
|
9342
|
+
"top-right",
|
|
9343
|
+
"bottom-left",
|
|
9344
|
+
"bottom-right"
|
|
9345
|
+
];
|
|
9346
|
+
var ALIGN_LIST = PANO_OVERLAY_ALIGNS.join(", ");
|
|
9347
|
+
var SAFE = {
|
|
9348
|
+
top: "var(--pano-safe-top)",
|
|
9349
|
+
right: "var(--pano-safe-right)",
|
|
9350
|
+
bottom: "var(--pano-safe-bottom)",
|
|
9351
|
+
left: "var(--pano-safe-left)"
|
|
9352
|
+
};
|
|
9353
|
+
function cssLength(value) {
|
|
9354
|
+
return typeof value === "number" ? `${value}px` : value;
|
|
9146
9355
|
}
|
|
9147
|
-
function
|
|
9148
|
-
|
|
9149
|
-
|
|
9356
|
+
function isOverlayCorner(align) {
|
|
9357
|
+
switch (align) {
|
|
9358
|
+
case "top-left":
|
|
9359
|
+
case "top-right":
|
|
9360
|
+
case "bottom-left":
|
|
9361
|
+
case "bottom-right":
|
|
9362
|
+
return true;
|
|
9363
|
+
case "top":
|
|
9364
|
+
case "bottom":
|
|
9365
|
+
case "left":
|
|
9366
|
+
case "right":
|
|
9367
|
+
return false;
|
|
9368
|
+
default: {
|
|
9369
|
+
const exhaustive = align;
|
|
9370
|
+
return exhaustive;
|
|
9371
|
+
}
|
|
9150
9372
|
}
|
|
9151
|
-
|
|
9152
|
-
|
|
9153
|
-
|
|
9373
|
+
}
|
|
9374
|
+
function resolveOverlayAxis(align, axis) {
|
|
9375
|
+
switch (align) {
|
|
9376
|
+
case "top":
|
|
9377
|
+
case "bottom":
|
|
9378
|
+
return "horizontal";
|
|
9379
|
+
case "left":
|
|
9380
|
+
case "right":
|
|
9381
|
+
return "vertical";
|
|
9382
|
+
case "top-left":
|
|
9383
|
+
case "top-right":
|
|
9384
|
+
case "bottom-left":
|
|
9385
|
+
case "bottom-right":
|
|
9386
|
+
return axis ?? "horizontal";
|
|
9387
|
+
default: {
|
|
9388
|
+
const exhaustive = align;
|
|
9389
|
+
return exhaustive;
|
|
9390
|
+
}
|
|
9154
9391
|
}
|
|
9155
|
-
lastToken.current = token;
|
|
9156
|
-
reporter.report(ready);
|
|
9157
9392
|
}
|
|
9158
|
-
|
|
9159
|
-
|
|
9160
|
-
|
|
9161
|
-
|
|
9162
|
-
|
|
9163
|
-
|
|
9164
|
-
|
|
9165
|
-
|
|
9166
|
-
|
|
9167
|
-
|
|
9168
|
-
|
|
9169
|
-
|
|
9170
|
-
|
|
9171
|
-
|
|
9172
|
-
|
|
9173
|
-
|
|
9174
|
-
|
|
9175
|
-
|
|
9176
|
-
|
|
9177
|
-
|
|
9178
|
-
|
|
9179
|
-
|
|
9180
|
-
|
|
9181
|
-
shatter: { duration: 1.2, krpanoBlend: "pano-view cinematic" },
|
|
9182
|
-
particles: { duration: 1.4, krpanoBlend: "pano-view cinematic" },
|
|
9183
|
-
glitch: { duration: 0.8, krpanoBlend: "pano-view cinematic" },
|
|
9184
|
-
swirl: { duration: 1.2, krpanoBlend: "pano-view cinematic" },
|
|
9185
|
-
clockWipe: { duration: 1, krpanoBlend: "pano-view cinematic" },
|
|
9186
|
-
ripple: { duration: 1.2, krpanoBlend: "pano-view cinematic" },
|
|
9187
|
-
zoomBlur: { duration: 1, krpanoBlend: "pano-view cinematic" },
|
|
9188
|
-
hexDissolve: { duration: 1.1, krpanoBlend: "pano-view cinematic" },
|
|
9189
|
-
filmBurn: { duration: 1.3, krpanoBlend: "pano-view cinematic" }
|
|
9190
|
-
};
|
|
9191
|
-
function resolveTransition(transition) {
|
|
9192
|
-
const preset = typeof transition === "string" ? transition : transition?.preset ?? "crossfade";
|
|
9193
|
-
return {
|
|
9194
|
-
preset,
|
|
9195
|
-
duration: Math.max(
|
|
9196
|
-
0,
|
|
9197
|
-
transition && typeof transition === "object" && Number.isFinite(transition.duration) ? transition.duration : TRANSITION_DEFAULTS[preset].duration
|
|
9198
|
-
)
|
|
9199
|
-
};
|
|
9393
|
+
function overlayCollapseEdge(align, axis) {
|
|
9394
|
+
switch (align) {
|
|
9395
|
+
case "top":
|
|
9396
|
+
return "top";
|
|
9397
|
+
case "bottom":
|
|
9398
|
+
return "bottom";
|
|
9399
|
+
case "left":
|
|
9400
|
+
return "left";
|
|
9401
|
+
case "right":
|
|
9402
|
+
return "right";
|
|
9403
|
+
case "top-left":
|
|
9404
|
+
return resolveOverlayAxis(align, axis) === "horizontal" ? "top" : "left";
|
|
9405
|
+
case "top-right":
|
|
9406
|
+
return resolveOverlayAxis(align, axis) === "horizontal" ? "top" : "right";
|
|
9407
|
+
case "bottom-left":
|
|
9408
|
+
return resolveOverlayAxis(align, axis) === "horizontal" ? "bottom" : "left";
|
|
9409
|
+
case "bottom-right":
|
|
9410
|
+
return resolveOverlayAxis(align, axis) === "horizontal" ? "bottom" : "right";
|
|
9411
|
+
default: {
|
|
9412
|
+
const exhaustive = align;
|
|
9413
|
+
return exhaustive;
|
|
9414
|
+
}
|
|
9415
|
+
}
|
|
9200
9416
|
}
|
|
9201
|
-
function
|
|
9202
|
-
|
|
9417
|
+
function overlayChevron(edge, collapsed) {
|
|
9418
|
+
switch (edge) {
|
|
9419
|
+
case "top":
|
|
9420
|
+
return collapsed ? "down" : "up";
|
|
9421
|
+
case "bottom":
|
|
9422
|
+
return collapsed ? "up" : "down";
|
|
9423
|
+
case "left":
|
|
9424
|
+
return collapsed ? "right" : "left";
|
|
9425
|
+
case "right":
|
|
9426
|
+
return collapsed ? "left" : "right";
|
|
9427
|
+
default: {
|
|
9428
|
+
const exhaustive = edge;
|
|
9429
|
+
return exhaustive;
|
|
9430
|
+
}
|
|
9431
|
+
}
|
|
9203
9432
|
}
|
|
9204
|
-
|
|
9205
|
-
|
|
9206
|
-
|
|
9207
|
-
|
|
9208
|
-
|
|
9209
|
-
|
|
9210
|
-
|
|
9211
|
-
|
|
9212
|
-
|
|
9213
|
-
|
|
9214
|
-
|
|
9433
|
+
function overlayContentAlign(align, axis) {
|
|
9434
|
+
const resolved = resolveOverlayAxis(align, axis);
|
|
9435
|
+
if (resolved === "horizontal") {
|
|
9436
|
+
switch (align) {
|
|
9437
|
+
case "top-left":
|
|
9438
|
+
case "bottom-left":
|
|
9439
|
+
return "start";
|
|
9440
|
+
case "top-right":
|
|
9441
|
+
case "bottom-right":
|
|
9442
|
+
return "end";
|
|
9443
|
+
case "top":
|
|
9444
|
+
case "bottom":
|
|
9445
|
+
case "left":
|
|
9446
|
+
case "right":
|
|
9447
|
+
return "center";
|
|
9448
|
+
default: {
|
|
9449
|
+
const exhaustive = align;
|
|
9450
|
+
return exhaustive;
|
|
9451
|
+
}
|
|
9452
|
+
}
|
|
9453
|
+
}
|
|
9454
|
+
switch (align) {
|
|
9455
|
+
case "top-left":
|
|
9456
|
+
case "top-right":
|
|
9457
|
+
return "start";
|
|
9458
|
+
case "bottom-left":
|
|
9459
|
+
case "bottom-right":
|
|
9460
|
+
return "end";
|
|
9461
|
+
case "top":
|
|
9462
|
+
case "bottom":
|
|
9463
|
+
case "left":
|
|
9464
|
+
case "right":
|
|
9465
|
+
return "center";
|
|
9466
|
+
default: {
|
|
9467
|
+
const exhaustive = align;
|
|
9468
|
+
return exhaustive;
|
|
9469
|
+
}
|
|
9470
|
+
}
|
|
9471
|
+
}
|
|
9472
|
+
function resolveOverlayInset(inset, fallback) {
|
|
9473
|
+
const fallbackLength = cssLength(fallback);
|
|
9474
|
+
if (inset === void 0) {
|
|
9475
|
+
return {
|
|
9476
|
+
top: fallbackLength,
|
|
9477
|
+
right: fallbackLength,
|
|
9478
|
+
bottom: fallbackLength,
|
|
9479
|
+
left: fallbackLength
|
|
9480
|
+
};
|
|
9481
|
+
}
|
|
9482
|
+
if (typeof inset === "number" || typeof inset === "string") {
|
|
9483
|
+
const value = cssLength(inset);
|
|
9484
|
+
return { top: value, right: value, bottom: value, left: value };
|
|
9485
|
+
}
|
|
9486
|
+
return {
|
|
9487
|
+
top: cssLength(inset.top ?? fallback),
|
|
9488
|
+
right: cssLength(inset.right ?? fallback),
|
|
9489
|
+
bottom: cssLength(inset.bottom ?? fallback),
|
|
9490
|
+
left: cssLength(inset.left ?? fallback)
|
|
9491
|
+
};
|
|
9492
|
+
}
|
|
9493
|
+
function overlayDockInset(edge, inset) {
|
|
9494
|
+
switch (edge) {
|
|
9495
|
+
case "top":
|
|
9496
|
+
return inset.top;
|
|
9497
|
+
case "bottom":
|
|
9498
|
+
return inset.bottom;
|
|
9499
|
+
case "left":
|
|
9500
|
+
return inset.left;
|
|
9501
|
+
case "right":
|
|
9502
|
+
return inset.right;
|
|
9503
|
+
default: {
|
|
9504
|
+
const exhaustive = edge;
|
|
9505
|
+
return exhaustive;
|
|
9506
|
+
}
|
|
9507
|
+
}
|
|
9508
|
+
}
|
|
9509
|
+
function resolveOverlayAnchor(anchor, defaults) {
|
|
9510
|
+
const align = anchor?.align ?? defaults.align;
|
|
9511
|
+
const axis = resolveOverlayAxis(align, anchor?.axis);
|
|
9512
|
+
const inset = resolveOverlayInset(anchor?.inset, defaults.inset);
|
|
9513
|
+
const collapseEdge = overlayCollapseEdge(align, anchor?.axis);
|
|
9514
|
+
return {
|
|
9515
|
+
align,
|
|
9516
|
+
axis,
|
|
9517
|
+
inset,
|
|
9518
|
+
collapseEdge,
|
|
9519
|
+
contentAlign: overlayContentAlign(align, anchor?.axis),
|
|
9520
|
+
dockInset: overlayDockInset(collapseEdge, inset)
|
|
9521
|
+
};
|
|
9522
|
+
}
|
|
9523
|
+
function withSafe(inset, safeVariable) {
|
|
9524
|
+
return `calc(${inset} + ${safeVariable})`;
|
|
9525
|
+
}
|
|
9526
|
+
function maxBox(inset) {
|
|
9527
|
+
return {
|
|
9528
|
+
maxWidth: `calc(100% - ${inset.left} - ${inset.right} - ${SAFE.left} - ${SAFE.right})`,
|
|
9529
|
+
maxHeight: `calc(100% - ${inset.top} - ${inset.bottom} - ${SAFE.top} - ${SAFE.bottom})`
|
|
9530
|
+
};
|
|
9531
|
+
}
|
|
9532
|
+
function horizontalSpan(inset, width) {
|
|
9533
|
+
const left = withSafe(inset.left, SAFE.left);
|
|
9534
|
+
const right = withSafe(inset.right, SAFE.right);
|
|
9535
|
+
if (width === void 0) {
|
|
9536
|
+
return { left, right, width: void 0, marginInline: void 0 };
|
|
9537
|
+
}
|
|
9538
|
+
return { left, right, width, marginInline: "auto" };
|
|
9539
|
+
}
|
|
9540
|
+
function verticalSpan(inset, height) {
|
|
9541
|
+
const top = withSafe(inset.top, SAFE.top);
|
|
9542
|
+
const bottom = withSafe(inset.bottom, SAFE.bottom);
|
|
9543
|
+
if (height === void 0) {
|
|
9544
|
+
return { top, bottom, height: void 0, marginBlock: void 0 };
|
|
9545
|
+
}
|
|
9546
|
+
return { top, bottom, height, marginBlock: "auto" };
|
|
9547
|
+
}
|
|
9548
|
+
function overlayBoxStyle(align, inset, width, height) {
|
|
9549
|
+
const widthValue = width === void 0 ? void 0 : cssLength(width);
|
|
9550
|
+
const heightValue = height === void 0 ? void 0 : cssLength(height);
|
|
9551
|
+
const limits = maxBox(inset);
|
|
9552
|
+
switch (align) {
|
|
9553
|
+
case "top":
|
|
9554
|
+
return {
|
|
9555
|
+
...horizontalSpan(inset, widthValue),
|
|
9556
|
+
top: withSafe(inset.top, SAFE.top),
|
|
9557
|
+
bottom: "auto",
|
|
9558
|
+
height: heightValue,
|
|
9559
|
+
...limits
|
|
9560
|
+
};
|
|
9561
|
+
case "bottom":
|
|
9562
|
+
return {
|
|
9563
|
+
...horizontalSpan(inset, widthValue),
|
|
9564
|
+
top: "auto",
|
|
9565
|
+
bottom: withSafe(inset.bottom, SAFE.bottom),
|
|
9566
|
+
height: heightValue,
|
|
9567
|
+
...limits
|
|
9568
|
+
};
|
|
9569
|
+
case "left":
|
|
9570
|
+
return {
|
|
9571
|
+
...verticalSpan(inset, heightValue),
|
|
9572
|
+
left: withSafe(inset.left, SAFE.left),
|
|
9573
|
+
right: "auto",
|
|
9574
|
+
width: widthValue,
|
|
9575
|
+
...limits
|
|
9576
|
+
};
|
|
9577
|
+
case "right":
|
|
9578
|
+
return {
|
|
9579
|
+
...verticalSpan(inset, heightValue),
|
|
9580
|
+
left: "auto",
|
|
9581
|
+
right: withSafe(inset.right, SAFE.right),
|
|
9582
|
+
width: widthValue,
|
|
9583
|
+
...limits
|
|
9584
|
+
};
|
|
9585
|
+
case "top-left":
|
|
9586
|
+
return {
|
|
9587
|
+
top: withSafe(inset.top, SAFE.top),
|
|
9588
|
+
left: withSafe(inset.left, SAFE.left),
|
|
9589
|
+
right: "auto",
|
|
9590
|
+
bottom: "auto",
|
|
9591
|
+
width: widthValue,
|
|
9592
|
+
height: heightValue,
|
|
9593
|
+
...limits
|
|
9594
|
+
};
|
|
9595
|
+
case "top-right":
|
|
9596
|
+
return {
|
|
9597
|
+
top: withSafe(inset.top, SAFE.top),
|
|
9598
|
+
right: withSafe(inset.right, SAFE.right),
|
|
9599
|
+
left: "auto",
|
|
9600
|
+
bottom: "auto",
|
|
9601
|
+
width: widthValue,
|
|
9602
|
+
height: heightValue,
|
|
9603
|
+
...limits
|
|
9604
|
+
};
|
|
9605
|
+
case "bottom-left":
|
|
9606
|
+
return {
|
|
9607
|
+
bottom: withSafe(inset.bottom, SAFE.bottom),
|
|
9608
|
+
left: withSafe(inset.left, SAFE.left),
|
|
9609
|
+
top: "auto",
|
|
9610
|
+
right: "auto",
|
|
9611
|
+
width: widthValue,
|
|
9612
|
+
height: heightValue,
|
|
9613
|
+
...limits
|
|
9614
|
+
};
|
|
9615
|
+
case "bottom-right":
|
|
9616
|
+
return {
|
|
9617
|
+
bottom: withSafe(inset.bottom, SAFE.bottom),
|
|
9618
|
+
right: withSafe(inset.right, SAFE.right),
|
|
9619
|
+
top: "auto",
|
|
9620
|
+
left: "auto",
|
|
9621
|
+
width: widthValue,
|
|
9622
|
+
height: heightValue,
|
|
9623
|
+
...limits
|
|
9624
|
+
};
|
|
9625
|
+
default: {
|
|
9626
|
+
const exhaustive = align;
|
|
9627
|
+
return exhaustive;
|
|
9628
|
+
}
|
|
9629
|
+
}
|
|
9630
|
+
}
|
|
9631
|
+
function isRecord2(value) {
|
|
9632
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
9633
|
+
}
|
|
9634
|
+
function parseInsetLength(value, field) {
|
|
9635
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
9636
|
+
if (typeof value === "string" && value.trim()) return value;
|
|
9637
|
+
throw new Error(`${field}: expected a finite number or a nonempty string`);
|
|
9638
|
+
}
|
|
9639
|
+
function parseInset(value, field) {
|
|
9640
|
+
if (typeof value === "number" || typeof value === "string") {
|
|
9641
|
+
return parseInsetLength(value, field);
|
|
9642
|
+
}
|
|
9643
|
+
if (!isRecord2(value)) throw new Error(`${field}: expected a number, string, or object`);
|
|
9644
|
+
const sides = ["top", "right", "bottom", "left"];
|
|
9645
|
+
const inset = {};
|
|
9646
|
+
for (const side of sides) {
|
|
9647
|
+
if (value[side] === void 0) continue;
|
|
9648
|
+
inset[side] = parseInsetLength(value[side], `${field}.${side}`);
|
|
9649
|
+
}
|
|
9650
|
+
return inset;
|
|
9651
|
+
}
|
|
9652
|
+
function parseOverlayAnchor(value, field) {
|
|
9653
|
+
if (!isRecord2(value)) throw new Error(`${field}: expected an object`);
|
|
9654
|
+
const align = value.align === void 0 ? void 0 : typeof value.align === "string" && PANO_OVERLAY_ALIGNS.includes(value.align) ? value.align : (() => {
|
|
9655
|
+
throw new Error(`${field}.align: expected ${ALIGN_LIST}`);
|
|
9656
|
+
})();
|
|
9657
|
+
const axis = value.axis === void 0 ? void 0 : value.axis === "horizontal" || value.axis === "vertical" ? value.axis : (() => {
|
|
9658
|
+
throw new Error(`${field}.axis: expected "horizontal" or "vertical"`);
|
|
9659
|
+
})();
|
|
9660
|
+
const inset = value.inset === void 0 ? void 0 : parseInset(value.inset, `${field}.inset`);
|
|
9661
|
+
return {
|
|
9662
|
+
...align === void 0 ? {} : { align },
|
|
9663
|
+
...axis === void 0 ? {} : { axis },
|
|
9664
|
+
...inset === void 0 ? {} : { inset }
|
|
9665
|
+
};
|
|
9666
|
+
}
|
|
9667
|
+
|
|
9668
|
+
// src/project-scenes.tsx
|
|
9669
|
+
import {
|
|
9670
|
+
useContext as useContext22,
|
|
9671
|
+
useMemo as useMemo22,
|
|
9672
|
+
useState as useState21
|
|
9673
|
+
} from "react";
|
|
9674
|
+
|
|
9675
|
+
// src/scenes.tsx
|
|
9676
|
+
import { useFrame as useFrame13, useThree as useThree16 } from "@react-three/fiber";
|
|
9677
|
+
import {
|
|
9678
|
+
Fragment as Fragment6,
|
|
9679
|
+
useCallback as useCallback9,
|
|
9680
|
+
useContext as useContext19,
|
|
9681
|
+
useEffect as useEffect23,
|
|
9682
|
+
useMemo as useMemo17,
|
|
9683
|
+
useRef as useRef23,
|
|
9684
|
+
useState as useState12
|
|
9685
|
+
} from "react";
|
|
9686
|
+
import {
|
|
9687
|
+
LinearSRGBColorSpace,
|
|
9688
|
+
LinearFilter as LinearFilter3,
|
|
9689
|
+
WebGLRenderTarget
|
|
9690
|
+
} from "three";
|
|
9691
|
+
|
|
9692
|
+
// src/scene-detail.tsx
|
|
9693
|
+
import { createContext as createContext16, useContext as useContext17 } from "react";
|
|
9694
|
+
var SceneDetailContext = createContext16(null);
|
|
9695
|
+
function useSceneDetailReporter() {
|
|
9696
|
+
return useContext17(SceneDetailContext);
|
|
9697
|
+
}
|
|
9698
|
+
function viewTilesAreDrawable(textures) {
|
|
9699
|
+
return textures.length > 0 && textures.every((texture) => texture != null);
|
|
9700
|
+
}
|
|
9701
|
+
function publishSceneDetail(reporter, lastToken, ready) {
|
|
9702
|
+
if (!reporter) {
|
|
9703
|
+
return;
|
|
9704
|
+
}
|
|
9705
|
+
const token = `${reporter.generation}:${ready ? 1 : 0}`;
|
|
9706
|
+
if (lastToken.current === token) {
|
|
9707
|
+
return;
|
|
9708
|
+
}
|
|
9709
|
+
lastToken.current = token;
|
|
9710
|
+
reporter.report(ready);
|
|
9711
|
+
}
|
|
9712
|
+
|
|
9713
|
+
// src/scene-transitions/presets.ts
|
|
9714
|
+
var TRANSITION_DEFAULTS = {
|
|
9715
|
+
none: { duration: 0, krpanoBlend: "NOBLEND" },
|
|
9716
|
+
crossfade: { duration: 1, krpanoBlend: "BLEND(1.0, easeInCubic)" },
|
|
9717
|
+
zoom: { duration: 2, krpanoBlend: "ZOOMBLEND(2.0, 2.0, easeInOutSine)" },
|
|
9718
|
+
blackout: { duration: 2, krpanoBlend: "COLORBLEND(2.0, 0x000000, easeOutSine)" },
|
|
9719
|
+
whiteFlash: { duration: 1, krpanoBlend: "LIGHTBLEND(1.0, 0xFFFFFF, 2.0, linear)" },
|
|
9720
|
+
slideRightToLeft: { duration: 1, krpanoBlend: "SLIDEBLEND(1.0, 0.0, 0.2, linear)" },
|
|
9721
|
+
slideTopToBottom: { duration: 1, krpanoBlend: "SLIDEBLEND(1.0, 90.0, 0.01, linear)" },
|
|
9722
|
+
slideDiagonal: { duration: 1, krpanoBlend: "SLIDEBLEND(1.0, 135.0, 0.4, linear)" },
|
|
9723
|
+
circleOpen: { duration: 1, krpanoBlend: "OPENBLEND(1.0, 0.0, 0.2, 0.0, linear)" },
|
|
9724
|
+
verticalOpen: { duration: 0.7, krpanoBlend: "OPENBLEND(0.7, 1.0, 0.1, 0.0, linear)" },
|
|
9725
|
+
horizontalOpen: { duration: 1, krpanoBlend: "OPENBLEND(1.0, -1.0, 0.3, 0.0, linear)" },
|
|
9726
|
+
ellipticZoomOpen: { duration: 1, krpanoBlend: "OPENBLEND(1.0, -0.5, 0.3, 0.8, linear)" },
|
|
9727
|
+
pixelate: { duration: 1, krpanoBlend: "pano-view cinematic" },
|
|
9728
|
+
gridWipe: { duration: 1.2, krpanoBlend: "pano-view cinematic" },
|
|
9729
|
+
gridWipeUp: { duration: 1.2, krpanoBlend: "pano-view cinematic" },
|
|
9730
|
+
gridWipeRight: { duration: 1.2, krpanoBlend: "pano-view cinematic" },
|
|
9731
|
+
gridWipeDiagonal: { duration: 1.2, krpanoBlend: "pano-view cinematic" },
|
|
9732
|
+
gridWipeCenter: { duration: 1.2, krpanoBlend: "pano-view cinematic" },
|
|
9733
|
+
gridWipeChecker: { duration: 1.2, krpanoBlend: "pano-view cinematic" },
|
|
9734
|
+
dissolve: { duration: 1, krpanoBlend: "pano-view cinematic" },
|
|
9735
|
+
shatter: { duration: 1.2, krpanoBlend: "pano-view cinematic" },
|
|
9736
|
+
particles: { duration: 1.4, krpanoBlend: "pano-view cinematic" },
|
|
9737
|
+
glitch: { duration: 0.8, krpanoBlend: "pano-view cinematic" },
|
|
9738
|
+
swirl: { duration: 1.2, krpanoBlend: "pano-view cinematic" },
|
|
9739
|
+
clockWipe: { duration: 1, krpanoBlend: "pano-view cinematic" },
|
|
9740
|
+
ripple: { duration: 1.2, krpanoBlend: "pano-view cinematic" },
|
|
9741
|
+
zoomBlur: { duration: 1, krpanoBlend: "pano-view cinematic" },
|
|
9742
|
+
hexDissolve: { duration: 1.1, krpanoBlend: "pano-view cinematic" },
|
|
9743
|
+
filmBurn: { duration: 1.3, krpanoBlend: "pano-view cinematic" }
|
|
9744
|
+
};
|
|
9745
|
+
function resolveTransition(transition) {
|
|
9746
|
+
const preset = typeof transition === "string" ? transition : transition?.preset ?? "crossfade";
|
|
9747
|
+
return {
|
|
9748
|
+
preset,
|
|
9749
|
+
duration: Math.max(
|
|
9750
|
+
0,
|
|
9751
|
+
transition && typeof transition === "object" && Number.isFinite(transition.duration) ? transition.duration : TRANSITION_DEFAULTS[preset].duration
|
|
9752
|
+
)
|
|
9753
|
+
};
|
|
9754
|
+
}
|
|
9755
|
+
function isSnapshotTransition(preset) {
|
|
9756
|
+
return preset !== "none" && preset !== "particles";
|
|
9757
|
+
}
|
|
9758
|
+
|
|
9759
|
+
// src/scene-transitions/snapshot-hold.tsx
|
|
9760
|
+
import { useFrame as useFrame8, useThree as useThree9 } from "@react-three/fiber";
|
|
9761
|
+
import { useEffect as useEffect15, useMemo as useMemo9, useRef as useRef15 } from "react";
|
|
9762
|
+
import { Vector3 as Vector38 } from "three";
|
|
9763
|
+
|
|
9764
|
+
// src/scene-transitions/overlay-utils.ts
|
|
9765
|
+
import { PlaneGeometry } from "three";
|
|
9766
|
+
var OVERLAY_RENDER_ORDER = 1e4;
|
|
9767
|
+
var FULLSCREEN_PLANE = new PlaneGeometry(1, 1);
|
|
9768
|
+
function isPerspectiveCamera(camera) {
|
|
9215
9769
|
return camera.isPerspectiveCamera === true;
|
|
9216
9770
|
}
|
|
9217
9771
|
function placeFullscreenOverlay(mesh, camera, direction) {
|
|
@@ -9540,8 +10094,8 @@ function createSnapshotMaterial(preset, texture) {
|
|
|
9540
10094
|
import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
9541
10095
|
function SnapshotHold({ snapshot }) {
|
|
9542
10096
|
const { camera, gl } = useThree9();
|
|
9543
|
-
const meshRef =
|
|
9544
|
-
const directionRef =
|
|
10097
|
+
const meshRef = useRef15(null);
|
|
10098
|
+
const directionRef = useRef15(new Vector38());
|
|
9545
10099
|
const material = useMemo9(
|
|
9546
10100
|
() => createSnapshotMaterial("crossfade", snapshot.texture),
|
|
9547
10101
|
[snapshot.texture]
|
|
@@ -9624,7 +10178,7 @@ function phaseAfterSnapshot(preset, hold) {
|
|
|
9624
10178
|
|
|
9625
10179
|
// src/scene-transitions/particle-overlay.tsx
|
|
9626
10180
|
import { useFrame as useFrame9, useThree as useThree10 } from "@react-three/fiber";
|
|
9627
|
-
import { useEffect as useEffect16, useMemo as useMemo10, useRef as
|
|
10181
|
+
import { useEffect as useEffect16, useMemo as useMemo10, useRef as useRef16 } from "react";
|
|
9628
10182
|
import {
|
|
9629
10183
|
DoubleSide as DoubleSide2,
|
|
9630
10184
|
InstancedBufferAttribute,
|
|
@@ -9711,10 +10265,10 @@ function ParticleOverlay({
|
|
|
9711
10265
|
onFinish
|
|
9712
10266
|
}) {
|
|
9713
10267
|
const { camera } = useThree10();
|
|
9714
|
-
const meshRef =
|
|
9715
|
-
const startRef =
|
|
9716
|
-
const finishedRef =
|
|
9717
|
-
const directionRef =
|
|
10268
|
+
const meshRef = useRef16(null);
|
|
10269
|
+
const startRef = useRef16(null);
|
|
10270
|
+
const finishedRef = useRef16(false);
|
|
10271
|
+
const directionRef = useRef16(new Vector39());
|
|
9718
10272
|
const geometry = useMemo10(() => createParticleGeometry(), []);
|
|
9719
10273
|
const material = useMemo10(
|
|
9720
10274
|
() => new ShaderMaterial2({
|
|
@@ -9770,7 +10324,7 @@ function ParticleOverlay({
|
|
|
9770
10324
|
|
|
9771
10325
|
// src/scene-transitions/snapshot-overlay.tsx
|
|
9772
10326
|
import { useFrame as useFrame10, useThree as useThree11 } from "@react-three/fiber";
|
|
9773
|
-
import { useEffect as useEffect17, useMemo as useMemo11, useRef as
|
|
10327
|
+
import { useEffect as useEffect17, useMemo as useMemo11, useRef as useRef17 } from "react";
|
|
9774
10328
|
import { Vector3 as Vector310 } from "three";
|
|
9775
10329
|
import { jsx as jsx16, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
9776
10330
|
function SnapshotOverlay({
|
|
@@ -9781,10 +10335,10 @@ function SnapshotOverlay({
|
|
|
9781
10335
|
onFinish
|
|
9782
10336
|
}) {
|
|
9783
10337
|
const { camera, gl } = useThree11();
|
|
9784
|
-
const meshRef =
|
|
9785
|
-
const startRef =
|
|
9786
|
-
const finishedRef =
|
|
9787
|
-
const directionRef =
|
|
10338
|
+
const meshRef = useRef17(null);
|
|
10339
|
+
const startRef = useRef17(null);
|
|
10340
|
+
const finishedRef = useRef17(false);
|
|
10341
|
+
const directionRef = useRef17(new Vector310());
|
|
9788
10342
|
const material = useMemo11(() => {
|
|
9789
10343
|
if (!isSnapshotTransition(transition.preset)) {
|
|
9790
10344
|
return null;
|
|
@@ -9874,7 +10428,7 @@ function TransitionOverlay(props) {
|
|
|
9874
10428
|
|
|
9875
10429
|
// src/sphere.tsx
|
|
9876
10430
|
import { useThree as useThree12 } from "@react-three/fiber";
|
|
9877
|
-
import { useEffect as useEffect18, useMemo as useMemo13, useRef as
|
|
10431
|
+
import { useEffect as useEffect18, useMemo as useMemo13, useRef as useRef19, useState as useState8 } from "react";
|
|
9878
10432
|
import {
|
|
9879
10433
|
BackSide as BackSide2,
|
|
9880
10434
|
LinearFilter,
|
|
@@ -9886,7 +10440,7 @@ import {
|
|
|
9886
10440
|
} from "three";
|
|
9887
10441
|
|
|
9888
10442
|
// src/pano-filter/pano-basic-material.tsx
|
|
9889
|
-
import { useLayoutEffect as useLayoutEffect4, useMemo as useMemo12, useRef as
|
|
10443
|
+
import { useLayoutEffect as useLayoutEffect4, useMemo as useMemo12, useRef as useRef18 } from "react";
|
|
9890
10444
|
import {
|
|
9891
10445
|
Matrix4,
|
|
9892
10446
|
Vector4
|
|
@@ -10086,9 +10640,9 @@ function PanoBasicMaterial({
|
|
|
10086
10640
|
const preset = snapshot.enabled && target === "panorama" ? snapshot.preset : "none";
|
|
10087
10641
|
const matrix = snapshot.enabled && (target === "panorama" || snapshot.colorMatrixScope === "all") ? snapshot.colorMatrix : null;
|
|
10088
10642
|
const hasMatrix = matrix !== null;
|
|
10089
|
-
const currentRef =
|
|
10643
|
+
const currentRef = useRef18({ matrix, intensity: snapshot.intensity });
|
|
10090
10644
|
currentRef.current = { matrix, intensity: snapshot.intensity };
|
|
10091
|
-
const shaderRef =
|
|
10645
|
+
const shaderRef = useRef18(null);
|
|
10092
10646
|
const onBeforeCompile = useMemo12(() => {
|
|
10093
10647
|
const compile = (shader) => {
|
|
10094
10648
|
shaderRef.current = shader;
|
|
@@ -10136,8 +10690,8 @@ function PanoBasicMaterial({
|
|
|
10136
10690
|
import { jsx as jsx19, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
10137
10691
|
function useEquirectTexture(url, anisotropy, generateMipmaps, onLoad, onError) {
|
|
10138
10692
|
const [texture, setTexture] = useState8(null);
|
|
10139
|
-
const onLoadRef =
|
|
10140
|
-
const onErrorRef =
|
|
10693
|
+
const onLoadRef = useRef19(onLoad);
|
|
10694
|
+
const onErrorRef = useRef19(onError);
|
|
10141
10695
|
onLoadRef.current = onLoad;
|
|
10142
10696
|
onErrorRef.current = onError;
|
|
10143
10697
|
useEffect18(() => {
|
|
@@ -10218,7 +10772,7 @@ function Sphere({
|
|
|
10218
10772
|
onPreviewError
|
|
10219
10773
|
);
|
|
10220
10774
|
const displayTexture = texture ?? previewTexture;
|
|
10221
|
-
const readyRef =
|
|
10775
|
+
const readyRef = useRef19(false);
|
|
10222
10776
|
const detailReporter = useSceneDetailReporter();
|
|
10223
10777
|
useEffect18(() => {
|
|
10224
10778
|
readyRef.current = false;
|
|
@@ -10264,13 +10818,14 @@ function Sphere({
|
|
|
10264
10818
|
|
|
10265
10819
|
// src/sphere-tile/sphere-tile.tsx
|
|
10266
10820
|
import { useFrame as useFrame11, useThree as useThree14 } from "@react-three/fiber";
|
|
10267
|
-
import { memo, useCallback as
|
|
10821
|
+
import { memo, useCallback as useCallback8, useEffect as useEffect21, useMemo as useMemo15, useRef as useRef21, useState as useState10 } from "react";
|
|
10268
10822
|
import { BackSide as BackSide3, Frustum, Matrix4 as Matrix42, PerspectiveCamera as PerspectiveCamera4 } from "three";
|
|
10269
10823
|
|
|
10270
10824
|
// src/tile/texture-manager.ts
|
|
10271
10825
|
import {
|
|
10272
10826
|
ClampToEdgeWrapping,
|
|
10273
10827
|
LinearFilter as LinearFilter2,
|
|
10828
|
+
LinearMipmapLinearFilter as LinearMipmapLinearFilter2,
|
|
10274
10829
|
SRGBColorSpace as SRGBColorSpace2,
|
|
10275
10830
|
TextureLoader as TextureLoader2
|
|
10276
10831
|
} from "three";
|
|
@@ -10279,6 +10834,20 @@ var EMPTY_TEXTURE_SNAPSHOT = {
|
|
|
10279
10834
|
texture: null,
|
|
10280
10835
|
error: null
|
|
10281
10836
|
};
|
|
10837
|
+
var MIPMAP_MEMORY_FACTOR = 4 / 3;
|
|
10838
|
+
function mipmappedTextureBytes(width, height) {
|
|
10839
|
+
return Math.ceil(width * height * 4 * MIPMAP_MEMORY_FACTOR);
|
|
10840
|
+
}
|
|
10841
|
+
function configureMipmappedTexture(texture, anisotropy) {
|
|
10842
|
+
texture.colorSpace = SRGBColorSpace2;
|
|
10843
|
+
texture.wrapS = ClampToEdgeWrapping;
|
|
10844
|
+
texture.wrapT = ClampToEdgeWrapping;
|
|
10845
|
+
texture.magFilter = LinearFilter2;
|
|
10846
|
+
texture.minFilter = LinearMipmapLinearFilter2;
|
|
10847
|
+
texture.generateMipmaps = true;
|
|
10848
|
+
texture.anisotropy = Math.max(1, anisotropy);
|
|
10849
|
+
texture.needsUpdate = true;
|
|
10850
|
+
}
|
|
10282
10851
|
var TileTextureManager = class {
|
|
10283
10852
|
constructor(options) {
|
|
10284
10853
|
this.loader = new TextureLoader2();
|
|
@@ -10430,7 +10999,10 @@ var TileTextureManager = class {
|
|
|
10430
10999
|
entry.texture = texture;
|
|
10431
11000
|
entry.status = "loaded";
|
|
10432
11001
|
entry.error = null;
|
|
10433
|
-
entry.bytes =
|
|
11002
|
+
entry.bytes = mipmappedTextureBytes(
|
|
11003
|
+
entry.address.width,
|
|
11004
|
+
entry.address.height
|
|
11005
|
+
);
|
|
10434
11006
|
entry.lastUsed = performance.now();
|
|
10435
11007
|
this.totalBytes += entry.bytes;
|
|
10436
11008
|
this.loaded += 1;
|
|
@@ -10453,14 +11025,7 @@ var TileTextureManager = class {
|
|
|
10453
11025
|
}
|
|
10454
11026
|
}
|
|
10455
11027
|
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;
|
|
11028
|
+
configureMipmappedTexture(texture, this.options.anisotropy);
|
|
10464
11029
|
}
|
|
10465
11030
|
evict() {
|
|
10466
11031
|
if (this.totalBytes <= this.options.maxBytes) {
|
|
@@ -10534,16 +11099,11 @@ function useSharedTileTextureManager() {
|
|
|
10534
11099
|
}
|
|
10535
11100
|
|
|
10536
11101
|
// 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";
|
|
11102
|
+
import { useEffect as useEffect20, useRef as useRef20, useState as useState9 } from "react";
|
|
11103
|
+
import { TextureLoader as TextureLoader3 } from "three";
|
|
10544
11104
|
function usePreviewTexture(url, anisotropy, onError) {
|
|
10545
11105
|
const [texture, setTexture] = useState9(null);
|
|
10546
|
-
const onErrorRef =
|
|
11106
|
+
const onErrorRef = useRef20(onError);
|
|
10547
11107
|
onErrorRef.current = onError;
|
|
10548
11108
|
useEffect20(() => {
|
|
10549
11109
|
if (!url) {
|
|
@@ -10560,14 +11120,7 @@ function usePreviewTexture(url, anisotropy, onError) {
|
|
|
10560
11120
|
loadedTexture.dispose();
|
|
10561
11121
|
return;
|
|
10562
11122
|
}
|
|
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;
|
|
11123
|
+
configureMipmappedTexture(loadedTexture, anisotropy);
|
|
10571
11124
|
setTexture(loadedTexture);
|
|
10572
11125
|
},
|
|
10573
11126
|
void 0,
|
|
@@ -10739,8 +11292,17 @@ function sphereTileGeometry(address, yawOffset2, radius = DEFAULT_PANORAMA_RADIU
|
|
|
10739
11292
|
geometry.computeBoundingSphere();
|
|
10740
11293
|
return geometry;
|
|
10741
11294
|
}
|
|
10742
|
-
function
|
|
10743
|
-
const
|
|
11295
|
+
function tanHalfFov(verticalFov) {
|
|
11296
|
+
const fov = Math.min(179, Math.max(1, verticalFov));
|
|
11297
|
+
return Math.tan(MathUtils6.degToRad(fov) * 0.5);
|
|
11298
|
+
}
|
|
11299
|
+
function preferredSphereLevel(levels, height, dpr, verticalFov, width = height) {
|
|
11300
|
+
const pixelHeight = Math.max(1, height) * dpr;
|
|
11301
|
+
const pixelWidth = Math.max(1, width) * dpr;
|
|
11302
|
+
const tanHalfV = tanHalfFov(verticalFov);
|
|
11303
|
+
const tanHalfH = pixelWidth / pixelHeight * tanHalfV;
|
|
11304
|
+
const edgeScale = 1 + Math.max(tanHalfV, tanHalfH) ** 2;
|
|
11305
|
+
const needed = pixelHeight * 0.5 / tanHalfV * Math.PI * edgeScale;
|
|
10744
11306
|
const index = levels.findIndex((level) => level.height >= needed);
|
|
10745
11307
|
return index < 0 ? levels.length - 1 : index;
|
|
10746
11308
|
}
|
|
@@ -10841,7 +11403,7 @@ function SphereTileSource({
|
|
|
10841
11403
|
anisotropy,
|
|
10842
11404
|
onPreviewError
|
|
10843
11405
|
);
|
|
10844
|
-
const callbacks =
|
|
11406
|
+
const callbacks = useRef21({
|
|
10845
11407
|
onReady,
|
|
10846
11408
|
onLoadProgress,
|
|
10847
11409
|
onTileError,
|
|
@@ -10874,8 +11436,8 @@ function SphereTileSource({
|
|
|
10874
11436
|
);
|
|
10875
11437
|
const manager = sharedManager ?? ownedManager;
|
|
10876
11438
|
const budget = manager.memoryBudgetBytes;
|
|
10877
|
-
const readyRef =
|
|
10878
|
-
const ready =
|
|
11439
|
+
const readyRef = useRef21(false);
|
|
11440
|
+
const ready = useCallback8(() => {
|
|
10879
11441
|
if (!readyRef.current) {
|
|
10880
11442
|
readyRef.current = true;
|
|
10881
11443
|
callbacks.current.onReady?.();
|
|
@@ -10916,10 +11478,10 @@ function SphereTileSource({
|
|
|
10916
11478
|
);
|
|
10917
11479
|
const [layers, setLayers] = useState10([]);
|
|
10918
11480
|
const detailReporter = useSceneDetailReporter();
|
|
10919
|
-
const detailReporterRef =
|
|
11481
|
+
const detailReporterRef = useRef21(detailReporter);
|
|
10920
11482
|
detailReporterRef.current = detailReporter;
|
|
10921
|
-
const detailTokenRef =
|
|
10922
|
-
const targetKeysRef =
|
|
11483
|
+
const detailTokenRef = useRef21("");
|
|
11484
|
+
const targetKeysRef = useRef21([]);
|
|
10923
11485
|
const scratch = useMemo15(
|
|
10924
11486
|
() => ({
|
|
10925
11487
|
camera: new PerspectiveCamera4(),
|
|
@@ -10968,7 +11530,13 @@ function SphereTileSource({
|
|
|
10968
11530
|
scratch.camera.matrixWorldInverse
|
|
10969
11531
|
);
|
|
10970
11532
|
scratch.frustum.setFromProjectionMatrix(scratch.matrix);
|
|
10971
|
-
let level = loadMode === "preview" ? -1 : loadMode === "base" ? 0 : preferredSphereLevel(
|
|
11533
|
+
let level = loadMode === "preview" ? -1 : loadMode === "base" ? 0 : preferredSphereLevel(
|
|
11534
|
+
config.levels,
|
|
11535
|
+
size.height,
|
|
11536
|
+
dpr,
|
|
11537
|
+
camera.fov,
|
|
11538
|
+
size.width
|
|
11539
|
+
);
|
|
10972
11540
|
const next = [];
|
|
10973
11541
|
let residentBytes = 0;
|
|
10974
11542
|
for (let index = 0; index <= level; index++) {
|
|
@@ -10976,7 +11544,7 @@ function SphereTileSource({
|
|
|
10976
11544
|
({ bounds }) => scratch.frustum.intersectsBox(bounds)
|
|
10977
11545
|
).map(({ address }) => address);
|
|
10978
11546
|
const bytes = addresses.reduce(
|
|
10979
|
-
(total, address) => total + address.width
|
|
11547
|
+
(total, address) => total + mipmappedTextureBytes(address.width, address.height),
|
|
10980
11548
|
0
|
|
10981
11549
|
);
|
|
10982
11550
|
if (residentBytes + bytes > budget) {
|
|
@@ -11042,7 +11610,7 @@ function SphereTile({ multires, ...props }) {
|
|
|
11042
11610
|
|
|
11043
11611
|
// src/tile/tile.tsx
|
|
11044
11612
|
import { useFrame as useFrame12, useThree as useThree15 } from "@react-three/fiber";
|
|
11045
|
-
import { memo as memo2, useEffect as useEffect22, useMemo as useMemo16, useRef as
|
|
11613
|
+
import { memo as memo2, useEffect as useEffect22, useMemo as useMemo16, useRef as useRef22, useState as useState11 } from "react";
|
|
11046
11614
|
import {
|
|
11047
11615
|
Frustum as Frustum2,
|
|
11048
11616
|
Matrix4 as Matrix43,
|
|
@@ -11055,6 +11623,7 @@ import {
|
|
|
11055
11623
|
import {
|
|
11056
11624
|
Box3 as Box32,
|
|
11057
11625
|
Euler as Euler4,
|
|
11626
|
+
MathUtils as MathUtils7,
|
|
11058
11627
|
Quaternion as Quaternion2,
|
|
11059
11628
|
Vector3 as Vector312
|
|
11060
11629
|
} from "three";
|
|
@@ -11149,8 +11718,19 @@ function makeTileAddress(face, level, faceSize, tileSize, col, row) {
|
|
|
11149
11718
|
function tileKey(address) {
|
|
11150
11719
|
return `${address.level}/${address.face}/${address.row}/${address.col}`;
|
|
11151
11720
|
}
|
|
11152
|
-
function
|
|
11153
|
-
const
|
|
11721
|
+
function tanHalfFov2(verticalFov) {
|
|
11722
|
+
const fov = Math.min(179, Math.max(1, verticalFov));
|
|
11723
|
+
return Math.tan(MathUtils7.degToRad(fov) * 0.5);
|
|
11724
|
+
}
|
|
11725
|
+
function getPreferredLevel(levels, viewportHeight, pixelRatio, verticalFov, currentLevel, viewportWidth = viewportHeight) {
|
|
11726
|
+
const height = Math.max(1, viewportHeight) * pixelRatio;
|
|
11727
|
+
const width = Math.max(1, viewportWidth) * pixelRatio;
|
|
11728
|
+
const tanHalfV = tanHalfFov2(verticalFov);
|
|
11729
|
+
const requiredFaceSize = Math.max(
|
|
11730
|
+
height / tanHalfV,
|
|
11731
|
+
height * tanHalfV,
|
|
11732
|
+
width * width * tanHalfV / height
|
|
11733
|
+
);
|
|
11154
11734
|
let preferredLevel = levels.length;
|
|
11155
11735
|
for (let index = 0; index < levels.length; index += 1) {
|
|
11156
11736
|
if (levels[index] >= requiredFaceSize) {
|
|
@@ -11481,9 +12061,9 @@ function Tile({
|
|
|
11481
12061
|
onPreviewError
|
|
11482
12062
|
);
|
|
11483
12063
|
const sharedManager = useSharedTileTextureManager();
|
|
11484
|
-
const progressRef =
|
|
11485
|
-
const errorRef =
|
|
11486
|
-
const levelChangeRef =
|
|
12064
|
+
const progressRef = useRef22(onLoadProgress);
|
|
12065
|
+
const errorRef = useRef22(onTileError);
|
|
12066
|
+
const levelChangeRef = useRef22(onLevelChange);
|
|
11487
12067
|
progressRef.current = onLoadProgress;
|
|
11488
12068
|
errorRef.current = onTileError;
|
|
11489
12069
|
levelChangeRef.current = onLevelChange;
|
|
@@ -11518,7 +12098,7 @@ function Tile({
|
|
|
11518
12098
|
queueMicrotask(() => manager.releaseUnused());
|
|
11519
12099
|
};
|
|
11520
12100
|
}, [manager, ownedManager]);
|
|
11521
|
-
const readyRef =
|
|
12101
|
+
const readyRef = useRef22(false);
|
|
11522
12102
|
useEffect22(() => {
|
|
11523
12103
|
readyRef.current = false;
|
|
11524
12104
|
}, [effectivePreviewUrl]);
|
|
@@ -11538,21 +12118,21 @@ function Tile({
|
|
|
11538
12118
|
[baseUrl, resolveTileUrl, template]
|
|
11539
12119
|
);
|
|
11540
12120
|
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 =
|
|
12121
|
+
const layerTokenRef = useRef22("");
|
|
12122
|
+
const currentLevelRef = useRef22(1);
|
|
12123
|
+
const lastUpdateAtRef = useRef22(-Infinity);
|
|
12124
|
+
const visibilityDirtyRef = useRef22(true);
|
|
12125
|
+
const lastVisibilityQuaternionRef = useRef22(camera.quaternion.clone());
|
|
12126
|
+
const lastVisibilityFovRef = useRef22(Number.NaN);
|
|
12127
|
+
const lastViewportRef = useRef22({ width: 0, height: 0, dpr: 0 });
|
|
12128
|
+
const frustumRef = useRef22(new Frustum2());
|
|
12129
|
+
const projectionMatrixRef = useRef22(new Matrix43());
|
|
12130
|
+
const visibilityCameraRef = useRef22(new PerspectiveCamera5());
|
|
12131
|
+
const trackedLoadModeRef = useRef22(loadMode);
|
|
12132
|
+
const targetKeysRef = useRef22([]);
|
|
12133
|
+
const detailTokenRef = useRef22("");
|
|
11554
12134
|
const detailReporter = useSceneDetailReporter();
|
|
11555
|
-
const detailReporterRef =
|
|
12135
|
+
const detailReporterRef = useRef22(detailReporter);
|
|
11556
12136
|
detailReporterRef.current = detailReporter;
|
|
11557
12137
|
useEffect22(() => {
|
|
11558
12138
|
currentLevelRef.current = 1;
|
|
@@ -11610,7 +12190,8 @@ function Tile({
|
|
|
11610
12190
|
size.height,
|
|
11611
12191
|
pixelRatio,
|
|
11612
12192
|
camera.fov,
|
|
11613
|
-
currentLevelRef.current
|
|
12193
|
+
currentLevelRef.current,
|
|
12194
|
+
size.width
|
|
11614
12195
|
);
|
|
11615
12196
|
if (targetLevel !== currentLevelRef.current) {
|
|
11616
12197
|
currentLevelRef.current = targetLevel;
|
|
@@ -11736,8 +12317,8 @@ function SnapshotCapture({
|
|
|
11736
12317
|
onCaptured
|
|
11737
12318
|
}) {
|
|
11738
12319
|
const { camera, gl, scene, size } = useThree16();
|
|
11739
|
-
const capturedRequestRef =
|
|
11740
|
-
const renderTargetRef =
|
|
12320
|
+
const capturedRequestRef = useRef23(0);
|
|
12321
|
+
const renderTargetRef = useRef23(null);
|
|
11741
12322
|
useEffect23(
|
|
11742
12323
|
() => () => {
|
|
11743
12324
|
renderTargetRef.current?.dispose();
|
|
@@ -11761,8 +12342,8 @@ function SnapshotCapture({
|
|
|
11761
12342
|
});
|
|
11762
12343
|
nextTarget.texture.colorSpace = LinearSRGBColorSpace;
|
|
11763
12344
|
nextTarget.texture.generateMipmaps = false;
|
|
11764
|
-
nextTarget.texture.minFilter =
|
|
11765
|
-
nextTarget.texture.magFilter =
|
|
12345
|
+
nextTarget.texture.minFilter = LinearFilter3;
|
|
12346
|
+
nextTarget.texture.magFilter = LinearFilter3;
|
|
11766
12347
|
const previousTarget = gl.getRenderTarget();
|
|
11767
12348
|
gl.setRenderTarget(nextTarget);
|
|
11768
12349
|
gl.clear();
|
|
@@ -11819,20 +12400,20 @@ function ScenesController({
|
|
|
11819
12400
|
const [transitionRunId, setTransitionRunId] = useState12(0);
|
|
11820
12401
|
const [snapshot, setSnapshot] = useState12(null);
|
|
11821
12402
|
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 =
|
|
12403
|
+
const requestedSceneIdRef = useRef23(activeSceneId);
|
|
12404
|
+
const captureReasonRef = useRef23("start");
|
|
12405
|
+
const interactionReleaseRef = useRef23(null);
|
|
12406
|
+
const slotsRef = useRef23(slots);
|
|
12407
|
+
const phaseRef = useRef23(phase);
|
|
12408
|
+
const liveSlotRef = useRef23(liveSlot);
|
|
12409
|
+
const transitionFromRef = useRef23(initialScene);
|
|
12410
|
+
const readySceneRef = useRef23(null);
|
|
12411
|
+
const waitRef = useRef23(null);
|
|
12412
|
+
const waitTimerRef = useRef23(null);
|
|
12413
|
+
const detailGenerationRef = useRef23(0);
|
|
11833
12414
|
const [detailGeneration, setDetailGeneration] = useState12(0);
|
|
11834
|
-
const mountedRef =
|
|
11835
|
-
const waitForDetailMsRef =
|
|
12415
|
+
const mountedRef = useRef23(true);
|
|
12416
|
+
const waitForDetailMsRef = useRef23(0);
|
|
11836
12417
|
waitForDetailMsRef.current = normalizeTransitionWaitMs(transitionWaitForDetailMs);
|
|
11837
12418
|
slotsRef.current = slots;
|
|
11838
12419
|
phaseRef.current = phase;
|
|
@@ -11847,14 +12428,14 @@ function ScenesController({
|
|
|
11847
12428
|
useEffect23(() => () => {
|
|
11848
12429
|
controlsRef?.current?.setSceneViewLimits(void 0);
|
|
11849
12430
|
}, [controlsRef]);
|
|
11850
|
-
const releaseInteraction =
|
|
12431
|
+
const releaseInteraction = useCallback9(() => {
|
|
11851
12432
|
interactionReleaseRef.current?.();
|
|
11852
12433
|
interactionReleaseRef.current = null;
|
|
11853
12434
|
}, []);
|
|
11854
|
-
const reportError =
|
|
12435
|
+
const reportError = useCallback9((sceneId, error) => {
|
|
11855
12436
|
onTransitionError?.({ sceneId, error });
|
|
11856
12437
|
}, [onTransitionError]);
|
|
11857
|
-
const clearDetailWait =
|
|
12438
|
+
const clearDetailWait = useCallback9((bumpGeneration) => {
|
|
11858
12439
|
if (waitTimerRef.current !== null) {
|
|
11859
12440
|
clearTimeout(waitTimerRef.current);
|
|
11860
12441
|
waitTimerRef.current = null;
|
|
@@ -11882,7 +12463,7 @@ function ScenesController({
|
|
|
11882
12463
|
clearDetailWait(false);
|
|
11883
12464
|
};
|
|
11884
12465
|
}, [clearDetailWait]);
|
|
11885
|
-
const startPreload =
|
|
12466
|
+
const startPreload = useCallback9((scene) => {
|
|
11886
12467
|
clearDetailWait(true);
|
|
11887
12468
|
const nextSlot = 1 - liveSlotRef.current;
|
|
11888
12469
|
requestedSceneIdRef.current = scene.id;
|
|
@@ -11920,13 +12501,13 @@ function ScenesController({
|
|
|
11920
12501
|
}
|
|
11921
12502
|
startPreload(requested);
|
|
11922
12503
|
}, [activeSceneId, clearDetailWait, pendingSlot, reportError, sceneMap, startPreload]);
|
|
11923
|
-
const notifySceneReady =
|
|
12504
|
+
const notifySceneReady = useCallback9((scene) => {
|
|
11924
12505
|
if (!scene || readySceneRef.current === scene) return;
|
|
11925
12506
|
readySceneRef.current = scene;
|
|
11926
12507
|
controlsRef?.current?.setSceneViewLimits(sceneMap.get(scene.id)?.viewLimits);
|
|
11927
12508
|
onSceneReady?.(scene.id);
|
|
11928
12509
|
}, [controlsRef, onSceneReady, sceneMap]);
|
|
11929
|
-
const handleReady =
|
|
12510
|
+
const handleReady = useCallback9((slot) => {
|
|
11930
12511
|
if (slot === liveSlotRef.current && pendingSlot === null && phaseRef.current === "idle") {
|
|
11931
12512
|
notifySceneReady(slotsRef.current[slot]);
|
|
11932
12513
|
return;
|
|
@@ -11962,7 +12543,7 @@ function ScenesController({
|
|
|
11962
12543
|
setPhase("capturing");
|
|
11963
12544
|
setCaptureRequestId((current) => current + 1);
|
|
11964
12545
|
}, [controlsRef, notifySceneReady, onTransitionEnd, pendingSlot, transition.preset]);
|
|
11965
|
-
const finishTransition =
|
|
12546
|
+
const finishTransition = useCallback9(() => {
|
|
11966
12547
|
const nextSlot = pendingSlot;
|
|
11967
12548
|
const previousScene = transitionFromRef.current;
|
|
11968
12549
|
const nextScene = nextSlot === null ? null : slotsRef.current[nextSlot];
|
|
@@ -11987,11 +12568,11 @@ function ScenesController({
|
|
|
11987
12568
|
});
|
|
11988
12569
|
}
|
|
11989
12570
|
}, [onTransitionEnd, pendingSlot, releaseInteraction, snapshot, transition.preset]);
|
|
11990
|
-
const finishTransitionRef =
|
|
12571
|
+
const finishTransitionRef = useRef23(finishTransition);
|
|
11991
12572
|
finishTransitionRef.current = finishTransition;
|
|
11992
|
-
const transitionRef =
|
|
12573
|
+
const transitionRef = useRef23(transition);
|
|
11993
12574
|
transitionRef.current = transition;
|
|
11994
|
-
const consumeDetailSignal =
|
|
12575
|
+
const consumeDetailSignal = useCallback9((signal) => {
|
|
11995
12576
|
const decision = acceptDetailWait(waitRef.current, signal);
|
|
11996
12577
|
waitRef.current = decision.wait;
|
|
11997
12578
|
if (!decision.start) {
|
|
@@ -12011,7 +12592,7 @@ function ScenesController({
|
|
|
12011
12592
|
setPhase("transitioning");
|
|
12012
12593
|
setTransitionRunId((current) => current + 1);
|
|
12013
12594
|
}, []);
|
|
12014
|
-
const handleCaptured =
|
|
12595
|
+
const handleCaptured = useCallback9((nextSnapshot) => {
|
|
12015
12596
|
if (captureReasonRef.current === "interrupt") {
|
|
12016
12597
|
setSnapshot((current) => {
|
|
12017
12598
|
current?.dispose();
|
|
@@ -12109,7 +12690,7 @@ function ScenesController({
|
|
|
12109
12690
|
startPreload,
|
|
12110
12691
|
transition.preset
|
|
12111
12692
|
]);
|
|
12112
|
-
const snapshotRef =
|
|
12693
|
+
const snapshotRef = useRef23(snapshot);
|
|
12113
12694
|
snapshotRef.current = snapshot;
|
|
12114
12695
|
useEffect23(() => () => {
|
|
12115
12696
|
releaseInteraction();
|
|
@@ -12162,7 +12743,7 @@ ${slots[1]?.id ?? ""}`;
|
|
|
12162
12743
|
}
|
|
12163
12744
|
}));
|
|
12164
12745
|
}, [consumeDetailSignal, detailGeneration, slotSceneKey]);
|
|
12165
|
-
return /* @__PURE__ */ jsxs13(
|
|
12746
|
+
return /* @__PURE__ */ jsxs13(Fragment6, { children: [
|
|
12166
12747
|
/* @__PURE__ */ jsx23(
|
|
12167
12748
|
SnapshotCapture,
|
|
12168
12749
|
{
|
|
@@ -12225,7 +12806,7 @@ function Scenes({
|
|
|
12225
12806
|
() => controlledId ?? defaultActiveSceneId ?? scenes[0]?.id ?? ""
|
|
12226
12807
|
);
|
|
12227
12808
|
const resolvedId = isControlled ? controlledId : internalId;
|
|
12228
|
-
const requestSceneChange =
|
|
12809
|
+
const requestSceneChange = useCallback9(
|
|
12229
12810
|
(id) => {
|
|
12230
12811
|
if (isControlled) {
|
|
12231
12812
|
onActiveSceneIdChange?.(id);
|
|
@@ -12235,12 +12816,12 @@ function Scenes({
|
|
|
12235
12816
|
},
|
|
12236
12817
|
[isControlled, onActiveSceneIdChange]
|
|
12237
12818
|
);
|
|
12238
|
-
const scenesRef =
|
|
12819
|
+
const scenesRef = useRef23(scenes);
|
|
12239
12820
|
scenesRef.current = scenes;
|
|
12240
|
-
const resolvedIdRef =
|
|
12821
|
+
const resolvedIdRef = useRef23(resolvedId);
|
|
12241
12822
|
resolvedIdRef.current = resolvedId;
|
|
12242
12823
|
const host = useContext19(ScenesHostContext);
|
|
12243
|
-
const phaseRef =
|
|
12824
|
+
const phaseRef = useRef23("idle");
|
|
12244
12825
|
useEffect23(() => {
|
|
12245
12826
|
if (!host) {
|
|
12246
12827
|
return;
|
|
@@ -12311,12 +12892,12 @@ function Scenes({
|
|
|
12311
12892
|
|
|
12312
12893
|
// src/hotspot/image-hotspot.tsx
|
|
12313
12894
|
import { useThree as useThree20 } from "@react-three/fiber";
|
|
12314
|
-
import { useEffect as useEffect26, useRef as
|
|
12895
|
+
import { useEffect as useEffect26, useRef as useRef27, useState as useState15 } from "react";
|
|
12315
12896
|
import {
|
|
12316
|
-
ClampToEdgeWrapping as
|
|
12317
|
-
LinearFilter as
|
|
12318
|
-
LinearMipmapLinearFilter as
|
|
12319
|
-
SRGBColorSpace as
|
|
12897
|
+
ClampToEdgeWrapping as ClampToEdgeWrapping2,
|
|
12898
|
+
LinearFilter as LinearFilter4,
|
|
12899
|
+
LinearMipmapLinearFilter as LinearMipmapLinearFilter3,
|
|
12900
|
+
SRGBColorSpace as SRGBColorSpace3,
|
|
12320
12901
|
TextureLoader as TextureLoader4
|
|
12321
12902
|
} from "three";
|
|
12322
12903
|
|
|
@@ -12327,13 +12908,13 @@ import {
|
|
|
12327
12908
|
useEffect as useEffect25,
|
|
12328
12909
|
useLayoutEffect as useLayoutEffect7,
|
|
12329
12910
|
useMemo as useMemo19,
|
|
12330
|
-
useRef as
|
|
12911
|
+
useRef as useRef26,
|
|
12331
12912
|
useState as useState14
|
|
12332
12913
|
} from "react";
|
|
12333
12914
|
import {
|
|
12334
12915
|
Box3 as Box34,
|
|
12335
12916
|
EdgesGeometry,
|
|
12336
|
-
MathUtils as
|
|
12917
|
+
MathUtils as MathUtils10,
|
|
12337
12918
|
Matrix4 as Matrix44,
|
|
12338
12919
|
PerspectiveCamera as PerspectiveCamera8,
|
|
12339
12920
|
Plane,
|
|
@@ -12441,12 +13022,12 @@ import { useFrame as useFrame14, useThree as useThree17 } from "@react-three/fib
|
|
|
12441
13022
|
import {
|
|
12442
13023
|
useContext as useContext20,
|
|
12443
13024
|
useLayoutEffect as useLayoutEffect5,
|
|
12444
|
-
useRef as
|
|
13025
|
+
useRef as useRef24,
|
|
12445
13026
|
useSyncExternalStore as useSyncExternalStore9
|
|
12446
13027
|
} from "react";
|
|
12447
13028
|
import { createRoot } from "react-dom/client";
|
|
12448
13029
|
import { Vector3 as Vector314 } from "three";
|
|
12449
|
-
import { Fragment as
|
|
13030
|
+
import { Fragment as Fragment7, jsx as jsx24, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
12450
13031
|
function useFallbackStereoView() {
|
|
12451
13032
|
const runtime = useContext20(WebVRRuntimeContext);
|
|
12452
13033
|
const host = runtime?.host ?? null;
|
|
@@ -12466,9 +13047,9 @@ function ProjectedHtml({
|
|
|
12466
13047
|
eye
|
|
12467
13048
|
}) {
|
|
12468
13049
|
const { camera, gl, events, size } = useThree17();
|
|
12469
|
-
const group =
|
|
12470
|
-
const overlay =
|
|
12471
|
-
const scratch =
|
|
13050
|
+
const group = useRef24(null);
|
|
13051
|
+
const overlay = useRef24(null);
|
|
13052
|
+
const scratch = useRef24(new Vector314());
|
|
12472
13053
|
const target = events.connected || gl.domElement.parentElement;
|
|
12473
13054
|
const updatePosition = () => {
|
|
12474
13055
|
const anchor = group.current;
|
|
@@ -12543,7 +13124,7 @@ function PanoHtml(props) {
|
|
|
12543
13124
|
if (mode === "mobilevr" && portrait) {
|
|
12544
13125
|
return null;
|
|
12545
13126
|
}
|
|
12546
|
-
return stereoView ? /* @__PURE__ */ jsxs14(
|
|
13127
|
+
return stereoView ? /* @__PURE__ */ jsxs14(Fragment7, { children: [
|
|
12547
13128
|
/* @__PURE__ */ jsx24(ProjectedHtml, { ...props, stereoView, eye: "left" }),
|
|
12548
13129
|
/* @__PURE__ */ jsx24(ProjectedHtml, { ...props, stereoView, eye: "right" })
|
|
12549
13130
|
] }) : /* @__PURE__ */ jsx24(ProjectedHtml, { ...props });
|
|
@@ -12680,7 +13261,7 @@ function HotspotTooltip({
|
|
|
12680
13261
|
|
|
12681
13262
|
// src/hotspot/transform.ts
|
|
12682
13263
|
import {
|
|
12683
|
-
MathUtils as
|
|
13264
|
+
MathUtils as MathUtils8,
|
|
12684
13265
|
PerspectiveCamera as PerspectiveCamera6,
|
|
12685
13266
|
Vector3 as Vector315
|
|
12686
13267
|
} from "three";
|
|
@@ -12692,7 +13273,7 @@ function applyHotspotTransform(group, camera, orientation2, surfaceQuaternion3,
|
|
|
12692
13273
|
} else {
|
|
12693
13274
|
group.quaternion.copy(surfaceQuaternion3);
|
|
12694
13275
|
}
|
|
12695
|
-
group.rotateOnAxis(LOCAL_FORWARD,
|
|
13276
|
+
group.rotateOnAxis(LOCAL_FORWARD, MathUtils8.degToRad(-rotation));
|
|
12696
13277
|
let scaleFactor = scaleMode === "fixed" && camera instanceof PerspectiveCamera6 ? fixedScaleFactor(camera.fov, referenceFov) : 1;
|
|
12697
13278
|
if (scaleMode === "fixed" && orientation2 === "billboard" && useAngularScale && camera instanceof PerspectiveCamera6) {
|
|
12698
13279
|
group.updateWorldMatrix(true, false);
|
|
@@ -12709,15 +13290,15 @@ function applyHotspotTransform(group, camera, orientation2, surfaceQuaternion3,
|
|
|
12709
13290
|
group.updateMatrixWorld();
|
|
12710
13291
|
}
|
|
12711
13292
|
function fixedScaleFactor(cameraFov, referenceFov) {
|
|
12712
|
-
const safeReferenceFov =
|
|
12713
|
-
return Math.tan(
|
|
13293
|
+
const safeReferenceFov = MathUtils8.clamp(referenceFov, 1, 179);
|
|
13294
|
+
return Math.tan(MathUtils8.degToRad(cameraFov) / 2) / Math.tan(MathUtils8.degToRad(safeReferenceFov) / 2);
|
|
12714
13295
|
}
|
|
12715
13296
|
function selectionFrameScale(worldScaleX, worldScaleY, cameraSpaceDepth, fovDegrees, viewportHeight, outsetPixels) {
|
|
12716
13297
|
const pixels = Number.isFinite(outsetPixels) && outsetPixels > 0 ? outsetPixels : 0;
|
|
12717
13298
|
const depth = Number.isFinite(cameraSpaceDepth) ? Math.max(cameraSpaceDepth, 1e-4) : 1e-4;
|
|
12718
13299
|
const height = Number.isFinite(viewportHeight) ? Math.max(viewportHeight, 1) : 1;
|
|
12719
|
-
const fov = Number.isFinite(fovDegrees) ?
|
|
12720
|
-
const pixelsPerWorldUnit = height / (2 * Math.tan(
|
|
13300
|
+
const fov = Number.isFinite(fovDegrees) ? MathUtils8.clamp(fovDegrees, 1, 179) : 75;
|
|
13301
|
+
const pixelsPerWorldUnit = height / (2 * Math.tan(MathUtils8.degToRad(fov) * 0.5) * depth);
|
|
12721
13302
|
const axis = (worldScale) => {
|
|
12722
13303
|
const pixelsPerLocalUnit = pixelsPerWorldUnit * Math.abs(worldScale);
|
|
12723
13304
|
if (pixelsPerLocalUnit < 1e-4) {
|
|
@@ -12731,9 +13312,9 @@ function selectionFrameScale(worldScaleX, worldScaleY, cameraSpaceDepth, fovDegr
|
|
|
12731
13312
|
// src/hotspot/hotspot-stroke-line.tsx
|
|
12732
13313
|
import { Line } from "@react-three/drei";
|
|
12733
13314
|
import { useFrame as useFrame15, useThree as useThree18 } from "@react-three/fiber";
|
|
12734
|
-
import { useLayoutEffect as useLayoutEffect6, useRef as
|
|
13315
|
+
import { useLayoutEffect as useLayoutEffect6, useRef as useRef25 } from "react";
|
|
12735
13316
|
import {
|
|
12736
|
-
MathUtils as
|
|
13317
|
+
MathUtils as MathUtils9,
|
|
12737
13318
|
PerspectiveCamera as PerspectiveCamera7,
|
|
12738
13319
|
Vector3 as Vector316
|
|
12739
13320
|
} from "three";
|
|
@@ -12747,7 +13328,7 @@ function applyScreenSpaceDashScale(object, camera, viewportHeight) {
|
|
|
12747
13328
|
object.getWorldPosition(LINE_WORLD_POSITION);
|
|
12748
13329
|
const depth = Math.max(camera.position.distanceTo(LINE_WORLD_POSITION), 1);
|
|
12749
13330
|
const fov = camera instanceof PerspectiveCamera7 ? camera.fov : 75;
|
|
12750
|
-
material.dashScale = viewportHeight / (2 * Math.tan(
|
|
13331
|
+
material.dashScale = viewportHeight / (2 * Math.tan(MathUtils9.degToRad(fov) * 0.5) * depth);
|
|
12751
13332
|
}
|
|
12752
13333
|
function resolveDash(dashSize, gapSize) {
|
|
12753
13334
|
if (dashSize === void 0 || !Number.isFinite(dashSize) || dashSize <= 0) {
|
|
@@ -12768,7 +13349,7 @@ function HotspotStrokeLine({
|
|
|
12768
13349
|
dashSize,
|
|
12769
13350
|
gapSize
|
|
12770
13351
|
}) {
|
|
12771
|
-
const lineRef =
|
|
13352
|
+
const lineRef = useRef25(null);
|
|
12772
13353
|
const { camera, size } = useThree18();
|
|
12773
13354
|
const dash = resolveDash(dashSize, gapSize);
|
|
12774
13355
|
useLayoutEffect6(() => {
|
|
@@ -12844,8 +13425,8 @@ var HOTSPOT_MODE_RENDERING = {
|
|
|
12844
13425
|
billboard: { orientation: "billboard", placement: "floating" }
|
|
12845
13426
|
};
|
|
12846
13427
|
function angularSizeToWorldSize(size, radius) {
|
|
12847
|
-
const safeSize = Number.isFinite(size) ?
|
|
12848
|
-
return 2 * radius * Math.tan(
|
|
13428
|
+
const safeSize = Number.isFinite(size) ? MathUtils10.clamp(Math.abs(size), MIN_ANGULAR_SIZE, MAX_ANGULAR_SIZE) : MIN_ANGULAR_SIZE;
|
|
13429
|
+
return 2 * radius * Math.tan(MathUtils10.degToRad(safeSize) / 2);
|
|
12849
13430
|
}
|
|
12850
13431
|
function resolveScale(scale) {
|
|
12851
13432
|
return Number.isFinite(scale) && scale > 0 ? scale : 1;
|
|
@@ -12858,31 +13439,31 @@ function resolveDistance(placement, distance, width, height) {
|
|
|
12858
13439
|
if (!Number.isFinite(distance)) {
|
|
12859
13440
|
return DEFAULT_FLOATING_DISTANCE;
|
|
12860
13441
|
}
|
|
12861
|
-
return
|
|
13442
|
+
return MathUtils10.clamp(Math.abs(distance), 0.1, maximumDistance);
|
|
12862
13443
|
}
|
|
12863
13444
|
function maximumHotspotDistance(width, height) {
|
|
12864
|
-
const safeWidth =
|
|
13445
|
+
const safeWidth = MathUtils10.clamp(
|
|
12865
13446
|
Math.abs(Number.isFinite(width) ? width : MIN_ANGULAR_SIZE),
|
|
12866
13447
|
MIN_ANGULAR_SIZE,
|
|
12867
13448
|
MAX_ANGULAR_SIZE
|
|
12868
13449
|
);
|
|
12869
|
-
const safeHeight =
|
|
13450
|
+
const safeHeight = MathUtils10.clamp(
|
|
12870
13451
|
Math.abs(Number.isFinite(height) ? height : MIN_ANGULAR_SIZE),
|
|
12871
13452
|
MIN_ANGULAR_SIZE,
|
|
12872
13453
|
MAX_ANGULAR_SIZE
|
|
12873
13454
|
);
|
|
12874
13455
|
const cornerFactor = Math.hypot(
|
|
12875
13456
|
1,
|
|
12876
|
-
Math.tan(
|
|
12877
|
-
Math.tan(
|
|
13457
|
+
Math.tan(MathUtils10.degToRad(safeWidth) / 2),
|
|
13458
|
+
Math.tan(MathUtils10.degToRad(safeHeight) / 2)
|
|
12878
13459
|
);
|
|
12879
13460
|
return (PANORAMA_RADIUS - PANORAMA_SURFACE_INSET) / cornerFactor;
|
|
12880
13461
|
}
|
|
12881
13462
|
function createSurfaceQuaternion(position) {
|
|
12882
13463
|
const outward = panoPositionToVector3(position).normalize();
|
|
12883
13464
|
const inward = outward.clone().negate();
|
|
12884
|
-
const pitch =
|
|
12885
|
-
const yaw =
|
|
13465
|
+
const pitch = MathUtils10.degToRad(position.pitch);
|
|
13466
|
+
const yaw = MathUtils10.degToRad(position.yaw);
|
|
12886
13467
|
const localUp = new Vector317(
|
|
12887
13468
|
-Math.sin(pitch) * Math.sin(yaw),
|
|
12888
13469
|
Math.cos(pitch),
|
|
@@ -12903,7 +13484,7 @@ function makeInteractionEvent(id, position, event) {
|
|
|
12903
13484
|
function angularDistance(a, b) {
|
|
12904
13485
|
const aVector = panoPositionToVector3(a);
|
|
12905
13486
|
const bVector = panoPositionToVector3(b);
|
|
12906
|
-
return
|
|
13487
|
+
return MathUtils10.radToDeg(aVector.angleTo(bVector));
|
|
12907
13488
|
}
|
|
12908
13489
|
var DRAG_POINTER = new Vector24();
|
|
12909
13490
|
var DRAG_RAYCASTER = new Raycaster2();
|
|
@@ -13186,13 +13767,13 @@ function HotspotAnchor({
|
|
|
13186
13767
|
const eventBus = useContext21(PanoEventBusContext);
|
|
13187
13768
|
const cursorApi = usePanoCursor();
|
|
13188
13769
|
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 =
|
|
13770
|
+
const groupRef = useRef26(null);
|
|
13771
|
+
const selectionFrameRef = useRef26(null);
|
|
13772
|
+
const tooltipAnchorRef = useRef26(null);
|
|
13773
|
+
const dragStateRef = useRef26(null);
|
|
13774
|
+
const updateDragRef = useRef26(() => void 0);
|
|
13775
|
+
const endDragRef = useRef26(() => void 0);
|
|
13776
|
+
const suppressNextClickRef = useRef26(false);
|
|
13196
13777
|
const [hovered, setHovered] = useState14(false);
|
|
13197
13778
|
const [dragging, setDragging] = useState14(false);
|
|
13198
13779
|
const [pinned, setPinned] = useState14(false);
|
|
@@ -13234,7 +13815,7 @@ function HotspotAnchor({
|
|
|
13234
13815
|
planeGeometry.dispose();
|
|
13235
13816
|
return geometry;
|
|
13236
13817
|
}, []);
|
|
13237
|
-
const eventHovered =
|
|
13818
|
+
const eventHovered = useRef26(false);
|
|
13238
13819
|
useEffect25(() => {
|
|
13239
13820
|
if (!visible || !interactive || pointerEvents === "none") eventHovered.current = false;
|
|
13240
13821
|
}, [visible, interactive, pointerEvents]);
|
|
@@ -13752,8 +14333,8 @@ import { jsx as jsx29 } from "react/jsx-runtime";
|
|
|
13752
14333
|
function useHotspotImageTexture(src, onLoad, onError) {
|
|
13753
14334
|
const gl = useThree20((state) => state.gl);
|
|
13754
14335
|
const [texture, setTexture] = useState15(null);
|
|
13755
|
-
const onLoadRef =
|
|
13756
|
-
const onErrorRef =
|
|
14336
|
+
const onLoadRef = useRef27(onLoad);
|
|
14337
|
+
const onErrorRef = useRef27(onError);
|
|
13757
14338
|
onLoadRef.current = onLoad;
|
|
13758
14339
|
onErrorRef.current = onError;
|
|
13759
14340
|
useEffect26(() => {
|
|
@@ -13772,11 +14353,11 @@ function useHotspotImageTexture(src, onLoad, onError) {
|
|
|
13772
14353
|
loadedTexture.dispose();
|
|
13773
14354
|
return;
|
|
13774
14355
|
}
|
|
13775
|
-
loadedTexture.colorSpace =
|
|
13776
|
-
loadedTexture.wrapS =
|
|
13777
|
-
loadedTexture.wrapT =
|
|
13778
|
-
loadedTexture.magFilter =
|
|
13779
|
-
loadedTexture.minFilter =
|
|
14356
|
+
loadedTexture.colorSpace = SRGBColorSpace3;
|
|
14357
|
+
loadedTexture.wrapS = ClampToEdgeWrapping2;
|
|
14358
|
+
loadedTexture.wrapT = ClampToEdgeWrapping2;
|
|
14359
|
+
loadedTexture.magFilter = LinearFilter4;
|
|
14360
|
+
loadedTexture.minFilter = LinearMipmapLinearFilter3;
|
|
13780
14361
|
loadedTexture.generateMipmaps = true;
|
|
13781
14362
|
loadedTexture.anisotropy = gl.capabilities.getMaxAnisotropy();
|
|
13782
14363
|
loadedTexture.needsUpdate = true;
|
|
@@ -13816,13 +14397,13 @@ function ImageHotspot({
|
|
|
13816
14397
|
}
|
|
13817
14398
|
|
|
13818
14399
|
// src/hotspot/graphic-hotspot.tsx
|
|
13819
|
-
import { useEffect as useEffect27, useRef as
|
|
14400
|
+
import { useEffect as useEffect27, useRef as useRef28, useState as useState16 } from "react";
|
|
13820
14401
|
import {
|
|
13821
14402
|
CanvasTexture,
|
|
13822
|
-
ClampToEdgeWrapping as
|
|
13823
|
-
LinearFilter as
|
|
13824
|
-
LinearMipmapLinearFilter as
|
|
13825
|
-
SRGBColorSpace as
|
|
14403
|
+
ClampToEdgeWrapping as ClampToEdgeWrapping3,
|
|
14404
|
+
LinearFilter as LinearFilter5,
|
|
14405
|
+
LinearMipmapLinearFilter as LinearMipmapLinearFilter4,
|
|
14406
|
+
SRGBColorSpace as SRGBColorSpace4
|
|
13826
14407
|
} from "three";
|
|
13827
14408
|
import { jsx as jsx30 } from "react/jsx-runtime";
|
|
13828
14409
|
var GRAPHIC_TEXTURE_SIZE = 512;
|
|
@@ -14003,19 +14584,19 @@ function createGraphicTexture(graphic, aspectWidth, aspectHeight) {
|
|
|
14003
14584
|
}
|
|
14004
14585
|
drawGraphic(context, graphic, aspectWidth, aspectHeight);
|
|
14005
14586
|
const texture = new CanvasTexture(canvas);
|
|
14006
|
-
texture.colorSpace =
|
|
14007
|
-
texture.wrapS =
|
|
14008
|
-
texture.wrapT =
|
|
14009
|
-
texture.magFilter =
|
|
14010
|
-
texture.minFilter =
|
|
14587
|
+
texture.colorSpace = SRGBColorSpace4;
|
|
14588
|
+
texture.wrapS = ClampToEdgeWrapping3;
|
|
14589
|
+
texture.wrapT = ClampToEdgeWrapping3;
|
|
14590
|
+
texture.magFilter = LinearFilter5;
|
|
14591
|
+
texture.minFilter = LinearMipmapLinearFilter4;
|
|
14011
14592
|
texture.generateMipmaps = true;
|
|
14012
14593
|
texture.needsUpdate = true;
|
|
14013
14594
|
return texture;
|
|
14014
14595
|
}
|
|
14015
14596
|
function useGraphicTexture(graphic, aspectWidth, aspectHeight, onLoad, onError) {
|
|
14016
14597
|
const [texture, setTexture] = useState16(null);
|
|
14017
|
-
const onLoadRef =
|
|
14018
|
-
const onErrorRef =
|
|
14598
|
+
const onLoadRef = useRef28(onLoad);
|
|
14599
|
+
const onErrorRef = useRef28(onError);
|
|
14019
14600
|
onLoadRef.current = onLoad;
|
|
14020
14601
|
onErrorRef.current = onError;
|
|
14021
14602
|
useEffect27(() => {
|
|
@@ -14057,12 +14638,12 @@ function GraphicHotspot(props) {
|
|
|
14057
14638
|
|
|
14058
14639
|
// src/hotspot/sequence-hotspot.tsx
|
|
14059
14640
|
import { useFrame as useFrame17, useThree as useThree21 } from "@react-three/fiber";
|
|
14060
|
-
import { useEffect as useEffect28, useRef as
|
|
14641
|
+
import { useEffect as useEffect28, useRef as useRef29, useState as useState17 } from "react";
|
|
14061
14642
|
import {
|
|
14062
|
-
ClampToEdgeWrapping as
|
|
14063
|
-
LinearFilter as
|
|
14064
|
-
LinearMipmapLinearFilter as
|
|
14065
|
-
SRGBColorSpace as
|
|
14643
|
+
ClampToEdgeWrapping as ClampToEdgeWrapping4,
|
|
14644
|
+
LinearFilter as LinearFilter6,
|
|
14645
|
+
LinearMipmapLinearFilter as LinearMipmapLinearFilter5,
|
|
14646
|
+
SRGBColorSpace as SRGBColorSpace5,
|
|
14066
14647
|
TextureLoader as TextureLoader5
|
|
14067
14648
|
} from "three";
|
|
14068
14649
|
import { jsx as jsx31 } from "react/jsx-runtime";
|
|
@@ -14081,8 +14662,8 @@ function useSpriteTexture({
|
|
|
14081
14662
|
}) {
|
|
14082
14663
|
const gl = useThree21((state) => state.gl);
|
|
14083
14664
|
const [texture, setTexture] = useState17(null);
|
|
14084
|
-
const onErrorRef =
|
|
14085
|
-
const onLoadProgressRef =
|
|
14665
|
+
const onErrorRef = useRef29(onError);
|
|
14666
|
+
const onLoadProgressRef = useRef29(onLoadProgress);
|
|
14086
14667
|
onErrorRef.current = onError;
|
|
14087
14668
|
onLoadProgressRef.current = onLoadProgress;
|
|
14088
14669
|
useEffect28(() => {
|
|
@@ -14102,11 +14683,11 @@ function useSpriteTexture({
|
|
|
14102
14683
|
loadedTexture.dispose();
|
|
14103
14684
|
return;
|
|
14104
14685
|
}
|
|
14105
|
-
loadedTexture.colorSpace =
|
|
14106
|
-
loadedTexture.wrapS =
|
|
14107
|
-
loadedTexture.wrapT =
|
|
14108
|
-
loadedTexture.magFilter =
|
|
14109
|
-
loadedTexture.minFilter =
|
|
14686
|
+
loadedTexture.colorSpace = SRGBColorSpace5;
|
|
14687
|
+
loadedTexture.wrapS = ClampToEdgeWrapping4;
|
|
14688
|
+
loadedTexture.wrapT = ClampToEdgeWrapping4;
|
|
14689
|
+
loadedTexture.magFilter = LinearFilter6;
|
|
14690
|
+
loadedTexture.minFilter = LinearMipmapLinearFilter5;
|
|
14110
14691
|
loadedTexture.generateMipmaps = true;
|
|
14111
14692
|
loadedTexture.anisotropy = gl.capabilities.getMaxAnisotropy();
|
|
14112
14693
|
loadedTexture.needsUpdate = true;
|
|
@@ -14156,13 +14737,13 @@ function SequenceHotspot({
|
|
|
14156
14737
|
const frameCount = resolveFrameCount(requestedFrameCount);
|
|
14157
14738
|
const safeFps = resolveFps(fps);
|
|
14158
14739
|
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 =
|
|
14740
|
+
const elapsedRef = useRef29(0);
|
|
14741
|
+
const frameIndexRef = useRef29(0);
|
|
14742
|
+
const endedRef = useRef29(false);
|
|
14743
|
+
const lastPlaybackStateRef = useRef29(null);
|
|
14744
|
+
const onFrameChangeRef = useRef29(onFrameChange);
|
|
14745
|
+
const onPlaybackStateChangeRef = useRef29(onPlaybackStateChange);
|
|
14746
|
+
const onEndedRef = useRef29(onEnded);
|
|
14166
14747
|
onFrameChangeRef.current = onFrameChange;
|
|
14167
14748
|
onPlaybackStateChangeRef.current = onPlaybackStateChange;
|
|
14168
14749
|
onEndedRef.current = onEnded;
|
|
@@ -14246,12 +14827,12 @@ function SequenceHotspot({
|
|
|
14246
14827
|
|
|
14247
14828
|
// src/hotspot/video-hotspot.tsx
|
|
14248
14829
|
import { useThree as useThree22 } from "@react-three/fiber";
|
|
14249
|
-
import { useEffect as useEffect29, useLayoutEffect as useLayoutEffect8, useRef as
|
|
14830
|
+
import { useEffect as useEffect29, useLayoutEffect as useLayoutEffect8, useRef as useRef30, useState as useState18 } from "react";
|
|
14250
14831
|
import {
|
|
14251
|
-
ClampToEdgeWrapping as
|
|
14252
|
-
LinearFilter as
|
|
14253
|
-
LinearMipmapLinearFilter as
|
|
14254
|
-
SRGBColorSpace as
|
|
14832
|
+
ClampToEdgeWrapping as ClampToEdgeWrapping5,
|
|
14833
|
+
LinearFilter as LinearFilter7,
|
|
14834
|
+
LinearMipmapLinearFilter as LinearMipmapLinearFilter6,
|
|
14835
|
+
SRGBColorSpace as SRGBColorSpace6,
|
|
14255
14836
|
TextureLoader as TextureLoader6,
|
|
14256
14837
|
VideoTexture
|
|
14257
14838
|
} from "three";
|
|
@@ -14317,7 +14898,7 @@ function clampVolume2(volume) {
|
|
|
14317
14898
|
function usePosterTexture(id, poster, onError) {
|
|
14318
14899
|
const gl = useThree22((state) => state.gl);
|
|
14319
14900
|
const [texture, setTexture] = useState18(null);
|
|
14320
|
-
const onErrorRef =
|
|
14901
|
+
const onErrorRef = useRef30(onError);
|
|
14321
14902
|
onErrorRef.current = onError;
|
|
14322
14903
|
useEffect29(() => {
|
|
14323
14904
|
let active = true;
|
|
@@ -14335,11 +14916,11 @@ function usePosterTexture(id, poster, onError) {
|
|
|
14335
14916
|
loadedTexture.dispose();
|
|
14336
14917
|
return;
|
|
14337
14918
|
}
|
|
14338
|
-
loadedTexture.colorSpace =
|
|
14339
|
-
loadedTexture.wrapS =
|
|
14340
|
-
loadedTexture.wrapT =
|
|
14341
|
-
loadedTexture.magFilter =
|
|
14342
|
-
loadedTexture.minFilter =
|
|
14919
|
+
loadedTexture.colorSpace = SRGBColorSpace6;
|
|
14920
|
+
loadedTexture.wrapS = ClampToEdgeWrapping5;
|
|
14921
|
+
loadedTexture.wrapT = ClampToEdgeWrapping5;
|
|
14922
|
+
loadedTexture.magFilter = LinearFilter7;
|
|
14923
|
+
loadedTexture.minFilter = LinearMipmapLinearFilter6;
|
|
14343
14924
|
loadedTexture.generateMipmaps = true;
|
|
14344
14925
|
loadedTexture.anisotropy = gl.capabilities.getMaxAnisotropy();
|
|
14345
14926
|
loadedTexture.needsUpdate = true;
|
|
@@ -14376,9 +14957,9 @@ function useVideoResource({
|
|
|
14376
14957
|
}) {
|
|
14377
14958
|
const gl = useThree22((state) => state.gl);
|
|
14378
14959
|
const [resource, setResource] = useState18(null);
|
|
14379
|
-
const onEndedRef =
|
|
14380
|
-
const onErrorRef =
|
|
14381
|
-
const onPlaybackStateChangeRef =
|
|
14960
|
+
const onEndedRef = useRef30(onEnded);
|
|
14961
|
+
const onErrorRef = useRef30(onError);
|
|
14962
|
+
const onPlaybackStateChangeRef = useRef30(onPlaybackStateChange);
|
|
14382
14963
|
onEndedRef.current = onEnded;
|
|
14383
14964
|
onErrorRef.current = onError;
|
|
14384
14965
|
onPlaybackStateChangeRef.current = onPlaybackStateChange;
|
|
@@ -14395,11 +14976,11 @@ function useVideoResource({
|
|
|
14395
14976
|
applyInlineVideoPlayback(video, playsInline ?? true);
|
|
14396
14977
|
video.poster = poster ?? "";
|
|
14397
14978
|
const texture = new VideoTexture(video);
|
|
14398
|
-
texture.colorSpace =
|
|
14399
|
-
texture.wrapS =
|
|
14400
|
-
texture.wrapT =
|
|
14401
|
-
texture.magFilter =
|
|
14402
|
-
texture.minFilter =
|
|
14979
|
+
texture.colorSpace = SRGBColorSpace6;
|
|
14980
|
+
texture.wrapS = ClampToEdgeWrapping5;
|
|
14981
|
+
texture.wrapT = ClampToEdgeWrapping5;
|
|
14982
|
+
texture.magFilter = LinearFilter7;
|
|
14983
|
+
texture.minFilter = LinearFilter7;
|
|
14403
14984
|
texture.generateMipmaps = false;
|
|
14404
14985
|
const notifyState = (state) => {
|
|
14405
14986
|
if (active) {
|
|
@@ -14495,8 +15076,8 @@ function VideoHotspot({
|
|
|
14495
15076
|
src
|
|
14496
15077
|
});
|
|
14497
15078
|
const posterTexture = usePosterTexture(id, poster, onError);
|
|
14498
|
-
const onPlaybackErrorRef =
|
|
14499
|
-
const onPlaybackStateChangeRef =
|
|
15079
|
+
const onPlaybackErrorRef = useRef30(onPlaybackError);
|
|
15080
|
+
const onPlaybackStateChangeRef = useRef30(onPlaybackStateChange);
|
|
14500
15081
|
onPlaybackErrorRef.current = onPlaybackError;
|
|
14501
15082
|
onPlaybackStateChangeRef.current = onPlaybackStateChange;
|
|
14502
15083
|
useLayoutEffect8(() => {
|
|
@@ -14537,18 +15118,18 @@ function VideoHotspot({
|
|
|
14537
15118
|
|
|
14538
15119
|
// src/hotspot/audio-hotspot.tsx
|
|
14539
15120
|
import { useFrame as useFrame18, useThree as useThree23 } from "@react-three/fiber";
|
|
14540
|
-
import { useEffect as useEffect30, useRef as
|
|
15121
|
+
import { useEffect as useEffect30, useRef as useRef31, useState as useState19 } from "react";
|
|
14541
15122
|
import {
|
|
14542
15123
|
CanvasTexture as CanvasTexture2,
|
|
14543
|
-
ClampToEdgeWrapping as
|
|
14544
|
-
LinearFilter as
|
|
14545
|
-
LinearMipmapLinearFilter as
|
|
14546
|
-
SRGBColorSpace as
|
|
15124
|
+
ClampToEdgeWrapping as ClampToEdgeWrapping6,
|
|
15125
|
+
LinearFilter as LinearFilter8,
|
|
15126
|
+
LinearMipmapLinearFilter as LinearMipmapLinearFilter7,
|
|
15127
|
+
SRGBColorSpace as SRGBColorSpace7,
|
|
14547
15128
|
TextureLoader as TextureLoader7
|
|
14548
15129
|
} from "three";
|
|
14549
15130
|
|
|
14550
15131
|
// src/hotspot/audio-spatial.ts
|
|
14551
|
-
import { MathUtils as
|
|
15132
|
+
import { MathUtils as MathUtils11, Vector3 as Vector318 } from "three";
|
|
14552
15133
|
var LOOK_DIR = new Vector318();
|
|
14553
15134
|
var SOURCE_DIR = new Vector318();
|
|
14554
15135
|
var RIGHT_DIR = new Vector318();
|
|
@@ -14576,11 +15157,11 @@ function lookRangeGain(angleDegrees, range) {
|
|
|
14576
15157
|
function audioSpatialFromView(camera, position, range) {
|
|
14577
15158
|
camera.getWorldDirection(LOOK_DIR);
|
|
14578
15159
|
SOURCE_DIR.copy(panoPositionToVector3(position)).normalize();
|
|
14579
|
-
const angleDegrees =
|
|
14580
|
-
Math.acos(
|
|
15160
|
+
const angleDegrees = MathUtils11.radToDeg(
|
|
15161
|
+
Math.acos(MathUtils11.clamp(LOOK_DIR.dot(SOURCE_DIR), -1, 1))
|
|
14581
15162
|
);
|
|
14582
15163
|
RIGHT_DIR.set(1, 0, 0).applyQuaternion(camera.quaternion);
|
|
14583
|
-
const pan =
|
|
15164
|
+
const pan = MathUtils11.clamp(
|
|
14584
15165
|
Math.atan2(SOURCE_DIR.dot(RIGHT_DIR), SOURCE_DIR.dot(LOOK_DIR)) / (Math.PI / 2),
|
|
14585
15166
|
-1,
|
|
14586
15167
|
1
|
|
@@ -14646,11 +15227,11 @@ function createSpeakerTexture(state) {
|
|
|
14646
15227
|
}
|
|
14647
15228
|
}
|
|
14648
15229
|
const texture = new CanvasTexture2(canvas);
|
|
14649
|
-
texture.colorSpace =
|
|
14650
|
-
texture.wrapS =
|
|
14651
|
-
texture.wrapT =
|
|
14652
|
-
texture.magFilter =
|
|
14653
|
-
texture.minFilter =
|
|
15230
|
+
texture.colorSpace = SRGBColorSpace7;
|
|
15231
|
+
texture.wrapS = ClampToEdgeWrapping6;
|
|
15232
|
+
texture.wrapT = ClampToEdgeWrapping6;
|
|
15233
|
+
texture.magFilter = LinearFilter8;
|
|
15234
|
+
texture.minFilter = LinearMipmapLinearFilter7;
|
|
14654
15235
|
texture.generateMipmaps = true;
|
|
14655
15236
|
texture.needsUpdate = true;
|
|
14656
15237
|
return texture;
|
|
@@ -14675,7 +15256,7 @@ function useSpeakerTextures(enabled) {
|
|
|
14675
15256
|
function useIconTexture(icon, enabled, onError, id) {
|
|
14676
15257
|
const gl = useThree23((state) => state.gl);
|
|
14677
15258
|
const [texture, setTexture] = useState19(null);
|
|
14678
|
-
const onErrorRef =
|
|
15259
|
+
const onErrorRef = useRef31(onError);
|
|
14679
15260
|
onErrorRef.current = onError;
|
|
14680
15261
|
useEffect30(() => {
|
|
14681
15262
|
let active = true;
|
|
@@ -14693,11 +15274,11 @@ function useIconTexture(icon, enabled, onError, id) {
|
|
|
14693
15274
|
loadedTexture.dispose();
|
|
14694
15275
|
return;
|
|
14695
15276
|
}
|
|
14696
|
-
loadedTexture.colorSpace =
|
|
14697
|
-
loadedTexture.wrapS =
|
|
14698
|
-
loadedTexture.wrapT =
|
|
14699
|
-
loadedTexture.magFilter =
|
|
14700
|
-
loadedTexture.minFilter =
|
|
15277
|
+
loadedTexture.colorSpace = SRGBColorSpace7;
|
|
15278
|
+
loadedTexture.wrapS = ClampToEdgeWrapping6;
|
|
15279
|
+
loadedTexture.wrapT = ClampToEdgeWrapping6;
|
|
15280
|
+
loadedTexture.magFilter = LinearFilter8;
|
|
15281
|
+
loadedTexture.minFilter = LinearMipmapLinearFilter7;
|
|
14701
15282
|
loadedTexture.generateMipmaps = true;
|
|
14702
15283
|
loadedTexture.anisotropy = gl.capabilities.getMaxAnisotropy();
|
|
14703
15284
|
loadedTexture.needsUpdate = true;
|
|
@@ -14735,12 +15316,12 @@ function useAudioHowl({
|
|
|
14735
15316
|
format
|
|
14736
15317
|
}) {
|
|
14737
15318
|
const [howl, setHowl] = useState19(null);
|
|
14738
|
-
const playingRef =
|
|
14739
|
-
const loopRef =
|
|
14740
|
-
const onEndedRef =
|
|
14741
|
-
const onErrorRef =
|
|
14742
|
-
const onPlaybackErrorRef =
|
|
14743
|
-
const onPlaybackStateChangeRef =
|
|
15319
|
+
const playingRef = useRef31(playing);
|
|
15320
|
+
const loopRef = useRef31(loop ?? false);
|
|
15321
|
+
const onEndedRef = useRef31(onEnded);
|
|
15322
|
+
const onErrorRef = useRef31(onError);
|
|
15323
|
+
const onPlaybackErrorRef = useRef31(onPlaybackError);
|
|
15324
|
+
const onPlaybackStateChangeRef = useRef31(onPlaybackStateChange);
|
|
14744
15325
|
playingRef.current = playing;
|
|
14745
15326
|
loopRef.current = loop ?? false;
|
|
14746
15327
|
onEndedRef.current = onEnded;
|
|
@@ -14833,11 +15414,11 @@ function AudioHotspot({
|
|
|
14833
15414
|
const stoppedIconTexture = useIconTexture(icon, marker, onError, id);
|
|
14834
15415
|
const playingIconTexture = useIconTexture(playingIcon, marker, onError, id);
|
|
14835
15416
|
const markerTexture = playing ? playingIconTexture ?? stoppedIconTexture ?? speakerTextures.playing : stoppedIconTexture ?? speakerTextures.stopped;
|
|
14836
|
-
const playingRef =
|
|
15417
|
+
const playingRef = useRef31(playing);
|
|
14837
15418
|
playingRef.current = playing;
|
|
14838
|
-
const mutedRef =
|
|
14839
|
-
const volumeRef =
|
|
14840
|
-
const rangeRef =
|
|
15419
|
+
const mutedRef = useRef31(muted);
|
|
15420
|
+
const volumeRef = useRef31(volume);
|
|
15421
|
+
const rangeRef = useRef31(range);
|
|
14841
15422
|
mutedRef.current = muted;
|
|
14842
15423
|
volumeRef.current = volume;
|
|
14843
15424
|
rangeRef.current = range;
|
|
@@ -14886,15 +15467,15 @@ function AudioHotspot({
|
|
|
14886
15467
|
}
|
|
14887
15468
|
|
|
14888
15469
|
// src/hotspot/text-hotspot.tsx
|
|
14889
|
-
import { useEffect as useEffect31, useRef as
|
|
15470
|
+
import { useEffect as useEffect31, useRef as useRef32, useState as useState20 } from "react";
|
|
14890
15471
|
import { useFrame as useFrame19, useThree as useThree24 } from "@react-three/fiber";
|
|
14891
15472
|
import {
|
|
14892
15473
|
CanvasTexture as CanvasTexture3,
|
|
14893
|
-
ClampToEdgeWrapping as
|
|
14894
|
-
LinearFilter as
|
|
14895
|
-
MathUtils as
|
|
15474
|
+
ClampToEdgeWrapping as ClampToEdgeWrapping7,
|
|
15475
|
+
LinearFilter as LinearFilter9,
|
|
15476
|
+
MathUtils as MathUtils12,
|
|
14896
15477
|
PerspectiveCamera as PerspectiveCamera9,
|
|
14897
|
-
SRGBColorSpace as
|
|
15478
|
+
SRGBColorSpace as SRGBColorSpace8
|
|
14898
15479
|
} from "three";
|
|
14899
15480
|
import { jsx as jsx34 } from "react/jsx-runtime";
|
|
14900
15481
|
var TEXT_TEXTURE_LONG_SIDE = 1024;
|
|
@@ -14967,7 +15548,7 @@ function projectedDevicePixels(angleDeg, fovDeg, viewportHeight) {
|
|
|
14967
15548
|
}
|
|
14968
15549
|
const fov = Math.min(179, Math.max(1, resolvePositive(fovDeg, DEFAULT_REFERENCE_FOV2)));
|
|
14969
15550
|
const angle = Math.min(179, Math.max(0.01, Math.abs(angleDeg)));
|
|
14970
|
-
return Math.tan(
|
|
15551
|
+
return Math.tan(MathUtils12.degToRad(angle) / 2) / Math.tan(MathUtils12.degToRad(fov) / 2) * viewportHeight;
|
|
14971
15552
|
}
|
|
14972
15553
|
function snapRasterLongSide(screenLong, layoutLong) {
|
|
14973
15554
|
if (!(screenLong > 0)) {
|
|
@@ -15157,11 +15738,11 @@ function createTextTexture(text, width, height, style, rasterLong) {
|
|
|
15157
15738
|
);
|
|
15158
15739
|
drawTextHotspot(context, layout.canvasWidth, layout.canvasHeight, text, style);
|
|
15159
15740
|
const texture = new CanvasTexture3(canvas);
|
|
15160
|
-
texture.colorSpace =
|
|
15161
|
-
texture.wrapS =
|
|
15162
|
-
texture.wrapT =
|
|
15163
|
-
texture.magFilter =
|
|
15164
|
-
texture.minFilter =
|
|
15741
|
+
texture.colorSpace = SRGBColorSpace8;
|
|
15742
|
+
texture.wrapS = ClampToEdgeWrapping7;
|
|
15743
|
+
texture.wrapT = ClampToEdgeWrapping7;
|
|
15744
|
+
texture.magFilter = LinearFilter9;
|
|
15745
|
+
texture.minFilter = LinearFilter9;
|
|
15165
15746
|
texture.generateMipmaps = false;
|
|
15166
15747
|
texture.needsUpdate = true;
|
|
15167
15748
|
return texture;
|
|
@@ -15206,8 +15787,8 @@ function useRasterLongSide(width, height, scale, scaleMode, referenceFov) {
|
|
|
15206
15787
|
function useTextTexture(text, width, height, style, scale, scaleMode, referenceFov, onLoad, onError) {
|
|
15207
15788
|
const rasterLong = useRasterLongSide(width, height, scale, scaleMode, referenceFov);
|
|
15208
15789
|
const [texture, setTexture] = useState20(null);
|
|
15209
|
-
const onLoadRef =
|
|
15210
|
-
const onErrorRef =
|
|
15790
|
+
const onLoadRef = useRef32(onLoad);
|
|
15791
|
+
const onErrorRef = useRef32(onError);
|
|
15211
15792
|
onLoadRef.current = onLoad;
|
|
15212
15793
|
onErrorRef.current = onError;
|
|
15213
15794
|
useEffect31(() => {
|
|
@@ -15436,7 +16017,7 @@ function IframeHotspot({
|
|
|
15436
16017
|
}
|
|
15437
16018
|
|
|
15438
16019
|
// src/hotspot/polygon-hotspot.tsx
|
|
15439
|
-
import { useEffect as useEffect32, useMemo as useMemo20, useRef as
|
|
16020
|
+
import { useEffect as useEffect32, useMemo as useMemo20, useRef as useRef33 } from "react";
|
|
15440
16021
|
import {
|
|
15441
16022
|
BufferGeometry as BufferGeometry2,
|
|
15442
16023
|
DoubleSide as DoubleSide5,
|
|
@@ -15715,7 +16296,7 @@ function PolygonHotspot({
|
|
|
15715
16296
|
[center, valid, vertices]
|
|
15716
16297
|
);
|
|
15717
16298
|
const resolvedStrokeOpacity = Math.max(0, Math.min(strokeOpacity, 1));
|
|
15718
|
-
const startVerticesRef =
|
|
16299
|
+
const startVerticesRef = useRef33(null);
|
|
15719
16300
|
const issuesKey = issues.map((issue) => issue.code).join(",");
|
|
15720
16301
|
useEffect32(() => {
|
|
15721
16302
|
if (!valid) onInvalid?.(issues);
|
|
@@ -15800,9 +16381,9 @@ function PolygonHotspot({
|
|
|
15800
16381
|
}
|
|
15801
16382
|
|
|
15802
16383
|
// src/hotspot/polyline-hotspot.tsx
|
|
15803
|
-
import { useEffect as useEffect33, useMemo as useMemo21, useRef as
|
|
16384
|
+
import { useEffect as useEffect33, useMemo as useMemo21, useRef as useRef34 } from "react";
|
|
15804
16385
|
import {
|
|
15805
|
-
MathUtils as
|
|
16386
|
+
MathUtils as MathUtils13,
|
|
15806
16387
|
Matrix4 as Matrix46,
|
|
15807
16388
|
Quaternion as Quaternion6,
|
|
15808
16389
|
Vector3 as Vector320
|
|
@@ -15839,8 +16420,8 @@ function polylineCenter(vertices) {
|
|
|
15839
16420
|
function surfaceQuaternion2(position) {
|
|
15840
16421
|
const outward = panoPositionToVector3(position).normalize();
|
|
15841
16422
|
const inward = outward.clone().negate();
|
|
15842
|
-
const pitch =
|
|
15843
|
-
const yaw =
|
|
16423
|
+
const pitch = MathUtils13.degToRad(position.pitch);
|
|
16424
|
+
const yaw = MathUtils13.degToRad(position.yaw);
|
|
15844
16425
|
const localUp = new Vector320(
|
|
15845
16426
|
-Math.sin(pitch) * Math.sin(yaw),
|
|
15846
16427
|
Math.cos(pitch),
|
|
@@ -15869,7 +16450,7 @@ function subdivisionSteps(vertices) {
|
|
|
15869
16450
|
}
|
|
15870
16451
|
return Math.min(
|
|
15871
16452
|
8,
|
|
15872
|
-
Math.max(1, Math.ceil(
|
|
16453
|
+
Math.max(1, Math.ceil(MathUtils13.radToDeg(maxAngle) / MAX_SEGMENT_DEGREES))
|
|
15873
16454
|
);
|
|
15874
16455
|
}
|
|
15875
16456
|
function makeLinePositions(vertices, center) {
|
|
@@ -15932,7 +16513,7 @@ function PolylineHotspot({
|
|
|
15932
16513
|
[center, valid, vertices]
|
|
15933
16514
|
);
|
|
15934
16515
|
const opacity = Math.max(0, Math.min(strokeOpacity, 1));
|
|
15935
|
-
const startVerticesRef =
|
|
16516
|
+
const startVerticesRef = useRef34(null);
|
|
15936
16517
|
useEffect33(() => {
|
|
15937
16518
|
if (!valid) onInvalid?.(issues);
|
|
15938
16519
|
}, [issues, onInvalid, valid]);
|
|
@@ -16249,7 +16830,7 @@ function ProjectScenes({
|
|
|
16249
16830
|
}
|
|
16250
16831
|
|
|
16251
16832
|
// src/background-audio.tsx
|
|
16252
|
-
import { useContext as useContext23, useEffect as useEffect34, useMemo as useMemo23, useRef as
|
|
16833
|
+
import { useContext as useContext23, useEffect as useEffect34, useMemo as useMemo23, useRef as useRef35, useState as useState22 } from "react";
|
|
16253
16834
|
var DEFAULT_FADE_MS = 400;
|
|
16254
16835
|
function resolveFadeMs(value) {
|
|
16255
16836
|
if (!Number.isFinite(value)) {
|
|
@@ -16301,21 +16882,21 @@ function BackgroundAudio({
|
|
|
16301
16882
|
const urls = resolveBackgroundAudioUrls(src, sources, sceneId);
|
|
16302
16883
|
usePanoMediaActivationIntent(playing && urls.length > 0);
|
|
16303
16884
|
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 =
|
|
16885
|
+
const currentRef = useRef35(null);
|
|
16886
|
+
const outgoingRef = useRef35([]);
|
|
16887
|
+
const fadingInRef = useRef35(false);
|
|
16888
|
+
const isFirstTrackRef = useRef35(true);
|
|
16889
|
+
const playingRef = useRef35(playing);
|
|
16890
|
+
const loopRef = useRef35(loop);
|
|
16891
|
+
const mutedRef = useRef35(muted);
|
|
16892
|
+
const volumeRef = useRef35(volume);
|
|
16893
|
+
const mutedPropRef = useRef35(muted);
|
|
16894
|
+
const volumePropRef = useRef35(volume);
|
|
16895
|
+
const fadeMsRef = useRef35(resolveFadeMs(fadeMs));
|
|
16896
|
+
const onPlaybackStateChangeRef = useRef35(onPlaybackStateChange);
|
|
16897
|
+
const onPlaybackErrorRef = useRef35(onPlaybackError);
|
|
16898
|
+
const onEndedRef = useRef35(onEnded);
|
|
16899
|
+
const onErrorRef = useRef35(onError);
|
|
16319
16900
|
playingRef.current = playing;
|
|
16320
16901
|
loopRef.current = loop;
|
|
16321
16902
|
fadeMsRef.current = resolveFadeMs(fadeMs);
|
|
@@ -16331,7 +16912,7 @@ function BackgroundAudio({
|
|
|
16331
16912
|
onPlaybackErrorRef.current = onPlaybackError;
|
|
16332
16913
|
onEndedRef.current = onEnded;
|
|
16333
16914
|
onErrorRef.current = onError;
|
|
16334
|
-
const snapshotRef =
|
|
16915
|
+
const snapshotRef = useRef35({
|
|
16335
16916
|
ready: false,
|
|
16336
16917
|
playing: false,
|
|
16337
16918
|
blocked: false,
|
|
@@ -16339,7 +16920,7 @@ function BackgroundAudio({
|
|
|
16339
16920
|
muted,
|
|
16340
16921
|
volume
|
|
16341
16922
|
});
|
|
16342
|
-
const snapshotListenersRef =
|
|
16923
|
+
const snapshotListenersRef = useRef35(/* @__PURE__ */ new Set());
|
|
16343
16924
|
const notifySnapshot = (patch) => {
|
|
16344
16925
|
const prev = snapshotRef.current;
|
|
16345
16926
|
snapshotRef.current = { ...prev, ...patch };
|
|
@@ -16347,7 +16928,7 @@ function BackgroundAudio({
|
|
|
16347
16928
|
listener();
|
|
16348
16929
|
}
|
|
16349
16930
|
};
|
|
16350
|
-
const isControlledRef =
|
|
16931
|
+
const isControlledRef = useRef35(isControlled);
|
|
16351
16932
|
isControlledRef.current = isControlled;
|
|
16352
16933
|
const controller = useMemo23(
|
|
16353
16934
|
() => ({
|
|
@@ -16635,11 +17216,11 @@ function PanoFilter({
|
|
|
16635
17216
|
import { useFrame as useFrame20, useThree as useThree25 } from "@react-three/fiber";
|
|
16636
17217
|
import {
|
|
16637
17218
|
forwardRef as forwardRef3,
|
|
16638
|
-
useCallback as
|
|
17219
|
+
useCallback as useCallback10,
|
|
16639
17220
|
useContext as useContext25,
|
|
16640
17221
|
useEffect as useEffect36,
|
|
16641
17222
|
useImperativeHandle as useImperativeHandle3,
|
|
16642
|
-
useRef as
|
|
17223
|
+
useRef as useRef36,
|
|
16643
17224
|
useState as useState23
|
|
16644
17225
|
} from "react";
|
|
16645
17226
|
import { Quaternion as Quaternion7 } from "three";
|
|
@@ -16679,30 +17260,30 @@ var Gyro = forwardRef3(function Gyro2({
|
|
|
16679
17260
|
const { gl } = useThree25();
|
|
16680
17261
|
const [internallyDisabled, setInternallyDisabled] = useState23(false);
|
|
16681
17262
|
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 =
|
|
17263
|
+
const availableRef = useRef36(false);
|
|
17264
|
+
const availabilityReportedRef = useRef36(null);
|
|
17265
|
+
const activeRef = useRef36(false);
|
|
17266
|
+
const permissionRef = useRef36(deviceOrientationPermissionState);
|
|
17267
|
+
const absoluteEventSourceRef = useRef36(null);
|
|
17268
|
+
const rawQuaternionRef = useRef36(new Quaternion7());
|
|
17269
|
+
const hasRawQuaternionRef = useRef36(false);
|
|
17270
|
+
const calibrationRef = useRef36(new Quaternion7());
|
|
17271
|
+
const hasCalibrationRef = useRef36(false);
|
|
17272
|
+
const calibratedQuaternionRef = useRef36(new Quaternion7());
|
|
17273
|
+
const absoluteOffsetRef = useRef36({ yaw: 0, pitch: 0 });
|
|
17274
|
+
const screenAngleRef = useRef36(getScreenOrientationAngle());
|
|
17275
|
+
const startPoseRef = useRef36(null);
|
|
17276
|
+
const enabledAtRef = useRef36(0);
|
|
17277
|
+
const filteredPoseRef = useRef36(null);
|
|
17278
|
+
const lastAppliedPoseRef = useRef36(null);
|
|
17279
|
+
const lastSamplePoseRef = useRef36(null);
|
|
17280
|
+
const lastSampleAtRef = useRef36(null);
|
|
17281
|
+
const previousYawRef = useRef36(void 0);
|
|
17282
|
+
const absoluteRef = useRef36(absolute);
|
|
17283
|
+
const northRef = useRef36(north);
|
|
16703
17284
|
absoluteRef.current = absolute;
|
|
16704
17285
|
northRef.current = north;
|
|
16705
|
-
const callbacksRef =
|
|
17286
|
+
const callbacksRef = useRef36({
|
|
16706
17287
|
onAvailable,
|
|
16707
17288
|
onUnavailable,
|
|
16708
17289
|
onEnable,
|
|
@@ -16719,7 +17300,7 @@ var Gyro = forwardRef3(function Gyro2({
|
|
|
16719
17300
|
if (!controlsRef) {
|
|
16720
17301
|
throw new Error("<Gyro> must be rendered inside <PanoViewer>.");
|
|
16721
17302
|
}
|
|
16722
|
-
const emit =
|
|
17303
|
+
const emit = useCallback10(
|
|
16723
17304
|
(type) => {
|
|
16724
17305
|
eventBus?.emit(type, void 0);
|
|
16725
17306
|
switch (type) {
|
|
@@ -16746,7 +17327,7 @@ var Gyro = forwardRef3(function Gyro2({
|
|
|
16746
17327
|
},
|
|
16747
17328
|
[eventBus]
|
|
16748
17329
|
);
|
|
16749
|
-
const setAvailable =
|
|
17330
|
+
const setAvailable = useCallback10(
|
|
16750
17331
|
(nextAvailable) => {
|
|
16751
17332
|
availableRef.current = nextAvailable;
|
|
16752
17333
|
setAvailableState(nextAvailable);
|
|
@@ -16758,7 +17339,7 @@ var Gyro = forwardRef3(function Gyro2({
|
|
|
16758
17339
|
},
|
|
16759
17340
|
[emit]
|
|
16760
17341
|
);
|
|
16761
|
-
const requestPermission =
|
|
17342
|
+
const requestPermission = useCallback10(async () => {
|
|
16762
17343
|
if (!availableRef.current) {
|
|
16763
17344
|
return false;
|
|
16764
17345
|
}
|
|
@@ -16791,7 +17372,7 @@ var Gyro = forwardRef3(function Gyro2({
|
|
|
16791
17372
|
emit("gyrodenied");
|
|
16792
17373
|
return false;
|
|
16793
17374
|
}, [emit, setAvailable]);
|
|
16794
|
-
const deactivate =
|
|
17375
|
+
const deactivate = useCallback10(() => {
|
|
16795
17376
|
if (activeRef.current) {
|
|
16796
17377
|
activeRef.current = false;
|
|
16797
17378
|
controlsRef.current?.setGyroActive(false);
|
|
@@ -16806,7 +17387,7 @@ var Gyro = forwardRef3(function Gyro2({
|
|
|
16806
17387
|
lastSampleAtRef.current = null;
|
|
16807
17388
|
previousYawRef.current = void 0;
|
|
16808
17389
|
}, [controlsRef, emit]);
|
|
16809
|
-
const anchorToView =
|
|
17390
|
+
const anchorToView = useCallback10(
|
|
16810
17391
|
(yaw, pitch) => {
|
|
16811
17392
|
if (!hasRawQuaternionRef.current) {
|
|
16812
17393
|
return;
|
|
@@ -16836,7 +17417,7 @@ var Gyro = forwardRef3(function Gyro2({
|
|
|
16836
17417
|
},
|
|
16837
17418
|
[]
|
|
16838
17419
|
);
|
|
16839
|
-
const resetSensor =
|
|
17420
|
+
const resetSensor = useCallback10(
|
|
16840
17421
|
(yaw, pitch) => {
|
|
16841
17422
|
if (!hasRawQuaternionRef.current) {
|
|
16842
17423
|
return;
|
|
@@ -17118,12 +17699,12 @@ var Gyro = forwardRef3(function Gyro2({
|
|
|
17118
17699
|
import { useThree as useThree28 } from "@react-three/fiber";
|
|
17119
17700
|
import {
|
|
17120
17701
|
forwardRef as forwardRef4,
|
|
17121
|
-
useCallback as
|
|
17702
|
+
useCallback as useCallback11,
|
|
17122
17703
|
useContext as useContext27,
|
|
17123
17704
|
useEffect as useEffect40,
|
|
17124
17705
|
useImperativeHandle as useImperativeHandle4,
|
|
17125
17706
|
useMemo as useMemo26,
|
|
17126
|
-
useRef as
|
|
17707
|
+
useRef as useRef40,
|
|
17127
17708
|
useState as useState24
|
|
17128
17709
|
} from "react";
|
|
17129
17710
|
|
|
@@ -17132,18 +17713,196 @@ function isMobileVRDevice() {
|
|
|
17132
17713
|
if (typeof navigator === "undefined") {
|
|
17133
17714
|
return false;
|
|
17134
17715
|
}
|
|
17135
|
-
return /Android|iPad|iPhone|iPod|Mobile/i.test(navigator.userAgent) || navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1;
|
|
17716
|
+
return /Android|iPad|iPhone|iPod|Mobile/i.test(navigator.userAgent) || navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1;
|
|
17717
|
+
}
|
|
17718
|
+
async function detectWebVRCapabilities() {
|
|
17719
|
+
const mobile = isMobileVRDevice();
|
|
17720
|
+
const sensor = typeof window !== "undefined" && window.isSecureContext && typeof DeviceOrientationEvent !== "undefined";
|
|
17721
|
+
let webxr = false;
|
|
17722
|
+
try {
|
|
17723
|
+
webxr = typeof navigator !== "undefined" && navigator.xr !== void 0 && await navigator.xr.isSessionSupported("immersive-vr");
|
|
17724
|
+
} catch {
|
|
17725
|
+
webxr = false;
|
|
17726
|
+
}
|
|
17727
|
+
return { webxr, mobile, sensor };
|
|
17728
|
+
}
|
|
17729
|
+
|
|
17730
|
+
// src/webvr/dpdb.ts
|
|
17731
|
+
var DEFAULT_WEBVR_DATABASE_URL = "https://storage.googleapis.com/cardboard-dpdb/dpdb.json";
|
|
17732
|
+
var SCREENSIZE_MIN = 3;
|
|
17733
|
+
var SCREENSIZE_MAX = 20;
|
|
17734
|
+
var cache = /* @__PURE__ */ new Map();
|
|
17735
|
+
function normalizeDatabaseUrl(value) {
|
|
17736
|
+
if (value === null || value === "") {
|
|
17737
|
+
return null;
|
|
17738
|
+
}
|
|
17739
|
+
if (value === void 0) {
|
|
17740
|
+
return DEFAULT_WEBVR_DATABASE_URL;
|
|
17741
|
+
}
|
|
17742
|
+
const trimmed = value.trim();
|
|
17743
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
17744
|
+
}
|
|
17745
|
+
function physicalResolution(screenWidth, screenHeight, devicePixelRatio) {
|
|
17746
|
+
const ratio = Number.isFinite(devicePixelRatio) && devicePixelRatio > 0 ? devicePixelRatio : 1;
|
|
17747
|
+
return [
|
|
17748
|
+
Math.round(Math.max(0, screenWidth) * ratio),
|
|
17749
|
+
Math.round(Math.max(0, screenHeight) * ratio)
|
|
17750
|
+
];
|
|
17751
|
+
}
|
|
17752
|
+
function resolutionsMatch(rule, physical) {
|
|
17753
|
+
const [rw, rh] = rule;
|
|
17754
|
+
const [pw, ph] = physical;
|
|
17755
|
+
return rw === pw && rh === ph || rw === ph && rh === pw;
|
|
17756
|
+
}
|
|
17757
|
+
function ruleMatches(rule, input, physical) {
|
|
17758
|
+
if (typeof rule.ua === "string") {
|
|
17759
|
+
return input.userAgent.includes(rule.ua);
|
|
17760
|
+
}
|
|
17761
|
+
if (Array.isArray(rule.res) && rule.res.length === 2 && typeof rule.res[0] === "number" && typeof rule.res[1] === "number") {
|
|
17762
|
+
return resolutionsMatch(
|
|
17763
|
+
[rule.res[0], rule.res[1]],
|
|
17764
|
+
physical
|
|
17765
|
+
);
|
|
17766
|
+
}
|
|
17767
|
+
return false;
|
|
17768
|
+
}
|
|
17769
|
+
function deviceMatches(device, input) {
|
|
17770
|
+
const rules = device.rules;
|
|
17771
|
+
if (!Array.isArray(rules) || rules.length === 0) {
|
|
17772
|
+
return false;
|
|
17773
|
+
}
|
|
17774
|
+
const physical = physicalResolution(
|
|
17775
|
+
input.screenWidth,
|
|
17776
|
+
input.screenHeight,
|
|
17777
|
+
input.devicePixelRatio
|
|
17778
|
+
);
|
|
17779
|
+
return rules.some(
|
|
17780
|
+
(rule) => rule !== null && typeof rule === "object" && ruleMatches(rule, input, physical)
|
|
17781
|
+
);
|
|
17782
|
+
}
|
|
17783
|
+
function diagonalInchesFromDpi(dpi, physicalWidth, physicalHeight) {
|
|
17784
|
+
const shortPx = Math.min(physicalWidth, physicalHeight);
|
|
17785
|
+
const longPx = Math.max(physicalWidth, physicalHeight);
|
|
17786
|
+
if (!(shortPx > 0 && longPx > 0)) {
|
|
17787
|
+
return null;
|
|
17788
|
+
}
|
|
17789
|
+
let dpiX;
|
|
17790
|
+
let dpiY;
|
|
17791
|
+
if (typeof dpi === "number") {
|
|
17792
|
+
if (!(Number.isFinite(dpi) && dpi > 0)) {
|
|
17793
|
+
return null;
|
|
17794
|
+
}
|
|
17795
|
+
dpiX = dpi;
|
|
17796
|
+
dpiY = dpi;
|
|
17797
|
+
} else if (Array.isArray(dpi) && dpi.length >= 1) {
|
|
17798
|
+
const first = dpi[0];
|
|
17799
|
+
const second = dpi.length >= 2 ? dpi[1] : first;
|
|
17800
|
+
if (typeof first !== "number" || typeof second !== "number" || !(Number.isFinite(first) && first > 0) || !(Number.isFinite(second) && second > 0)) {
|
|
17801
|
+
return null;
|
|
17802
|
+
}
|
|
17803
|
+
dpiX = first;
|
|
17804
|
+
dpiY = second;
|
|
17805
|
+
} else {
|
|
17806
|
+
return null;
|
|
17807
|
+
}
|
|
17808
|
+
const widthIn = shortPx / dpiX;
|
|
17809
|
+
const heightIn = longPx / dpiY;
|
|
17810
|
+
const diagonal = Math.sqrt(widthIn * widthIn + heightIn * heightIn);
|
|
17811
|
+
if (!Number.isFinite(diagonal) || diagonal < SCREENSIZE_MIN || diagonal > SCREENSIZE_MAX) {
|
|
17812
|
+
return null;
|
|
17813
|
+
}
|
|
17814
|
+
return Math.round(diagonal * 10) / 10;
|
|
17815
|
+
}
|
|
17816
|
+
function matchDpdbDevice(document2, input) {
|
|
17817
|
+
const devices = document2.devices;
|
|
17818
|
+
if (!Array.isArray(devices)) {
|
|
17819
|
+
return null;
|
|
17820
|
+
}
|
|
17821
|
+
const physical = physicalResolution(
|
|
17822
|
+
input.screenWidth,
|
|
17823
|
+
input.screenHeight,
|
|
17824
|
+
input.devicePixelRatio
|
|
17825
|
+
);
|
|
17826
|
+
for (const device of devices) {
|
|
17827
|
+
if (!deviceMatches(device, input)) {
|
|
17828
|
+
continue;
|
|
17829
|
+
}
|
|
17830
|
+
if (device.dpi === void 0) {
|
|
17831
|
+
continue;
|
|
17832
|
+
}
|
|
17833
|
+
const screensizeInches = diagonalInchesFromDpi(
|
|
17834
|
+
device.dpi,
|
|
17835
|
+
physical[0],
|
|
17836
|
+
physical[1]
|
|
17837
|
+
);
|
|
17838
|
+
if (screensizeInches === null) {
|
|
17839
|
+
continue;
|
|
17840
|
+
}
|
|
17841
|
+
return { device, screensizeInches };
|
|
17842
|
+
}
|
|
17843
|
+
return null;
|
|
17844
|
+
}
|
|
17845
|
+
function readDpdbMatchInput(globalObject = globalThis) {
|
|
17846
|
+
const navigatorObject = globalObject.navigator;
|
|
17847
|
+
const screenObject = globalObject.screen;
|
|
17848
|
+
if (!navigatorObject || !screenObject) {
|
|
17849
|
+
return null;
|
|
17850
|
+
}
|
|
17851
|
+
const width = screenObject.width;
|
|
17852
|
+
const height = screenObject.height;
|
|
17853
|
+
if (typeof width !== "number" || typeof height !== "number" || !(width > 0 && height > 0)) {
|
|
17854
|
+
return null;
|
|
17855
|
+
}
|
|
17856
|
+
const dpr = typeof globalObject.devicePixelRatio === "number" ? globalObject.devicePixelRatio : 1;
|
|
17857
|
+
return {
|
|
17858
|
+
userAgent: navigatorObject.userAgent ?? "",
|
|
17859
|
+
screenWidth: width,
|
|
17860
|
+
screenHeight: height,
|
|
17861
|
+
devicePixelRatio: dpr
|
|
17862
|
+
};
|
|
17136
17863
|
}
|
|
17137
|
-
async function
|
|
17138
|
-
const mobile = isMobileVRDevice();
|
|
17139
|
-
const sensor = typeof window !== "undefined" && window.isSecureContext && typeof DeviceOrientationEvent !== "undefined";
|
|
17140
|
-
let webxr = false;
|
|
17864
|
+
async function fetchDpdbDocument(url) {
|
|
17141
17865
|
try {
|
|
17142
|
-
|
|
17866
|
+
const response = await fetch(url, {
|
|
17867
|
+
credentials: "omit",
|
|
17868
|
+
mode: "cors"
|
|
17869
|
+
});
|
|
17870
|
+
if (!response.ok) {
|
|
17871
|
+
return null;
|
|
17872
|
+
}
|
|
17873
|
+
const data = await response.json();
|
|
17874
|
+
if (data === null || typeof data !== "object" || !("devices" in data) || !Array.isArray(data.devices)) {
|
|
17875
|
+
return null;
|
|
17876
|
+
}
|
|
17877
|
+
return data;
|
|
17143
17878
|
} catch {
|
|
17144
|
-
|
|
17879
|
+
return null;
|
|
17145
17880
|
}
|
|
17146
|
-
|
|
17881
|
+
}
|
|
17882
|
+
function loadDpdbDocument(url) {
|
|
17883
|
+
const existing = cache.get(url);
|
|
17884
|
+
if (existing) {
|
|
17885
|
+
return existing;
|
|
17886
|
+
}
|
|
17887
|
+
const pending = fetchDpdbDocument(url).then((document2) => {
|
|
17888
|
+
if (!document2) {
|
|
17889
|
+
cache.delete(url);
|
|
17890
|
+
}
|
|
17891
|
+
return document2;
|
|
17892
|
+
});
|
|
17893
|
+
cache.set(url, pending);
|
|
17894
|
+
return pending;
|
|
17895
|
+
}
|
|
17896
|
+
async function resolveScreensizeFromDpdb(databaseUrl, input = readDpdbMatchInput()) {
|
|
17897
|
+
const url = normalizeDatabaseUrl(databaseUrl);
|
|
17898
|
+
if (!url || !input) {
|
|
17899
|
+
return null;
|
|
17900
|
+
}
|
|
17901
|
+
const document2 = await loadDpdbDocument(url);
|
|
17902
|
+
if (!document2) {
|
|
17903
|
+
return null;
|
|
17904
|
+
}
|
|
17905
|
+
return matchDpdbDevice(document2, input)?.screensizeInches ?? null;
|
|
17147
17906
|
}
|
|
17148
17907
|
|
|
17149
17908
|
// src/webvr/presentation.ts
|
|
@@ -17303,7 +18062,7 @@ function subscribeWebVRPresentationExit(element, onExit) {
|
|
|
17303
18062
|
|
|
17304
18063
|
// src/webvr/reticle.tsx
|
|
17305
18064
|
import { useFrame as useFrame21, useThree as useThree26 } from "@react-three/fiber";
|
|
17306
|
-
import { useRef as
|
|
18065
|
+
import { useRef as useRef37 } from "react";
|
|
17307
18066
|
import {
|
|
17308
18067
|
DoubleSide as DoubleSide6,
|
|
17309
18068
|
Raycaster as Raycaster4,
|
|
@@ -17396,13 +18155,13 @@ function WebVRReticle({
|
|
|
17396
18155
|
scale = RETICLE_SCALE,
|
|
17397
18156
|
visible
|
|
17398
18157
|
}) {
|
|
17399
|
-
const groupRef =
|
|
17400
|
-
const ringMeshRef =
|
|
17401
|
-
const directionRef =
|
|
17402
|
-
const raycasterRef =
|
|
17403
|
-
const hoveredRef =
|
|
17404
|
-
const dwellRef =
|
|
17405
|
-
const clickedRef =
|
|
18158
|
+
const groupRef = useRef37(null);
|
|
18159
|
+
const ringMeshRef = useRef37(null);
|
|
18160
|
+
const directionRef = useRef37(new Vector321());
|
|
18161
|
+
const raycasterRef = useRef37(new Raycaster4());
|
|
18162
|
+
const hoveredRef = useRef37(null);
|
|
18163
|
+
const dwellRef = useRef37(0);
|
|
18164
|
+
const clickedRef = useRef37(false);
|
|
17406
18165
|
const { camera, gl, scene } = useThree26();
|
|
17407
18166
|
useFrame21((_, deltaSeconds) => {
|
|
17408
18167
|
const group = groupRef.current;
|
|
@@ -17565,7 +18324,7 @@ function WebVRReticle({
|
|
|
17565
18324
|
|
|
17566
18325
|
// src/webvr/stereo.tsx
|
|
17567
18326
|
import { useFrame as useFrame22, useThree as useThree27 } from "@react-three/fiber";
|
|
17568
|
-
import { useContext as useContext26, useEffect as useEffect37, useMemo as useMemo25, useRef as
|
|
18327
|
+
import { useContext as useContext26, useEffect as useEffect37, useMemo as useMemo25, useRef as useRef38 } from "react";
|
|
17569
18328
|
import {
|
|
17570
18329
|
Matrix4 as Matrix47,
|
|
17571
18330
|
Mesh as Mesh6,
|
|
@@ -17580,6 +18339,40 @@ import {
|
|
|
17580
18339
|
WebGLRenderTarget as WebGLRenderTarget2
|
|
17581
18340
|
} from "three";
|
|
17582
18341
|
|
|
18342
|
+
// src/webvr/lens-center.ts
|
|
18343
|
+
function physicalScreenFromDiagonal(screensizeInches, displayAspect) {
|
|
18344
|
+
if (!(Number.isFinite(screensizeInches) && screensizeInches > 0 && Number.isFinite(displayAspect) && displayAspect > 0)) {
|
|
18345
|
+
return null;
|
|
18346
|
+
}
|
|
18347
|
+
const diagonalMm = screensizeInches * 25.4;
|
|
18348
|
+
const heightMm = diagonalMm / Math.sqrt(displayAspect * displayAspect + 1);
|
|
18349
|
+
const widthMm = heightMm * displayAspect;
|
|
18350
|
+
if (!(heightMm > 0 && widthMm > 0)) {
|
|
18351
|
+
return null;
|
|
18352
|
+
}
|
|
18353
|
+
return { widthMm, heightMm };
|
|
18354
|
+
}
|
|
18355
|
+
function computeStereoLensCenters(profile, screensize, displayAspect) {
|
|
18356
|
+
const zero = { left: { x: 0, y: 0 }, right: { x: 0, y: 0 } };
|
|
18357
|
+
if (screensize === "auto") {
|
|
18358
|
+
return zero;
|
|
18359
|
+
}
|
|
18360
|
+
const screen = physicalScreenFromDiagonal(screensize, displayAspect);
|
|
18361
|
+
if (!screen) {
|
|
18362
|
+
return zero;
|
|
18363
|
+
}
|
|
18364
|
+
const halfEyeWidthMm = screen.widthMm / 4;
|
|
18365
|
+
const ipdMm = Number.isFinite(profile.ipdMm) ? profile.ipdMm : 60;
|
|
18366
|
+
const x = halfEyeWidthMm > 0 ? (halfEyeWidthMm - ipdMm / 2) / halfEyeWidthMm : 0;
|
|
18367
|
+
const trayDistanceMm = typeof profile.trayDistanceMm === "number" && Number.isFinite(profile.trayDistanceMm) && profile.trayDistanceMm > 0 ? profile.trayDistanceMm : 0;
|
|
18368
|
+
const y = trayDistanceMm > 0 && screen.heightMm > 0 ? 2 * trayDistanceMm / screen.heightMm - 1 : 0;
|
|
18369
|
+
const clampUnit = (value) => Math.max(-1, Math.min(1, Number.isFinite(value) ? value : 0));
|
|
18370
|
+
return {
|
|
18371
|
+
left: { x: clampUnit(x), y: clampUnit(y) },
|
|
18372
|
+
right: { x: clampUnit(-x), y: clampUnit(y) }
|
|
18373
|
+
};
|
|
18374
|
+
}
|
|
18375
|
+
|
|
17583
18376
|
// src/webvr/stereo-disparity.ts
|
|
17584
18377
|
var WEBVR_PANORAMA_VIRTUAL_DISTANCE_M = 2;
|
|
17585
18378
|
function panoramaStereoHalfAngle(ipdMm, virtualDistanceM = WEBVR_PANORAMA_VIRTUAL_DISTANCE_M) {
|
|
@@ -17595,19 +18388,32 @@ function panoramaStereoToeInYaw(eye, halfAngleRad) {
|
|
|
17595
18388
|
}
|
|
17596
18389
|
|
|
17597
18390
|
// src/webvr/stereo-layout.ts
|
|
17598
|
-
|
|
18391
|
+
var DEFAULT_WEBVR_OVERSAMPLING = 1;
|
|
18392
|
+
var MIN_WEBVR_OVERSAMPLING = 0.5;
|
|
18393
|
+
var MAX_WEBVR_OVERSAMPLING = 2;
|
|
18394
|
+
function clampWebVROversampling(value) {
|
|
18395
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
18396
|
+
return DEFAULT_WEBVR_OVERSAMPLING;
|
|
18397
|
+
}
|
|
18398
|
+
return Math.max(
|
|
18399
|
+
MIN_WEBVR_OVERSAMPLING,
|
|
18400
|
+
Math.min(MAX_WEBVR_OVERSAMPLING, value)
|
|
18401
|
+
);
|
|
18402
|
+
}
|
|
18403
|
+
function computeStereoLayout(logicalWidth, logicalHeight, pixelRatio, oversampling = DEFAULT_WEBVR_OVERSAMPLING) {
|
|
17599
18404
|
const fullWidth = Math.max(2, Math.floor(logicalWidth));
|
|
17600
18405
|
const fullHeight = Math.max(1, Math.floor(logicalHeight));
|
|
17601
18406
|
const leftWidth = Math.max(1, Math.floor(fullWidth / 2));
|
|
17602
18407
|
const rightWidth = Math.max(1, fullWidth - leftWidth);
|
|
17603
18408
|
const ratio = Number.isFinite(pixelRatio) && pixelRatio > 0 ? pixelRatio : 1;
|
|
18409
|
+
const scale = clampWebVROversampling(oversampling);
|
|
17604
18410
|
return {
|
|
17605
18411
|
fullWidth,
|
|
17606
18412
|
fullHeight,
|
|
17607
18413
|
left: { width: leftWidth, height: fullHeight, offsetX: 0 },
|
|
17608
18414
|
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)),
|
|
18415
|
+
renderTargetWidth: Math.max(1, Math.floor(leftWidth * ratio * scale)),
|
|
18416
|
+
renderTargetHeight: Math.max(1, Math.floor(fullHeight * ratio * scale)),
|
|
17611
18417
|
stereoAspect: leftWidth / fullWidth
|
|
17612
18418
|
};
|
|
17613
18419
|
}
|
|
@@ -17624,12 +18430,13 @@ void main() {
|
|
|
17624
18430
|
var fragmentShader = `
|
|
17625
18431
|
uniform sampler2D sourceTexture;
|
|
17626
18432
|
uniform vec2 distortion;
|
|
18433
|
+
uniform vec2 lensCenter;
|
|
17627
18434
|
varying vec2 vUv;
|
|
17628
18435
|
void main() {
|
|
17629
|
-
vec2 centered = vUv * 2.0 - 1.0;
|
|
18436
|
+
vec2 centered = vUv * 2.0 - 1.0 - lensCenter;
|
|
17630
18437
|
float radius2 = dot(centered, centered);
|
|
17631
18438
|
float scale = 1.0 + distortion.x * radius2 + distortion.y * radius2 * radius2;
|
|
17632
|
-
vec2 sourceUv = centered * scale * 0.5 + 0.5;
|
|
18439
|
+
vec2 sourceUv = (centered * scale + lensCenter) * 0.5 + 0.5;
|
|
17633
18440
|
if (sourceUv.x < 0.0 || sourceUv.x > 1.0 || sourceUv.y < 0.0 || sourceUv.y > 1.0) {
|
|
17634
18441
|
gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
|
|
17635
18442
|
} else {
|
|
@@ -17649,6 +18456,7 @@ function createDistortionResources() {
|
|
|
17649
18456
|
fragmentShader,
|
|
17650
18457
|
uniforms: {
|
|
17651
18458
|
distortion: { value: new Vector28() },
|
|
18459
|
+
lensCenter: { value: new Vector28() },
|
|
17652
18460
|
sourceTexture: { value: target.texture }
|
|
17653
18461
|
},
|
|
17654
18462
|
vertexShader
|
|
@@ -17665,12 +18473,27 @@ function createDistortionResources() {
|
|
|
17665
18473
|
target
|
|
17666
18474
|
};
|
|
17667
18475
|
}
|
|
17668
|
-
function
|
|
18476
|
+
function applyEyeViewOffset(eyeCamera, eye, center) {
|
|
18477
|
+
const fullWidth = eye.width;
|
|
18478
|
+
const fullHeight = eye.height;
|
|
18479
|
+
const offsetX = ((center.x + 1) / 2 - 0.5) * fullWidth;
|
|
18480
|
+
const offsetY = (0.5 - (center.y + 1) / 2) * fullHeight;
|
|
18481
|
+
eyeCamera.setViewOffset(
|
|
18482
|
+
fullWidth,
|
|
18483
|
+
fullHeight,
|
|
18484
|
+
offsetX,
|
|
18485
|
+
offsetY,
|
|
18486
|
+
fullWidth,
|
|
18487
|
+
fullHeight
|
|
18488
|
+
);
|
|
18489
|
+
}
|
|
18490
|
+
function syncStereoCameras(stereo, camera, profile, screensize, oversampling, size, gl) {
|
|
17669
18491
|
gl.getSize(size);
|
|
17670
18492
|
const layout = computeStereoLayout(
|
|
17671
18493
|
size.x,
|
|
17672
18494
|
size.y,
|
|
17673
|
-
gl.getPixelRatio()
|
|
18495
|
+
gl.getPixelRatio(),
|
|
18496
|
+
oversampling
|
|
17674
18497
|
);
|
|
17675
18498
|
const screenToLensMm = profile.screenToLensMm ?? 42;
|
|
17676
18499
|
const displayAspect = layout.fullWidth / layout.fullHeight;
|
|
@@ -17689,34 +18512,40 @@ function syncStereoCameras(stereo, camera, profile, screensize, size, gl) {
|
|
|
17689
18512
|
TOE_IN.makeRotationY(panoramaStereoToeInYaw("right", halfAngle));
|
|
17690
18513
|
stereo.cameraR.matrix.multiply(TOE_IN);
|
|
17691
18514
|
stereo.cameraR.matrixWorldNeedsUpdate = true;
|
|
18515
|
+
const centers = computeStereoLensCenters(profile, screensize, displayAspect);
|
|
18516
|
+
applyEyeViewOffset(stereo.cameraL, layout.left, centers.left);
|
|
18517
|
+
applyEyeViewOffset(stereo.cameraR, layout.right, centers.right);
|
|
17692
18518
|
stereo.cameraL.updateMatrixWorld(true);
|
|
17693
18519
|
stereo.cameraR.updateMatrixWorld(true);
|
|
17694
|
-
return layout;
|
|
18520
|
+
return { layout, centers };
|
|
17695
18521
|
}
|
|
17696
18522
|
function WebVRStereoRenderer({
|
|
17697
18523
|
mode,
|
|
18524
|
+
oversampling = 1,
|
|
17698
18525
|
profile,
|
|
17699
18526
|
screensize
|
|
17700
18527
|
}) {
|
|
17701
18528
|
const { camera, gl } = useThree27();
|
|
17702
18529
|
const runtime = useContext26(WebVRRuntimeContext);
|
|
17703
|
-
const fallbackStereoRef =
|
|
18530
|
+
const fallbackStereoRef = useRef38(null);
|
|
17704
18531
|
if (!fallbackStereoRef.current) {
|
|
17705
18532
|
fallbackStereoRef.current = new StereoCamera2();
|
|
17706
18533
|
}
|
|
17707
18534
|
const stereo = runtime?.stereoView.stereo ?? fallbackStereoRef.current;
|
|
17708
|
-
const stereoRef =
|
|
18535
|
+
const stereoRef = useRef38(stereo);
|
|
17709
18536
|
stereoRef.current = stereo;
|
|
17710
18537
|
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 =
|
|
18538
|
+
const sizeRef = useRef38(new Vector28());
|
|
18539
|
+
const viewportRef = useRef38(new Vector42());
|
|
18540
|
+
const scissorRef = useRef38(new Vector42());
|
|
18541
|
+
const originalFovRef = useRef38(null);
|
|
18542
|
+
const stereoActiveRef = useRef38(false);
|
|
18543
|
+
const profileRef = useRef38(profile);
|
|
18544
|
+
const screensizeRef = useRef38(screensize);
|
|
18545
|
+
const oversamplingRef = useRef38(clampWebVROversampling(oversampling));
|
|
17718
18546
|
profileRef.current = profile;
|
|
17719
18547
|
screensizeRef.current = screensize;
|
|
18548
|
+
oversamplingRef.current = clampWebVROversampling(oversampling);
|
|
17720
18549
|
useEffect37(
|
|
17721
18550
|
() => () => {
|
|
17722
18551
|
resources.geometry.dispose();
|
|
@@ -17737,11 +18566,12 @@ function WebVRStereoRenderer({
|
|
|
17737
18566
|
if (originalFovRef.current === null) {
|
|
17738
18567
|
originalFovRef.current = cameraToRender.fov;
|
|
17739
18568
|
}
|
|
17740
|
-
const layout = syncStereoCameras(
|
|
18569
|
+
const { layout, centers } = syncStereoCameras(
|
|
17741
18570
|
stereoRef.current,
|
|
17742
18571
|
cameraToRender,
|
|
17743
18572
|
currentProfile,
|
|
17744
18573
|
currentScreensize,
|
|
18574
|
+
oversamplingRef.current,
|
|
17745
18575
|
sizeRef.current,
|
|
17746
18576
|
gl
|
|
17747
18577
|
);
|
|
@@ -17753,7 +18583,7 @@ function WebVRStereoRenderer({
|
|
|
17753
18583
|
gl.getScissor(scissorRef.current);
|
|
17754
18584
|
gl.autoClear = true;
|
|
17755
18585
|
gl.setScissorTest(true);
|
|
17756
|
-
const renderEye = (eyeCamera, eye) => {
|
|
18586
|
+
const renderEye = (eyeCamera, eye, center) => {
|
|
17757
18587
|
if (hasDistortion) {
|
|
17758
18588
|
if (resources.target.width !== layout.renderTargetWidth || resources.target.height !== layout.renderTargetHeight) {
|
|
17759
18589
|
resources.target.setSize(
|
|
@@ -17770,6 +18600,7 @@ function WebVRStereoRenderer({
|
|
|
17770
18600
|
currentProfile.k1,
|
|
17771
18601
|
currentProfile.k2
|
|
17772
18602
|
);
|
|
18603
|
+
resources.material.uniforms.lensCenter?.value.set(center.x, center.y);
|
|
17773
18604
|
originalRender(resources.scene, resources.camera);
|
|
17774
18605
|
return;
|
|
17775
18606
|
}
|
|
@@ -17778,8 +18609,8 @@ function WebVRStereoRenderer({
|
|
|
17778
18609
|
gl.setScissor(eye.offsetX, 0, eye.width, eye.height);
|
|
17779
18610
|
originalRender(sceneToRender, eyeCamera);
|
|
17780
18611
|
};
|
|
17781
|
-
renderEye(stereoRef.current.cameraL, layout.left);
|
|
17782
|
-
renderEye(stereoRef.current.cameraR, layout.right);
|
|
18612
|
+
renderEye(stereoRef.current.cameraL, layout.left, centers.left);
|
|
18613
|
+
renderEye(stereoRef.current.cameraR, layout.right, centers.right);
|
|
17783
18614
|
gl.setRenderTarget(previousTarget);
|
|
17784
18615
|
gl.setViewport(viewportRef.current);
|
|
17785
18616
|
gl.setScissor(scissorRef.current);
|
|
@@ -17810,6 +18641,7 @@ function WebVRStereoRenderer({
|
|
|
17810
18641
|
camera,
|
|
17811
18642
|
profileRef.current,
|
|
17812
18643
|
screensizeRef.current,
|
|
18644
|
+
oversamplingRef.current,
|
|
17813
18645
|
sizeRef.current,
|
|
17814
18646
|
gl
|
|
17815
18647
|
);
|
|
@@ -17825,7 +18657,7 @@ function WebVRStereoRenderer({
|
|
|
17825
18657
|
}
|
|
17826
18658
|
|
|
17827
18659
|
// src/webvr/pointerlock.ts
|
|
17828
|
-
import { useEffect as useEffect38, useRef as
|
|
18660
|
+
import { useEffect as useEffect38, useRef as useRef39 } from "react";
|
|
17829
18661
|
var POINTER_LOCK_CURSOR_ID = "webvr:pointerlock";
|
|
17830
18662
|
async function requestWebVRPointerLock(element) {
|
|
17831
18663
|
if (typeof document === "undefined") {
|
|
@@ -17858,8 +18690,8 @@ function exitWebVRPointerLock(element) {
|
|
|
17858
18690
|
}
|
|
17859
18691
|
function useWebVRPointerLock(enabled, element) {
|
|
17860
18692
|
const cursor = usePanoCursor();
|
|
17861
|
-
const cursorRef =
|
|
17862
|
-
const enabledRef =
|
|
18693
|
+
const cursorRef = useRef39(cursor);
|
|
18694
|
+
const enabledRef = useRef39(enabled);
|
|
17863
18695
|
cursorRef.current = cursor;
|
|
17864
18696
|
enabledRef.current = enabled;
|
|
17865
18697
|
useEffect38(() => {
|
|
@@ -18039,8 +18871,44 @@ function useWebVRWakeLock(enabled) {
|
|
|
18039
18871
|
}, [enabled]);
|
|
18040
18872
|
}
|
|
18041
18873
|
|
|
18874
|
+
// src/webvr/xr-quality.ts
|
|
18875
|
+
function clampWebVRFoveation(value) {
|
|
18876
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
18877
|
+
return void 0;
|
|
18878
|
+
}
|
|
18879
|
+
return Math.max(0, Math.min(1, value));
|
|
18880
|
+
}
|
|
18881
|
+
function resolveWebVRFrameRateOption(frameRate) {
|
|
18882
|
+
if (frameRate === void 0) {
|
|
18883
|
+
return void 0;
|
|
18884
|
+
}
|
|
18885
|
+
if (frameRate === "low" || frameRate === "mid" || frameRate === "high") {
|
|
18886
|
+
return frameRate;
|
|
18887
|
+
}
|
|
18888
|
+
if (typeof frameRate !== "number" || !Number.isFinite(frameRate)) {
|
|
18889
|
+
return void 0;
|
|
18890
|
+
}
|
|
18891
|
+
const target = frameRate;
|
|
18892
|
+
return (rates) => {
|
|
18893
|
+
if (rates.length === 0) {
|
|
18894
|
+
return false;
|
|
18895
|
+
}
|
|
18896
|
+
let best = rates[0];
|
|
18897
|
+
let bestDelta = Math.abs(best - target);
|
|
18898
|
+
for (let i = 1; i < rates.length; i += 1) {
|
|
18899
|
+
const candidate = rates[i];
|
|
18900
|
+
const delta = Math.abs(candidate - target);
|
|
18901
|
+
if (delta < bestDelta) {
|
|
18902
|
+
best = candidate;
|
|
18903
|
+
bestDelta = delta;
|
|
18904
|
+
}
|
|
18905
|
+
}
|
|
18906
|
+
return best;
|
|
18907
|
+
};
|
|
18908
|
+
}
|
|
18909
|
+
|
|
18042
18910
|
// src/webvr/webvr.tsx
|
|
18043
|
-
import { Fragment as
|
|
18911
|
+
import { Fragment as Fragment8, jsx as jsx40, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
18044
18912
|
function initializeSettings(screensize, profile) {
|
|
18045
18913
|
const stored = loadWebVRSettings();
|
|
18046
18914
|
return {
|
|
@@ -18057,7 +18925,15 @@ var WebVR = forwardRef4(function WebVR2({
|
|
|
18057
18925
|
desktopSupport = false,
|
|
18058
18926
|
fakeSupport = true,
|
|
18059
18927
|
screensize,
|
|
18928
|
+
databaseUrl,
|
|
18060
18929
|
profile,
|
|
18930
|
+
absolute = false,
|
|
18931
|
+
north = 0,
|
|
18932
|
+
friction = 0,
|
|
18933
|
+
touchSupport = false,
|
|
18934
|
+
oversampling = 1,
|
|
18935
|
+
foveation,
|
|
18936
|
+
frameRate,
|
|
18061
18937
|
cursor = true,
|
|
18062
18938
|
cursorDwellMs = DEFAULT_WEBVR_CURSOR_DWELL_MS,
|
|
18063
18939
|
wakelock = true,
|
|
@@ -18073,20 +18949,36 @@ var WebVR = forwardRef4(function WebVR2({
|
|
|
18073
18949
|
const controlsRef = useContext27(PanoramaViewContext);
|
|
18074
18950
|
const eventBus = useContext27(PanoEventBusContext);
|
|
18075
18951
|
const gl = useThree28((state) => state.gl);
|
|
18076
|
-
const gyroRef =
|
|
18077
|
-
const capabilitiesRef =
|
|
18952
|
+
const gyroRef = useRef40(null);
|
|
18953
|
+
const capabilitiesRef = useRef40({
|
|
18078
18954
|
mobile: false,
|
|
18079
18955
|
sensor: false,
|
|
18080
18956
|
webxr: false
|
|
18081
18957
|
});
|
|
18082
|
-
const availableRef =
|
|
18083
|
-
const modeRef =
|
|
18084
|
-
const webXRSessionRef =
|
|
18958
|
+
const availableRef = useRef40(false);
|
|
18959
|
+
const modeRef = useRef40(null);
|
|
18960
|
+
const webXRSessionRef = useRef40(null);
|
|
18961
|
+
const dpdbRequestIdRef = useRef40(0);
|
|
18962
|
+
const databaseUrlRef = useRef40(databaseUrl);
|
|
18963
|
+
databaseUrlRef.current = databaseUrl;
|
|
18964
|
+
const oversamplingRef = useRef40(clampWebVROversampling(oversampling));
|
|
18965
|
+
oversamplingRef.current = clampWebVROversampling(oversampling);
|
|
18966
|
+
const foveationRef = useRef40(clampWebVRFoveation(foveation));
|
|
18967
|
+
foveationRef.current = clampWebVRFoveation(foveation);
|
|
18968
|
+
const frameRateRef = useRef40(frameRate);
|
|
18969
|
+
frameRateRef.current = frameRate;
|
|
18970
|
+
const screensizePropRef = useRef40(screensize);
|
|
18971
|
+
screensizePropRef.current = screensize;
|
|
18972
|
+
const profilePropRef = useRef40(profile);
|
|
18973
|
+
profilePropRef.current = profile;
|
|
18085
18974
|
const [mode, setMode] = useState24(null);
|
|
18086
18975
|
const [settings, setSettings] = useState24(
|
|
18087
18976
|
() => initializeSettings(screensize, profile)
|
|
18088
18977
|
);
|
|
18089
|
-
const
|
|
18978
|
+
const [detectedScreensize, setDetectedScreensize] = useState24(
|
|
18979
|
+
null
|
|
18980
|
+
);
|
|
18981
|
+
const callbacksRef = useRef40({
|
|
18090
18982
|
onAvailable,
|
|
18091
18983
|
onDenied,
|
|
18092
18984
|
onEnterVR,
|
|
@@ -18110,18 +19002,44 @@ var WebVR = forwardRef4(function WebVR2({
|
|
|
18110
19002
|
() => resolveWebVRProfile(profile, settings.profileId),
|
|
18111
19003
|
[profile, settings.profileId]
|
|
18112
19004
|
);
|
|
18113
|
-
const
|
|
19005
|
+
const effectiveScreensize = settings.screensize === "auto" ? detectedScreensize ?? "auto" : settings.screensize;
|
|
19006
|
+
const resolvedOversampling = clampWebVROversampling(oversampling);
|
|
19007
|
+
const reportDenied = useCallback11(
|
|
18114
19008
|
(error) => {
|
|
18115
19009
|
eventBus.emit("vrdenied", { error });
|
|
18116
19010
|
callbacksRef.current.onDenied?.(error);
|
|
18117
19011
|
},
|
|
18118
19012
|
[eventBus]
|
|
18119
19013
|
);
|
|
18120
|
-
const reportUnknownDevice =
|
|
19014
|
+
const reportUnknownDevice = useCallback11(() => {
|
|
18121
19015
|
eventBus.emit("vrunknowndevice", void 0);
|
|
18122
19016
|
callbacksRef.current.onUnknownDevice?.();
|
|
18123
19017
|
}, [eventBus]);
|
|
18124
|
-
const
|
|
19018
|
+
const clearDetectedScreensize = useCallback11(() => {
|
|
19019
|
+
dpdbRequestIdRef.current += 1;
|
|
19020
|
+
setDetectedScreensize(null);
|
|
19021
|
+
updateWebVRHost(host, { detectedScreensize: null });
|
|
19022
|
+
}, [host]);
|
|
19023
|
+
const resolveAutoScreensize = useCallback11(() => {
|
|
19024
|
+
const requestId = ++dpdbRequestIdRef.current;
|
|
19025
|
+
const url = normalizeDatabaseUrl(databaseUrlRef.current);
|
|
19026
|
+
if (!url) {
|
|
19027
|
+
reportUnknownDevice();
|
|
19028
|
+
return;
|
|
19029
|
+
}
|
|
19030
|
+
void resolveScreensizeFromDpdb(url).then((inches) => {
|
|
19031
|
+
if (requestId !== dpdbRequestIdRef.current) {
|
|
19032
|
+
return;
|
|
19033
|
+
}
|
|
19034
|
+
if (inches === null) {
|
|
19035
|
+
reportUnknownDevice();
|
|
19036
|
+
return;
|
|
19037
|
+
}
|
|
19038
|
+
setDetectedScreensize(inches);
|
|
19039
|
+
updateWebVRHost(host, { detectedScreensize: inches });
|
|
19040
|
+
});
|
|
19041
|
+
}, [host, reportUnknownDevice]);
|
|
19042
|
+
const activate = useCallback11(
|
|
18125
19043
|
(nextMode) => {
|
|
18126
19044
|
if (modeRef.current === nextMode) {
|
|
18127
19045
|
return;
|
|
@@ -18136,7 +19054,7 @@ var WebVR = forwardRef4(function WebVR2({
|
|
|
18136
19054
|
},
|
|
18137
19055
|
[controlsRef, eventBus]
|
|
18138
19056
|
);
|
|
18139
|
-
const deactivate =
|
|
19057
|
+
const deactivate = useCallback11(
|
|
18140
19058
|
(expectedMode) => {
|
|
18141
19059
|
const previousMode = modeRef.current;
|
|
18142
19060
|
if (!previousMode || expectedMode && previousMode !== expectedMode) {
|
|
@@ -18144,6 +19062,7 @@ var WebVR = forwardRef4(function WebVR2({
|
|
|
18144
19062
|
}
|
|
18145
19063
|
modeRef.current = null;
|
|
18146
19064
|
setMode(null);
|
|
19065
|
+
clearDetectedScreensize();
|
|
18147
19066
|
if (previousMode === "fake") {
|
|
18148
19067
|
controlsRef.current?.setGyroActive(false);
|
|
18149
19068
|
}
|
|
@@ -18151,24 +19070,42 @@ var WebVR = forwardRef4(function WebVR2({
|
|
|
18151
19070
|
eventBus.emit("vrexit", { mode: previousMode });
|
|
18152
19071
|
callbacksRef.current.onExitVR?.(previousMode);
|
|
18153
19072
|
},
|
|
18154
|
-
[controlsRef, eventBus, gl.domElement]
|
|
19073
|
+
[clearDetectedScreensize, controlsRef, eventBus, gl.domElement]
|
|
18155
19074
|
);
|
|
18156
|
-
const requestPermission =
|
|
19075
|
+
const requestPermission = useCallback11(async () => {
|
|
18157
19076
|
return await gyroRef.current?.requestPermission() ?? false;
|
|
18158
19077
|
}, []);
|
|
18159
|
-
const
|
|
19078
|
+
const applyWebXRQuality = useCallback11(() => {
|
|
19079
|
+
const scale = oversamplingRef.current;
|
|
19080
|
+
if (typeof gl.xr.setFramebufferScaleFactor === "function") {
|
|
19081
|
+
gl.xr.setFramebufferScaleFactor(scale);
|
|
19082
|
+
}
|
|
19083
|
+
const nextFoveation = foveationRef.current;
|
|
19084
|
+
if (nextFoveation !== void 0 && typeof gl.xr.setFoveation === "function") {
|
|
19085
|
+
gl.xr.setFoveation(nextFoveation);
|
|
19086
|
+
}
|
|
19087
|
+
const frameRateOption = resolveWebVRFrameRateOption(frameRateRef.current);
|
|
19088
|
+
if (frameRateOption !== void 0) {
|
|
19089
|
+
xrStore.setFrameRate(frameRateOption);
|
|
19090
|
+
}
|
|
19091
|
+
}, [gl.xr, xrStore]);
|
|
19092
|
+
const enterVR = useCallback11(async () => {
|
|
18160
19093
|
if (modeRef.current) {
|
|
18161
19094
|
return true;
|
|
18162
19095
|
}
|
|
18163
19096
|
const capabilities = capabilitiesRef.current;
|
|
18164
19097
|
if (capabilities.webxr) {
|
|
18165
19098
|
try {
|
|
19099
|
+
if (typeof gl.xr.setFramebufferScaleFactor === "function") {
|
|
19100
|
+
gl.xr.setFramebufferScaleFactor(oversamplingRef.current);
|
|
19101
|
+
}
|
|
18166
19102
|
await xrStore.enterVR();
|
|
18167
19103
|
const session2 = xrStore.getState().session;
|
|
18168
19104
|
if (!session2) {
|
|
18169
19105
|
throw new Error("The WebXR session did not start.");
|
|
18170
19106
|
}
|
|
18171
19107
|
webXRSessionRef.current = session2;
|
|
19108
|
+
applyWebXRQuality();
|
|
18172
19109
|
session2.addEventListener(
|
|
18173
19110
|
"end",
|
|
18174
19111
|
() => {
|
|
@@ -18198,10 +19135,10 @@ var WebVR = forwardRef4(function WebVR2({
|
|
|
18198
19135
|
reportDenied();
|
|
18199
19136
|
return false;
|
|
18200
19137
|
}
|
|
19138
|
+
activate("mobilevr");
|
|
18201
19139
|
if (settings.screensize === "auto") {
|
|
18202
|
-
|
|
19140
|
+
resolveAutoScreensize();
|
|
18203
19141
|
}
|
|
18204
|
-
activate("mobilevr");
|
|
18205
19142
|
return true;
|
|
18206
19143
|
}
|
|
18207
19144
|
if (fakeSupport) {
|
|
@@ -18220,21 +19157,23 @@ var WebVR = forwardRef4(function WebVR2({
|
|
|
18220
19157
|
return false;
|
|
18221
19158
|
}, [
|
|
18222
19159
|
activate,
|
|
19160
|
+
applyWebXRQuality,
|
|
18223
19161
|
deactivate,
|
|
18224
19162
|
desktopSupport,
|
|
18225
19163
|
eventBus,
|
|
18226
19164
|
fakeSupport,
|
|
18227
19165
|
gl.domElement,
|
|
19166
|
+
gl.xr,
|
|
18228
19167
|
mobileVr,
|
|
18229
19168
|
mousePointerLock,
|
|
18230
19169
|
reportDenied,
|
|
18231
|
-
reportUnknownDevice,
|
|
18232
19170
|
requestPermission,
|
|
19171
|
+
resolveAutoScreensize,
|
|
18233
19172
|
settings.screensize,
|
|
18234
19173
|
wakelock,
|
|
18235
19174
|
xrStore
|
|
18236
19175
|
]);
|
|
18237
|
-
const exitVR =
|
|
19176
|
+
const exitVR = useCallback11(async () => {
|
|
18238
19177
|
if (modeRef.current === "webxr") {
|
|
18239
19178
|
const session2 = webXRSessionRef.current ?? xrStore.getState().session ?? null;
|
|
18240
19179
|
if (session2) {
|
|
@@ -18247,21 +19186,52 @@ var WebVR = forwardRef4(function WebVR2({
|
|
|
18247
19186
|
deactivate();
|
|
18248
19187
|
leaveWebVRPresentation();
|
|
18249
19188
|
}, [deactivate, xrStore]);
|
|
18250
|
-
const toggleVR =
|
|
19189
|
+
const toggleVR = useCallback11(async () => {
|
|
18251
19190
|
if (modeRef.current) {
|
|
18252
19191
|
await exitVR();
|
|
18253
19192
|
return false;
|
|
18254
19193
|
}
|
|
18255
19194
|
return enterVR();
|
|
18256
19195
|
}, [enterVR, exitVR]);
|
|
18257
|
-
const updateSettings =
|
|
18258
|
-
|
|
18259
|
-
|
|
18260
|
-
|
|
18261
|
-
|
|
18262
|
-
|
|
18263
|
-
|
|
18264
|
-
|
|
19196
|
+
const updateSettings = useCallback11(
|
|
19197
|
+
(next) => {
|
|
19198
|
+
const normalized = {
|
|
19199
|
+
profileId: next.profileId,
|
|
19200
|
+
screensize: next.screensize === "auto" ? "auto" : Math.round(Math.max(3, Math.min(20, next.screensize)) * 10) / 10
|
|
19201
|
+
};
|
|
19202
|
+
setSettings(normalized);
|
|
19203
|
+
saveWebVRSettings(normalized);
|
|
19204
|
+
if (normalized.screensize === "auto") {
|
|
19205
|
+
if (modeRef.current === "mobilevr") {
|
|
19206
|
+
setDetectedScreensize(null);
|
|
19207
|
+
updateWebVRHost(host, { detectedScreensize: null });
|
|
19208
|
+
resolveAutoScreensize();
|
|
19209
|
+
}
|
|
19210
|
+
} else {
|
|
19211
|
+
clearDetectedScreensize();
|
|
19212
|
+
}
|
|
19213
|
+
},
|
|
19214
|
+
[clearDetectedScreensize, host, resolveAutoScreensize]
|
|
19215
|
+
);
|
|
19216
|
+
const resetSettings = useCallback11(() => {
|
|
19217
|
+
clearWebVRSettings();
|
|
19218
|
+
const next = resolveInitialWebVRSettings(
|
|
19219
|
+
screensizePropRef.current,
|
|
19220
|
+
profilePropRef.current
|
|
19221
|
+
);
|
|
19222
|
+
setSettings(next);
|
|
19223
|
+
if (next.screensize === "auto") {
|
|
19224
|
+
if (modeRef.current === "mobilevr") {
|
|
19225
|
+
setDetectedScreensize(null);
|
|
19226
|
+
updateWebVRHost(host, { detectedScreensize: null });
|
|
19227
|
+
resolveAutoScreensize();
|
|
19228
|
+
} else {
|
|
19229
|
+
clearDetectedScreensize();
|
|
19230
|
+
}
|
|
19231
|
+
} else {
|
|
19232
|
+
clearDetectedScreensize();
|
|
19233
|
+
}
|
|
19234
|
+
}, [clearDetectedScreensize, host, resolveAutoScreensize]);
|
|
18265
19235
|
const controller = useMemo26(
|
|
18266
19236
|
() => ({
|
|
18267
19237
|
closeSetup: () => updateWebVRHost(host, { setupOpen: false }),
|
|
@@ -18269,10 +19239,19 @@ var WebVR = forwardRef4(function WebVR2({
|
|
|
18269
19239
|
exitVR,
|
|
18270
19240
|
openSetup: () => updateWebVRHost(host, { setupOpen: true }),
|
|
18271
19241
|
requestPermission,
|
|
19242
|
+
resetSettings,
|
|
18272
19243
|
toggleVR,
|
|
18273
19244
|
updateSettings
|
|
18274
19245
|
}),
|
|
18275
|
-
[
|
|
19246
|
+
[
|
|
19247
|
+
enterVR,
|
|
19248
|
+
exitVR,
|
|
19249
|
+
host,
|
|
19250
|
+
requestPermission,
|
|
19251
|
+
resetSettings,
|
|
19252
|
+
toggleVR,
|
|
19253
|
+
updateSettings
|
|
19254
|
+
]
|
|
18276
19255
|
);
|
|
18277
19256
|
useImperativeHandle4(
|
|
18278
19257
|
ref,
|
|
@@ -18280,12 +19259,15 @@ var WebVR = forwardRef4(function WebVR2({
|
|
|
18280
19259
|
enterVR,
|
|
18281
19260
|
exitVR,
|
|
18282
19261
|
getMode: () => modeRef.current,
|
|
19262
|
+
getState: () => getWebVRState(host),
|
|
18283
19263
|
isAvailable: () => availableRef.current,
|
|
18284
19264
|
isEnabled: () => modeRef.current !== null,
|
|
18285
19265
|
requestPermission,
|
|
19266
|
+
resetSettings,
|
|
19267
|
+
subscribe: (onStoreChange) => subscribeWebVRHost(host, onStoreChange),
|
|
18286
19268
|
toggleVR
|
|
18287
19269
|
}),
|
|
18288
|
-
[enterVR, exitVR, requestPermission, toggleVR]
|
|
19270
|
+
[enterVR, exitVR, host, requestPermission, resetSettings, toggleVR]
|
|
18289
19271
|
);
|
|
18290
19272
|
useEffect40(() => {
|
|
18291
19273
|
let active = true;
|
|
@@ -18314,13 +19296,24 @@ var WebVR = forwardRef4(function WebVR2({
|
|
|
18314
19296
|
return () => {
|
|
18315
19297
|
if (host.controller === controller) {
|
|
18316
19298
|
host.controller = null;
|
|
18317
|
-
|
|
19299
|
+
dpdbRequestIdRef.current += 1;
|
|
19300
|
+
setDetectedScreensize(null);
|
|
19301
|
+
updateWebVRHost(host, {
|
|
19302
|
+
detectedScreensize: null,
|
|
19303
|
+
mode: null,
|
|
19304
|
+
setupOpen: false
|
|
19305
|
+
});
|
|
18318
19306
|
}
|
|
18319
19307
|
};
|
|
18320
19308
|
}, [controller, host]);
|
|
18321
19309
|
useEffect40(() => {
|
|
18322
|
-
updateWebVRHost(host, {
|
|
18323
|
-
|
|
19310
|
+
updateWebVRHost(host, {
|
|
19311
|
+
chrome,
|
|
19312
|
+
detectedScreensize,
|
|
19313
|
+
mode,
|
|
19314
|
+
settings
|
|
19315
|
+
});
|
|
19316
|
+
}, [chrome, detectedScreensize, host, mode, settings]);
|
|
18324
19317
|
useEffect40(() => {
|
|
18325
19318
|
if (mode !== "fake") {
|
|
18326
19319
|
return;
|
|
@@ -18369,6 +19362,23 @@ var WebVR = forwardRef4(function WebVR2({
|
|
|
18369
19362
|
void exitVR();
|
|
18370
19363
|
});
|
|
18371
19364
|
}, [exitVR, gl.domElement, mode]);
|
|
19365
|
+
useEffect40(() => {
|
|
19366
|
+
if (mode !== "webxr") {
|
|
19367
|
+
return;
|
|
19368
|
+
}
|
|
19369
|
+
const session2 = webXRSessionRef.current ?? xrStore.getState().session ?? null;
|
|
19370
|
+
if (!session2) {
|
|
19371
|
+
return;
|
|
19372
|
+
}
|
|
19373
|
+
const nextFoveation = foveationRef.current;
|
|
19374
|
+
if (nextFoveation !== void 0 && typeof gl.xr.setFoveation === "function") {
|
|
19375
|
+
gl.xr.setFoveation(nextFoveation);
|
|
19376
|
+
}
|
|
19377
|
+
const frameRateOption = resolveWebVRFrameRateOption(frameRateRef.current);
|
|
19378
|
+
if (frameRateOption !== void 0) {
|
|
19379
|
+
xrStore.setFrameRate(frameRateOption);
|
|
19380
|
+
}
|
|
19381
|
+
}, [foveation, frameRate, gl.xr, mode, xrStore]);
|
|
18372
19382
|
useWebVRPointerLock(
|
|
18373
19383
|
mousePointerLock && mode === "fake",
|
|
18374
19384
|
gl.domElement
|
|
@@ -18376,27 +19386,31 @@ var WebVR = forwardRef4(function WebVR2({
|
|
|
18376
19386
|
useWebVRWakeLock(
|
|
18377
19387
|
wakelock && (mode === "mobilevr" || mode === "fake")
|
|
18378
19388
|
);
|
|
18379
|
-
return /* @__PURE__ */ jsxs21(
|
|
19389
|
+
return /* @__PURE__ */ jsxs21(Fragment8, { children: [
|
|
18380
19390
|
/* @__PURE__ */ jsx40(
|
|
18381
19391
|
Gyro,
|
|
18382
19392
|
{
|
|
18383
19393
|
ref: gyroRef,
|
|
19394
|
+
absolute,
|
|
18384
19395
|
desktopSupport,
|
|
18385
19396
|
enabled: mode === "mobilevr",
|
|
19397
|
+
friction,
|
|
19398
|
+
north,
|
|
18386
19399
|
onDenied: () => {
|
|
18387
19400
|
reportDenied();
|
|
18388
19401
|
deactivate("mobilevr");
|
|
18389
19402
|
},
|
|
18390
19403
|
softstart: 0,
|
|
18391
|
-
touchMode: "off"
|
|
19404
|
+
touchMode: touchSupport ? "horizontaloffset" : "off"
|
|
18392
19405
|
}
|
|
18393
19406
|
),
|
|
18394
19407
|
/* @__PURE__ */ jsx40(
|
|
18395
19408
|
WebVRStereoRenderer,
|
|
18396
19409
|
{
|
|
18397
19410
|
mode,
|
|
19411
|
+
oversampling: resolvedOversampling,
|
|
18398
19412
|
profile: resolvedProfile,
|
|
18399
|
-
screensize:
|
|
19413
|
+
screensize: effectiveScreensize
|
|
18400
19414
|
}
|
|
18401
19415
|
),
|
|
18402
19416
|
/* @__PURE__ */ jsx40(
|
|
@@ -18412,12 +19426,12 @@ var WebVR = forwardRef4(function WebVR2({
|
|
|
18412
19426
|
|
|
18413
19427
|
// src/pano-scene-menu.tsx
|
|
18414
19428
|
import {
|
|
18415
|
-
useCallback as
|
|
19429
|
+
useCallback as useCallback12,
|
|
18416
19430
|
useEffect as useEffect41,
|
|
18417
19431
|
useId as useId3,
|
|
18418
19432
|
useLayoutEffect as useLayoutEffect9,
|
|
18419
19433
|
useMemo as useMemo27,
|
|
18420
|
-
useRef as
|
|
19434
|
+
useRef as useRef41,
|
|
18421
19435
|
useState as useState25
|
|
18422
19436
|
} from "react";
|
|
18423
19437
|
|
|
@@ -18551,6 +19565,13 @@ function pushSample(samples, sample, maxCount = 8) {
|
|
|
18551
19565
|
return next;
|
|
18552
19566
|
}
|
|
18553
19567
|
|
|
19568
|
+
// src/overlay/toggle.ts
|
|
19569
|
+
function resolveOverlayToggleIcon(icon, collapsed) {
|
|
19570
|
+
if (icon === void 0) return void 0;
|
|
19571
|
+
if (typeof icon === "function") return icon({ collapsed });
|
|
19572
|
+
return icon;
|
|
19573
|
+
}
|
|
19574
|
+
|
|
18554
19575
|
// src/pano-scene-menu.tsx
|
|
18555
19576
|
import { jsx as jsx41, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
18556
19577
|
var SCENE_MENU_DRAG_THRESHOLD_PX = 6;
|
|
@@ -18571,37 +19592,15 @@ var DEFAULT_PANO_SCENE_MENU_APPEARANCE = {
|
|
|
18571
19592
|
controlBackground: "rgba(255, 255, 255, 0.12)"
|
|
18572
19593
|
};
|
|
18573
19594
|
var DEFAULT_INSET = 12;
|
|
18574
|
-
function cssLength(value) {
|
|
18575
|
-
return typeof value === "number" ? `${value}px` : value;
|
|
18576
|
-
}
|
|
18577
19595
|
function resolveAppearance2(appearance) {
|
|
18578
19596
|
return {
|
|
18579
19597
|
...DEFAULT_PANO_SCENE_MENU_APPEARANCE,
|
|
18580
19598
|
...appearance
|
|
18581
19599
|
};
|
|
18582
19600
|
}
|
|
18583
|
-
function resolveInset(inset) {
|
|
18584
|
-
if (inset === void 0) {
|
|
18585
|
-
const value = cssLength(DEFAULT_INSET);
|
|
18586
|
-
return { top: value, right: value, bottom: value, left: value };
|
|
18587
|
-
}
|
|
18588
|
-
if (typeof inset === "number" || typeof inset === "string") {
|
|
18589
|
-
const value = cssLength(inset);
|
|
18590
|
-
return { top: value, right: value, bottom: value, left: value };
|
|
18591
|
-
}
|
|
18592
|
-
return {
|
|
18593
|
-
top: cssLength(inset.top ?? DEFAULT_INSET),
|
|
18594
|
-
right: cssLength(inset.right ?? DEFAULT_INSET),
|
|
18595
|
-
bottom: cssLength(inset.bottom ?? DEFAULT_INSET),
|
|
18596
|
-
left: cssLength(inset.left ?? DEFAULT_INSET)
|
|
18597
|
-
};
|
|
18598
|
-
}
|
|
18599
19601
|
function itemLabel(item) {
|
|
18600
19602
|
return item.title?.trim() || item.id;
|
|
18601
19603
|
}
|
|
18602
|
-
function isHorizontal(placement) {
|
|
18603
|
-
return placement === "top" || placement === "bottom";
|
|
18604
|
-
}
|
|
18605
19604
|
var CHEVRON_PATHS = {
|
|
18606
19605
|
// Keep glyphs optically centered in the 16×16 viewBox.
|
|
18607
19606
|
up: "M3 11l5-6 5 6",
|
|
@@ -18615,40 +19614,6 @@ function arrowChevron(direction, orientation2) {
|
|
|
18615
19614
|
}
|
|
18616
19615
|
return orientation2 === "horizontal" ? "right" : "down";
|
|
18617
19616
|
}
|
|
18618
|
-
function toggleChevron(placement, expanded) {
|
|
18619
|
-
switch (placement) {
|
|
18620
|
-
case "bottom":
|
|
18621
|
-
return expanded ? "down" : "up";
|
|
18622
|
-
case "top":
|
|
18623
|
-
return expanded ? "up" : "down";
|
|
18624
|
-
case "left":
|
|
18625
|
-
return expanded ? "left" : "right";
|
|
18626
|
-
case "right":
|
|
18627
|
-
return expanded ? "right" : "left";
|
|
18628
|
-
default: {
|
|
18629
|
-
const exhaustive = placement;
|
|
18630
|
-
void exhaustive;
|
|
18631
|
-
return "down";
|
|
18632
|
-
}
|
|
18633
|
-
}
|
|
18634
|
-
}
|
|
18635
|
-
function dockInset(placement, inset) {
|
|
18636
|
-
switch (placement) {
|
|
18637
|
-
case "top":
|
|
18638
|
-
return inset.top;
|
|
18639
|
-
case "bottom":
|
|
18640
|
-
return inset.bottom;
|
|
18641
|
-
case "left":
|
|
18642
|
-
return inset.left;
|
|
18643
|
-
case "right":
|
|
18644
|
-
return inset.right;
|
|
18645
|
-
default: {
|
|
18646
|
-
const exhaustive = placement;
|
|
18647
|
-
void exhaustive;
|
|
18648
|
-
return inset.bottom;
|
|
18649
|
-
}
|
|
18650
|
-
}
|
|
18651
|
-
}
|
|
18652
19617
|
function Chevron({ arrow }) {
|
|
18653
19618
|
return /* @__PURE__ */ jsx41(
|
|
18654
19619
|
"svg",
|
|
@@ -18671,6 +19636,7 @@ function ControlButton({
|
|
|
18671
19636
|
disabled,
|
|
18672
19637
|
label,
|
|
18673
19638
|
onClick,
|
|
19639
|
+
style,
|
|
18674
19640
|
children
|
|
18675
19641
|
}) {
|
|
18676
19642
|
return /* @__PURE__ */ jsx41(
|
|
@@ -18683,108 +19649,18 @@ function ControlButton({
|
|
|
18683
19649
|
onPointerDown: (event) => {
|
|
18684
19650
|
event.stopPropagation();
|
|
18685
19651
|
},
|
|
19652
|
+
style,
|
|
18686
19653
|
title: label,
|
|
18687
19654
|
type: "button",
|
|
18688
19655
|
children
|
|
18689
19656
|
}
|
|
18690
19657
|
);
|
|
18691
19658
|
}
|
|
18692
|
-
function horizontalAlignStyle(align, inset, widthValue) {
|
|
18693
|
-
const left = `calc(${inset.left} + var(--pano-safe-left))`;
|
|
18694
|
-
const right = `calc(${inset.right} + var(--pano-safe-right))`;
|
|
18695
|
-
if (!widthValue) {
|
|
18696
|
-
return { left, right, width: void 0, marginInline: void 0 };
|
|
18697
|
-
}
|
|
18698
|
-
switch (align) {
|
|
18699
|
-
case "start":
|
|
18700
|
-
return { left, right: "auto", width: widthValue, marginInline: void 0 };
|
|
18701
|
-
case "end":
|
|
18702
|
-
return { left: "auto", right, width: widthValue, marginInline: void 0 };
|
|
18703
|
-
case "center":
|
|
18704
|
-
return { left, right, width: widthValue, marginInline: "auto" };
|
|
18705
|
-
default: {
|
|
18706
|
-
const exhaustive = align;
|
|
18707
|
-
void exhaustive;
|
|
18708
|
-
return { left, right, width: widthValue, marginInline: "auto" };
|
|
18709
|
-
}
|
|
18710
|
-
}
|
|
18711
|
-
}
|
|
18712
|
-
function verticalAlignStyle(align, inset, heightValue) {
|
|
18713
|
-
const top = `calc(${inset.top} + var(--pano-safe-top))`;
|
|
18714
|
-
const bottom = `calc(${inset.bottom} + var(--pano-safe-bottom))`;
|
|
18715
|
-
if (!heightValue) {
|
|
18716
|
-
return { top, bottom, height: void 0, marginBlock: void 0 };
|
|
18717
|
-
}
|
|
18718
|
-
switch (align) {
|
|
18719
|
-
case "start":
|
|
18720
|
-
return { top, bottom: "auto", height: heightValue, marginBlock: void 0 };
|
|
18721
|
-
case "end":
|
|
18722
|
-
return { top: "auto", bottom, height: heightValue, marginBlock: void 0 };
|
|
18723
|
-
case "center":
|
|
18724
|
-
return { top, bottom, height: heightValue, marginBlock: "auto" };
|
|
18725
|
-
default: {
|
|
18726
|
-
const exhaustive = align;
|
|
18727
|
-
void exhaustive;
|
|
18728
|
-
return { top, bottom, height: heightValue, marginBlock: "auto" };
|
|
18729
|
-
}
|
|
18730
|
-
}
|
|
18731
|
-
}
|
|
18732
|
-
function placementBoxStyle(placement, inset, width, height, align) {
|
|
18733
|
-
const widthValue = width === void 0 ? void 0 : cssLength(width);
|
|
18734
|
-
const heightValue = height === void 0 ? void 0 : cssLength(height);
|
|
18735
|
-
const maxWidth = `calc(100% - ${inset.left} - ${inset.right} - var(--pano-safe-left) - var(--pano-safe-right))`;
|
|
18736
|
-
const maxHeight = `calc(100% - ${inset.top} - ${inset.bottom} - var(--pano-safe-top) - var(--pano-safe-bottom))`;
|
|
18737
|
-
switch (placement) {
|
|
18738
|
-
case "top":
|
|
18739
|
-
return {
|
|
18740
|
-
...horizontalAlignStyle(align, inset, widthValue),
|
|
18741
|
-
top: `calc(${inset.top} + var(--pano-safe-top))`,
|
|
18742
|
-
bottom: "auto",
|
|
18743
|
-
maxWidth,
|
|
18744
|
-
height: heightValue,
|
|
18745
|
-
maxHeight
|
|
18746
|
-
};
|
|
18747
|
-
case "bottom":
|
|
18748
|
-
return {
|
|
18749
|
-
...horizontalAlignStyle(align, inset, widthValue),
|
|
18750
|
-
top: "auto",
|
|
18751
|
-
bottom: `calc(${inset.bottom} + var(--pano-safe-bottom))`,
|
|
18752
|
-
maxWidth,
|
|
18753
|
-
height: heightValue,
|
|
18754
|
-
maxHeight
|
|
18755
|
-
};
|
|
18756
|
-
case "left":
|
|
18757
|
-
return {
|
|
18758
|
-
...verticalAlignStyle(align, inset, heightValue),
|
|
18759
|
-
right: "auto",
|
|
18760
|
-
left: `calc(${inset.left} + var(--pano-safe-left))`,
|
|
18761
|
-
width: widthValue,
|
|
18762
|
-
maxWidth,
|
|
18763
|
-
maxHeight
|
|
18764
|
-
};
|
|
18765
|
-
case "right":
|
|
18766
|
-
return {
|
|
18767
|
-
...verticalAlignStyle(align, inset, heightValue),
|
|
18768
|
-
right: `calc(${inset.right} + var(--pano-safe-right))`,
|
|
18769
|
-
left: "auto",
|
|
18770
|
-
width: widthValue,
|
|
18771
|
-
maxWidth,
|
|
18772
|
-
maxHeight
|
|
18773
|
-
};
|
|
18774
|
-
default: {
|
|
18775
|
-
const exhaustive = placement;
|
|
18776
|
-
void exhaustive;
|
|
18777
|
-
return {};
|
|
18778
|
-
}
|
|
18779
|
-
}
|
|
18780
|
-
}
|
|
18781
19659
|
function PanoSceneMenu({
|
|
18782
19660
|
items,
|
|
18783
19661
|
activeId = null,
|
|
18784
19662
|
onSelect,
|
|
18785
|
-
|
|
18786
|
-
align = "center",
|
|
18787
|
-
inset,
|
|
19663
|
+
anchor,
|
|
18788
19664
|
width,
|
|
18789
19665
|
height,
|
|
18790
19666
|
collapsible = false,
|
|
@@ -18801,15 +19677,19 @@ function PanoSceneMenu({
|
|
|
18801
19677
|
previousLabel = "Previous scene",
|
|
18802
19678
|
nextLabel = "Next scene",
|
|
18803
19679
|
expandLabel = "Show scenes",
|
|
18804
|
-
collapseLabel = "Hide scenes"
|
|
19680
|
+
collapseLabel = "Hide scenes",
|
|
19681
|
+
toggle
|
|
18805
19682
|
}) {
|
|
18806
19683
|
const listId = useId3();
|
|
18807
|
-
const listRef =
|
|
18808
|
-
const trackRef =
|
|
18809
|
-
const itemRefs =
|
|
19684
|
+
const listRef = useRef41(null);
|
|
19685
|
+
const trackRef = useRef41(null);
|
|
19686
|
+
const itemRefs = useRef41(/* @__PURE__ */ new Map());
|
|
18810
19687
|
const resolved = resolveAppearance2(appearance);
|
|
18811
|
-
const
|
|
18812
|
-
|
|
19688
|
+
const resolvedAnchor = resolveOverlayAnchor(anchor, {
|
|
19689
|
+
align: "bottom",
|
|
19690
|
+
inset: DEFAULT_INSET
|
|
19691
|
+
});
|
|
19692
|
+
const horizontal = resolvedAnchor.axis === "horizontal";
|
|
18813
19693
|
const customDrag = dragMotionProp !== false;
|
|
18814
19694
|
const dragMotion = resolveDragMotion(
|
|
18815
19695
|
dragMotionProp === false ? false : dragMotionProp
|
|
@@ -18820,9 +19700,9 @@ function PanoSceneMenu({
|
|
|
18820
19700
|
const [offset, setOffset] = useState25(0);
|
|
18821
19701
|
const [viewportSize, setViewportSize] = useState25(0);
|
|
18822
19702
|
const [contentSize, setContentSize] = useState25(0);
|
|
18823
|
-
const offsetRef =
|
|
18824
|
-
const dragRef =
|
|
18825
|
-
const animRef =
|
|
19703
|
+
const offsetRef = useRef41(0);
|
|
19704
|
+
const dragRef = useRef41(null);
|
|
19705
|
+
const animRef = useRef41(null);
|
|
18826
19706
|
const maxOffset = Math.max(0, contentSize - viewportSize);
|
|
18827
19707
|
offsetRef.current = offset;
|
|
18828
19708
|
const activeIndex = useMemo27(() => {
|
|
@@ -18831,18 +19711,18 @@ function PanoSceneMenu({
|
|
|
18831
19711
|
}
|
|
18832
19712
|
return items.findIndex((item) => item.id === activeId);
|
|
18833
19713
|
}, [activeId, items]);
|
|
18834
|
-
const cancelScrollAnimation =
|
|
19714
|
+
const cancelScrollAnimation = useCallback12(() => {
|
|
18835
19715
|
const anim = animRef.current;
|
|
18836
19716
|
if (anim?.raf != null) {
|
|
18837
19717
|
cancelAnimationFrame(anim.raf);
|
|
18838
19718
|
}
|
|
18839
19719
|
animRef.current = null;
|
|
18840
19720
|
}, []);
|
|
18841
|
-
const clampOffset =
|
|
19721
|
+
const clampOffset = useCallback12(
|
|
18842
19722
|
(value) => Math.min(maxOffset, Math.max(0, value)),
|
|
18843
19723
|
[maxOffset]
|
|
18844
19724
|
);
|
|
18845
|
-
const startScrollAnimation =
|
|
19725
|
+
const startScrollAnimation = useCallback12(
|
|
18846
19726
|
(velocity) => {
|
|
18847
19727
|
cancelScrollAnimation();
|
|
18848
19728
|
const current = offsetRef.current;
|
|
@@ -18982,15 +19862,15 @@ function PanoSceneMenu({
|
|
|
18982
19862
|
"--pano-scene-menu-label-align": resolved.labelAlign,
|
|
18983
19863
|
"--pano-scene-menu-font-size": cssLength(resolved.fontSize),
|
|
18984
19864
|
"--pano-scene-menu-control-color": resolved.controlColor,
|
|
18985
|
-
"--pano-scene-menu-control-background": resolved.controlBackground
|
|
18986
|
-
"--pano-scene-menu-dock-inset": dockInset(placement, resolvedInset)
|
|
19865
|
+
"--pano-scene-menu-control-background": resolved.controlBackground
|
|
18987
19866
|
};
|
|
18988
19867
|
return {
|
|
18989
19868
|
...vars,
|
|
18990
|
-
|
|
19869
|
+
["--pano-overlay-dock-inset"]: resolvedAnchor.dockInset,
|
|
19870
|
+
...overlayBoxStyle(resolvedAnchor.align, resolvedAnchor.inset, width, height),
|
|
18991
19871
|
...style
|
|
18992
19872
|
};
|
|
18993
|
-
}, [
|
|
19873
|
+
}, [height, resolved, resolvedAnchor, style, width]);
|
|
18994
19874
|
const setExpanded = (next) => {
|
|
18995
19875
|
if (!collapsible) {
|
|
18996
19876
|
return;
|
|
@@ -19109,7 +19989,7 @@ function PanoSceneMenu({
|
|
|
19109
19989
|
setOffset((previous) => clampOffset(previous + event.deltaX));
|
|
19110
19990
|
};
|
|
19111
19991
|
const axisPoint = (event) => horizontal ? event.clientX : event.clientY;
|
|
19112
|
-
const endSuppressClickRef =
|
|
19992
|
+
const endSuppressClickRef = useRef41(false);
|
|
19113
19993
|
const beginListDrag = (event, captureTarget) => {
|
|
19114
19994
|
if (!customDrag || event.button !== 0) return;
|
|
19115
19995
|
cancelScrollAnimation();
|
|
@@ -19196,13 +20076,13 @@ function PanoSceneMenu({
|
|
|
19196
20076
|
"div",
|
|
19197
20077
|
{
|
|
19198
20078
|
"aria-label": label,
|
|
19199
|
-
className: cn("pano-scene-menu", className),
|
|
19200
|
-
"data-align":
|
|
20079
|
+
className: cn("pano-overlay-anchor", "pano-scene-menu", className),
|
|
20080
|
+
"data-align": resolvedAnchor.contentAlign,
|
|
20081
|
+
"data-collapse-edge": resolvedAnchor.collapseEdge,
|
|
20082
|
+
"data-collapsed": collapsible && !expanded ? "true" : "false",
|
|
19201
20083
|
"data-collapsible": collapsible ? "true" : void 0,
|
|
19202
20084
|
"data-drag-motion": customDrag ? "custom" : "native",
|
|
19203
|
-
"data-expanded": expanded ? "true" : "false",
|
|
19204
20085
|
"data-orientation": orientation2,
|
|
19205
|
-
"data-placement": placement,
|
|
19206
20086
|
role: "group",
|
|
19207
20087
|
style: rootStyle,
|
|
19208
20088
|
children: [
|
|
@@ -19307,10 +20187,19 @@ function PanoSceneMenu({
|
|
|
19307
20187
|
collapsible ? /* @__PURE__ */ jsx41(
|
|
19308
20188
|
ControlButton,
|
|
19309
20189
|
{
|
|
19310
|
-
className:
|
|
20190
|
+
className: cn(
|
|
20191
|
+
"pano-scene-menu-toggle pano-overlay-anchor-toggle",
|
|
20192
|
+
toggle?.className
|
|
20193
|
+
),
|
|
19311
20194
|
label: expanded ? collapseLabel : expandLabel,
|
|
19312
20195
|
onClick: () => setExpanded(!expanded),
|
|
19313
|
-
|
|
20196
|
+
style: toggle?.style,
|
|
20197
|
+
children: toggle?.icon === void 0 ? /* @__PURE__ */ jsx41(
|
|
20198
|
+
Chevron,
|
|
20199
|
+
{
|
|
20200
|
+
arrow: overlayChevron(resolvedAnchor.collapseEdge, !expanded)
|
|
20201
|
+
}
|
|
20202
|
+
) : resolveOverlayToggleIcon(toggle.icon, !expanded)
|
|
19314
20203
|
}
|
|
19315
20204
|
) : null
|
|
19316
20205
|
]
|
|
@@ -19319,7 +20208,7 @@ function PanoSceneMenu({
|
|
|
19319
20208
|
}
|
|
19320
20209
|
|
|
19321
20210
|
// src/use-pano-viewer.ts
|
|
19322
|
-
import { useMemo as useMemo28, useRef as
|
|
20211
|
+
import { useMemo as useMemo28, useRef as useRef42 } from "react";
|
|
19323
20212
|
function createPanoViewerHandle(ref) {
|
|
19324
20213
|
return {
|
|
19325
20214
|
getView: () => ref.current?.getView() ?? { yaw: 0, pitch: 0, fov: 75 },
|
|
@@ -19350,6 +20239,36 @@ function createPanoViewerHandle(ref) {
|
|
|
19350
20239
|
isVRAvailable: () => ref.current?.isVRAvailable() ?? false,
|
|
19351
20240
|
isVREnabled: () => ref.current?.isVREnabled() ?? false,
|
|
19352
20241
|
getVRMode: () => ref.current?.getVRMode() ?? null,
|
|
20242
|
+
getVRState: () => ref.current?.getVRState() ?? EMPTY_WEBVR_STATE,
|
|
20243
|
+
subscribeVR: (onStoreChange) => {
|
|
20244
|
+
let disposed = false;
|
|
20245
|
+
let unsubscribe;
|
|
20246
|
+
const timers = [];
|
|
20247
|
+
const attach = () => {
|
|
20248
|
+
if (disposed || unsubscribe) {
|
|
20249
|
+
return;
|
|
20250
|
+
}
|
|
20251
|
+
const handle = ref.current;
|
|
20252
|
+
if (!handle) {
|
|
20253
|
+
return;
|
|
20254
|
+
}
|
|
20255
|
+
unsubscribe = handle.subscribeVR(onStoreChange);
|
|
20256
|
+
onStoreChange();
|
|
20257
|
+
};
|
|
20258
|
+
attach();
|
|
20259
|
+
if (typeof window !== "undefined") {
|
|
20260
|
+
for (const delay of [0, 16, 50, 100, 250]) {
|
|
20261
|
+
timers.push(window.setTimeout(attach, delay));
|
|
20262
|
+
}
|
|
20263
|
+
}
|
|
20264
|
+
return () => {
|
|
20265
|
+
disposed = true;
|
|
20266
|
+
for (const id of timers) {
|
|
20267
|
+
window.clearTimeout(id);
|
|
20268
|
+
}
|
|
20269
|
+
unsubscribe?.();
|
|
20270
|
+
};
|
|
20271
|
+
},
|
|
19353
20272
|
requestVRPermission: () => ref.current?.requestVRPermission() ?? Promise.resolve(false),
|
|
19354
20273
|
getVideo: () => ref.current?.getVideo() ?? null,
|
|
19355
20274
|
subscribeVideo: (onStoreChange) => ref.current?.subscribeVideo(onStoreChange) ?? (() => {
|
|
@@ -19401,7 +20320,7 @@ function createPanoViewerHandle(ref) {
|
|
|
19401
20320
|
};
|
|
19402
20321
|
}
|
|
19403
20322
|
function usePanoViewer() {
|
|
19404
|
-
const ref =
|
|
20323
|
+
const ref = useRef42(null);
|
|
19405
20324
|
const handle = useMemo28(() => createPanoViewerHandle(ref), []);
|
|
19406
20325
|
return useMemo28(() => ({ ref, ...handle }), [handle]);
|
|
19407
20326
|
}
|
|
@@ -19409,25 +20328,25 @@ function usePanoViewer() {
|
|
|
19409
20328
|
// src/video/pano-video.tsx
|
|
19410
20329
|
import { useThree as useThree29 } from "@react-three/fiber";
|
|
19411
20330
|
import {
|
|
19412
|
-
useCallback as
|
|
20331
|
+
useCallback as useCallback13,
|
|
19413
20332
|
useContext as useContext28,
|
|
19414
20333
|
useEffect as useEffect42,
|
|
19415
20334
|
useLayoutEffect as useLayoutEffect10,
|
|
19416
20335
|
useMemo as useMemo29,
|
|
19417
|
-
useRef as
|
|
20336
|
+
useRef as useRef43,
|
|
19418
20337
|
useState as useState26
|
|
19419
20338
|
} from "react";
|
|
19420
20339
|
import {
|
|
19421
20340
|
BackSide as BackSide4,
|
|
19422
|
-
LinearFilter as
|
|
19423
|
-
LinearMipmapLinearFilter as
|
|
19424
|
-
MathUtils as
|
|
20341
|
+
LinearFilter as LinearFilter10,
|
|
20342
|
+
LinearMipmapLinearFilter as LinearMipmapLinearFilter8,
|
|
20343
|
+
MathUtils as MathUtils14,
|
|
19425
20344
|
RepeatWrapping as RepeatWrapping2,
|
|
19426
|
-
SRGBColorSpace as
|
|
20345
|
+
SRGBColorSpace as SRGBColorSpace9,
|
|
19427
20346
|
TextureLoader as TextureLoader8,
|
|
19428
20347
|
VideoTexture as VideoTexture2
|
|
19429
20348
|
} from "three";
|
|
19430
|
-
import { Fragment as
|
|
20349
|
+
import { Fragment as Fragment9, jsx as jsx42, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
19431
20350
|
var EMPTY_TRACKS = [];
|
|
19432
20351
|
var EMPTY_RATES = DEFAULT_PANO_VIDEO_PLAYBACK_RATES;
|
|
19433
20352
|
function createEmptySnapshot() {
|
|
@@ -19503,7 +20422,7 @@ function findTextTrack(video, tracks, trackId) {
|
|
|
19503
20422
|
return list.length > 0 ? list[0] : null;
|
|
19504
20423
|
}
|
|
19505
20424
|
function applyEquirectangularLayout(texture, anisotropy) {
|
|
19506
|
-
texture.colorSpace =
|
|
20425
|
+
texture.colorSpace = SRGBColorSpace9;
|
|
19507
20426
|
texture.wrapS = RepeatWrapping2;
|
|
19508
20427
|
texture.repeat.x = -1;
|
|
19509
20428
|
texture.offset.x = 1;
|
|
@@ -19513,7 +20432,7 @@ function applyEquirectangularLayout(texture, anisotropy) {
|
|
|
19513
20432
|
function usePosterTexture2(poster, onError) {
|
|
19514
20433
|
const gl = useThree29((state) => state.gl);
|
|
19515
20434
|
const [texture, setTexture] = useState26(null);
|
|
19516
|
-
const onErrorRef =
|
|
20435
|
+
const onErrorRef = useRef43(onError);
|
|
19517
20436
|
onErrorRef.current = onError;
|
|
19518
20437
|
useEffect42(() => {
|
|
19519
20438
|
let active = true;
|
|
@@ -19536,8 +20455,8 @@ function usePosterTexture2(poster, onError) {
|
|
|
19536
20455
|
gl.capabilities.getMaxAnisotropy()
|
|
19537
20456
|
);
|
|
19538
20457
|
loadedTexture.wrapT = RepeatWrapping2;
|
|
19539
|
-
loadedTexture.magFilter =
|
|
19540
|
-
loadedTexture.minFilter =
|
|
20458
|
+
loadedTexture.magFilter = LinearFilter10;
|
|
20459
|
+
loadedTexture.minFilter = LinearMipmapLinearFilter8;
|
|
19541
20460
|
loadedTexture.generateMipmaps = true;
|
|
19542
20461
|
setTexture(loadedTexture);
|
|
19543
20462
|
},
|
|
@@ -19631,17 +20550,17 @@ function PanoVideo({
|
|
|
19631
20550
|
() => captionsEnabled ? defaultPanoVideoTrackId(tracks) : null
|
|
19632
20551
|
);
|
|
19633
20552
|
const [ready, setReady] = useState26(false);
|
|
19634
|
-
const autoPlayRef =
|
|
20553
|
+
const autoPlayRef = useRef43(autoPlay);
|
|
19635
20554
|
autoPlayRef.current = autoPlay;
|
|
19636
|
-
const blockedRef =
|
|
19637
|
-
const captionAppearanceOverrideRef =
|
|
20555
|
+
const blockedRef = useRef43(false);
|
|
20556
|
+
const captionAppearanceOverrideRef = useRef43(
|
|
19638
20557
|
{}
|
|
19639
20558
|
);
|
|
19640
|
-
const mediaCapabilitiesRef =
|
|
20559
|
+
const mediaCapabilitiesRef = useRef43({
|
|
19641
20560
|
volumeAdjustable: true,
|
|
19642
20561
|
playbackRates: [...DEFAULT_PANO_VIDEO_PLAYBACK_RATES]
|
|
19643
20562
|
});
|
|
19644
|
-
const storeRef =
|
|
20563
|
+
const storeRef = useRef43(null);
|
|
19645
20564
|
if (!storeRef.current) {
|
|
19646
20565
|
storeRef.current = {
|
|
19647
20566
|
snapshot: {
|
|
@@ -19651,7 +20570,7 @@ function PanoVideo({
|
|
|
19651
20570
|
listeners: /* @__PURE__ */ new Set()
|
|
19652
20571
|
};
|
|
19653
20572
|
}
|
|
19654
|
-
const actionsRef =
|
|
20573
|
+
const actionsRef = useRef43({
|
|
19655
20574
|
play: async () => {
|
|
19656
20575
|
},
|
|
19657
20576
|
pause: () => {
|
|
@@ -19671,12 +20590,12 @@ function PanoVideo({
|
|
|
19671
20590
|
setCaptionAppearance: (_appearance) => {
|
|
19672
20591
|
}
|
|
19673
20592
|
});
|
|
19674
|
-
const onLoadRef =
|
|
19675
|
-
const onErrorRef =
|
|
19676
|
-
const onPlaybackStateChangeRef =
|
|
19677
|
-
const onEndedRef =
|
|
19678
|
-
const onVariantChangeRef =
|
|
19679
|
-
const onTrackChangeRef =
|
|
20593
|
+
const onLoadRef = useRef43(onLoad);
|
|
20594
|
+
const onErrorRef = useRef43(onError);
|
|
20595
|
+
const onPlaybackStateChangeRef = useRef43(onPlaybackStateChange);
|
|
20596
|
+
const onEndedRef = useRef43(onEnded);
|
|
20597
|
+
const onVariantChangeRef = useRef43(onVariantChange);
|
|
20598
|
+
const onTrackChangeRef = useRef43(onTrackChange);
|
|
19680
20599
|
onLoadRef.current = onLoad;
|
|
19681
20600
|
onErrorRef.current = onError;
|
|
19682
20601
|
onPlaybackStateChangeRef.current = onPlaybackStateChange;
|
|
@@ -19693,8 +20612,8 @@ function PanoVideo({
|
|
|
19693
20612
|
video.preload = "metadata";
|
|
19694
20613
|
const texture = new VideoTexture2(video);
|
|
19695
20614
|
applyEquirectangularLayout(texture, 1);
|
|
19696
|
-
texture.magFilter =
|
|
19697
|
-
texture.minFilter =
|
|
20615
|
+
texture.magFilter = LinearFilter10;
|
|
20616
|
+
texture.minFilter = LinearFilter10;
|
|
19698
20617
|
texture.generateMipmaps = false;
|
|
19699
20618
|
return { video, texture };
|
|
19700
20619
|
}, []);
|
|
@@ -19735,7 +20654,7 @@ function PanoVideo({
|
|
|
19735
20654
|
activeVariant?.poster ?? poster,
|
|
19736
20655
|
onError
|
|
19737
20656
|
);
|
|
19738
|
-
const emitSnapshot =
|
|
20657
|
+
const emitSnapshot = useCallback13(
|
|
19739
20658
|
(patch) => {
|
|
19740
20659
|
const store = storeRef.current;
|
|
19741
20660
|
const video = resource?.video;
|
|
@@ -20126,11 +21045,11 @@ function PanoVideo({
|
|
|
20126
21045
|
if (variants.length === 0) {
|
|
20127
21046
|
return null;
|
|
20128
21047
|
}
|
|
20129
|
-
return /* @__PURE__ */ jsxs23(
|
|
21048
|
+
return /* @__PURE__ */ jsxs23(Fragment9, { children: [
|
|
20130
21049
|
activeTexture ? /* @__PURE__ */ jsxs23(
|
|
20131
21050
|
"mesh",
|
|
20132
21051
|
{
|
|
20133
|
-
rotation: [0,
|
|
21052
|
+
rotation: [0, MathUtils14.degToRad(90 + yawOffset2), 0],
|
|
20134
21053
|
visible,
|
|
20135
21054
|
children: [
|
|
20136
21055
|
/* @__PURE__ */ jsx42("sphereGeometry", { args: [DEFAULT_PANORAMA_RADIUS, 128, 64] }),
|
|
@@ -20151,12 +21070,12 @@ function PanoVideo({
|
|
|
20151
21070
|
|
|
20152
21071
|
// src/map/pano-map.tsx
|
|
20153
21072
|
import {
|
|
20154
|
-
useCallback as
|
|
21073
|
+
useCallback as useCallback14,
|
|
20155
21074
|
useEffect as useEffect44,
|
|
20156
21075
|
useId as useId4,
|
|
20157
21076
|
useLayoutEffect as useLayoutEffect11,
|
|
20158
21077
|
useMemo as useMemo30,
|
|
20159
|
-
useRef as
|
|
21078
|
+
useRef as useRef45,
|
|
20160
21079
|
useState as useState28
|
|
20161
21080
|
} from "react";
|
|
20162
21081
|
|
|
@@ -20218,12 +21137,12 @@ function normalizeDegrees(value) {
|
|
|
20218
21137
|
}
|
|
20219
21138
|
|
|
20220
21139
|
// src/map/use-map-view.ts
|
|
20221
|
-
import { useContext as useContext29, useEffect as useEffect43, useRef as
|
|
21140
|
+
import { useContext as useContext29, useEffect as useEffect43, useRef as useRef44, useState as useState27 } from "react";
|
|
20222
21141
|
var DEFAULT_VIEW2 = { yaw: 0, pitch: 0, fov: 75 };
|
|
20223
21142
|
function useMapView(controlled) {
|
|
20224
21143
|
const eventBus = useContext29(PanoEventBusContext);
|
|
20225
21144
|
const [view, setView] = useState27(controlled ?? DEFAULT_VIEW2);
|
|
20226
|
-
const controlledRef =
|
|
21145
|
+
const controlledRef = useRef44(controlled);
|
|
20227
21146
|
controlledRef.current = controlled;
|
|
20228
21147
|
useEffect43(() => {
|
|
20229
21148
|
if (controlled !== void 0) {
|
|
@@ -20240,7 +21159,7 @@ function useMapView(controlled) {
|
|
|
20240
21159
|
}
|
|
20241
21160
|
|
|
20242
21161
|
// src/map/pano-map.tsx
|
|
20243
|
-
import { Fragment as
|
|
21162
|
+
import { Fragment as Fragment10, jsx as jsx43, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
20244
21163
|
var DEFAULT_ICON_SIZE2 = 28;
|
|
20245
21164
|
var DEFAULT_SECTOR_COLOR = "#ffffff";
|
|
20246
21165
|
var DEFAULT_SECTOR_OPACITY = 0.55;
|
|
@@ -20377,20 +21296,20 @@ function PanoMap({
|
|
|
20377
21296
|
}) {
|
|
20378
21297
|
const reactId = useId4().replace(/:/g, "");
|
|
20379
21298
|
const view = useMapView(controlledView);
|
|
20380
|
-
const rootRef =
|
|
20381
|
-
const containerRef =
|
|
20382
|
-
const sectorNodeRef =
|
|
20383
|
-
const yawRef =
|
|
21299
|
+
const rootRef = useRef45(null);
|
|
21300
|
+
const containerRef = useRef45(null);
|
|
21301
|
+
const sectorNodeRef = useRef45(null);
|
|
21302
|
+
const yawRef = useRef45(view.yaw);
|
|
20384
21303
|
const [size, setSize] = useState28({ width: 0, height: 0 });
|
|
20385
21304
|
const [imageSize2, setImageSize] = useState28({ width: 0, height: 0 });
|
|
20386
21305
|
const [scale, setScale] = useState28(1);
|
|
20387
21306
|
const [pan, setPan] = useState28({ x: 0, y: 0 });
|
|
20388
21307
|
const [uncontrolledCollapsed, setUncontrolledCollapsed] = useState28(false);
|
|
20389
|
-
const dragRef =
|
|
20390
|
-
const panAnimRef =
|
|
20391
|
-
const panRef =
|
|
20392
|
-
const scaleRef =
|
|
20393
|
-
const initialViewKeyRef =
|
|
21308
|
+
const dragRef = useRef45(null);
|
|
21309
|
+
const panAnimRef = useRef45(null);
|
|
21310
|
+
const panRef = useRef45(pan);
|
|
21311
|
+
const scaleRef = useRef45(scale);
|
|
21312
|
+
const initialViewKeyRef = useRef45(null);
|
|
20394
21313
|
const spots = map.spots;
|
|
20395
21314
|
const iconSize = map.iconSize ?? DEFAULT_ICON_SIZE2;
|
|
20396
21315
|
const interaction = map.interaction ?? "fixed";
|
|
@@ -20450,7 +21369,7 @@ function PanoMap({
|
|
|
20450
21369
|
};
|
|
20451
21370
|
panRef.current = pan;
|
|
20452
21371
|
scaleRef.current = scale;
|
|
20453
|
-
const panBoundsFor =
|
|
21372
|
+
const panBoundsFor = useCallback14(
|
|
20454
21373
|
(nextScale) => {
|
|
20455
21374
|
const width = fit.width * nextScale;
|
|
20456
21375
|
const height = fit.height * nextScale;
|
|
@@ -20466,7 +21385,7 @@ function PanoMap({
|
|
|
20466
21385
|
},
|
|
20467
21386
|
[fit, size]
|
|
20468
21387
|
);
|
|
20469
|
-
const clampPan =
|
|
21388
|
+
const clampPan = useCallback14(
|
|
20470
21389
|
(nextScale, nextPan) => {
|
|
20471
21390
|
const bounds = panBoundsFor(nextScale);
|
|
20472
21391
|
return {
|
|
@@ -20476,14 +21395,14 @@ function PanoMap({
|
|
|
20476
21395
|
},
|
|
20477
21396
|
[panBoundsFor]
|
|
20478
21397
|
);
|
|
20479
|
-
const cancelPanAnimation =
|
|
21398
|
+
const cancelPanAnimation = useCallback14(() => {
|
|
20480
21399
|
const anim = panAnimRef.current;
|
|
20481
21400
|
if (anim?.raf != null) {
|
|
20482
21401
|
cancelAnimationFrame(anim.raf);
|
|
20483
21402
|
}
|
|
20484
21403
|
panAnimRef.current = null;
|
|
20485
21404
|
}, []);
|
|
20486
|
-
const startPanAnimation =
|
|
21405
|
+
const startPanAnimation = useCallback14(
|
|
20487
21406
|
(velocity) => {
|
|
20488
21407
|
cancelPanAnimation();
|
|
20489
21408
|
const current = panRef.current;
|
|
@@ -20589,7 +21508,7 @@ function PanoMap({
|
|
|
20589
21508
|
size.height,
|
|
20590
21509
|
size.width
|
|
20591
21510
|
]);
|
|
20592
|
-
const applyZoom =
|
|
21511
|
+
const applyZoom = useCallback14(
|
|
20593
21512
|
(nextScale, origin) => {
|
|
20594
21513
|
if (!gestureZoom) return;
|
|
20595
21514
|
cancelPanAnimation();
|
|
@@ -20801,7 +21720,7 @@ function PanoMap({
|
|
|
20801
21720
|
children: collapsed ? "\u25A3" : "\u25A2"
|
|
20802
21721
|
}
|
|
20803
21722
|
) : null,
|
|
20804
|
-
zoomControls && !collapsed ? /* @__PURE__ */ jsxs24(
|
|
21723
|
+
zoomControls && !collapsed ? /* @__PURE__ */ jsxs24(Fragment10, { children: [
|
|
20805
21724
|
/* @__PURE__ */ jsx43(
|
|
20806
21725
|
"button",
|
|
20807
21726
|
{
|
|
@@ -21043,17 +21962,27 @@ import {
|
|
|
21043
21962
|
useEffect as useEffect45,
|
|
21044
21963
|
useId as useId5,
|
|
21045
21964
|
useMemo as useMemo31,
|
|
21046
|
-
useRef as
|
|
21965
|
+
useRef as useRef46,
|
|
21047
21966
|
useState as useState29
|
|
21048
21967
|
} from "react";
|
|
21049
|
-
import { Fragment as
|
|
21968
|
+
import { Fragment as Fragment11, jsx as jsx44, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
21050
21969
|
var DEFAULT_DIALOG_WIDTH = 720;
|
|
21051
21970
|
var DEFAULT_DIALOG_HEIGHT = 520;
|
|
21052
|
-
|
|
21053
|
-
|
|
21054
|
-
|
|
21055
|
-
return {
|
|
21971
|
+
var MAP_ANCHOR_DEFAULTS = { align: "bottom-left", inset: 16 };
|
|
21972
|
+
function mergeAnchor(base, override) {
|
|
21973
|
+
if (base === void 0 && override === void 0) return void 0;
|
|
21974
|
+
return {
|
|
21975
|
+
...base,
|
|
21976
|
+
...override,
|
|
21977
|
+
inset: override?.inset !== void 0 ? override.inset : base?.inset
|
|
21978
|
+
};
|
|
21056
21979
|
}
|
|
21980
|
+
var CHEVRON_PATHS2 = {
|
|
21981
|
+
up: "M3 11l5-6 5 6",
|
|
21982
|
+
down: "M3 5l5 6 5-6",
|
|
21983
|
+
left: "M11 3 5 8l6 5",
|
|
21984
|
+
right: "M5 3l6 5-6 5"
|
|
21985
|
+
};
|
|
21057
21986
|
function PanoMapDialogShell({
|
|
21058
21987
|
open,
|
|
21059
21988
|
onOpenChange,
|
|
@@ -21066,8 +21995,8 @@ function PanoMapDialogShell({
|
|
|
21066
21995
|
usePanoModal(open);
|
|
21067
21996
|
const { size } = usePanoOverlay();
|
|
21068
21997
|
const titleId = useId5();
|
|
21069
|
-
const panelRef =
|
|
21070
|
-
const previouslyFocused =
|
|
21998
|
+
const panelRef = useRef46(null);
|
|
21999
|
+
const previouslyFocused = useRef46(null);
|
|
21071
22000
|
useEffect45(() => {
|
|
21072
22001
|
if (!open) return;
|
|
21073
22002
|
const active = panelRef.current?.ownerDocument.activeElement;
|
|
@@ -21096,7 +22025,7 @@ function PanoMapDialogShell({
|
|
|
21096
22025
|
const height = Math.min(preferredHeight, Math.max(0, size.height - 32));
|
|
21097
22026
|
const left = Math.max(0, (size.width - width) / 2);
|
|
21098
22027
|
const top = Math.max(0, (size.height - height) / 2);
|
|
21099
|
-
return /* @__PURE__ */ jsxs25(
|
|
22028
|
+
return /* @__PURE__ */ jsxs25(Fragment11, { children: [
|
|
21100
22029
|
/* @__PURE__ */ jsx44(
|
|
21101
22030
|
"div",
|
|
21102
22031
|
{
|
|
@@ -21165,11 +22094,9 @@ function PanoMapOverlay({
|
|
|
21165
22094
|
placementSceneId,
|
|
21166
22095
|
presentationOverride,
|
|
21167
22096
|
presentation: presentationModeProp,
|
|
21168
|
-
|
|
22097
|
+
anchor: anchorProp,
|
|
21169
22098
|
width: widthProp,
|
|
21170
22099
|
height: heightProp,
|
|
21171
|
-
offsetX: offsetXProp,
|
|
21172
|
-
offsetY: offsetYProp,
|
|
21173
22100
|
dialogWidth = DEFAULT_DIALOG_WIDTH,
|
|
21174
22101
|
dialogHeight = DEFAULT_DIALOG_HEIGHT,
|
|
21175
22102
|
interaction,
|
|
@@ -21183,23 +22110,22 @@ function PanoMapOverlay({
|
|
|
21183
22110
|
title = "Map",
|
|
21184
22111
|
className,
|
|
21185
22112
|
style,
|
|
22113
|
+
toggle,
|
|
21186
22114
|
editorSurface = false
|
|
21187
22115
|
}) {
|
|
21188
22116
|
const { size } = usePanoOverlay();
|
|
21189
22117
|
const [open, setOpen] = useState29(false);
|
|
21190
22118
|
const [collapsed, setCollapsed] = useState29(false);
|
|
21191
22119
|
const basePresentation = presentationOverride ?? map.presentation ?? {
|
|
21192
|
-
mode: "
|
|
21193
|
-
corner: "bottom-left",
|
|
22120
|
+
mode: "panel",
|
|
21194
22121
|
width: 220,
|
|
21195
|
-
height: 160
|
|
21196
|
-
offsetX: 16,
|
|
21197
|
-
offsetY: 16
|
|
22122
|
+
height: 160
|
|
21198
22123
|
};
|
|
21199
22124
|
const presentationMode = presentationModeProp ?? basePresentation.mode;
|
|
21200
|
-
const
|
|
21201
|
-
|
|
21202
|
-
|
|
22125
|
+
const resolvedAnchor = resolveOverlayAnchor(
|
|
22126
|
+
mergeAnchor(basePresentation.anchor, anchorProp),
|
|
22127
|
+
MAP_ANCHOR_DEFAULTS
|
|
22128
|
+
);
|
|
21203
22129
|
const width = widthProp ?? basePresentation.width ?? (presentationMode === "dialog" ? 48 : 220);
|
|
21204
22130
|
const height = heightProp ?? basePresentation.height ?? (presentationMode === "dialog" ? 48 : 160);
|
|
21205
22131
|
const resolvedMap = useMemo31(() => {
|
|
@@ -21231,15 +22157,15 @@ function PanoMapOverlay({
|
|
|
21231
22157
|
}
|
|
21232
22158
|
};
|
|
21233
22159
|
const editorBox = useMemo31(() => {
|
|
21234
|
-
const
|
|
21235
|
-
const
|
|
22160
|
+
const panelWidth = widthProp !== void 0 && Number.isFinite(widthProp) && widthProp > 0 ? widthProp : Math.min(420, Math.max(240, size.width * 0.45));
|
|
22161
|
+
const panelHeight = heightProp !== void 0 && Number.isFinite(heightProp) && heightProp > 0 ? heightProp : Math.min(320, Math.max(180, size.height * 0.45));
|
|
21236
22162
|
return {
|
|
21237
22163
|
left: 16,
|
|
21238
22164
|
right: "auto",
|
|
21239
22165
|
top: "auto",
|
|
21240
22166
|
bottom: 16,
|
|
21241
|
-
width:
|
|
21242
|
-
height:
|
|
22167
|
+
width: panelWidth,
|
|
22168
|
+
height: panelHeight
|
|
21243
22169
|
};
|
|
21244
22170
|
}, [heightProp, size.height, size.width, widthProp]);
|
|
21245
22171
|
if (editorSurface) {
|
|
@@ -21259,7 +22185,7 @@ function PanoMapOverlay({
|
|
|
21259
22185
|
);
|
|
21260
22186
|
}
|
|
21261
22187
|
if (presentationMode === "dialog") {
|
|
21262
|
-
const launcherBox =
|
|
22188
|
+
const launcherBox = overlayBoxStyle(resolvedAnchor.align, resolvedAnchor.inset, width, height);
|
|
21263
22189
|
return /* @__PURE__ */ jsxs25("div", { className: ["pano-map-overlay", className].filter(Boolean).join(" "), "data-pano-map-overlay": "", children: [
|
|
21264
22190
|
/* @__PURE__ */ jsx44(
|
|
21265
22191
|
"button",
|
|
@@ -21291,29 +22217,63 @@ function PanoMapOverlay({
|
|
|
21291
22217
|
)
|
|
21292
22218
|
] });
|
|
21293
22219
|
}
|
|
21294
|
-
const
|
|
21295
|
-
const
|
|
21296
|
-
const
|
|
21297
|
-
return /* @__PURE__ */
|
|
22220
|
+
const collapseEnabled = showCollapseControl ?? map.controls?.collapse === true;
|
|
22221
|
+
const box = overlayBoxStyle(resolvedAnchor.align, resolvedAnchor.inset, width, height);
|
|
22222
|
+
const arrow = overlayChevron(resolvedAnchor.collapseEdge, collapsed);
|
|
22223
|
+
return /* @__PURE__ */ jsxs25(
|
|
21298
22224
|
"div",
|
|
21299
22225
|
{
|
|
21300
|
-
className: ["pano-map-overlay", className].filter(Boolean).join(" "),
|
|
22226
|
+
className: ["pano-overlay-anchor", "pano-map-overlay", className].filter(Boolean).join(" "),
|
|
21301
22227
|
style: {
|
|
21302
22228
|
position: "absolute",
|
|
21303
|
-
pointerEvents: "auto",
|
|
22229
|
+
pointerEvents: collapseEnabled && collapsed ? "none" : "auto",
|
|
22230
|
+
["--pano-overlay-dock-inset"]: resolvedAnchor.dockInset,
|
|
22231
|
+
["--pano-overlay-anchor-radius"]: "8px",
|
|
21304
22232
|
...box,
|
|
21305
22233
|
...style
|
|
21306
22234
|
},
|
|
21307
22235
|
"data-pano-map-overlay": "",
|
|
21308
|
-
"data-presentation": "
|
|
21309
|
-
|
|
21310
|
-
|
|
21311
|
-
|
|
21312
|
-
|
|
21313
|
-
|
|
21314
|
-
|
|
21315
|
-
|
|
21316
|
-
|
|
22236
|
+
"data-presentation": "panel",
|
|
22237
|
+
"data-collapse-edge": resolvedAnchor.collapseEdge,
|
|
22238
|
+
"data-collapsed": collapseEnabled && collapsed ? "true" : "false",
|
|
22239
|
+
children: [
|
|
22240
|
+
/* @__PURE__ */ jsx44(
|
|
22241
|
+
"div",
|
|
22242
|
+
{
|
|
22243
|
+
className: "pano-map-overlay-surface",
|
|
22244
|
+
"aria-hidden": collapseEnabled && collapsed ? true : void 0,
|
|
22245
|
+
...collapseEnabled && collapsed ? { inert: true } : null,
|
|
22246
|
+
style: { height: "100%", width: "100%" },
|
|
22247
|
+
children: /* @__PURE__ */ jsx44(PanoMap, { ...mapProps, showCollapseControl: false })
|
|
22248
|
+
}
|
|
22249
|
+
),
|
|
22250
|
+
collapseEnabled ? /* @__PURE__ */ jsx44(
|
|
22251
|
+
"button",
|
|
22252
|
+
{
|
|
22253
|
+
type: "button",
|
|
22254
|
+
className: ["pano-map-control", "pano-overlay-anchor-toggle", toggle?.className].filter(Boolean).join(" "),
|
|
22255
|
+
"aria-label": collapsed ? "Expand map" : "Collapse map",
|
|
22256
|
+
"aria-pressed": !collapsed,
|
|
22257
|
+
style: toggle?.style,
|
|
22258
|
+
onClick: () => setCollapsed((value) => !value),
|
|
22259
|
+
children: toggle?.icon === void 0 ? /* @__PURE__ */ jsx44(
|
|
22260
|
+
"svg",
|
|
22261
|
+
{
|
|
22262
|
+
"aria-hidden": true,
|
|
22263
|
+
fill: "none",
|
|
22264
|
+
height: "16",
|
|
22265
|
+
stroke: "currentColor",
|
|
22266
|
+
strokeLinecap: "round",
|
|
22267
|
+
strokeLinejoin: "round",
|
|
22268
|
+
strokeWidth: "1.75",
|
|
22269
|
+
viewBox: "0 0 16 16",
|
|
22270
|
+
width: "16",
|
|
22271
|
+
children: /* @__PURE__ */ jsx44("path", { d: CHEVRON_PATHS2[arrow] })
|
|
22272
|
+
}
|
|
22273
|
+
) : resolveOverlayToggleIcon(toggle.icon, collapsed)
|
|
22274
|
+
}
|
|
22275
|
+
) : null
|
|
22276
|
+
]
|
|
21317
22277
|
}
|
|
21318
22278
|
);
|
|
21319
22279
|
}
|
|
@@ -21330,6 +22290,7 @@ export {
|
|
|
21330
22290
|
DEFAULT_PANO_VIDEO_PLAYBACK_RATES,
|
|
21331
22291
|
DEFAULT_WEBVR_CHROME_APPEARANCE,
|
|
21332
22292
|
DEFAULT_WEBVR_CURSOR_DWELL_MS,
|
|
22293
|
+
EMPTY_WEBVR_STATE,
|
|
21333
22294
|
GraphicHotspot,
|
|
21334
22295
|
Gyro,
|
|
21335
22296
|
IframeHotspot,
|
|
@@ -21339,11 +22300,13 @@ export {
|
|
|
21339
22300
|
MIN_PANO_CONTEXT_MENU_BACKGROUND_OPACITY,
|
|
21340
22301
|
MouseControls,
|
|
21341
22302
|
PANO_FILTER_PRESETS,
|
|
22303
|
+
PANO_OVERLAY_ALIGNS,
|
|
21342
22304
|
PanoContextMenu,
|
|
21343
22305
|
PanoEvents,
|
|
21344
22306
|
PanoFilter,
|
|
21345
22307
|
PanoMap,
|
|
21346
22308
|
PanoMapOverlay,
|
|
22309
|
+
PanoOverlay,
|
|
21347
22310
|
PanoOverlayPortalProvider,
|
|
21348
22311
|
PanoSceneMenu,
|
|
21349
22312
|
PanoVideo,
|
|
@@ -21373,9 +22336,13 @@ export {
|
|
|
21373
22336
|
headingFromVector,
|
|
21374
22337
|
horizontalFov,
|
|
21375
22338
|
imagePointToContainer,
|
|
22339
|
+
isOverlayCorner,
|
|
21376
22340
|
normalizePanoPosition,
|
|
21377
22341
|
normalizePanoYaw,
|
|
21378
22342
|
panoPositionToVector3,
|
|
22343
|
+
parseOverlayAnchor,
|
|
22344
|
+
resolveOverlayAnchor,
|
|
22345
|
+
resolveOverlayToggleIcon,
|
|
21379
22346
|
resolvePanoContextMenuEntries,
|
|
21380
22347
|
sectorRotation,
|
|
21381
22348
|
unwrapPolygonVertices,
|