@ericchen1990/pano-view 3.3.0 → 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 +30 -6
- package/README.zh-CN.md +9 -3
- package/dist/index.cjs +1264 -904
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +12 -1
- package/dist/index.d.ts +12 -1
- package/dist/index.mjs +992 -632
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -9700,7 +9700,7 @@ function usePanoViewer() {
|
|
|
9700
9700
|
|
|
9701
9701
|
// src/sphere-tile/sphere-tile.tsx
|
|
9702
9702
|
var import_fiber16 = require("@react-three/fiber");
|
|
9703
|
-
var
|
|
9703
|
+
var import_react40 = require("react");
|
|
9704
9704
|
var import_three14 = require("three");
|
|
9705
9705
|
|
|
9706
9706
|
// src/asset-url.ts
|
|
@@ -9968,6 +9968,27 @@ function PanoBasicMaterial({
|
|
|
9968
9968
|
);
|
|
9969
9969
|
}
|
|
9970
9970
|
|
|
9971
|
+
// src/scene-detail.tsx
|
|
9972
|
+
var import_react37 = require("react");
|
|
9973
|
+
var SceneDetailContext = (0, import_react37.createContext)(null);
|
|
9974
|
+
function useSceneDetailReporter() {
|
|
9975
|
+
return (0, import_react37.useContext)(SceneDetailContext);
|
|
9976
|
+
}
|
|
9977
|
+
function viewTilesAreDrawable(textures) {
|
|
9978
|
+
return textures.length > 0 && textures.every((texture) => texture != null);
|
|
9979
|
+
}
|
|
9980
|
+
function publishSceneDetail(reporter, lastToken, ready) {
|
|
9981
|
+
if (!reporter) {
|
|
9982
|
+
return;
|
|
9983
|
+
}
|
|
9984
|
+
const token = `${reporter.generation}:${ready ? 1 : 0}`;
|
|
9985
|
+
if (lastToken.current === token) {
|
|
9986
|
+
return;
|
|
9987
|
+
}
|
|
9988
|
+
lastToken.current = token;
|
|
9989
|
+
reporter.report(ready);
|
|
9990
|
+
}
|
|
9991
|
+
|
|
9971
9992
|
// src/tile/texture-manager.ts
|
|
9972
9993
|
var import_three11 = require("three");
|
|
9973
9994
|
var EMPTY_TEXTURE_SNAPSHOT = {
|
|
@@ -10195,9 +10216,9 @@ var TileTextureManager = class {
|
|
|
10195
10216
|
|
|
10196
10217
|
// src/tile/texture-manager-context.tsx
|
|
10197
10218
|
var import_fiber15 = require("@react-three/fiber");
|
|
10198
|
-
var
|
|
10219
|
+
var import_react38 = require("react");
|
|
10199
10220
|
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
10200
|
-
var TileTextureManagerContext = (0,
|
|
10221
|
+
var TileTextureManagerContext = (0, import_react38.createContext)(null);
|
|
10201
10222
|
function TileTextureManagerProvider({
|
|
10202
10223
|
children,
|
|
10203
10224
|
maxTextureMemoryMb = 128,
|
|
@@ -10205,7 +10226,7 @@ function TileTextureManagerProvider({
|
|
|
10205
10226
|
}) {
|
|
10206
10227
|
const gl = (0, import_fiber15.useThree)((state) => state.gl);
|
|
10207
10228
|
const anisotropy = gl.capabilities.getMaxAnisotropy();
|
|
10208
|
-
const manager = (0,
|
|
10229
|
+
const manager = (0, import_react38.useMemo)(
|
|
10209
10230
|
() => new TileTextureManager({
|
|
10210
10231
|
anisotropy,
|
|
10211
10232
|
maxBytes: Math.max(1, maxTextureMemoryMb) * 1024 * 1024,
|
|
@@ -10214,24 +10235,24 @@ function TileTextureManagerProvider({
|
|
|
10214
10235
|
}),
|
|
10215
10236
|
[anisotropy, maxConcurrentLoads, maxTextureMemoryMb]
|
|
10216
10237
|
);
|
|
10217
|
-
(0,
|
|
10238
|
+
(0, import_react38.useEffect)(() => {
|
|
10218
10239
|
manager.resume();
|
|
10219
10240
|
return () => manager.dispose();
|
|
10220
10241
|
}, [manager]);
|
|
10221
10242
|
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TileTextureManagerContext.Provider, { value: manager, children });
|
|
10222
10243
|
}
|
|
10223
10244
|
function useSharedTileTextureManager() {
|
|
10224
|
-
return (0,
|
|
10245
|
+
return (0, import_react38.useContext)(TileTextureManagerContext);
|
|
10225
10246
|
}
|
|
10226
10247
|
|
|
10227
10248
|
// src/tile/texture-hooks.ts
|
|
10228
|
-
var
|
|
10249
|
+
var import_react39 = require("react");
|
|
10229
10250
|
var import_three12 = require("three");
|
|
10230
10251
|
function usePreviewTexture(url, anisotropy, onError) {
|
|
10231
|
-
const [texture, setTexture] = (0,
|
|
10232
|
-
const onErrorRef = (0,
|
|
10252
|
+
const [texture, setTexture] = (0, import_react39.useState)(null);
|
|
10253
|
+
const onErrorRef = (0, import_react39.useRef)(onError);
|
|
10233
10254
|
onErrorRef.current = onError;
|
|
10234
|
-
(0,
|
|
10255
|
+
(0, import_react39.useEffect)(() => {
|
|
10235
10256
|
if (!url) {
|
|
10236
10257
|
setTexture(null);
|
|
10237
10258
|
return;
|
|
@@ -10268,7 +10289,7 @@ function usePreviewTexture(url, anisotropy, onError) {
|
|
|
10268
10289
|
active = false;
|
|
10269
10290
|
};
|
|
10270
10291
|
}, [anisotropy, url]);
|
|
10271
|
-
(0,
|
|
10292
|
+
(0, import_react39.useEffect)(
|
|
10272
10293
|
() => () => {
|
|
10273
10294
|
texture?.dispose();
|
|
10274
10295
|
},
|
|
@@ -10277,14 +10298,14 @@ function usePreviewTexture(url, anisotropy, onError) {
|
|
|
10277
10298
|
return texture;
|
|
10278
10299
|
}
|
|
10279
10300
|
function useManagedTexture(manager, key, url, address) {
|
|
10280
|
-
const [managedState, setManagedState] = (0,
|
|
10301
|
+
const [managedState, setManagedState] = (0, import_react39.useState)(() => ({
|
|
10281
10302
|
manager,
|
|
10282
10303
|
key,
|
|
10283
10304
|
url,
|
|
10284
10305
|
snapshot: manager.getSnapshot(key)
|
|
10285
10306
|
}));
|
|
10286
10307
|
const snapshot = managedState.manager === manager && managedState.key === key && managedState.url === url ? managedState.snapshot : manager.getSnapshot(key);
|
|
10287
|
-
(0,
|
|
10308
|
+
(0, import_react39.useEffect)(
|
|
10288
10309
|
() => manager.acquire(key, url, address, (nextSnapshot) => {
|
|
10289
10310
|
setManagedState({
|
|
10290
10311
|
manager,
|
|
@@ -10427,13 +10448,22 @@ function preferredSphereLevel(levels, height, dpr, verticalFov) {
|
|
|
10427
10448
|
|
|
10428
10449
|
// src/sphere-tile/sphere-tile.tsx
|
|
10429
10450
|
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
10451
|
+
function sphereTileViewShouldRefresh(input) {
|
|
10452
|
+
if (input.loadModeChanged || input.managerChanged) {
|
|
10453
|
+
return true;
|
|
10454
|
+
}
|
|
10455
|
+
if (input.elapsedMs < 100 || input.viewUnchanged) {
|
|
10456
|
+
return false;
|
|
10457
|
+
}
|
|
10458
|
+
return true;
|
|
10459
|
+
}
|
|
10430
10460
|
function SpherePatch({
|
|
10431
10461
|
address,
|
|
10432
10462
|
texture,
|
|
10433
10463
|
yawOffset,
|
|
10434
10464
|
preview = false
|
|
10435
10465
|
}) {
|
|
10436
|
-
const geometry = (0,
|
|
10466
|
+
const geometry = (0, import_react40.useMemo)(
|
|
10437
10467
|
() => sphereTileGeometry(
|
|
10438
10468
|
address,
|
|
10439
10469
|
yawOffset,
|
|
@@ -10441,7 +10471,7 @@ function SpherePatch({
|
|
|
10441
10471
|
),
|
|
10442
10472
|
[address, yawOffset, preview]
|
|
10443
10473
|
);
|
|
10444
|
-
(0,
|
|
10474
|
+
(0, import_react40.useEffect)(() => () => geometry.dispose(), [geometry]);
|
|
10445
10475
|
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
10446
10476
|
"mesh",
|
|
10447
10477
|
{
|
|
@@ -10460,7 +10490,7 @@ function SpherePatch({
|
|
|
10460
10490
|
}
|
|
10461
10491
|
);
|
|
10462
10492
|
}
|
|
10463
|
-
var ManagedPatch = (0,
|
|
10493
|
+
var ManagedPatch = (0, import_react40.memo)(function ManagedPatch2({
|
|
10464
10494
|
address,
|
|
10465
10495
|
manager,
|
|
10466
10496
|
resolveUrl,
|
|
@@ -10474,7 +10504,7 @@ var ManagedPatch = (0, import_react39.memo)(function ManagedPatch2({
|
|
|
10474
10504
|
url,
|
|
10475
10505
|
address
|
|
10476
10506
|
);
|
|
10477
|
-
(0,
|
|
10507
|
+
(0, import_react40.useEffect)(() => {
|
|
10478
10508
|
if (snapshot.texture) ready();
|
|
10479
10509
|
}, [snapshot.texture, ready]);
|
|
10480
10510
|
return snapshot.texture ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
@@ -10512,7 +10542,7 @@ function SphereTileSource({
|
|
|
10512
10542
|
anisotropy,
|
|
10513
10543
|
onPreviewError
|
|
10514
10544
|
);
|
|
10515
|
-
const callbacks = (0,
|
|
10545
|
+
const callbacks = (0, import_react40.useRef)({
|
|
10516
10546
|
onReady,
|
|
10517
10547
|
onLoadProgress,
|
|
10518
10548
|
onTileError,
|
|
@@ -10524,7 +10554,7 @@ function SphereTileSource({
|
|
|
10524
10554
|
1,
|
|
10525
10555
|
Number.isFinite(maxTextureMemoryMb) ? maxTextureMemoryMb : 128
|
|
10526
10556
|
) * 1024 * 1024;
|
|
10527
|
-
const ownedManager = (0,
|
|
10557
|
+
const ownedManager = (0, import_react40.useMemo)(
|
|
10528
10558
|
() => new TileTextureManager({
|
|
10529
10559
|
anisotropy,
|
|
10530
10560
|
maxBytes: ownedBudget,
|
|
@@ -10545,17 +10575,17 @@ function SphereTileSource({
|
|
|
10545
10575
|
);
|
|
10546
10576
|
const manager = sharedManager ?? ownedManager;
|
|
10547
10577
|
const budget = manager.memoryBudgetBytes;
|
|
10548
|
-
const readyRef = (0,
|
|
10549
|
-
const ready = (0,
|
|
10578
|
+
const readyRef = (0, import_react40.useRef)(false);
|
|
10579
|
+
const ready = (0, import_react40.useCallback)(() => {
|
|
10550
10580
|
if (!readyRef.current) {
|
|
10551
10581
|
readyRef.current = true;
|
|
10552
10582
|
callbacks.current.onReady?.();
|
|
10553
10583
|
}
|
|
10554
10584
|
}, []);
|
|
10555
|
-
(0,
|
|
10585
|
+
(0, import_react40.useEffect)(() => {
|
|
10556
10586
|
if (preview) ready();
|
|
10557
10587
|
}, [preview, ready]);
|
|
10558
|
-
(0,
|
|
10588
|
+
(0, import_react40.useEffect)(() => {
|
|
10559
10589
|
manager.resume();
|
|
10560
10590
|
return () => {
|
|
10561
10591
|
if (manager === ownedManager) {
|
|
@@ -10565,14 +10595,14 @@ function SphereTileSource({
|
|
|
10565
10595
|
queueMicrotask(() => manager.releaseUnused());
|
|
10566
10596
|
};
|
|
10567
10597
|
}, [manager, ownedManager]);
|
|
10568
|
-
const resolveUrl = (0,
|
|
10598
|
+
const resolveUrl = (0, import_react40.useMemo)(
|
|
10569
10599
|
() => (address) => resolveAssetUrl(
|
|
10570
10600
|
baseUrl,
|
|
10571
10601
|
resolveTileUrl ? resolveTileUrl(address) : resolveSphereTemplateUrl(urlTemplate, address, indexBase)
|
|
10572
10602
|
),
|
|
10573
10603
|
[baseUrl, resolveTileUrl, urlTemplate, indexBase]
|
|
10574
10604
|
);
|
|
10575
|
-
const candidates = (0,
|
|
10605
|
+
const candidates = (0, import_react40.useMemo)(
|
|
10576
10606
|
() => config.levels.map(
|
|
10577
10607
|
(level, index) => sphereTileAddresses(level, index, config.tileSize).map((address) => ({
|
|
10578
10608
|
address,
|
|
@@ -10581,12 +10611,17 @@ function SphereTileSource({
|
|
|
10581
10611
|
),
|
|
10582
10612
|
[config, yawOffset]
|
|
10583
10613
|
);
|
|
10584
|
-
const previewAddress = (0,
|
|
10614
|
+
const previewAddress = (0, import_react40.useMemo)(
|
|
10585
10615
|
() => sphereTileAddresses({ width: 2, height: 1 }, 0, 2)[0],
|
|
10586
10616
|
[]
|
|
10587
10617
|
);
|
|
10588
|
-
const [layers, setLayers] = (0,
|
|
10589
|
-
const
|
|
10618
|
+
const [layers, setLayers] = (0, import_react40.useState)([]);
|
|
10619
|
+
const detailReporter = useSceneDetailReporter();
|
|
10620
|
+
const detailReporterRef = (0, import_react40.useRef)(detailReporter);
|
|
10621
|
+
detailReporterRef.current = detailReporter;
|
|
10622
|
+
const detailTokenRef = (0, import_react40.useRef)("");
|
|
10623
|
+
const targetKeysRef = (0, import_react40.useRef)([]);
|
|
10624
|
+
const scratch = (0, import_react40.useMemo)(
|
|
10590
10625
|
() => ({
|
|
10591
10626
|
camera: new import_three14.PerspectiveCamera(),
|
|
10592
10627
|
frustum: new import_three14.Frustum(),
|
|
@@ -10607,53 +10642,72 @@ function SphereTileSource({
|
|
|
10607
10642
|
(0, import_fiber16.useFrame)(() => {
|
|
10608
10643
|
if (!(camera instanceof import_three14.PerspectiveCamera)) return;
|
|
10609
10644
|
const now = performance.now(), dpr = gl.getPixelRatio();
|
|
10610
|
-
const
|
|
10611
|
-
|
|
10612
|
-
|
|
10613
|
-
|
|
10614
|
-
|
|
10615
|
-
|
|
10616
|
-
|
|
10617
|
-
|
|
10618
|
-
|
|
10619
|
-
|
|
10620
|
-
|
|
10621
|
-
|
|
10622
|
-
|
|
10623
|
-
|
|
10624
|
-
|
|
10625
|
-
|
|
10626
|
-
scratch.
|
|
10627
|
-
scratch.
|
|
10628
|
-
|
|
10629
|
-
|
|
10630
|
-
|
|
10631
|
-
|
|
10632
|
-
|
|
10633
|
-
|
|
10634
|
-
|
|
10635
|
-
({ bounds }) => scratch.frustum.intersectsBox(bounds)
|
|
10636
|
-
).map(({ address }) => address);
|
|
10637
|
-
const bytes = addresses.reduce(
|
|
10638
|
-
(total, address) => total + address.width * address.height * 4,
|
|
10639
|
-
0
|
|
10645
|
+
const managerChanged = scratch.manager !== manager;
|
|
10646
|
+
const loadModeChanged = scratch.loadMode !== loadMode;
|
|
10647
|
+
const viewUnchanged = scratch.fov === camera.fov && scratch.width === size.width && scratch.height === size.height && scratch.dpr === dpr && scratch.quaternion.angleTo(camera.quaternion) < 1e-4;
|
|
10648
|
+
if (sphereTileViewShouldRefresh({
|
|
10649
|
+
loadModeChanged,
|
|
10650
|
+
managerChanged,
|
|
10651
|
+
elapsedMs: now - scratch.time,
|
|
10652
|
+
viewUnchanged
|
|
10653
|
+
})) {
|
|
10654
|
+
const reset = managerChanged || loadModeChanged;
|
|
10655
|
+
scratch.time = now;
|
|
10656
|
+
scratch.fov = camera.fov;
|
|
10657
|
+
scratch.width = size.width;
|
|
10658
|
+
scratch.height = size.height;
|
|
10659
|
+
scratch.dpr = dpr;
|
|
10660
|
+
scratch.quaternion.copy(camera.quaternion);
|
|
10661
|
+
scratch.manager = manager;
|
|
10662
|
+
scratch.loadMode = loadMode;
|
|
10663
|
+
scratch.camera.copy(camera, false);
|
|
10664
|
+
scratch.camera.fov = Math.min(179, camera.fov + 8);
|
|
10665
|
+
scratch.camera.updateProjectionMatrix();
|
|
10666
|
+
scratch.camera.updateMatrixWorld();
|
|
10667
|
+
scratch.matrix.multiplyMatrices(
|
|
10668
|
+
scratch.camera.projectionMatrix,
|
|
10669
|
+
scratch.camera.matrixWorldInverse
|
|
10640
10670
|
);
|
|
10641
|
-
|
|
10642
|
-
|
|
10643
|
-
|
|
10671
|
+
scratch.frustum.setFromProjectionMatrix(scratch.matrix);
|
|
10672
|
+
let level = loadMode === "preview" ? -1 : loadMode === "base" ? 0 : preferredSphereLevel(config.levels, size.height, dpr, camera.fov);
|
|
10673
|
+
const next = [];
|
|
10674
|
+
let residentBytes = 0;
|
|
10675
|
+
for (let index = 0; index <= level; index++) {
|
|
10676
|
+
const addresses = candidates[index].filter(
|
|
10677
|
+
({ bounds }) => scratch.frustum.intersectsBox(bounds)
|
|
10678
|
+
).map(({ address }) => address);
|
|
10679
|
+
const bytes = addresses.reduce(
|
|
10680
|
+
(total, address) => total + address.width * address.height * 4,
|
|
10681
|
+
0
|
|
10682
|
+
);
|
|
10683
|
+
if (residentBytes + bytes > budget) {
|
|
10684
|
+
level = index - 1;
|
|
10685
|
+
break;
|
|
10686
|
+
}
|
|
10687
|
+
residentBytes += bytes;
|
|
10688
|
+
next.push({ level: index, addresses });
|
|
10689
|
+
}
|
|
10690
|
+
const targetLayer = loadMode === "full" ? next[next.length - 1] : void 0;
|
|
10691
|
+
targetKeysRef.current = targetLayer ? targetLayer.addresses.map(
|
|
10692
|
+
(address) => `${resolveUrl(address)}\0${sphereTileKey(address)}`
|
|
10693
|
+
) : [];
|
|
10694
|
+
if (level !== scratch.level) {
|
|
10695
|
+
scratch.level = level;
|
|
10696
|
+
if (level >= 0) callbacks.current.onLevelChange?.(level);
|
|
10697
|
+
}
|
|
10698
|
+
const token = next.map((layer) => layer.addresses.map(sphereTileKey).join(",")).join(";");
|
|
10699
|
+
if (token !== scratch.token || reset) {
|
|
10700
|
+
scratch.token = token;
|
|
10701
|
+
setLayers(next);
|
|
10644
10702
|
}
|
|
10645
|
-
residentBytes += bytes;
|
|
10646
|
-
next.push({ level: index, addresses });
|
|
10647
|
-
}
|
|
10648
|
-
if (level !== scratch.level) {
|
|
10649
|
-
scratch.level = level;
|
|
10650
|
-
if (level >= 0) callbacks.current.onLevelChange?.(level);
|
|
10651
|
-
}
|
|
10652
|
-
const token = next.map((layer) => layer.addresses.map(sphereTileKey).join(",")).join(";");
|
|
10653
|
-
if (token !== scratch.token || reset) {
|
|
10654
|
-
scratch.token = token;
|
|
10655
|
-
setLayers(next);
|
|
10656
10703
|
}
|
|
10704
|
+
publishSceneDetail(
|
|
10705
|
+
detailReporterRef.current,
|
|
10706
|
+
detailTokenRef,
|
|
10707
|
+
loadMode === "full" && viewTilesAreDrawable(
|
|
10708
|
+
targetKeysRef.current.map((key) => manager.getSnapshot(key).texture)
|
|
10709
|
+
)
|
|
10710
|
+
);
|
|
10657
10711
|
});
|
|
10658
10712
|
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("group", { visible, children: [
|
|
10659
10713
|
preview ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
@@ -10682,23 +10736,23 @@ function SphereTileSource({
|
|
|
10682
10736
|
}
|
|
10683
10737
|
function SphereTile({ multires, ...props }) {
|
|
10684
10738
|
const token = typeof multires === "string" ? multires : JSON.stringify(multires);
|
|
10685
|
-
const config = (0,
|
|
10739
|
+
const config = (0, import_react40.useMemo)(() => parseSphereMultires(multires), [token]);
|
|
10686
10740
|
const sourceKey = `${props.baseUrl}\0${token}\0${props.previewUrl}\0${props.urlTemplate ?? ""}\0${props.indexBase ?? 1}`;
|
|
10687
10741
|
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(SphereTileSource, { ...props, config }, sourceKey);
|
|
10688
10742
|
}
|
|
10689
10743
|
|
|
10690
10744
|
// src/sphere.tsx
|
|
10691
10745
|
var import_fiber17 = require("@react-three/fiber");
|
|
10692
|
-
var
|
|
10746
|
+
var import_react41 = require("react");
|
|
10693
10747
|
var import_three15 = require("three");
|
|
10694
10748
|
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
10695
10749
|
function useEquirectTexture(url, anisotropy, generateMipmaps, onLoad, onError) {
|
|
10696
|
-
const [texture, setTexture] = (0,
|
|
10697
|
-
const onLoadRef = (0,
|
|
10698
|
-
const onErrorRef = (0,
|
|
10750
|
+
const [texture, setTexture] = (0, import_react41.useState)(null);
|
|
10751
|
+
const onLoadRef = (0, import_react41.useRef)(onLoad);
|
|
10752
|
+
const onErrorRef = (0, import_react41.useRef)(onError);
|
|
10699
10753
|
onLoadRef.current = onLoad;
|
|
10700
10754
|
onErrorRef.current = onError;
|
|
10701
|
-
(0,
|
|
10755
|
+
(0, import_react41.useEffect)(() => {
|
|
10702
10756
|
if (!url) {
|
|
10703
10757
|
setTexture(null);
|
|
10704
10758
|
return;
|
|
@@ -10737,7 +10791,7 @@ function useEquirectTexture(url, anisotropy, generateMipmaps, onLoad, onError) {
|
|
|
10737
10791
|
active = false;
|
|
10738
10792
|
};
|
|
10739
10793
|
}, [anisotropy, generateMipmaps, url]);
|
|
10740
|
-
(0,
|
|
10794
|
+
(0, import_react41.useEffect)(
|
|
10741
10795
|
() => () => {
|
|
10742
10796
|
texture?.dispose();
|
|
10743
10797
|
},
|
|
@@ -10757,7 +10811,7 @@ function Sphere({
|
|
|
10757
10811
|
}) {
|
|
10758
10812
|
const gl = (0, import_fiber17.useThree)((state) => state.gl);
|
|
10759
10813
|
const anisotropy = gl.capabilities.getMaxAnisotropy();
|
|
10760
|
-
const resolvedPreviewUrl = (0,
|
|
10814
|
+
const resolvedPreviewUrl = (0, import_react41.useMemo)(
|
|
10761
10815
|
() => resolveUrlAgainstFile(src, previewUrl),
|
|
10762
10816
|
[previewUrl, src]
|
|
10763
10817
|
);
|
|
@@ -10776,11 +10830,21 @@ function Sphere({
|
|
|
10776
10830
|
onPreviewError
|
|
10777
10831
|
);
|
|
10778
10832
|
const displayTexture = texture ?? previewTexture;
|
|
10779
|
-
const readyRef = (0,
|
|
10780
|
-
|
|
10833
|
+
const readyRef = (0, import_react41.useRef)(false);
|
|
10834
|
+
const detailReporter = useSceneDetailReporter();
|
|
10835
|
+
(0, import_react41.useEffect)(() => {
|
|
10781
10836
|
readyRef.current = false;
|
|
10782
10837
|
}, [resolvedPreviewUrl, src]);
|
|
10783
|
-
(0,
|
|
10838
|
+
(0, import_react41.useEffect)(() => {
|
|
10839
|
+
if (!detailReporter) {
|
|
10840
|
+
return;
|
|
10841
|
+
}
|
|
10842
|
+
detailReporter.report(texture != null);
|
|
10843
|
+
return () => {
|
|
10844
|
+
detailReporter.report(false);
|
|
10845
|
+
};
|
|
10846
|
+
}, [detailReporter, texture]);
|
|
10847
|
+
(0, import_react41.useEffect)(() => {
|
|
10784
10848
|
if (!displayTexture || readyRef.current) {
|
|
10785
10849
|
return;
|
|
10786
10850
|
}
|
|
@@ -10812,7 +10876,7 @@ function Sphere({
|
|
|
10812
10876
|
|
|
10813
10877
|
// src/video/pano-video.tsx
|
|
10814
10878
|
var import_fiber18 = require("@react-three/fiber");
|
|
10815
|
-
var
|
|
10879
|
+
var import_react42 = require("react");
|
|
10816
10880
|
var import_three16 = require("three");
|
|
10817
10881
|
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
10818
10882
|
var EMPTY_TRACKS = [];
|
|
@@ -10899,10 +10963,10 @@ function applyEquirectangularLayout(texture, anisotropy) {
|
|
|
10899
10963
|
}
|
|
10900
10964
|
function usePosterTexture(poster, onError) {
|
|
10901
10965
|
const gl = (0, import_fiber18.useThree)((state) => state.gl);
|
|
10902
|
-
const [texture, setTexture] = (0,
|
|
10903
|
-
const onErrorRef = (0,
|
|
10966
|
+
const [texture, setTexture] = (0, import_react42.useState)(null);
|
|
10967
|
+
const onErrorRef = (0, import_react42.useRef)(onError);
|
|
10904
10968
|
onErrorRef.current = onError;
|
|
10905
|
-
(0,
|
|
10969
|
+
(0, import_react42.useEffect)(() => {
|
|
10906
10970
|
let active = true;
|
|
10907
10971
|
setTexture(null);
|
|
10908
10972
|
if (!poster) {
|
|
@@ -10939,7 +11003,7 @@ function usePosterTexture(poster, onError) {
|
|
|
10939
11003
|
active = false;
|
|
10940
11004
|
};
|
|
10941
11005
|
}, [gl, poster]);
|
|
10942
|
-
(0,
|
|
11006
|
+
(0, import_react42.useEffect)(
|
|
10943
11007
|
() => () => {
|
|
10944
11008
|
texture?.dispose();
|
|
10945
11009
|
},
|
|
@@ -10998,38 +11062,38 @@ function PanoVideo({
|
|
|
10998
11062
|
}) {
|
|
10999
11063
|
usePanoMediaActivationIntent(autoPlay);
|
|
11000
11064
|
const gl = (0, import_fiber18.useThree)((state) => state.gl);
|
|
11001
|
-
const host = (0,
|
|
11002
|
-
const overlay = (0,
|
|
11003
|
-
const variants = (0,
|
|
11065
|
+
const host = (0, import_react42.useContext)(PanoVideoHostContext);
|
|
11066
|
+
const overlay = (0, import_react42.useContext)(PanoChromeOverlayContext);
|
|
11067
|
+
const variants = (0, import_react42.useMemo)(
|
|
11004
11068
|
() => resolvePanoVideoVariants({ poster, src, variants: variantsProp }),
|
|
11005
11069
|
[poster, src, variantsProp]
|
|
11006
11070
|
);
|
|
11007
11071
|
const tracks = tracksProp ?? EMPTY_TRACKS;
|
|
11008
11072
|
const captionsEnabled = captions !== false;
|
|
11009
|
-
const captionAppearance = (0,
|
|
11073
|
+
const captionAppearance = (0, import_react42.useMemo)(
|
|
11010
11074
|
() => resolvePanoVideoCaptionAppearance(
|
|
11011
11075
|
typeof captions === "object" ? captions : void 0
|
|
11012
11076
|
),
|
|
11013
11077
|
[captions]
|
|
11014
11078
|
);
|
|
11015
|
-
const [variantId, setVariantId] = (0,
|
|
11079
|
+
const [variantId, setVariantId] = (0, import_react42.useState)(
|
|
11016
11080
|
() => resolvePanoVideoVariantId(variants, defaultVariantId)
|
|
11017
11081
|
);
|
|
11018
|
-
const [trackId, setTrackId] = (0,
|
|
11082
|
+
const [trackId, setTrackId] = (0, import_react42.useState)(
|
|
11019
11083
|
() => captionsEnabled ? defaultPanoVideoTrackId(tracks) : null
|
|
11020
11084
|
);
|
|
11021
|
-
const [ready, setReady] = (0,
|
|
11022
|
-
const autoPlayRef = (0,
|
|
11085
|
+
const [ready, setReady] = (0, import_react42.useState)(false);
|
|
11086
|
+
const autoPlayRef = (0, import_react42.useRef)(autoPlay);
|
|
11023
11087
|
autoPlayRef.current = autoPlay;
|
|
11024
|
-
const blockedRef = (0,
|
|
11025
|
-
const captionAppearanceOverrideRef = (0,
|
|
11088
|
+
const blockedRef = (0, import_react42.useRef)(false);
|
|
11089
|
+
const captionAppearanceOverrideRef = (0, import_react42.useRef)(
|
|
11026
11090
|
{}
|
|
11027
11091
|
);
|
|
11028
|
-
const mediaCapabilitiesRef = (0,
|
|
11092
|
+
const mediaCapabilitiesRef = (0, import_react42.useRef)({
|
|
11029
11093
|
volumeAdjustable: true,
|
|
11030
11094
|
playbackRates: [...DEFAULT_PANO_VIDEO_PLAYBACK_RATES]
|
|
11031
11095
|
});
|
|
11032
|
-
const storeRef = (0,
|
|
11096
|
+
const storeRef = (0, import_react42.useRef)(null);
|
|
11033
11097
|
if (!storeRef.current) {
|
|
11034
11098
|
storeRef.current = {
|
|
11035
11099
|
snapshot: {
|
|
@@ -11039,7 +11103,7 @@ function PanoVideo({
|
|
|
11039
11103
|
listeners: /* @__PURE__ */ new Set()
|
|
11040
11104
|
};
|
|
11041
11105
|
}
|
|
11042
|
-
const actionsRef = (0,
|
|
11106
|
+
const actionsRef = (0, import_react42.useRef)({
|
|
11043
11107
|
play: async () => {
|
|
11044
11108
|
},
|
|
11045
11109
|
pause: () => {
|
|
@@ -11059,19 +11123,19 @@ function PanoVideo({
|
|
|
11059
11123
|
setCaptionAppearance: (_appearance) => {
|
|
11060
11124
|
}
|
|
11061
11125
|
});
|
|
11062
|
-
const onLoadRef = (0,
|
|
11063
|
-
const onErrorRef = (0,
|
|
11064
|
-
const onPlaybackStateChangeRef = (0,
|
|
11065
|
-
const onEndedRef = (0,
|
|
11066
|
-
const onVariantChangeRef = (0,
|
|
11067
|
-
const onTrackChangeRef = (0,
|
|
11126
|
+
const onLoadRef = (0, import_react42.useRef)(onLoad);
|
|
11127
|
+
const onErrorRef = (0, import_react42.useRef)(onError);
|
|
11128
|
+
const onPlaybackStateChangeRef = (0, import_react42.useRef)(onPlaybackStateChange);
|
|
11129
|
+
const onEndedRef = (0, import_react42.useRef)(onEnded);
|
|
11130
|
+
const onVariantChangeRef = (0, import_react42.useRef)(onVariantChange);
|
|
11131
|
+
const onTrackChangeRef = (0, import_react42.useRef)(onTrackChange);
|
|
11068
11132
|
onLoadRef.current = onLoad;
|
|
11069
11133
|
onErrorRef.current = onError;
|
|
11070
11134
|
onPlaybackStateChangeRef.current = onPlaybackStateChange;
|
|
11071
11135
|
onEndedRef.current = onEnded;
|
|
11072
11136
|
onVariantChangeRef.current = onVariantChange;
|
|
11073
11137
|
onTrackChangeRef.current = onTrackChange;
|
|
11074
|
-
const resource = (0,
|
|
11138
|
+
const resource = (0, import_react42.useMemo)(() => {
|
|
11075
11139
|
if (typeof document === "undefined") {
|
|
11076
11140
|
return null;
|
|
11077
11141
|
}
|
|
@@ -11088,7 +11152,7 @@ function PanoVideo({
|
|
|
11088
11152
|
texture.generateMipmaps = false;
|
|
11089
11153
|
return { video, texture };
|
|
11090
11154
|
}, []);
|
|
11091
|
-
(0,
|
|
11155
|
+
(0, import_react42.useEffect)(
|
|
11092
11156
|
() => () => {
|
|
11093
11157
|
if (!resource) {
|
|
11094
11158
|
return;
|
|
@@ -11103,13 +11167,13 @@ function PanoVideo({
|
|
|
11103
11167
|
},
|
|
11104
11168
|
[resource]
|
|
11105
11169
|
);
|
|
11106
|
-
(0,
|
|
11170
|
+
(0, import_react42.useEffect)(() => {
|
|
11107
11171
|
if (!resource) {
|
|
11108
11172
|
return;
|
|
11109
11173
|
}
|
|
11110
11174
|
resource.texture.anisotropy = gl.capabilities.getMaxAnisotropy();
|
|
11111
11175
|
}, [gl, resource]);
|
|
11112
|
-
(0,
|
|
11176
|
+
(0, import_react42.useEffect)(() => {
|
|
11113
11177
|
if (!resource || !overlay?.overlayElement) {
|
|
11114
11178
|
return;
|
|
11115
11179
|
}
|
|
@@ -11132,7 +11196,7 @@ function PanoVideo({
|
|
|
11132
11196
|
activeVariant?.poster ?? poster,
|
|
11133
11197
|
onError
|
|
11134
11198
|
);
|
|
11135
|
-
const emitSnapshot = (0,
|
|
11199
|
+
const emitSnapshot = (0, import_react42.useCallback)(
|
|
11136
11200
|
(patch) => {
|
|
11137
11201
|
const store = storeRef.current;
|
|
11138
11202
|
const video = resource?.video;
|
|
@@ -11184,7 +11248,7 @@ function PanoVideo({
|
|
|
11184
11248
|
captionAppearance
|
|
11185
11249
|
]
|
|
11186
11250
|
);
|
|
11187
|
-
const controller = (0,
|
|
11251
|
+
const controller = (0, import_react42.useMemo)(
|
|
11188
11252
|
() => ({
|
|
11189
11253
|
subscribe: (onStoreChange) => {
|
|
11190
11254
|
const store = storeRef.current;
|
|
@@ -11236,7 +11300,7 @@ function PanoVideo({
|
|
|
11236
11300
|
}),
|
|
11237
11301
|
[]
|
|
11238
11302
|
);
|
|
11239
|
-
(0,
|
|
11303
|
+
(0, import_react42.useLayoutEffect)(() => {
|
|
11240
11304
|
if (!host || variants.length === 0) {
|
|
11241
11305
|
return;
|
|
11242
11306
|
}
|
|
@@ -11249,7 +11313,7 @@ function PanoVideo({
|
|
|
11249
11313
|
notifyPanoVideoHost(host);
|
|
11250
11314
|
};
|
|
11251
11315
|
}, [captionsEnabled, controller, controls, host, variants.length]);
|
|
11252
|
-
(0,
|
|
11316
|
+
(0, import_react42.useLayoutEffect)(() => {
|
|
11253
11317
|
if (!resource) {
|
|
11254
11318
|
return;
|
|
11255
11319
|
}
|
|
@@ -11262,10 +11326,10 @@ function PanoVideo({
|
|
|
11262
11326
|
};
|
|
11263
11327
|
emitSnapshot();
|
|
11264
11328
|
}, [emitSnapshot, playbackRates, resource]);
|
|
11265
|
-
(0,
|
|
11329
|
+
(0, import_react42.useEffect)(() => {
|
|
11266
11330
|
emitSnapshot();
|
|
11267
11331
|
}, [emitSnapshot]);
|
|
11268
|
-
(0,
|
|
11332
|
+
(0, import_react42.useEffect)(() => {
|
|
11269
11333
|
if (!resource || !activeVariant || !mediaKey) {
|
|
11270
11334
|
return;
|
|
11271
11335
|
}
|
|
@@ -11322,7 +11386,7 @@ function PanoVideo({
|
|
|
11322
11386
|
video.removeEventListener("error", handleError);
|
|
11323
11387
|
};
|
|
11324
11388
|
}, [mediaKey, resource]);
|
|
11325
|
-
(0,
|
|
11389
|
+
(0, import_react42.useEffect)(() => {
|
|
11326
11390
|
if (!resource) {
|
|
11327
11391
|
return;
|
|
11328
11392
|
}
|
|
@@ -11414,7 +11478,7 @@ function PanoVideo({
|
|
|
11414
11478
|
}
|
|
11415
11479
|
};
|
|
11416
11480
|
}, [emitSnapshot, resource]);
|
|
11417
|
-
(0,
|
|
11481
|
+
(0, import_react42.useEffect)(() => {
|
|
11418
11482
|
if (!resource) {
|
|
11419
11483
|
return;
|
|
11420
11484
|
}
|
|
@@ -11434,7 +11498,7 @@ function PanoVideo({
|
|
|
11434
11498
|
}
|
|
11435
11499
|
video.preload = preload;
|
|
11436
11500
|
}, [loop, muted, playsInline, preload, resource, volume]);
|
|
11437
|
-
(0,
|
|
11501
|
+
(0, import_react42.useEffect)(() => {
|
|
11438
11502
|
if (!resource) {
|
|
11439
11503
|
return;
|
|
11440
11504
|
}
|
|
@@ -11484,7 +11548,7 @@ function PanoVideo({
|
|
|
11484
11548
|
video.removeEventListener("ratechange", handleVolume);
|
|
11485
11549
|
};
|
|
11486
11550
|
}, [emitSnapshot, resource]);
|
|
11487
|
-
(0,
|
|
11551
|
+
(0, import_react42.useEffect)(() => {
|
|
11488
11552
|
if (!resource) {
|
|
11489
11553
|
return;
|
|
11490
11554
|
}
|
|
@@ -11519,7 +11583,7 @@ function PanoVideo({
|
|
|
11519
11583
|
video.textTracks.removeEventListener("change", applyModes);
|
|
11520
11584
|
};
|
|
11521
11585
|
}, [emitSnapshot, resource, trackId, tracks]);
|
|
11522
|
-
(0,
|
|
11586
|
+
(0, import_react42.useEffect)(() => {
|
|
11523
11587
|
if (!captionsEnabled) {
|
|
11524
11588
|
setTrackId(null);
|
|
11525
11589
|
return;
|
|
@@ -11554,9 +11618,9 @@ function PanoVideo({
|
|
|
11554
11618
|
}
|
|
11555
11619
|
|
|
11556
11620
|
// src/scenes.tsx
|
|
11557
|
-
var
|
|
11558
|
-
var
|
|
11559
|
-
var
|
|
11621
|
+
var import_fiber23 = require("@react-three/fiber");
|
|
11622
|
+
var import_react47 = require("react");
|
|
11623
|
+
var import_three24 = require("three");
|
|
11560
11624
|
|
|
11561
11625
|
// src/scene-transitions/presets.ts
|
|
11562
11626
|
var TRANSITION_DEFAULTS = {
|
|
@@ -11604,9 +11668,33 @@ function isSnapshotTransition(preset) {
|
|
|
11604
11668
|
return preset !== "none" && preset !== "particles";
|
|
11605
11669
|
}
|
|
11606
11670
|
|
|
11607
|
-
// src/scene-transitions/
|
|
11671
|
+
// src/scene-transitions/snapshot-hold.tsx
|
|
11608
11672
|
var import_fiber19 = require("@react-three/fiber");
|
|
11609
|
-
var
|
|
11673
|
+
var import_react43 = require("react");
|
|
11674
|
+
var import_three19 = require("three");
|
|
11675
|
+
|
|
11676
|
+
// src/scene-transitions/overlay-utils.ts
|
|
11677
|
+
var import_three17 = require("three");
|
|
11678
|
+
var OVERLAY_RENDER_ORDER = 1e4;
|
|
11679
|
+
var FULLSCREEN_PLANE = new import_three17.PlaneGeometry(1, 1);
|
|
11680
|
+
function isPerspectiveCamera(camera) {
|
|
11681
|
+
return camera.isPerspectiveCamera === true;
|
|
11682
|
+
}
|
|
11683
|
+
function placeFullscreenOverlay(mesh, camera, direction) {
|
|
11684
|
+
const distance = Math.max(camera.near * 1.1, 0.11);
|
|
11685
|
+
camera.getWorldDirection(direction);
|
|
11686
|
+
mesh.position.copy(camera.position).addScaledVector(direction, distance);
|
|
11687
|
+
mesh.quaternion.copy(camera.quaternion);
|
|
11688
|
+
const height = 2 * distance * Math.tan(camera.fov * Math.PI / 360);
|
|
11689
|
+
mesh.scale.set(height * camera.aspect, height, 1);
|
|
11690
|
+
}
|
|
11691
|
+
function overlayProgress(elapsedTime, duration, startTime) {
|
|
11692
|
+
const started = startTime ?? elapsedTime;
|
|
11693
|
+
const progress = duration === 0 ? 1 : Math.min(1, (elapsedTime - started) / duration);
|
|
11694
|
+
return { startTime: started, progress };
|
|
11695
|
+
}
|
|
11696
|
+
|
|
11697
|
+
// src/scene-transitions/snapshot-shaders.ts
|
|
11610
11698
|
var import_three18 = require("three");
|
|
11611
11699
|
|
|
11612
11700
|
// src/scene-transitions/glsl.ts
|
|
@@ -11639,227 +11727,65 @@ float fbm(vec2 p) {
|
|
|
11639
11727
|
}
|
|
11640
11728
|
`;
|
|
11641
11729
|
|
|
11642
|
-
// src/scene-transitions/
|
|
11643
|
-
var
|
|
11644
|
-
|
|
11645
|
-
|
|
11646
|
-
|
|
11647
|
-
|
|
11730
|
+
// src/scene-transitions/snapshot-shaders.ts
|
|
11731
|
+
var SNAPSHOT_VERTEX_SHADER = `
|
|
11732
|
+
varying vec2 vUv;
|
|
11733
|
+
void main() {
|
|
11734
|
+
vUv = uv;
|
|
11735
|
+
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
11736
|
+
}
|
|
11737
|
+
`;
|
|
11738
|
+
var HEADER = `
|
|
11739
|
+
uniform sampler2D map;
|
|
11740
|
+
uniform float progress;
|
|
11741
|
+
uniform vec2 resolution;
|
|
11742
|
+
varying vec2 vUv;
|
|
11743
|
+
${GLSL_COMMON}
|
|
11744
|
+
|
|
11745
|
+
vec2 aspectGrid(float rows) {
|
|
11746
|
+
float aspect = resolution.x / max(resolution.y, 1.0);
|
|
11747
|
+
return vec2(max(8.0, floor(rows * aspect)), rows);
|
|
11648
11748
|
}
|
|
11649
|
-
|
|
11650
|
-
|
|
11651
|
-
|
|
11652
|
-
mesh.position.copy(camera.position).addScaledVector(direction, distance);
|
|
11653
|
-
mesh.quaternion.copy(camera.quaternion);
|
|
11654
|
-
const height = 2 * distance * Math.tan(camera.fov * Math.PI / 360);
|
|
11655
|
-
mesh.scale.set(height * camera.aspect, height, 1);
|
|
11749
|
+
|
|
11750
|
+
vec2 gridCellId() {
|
|
11751
|
+
return floor(vUv * aspectGrid(16.0));
|
|
11656
11752
|
}
|
|
11657
|
-
|
|
11658
|
-
|
|
11659
|
-
|
|
11660
|
-
return
|
|
11753
|
+
|
|
11754
|
+
vec2 gridCellUv() {
|
|
11755
|
+
vec2 cells = aspectGrid(16.0);
|
|
11756
|
+
return (floor(vUv * cells) + 0.5) / cells;
|
|
11661
11757
|
}
|
|
11662
11758
|
|
|
11663
|
-
|
|
11664
|
-
|
|
11665
|
-
|
|
11666
|
-
|
|
11667
|
-
|
|
11668
|
-
|
|
11669
|
-
|
|
11670
|
-
|
|
11671
|
-
|
|
11672
|
-
|
|
11673
|
-
|
|
11759
|
+
float gridWipeAlpha(float spatialOrder, float t) {
|
|
11760
|
+
vec2 cells = aspectGrid(16.0);
|
|
11761
|
+
vec2 id = floor(vUv * cells);
|
|
11762
|
+
vec2 local = fract(vUv * cells);
|
|
11763
|
+
float order = mix(clamp(spatialOrder, 0.0, 1.0), hash(id), 0.12);
|
|
11764
|
+
float disappear = smoothstep(order, order + 0.16, t);
|
|
11765
|
+
float sc = mix(1.0, 0.18, disappear);
|
|
11766
|
+
vec2 scaled = 0.5 + (local - 0.5) / max(sc, 0.001);
|
|
11767
|
+
float inside = step(0.0, scaled.x) * step(scaled.x, 1.0) * step(0.0, scaled.y) * step(scaled.y, 1.0);
|
|
11768
|
+
return inside * (1.0 - disappear);
|
|
11769
|
+
}
|
|
11674
11770
|
|
|
11675
|
-
|
|
11676
|
-
|
|
11677
|
-
|
|
11678
|
-
float gy = floor(id / grid.x);
|
|
11679
|
-
vec2 cell = vec2(gx, gy);
|
|
11680
|
-
float h = hash(cell);
|
|
11681
|
-
float h2 = hash(cell + 19.2);
|
|
11682
|
-
float h3 = hash(cell + 7.7);
|
|
11683
|
-
vec2 randomDir = normalize(vec2(h, h2) * 2.0 - 1.0 + 1e-5);
|
|
11684
|
-
vec2 fromCenter = (cell + 0.5) / grid - 0.5 + 1e-5;
|
|
11685
|
-
vec2 dir = normalize(mix(randomDir, normalize(fromCenter), 0.65));
|
|
11686
|
-
float delay = h3 * 0.28;
|
|
11687
|
-
float lt = clamp((progress - delay) / max(1.0 - delay, 0.001), 0.0, 1.0);
|
|
11688
|
-
float explode = lt * lt;
|
|
11689
|
-
float scale = mix(1.0, 0.18, explode);
|
|
11690
|
-
float angle = (h * 2.0 - 1.0) * explode * 4.2;
|
|
11691
|
-
float ca = cos(angle);
|
|
11692
|
-
float sa = sin(angle);
|
|
11693
|
-
vec2 cellSize = 1.0 / grid;
|
|
11694
|
-
vec2 local = position.xy * cellSize * scale;
|
|
11695
|
-
vec2 rotated = vec2(local.x * ca - local.y * sa, local.x * sa + local.y * ca);
|
|
11696
|
-
vec2 planeCenter = (cell + 0.5) / grid - 0.5;
|
|
11697
|
-
vec2 exploded = planeCenter + dir * explode * 0.9;
|
|
11698
|
-
vec3 pos = vec3(exploded + rotated, -explode * 0.14);
|
|
11699
|
-
vUv = (cell + uv) / grid;
|
|
11700
|
-
vAlpha = 1.0 - explode;
|
|
11701
|
-
gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
|
|
11702
|
-
}
|
|
11703
|
-
`;
|
|
11704
|
-
var PARTICLE_FRAGMENT_SHADER = `
|
|
11705
|
-
uniform sampler2D map;
|
|
11706
|
-
varying vec2 vUv;
|
|
11707
|
-
varying float vAlpha;
|
|
11771
|
+
float hexRound(float x) {
|
|
11772
|
+
return floor(x + 0.5);
|
|
11773
|
+
}
|
|
11708
11774
|
|
|
11709
|
-
|
|
11710
|
-
|
|
11711
|
-
|
|
11712
|
-
|
|
11713
|
-
|
|
11714
|
-
|
|
11715
|
-
|
|
11716
|
-
|
|
11717
|
-
|
|
11718
|
-
|
|
11719
|
-
if (
|
|
11720
|
-
|
|
11721
|
-
}
|
|
11722
|
-
geometry.setAttribute("position", quad.attributes.position.clone());
|
|
11723
|
-
geometry.setAttribute("uv", quad.attributes.uv.clone());
|
|
11724
|
-
const indexes = new Float32Array(PARTICLE_COUNT);
|
|
11725
|
-
for (let i = 0; i < PARTICLE_COUNT; i += 1) {
|
|
11726
|
-
indexes[i] = i;
|
|
11775
|
+
vec2 hexCellId(vec2 uv) {
|
|
11776
|
+
float aspect = resolution.x / max(resolution.y, 1.0);
|
|
11777
|
+
vec2 p = (uv - 0.5) * vec2(aspect, 1.0) * 12.0;
|
|
11778
|
+
float q = 1.1547005 * p.x;
|
|
11779
|
+
float r = -0.5773503 * p.x + p.y;
|
|
11780
|
+
vec3 cube = vec3(q, -q - r, r);
|
|
11781
|
+
vec3 rounded = vec3(hexRound(cube.x), hexRound(cube.y), hexRound(cube.z));
|
|
11782
|
+
vec3 diff = abs(rounded - cube);
|
|
11783
|
+
if (diff.x > diff.y && diff.x > diff.z) {
|
|
11784
|
+
rounded.x = -rounded.y - rounded.z;
|
|
11785
|
+
} else if (diff.y > diff.z) {
|
|
11786
|
+
rounded.y = -rounded.x - rounded.z;
|
|
11727
11787
|
}
|
|
11728
|
-
|
|
11729
|
-
geometry.instanceCount = PARTICLE_COUNT;
|
|
11730
|
-
quad.dispose();
|
|
11731
|
-
return geometry;
|
|
11732
|
-
}
|
|
11733
|
-
function ParticleOverlay({
|
|
11734
|
-
snapshot,
|
|
11735
|
-
transition,
|
|
11736
|
-
running,
|
|
11737
|
-
runId,
|
|
11738
|
-
onFinish
|
|
11739
|
-
}) {
|
|
11740
|
-
const { camera } = (0, import_fiber19.useThree)();
|
|
11741
|
-
const meshRef = (0, import_react42.useRef)(null);
|
|
11742
|
-
const startRef = (0, import_react42.useRef)(null);
|
|
11743
|
-
const finishedRef = (0, import_react42.useRef)(false);
|
|
11744
|
-
const directionRef = (0, import_react42.useRef)(new import_three18.Vector3());
|
|
11745
|
-
const geometry = (0, import_react42.useMemo)(() => createParticleGeometry(), []);
|
|
11746
|
-
const material = (0, import_react42.useMemo)(
|
|
11747
|
-
() => new import_three18.ShaderMaterial({
|
|
11748
|
-
transparent: true,
|
|
11749
|
-
depthTest: false,
|
|
11750
|
-
depthWrite: false,
|
|
11751
|
-
side: import_three18.DoubleSide,
|
|
11752
|
-
uniforms: {
|
|
11753
|
-
map: { value: snapshot.texture },
|
|
11754
|
-
progress: { value: 0 },
|
|
11755
|
-
grid: { value: new import_three18.Vector2(PARTICLE_GRID, PARTICLE_GRID) }
|
|
11756
|
-
},
|
|
11757
|
-
vertexShader: PARTICLE_VERTEX_SHADER,
|
|
11758
|
-
fragmentShader: PARTICLE_FRAGMENT_SHADER
|
|
11759
|
-
}),
|
|
11760
|
-
[snapshot.texture]
|
|
11761
|
-
);
|
|
11762
|
-
(0, import_react42.useEffect)(() => () => geometry.dispose(), [geometry]);
|
|
11763
|
-
(0, import_react42.useEffect)(() => () => material.dispose(), [material]);
|
|
11764
|
-
(0, import_react42.useEffect)(() => {
|
|
11765
|
-
startRef.current = null;
|
|
11766
|
-
finishedRef.current = false;
|
|
11767
|
-
material.uniforms.progress.value = 0;
|
|
11768
|
-
}, [material, runId]);
|
|
11769
|
-
(0, import_fiber19.useFrame)((state) => {
|
|
11770
|
-
const mesh = meshRef.current;
|
|
11771
|
-
if (!mesh || !isPerspectiveCamera(camera)) {
|
|
11772
|
-
return;
|
|
11773
|
-
}
|
|
11774
|
-
placeFullscreenOverlay(mesh, camera, directionRef.current);
|
|
11775
|
-
if (!running || finishedRef.current) {
|
|
11776
|
-
return;
|
|
11777
|
-
}
|
|
11778
|
-
const next = overlayProgress(state.clock.elapsedTime, transition.duration, startRef.current);
|
|
11779
|
-
startRef.current = next.startTime;
|
|
11780
|
-
material.uniforms.progress.value = next.progress;
|
|
11781
|
-
if (next.progress === 1) {
|
|
11782
|
-
finishedRef.current = true;
|
|
11783
|
-
onFinish();
|
|
11784
|
-
}
|
|
11785
|
-
});
|
|
11786
|
-
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
11787
|
-
"mesh",
|
|
11788
|
-
{
|
|
11789
|
-
ref: meshRef,
|
|
11790
|
-
frustumCulled: false,
|
|
11791
|
-
geometry,
|
|
11792
|
-
material,
|
|
11793
|
-
renderOrder: OVERLAY_RENDER_ORDER
|
|
11794
|
-
}
|
|
11795
|
-
);
|
|
11796
|
-
}
|
|
11797
|
-
|
|
11798
|
-
// src/scene-transitions/snapshot-overlay.tsx
|
|
11799
|
-
var import_fiber20 = require("@react-three/fiber");
|
|
11800
|
-
var import_react43 = require("react");
|
|
11801
|
-
var import_three20 = require("three");
|
|
11802
|
-
|
|
11803
|
-
// src/scene-transitions/snapshot-shaders.ts
|
|
11804
|
-
var import_three19 = require("three");
|
|
11805
|
-
var SNAPSHOT_VERTEX_SHADER = `
|
|
11806
|
-
varying vec2 vUv;
|
|
11807
|
-
void main() {
|
|
11808
|
-
vUv = uv;
|
|
11809
|
-
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
11810
|
-
}
|
|
11811
|
-
`;
|
|
11812
|
-
var HEADER = `
|
|
11813
|
-
uniform sampler2D map;
|
|
11814
|
-
uniform float progress;
|
|
11815
|
-
uniform vec2 resolution;
|
|
11816
|
-
varying vec2 vUv;
|
|
11817
|
-
${GLSL_COMMON}
|
|
11818
|
-
|
|
11819
|
-
vec2 aspectGrid(float rows) {
|
|
11820
|
-
float aspect = resolution.x / max(resolution.y, 1.0);
|
|
11821
|
-
return vec2(max(8.0, floor(rows * aspect)), rows);
|
|
11822
|
-
}
|
|
11823
|
-
|
|
11824
|
-
vec2 gridCellId() {
|
|
11825
|
-
return floor(vUv * aspectGrid(16.0));
|
|
11826
|
-
}
|
|
11827
|
-
|
|
11828
|
-
vec2 gridCellUv() {
|
|
11829
|
-
vec2 cells = aspectGrid(16.0);
|
|
11830
|
-
return (floor(vUv * cells) + 0.5) / cells;
|
|
11831
|
-
}
|
|
11832
|
-
|
|
11833
|
-
float gridWipeAlpha(float spatialOrder, float t) {
|
|
11834
|
-
vec2 cells = aspectGrid(16.0);
|
|
11835
|
-
vec2 id = floor(vUv * cells);
|
|
11836
|
-
vec2 local = fract(vUv * cells);
|
|
11837
|
-
float order = mix(clamp(spatialOrder, 0.0, 1.0), hash(id), 0.12);
|
|
11838
|
-
float disappear = smoothstep(order, order + 0.16, t);
|
|
11839
|
-
float sc = mix(1.0, 0.18, disappear);
|
|
11840
|
-
vec2 scaled = 0.5 + (local - 0.5) / max(sc, 0.001);
|
|
11841
|
-
float inside = step(0.0, scaled.x) * step(scaled.x, 1.0) * step(0.0, scaled.y) * step(scaled.y, 1.0);
|
|
11842
|
-
return inside * (1.0 - disappear);
|
|
11843
|
-
}
|
|
11844
|
-
|
|
11845
|
-
float hexRound(float x) {
|
|
11846
|
-
return floor(x + 0.5);
|
|
11847
|
-
}
|
|
11848
|
-
|
|
11849
|
-
vec2 hexCellId(vec2 uv) {
|
|
11850
|
-
float aspect = resolution.x / max(resolution.y, 1.0);
|
|
11851
|
-
vec2 p = (uv - 0.5) * vec2(aspect, 1.0) * 12.0;
|
|
11852
|
-
float q = 1.1547005 * p.x;
|
|
11853
|
-
float r = -0.5773503 * p.x + p.y;
|
|
11854
|
-
vec3 cube = vec3(q, -q - r, r);
|
|
11855
|
-
vec3 rounded = vec3(hexRound(cube.x), hexRound(cube.y), hexRound(cube.z));
|
|
11856
|
-
vec3 diff = abs(rounded - cube);
|
|
11857
|
-
if (diff.x > diff.y && diff.x > diff.z) {
|
|
11858
|
-
rounded.x = -rounded.y - rounded.z;
|
|
11859
|
-
} else if (diff.y > diff.z) {
|
|
11860
|
-
rounded.y = -rounded.x - rounded.z;
|
|
11861
|
-
}
|
|
11862
|
-
return rounded.xz;
|
|
11788
|
+
return rounded.xz;
|
|
11863
11789
|
}
|
|
11864
11790
|
`;
|
|
11865
11791
|
var FOOTER = `
|
|
@@ -12061,23 +11987,250 @@ var SNAPSHOT_FRAGMENT_SHADERS = {
|
|
|
12061
11987
|
`)
|
|
12062
11988
|
};
|
|
12063
11989
|
function createSnapshotMaterial(preset, texture) {
|
|
12064
|
-
return new
|
|
11990
|
+
return new import_three18.ShaderMaterial({
|
|
12065
11991
|
transparent: true,
|
|
12066
11992
|
depthTest: false,
|
|
12067
11993
|
depthWrite: false,
|
|
12068
|
-
side:
|
|
11994
|
+
side: import_three18.DoubleSide,
|
|
12069
11995
|
uniforms: {
|
|
12070
11996
|
map: { value: texture },
|
|
12071
11997
|
progress: { value: 0 },
|
|
12072
|
-
resolution: { value: new
|
|
11998
|
+
resolution: { value: new import_three18.Vector2(1, 1) }
|
|
12073
11999
|
},
|
|
12074
12000
|
vertexShader: SNAPSHOT_VERTEX_SHADER,
|
|
12075
12001
|
fragmentShader: SNAPSHOT_FRAGMENT_SHADERS[preset]
|
|
12076
12002
|
});
|
|
12077
12003
|
}
|
|
12078
12004
|
|
|
12079
|
-
// src/scene-transitions/snapshot-
|
|
12005
|
+
// src/scene-transitions/snapshot-hold.tsx
|
|
12006
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
12007
|
+
function SnapshotHold({ snapshot }) {
|
|
12008
|
+
const { camera, gl } = (0, import_fiber19.useThree)();
|
|
12009
|
+
const meshRef = (0, import_react43.useRef)(null);
|
|
12010
|
+
const directionRef = (0, import_react43.useRef)(new import_three19.Vector3());
|
|
12011
|
+
const material = (0, import_react43.useMemo)(
|
|
12012
|
+
() => createSnapshotMaterial("crossfade", snapshot.texture),
|
|
12013
|
+
[snapshot.texture]
|
|
12014
|
+
);
|
|
12015
|
+
(0, import_react43.useEffect)(() => () => material.dispose(), [material]);
|
|
12016
|
+
(0, import_fiber19.useFrame)(() => {
|
|
12017
|
+
const mesh = meshRef.current;
|
|
12018
|
+
if (!mesh || !isPerspectiveCamera(camera)) {
|
|
12019
|
+
return;
|
|
12020
|
+
}
|
|
12021
|
+
placeFullscreenOverlay(mesh, camera, directionRef.current);
|
|
12022
|
+
const context = gl.getContext();
|
|
12023
|
+
material.uniforms.resolution.value.set(
|
|
12024
|
+
context.drawingBufferWidth,
|
|
12025
|
+
context.drawingBufferHeight
|
|
12026
|
+
);
|
|
12027
|
+
material.uniforms.progress.value = 0;
|
|
12028
|
+
});
|
|
12029
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("mesh", { frustumCulled: false, ref: meshRef, renderOrder: OVERLAY_RENDER_ORDER, children: [
|
|
12030
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("primitive", { attach: "geometry", object: FULLSCREEN_PLANE }),
|
|
12031
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("primitive", { attach: "material", object: material })
|
|
12032
|
+
] });
|
|
12033
|
+
}
|
|
12034
|
+
|
|
12035
|
+
// src/scene-transition-policy.ts
|
|
12036
|
+
function pendingSceneUsesBaseLayer(phase, isPending) {
|
|
12037
|
+
return isPending && (phase === "preloading" || phase === "capturing");
|
|
12038
|
+
}
|
|
12039
|
+
function normalizeTransitionWaitMs(value) {
|
|
12040
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) {
|
|
12041
|
+
return 0;
|
|
12042
|
+
}
|
|
12043
|
+
return value;
|
|
12044
|
+
}
|
|
12045
|
+
function planDetailHold(input) {
|
|
12046
|
+
if (input.waitMs <= 0) {
|
|
12047
|
+
return null;
|
|
12048
|
+
}
|
|
12049
|
+
return {
|
|
12050
|
+
generation: input.generation,
|
|
12051
|
+
sceneId: input.sceneId,
|
|
12052
|
+
deadline: input.now + input.waitMs
|
|
12053
|
+
};
|
|
12054
|
+
}
|
|
12055
|
+
function acceptDetailWait(wait, signal) {
|
|
12056
|
+
if (!wait) {
|
|
12057
|
+
return { wait: null, start: false };
|
|
12058
|
+
}
|
|
12059
|
+
switch (signal.kind) {
|
|
12060
|
+
case "ready":
|
|
12061
|
+
if (signal.generation !== wait.generation || signal.sceneId !== wait.sceneId) {
|
|
12062
|
+
return { wait, start: false };
|
|
12063
|
+
}
|
|
12064
|
+
return { wait: null, start: true };
|
|
12065
|
+
case "timeout":
|
|
12066
|
+
if (signal.generation !== wait.generation || signal.now < wait.deadline) {
|
|
12067
|
+
return { wait, start: false };
|
|
12068
|
+
}
|
|
12069
|
+
return { wait: null, start: true };
|
|
12070
|
+
case "cancel":
|
|
12071
|
+
if (signal.generation !== wait.generation) {
|
|
12072
|
+
return { wait, start: false };
|
|
12073
|
+
}
|
|
12074
|
+
return { wait: null, start: false };
|
|
12075
|
+
default: {
|
|
12076
|
+
const exhaustive = signal;
|
|
12077
|
+
return exhaustive;
|
|
12078
|
+
}
|
|
12079
|
+
}
|
|
12080
|
+
}
|
|
12081
|
+
function phaseAfterSnapshot(preset, hold) {
|
|
12082
|
+
if (hold) {
|
|
12083
|
+
return "awaitingDetail";
|
|
12084
|
+
}
|
|
12085
|
+
if (preset === "none") {
|
|
12086
|
+
return "idle";
|
|
12087
|
+
}
|
|
12088
|
+
return "transitioning";
|
|
12089
|
+
}
|
|
12090
|
+
|
|
12091
|
+
// src/scene-transitions/particle-overlay.tsx
|
|
12092
|
+
var import_fiber20 = require("@react-three/fiber");
|
|
12093
|
+
var import_react44 = require("react");
|
|
12094
|
+
var import_three20 = require("three");
|
|
12080
12095
|
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
12096
|
+
var PARTICLE_GRID = 48;
|
|
12097
|
+
var PARTICLE_COUNT = PARTICLE_GRID * PARTICLE_GRID;
|
|
12098
|
+
var PARTICLE_VERTEX_SHADER = `
|
|
12099
|
+
attribute float instanceIndex;
|
|
12100
|
+
uniform float progress;
|
|
12101
|
+
uniform vec2 grid;
|
|
12102
|
+
varying vec2 vUv;
|
|
12103
|
+
varying float vAlpha;
|
|
12104
|
+
${GLSL_COMMON}
|
|
12105
|
+
|
|
12106
|
+
void main() {
|
|
12107
|
+
float id = instanceIndex;
|
|
12108
|
+
float gx = mod(id, grid.x);
|
|
12109
|
+
float gy = floor(id / grid.x);
|
|
12110
|
+
vec2 cell = vec2(gx, gy);
|
|
12111
|
+
float h = hash(cell);
|
|
12112
|
+
float h2 = hash(cell + 19.2);
|
|
12113
|
+
float h3 = hash(cell + 7.7);
|
|
12114
|
+
vec2 randomDir = normalize(vec2(h, h2) * 2.0 - 1.0 + 1e-5);
|
|
12115
|
+
vec2 fromCenter = (cell + 0.5) / grid - 0.5 + 1e-5;
|
|
12116
|
+
vec2 dir = normalize(mix(randomDir, normalize(fromCenter), 0.65));
|
|
12117
|
+
float delay = h3 * 0.28;
|
|
12118
|
+
float lt = clamp((progress - delay) / max(1.0 - delay, 0.001), 0.0, 1.0);
|
|
12119
|
+
float explode = lt * lt;
|
|
12120
|
+
float scale = mix(1.0, 0.18, explode);
|
|
12121
|
+
float angle = (h * 2.0 - 1.0) * explode * 4.2;
|
|
12122
|
+
float ca = cos(angle);
|
|
12123
|
+
float sa = sin(angle);
|
|
12124
|
+
vec2 cellSize = 1.0 / grid;
|
|
12125
|
+
vec2 local = position.xy * cellSize * scale;
|
|
12126
|
+
vec2 rotated = vec2(local.x * ca - local.y * sa, local.x * sa + local.y * ca);
|
|
12127
|
+
vec2 planeCenter = (cell + 0.5) / grid - 0.5;
|
|
12128
|
+
vec2 exploded = planeCenter + dir * explode * 0.9;
|
|
12129
|
+
vec3 pos = vec3(exploded + rotated, -explode * 0.14);
|
|
12130
|
+
vUv = (cell + uv) / grid;
|
|
12131
|
+
vAlpha = 1.0 - explode;
|
|
12132
|
+
gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
|
|
12133
|
+
}
|
|
12134
|
+
`;
|
|
12135
|
+
var PARTICLE_FRAGMENT_SHADER = `
|
|
12136
|
+
uniform sampler2D map;
|
|
12137
|
+
varying vec2 vUv;
|
|
12138
|
+
varying float vAlpha;
|
|
12139
|
+
|
|
12140
|
+
void main() {
|
|
12141
|
+
vec4 old = texture2D(map, vUv);
|
|
12142
|
+
old.rgb *= 1.0 + 0.22 * (1.0 - vAlpha);
|
|
12143
|
+
gl_FragColor = vec4(old.rgb, old.a * vAlpha);
|
|
12144
|
+
#include <colorspace_fragment>
|
|
12145
|
+
}
|
|
12146
|
+
`;
|
|
12147
|
+
function createParticleGeometry() {
|
|
12148
|
+
const quad = new import_three20.PlaneGeometry(1, 1);
|
|
12149
|
+
const geometry = new import_three20.InstancedBufferGeometry();
|
|
12150
|
+
if (quad.index) {
|
|
12151
|
+
geometry.setIndex(quad.index.clone());
|
|
12152
|
+
}
|
|
12153
|
+
geometry.setAttribute("position", quad.attributes.position.clone());
|
|
12154
|
+
geometry.setAttribute("uv", quad.attributes.uv.clone());
|
|
12155
|
+
const indexes = new Float32Array(PARTICLE_COUNT);
|
|
12156
|
+
for (let i = 0; i < PARTICLE_COUNT; i += 1) {
|
|
12157
|
+
indexes[i] = i;
|
|
12158
|
+
}
|
|
12159
|
+
geometry.setAttribute("instanceIndex", new import_three20.InstancedBufferAttribute(indexes, 1));
|
|
12160
|
+
geometry.instanceCount = PARTICLE_COUNT;
|
|
12161
|
+
quad.dispose();
|
|
12162
|
+
return geometry;
|
|
12163
|
+
}
|
|
12164
|
+
function ParticleOverlay({
|
|
12165
|
+
snapshot,
|
|
12166
|
+
transition,
|
|
12167
|
+
running,
|
|
12168
|
+
runId,
|
|
12169
|
+
onFinish
|
|
12170
|
+
}) {
|
|
12171
|
+
const { camera } = (0, import_fiber20.useThree)();
|
|
12172
|
+
const meshRef = (0, import_react44.useRef)(null);
|
|
12173
|
+
const startRef = (0, import_react44.useRef)(null);
|
|
12174
|
+
const finishedRef = (0, import_react44.useRef)(false);
|
|
12175
|
+
const directionRef = (0, import_react44.useRef)(new import_three20.Vector3());
|
|
12176
|
+
const geometry = (0, import_react44.useMemo)(() => createParticleGeometry(), []);
|
|
12177
|
+
const material = (0, import_react44.useMemo)(
|
|
12178
|
+
() => new import_three20.ShaderMaterial({
|
|
12179
|
+
transparent: true,
|
|
12180
|
+
depthTest: false,
|
|
12181
|
+
depthWrite: false,
|
|
12182
|
+
side: import_three20.DoubleSide,
|
|
12183
|
+
uniforms: {
|
|
12184
|
+
map: { value: snapshot.texture },
|
|
12185
|
+
progress: { value: 0 },
|
|
12186
|
+
grid: { value: new import_three20.Vector2(PARTICLE_GRID, PARTICLE_GRID) }
|
|
12187
|
+
},
|
|
12188
|
+
vertexShader: PARTICLE_VERTEX_SHADER,
|
|
12189
|
+
fragmentShader: PARTICLE_FRAGMENT_SHADER
|
|
12190
|
+
}),
|
|
12191
|
+
[snapshot.texture]
|
|
12192
|
+
);
|
|
12193
|
+
(0, import_react44.useEffect)(() => () => geometry.dispose(), [geometry]);
|
|
12194
|
+
(0, import_react44.useEffect)(() => () => material.dispose(), [material]);
|
|
12195
|
+
(0, import_react44.useEffect)(() => {
|
|
12196
|
+
startRef.current = null;
|
|
12197
|
+
finishedRef.current = false;
|
|
12198
|
+
material.uniforms.progress.value = 0;
|
|
12199
|
+
}, [material, runId]);
|
|
12200
|
+
(0, import_fiber20.useFrame)((state) => {
|
|
12201
|
+
const mesh = meshRef.current;
|
|
12202
|
+
if (!mesh || !isPerspectiveCamera(camera)) {
|
|
12203
|
+
return;
|
|
12204
|
+
}
|
|
12205
|
+
placeFullscreenOverlay(mesh, camera, directionRef.current);
|
|
12206
|
+
if (!running || finishedRef.current) {
|
|
12207
|
+
return;
|
|
12208
|
+
}
|
|
12209
|
+
const next = overlayProgress(state.clock.elapsedTime, transition.duration, startRef.current);
|
|
12210
|
+
startRef.current = next.startTime;
|
|
12211
|
+
material.uniforms.progress.value = next.progress;
|
|
12212
|
+
if (next.progress === 1) {
|
|
12213
|
+
finishedRef.current = true;
|
|
12214
|
+
onFinish();
|
|
12215
|
+
}
|
|
12216
|
+
});
|
|
12217
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
12218
|
+
"mesh",
|
|
12219
|
+
{
|
|
12220
|
+
ref: meshRef,
|
|
12221
|
+
frustumCulled: false,
|
|
12222
|
+
geometry,
|
|
12223
|
+
material,
|
|
12224
|
+
renderOrder: OVERLAY_RENDER_ORDER
|
|
12225
|
+
}
|
|
12226
|
+
);
|
|
12227
|
+
}
|
|
12228
|
+
|
|
12229
|
+
// src/scene-transitions/snapshot-overlay.tsx
|
|
12230
|
+
var import_fiber21 = require("@react-three/fiber");
|
|
12231
|
+
var import_react45 = require("react");
|
|
12232
|
+
var import_three21 = require("three");
|
|
12233
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
12081
12234
|
function SnapshotOverlay({
|
|
12082
12235
|
snapshot,
|
|
12083
12236
|
transition,
|
|
@@ -12085,26 +12238,26 @@ function SnapshotOverlay({
|
|
|
12085
12238
|
runId,
|
|
12086
12239
|
onFinish
|
|
12087
12240
|
}) {
|
|
12088
|
-
const { camera, gl } = (0,
|
|
12089
|
-
const meshRef = (0,
|
|
12090
|
-
const startRef = (0,
|
|
12091
|
-
const finishedRef = (0,
|
|
12092
|
-
const directionRef = (0,
|
|
12093
|
-
const material = (0,
|
|
12241
|
+
const { camera, gl } = (0, import_fiber21.useThree)();
|
|
12242
|
+
const meshRef = (0, import_react45.useRef)(null);
|
|
12243
|
+
const startRef = (0, import_react45.useRef)(null);
|
|
12244
|
+
const finishedRef = (0, import_react45.useRef)(false);
|
|
12245
|
+
const directionRef = (0, import_react45.useRef)(new import_three21.Vector3());
|
|
12246
|
+
const material = (0, import_react45.useMemo)(() => {
|
|
12094
12247
|
if (!isSnapshotTransition(transition.preset)) {
|
|
12095
12248
|
return null;
|
|
12096
12249
|
}
|
|
12097
12250
|
return createSnapshotMaterial(transition.preset, snapshot.texture);
|
|
12098
12251
|
}, [snapshot.texture, transition.preset]);
|
|
12099
|
-
(0,
|
|
12100
|
-
(0,
|
|
12252
|
+
(0, import_react45.useEffect)(() => () => material?.dispose(), [material]);
|
|
12253
|
+
(0, import_react45.useEffect)(() => {
|
|
12101
12254
|
startRef.current = null;
|
|
12102
12255
|
finishedRef.current = false;
|
|
12103
12256
|
if (material) {
|
|
12104
12257
|
material.uniforms.progress.value = 0;
|
|
12105
12258
|
}
|
|
12106
12259
|
}, [material, runId]);
|
|
12107
|
-
(0,
|
|
12260
|
+
(0, import_fiber21.useFrame)((state) => {
|
|
12108
12261
|
const mesh = meshRef.current;
|
|
12109
12262
|
if (!mesh || !material || !isPerspectiveCamera(camera)) {
|
|
12110
12263
|
return;
|
|
@@ -12126,21 +12279,21 @@ function SnapshotOverlay({
|
|
|
12126
12279
|
if (!material) {
|
|
12127
12280
|
return null;
|
|
12128
12281
|
}
|
|
12129
|
-
return /* @__PURE__ */ (0,
|
|
12130
|
-
/* @__PURE__ */ (0,
|
|
12131
|
-
/* @__PURE__ */ (0,
|
|
12282
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("mesh", { ref: meshRef, renderOrder: OVERLAY_RENDER_ORDER, frustumCulled: false, children: [
|
|
12283
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("primitive", { attach: "geometry", object: FULLSCREEN_PLANE }),
|
|
12284
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("primitive", { attach: "material", object: material })
|
|
12132
12285
|
] });
|
|
12133
12286
|
}
|
|
12134
12287
|
|
|
12135
12288
|
// src/scene-transitions/transition-overlay.tsx
|
|
12136
|
-
var
|
|
12289
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
12137
12290
|
function TransitionOverlay(props) {
|
|
12138
12291
|
const { preset } = props.transition;
|
|
12139
12292
|
switch (preset) {
|
|
12140
12293
|
case "none":
|
|
12141
12294
|
return null;
|
|
12142
12295
|
case "particles":
|
|
12143
|
-
return /* @__PURE__ */ (0,
|
|
12296
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ParticleOverlay, { ...props });
|
|
12144
12297
|
case "crossfade":
|
|
12145
12298
|
case "zoom":
|
|
12146
12299
|
case "blackout":
|
|
@@ -12168,7 +12321,7 @@ function TransitionOverlay(props) {
|
|
|
12168
12321
|
case "zoomBlur":
|
|
12169
12322
|
case "hexDissolve":
|
|
12170
12323
|
case "filmBurn":
|
|
12171
|
-
return /* @__PURE__ */ (0,
|
|
12324
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SnapshotOverlay, { ...props });
|
|
12172
12325
|
default: {
|
|
12173
12326
|
const exhaustive = preset;
|
|
12174
12327
|
void exhaustive;
|
|
@@ -12178,12 +12331,12 @@ function TransitionOverlay(props) {
|
|
|
12178
12331
|
}
|
|
12179
12332
|
|
|
12180
12333
|
// src/tile/tile.tsx
|
|
12181
|
-
var
|
|
12182
|
-
var
|
|
12183
|
-
var
|
|
12334
|
+
var import_fiber22 = require("@react-three/fiber");
|
|
12335
|
+
var import_react46 = require("react");
|
|
12336
|
+
var import_three23 = require("three");
|
|
12184
12337
|
|
|
12185
12338
|
// src/tile/face-layout.ts
|
|
12186
|
-
var
|
|
12339
|
+
var import_three22 = require("three");
|
|
12187
12340
|
var CUBE_FACES = ["f", "r", "b", "l", "u", "d"];
|
|
12188
12341
|
var PREVIEW_FACE_ORDER = ["l", "f", "r", "b", "u", "d"];
|
|
12189
12342
|
var CUBE_RADIUS = DEFAULT_PANORAMA_RADIUS;
|
|
@@ -12234,8 +12387,8 @@ function getFaceQuaternion(face) {
|
|
|
12234
12387
|
return cached;
|
|
12235
12388
|
}
|
|
12236
12389
|
const transform = getFaceTransform(face);
|
|
12237
|
-
const quaternion = new
|
|
12238
|
-
new
|
|
12390
|
+
const quaternion = new import_three22.Quaternion().setFromEuler(
|
|
12391
|
+
new import_three22.Euler(...transform.rotation, "XYZ")
|
|
12239
12392
|
);
|
|
12240
12393
|
faceQuaternionCache.set(face, quaternion);
|
|
12241
12394
|
return quaternion;
|
|
@@ -12246,17 +12399,17 @@ function getTileBoundingBox(address, radius = CUBE_RADIUS) {
|
|
|
12246
12399
|
const halfWidth = local.width / 2;
|
|
12247
12400
|
const halfHeight = local.height / 2;
|
|
12248
12401
|
const quaternion = getFaceQuaternion(address.face);
|
|
12249
|
-
const position = new
|
|
12402
|
+
const position = new import_three22.Vector3(...transform.position);
|
|
12250
12403
|
const corners = [
|
|
12251
|
-
new
|
|
12252
|
-
new
|
|
12253
|
-
new
|
|
12254
|
-
new
|
|
12404
|
+
new import_three22.Vector3(local.x - halfWidth, local.y - halfHeight, 0),
|
|
12405
|
+
new import_three22.Vector3(local.x + halfWidth, local.y - halfHeight, 0),
|
|
12406
|
+
new import_three22.Vector3(local.x - halfWidth, local.y + halfHeight, 0),
|
|
12407
|
+
new import_three22.Vector3(local.x + halfWidth, local.y + halfHeight, 0)
|
|
12255
12408
|
];
|
|
12256
12409
|
for (const corner of corners) {
|
|
12257
12410
|
corner.applyQuaternion(quaternion).add(position);
|
|
12258
12411
|
}
|
|
12259
|
-
return new
|
|
12412
|
+
return new import_three22.Box3().setFromPoints(corners);
|
|
12260
12413
|
}
|
|
12261
12414
|
function makeTileAddress(face, level, faceSize, tileSize, col, row) {
|
|
12262
12415
|
const left = (col - 1) * tileSize;
|
|
@@ -12359,21 +12512,37 @@ function resolveTemplateUrl(template, address) {
|
|
|
12359
12512
|
}
|
|
12360
12513
|
|
|
12361
12514
|
// src/tile/tile.tsx
|
|
12362
|
-
var
|
|
12515
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
12363
12516
|
var MAX_LOD_UPDATE_INTERVAL_MS = 100;
|
|
12364
12517
|
var FAST_ROTATION_THRESHOLD_RADIANS = Math.PI / 180;
|
|
12365
12518
|
var FAST_FOV_THRESHOLD_DEGREES = 0.5;
|
|
12366
12519
|
var VIEW_CHANGE_EPSILON = 1e-4;
|
|
12520
|
+
function decideTileLodUpdate(input) {
|
|
12521
|
+
if (input.loadMode === "preview") {
|
|
12522
|
+
return false;
|
|
12523
|
+
}
|
|
12524
|
+
const loadModeChanged = input.loadMode !== input.trackedLoadMode;
|
|
12525
|
+
const viewChanged = input.visibilityDirty || loadModeChanged || input.viewportChanged || input.rotationDelta > VIEW_CHANGE_EPSILON || input.fovDelta > VIEW_CHANGE_EPSILON;
|
|
12526
|
+
if (!viewChanged) {
|
|
12527
|
+
return false;
|
|
12528
|
+
}
|
|
12529
|
+
const movingQuickly = input.rotationDelta >= FAST_ROTATION_THRESHOLD_RADIANS || input.fovDelta >= FAST_FOV_THRESHOLD_DEGREES;
|
|
12530
|
+
const immediate = input.visibilityDirty || loadModeChanged || input.viewportChanged || movingQuickly;
|
|
12531
|
+
if (!immediate && input.now - input.lastUpdateAt < MAX_LOD_UPDATE_INTERVAL_MS) {
|
|
12532
|
+
return false;
|
|
12533
|
+
}
|
|
12534
|
+
return true;
|
|
12535
|
+
}
|
|
12367
12536
|
var VISIBILITY_FOV_PADDING_DEGREES = 8;
|
|
12368
12537
|
var PREVIEW_RADIUS = CUBE_RADIUS + 0.05;
|
|
12369
|
-
var SHARED_TILE_GEOMETRY = new
|
|
12538
|
+
var SHARED_TILE_GEOMETRY = new import_three23.PlaneGeometry(1, 1);
|
|
12370
12539
|
function PreviewFace({
|
|
12371
12540
|
face,
|
|
12372
12541
|
texture,
|
|
12373
12542
|
faceOrder
|
|
12374
12543
|
}) {
|
|
12375
|
-
const geometry = (0,
|
|
12376
|
-
const nextGeometry = new
|
|
12544
|
+
const geometry = (0, import_react46.useMemo)(() => {
|
|
12545
|
+
const nextGeometry = new import_three23.PlaneGeometry(
|
|
12377
12546
|
PREVIEW_RADIUS * 2,
|
|
12378
12547
|
PREVIEW_RADIUS * 2
|
|
12379
12548
|
);
|
|
@@ -12387,21 +12556,21 @@ function PreviewFace({
|
|
|
12387
12556
|
uv.needsUpdate = true;
|
|
12388
12557
|
return nextGeometry;
|
|
12389
12558
|
}, [face, faceOrder]);
|
|
12390
|
-
(0,
|
|
12559
|
+
(0, import_react46.useEffect)(
|
|
12391
12560
|
() => () => {
|
|
12392
12561
|
geometry.dispose();
|
|
12393
12562
|
},
|
|
12394
12563
|
[geometry]
|
|
12395
12564
|
);
|
|
12396
12565
|
const transform = getFaceTransform(face, PREVIEW_RADIUS);
|
|
12397
|
-
return /* @__PURE__ */ (0,
|
|
12566
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
12398
12567
|
"mesh",
|
|
12399
12568
|
{
|
|
12400
12569
|
geometry,
|
|
12401
12570
|
position: transform.position,
|
|
12402
12571
|
renderOrder: -100,
|
|
12403
12572
|
rotation: transform.rotation,
|
|
12404
|
-
children: /* @__PURE__ */ (0,
|
|
12573
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
12405
12574
|
PanoBasicMaterial,
|
|
12406
12575
|
{
|
|
12407
12576
|
depthTest: false,
|
|
@@ -12417,7 +12586,7 @@ function PreviewCube({
|
|
|
12417
12586
|
texture,
|
|
12418
12587
|
faceOrder
|
|
12419
12588
|
}) {
|
|
12420
|
-
return CUBE_FACES.map((face) => /* @__PURE__ */ (0,
|
|
12589
|
+
return CUBE_FACES.map((face) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
12421
12590
|
PreviewFace,
|
|
12422
12591
|
{
|
|
12423
12592
|
face,
|
|
@@ -12427,7 +12596,7 @@ function PreviewCube({
|
|
|
12427
12596
|
face
|
|
12428
12597
|
));
|
|
12429
12598
|
}
|
|
12430
|
-
var TileMesh = (0,
|
|
12599
|
+
var TileMesh = (0, import_react46.memo)(function TileMesh2({
|
|
12431
12600
|
address,
|
|
12432
12601
|
manager,
|
|
12433
12602
|
renderOrder,
|
|
@@ -12441,14 +12610,14 @@ var TileMesh = (0, import_react44.memo)(function TileMesh2({
|
|
|
12441
12610
|
if (!snapshot.texture) {
|
|
12442
12611
|
return null;
|
|
12443
12612
|
}
|
|
12444
|
-
return /* @__PURE__ */ (0,
|
|
12613
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("group", { position: transform.position, rotation: transform.rotation, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
12445
12614
|
"mesh",
|
|
12446
12615
|
{
|
|
12447
12616
|
geometry: SHARED_TILE_GEOMETRY,
|
|
12448
12617
|
position: [layout.x, layout.y, 0],
|
|
12449
12618
|
renderOrder,
|
|
12450
12619
|
scale: [layout.width, layout.height, 1],
|
|
12451
|
-
children: /* @__PURE__ */ (0,
|
|
12620
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
12452
12621
|
PanoBasicMaterial,
|
|
12453
12622
|
{
|
|
12454
12623
|
depthTest: false,
|
|
@@ -12460,12 +12629,12 @@ var TileMesh = (0, import_react44.memo)(function TileMesh2({
|
|
|
12460
12629
|
}
|
|
12461
12630
|
) });
|
|
12462
12631
|
});
|
|
12463
|
-
var TileLayerMeshes = (0,
|
|
12632
|
+
var TileLayerMeshes = (0, import_react46.memo)(function TileLayerMeshes2({
|
|
12464
12633
|
layer,
|
|
12465
12634
|
manager,
|
|
12466
12635
|
resolveUrl
|
|
12467
12636
|
}) {
|
|
12468
|
-
return layer.addresses.map((address) => /* @__PURE__ */ (0,
|
|
12637
|
+
return layer.addresses.map((address) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
12469
12638
|
TileMesh,
|
|
12470
12639
|
{
|
|
12471
12640
|
address,
|
|
@@ -12565,8 +12734,8 @@ function parentAddresses(child, parentLevel, parentFaceSize, tileSize) {
|
|
|
12565
12734
|
return addresses;
|
|
12566
12735
|
}
|
|
12567
12736
|
function centerFacingAddress(candidates, camera) {
|
|
12568
|
-
const direction = camera.getWorldDirection(new
|
|
12569
|
-
const center = new
|
|
12737
|
+
const direction = camera.getWorldDirection(new import_three23.Vector3());
|
|
12738
|
+
const center = new import_three23.Vector3();
|
|
12570
12739
|
let bestCandidate = candidates[0];
|
|
12571
12740
|
let bestAlignment = -Infinity;
|
|
12572
12741
|
for (const candidate of candidates) {
|
|
@@ -12631,11 +12800,11 @@ function Tile({
|
|
|
12631
12800
|
onTileError,
|
|
12632
12801
|
onLevelChange
|
|
12633
12802
|
}) {
|
|
12634
|
-
const { camera, gl, size } = (0,
|
|
12635
|
-
const multiresConfig = (0,
|
|
12803
|
+
const { camera, gl, size } = (0, import_fiber22.useThree)();
|
|
12804
|
+
const multiresConfig = (0, import_react46.useMemo)(() => parseMultires(multires), [multires]);
|
|
12636
12805
|
const { levels, tileSize } = multiresConfig;
|
|
12637
12806
|
const multiresToken = `${tileSize}:${levels.join(",")}`;
|
|
12638
|
-
const candidatesByLevel = (0,
|
|
12807
|
+
const candidatesByLevel = (0, import_react46.useMemo)(
|
|
12639
12808
|
() => buildTileCandidates(levels, tileSize),
|
|
12640
12809
|
[levels, tileSize]
|
|
12641
12810
|
);
|
|
@@ -12647,13 +12816,13 @@ function Tile({
|
|
|
12647
12816
|
onPreviewError
|
|
12648
12817
|
);
|
|
12649
12818
|
const sharedManager = useSharedTileTextureManager();
|
|
12650
|
-
const progressRef = (0,
|
|
12651
|
-
const errorRef = (0,
|
|
12652
|
-
const levelChangeRef = (0,
|
|
12819
|
+
const progressRef = (0, import_react46.useRef)(onLoadProgress);
|
|
12820
|
+
const errorRef = (0, import_react46.useRef)(onTileError);
|
|
12821
|
+
const levelChangeRef = (0, import_react46.useRef)(onLevelChange);
|
|
12653
12822
|
progressRef.current = onLoadProgress;
|
|
12654
12823
|
errorRef.current = onTileError;
|
|
12655
12824
|
levelChangeRef.current = onLevelChange;
|
|
12656
|
-
const ownedManager = (0,
|
|
12825
|
+
const ownedManager = (0, import_react46.useMemo)(
|
|
12657
12826
|
() => new TileTextureManager({
|
|
12658
12827
|
anisotropy,
|
|
12659
12828
|
maxBytes: Math.max(1, maxTextureMemoryMb) * 1024 * 1024,
|
|
@@ -12674,7 +12843,7 @@ function Tile({
|
|
|
12674
12843
|
]
|
|
12675
12844
|
);
|
|
12676
12845
|
const manager = sharedManager ?? ownedManager;
|
|
12677
|
-
(0,
|
|
12846
|
+
(0, import_react46.useEffect)(() => {
|
|
12678
12847
|
manager.resume();
|
|
12679
12848
|
return () => {
|
|
12680
12849
|
if (manager === ownedManager) {
|
|
@@ -12684,11 +12853,11 @@ function Tile({
|
|
|
12684
12853
|
queueMicrotask(() => manager.releaseUnused());
|
|
12685
12854
|
};
|
|
12686
12855
|
}, [manager, ownedManager]);
|
|
12687
|
-
const readyRef = (0,
|
|
12688
|
-
(0,
|
|
12856
|
+
const readyRef = (0, import_react46.useRef)(false);
|
|
12857
|
+
(0, import_react46.useEffect)(() => {
|
|
12689
12858
|
readyRef.current = false;
|
|
12690
12859
|
}, [effectivePreviewUrl]);
|
|
12691
|
-
(0,
|
|
12860
|
+
(0, import_react46.useEffect)(() => {
|
|
12692
12861
|
if (!previewTexture || readyRef.current) {
|
|
12693
12862
|
return;
|
|
12694
12863
|
}
|
|
@@ -12696,31 +12865,37 @@ function Tile({
|
|
|
12696
12865
|
onReady?.();
|
|
12697
12866
|
}, [onReady, previewTexture]);
|
|
12698
12867
|
const template = urlTemplate ?? buildDefaultTileUrlTemplate();
|
|
12699
|
-
const resolveUrl = (0,
|
|
12868
|
+
const resolveUrl = (0, import_react46.useMemo)(
|
|
12700
12869
|
() => (address) => {
|
|
12701
12870
|
const relativePath = resolveTileUrl ? resolveTileUrl(address) : resolveTemplateUrl(template, address);
|
|
12702
12871
|
return resolveRelativeTileUrl(baseUrl, relativePath);
|
|
12703
12872
|
},
|
|
12704
12873
|
[baseUrl, resolveTileUrl, template]
|
|
12705
12874
|
);
|
|
12706
|
-
const [layers, setLayers] = (0,
|
|
12707
|
-
const layerTokenRef = (0,
|
|
12708
|
-
const currentLevelRef = (0,
|
|
12709
|
-
const lastUpdateAtRef = (0,
|
|
12710
|
-
const visibilityDirtyRef = (0,
|
|
12711
|
-
const lastVisibilityQuaternionRef = (0,
|
|
12712
|
-
const lastVisibilityFovRef = (0,
|
|
12713
|
-
const lastViewportRef = (0,
|
|
12714
|
-
const frustumRef = (0,
|
|
12715
|
-
const projectionMatrixRef = (0,
|
|
12716
|
-
const visibilityCameraRef = (0,
|
|
12717
|
-
(0,
|
|
12875
|
+
const [layers, setLayers] = (0, import_react46.useState)([]);
|
|
12876
|
+
const layerTokenRef = (0, import_react46.useRef)("");
|
|
12877
|
+
const currentLevelRef = (0, import_react46.useRef)(1);
|
|
12878
|
+
const lastUpdateAtRef = (0, import_react46.useRef)(-Infinity);
|
|
12879
|
+
const visibilityDirtyRef = (0, import_react46.useRef)(true);
|
|
12880
|
+
const lastVisibilityQuaternionRef = (0, import_react46.useRef)(camera.quaternion.clone());
|
|
12881
|
+
const lastVisibilityFovRef = (0, import_react46.useRef)(Number.NaN);
|
|
12882
|
+
const lastViewportRef = (0, import_react46.useRef)({ width: 0, height: 0, dpr: 0 });
|
|
12883
|
+
const frustumRef = (0, import_react46.useRef)(new import_three23.Frustum());
|
|
12884
|
+
const projectionMatrixRef = (0, import_react46.useRef)(new import_three23.Matrix4());
|
|
12885
|
+
const visibilityCameraRef = (0, import_react46.useRef)(new import_three23.PerspectiveCamera());
|
|
12886
|
+
const trackedLoadModeRef = (0, import_react46.useRef)(loadMode);
|
|
12887
|
+
const targetKeysRef = (0, import_react46.useRef)([]);
|
|
12888
|
+
const detailTokenRef = (0, import_react46.useRef)("");
|
|
12889
|
+
const detailReporter = useSceneDetailReporter();
|
|
12890
|
+
const detailReporterRef = (0, import_react46.useRef)(detailReporter);
|
|
12891
|
+
detailReporterRef.current = detailReporter;
|
|
12892
|
+
(0, import_react46.useEffect)(() => {
|
|
12718
12893
|
currentLevelRef.current = 1;
|
|
12719
12894
|
layerTokenRef.current = "";
|
|
12720
12895
|
visibilityDirtyRef.current = true;
|
|
12721
12896
|
setLayers([]);
|
|
12722
12897
|
}, [manager, multiresToken]);
|
|
12723
|
-
(0,
|
|
12898
|
+
(0, import_react46.useEffect)(() => {
|
|
12724
12899
|
if (loadMode !== "preview") {
|
|
12725
12900
|
return;
|
|
12726
12901
|
}
|
|
@@ -12734,11 +12909,14 @@ function Tile({
|
|
|
12734
12909
|
setLayers(nextLayers);
|
|
12735
12910
|
}
|
|
12736
12911
|
};
|
|
12737
|
-
(0,
|
|
12738
|
-
if (
|
|
12912
|
+
(0, import_fiber22.useFrame)(() => {
|
|
12913
|
+
if (!(camera instanceof import_three23.PerspectiveCamera)) {
|
|
12739
12914
|
return;
|
|
12740
12915
|
}
|
|
12741
|
-
if (
|
|
12916
|
+
if (loadMode === "preview") {
|
|
12917
|
+
trackedLoadModeRef.current = "preview";
|
|
12918
|
+
targetKeysRef.current = [];
|
|
12919
|
+
publishSceneDetail(detailReporterRef.current, detailTokenRef, false);
|
|
12742
12920
|
return;
|
|
12743
12921
|
}
|
|
12744
12922
|
const now = performance.now();
|
|
@@ -12749,60 +12927,75 @@ function Tile({
|
|
|
12749
12927
|
const fovDelta = Number.isFinite(lastVisibilityFovRef.current) ? Math.abs(camera.fov - lastVisibilityFovRef.current) : Infinity;
|
|
12750
12928
|
const lastViewport = lastViewportRef.current;
|
|
12751
12929
|
const viewportChanged = lastViewport.width !== size.width || lastViewport.height !== size.height || lastViewport.dpr !== pixelRatio;
|
|
12752
|
-
const
|
|
12753
|
-
|
|
12754
|
-
|
|
12755
|
-
|
|
12756
|
-
|
|
12757
|
-
|
|
12758
|
-
|
|
12759
|
-
|
|
12760
|
-
|
|
12761
|
-
|
|
12762
|
-
|
|
12763
|
-
|
|
12764
|
-
|
|
12765
|
-
|
|
12766
|
-
|
|
12767
|
-
|
|
12768
|
-
|
|
12769
|
-
|
|
12770
|
-
|
|
12771
|
-
|
|
12772
|
-
|
|
12773
|
-
|
|
12774
|
-
|
|
12775
|
-
|
|
12776
|
-
|
|
12777
|
-
camera
|
|
12778
|
-
|
|
12779
|
-
|
|
12780
|
-
|
|
12781
|
-
|
|
12782
|
-
|
|
12783
|
-
|
|
12784
|
-
|
|
12785
|
-
|
|
12786
|
-
|
|
12787
|
-
|
|
12788
|
-
|
|
12789
|
-
|
|
12790
|
-
|
|
12791
|
-
|
|
12930
|
+
const updateLod = decideTileLodUpdate({
|
|
12931
|
+
loadMode,
|
|
12932
|
+
trackedLoadMode: trackedLoadModeRef.current,
|
|
12933
|
+
now,
|
|
12934
|
+
lastUpdateAt: lastUpdateAtRef.current,
|
|
12935
|
+
visibilityDirty: visibilityDirtyRef.current,
|
|
12936
|
+
viewportChanged,
|
|
12937
|
+
rotationDelta,
|
|
12938
|
+
fovDelta
|
|
12939
|
+
});
|
|
12940
|
+
if (updateLod) {
|
|
12941
|
+
trackedLoadModeRef.current = loadMode;
|
|
12942
|
+
lastUpdateAtRef.current = now;
|
|
12943
|
+
const targetLevel = loadMode === "base" ? 1 : getPreferredLevel(
|
|
12944
|
+
levels,
|
|
12945
|
+
size.height,
|
|
12946
|
+
pixelRatio,
|
|
12947
|
+
camera.fov,
|
|
12948
|
+
currentLevelRef.current
|
|
12949
|
+
);
|
|
12950
|
+
if (targetLevel !== currentLevelRef.current) {
|
|
12951
|
+
currentLevelRef.current = targetLevel;
|
|
12952
|
+
levelChangeRef.current?.(targetLevel);
|
|
12953
|
+
}
|
|
12954
|
+
const visibilityCamera = visibilityCameraRef.current;
|
|
12955
|
+
visibilityCamera.copy(camera, false);
|
|
12956
|
+
visibilityCamera.fov = Math.min(
|
|
12957
|
+
179,
|
|
12958
|
+
camera.fov + VISIBILITY_FOV_PADDING_DEGREES
|
|
12959
|
+
);
|
|
12960
|
+
visibilityCamera.aspect = camera.aspect;
|
|
12961
|
+
updateVisibilityFrustum(
|
|
12962
|
+
visibilityCamera,
|
|
12963
|
+
projectionMatrixRef.current,
|
|
12964
|
+
frustumRef.current
|
|
12965
|
+
);
|
|
12966
|
+
const nextLayers = buildLayers(
|
|
12967
|
+
targetLevel,
|
|
12968
|
+
levels,
|
|
12969
|
+
tileSize,
|
|
12970
|
+
frustumRef.current,
|
|
12971
|
+
camera,
|
|
12972
|
+
candidatesByLevel
|
|
12973
|
+
);
|
|
12974
|
+
visibilityDirtyRef.current = false;
|
|
12975
|
+
lastVisibilityQuaternionRef.current.copy(camera.quaternion);
|
|
12976
|
+
lastVisibilityFovRef.current = camera.fov;
|
|
12977
|
+
lastViewportRef.current = {
|
|
12978
|
+
width: size.width,
|
|
12979
|
+
height: size.height,
|
|
12980
|
+
dpr: pixelRatio
|
|
12981
|
+
};
|
|
12982
|
+
const targetLayer = nextLayers.find((layer) => layer.level === targetLevel);
|
|
12983
|
+
targetKeysRef.current = loadMode === "full" ? (targetLayer?.addresses ?? []).map(
|
|
12984
|
+
(address) => `${resolveUrl(address)}\0${tileKey(address)}`
|
|
12985
|
+
) : [];
|
|
12986
|
+
commitLayers(nextLayers);
|
|
12987
|
+
}
|
|
12988
|
+
publishSceneDetail(
|
|
12989
|
+
detailReporterRef.current,
|
|
12990
|
+
detailTokenRef,
|
|
12991
|
+
loadMode === "full" && viewTilesAreDrawable(
|
|
12992
|
+
targetKeysRef.current.map((key) => manager.getSnapshot(key).texture)
|
|
12993
|
+
)
|
|
12792
12994
|
);
|
|
12793
|
-
visibilityDirtyRef.current = false;
|
|
12794
|
-
lastVisibilityQuaternionRef.current.copy(camera.quaternion);
|
|
12795
|
-
lastVisibilityFovRef.current = camera.fov;
|
|
12796
|
-
lastViewportRef.current = {
|
|
12797
|
-
width: size.width,
|
|
12798
|
-
height: size.height,
|
|
12799
|
-
dpr: pixelRatio
|
|
12800
|
-
};
|
|
12801
|
-
commitLayers(nextLayers);
|
|
12802
12995
|
});
|
|
12803
|
-
return /* @__PURE__ */ (0,
|
|
12804
|
-
previewTexture ? /* @__PURE__ */ (0,
|
|
12805
|
-
layers.map((layer) => /* @__PURE__ */ (0,
|
|
12996
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("group", { visible, children: [
|
|
12997
|
+
previewTexture ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PreviewCube, { texture: previewTexture, faceOrder: previewFaceOrder }) : null,
|
|
12998
|
+
layers.map((layer) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
12806
12999
|
TileLayerMeshes,
|
|
12807
13000
|
{
|
|
12808
13001
|
layer,
|
|
@@ -12815,7 +13008,7 @@ function Tile({
|
|
|
12815
13008
|
}
|
|
12816
13009
|
|
|
12817
13010
|
// src/scenes.tsx
|
|
12818
|
-
var
|
|
13011
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
12819
13012
|
function SceneSource({
|
|
12820
13013
|
scene,
|
|
12821
13014
|
visible,
|
|
@@ -12828,7 +13021,7 @@ function SceneSource({
|
|
|
12828
13021
|
}
|
|
12829
13022
|
switch (scene.type) {
|
|
12830
13023
|
case "sphere":
|
|
12831
|
-
return /* @__PURE__ */ (0,
|
|
13024
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
12832
13025
|
Sphere,
|
|
12833
13026
|
{
|
|
12834
13027
|
src: scene.src,
|
|
@@ -12841,7 +13034,7 @@ function SceneSource({
|
|
|
12841
13034
|
);
|
|
12842
13035
|
case "tile": {
|
|
12843
13036
|
const { id: _id, type: _type, ...tileProps } = scene;
|
|
12844
|
-
return /* @__PURE__ */ (0,
|
|
13037
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
12845
13038
|
Tile,
|
|
12846
13039
|
{
|
|
12847
13040
|
...tileProps,
|
|
@@ -12854,7 +13047,7 @@ function SceneSource({
|
|
|
12854
13047
|
}
|
|
12855
13048
|
case "sphereTile": {
|
|
12856
13049
|
const { id: _id, type: _type, ...tileProps } = scene;
|
|
12857
|
-
return /* @__PURE__ */ (0,
|
|
13050
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
12858
13051
|
SphereTile,
|
|
12859
13052
|
{
|
|
12860
13053
|
...tileProps,
|
|
@@ -12877,17 +13070,17 @@ function SnapshotCapture({
|
|
|
12877
13070
|
maxPixels,
|
|
12878
13071
|
onCaptured
|
|
12879
13072
|
}) {
|
|
12880
|
-
const { camera, gl, scene, size } = (0,
|
|
12881
|
-
const capturedRequestRef = (0,
|
|
12882
|
-
const renderTargetRef = (0,
|
|
12883
|
-
(0,
|
|
13073
|
+
const { camera, gl, scene, size } = (0, import_fiber23.useThree)();
|
|
13074
|
+
const capturedRequestRef = (0, import_react47.useRef)(0);
|
|
13075
|
+
const renderTargetRef = (0, import_react47.useRef)(null);
|
|
13076
|
+
(0, import_react47.useEffect)(
|
|
12884
13077
|
() => () => {
|
|
12885
13078
|
renderTargetRef.current?.dispose();
|
|
12886
13079
|
renderTargetRef.current = null;
|
|
12887
13080
|
},
|
|
12888
13081
|
[]
|
|
12889
13082
|
);
|
|
12890
|
-
(0,
|
|
13083
|
+
(0, import_fiber23.useFrame)(() => {
|
|
12891
13084
|
if (requestId === 0 || requestId === capturedRequestRef.current) {
|
|
12892
13085
|
return;
|
|
12893
13086
|
}
|
|
@@ -12897,14 +13090,14 @@ function SnapshotCapture({
|
|
|
12897
13090
|
const scale = Math.min(1, Math.sqrt(maxPixels / (sourceWidth * sourceHeight)));
|
|
12898
13091
|
const width = Math.max(1, Math.floor(sourceWidth * scale));
|
|
12899
13092
|
const height = Math.max(1, Math.floor(sourceHeight * scale));
|
|
12900
|
-
const nextTarget = new
|
|
13093
|
+
const nextTarget = new import_three24.WebGLRenderTarget(width, height, {
|
|
12901
13094
|
depthBuffer: false,
|
|
12902
13095
|
stencilBuffer: false
|
|
12903
13096
|
});
|
|
12904
|
-
nextTarget.texture.colorSpace =
|
|
13097
|
+
nextTarget.texture.colorSpace = import_three24.LinearSRGBColorSpace;
|
|
12905
13098
|
nextTarget.texture.generateMipmaps = false;
|
|
12906
|
-
nextTarget.texture.minFilter =
|
|
12907
|
-
nextTarget.texture.magFilter =
|
|
13099
|
+
nextTarget.texture.minFilter = import_three24.LinearFilter;
|
|
13100
|
+
nextTarget.texture.magFilter = import_three24.LinearFilter;
|
|
12908
13101
|
const previousTarget = gl.getRenderTarget();
|
|
12909
13102
|
gl.setRenderTarget(nextTarget);
|
|
12910
13103
|
gl.clear();
|
|
@@ -12935,53 +13128,90 @@ function ScenesController({
|
|
|
12935
13128
|
onTransitionEnd,
|
|
12936
13129
|
onTransitionError,
|
|
12937
13130
|
snapshotMaxPixels = 3686400,
|
|
13131
|
+
transitionWaitForDetailMs,
|
|
12938
13132
|
phaseRef: externalPhaseRef
|
|
12939
13133
|
}) {
|
|
12940
|
-
const controlsRef = (0,
|
|
13134
|
+
const controlsRef = (0, import_react47.useContext)(PanoramaViewContext);
|
|
12941
13135
|
const manager = useSharedTileTextureManager();
|
|
12942
|
-
const transition = (0,
|
|
13136
|
+
const transition = (0, import_react47.useMemo)(
|
|
12943
13137
|
() => resolveTransition(transitionInput),
|
|
12944
13138
|
[transitionInput]
|
|
12945
13139
|
);
|
|
12946
|
-
const sceneMap = (0,
|
|
13140
|
+
const sceneMap = (0, import_react47.useMemo)(
|
|
12947
13141
|
() => new Map(scenes.map((scene) => [scene.id, scene])),
|
|
12948
13142
|
[scenes]
|
|
12949
13143
|
);
|
|
12950
13144
|
const initialScene = sceneMap.get(activeSceneId) ?? null;
|
|
12951
|
-
const [slots, setSlots] = (0,
|
|
13145
|
+
const [slots, setSlots] = (0, import_react47.useState)([
|
|
12952
13146
|
initialScene,
|
|
12953
13147
|
null
|
|
12954
13148
|
]);
|
|
12955
|
-
const [activeSlot, setActiveSlot] = (0,
|
|
12956
|
-
const [liveSlot, setLiveSlot] = (0,
|
|
12957
|
-
const [pendingSlot, setPendingSlot] = (0,
|
|
12958
|
-
const [phase, setPhase] = (0,
|
|
12959
|
-
const [captureRequestId, setCaptureRequestId] = (0,
|
|
12960
|
-
const [transitionRunId, setTransitionRunId] = (0,
|
|
12961
|
-
const [snapshot, setSnapshot] = (0,
|
|
12962
|
-
const [recoveryKey, setRecoveryKey] = (0,
|
|
12963
|
-
const requestedSceneIdRef = (0,
|
|
12964
|
-
const captureReasonRef = (0,
|
|
12965
|
-
const interactionReleaseRef = (0,
|
|
12966
|
-
const slotsRef = (0,
|
|
12967
|
-
const phaseRef = (0,
|
|
12968
|
-
const liveSlotRef = (0,
|
|
12969
|
-
const transitionFromRef = (0,
|
|
12970
|
-
const readySceneRef = (0,
|
|
13149
|
+
const [activeSlot, setActiveSlot] = (0, import_react47.useState)(0);
|
|
13150
|
+
const [liveSlot, setLiveSlot] = (0, import_react47.useState)(0);
|
|
13151
|
+
const [pendingSlot, setPendingSlot] = (0, import_react47.useState)(null);
|
|
13152
|
+
const [phase, setPhase] = (0, import_react47.useState)(initialScene ? "idle" : "preloading");
|
|
13153
|
+
const [captureRequestId, setCaptureRequestId] = (0, import_react47.useState)(0);
|
|
13154
|
+
const [transitionRunId, setTransitionRunId] = (0, import_react47.useState)(0);
|
|
13155
|
+
const [snapshot, setSnapshot] = (0, import_react47.useState)(null);
|
|
13156
|
+
const [recoveryKey, setRecoveryKey] = (0, import_react47.useState)(0);
|
|
13157
|
+
const requestedSceneIdRef = (0, import_react47.useRef)(activeSceneId);
|
|
13158
|
+
const captureReasonRef = (0, import_react47.useRef)("start");
|
|
13159
|
+
const interactionReleaseRef = (0, import_react47.useRef)(null);
|
|
13160
|
+
const slotsRef = (0, import_react47.useRef)(slots);
|
|
13161
|
+
const phaseRef = (0, import_react47.useRef)(phase);
|
|
13162
|
+
const liveSlotRef = (0, import_react47.useRef)(liveSlot);
|
|
13163
|
+
const transitionFromRef = (0, import_react47.useRef)(initialScene);
|
|
13164
|
+
const readySceneRef = (0, import_react47.useRef)(null);
|
|
13165
|
+
const waitRef = (0, import_react47.useRef)(null);
|
|
13166
|
+
const waitTimerRef = (0, import_react47.useRef)(null);
|
|
13167
|
+
const detailGenerationRef = (0, import_react47.useRef)(0);
|
|
13168
|
+
const [detailGeneration, setDetailGeneration] = (0, import_react47.useState)(0);
|
|
13169
|
+
const mountedRef = (0, import_react47.useRef)(true);
|
|
13170
|
+
const waitForDetailMsRef = (0, import_react47.useRef)(0);
|
|
13171
|
+
waitForDetailMsRef.current = normalizeTransitionWaitMs(transitionWaitForDetailMs);
|
|
12971
13172
|
slotsRef.current = slots;
|
|
12972
13173
|
phaseRef.current = phase;
|
|
12973
13174
|
if (externalPhaseRef) {
|
|
12974
13175
|
externalPhaseRef.current = phase;
|
|
12975
13176
|
}
|
|
12976
13177
|
liveSlotRef.current = liveSlot;
|
|
12977
|
-
const releaseInteraction = (0,
|
|
13178
|
+
const releaseInteraction = (0, import_react47.useCallback)(() => {
|
|
12978
13179
|
interactionReleaseRef.current?.();
|
|
12979
13180
|
interactionReleaseRef.current = null;
|
|
12980
13181
|
}, []);
|
|
12981
|
-
const reportError = (0,
|
|
13182
|
+
const reportError = (0, import_react47.useCallback)((sceneId, error) => {
|
|
12982
13183
|
onTransitionError?.({ sceneId, error });
|
|
12983
13184
|
}, [onTransitionError]);
|
|
12984
|
-
const
|
|
13185
|
+
const clearDetailWait = (0, import_react47.useCallback)((bumpGeneration) => {
|
|
13186
|
+
if (waitTimerRef.current !== null) {
|
|
13187
|
+
clearTimeout(waitTimerRef.current);
|
|
13188
|
+
waitTimerRef.current = null;
|
|
13189
|
+
}
|
|
13190
|
+
const generation = waitRef.current?.generation;
|
|
13191
|
+
if (generation === void 0) {
|
|
13192
|
+
waitRef.current = null;
|
|
13193
|
+
} else {
|
|
13194
|
+
waitRef.current = acceptDetailWait(waitRef.current, {
|
|
13195
|
+
kind: "cancel",
|
|
13196
|
+
generation
|
|
13197
|
+
}).wait;
|
|
13198
|
+
}
|
|
13199
|
+
if (!bumpGeneration || !mountedRef.current) {
|
|
13200
|
+
return;
|
|
13201
|
+
}
|
|
13202
|
+
const nextGeneration = detailGenerationRef.current + 1;
|
|
13203
|
+
detailGenerationRef.current = nextGeneration;
|
|
13204
|
+
setDetailGeneration(nextGeneration);
|
|
13205
|
+
}, []);
|
|
13206
|
+
(0, import_react47.useEffect)(() => {
|
|
13207
|
+
mountedRef.current = true;
|
|
13208
|
+
return () => {
|
|
13209
|
+
mountedRef.current = false;
|
|
13210
|
+
clearDetailWait(false);
|
|
13211
|
+
};
|
|
13212
|
+
}, [clearDetailWait]);
|
|
13213
|
+
const startPreload = (0, import_react47.useCallback)((scene) => {
|
|
13214
|
+
clearDetailWait(true);
|
|
12985
13215
|
const nextSlot = 1 - liveSlotRef.current;
|
|
12986
13216
|
requestedSceneIdRef.current = scene.id;
|
|
12987
13217
|
setSlots((current) => {
|
|
@@ -12991,8 +13221,8 @@ function ScenesController({
|
|
|
12991
13221
|
});
|
|
12992
13222
|
setPendingSlot(nextSlot);
|
|
12993
13223
|
setPhase("preloading");
|
|
12994
|
-
}, []);
|
|
12995
|
-
(0,
|
|
13224
|
+
}, [clearDetailWait]);
|
|
13225
|
+
(0, import_react47.useEffect)(() => {
|
|
12996
13226
|
const requested = sceneMap.get(activeSceneId);
|
|
12997
13227
|
if (!requested) {
|
|
12998
13228
|
reportError(activeSceneId, new Error(`Unknown panorama scene: ${activeSceneId}`));
|
|
@@ -13007,22 +13237,23 @@ function ScenesController({
|
|
|
13007
13237
|
requestedSceneIdRef.current = requested.id;
|
|
13008
13238
|
return;
|
|
13009
13239
|
}
|
|
13010
|
-
if (phaseRef.current === "transitioning" || phaseRef.current === "capturing") {
|
|
13240
|
+
if (phaseRef.current === "transitioning" || phaseRef.current === "capturing" || phaseRef.current === "awaitingDetail") {
|
|
13011
13241
|
if (requestedSceneIdRef.current === requested.id) return;
|
|
13012
13242
|
requestedSceneIdRef.current = requested.id;
|
|
13013
13243
|
captureReasonRef.current = "interrupt";
|
|
13244
|
+
clearDetailWait(true);
|
|
13014
13245
|
setPhase("recapturing");
|
|
13015
13246
|
setCaptureRequestId((current) => current + 1);
|
|
13016
13247
|
return;
|
|
13017
13248
|
}
|
|
13018
13249
|
startPreload(requested);
|
|
13019
|
-
}, [activeSceneId, pendingSlot, reportError, sceneMap, startPreload]);
|
|
13020
|
-
const notifySceneReady = (0,
|
|
13250
|
+
}, [activeSceneId, clearDetailWait, pendingSlot, reportError, sceneMap, startPreload]);
|
|
13251
|
+
const notifySceneReady = (0, import_react47.useCallback)((scene) => {
|
|
13021
13252
|
if (!scene || readySceneRef.current === scene) return;
|
|
13022
13253
|
readySceneRef.current = scene;
|
|
13023
13254
|
onSceneReady?.(scene.id);
|
|
13024
13255
|
}, [onSceneReady]);
|
|
13025
|
-
const handleReady = (0,
|
|
13256
|
+
const handleReady = (0, import_react47.useCallback)((slot) => {
|
|
13026
13257
|
if (slot === liveSlotRef.current && pendingSlot === null && phaseRef.current === "idle") {
|
|
13027
13258
|
notifySceneReady(slotsRef.current[slot]);
|
|
13028
13259
|
return;
|
|
@@ -13030,7 +13261,7 @@ function ScenesController({
|
|
|
13030
13261
|
if (slot !== pendingSlot || phaseRef.current !== "preloading") {
|
|
13031
13262
|
return;
|
|
13032
13263
|
}
|
|
13033
|
-
if (transition.preset === "none") {
|
|
13264
|
+
if (transition.preset === "none" && waitForDetailMsRef.current === 0) {
|
|
13034
13265
|
const previousScene = slotsRef.current[liveSlotRef.current];
|
|
13035
13266
|
const nextScene = slotsRef.current[slot];
|
|
13036
13267
|
setSlots((current) => {
|
|
@@ -13058,64 +13289,167 @@ function ScenesController({
|
|
|
13058
13289
|
setPhase("capturing");
|
|
13059
13290
|
setCaptureRequestId((current) => current + 1);
|
|
13060
13291
|
}, [controlsRef, notifySceneReady, onTransitionEnd, pendingSlot, transition.preset]);
|
|
13061
|
-
const
|
|
13062
|
-
|
|
13063
|
-
|
|
13064
|
-
|
|
13065
|
-
|
|
13292
|
+
const finishTransition = (0, import_react47.useCallback)(() => {
|
|
13293
|
+
const nextSlot = pendingSlot;
|
|
13294
|
+
const previousScene = transitionFromRef.current;
|
|
13295
|
+
const nextScene = nextSlot === null ? null : slotsRef.current[nextSlot];
|
|
13296
|
+
if (nextSlot === null || !nextScene) {
|
|
13297
|
+
releaseInteraction();
|
|
13298
|
+
setPhase("idle");
|
|
13299
|
+
return;
|
|
13300
|
+
}
|
|
13301
|
+
setActiveSlot(nextSlot);
|
|
13302
|
+
setLiveSlot(nextSlot);
|
|
13303
|
+
setPendingSlot(null);
|
|
13304
|
+
setPhase("idle");
|
|
13305
|
+
const oldSnapshot = snapshot;
|
|
13306
|
+
setSnapshot(null);
|
|
13307
|
+
oldSnapshot?.dispose();
|
|
13308
|
+
releaseInteraction();
|
|
13309
|
+
if (previousScene) {
|
|
13310
|
+
onTransitionEnd?.({
|
|
13311
|
+
previousSceneId: previousScene.id,
|
|
13312
|
+
sceneId: nextScene.id,
|
|
13313
|
+
preset: transition.preset
|
|
13314
|
+
});
|
|
13315
|
+
}
|
|
13316
|
+
}, [onTransitionEnd, pendingSlot, releaseInteraction, snapshot, transition.preset]);
|
|
13317
|
+
const finishTransitionRef = (0, import_react47.useRef)(finishTransition);
|
|
13318
|
+
finishTransitionRef.current = finishTransition;
|
|
13319
|
+
const transitionRef = (0, import_react47.useRef)(transition);
|
|
13320
|
+
transitionRef.current = transition;
|
|
13321
|
+
const consumeDetailSignal = (0, import_react47.useCallback)((signal) => {
|
|
13322
|
+
const decision = acceptDetailWait(waitRef.current, signal);
|
|
13323
|
+
waitRef.current = decision.wait;
|
|
13324
|
+
if (!decision.start) {
|
|
13325
|
+
return;
|
|
13326
|
+
}
|
|
13327
|
+
if (waitTimerRef.current !== null) {
|
|
13328
|
+
clearTimeout(waitTimerRef.current);
|
|
13329
|
+
waitTimerRef.current = null;
|
|
13330
|
+
}
|
|
13331
|
+
if (!mountedRef.current) {
|
|
13332
|
+
return;
|
|
13333
|
+
}
|
|
13334
|
+
if (transitionRef.current.preset === "none") {
|
|
13335
|
+
finishTransitionRef.current();
|
|
13336
|
+
return;
|
|
13337
|
+
}
|
|
13338
|
+
setPhase("transitioning");
|
|
13339
|
+
setTransitionRunId((current) => current + 1);
|
|
13340
|
+
}, []);
|
|
13341
|
+
const handleCaptured = (0, import_react47.useCallback)((nextSnapshot) => {
|
|
13066
13342
|
if (captureReasonRef.current === "interrupt") {
|
|
13343
|
+
setSnapshot((current) => {
|
|
13344
|
+
current?.dispose();
|
|
13345
|
+
return nextSnapshot;
|
|
13346
|
+
});
|
|
13067
13347
|
startPreload(sceneMap.get(requestedSceneIdRef.current));
|
|
13068
13348
|
return;
|
|
13069
13349
|
}
|
|
13070
|
-
const sourceSlot = liveSlotRef.current;
|
|
13071
|
-
|
|
13072
|
-
|
|
13073
|
-
next
|
|
13074
|
-
|
|
13350
|
+
const sourceSlot = liveSlotRef.current;
|
|
13351
|
+
const incoming = pendingSlot === null ? null : slotsRef.current[pendingSlot];
|
|
13352
|
+
setSlots((current) => {
|
|
13353
|
+
const next = [...current];
|
|
13354
|
+
next[sourceSlot] = null;
|
|
13355
|
+
return next;
|
|
13356
|
+
});
|
|
13357
|
+
manager?.releaseUnused();
|
|
13358
|
+
if (pendingSlot !== null && incoming) {
|
|
13359
|
+
notifySceneReady(incoming);
|
|
13360
|
+
setLiveSlot(pendingSlot);
|
|
13361
|
+
}
|
|
13362
|
+
if (waitTimerRef.current !== null) {
|
|
13363
|
+
clearTimeout(waitTimerRef.current);
|
|
13364
|
+
waitTimerRef.current = null;
|
|
13365
|
+
}
|
|
13366
|
+
waitRef.current = null;
|
|
13367
|
+
let hold = null;
|
|
13368
|
+
if (incoming && waitForDetailMsRef.current > 0) {
|
|
13369
|
+
const now = performance.now();
|
|
13370
|
+
const generation = detailGenerationRef.current + 1;
|
|
13371
|
+
detailGenerationRef.current = generation;
|
|
13372
|
+
hold = planDetailHold({
|
|
13373
|
+
waitMs: waitForDetailMsRef.current,
|
|
13374
|
+
now,
|
|
13375
|
+
generation,
|
|
13376
|
+
sceneId: incoming.id
|
|
13377
|
+
});
|
|
13378
|
+
if (hold) {
|
|
13379
|
+
const deadline = hold.deadline;
|
|
13380
|
+
waitRef.current = hold;
|
|
13381
|
+
setDetailGeneration(generation);
|
|
13382
|
+
waitTimerRef.current = setTimeout(() => {
|
|
13383
|
+
consumeDetailSignal({
|
|
13384
|
+
kind: "timeout",
|
|
13385
|
+
generation,
|
|
13386
|
+
now: deadline
|
|
13387
|
+
});
|
|
13388
|
+
}, Math.max(0, deadline - performance.now()));
|
|
13389
|
+
}
|
|
13390
|
+
}
|
|
13391
|
+
const nextPhase = phaseAfterSnapshot(transition.preset, hold);
|
|
13392
|
+
if (nextPhase === "awaitingDetail") {
|
|
13393
|
+
setSnapshot((current) => {
|
|
13394
|
+
current?.dispose();
|
|
13395
|
+
return nextSnapshot;
|
|
13396
|
+
});
|
|
13397
|
+
setPhase("awaitingDetail");
|
|
13398
|
+
return;
|
|
13399
|
+
}
|
|
13400
|
+
if (nextPhase === "idle") {
|
|
13401
|
+
nextSnapshot.dispose();
|
|
13402
|
+
setSnapshot((current) => {
|
|
13403
|
+
current?.dispose();
|
|
13404
|
+
return null;
|
|
13405
|
+
});
|
|
13406
|
+
if (pendingSlot !== null) {
|
|
13407
|
+
setActiveSlot(pendingSlot);
|
|
13408
|
+
}
|
|
13409
|
+
setPendingSlot(null);
|
|
13410
|
+
setPhase("idle");
|
|
13411
|
+
releaseInteraction();
|
|
13412
|
+
const previousScene = transitionFromRef.current;
|
|
13413
|
+
if (previousScene && incoming) {
|
|
13414
|
+
onTransitionEnd?.({
|
|
13415
|
+
previousSceneId: previousScene.id,
|
|
13416
|
+
sceneId: incoming.id,
|
|
13417
|
+
preset: "none"
|
|
13418
|
+
});
|
|
13419
|
+
}
|
|
13420
|
+
return;
|
|
13421
|
+
}
|
|
13422
|
+
setSnapshot((current) => {
|
|
13423
|
+
current?.dispose();
|
|
13424
|
+
return nextSnapshot;
|
|
13075
13425
|
});
|
|
13076
|
-
manager?.releaseUnused();
|
|
13077
|
-
if (pendingSlot !== null) {
|
|
13078
|
-
notifySceneReady(slotsRef.current[pendingSlot]);
|
|
13079
|
-
setLiveSlot(pendingSlot);
|
|
13080
|
-
}
|
|
13081
13426
|
setPhase("transitioning");
|
|
13082
13427
|
setTransitionRunId((current) => current + 1);
|
|
13083
|
-
}, [
|
|
13084
|
-
|
|
13085
|
-
|
|
13086
|
-
|
|
13087
|
-
|
|
13088
|
-
|
|
13089
|
-
|
|
13090
|
-
|
|
13091
|
-
|
|
13092
|
-
|
|
13093
|
-
|
|
13094
|
-
|
|
13095
|
-
|
|
13096
|
-
|
|
13097
|
-
const oldSnapshot = snapshot;
|
|
13098
|
-
setSnapshot(null);
|
|
13099
|
-
oldSnapshot?.dispose();
|
|
13100
|
-
releaseInteraction();
|
|
13101
|
-
if (previousScene) {
|
|
13102
|
-
onTransitionEnd?.({
|
|
13103
|
-
previousSceneId: previousScene.id,
|
|
13104
|
-
sceneId: nextScene.id,
|
|
13105
|
-
preset: transition.preset
|
|
13106
|
-
});
|
|
13107
|
-
}
|
|
13108
|
-
}, [onTransitionEnd, pendingSlot, releaseInteraction, snapshot, transition.preset]);
|
|
13109
|
-
(0, import_react45.useEffect)(() => () => {
|
|
13428
|
+
}, [
|
|
13429
|
+
consumeDetailSignal,
|
|
13430
|
+
manager,
|
|
13431
|
+
notifySceneReady,
|
|
13432
|
+
onTransitionEnd,
|
|
13433
|
+
pendingSlot,
|
|
13434
|
+
releaseInteraction,
|
|
13435
|
+
sceneMap,
|
|
13436
|
+
startPreload,
|
|
13437
|
+
transition.preset
|
|
13438
|
+
]);
|
|
13439
|
+
const snapshotRef = (0, import_react47.useRef)(snapshot);
|
|
13440
|
+
snapshotRef.current = snapshot;
|
|
13441
|
+
(0, import_react47.useEffect)(() => () => {
|
|
13110
13442
|
releaseInteraction();
|
|
13111
|
-
|
|
13112
|
-
|
|
13113
|
-
|
|
13114
|
-
(0,
|
|
13443
|
+
snapshotRef.current?.dispose();
|
|
13444
|
+
snapshotRef.current = null;
|
|
13445
|
+
}, [releaseInteraction]);
|
|
13446
|
+
const { gl } = (0, import_fiber23.useThree)();
|
|
13447
|
+
(0, import_react47.useEffect)(() => {
|
|
13115
13448
|
const canvas = gl.domElement;
|
|
13116
13449
|
const onContextLost = (event) => {
|
|
13117
13450
|
event.preventDefault();
|
|
13118
13451
|
releaseInteraction();
|
|
13452
|
+
clearDetailWait(true);
|
|
13119
13453
|
manager?.dispose();
|
|
13120
13454
|
snapshot?.dispose();
|
|
13121
13455
|
setSnapshot(null);
|
|
@@ -13133,11 +13467,30 @@ function ScenesController({
|
|
|
13133
13467
|
canvas.removeEventListener("webglcontextlost", onContextLost);
|
|
13134
13468
|
canvas.removeEventListener("webglcontextrestored", onContextRestored);
|
|
13135
13469
|
};
|
|
13136
|
-
}, [gl, manager, releaseInteraction, snapshot]);
|
|
13470
|
+
}, [clearDetailWait, gl, manager, releaseInteraction, snapshot]);
|
|
13137
13471
|
const renderedScene = slots[liveSlot];
|
|
13138
13472
|
const snapshotVisible = snapshot !== null && (phase === "transitioning" || phase === "recapturing" || phase === "preloading");
|
|
13139
|
-
|
|
13140
|
-
|
|
13473
|
+
const slotSceneKey = `${slots[0]?.id ?? ""}
|
|
13474
|
+
${slots[1]?.id ?? ""}`;
|
|
13475
|
+
const detailReporters = (0, import_react47.useMemo)(() => {
|
|
13476
|
+
const [firstSceneId = "", secondSceneId = ""] = slotSceneKey.split("\n");
|
|
13477
|
+
const sceneIds = [firstSceneId, secondSceneId];
|
|
13478
|
+
return sceneIds.map((sceneId) => ({
|
|
13479
|
+
generation: detailGeneration,
|
|
13480
|
+
report: (ready) => {
|
|
13481
|
+
if (!ready || sceneId === "") {
|
|
13482
|
+
return;
|
|
13483
|
+
}
|
|
13484
|
+
consumeDetailSignal({
|
|
13485
|
+
kind: "ready",
|
|
13486
|
+
generation: detailGeneration,
|
|
13487
|
+
sceneId
|
|
13488
|
+
});
|
|
13489
|
+
}
|
|
13490
|
+
}));
|
|
13491
|
+
}, [consumeDetailSignal, detailGeneration, slotSceneKey]);
|
|
13492
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_react47.Fragment, { children: [
|
|
13493
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
13141
13494
|
SnapshotCapture,
|
|
13142
13495
|
{
|
|
13143
13496
|
requestId: captureRequestId,
|
|
@@ -13149,23 +13502,30 @@ function ScenesController({
|
|
|
13149
13502
|
const source = slots[slot];
|
|
13150
13503
|
const isLive = slot === liveSlot;
|
|
13151
13504
|
const isPending = slot === pendingSlot;
|
|
13152
|
-
return /* @__PURE__ */ (0,
|
|
13153
|
-
|
|
13505
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
13506
|
+
SceneDetailContext.Provider,
|
|
13154
13507
|
{
|
|
13155
|
-
|
|
13156
|
-
|
|
13157
|
-
|
|
13158
|
-
|
|
13159
|
-
|
|
13160
|
-
|
|
13161
|
-
|
|
13508
|
+
value: detailReporters[slot],
|
|
13509
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
13510
|
+
SceneSource,
|
|
13511
|
+
{
|
|
13512
|
+
scene: source,
|
|
13513
|
+
visible: isLive,
|
|
13514
|
+
baseOnly: pendingSceneUsesBaseLayer(phase, isPending),
|
|
13515
|
+
onReady: () => handleReady(slot),
|
|
13516
|
+
onError: (error) => {
|
|
13517
|
+
if (source) {
|
|
13518
|
+
reportError(source.id, error);
|
|
13519
|
+
}
|
|
13520
|
+
}
|
|
13162
13521
|
}
|
|
13163
|
-
|
|
13522
|
+
)
|
|
13164
13523
|
},
|
|
13165
13524
|
`${slot}:${source?.id ?? "empty"}:${recoveryKey}`
|
|
13166
13525
|
);
|
|
13167
13526
|
}),
|
|
13168
|
-
|
|
13527
|
+
snapshot !== null && phase === "awaitingDetail" ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SnapshotHold, { snapshot }) : null,
|
|
13528
|
+
snapshotVisible ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
13169
13529
|
TransitionOverlay,
|
|
13170
13530
|
{
|
|
13171
13531
|
snapshot,
|
|
@@ -13188,11 +13548,11 @@ function Scenes({
|
|
|
13188
13548
|
...rest
|
|
13189
13549
|
}) {
|
|
13190
13550
|
const isControlled = controlledId !== void 0;
|
|
13191
|
-
const [internalId, setInternalId] = (0,
|
|
13551
|
+
const [internalId, setInternalId] = (0, import_react47.useState)(
|
|
13192
13552
|
() => controlledId ?? defaultActiveSceneId ?? scenes[0]?.id ?? ""
|
|
13193
13553
|
);
|
|
13194
13554
|
const resolvedId = isControlled ? controlledId : internalId;
|
|
13195
|
-
const requestSceneChange = (0,
|
|
13555
|
+
const requestSceneChange = (0, import_react47.useCallback)(
|
|
13196
13556
|
(id) => {
|
|
13197
13557
|
if (isControlled) {
|
|
13198
13558
|
onActiveSceneIdChange?.(id);
|
|
@@ -13202,13 +13562,13 @@ function Scenes({
|
|
|
13202
13562
|
},
|
|
13203
13563
|
[isControlled, onActiveSceneIdChange]
|
|
13204
13564
|
);
|
|
13205
|
-
const scenesRef = (0,
|
|
13565
|
+
const scenesRef = (0, import_react47.useRef)(scenes);
|
|
13206
13566
|
scenesRef.current = scenes;
|
|
13207
|
-
const resolvedIdRef = (0,
|
|
13567
|
+
const resolvedIdRef = (0, import_react47.useRef)(resolvedId);
|
|
13208
13568
|
resolvedIdRef.current = resolvedId;
|
|
13209
|
-
const host = (0,
|
|
13210
|
-
const phaseRef = (0,
|
|
13211
|
-
(0,
|
|
13569
|
+
const host = (0, import_react47.useContext)(ScenesHostContext);
|
|
13570
|
+
const phaseRef = (0, import_react47.useRef)("idle");
|
|
13571
|
+
(0, import_react47.useEffect)(() => {
|
|
13212
13572
|
if (!host) {
|
|
13213
13573
|
return;
|
|
13214
13574
|
}
|
|
@@ -13258,12 +13618,12 @@ function Scenes({
|
|
|
13258
13618
|
}
|
|
13259
13619
|
};
|
|
13260
13620
|
}, [host, requestSceneChange]);
|
|
13261
|
-
return /* @__PURE__ */ (0,
|
|
13621
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
13262
13622
|
TileTextureManagerProvider,
|
|
13263
13623
|
{
|
|
13264
13624
|
maxTextureMemoryMb,
|
|
13265
13625
|
maxConcurrentLoads: maxConcurrentTileLoads,
|
|
13266
|
-
children: /* @__PURE__ */ (0,
|
|
13626
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
13267
13627
|
ScenesController,
|
|
13268
13628
|
{
|
|
13269
13629
|
...rest,
|
|
@@ -13277,28 +13637,28 @@ function Scenes({
|
|
|
13277
13637
|
}
|
|
13278
13638
|
|
|
13279
13639
|
// src/hotspot/image-hotspot.tsx
|
|
13280
|
-
var
|
|
13281
|
-
var
|
|
13282
|
-
var
|
|
13640
|
+
var import_fiber26 = require("@react-three/fiber");
|
|
13641
|
+
var import_react51 = require("react");
|
|
13642
|
+
var import_three29 = require("three");
|
|
13283
13643
|
|
|
13284
13644
|
// src/hotspot/hotspot-anchor.tsx
|
|
13285
|
-
var
|
|
13286
|
-
var
|
|
13287
|
-
var
|
|
13645
|
+
var import_fiber25 = require("@react-three/fiber");
|
|
13646
|
+
var import_react50 = require("react");
|
|
13647
|
+
var import_three27 = require("three");
|
|
13288
13648
|
|
|
13289
13649
|
// src/hotspot/hotspot-tooltip.tsx
|
|
13290
|
-
var
|
|
13650
|
+
var import_react49 = require("react");
|
|
13291
13651
|
|
|
13292
13652
|
// src/webvr/stereo-html.tsx
|
|
13293
|
-
var
|
|
13294
|
-
var
|
|
13653
|
+
var import_fiber24 = require("@react-three/fiber");
|
|
13654
|
+
var import_react48 = require("react");
|
|
13295
13655
|
var import_client = require("react-dom/client");
|
|
13296
|
-
var
|
|
13297
|
-
var
|
|
13656
|
+
var import_three25 = require("three");
|
|
13657
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
13298
13658
|
function useFallbackStereoView() {
|
|
13299
|
-
const runtime = (0,
|
|
13659
|
+
const runtime = (0, import_react48.useContext)(WebVRRuntimeContext);
|
|
13300
13660
|
const host = runtime?.host ?? null;
|
|
13301
|
-
const fallback = (0,
|
|
13661
|
+
const fallback = (0, import_react48.useSyncExternalStore)(
|
|
13302
13662
|
(onStoreChange) => host ? subscribeWebVRHost(host, onStoreChange) : () => void 0,
|
|
13303
13663
|
() => isFallbackStereoMode(host?.snapshot.mode ?? null),
|
|
13304
13664
|
() => false
|
|
@@ -13313,10 +13673,10 @@ function ProjectedHtml({
|
|
|
13313
13673
|
stereoView,
|
|
13314
13674
|
eye
|
|
13315
13675
|
}) {
|
|
13316
|
-
const { camera, gl, events, size } = (0,
|
|
13317
|
-
const group = (0,
|
|
13318
|
-
const overlay = (0,
|
|
13319
|
-
const scratch = (0,
|
|
13676
|
+
const { camera, gl, events, size } = (0, import_fiber24.useThree)();
|
|
13677
|
+
const group = (0, import_react48.useRef)(null);
|
|
13678
|
+
const overlay = (0, import_react48.useRef)(null);
|
|
13679
|
+
const scratch = (0, import_react48.useRef)(new import_three25.Vector3());
|
|
13320
13680
|
const target = events.connected || gl.domElement.parentElement;
|
|
13321
13681
|
const updatePosition = () => {
|
|
13322
13682
|
const anchor = group.current;
|
|
@@ -13344,7 +13704,7 @@ function ProjectedHtml({
|
|
|
13344
13704
|
)
|
|
13345
13705
|
);
|
|
13346
13706
|
};
|
|
13347
|
-
(0,
|
|
13707
|
+
(0, import_react48.useLayoutEffect)(() => {
|
|
13348
13708
|
if (!target) return;
|
|
13349
13709
|
const element = document.createElement("div");
|
|
13350
13710
|
Object.assign(element.style, {
|
|
@@ -13362,9 +13722,9 @@ function ProjectedHtml({
|
|
|
13362
13722
|
queueMicrotask(() => root.unmount());
|
|
13363
13723
|
};
|
|
13364
13724
|
}, [target]);
|
|
13365
|
-
(0,
|
|
13725
|
+
(0, import_react48.useLayoutEffect)(() => {
|
|
13366
13726
|
overlay.current?.root.render(
|
|
13367
|
-
/* @__PURE__ */ (0,
|
|
13727
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
13368
13728
|
"div",
|
|
13369
13729
|
{
|
|
13370
13730
|
"aria-hidden": eye === "right" || void 0,
|
|
@@ -13375,19 +13735,19 @@ function ProjectedHtml({
|
|
|
13375
13735
|
);
|
|
13376
13736
|
updatePosition();
|
|
13377
13737
|
});
|
|
13378
|
-
(0,
|
|
13379
|
-
return /* @__PURE__ */ (0,
|
|
13738
|
+
(0, import_fiber24.useFrame)(updatePosition);
|
|
13739
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("group", { ref: group });
|
|
13380
13740
|
}
|
|
13381
13741
|
function PanoHtml(props) {
|
|
13382
13742
|
const stereoView = useFallbackStereoView();
|
|
13383
|
-
return stereoView ? /* @__PURE__ */ (0,
|
|
13384
|
-
/* @__PURE__ */ (0,
|
|
13385
|
-
/* @__PURE__ */ (0,
|
|
13386
|
-
] }) : /* @__PURE__ */ (0,
|
|
13743
|
+
return stereoView ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
|
|
13744
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ProjectedHtml, { ...props, stereoView, eye: "left" }),
|
|
13745
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ProjectedHtml, { ...props, stereoView, eye: "right" })
|
|
13746
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ProjectedHtml, { ...props });
|
|
13387
13747
|
}
|
|
13388
13748
|
|
|
13389
13749
|
// src/hotspot/hotspot-tooltip.tsx
|
|
13390
|
-
var
|
|
13750
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
13391
13751
|
var DEFAULT_HOTSPOT_TOOLTIP_OFFSET = 12;
|
|
13392
13752
|
var DEFAULT_HOTSPOT_TOOLTIP_APPEARANCE = {
|
|
13393
13753
|
background: "rgba(22, 22, 22, 0.72)",
|
|
@@ -13459,16 +13819,16 @@ function HotspotTooltip({
|
|
|
13459
13819
|
offset = DEFAULT_HOTSPOT_TOOLTIP_OFFSET,
|
|
13460
13820
|
appearance
|
|
13461
13821
|
}) {
|
|
13462
|
-
const [imageFailed, setImageFailed] = (0,
|
|
13463
|
-
(0,
|
|
13822
|
+
const [imageFailed, setImageFailed] = (0, import_react49.useState)(false);
|
|
13823
|
+
(0, import_react49.useEffect)(() => {
|
|
13464
13824
|
setImageFailed(false);
|
|
13465
13825
|
}, [content.image]);
|
|
13466
13826
|
const showImage = Boolean(content.image) && !imageFailed;
|
|
13467
|
-
const resolvedAppearance = (0,
|
|
13827
|
+
const resolvedAppearance = (0, import_react49.useMemo)(
|
|
13468
13828
|
() => resolveHotspotTooltipAppearance(appearance),
|
|
13469
13829
|
[appearance]
|
|
13470
13830
|
);
|
|
13471
|
-
const bubbleStyle = (0,
|
|
13831
|
+
const bubbleStyle = (0, import_react49.useMemo)(
|
|
13472
13832
|
() => ({
|
|
13473
13833
|
background: resolvedAppearance.background,
|
|
13474
13834
|
border: resolvedAppearance.border,
|
|
@@ -13490,8 +13850,8 @@ function HotspotTooltip({
|
|
|
13490
13850
|
if (!showImage && !content.text) {
|
|
13491
13851
|
return null;
|
|
13492
13852
|
}
|
|
13493
|
-
return /* @__PURE__ */ (0,
|
|
13494
|
-
showImage ? /* @__PURE__ */ (0,
|
|
13853
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(PanoHtml, { pointerEvents: "none", style: WRAPPER_STYLE, zIndexRange: [20, 10], children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "pano-hotspot-tooltip", role: "tooltip", style: bubbleStyle, children: [
|
|
13854
|
+
showImage ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
13495
13855
|
"img",
|
|
13496
13856
|
{
|
|
13497
13857
|
alt: content.imageAlt ?? content.text ?? "",
|
|
@@ -13500,7 +13860,7 @@ function HotspotTooltip({
|
|
|
13500
13860
|
src: content.image
|
|
13501
13861
|
}
|
|
13502
13862
|
) : null,
|
|
13503
|
-
content.text ? /* @__PURE__ */ (0,
|
|
13863
|
+
content.text ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
13504
13864
|
"p",
|
|
13505
13865
|
{
|
|
13506
13866
|
className: "pano-hotspot-tooltip-text",
|
|
@@ -13516,18 +13876,18 @@ function HotspotTooltip({
|
|
|
13516
13876
|
}
|
|
13517
13877
|
|
|
13518
13878
|
// src/hotspot/transform.ts
|
|
13519
|
-
var
|
|
13520
|
-
var LOCAL_FORWARD = new
|
|
13521
|
-
var CAMERA_POSITION = new
|
|
13879
|
+
var import_three26 = require("three");
|
|
13880
|
+
var LOCAL_FORWARD = new import_three26.Vector3(0, 0, 1);
|
|
13881
|
+
var CAMERA_POSITION = new import_three26.Vector3();
|
|
13522
13882
|
function applyHotspotTransform(group, camera, orientation2, surfaceQuaternion3, rotation, scaleMode, referenceFov, useAngularScale, worldWidth, worldHeight, distance) {
|
|
13523
13883
|
if (orientation2 === "billboard") {
|
|
13524
13884
|
group.quaternion.copy(camera.quaternion);
|
|
13525
13885
|
} else {
|
|
13526
13886
|
group.quaternion.copy(surfaceQuaternion3);
|
|
13527
13887
|
}
|
|
13528
|
-
group.rotateOnAxis(LOCAL_FORWARD,
|
|
13529
|
-
let scaleFactor = scaleMode === "fixed" && camera instanceof
|
|
13530
|
-
if (scaleMode === "fixed" && orientation2 === "billboard" && useAngularScale && camera instanceof
|
|
13888
|
+
group.rotateOnAxis(LOCAL_FORWARD, import_three26.MathUtils.degToRad(-rotation));
|
|
13889
|
+
let scaleFactor = scaleMode === "fixed" && camera instanceof import_three26.PerspectiveCamera ? fixedScaleFactor(camera.fov, referenceFov) : 1;
|
|
13890
|
+
if (scaleMode === "fixed" && orientation2 === "billboard" && useAngularScale && camera instanceof import_three26.PerspectiveCamera) {
|
|
13531
13891
|
group.updateWorldMatrix(true, false);
|
|
13532
13892
|
CAMERA_POSITION.setFromMatrixPosition(group.matrixWorld).applyMatrix4(
|
|
13533
13893
|
camera.matrixWorldInverse
|
|
@@ -13542,12 +13902,12 @@ function applyHotspotTransform(group, camera, orientation2, surfaceQuaternion3,
|
|
|
13542
13902
|
group.updateMatrixWorld();
|
|
13543
13903
|
}
|
|
13544
13904
|
function fixedScaleFactor(cameraFov, referenceFov) {
|
|
13545
|
-
const safeReferenceFov =
|
|
13546
|
-
return Math.tan(
|
|
13905
|
+
const safeReferenceFov = import_three26.MathUtils.clamp(referenceFov, 1, 179);
|
|
13906
|
+
return Math.tan(import_three26.MathUtils.degToRad(cameraFov) / 2) / Math.tan(import_three26.MathUtils.degToRad(safeReferenceFov) / 2);
|
|
13547
13907
|
}
|
|
13548
13908
|
|
|
13549
13909
|
// src/hotspot/hotspot-anchor.tsx
|
|
13550
|
-
var
|
|
13910
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
13551
13911
|
var DEFAULT_FLOATING_DISTANCE = 10;
|
|
13552
13912
|
var PANORAMA_RADIUS = DEFAULT_PANORAMA_RADIUS;
|
|
13553
13913
|
var PANORAMA_SURFACE_INSET = 4;
|
|
@@ -13555,27 +13915,27 @@ var DEFAULT_REFERENCE_FOV = 75;
|
|
|
13555
13915
|
var MIN_ANGULAR_SIZE = 0.01;
|
|
13556
13916
|
var MAX_ANGULAR_SIZE = 179;
|
|
13557
13917
|
var DRAG_EPSILON_DEGREES = 1e-3;
|
|
13558
|
-
var TOOLTIP_WORLD_BOX = new
|
|
13559
|
-
var TOOLTIP_LOCAL_BOX = new
|
|
13560
|
-
var TOOLTIP_CORNER = new
|
|
13561
|
-
var TOOLTIP_INVERSE = new
|
|
13562
|
-
var TOOLTIP_WORLD_CORNER = new
|
|
13563
|
-
var TOOLTIP_PROJECTED = new
|
|
13564
|
-
var TOOLTIP_RAY_ORIGIN = new
|
|
13565
|
-
var TOOLTIP_RAY_FAR = new
|
|
13566
|
-
var TOOLTIP_RAY_DIRECTION = new
|
|
13567
|
-
var TOOLTIP_RAY = new
|
|
13568
|
-
var TOOLTIP_PLANE = new
|
|
13569
|
-
var TOOLTIP_INTERSECTION = new
|
|
13570
|
-
var TOOLTIP_PLANE_NORMAL = new
|
|
13571
|
-
var TOOLTIP_PLANE_POINT = new
|
|
13918
|
+
var TOOLTIP_WORLD_BOX = new import_three27.Box3();
|
|
13919
|
+
var TOOLTIP_LOCAL_BOX = new import_three27.Box3();
|
|
13920
|
+
var TOOLTIP_CORNER = new import_three27.Vector3();
|
|
13921
|
+
var TOOLTIP_INVERSE = new import_three27.Matrix4();
|
|
13922
|
+
var TOOLTIP_WORLD_CORNER = new import_three27.Vector3();
|
|
13923
|
+
var TOOLTIP_PROJECTED = new import_three27.Vector3();
|
|
13924
|
+
var TOOLTIP_RAY_ORIGIN = new import_three27.Vector3();
|
|
13925
|
+
var TOOLTIP_RAY_FAR = new import_three27.Vector3();
|
|
13926
|
+
var TOOLTIP_RAY_DIRECTION = new import_three27.Vector3();
|
|
13927
|
+
var TOOLTIP_RAY = new import_three27.Ray();
|
|
13928
|
+
var TOOLTIP_PLANE = new import_three27.Plane();
|
|
13929
|
+
var TOOLTIP_INTERSECTION = new import_three27.Vector3();
|
|
13930
|
+
var TOOLTIP_PLANE_NORMAL = new import_three27.Vector3();
|
|
13931
|
+
var TOOLTIP_PLANE_POINT = new import_three27.Vector3();
|
|
13572
13932
|
var HOTSPOT_MODE_RENDERING = {
|
|
13573
13933
|
surface: { orientation: "surface", placement: "surface" },
|
|
13574
13934
|
billboard: { orientation: "billboard", placement: "floating" }
|
|
13575
13935
|
};
|
|
13576
13936
|
function angularSizeToWorldSize(size, radius) {
|
|
13577
|
-
const safeSize = Number.isFinite(size) ?
|
|
13578
|
-
return 2 * radius * Math.tan(
|
|
13937
|
+
const safeSize = Number.isFinite(size) ? import_three27.MathUtils.clamp(Math.abs(size), MIN_ANGULAR_SIZE, MAX_ANGULAR_SIZE) : MIN_ANGULAR_SIZE;
|
|
13938
|
+
return 2 * radius * Math.tan(import_three27.MathUtils.degToRad(safeSize) / 2);
|
|
13579
13939
|
}
|
|
13580
13940
|
function resolveScale(scale) {
|
|
13581
13941
|
return Number.isFinite(scale) && scale > 0 ? scale : 1;
|
|
@@ -13588,39 +13948,39 @@ function resolveDistance(placement, distance, width, height) {
|
|
|
13588
13948
|
if (!Number.isFinite(distance)) {
|
|
13589
13949
|
return DEFAULT_FLOATING_DISTANCE;
|
|
13590
13950
|
}
|
|
13591
|
-
return
|
|
13951
|
+
return import_three27.MathUtils.clamp(Math.abs(distance), 0.1, maximumDistance);
|
|
13592
13952
|
}
|
|
13593
13953
|
function maximumHotspotDistance(width, height) {
|
|
13594
|
-
const safeWidth =
|
|
13954
|
+
const safeWidth = import_three27.MathUtils.clamp(
|
|
13595
13955
|
Math.abs(Number.isFinite(width) ? width : MIN_ANGULAR_SIZE),
|
|
13596
13956
|
MIN_ANGULAR_SIZE,
|
|
13597
13957
|
MAX_ANGULAR_SIZE
|
|
13598
13958
|
);
|
|
13599
|
-
const safeHeight =
|
|
13959
|
+
const safeHeight = import_three27.MathUtils.clamp(
|
|
13600
13960
|
Math.abs(Number.isFinite(height) ? height : MIN_ANGULAR_SIZE),
|
|
13601
13961
|
MIN_ANGULAR_SIZE,
|
|
13602
13962
|
MAX_ANGULAR_SIZE
|
|
13603
13963
|
);
|
|
13604
13964
|
const cornerFactor = Math.hypot(
|
|
13605
13965
|
1,
|
|
13606
|
-
Math.tan(
|
|
13607
|
-
Math.tan(
|
|
13966
|
+
Math.tan(import_three27.MathUtils.degToRad(safeWidth) / 2),
|
|
13967
|
+
Math.tan(import_three27.MathUtils.degToRad(safeHeight) / 2)
|
|
13608
13968
|
);
|
|
13609
13969
|
return (PANORAMA_RADIUS - PANORAMA_SURFACE_INSET) / cornerFactor;
|
|
13610
13970
|
}
|
|
13611
13971
|
function createSurfaceQuaternion(position) {
|
|
13612
13972
|
const outward = panoPositionToVector3(position).normalize();
|
|
13613
13973
|
const inward = outward.clone().negate();
|
|
13614
|
-
const pitch =
|
|
13615
|
-
const yaw =
|
|
13616
|
-
const localUp = new
|
|
13974
|
+
const pitch = import_three27.MathUtils.degToRad(position.pitch);
|
|
13975
|
+
const yaw = import_three27.MathUtils.degToRad(position.yaw);
|
|
13976
|
+
const localUp = new import_three27.Vector3(
|
|
13617
13977
|
-Math.sin(pitch) * Math.sin(yaw),
|
|
13618
13978
|
Math.cos(pitch),
|
|
13619
13979
|
Math.sin(pitch) * Math.cos(yaw)
|
|
13620
13980
|
).normalize();
|
|
13621
13981
|
const localRight = localUp.clone().cross(inward).normalize();
|
|
13622
|
-
const basis = new
|
|
13623
|
-
return new
|
|
13982
|
+
const basis = new import_three27.Matrix4().makeBasis(localRight, localUp, inward);
|
|
13983
|
+
return new import_three27.Quaternion().setFromRotationMatrix(basis);
|
|
13624
13984
|
}
|
|
13625
13985
|
function makeInteractionEvent(id, position, event) {
|
|
13626
13986
|
return {
|
|
@@ -13633,7 +13993,7 @@ function makeInteractionEvent(id, position, event) {
|
|
|
13633
13993
|
function angularDistance(a, b) {
|
|
13634
13994
|
const aVector = panoPositionToVector3(a);
|
|
13635
13995
|
const bVector = panoPositionToVector3(b);
|
|
13636
|
-
return
|
|
13996
|
+
return import_three27.MathUtils.radToDeg(aVector.angleTo(bVector));
|
|
13637
13997
|
}
|
|
13638
13998
|
function isTooltipOpen(trigger, hovered, focused, pinned) {
|
|
13639
13999
|
switch (trigger) {
|
|
@@ -13864,24 +14224,24 @@ function HotspotAnchor({
|
|
|
13864
14224
|
onPositionChange,
|
|
13865
14225
|
onDragEnd
|
|
13866
14226
|
}) {
|
|
13867
|
-
const controlsRef = (0,
|
|
13868
|
-
const hotspotTargetRegistry = (0,
|
|
13869
|
-
const eventBus = (0,
|
|
14227
|
+
const controlsRef = (0, import_react50.useContext)(PanoramaViewContext);
|
|
14228
|
+
const hotspotTargetRegistry = (0, import_react50.useContext)(HotspotTargetRegistryContext);
|
|
14229
|
+
const eventBus = (0, import_react50.useContext)(PanoEventBusContext);
|
|
13870
14230
|
const cursorApi = usePanoCursor();
|
|
13871
|
-
const { camera, size } = (0,
|
|
13872
|
-
const groupRef = (0,
|
|
13873
|
-
const tooltipAnchorRef = (0,
|
|
13874
|
-
const dragStateRef = (0,
|
|
13875
|
-
const suppressNextClickRef = (0,
|
|
13876
|
-
const [hovered, setHovered] = (0,
|
|
13877
|
-
const [dragging, setDragging] = (0,
|
|
13878
|
-
const [pinned, setPinned] = (0,
|
|
13879
|
-
const tooltipContent = (0,
|
|
14231
|
+
const { camera, size } = (0, import_fiber25.useThree)();
|
|
14232
|
+
const groupRef = (0, import_react50.useRef)(null);
|
|
14233
|
+
const tooltipAnchorRef = (0, import_react50.useRef)(null);
|
|
14234
|
+
const dragStateRef = (0, import_react50.useRef)(null);
|
|
14235
|
+
const suppressNextClickRef = (0, import_react50.useRef)(false);
|
|
14236
|
+
const [hovered, setHovered] = (0, import_react50.useState)(false);
|
|
14237
|
+
const [dragging, setDragging] = (0, import_react50.useState)(false);
|
|
14238
|
+
const [pinned, setPinned] = (0, import_react50.useState)(false);
|
|
14239
|
+
const tooltipContent = (0, import_react50.useMemo)(
|
|
13880
14240
|
() => resolveHotspotTooltipContent(tooltip),
|
|
13881
14241
|
[tooltip]
|
|
13882
14242
|
);
|
|
13883
14243
|
const normalizedPosition = normalizePanoPosition(position);
|
|
13884
|
-
(0,
|
|
14244
|
+
(0, import_react50.useEffect)(() => {
|
|
13885
14245
|
if (!hotspotTargetRegistry) {
|
|
13886
14246
|
return;
|
|
13887
14247
|
}
|
|
@@ -13898,19 +14258,19 @@ function HotspotAnchor({
|
|
|
13898
14258
|
scaledWidth,
|
|
13899
14259
|
scaledHeight
|
|
13900
14260
|
);
|
|
13901
|
-
const worldPosition = (0,
|
|
14261
|
+
const worldPosition = (0, import_react50.useMemo)(
|
|
13902
14262
|
() => panoPositionToVector3(normalizedPosition, resolvedDistance),
|
|
13903
14263
|
[normalizedPosition.pitch, normalizedPosition.yaw, resolvedDistance]
|
|
13904
14264
|
);
|
|
13905
|
-
const surfaceQuaternion3 = (0,
|
|
14265
|
+
const surfaceQuaternion3 = (0, import_react50.useMemo)(
|
|
13906
14266
|
() => createSurfaceQuaternion(normalizedPosition),
|
|
13907
14267
|
[normalizedPosition.pitch, normalizedPosition.yaw]
|
|
13908
14268
|
);
|
|
13909
14269
|
const worldWidth = angularSizeToWorldSize(scaledWidth, resolvedDistance);
|
|
13910
14270
|
const worldHeight = angularSizeToWorldSize(scaledHeight, resolvedDistance);
|
|
13911
|
-
const focusGeometry = (0,
|
|
13912
|
-
const planeGeometry = new
|
|
13913
|
-
const geometry = new
|
|
14271
|
+
const focusGeometry = (0, import_react50.useMemo)(() => {
|
|
14272
|
+
const planeGeometry = new import_three27.PlaneGeometry(1, 1);
|
|
14273
|
+
const geometry = new import_three27.EdgesGeometry(planeGeometry);
|
|
13914
14274
|
planeGeometry.dispose();
|
|
13915
14275
|
return geometry;
|
|
13916
14276
|
}, []);
|
|
@@ -13935,14 +14295,14 @@ function HotspotAnchor({
|
|
|
13935
14295
|
});
|
|
13936
14296
|
const tooltipOpen = visible && tooltipContent !== null && isTooltipOpen(tooltipTrigger, hovered, focused, pinned);
|
|
13937
14297
|
const cursorClaimId = hotspotCursorClaimId(id);
|
|
13938
|
-
(0,
|
|
14298
|
+
(0, import_react50.useEffect)(
|
|
13939
14299
|
() => () => {
|
|
13940
14300
|
dragStateRef.current?.releaseInteractionLock();
|
|
13941
14301
|
dragStateRef.current = null;
|
|
13942
14302
|
},
|
|
13943
14303
|
[]
|
|
13944
14304
|
);
|
|
13945
|
-
(0,
|
|
14305
|
+
(0, import_react50.useEffect)(() => {
|
|
13946
14306
|
if (!cursorApi) {
|
|
13947
14307
|
return;
|
|
13948
14308
|
}
|
|
@@ -13964,14 +14324,14 @@ function HotspotAnchor({
|
|
|
13964
14324
|
hovered,
|
|
13965
14325
|
visible
|
|
13966
14326
|
]);
|
|
13967
|
-
(0,
|
|
14327
|
+
(0, import_react50.useEffect)(
|
|
13968
14328
|
() => () => {
|
|
13969
14329
|
cursorApi?.release(cursorClaimId);
|
|
13970
14330
|
},
|
|
13971
14331
|
[cursorApi, cursorClaimId]
|
|
13972
14332
|
);
|
|
13973
|
-
(0,
|
|
13974
|
-
(0,
|
|
14333
|
+
(0, import_react50.useEffect)(() => () => focusGeometry.dispose(), [focusGeometry]);
|
|
14334
|
+
(0, import_react50.useEffect)(() => {
|
|
13975
14335
|
if (tooltipTrigger !== "click") {
|
|
13976
14336
|
setPinned(false);
|
|
13977
14337
|
return;
|
|
@@ -13980,12 +14340,12 @@ function HotspotAnchor({
|
|
|
13980
14340
|
setPinned(false);
|
|
13981
14341
|
});
|
|
13982
14342
|
}, [eventBus, tooltipTrigger]);
|
|
13983
|
-
(0,
|
|
14343
|
+
(0, import_react50.useEffect)(() => {
|
|
13984
14344
|
if (tooltipTrigger !== "hover") {
|
|
13985
14345
|
setHovered(false);
|
|
13986
14346
|
}
|
|
13987
14347
|
}, [tooltipTrigger]);
|
|
13988
|
-
(0,
|
|
14348
|
+
(0, import_react50.useEffect)(() => {
|
|
13989
14349
|
if (acceptsPointer) {
|
|
13990
14350
|
return;
|
|
13991
14351
|
}
|
|
@@ -13998,7 +14358,7 @@ function HotspotAnchor({
|
|
|
13998
14358
|
dragStateRef.current = null;
|
|
13999
14359
|
setDragging(false);
|
|
14000
14360
|
}, [acceptsPointer]);
|
|
14001
|
-
(0,
|
|
14361
|
+
(0, import_react50.useLayoutEffect)(() => {
|
|
14002
14362
|
const group = groupRef.current;
|
|
14003
14363
|
if (!group) {
|
|
14004
14364
|
return;
|
|
@@ -14041,7 +14401,7 @@ function HotspotAnchor({
|
|
|
14041
14401
|
worldHeight,
|
|
14042
14402
|
worldWidth
|
|
14043
14403
|
]);
|
|
14044
|
-
(0,
|
|
14404
|
+
(0, import_fiber25.useFrame)((state) => {
|
|
14045
14405
|
const group = groupRef.current;
|
|
14046
14406
|
if (!group) {
|
|
14047
14407
|
return;
|
|
@@ -14100,7 +14460,7 @@ function HotspotAnchor({
|
|
|
14100
14460
|
setHovered(true);
|
|
14101
14461
|
}
|
|
14102
14462
|
};
|
|
14103
|
-
return /* @__PURE__ */ (0,
|
|
14463
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
14104
14464
|
"group",
|
|
14105
14465
|
{
|
|
14106
14466
|
ref: groupRef,
|
|
@@ -14177,18 +14537,18 @@ function HotspotAnchor({
|
|
|
14177
14537
|
} : void 0,
|
|
14178
14538
|
onPointerUp: acceptsPointer ? (event) => releasePointer(event, true) : void 0,
|
|
14179
14539
|
children: [
|
|
14180
|
-
focused ? focusContent ?? /* @__PURE__ */ (0,
|
|
14540
|
+
focused ? focusContent ?? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
14181
14541
|
"lineSegments",
|
|
14182
14542
|
{
|
|
14183
14543
|
geometry: focusGeometry,
|
|
14184
14544
|
position: [0, 0, 0.01],
|
|
14185
14545
|
renderOrder: renderOrder + 1,
|
|
14186
14546
|
scale: [1.12, 1.12, 1],
|
|
14187
|
-
children: /* @__PURE__ */ (0,
|
|
14547
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("lineBasicMaterial", { color: "#f5fbfc", depthTest: false })
|
|
14188
14548
|
}
|
|
14189
14549
|
) : null,
|
|
14190
14550
|
children,
|
|
14191
|
-
tooltipOpen && tooltipContent ? /* @__PURE__ */ (0,
|
|
14551
|
+
tooltipOpen && tooltipContent ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("group", { ref: tooltipAnchorRef, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
14192
14552
|
HotspotTooltip,
|
|
14193
14553
|
{
|
|
14194
14554
|
appearance: tooltipAppearance,
|
|
@@ -14203,10 +14563,10 @@ function HotspotAnchor({
|
|
|
14203
14563
|
}
|
|
14204
14564
|
|
|
14205
14565
|
// src/hotspot/hotspot-plane.tsx
|
|
14206
|
-
var
|
|
14207
|
-
var
|
|
14566
|
+
var import_three28 = require("three");
|
|
14567
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
14208
14568
|
var HOTSPOT_ALPHA_CUTOFF = 0.05;
|
|
14209
|
-
var SAMPLE_UV = new
|
|
14569
|
+
var SAMPLE_UV = new import_three28.Vector2();
|
|
14210
14570
|
var RAYCAST_HITS = [];
|
|
14211
14571
|
var IMAGE_DATA_CACHE = /* @__PURE__ */ new WeakMap();
|
|
14212
14572
|
function clampOpacity(opacity) {
|
|
@@ -14280,8 +14640,8 @@ function sampleTextureAlpha(texture, u, v) {
|
|
|
14280
14640
|
}
|
|
14281
14641
|
function hotspotPlaneRaycast(raycaster, intersects2) {
|
|
14282
14642
|
const material = Array.isArray(this.material) ? this.material[0] : this.material;
|
|
14283
|
-
if (!(material instanceof
|
|
14284
|
-
|
|
14643
|
+
if (!(material instanceof import_three28.MeshBasicMaterial)) {
|
|
14644
|
+
import_three28.Mesh.prototype.raycast.call(this, raycaster, intersects2);
|
|
14285
14645
|
return;
|
|
14286
14646
|
}
|
|
14287
14647
|
const cutoff = Math.max(material.alphaTest, HOTSPOT_ALPHA_CUTOFF);
|
|
@@ -14289,7 +14649,7 @@ function hotspotPlaneRaycast(raycaster, intersects2) {
|
|
|
14289
14649
|
return;
|
|
14290
14650
|
}
|
|
14291
14651
|
RAYCAST_HITS.length = 0;
|
|
14292
|
-
|
|
14652
|
+
import_three28.Mesh.prototype.raycast.call(this, raycaster, RAYCAST_HITS);
|
|
14293
14653
|
const map = material.map;
|
|
14294
14654
|
for (const hit of RAYCAST_HITS) {
|
|
14295
14655
|
if (!map || !hit.uv) {
|
|
@@ -14306,16 +14666,16 @@ function HotspotPlane({
|
|
|
14306
14666
|
map,
|
|
14307
14667
|
opacity
|
|
14308
14668
|
}) {
|
|
14309
|
-
return /* @__PURE__ */ (0,
|
|
14310
|
-
/* @__PURE__ */ (0,
|
|
14311
|
-
/* @__PURE__ */ (0,
|
|
14669
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("mesh", { raycast: hotspotPlaneRaycast, children: [
|
|
14670
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("planeGeometry", { args: [1, 1] }),
|
|
14671
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
14312
14672
|
PanoBasicMaterial,
|
|
14313
14673
|
{
|
|
14314
14674
|
target: "hotspot",
|
|
14315
14675
|
alphaTest: HOTSPOT_ALPHA_CUTOFF,
|
|
14316
14676
|
map,
|
|
14317
14677
|
opacity: map ? clampOpacity(opacity) : 0,
|
|
14318
|
-
side:
|
|
14678
|
+
side: import_three28.DoubleSide,
|
|
14319
14679
|
toneMapped: false,
|
|
14320
14680
|
transparent: true
|
|
14321
14681
|
}
|
|
@@ -14324,15 +14684,15 @@ function HotspotPlane({
|
|
|
14324
14684
|
}
|
|
14325
14685
|
|
|
14326
14686
|
// src/hotspot/image-hotspot.tsx
|
|
14327
|
-
var
|
|
14687
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
14328
14688
|
function useHotspotImageTexture(src, onLoad, onError) {
|
|
14329
|
-
const gl = (0,
|
|
14330
|
-
const [texture, setTexture] = (0,
|
|
14331
|
-
const onLoadRef = (0,
|
|
14332
|
-
const onErrorRef = (0,
|
|
14689
|
+
const gl = (0, import_fiber26.useThree)((state) => state.gl);
|
|
14690
|
+
const [texture, setTexture] = (0, import_react51.useState)(null);
|
|
14691
|
+
const onLoadRef = (0, import_react51.useRef)(onLoad);
|
|
14692
|
+
const onErrorRef = (0, import_react51.useRef)(onError);
|
|
14333
14693
|
onLoadRef.current = onLoad;
|
|
14334
14694
|
onErrorRef.current = onError;
|
|
14335
|
-
(0,
|
|
14695
|
+
(0, import_react51.useEffect)(() => {
|
|
14336
14696
|
let active = true;
|
|
14337
14697
|
setTexture(null);
|
|
14338
14698
|
if (!src) {
|
|
@@ -14340,7 +14700,7 @@ function useHotspotImageTexture(src, onLoad, onError) {
|
|
|
14340
14700
|
active = false;
|
|
14341
14701
|
};
|
|
14342
14702
|
}
|
|
14343
|
-
const loader = new
|
|
14703
|
+
const loader = new import_three29.TextureLoader();
|
|
14344
14704
|
loader.load(
|
|
14345
14705
|
src,
|
|
14346
14706
|
(loadedTexture) => {
|
|
@@ -14348,11 +14708,11 @@ function useHotspotImageTexture(src, onLoad, onError) {
|
|
|
14348
14708
|
loadedTexture.dispose();
|
|
14349
14709
|
return;
|
|
14350
14710
|
}
|
|
14351
|
-
loadedTexture.colorSpace =
|
|
14352
|
-
loadedTexture.wrapS =
|
|
14353
|
-
loadedTexture.wrapT =
|
|
14354
|
-
loadedTexture.magFilter =
|
|
14355
|
-
loadedTexture.minFilter =
|
|
14711
|
+
loadedTexture.colorSpace = import_three29.SRGBColorSpace;
|
|
14712
|
+
loadedTexture.wrapS = import_three29.ClampToEdgeWrapping;
|
|
14713
|
+
loadedTexture.wrapT = import_three29.ClampToEdgeWrapping;
|
|
14714
|
+
loadedTexture.magFilter = import_three29.LinearFilter;
|
|
14715
|
+
loadedTexture.minFilter = import_three29.LinearMipmapLinearFilter;
|
|
14356
14716
|
loadedTexture.generateMipmaps = true;
|
|
14357
14717
|
loadedTexture.anisotropy = gl.capabilities.getMaxAnisotropy();
|
|
14358
14718
|
loadedTexture.needsUpdate = true;
|
|
@@ -14370,7 +14730,7 @@ function useHotspotImageTexture(src, onLoad, onError) {
|
|
|
14370
14730
|
active = false;
|
|
14371
14731
|
};
|
|
14372
14732
|
}, [gl, src]);
|
|
14373
|
-
(0,
|
|
14733
|
+
(0, import_react51.useEffect)(
|
|
14374
14734
|
() => () => {
|
|
14375
14735
|
texture?.dispose();
|
|
14376
14736
|
},
|
|
@@ -14388,20 +14748,20 @@ function ImageHotspot({
|
|
|
14388
14748
|
...anchorProps
|
|
14389
14749
|
}) {
|
|
14390
14750
|
const texture = useHotspotImageTexture(src, onLoad, onError);
|
|
14391
|
-
return /* @__PURE__ */ (0,
|
|
14751
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(HotspotAnchor, { ...anchorProps, height, width, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(HotspotPlane, { map: texture, opacity }) });
|
|
14392
14752
|
}
|
|
14393
14753
|
|
|
14394
14754
|
// src/hotspot/polygon-hotspot.tsx
|
|
14395
|
-
var
|
|
14396
|
-
var
|
|
14755
|
+
var import_react53 = require("react");
|
|
14756
|
+
var import_three31 = require("three");
|
|
14397
14757
|
|
|
14398
14758
|
// src/hotspot/hotspot-stroke-line.tsx
|
|
14399
14759
|
var import_drei = require("@react-three/drei");
|
|
14400
|
-
var
|
|
14401
|
-
var
|
|
14402
|
-
var
|
|
14403
|
-
var
|
|
14404
|
-
var LINE_WORLD_POSITION = new
|
|
14760
|
+
var import_fiber27 = require("@react-three/fiber");
|
|
14761
|
+
var import_react52 = require("react");
|
|
14762
|
+
var import_three30 = require("three");
|
|
14763
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
14764
|
+
var LINE_WORLD_POSITION = new import_three30.Vector3();
|
|
14405
14765
|
function applyScreenSpaceDashScale(object, camera, viewportHeight) {
|
|
14406
14766
|
const material = object?.material;
|
|
14407
14767
|
if (!object || typeof material?.dashScale !== "number") {
|
|
@@ -14409,8 +14769,8 @@ function applyScreenSpaceDashScale(object, camera, viewportHeight) {
|
|
|
14409
14769
|
}
|
|
14410
14770
|
object.getWorldPosition(LINE_WORLD_POSITION);
|
|
14411
14771
|
const depth = Math.max(camera.position.distanceTo(LINE_WORLD_POSITION), 1);
|
|
14412
|
-
const fov = camera instanceof
|
|
14413
|
-
material.dashScale = viewportHeight / (2 * Math.tan(
|
|
14772
|
+
const fov = camera instanceof import_three30.PerspectiveCamera ? camera.fov : 75;
|
|
14773
|
+
material.dashScale = viewportHeight / (2 * Math.tan(import_three30.MathUtils.degToRad(fov) * 0.5) * depth);
|
|
14414
14774
|
}
|
|
14415
14775
|
function resolveDash(dashSize, gapSize) {
|
|
14416
14776
|
if (dashSize === void 0 || !Number.isFinite(dashSize) || dashSize <= 0) {
|
|
@@ -14431,22 +14791,22 @@ function HotspotStrokeLine({
|
|
|
14431
14791
|
dashSize,
|
|
14432
14792
|
gapSize
|
|
14433
14793
|
}) {
|
|
14434
|
-
const lineRef = (0,
|
|
14435
|
-
const { camera, size } = (0,
|
|
14794
|
+
const lineRef = (0, import_react52.useRef)(null);
|
|
14795
|
+
const { camera, size } = (0, import_fiber27.useThree)();
|
|
14436
14796
|
const dash = resolveDash(dashSize, gapSize);
|
|
14437
|
-
(0,
|
|
14797
|
+
(0, import_react52.useLayoutEffect)(() => {
|
|
14438
14798
|
if (!dash.dashed) {
|
|
14439
14799
|
return;
|
|
14440
14800
|
}
|
|
14441
14801
|
applyScreenSpaceDashScale(lineRef.current, camera, size.height);
|
|
14442
14802
|
}, [camera, dash.dashed, dash.dashSize, dash.gapSize, size.height]);
|
|
14443
|
-
(0,
|
|
14803
|
+
(0, import_fiber27.useFrame)((state) => {
|
|
14444
14804
|
if (!dash.dashed) {
|
|
14445
14805
|
return;
|
|
14446
14806
|
}
|
|
14447
14807
|
applyScreenSpaceDashScale(lineRef.current, state.camera, state.size.height);
|
|
14448
14808
|
});
|
|
14449
|
-
return /* @__PURE__ */ (0,
|
|
14809
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
14450
14810
|
import_drei.Line,
|
|
14451
14811
|
{
|
|
14452
14812
|
ref: lineRef,
|
|
@@ -14468,7 +14828,7 @@ function HotspotStrokeLine({
|
|
|
14468
14828
|
}
|
|
14469
14829
|
|
|
14470
14830
|
// src/hotspot/polygon-hotspot.tsx
|
|
14471
|
-
var
|
|
14831
|
+
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
14472
14832
|
var POLYGON_RADIUS = 990;
|
|
14473
14833
|
var MAX_FILL_SEGMENT_DEGREES = 7;
|
|
14474
14834
|
function cloneVertices(vertices) {
|
|
@@ -14503,7 +14863,7 @@ function intersects(a, b, c, d) {
|
|
|
14503
14863
|
}
|
|
14504
14864
|
function hasSelfIntersection(vertices) {
|
|
14505
14865
|
const points = vertices.map(
|
|
14506
|
-
(vertex) => new
|
|
14866
|
+
(vertex) => new import_three31.Vector2(vertex.unwrappedYaw, vertex.pitch)
|
|
14507
14867
|
);
|
|
14508
14868
|
for (let index = 0; index < points.length; index += 1) {
|
|
14509
14869
|
const nextIndex = (index + 1) % points.length;
|
|
@@ -14540,7 +14900,7 @@ function polygonContainsDirection(vertices, direction) {
|
|
|
14540
14900
|
}
|
|
14541
14901
|
function fitsHemisphere(vertices) {
|
|
14542
14902
|
const directions = vertices.map((vertex) => panoPositionToVector3(vertex).normalize());
|
|
14543
|
-
const candidates = [new
|
|
14903
|
+
const candidates = [new import_three31.Vector3()];
|
|
14544
14904
|
for (const direction of directions) {
|
|
14545
14905
|
candidates[0].add(direction);
|
|
14546
14906
|
candidates.push(direction.clone());
|
|
@@ -14564,7 +14924,7 @@ function validatePolygonVertices(vertices) {
|
|
|
14564
14924
|
if (hasSelfIntersection(unwrapped)) {
|
|
14565
14925
|
issues.push({ code: "self_intersection", message: "Polygon edges cannot cross." });
|
|
14566
14926
|
}
|
|
14567
|
-
if (polygonContainsDirection(normalized, new
|
|
14927
|
+
if (polygonContainsDirection(normalized, new import_three31.Vector3(0, 1, 0)) || polygonContainsDirection(normalized, new import_three31.Vector3(0, -1, 0))) {
|
|
14568
14928
|
issues.push({ code: "contains_pole", message: "Polygons cannot contain a panorama pole." });
|
|
14569
14929
|
}
|
|
14570
14930
|
if (!fitsHemisphere(normalized)) {
|
|
@@ -14575,7 +14935,7 @@ function validatePolygonVertices(vertices) {
|
|
|
14575
14935
|
function polygonCenter(vertices) {
|
|
14576
14936
|
const sum = vertices.reduce(
|
|
14577
14937
|
(total, vertex) => total.add(panoPositionToVector3(vertex).normalize()),
|
|
14578
|
-
new
|
|
14938
|
+
new import_three31.Vector3()
|
|
14579
14939
|
);
|
|
14580
14940
|
return sum.lengthSq() > 1e-8 ? vector3ToPanoPosition(sum) : normalizePanoPosition(vertices[0]);
|
|
14581
14941
|
}
|
|
@@ -14584,20 +14944,20 @@ function surfaceQuaternion(position) {
|
|
|
14584
14944
|
const inward = outward.clone().negate();
|
|
14585
14945
|
const pitch = position.pitch * Math.PI / 180;
|
|
14586
14946
|
const yaw = position.yaw * Math.PI / 180;
|
|
14587
|
-
const localUp = new
|
|
14947
|
+
const localUp = new import_three31.Vector3(
|
|
14588
14948
|
-Math.sin(pitch) * Math.sin(yaw),
|
|
14589
14949
|
Math.cos(pitch),
|
|
14590
14950
|
Math.sin(pitch) * Math.cos(yaw)
|
|
14591
14951
|
).normalize();
|
|
14592
|
-
return new
|
|
14593
|
-
new
|
|
14952
|
+
return new import_three31.Quaternion().setFromRotationMatrix(
|
|
14953
|
+
new import_three31.Matrix4().makeBasis(localUp.clone().cross(inward).normalize(), localUp, inward)
|
|
14594
14954
|
);
|
|
14595
14955
|
}
|
|
14596
14956
|
function makeWorldToLocal(center) {
|
|
14597
|
-
return new
|
|
14957
|
+
return new import_three31.Matrix4().compose(
|
|
14598
14958
|
panoPositionToVector3(center, POLYGON_RADIUS),
|
|
14599
14959
|
surfaceQuaternion(center),
|
|
14600
|
-
new
|
|
14960
|
+
new import_three31.Vector3(1, 1, 1)
|
|
14601
14961
|
).invert();
|
|
14602
14962
|
}
|
|
14603
14963
|
function projectedPoint(a, b, c, weightB, weightC, radius, worldToLocal) {
|
|
@@ -14652,8 +15012,8 @@ function addSubdividedTriangle(positions, indices, a, b, c, worldToLocal, steps)
|
|
|
14652
15012
|
}
|
|
14653
15013
|
function makeFillGeometry(vertices, center) {
|
|
14654
15014
|
const unwrapped = unwrapPolygonVertices(vertices);
|
|
14655
|
-
const contour = unwrapped.map((vertex) => new
|
|
14656
|
-
const triangles =
|
|
15015
|
+
const contour = unwrapped.map((vertex) => new import_three31.Vector2(vertex.unwrappedYaw, vertex.pitch));
|
|
15016
|
+
const triangles = import_three31.ShapeUtils.triangulateShape(contour, []);
|
|
14657
15017
|
const positions = [];
|
|
14658
15018
|
const indices = [];
|
|
14659
15019
|
const worldToLocal = makeWorldToLocal(center);
|
|
@@ -14669,7 +15029,7 @@ function makeFillGeometry(vertices, center) {
|
|
|
14669
15029
|
steps
|
|
14670
15030
|
);
|
|
14671
15031
|
}
|
|
14672
|
-
return new
|
|
15032
|
+
return new import_three31.BufferGeometry().setAttribute("position", new import_three31.Float32BufferAttribute(positions, 3)).setIndex(indices);
|
|
14673
15033
|
}
|
|
14674
15034
|
function makeStrokePositions(vertices, center) {
|
|
14675
15035
|
const points = [];
|
|
@@ -14724,24 +15084,24 @@ function PolygonHotspot({
|
|
|
14724
15084
|
onInvalid,
|
|
14725
15085
|
...anchorProps
|
|
14726
15086
|
}) {
|
|
14727
|
-
const issues = (0,
|
|
15087
|
+
const issues = (0, import_react53.useMemo)(() => validatePolygonVertices(vertices), [vertices]);
|
|
14728
15088
|
const valid = issues.length === 0;
|
|
14729
|
-
const center = (0,
|
|
14730
|
-
const fillGeometry = (0,
|
|
15089
|
+
const center = (0, import_react53.useMemo)(() => valid ? polygonCenter(vertices) : null, [valid, vertices]);
|
|
15090
|
+
const fillGeometry = (0, import_react53.useMemo)(
|
|
14731
15091
|
() => valid && center ? makeFillGeometry(vertices, center) : null,
|
|
14732
15092
|
[center, valid, vertices]
|
|
14733
15093
|
);
|
|
14734
|
-
const strokePoints = (0,
|
|
15094
|
+
const strokePoints = (0, import_react53.useMemo)(
|
|
14735
15095
|
() => valid && center ? makeStrokePositions(vertices, center) : null,
|
|
14736
15096
|
[center, valid, vertices]
|
|
14737
15097
|
);
|
|
14738
15098
|
const resolvedStrokeOpacity = Math.max(0, Math.min(strokeOpacity, 1));
|
|
14739
|
-
const startVerticesRef = (0,
|
|
15099
|
+
const startVerticesRef = (0, import_react53.useRef)(null);
|
|
14740
15100
|
const issuesKey = issues.map((issue) => issue.code).join(",");
|
|
14741
|
-
(0,
|
|
15101
|
+
(0, import_react53.useEffect)(() => {
|
|
14742
15102
|
if (!valid) onInvalid?.(issues);
|
|
14743
15103
|
}, [issues, issuesKey, onInvalid, valid]);
|
|
14744
|
-
(0,
|
|
15104
|
+
(0, import_react53.useEffect)(() => () => fillGeometry?.dispose(), [fillGeometry]);
|
|
14745
15105
|
if (!valid || !center || !fillGeometry || !strokePoints || strokePoints.length < 2) {
|
|
14746
15106
|
return null;
|
|
14747
15107
|
}
|
|
@@ -14756,7 +15116,7 @@ function PolygonHotspot({
|
|
|
14756
15116
|
startPosition: event.startPosition
|
|
14757
15117
|
});
|
|
14758
15118
|
};
|
|
14759
|
-
return /* @__PURE__ */ (0,
|
|
15119
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
|
|
14760
15120
|
HotspotAnchor,
|
|
14761
15121
|
{
|
|
14762
15122
|
...anchorProps,
|
|
@@ -14771,7 +15131,7 @@ function PolygonHotspot({
|
|
|
14771
15131
|
draggable,
|
|
14772
15132
|
interactive,
|
|
14773
15133
|
useAngularScale: false,
|
|
14774
|
-
focusContent: /* @__PURE__ */ (0,
|
|
15134
|
+
focusContent: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
14775
15135
|
HotspotStrokeLine,
|
|
14776
15136
|
{
|
|
14777
15137
|
color: "#75cbd3",
|
|
@@ -14793,17 +15153,17 @@ function PolygonHotspot({
|
|
|
14793
15153
|
startVerticesRef.current = null;
|
|
14794
15154
|
},
|
|
14795
15155
|
children: [
|
|
14796
|
-
/* @__PURE__ */ (0,
|
|
15156
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("mesh", { geometry: fillGeometry, renderOrder, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
14797
15157
|
"meshBasicMaterial",
|
|
14798
15158
|
{
|
|
14799
15159
|
color: fill,
|
|
14800
15160
|
depthWrite: false,
|
|
14801
15161
|
opacity: Math.max(0, Math.min(fillOpacity, 1)),
|
|
14802
|
-
side:
|
|
15162
|
+
side: import_three31.DoubleSide,
|
|
14803
15163
|
transparent: true
|
|
14804
15164
|
}
|
|
14805
15165
|
) }),
|
|
14806
|
-
/* @__PURE__ */ (0,
|
|
15166
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
14807
15167
|
HotspotStrokeLine,
|
|
14808
15168
|
{
|
|
14809
15169
|
color: stroke,
|
|
@@ -14821,9 +15181,9 @@ function PolygonHotspot({
|
|
|
14821
15181
|
}
|
|
14822
15182
|
|
|
14823
15183
|
// src/hotspot/polyline-hotspot.tsx
|
|
14824
|
-
var
|
|
14825
|
-
var
|
|
14826
|
-
var
|
|
15184
|
+
var import_react54 = require("react");
|
|
15185
|
+
var import_three32 = require("three");
|
|
15186
|
+
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
14827
15187
|
var POLYLINE_RADIUS = 990;
|
|
14828
15188
|
var MAX_SEGMENT_DEGREES = 7;
|
|
14829
15189
|
function cloneVertices2(vertices) {
|
|
@@ -14848,29 +15208,29 @@ function unwrapVertices(vertices) {
|
|
|
14848
15208
|
function polylineCenter(vertices) {
|
|
14849
15209
|
const sum = vertices.reduce(
|
|
14850
15210
|
(total, vertex) => total.add(panoPositionToVector3(vertex).normalize()),
|
|
14851
|
-
new
|
|
15211
|
+
new import_three32.Vector3()
|
|
14852
15212
|
);
|
|
14853
15213
|
return sum.lengthSq() > 1e-8 ? vector3ToPanoPosition(sum) : normalizePanoPosition(vertices[0]);
|
|
14854
15214
|
}
|
|
14855
15215
|
function surfaceQuaternion2(position) {
|
|
14856
15216
|
const outward = panoPositionToVector3(position).normalize();
|
|
14857
15217
|
const inward = outward.clone().negate();
|
|
14858
|
-
const pitch =
|
|
14859
|
-
const yaw =
|
|
14860
|
-
const localUp = new
|
|
15218
|
+
const pitch = import_three32.MathUtils.degToRad(position.pitch);
|
|
15219
|
+
const yaw = import_three32.MathUtils.degToRad(position.yaw);
|
|
15220
|
+
const localUp = new import_three32.Vector3(
|
|
14861
15221
|
-Math.sin(pitch) * Math.sin(yaw),
|
|
14862
15222
|
Math.cos(pitch),
|
|
14863
15223
|
Math.sin(pitch) * Math.cos(yaw)
|
|
14864
15224
|
).normalize();
|
|
14865
|
-
return new
|
|
14866
|
-
new
|
|
15225
|
+
return new import_three32.Quaternion().setFromRotationMatrix(
|
|
15226
|
+
new import_three32.Matrix4().makeBasis(localUp.clone().cross(inward).normalize(), localUp, inward)
|
|
14867
15227
|
);
|
|
14868
15228
|
}
|
|
14869
15229
|
function makeWorldToLocal2(center) {
|
|
14870
|
-
return new
|
|
15230
|
+
return new import_three32.Matrix4().compose(
|
|
14871
15231
|
panoPositionToVector3(center, POLYLINE_RADIUS),
|
|
14872
15232
|
surfaceQuaternion2(center),
|
|
14873
|
-
new
|
|
15233
|
+
new import_three32.Vector3(1, 1, 1)
|
|
14874
15234
|
).invert();
|
|
14875
15235
|
}
|
|
14876
15236
|
function subdivisionSteps(vertices) {
|
|
@@ -14885,7 +15245,7 @@ function subdivisionSteps(vertices) {
|
|
|
14885
15245
|
}
|
|
14886
15246
|
return Math.min(
|
|
14887
15247
|
8,
|
|
14888
|
-
Math.max(1, Math.ceil(
|
|
15248
|
+
Math.max(1, Math.ceil(import_three32.MathUtils.radToDeg(maxAngle) / MAX_SEGMENT_DEGREES))
|
|
14889
15249
|
);
|
|
14890
15250
|
}
|
|
14891
15251
|
function makeLinePositions(vertices, center) {
|
|
@@ -14940,16 +15300,16 @@ function PolylineHotspot({
|
|
|
14940
15300
|
onInvalid,
|
|
14941
15301
|
...anchorProps
|
|
14942
15302
|
}) {
|
|
14943
|
-
const issues = (0,
|
|
15303
|
+
const issues = (0, import_react54.useMemo)(() => validatePolylineVertices(vertices), [vertices]);
|
|
14944
15304
|
const valid = issues.length === 0;
|
|
14945
|
-
const center = (0,
|
|
14946
|
-
const linePoints = (0,
|
|
15305
|
+
const center = (0, import_react54.useMemo)(() => valid ? polylineCenter(vertices) : null, [valid, vertices]);
|
|
15306
|
+
const linePoints = (0, import_react54.useMemo)(
|
|
14947
15307
|
() => valid && center ? makeLinePositions(vertices, center) : null,
|
|
14948
15308
|
[center, valid, vertices]
|
|
14949
15309
|
);
|
|
14950
15310
|
const opacity = Math.max(0, Math.min(strokeOpacity, 1));
|
|
14951
|
-
const startVerticesRef = (0,
|
|
14952
|
-
(0,
|
|
15311
|
+
const startVerticesRef = (0, import_react54.useRef)(null);
|
|
15312
|
+
(0, import_react54.useEffect)(() => {
|
|
14953
15313
|
if (!valid) onInvalid?.(issues);
|
|
14954
15314
|
}, [issues, onInvalid, valid]);
|
|
14955
15315
|
if (!valid || !center || !linePoints || linePoints.length < 2) return null;
|
|
@@ -14963,7 +15323,7 @@ function PolylineHotspot({
|
|
|
14963
15323
|
startPosition: event.startPosition
|
|
14964
15324
|
});
|
|
14965
15325
|
};
|
|
14966
|
-
return /* @__PURE__ */ (0,
|
|
15326
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
14967
15327
|
HotspotAnchor,
|
|
14968
15328
|
{
|
|
14969
15329
|
...anchorProps,
|
|
@@ -14977,7 +15337,7 @@ function PolylineHotspot({
|
|
|
14977
15337
|
renderOrder,
|
|
14978
15338
|
draggable,
|
|
14979
15339
|
useAngularScale: false,
|
|
14980
|
-
focusContent: /* @__PURE__ */ (0,
|
|
15340
|
+
focusContent: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
14981
15341
|
HotspotStrokeLine,
|
|
14982
15342
|
{
|
|
14983
15343
|
color: "#75cbd3",
|
|
@@ -14998,7 +15358,7 @@ function PolylineHotspot({
|
|
|
14998
15358
|
emitVerticesChange(event, onDragEnd);
|
|
14999
15359
|
startVerticesRef.current = null;
|
|
15000
15360
|
},
|
|
15001
|
-
children: /* @__PURE__ */ (0,
|
|
15361
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
15002
15362
|
HotspotStrokeLine,
|
|
15003
15363
|
{
|
|
15004
15364
|
color: stroke,
|
|
@@ -15015,9 +15375,9 @@ function PolylineHotspot({
|
|
|
15015
15375
|
}
|
|
15016
15376
|
|
|
15017
15377
|
// src/hotspot/graphic-hotspot.tsx
|
|
15018
|
-
var
|
|
15019
|
-
var
|
|
15020
|
-
var
|
|
15378
|
+
var import_react55 = require("react");
|
|
15379
|
+
var import_three33 = require("three");
|
|
15380
|
+
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
15021
15381
|
var GRAPHIC_TEXTURE_SIZE = 512;
|
|
15022
15382
|
function resolveStrokeWidth(value) {
|
|
15023
15383
|
return Number.isFinite(value) ? Math.max(value, 0) : 8;
|
|
@@ -15195,23 +15555,23 @@ function createGraphicTexture(graphic, aspectWidth, aspectHeight) {
|
|
|
15195
15555
|
throw new Error("Canvas 2D is unavailable for this graphic hotspot.");
|
|
15196
15556
|
}
|
|
15197
15557
|
drawGraphic(context, graphic, aspectWidth, aspectHeight);
|
|
15198
|
-
const texture = new
|
|
15199
|
-
texture.colorSpace =
|
|
15200
|
-
texture.wrapS =
|
|
15201
|
-
texture.wrapT =
|
|
15202
|
-
texture.magFilter =
|
|
15203
|
-
texture.minFilter =
|
|
15558
|
+
const texture = new import_three33.CanvasTexture(canvas);
|
|
15559
|
+
texture.colorSpace = import_three33.SRGBColorSpace;
|
|
15560
|
+
texture.wrapS = import_three33.ClampToEdgeWrapping;
|
|
15561
|
+
texture.wrapT = import_three33.ClampToEdgeWrapping;
|
|
15562
|
+
texture.magFilter = import_three33.LinearFilter;
|
|
15563
|
+
texture.minFilter = import_three33.LinearMipmapLinearFilter;
|
|
15204
15564
|
texture.generateMipmaps = true;
|
|
15205
15565
|
texture.needsUpdate = true;
|
|
15206
15566
|
return texture;
|
|
15207
15567
|
}
|
|
15208
15568
|
function useGraphicTexture(graphic, aspectWidth, aspectHeight, onLoad, onError) {
|
|
15209
|
-
const [texture, setTexture] = (0,
|
|
15210
|
-
const onLoadRef = (0,
|
|
15211
|
-
const onErrorRef = (0,
|
|
15569
|
+
const [texture, setTexture] = (0, import_react55.useState)(null);
|
|
15570
|
+
const onLoadRef = (0, import_react55.useRef)(onLoad);
|
|
15571
|
+
const onErrorRef = (0, import_react55.useRef)(onError);
|
|
15212
15572
|
onLoadRef.current = onLoad;
|
|
15213
15573
|
onErrorRef.current = onError;
|
|
15214
|
-
(0,
|
|
15574
|
+
(0, import_react55.useEffect)(() => {
|
|
15215
15575
|
let nextTexture = null;
|
|
15216
15576
|
try {
|
|
15217
15577
|
nextTexture = createGraphicTexture(graphic, aspectWidth, aspectHeight);
|
|
@@ -15237,22 +15597,22 @@ function CanvasGraphicHotspot({
|
|
|
15237
15597
|
...anchorProps
|
|
15238
15598
|
}) {
|
|
15239
15599
|
const texture = useGraphicTexture(graphic, width, height, onLoad, onError);
|
|
15240
|
-
return /* @__PURE__ */ (0,
|
|
15600
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(HotspotAnchor, { ...anchorProps, height, width, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(HotspotPlane, { map: texture, opacity }) });
|
|
15241
15601
|
}
|
|
15242
15602
|
function GraphicHotspot(props) {
|
|
15243
15603
|
const { graphic, ...restProps } = props;
|
|
15244
15604
|
if (graphic.kind === "svg") {
|
|
15245
15605
|
const imageProps = restProps;
|
|
15246
|
-
return /* @__PURE__ */ (0,
|
|
15606
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ImageHotspot, { ...imageProps, src: graphic.src });
|
|
15247
15607
|
}
|
|
15248
|
-
return /* @__PURE__ */ (0,
|
|
15608
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(CanvasGraphicHotspot, { ...restProps, graphic });
|
|
15249
15609
|
}
|
|
15250
15610
|
|
|
15251
15611
|
// src/hotspot/sequence-hotspot.tsx
|
|
15252
|
-
var
|
|
15253
|
-
var
|
|
15254
|
-
var
|
|
15255
|
-
var
|
|
15612
|
+
var import_fiber28 = require("@react-three/fiber");
|
|
15613
|
+
var import_react56 = require("react");
|
|
15614
|
+
var import_three34 = require("three");
|
|
15615
|
+
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
15256
15616
|
var DEFAULT_SEQUENCE_FPS = 12;
|
|
15257
15617
|
function resolveFps(value) {
|
|
15258
15618
|
return Number.isFinite(value) && value > 0 ? value : DEFAULT_SEQUENCE_FPS;
|
|
@@ -15266,13 +15626,13 @@ function useSpriteTexture({
|
|
|
15266
15626
|
onError,
|
|
15267
15627
|
onLoadProgress
|
|
15268
15628
|
}) {
|
|
15269
|
-
const gl = (0,
|
|
15270
|
-
const [texture, setTexture] = (0,
|
|
15271
|
-
const onErrorRef = (0,
|
|
15272
|
-
const onLoadProgressRef = (0,
|
|
15629
|
+
const gl = (0, import_fiber28.useThree)((state) => state.gl);
|
|
15630
|
+
const [texture, setTexture] = (0, import_react56.useState)(null);
|
|
15631
|
+
const onErrorRef = (0, import_react56.useRef)(onError);
|
|
15632
|
+
const onLoadProgressRef = (0, import_react56.useRef)(onLoadProgress);
|
|
15273
15633
|
onErrorRef.current = onError;
|
|
15274
15634
|
onLoadProgressRef.current = onLoadProgress;
|
|
15275
|
-
(0,
|
|
15635
|
+
(0, import_react56.useEffect)(() => {
|
|
15276
15636
|
let active = true;
|
|
15277
15637
|
setTexture(null);
|
|
15278
15638
|
if (!src) {
|
|
@@ -15281,7 +15641,7 @@ function useSpriteTexture({
|
|
|
15281
15641
|
active = false;
|
|
15282
15642
|
};
|
|
15283
15643
|
}
|
|
15284
|
-
const loader = new
|
|
15644
|
+
const loader = new import_three34.TextureLoader();
|
|
15285
15645
|
loader.load(
|
|
15286
15646
|
src,
|
|
15287
15647
|
(loadedTexture) => {
|
|
@@ -15289,11 +15649,11 @@ function useSpriteTexture({
|
|
|
15289
15649
|
loadedTexture.dispose();
|
|
15290
15650
|
return;
|
|
15291
15651
|
}
|
|
15292
|
-
loadedTexture.colorSpace =
|
|
15293
|
-
loadedTexture.wrapS =
|
|
15294
|
-
loadedTexture.wrapT =
|
|
15295
|
-
loadedTexture.magFilter =
|
|
15296
|
-
loadedTexture.minFilter =
|
|
15652
|
+
loadedTexture.colorSpace = import_three34.SRGBColorSpace;
|
|
15653
|
+
loadedTexture.wrapS = import_three34.ClampToEdgeWrapping;
|
|
15654
|
+
loadedTexture.wrapT = import_three34.ClampToEdgeWrapping;
|
|
15655
|
+
loadedTexture.magFilter = import_three34.LinearFilter;
|
|
15656
|
+
loadedTexture.minFilter = import_three34.LinearMipmapLinearFilter;
|
|
15297
15657
|
loadedTexture.generateMipmaps = true;
|
|
15298
15658
|
loadedTexture.anisotropy = gl.capabilities.getMaxAnisotropy();
|
|
15299
15659
|
loadedTexture.needsUpdate = true;
|
|
@@ -15313,7 +15673,7 @@ function useSpriteTexture({
|
|
|
15313
15673
|
active = false;
|
|
15314
15674
|
};
|
|
15315
15675
|
}, [gl, id, src]);
|
|
15316
|
-
(0,
|
|
15676
|
+
(0, import_react56.useEffect)(
|
|
15317
15677
|
() => () => {
|
|
15318
15678
|
texture?.dispose();
|
|
15319
15679
|
},
|
|
@@ -15342,24 +15702,24 @@ function SequenceHotspot({
|
|
|
15342
15702
|
const texture = useSpriteTexture({ id, src, onError, onLoadProgress });
|
|
15343
15703
|
const frameCount = resolveFrameCount(requestedFrameCount);
|
|
15344
15704
|
const safeFps = resolveFps(fps);
|
|
15345
|
-
const [frameIndex, setFrameIndex] = (0,
|
|
15346
|
-
const elapsedRef = (0,
|
|
15347
|
-
const frameIndexRef = (0,
|
|
15348
|
-
const endedRef = (0,
|
|
15349
|
-
const lastPlaybackStateRef = (0,
|
|
15350
|
-
const onFrameChangeRef = (0,
|
|
15351
|
-
const onPlaybackStateChangeRef = (0,
|
|
15352
|
-
const onEndedRef = (0,
|
|
15705
|
+
const [frameIndex, setFrameIndex] = (0, import_react56.useState)(0);
|
|
15706
|
+
const elapsedRef = (0, import_react56.useRef)(0);
|
|
15707
|
+
const frameIndexRef = (0, import_react56.useRef)(0);
|
|
15708
|
+
const endedRef = (0, import_react56.useRef)(false);
|
|
15709
|
+
const lastPlaybackStateRef = (0, import_react56.useRef)(null);
|
|
15710
|
+
const onFrameChangeRef = (0, import_react56.useRef)(onFrameChange);
|
|
15711
|
+
const onPlaybackStateChangeRef = (0, import_react56.useRef)(onPlaybackStateChange);
|
|
15712
|
+
const onEndedRef = (0, import_react56.useRef)(onEnded);
|
|
15353
15713
|
onFrameChangeRef.current = onFrameChange;
|
|
15354
15714
|
onPlaybackStateChangeRef.current = onPlaybackStateChange;
|
|
15355
15715
|
onEndedRef.current = onEnded;
|
|
15356
|
-
(0,
|
|
15716
|
+
(0, import_react56.useEffect)(() => {
|
|
15357
15717
|
elapsedRef.current = 0;
|
|
15358
15718
|
frameIndexRef.current = 0;
|
|
15359
15719
|
endedRef.current = false;
|
|
15360
15720
|
setFrameIndex(0);
|
|
15361
15721
|
}, [frameCount, frameDirection, src]);
|
|
15362
|
-
(0,
|
|
15722
|
+
(0, import_react56.useEffect)(() => {
|
|
15363
15723
|
if (!texture) {
|
|
15364
15724
|
return;
|
|
15365
15725
|
}
|
|
@@ -15373,13 +15733,13 @@ function SequenceHotspot({
|
|
|
15373
15733
|
);
|
|
15374
15734
|
texture.needsUpdate = true;
|
|
15375
15735
|
}, [frameCount, frameDirection, frameIndex, texture]);
|
|
15376
|
-
(0,
|
|
15736
|
+
(0, import_react56.useEffect)(() => {
|
|
15377
15737
|
if (!texture) {
|
|
15378
15738
|
return;
|
|
15379
15739
|
}
|
|
15380
15740
|
onFrameChangeRef.current?.({ id, index: 0, src });
|
|
15381
15741
|
}, [id, src, texture]);
|
|
15382
|
-
(0,
|
|
15742
|
+
(0, import_react56.useEffect)(() => {
|
|
15383
15743
|
if (!texture) {
|
|
15384
15744
|
return;
|
|
15385
15745
|
}
|
|
@@ -15398,7 +15758,7 @@ function SequenceHotspot({
|
|
|
15398
15758
|
onPlaybackStateChangeRef.current?.(nextState);
|
|
15399
15759
|
}
|
|
15400
15760
|
}, [playing, texture]);
|
|
15401
|
-
(0,
|
|
15761
|
+
(0, import_fiber28.useFrame)((_, deltaSeconds) => {
|
|
15402
15762
|
if (!texture || !playing || endedRef.current) {
|
|
15403
15763
|
return;
|
|
15404
15764
|
}
|
|
@@ -15428,14 +15788,14 @@ function SequenceHotspot({
|
|
|
15428
15788
|
onFrameChangeRef.current?.({ id, index: nextIndex, src });
|
|
15429
15789
|
}
|
|
15430
15790
|
});
|
|
15431
|
-
return /* @__PURE__ */ (0,
|
|
15791
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(HotspotAnchor, { ...anchorProps, id, height, width, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(HotspotPlane, { map: texture, opacity }) });
|
|
15432
15792
|
}
|
|
15433
15793
|
|
|
15434
15794
|
// src/hotspot/video-hotspot.tsx
|
|
15435
|
-
var
|
|
15436
|
-
var
|
|
15437
|
-
var
|
|
15438
|
-
var
|
|
15795
|
+
var import_fiber29 = require("@react-three/fiber");
|
|
15796
|
+
var import_react57 = require("react");
|
|
15797
|
+
var import_three35 = require("three");
|
|
15798
|
+
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
15439
15799
|
function clampVolume2(volume) {
|
|
15440
15800
|
if (!Number.isFinite(volume)) {
|
|
15441
15801
|
return 1;
|
|
@@ -15443,11 +15803,11 @@ function clampVolume2(volume) {
|
|
|
15443
15803
|
return Math.max(0, Math.min(volume, 1));
|
|
15444
15804
|
}
|
|
15445
15805
|
function usePosterTexture2(id, poster, onError) {
|
|
15446
|
-
const gl = (0,
|
|
15447
|
-
const [texture, setTexture] = (0,
|
|
15448
|
-
const onErrorRef = (0,
|
|
15806
|
+
const gl = (0, import_fiber29.useThree)((state) => state.gl);
|
|
15807
|
+
const [texture, setTexture] = (0, import_react57.useState)(null);
|
|
15808
|
+
const onErrorRef = (0, import_react57.useRef)(onError);
|
|
15449
15809
|
onErrorRef.current = onError;
|
|
15450
|
-
(0,
|
|
15810
|
+
(0, import_react57.useEffect)(() => {
|
|
15451
15811
|
let active = true;
|
|
15452
15812
|
setTexture(null);
|
|
15453
15813
|
if (!poster) {
|
|
@@ -15455,7 +15815,7 @@ function usePosterTexture2(id, poster, onError) {
|
|
|
15455
15815
|
active = false;
|
|
15456
15816
|
};
|
|
15457
15817
|
}
|
|
15458
|
-
const loader = new
|
|
15818
|
+
const loader = new import_three35.TextureLoader();
|
|
15459
15819
|
loader.load(
|
|
15460
15820
|
poster,
|
|
15461
15821
|
(loadedTexture) => {
|
|
@@ -15463,11 +15823,11 @@ function usePosterTexture2(id, poster, onError) {
|
|
|
15463
15823
|
loadedTexture.dispose();
|
|
15464
15824
|
return;
|
|
15465
15825
|
}
|
|
15466
|
-
loadedTexture.colorSpace =
|
|
15467
|
-
loadedTexture.wrapS =
|
|
15468
|
-
loadedTexture.wrapT =
|
|
15469
|
-
loadedTexture.magFilter =
|
|
15470
|
-
loadedTexture.minFilter =
|
|
15826
|
+
loadedTexture.colorSpace = import_three35.SRGBColorSpace;
|
|
15827
|
+
loadedTexture.wrapS = import_three35.ClampToEdgeWrapping;
|
|
15828
|
+
loadedTexture.wrapT = import_three35.ClampToEdgeWrapping;
|
|
15829
|
+
loadedTexture.magFilter = import_three35.LinearFilter;
|
|
15830
|
+
loadedTexture.minFilter = import_three35.LinearMipmapLinearFilter;
|
|
15471
15831
|
loadedTexture.generateMipmaps = true;
|
|
15472
15832
|
loadedTexture.anisotropy = gl.capabilities.getMaxAnisotropy();
|
|
15473
15833
|
loadedTexture.needsUpdate = true;
|
|
@@ -15484,7 +15844,7 @@ function usePosterTexture2(id, poster, onError) {
|
|
|
15484
15844
|
active = false;
|
|
15485
15845
|
};
|
|
15486
15846
|
}, [gl, id, poster]);
|
|
15487
|
-
(0,
|
|
15847
|
+
(0, import_react57.useEffect)(
|
|
15488
15848
|
() => () => {
|
|
15489
15849
|
texture?.dispose();
|
|
15490
15850
|
},
|
|
@@ -15502,14 +15862,14 @@ function useVideoResource({
|
|
|
15502
15862
|
poster,
|
|
15503
15863
|
src
|
|
15504
15864
|
}) {
|
|
15505
|
-
const [resource, setResource] = (0,
|
|
15506
|
-
const onEndedRef = (0,
|
|
15507
|
-
const onErrorRef = (0,
|
|
15508
|
-
const onPlaybackStateChangeRef = (0,
|
|
15865
|
+
const [resource, setResource] = (0, import_react57.useState)(null);
|
|
15866
|
+
const onEndedRef = (0, import_react57.useRef)(onEnded);
|
|
15867
|
+
const onErrorRef = (0, import_react57.useRef)(onError);
|
|
15868
|
+
const onPlaybackStateChangeRef = (0, import_react57.useRef)(onPlaybackStateChange);
|
|
15509
15869
|
onEndedRef.current = onEnded;
|
|
15510
15870
|
onErrorRef.current = onError;
|
|
15511
15871
|
onPlaybackStateChangeRef.current = onPlaybackStateChange;
|
|
15512
|
-
(0,
|
|
15872
|
+
(0, import_react57.useEffect)(() => {
|
|
15513
15873
|
if (!src) {
|
|
15514
15874
|
setResource(null);
|
|
15515
15875
|
return;
|
|
@@ -15526,12 +15886,12 @@ function useVideoResource({
|
|
|
15526
15886
|
video.setAttribute("webkit-playsinline", "true");
|
|
15527
15887
|
}
|
|
15528
15888
|
video.poster = poster ?? "";
|
|
15529
|
-
const texture = new
|
|
15530
|
-
texture.colorSpace =
|
|
15531
|
-
texture.wrapS =
|
|
15532
|
-
texture.wrapT =
|
|
15533
|
-
texture.magFilter =
|
|
15534
|
-
texture.minFilter =
|
|
15889
|
+
const texture = new import_three35.VideoTexture(video);
|
|
15890
|
+
texture.colorSpace = import_three35.SRGBColorSpace;
|
|
15891
|
+
texture.wrapS = import_three35.ClampToEdgeWrapping;
|
|
15892
|
+
texture.wrapT = import_three35.ClampToEdgeWrapping;
|
|
15893
|
+
texture.magFilter = import_three35.LinearFilter;
|
|
15894
|
+
texture.minFilter = import_three35.LinearFilter;
|
|
15535
15895
|
texture.generateMipmaps = false;
|
|
15536
15896
|
const notifyState = (state) => {
|
|
15537
15897
|
if (active) {
|
|
@@ -15616,11 +15976,11 @@ function VideoHotspot({
|
|
|
15616
15976
|
src
|
|
15617
15977
|
});
|
|
15618
15978
|
const posterTexture = usePosterTexture2(id, poster, onError);
|
|
15619
|
-
const onPlaybackErrorRef = (0,
|
|
15620
|
-
const onPlaybackStateChangeRef = (0,
|
|
15979
|
+
const onPlaybackErrorRef = (0, import_react57.useRef)(onPlaybackError);
|
|
15980
|
+
const onPlaybackStateChangeRef = (0, import_react57.useRef)(onPlaybackStateChange);
|
|
15621
15981
|
onPlaybackErrorRef.current = onPlaybackError;
|
|
15622
15982
|
onPlaybackStateChangeRef.current = onPlaybackStateChange;
|
|
15623
|
-
(0,
|
|
15983
|
+
(0, import_react57.useEffect)(() => {
|
|
15624
15984
|
if (!resource) {
|
|
15625
15985
|
return;
|
|
15626
15986
|
}
|
|
@@ -15637,7 +15997,7 @@ function VideoHotspot({
|
|
|
15637
15997
|
}
|
|
15638
15998
|
resource.video.preload = preload;
|
|
15639
15999
|
}, [loop, muted, playsInline, preload, resource, volume]);
|
|
15640
|
-
(0,
|
|
16000
|
+
(0, import_react57.useEffect)(() => {
|
|
15641
16001
|
if (!resource) {
|
|
15642
16002
|
return;
|
|
15643
16003
|
}
|
|
@@ -15660,14 +16020,14 @@ function VideoHotspot({
|
|
|
15660
16020
|
};
|
|
15661
16021
|
}, [playing, resource]);
|
|
15662
16022
|
const activeTexture = resource?.ready ? resource.texture : posterTexture;
|
|
15663
|
-
return /* @__PURE__ */ (0,
|
|
16023
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(HotspotAnchor, { ...anchorProps, id, height, width, children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(HotspotPlane, { map: activeTexture, opacity }) });
|
|
15664
16024
|
}
|
|
15665
16025
|
|
|
15666
16026
|
// src/hotspot/audio-hotspot.tsx
|
|
15667
|
-
var
|
|
15668
|
-
var
|
|
15669
|
-
var
|
|
15670
|
-
var
|
|
16027
|
+
var import_fiber30 = require("@react-three/fiber");
|
|
16028
|
+
var import_react58 = require("react");
|
|
16029
|
+
var import_three36 = require("three");
|
|
16030
|
+
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
15671
16031
|
var SPEAKER_TEXTURE_SIZE = 512;
|
|
15672
16032
|
function paintSpeakerBody(context, center) {
|
|
15673
16033
|
context.fillStyle = "#f5fbfc";
|
|
@@ -15720,19 +16080,19 @@ function createSpeakerTexture(state) {
|
|
|
15720
16080
|
return exhaustive;
|
|
15721
16081
|
}
|
|
15722
16082
|
}
|
|
15723
|
-
const texture = new
|
|
15724
|
-
texture.colorSpace =
|
|
15725
|
-
texture.wrapS =
|
|
15726
|
-
texture.wrapT =
|
|
15727
|
-
texture.magFilter =
|
|
15728
|
-
texture.minFilter =
|
|
16083
|
+
const texture = new import_three36.CanvasTexture(canvas);
|
|
16084
|
+
texture.colorSpace = import_three36.SRGBColorSpace;
|
|
16085
|
+
texture.wrapS = import_three36.ClampToEdgeWrapping;
|
|
16086
|
+
texture.wrapT = import_three36.ClampToEdgeWrapping;
|
|
16087
|
+
texture.magFilter = import_three36.LinearFilter;
|
|
16088
|
+
texture.minFilter = import_three36.LinearMipmapLinearFilter;
|
|
15729
16089
|
texture.generateMipmaps = true;
|
|
15730
16090
|
texture.needsUpdate = true;
|
|
15731
16091
|
return texture;
|
|
15732
16092
|
}
|
|
15733
16093
|
function useSpeakerTextures(enabled) {
|
|
15734
|
-
const [textures, setTextures] = (0,
|
|
15735
|
-
(0,
|
|
16094
|
+
const [textures, setTextures] = (0, import_react58.useState)({ playing: null, stopped: null });
|
|
16095
|
+
(0, import_react58.useEffect)(() => {
|
|
15736
16096
|
if (!enabled) {
|
|
15737
16097
|
setTextures({ playing: null, stopped: null });
|
|
15738
16098
|
return;
|
|
@@ -15748,11 +16108,11 @@ function useSpeakerTextures(enabled) {
|
|
|
15748
16108
|
return textures;
|
|
15749
16109
|
}
|
|
15750
16110
|
function useIconTexture(icon, enabled, onError, id) {
|
|
15751
|
-
const gl = (0,
|
|
15752
|
-
const [texture, setTexture] = (0,
|
|
15753
|
-
const onErrorRef = (0,
|
|
16111
|
+
const gl = (0, import_fiber30.useThree)((state) => state.gl);
|
|
16112
|
+
const [texture, setTexture] = (0, import_react58.useState)(null);
|
|
16113
|
+
const onErrorRef = (0, import_react58.useRef)(onError);
|
|
15754
16114
|
onErrorRef.current = onError;
|
|
15755
|
-
(0,
|
|
16115
|
+
(0, import_react58.useEffect)(() => {
|
|
15756
16116
|
let active = true;
|
|
15757
16117
|
setTexture(null);
|
|
15758
16118
|
if (!enabled || !icon) {
|
|
@@ -15760,7 +16120,7 @@ function useIconTexture(icon, enabled, onError, id) {
|
|
|
15760
16120
|
active = false;
|
|
15761
16121
|
};
|
|
15762
16122
|
}
|
|
15763
|
-
const loader = new
|
|
16123
|
+
const loader = new import_three36.TextureLoader();
|
|
15764
16124
|
loader.load(
|
|
15765
16125
|
icon,
|
|
15766
16126
|
(loadedTexture) => {
|
|
@@ -15768,11 +16128,11 @@ function useIconTexture(icon, enabled, onError, id) {
|
|
|
15768
16128
|
loadedTexture.dispose();
|
|
15769
16129
|
return;
|
|
15770
16130
|
}
|
|
15771
|
-
loadedTexture.colorSpace =
|
|
15772
|
-
loadedTexture.wrapS =
|
|
15773
|
-
loadedTexture.wrapT =
|
|
15774
|
-
loadedTexture.magFilter =
|
|
15775
|
-
loadedTexture.minFilter =
|
|
16131
|
+
loadedTexture.colorSpace = import_three36.SRGBColorSpace;
|
|
16132
|
+
loadedTexture.wrapS = import_three36.ClampToEdgeWrapping;
|
|
16133
|
+
loadedTexture.wrapT = import_three36.ClampToEdgeWrapping;
|
|
16134
|
+
loadedTexture.magFilter = import_three36.LinearFilter;
|
|
16135
|
+
loadedTexture.minFilter = import_three36.LinearMipmapLinearFilter;
|
|
15776
16136
|
loadedTexture.generateMipmaps = true;
|
|
15777
16137
|
loadedTexture.anisotropy = gl.capabilities.getMaxAnisotropy();
|
|
15778
16138
|
loadedTexture.needsUpdate = true;
|
|
@@ -15789,7 +16149,7 @@ function useIconTexture(icon, enabled, onError, id) {
|
|
|
15789
16149
|
active = false;
|
|
15790
16150
|
};
|
|
15791
16151
|
}, [enabled, gl, icon, id]);
|
|
15792
|
-
(0,
|
|
16152
|
+
(0, import_react58.useEffect)(
|
|
15793
16153
|
() => () => {
|
|
15794
16154
|
texture?.dispose();
|
|
15795
16155
|
},
|
|
@@ -15808,13 +16168,13 @@ function useAudioHowl({
|
|
|
15808
16168
|
playing,
|
|
15809
16169
|
src
|
|
15810
16170
|
}) {
|
|
15811
|
-
const [howl, setHowl] = (0,
|
|
15812
|
-
const playingRef = (0,
|
|
15813
|
-
const loopRef = (0,
|
|
15814
|
-
const onEndedRef = (0,
|
|
15815
|
-
const onErrorRef = (0,
|
|
15816
|
-
const onPlaybackErrorRef = (0,
|
|
15817
|
-
const onPlaybackStateChangeRef = (0,
|
|
16171
|
+
const [howl, setHowl] = (0, import_react58.useState)(null);
|
|
16172
|
+
const playingRef = (0, import_react58.useRef)(playing);
|
|
16173
|
+
const loopRef = (0, import_react58.useRef)(loop ?? false);
|
|
16174
|
+
const onEndedRef = (0, import_react58.useRef)(onEnded);
|
|
16175
|
+
const onErrorRef = (0, import_react58.useRef)(onError);
|
|
16176
|
+
const onPlaybackErrorRef = (0, import_react58.useRef)(onPlaybackError);
|
|
16177
|
+
const onPlaybackStateChangeRef = (0, import_react58.useRef)(onPlaybackStateChange);
|
|
15818
16178
|
playingRef.current = playing;
|
|
15819
16179
|
loopRef.current = loop ?? false;
|
|
15820
16180
|
onEndedRef.current = onEnded;
|
|
@@ -15822,7 +16182,7 @@ function useAudioHowl({
|
|
|
15822
16182
|
onPlaybackErrorRef.current = onPlaybackError;
|
|
15823
16183
|
onPlaybackStateChangeRef.current = onPlaybackStateChange;
|
|
15824
16184
|
const sourcesKey = sourceList(src).join("\0");
|
|
15825
|
-
(0,
|
|
16185
|
+
(0, import_react58.useEffect)(() => {
|
|
15826
16186
|
const sources = sourcesKey.length > 0 ? sourcesKey.split("\0") : [];
|
|
15827
16187
|
if (sources.length === 0) {
|
|
15828
16188
|
setHowl(null);
|
|
@@ -15859,7 +16219,7 @@ function useAudioHowl({
|
|
|
15859
16219
|
handle.dispose();
|
|
15860
16220
|
};
|
|
15861
16221
|
}, [crossOrigin, id, sourcesKey]);
|
|
15862
|
-
(0,
|
|
16222
|
+
(0, import_react58.useEffect)(() => {
|
|
15863
16223
|
howl?.loop(loop ?? false);
|
|
15864
16224
|
}, [howl, loop]);
|
|
15865
16225
|
return howl;
|
|
@@ -15887,7 +16247,7 @@ function AudioHotspot({
|
|
|
15887
16247
|
...anchorProps
|
|
15888
16248
|
}) {
|
|
15889
16249
|
usePanoMediaActivationIntent(playing);
|
|
15890
|
-
const camera = (0,
|
|
16250
|
+
const camera = (0, import_fiber30.useThree)((state) => state.camera);
|
|
15891
16251
|
const howl = useAudioHowl({
|
|
15892
16252
|
crossOrigin,
|
|
15893
16253
|
id,
|
|
@@ -15903,15 +16263,15 @@ function AudioHotspot({
|
|
|
15903
16263
|
const stoppedIconTexture = useIconTexture(icon, marker, onError, id);
|
|
15904
16264
|
const playingIconTexture = useIconTexture(playingIcon, marker, onError, id);
|
|
15905
16265
|
const markerTexture = playing ? playingIconTexture ?? stoppedIconTexture ?? speakerTextures.playing : stoppedIconTexture ?? speakerTextures.stopped;
|
|
15906
|
-
const playingRef = (0,
|
|
16266
|
+
const playingRef = (0, import_react58.useRef)(playing);
|
|
15907
16267
|
playingRef.current = playing;
|
|
15908
|
-
const mutedRef = (0,
|
|
15909
|
-
const volumeRef = (0,
|
|
15910
|
-
const rangeRef = (0,
|
|
16268
|
+
const mutedRef = (0, import_react58.useRef)(muted);
|
|
16269
|
+
const volumeRef = (0, import_react58.useRef)(volume);
|
|
16270
|
+
const rangeRef = (0, import_react58.useRef)(range);
|
|
15911
16271
|
mutedRef.current = muted;
|
|
15912
16272
|
volumeRef.current = volume;
|
|
15913
16273
|
rangeRef.current = range;
|
|
15914
|
-
(0,
|
|
16274
|
+
(0, import_react58.useEffect)(() => {
|
|
15915
16275
|
if (!howl) {
|
|
15916
16276
|
return;
|
|
15917
16277
|
}
|
|
@@ -15921,7 +16281,7 @@ function AudioHotspot({
|
|
|
15921
16281
|
}
|
|
15922
16282
|
howl.play();
|
|
15923
16283
|
}, [howl, playing]);
|
|
15924
|
-
(0,
|
|
16284
|
+
(0, import_react58.useEffect)(() => {
|
|
15925
16285
|
if (!howl || !pauseWhenHidden) {
|
|
15926
16286
|
return;
|
|
15927
16287
|
}
|
|
@@ -15939,7 +16299,7 @@ function AudioHotspot({
|
|
|
15939
16299
|
document.removeEventListener("visibilitychange", handleVisibility);
|
|
15940
16300
|
};
|
|
15941
16301
|
}, [howl, pauseWhenHidden]);
|
|
15942
|
-
(0,
|
|
16302
|
+
(0, import_fiber30.useFrame)(() => {
|
|
15943
16303
|
if (!howl) {
|
|
15944
16304
|
return;
|
|
15945
16305
|
}
|
|
@@ -15952,13 +16312,13 @@ function AudioHotspot({
|
|
|
15952
16312
|
howl.mute(mutedRef.current);
|
|
15953
16313
|
howl.volume(clampAudioVolume(volumeRef.current) * spatial.gain);
|
|
15954
16314
|
});
|
|
15955
|
-
return /* @__PURE__ */ (0,
|
|
16315
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(HotspotAnchor, { ...anchorProps, id, height, width, children: marker ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(HotspotPlane, { map: markerTexture, opacity }) : null });
|
|
15956
16316
|
}
|
|
15957
16317
|
|
|
15958
16318
|
// src/hotspot/text-hotspot.tsx
|
|
15959
|
-
var
|
|
15960
|
-
var
|
|
15961
|
-
var
|
|
16319
|
+
var import_react59 = require("react");
|
|
16320
|
+
var import_three37 = require("three");
|
|
16321
|
+
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
15962
16322
|
var TEXT_TEXTURE_LONG_SIDE = 1024;
|
|
15963
16323
|
var DEFAULT_FONT_FAMILY = "system-ui, sans-serif";
|
|
15964
16324
|
var DEFAULT_FONT_SIZE = 96;
|
|
@@ -16167,23 +16527,23 @@ function createTextTexture(text, width, height, style) {
|
|
|
16167
16527
|
throw new Error("Canvas 2D is unavailable for this text hotspot.");
|
|
16168
16528
|
}
|
|
16169
16529
|
drawTextHotspot(context, canvasWidth, canvasHeight, text, style);
|
|
16170
|
-
const texture = new
|
|
16171
|
-
texture.colorSpace =
|
|
16172
|
-
texture.wrapS =
|
|
16173
|
-
texture.wrapT =
|
|
16174
|
-
texture.magFilter =
|
|
16175
|
-
texture.minFilter =
|
|
16530
|
+
const texture = new import_three37.CanvasTexture(canvas);
|
|
16531
|
+
texture.colorSpace = import_three37.SRGBColorSpace;
|
|
16532
|
+
texture.wrapS = import_three37.ClampToEdgeWrapping;
|
|
16533
|
+
texture.wrapT = import_three37.ClampToEdgeWrapping;
|
|
16534
|
+
texture.magFilter = import_three37.LinearFilter;
|
|
16535
|
+
texture.minFilter = import_three37.LinearMipmapLinearFilter;
|
|
16176
16536
|
texture.generateMipmaps = true;
|
|
16177
16537
|
texture.needsUpdate = true;
|
|
16178
16538
|
return texture;
|
|
16179
16539
|
}
|
|
16180
16540
|
function useTextTexture(text, width, height, style, onLoad, onError) {
|
|
16181
|
-
const [texture, setTexture] = (0,
|
|
16182
|
-
const onLoadRef = (0,
|
|
16183
|
-
const onErrorRef = (0,
|
|
16541
|
+
const [texture, setTexture] = (0, import_react59.useState)(null);
|
|
16542
|
+
const onLoadRef = (0, import_react59.useRef)(onLoad);
|
|
16543
|
+
const onErrorRef = (0, import_react59.useRef)(onError);
|
|
16184
16544
|
onLoadRef.current = onLoad;
|
|
16185
16545
|
onErrorRef.current = onError;
|
|
16186
|
-
(0,
|
|
16546
|
+
(0, import_react59.useEffect)(() => {
|
|
16187
16547
|
let cancelled = false;
|
|
16188
16548
|
let nextTexture = null;
|
|
16189
16549
|
const run = async () => {
|
|
@@ -16276,13 +16636,13 @@ function TextHotspot({
|
|
|
16276
16636
|
whiteSpace
|
|
16277
16637
|
};
|
|
16278
16638
|
const texture = useTextTexture(text, width, height, style, onLoad, onError);
|
|
16279
|
-
return /* @__PURE__ */ (0,
|
|
16639
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(HotspotAnchor, { ...anchorProps, height, width, children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(HotspotPlane, { map: texture, opacity }) });
|
|
16280
16640
|
}
|
|
16281
16641
|
|
|
16282
16642
|
// src/hotspot/iframe-hotspot.tsx
|
|
16283
16643
|
var import_drei2 = require("@react-three/drei");
|
|
16284
|
-
var
|
|
16285
|
-
var
|
|
16644
|
+
var import_three38 = require("three");
|
|
16645
|
+
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
16286
16646
|
var IFRAME_LONG_SIDE = 800;
|
|
16287
16647
|
var CSS3D_DISTANCE_FACTOR = 400;
|
|
16288
16648
|
var DEFAULT_SANDBOX = "allow-scripts allow-popups allow-forms";
|
|
@@ -16339,7 +16699,7 @@ function IframeHotspot({
|
|
|
16339
16699
|
interactive,
|
|
16340
16700
|
pointerEvents
|
|
16341
16701
|
);
|
|
16342
|
-
return /* @__PURE__ */ (0,
|
|
16702
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
16343
16703
|
HotspotAnchor,
|
|
16344
16704
|
{
|
|
16345
16705
|
...anchorProps,
|
|
@@ -16348,20 +16708,20 @@ function IframeHotspot({
|
|
|
16348
16708
|
pointerEvents,
|
|
16349
16709
|
width,
|
|
16350
16710
|
children: [
|
|
16351
|
-
/* @__PURE__ */ (0,
|
|
16352
|
-
/* @__PURE__ */ (0,
|
|
16353
|
-
/* @__PURE__ */ (0,
|
|
16711
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("mesh", { children: [
|
|
16712
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("planeGeometry", { args: [1, 1] }),
|
|
16713
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
16354
16714
|
"meshBasicMaterial",
|
|
16355
16715
|
{
|
|
16356
16716
|
depthWrite: false,
|
|
16357
16717
|
opacity: 0,
|
|
16358
|
-
side:
|
|
16718
|
+
side: import_three38.DoubleSide,
|
|
16359
16719
|
toneMapped: false,
|
|
16360
16720
|
transparent: true
|
|
16361
16721
|
}
|
|
16362
16722
|
)
|
|
16363
16723
|
] }),
|
|
16364
|
-
/* @__PURE__ */ (0,
|
|
16724
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
16365
16725
|
import_drei2.Html,
|
|
16366
16726
|
{
|
|
16367
16727
|
distanceFactor: CSS3D_DISTANCE_FACTOR,
|
|
@@ -16376,7 +16736,7 @@ function IframeHotspot({
|
|
|
16376
16736
|
},
|
|
16377
16737
|
transform: true,
|
|
16378
16738
|
zIndexRange: [10, 0],
|
|
16379
|
-
children: /* @__PURE__ */ (0,
|
|
16739
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
16380
16740
|
"iframe",
|
|
16381
16741
|
{
|
|
16382
16742
|
allow,
|