@ericchen1990/pano-view 3.2.3 → 3.4.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 +64 -8
- package/README.zh-CN.md +40 -4
- package/dist/index.cjs +1318 -920
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +21 -2
- package/dist/index.d.ts +21 -2
- package/dist/index.mjs +1140 -742
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -9716,8 +9716,8 @@ function usePanoViewer() {
|
|
|
9716
9716
|
}
|
|
9717
9717
|
|
|
9718
9718
|
// src/sphere-tile/sphere-tile.tsx
|
|
9719
|
-
import { useFrame as useFrame9, useThree as
|
|
9720
|
-
import { memo, useCallback as useCallback9, useEffect as
|
|
9719
|
+
import { useFrame as useFrame9, useThree as useThree14 } from "@react-three/fiber";
|
|
9720
|
+
import { memo, useCallback as useCallback9, useEffect as useEffect23, useMemo as useMemo15, useRef as useRef23, useState as useState10 } from "react";
|
|
9721
9721
|
import { BackSide as BackSide2, Frustum, Matrix4 as Matrix42, PerspectiveCamera as PerspectiveCamera3 } from "three";
|
|
9722
9722
|
|
|
9723
9723
|
// src/asset-url.ts
|
|
@@ -9988,6 +9988,27 @@ function PanoBasicMaterial({
|
|
|
9988
9988
|
);
|
|
9989
9989
|
}
|
|
9990
9990
|
|
|
9991
|
+
// src/scene-detail.tsx
|
|
9992
|
+
import { createContext as createContext15, useContext as useContext21 } from "react";
|
|
9993
|
+
var SceneDetailContext = createContext15(null);
|
|
9994
|
+
function useSceneDetailReporter() {
|
|
9995
|
+
return useContext21(SceneDetailContext);
|
|
9996
|
+
}
|
|
9997
|
+
function viewTilesAreDrawable(textures) {
|
|
9998
|
+
return textures.length > 0 && textures.every((texture) => texture != null);
|
|
9999
|
+
}
|
|
10000
|
+
function publishSceneDetail(reporter, lastToken, ready) {
|
|
10001
|
+
if (!reporter) {
|
|
10002
|
+
return;
|
|
10003
|
+
}
|
|
10004
|
+
const token = `${reporter.generation}:${ready ? 1 : 0}`;
|
|
10005
|
+
if (lastToken.current === token) {
|
|
10006
|
+
return;
|
|
10007
|
+
}
|
|
10008
|
+
lastToken.current = token;
|
|
10009
|
+
reporter.report(ready);
|
|
10010
|
+
}
|
|
10011
|
+
|
|
9991
10012
|
// src/tile/texture-manager.ts
|
|
9992
10013
|
import {
|
|
9993
10014
|
ClampToEdgeWrapping,
|
|
@@ -10014,6 +10035,9 @@ var TileTextureManager = class {
|
|
|
10014
10035
|
this.generation = 0;
|
|
10015
10036
|
this.options = options;
|
|
10016
10037
|
}
|
|
10038
|
+
get memoryBudgetBytes() {
|
|
10039
|
+
return this.options.maxBytes;
|
|
10040
|
+
}
|
|
10017
10041
|
resume() {
|
|
10018
10042
|
this.disposed = false;
|
|
10019
10043
|
this.drain();
|
|
@@ -10081,7 +10105,7 @@ var TileTextureManager = class {
|
|
|
10081
10105
|
this.totalBytes = 0;
|
|
10082
10106
|
}
|
|
10083
10107
|
/**
|
|
10084
|
-
* Releases textures that are no longer rendered by any
|
|
10108
|
+
* Releases textures that are no longer rendered by any tile source.
|
|
10085
10109
|
* Scene transitions call this after the outgoing panorama has been
|
|
10086
10110
|
* snapshotted, so the incoming scene never competes with stale GPU tiles.
|
|
10087
10111
|
*/
|
|
@@ -10215,8 +10239,44 @@ var TileTextureManager = class {
|
|
|
10215
10239
|
}
|
|
10216
10240
|
};
|
|
10217
10241
|
|
|
10242
|
+
// src/tile/texture-manager-context.tsx
|
|
10243
|
+
import { useThree as useThree13 } from "@react-three/fiber";
|
|
10244
|
+
import {
|
|
10245
|
+
createContext as createContext16,
|
|
10246
|
+
useContext as useContext22,
|
|
10247
|
+
useEffect as useEffect21,
|
|
10248
|
+
useMemo as useMemo14
|
|
10249
|
+
} from "react";
|
|
10250
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
10251
|
+
var TileTextureManagerContext = createContext16(null);
|
|
10252
|
+
function TileTextureManagerProvider({
|
|
10253
|
+
children,
|
|
10254
|
+
maxTextureMemoryMb = 128,
|
|
10255
|
+
maxConcurrentLoads = 4
|
|
10256
|
+
}) {
|
|
10257
|
+
const gl = useThree13((state) => state.gl);
|
|
10258
|
+
const anisotropy = gl.capabilities.getMaxAnisotropy();
|
|
10259
|
+
const manager = useMemo14(
|
|
10260
|
+
() => new TileTextureManager({
|
|
10261
|
+
anisotropy,
|
|
10262
|
+
maxBytes: Math.max(1, maxTextureMemoryMb) * 1024 * 1024,
|
|
10263
|
+
concurrency: Math.max(1, Math.floor(maxConcurrentLoads)),
|
|
10264
|
+
retryCount: 1
|
|
10265
|
+
}),
|
|
10266
|
+
[anisotropy, maxConcurrentLoads, maxTextureMemoryMb]
|
|
10267
|
+
);
|
|
10268
|
+
useEffect21(() => {
|
|
10269
|
+
manager.resume();
|
|
10270
|
+
return () => manager.dispose();
|
|
10271
|
+
}, [manager]);
|
|
10272
|
+
return /* @__PURE__ */ jsx15(TileTextureManagerContext.Provider, { value: manager, children });
|
|
10273
|
+
}
|
|
10274
|
+
function useSharedTileTextureManager() {
|
|
10275
|
+
return useContext22(TileTextureManagerContext);
|
|
10276
|
+
}
|
|
10277
|
+
|
|
10218
10278
|
// src/tile/texture-hooks.ts
|
|
10219
|
-
import { useEffect as
|
|
10279
|
+
import { useEffect as useEffect22, useRef as useRef22, useState as useState9 } from "react";
|
|
10220
10280
|
import {
|
|
10221
10281
|
ClampToEdgeWrapping as ClampToEdgeWrapping2,
|
|
10222
10282
|
LinearFilter as LinearFilter2,
|
|
@@ -10227,7 +10287,7 @@ function usePreviewTexture(url, anisotropy, onError) {
|
|
|
10227
10287
|
const [texture, setTexture] = useState9(null);
|
|
10228
10288
|
const onErrorRef = useRef22(onError);
|
|
10229
10289
|
onErrorRef.current = onError;
|
|
10230
|
-
|
|
10290
|
+
useEffect22(() => {
|
|
10231
10291
|
if (!url) {
|
|
10232
10292
|
setTexture(null);
|
|
10233
10293
|
return;
|
|
@@ -10264,7 +10324,7 @@ function usePreviewTexture(url, anisotropy, onError) {
|
|
|
10264
10324
|
active = false;
|
|
10265
10325
|
};
|
|
10266
10326
|
}, [anisotropy, url]);
|
|
10267
|
-
|
|
10327
|
+
useEffect22(
|
|
10268
10328
|
() => () => {
|
|
10269
10329
|
texture?.dispose();
|
|
10270
10330
|
},
|
|
@@ -10280,7 +10340,7 @@ function useManagedTexture(manager, key, url, address) {
|
|
|
10280
10340
|
snapshot: manager.getSnapshot(key)
|
|
10281
10341
|
}));
|
|
10282
10342
|
const snapshot = managedState.manager === manager && managedState.key === key && managedState.url === url ? managedState.snapshot : manager.getSnapshot(key);
|
|
10283
|
-
|
|
10343
|
+
useEffect22(
|
|
10284
10344
|
() => manager.acquire(key, url, address, (nextSnapshot) => {
|
|
10285
10345
|
setManagedState({
|
|
10286
10346
|
manager,
|
|
@@ -10428,14 +10488,23 @@ function preferredSphereLevel(levels, height, dpr, verticalFov) {
|
|
|
10428
10488
|
}
|
|
10429
10489
|
|
|
10430
10490
|
// src/sphere-tile/sphere-tile.tsx
|
|
10431
|
-
import { jsx as
|
|
10491
|
+
import { jsx as jsx16, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
10492
|
+
function sphereTileViewShouldRefresh(input) {
|
|
10493
|
+
if (input.loadModeChanged || input.managerChanged) {
|
|
10494
|
+
return true;
|
|
10495
|
+
}
|
|
10496
|
+
if (input.elapsedMs < 100 || input.viewUnchanged) {
|
|
10497
|
+
return false;
|
|
10498
|
+
}
|
|
10499
|
+
return true;
|
|
10500
|
+
}
|
|
10432
10501
|
function SpherePatch({
|
|
10433
10502
|
address,
|
|
10434
10503
|
texture,
|
|
10435
10504
|
yawOffset,
|
|
10436
10505
|
preview = false
|
|
10437
10506
|
}) {
|
|
10438
|
-
const geometry =
|
|
10507
|
+
const geometry = useMemo15(
|
|
10439
10508
|
() => sphereTileGeometry(
|
|
10440
10509
|
address,
|
|
10441
10510
|
yawOffset,
|
|
@@ -10443,13 +10512,13 @@ function SpherePatch({
|
|
|
10443
10512
|
),
|
|
10444
10513
|
[address, yawOffset, preview]
|
|
10445
10514
|
);
|
|
10446
|
-
|
|
10447
|
-
return /* @__PURE__ */
|
|
10515
|
+
useEffect23(() => () => geometry.dispose(), [geometry]);
|
|
10516
|
+
return /* @__PURE__ */ jsx16(
|
|
10448
10517
|
"mesh",
|
|
10449
10518
|
{
|
|
10450
10519
|
geometry,
|
|
10451
10520
|
renderOrder: preview ? -1e3 : -900 + address.level,
|
|
10452
|
-
children: /* @__PURE__ */
|
|
10521
|
+
children: /* @__PURE__ */ jsx16(
|
|
10453
10522
|
PanoBasicMaterial,
|
|
10454
10523
|
{
|
|
10455
10524
|
map: texture,
|
|
@@ -10476,10 +10545,10 @@ var ManagedPatch = memo(function ManagedPatch2({
|
|
|
10476
10545
|
url,
|
|
10477
10546
|
address
|
|
10478
10547
|
);
|
|
10479
|
-
|
|
10548
|
+
useEffect23(() => {
|
|
10480
10549
|
if (snapshot.texture) ready();
|
|
10481
10550
|
}, [snapshot.texture, ready]);
|
|
10482
|
-
return snapshot.texture ? /* @__PURE__ */
|
|
10551
|
+
return snapshot.texture ? /* @__PURE__ */ jsx16(
|
|
10483
10552
|
SpherePatch,
|
|
10484
10553
|
{
|
|
10485
10554
|
address,
|
|
@@ -10507,7 +10576,7 @@ function SphereTileSource({
|
|
|
10507
10576
|
onTileError,
|
|
10508
10577
|
onLevelChange
|
|
10509
10578
|
}) {
|
|
10510
|
-
const { camera, gl, size } =
|
|
10579
|
+
const { camera, gl, size } = useThree14();
|
|
10511
10580
|
const anisotropy = gl.capabilities.getMaxAnisotropy();
|
|
10512
10581
|
const preview = usePreviewTexture(
|
|
10513
10582
|
resolveAssetUrl(baseUrl, previewUrl),
|
|
@@ -10521,14 +10590,15 @@ function SphereTileSource({
|
|
|
10521
10590
|
onLevelChange
|
|
10522
10591
|
});
|
|
10523
10592
|
callbacks.current = { onReady, onLoadProgress, onTileError, onLevelChange };
|
|
10524
|
-
const
|
|
10593
|
+
const sharedManager = useSharedTileTextureManager();
|
|
10594
|
+
const ownedBudget = Math.max(
|
|
10525
10595
|
1,
|
|
10526
10596
|
Number.isFinite(maxTextureMemoryMb) ? maxTextureMemoryMb : 128
|
|
10527
10597
|
) * 1024 * 1024;
|
|
10528
|
-
const
|
|
10598
|
+
const ownedManager = useMemo15(
|
|
10529
10599
|
() => new TileTextureManager({
|
|
10530
10600
|
anisotropy,
|
|
10531
|
-
maxBytes:
|
|
10601
|
+
maxBytes: ownedBudget,
|
|
10532
10602
|
concurrency: Math.max(
|
|
10533
10603
|
1,
|
|
10534
10604
|
Math.floor(
|
|
@@ -10542,8 +10612,10 @@ function SphereTileSource({
|
|
|
10542
10612
|
onProgress: (progress) => callbacks.current.onLoadProgress?.(progress),
|
|
10543
10613
|
onError: (error) => callbacks.current.onTileError?.(error)
|
|
10544
10614
|
}),
|
|
10545
|
-
[anisotropy,
|
|
10615
|
+
[anisotropy, ownedBudget, maxConcurrentLoads, retryCount]
|
|
10546
10616
|
);
|
|
10617
|
+
const manager = sharedManager ?? ownedManager;
|
|
10618
|
+
const budget = manager.memoryBudgetBytes;
|
|
10547
10619
|
const readyRef = useRef23(false);
|
|
10548
10620
|
const ready = useCallback9(() => {
|
|
10549
10621
|
if (!readyRef.current) {
|
|
@@ -10551,21 +10623,27 @@ function SphereTileSource({
|
|
|
10551
10623
|
callbacks.current.onReady?.();
|
|
10552
10624
|
}
|
|
10553
10625
|
}, []);
|
|
10554
|
-
|
|
10626
|
+
useEffect23(() => {
|
|
10555
10627
|
if (preview) ready();
|
|
10556
10628
|
}, [preview, ready]);
|
|
10557
|
-
|
|
10629
|
+
useEffect23(() => {
|
|
10558
10630
|
manager.resume();
|
|
10559
|
-
return () =>
|
|
10560
|
-
|
|
10561
|
-
|
|
10631
|
+
return () => {
|
|
10632
|
+
if (manager === ownedManager) {
|
|
10633
|
+
manager.dispose();
|
|
10634
|
+
return;
|
|
10635
|
+
}
|
|
10636
|
+
queueMicrotask(() => manager.releaseUnused());
|
|
10637
|
+
};
|
|
10638
|
+
}, [manager, ownedManager]);
|
|
10639
|
+
const resolveUrl = useMemo15(
|
|
10562
10640
|
() => (address) => resolveAssetUrl(
|
|
10563
10641
|
baseUrl,
|
|
10564
10642
|
resolveTileUrl ? resolveTileUrl(address) : resolveSphereTemplateUrl(urlTemplate, address, indexBase)
|
|
10565
10643
|
),
|
|
10566
10644
|
[baseUrl, resolveTileUrl, urlTemplate, indexBase]
|
|
10567
10645
|
);
|
|
10568
|
-
const candidates =
|
|
10646
|
+
const candidates = useMemo15(
|
|
10569
10647
|
() => config.levels.map(
|
|
10570
10648
|
(level, index) => sphereTileAddresses(level, index, config.tileSize).map((address) => ({
|
|
10571
10649
|
address,
|
|
@@ -10574,12 +10652,17 @@ function SphereTileSource({
|
|
|
10574
10652
|
),
|
|
10575
10653
|
[config, yawOffset]
|
|
10576
10654
|
);
|
|
10577
|
-
const previewAddress =
|
|
10655
|
+
const previewAddress = useMemo15(
|
|
10578
10656
|
() => sphereTileAddresses({ width: 2, height: 1 }, 0, 2)[0],
|
|
10579
10657
|
[]
|
|
10580
10658
|
);
|
|
10581
10659
|
const [layers, setLayers] = useState10([]);
|
|
10582
|
-
const
|
|
10660
|
+
const detailReporter = useSceneDetailReporter();
|
|
10661
|
+
const detailReporterRef = useRef23(detailReporter);
|
|
10662
|
+
detailReporterRef.current = detailReporter;
|
|
10663
|
+
const detailTokenRef = useRef23("");
|
|
10664
|
+
const targetKeysRef = useRef23([]);
|
|
10665
|
+
const scratch = useMemo15(
|
|
10583
10666
|
() => ({
|
|
10584
10667
|
camera: new PerspectiveCamera3(),
|
|
10585
10668
|
frustum: new Frustum(),
|
|
@@ -10600,56 +10683,75 @@ function SphereTileSource({
|
|
|
10600
10683
|
useFrame9(() => {
|
|
10601
10684
|
if (!(camera instanceof PerspectiveCamera3)) return;
|
|
10602
10685
|
const now = performance.now(), dpr = gl.getPixelRatio();
|
|
10603
|
-
const
|
|
10604
|
-
|
|
10605
|
-
|
|
10606
|
-
|
|
10607
|
-
|
|
10608
|
-
|
|
10609
|
-
|
|
10610
|
-
|
|
10611
|
-
|
|
10612
|
-
|
|
10613
|
-
|
|
10614
|
-
|
|
10615
|
-
|
|
10616
|
-
|
|
10617
|
-
|
|
10618
|
-
|
|
10619
|
-
scratch.
|
|
10620
|
-
scratch.
|
|
10621
|
-
|
|
10622
|
-
|
|
10623
|
-
|
|
10624
|
-
|
|
10625
|
-
|
|
10626
|
-
|
|
10627
|
-
|
|
10628
|
-
({ bounds }) => scratch.frustum.intersectsBox(bounds)
|
|
10629
|
-
).map(({ address }) => address);
|
|
10630
|
-
const bytes = addresses.reduce(
|
|
10631
|
-
(total, address) => total + address.width * address.height * 4,
|
|
10632
|
-
0
|
|
10686
|
+
const managerChanged = scratch.manager !== manager;
|
|
10687
|
+
const loadModeChanged = scratch.loadMode !== loadMode;
|
|
10688
|
+
const viewUnchanged = scratch.fov === camera.fov && scratch.width === size.width && scratch.height === size.height && scratch.dpr === dpr && scratch.quaternion.angleTo(camera.quaternion) < 1e-4;
|
|
10689
|
+
if (sphereTileViewShouldRefresh({
|
|
10690
|
+
loadModeChanged,
|
|
10691
|
+
managerChanged,
|
|
10692
|
+
elapsedMs: now - scratch.time,
|
|
10693
|
+
viewUnchanged
|
|
10694
|
+
})) {
|
|
10695
|
+
const reset = managerChanged || loadModeChanged;
|
|
10696
|
+
scratch.time = now;
|
|
10697
|
+
scratch.fov = camera.fov;
|
|
10698
|
+
scratch.width = size.width;
|
|
10699
|
+
scratch.height = size.height;
|
|
10700
|
+
scratch.dpr = dpr;
|
|
10701
|
+
scratch.quaternion.copy(camera.quaternion);
|
|
10702
|
+
scratch.manager = manager;
|
|
10703
|
+
scratch.loadMode = loadMode;
|
|
10704
|
+
scratch.camera.copy(camera, false);
|
|
10705
|
+
scratch.camera.fov = Math.min(179, camera.fov + 8);
|
|
10706
|
+
scratch.camera.updateProjectionMatrix();
|
|
10707
|
+
scratch.camera.updateMatrixWorld();
|
|
10708
|
+
scratch.matrix.multiplyMatrices(
|
|
10709
|
+
scratch.camera.projectionMatrix,
|
|
10710
|
+
scratch.camera.matrixWorldInverse
|
|
10633
10711
|
);
|
|
10634
|
-
|
|
10635
|
-
|
|
10636
|
-
|
|
10712
|
+
scratch.frustum.setFromProjectionMatrix(scratch.matrix);
|
|
10713
|
+
let level = loadMode === "preview" ? -1 : loadMode === "base" ? 0 : preferredSphereLevel(config.levels, size.height, dpr, camera.fov);
|
|
10714
|
+
const next = [];
|
|
10715
|
+
let residentBytes = 0;
|
|
10716
|
+
for (let index = 0; index <= level; index++) {
|
|
10717
|
+
const addresses = candidates[index].filter(
|
|
10718
|
+
({ bounds }) => scratch.frustum.intersectsBox(bounds)
|
|
10719
|
+
).map(({ address }) => address);
|
|
10720
|
+
const bytes = addresses.reduce(
|
|
10721
|
+
(total, address) => total + address.width * address.height * 4,
|
|
10722
|
+
0
|
|
10723
|
+
);
|
|
10724
|
+
if (residentBytes + bytes > budget) {
|
|
10725
|
+
level = index - 1;
|
|
10726
|
+
break;
|
|
10727
|
+
}
|
|
10728
|
+
residentBytes += bytes;
|
|
10729
|
+
next.push({ level: index, addresses });
|
|
10730
|
+
}
|
|
10731
|
+
const targetLayer = loadMode === "full" ? next[next.length - 1] : void 0;
|
|
10732
|
+
targetKeysRef.current = targetLayer ? targetLayer.addresses.map(
|
|
10733
|
+
(address) => `${resolveUrl(address)}\0${sphereTileKey(address)}`
|
|
10734
|
+
) : [];
|
|
10735
|
+
if (level !== scratch.level) {
|
|
10736
|
+
scratch.level = level;
|
|
10737
|
+
if (level >= 0) callbacks.current.onLevelChange?.(level);
|
|
10738
|
+
}
|
|
10739
|
+
const token = next.map((layer) => layer.addresses.map(sphereTileKey).join(",")).join(";");
|
|
10740
|
+
if (token !== scratch.token || reset) {
|
|
10741
|
+
scratch.token = token;
|
|
10742
|
+
setLayers(next);
|
|
10637
10743
|
}
|
|
10638
|
-
residentBytes += bytes;
|
|
10639
|
-
next.push({ level: index, addresses });
|
|
10640
|
-
}
|
|
10641
|
-
if (level !== scratch.level) {
|
|
10642
|
-
scratch.level = level;
|
|
10643
|
-
if (level >= 0) callbacks.current.onLevelChange?.(level);
|
|
10644
|
-
}
|
|
10645
|
-
const token = next.map((layer) => layer.addresses.map(sphereTileKey).join(",")).join(";");
|
|
10646
|
-
if (token !== scratch.token || reset) {
|
|
10647
|
-
scratch.token = token;
|
|
10648
|
-
setLayers(next);
|
|
10649
10744
|
}
|
|
10745
|
+
publishSceneDetail(
|
|
10746
|
+
detailReporterRef.current,
|
|
10747
|
+
detailTokenRef,
|
|
10748
|
+
loadMode === "full" && viewTilesAreDrawable(
|
|
10749
|
+
targetKeysRef.current.map((key) => manager.getSnapshot(key).texture)
|
|
10750
|
+
)
|
|
10751
|
+
);
|
|
10650
10752
|
});
|
|
10651
10753
|
return /* @__PURE__ */ jsxs9("group", { visible, children: [
|
|
10652
|
-
preview ? /* @__PURE__ */
|
|
10754
|
+
preview ? /* @__PURE__ */ jsx16(
|
|
10653
10755
|
SpherePatch,
|
|
10654
10756
|
{
|
|
10655
10757
|
address: previewAddress,
|
|
@@ -10659,7 +10761,7 @@ function SphereTileSource({
|
|
|
10659
10761
|
}
|
|
10660
10762
|
) : null,
|
|
10661
10763
|
loadMode !== "preview" ? layers.flatMap(
|
|
10662
|
-
(layer) => layer.addresses.map((address) => /* @__PURE__ */
|
|
10764
|
+
(layer) => layer.addresses.map((address) => /* @__PURE__ */ jsx16(
|
|
10663
10765
|
ManagedPatch,
|
|
10664
10766
|
{
|
|
10665
10767
|
address,
|
|
@@ -10675,14 +10777,14 @@ function SphereTileSource({
|
|
|
10675
10777
|
}
|
|
10676
10778
|
function SphereTile({ multires, ...props }) {
|
|
10677
10779
|
const token = typeof multires === "string" ? multires : JSON.stringify(multires);
|
|
10678
|
-
const config =
|
|
10780
|
+
const config = useMemo15(() => parseSphereMultires(multires), [token]);
|
|
10679
10781
|
const sourceKey = `${props.baseUrl}\0${token}\0${props.previewUrl}\0${props.urlTemplate ?? ""}\0${props.indexBase ?? 1}`;
|
|
10680
|
-
return /* @__PURE__ */
|
|
10782
|
+
return /* @__PURE__ */ jsx16(SphereTileSource, { ...props, config }, sourceKey);
|
|
10681
10783
|
}
|
|
10682
10784
|
|
|
10683
10785
|
// src/sphere.tsx
|
|
10684
|
-
import { useThree as
|
|
10685
|
-
import { useEffect as
|
|
10786
|
+
import { useThree as useThree15 } from "@react-three/fiber";
|
|
10787
|
+
import { useEffect as useEffect24, useMemo as useMemo16, useRef as useRef24, useState as useState11 } from "react";
|
|
10686
10788
|
import {
|
|
10687
10789
|
BackSide as BackSide3,
|
|
10688
10790
|
LinearFilter as LinearFilter3,
|
|
@@ -10692,14 +10794,14 @@ import {
|
|
|
10692
10794
|
SRGBColorSpace as SRGBColorSpace3,
|
|
10693
10795
|
TextureLoader as TextureLoader3
|
|
10694
10796
|
} from "three";
|
|
10695
|
-
import { jsx as
|
|
10797
|
+
import { jsx as jsx17, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
10696
10798
|
function useEquirectTexture(url, anisotropy, generateMipmaps, onLoad, onError) {
|
|
10697
10799
|
const [texture, setTexture] = useState11(null);
|
|
10698
10800
|
const onLoadRef = useRef24(onLoad);
|
|
10699
10801
|
const onErrorRef = useRef24(onError);
|
|
10700
10802
|
onLoadRef.current = onLoad;
|
|
10701
10803
|
onErrorRef.current = onError;
|
|
10702
|
-
|
|
10804
|
+
useEffect24(() => {
|
|
10703
10805
|
if (!url) {
|
|
10704
10806
|
setTexture(null);
|
|
10705
10807
|
return;
|
|
@@ -10738,7 +10840,7 @@ function useEquirectTexture(url, anisotropy, generateMipmaps, onLoad, onError) {
|
|
|
10738
10840
|
active = false;
|
|
10739
10841
|
};
|
|
10740
10842
|
}, [anisotropy, generateMipmaps, url]);
|
|
10741
|
-
|
|
10843
|
+
useEffect24(
|
|
10742
10844
|
() => () => {
|
|
10743
10845
|
texture?.dispose();
|
|
10744
10846
|
},
|
|
@@ -10756,9 +10858,9 @@ function Sphere({
|
|
|
10756
10858
|
onPreviewError,
|
|
10757
10859
|
visible = true
|
|
10758
10860
|
}) {
|
|
10759
|
-
const gl =
|
|
10861
|
+
const gl = useThree15((state) => state.gl);
|
|
10760
10862
|
const anisotropy = gl.capabilities.getMaxAnisotropy();
|
|
10761
|
-
const resolvedPreviewUrl =
|
|
10863
|
+
const resolvedPreviewUrl = useMemo16(
|
|
10762
10864
|
() => resolveUrlAgainstFile(src, previewUrl),
|
|
10763
10865
|
[previewUrl, src]
|
|
10764
10866
|
);
|
|
@@ -10778,10 +10880,20 @@ function Sphere({
|
|
|
10778
10880
|
);
|
|
10779
10881
|
const displayTexture = texture ?? previewTexture;
|
|
10780
10882
|
const readyRef = useRef24(false);
|
|
10781
|
-
|
|
10883
|
+
const detailReporter = useSceneDetailReporter();
|
|
10884
|
+
useEffect24(() => {
|
|
10782
10885
|
readyRef.current = false;
|
|
10783
10886
|
}, [resolvedPreviewUrl, src]);
|
|
10784
|
-
|
|
10887
|
+
useEffect24(() => {
|
|
10888
|
+
if (!detailReporter) {
|
|
10889
|
+
return;
|
|
10890
|
+
}
|
|
10891
|
+
detailReporter.report(texture != null);
|
|
10892
|
+
return () => {
|
|
10893
|
+
detailReporter.report(false);
|
|
10894
|
+
};
|
|
10895
|
+
}, [detailReporter, texture]);
|
|
10896
|
+
useEffect24(() => {
|
|
10785
10897
|
if (!displayTexture || readyRef.current) {
|
|
10786
10898
|
return;
|
|
10787
10899
|
}
|
|
@@ -10797,8 +10909,8 @@ function Sphere({
|
|
|
10797
10909
|
rotation: [0, MathUtils6.degToRad(90 + yawOffset), 0],
|
|
10798
10910
|
visible,
|
|
10799
10911
|
children: [
|
|
10800
|
-
/* @__PURE__ */
|
|
10801
|
-
/* @__PURE__ */
|
|
10912
|
+
/* @__PURE__ */ jsx17("sphereGeometry", { args: [DEFAULT_PANORAMA_RADIUS, 128, 64] }),
|
|
10913
|
+
/* @__PURE__ */ jsx17(
|
|
10802
10914
|
PanoBasicMaterial,
|
|
10803
10915
|
{
|
|
10804
10916
|
map: displayTexture,
|
|
@@ -10812,13 +10924,13 @@ function Sphere({
|
|
|
10812
10924
|
}
|
|
10813
10925
|
|
|
10814
10926
|
// src/video/pano-video.tsx
|
|
10815
|
-
import { useThree as
|
|
10927
|
+
import { useThree as useThree16 } from "@react-three/fiber";
|
|
10816
10928
|
import {
|
|
10817
10929
|
useCallback as useCallback10,
|
|
10818
|
-
useContext as
|
|
10819
|
-
useEffect as
|
|
10930
|
+
useContext as useContext23,
|
|
10931
|
+
useEffect as useEffect25,
|
|
10820
10932
|
useLayoutEffect as useLayoutEffect3,
|
|
10821
|
-
useMemo as
|
|
10933
|
+
useMemo as useMemo17,
|
|
10822
10934
|
useRef as useRef25,
|
|
10823
10935
|
useState as useState12
|
|
10824
10936
|
} from "react";
|
|
@@ -10832,7 +10944,7 @@ import {
|
|
|
10832
10944
|
TextureLoader as TextureLoader4,
|
|
10833
10945
|
VideoTexture
|
|
10834
10946
|
} from "three";
|
|
10835
|
-
import { Fragment as Fragment5, jsx as
|
|
10947
|
+
import { Fragment as Fragment5, jsx as jsx18, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
10836
10948
|
var EMPTY_TRACKS = [];
|
|
10837
10949
|
var EMPTY_RATES = DEFAULT_PANO_VIDEO_PLAYBACK_RATES;
|
|
10838
10950
|
function createEmptySnapshot() {
|
|
@@ -10916,11 +11028,11 @@ function applyEquirectangularLayout(texture, anisotropy) {
|
|
|
10916
11028
|
texture.needsUpdate = true;
|
|
10917
11029
|
}
|
|
10918
11030
|
function usePosterTexture(poster, onError) {
|
|
10919
|
-
const gl =
|
|
11031
|
+
const gl = useThree16((state) => state.gl);
|
|
10920
11032
|
const [texture, setTexture] = useState12(null);
|
|
10921
11033
|
const onErrorRef = useRef25(onError);
|
|
10922
11034
|
onErrorRef.current = onError;
|
|
10923
|
-
|
|
11035
|
+
useEffect25(() => {
|
|
10924
11036
|
let active = true;
|
|
10925
11037
|
setTexture(null);
|
|
10926
11038
|
if (!poster) {
|
|
@@ -10957,7 +11069,7 @@ function usePosterTexture(poster, onError) {
|
|
|
10957
11069
|
active = false;
|
|
10958
11070
|
};
|
|
10959
11071
|
}, [gl, poster]);
|
|
10960
|
-
|
|
11072
|
+
useEffect25(
|
|
10961
11073
|
() => () => {
|
|
10962
11074
|
texture?.dispose();
|
|
10963
11075
|
},
|
|
@@ -11015,16 +11127,16 @@ function PanoVideo({
|
|
|
11015
11127
|
onTrackChange
|
|
11016
11128
|
}) {
|
|
11017
11129
|
usePanoMediaActivationIntent(autoPlay);
|
|
11018
|
-
const gl =
|
|
11019
|
-
const host =
|
|
11020
|
-
const overlay =
|
|
11021
|
-
const variants =
|
|
11130
|
+
const gl = useThree16((state) => state.gl);
|
|
11131
|
+
const host = useContext23(PanoVideoHostContext);
|
|
11132
|
+
const overlay = useContext23(PanoChromeOverlayContext);
|
|
11133
|
+
const variants = useMemo17(
|
|
11022
11134
|
() => resolvePanoVideoVariants({ poster, src, variants: variantsProp }),
|
|
11023
11135
|
[poster, src, variantsProp]
|
|
11024
11136
|
);
|
|
11025
11137
|
const tracks = tracksProp ?? EMPTY_TRACKS;
|
|
11026
11138
|
const captionsEnabled = captions !== false;
|
|
11027
|
-
const captionAppearance =
|
|
11139
|
+
const captionAppearance = useMemo17(
|
|
11028
11140
|
() => resolvePanoVideoCaptionAppearance(
|
|
11029
11141
|
typeof captions === "object" ? captions : void 0
|
|
11030
11142
|
),
|
|
@@ -11089,7 +11201,7 @@ function PanoVideo({
|
|
|
11089
11201
|
onEndedRef.current = onEnded;
|
|
11090
11202
|
onVariantChangeRef.current = onVariantChange;
|
|
11091
11203
|
onTrackChangeRef.current = onTrackChange;
|
|
11092
|
-
const resource =
|
|
11204
|
+
const resource = useMemo17(() => {
|
|
11093
11205
|
if (typeof document === "undefined") {
|
|
11094
11206
|
return null;
|
|
11095
11207
|
}
|
|
@@ -11106,7 +11218,7 @@ function PanoVideo({
|
|
|
11106
11218
|
texture.generateMipmaps = false;
|
|
11107
11219
|
return { video, texture };
|
|
11108
11220
|
}, []);
|
|
11109
|
-
|
|
11221
|
+
useEffect25(
|
|
11110
11222
|
() => () => {
|
|
11111
11223
|
if (!resource) {
|
|
11112
11224
|
return;
|
|
@@ -11121,13 +11233,13 @@ function PanoVideo({
|
|
|
11121
11233
|
},
|
|
11122
11234
|
[resource]
|
|
11123
11235
|
);
|
|
11124
|
-
|
|
11236
|
+
useEffect25(() => {
|
|
11125
11237
|
if (!resource) {
|
|
11126
11238
|
return;
|
|
11127
11239
|
}
|
|
11128
11240
|
resource.texture.anisotropy = gl.capabilities.getMaxAnisotropy();
|
|
11129
11241
|
}, [gl, resource]);
|
|
11130
|
-
|
|
11242
|
+
useEffect25(() => {
|
|
11131
11243
|
if (!resource || !overlay?.overlayElement) {
|
|
11132
11244
|
return;
|
|
11133
11245
|
}
|
|
@@ -11202,7 +11314,7 @@ function PanoVideo({
|
|
|
11202
11314
|
captionAppearance
|
|
11203
11315
|
]
|
|
11204
11316
|
);
|
|
11205
|
-
const controller =
|
|
11317
|
+
const controller = useMemo17(
|
|
11206
11318
|
() => ({
|
|
11207
11319
|
subscribe: (onStoreChange) => {
|
|
11208
11320
|
const store = storeRef.current;
|
|
@@ -11280,10 +11392,10 @@ function PanoVideo({
|
|
|
11280
11392
|
};
|
|
11281
11393
|
emitSnapshot();
|
|
11282
11394
|
}, [emitSnapshot, playbackRates, resource]);
|
|
11283
|
-
|
|
11395
|
+
useEffect25(() => {
|
|
11284
11396
|
emitSnapshot();
|
|
11285
11397
|
}, [emitSnapshot]);
|
|
11286
|
-
|
|
11398
|
+
useEffect25(() => {
|
|
11287
11399
|
if (!resource || !activeVariant || !mediaKey) {
|
|
11288
11400
|
return;
|
|
11289
11401
|
}
|
|
@@ -11340,7 +11452,7 @@ function PanoVideo({
|
|
|
11340
11452
|
video.removeEventListener("error", handleError);
|
|
11341
11453
|
};
|
|
11342
11454
|
}, [mediaKey, resource]);
|
|
11343
|
-
|
|
11455
|
+
useEffect25(() => {
|
|
11344
11456
|
if (!resource) {
|
|
11345
11457
|
return;
|
|
11346
11458
|
}
|
|
@@ -11432,7 +11544,7 @@ function PanoVideo({
|
|
|
11432
11544
|
}
|
|
11433
11545
|
};
|
|
11434
11546
|
}, [emitSnapshot, resource]);
|
|
11435
|
-
|
|
11547
|
+
useEffect25(() => {
|
|
11436
11548
|
if (!resource) {
|
|
11437
11549
|
return;
|
|
11438
11550
|
}
|
|
@@ -11452,7 +11564,7 @@ function PanoVideo({
|
|
|
11452
11564
|
}
|
|
11453
11565
|
video.preload = preload;
|
|
11454
11566
|
}, [loop, muted, playsInline, preload, resource, volume]);
|
|
11455
|
-
|
|
11567
|
+
useEffect25(() => {
|
|
11456
11568
|
if (!resource) {
|
|
11457
11569
|
return;
|
|
11458
11570
|
}
|
|
@@ -11502,7 +11614,7 @@ function PanoVideo({
|
|
|
11502
11614
|
video.removeEventListener("ratechange", handleVolume);
|
|
11503
11615
|
};
|
|
11504
11616
|
}, [emitSnapshot, resource]);
|
|
11505
|
-
|
|
11617
|
+
useEffect25(() => {
|
|
11506
11618
|
if (!resource) {
|
|
11507
11619
|
return;
|
|
11508
11620
|
}
|
|
@@ -11537,7 +11649,7 @@ function PanoVideo({
|
|
|
11537
11649
|
video.textTracks.removeEventListener("change", applyModes);
|
|
11538
11650
|
};
|
|
11539
11651
|
}, [emitSnapshot, resource, trackId, tracks]);
|
|
11540
|
-
|
|
11652
|
+
useEffect25(() => {
|
|
11541
11653
|
if (!captionsEnabled) {
|
|
11542
11654
|
setTrackId(null);
|
|
11543
11655
|
return;
|
|
@@ -11555,8 +11667,8 @@ function PanoVideo({
|
|
|
11555
11667
|
rotation: [0, MathUtils7.degToRad(90 + yawOffset), 0],
|
|
11556
11668
|
visible,
|
|
11557
11669
|
children: [
|
|
11558
|
-
/* @__PURE__ */
|
|
11559
|
-
/* @__PURE__ */
|
|
11670
|
+
/* @__PURE__ */ jsx18("sphereGeometry", { args: [DEFAULT_PANORAMA_RADIUS, 128, 64] }),
|
|
11671
|
+
/* @__PURE__ */ jsx18(
|
|
11560
11672
|
PanoBasicMaterial,
|
|
11561
11673
|
{
|
|
11562
11674
|
map: activeTexture,
|
|
@@ -11567,19 +11679,19 @@ function PanoVideo({
|
|
|
11567
11679
|
]
|
|
11568
11680
|
}
|
|
11569
11681
|
) : null,
|
|
11570
|
-
captionsEnabled ? /* @__PURE__ */
|
|
11682
|
+
captionsEnabled ? /* @__PURE__ */ jsx18(PanoVideoCaptions, { appearance: typeof captions === "object" ? captions : void 0 }) : null
|
|
11571
11683
|
] });
|
|
11572
11684
|
}
|
|
11573
11685
|
|
|
11574
11686
|
// src/scenes.tsx
|
|
11575
|
-
import { useFrame as
|
|
11687
|
+
import { useFrame as useFrame14, useThree as useThree21 } from "@react-three/fiber";
|
|
11576
11688
|
import {
|
|
11577
11689
|
Fragment as Fragment6,
|
|
11578
11690
|
useCallback as useCallback11,
|
|
11579
|
-
useContext as
|
|
11580
|
-
useEffect as
|
|
11581
|
-
useMemo as
|
|
11582
|
-
useRef as
|
|
11691
|
+
useContext as useContext24,
|
|
11692
|
+
useEffect as useEffect30,
|
|
11693
|
+
useMemo as useMemo22,
|
|
11694
|
+
useRef as useRef30,
|
|
11583
11695
|
useState as useState14
|
|
11584
11696
|
} from "react";
|
|
11585
11697
|
import {
|
|
@@ -11634,18 +11746,34 @@ function isSnapshotTransition(preset) {
|
|
|
11634
11746
|
return preset !== "none" && preset !== "particles";
|
|
11635
11747
|
}
|
|
11636
11748
|
|
|
11637
|
-
// src/scene-transitions/
|
|
11638
|
-
import { useFrame as useFrame10, useThree as
|
|
11639
|
-
import { useEffect as
|
|
11640
|
-
import {
|
|
11641
|
-
|
|
11642
|
-
|
|
11643
|
-
|
|
11644
|
-
|
|
11645
|
-
|
|
11646
|
-
|
|
11647
|
-
|
|
11648
|
-
}
|
|
11749
|
+
// src/scene-transitions/snapshot-hold.tsx
|
|
11750
|
+
import { useFrame as useFrame10, useThree as useThree17 } from "@react-three/fiber";
|
|
11751
|
+
import { useEffect as useEffect26, useMemo as useMemo18, useRef as useRef26 } from "react";
|
|
11752
|
+
import { Vector3 as Vector310 } from "three";
|
|
11753
|
+
|
|
11754
|
+
// src/scene-transitions/overlay-utils.ts
|
|
11755
|
+
import { PlaneGeometry as PlaneGeometry2 } from "three";
|
|
11756
|
+
var OVERLAY_RENDER_ORDER = 1e4;
|
|
11757
|
+
var FULLSCREEN_PLANE = new PlaneGeometry2(1, 1);
|
|
11758
|
+
function isPerspectiveCamera(camera) {
|
|
11759
|
+
return camera.isPerspectiveCamera === true;
|
|
11760
|
+
}
|
|
11761
|
+
function placeFullscreenOverlay(mesh, camera, direction) {
|
|
11762
|
+
const distance = Math.max(camera.near * 1.1, 0.11);
|
|
11763
|
+
camera.getWorldDirection(direction);
|
|
11764
|
+
mesh.position.copy(camera.position).addScaledVector(direction, distance);
|
|
11765
|
+
mesh.quaternion.copy(camera.quaternion);
|
|
11766
|
+
const height = 2 * distance * Math.tan(camera.fov * Math.PI / 360);
|
|
11767
|
+
mesh.scale.set(height * camera.aspect, height, 1);
|
|
11768
|
+
}
|
|
11769
|
+
function overlayProgress(elapsedTime, duration, startTime) {
|
|
11770
|
+
const started = startTime ?? elapsedTime;
|
|
11771
|
+
const progress = duration === 0 ? 1 : Math.min(1, (elapsedTime - started) / duration);
|
|
11772
|
+
return { startTime: started, progress };
|
|
11773
|
+
}
|
|
11774
|
+
|
|
11775
|
+
// src/scene-transitions/snapshot-shaders.ts
|
|
11776
|
+
import { DoubleSide as DoubleSide2, ShaderMaterial as ShaderMaterial2, Vector2 as Vector24 } from "three";
|
|
11649
11777
|
|
|
11650
11778
|
// src/scene-transitions/glsl.ts
|
|
11651
11779
|
var GLSL_COMMON = `
|
|
@@ -11677,186 +11805,24 @@ float fbm(vec2 p) {
|
|
|
11677
11805
|
}
|
|
11678
11806
|
`;
|
|
11679
11807
|
|
|
11680
|
-
// src/scene-transitions/
|
|
11681
|
-
|
|
11682
|
-
var OVERLAY_RENDER_ORDER = 1e4;
|
|
11683
|
-
var FULLSCREEN_PLANE = new PlaneGeometry2(1, 1);
|
|
11684
|
-
function isPerspectiveCamera(camera) {
|
|
11685
|
-
return camera.isPerspectiveCamera === true;
|
|
11686
|
-
}
|
|
11687
|
-
function placeFullscreenOverlay(mesh, camera, direction) {
|
|
11688
|
-
const distance = Math.max(camera.near * 1.1, 0.11);
|
|
11689
|
-
camera.getWorldDirection(direction);
|
|
11690
|
-
mesh.position.copy(camera.position).addScaledVector(direction, distance);
|
|
11691
|
-
mesh.quaternion.copy(camera.quaternion);
|
|
11692
|
-
const height = 2 * distance * Math.tan(camera.fov * Math.PI / 360);
|
|
11693
|
-
mesh.scale.set(height * camera.aspect, height, 1);
|
|
11694
|
-
}
|
|
11695
|
-
function overlayProgress(elapsedTime, duration, startTime) {
|
|
11696
|
-
const started = startTime ?? elapsedTime;
|
|
11697
|
-
const progress = duration === 0 ? 1 : Math.min(1, (elapsedTime - started) / duration);
|
|
11698
|
-
return { startTime: started, progress };
|
|
11699
|
-
}
|
|
11700
|
-
|
|
11701
|
-
// src/scene-transitions/particle-overlay.tsx
|
|
11702
|
-
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
11703
|
-
var PARTICLE_GRID = 48;
|
|
11704
|
-
var PARTICLE_COUNT = PARTICLE_GRID * PARTICLE_GRID;
|
|
11705
|
-
var PARTICLE_VERTEX_SHADER = `
|
|
11706
|
-
attribute float instanceIndex;
|
|
11707
|
-
uniform float progress;
|
|
11708
|
-
uniform vec2 grid;
|
|
11808
|
+
// src/scene-transitions/snapshot-shaders.ts
|
|
11809
|
+
var SNAPSHOT_VERTEX_SHADER = `
|
|
11709
11810
|
varying vec2 vUv;
|
|
11710
|
-
varying float vAlpha;
|
|
11711
|
-
${GLSL_COMMON}
|
|
11712
|
-
|
|
11713
11811
|
void main() {
|
|
11714
|
-
|
|
11715
|
-
|
|
11716
|
-
float gy = floor(id / grid.x);
|
|
11717
|
-
vec2 cell = vec2(gx, gy);
|
|
11718
|
-
float h = hash(cell);
|
|
11719
|
-
float h2 = hash(cell + 19.2);
|
|
11720
|
-
float h3 = hash(cell + 7.7);
|
|
11721
|
-
vec2 randomDir = normalize(vec2(h, h2) * 2.0 - 1.0 + 1e-5);
|
|
11722
|
-
vec2 fromCenter = (cell + 0.5) / grid - 0.5 + 1e-5;
|
|
11723
|
-
vec2 dir = normalize(mix(randomDir, normalize(fromCenter), 0.65));
|
|
11724
|
-
float delay = h3 * 0.28;
|
|
11725
|
-
float lt = clamp((progress - delay) / max(1.0 - delay, 0.001), 0.0, 1.0);
|
|
11726
|
-
float explode = lt * lt;
|
|
11727
|
-
float scale = mix(1.0, 0.18, explode);
|
|
11728
|
-
float angle = (h * 2.0 - 1.0) * explode * 4.2;
|
|
11729
|
-
float ca = cos(angle);
|
|
11730
|
-
float sa = sin(angle);
|
|
11731
|
-
vec2 cellSize = 1.0 / grid;
|
|
11732
|
-
vec2 local = position.xy * cellSize * scale;
|
|
11733
|
-
vec2 rotated = vec2(local.x * ca - local.y * sa, local.x * sa + local.y * ca);
|
|
11734
|
-
vec2 planeCenter = (cell + 0.5) / grid - 0.5;
|
|
11735
|
-
vec2 exploded = planeCenter + dir * explode * 0.9;
|
|
11736
|
-
vec3 pos = vec3(exploded + rotated, -explode * 0.14);
|
|
11737
|
-
vUv = (cell + uv) / grid;
|
|
11738
|
-
vAlpha = 1.0 - explode;
|
|
11739
|
-
gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
|
|
11812
|
+
vUv = uv;
|
|
11813
|
+
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
11740
11814
|
}
|
|
11741
11815
|
`;
|
|
11742
|
-
var
|
|
11743
|
-
|
|
11744
|
-
|
|
11745
|
-
|
|
11816
|
+
var HEADER = `
|
|
11817
|
+
uniform sampler2D map;
|
|
11818
|
+
uniform float progress;
|
|
11819
|
+
uniform vec2 resolution;
|
|
11820
|
+
varying vec2 vUv;
|
|
11821
|
+
${GLSL_COMMON}
|
|
11746
11822
|
|
|
11747
|
-
|
|
11748
|
-
|
|
11749
|
-
|
|
11750
|
-
gl_FragColor = vec4(old.rgb, old.a * vAlpha);
|
|
11751
|
-
#include <colorspace_fragment>
|
|
11752
|
-
}
|
|
11753
|
-
`;
|
|
11754
|
-
function createParticleGeometry() {
|
|
11755
|
-
const quad = new PlaneGeometry3(1, 1);
|
|
11756
|
-
const geometry = new InstancedBufferGeometry();
|
|
11757
|
-
if (quad.index) {
|
|
11758
|
-
geometry.setIndex(quad.index.clone());
|
|
11759
|
-
}
|
|
11760
|
-
geometry.setAttribute("position", quad.attributes.position.clone());
|
|
11761
|
-
geometry.setAttribute("uv", quad.attributes.uv.clone());
|
|
11762
|
-
const indexes = new Float32Array(PARTICLE_COUNT);
|
|
11763
|
-
for (let i = 0; i < PARTICLE_COUNT; i += 1) {
|
|
11764
|
-
indexes[i] = i;
|
|
11765
|
-
}
|
|
11766
|
-
geometry.setAttribute("instanceIndex", new InstancedBufferAttribute(indexes, 1));
|
|
11767
|
-
geometry.instanceCount = PARTICLE_COUNT;
|
|
11768
|
-
quad.dispose();
|
|
11769
|
-
return geometry;
|
|
11770
|
-
}
|
|
11771
|
-
function ParticleOverlay({
|
|
11772
|
-
snapshot,
|
|
11773
|
-
transition,
|
|
11774
|
-
running,
|
|
11775
|
-
runId,
|
|
11776
|
-
onFinish
|
|
11777
|
-
}) {
|
|
11778
|
-
const { camera } = useThree16();
|
|
11779
|
-
const meshRef = useRef26(null);
|
|
11780
|
-
const startRef = useRef26(null);
|
|
11781
|
-
const finishedRef = useRef26(false);
|
|
11782
|
-
const directionRef = useRef26(new Vector310());
|
|
11783
|
-
const geometry = useMemo17(() => createParticleGeometry(), []);
|
|
11784
|
-
const material = useMemo17(
|
|
11785
|
-
() => new ShaderMaterial2({
|
|
11786
|
-
transparent: true,
|
|
11787
|
-
depthTest: false,
|
|
11788
|
-
depthWrite: false,
|
|
11789
|
-
side: DoubleSide2,
|
|
11790
|
-
uniforms: {
|
|
11791
|
-
map: { value: snapshot.texture },
|
|
11792
|
-
progress: { value: 0 },
|
|
11793
|
-
grid: { value: new Vector24(PARTICLE_GRID, PARTICLE_GRID) }
|
|
11794
|
-
},
|
|
11795
|
-
vertexShader: PARTICLE_VERTEX_SHADER,
|
|
11796
|
-
fragmentShader: PARTICLE_FRAGMENT_SHADER
|
|
11797
|
-
}),
|
|
11798
|
-
[snapshot.texture]
|
|
11799
|
-
);
|
|
11800
|
-
useEffect25(() => () => geometry.dispose(), [geometry]);
|
|
11801
|
-
useEffect25(() => () => material.dispose(), [material]);
|
|
11802
|
-
useEffect25(() => {
|
|
11803
|
-
startRef.current = null;
|
|
11804
|
-
finishedRef.current = false;
|
|
11805
|
-
material.uniforms.progress.value = 0;
|
|
11806
|
-
}, [material, runId]);
|
|
11807
|
-
useFrame10((state) => {
|
|
11808
|
-
const mesh = meshRef.current;
|
|
11809
|
-
if (!mesh || !isPerspectiveCamera(camera)) {
|
|
11810
|
-
return;
|
|
11811
|
-
}
|
|
11812
|
-
placeFullscreenOverlay(mesh, camera, directionRef.current);
|
|
11813
|
-
if (!running || finishedRef.current) {
|
|
11814
|
-
return;
|
|
11815
|
-
}
|
|
11816
|
-
const next = overlayProgress(state.clock.elapsedTime, transition.duration, startRef.current);
|
|
11817
|
-
startRef.current = next.startTime;
|
|
11818
|
-
material.uniforms.progress.value = next.progress;
|
|
11819
|
-
if (next.progress === 1) {
|
|
11820
|
-
finishedRef.current = true;
|
|
11821
|
-
onFinish();
|
|
11822
|
-
}
|
|
11823
|
-
});
|
|
11824
|
-
return /* @__PURE__ */ jsx18(
|
|
11825
|
-
"mesh",
|
|
11826
|
-
{
|
|
11827
|
-
ref: meshRef,
|
|
11828
|
-
frustumCulled: false,
|
|
11829
|
-
geometry,
|
|
11830
|
-
material,
|
|
11831
|
-
renderOrder: OVERLAY_RENDER_ORDER
|
|
11832
|
-
}
|
|
11833
|
-
);
|
|
11834
|
-
}
|
|
11835
|
-
|
|
11836
|
-
// src/scene-transitions/snapshot-overlay.tsx
|
|
11837
|
-
import { useFrame as useFrame11, useThree as useThree17 } from "@react-three/fiber";
|
|
11838
|
-
import { useEffect as useEffect26, useMemo as useMemo18, useRef as useRef27 } from "react";
|
|
11839
|
-
import { Vector3 as Vector311 } from "three";
|
|
11840
|
-
|
|
11841
|
-
// src/scene-transitions/snapshot-shaders.ts
|
|
11842
|
-
import { DoubleSide as DoubleSide3, ShaderMaterial as ShaderMaterial3, Vector2 as Vector25 } from "three";
|
|
11843
|
-
var SNAPSHOT_VERTEX_SHADER = `
|
|
11844
|
-
varying vec2 vUv;
|
|
11845
|
-
void main() {
|
|
11846
|
-
vUv = uv;
|
|
11847
|
-
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
11848
|
-
}
|
|
11849
|
-
`;
|
|
11850
|
-
var HEADER = `
|
|
11851
|
-
uniform sampler2D map;
|
|
11852
|
-
uniform float progress;
|
|
11853
|
-
uniform vec2 resolution;
|
|
11854
|
-
varying vec2 vUv;
|
|
11855
|
-
${GLSL_COMMON}
|
|
11856
|
-
|
|
11857
|
-
vec2 aspectGrid(float rows) {
|
|
11858
|
-
float aspect = resolution.x / max(resolution.y, 1.0);
|
|
11859
|
-
return vec2(max(8.0, floor(rows * aspect)), rows);
|
|
11823
|
+
vec2 aspectGrid(float rows) {
|
|
11824
|
+
float aspect = resolution.x / max(resolution.y, 1.0);
|
|
11825
|
+
return vec2(max(8.0, floor(rows * aspect)), rows);
|
|
11860
11826
|
}
|
|
11861
11827
|
|
|
11862
11828
|
vec2 gridCellId() {
|
|
@@ -12099,50 +12065,285 @@ var SNAPSHOT_FRAGMENT_SHADERS = {
|
|
|
12099
12065
|
`)
|
|
12100
12066
|
};
|
|
12101
12067
|
function createSnapshotMaterial(preset, texture) {
|
|
12102
|
-
return new
|
|
12068
|
+
return new ShaderMaterial2({
|
|
12103
12069
|
transparent: true,
|
|
12104
12070
|
depthTest: false,
|
|
12105
12071
|
depthWrite: false,
|
|
12106
|
-
side:
|
|
12072
|
+
side: DoubleSide2,
|
|
12107
12073
|
uniforms: {
|
|
12108
12074
|
map: { value: texture },
|
|
12109
12075
|
progress: { value: 0 },
|
|
12110
|
-
resolution: { value: new
|
|
12076
|
+
resolution: { value: new Vector24(1, 1) }
|
|
12111
12077
|
},
|
|
12112
12078
|
vertexShader: SNAPSHOT_VERTEX_SHADER,
|
|
12113
12079
|
fragmentShader: SNAPSHOT_FRAGMENT_SHADERS[preset]
|
|
12114
12080
|
});
|
|
12115
12081
|
}
|
|
12116
12082
|
|
|
12117
|
-
// src/scene-transitions/snapshot-
|
|
12083
|
+
// src/scene-transitions/snapshot-hold.tsx
|
|
12118
12084
|
import { jsx as jsx19, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
12119
|
-
function
|
|
12085
|
+
function SnapshotHold({ snapshot }) {
|
|
12086
|
+
const { camera, gl } = useThree17();
|
|
12087
|
+
const meshRef = useRef26(null);
|
|
12088
|
+
const directionRef = useRef26(new Vector310());
|
|
12089
|
+
const material = useMemo18(
|
|
12090
|
+
() => createSnapshotMaterial("crossfade", snapshot.texture),
|
|
12091
|
+
[snapshot.texture]
|
|
12092
|
+
);
|
|
12093
|
+
useEffect26(() => () => material.dispose(), [material]);
|
|
12094
|
+
useFrame10(() => {
|
|
12095
|
+
const mesh = meshRef.current;
|
|
12096
|
+
if (!mesh || !isPerspectiveCamera(camera)) {
|
|
12097
|
+
return;
|
|
12098
|
+
}
|
|
12099
|
+
placeFullscreenOverlay(mesh, camera, directionRef.current);
|
|
12100
|
+
const context = gl.getContext();
|
|
12101
|
+
material.uniforms.resolution.value.set(
|
|
12102
|
+
context.drawingBufferWidth,
|
|
12103
|
+
context.drawingBufferHeight
|
|
12104
|
+
);
|
|
12105
|
+
material.uniforms.progress.value = 0;
|
|
12106
|
+
});
|
|
12107
|
+
return /* @__PURE__ */ jsxs12("mesh", { frustumCulled: false, ref: meshRef, renderOrder: OVERLAY_RENDER_ORDER, children: [
|
|
12108
|
+
/* @__PURE__ */ jsx19("primitive", { attach: "geometry", object: FULLSCREEN_PLANE }),
|
|
12109
|
+
/* @__PURE__ */ jsx19("primitive", { attach: "material", object: material })
|
|
12110
|
+
] });
|
|
12111
|
+
}
|
|
12112
|
+
|
|
12113
|
+
// src/scene-transition-policy.ts
|
|
12114
|
+
function pendingSceneUsesBaseLayer(phase, isPending) {
|
|
12115
|
+
return isPending && (phase === "preloading" || phase === "capturing");
|
|
12116
|
+
}
|
|
12117
|
+
function normalizeTransitionWaitMs(value) {
|
|
12118
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) {
|
|
12119
|
+
return 0;
|
|
12120
|
+
}
|
|
12121
|
+
return value;
|
|
12122
|
+
}
|
|
12123
|
+
function planDetailHold(input) {
|
|
12124
|
+
if (input.waitMs <= 0) {
|
|
12125
|
+
return null;
|
|
12126
|
+
}
|
|
12127
|
+
return {
|
|
12128
|
+
generation: input.generation,
|
|
12129
|
+
sceneId: input.sceneId,
|
|
12130
|
+
deadline: input.now + input.waitMs
|
|
12131
|
+
};
|
|
12132
|
+
}
|
|
12133
|
+
function acceptDetailWait(wait, signal) {
|
|
12134
|
+
if (!wait) {
|
|
12135
|
+
return { wait: null, start: false };
|
|
12136
|
+
}
|
|
12137
|
+
switch (signal.kind) {
|
|
12138
|
+
case "ready":
|
|
12139
|
+
if (signal.generation !== wait.generation || signal.sceneId !== wait.sceneId) {
|
|
12140
|
+
return { wait, start: false };
|
|
12141
|
+
}
|
|
12142
|
+
return { wait: null, start: true };
|
|
12143
|
+
case "timeout":
|
|
12144
|
+
if (signal.generation !== wait.generation || signal.now < wait.deadline) {
|
|
12145
|
+
return { wait, start: false };
|
|
12146
|
+
}
|
|
12147
|
+
return { wait: null, start: true };
|
|
12148
|
+
case "cancel":
|
|
12149
|
+
if (signal.generation !== wait.generation) {
|
|
12150
|
+
return { wait, start: false };
|
|
12151
|
+
}
|
|
12152
|
+
return { wait: null, start: false };
|
|
12153
|
+
default: {
|
|
12154
|
+
const exhaustive = signal;
|
|
12155
|
+
return exhaustive;
|
|
12156
|
+
}
|
|
12157
|
+
}
|
|
12158
|
+
}
|
|
12159
|
+
function phaseAfterSnapshot(preset, hold) {
|
|
12160
|
+
if (hold) {
|
|
12161
|
+
return "awaitingDetail";
|
|
12162
|
+
}
|
|
12163
|
+
if (preset === "none") {
|
|
12164
|
+
return "idle";
|
|
12165
|
+
}
|
|
12166
|
+
return "transitioning";
|
|
12167
|
+
}
|
|
12168
|
+
|
|
12169
|
+
// src/scene-transitions/particle-overlay.tsx
|
|
12170
|
+
import { useFrame as useFrame11, useThree as useThree18 } from "@react-three/fiber";
|
|
12171
|
+
import { useEffect as useEffect27, useMemo as useMemo19, useRef as useRef27 } from "react";
|
|
12172
|
+
import {
|
|
12173
|
+
DoubleSide as DoubleSide3,
|
|
12174
|
+
InstancedBufferAttribute,
|
|
12175
|
+
InstancedBufferGeometry,
|
|
12176
|
+
PlaneGeometry as PlaneGeometry3,
|
|
12177
|
+
ShaderMaterial as ShaderMaterial3,
|
|
12178
|
+
Vector2 as Vector25,
|
|
12179
|
+
Vector3 as Vector311
|
|
12180
|
+
} from "three";
|
|
12181
|
+
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
12182
|
+
var PARTICLE_GRID = 48;
|
|
12183
|
+
var PARTICLE_COUNT = PARTICLE_GRID * PARTICLE_GRID;
|
|
12184
|
+
var PARTICLE_VERTEX_SHADER = `
|
|
12185
|
+
attribute float instanceIndex;
|
|
12186
|
+
uniform float progress;
|
|
12187
|
+
uniform vec2 grid;
|
|
12188
|
+
varying vec2 vUv;
|
|
12189
|
+
varying float vAlpha;
|
|
12190
|
+
${GLSL_COMMON}
|
|
12191
|
+
|
|
12192
|
+
void main() {
|
|
12193
|
+
float id = instanceIndex;
|
|
12194
|
+
float gx = mod(id, grid.x);
|
|
12195
|
+
float gy = floor(id / grid.x);
|
|
12196
|
+
vec2 cell = vec2(gx, gy);
|
|
12197
|
+
float h = hash(cell);
|
|
12198
|
+
float h2 = hash(cell + 19.2);
|
|
12199
|
+
float h3 = hash(cell + 7.7);
|
|
12200
|
+
vec2 randomDir = normalize(vec2(h, h2) * 2.0 - 1.0 + 1e-5);
|
|
12201
|
+
vec2 fromCenter = (cell + 0.5) / grid - 0.5 + 1e-5;
|
|
12202
|
+
vec2 dir = normalize(mix(randomDir, normalize(fromCenter), 0.65));
|
|
12203
|
+
float delay = h3 * 0.28;
|
|
12204
|
+
float lt = clamp((progress - delay) / max(1.0 - delay, 0.001), 0.0, 1.0);
|
|
12205
|
+
float explode = lt * lt;
|
|
12206
|
+
float scale = mix(1.0, 0.18, explode);
|
|
12207
|
+
float angle = (h * 2.0 - 1.0) * explode * 4.2;
|
|
12208
|
+
float ca = cos(angle);
|
|
12209
|
+
float sa = sin(angle);
|
|
12210
|
+
vec2 cellSize = 1.0 / grid;
|
|
12211
|
+
vec2 local = position.xy * cellSize * scale;
|
|
12212
|
+
vec2 rotated = vec2(local.x * ca - local.y * sa, local.x * sa + local.y * ca);
|
|
12213
|
+
vec2 planeCenter = (cell + 0.5) / grid - 0.5;
|
|
12214
|
+
vec2 exploded = planeCenter + dir * explode * 0.9;
|
|
12215
|
+
vec3 pos = vec3(exploded + rotated, -explode * 0.14);
|
|
12216
|
+
vUv = (cell + uv) / grid;
|
|
12217
|
+
vAlpha = 1.0 - explode;
|
|
12218
|
+
gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
|
|
12219
|
+
}
|
|
12220
|
+
`;
|
|
12221
|
+
var PARTICLE_FRAGMENT_SHADER = `
|
|
12222
|
+
uniform sampler2D map;
|
|
12223
|
+
varying vec2 vUv;
|
|
12224
|
+
varying float vAlpha;
|
|
12225
|
+
|
|
12226
|
+
void main() {
|
|
12227
|
+
vec4 old = texture2D(map, vUv);
|
|
12228
|
+
old.rgb *= 1.0 + 0.22 * (1.0 - vAlpha);
|
|
12229
|
+
gl_FragColor = vec4(old.rgb, old.a * vAlpha);
|
|
12230
|
+
#include <colorspace_fragment>
|
|
12231
|
+
}
|
|
12232
|
+
`;
|
|
12233
|
+
function createParticleGeometry() {
|
|
12234
|
+
const quad = new PlaneGeometry3(1, 1);
|
|
12235
|
+
const geometry = new InstancedBufferGeometry();
|
|
12236
|
+
if (quad.index) {
|
|
12237
|
+
geometry.setIndex(quad.index.clone());
|
|
12238
|
+
}
|
|
12239
|
+
geometry.setAttribute("position", quad.attributes.position.clone());
|
|
12240
|
+
geometry.setAttribute("uv", quad.attributes.uv.clone());
|
|
12241
|
+
const indexes = new Float32Array(PARTICLE_COUNT);
|
|
12242
|
+
for (let i = 0; i < PARTICLE_COUNT; i += 1) {
|
|
12243
|
+
indexes[i] = i;
|
|
12244
|
+
}
|
|
12245
|
+
geometry.setAttribute("instanceIndex", new InstancedBufferAttribute(indexes, 1));
|
|
12246
|
+
geometry.instanceCount = PARTICLE_COUNT;
|
|
12247
|
+
quad.dispose();
|
|
12248
|
+
return geometry;
|
|
12249
|
+
}
|
|
12250
|
+
function ParticleOverlay({
|
|
12120
12251
|
snapshot,
|
|
12121
12252
|
transition,
|
|
12122
12253
|
running,
|
|
12123
12254
|
runId,
|
|
12124
12255
|
onFinish
|
|
12125
12256
|
}) {
|
|
12126
|
-
const { camera
|
|
12257
|
+
const { camera } = useThree18();
|
|
12127
12258
|
const meshRef = useRef27(null);
|
|
12128
12259
|
const startRef = useRef27(null);
|
|
12129
12260
|
const finishedRef = useRef27(false);
|
|
12130
12261
|
const directionRef = useRef27(new Vector311());
|
|
12131
|
-
const
|
|
12262
|
+
const geometry = useMemo19(() => createParticleGeometry(), []);
|
|
12263
|
+
const material = useMemo19(
|
|
12264
|
+
() => new ShaderMaterial3({
|
|
12265
|
+
transparent: true,
|
|
12266
|
+
depthTest: false,
|
|
12267
|
+
depthWrite: false,
|
|
12268
|
+
side: DoubleSide3,
|
|
12269
|
+
uniforms: {
|
|
12270
|
+
map: { value: snapshot.texture },
|
|
12271
|
+
progress: { value: 0 },
|
|
12272
|
+
grid: { value: new Vector25(PARTICLE_GRID, PARTICLE_GRID) }
|
|
12273
|
+
},
|
|
12274
|
+
vertexShader: PARTICLE_VERTEX_SHADER,
|
|
12275
|
+
fragmentShader: PARTICLE_FRAGMENT_SHADER
|
|
12276
|
+
}),
|
|
12277
|
+
[snapshot.texture]
|
|
12278
|
+
);
|
|
12279
|
+
useEffect27(() => () => geometry.dispose(), [geometry]);
|
|
12280
|
+
useEffect27(() => () => material.dispose(), [material]);
|
|
12281
|
+
useEffect27(() => {
|
|
12282
|
+
startRef.current = null;
|
|
12283
|
+
finishedRef.current = false;
|
|
12284
|
+
material.uniforms.progress.value = 0;
|
|
12285
|
+
}, [material, runId]);
|
|
12286
|
+
useFrame11((state) => {
|
|
12287
|
+
const mesh = meshRef.current;
|
|
12288
|
+
if (!mesh || !isPerspectiveCamera(camera)) {
|
|
12289
|
+
return;
|
|
12290
|
+
}
|
|
12291
|
+
placeFullscreenOverlay(mesh, camera, directionRef.current);
|
|
12292
|
+
if (!running || finishedRef.current) {
|
|
12293
|
+
return;
|
|
12294
|
+
}
|
|
12295
|
+
const next = overlayProgress(state.clock.elapsedTime, transition.duration, startRef.current);
|
|
12296
|
+
startRef.current = next.startTime;
|
|
12297
|
+
material.uniforms.progress.value = next.progress;
|
|
12298
|
+
if (next.progress === 1) {
|
|
12299
|
+
finishedRef.current = true;
|
|
12300
|
+
onFinish();
|
|
12301
|
+
}
|
|
12302
|
+
});
|
|
12303
|
+
return /* @__PURE__ */ jsx20(
|
|
12304
|
+
"mesh",
|
|
12305
|
+
{
|
|
12306
|
+
ref: meshRef,
|
|
12307
|
+
frustumCulled: false,
|
|
12308
|
+
geometry,
|
|
12309
|
+
material,
|
|
12310
|
+
renderOrder: OVERLAY_RENDER_ORDER
|
|
12311
|
+
}
|
|
12312
|
+
);
|
|
12313
|
+
}
|
|
12314
|
+
|
|
12315
|
+
// src/scene-transitions/snapshot-overlay.tsx
|
|
12316
|
+
import { useFrame as useFrame12, useThree as useThree19 } from "@react-three/fiber";
|
|
12317
|
+
import { useEffect as useEffect28, useMemo as useMemo20, useRef as useRef28 } from "react";
|
|
12318
|
+
import { Vector3 as Vector312 } from "three";
|
|
12319
|
+
import { jsx as jsx21, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
12320
|
+
function SnapshotOverlay({
|
|
12321
|
+
snapshot,
|
|
12322
|
+
transition,
|
|
12323
|
+
running,
|
|
12324
|
+
runId,
|
|
12325
|
+
onFinish
|
|
12326
|
+
}) {
|
|
12327
|
+
const { camera, gl } = useThree19();
|
|
12328
|
+
const meshRef = useRef28(null);
|
|
12329
|
+
const startRef = useRef28(null);
|
|
12330
|
+
const finishedRef = useRef28(false);
|
|
12331
|
+
const directionRef = useRef28(new Vector312());
|
|
12332
|
+
const material = useMemo20(() => {
|
|
12132
12333
|
if (!isSnapshotTransition(transition.preset)) {
|
|
12133
12334
|
return null;
|
|
12134
12335
|
}
|
|
12135
12336
|
return createSnapshotMaterial(transition.preset, snapshot.texture);
|
|
12136
12337
|
}, [snapshot.texture, transition.preset]);
|
|
12137
|
-
|
|
12138
|
-
|
|
12338
|
+
useEffect28(() => () => material?.dispose(), [material]);
|
|
12339
|
+
useEffect28(() => {
|
|
12139
12340
|
startRef.current = null;
|
|
12140
12341
|
finishedRef.current = false;
|
|
12141
12342
|
if (material) {
|
|
12142
12343
|
material.uniforms.progress.value = 0;
|
|
12143
12344
|
}
|
|
12144
12345
|
}, [material, runId]);
|
|
12145
|
-
|
|
12346
|
+
useFrame12((state) => {
|
|
12146
12347
|
const mesh = meshRef.current;
|
|
12147
12348
|
if (!mesh || !material || !isPerspectiveCamera(camera)) {
|
|
12148
12349
|
return;
|
|
@@ -12164,21 +12365,21 @@ function SnapshotOverlay({
|
|
|
12164
12365
|
if (!material) {
|
|
12165
12366
|
return null;
|
|
12166
12367
|
}
|
|
12167
|
-
return /* @__PURE__ */
|
|
12168
|
-
/* @__PURE__ */
|
|
12169
|
-
/* @__PURE__ */
|
|
12368
|
+
return /* @__PURE__ */ jsxs13("mesh", { ref: meshRef, renderOrder: OVERLAY_RENDER_ORDER, frustumCulled: false, children: [
|
|
12369
|
+
/* @__PURE__ */ jsx21("primitive", { attach: "geometry", object: FULLSCREEN_PLANE }),
|
|
12370
|
+
/* @__PURE__ */ jsx21("primitive", { attach: "material", object: material })
|
|
12170
12371
|
] });
|
|
12171
12372
|
}
|
|
12172
12373
|
|
|
12173
12374
|
// src/scene-transitions/transition-overlay.tsx
|
|
12174
|
-
import { jsx as
|
|
12375
|
+
import { jsx as jsx22 } from "react/jsx-runtime";
|
|
12175
12376
|
function TransitionOverlay(props) {
|
|
12176
12377
|
const { preset } = props.transition;
|
|
12177
12378
|
switch (preset) {
|
|
12178
12379
|
case "none":
|
|
12179
12380
|
return null;
|
|
12180
12381
|
case "particles":
|
|
12181
|
-
return /* @__PURE__ */
|
|
12382
|
+
return /* @__PURE__ */ jsx22(ParticleOverlay, { ...props });
|
|
12182
12383
|
case "crossfade":
|
|
12183
12384
|
case "zoom":
|
|
12184
12385
|
case "blackout":
|
|
@@ -12206,7 +12407,7 @@ function TransitionOverlay(props) {
|
|
|
12206
12407
|
case "zoomBlur":
|
|
12207
12408
|
case "hexDissolve":
|
|
12208
12409
|
case "filmBurn":
|
|
12209
|
-
return /* @__PURE__ */
|
|
12410
|
+
return /* @__PURE__ */ jsx22(SnapshotOverlay, { ...props });
|
|
12210
12411
|
default: {
|
|
12211
12412
|
const exhaustive = preset;
|
|
12212
12413
|
void exhaustive;
|
|
@@ -12215,53 +12416,15 @@ function TransitionOverlay(props) {
|
|
|
12215
12416
|
}
|
|
12216
12417
|
}
|
|
12217
12418
|
|
|
12218
|
-
// src/tile/texture-manager-context.tsx
|
|
12219
|
-
import { useThree as useThree18 } from "@react-three/fiber";
|
|
12220
|
-
import {
|
|
12221
|
-
createContext as createContext15,
|
|
12222
|
-
useContext as useContext22,
|
|
12223
|
-
useEffect as useEffect27,
|
|
12224
|
-
useMemo as useMemo19
|
|
12225
|
-
} from "react";
|
|
12226
|
-
import { jsx as jsx21 } from "react/jsx-runtime";
|
|
12227
|
-
var TileTextureManagerContext = createContext15(
|
|
12228
|
-
null
|
|
12229
|
-
);
|
|
12230
|
-
function TileTextureManagerProvider({
|
|
12231
|
-
children,
|
|
12232
|
-
maxTextureMemoryMb = 128,
|
|
12233
|
-
maxConcurrentLoads = 4
|
|
12234
|
-
}) {
|
|
12235
|
-
const gl = useThree18((state) => state.gl);
|
|
12236
|
-
const anisotropy = gl.capabilities.getMaxAnisotropy();
|
|
12237
|
-
const manager = useMemo19(
|
|
12238
|
-
() => new TileTextureManager({
|
|
12239
|
-
anisotropy,
|
|
12240
|
-
maxBytes: Math.max(1, maxTextureMemoryMb) * 1024 * 1024,
|
|
12241
|
-
concurrency: Math.max(1, Math.floor(maxConcurrentLoads)),
|
|
12242
|
-
retryCount: 1
|
|
12243
|
-
}),
|
|
12244
|
-
[anisotropy, maxConcurrentLoads, maxTextureMemoryMb]
|
|
12245
|
-
);
|
|
12246
|
-
useEffect27(() => {
|
|
12247
|
-
manager.resume();
|
|
12248
|
-
return () => manager.dispose();
|
|
12249
|
-
}, [manager]);
|
|
12250
|
-
return /* @__PURE__ */ jsx21(TileTextureManagerContext.Provider, { value: manager, children });
|
|
12251
|
-
}
|
|
12252
|
-
function useSharedTileTextureManager() {
|
|
12253
|
-
return useContext22(TileTextureManagerContext);
|
|
12254
|
-
}
|
|
12255
|
-
|
|
12256
12419
|
// src/tile/tile.tsx
|
|
12257
|
-
import { useFrame as
|
|
12258
|
-
import { memo as memo2, useEffect as
|
|
12420
|
+
import { useFrame as useFrame13, useThree as useThree20 } from "@react-three/fiber";
|
|
12421
|
+
import { memo as memo2, useEffect as useEffect29, useMemo as useMemo21, useRef as useRef29, useState as useState13 } from "react";
|
|
12259
12422
|
import {
|
|
12260
12423
|
Frustum as Frustum2,
|
|
12261
12424
|
Matrix4 as Matrix43,
|
|
12262
12425
|
PlaneGeometry as PlaneGeometry4,
|
|
12263
12426
|
PerspectiveCamera as PerspectiveCamera5,
|
|
12264
|
-
Vector3 as
|
|
12427
|
+
Vector3 as Vector314
|
|
12265
12428
|
} from "three";
|
|
12266
12429
|
|
|
12267
12430
|
// src/tile/face-layout.ts
|
|
@@ -12269,7 +12432,7 @@ import {
|
|
|
12269
12432
|
Box3 as Box32,
|
|
12270
12433
|
Euler as Euler3,
|
|
12271
12434
|
Quaternion as Quaternion2,
|
|
12272
|
-
Vector3 as
|
|
12435
|
+
Vector3 as Vector313
|
|
12273
12436
|
} from "three";
|
|
12274
12437
|
var CUBE_FACES = ["f", "r", "b", "l", "u", "d"];
|
|
12275
12438
|
var PREVIEW_FACE_ORDER = ["l", "f", "r", "b", "u", "d"];
|
|
@@ -12333,12 +12496,12 @@ function getTileBoundingBox(address, radius = CUBE_RADIUS) {
|
|
|
12333
12496
|
const halfWidth = local.width / 2;
|
|
12334
12497
|
const halfHeight = local.height / 2;
|
|
12335
12498
|
const quaternion = getFaceQuaternion(address.face);
|
|
12336
|
-
const position = new
|
|
12499
|
+
const position = new Vector313(...transform.position);
|
|
12337
12500
|
const corners = [
|
|
12338
|
-
new
|
|
12339
|
-
new
|
|
12340
|
-
new
|
|
12341
|
-
new
|
|
12501
|
+
new Vector313(local.x - halfWidth, local.y - halfHeight, 0),
|
|
12502
|
+
new Vector313(local.x + halfWidth, local.y - halfHeight, 0),
|
|
12503
|
+
new Vector313(local.x - halfWidth, local.y + halfHeight, 0),
|
|
12504
|
+
new Vector313(local.x + halfWidth, local.y + halfHeight, 0)
|
|
12342
12505
|
];
|
|
12343
12506
|
for (const corner of corners) {
|
|
12344
12507
|
corner.applyQuaternion(quaternion).add(position);
|
|
@@ -12446,11 +12609,27 @@ function resolveTemplateUrl(template, address) {
|
|
|
12446
12609
|
}
|
|
12447
12610
|
|
|
12448
12611
|
// src/tile/tile.tsx
|
|
12449
|
-
import { jsx as
|
|
12612
|
+
import { jsx as jsx23, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
12450
12613
|
var MAX_LOD_UPDATE_INTERVAL_MS = 100;
|
|
12451
12614
|
var FAST_ROTATION_THRESHOLD_RADIANS = Math.PI / 180;
|
|
12452
12615
|
var FAST_FOV_THRESHOLD_DEGREES = 0.5;
|
|
12453
12616
|
var VIEW_CHANGE_EPSILON = 1e-4;
|
|
12617
|
+
function decideTileLodUpdate(input) {
|
|
12618
|
+
if (input.loadMode === "preview") {
|
|
12619
|
+
return false;
|
|
12620
|
+
}
|
|
12621
|
+
const loadModeChanged = input.loadMode !== input.trackedLoadMode;
|
|
12622
|
+
const viewChanged = input.visibilityDirty || loadModeChanged || input.viewportChanged || input.rotationDelta > VIEW_CHANGE_EPSILON || input.fovDelta > VIEW_CHANGE_EPSILON;
|
|
12623
|
+
if (!viewChanged) {
|
|
12624
|
+
return false;
|
|
12625
|
+
}
|
|
12626
|
+
const movingQuickly = input.rotationDelta >= FAST_ROTATION_THRESHOLD_RADIANS || input.fovDelta >= FAST_FOV_THRESHOLD_DEGREES;
|
|
12627
|
+
const immediate = input.visibilityDirty || loadModeChanged || input.viewportChanged || movingQuickly;
|
|
12628
|
+
if (!immediate && input.now - input.lastUpdateAt < MAX_LOD_UPDATE_INTERVAL_MS) {
|
|
12629
|
+
return false;
|
|
12630
|
+
}
|
|
12631
|
+
return true;
|
|
12632
|
+
}
|
|
12454
12633
|
var VISIBILITY_FOV_PADDING_DEGREES = 8;
|
|
12455
12634
|
var PREVIEW_RADIUS = CUBE_RADIUS + 0.05;
|
|
12456
12635
|
var SHARED_TILE_GEOMETRY = new PlaneGeometry4(1, 1);
|
|
@@ -12459,7 +12638,7 @@ function PreviewFace({
|
|
|
12459
12638
|
texture,
|
|
12460
12639
|
faceOrder
|
|
12461
12640
|
}) {
|
|
12462
|
-
const geometry =
|
|
12641
|
+
const geometry = useMemo21(() => {
|
|
12463
12642
|
const nextGeometry = new PlaneGeometry4(
|
|
12464
12643
|
PREVIEW_RADIUS * 2,
|
|
12465
12644
|
PREVIEW_RADIUS * 2
|
|
@@ -12474,21 +12653,21 @@ function PreviewFace({
|
|
|
12474
12653
|
uv.needsUpdate = true;
|
|
12475
12654
|
return nextGeometry;
|
|
12476
12655
|
}, [face, faceOrder]);
|
|
12477
|
-
|
|
12656
|
+
useEffect29(
|
|
12478
12657
|
() => () => {
|
|
12479
12658
|
geometry.dispose();
|
|
12480
12659
|
},
|
|
12481
12660
|
[geometry]
|
|
12482
12661
|
);
|
|
12483
12662
|
const transform = getFaceTransform(face, PREVIEW_RADIUS);
|
|
12484
|
-
return /* @__PURE__ */
|
|
12663
|
+
return /* @__PURE__ */ jsx23(
|
|
12485
12664
|
"mesh",
|
|
12486
12665
|
{
|
|
12487
12666
|
geometry,
|
|
12488
12667
|
position: transform.position,
|
|
12489
12668
|
renderOrder: -100,
|
|
12490
12669
|
rotation: transform.rotation,
|
|
12491
|
-
children: /* @__PURE__ */
|
|
12670
|
+
children: /* @__PURE__ */ jsx23(
|
|
12492
12671
|
PanoBasicMaterial,
|
|
12493
12672
|
{
|
|
12494
12673
|
depthTest: false,
|
|
@@ -12504,7 +12683,7 @@ function PreviewCube({
|
|
|
12504
12683
|
texture,
|
|
12505
12684
|
faceOrder
|
|
12506
12685
|
}) {
|
|
12507
|
-
return CUBE_FACES.map((face) => /* @__PURE__ */
|
|
12686
|
+
return CUBE_FACES.map((face) => /* @__PURE__ */ jsx23(
|
|
12508
12687
|
PreviewFace,
|
|
12509
12688
|
{
|
|
12510
12689
|
face,
|
|
@@ -12528,14 +12707,14 @@ var TileMesh = memo2(function TileMesh2({
|
|
|
12528
12707
|
if (!snapshot.texture) {
|
|
12529
12708
|
return null;
|
|
12530
12709
|
}
|
|
12531
|
-
return /* @__PURE__ */
|
|
12710
|
+
return /* @__PURE__ */ jsx23("group", { position: transform.position, rotation: transform.rotation, children: /* @__PURE__ */ jsx23(
|
|
12532
12711
|
"mesh",
|
|
12533
12712
|
{
|
|
12534
12713
|
geometry: SHARED_TILE_GEOMETRY,
|
|
12535
12714
|
position: [layout.x, layout.y, 0],
|
|
12536
12715
|
renderOrder,
|
|
12537
12716
|
scale: [layout.width, layout.height, 1],
|
|
12538
|
-
children: /* @__PURE__ */
|
|
12717
|
+
children: /* @__PURE__ */ jsx23(
|
|
12539
12718
|
PanoBasicMaterial,
|
|
12540
12719
|
{
|
|
12541
12720
|
depthTest: false,
|
|
@@ -12552,7 +12731,7 @@ var TileLayerMeshes = memo2(function TileLayerMeshes2({
|
|
|
12552
12731
|
manager,
|
|
12553
12732
|
resolveUrl
|
|
12554
12733
|
}) {
|
|
12555
|
-
return layer.addresses.map((address) => /* @__PURE__ */
|
|
12734
|
+
return layer.addresses.map((address) => /* @__PURE__ */ jsx23(
|
|
12556
12735
|
TileMesh,
|
|
12557
12736
|
{
|
|
12558
12737
|
address,
|
|
@@ -12652,8 +12831,8 @@ function parentAddresses(child, parentLevel, parentFaceSize, tileSize) {
|
|
|
12652
12831
|
return addresses;
|
|
12653
12832
|
}
|
|
12654
12833
|
function centerFacingAddress(candidates, camera) {
|
|
12655
|
-
const direction = camera.getWorldDirection(new
|
|
12656
|
-
const center = new
|
|
12834
|
+
const direction = camera.getWorldDirection(new Vector314());
|
|
12835
|
+
const center = new Vector314();
|
|
12657
12836
|
let bestCandidate = candidates[0];
|
|
12658
12837
|
let bestAlignment = -Infinity;
|
|
12659
12838
|
for (const candidate of candidates) {
|
|
@@ -12718,11 +12897,11 @@ function Tile({
|
|
|
12718
12897
|
onTileError,
|
|
12719
12898
|
onLevelChange
|
|
12720
12899
|
}) {
|
|
12721
|
-
const { camera, gl, size } =
|
|
12722
|
-
const multiresConfig =
|
|
12900
|
+
const { camera, gl, size } = useThree20();
|
|
12901
|
+
const multiresConfig = useMemo21(() => parseMultires(multires), [multires]);
|
|
12723
12902
|
const { levels, tileSize } = multiresConfig;
|
|
12724
12903
|
const multiresToken = `${tileSize}:${levels.join(",")}`;
|
|
12725
|
-
const candidatesByLevel =
|
|
12904
|
+
const candidatesByLevel = useMemo21(
|
|
12726
12905
|
() => buildTileCandidates(levels, tileSize),
|
|
12727
12906
|
[levels, tileSize]
|
|
12728
12907
|
);
|
|
@@ -12734,13 +12913,13 @@ function Tile({
|
|
|
12734
12913
|
onPreviewError
|
|
12735
12914
|
);
|
|
12736
12915
|
const sharedManager = useSharedTileTextureManager();
|
|
12737
|
-
const progressRef =
|
|
12738
|
-
const errorRef =
|
|
12739
|
-
const levelChangeRef =
|
|
12916
|
+
const progressRef = useRef29(onLoadProgress);
|
|
12917
|
+
const errorRef = useRef29(onTileError);
|
|
12918
|
+
const levelChangeRef = useRef29(onLevelChange);
|
|
12740
12919
|
progressRef.current = onLoadProgress;
|
|
12741
12920
|
errorRef.current = onTileError;
|
|
12742
12921
|
levelChangeRef.current = onLevelChange;
|
|
12743
|
-
const ownedManager =
|
|
12922
|
+
const ownedManager = useMemo21(
|
|
12744
12923
|
() => new TileTextureManager({
|
|
12745
12924
|
anisotropy,
|
|
12746
12925
|
maxBytes: Math.max(1, maxTextureMemoryMb) * 1024 * 1024,
|
|
@@ -12761,7 +12940,7 @@ function Tile({
|
|
|
12761
12940
|
]
|
|
12762
12941
|
);
|
|
12763
12942
|
const manager = sharedManager ?? ownedManager;
|
|
12764
|
-
|
|
12943
|
+
useEffect29(() => {
|
|
12765
12944
|
manager.resume();
|
|
12766
12945
|
return () => {
|
|
12767
12946
|
if (manager === ownedManager) {
|
|
@@ -12771,11 +12950,11 @@ function Tile({
|
|
|
12771
12950
|
queueMicrotask(() => manager.releaseUnused());
|
|
12772
12951
|
};
|
|
12773
12952
|
}, [manager, ownedManager]);
|
|
12774
|
-
const readyRef =
|
|
12775
|
-
|
|
12953
|
+
const readyRef = useRef29(false);
|
|
12954
|
+
useEffect29(() => {
|
|
12776
12955
|
readyRef.current = false;
|
|
12777
12956
|
}, [effectivePreviewUrl]);
|
|
12778
|
-
|
|
12957
|
+
useEffect29(() => {
|
|
12779
12958
|
if (!previewTexture || readyRef.current) {
|
|
12780
12959
|
return;
|
|
12781
12960
|
}
|
|
@@ -12783,7 +12962,7 @@ function Tile({
|
|
|
12783
12962
|
onReady?.();
|
|
12784
12963
|
}, [onReady, previewTexture]);
|
|
12785
12964
|
const template = urlTemplate ?? buildDefaultTileUrlTemplate();
|
|
12786
|
-
const resolveUrl =
|
|
12965
|
+
const resolveUrl = useMemo21(
|
|
12787
12966
|
() => (address) => {
|
|
12788
12967
|
const relativePath = resolveTileUrl ? resolveTileUrl(address) : resolveTemplateUrl(template, address);
|
|
12789
12968
|
return resolveRelativeTileUrl(baseUrl, relativePath);
|
|
@@ -12791,23 +12970,29 @@ function Tile({
|
|
|
12791
12970
|
[baseUrl, resolveTileUrl, template]
|
|
12792
12971
|
);
|
|
12793
12972
|
const [layers, setLayers] = useState13([]);
|
|
12794
|
-
const layerTokenRef =
|
|
12795
|
-
const currentLevelRef =
|
|
12796
|
-
const lastUpdateAtRef =
|
|
12797
|
-
const visibilityDirtyRef =
|
|
12798
|
-
const lastVisibilityQuaternionRef =
|
|
12799
|
-
const lastVisibilityFovRef =
|
|
12800
|
-
const lastViewportRef =
|
|
12801
|
-
const frustumRef =
|
|
12802
|
-
const projectionMatrixRef =
|
|
12803
|
-
const visibilityCameraRef =
|
|
12804
|
-
|
|
12973
|
+
const layerTokenRef = useRef29("");
|
|
12974
|
+
const currentLevelRef = useRef29(1);
|
|
12975
|
+
const lastUpdateAtRef = useRef29(-Infinity);
|
|
12976
|
+
const visibilityDirtyRef = useRef29(true);
|
|
12977
|
+
const lastVisibilityQuaternionRef = useRef29(camera.quaternion.clone());
|
|
12978
|
+
const lastVisibilityFovRef = useRef29(Number.NaN);
|
|
12979
|
+
const lastViewportRef = useRef29({ width: 0, height: 0, dpr: 0 });
|
|
12980
|
+
const frustumRef = useRef29(new Frustum2());
|
|
12981
|
+
const projectionMatrixRef = useRef29(new Matrix43());
|
|
12982
|
+
const visibilityCameraRef = useRef29(new PerspectiveCamera5());
|
|
12983
|
+
const trackedLoadModeRef = useRef29(loadMode);
|
|
12984
|
+
const targetKeysRef = useRef29([]);
|
|
12985
|
+
const detailTokenRef = useRef29("");
|
|
12986
|
+
const detailReporter = useSceneDetailReporter();
|
|
12987
|
+
const detailReporterRef = useRef29(detailReporter);
|
|
12988
|
+
detailReporterRef.current = detailReporter;
|
|
12989
|
+
useEffect29(() => {
|
|
12805
12990
|
currentLevelRef.current = 1;
|
|
12806
12991
|
layerTokenRef.current = "";
|
|
12807
12992
|
visibilityDirtyRef.current = true;
|
|
12808
12993
|
setLayers([]);
|
|
12809
12994
|
}, [manager, multiresToken]);
|
|
12810
|
-
|
|
12995
|
+
useEffect29(() => {
|
|
12811
12996
|
if (loadMode !== "preview") {
|
|
12812
12997
|
return;
|
|
12813
12998
|
}
|
|
@@ -12821,11 +13006,14 @@ function Tile({
|
|
|
12821
13006
|
setLayers(nextLayers);
|
|
12822
13007
|
}
|
|
12823
13008
|
};
|
|
12824
|
-
|
|
12825
|
-
if (
|
|
13009
|
+
useFrame13(() => {
|
|
13010
|
+
if (!(camera instanceof PerspectiveCamera5)) {
|
|
12826
13011
|
return;
|
|
12827
13012
|
}
|
|
12828
|
-
if (
|
|
13013
|
+
if (loadMode === "preview") {
|
|
13014
|
+
trackedLoadModeRef.current = "preview";
|
|
13015
|
+
targetKeysRef.current = [];
|
|
13016
|
+
publishSceneDetail(detailReporterRef.current, detailTokenRef, false);
|
|
12829
13017
|
return;
|
|
12830
13018
|
}
|
|
12831
13019
|
const now = performance.now();
|
|
@@ -12836,60 +13024,75 @@ function Tile({
|
|
|
12836
13024
|
const fovDelta = Number.isFinite(lastVisibilityFovRef.current) ? Math.abs(camera.fov - lastVisibilityFovRef.current) : Infinity;
|
|
12837
13025
|
const lastViewport = lastViewportRef.current;
|
|
12838
13026
|
const viewportChanged = lastViewport.width !== size.width || lastViewport.height !== size.height || lastViewport.dpr !== pixelRatio;
|
|
12839
|
-
const
|
|
12840
|
-
|
|
12841
|
-
|
|
12842
|
-
|
|
12843
|
-
|
|
12844
|
-
|
|
12845
|
-
|
|
12846
|
-
|
|
12847
|
-
|
|
12848
|
-
|
|
12849
|
-
|
|
12850
|
-
|
|
12851
|
-
|
|
12852
|
-
|
|
12853
|
-
|
|
12854
|
-
|
|
12855
|
-
|
|
12856
|
-
|
|
12857
|
-
|
|
12858
|
-
|
|
12859
|
-
|
|
12860
|
-
|
|
12861
|
-
|
|
12862
|
-
|
|
12863
|
-
|
|
12864
|
-
camera
|
|
12865
|
-
|
|
12866
|
-
|
|
12867
|
-
|
|
12868
|
-
|
|
12869
|
-
|
|
12870
|
-
|
|
12871
|
-
|
|
12872
|
-
|
|
12873
|
-
|
|
12874
|
-
|
|
12875
|
-
|
|
12876
|
-
|
|
12877
|
-
|
|
12878
|
-
|
|
13027
|
+
const updateLod = decideTileLodUpdate({
|
|
13028
|
+
loadMode,
|
|
13029
|
+
trackedLoadMode: trackedLoadModeRef.current,
|
|
13030
|
+
now,
|
|
13031
|
+
lastUpdateAt: lastUpdateAtRef.current,
|
|
13032
|
+
visibilityDirty: visibilityDirtyRef.current,
|
|
13033
|
+
viewportChanged,
|
|
13034
|
+
rotationDelta,
|
|
13035
|
+
fovDelta
|
|
13036
|
+
});
|
|
13037
|
+
if (updateLod) {
|
|
13038
|
+
trackedLoadModeRef.current = loadMode;
|
|
13039
|
+
lastUpdateAtRef.current = now;
|
|
13040
|
+
const targetLevel = loadMode === "base" ? 1 : getPreferredLevel(
|
|
13041
|
+
levels,
|
|
13042
|
+
size.height,
|
|
13043
|
+
pixelRatio,
|
|
13044
|
+
camera.fov,
|
|
13045
|
+
currentLevelRef.current
|
|
13046
|
+
);
|
|
13047
|
+
if (targetLevel !== currentLevelRef.current) {
|
|
13048
|
+
currentLevelRef.current = targetLevel;
|
|
13049
|
+
levelChangeRef.current?.(targetLevel);
|
|
13050
|
+
}
|
|
13051
|
+
const visibilityCamera = visibilityCameraRef.current;
|
|
13052
|
+
visibilityCamera.copy(camera, false);
|
|
13053
|
+
visibilityCamera.fov = Math.min(
|
|
13054
|
+
179,
|
|
13055
|
+
camera.fov + VISIBILITY_FOV_PADDING_DEGREES
|
|
13056
|
+
);
|
|
13057
|
+
visibilityCamera.aspect = camera.aspect;
|
|
13058
|
+
updateVisibilityFrustum(
|
|
13059
|
+
visibilityCamera,
|
|
13060
|
+
projectionMatrixRef.current,
|
|
13061
|
+
frustumRef.current
|
|
13062
|
+
);
|
|
13063
|
+
const nextLayers = buildLayers(
|
|
13064
|
+
targetLevel,
|
|
13065
|
+
levels,
|
|
13066
|
+
tileSize,
|
|
13067
|
+
frustumRef.current,
|
|
13068
|
+
camera,
|
|
13069
|
+
candidatesByLevel
|
|
13070
|
+
);
|
|
13071
|
+
visibilityDirtyRef.current = false;
|
|
13072
|
+
lastVisibilityQuaternionRef.current.copy(camera.quaternion);
|
|
13073
|
+
lastVisibilityFovRef.current = camera.fov;
|
|
13074
|
+
lastViewportRef.current = {
|
|
13075
|
+
width: size.width,
|
|
13076
|
+
height: size.height,
|
|
13077
|
+
dpr: pixelRatio
|
|
13078
|
+
};
|
|
13079
|
+
const targetLayer = nextLayers.find((layer) => layer.level === targetLevel);
|
|
13080
|
+
targetKeysRef.current = loadMode === "full" ? (targetLayer?.addresses ?? []).map(
|
|
13081
|
+
(address) => `${resolveUrl(address)}\0${tileKey(address)}`
|
|
13082
|
+
) : [];
|
|
13083
|
+
commitLayers(nextLayers);
|
|
13084
|
+
}
|
|
13085
|
+
publishSceneDetail(
|
|
13086
|
+
detailReporterRef.current,
|
|
13087
|
+
detailTokenRef,
|
|
13088
|
+
loadMode === "full" && viewTilesAreDrawable(
|
|
13089
|
+
targetKeysRef.current.map((key) => manager.getSnapshot(key).texture)
|
|
13090
|
+
)
|
|
12879
13091
|
);
|
|
12880
|
-
visibilityDirtyRef.current = false;
|
|
12881
|
-
lastVisibilityQuaternionRef.current.copy(camera.quaternion);
|
|
12882
|
-
lastVisibilityFovRef.current = camera.fov;
|
|
12883
|
-
lastViewportRef.current = {
|
|
12884
|
-
width: size.width,
|
|
12885
|
-
height: size.height,
|
|
12886
|
-
dpr: pixelRatio
|
|
12887
|
-
};
|
|
12888
|
-
commitLayers(nextLayers);
|
|
12889
13092
|
});
|
|
12890
|
-
return /* @__PURE__ */
|
|
12891
|
-
previewTexture ? /* @__PURE__ */
|
|
12892
|
-
layers.map((layer) => /* @__PURE__ */
|
|
13093
|
+
return /* @__PURE__ */ jsxs14("group", { visible, children: [
|
|
13094
|
+
previewTexture ? /* @__PURE__ */ jsx23(PreviewCube, { texture: previewTexture, faceOrder: previewFaceOrder }) : null,
|
|
13095
|
+
layers.map((layer) => /* @__PURE__ */ jsx23(
|
|
12893
13096
|
TileLayerMeshes,
|
|
12894
13097
|
{
|
|
12895
13098
|
layer,
|
|
@@ -12902,7 +13105,7 @@ function Tile({
|
|
|
12902
13105
|
}
|
|
12903
13106
|
|
|
12904
13107
|
// src/scenes.tsx
|
|
12905
|
-
import { jsx as
|
|
13108
|
+
import { jsx as jsx24, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
12906
13109
|
function SceneSource({
|
|
12907
13110
|
scene,
|
|
12908
13111
|
visible,
|
|
@@ -12915,7 +13118,7 @@ function SceneSource({
|
|
|
12915
13118
|
}
|
|
12916
13119
|
switch (scene.type) {
|
|
12917
13120
|
case "sphere":
|
|
12918
|
-
return /* @__PURE__ */
|
|
13121
|
+
return /* @__PURE__ */ jsx24(
|
|
12919
13122
|
Sphere,
|
|
12920
13123
|
{
|
|
12921
13124
|
src: scene.src,
|
|
@@ -12928,7 +13131,7 @@ function SceneSource({
|
|
|
12928
13131
|
);
|
|
12929
13132
|
case "tile": {
|
|
12930
13133
|
const { id: _id, type: _type, ...tileProps } = scene;
|
|
12931
|
-
return /* @__PURE__ */
|
|
13134
|
+
return /* @__PURE__ */ jsx24(
|
|
12932
13135
|
Tile,
|
|
12933
13136
|
{
|
|
12934
13137
|
...tileProps,
|
|
@@ -12939,6 +13142,19 @@ function SceneSource({
|
|
|
12939
13142
|
}
|
|
12940
13143
|
);
|
|
12941
13144
|
}
|
|
13145
|
+
case "sphereTile": {
|
|
13146
|
+
const { id: _id, type: _type, ...tileProps } = scene;
|
|
13147
|
+
return /* @__PURE__ */ jsx24(
|
|
13148
|
+
SphereTile,
|
|
13149
|
+
{
|
|
13150
|
+
...tileProps,
|
|
13151
|
+
visible,
|
|
13152
|
+
loadMode: baseOnly ? "base" : "full",
|
|
13153
|
+
onReady,
|
|
13154
|
+
onPreviewError: onError
|
|
13155
|
+
}
|
|
13156
|
+
);
|
|
13157
|
+
}
|
|
12942
13158
|
default: {
|
|
12943
13159
|
const exhaustive = scene;
|
|
12944
13160
|
void exhaustive;
|
|
@@ -12951,17 +13167,17 @@ function SnapshotCapture({
|
|
|
12951
13167
|
maxPixels,
|
|
12952
13168
|
onCaptured
|
|
12953
13169
|
}) {
|
|
12954
|
-
const { camera, gl, scene, size } =
|
|
12955
|
-
const capturedRequestRef =
|
|
12956
|
-
const renderTargetRef =
|
|
12957
|
-
|
|
13170
|
+
const { camera, gl, scene, size } = useThree21();
|
|
13171
|
+
const capturedRequestRef = useRef30(0);
|
|
13172
|
+
const renderTargetRef = useRef30(null);
|
|
13173
|
+
useEffect30(
|
|
12958
13174
|
() => () => {
|
|
12959
13175
|
renderTargetRef.current?.dispose();
|
|
12960
13176
|
renderTargetRef.current = null;
|
|
12961
13177
|
},
|
|
12962
13178
|
[]
|
|
12963
13179
|
);
|
|
12964
|
-
|
|
13180
|
+
useFrame14(() => {
|
|
12965
13181
|
if (requestId === 0 || requestId === capturedRequestRef.current) {
|
|
12966
13182
|
return;
|
|
12967
13183
|
}
|
|
@@ -13005,18 +13221,20 @@ function ScenesController({
|
|
|
13005
13221
|
activeSceneId,
|
|
13006
13222
|
transition: transitionInput,
|
|
13007
13223
|
renderHotspots,
|
|
13224
|
+
onSceneReady,
|
|
13008
13225
|
onTransitionEnd,
|
|
13009
13226
|
onTransitionError,
|
|
13010
13227
|
snapshotMaxPixels = 3686400,
|
|
13228
|
+
transitionWaitForDetailMs,
|
|
13011
13229
|
phaseRef: externalPhaseRef
|
|
13012
13230
|
}) {
|
|
13013
|
-
const controlsRef =
|
|
13231
|
+
const controlsRef = useContext24(PanoramaViewContext);
|
|
13014
13232
|
const manager = useSharedTileTextureManager();
|
|
13015
|
-
const transition =
|
|
13233
|
+
const transition = useMemo22(
|
|
13016
13234
|
() => resolveTransition(transitionInput),
|
|
13017
13235
|
[transitionInput]
|
|
13018
13236
|
);
|
|
13019
|
-
const sceneMap =
|
|
13237
|
+
const sceneMap = useMemo22(
|
|
13020
13238
|
() => new Map(scenes.map((scene) => [scene.id, scene])),
|
|
13021
13239
|
[scenes]
|
|
13022
13240
|
);
|
|
@@ -13033,13 +13251,21 @@ function ScenesController({
|
|
|
13033
13251
|
const [transitionRunId, setTransitionRunId] = useState14(0);
|
|
13034
13252
|
const [snapshot, setSnapshot] = useState14(null);
|
|
13035
13253
|
const [recoveryKey, setRecoveryKey] = useState14(0);
|
|
13036
|
-
const requestedSceneIdRef =
|
|
13037
|
-
const captureReasonRef =
|
|
13038
|
-
const interactionReleaseRef =
|
|
13039
|
-
const slotsRef =
|
|
13040
|
-
const phaseRef =
|
|
13041
|
-
const liveSlotRef =
|
|
13042
|
-
const transitionFromRef =
|
|
13254
|
+
const requestedSceneIdRef = useRef30(activeSceneId);
|
|
13255
|
+
const captureReasonRef = useRef30("start");
|
|
13256
|
+
const interactionReleaseRef = useRef30(null);
|
|
13257
|
+
const slotsRef = useRef30(slots);
|
|
13258
|
+
const phaseRef = useRef30(phase);
|
|
13259
|
+
const liveSlotRef = useRef30(liveSlot);
|
|
13260
|
+
const transitionFromRef = useRef30(initialScene);
|
|
13261
|
+
const readySceneRef = useRef30(null);
|
|
13262
|
+
const waitRef = useRef30(null);
|
|
13263
|
+
const waitTimerRef = useRef30(null);
|
|
13264
|
+
const detailGenerationRef = useRef30(0);
|
|
13265
|
+
const [detailGeneration, setDetailGeneration] = useState14(0);
|
|
13266
|
+
const mountedRef = useRef30(true);
|
|
13267
|
+
const waitForDetailMsRef = useRef30(0);
|
|
13268
|
+
waitForDetailMsRef.current = normalizeTransitionWaitMs(transitionWaitForDetailMs);
|
|
13043
13269
|
slotsRef.current = slots;
|
|
13044
13270
|
phaseRef.current = phase;
|
|
13045
13271
|
if (externalPhaseRef) {
|
|
@@ -13053,7 +13279,36 @@ function ScenesController({
|
|
|
13053
13279
|
const reportError = useCallback11((sceneId, error) => {
|
|
13054
13280
|
onTransitionError?.({ sceneId, error });
|
|
13055
13281
|
}, [onTransitionError]);
|
|
13282
|
+
const clearDetailWait = useCallback11((bumpGeneration) => {
|
|
13283
|
+
if (waitTimerRef.current !== null) {
|
|
13284
|
+
clearTimeout(waitTimerRef.current);
|
|
13285
|
+
waitTimerRef.current = null;
|
|
13286
|
+
}
|
|
13287
|
+
const generation = waitRef.current?.generation;
|
|
13288
|
+
if (generation === void 0) {
|
|
13289
|
+
waitRef.current = null;
|
|
13290
|
+
} else {
|
|
13291
|
+
waitRef.current = acceptDetailWait(waitRef.current, {
|
|
13292
|
+
kind: "cancel",
|
|
13293
|
+
generation
|
|
13294
|
+
}).wait;
|
|
13295
|
+
}
|
|
13296
|
+
if (!bumpGeneration || !mountedRef.current) {
|
|
13297
|
+
return;
|
|
13298
|
+
}
|
|
13299
|
+
const nextGeneration = detailGenerationRef.current + 1;
|
|
13300
|
+
detailGenerationRef.current = nextGeneration;
|
|
13301
|
+
setDetailGeneration(nextGeneration);
|
|
13302
|
+
}, []);
|
|
13303
|
+
useEffect30(() => {
|
|
13304
|
+
mountedRef.current = true;
|
|
13305
|
+
return () => {
|
|
13306
|
+
mountedRef.current = false;
|
|
13307
|
+
clearDetailWait(false);
|
|
13308
|
+
};
|
|
13309
|
+
}, [clearDetailWait]);
|
|
13056
13310
|
const startPreload = useCallback11((scene) => {
|
|
13311
|
+
clearDetailWait(true);
|
|
13057
13312
|
const nextSlot = 1 - liveSlotRef.current;
|
|
13058
13313
|
requestedSceneIdRef.current = scene.id;
|
|
13059
13314
|
setSlots((current) => {
|
|
@@ -13063,8 +13318,8 @@ function ScenesController({
|
|
|
13063
13318
|
});
|
|
13064
13319
|
setPendingSlot(nextSlot);
|
|
13065
13320
|
setPhase("preloading");
|
|
13066
|
-
}, []);
|
|
13067
|
-
|
|
13321
|
+
}, [clearDetailWait]);
|
|
13322
|
+
useEffect30(() => {
|
|
13068
13323
|
const requested = sceneMap.get(activeSceneId);
|
|
13069
13324
|
if (!requested) {
|
|
13070
13325
|
reportError(activeSceneId, new Error(`Unknown panorama scene: ${activeSceneId}`));
|
|
@@ -13079,20 +13334,31 @@ function ScenesController({
|
|
|
13079
13334
|
requestedSceneIdRef.current = requested.id;
|
|
13080
13335
|
return;
|
|
13081
13336
|
}
|
|
13082
|
-
if (phaseRef.current === "transitioning" || phaseRef.current === "capturing") {
|
|
13337
|
+
if (phaseRef.current === "transitioning" || phaseRef.current === "capturing" || phaseRef.current === "awaitingDetail") {
|
|
13338
|
+
if (requestedSceneIdRef.current === requested.id) return;
|
|
13083
13339
|
requestedSceneIdRef.current = requested.id;
|
|
13084
13340
|
captureReasonRef.current = "interrupt";
|
|
13341
|
+
clearDetailWait(true);
|
|
13085
13342
|
setPhase("recapturing");
|
|
13086
13343
|
setCaptureRequestId((current) => current + 1);
|
|
13087
13344
|
return;
|
|
13088
13345
|
}
|
|
13089
13346
|
startPreload(requested);
|
|
13090
|
-
}, [activeSceneId, pendingSlot, reportError, sceneMap, startPreload]);
|
|
13347
|
+
}, [activeSceneId, clearDetailWait, pendingSlot, reportError, sceneMap, startPreload]);
|
|
13348
|
+
const notifySceneReady = useCallback11((scene) => {
|
|
13349
|
+
if (!scene || readySceneRef.current === scene) return;
|
|
13350
|
+
readySceneRef.current = scene;
|
|
13351
|
+
onSceneReady?.(scene.id);
|
|
13352
|
+
}, [onSceneReady]);
|
|
13091
13353
|
const handleReady = useCallback11((slot) => {
|
|
13354
|
+
if (slot === liveSlotRef.current && pendingSlot === null && phaseRef.current === "idle") {
|
|
13355
|
+
notifySceneReady(slotsRef.current[slot]);
|
|
13356
|
+
return;
|
|
13357
|
+
}
|
|
13092
13358
|
if (slot !== pendingSlot || phaseRef.current !== "preloading") {
|
|
13093
13359
|
return;
|
|
13094
13360
|
}
|
|
13095
|
-
if (transition.preset === "none") {
|
|
13361
|
+
if (transition.preset === "none" && waitForDetailMsRef.current === 0) {
|
|
13096
13362
|
const previousScene = slotsRef.current[liveSlotRef.current];
|
|
13097
13363
|
const nextScene = slotsRef.current[slot];
|
|
13098
13364
|
setSlots((current) => {
|
|
@@ -13104,6 +13370,7 @@ function ScenesController({
|
|
|
13104
13370
|
setActiveSlot(slot);
|
|
13105
13371
|
setPendingSlot(null);
|
|
13106
13372
|
setPhase("idle");
|
|
13373
|
+
notifySceneReady(nextScene);
|
|
13107
13374
|
if (previousScene && nextScene) {
|
|
13108
13375
|
onTransitionEnd?.({
|
|
13109
13376
|
previousSceneId: previousScene.id,
|
|
@@ -13118,29 +13385,7 @@ function ScenesController({
|
|
|
13118
13385
|
captureReasonRef.current = "start";
|
|
13119
13386
|
setPhase("capturing");
|
|
13120
13387
|
setCaptureRequestId((current) => current + 1);
|
|
13121
|
-
}, [controlsRef, onTransitionEnd, pendingSlot, transition.preset]);
|
|
13122
|
-
const handleCaptured = useCallback11((nextSnapshot) => {
|
|
13123
|
-
setSnapshot((current) => {
|
|
13124
|
-
current?.dispose();
|
|
13125
|
-
return nextSnapshot;
|
|
13126
|
-
});
|
|
13127
|
-
if (captureReasonRef.current === "interrupt") {
|
|
13128
|
-
startPreload(sceneMap.get(requestedSceneIdRef.current));
|
|
13129
|
-
return;
|
|
13130
|
-
}
|
|
13131
|
-
const sourceSlot = liveSlotRef.current;
|
|
13132
|
-
setSlots((current) => {
|
|
13133
|
-
const next = [...current];
|
|
13134
|
-
next[sourceSlot] = null;
|
|
13135
|
-
return next;
|
|
13136
|
-
});
|
|
13137
|
-
manager?.releaseUnused();
|
|
13138
|
-
if (pendingSlot !== null) {
|
|
13139
|
-
setLiveSlot(pendingSlot);
|
|
13140
|
-
}
|
|
13141
|
-
setPhase("transitioning");
|
|
13142
|
-
setTransitionRunId((current) => current + 1);
|
|
13143
|
-
}, [manager, pendingSlot, sceneMap, startPreload]);
|
|
13388
|
+
}, [controlsRef, notifySceneReady, onTransitionEnd, pendingSlot, transition.preset]);
|
|
13144
13389
|
const finishTransition = useCallback11(() => {
|
|
13145
13390
|
const nextSlot = pendingSlot;
|
|
13146
13391
|
const previousScene = transitionFromRef.current;
|
|
@@ -13166,16 +13411,142 @@ function ScenesController({
|
|
|
13166
13411
|
});
|
|
13167
13412
|
}
|
|
13168
13413
|
}, [onTransitionEnd, pendingSlot, releaseInteraction, snapshot, transition.preset]);
|
|
13169
|
-
|
|
13414
|
+
const finishTransitionRef = useRef30(finishTransition);
|
|
13415
|
+
finishTransitionRef.current = finishTransition;
|
|
13416
|
+
const transitionRef = useRef30(transition);
|
|
13417
|
+
transitionRef.current = transition;
|
|
13418
|
+
const consumeDetailSignal = useCallback11((signal) => {
|
|
13419
|
+
const decision = acceptDetailWait(waitRef.current, signal);
|
|
13420
|
+
waitRef.current = decision.wait;
|
|
13421
|
+
if (!decision.start) {
|
|
13422
|
+
return;
|
|
13423
|
+
}
|
|
13424
|
+
if (waitTimerRef.current !== null) {
|
|
13425
|
+
clearTimeout(waitTimerRef.current);
|
|
13426
|
+
waitTimerRef.current = null;
|
|
13427
|
+
}
|
|
13428
|
+
if (!mountedRef.current) {
|
|
13429
|
+
return;
|
|
13430
|
+
}
|
|
13431
|
+
if (transitionRef.current.preset === "none") {
|
|
13432
|
+
finishTransitionRef.current();
|
|
13433
|
+
return;
|
|
13434
|
+
}
|
|
13435
|
+
setPhase("transitioning");
|
|
13436
|
+
setTransitionRunId((current) => current + 1);
|
|
13437
|
+
}, []);
|
|
13438
|
+
const handleCaptured = useCallback11((nextSnapshot) => {
|
|
13439
|
+
if (captureReasonRef.current === "interrupt") {
|
|
13440
|
+
setSnapshot((current) => {
|
|
13441
|
+
current?.dispose();
|
|
13442
|
+
return nextSnapshot;
|
|
13443
|
+
});
|
|
13444
|
+
startPreload(sceneMap.get(requestedSceneIdRef.current));
|
|
13445
|
+
return;
|
|
13446
|
+
}
|
|
13447
|
+
const sourceSlot = liveSlotRef.current;
|
|
13448
|
+
const incoming = pendingSlot === null ? null : slotsRef.current[pendingSlot];
|
|
13449
|
+
setSlots((current) => {
|
|
13450
|
+
const next = [...current];
|
|
13451
|
+
next[sourceSlot] = null;
|
|
13452
|
+
return next;
|
|
13453
|
+
});
|
|
13454
|
+
manager?.releaseUnused();
|
|
13455
|
+
if (pendingSlot !== null && incoming) {
|
|
13456
|
+
notifySceneReady(incoming);
|
|
13457
|
+
setLiveSlot(pendingSlot);
|
|
13458
|
+
}
|
|
13459
|
+
if (waitTimerRef.current !== null) {
|
|
13460
|
+
clearTimeout(waitTimerRef.current);
|
|
13461
|
+
waitTimerRef.current = null;
|
|
13462
|
+
}
|
|
13463
|
+
waitRef.current = null;
|
|
13464
|
+
let hold = null;
|
|
13465
|
+
if (incoming && waitForDetailMsRef.current > 0) {
|
|
13466
|
+
const now = performance.now();
|
|
13467
|
+
const generation = detailGenerationRef.current + 1;
|
|
13468
|
+
detailGenerationRef.current = generation;
|
|
13469
|
+
hold = planDetailHold({
|
|
13470
|
+
waitMs: waitForDetailMsRef.current,
|
|
13471
|
+
now,
|
|
13472
|
+
generation,
|
|
13473
|
+
sceneId: incoming.id
|
|
13474
|
+
});
|
|
13475
|
+
if (hold) {
|
|
13476
|
+
const deadline = hold.deadline;
|
|
13477
|
+
waitRef.current = hold;
|
|
13478
|
+
setDetailGeneration(generation);
|
|
13479
|
+
waitTimerRef.current = setTimeout(() => {
|
|
13480
|
+
consumeDetailSignal({
|
|
13481
|
+
kind: "timeout",
|
|
13482
|
+
generation,
|
|
13483
|
+
now: deadline
|
|
13484
|
+
});
|
|
13485
|
+
}, Math.max(0, deadline - performance.now()));
|
|
13486
|
+
}
|
|
13487
|
+
}
|
|
13488
|
+
const nextPhase = phaseAfterSnapshot(transition.preset, hold);
|
|
13489
|
+
if (nextPhase === "awaitingDetail") {
|
|
13490
|
+
setSnapshot((current) => {
|
|
13491
|
+
current?.dispose();
|
|
13492
|
+
return nextSnapshot;
|
|
13493
|
+
});
|
|
13494
|
+
setPhase("awaitingDetail");
|
|
13495
|
+
return;
|
|
13496
|
+
}
|
|
13497
|
+
if (nextPhase === "idle") {
|
|
13498
|
+
nextSnapshot.dispose();
|
|
13499
|
+
setSnapshot((current) => {
|
|
13500
|
+
current?.dispose();
|
|
13501
|
+
return null;
|
|
13502
|
+
});
|
|
13503
|
+
if (pendingSlot !== null) {
|
|
13504
|
+
setActiveSlot(pendingSlot);
|
|
13505
|
+
}
|
|
13506
|
+
setPendingSlot(null);
|
|
13507
|
+
setPhase("idle");
|
|
13508
|
+
releaseInteraction();
|
|
13509
|
+
const previousScene = transitionFromRef.current;
|
|
13510
|
+
if (previousScene && incoming) {
|
|
13511
|
+
onTransitionEnd?.({
|
|
13512
|
+
previousSceneId: previousScene.id,
|
|
13513
|
+
sceneId: incoming.id,
|
|
13514
|
+
preset: "none"
|
|
13515
|
+
});
|
|
13516
|
+
}
|
|
13517
|
+
return;
|
|
13518
|
+
}
|
|
13519
|
+
setSnapshot((current) => {
|
|
13520
|
+
current?.dispose();
|
|
13521
|
+
return nextSnapshot;
|
|
13522
|
+
});
|
|
13523
|
+
setPhase("transitioning");
|
|
13524
|
+
setTransitionRunId((current) => current + 1);
|
|
13525
|
+
}, [
|
|
13526
|
+
consumeDetailSignal,
|
|
13527
|
+
manager,
|
|
13528
|
+
notifySceneReady,
|
|
13529
|
+
onTransitionEnd,
|
|
13530
|
+
pendingSlot,
|
|
13531
|
+
releaseInteraction,
|
|
13532
|
+
sceneMap,
|
|
13533
|
+
startPreload,
|
|
13534
|
+
transition.preset
|
|
13535
|
+
]);
|
|
13536
|
+
const snapshotRef = useRef30(snapshot);
|
|
13537
|
+
snapshotRef.current = snapshot;
|
|
13538
|
+
useEffect30(() => () => {
|
|
13170
13539
|
releaseInteraction();
|
|
13171
|
-
|
|
13172
|
-
|
|
13173
|
-
|
|
13174
|
-
|
|
13540
|
+
snapshotRef.current?.dispose();
|
|
13541
|
+
snapshotRef.current = null;
|
|
13542
|
+
}, [releaseInteraction]);
|
|
13543
|
+
const { gl } = useThree21();
|
|
13544
|
+
useEffect30(() => {
|
|
13175
13545
|
const canvas = gl.domElement;
|
|
13176
13546
|
const onContextLost = (event) => {
|
|
13177
13547
|
event.preventDefault();
|
|
13178
13548
|
releaseInteraction();
|
|
13549
|
+
clearDetailWait(true);
|
|
13179
13550
|
manager?.dispose();
|
|
13180
13551
|
snapshot?.dispose();
|
|
13181
13552
|
setSnapshot(null);
|
|
@@ -13183,6 +13554,7 @@ function ScenesController({
|
|
|
13183
13554
|
setPhase("idle");
|
|
13184
13555
|
};
|
|
13185
13556
|
const onContextRestored = () => {
|
|
13557
|
+
readySceneRef.current = null;
|
|
13186
13558
|
manager?.resume();
|
|
13187
13559
|
setRecoveryKey((current) => current + 1);
|
|
13188
13560
|
};
|
|
@@ -13192,11 +13564,30 @@ function ScenesController({
|
|
|
13192
13564
|
canvas.removeEventListener("webglcontextlost", onContextLost);
|
|
13193
13565
|
canvas.removeEventListener("webglcontextrestored", onContextRestored);
|
|
13194
13566
|
};
|
|
13195
|
-
}, [gl, manager, releaseInteraction, snapshot]);
|
|
13567
|
+
}, [clearDetailWait, gl, manager, releaseInteraction, snapshot]);
|
|
13196
13568
|
const renderedScene = slots[liveSlot];
|
|
13197
13569
|
const snapshotVisible = snapshot !== null && (phase === "transitioning" || phase === "recapturing" || phase === "preloading");
|
|
13198
|
-
|
|
13199
|
-
|
|
13570
|
+
const slotSceneKey = `${slots[0]?.id ?? ""}
|
|
13571
|
+
${slots[1]?.id ?? ""}`;
|
|
13572
|
+
const detailReporters = useMemo22(() => {
|
|
13573
|
+
const [firstSceneId = "", secondSceneId = ""] = slotSceneKey.split("\n");
|
|
13574
|
+
const sceneIds = [firstSceneId, secondSceneId];
|
|
13575
|
+
return sceneIds.map((sceneId) => ({
|
|
13576
|
+
generation: detailGeneration,
|
|
13577
|
+
report: (ready) => {
|
|
13578
|
+
if (!ready || sceneId === "") {
|
|
13579
|
+
return;
|
|
13580
|
+
}
|
|
13581
|
+
consumeDetailSignal({
|
|
13582
|
+
kind: "ready",
|
|
13583
|
+
generation: detailGeneration,
|
|
13584
|
+
sceneId
|
|
13585
|
+
});
|
|
13586
|
+
}
|
|
13587
|
+
}));
|
|
13588
|
+
}, [consumeDetailSignal, detailGeneration, slotSceneKey]);
|
|
13589
|
+
return /* @__PURE__ */ jsxs15(Fragment6, { children: [
|
|
13590
|
+
/* @__PURE__ */ jsx24(
|
|
13200
13591
|
SnapshotCapture,
|
|
13201
13592
|
{
|
|
13202
13593
|
requestId: captureRequestId,
|
|
@@ -13208,23 +13599,30 @@ function ScenesController({
|
|
|
13208
13599
|
const source = slots[slot];
|
|
13209
13600
|
const isLive = slot === liveSlot;
|
|
13210
13601
|
const isPending = slot === pendingSlot;
|
|
13211
|
-
return /* @__PURE__ */
|
|
13212
|
-
|
|
13602
|
+
return /* @__PURE__ */ jsx24(
|
|
13603
|
+
SceneDetailContext.Provider,
|
|
13213
13604
|
{
|
|
13214
|
-
|
|
13215
|
-
|
|
13216
|
-
|
|
13217
|
-
|
|
13218
|
-
|
|
13219
|
-
|
|
13220
|
-
|
|
13605
|
+
value: detailReporters[slot],
|
|
13606
|
+
children: /* @__PURE__ */ jsx24(
|
|
13607
|
+
SceneSource,
|
|
13608
|
+
{
|
|
13609
|
+
scene: source,
|
|
13610
|
+
visible: isLive,
|
|
13611
|
+
baseOnly: pendingSceneUsesBaseLayer(phase, isPending),
|
|
13612
|
+
onReady: () => handleReady(slot),
|
|
13613
|
+
onError: (error) => {
|
|
13614
|
+
if (source) {
|
|
13615
|
+
reportError(source.id, error);
|
|
13616
|
+
}
|
|
13617
|
+
}
|
|
13221
13618
|
}
|
|
13222
|
-
|
|
13619
|
+
)
|
|
13223
13620
|
},
|
|
13224
13621
|
`${slot}:${source?.id ?? "empty"}:${recoveryKey}`
|
|
13225
13622
|
);
|
|
13226
13623
|
}),
|
|
13227
|
-
|
|
13624
|
+
snapshot !== null && phase === "awaitingDetail" ? /* @__PURE__ */ jsx24(SnapshotHold, { snapshot }) : null,
|
|
13625
|
+
snapshotVisible ? /* @__PURE__ */ jsx24(
|
|
13228
13626
|
TransitionOverlay,
|
|
13229
13627
|
{
|
|
13230
13628
|
snapshot,
|
|
@@ -13261,13 +13659,13 @@ function Scenes({
|
|
|
13261
13659
|
},
|
|
13262
13660
|
[isControlled, onActiveSceneIdChange]
|
|
13263
13661
|
);
|
|
13264
|
-
const scenesRef =
|
|
13662
|
+
const scenesRef = useRef30(scenes);
|
|
13265
13663
|
scenesRef.current = scenes;
|
|
13266
|
-
const resolvedIdRef =
|
|
13664
|
+
const resolvedIdRef = useRef30(resolvedId);
|
|
13267
13665
|
resolvedIdRef.current = resolvedId;
|
|
13268
|
-
const host =
|
|
13269
|
-
const phaseRef =
|
|
13270
|
-
|
|
13666
|
+
const host = useContext24(ScenesHostContext);
|
|
13667
|
+
const phaseRef = useRef30("idle");
|
|
13668
|
+
useEffect30(() => {
|
|
13271
13669
|
if (!host) {
|
|
13272
13670
|
return;
|
|
13273
13671
|
}
|
|
@@ -13317,12 +13715,12 @@ function Scenes({
|
|
|
13317
13715
|
}
|
|
13318
13716
|
};
|
|
13319
13717
|
}, [host, requestSceneChange]);
|
|
13320
|
-
return /* @__PURE__ */
|
|
13718
|
+
return /* @__PURE__ */ jsx24(
|
|
13321
13719
|
TileTextureManagerProvider,
|
|
13322
13720
|
{
|
|
13323
13721
|
maxTextureMemoryMb,
|
|
13324
13722
|
maxConcurrentLoads: maxConcurrentTileLoads,
|
|
13325
|
-
children: /* @__PURE__ */
|
|
13723
|
+
children: /* @__PURE__ */ jsx24(
|
|
13326
13724
|
ScenesController,
|
|
13327
13725
|
{
|
|
13328
13726
|
...rest,
|
|
@@ -13336,8 +13734,8 @@ function Scenes({
|
|
|
13336
13734
|
}
|
|
13337
13735
|
|
|
13338
13736
|
// src/hotspot/image-hotspot.tsx
|
|
13339
|
-
import { useThree as
|
|
13340
|
-
import { useEffect as
|
|
13737
|
+
import { useThree as useThree24 } from "@react-three/fiber";
|
|
13738
|
+
import { useEffect as useEffect33, useRef as useRef33, useState as useState17 } from "react";
|
|
13341
13739
|
import {
|
|
13342
13740
|
ClampToEdgeWrapping as ClampToEdgeWrapping3,
|
|
13343
13741
|
LinearFilter as LinearFilter6,
|
|
@@ -13347,13 +13745,13 @@ import {
|
|
|
13347
13745
|
} from "three";
|
|
13348
13746
|
|
|
13349
13747
|
// src/hotspot/hotspot-anchor.tsx
|
|
13350
|
-
import { useFrame as
|
|
13748
|
+
import { useFrame as useFrame16, useThree as useThree23 } from "@react-three/fiber";
|
|
13351
13749
|
import {
|
|
13352
|
-
useContext as
|
|
13353
|
-
useEffect as
|
|
13750
|
+
useContext as useContext26,
|
|
13751
|
+
useEffect as useEffect32,
|
|
13354
13752
|
useLayoutEffect as useLayoutEffect5,
|
|
13355
|
-
useMemo as
|
|
13356
|
-
useRef as
|
|
13753
|
+
useMemo as useMemo24,
|
|
13754
|
+
useRef as useRef32,
|
|
13357
13755
|
useState as useState16
|
|
13358
13756
|
} from "react";
|
|
13359
13757
|
import {
|
|
@@ -13365,25 +13763,25 @@ import {
|
|
|
13365
13763
|
PlaneGeometry as PlaneGeometry5,
|
|
13366
13764
|
Quaternion as Quaternion4,
|
|
13367
13765
|
Ray,
|
|
13368
|
-
Vector3 as
|
|
13766
|
+
Vector3 as Vector317
|
|
13369
13767
|
} from "three";
|
|
13370
13768
|
|
|
13371
13769
|
// src/hotspot/hotspot-tooltip.tsx
|
|
13372
|
-
import { useEffect as
|
|
13770
|
+
import { useEffect as useEffect31, useMemo as useMemo23, useState as useState15 } from "react";
|
|
13373
13771
|
|
|
13374
13772
|
// src/webvr/stereo-html.tsx
|
|
13375
|
-
import { useFrame as
|
|
13773
|
+
import { useFrame as useFrame15, useThree as useThree22 } from "@react-three/fiber";
|
|
13376
13774
|
import {
|
|
13377
|
-
useContext as
|
|
13775
|
+
useContext as useContext25,
|
|
13378
13776
|
useLayoutEffect as useLayoutEffect4,
|
|
13379
|
-
useRef as
|
|
13777
|
+
useRef as useRef31,
|
|
13380
13778
|
useSyncExternalStore as useSyncExternalStore7
|
|
13381
13779
|
} from "react";
|
|
13382
13780
|
import { createRoot } from "react-dom/client";
|
|
13383
|
-
import { Vector3 as
|
|
13384
|
-
import { Fragment as Fragment7, jsx as
|
|
13781
|
+
import { Vector3 as Vector315 } from "three";
|
|
13782
|
+
import { Fragment as Fragment7, jsx as jsx25, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
13385
13783
|
function useFallbackStereoView() {
|
|
13386
|
-
const runtime =
|
|
13784
|
+
const runtime = useContext25(WebVRRuntimeContext);
|
|
13387
13785
|
const host = runtime?.host ?? null;
|
|
13388
13786
|
const fallback = useSyncExternalStore7(
|
|
13389
13787
|
(onStoreChange) => host ? subscribeWebVRHost(host, onStoreChange) : () => void 0,
|
|
@@ -13400,10 +13798,10 @@ function ProjectedHtml({
|
|
|
13400
13798
|
stereoView,
|
|
13401
13799
|
eye
|
|
13402
13800
|
}) {
|
|
13403
|
-
const { camera, gl, events, size } =
|
|
13404
|
-
const group =
|
|
13405
|
-
const overlay =
|
|
13406
|
-
const scratch =
|
|
13801
|
+
const { camera, gl, events, size } = useThree22();
|
|
13802
|
+
const group = useRef31(null);
|
|
13803
|
+
const overlay = useRef31(null);
|
|
13804
|
+
const scratch = useRef31(new Vector315());
|
|
13407
13805
|
const target = events.connected || gl.domElement.parentElement;
|
|
13408
13806
|
const updatePosition = () => {
|
|
13409
13807
|
const anchor = group.current;
|
|
@@ -13451,7 +13849,7 @@ function ProjectedHtml({
|
|
|
13451
13849
|
}, [target]);
|
|
13452
13850
|
useLayoutEffect4(() => {
|
|
13453
13851
|
overlay.current?.root.render(
|
|
13454
|
-
/* @__PURE__ */
|
|
13852
|
+
/* @__PURE__ */ jsx25(
|
|
13455
13853
|
"div",
|
|
13456
13854
|
{
|
|
13457
13855
|
"aria-hidden": eye === "right" || void 0,
|
|
@@ -13462,19 +13860,19 @@ function ProjectedHtml({
|
|
|
13462
13860
|
);
|
|
13463
13861
|
updatePosition();
|
|
13464
13862
|
});
|
|
13465
|
-
|
|
13466
|
-
return /* @__PURE__ */
|
|
13863
|
+
useFrame15(updatePosition);
|
|
13864
|
+
return /* @__PURE__ */ jsx25("group", { ref: group });
|
|
13467
13865
|
}
|
|
13468
13866
|
function PanoHtml(props) {
|
|
13469
13867
|
const stereoView = useFallbackStereoView();
|
|
13470
|
-
return stereoView ? /* @__PURE__ */
|
|
13471
|
-
/* @__PURE__ */
|
|
13472
|
-
/* @__PURE__ */
|
|
13473
|
-
] }) : /* @__PURE__ */
|
|
13868
|
+
return stereoView ? /* @__PURE__ */ jsxs16(Fragment7, { children: [
|
|
13869
|
+
/* @__PURE__ */ jsx25(ProjectedHtml, { ...props, stereoView, eye: "left" }),
|
|
13870
|
+
/* @__PURE__ */ jsx25(ProjectedHtml, { ...props, stereoView, eye: "right" })
|
|
13871
|
+
] }) : /* @__PURE__ */ jsx25(ProjectedHtml, { ...props });
|
|
13474
13872
|
}
|
|
13475
13873
|
|
|
13476
13874
|
// src/hotspot/hotspot-tooltip.tsx
|
|
13477
|
-
import { jsx as
|
|
13875
|
+
import { jsx as jsx26, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
13478
13876
|
var DEFAULT_HOTSPOT_TOOLTIP_OFFSET = 12;
|
|
13479
13877
|
var DEFAULT_HOTSPOT_TOOLTIP_APPEARANCE = {
|
|
13480
13878
|
background: "rgba(22, 22, 22, 0.72)",
|
|
@@ -13547,15 +13945,15 @@ function HotspotTooltip({
|
|
|
13547
13945
|
appearance
|
|
13548
13946
|
}) {
|
|
13549
13947
|
const [imageFailed, setImageFailed] = useState15(false);
|
|
13550
|
-
|
|
13948
|
+
useEffect31(() => {
|
|
13551
13949
|
setImageFailed(false);
|
|
13552
13950
|
}, [content.image]);
|
|
13553
13951
|
const showImage = Boolean(content.image) && !imageFailed;
|
|
13554
|
-
const resolvedAppearance =
|
|
13952
|
+
const resolvedAppearance = useMemo23(
|
|
13555
13953
|
() => resolveHotspotTooltipAppearance(appearance),
|
|
13556
13954
|
[appearance]
|
|
13557
13955
|
);
|
|
13558
|
-
const bubbleStyle =
|
|
13956
|
+
const bubbleStyle = useMemo23(
|
|
13559
13957
|
() => ({
|
|
13560
13958
|
background: resolvedAppearance.background,
|
|
13561
13959
|
border: resolvedAppearance.border,
|
|
@@ -13577,8 +13975,8 @@ function HotspotTooltip({
|
|
|
13577
13975
|
if (!showImage && !content.text) {
|
|
13578
13976
|
return null;
|
|
13579
13977
|
}
|
|
13580
|
-
return /* @__PURE__ */
|
|
13581
|
-
showImage ? /* @__PURE__ */
|
|
13978
|
+
return /* @__PURE__ */ jsx26(PanoHtml, { pointerEvents: "none", style: WRAPPER_STYLE, zIndexRange: [20, 10], children: /* @__PURE__ */ jsxs17("div", { className: "pano-hotspot-tooltip", role: "tooltip", style: bubbleStyle, children: [
|
|
13979
|
+
showImage ? /* @__PURE__ */ jsx26(
|
|
13582
13980
|
"img",
|
|
13583
13981
|
{
|
|
13584
13982
|
alt: content.imageAlt ?? content.text ?? "",
|
|
@@ -13587,7 +13985,7 @@ function HotspotTooltip({
|
|
|
13587
13985
|
src: content.image
|
|
13588
13986
|
}
|
|
13589
13987
|
) : null,
|
|
13590
|
-
content.text ? /* @__PURE__ */
|
|
13988
|
+
content.text ? /* @__PURE__ */ jsx26(
|
|
13591
13989
|
"p",
|
|
13592
13990
|
{
|
|
13593
13991
|
className: "pano-hotspot-tooltip-text",
|
|
@@ -13606,10 +14004,10 @@ function HotspotTooltip({
|
|
|
13606
14004
|
import {
|
|
13607
14005
|
MathUtils as MathUtils8,
|
|
13608
14006
|
PerspectiveCamera as PerspectiveCamera6,
|
|
13609
|
-
Vector3 as
|
|
14007
|
+
Vector3 as Vector316
|
|
13610
14008
|
} from "three";
|
|
13611
|
-
var LOCAL_FORWARD = new
|
|
13612
|
-
var CAMERA_POSITION = new
|
|
14009
|
+
var LOCAL_FORWARD = new Vector316(0, 0, 1);
|
|
14010
|
+
var CAMERA_POSITION = new Vector316();
|
|
13613
14011
|
function applyHotspotTransform(group, camera, orientation2, surfaceQuaternion3, rotation, scaleMode, referenceFov, useAngularScale, worldWidth, worldHeight, distance) {
|
|
13614
14012
|
if (orientation2 === "billboard") {
|
|
13615
14013
|
group.quaternion.copy(camera.quaternion);
|
|
@@ -13638,7 +14036,7 @@ function fixedScaleFactor(cameraFov, referenceFov) {
|
|
|
13638
14036
|
}
|
|
13639
14037
|
|
|
13640
14038
|
// src/hotspot/hotspot-anchor.tsx
|
|
13641
|
-
import { jsx as
|
|
14039
|
+
import { jsx as jsx27, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
13642
14040
|
var DEFAULT_FLOATING_DISTANCE = 10;
|
|
13643
14041
|
var PANORAMA_RADIUS = DEFAULT_PANORAMA_RADIUS;
|
|
13644
14042
|
var PANORAMA_SURFACE_INSET = 4;
|
|
@@ -13648,18 +14046,18 @@ var MAX_ANGULAR_SIZE = 179;
|
|
|
13648
14046
|
var DRAG_EPSILON_DEGREES = 1e-3;
|
|
13649
14047
|
var TOOLTIP_WORLD_BOX = new Box34();
|
|
13650
14048
|
var TOOLTIP_LOCAL_BOX = new Box34();
|
|
13651
|
-
var TOOLTIP_CORNER = new
|
|
14049
|
+
var TOOLTIP_CORNER = new Vector317();
|
|
13652
14050
|
var TOOLTIP_INVERSE = new Matrix44();
|
|
13653
|
-
var TOOLTIP_WORLD_CORNER = new
|
|
13654
|
-
var TOOLTIP_PROJECTED = new
|
|
13655
|
-
var TOOLTIP_RAY_ORIGIN = new
|
|
13656
|
-
var TOOLTIP_RAY_FAR = new
|
|
13657
|
-
var TOOLTIP_RAY_DIRECTION = new
|
|
14051
|
+
var TOOLTIP_WORLD_CORNER = new Vector317();
|
|
14052
|
+
var TOOLTIP_PROJECTED = new Vector317();
|
|
14053
|
+
var TOOLTIP_RAY_ORIGIN = new Vector317();
|
|
14054
|
+
var TOOLTIP_RAY_FAR = new Vector317();
|
|
14055
|
+
var TOOLTIP_RAY_DIRECTION = new Vector317();
|
|
13658
14056
|
var TOOLTIP_RAY = new Ray();
|
|
13659
14057
|
var TOOLTIP_PLANE = new Plane();
|
|
13660
|
-
var TOOLTIP_INTERSECTION = new
|
|
13661
|
-
var TOOLTIP_PLANE_NORMAL = new
|
|
13662
|
-
var TOOLTIP_PLANE_POINT = new
|
|
14058
|
+
var TOOLTIP_INTERSECTION = new Vector317();
|
|
14059
|
+
var TOOLTIP_PLANE_NORMAL = new Vector317();
|
|
14060
|
+
var TOOLTIP_PLANE_POINT = new Vector317();
|
|
13663
14061
|
var HOTSPOT_MODE_RENDERING = {
|
|
13664
14062
|
surface: { orientation: "surface", placement: "surface" },
|
|
13665
14063
|
billboard: { orientation: "billboard", placement: "floating" }
|
|
@@ -13704,7 +14102,7 @@ function createSurfaceQuaternion(position) {
|
|
|
13704
14102
|
const inward = outward.clone().negate();
|
|
13705
14103
|
const pitch = MathUtils9.degToRad(position.pitch);
|
|
13706
14104
|
const yaw = MathUtils9.degToRad(position.yaw);
|
|
13707
|
-
const localUp = new
|
|
14105
|
+
const localUp = new Vector317(
|
|
13708
14106
|
-Math.sin(pitch) * Math.sin(yaw),
|
|
13709
14107
|
Math.cos(pitch),
|
|
13710
14108
|
Math.sin(pitch) * Math.cos(yaw)
|
|
@@ -13955,24 +14353,24 @@ function HotspotAnchor({
|
|
|
13955
14353
|
onPositionChange,
|
|
13956
14354
|
onDragEnd
|
|
13957
14355
|
}) {
|
|
13958
|
-
const controlsRef =
|
|
13959
|
-
const hotspotTargetRegistry =
|
|
13960
|
-
const eventBus =
|
|
14356
|
+
const controlsRef = useContext26(PanoramaViewContext);
|
|
14357
|
+
const hotspotTargetRegistry = useContext26(HotspotTargetRegistryContext);
|
|
14358
|
+
const eventBus = useContext26(PanoEventBusContext);
|
|
13961
14359
|
const cursorApi = usePanoCursor();
|
|
13962
|
-
const { camera, size } =
|
|
13963
|
-
const groupRef =
|
|
13964
|
-
const tooltipAnchorRef =
|
|
13965
|
-
const dragStateRef =
|
|
13966
|
-
const suppressNextClickRef =
|
|
14360
|
+
const { camera, size } = useThree23();
|
|
14361
|
+
const groupRef = useRef32(null);
|
|
14362
|
+
const tooltipAnchorRef = useRef32(null);
|
|
14363
|
+
const dragStateRef = useRef32(null);
|
|
14364
|
+
const suppressNextClickRef = useRef32(false);
|
|
13967
14365
|
const [hovered, setHovered] = useState16(false);
|
|
13968
14366
|
const [dragging, setDragging] = useState16(false);
|
|
13969
14367
|
const [pinned, setPinned] = useState16(false);
|
|
13970
|
-
const tooltipContent =
|
|
14368
|
+
const tooltipContent = useMemo24(
|
|
13971
14369
|
() => resolveHotspotTooltipContent(tooltip),
|
|
13972
14370
|
[tooltip]
|
|
13973
14371
|
);
|
|
13974
14372
|
const normalizedPosition = normalizePanoPosition(position);
|
|
13975
|
-
|
|
14373
|
+
useEffect32(() => {
|
|
13976
14374
|
if (!hotspotTargetRegistry) {
|
|
13977
14375
|
return;
|
|
13978
14376
|
}
|
|
@@ -13989,17 +14387,17 @@ function HotspotAnchor({
|
|
|
13989
14387
|
scaledWidth,
|
|
13990
14388
|
scaledHeight
|
|
13991
14389
|
);
|
|
13992
|
-
const worldPosition =
|
|
14390
|
+
const worldPosition = useMemo24(
|
|
13993
14391
|
() => panoPositionToVector3(normalizedPosition, resolvedDistance),
|
|
13994
14392
|
[normalizedPosition.pitch, normalizedPosition.yaw, resolvedDistance]
|
|
13995
14393
|
);
|
|
13996
|
-
const surfaceQuaternion3 =
|
|
14394
|
+
const surfaceQuaternion3 = useMemo24(
|
|
13997
14395
|
() => createSurfaceQuaternion(normalizedPosition),
|
|
13998
14396
|
[normalizedPosition.pitch, normalizedPosition.yaw]
|
|
13999
14397
|
);
|
|
14000
14398
|
const worldWidth = angularSizeToWorldSize(scaledWidth, resolvedDistance);
|
|
14001
14399
|
const worldHeight = angularSizeToWorldSize(scaledHeight, resolvedDistance);
|
|
14002
|
-
const focusGeometry =
|
|
14400
|
+
const focusGeometry = useMemo24(() => {
|
|
14003
14401
|
const planeGeometry = new PlaneGeometry5(1, 1);
|
|
14004
14402
|
const geometry = new EdgesGeometry(planeGeometry);
|
|
14005
14403
|
planeGeometry.dispose();
|
|
@@ -14026,14 +14424,14 @@ function HotspotAnchor({
|
|
|
14026
14424
|
});
|
|
14027
14425
|
const tooltipOpen = visible && tooltipContent !== null && isTooltipOpen(tooltipTrigger, hovered, focused, pinned);
|
|
14028
14426
|
const cursorClaimId = hotspotCursorClaimId(id);
|
|
14029
|
-
|
|
14427
|
+
useEffect32(
|
|
14030
14428
|
() => () => {
|
|
14031
14429
|
dragStateRef.current?.releaseInteractionLock();
|
|
14032
14430
|
dragStateRef.current = null;
|
|
14033
14431
|
},
|
|
14034
14432
|
[]
|
|
14035
14433
|
);
|
|
14036
|
-
|
|
14434
|
+
useEffect32(() => {
|
|
14037
14435
|
if (!cursorApi) {
|
|
14038
14436
|
return;
|
|
14039
14437
|
}
|
|
@@ -14055,14 +14453,14 @@ function HotspotAnchor({
|
|
|
14055
14453
|
hovered,
|
|
14056
14454
|
visible
|
|
14057
14455
|
]);
|
|
14058
|
-
|
|
14456
|
+
useEffect32(
|
|
14059
14457
|
() => () => {
|
|
14060
14458
|
cursorApi?.release(cursorClaimId);
|
|
14061
14459
|
},
|
|
14062
14460
|
[cursorApi, cursorClaimId]
|
|
14063
14461
|
);
|
|
14064
|
-
|
|
14065
|
-
|
|
14462
|
+
useEffect32(() => () => focusGeometry.dispose(), [focusGeometry]);
|
|
14463
|
+
useEffect32(() => {
|
|
14066
14464
|
if (tooltipTrigger !== "click") {
|
|
14067
14465
|
setPinned(false);
|
|
14068
14466
|
return;
|
|
@@ -14071,12 +14469,12 @@ function HotspotAnchor({
|
|
|
14071
14469
|
setPinned(false);
|
|
14072
14470
|
});
|
|
14073
14471
|
}, [eventBus, tooltipTrigger]);
|
|
14074
|
-
|
|
14472
|
+
useEffect32(() => {
|
|
14075
14473
|
if (tooltipTrigger !== "hover") {
|
|
14076
14474
|
setHovered(false);
|
|
14077
14475
|
}
|
|
14078
14476
|
}, [tooltipTrigger]);
|
|
14079
|
-
|
|
14477
|
+
useEffect32(() => {
|
|
14080
14478
|
if (acceptsPointer) {
|
|
14081
14479
|
return;
|
|
14082
14480
|
}
|
|
@@ -14132,7 +14530,7 @@ function HotspotAnchor({
|
|
|
14132
14530
|
worldHeight,
|
|
14133
14531
|
worldWidth
|
|
14134
14532
|
]);
|
|
14135
|
-
|
|
14533
|
+
useFrame16((state) => {
|
|
14136
14534
|
const group = groupRef.current;
|
|
14137
14535
|
if (!group) {
|
|
14138
14536
|
return;
|
|
@@ -14191,7 +14589,7 @@ function HotspotAnchor({
|
|
|
14191
14589
|
setHovered(true);
|
|
14192
14590
|
}
|
|
14193
14591
|
};
|
|
14194
|
-
return /* @__PURE__ */
|
|
14592
|
+
return /* @__PURE__ */ jsxs18(
|
|
14195
14593
|
"group",
|
|
14196
14594
|
{
|
|
14197
14595
|
ref: groupRef,
|
|
@@ -14268,18 +14666,18 @@ function HotspotAnchor({
|
|
|
14268
14666
|
} : void 0,
|
|
14269
14667
|
onPointerUp: acceptsPointer ? (event) => releasePointer(event, true) : void 0,
|
|
14270
14668
|
children: [
|
|
14271
|
-
focused ? focusContent ?? /* @__PURE__ */
|
|
14669
|
+
focused ? focusContent ?? /* @__PURE__ */ jsx27(
|
|
14272
14670
|
"lineSegments",
|
|
14273
14671
|
{
|
|
14274
14672
|
geometry: focusGeometry,
|
|
14275
14673
|
position: [0, 0, 0.01],
|
|
14276
14674
|
renderOrder: renderOrder + 1,
|
|
14277
14675
|
scale: [1.12, 1.12, 1],
|
|
14278
|
-
children: /* @__PURE__ */
|
|
14676
|
+
children: /* @__PURE__ */ jsx27("lineBasicMaterial", { color: "#f5fbfc", depthTest: false })
|
|
14279
14677
|
}
|
|
14280
14678
|
) : null,
|
|
14281
14679
|
children,
|
|
14282
|
-
tooltipOpen && tooltipContent ? /* @__PURE__ */
|
|
14680
|
+
tooltipOpen && tooltipContent ? /* @__PURE__ */ jsx27("group", { ref: tooltipAnchorRef, children: /* @__PURE__ */ jsx27(
|
|
14283
14681
|
HotspotTooltip,
|
|
14284
14682
|
{
|
|
14285
14683
|
appearance: tooltipAppearance,
|
|
@@ -14296,11 +14694,11 @@ function HotspotAnchor({
|
|
|
14296
14694
|
// src/hotspot/hotspot-plane.tsx
|
|
14297
14695
|
import {
|
|
14298
14696
|
DoubleSide as DoubleSide4,
|
|
14299
|
-
Mesh as
|
|
14697
|
+
Mesh as Mesh6,
|
|
14300
14698
|
MeshBasicMaterial,
|
|
14301
14699
|
Vector2 as Vector26
|
|
14302
14700
|
} from "three";
|
|
14303
|
-
import { jsx as
|
|
14701
|
+
import { jsx as jsx28, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
14304
14702
|
var HOTSPOT_ALPHA_CUTOFF = 0.05;
|
|
14305
14703
|
var SAMPLE_UV = new Vector26();
|
|
14306
14704
|
var RAYCAST_HITS = [];
|
|
@@ -14377,7 +14775,7 @@ function sampleTextureAlpha(texture, u, v) {
|
|
|
14377
14775
|
function hotspotPlaneRaycast(raycaster, intersects2) {
|
|
14378
14776
|
const material = Array.isArray(this.material) ? this.material[0] : this.material;
|
|
14379
14777
|
if (!(material instanceof MeshBasicMaterial)) {
|
|
14380
|
-
|
|
14778
|
+
Mesh6.prototype.raycast.call(this, raycaster, intersects2);
|
|
14381
14779
|
return;
|
|
14382
14780
|
}
|
|
14383
14781
|
const cutoff = Math.max(material.alphaTest, HOTSPOT_ALPHA_CUTOFF);
|
|
@@ -14385,7 +14783,7 @@ function hotspotPlaneRaycast(raycaster, intersects2) {
|
|
|
14385
14783
|
return;
|
|
14386
14784
|
}
|
|
14387
14785
|
RAYCAST_HITS.length = 0;
|
|
14388
|
-
|
|
14786
|
+
Mesh6.prototype.raycast.call(this, raycaster, RAYCAST_HITS);
|
|
14389
14787
|
const map = material.map;
|
|
14390
14788
|
for (const hit of RAYCAST_HITS) {
|
|
14391
14789
|
if (!map || !hit.uv) {
|
|
@@ -14402,9 +14800,9 @@ function HotspotPlane({
|
|
|
14402
14800
|
map,
|
|
14403
14801
|
opacity
|
|
14404
14802
|
}) {
|
|
14405
|
-
return /* @__PURE__ */
|
|
14406
|
-
/* @__PURE__ */
|
|
14407
|
-
/* @__PURE__ */
|
|
14803
|
+
return /* @__PURE__ */ jsxs19("mesh", { raycast: hotspotPlaneRaycast, children: [
|
|
14804
|
+
/* @__PURE__ */ jsx28("planeGeometry", { args: [1, 1] }),
|
|
14805
|
+
/* @__PURE__ */ jsx28(
|
|
14408
14806
|
PanoBasicMaterial,
|
|
14409
14807
|
{
|
|
14410
14808
|
target: "hotspot",
|
|
@@ -14420,15 +14818,15 @@ function HotspotPlane({
|
|
|
14420
14818
|
}
|
|
14421
14819
|
|
|
14422
14820
|
// src/hotspot/image-hotspot.tsx
|
|
14423
|
-
import { jsx as
|
|
14821
|
+
import { jsx as jsx29 } from "react/jsx-runtime";
|
|
14424
14822
|
function useHotspotImageTexture(src, onLoad, onError) {
|
|
14425
|
-
const gl =
|
|
14823
|
+
const gl = useThree24((state) => state.gl);
|
|
14426
14824
|
const [texture, setTexture] = useState17(null);
|
|
14427
|
-
const onLoadRef =
|
|
14428
|
-
const onErrorRef =
|
|
14825
|
+
const onLoadRef = useRef33(onLoad);
|
|
14826
|
+
const onErrorRef = useRef33(onError);
|
|
14429
14827
|
onLoadRef.current = onLoad;
|
|
14430
14828
|
onErrorRef.current = onError;
|
|
14431
|
-
|
|
14829
|
+
useEffect33(() => {
|
|
14432
14830
|
let active = true;
|
|
14433
14831
|
setTexture(null);
|
|
14434
14832
|
if (!src) {
|
|
@@ -14466,7 +14864,7 @@ function useHotspotImageTexture(src, onLoad, onError) {
|
|
|
14466
14864
|
active = false;
|
|
14467
14865
|
};
|
|
14468
14866
|
}, [gl, src]);
|
|
14469
|
-
|
|
14867
|
+
useEffect33(
|
|
14470
14868
|
() => () => {
|
|
14471
14869
|
texture?.dispose();
|
|
14472
14870
|
},
|
|
@@ -14484,11 +14882,11 @@ function ImageHotspot({
|
|
|
14484
14882
|
...anchorProps
|
|
14485
14883
|
}) {
|
|
14486
14884
|
const texture = useHotspotImageTexture(src, onLoad, onError);
|
|
14487
|
-
return /* @__PURE__ */
|
|
14885
|
+
return /* @__PURE__ */ jsx29(HotspotAnchor, { ...anchorProps, height, width, children: /* @__PURE__ */ jsx29(HotspotPlane, { map: texture, opacity }) });
|
|
14488
14886
|
}
|
|
14489
14887
|
|
|
14490
14888
|
// src/hotspot/polygon-hotspot.tsx
|
|
14491
|
-
import { useEffect as
|
|
14889
|
+
import { useEffect as useEffect34, useMemo as useMemo25, useRef as useRef35 } from "react";
|
|
14492
14890
|
import {
|
|
14493
14891
|
BufferGeometry as BufferGeometry2,
|
|
14494
14892
|
DoubleSide as DoubleSide5,
|
|
@@ -14497,20 +14895,20 @@ import {
|
|
|
14497
14895
|
Quaternion as Quaternion5,
|
|
14498
14896
|
ShapeUtils,
|
|
14499
14897
|
Vector2 as Vector27,
|
|
14500
|
-
Vector3 as
|
|
14898
|
+
Vector3 as Vector319
|
|
14501
14899
|
} from "three";
|
|
14502
14900
|
|
|
14503
14901
|
// src/hotspot/hotspot-stroke-line.tsx
|
|
14504
14902
|
import { Line } from "@react-three/drei";
|
|
14505
|
-
import { useFrame as
|
|
14506
|
-
import { useLayoutEffect as useLayoutEffect6, useRef as
|
|
14903
|
+
import { useFrame as useFrame17, useThree as useThree25 } from "@react-three/fiber";
|
|
14904
|
+
import { useLayoutEffect as useLayoutEffect6, useRef as useRef34 } from "react";
|
|
14507
14905
|
import {
|
|
14508
14906
|
MathUtils as MathUtils10,
|
|
14509
14907
|
PerspectiveCamera as PerspectiveCamera7,
|
|
14510
|
-
Vector3 as
|
|
14908
|
+
Vector3 as Vector318
|
|
14511
14909
|
} from "three";
|
|
14512
|
-
import { jsx as
|
|
14513
|
-
var LINE_WORLD_POSITION = new
|
|
14910
|
+
import { jsx as jsx30 } from "react/jsx-runtime";
|
|
14911
|
+
var LINE_WORLD_POSITION = new Vector318();
|
|
14514
14912
|
function applyScreenSpaceDashScale(object, camera, viewportHeight) {
|
|
14515
14913
|
const material = object?.material;
|
|
14516
14914
|
if (!object || typeof material?.dashScale !== "number") {
|
|
@@ -14540,8 +14938,8 @@ function HotspotStrokeLine({
|
|
|
14540
14938
|
dashSize,
|
|
14541
14939
|
gapSize
|
|
14542
14940
|
}) {
|
|
14543
|
-
const lineRef =
|
|
14544
|
-
const { camera, size } =
|
|
14941
|
+
const lineRef = useRef34(null);
|
|
14942
|
+
const { camera, size } = useThree25();
|
|
14545
14943
|
const dash = resolveDash(dashSize, gapSize);
|
|
14546
14944
|
useLayoutEffect6(() => {
|
|
14547
14945
|
if (!dash.dashed) {
|
|
@@ -14549,13 +14947,13 @@ function HotspotStrokeLine({
|
|
|
14549
14947
|
}
|
|
14550
14948
|
applyScreenSpaceDashScale(lineRef.current, camera, size.height);
|
|
14551
14949
|
}, [camera, dash.dashed, dash.dashSize, dash.gapSize, size.height]);
|
|
14552
|
-
|
|
14950
|
+
useFrame17((state) => {
|
|
14553
14951
|
if (!dash.dashed) {
|
|
14554
14952
|
return;
|
|
14555
14953
|
}
|
|
14556
14954
|
applyScreenSpaceDashScale(lineRef.current, state.camera, state.size.height);
|
|
14557
14955
|
});
|
|
14558
|
-
return /* @__PURE__ */
|
|
14956
|
+
return /* @__PURE__ */ jsx30(
|
|
14559
14957
|
Line,
|
|
14560
14958
|
{
|
|
14561
14959
|
ref: lineRef,
|
|
@@ -14577,7 +14975,7 @@ function HotspotStrokeLine({
|
|
|
14577
14975
|
}
|
|
14578
14976
|
|
|
14579
14977
|
// src/hotspot/polygon-hotspot.tsx
|
|
14580
|
-
import { jsx as
|
|
14978
|
+
import { jsx as jsx31, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
14581
14979
|
var POLYGON_RADIUS = 990;
|
|
14582
14980
|
var MAX_FILL_SEGMENT_DEGREES = 7;
|
|
14583
14981
|
function cloneVertices(vertices) {
|
|
@@ -14649,7 +15047,7 @@ function polygonContainsDirection(vertices, direction) {
|
|
|
14649
15047
|
}
|
|
14650
15048
|
function fitsHemisphere(vertices) {
|
|
14651
15049
|
const directions = vertices.map((vertex) => panoPositionToVector3(vertex).normalize());
|
|
14652
|
-
const candidates = [new
|
|
15050
|
+
const candidates = [new Vector319()];
|
|
14653
15051
|
for (const direction of directions) {
|
|
14654
15052
|
candidates[0].add(direction);
|
|
14655
15053
|
candidates.push(direction.clone());
|
|
@@ -14673,7 +15071,7 @@ function validatePolygonVertices(vertices) {
|
|
|
14673
15071
|
if (hasSelfIntersection(unwrapped)) {
|
|
14674
15072
|
issues.push({ code: "self_intersection", message: "Polygon edges cannot cross." });
|
|
14675
15073
|
}
|
|
14676
|
-
if (polygonContainsDirection(normalized, new
|
|
15074
|
+
if (polygonContainsDirection(normalized, new Vector319(0, 1, 0)) || polygonContainsDirection(normalized, new Vector319(0, -1, 0))) {
|
|
14677
15075
|
issues.push({ code: "contains_pole", message: "Polygons cannot contain a panorama pole." });
|
|
14678
15076
|
}
|
|
14679
15077
|
if (!fitsHemisphere(normalized)) {
|
|
@@ -14684,7 +15082,7 @@ function validatePolygonVertices(vertices) {
|
|
|
14684
15082
|
function polygonCenter(vertices) {
|
|
14685
15083
|
const sum = vertices.reduce(
|
|
14686
15084
|
(total, vertex) => total.add(panoPositionToVector3(vertex).normalize()),
|
|
14687
|
-
new
|
|
15085
|
+
new Vector319()
|
|
14688
15086
|
);
|
|
14689
15087
|
return sum.lengthSq() > 1e-8 ? vector3ToPanoPosition(sum) : normalizePanoPosition(vertices[0]);
|
|
14690
15088
|
}
|
|
@@ -14693,7 +15091,7 @@ function surfaceQuaternion(position) {
|
|
|
14693
15091
|
const inward = outward.clone().negate();
|
|
14694
15092
|
const pitch = position.pitch * Math.PI / 180;
|
|
14695
15093
|
const yaw = position.yaw * Math.PI / 180;
|
|
14696
|
-
const localUp = new
|
|
15094
|
+
const localUp = new Vector319(
|
|
14697
15095
|
-Math.sin(pitch) * Math.sin(yaw),
|
|
14698
15096
|
Math.cos(pitch),
|
|
14699
15097
|
Math.sin(pitch) * Math.cos(yaw)
|
|
@@ -14706,7 +15104,7 @@ function makeWorldToLocal(center) {
|
|
|
14706
15104
|
return new Matrix45().compose(
|
|
14707
15105
|
panoPositionToVector3(center, POLYGON_RADIUS),
|
|
14708
15106
|
surfaceQuaternion(center),
|
|
14709
|
-
new
|
|
15107
|
+
new Vector319(1, 1, 1)
|
|
14710
15108
|
).invert();
|
|
14711
15109
|
}
|
|
14712
15110
|
function projectedPoint(a, b, c, weightB, weightC, radius, worldToLocal) {
|
|
@@ -14833,24 +15231,24 @@ function PolygonHotspot({
|
|
|
14833
15231
|
onInvalid,
|
|
14834
15232
|
...anchorProps
|
|
14835
15233
|
}) {
|
|
14836
|
-
const issues =
|
|
15234
|
+
const issues = useMemo25(() => validatePolygonVertices(vertices), [vertices]);
|
|
14837
15235
|
const valid = issues.length === 0;
|
|
14838
|
-
const center =
|
|
14839
|
-
const fillGeometry =
|
|
15236
|
+
const center = useMemo25(() => valid ? polygonCenter(vertices) : null, [valid, vertices]);
|
|
15237
|
+
const fillGeometry = useMemo25(
|
|
14840
15238
|
() => valid && center ? makeFillGeometry(vertices, center) : null,
|
|
14841
15239
|
[center, valid, vertices]
|
|
14842
15240
|
);
|
|
14843
|
-
const strokePoints =
|
|
15241
|
+
const strokePoints = useMemo25(
|
|
14844
15242
|
() => valid && center ? makeStrokePositions(vertices, center) : null,
|
|
14845
15243
|
[center, valid, vertices]
|
|
14846
15244
|
);
|
|
14847
15245
|
const resolvedStrokeOpacity = Math.max(0, Math.min(strokeOpacity, 1));
|
|
14848
|
-
const startVerticesRef =
|
|
15246
|
+
const startVerticesRef = useRef35(null);
|
|
14849
15247
|
const issuesKey = issues.map((issue) => issue.code).join(",");
|
|
14850
|
-
|
|
15248
|
+
useEffect34(() => {
|
|
14851
15249
|
if (!valid) onInvalid?.(issues);
|
|
14852
15250
|
}, [issues, issuesKey, onInvalid, valid]);
|
|
14853
|
-
|
|
15251
|
+
useEffect34(() => () => fillGeometry?.dispose(), [fillGeometry]);
|
|
14854
15252
|
if (!valid || !center || !fillGeometry || !strokePoints || strokePoints.length < 2) {
|
|
14855
15253
|
return null;
|
|
14856
15254
|
}
|
|
@@ -14865,7 +15263,7 @@ function PolygonHotspot({
|
|
|
14865
15263
|
startPosition: event.startPosition
|
|
14866
15264
|
});
|
|
14867
15265
|
};
|
|
14868
|
-
return /* @__PURE__ */
|
|
15266
|
+
return /* @__PURE__ */ jsxs20(
|
|
14869
15267
|
HotspotAnchor,
|
|
14870
15268
|
{
|
|
14871
15269
|
...anchorProps,
|
|
@@ -14880,7 +15278,7 @@ function PolygonHotspot({
|
|
|
14880
15278
|
draggable,
|
|
14881
15279
|
interactive,
|
|
14882
15280
|
useAngularScale: false,
|
|
14883
|
-
focusContent: /* @__PURE__ */
|
|
15281
|
+
focusContent: /* @__PURE__ */ jsx31(
|
|
14884
15282
|
HotspotStrokeLine,
|
|
14885
15283
|
{
|
|
14886
15284
|
color: "#75cbd3",
|
|
@@ -14902,7 +15300,7 @@ function PolygonHotspot({
|
|
|
14902
15300
|
startVerticesRef.current = null;
|
|
14903
15301
|
},
|
|
14904
15302
|
children: [
|
|
14905
|
-
/* @__PURE__ */
|
|
15303
|
+
/* @__PURE__ */ jsx31("mesh", { geometry: fillGeometry, renderOrder, children: /* @__PURE__ */ jsx31(
|
|
14906
15304
|
"meshBasicMaterial",
|
|
14907
15305
|
{
|
|
14908
15306
|
color: fill,
|
|
@@ -14912,7 +15310,7 @@ function PolygonHotspot({
|
|
|
14912
15310
|
transparent: true
|
|
14913
15311
|
}
|
|
14914
15312
|
) }),
|
|
14915
|
-
/* @__PURE__ */
|
|
15313
|
+
/* @__PURE__ */ jsx31(
|
|
14916
15314
|
HotspotStrokeLine,
|
|
14917
15315
|
{
|
|
14918
15316
|
color: stroke,
|
|
@@ -14930,14 +15328,14 @@ function PolygonHotspot({
|
|
|
14930
15328
|
}
|
|
14931
15329
|
|
|
14932
15330
|
// src/hotspot/polyline-hotspot.tsx
|
|
14933
|
-
import { useEffect as
|
|
15331
|
+
import { useEffect as useEffect35, useMemo as useMemo26, useRef as useRef36 } from "react";
|
|
14934
15332
|
import {
|
|
14935
15333
|
MathUtils as MathUtils11,
|
|
14936
15334
|
Matrix4 as Matrix46,
|
|
14937
15335
|
Quaternion as Quaternion6,
|
|
14938
|
-
Vector3 as
|
|
15336
|
+
Vector3 as Vector320
|
|
14939
15337
|
} from "three";
|
|
14940
|
-
import { jsx as
|
|
15338
|
+
import { jsx as jsx32 } from "react/jsx-runtime";
|
|
14941
15339
|
var POLYLINE_RADIUS = 990;
|
|
14942
15340
|
var MAX_SEGMENT_DEGREES = 7;
|
|
14943
15341
|
function cloneVertices2(vertices) {
|
|
@@ -14962,7 +15360,7 @@ function unwrapVertices(vertices) {
|
|
|
14962
15360
|
function polylineCenter(vertices) {
|
|
14963
15361
|
const sum = vertices.reduce(
|
|
14964
15362
|
(total, vertex) => total.add(panoPositionToVector3(vertex).normalize()),
|
|
14965
|
-
new
|
|
15363
|
+
new Vector320()
|
|
14966
15364
|
);
|
|
14967
15365
|
return sum.lengthSq() > 1e-8 ? vector3ToPanoPosition(sum) : normalizePanoPosition(vertices[0]);
|
|
14968
15366
|
}
|
|
@@ -14971,7 +15369,7 @@ function surfaceQuaternion2(position) {
|
|
|
14971
15369
|
const inward = outward.clone().negate();
|
|
14972
15370
|
const pitch = MathUtils11.degToRad(position.pitch);
|
|
14973
15371
|
const yaw = MathUtils11.degToRad(position.yaw);
|
|
14974
|
-
const localUp = new
|
|
15372
|
+
const localUp = new Vector320(
|
|
14975
15373
|
-Math.sin(pitch) * Math.sin(yaw),
|
|
14976
15374
|
Math.cos(pitch),
|
|
14977
15375
|
Math.sin(pitch) * Math.cos(yaw)
|
|
@@ -14984,7 +15382,7 @@ function makeWorldToLocal2(center) {
|
|
|
14984
15382
|
return new Matrix46().compose(
|
|
14985
15383
|
panoPositionToVector3(center, POLYLINE_RADIUS),
|
|
14986
15384
|
surfaceQuaternion2(center),
|
|
14987
|
-
new
|
|
15385
|
+
new Vector320(1, 1, 1)
|
|
14988
15386
|
).invert();
|
|
14989
15387
|
}
|
|
14990
15388
|
function subdivisionSteps(vertices) {
|
|
@@ -15054,16 +15452,16 @@ function PolylineHotspot({
|
|
|
15054
15452
|
onInvalid,
|
|
15055
15453
|
...anchorProps
|
|
15056
15454
|
}) {
|
|
15057
|
-
const issues =
|
|
15455
|
+
const issues = useMemo26(() => validatePolylineVertices(vertices), [vertices]);
|
|
15058
15456
|
const valid = issues.length === 0;
|
|
15059
|
-
const center =
|
|
15060
|
-
const linePoints =
|
|
15457
|
+
const center = useMemo26(() => valid ? polylineCenter(vertices) : null, [valid, vertices]);
|
|
15458
|
+
const linePoints = useMemo26(
|
|
15061
15459
|
() => valid && center ? makeLinePositions(vertices, center) : null,
|
|
15062
15460
|
[center, valid, vertices]
|
|
15063
15461
|
);
|
|
15064
15462
|
const opacity = Math.max(0, Math.min(strokeOpacity, 1));
|
|
15065
|
-
const startVerticesRef =
|
|
15066
|
-
|
|
15463
|
+
const startVerticesRef = useRef36(null);
|
|
15464
|
+
useEffect35(() => {
|
|
15067
15465
|
if (!valid) onInvalid?.(issues);
|
|
15068
15466
|
}, [issues, onInvalid, valid]);
|
|
15069
15467
|
if (!valid || !center || !linePoints || linePoints.length < 2) return null;
|
|
@@ -15077,7 +15475,7 @@ function PolylineHotspot({
|
|
|
15077
15475
|
startPosition: event.startPosition
|
|
15078
15476
|
});
|
|
15079
15477
|
};
|
|
15080
|
-
return /* @__PURE__ */
|
|
15478
|
+
return /* @__PURE__ */ jsx32(
|
|
15081
15479
|
HotspotAnchor,
|
|
15082
15480
|
{
|
|
15083
15481
|
...anchorProps,
|
|
@@ -15091,7 +15489,7 @@ function PolylineHotspot({
|
|
|
15091
15489
|
renderOrder,
|
|
15092
15490
|
draggable,
|
|
15093
15491
|
useAngularScale: false,
|
|
15094
|
-
focusContent: /* @__PURE__ */
|
|
15492
|
+
focusContent: /* @__PURE__ */ jsx32(
|
|
15095
15493
|
HotspotStrokeLine,
|
|
15096
15494
|
{
|
|
15097
15495
|
color: "#75cbd3",
|
|
@@ -15112,7 +15510,7 @@ function PolylineHotspot({
|
|
|
15112
15510
|
emitVerticesChange(event, onDragEnd);
|
|
15113
15511
|
startVerticesRef.current = null;
|
|
15114
15512
|
},
|
|
15115
|
-
children: /* @__PURE__ */
|
|
15513
|
+
children: /* @__PURE__ */ jsx32(
|
|
15116
15514
|
HotspotStrokeLine,
|
|
15117
15515
|
{
|
|
15118
15516
|
color: stroke,
|
|
@@ -15129,7 +15527,7 @@ function PolylineHotspot({
|
|
|
15129
15527
|
}
|
|
15130
15528
|
|
|
15131
15529
|
// src/hotspot/graphic-hotspot.tsx
|
|
15132
|
-
import { useEffect as
|
|
15530
|
+
import { useEffect as useEffect36, useRef as useRef37, useState as useState18 } from "react";
|
|
15133
15531
|
import {
|
|
15134
15532
|
CanvasTexture,
|
|
15135
15533
|
ClampToEdgeWrapping as ClampToEdgeWrapping4,
|
|
@@ -15137,7 +15535,7 @@ import {
|
|
|
15137
15535
|
LinearMipmapLinearFilter as LinearMipmapLinearFilter4,
|
|
15138
15536
|
SRGBColorSpace as SRGBColorSpace6
|
|
15139
15537
|
} from "three";
|
|
15140
|
-
import { jsx as
|
|
15538
|
+
import { jsx as jsx33 } from "react/jsx-runtime";
|
|
15141
15539
|
var GRAPHIC_TEXTURE_SIZE = 512;
|
|
15142
15540
|
function resolveStrokeWidth(value) {
|
|
15143
15541
|
return Number.isFinite(value) ? Math.max(value, 0) : 8;
|
|
@@ -15327,11 +15725,11 @@ function createGraphicTexture(graphic, aspectWidth, aspectHeight) {
|
|
|
15327
15725
|
}
|
|
15328
15726
|
function useGraphicTexture(graphic, aspectWidth, aspectHeight, onLoad, onError) {
|
|
15329
15727
|
const [texture, setTexture] = useState18(null);
|
|
15330
|
-
const onLoadRef =
|
|
15331
|
-
const onErrorRef =
|
|
15728
|
+
const onLoadRef = useRef37(onLoad);
|
|
15729
|
+
const onErrorRef = useRef37(onError);
|
|
15332
15730
|
onLoadRef.current = onLoad;
|
|
15333
15731
|
onErrorRef.current = onError;
|
|
15334
|
-
|
|
15732
|
+
useEffect36(() => {
|
|
15335
15733
|
let nextTexture = null;
|
|
15336
15734
|
try {
|
|
15337
15735
|
nextTexture = createGraphicTexture(graphic, aspectWidth, aspectHeight);
|
|
@@ -15357,20 +15755,20 @@ function CanvasGraphicHotspot({
|
|
|
15357
15755
|
...anchorProps
|
|
15358
15756
|
}) {
|
|
15359
15757
|
const texture = useGraphicTexture(graphic, width, height, onLoad, onError);
|
|
15360
|
-
return /* @__PURE__ */
|
|
15758
|
+
return /* @__PURE__ */ jsx33(HotspotAnchor, { ...anchorProps, height, width, children: /* @__PURE__ */ jsx33(HotspotPlane, { map: texture, opacity }) });
|
|
15361
15759
|
}
|
|
15362
15760
|
function GraphicHotspot(props) {
|
|
15363
15761
|
const { graphic, ...restProps } = props;
|
|
15364
15762
|
if (graphic.kind === "svg") {
|
|
15365
15763
|
const imageProps = restProps;
|
|
15366
|
-
return /* @__PURE__ */
|
|
15764
|
+
return /* @__PURE__ */ jsx33(ImageHotspot, { ...imageProps, src: graphic.src });
|
|
15367
15765
|
}
|
|
15368
|
-
return /* @__PURE__ */
|
|
15766
|
+
return /* @__PURE__ */ jsx33(CanvasGraphicHotspot, { ...restProps, graphic });
|
|
15369
15767
|
}
|
|
15370
15768
|
|
|
15371
15769
|
// src/hotspot/sequence-hotspot.tsx
|
|
15372
|
-
import { useFrame as
|
|
15373
|
-
import { useEffect as
|
|
15770
|
+
import { useFrame as useFrame18, useThree as useThree26 } from "@react-three/fiber";
|
|
15771
|
+
import { useEffect as useEffect37, useRef as useRef38, useState as useState19 } from "react";
|
|
15374
15772
|
import {
|
|
15375
15773
|
ClampToEdgeWrapping as ClampToEdgeWrapping5,
|
|
15376
15774
|
LinearFilter as LinearFilter8,
|
|
@@ -15378,7 +15776,7 @@ import {
|
|
|
15378
15776
|
SRGBColorSpace as SRGBColorSpace7,
|
|
15379
15777
|
TextureLoader as TextureLoader6
|
|
15380
15778
|
} from "three";
|
|
15381
|
-
import { jsx as
|
|
15779
|
+
import { jsx as jsx34 } from "react/jsx-runtime";
|
|
15382
15780
|
var DEFAULT_SEQUENCE_FPS = 12;
|
|
15383
15781
|
function resolveFps(value) {
|
|
15384
15782
|
return Number.isFinite(value) && value > 0 ? value : DEFAULT_SEQUENCE_FPS;
|
|
@@ -15392,13 +15790,13 @@ function useSpriteTexture({
|
|
|
15392
15790
|
onError,
|
|
15393
15791
|
onLoadProgress
|
|
15394
15792
|
}) {
|
|
15395
|
-
const gl =
|
|
15793
|
+
const gl = useThree26((state) => state.gl);
|
|
15396
15794
|
const [texture, setTexture] = useState19(null);
|
|
15397
|
-
const onErrorRef =
|
|
15398
|
-
const onLoadProgressRef =
|
|
15795
|
+
const onErrorRef = useRef38(onError);
|
|
15796
|
+
const onLoadProgressRef = useRef38(onLoadProgress);
|
|
15399
15797
|
onErrorRef.current = onError;
|
|
15400
15798
|
onLoadProgressRef.current = onLoadProgress;
|
|
15401
|
-
|
|
15799
|
+
useEffect37(() => {
|
|
15402
15800
|
let active = true;
|
|
15403
15801
|
setTexture(null);
|
|
15404
15802
|
if (!src) {
|
|
@@ -15439,7 +15837,7 @@ function useSpriteTexture({
|
|
|
15439
15837
|
active = false;
|
|
15440
15838
|
};
|
|
15441
15839
|
}, [gl, id, src]);
|
|
15442
|
-
|
|
15840
|
+
useEffect37(
|
|
15443
15841
|
() => () => {
|
|
15444
15842
|
texture?.dispose();
|
|
15445
15843
|
},
|
|
@@ -15469,23 +15867,23 @@ function SequenceHotspot({
|
|
|
15469
15867
|
const frameCount = resolveFrameCount(requestedFrameCount);
|
|
15470
15868
|
const safeFps = resolveFps(fps);
|
|
15471
15869
|
const [frameIndex, setFrameIndex] = useState19(0);
|
|
15472
|
-
const elapsedRef =
|
|
15473
|
-
const frameIndexRef =
|
|
15474
|
-
const endedRef =
|
|
15475
|
-
const lastPlaybackStateRef =
|
|
15476
|
-
const onFrameChangeRef =
|
|
15477
|
-
const onPlaybackStateChangeRef =
|
|
15478
|
-
const onEndedRef =
|
|
15870
|
+
const elapsedRef = useRef38(0);
|
|
15871
|
+
const frameIndexRef = useRef38(0);
|
|
15872
|
+
const endedRef = useRef38(false);
|
|
15873
|
+
const lastPlaybackStateRef = useRef38(null);
|
|
15874
|
+
const onFrameChangeRef = useRef38(onFrameChange);
|
|
15875
|
+
const onPlaybackStateChangeRef = useRef38(onPlaybackStateChange);
|
|
15876
|
+
const onEndedRef = useRef38(onEnded);
|
|
15479
15877
|
onFrameChangeRef.current = onFrameChange;
|
|
15480
15878
|
onPlaybackStateChangeRef.current = onPlaybackStateChange;
|
|
15481
15879
|
onEndedRef.current = onEnded;
|
|
15482
|
-
|
|
15880
|
+
useEffect37(() => {
|
|
15483
15881
|
elapsedRef.current = 0;
|
|
15484
15882
|
frameIndexRef.current = 0;
|
|
15485
15883
|
endedRef.current = false;
|
|
15486
15884
|
setFrameIndex(0);
|
|
15487
15885
|
}, [frameCount, frameDirection, src]);
|
|
15488
|
-
|
|
15886
|
+
useEffect37(() => {
|
|
15489
15887
|
if (!texture) {
|
|
15490
15888
|
return;
|
|
15491
15889
|
}
|
|
@@ -15499,13 +15897,13 @@ function SequenceHotspot({
|
|
|
15499
15897
|
);
|
|
15500
15898
|
texture.needsUpdate = true;
|
|
15501
15899
|
}, [frameCount, frameDirection, frameIndex, texture]);
|
|
15502
|
-
|
|
15900
|
+
useEffect37(() => {
|
|
15503
15901
|
if (!texture) {
|
|
15504
15902
|
return;
|
|
15505
15903
|
}
|
|
15506
15904
|
onFrameChangeRef.current?.({ id, index: 0, src });
|
|
15507
15905
|
}, [id, src, texture]);
|
|
15508
|
-
|
|
15906
|
+
useEffect37(() => {
|
|
15509
15907
|
if (!texture) {
|
|
15510
15908
|
return;
|
|
15511
15909
|
}
|
|
@@ -15524,7 +15922,7 @@ function SequenceHotspot({
|
|
|
15524
15922
|
onPlaybackStateChangeRef.current?.(nextState);
|
|
15525
15923
|
}
|
|
15526
15924
|
}, [playing, texture]);
|
|
15527
|
-
|
|
15925
|
+
useFrame18((_, deltaSeconds) => {
|
|
15528
15926
|
if (!texture || !playing || endedRef.current) {
|
|
15529
15927
|
return;
|
|
15530
15928
|
}
|
|
@@ -15554,12 +15952,12 @@ function SequenceHotspot({
|
|
|
15554
15952
|
onFrameChangeRef.current?.({ id, index: nextIndex, src });
|
|
15555
15953
|
}
|
|
15556
15954
|
});
|
|
15557
|
-
return /* @__PURE__ */
|
|
15955
|
+
return /* @__PURE__ */ jsx34(HotspotAnchor, { ...anchorProps, id, height, width, children: /* @__PURE__ */ jsx34(HotspotPlane, { map: texture, opacity }) });
|
|
15558
15956
|
}
|
|
15559
15957
|
|
|
15560
15958
|
// src/hotspot/video-hotspot.tsx
|
|
15561
|
-
import { useThree as
|
|
15562
|
-
import { useEffect as
|
|
15959
|
+
import { useThree as useThree27 } from "@react-three/fiber";
|
|
15960
|
+
import { useEffect as useEffect38, useRef as useRef39, useState as useState20 } from "react";
|
|
15563
15961
|
import {
|
|
15564
15962
|
ClampToEdgeWrapping as ClampToEdgeWrapping6,
|
|
15565
15963
|
LinearFilter as LinearFilter9,
|
|
@@ -15568,7 +15966,7 @@ import {
|
|
|
15568
15966
|
TextureLoader as TextureLoader7,
|
|
15569
15967
|
VideoTexture as VideoTexture2
|
|
15570
15968
|
} from "three";
|
|
15571
|
-
import { jsx as
|
|
15969
|
+
import { jsx as jsx35 } from "react/jsx-runtime";
|
|
15572
15970
|
function clampVolume2(volume) {
|
|
15573
15971
|
if (!Number.isFinite(volume)) {
|
|
15574
15972
|
return 1;
|
|
@@ -15576,11 +15974,11 @@ function clampVolume2(volume) {
|
|
|
15576
15974
|
return Math.max(0, Math.min(volume, 1));
|
|
15577
15975
|
}
|
|
15578
15976
|
function usePosterTexture2(id, poster, onError) {
|
|
15579
|
-
const gl =
|
|
15977
|
+
const gl = useThree27((state) => state.gl);
|
|
15580
15978
|
const [texture, setTexture] = useState20(null);
|
|
15581
|
-
const onErrorRef =
|
|
15979
|
+
const onErrorRef = useRef39(onError);
|
|
15582
15980
|
onErrorRef.current = onError;
|
|
15583
|
-
|
|
15981
|
+
useEffect38(() => {
|
|
15584
15982
|
let active = true;
|
|
15585
15983
|
setTexture(null);
|
|
15586
15984
|
if (!poster) {
|
|
@@ -15617,7 +16015,7 @@ function usePosterTexture2(id, poster, onError) {
|
|
|
15617
16015
|
active = false;
|
|
15618
16016
|
};
|
|
15619
16017
|
}, [gl, id, poster]);
|
|
15620
|
-
|
|
16018
|
+
useEffect38(
|
|
15621
16019
|
() => () => {
|
|
15622
16020
|
texture?.dispose();
|
|
15623
16021
|
},
|
|
@@ -15636,13 +16034,13 @@ function useVideoResource({
|
|
|
15636
16034
|
src
|
|
15637
16035
|
}) {
|
|
15638
16036
|
const [resource, setResource] = useState20(null);
|
|
15639
|
-
const onEndedRef =
|
|
15640
|
-
const onErrorRef =
|
|
15641
|
-
const onPlaybackStateChangeRef =
|
|
16037
|
+
const onEndedRef = useRef39(onEnded);
|
|
16038
|
+
const onErrorRef = useRef39(onError);
|
|
16039
|
+
const onPlaybackStateChangeRef = useRef39(onPlaybackStateChange);
|
|
15642
16040
|
onEndedRef.current = onEnded;
|
|
15643
16041
|
onErrorRef.current = onError;
|
|
15644
16042
|
onPlaybackStateChangeRef.current = onPlaybackStateChange;
|
|
15645
|
-
|
|
16043
|
+
useEffect38(() => {
|
|
15646
16044
|
if (!src) {
|
|
15647
16045
|
setResource(null);
|
|
15648
16046
|
return;
|
|
@@ -15749,11 +16147,11 @@ function VideoHotspot({
|
|
|
15749
16147
|
src
|
|
15750
16148
|
});
|
|
15751
16149
|
const posterTexture = usePosterTexture2(id, poster, onError);
|
|
15752
|
-
const onPlaybackErrorRef =
|
|
15753
|
-
const onPlaybackStateChangeRef =
|
|
16150
|
+
const onPlaybackErrorRef = useRef39(onPlaybackError);
|
|
16151
|
+
const onPlaybackStateChangeRef = useRef39(onPlaybackStateChange);
|
|
15754
16152
|
onPlaybackErrorRef.current = onPlaybackError;
|
|
15755
16153
|
onPlaybackStateChangeRef.current = onPlaybackStateChange;
|
|
15756
|
-
|
|
16154
|
+
useEffect38(() => {
|
|
15757
16155
|
if (!resource) {
|
|
15758
16156
|
return;
|
|
15759
16157
|
}
|
|
@@ -15770,7 +16168,7 @@ function VideoHotspot({
|
|
|
15770
16168
|
}
|
|
15771
16169
|
resource.video.preload = preload;
|
|
15772
16170
|
}, [loop, muted, playsInline, preload, resource, volume]);
|
|
15773
|
-
|
|
16171
|
+
useEffect38(() => {
|
|
15774
16172
|
if (!resource) {
|
|
15775
16173
|
return;
|
|
15776
16174
|
}
|
|
@@ -15793,12 +16191,12 @@ function VideoHotspot({
|
|
|
15793
16191
|
};
|
|
15794
16192
|
}, [playing, resource]);
|
|
15795
16193
|
const activeTexture = resource?.ready ? resource.texture : posterTexture;
|
|
15796
|
-
return /* @__PURE__ */
|
|
16194
|
+
return /* @__PURE__ */ jsx35(HotspotAnchor, { ...anchorProps, id, height, width, children: /* @__PURE__ */ jsx35(HotspotPlane, { map: activeTexture, opacity }) });
|
|
15797
16195
|
}
|
|
15798
16196
|
|
|
15799
16197
|
// src/hotspot/audio-hotspot.tsx
|
|
15800
|
-
import { useFrame as
|
|
15801
|
-
import { useEffect as
|
|
16198
|
+
import { useFrame as useFrame19, useThree as useThree28 } from "@react-three/fiber";
|
|
16199
|
+
import { useEffect as useEffect39, useRef as useRef40, useState as useState21 } from "react";
|
|
15802
16200
|
import {
|
|
15803
16201
|
CanvasTexture as CanvasTexture2,
|
|
15804
16202
|
ClampToEdgeWrapping as ClampToEdgeWrapping7,
|
|
@@ -15807,7 +16205,7 @@ import {
|
|
|
15807
16205
|
SRGBColorSpace as SRGBColorSpace9,
|
|
15808
16206
|
TextureLoader as TextureLoader8
|
|
15809
16207
|
} from "three";
|
|
15810
|
-
import { jsx as
|
|
16208
|
+
import { jsx as jsx36 } from "react/jsx-runtime";
|
|
15811
16209
|
var SPEAKER_TEXTURE_SIZE = 512;
|
|
15812
16210
|
function paintSpeakerBody(context, center) {
|
|
15813
16211
|
context.fillStyle = "#f5fbfc";
|
|
@@ -15872,7 +16270,7 @@ function createSpeakerTexture(state) {
|
|
|
15872
16270
|
}
|
|
15873
16271
|
function useSpeakerTextures(enabled) {
|
|
15874
16272
|
const [textures, setTextures] = useState21({ playing: null, stopped: null });
|
|
15875
|
-
|
|
16273
|
+
useEffect39(() => {
|
|
15876
16274
|
if (!enabled) {
|
|
15877
16275
|
setTextures({ playing: null, stopped: null });
|
|
15878
16276
|
return;
|
|
@@ -15888,11 +16286,11 @@ function useSpeakerTextures(enabled) {
|
|
|
15888
16286
|
return textures;
|
|
15889
16287
|
}
|
|
15890
16288
|
function useIconTexture(icon, enabled, onError, id) {
|
|
15891
|
-
const gl =
|
|
16289
|
+
const gl = useThree28((state) => state.gl);
|
|
15892
16290
|
const [texture, setTexture] = useState21(null);
|
|
15893
|
-
const onErrorRef =
|
|
16291
|
+
const onErrorRef = useRef40(onError);
|
|
15894
16292
|
onErrorRef.current = onError;
|
|
15895
|
-
|
|
16293
|
+
useEffect39(() => {
|
|
15896
16294
|
let active = true;
|
|
15897
16295
|
setTexture(null);
|
|
15898
16296
|
if (!enabled || !icon) {
|
|
@@ -15929,7 +16327,7 @@ function useIconTexture(icon, enabled, onError, id) {
|
|
|
15929
16327
|
active = false;
|
|
15930
16328
|
};
|
|
15931
16329
|
}, [enabled, gl, icon, id]);
|
|
15932
|
-
|
|
16330
|
+
useEffect39(
|
|
15933
16331
|
() => () => {
|
|
15934
16332
|
texture?.dispose();
|
|
15935
16333
|
},
|
|
@@ -15949,12 +16347,12 @@ function useAudioHowl({
|
|
|
15949
16347
|
src
|
|
15950
16348
|
}) {
|
|
15951
16349
|
const [howl, setHowl] = useState21(null);
|
|
15952
|
-
const playingRef =
|
|
15953
|
-
const loopRef =
|
|
15954
|
-
const onEndedRef =
|
|
15955
|
-
const onErrorRef =
|
|
15956
|
-
const onPlaybackErrorRef =
|
|
15957
|
-
const onPlaybackStateChangeRef =
|
|
16350
|
+
const playingRef = useRef40(playing);
|
|
16351
|
+
const loopRef = useRef40(loop ?? false);
|
|
16352
|
+
const onEndedRef = useRef40(onEnded);
|
|
16353
|
+
const onErrorRef = useRef40(onError);
|
|
16354
|
+
const onPlaybackErrorRef = useRef40(onPlaybackError);
|
|
16355
|
+
const onPlaybackStateChangeRef = useRef40(onPlaybackStateChange);
|
|
15958
16356
|
playingRef.current = playing;
|
|
15959
16357
|
loopRef.current = loop ?? false;
|
|
15960
16358
|
onEndedRef.current = onEnded;
|
|
@@ -15962,7 +16360,7 @@ function useAudioHowl({
|
|
|
15962
16360
|
onPlaybackErrorRef.current = onPlaybackError;
|
|
15963
16361
|
onPlaybackStateChangeRef.current = onPlaybackStateChange;
|
|
15964
16362
|
const sourcesKey = sourceList(src).join("\0");
|
|
15965
|
-
|
|
16363
|
+
useEffect39(() => {
|
|
15966
16364
|
const sources = sourcesKey.length > 0 ? sourcesKey.split("\0") : [];
|
|
15967
16365
|
if (sources.length === 0) {
|
|
15968
16366
|
setHowl(null);
|
|
@@ -15999,7 +16397,7 @@ function useAudioHowl({
|
|
|
15999
16397
|
handle.dispose();
|
|
16000
16398
|
};
|
|
16001
16399
|
}, [crossOrigin, id, sourcesKey]);
|
|
16002
|
-
|
|
16400
|
+
useEffect39(() => {
|
|
16003
16401
|
howl?.loop(loop ?? false);
|
|
16004
16402
|
}, [howl, loop]);
|
|
16005
16403
|
return howl;
|
|
@@ -16027,7 +16425,7 @@ function AudioHotspot({
|
|
|
16027
16425
|
...anchorProps
|
|
16028
16426
|
}) {
|
|
16029
16427
|
usePanoMediaActivationIntent(playing);
|
|
16030
|
-
const camera =
|
|
16428
|
+
const camera = useThree28((state) => state.camera);
|
|
16031
16429
|
const howl = useAudioHowl({
|
|
16032
16430
|
crossOrigin,
|
|
16033
16431
|
id,
|
|
@@ -16043,15 +16441,15 @@ function AudioHotspot({
|
|
|
16043
16441
|
const stoppedIconTexture = useIconTexture(icon, marker, onError, id);
|
|
16044
16442
|
const playingIconTexture = useIconTexture(playingIcon, marker, onError, id);
|
|
16045
16443
|
const markerTexture = playing ? playingIconTexture ?? stoppedIconTexture ?? speakerTextures.playing : stoppedIconTexture ?? speakerTextures.stopped;
|
|
16046
|
-
const playingRef =
|
|
16444
|
+
const playingRef = useRef40(playing);
|
|
16047
16445
|
playingRef.current = playing;
|
|
16048
|
-
const mutedRef =
|
|
16049
|
-
const volumeRef =
|
|
16050
|
-
const rangeRef =
|
|
16446
|
+
const mutedRef = useRef40(muted);
|
|
16447
|
+
const volumeRef = useRef40(volume);
|
|
16448
|
+
const rangeRef = useRef40(range);
|
|
16051
16449
|
mutedRef.current = muted;
|
|
16052
16450
|
volumeRef.current = volume;
|
|
16053
16451
|
rangeRef.current = range;
|
|
16054
|
-
|
|
16452
|
+
useEffect39(() => {
|
|
16055
16453
|
if (!howl) {
|
|
16056
16454
|
return;
|
|
16057
16455
|
}
|
|
@@ -16061,7 +16459,7 @@ function AudioHotspot({
|
|
|
16061
16459
|
}
|
|
16062
16460
|
howl.play();
|
|
16063
16461
|
}, [howl, playing]);
|
|
16064
|
-
|
|
16462
|
+
useEffect39(() => {
|
|
16065
16463
|
if (!howl || !pauseWhenHidden) {
|
|
16066
16464
|
return;
|
|
16067
16465
|
}
|
|
@@ -16079,7 +16477,7 @@ function AudioHotspot({
|
|
|
16079
16477
|
document.removeEventListener("visibilitychange", handleVisibility);
|
|
16080
16478
|
};
|
|
16081
16479
|
}, [howl, pauseWhenHidden]);
|
|
16082
|
-
|
|
16480
|
+
useFrame19(() => {
|
|
16083
16481
|
if (!howl) {
|
|
16084
16482
|
return;
|
|
16085
16483
|
}
|
|
@@ -16092,11 +16490,11 @@ function AudioHotspot({
|
|
|
16092
16490
|
howl.mute(mutedRef.current);
|
|
16093
16491
|
howl.volume(clampAudioVolume(volumeRef.current) * spatial.gain);
|
|
16094
16492
|
});
|
|
16095
|
-
return /* @__PURE__ */
|
|
16493
|
+
return /* @__PURE__ */ jsx36(HotspotAnchor, { ...anchorProps, id, height, width, children: marker ? /* @__PURE__ */ jsx36(HotspotPlane, { map: markerTexture, opacity }) : null });
|
|
16096
16494
|
}
|
|
16097
16495
|
|
|
16098
16496
|
// src/hotspot/text-hotspot.tsx
|
|
16099
|
-
import { useEffect as
|
|
16497
|
+
import { useEffect as useEffect40, useRef as useRef41, useState as useState22 } from "react";
|
|
16100
16498
|
import {
|
|
16101
16499
|
CanvasTexture as CanvasTexture3,
|
|
16102
16500
|
ClampToEdgeWrapping as ClampToEdgeWrapping8,
|
|
@@ -16104,7 +16502,7 @@ import {
|
|
|
16104
16502
|
LinearMipmapLinearFilter as LinearMipmapLinearFilter8,
|
|
16105
16503
|
SRGBColorSpace as SRGBColorSpace10
|
|
16106
16504
|
} from "three";
|
|
16107
|
-
import { jsx as
|
|
16505
|
+
import { jsx as jsx37 } from "react/jsx-runtime";
|
|
16108
16506
|
var TEXT_TEXTURE_LONG_SIDE = 1024;
|
|
16109
16507
|
var DEFAULT_FONT_FAMILY = "system-ui, sans-serif";
|
|
16110
16508
|
var DEFAULT_FONT_SIZE = 96;
|
|
@@ -16325,11 +16723,11 @@ function createTextTexture(text, width, height, style) {
|
|
|
16325
16723
|
}
|
|
16326
16724
|
function useTextTexture(text, width, height, style, onLoad, onError) {
|
|
16327
16725
|
const [texture, setTexture] = useState22(null);
|
|
16328
|
-
const onLoadRef =
|
|
16329
|
-
const onErrorRef =
|
|
16726
|
+
const onLoadRef = useRef41(onLoad);
|
|
16727
|
+
const onErrorRef = useRef41(onError);
|
|
16330
16728
|
onLoadRef.current = onLoad;
|
|
16331
16729
|
onErrorRef.current = onError;
|
|
16332
|
-
|
|
16730
|
+
useEffect40(() => {
|
|
16333
16731
|
let cancelled = false;
|
|
16334
16732
|
let nextTexture = null;
|
|
16335
16733
|
const run = async () => {
|
|
@@ -16422,13 +16820,13 @@ function TextHotspot({
|
|
|
16422
16820
|
whiteSpace
|
|
16423
16821
|
};
|
|
16424
16822
|
const texture = useTextTexture(text, width, height, style, onLoad, onError);
|
|
16425
|
-
return /* @__PURE__ */
|
|
16823
|
+
return /* @__PURE__ */ jsx37(HotspotAnchor, { ...anchorProps, height, width, children: /* @__PURE__ */ jsx37(HotspotPlane, { map: texture, opacity }) });
|
|
16426
16824
|
}
|
|
16427
16825
|
|
|
16428
16826
|
// src/hotspot/iframe-hotspot.tsx
|
|
16429
16827
|
import { Html } from "@react-three/drei";
|
|
16430
16828
|
import { DoubleSide as DoubleSide6 } from "three";
|
|
16431
|
-
import { jsx as
|
|
16829
|
+
import { jsx as jsx38, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
16432
16830
|
var IFRAME_LONG_SIDE = 800;
|
|
16433
16831
|
var CSS3D_DISTANCE_FACTOR = 400;
|
|
16434
16832
|
var DEFAULT_SANDBOX = "allow-scripts allow-popups allow-forms";
|
|
@@ -16485,7 +16883,7 @@ function IframeHotspot({
|
|
|
16485
16883
|
interactive,
|
|
16486
16884
|
pointerEvents
|
|
16487
16885
|
);
|
|
16488
|
-
return /* @__PURE__ */
|
|
16886
|
+
return /* @__PURE__ */ jsxs21(
|
|
16489
16887
|
HotspotAnchor,
|
|
16490
16888
|
{
|
|
16491
16889
|
...anchorProps,
|
|
@@ -16494,9 +16892,9 @@ function IframeHotspot({
|
|
|
16494
16892
|
pointerEvents,
|
|
16495
16893
|
width,
|
|
16496
16894
|
children: [
|
|
16497
|
-
/* @__PURE__ */
|
|
16498
|
-
/* @__PURE__ */
|
|
16499
|
-
/* @__PURE__ */
|
|
16895
|
+
/* @__PURE__ */ jsxs21("mesh", { children: [
|
|
16896
|
+
/* @__PURE__ */ jsx38("planeGeometry", { args: [1, 1] }),
|
|
16897
|
+
/* @__PURE__ */ jsx38(
|
|
16500
16898
|
"meshBasicMaterial",
|
|
16501
16899
|
{
|
|
16502
16900
|
depthWrite: false,
|
|
@@ -16507,7 +16905,7 @@ function IframeHotspot({
|
|
|
16507
16905
|
}
|
|
16508
16906
|
)
|
|
16509
16907
|
] }),
|
|
16510
|
-
/* @__PURE__ */
|
|
16908
|
+
/* @__PURE__ */ jsx38(
|
|
16511
16909
|
Html,
|
|
16512
16910
|
{
|
|
16513
16911
|
distanceFactor: CSS3D_DISTANCE_FACTOR,
|
|
@@ -16522,7 +16920,7 @@ function IframeHotspot({
|
|
|
16522
16920
|
},
|
|
16523
16921
|
transform: true,
|
|
16524
16922
|
zIndexRange: [10, 0],
|
|
16525
|
-
children: /* @__PURE__ */
|
|
16923
|
+
children: /* @__PURE__ */ jsx38(
|
|
16526
16924
|
"iframe",
|
|
16527
16925
|
{
|
|
16528
16926
|
allow,
|