@ericchen1990/pano-view 3.1.3 → 3.2.1
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 +65 -4
- package/README.zh-CN.md +55 -4
- package/dist/index.cjs +1413 -984
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +172 -81
- package/dist/index.d.ts +172 -81
- package/dist/index.mjs +1474 -1042
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -4
package/dist/index.cjs
CHANGED
|
@@ -2278,6 +2278,7 @@ __export(index_exports, {
|
|
|
2278
2278
|
Scenes: () => Scenes,
|
|
2279
2279
|
SequenceHotspot: () => SequenceHotspot,
|
|
2280
2280
|
Sphere: () => Sphere,
|
|
2281
|
+
SphereTile: () => SphereTile,
|
|
2281
2282
|
TextHotspot: () => TextHotspot,
|
|
2282
2283
|
Tile: () => Tile,
|
|
2283
2284
|
TouchControls: () => TouchControls,
|
|
@@ -3786,7 +3787,9 @@ var DEFAULT_PANO_FILTER_INTENSITY = 1;
|
|
|
3786
3787
|
var DEFAULT_PANO_FILTER_SNAPSHOT = {
|
|
3787
3788
|
preset: "none",
|
|
3788
3789
|
intensity: DEFAULT_PANO_FILTER_INTENSITY,
|
|
3789
|
-
enabled: true
|
|
3790
|
+
enabled: true,
|
|
3791
|
+
colorMatrix: null,
|
|
3792
|
+
colorMatrixScope: "panorama"
|
|
3790
3793
|
};
|
|
3791
3794
|
function clampPanoFilterIntensity(value) {
|
|
3792
3795
|
if (!Number.isFinite(value)) {
|
|
@@ -3795,15 +3798,17 @@ function clampPanoFilterIntensity(value) {
|
|
|
3795
3798
|
return Math.max(0, Math.min(value, 1));
|
|
3796
3799
|
}
|
|
3797
3800
|
function resolvePanoFilterSnapshot(input) {
|
|
3801
|
+
if (input.colorMatrix && (input.colorMatrix.length !== 20 || input.colorMatrix.some((value) => !Number.isFinite(value)))) {
|
|
3802
|
+
throw new Error("colorMatrix must contain 20 finite numbers");
|
|
3803
|
+
}
|
|
3798
3804
|
return {
|
|
3805
|
+
colorMatrix: input.colorMatrix ? [...input.colorMatrix] : null,
|
|
3806
|
+
colorMatrixScope: input.colorMatrixScope ?? "panorama",
|
|
3799
3807
|
preset: input.preset ?? "none",
|
|
3800
3808
|
intensity: clampPanoFilterIntensity(input.intensity),
|
|
3801
3809
|
enabled: input.enabled !== false
|
|
3802
3810
|
};
|
|
3803
3811
|
}
|
|
3804
|
-
function isPanoFilterActive(snapshot) {
|
|
3805
|
-
return snapshot.enabled && snapshot.preset !== "none";
|
|
3806
|
-
}
|
|
3807
3812
|
|
|
3808
3813
|
// src/pano-filter/host.ts
|
|
3809
3814
|
var PanoFilterHostContext = (0, import_react10.createContext)(null);
|
|
@@ -8055,15 +8060,23 @@ var import_react28 = require("react");
|
|
|
8055
8060
|
function PanoFilter({
|
|
8056
8061
|
preset = "none",
|
|
8057
8062
|
intensity,
|
|
8058
|
-
enabled = true
|
|
8063
|
+
enabled = true,
|
|
8064
|
+
colorMatrix,
|
|
8065
|
+
colorMatrixScope
|
|
8059
8066
|
}) {
|
|
8060
8067
|
const host = (0, import_react28.useContext)(PanoFilterHostContext);
|
|
8061
8068
|
if (!host) {
|
|
8062
8069
|
throw new Error("<PanoFilter> must be rendered inside <PanoViewer>.");
|
|
8063
8070
|
}
|
|
8064
8071
|
const snapshot = (0, import_react28.useMemo)(
|
|
8065
|
-
() => resolvePanoFilterSnapshot({
|
|
8066
|
-
|
|
8072
|
+
() => resolvePanoFilterSnapshot({
|
|
8073
|
+
preset,
|
|
8074
|
+
intensity,
|
|
8075
|
+
enabled,
|
|
8076
|
+
colorMatrix,
|
|
8077
|
+
colorMatrixScope
|
|
8078
|
+
}),
|
|
8079
|
+
[enabled, intensity, preset, colorMatrix, colorMatrixScope]
|
|
8067
8080
|
);
|
|
8068
8081
|
(0, import_react28.useEffect)(() => {
|
|
8069
8082
|
claimPanoFilter(host);
|
|
@@ -9684,10 +9697,10 @@ function usePanoViewer() {
|
|
|
9684
9697
|
return (0, import_react35.useMemo)(() => ({ ref, ...handle }), [handle]);
|
|
9685
9698
|
}
|
|
9686
9699
|
|
|
9687
|
-
// src/sphere.tsx
|
|
9700
|
+
// src/sphere-tile/sphere-tile.tsx
|
|
9688
9701
|
var import_fiber15 = require("@react-three/fiber");
|
|
9689
|
-
var
|
|
9690
|
-
var
|
|
9702
|
+
var import_react38 = require("react");
|
|
9703
|
+
var import_three14 = require("three");
|
|
9691
9704
|
|
|
9692
9705
|
// src/asset-url.ts
|
|
9693
9706
|
function isAbsoluteAssetUrl(url) {
|
|
@@ -9712,6 +9725,7 @@ function resolveUrlAgainstFile(fileUrl, path) {
|
|
|
9712
9725
|
|
|
9713
9726
|
// src/pano-filter/pano-basic-material.tsx
|
|
9714
9727
|
var import_react36 = require("react");
|
|
9728
|
+
var import_three10 = require("three");
|
|
9715
9729
|
|
|
9716
9730
|
// src/pano-filter/shaders.ts
|
|
9717
9731
|
var GLSL_FILTER_COMMON = `
|
|
@@ -9860,77 +9874,327 @@ ${applyPanoFilterFunction(panoFilterBody(preset))}`
|
|
|
9860
9874
|
diffuseColor.rgb = mix(diffuseColor.rgb, applyPanoFilter(diffuseColor.rgb), clamp(uPanoFilterIntensity, 0.0, 1.0));`
|
|
9861
9875
|
);
|
|
9862
9876
|
}
|
|
9877
|
+
function injectPanoColorMatrixShader(shader) {
|
|
9878
|
+
shader.fragmentShader = shader.fragmentShader.replace(
|
|
9879
|
+
"#include <common>",
|
|
9880
|
+
`#include <common>
|
|
9881
|
+
uniform mat4 uPanoColorMatrix;
|
|
9882
|
+
uniform vec4 uPanoColorOffset;
|
|
9883
|
+
uniform float uPanoColorMatrixIntensity;`
|
|
9884
|
+
).replace(
|
|
9885
|
+
"#include <colorspace_fragment>",
|
|
9886
|
+
`#include <colorspace_fragment>
|
|
9887
|
+
gl_FragColor = mix(gl_FragColor, clamp(uPanoColorMatrix * gl_FragColor + uPanoColorOffset, 0.0, 1.0), uPanoColorMatrixIntensity);`
|
|
9888
|
+
);
|
|
9889
|
+
}
|
|
9863
9890
|
|
|
9864
9891
|
// src/pano-filter/pano-basic-material.tsx
|
|
9865
9892
|
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
9893
|
+
function matrixUniforms(matrix) {
|
|
9894
|
+
return {
|
|
9895
|
+
matrix: new import_three10.Matrix4().set(
|
|
9896
|
+
matrix[0],
|
|
9897
|
+
matrix[1],
|
|
9898
|
+
matrix[2],
|
|
9899
|
+
matrix[3],
|
|
9900
|
+
matrix[5],
|
|
9901
|
+
matrix[6],
|
|
9902
|
+
matrix[7],
|
|
9903
|
+
matrix[8],
|
|
9904
|
+
matrix[10],
|
|
9905
|
+
matrix[11],
|
|
9906
|
+
matrix[12],
|
|
9907
|
+
matrix[13],
|
|
9908
|
+
matrix[15],
|
|
9909
|
+
matrix[16],
|
|
9910
|
+
matrix[17],
|
|
9911
|
+
matrix[18]
|
|
9912
|
+
),
|
|
9913
|
+
offset: new import_three10.Vector4(matrix[4], matrix[9], matrix[14], matrix[19])
|
|
9914
|
+
};
|
|
9915
|
+
}
|
|
9866
9916
|
function PanoBasicMaterial({
|
|
9867
|
-
|
|
9868
|
-
|
|
9869
|
-
depthTest,
|
|
9870
|
-
depthWrite,
|
|
9871
|
-
toneMapped = false
|
|
9917
|
+
target = "panorama",
|
|
9918
|
+
...props
|
|
9872
9919
|
}) {
|
|
9873
9920
|
const snapshot = usePanoFilterSnapshot();
|
|
9874
|
-
const
|
|
9875
|
-
const
|
|
9876
|
-
const
|
|
9877
|
-
|
|
9878
|
-
|
|
9879
|
-
const
|
|
9921
|
+
const preset = snapshot.enabled && target === "panorama" ? snapshot.preset : "none";
|
|
9922
|
+
const matrix = snapshot.enabled && (target === "panorama" || snapshot.colorMatrixScope === "all") ? snapshot.colorMatrix : null;
|
|
9923
|
+
const hasMatrix = matrix !== null;
|
|
9924
|
+
const currentRef = (0, import_react36.useRef)({ matrix, intensity: snapshot.intensity });
|
|
9925
|
+
currentRef.current = { matrix, intensity: snapshot.intensity };
|
|
9926
|
+
const shaderRef = (0, import_react36.useRef)(null);
|
|
9880
9927
|
const onBeforeCompile = (0, import_react36.useMemo)(() => {
|
|
9881
|
-
if (!active || preset === "none") {
|
|
9882
|
-
return void 0;
|
|
9883
|
-
}
|
|
9884
9928
|
const compile = (shader) => {
|
|
9885
|
-
|
|
9886
|
-
|
|
9887
|
-
|
|
9888
|
-
|
|
9889
|
-
|
|
9890
|
-
if (
|
|
9891
|
-
|
|
9929
|
+
shaderRef.current = shader;
|
|
9930
|
+
if (preset !== "none") {
|
|
9931
|
+
injectPanoFilterShader(shader, preset);
|
|
9932
|
+
shader.uniforms.uPanoFilterIntensity.value = currentRef.current.intensity;
|
|
9933
|
+
}
|
|
9934
|
+
if (hasMatrix && currentRef.current.matrix) {
|
|
9935
|
+
injectPanoColorMatrixShader(shader);
|
|
9936
|
+
const values = matrixUniforms(currentRef.current.matrix);
|
|
9937
|
+
shader.uniforms.uPanoColorMatrix = { value: values.matrix };
|
|
9938
|
+
shader.uniforms.uPanoColorOffset = { value: values.offset };
|
|
9939
|
+
shader.uniforms.uPanoColorMatrixIntensity = {
|
|
9940
|
+
value: currentRef.current.intensity
|
|
9941
|
+
};
|
|
9892
9942
|
}
|
|
9893
9943
|
};
|
|
9894
|
-
compile.toString = () => `pano-filter:${preset}`;
|
|
9944
|
+
compile.toString = () => `pano-filter:${preset}:matrix:${hasMatrix}`;
|
|
9895
9945
|
return compile;
|
|
9896
|
-
}, [
|
|
9897
|
-
(0, import_react36.useLayoutEffect)(() => {
|
|
9898
|
-
if (!active) {
|
|
9899
|
-
intensityUniformRef.current = null;
|
|
9900
|
-
}
|
|
9901
|
-
const material = materialRef.current;
|
|
9902
|
-
if (!material) {
|
|
9903
|
-
return;
|
|
9904
|
-
}
|
|
9905
|
-
material.needsUpdate = true;
|
|
9906
|
-
}, [active, preset]);
|
|
9946
|
+
}, [preset, hasMatrix]);
|
|
9907
9947
|
(0, import_react36.useLayoutEffect)(() => {
|
|
9908
|
-
|
|
9909
|
-
|
|
9910
|
-
|
|
9911
|
-
|
|
9948
|
+
const shader = shaderRef.current;
|
|
9949
|
+
if (!shader) return;
|
|
9950
|
+
if (shader.uniforms.uPanoFilterIntensity)
|
|
9951
|
+
shader.uniforms.uPanoFilterIntensity.value = snapshot.intensity;
|
|
9952
|
+
if (shader.uniforms.uPanoColorMatrix && matrix) {
|
|
9953
|
+
const values = matrixUniforms(matrix);
|
|
9954
|
+
shader.uniforms.uPanoColorMatrix.value = values.matrix;
|
|
9955
|
+
shader.uniforms.uPanoColorOffset.value = values.offset;
|
|
9956
|
+
shader.uniforms.uPanoColorMatrixIntensity.value = snapshot.intensity;
|
|
9957
|
+
}
|
|
9958
|
+
}, [matrix, snapshot.intensity]);
|
|
9912
9959
|
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
9913
9960
|
"meshBasicMaterial",
|
|
9914
9961
|
{
|
|
9915
|
-
|
|
9916
|
-
|
|
9917
|
-
|
|
9918
|
-
map,
|
|
9919
|
-
onBeforeCompile,
|
|
9920
|
-
side,
|
|
9921
|
-
toneMapped
|
|
9962
|
+
toneMapped: false,
|
|
9963
|
+
...props,
|
|
9964
|
+
onBeforeCompile
|
|
9922
9965
|
},
|
|
9923
|
-
|
|
9966
|
+
`${preset}:${hasMatrix}`
|
|
9924
9967
|
);
|
|
9925
9968
|
}
|
|
9926
9969
|
|
|
9927
|
-
// src/
|
|
9928
|
-
var
|
|
9929
|
-
|
|
9970
|
+
// src/tile/texture-manager.ts
|
|
9971
|
+
var import_three11 = require("three");
|
|
9972
|
+
var EMPTY_TEXTURE_SNAPSHOT = {
|
|
9973
|
+
status: "idle",
|
|
9974
|
+
texture: null,
|
|
9975
|
+
error: null
|
|
9976
|
+
};
|
|
9977
|
+
var TileTextureManager = class {
|
|
9978
|
+
constructor(options) {
|
|
9979
|
+
this.loader = new import_three11.TextureLoader();
|
|
9980
|
+
this.entries = /* @__PURE__ */ new Map();
|
|
9981
|
+
this.queue = [];
|
|
9982
|
+
this.activeLoads = 0;
|
|
9983
|
+
this.totalBytes = 0;
|
|
9984
|
+
this.requested = 0;
|
|
9985
|
+
this.loaded = 0;
|
|
9986
|
+
this.failed = 0;
|
|
9987
|
+
this.disposed = false;
|
|
9988
|
+
this.generation = 0;
|
|
9989
|
+
this.options = options;
|
|
9990
|
+
}
|
|
9991
|
+
resume() {
|
|
9992
|
+
this.disposed = false;
|
|
9993
|
+
this.drain();
|
|
9994
|
+
}
|
|
9995
|
+
getSnapshot(key) {
|
|
9996
|
+
const entry = this.entries.get(key);
|
|
9997
|
+
return entry ? this.snapshot(entry) : EMPTY_TEXTURE_SNAPSHOT;
|
|
9998
|
+
}
|
|
9999
|
+
acquire(key, url, address, listener) {
|
|
10000
|
+
let entry = this.entries.get(key);
|
|
10001
|
+
if (!entry) {
|
|
10002
|
+
entry = {
|
|
10003
|
+
key,
|
|
10004
|
+
url,
|
|
10005
|
+
address,
|
|
10006
|
+
status: "idle",
|
|
10007
|
+
texture: null,
|
|
10008
|
+
error: null,
|
|
10009
|
+
refs: 0,
|
|
10010
|
+
listeners: /* @__PURE__ */ new Set(),
|
|
10011
|
+
lastUsed: performance.now(),
|
|
10012
|
+
bytes: 0
|
|
10013
|
+
};
|
|
10014
|
+
this.entries.set(key, entry);
|
|
10015
|
+
}
|
|
10016
|
+
entry.refs += 1;
|
|
10017
|
+
entry.lastUsed = performance.now();
|
|
10018
|
+
entry.listeners.add(listener);
|
|
10019
|
+
listener(this.snapshot(entry));
|
|
10020
|
+
if (entry.status === "idle") {
|
|
10021
|
+
entry.status = "queued";
|
|
10022
|
+
this.queue.push(entry);
|
|
10023
|
+
this.requested += 1;
|
|
10024
|
+
this.emitProgress();
|
|
10025
|
+
this.drain();
|
|
10026
|
+
}
|
|
10027
|
+
return () => {
|
|
10028
|
+
entry.listeners.delete(listener);
|
|
10029
|
+
entry.refs = Math.max(0, entry.refs - 1);
|
|
10030
|
+
entry.lastUsed = performance.now();
|
|
10031
|
+
if (entry.refs === 0 && entry.status === "queued") {
|
|
10032
|
+
const queueIndex = this.queue.indexOf(entry);
|
|
10033
|
+
if (queueIndex >= 0) {
|
|
10034
|
+
this.queue.splice(queueIndex, 1);
|
|
10035
|
+
}
|
|
10036
|
+
entry.status = "idle";
|
|
10037
|
+
this.entries.delete(entry.key);
|
|
10038
|
+
this.requested = Math.max(0, this.requested - 1);
|
|
10039
|
+
this.emitProgress();
|
|
10040
|
+
this.drain();
|
|
10041
|
+
return;
|
|
10042
|
+
}
|
|
10043
|
+
this.evict();
|
|
10044
|
+
};
|
|
10045
|
+
}
|
|
10046
|
+
dispose() {
|
|
10047
|
+
this.disposed = true;
|
|
10048
|
+
this.generation += 1;
|
|
10049
|
+
this.queue.length = 0;
|
|
10050
|
+
for (const entry of this.entries.values()) {
|
|
10051
|
+
entry.texture?.dispose();
|
|
10052
|
+
entry.listeners.clear();
|
|
10053
|
+
}
|
|
10054
|
+
this.entries.clear();
|
|
10055
|
+
this.totalBytes = 0;
|
|
10056
|
+
}
|
|
10057
|
+
/**
|
|
10058
|
+
* Releases textures that are no longer rendered by any Tile instance.
|
|
10059
|
+
* Scene transitions call this after the outgoing panorama has been
|
|
10060
|
+
* snapshotted, so the incoming scene never competes with stale GPU tiles.
|
|
10061
|
+
*/
|
|
10062
|
+
releaseUnused() {
|
|
10063
|
+
for (const entry of Array.from(this.entries.values())) {
|
|
10064
|
+
if (entry.refs > 0) {
|
|
10065
|
+
continue;
|
|
10066
|
+
}
|
|
10067
|
+
entry.texture?.dispose();
|
|
10068
|
+
this.totalBytes -= entry.bytes;
|
|
10069
|
+
this.entries.delete(entry.key);
|
|
10070
|
+
}
|
|
10071
|
+
this.totalBytes = Math.max(0, this.totalBytes);
|
|
10072
|
+
}
|
|
10073
|
+
snapshot(entry) {
|
|
10074
|
+
return {
|
|
10075
|
+
status: entry.status,
|
|
10076
|
+
texture: entry.texture,
|
|
10077
|
+
error: entry.error
|
|
10078
|
+
};
|
|
10079
|
+
}
|
|
10080
|
+
notify(entry) {
|
|
10081
|
+
const snapshot = this.snapshot(entry);
|
|
10082
|
+
for (const listener of entry.listeners) {
|
|
10083
|
+
listener(snapshot);
|
|
10084
|
+
}
|
|
10085
|
+
}
|
|
10086
|
+
emitProgress() {
|
|
10087
|
+
this.options.onProgress?.({
|
|
10088
|
+
requested: this.requested,
|
|
10089
|
+
loaded: this.loaded,
|
|
10090
|
+
failed: this.failed,
|
|
10091
|
+
active: this.activeLoads,
|
|
10092
|
+
queued: this.queue.length
|
|
10093
|
+
});
|
|
10094
|
+
}
|
|
10095
|
+
drain() {
|
|
10096
|
+
while (!this.disposed && this.activeLoads < this.options.concurrency && this.queue.length > 0) {
|
|
10097
|
+
const entry = this.queue.shift();
|
|
10098
|
+
if (entry.refs === 0) {
|
|
10099
|
+
entry.status = "idle";
|
|
10100
|
+
this.entries.delete(entry.key);
|
|
10101
|
+
this.requested = Math.max(0, this.requested - 1);
|
|
10102
|
+
continue;
|
|
10103
|
+
}
|
|
10104
|
+
entry.status = "loading";
|
|
10105
|
+
this.activeLoads += 1;
|
|
10106
|
+
this.notify(entry);
|
|
10107
|
+
this.emitProgress();
|
|
10108
|
+
void this.loadAndFinish(entry);
|
|
10109
|
+
}
|
|
10110
|
+
}
|
|
10111
|
+
async load(entry, generation) {
|
|
10112
|
+
let lastError = null;
|
|
10113
|
+
for (let attempt = 0; attempt <= this.options.retryCount; attempt += 1) {
|
|
10114
|
+
if (this.disposed || generation !== this.generation) return;
|
|
10115
|
+
try {
|
|
10116
|
+
const texture = await this.loader.loadAsync(entry.url);
|
|
10117
|
+
if (this.disposed || generation !== this.generation) {
|
|
10118
|
+
texture.dispose();
|
|
10119
|
+
return;
|
|
10120
|
+
}
|
|
10121
|
+
this.configureTexture(texture);
|
|
10122
|
+
entry.texture = texture;
|
|
10123
|
+
entry.status = "loaded";
|
|
10124
|
+
entry.error = null;
|
|
10125
|
+
entry.bytes = entry.address.width * entry.address.height * 4;
|
|
10126
|
+
entry.lastUsed = performance.now();
|
|
10127
|
+
this.totalBytes += entry.bytes;
|
|
10128
|
+
this.loaded += 1;
|
|
10129
|
+
this.notify(entry);
|
|
10130
|
+
return;
|
|
10131
|
+
} catch (error) {
|
|
10132
|
+
lastError = error;
|
|
10133
|
+
}
|
|
10134
|
+
}
|
|
10135
|
+
if (!this.disposed && generation === this.generation) {
|
|
10136
|
+
entry.status = "error";
|
|
10137
|
+
entry.error = lastError;
|
|
10138
|
+
this.failed += 1;
|
|
10139
|
+
this.notify(entry);
|
|
10140
|
+
this.options.onError?.({
|
|
10141
|
+
address: entry.address,
|
|
10142
|
+
url: entry.url,
|
|
10143
|
+
error: lastError
|
|
10144
|
+
});
|
|
10145
|
+
}
|
|
10146
|
+
}
|
|
10147
|
+
configureTexture(texture) {
|
|
10148
|
+
texture.colorSpace = import_three11.SRGBColorSpace;
|
|
10149
|
+
texture.wrapS = import_three11.ClampToEdgeWrapping;
|
|
10150
|
+
texture.wrapT = import_three11.ClampToEdgeWrapping;
|
|
10151
|
+
texture.magFilter = import_three11.LinearFilter;
|
|
10152
|
+
texture.minFilter = import_three11.LinearFilter;
|
|
10153
|
+
texture.generateMipmaps = false;
|
|
10154
|
+
texture.anisotropy = Math.min(4, this.options.anisotropy);
|
|
10155
|
+
texture.needsUpdate = true;
|
|
10156
|
+
}
|
|
10157
|
+
evict() {
|
|
10158
|
+
if (this.totalBytes <= this.options.maxBytes) {
|
|
10159
|
+
return;
|
|
10160
|
+
}
|
|
10161
|
+
const candidates = Array.from(this.entries.values()).filter((entry) => entry.refs === 0 && entry.texture).sort((a, b) => a.lastUsed - b.lastUsed);
|
|
10162
|
+
for (const entry of candidates) {
|
|
10163
|
+
if (this.totalBytes <= this.options.maxBytes) {
|
|
10164
|
+
break;
|
|
10165
|
+
}
|
|
10166
|
+
entry.texture?.dispose();
|
|
10167
|
+
this.totalBytes -= entry.bytes;
|
|
10168
|
+
this.entries.delete(entry.key);
|
|
10169
|
+
}
|
|
10170
|
+
this.totalBytes = Math.max(0, this.totalBytes);
|
|
10171
|
+
}
|
|
10172
|
+
finishLoad(generation) {
|
|
10173
|
+
this.activeLoads = Math.max(0, this.activeLoads - 1);
|
|
10174
|
+
if (!this.disposed && generation === this.generation) {
|
|
10175
|
+
this.emitProgress();
|
|
10176
|
+
this.evict();
|
|
10177
|
+
}
|
|
10178
|
+
if (!this.disposed) {
|
|
10179
|
+
this.drain();
|
|
10180
|
+
}
|
|
10181
|
+
}
|
|
10182
|
+
async loadAndFinish(entry) {
|
|
10183
|
+
const generation = this.generation;
|
|
10184
|
+
try {
|
|
10185
|
+
await this.load(entry, generation);
|
|
10186
|
+
} finally {
|
|
10187
|
+
this.finishLoad(generation);
|
|
10188
|
+
}
|
|
10189
|
+
}
|
|
10190
|
+
};
|
|
10191
|
+
|
|
10192
|
+
// src/tile/texture-hooks.ts
|
|
10193
|
+
var import_react37 = require("react");
|
|
10194
|
+
var import_three12 = require("three");
|
|
10195
|
+
function usePreviewTexture(url, anisotropy, onError) {
|
|
9930
10196
|
const [texture, setTexture] = (0, import_react37.useState)(null);
|
|
9931
|
-
const onLoadRef = (0, import_react37.useRef)(onLoad);
|
|
9932
10197
|
const onErrorRef = (0, import_react37.useRef)(onError);
|
|
9933
|
-
onLoadRef.current = onLoad;
|
|
9934
10198
|
onErrorRef.current = onError;
|
|
9935
10199
|
(0, import_react37.useEffect)(() => {
|
|
9936
10200
|
if (!url) {
|
|
@@ -9938,7 +10202,7 @@ function useEquirectTexture(url, anisotropy, generateMipmaps, onLoad, onError) {
|
|
|
9938
10202
|
return;
|
|
9939
10203
|
}
|
|
9940
10204
|
let active = true;
|
|
9941
|
-
const loader = new
|
|
10205
|
+
const loader = new import_three12.TextureLoader();
|
|
9942
10206
|
setTexture(null);
|
|
9943
10207
|
loader.load(
|
|
9944
10208
|
url,
|
|
@@ -9947,14 +10211,472 @@ function useEquirectTexture(url, anisotropy, generateMipmaps, onLoad, onError) {
|
|
|
9947
10211
|
loadedTexture.dispose();
|
|
9948
10212
|
return;
|
|
9949
10213
|
}
|
|
9950
|
-
loadedTexture.colorSpace =
|
|
9951
|
-
loadedTexture.wrapS =
|
|
9952
|
-
loadedTexture.
|
|
9953
|
-
loadedTexture.
|
|
9954
|
-
loadedTexture.
|
|
9955
|
-
loadedTexture.
|
|
9956
|
-
loadedTexture.
|
|
9957
|
-
loadedTexture.
|
|
10214
|
+
loadedTexture.colorSpace = import_three12.SRGBColorSpace;
|
|
10215
|
+
loadedTexture.wrapS = import_three12.ClampToEdgeWrapping;
|
|
10216
|
+
loadedTexture.wrapT = import_three12.ClampToEdgeWrapping;
|
|
10217
|
+
loadedTexture.magFilter = import_three12.LinearFilter;
|
|
10218
|
+
loadedTexture.minFilter = import_three12.LinearFilter;
|
|
10219
|
+
loadedTexture.generateMipmaps = false;
|
|
10220
|
+
loadedTexture.anisotropy = Math.min(4, anisotropy);
|
|
10221
|
+
loadedTexture.needsUpdate = true;
|
|
10222
|
+
setTexture(loadedTexture);
|
|
10223
|
+
},
|
|
10224
|
+
void 0,
|
|
10225
|
+
(error) => {
|
|
10226
|
+
if (active) {
|
|
10227
|
+
setTexture(null);
|
|
10228
|
+
onErrorRef.current?.(error);
|
|
10229
|
+
}
|
|
10230
|
+
}
|
|
10231
|
+
);
|
|
10232
|
+
return () => {
|
|
10233
|
+
active = false;
|
|
10234
|
+
};
|
|
10235
|
+
}, [anisotropy, url]);
|
|
10236
|
+
(0, import_react37.useEffect)(
|
|
10237
|
+
() => () => {
|
|
10238
|
+
texture?.dispose();
|
|
10239
|
+
},
|
|
10240
|
+
[texture]
|
|
10241
|
+
);
|
|
10242
|
+
return texture;
|
|
10243
|
+
}
|
|
10244
|
+
function useManagedTexture(manager, key, url, address) {
|
|
10245
|
+
const [managedState, setManagedState] = (0, import_react37.useState)(() => ({
|
|
10246
|
+
manager,
|
|
10247
|
+
key,
|
|
10248
|
+
url,
|
|
10249
|
+
snapshot: manager.getSnapshot(key)
|
|
10250
|
+
}));
|
|
10251
|
+
const snapshot = managedState.manager === manager && managedState.key === key && managedState.url === url ? managedState.snapshot : manager.getSnapshot(key);
|
|
10252
|
+
(0, import_react37.useEffect)(
|
|
10253
|
+
() => manager.acquire(key, url, address, (nextSnapshot) => {
|
|
10254
|
+
setManagedState({
|
|
10255
|
+
manager,
|
|
10256
|
+
key,
|
|
10257
|
+
url,
|
|
10258
|
+
snapshot: nextSnapshot
|
|
10259
|
+
});
|
|
10260
|
+
}),
|
|
10261
|
+
[key, manager, url]
|
|
10262
|
+
);
|
|
10263
|
+
return snapshot;
|
|
10264
|
+
}
|
|
10265
|
+
|
|
10266
|
+
// src/sphere-tile/layout.ts
|
|
10267
|
+
var import_three13 = require("three");
|
|
10268
|
+
function positiveInteger(value, name) {
|
|
10269
|
+
if (!Number.isSafeInteger(value) || value <= 0) {
|
|
10270
|
+
throw new Error(`${name} must be a positive safe integer`);
|
|
10271
|
+
}
|
|
10272
|
+
return value;
|
|
10273
|
+
}
|
|
10274
|
+
function parseSphereMultires(input) {
|
|
10275
|
+
const parts = typeof input === "string" ? input.split(",").map((part) => part.trim()) : null;
|
|
10276
|
+
const tileSize = positiveInteger(
|
|
10277
|
+
parts ? Number(parts[0]) : input.tileSize,
|
|
10278
|
+
"tileSize"
|
|
10279
|
+
);
|
|
10280
|
+
const levels = parts ? parts.slice(1).map((part) => {
|
|
10281
|
+
const match = /^(\d+)\s*x\s*(\d+)$/i.exec(part);
|
|
10282
|
+
if (!match)
|
|
10283
|
+
throw new Error("sphere multires levels must use widthxheight");
|
|
10284
|
+
return { width: Number(match[1]), height: Number(match[2]) };
|
|
10285
|
+
}) : input.levels.map((level) => ({ ...level }));
|
|
10286
|
+
if (levels.length === 0)
|
|
10287
|
+
throw new Error("sphere multires needs at least one level");
|
|
10288
|
+
levels.forEach((level, index) => {
|
|
10289
|
+
positiveInteger(level.width, "level width");
|
|
10290
|
+
positiveInteger(level.height, "level height");
|
|
10291
|
+
if (Math.abs(level.width - level.height * 2) > 2)
|
|
10292
|
+
throw new Error("sphere levels must be full 2:1 equirectangular images");
|
|
10293
|
+
const previous = levels[index - 1];
|
|
10294
|
+
if (previous && (level.width <= previous.width || level.height <= previous.height)) {
|
|
10295
|
+
throw new Error("sphere multires dimensions must be strictly ascending");
|
|
10296
|
+
}
|
|
10297
|
+
});
|
|
10298
|
+
return { tileSize, levels };
|
|
10299
|
+
}
|
|
10300
|
+
function resolveSphereTemplateUrl(template, address, indexBase = 1) {
|
|
10301
|
+
return template.replace(/%l/g, String(address.level + indexBase)).replace(
|
|
10302
|
+
/%(0*)([hxucvywr])/g,
|
|
10303
|
+
(_match, zeroes, placeholder) => String(
|
|
10304
|
+
("hxuc".includes(placeholder) ? address.col : address.row) + indexBase
|
|
10305
|
+
).padStart(zeroes.length + 1, "0")
|
|
10306
|
+
);
|
|
10307
|
+
}
|
|
10308
|
+
function sphereTileKey(address) {
|
|
10309
|
+
return `${address.level}/${address.row}/${address.col}`;
|
|
10310
|
+
}
|
|
10311
|
+
function sphereTileAddresses(size, level, tileSize) {
|
|
10312
|
+
const addresses = [];
|
|
10313
|
+
for (let row = 0; row < Math.ceil(size.height / tileSize); row++) {
|
|
10314
|
+
for (let col = 0; col < Math.ceil(size.width / tileSize); col++) {
|
|
10315
|
+
addresses.push({
|
|
10316
|
+
level,
|
|
10317
|
+
col,
|
|
10318
|
+
row,
|
|
10319
|
+
imageWidth: size.width,
|
|
10320
|
+
imageHeight: size.height,
|
|
10321
|
+
tileSize,
|
|
10322
|
+
width: Math.min(tileSize, size.width - col * tileSize),
|
|
10323
|
+
height: Math.min(tileSize, size.height - row * tileSize)
|
|
10324
|
+
});
|
|
10325
|
+
}
|
|
10326
|
+
}
|
|
10327
|
+
return addresses;
|
|
10328
|
+
}
|
|
10329
|
+
function sphereTileRange(address) {
|
|
10330
|
+
return {
|
|
10331
|
+
left: address.col * address.tileSize / address.imageWidth,
|
|
10332
|
+
right: (address.col * address.tileSize + address.width) / address.imageWidth,
|
|
10333
|
+
top: address.row * address.tileSize / address.imageHeight,
|
|
10334
|
+
bottom: (address.row * address.tileSize + address.height) / address.imageHeight
|
|
10335
|
+
};
|
|
10336
|
+
}
|
|
10337
|
+
function spherePoint(u, v, yawOffset = 0, radius = DEFAULT_PANORAMA_RADIUS) {
|
|
10338
|
+
const yaw = (u - 0.5) * Math.PI * 2 + import_three13.MathUtils.degToRad(yawOffset);
|
|
10339
|
+
const pitch = (0.5 - v) * Math.PI;
|
|
10340
|
+
return new import_three13.Vector3(
|
|
10341
|
+
Math.sin(yaw) * Math.cos(pitch) * radius,
|
|
10342
|
+
Math.sin(pitch) * radius,
|
|
10343
|
+
-Math.cos(yaw) * Math.cos(pitch) * radius
|
|
10344
|
+
);
|
|
10345
|
+
}
|
|
10346
|
+
function sphereTileBounds(address, yawOffset) {
|
|
10347
|
+
const { left, right, top, bottom } = sphereTileRange(address);
|
|
10348
|
+
const us = [left, right];
|
|
10349
|
+
for (let i = -4; i <= 8; i++) {
|
|
10350
|
+
const u = 0.5 + (i * 90 - yawOffset % 360) / 360;
|
|
10351
|
+
if (u > left && u < right) us.push(u);
|
|
10352
|
+
}
|
|
10353
|
+
const vs = top < 0.5 && bottom > 0.5 ? [top, 0.5, bottom] : [top, bottom];
|
|
10354
|
+
return new import_three13.Box3().setFromPoints(
|
|
10355
|
+
us.flatMap((u) => vs.map((v) => spherePoint(u, v, yawOffset)))
|
|
10356
|
+
);
|
|
10357
|
+
}
|
|
10358
|
+
function sphereTileGeometry(address, yawOffset, radius = DEFAULT_PANORAMA_RADIUS) {
|
|
10359
|
+
const { left, right, top, bottom } = sphereTileRange(address);
|
|
10360
|
+
const columns = Math.max(2, Math.ceil((right - left) * 360 / 3));
|
|
10361
|
+
const rows = Math.max(2, Math.ceil((bottom - top) * 180 / 3));
|
|
10362
|
+
const positions = [], uvs = [], indices = [];
|
|
10363
|
+
for (let row = 0; row <= rows; row++) {
|
|
10364
|
+
for (let col = 0; col <= columns; col++) {
|
|
10365
|
+
const u = col / columns, v = row / rows;
|
|
10366
|
+
const point = spherePoint(
|
|
10367
|
+
left + (right - left) * u,
|
|
10368
|
+
top + (bottom - top) * v,
|
|
10369
|
+
yawOffset,
|
|
10370
|
+
radius
|
|
10371
|
+
);
|
|
10372
|
+
positions.push(point.x, point.y, point.z);
|
|
10373
|
+
uvs.push(u, 1 - v);
|
|
10374
|
+
if (row < rows && col < columns) {
|
|
10375
|
+
const a = row * (columns + 1) + col, b = a + 1, c = a + columns + 1, d = c + 1;
|
|
10376
|
+
indices.push(a, b, c, b, d, c);
|
|
10377
|
+
}
|
|
10378
|
+
}
|
|
10379
|
+
}
|
|
10380
|
+
const geometry = new import_three13.BufferGeometry();
|
|
10381
|
+
geometry.setAttribute("position", new import_three13.Float32BufferAttribute(positions, 3));
|
|
10382
|
+
geometry.setAttribute("uv", new import_three13.Float32BufferAttribute(uvs, 2));
|
|
10383
|
+
geometry.setIndex(indices);
|
|
10384
|
+
geometry.computeBoundingSphere();
|
|
10385
|
+
return geometry;
|
|
10386
|
+
}
|
|
10387
|
+
function preferredSphereLevel(levels, height, dpr, verticalFov) {
|
|
10388
|
+
const needed = height * dpr * 180 / Math.max(1, verticalFov);
|
|
10389
|
+
const index = levels.findIndex((level) => level.height >= needed);
|
|
10390
|
+
return index < 0 ? levels.length - 1 : index;
|
|
10391
|
+
}
|
|
10392
|
+
|
|
10393
|
+
// src/sphere-tile/sphere-tile.tsx
|
|
10394
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
10395
|
+
function SpherePatch({
|
|
10396
|
+
address,
|
|
10397
|
+
texture,
|
|
10398
|
+
yawOffset,
|
|
10399
|
+
preview = false
|
|
10400
|
+
}) {
|
|
10401
|
+
const geometry = (0, import_react38.useMemo)(
|
|
10402
|
+
() => sphereTileGeometry(
|
|
10403
|
+
address,
|
|
10404
|
+
yawOffset,
|
|
10405
|
+
DEFAULT_PANORAMA_RADIUS + (preview ? 0.05 : 0)
|
|
10406
|
+
),
|
|
10407
|
+
[address, yawOffset, preview]
|
|
10408
|
+
);
|
|
10409
|
+
(0, import_react38.useEffect)(() => () => geometry.dispose(), [geometry]);
|
|
10410
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
10411
|
+
"mesh",
|
|
10412
|
+
{
|
|
10413
|
+
geometry,
|
|
10414
|
+
renderOrder: preview ? -1e3 : -900 + address.level,
|
|
10415
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
10416
|
+
PanoBasicMaterial,
|
|
10417
|
+
{
|
|
10418
|
+
map: texture,
|
|
10419
|
+
side: import_three14.BackSide,
|
|
10420
|
+
depthTest: false,
|
|
10421
|
+
depthWrite: false,
|
|
10422
|
+
toneMapped: false
|
|
10423
|
+
}
|
|
10424
|
+
)
|
|
10425
|
+
}
|
|
10426
|
+
);
|
|
10427
|
+
}
|
|
10428
|
+
var ManagedPatch = (0, import_react38.memo)(function ManagedPatch2({
|
|
10429
|
+
address,
|
|
10430
|
+
manager,
|
|
10431
|
+
resolveUrl,
|
|
10432
|
+
yawOffset,
|
|
10433
|
+
ready
|
|
10434
|
+
}) {
|
|
10435
|
+
const url = resolveUrl(address);
|
|
10436
|
+
const snapshot = useManagedTexture(
|
|
10437
|
+
manager,
|
|
10438
|
+
`${url}\0${sphereTileKey(address)}`,
|
|
10439
|
+
url,
|
|
10440
|
+
address
|
|
10441
|
+
);
|
|
10442
|
+
(0, import_react38.useEffect)(() => {
|
|
10443
|
+
if (snapshot.texture) ready();
|
|
10444
|
+
}, [snapshot.texture, ready]);
|
|
10445
|
+
return snapshot.texture ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
10446
|
+
SpherePatch,
|
|
10447
|
+
{
|
|
10448
|
+
address,
|
|
10449
|
+
texture: snapshot.texture,
|
|
10450
|
+
yawOffset
|
|
10451
|
+
}
|
|
10452
|
+
) : null;
|
|
10453
|
+
});
|
|
10454
|
+
function SphereTileSource({
|
|
10455
|
+
config,
|
|
10456
|
+
baseUrl,
|
|
10457
|
+
previewUrl,
|
|
10458
|
+
urlTemplate = "tiles/%l/%h_%v.webp",
|
|
10459
|
+
indexBase = 1,
|
|
10460
|
+
resolveTileUrl,
|
|
10461
|
+
yawOffset = 0,
|
|
10462
|
+
maxTextureMemoryMb = 128,
|
|
10463
|
+
maxConcurrentLoads = 4,
|
|
10464
|
+
retryCount = 1,
|
|
10465
|
+
loadMode = "full",
|
|
10466
|
+
visible = true,
|
|
10467
|
+
onReady,
|
|
10468
|
+
onPreviewError,
|
|
10469
|
+
onLoadProgress,
|
|
10470
|
+
onTileError,
|
|
10471
|
+
onLevelChange
|
|
10472
|
+
}) {
|
|
10473
|
+
const { camera, gl, size } = (0, import_fiber15.useThree)();
|
|
10474
|
+
const anisotropy = gl.capabilities.getMaxAnisotropy();
|
|
10475
|
+
const preview = usePreviewTexture(
|
|
10476
|
+
resolveAssetUrl(baseUrl, previewUrl),
|
|
10477
|
+
anisotropy,
|
|
10478
|
+
onPreviewError
|
|
10479
|
+
);
|
|
10480
|
+
const callbacks = (0, import_react38.useRef)({
|
|
10481
|
+
onReady,
|
|
10482
|
+
onLoadProgress,
|
|
10483
|
+
onTileError,
|
|
10484
|
+
onLevelChange
|
|
10485
|
+
});
|
|
10486
|
+
callbacks.current = { onReady, onLoadProgress, onTileError, onLevelChange };
|
|
10487
|
+
const budget = Math.max(
|
|
10488
|
+
1,
|
|
10489
|
+
Number.isFinite(maxTextureMemoryMb) ? maxTextureMemoryMb : 128
|
|
10490
|
+
) * 1024 * 1024;
|
|
10491
|
+
const manager = (0, import_react38.useMemo)(
|
|
10492
|
+
() => new TileTextureManager({
|
|
10493
|
+
anisotropy,
|
|
10494
|
+
maxBytes: budget,
|
|
10495
|
+
concurrency: Math.max(
|
|
10496
|
+
1,
|
|
10497
|
+
Math.floor(
|
|
10498
|
+
Number.isFinite(maxConcurrentLoads) ? maxConcurrentLoads : 4
|
|
10499
|
+
)
|
|
10500
|
+
),
|
|
10501
|
+
retryCount: Math.max(
|
|
10502
|
+
0,
|
|
10503
|
+
Math.floor(Number.isFinite(retryCount) ? retryCount : 1)
|
|
10504
|
+
),
|
|
10505
|
+
onProgress: (progress) => callbacks.current.onLoadProgress?.(progress),
|
|
10506
|
+
onError: (error) => callbacks.current.onTileError?.(error)
|
|
10507
|
+
}),
|
|
10508
|
+
[anisotropy, budget, maxConcurrentLoads, retryCount]
|
|
10509
|
+
);
|
|
10510
|
+
const readyRef = (0, import_react38.useRef)(false);
|
|
10511
|
+
const ready = (0, import_react38.useCallback)(() => {
|
|
10512
|
+
if (!readyRef.current) {
|
|
10513
|
+
readyRef.current = true;
|
|
10514
|
+
callbacks.current.onReady?.();
|
|
10515
|
+
}
|
|
10516
|
+
}, []);
|
|
10517
|
+
(0, import_react38.useEffect)(() => {
|
|
10518
|
+
if (preview) ready();
|
|
10519
|
+
}, [preview, ready]);
|
|
10520
|
+
(0, import_react38.useEffect)(() => {
|
|
10521
|
+
manager.resume();
|
|
10522
|
+
return () => manager.dispose();
|
|
10523
|
+
}, [manager]);
|
|
10524
|
+
const resolveUrl = (0, import_react38.useMemo)(
|
|
10525
|
+
() => (address) => resolveAssetUrl(
|
|
10526
|
+
baseUrl,
|
|
10527
|
+
resolveTileUrl ? resolveTileUrl(address) : resolveSphereTemplateUrl(urlTemplate, address, indexBase)
|
|
10528
|
+
),
|
|
10529
|
+
[baseUrl, resolveTileUrl, urlTemplate, indexBase]
|
|
10530
|
+
);
|
|
10531
|
+
const candidates = (0, import_react38.useMemo)(
|
|
10532
|
+
() => config.levels.map(
|
|
10533
|
+
(level, index) => sphereTileAddresses(level, index, config.tileSize).map((address) => ({
|
|
10534
|
+
address,
|
|
10535
|
+
bounds: sphereTileBounds(address, yawOffset)
|
|
10536
|
+
}))
|
|
10537
|
+
),
|
|
10538
|
+
[config, yawOffset]
|
|
10539
|
+
);
|
|
10540
|
+
const previewAddress = (0, import_react38.useMemo)(
|
|
10541
|
+
() => sphereTileAddresses({ width: 2, height: 1 }, 0, 2)[0],
|
|
10542
|
+
[]
|
|
10543
|
+
);
|
|
10544
|
+
const [layers, setLayers] = (0, import_react38.useState)([]);
|
|
10545
|
+
const scratch = (0, import_react38.useMemo)(
|
|
10546
|
+
() => ({
|
|
10547
|
+
camera: new import_three14.PerspectiveCamera(),
|
|
10548
|
+
frustum: new import_three14.Frustum(),
|
|
10549
|
+
matrix: new import_three14.Matrix4(),
|
|
10550
|
+
quaternion: camera.quaternion.clone(),
|
|
10551
|
+
fov: NaN,
|
|
10552
|
+
width: 0,
|
|
10553
|
+
height: 0,
|
|
10554
|
+
dpr: 0,
|
|
10555
|
+
time: -Infinity,
|
|
10556
|
+
token: "",
|
|
10557
|
+
level: -1,
|
|
10558
|
+
loadMode: "",
|
|
10559
|
+
manager: null
|
|
10560
|
+
}),
|
|
10561
|
+
[camera, candidates]
|
|
10562
|
+
);
|
|
10563
|
+
(0, import_fiber15.useFrame)(() => {
|
|
10564
|
+
if (!(camera instanceof import_three14.PerspectiveCamera)) return;
|
|
10565
|
+
const now = performance.now(), dpr = gl.getPixelRatio();
|
|
10566
|
+
const reset = scratch.manager !== manager || scratch.loadMode !== loadMode;
|
|
10567
|
+
if (!reset && (now - scratch.time < 100 || scratch.fov === camera.fov && scratch.width === size.width && scratch.height === size.height && scratch.dpr === dpr && scratch.quaternion.angleTo(camera.quaternion) < 1e-4))
|
|
10568
|
+
return;
|
|
10569
|
+
scratch.time = now;
|
|
10570
|
+
scratch.fov = camera.fov;
|
|
10571
|
+
scratch.width = size.width;
|
|
10572
|
+
scratch.height = size.height;
|
|
10573
|
+
scratch.dpr = dpr;
|
|
10574
|
+
scratch.quaternion.copy(camera.quaternion);
|
|
10575
|
+
scratch.manager = manager;
|
|
10576
|
+
scratch.loadMode = loadMode;
|
|
10577
|
+
scratch.camera.copy(camera, false);
|
|
10578
|
+
scratch.camera.fov = Math.min(179, camera.fov + 8);
|
|
10579
|
+
scratch.camera.updateProjectionMatrix();
|
|
10580
|
+
scratch.camera.updateMatrixWorld();
|
|
10581
|
+
scratch.matrix.multiplyMatrices(
|
|
10582
|
+
scratch.camera.projectionMatrix,
|
|
10583
|
+
scratch.camera.matrixWorldInverse
|
|
10584
|
+
);
|
|
10585
|
+
scratch.frustum.setFromProjectionMatrix(scratch.matrix);
|
|
10586
|
+
let level = loadMode === "preview" ? -1 : loadMode === "base" ? 0 : preferredSphereLevel(config.levels, size.height, dpr, camera.fov);
|
|
10587
|
+
const next = [];
|
|
10588
|
+
let residentBytes = 0;
|
|
10589
|
+
for (let index = 0; index <= level; index++) {
|
|
10590
|
+
const addresses = candidates[index].filter(
|
|
10591
|
+
({ bounds }) => scratch.frustum.intersectsBox(bounds)
|
|
10592
|
+
).map(({ address }) => address);
|
|
10593
|
+
const bytes = addresses.reduce(
|
|
10594
|
+
(total, address) => total + address.width * address.height * 4,
|
|
10595
|
+
0
|
|
10596
|
+
);
|
|
10597
|
+
if (residentBytes + bytes > budget) {
|
|
10598
|
+
level = index - 1;
|
|
10599
|
+
break;
|
|
10600
|
+
}
|
|
10601
|
+
residentBytes += bytes;
|
|
10602
|
+
next.push({ level: index, addresses });
|
|
10603
|
+
}
|
|
10604
|
+
if (level !== scratch.level) {
|
|
10605
|
+
scratch.level = level;
|
|
10606
|
+
if (level >= 0) callbacks.current.onLevelChange?.(level);
|
|
10607
|
+
}
|
|
10608
|
+
const token = next.map((layer) => layer.addresses.map(sphereTileKey).join(",")).join(";");
|
|
10609
|
+
if (token !== scratch.token || reset) {
|
|
10610
|
+
scratch.token = token;
|
|
10611
|
+
setLayers(next);
|
|
10612
|
+
}
|
|
10613
|
+
});
|
|
10614
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("group", { visible, children: [
|
|
10615
|
+
preview ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
10616
|
+
SpherePatch,
|
|
10617
|
+
{
|
|
10618
|
+
address: previewAddress,
|
|
10619
|
+
texture: preview,
|
|
10620
|
+
yawOffset,
|
|
10621
|
+
preview: true
|
|
10622
|
+
}
|
|
10623
|
+
) : null,
|
|
10624
|
+
loadMode !== "preview" ? layers.flatMap(
|
|
10625
|
+
(layer) => layer.addresses.map((address) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
10626
|
+
ManagedPatch,
|
|
10627
|
+
{
|
|
10628
|
+
address,
|
|
10629
|
+
manager,
|
|
10630
|
+
resolveUrl,
|
|
10631
|
+
yawOffset,
|
|
10632
|
+
ready
|
|
10633
|
+
},
|
|
10634
|
+
sphereTileKey(address)
|
|
10635
|
+
))
|
|
10636
|
+
) : null
|
|
10637
|
+
] });
|
|
10638
|
+
}
|
|
10639
|
+
function SphereTile({ multires, ...props }) {
|
|
10640
|
+
const token = typeof multires === "string" ? multires : JSON.stringify(multires);
|
|
10641
|
+
const config = (0, import_react38.useMemo)(() => parseSphereMultires(multires), [token]);
|
|
10642
|
+
const sourceKey = `${props.baseUrl}\0${token}\0${props.previewUrl}\0${props.urlTemplate ?? ""}\0${props.indexBase ?? 1}`;
|
|
10643
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(SphereTileSource, { ...props, config }, sourceKey);
|
|
10644
|
+
}
|
|
10645
|
+
|
|
10646
|
+
// src/sphere.tsx
|
|
10647
|
+
var import_fiber16 = require("@react-three/fiber");
|
|
10648
|
+
var import_react39 = require("react");
|
|
10649
|
+
var import_three15 = require("three");
|
|
10650
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
10651
|
+
function useEquirectTexture(url, anisotropy, generateMipmaps, onLoad, onError) {
|
|
10652
|
+
const [texture, setTexture] = (0, import_react39.useState)(null);
|
|
10653
|
+
const onLoadRef = (0, import_react39.useRef)(onLoad);
|
|
10654
|
+
const onErrorRef = (0, import_react39.useRef)(onError);
|
|
10655
|
+
onLoadRef.current = onLoad;
|
|
10656
|
+
onErrorRef.current = onError;
|
|
10657
|
+
(0, import_react39.useEffect)(() => {
|
|
10658
|
+
if (!url) {
|
|
10659
|
+
setTexture(null);
|
|
10660
|
+
return;
|
|
10661
|
+
}
|
|
10662
|
+
let active = true;
|
|
10663
|
+
const loader = new import_three15.TextureLoader();
|
|
10664
|
+
setTexture(null);
|
|
10665
|
+
loader.load(
|
|
10666
|
+
url,
|
|
10667
|
+
(loadedTexture) => {
|
|
10668
|
+
if (!active) {
|
|
10669
|
+
loadedTexture.dispose();
|
|
10670
|
+
return;
|
|
10671
|
+
}
|
|
10672
|
+
loadedTexture.colorSpace = import_three15.SRGBColorSpace;
|
|
10673
|
+
loadedTexture.wrapS = import_three15.RepeatWrapping;
|
|
10674
|
+
loadedTexture.repeat.x = -1;
|
|
10675
|
+
loadedTexture.offset.x = 1;
|
|
10676
|
+
loadedTexture.anisotropy = anisotropy;
|
|
10677
|
+
loadedTexture.magFilter = import_three15.LinearFilter;
|
|
10678
|
+
loadedTexture.minFilter = generateMipmaps ? import_three15.LinearMipmapLinearFilter : import_three15.LinearFilter;
|
|
10679
|
+
loadedTexture.generateMipmaps = generateMipmaps;
|
|
9958
10680
|
loadedTexture.needsUpdate = true;
|
|
9959
10681
|
setTexture(loadedTexture);
|
|
9960
10682
|
onLoadRef.current?.(loadedTexture);
|
|
@@ -9971,7 +10693,7 @@ function useEquirectTexture(url, anisotropy, generateMipmaps, onLoad, onError) {
|
|
|
9971
10693
|
active = false;
|
|
9972
10694
|
};
|
|
9973
10695
|
}, [anisotropy, generateMipmaps, url]);
|
|
9974
|
-
(0,
|
|
10696
|
+
(0, import_react39.useEffect)(
|
|
9975
10697
|
() => () => {
|
|
9976
10698
|
texture?.dispose();
|
|
9977
10699
|
},
|
|
@@ -9989,9 +10711,9 @@ function Sphere({
|
|
|
9989
10711
|
onPreviewError,
|
|
9990
10712
|
visible = true
|
|
9991
10713
|
}) {
|
|
9992
|
-
const gl = (0,
|
|
10714
|
+
const gl = (0, import_fiber16.useThree)((state) => state.gl);
|
|
9993
10715
|
const anisotropy = gl.capabilities.getMaxAnisotropy();
|
|
9994
|
-
const resolvedPreviewUrl = (0,
|
|
10716
|
+
const resolvedPreviewUrl = (0, import_react39.useMemo)(
|
|
9995
10717
|
() => resolveUrlAgainstFile(src, previewUrl),
|
|
9996
10718
|
[previewUrl, src]
|
|
9997
10719
|
);
|
|
@@ -10010,11 +10732,11 @@ function Sphere({
|
|
|
10010
10732
|
onPreviewError
|
|
10011
10733
|
);
|
|
10012
10734
|
const displayTexture = texture ?? previewTexture;
|
|
10013
|
-
const readyRef = (0,
|
|
10014
|
-
(0,
|
|
10735
|
+
const readyRef = (0, import_react39.useRef)(false);
|
|
10736
|
+
(0, import_react39.useEffect)(() => {
|
|
10015
10737
|
readyRef.current = false;
|
|
10016
10738
|
}, [resolvedPreviewUrl, src]);
|
|
10017
|
-
(0,
|
|
10739
|
+
(0, import_react39.useEffect)(() => {
|
|
10018
10740
|
if (!displayTexture || readyRef.current) {
|
|
10019
10741
|
return;
|
|
10020
10742
|
}
|
|
@@ -10024,18 +10746,18 @@ function Sphere({
|
|
|
10024
10746
|
if (!displayTexture) {
|
|
10025
10747
|
return null;
|
|
10026
10748
|
}
|
|
10027
|
-
return /* @__PURE__ */ (0,
|
|
10749
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
10028
10750
|
"mesh",
|
|
10029
10751
|
{
|
|
10030
|
-
rotation: [0,
|
|
10752
|
+
rotation: [0, import_three15.MathUtils.degToRad(90 + yawOffset), 0],
|
|
10031
10753
|
visible,
|
|
10032
10754
|
children: [
|
|
10033
|
-
/* @__PURE__ */ (0,
|
|
10034
|
-
/* @__PURE__ */ (0,
|
|
10755
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("sphereGeometry", { args: [DEFAULT_PANORAMA_RADIUS, 128, 64] }),
|
|
10756
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
10035
10757
|
PanoBasicMaterial,
|
|
10036
10758
|
{
|
|
10037
10759
|
map: displayTexture,
|
|
10038
|
-
side:
|
|
10760
|
+
side: import_three15.BackSide,
|
|
10039
10761
|
toneMapped: false
|
|
10040
10762
|
}
|
|
10041
10763
|
)
|
|
@@ -10045,10 +10767,10 @@ function Sphere({
|
|
|
10045
10767
|
}
|
|
10046
10768
|
|
|
10047
10769
|
// src/video/pano-video.tsx
|
|
10048
|
-
var
|
|
10049
|
-
var
|
|
10050
|
-
var
|
|
10051
|
-
var
|
|
10770
|
+
var import_fiber17 = require("@react-three/fiber");
|
|
10771
|
+
var import_react40 = require("react");
|
|
10772
|
+
var import_three16 = require("three");
|
|
10773
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
10052
10774
|
var EMPTY_TRACKS = [];
|
|
10053
10775
|
var EMPTY_RATES = DEFAULT_PANO_VIDEO_PLAYBACK_RATES;
|
|
10054
10776
|
function createEmptySnapshot() {
|
|
@@ -10124,19 +10846,19 @@ function findTextTrack(video, tracks, trackId) {
|
|
|
10124
10846
|
return list.length > 0 ? list[0] : null;
|
|
10125
10847
|
}
|
|
10126
10848
|
function applyEquirectangularLayout(texture, anisotropy) {
|
|
10127
|
-
texture.colorSpace =
|
|
10128
|
-
texture.wrapS =
|
|
10849
|
+
texture.colorSpace = import_three16.SRGBColorSpace;
|
|
10850
|
+
texture.wrapS = import_three16.RepeatWrapping;
|
|
10129
10851
|
texture.repeat.x = -1;
|
|
10130
10852
|
texture.offset.x = 1;
|
|
10131
10853
|
texture.anisotropy = anisotropy;
|
|
10132
10854
|
texture.needsUpdate = true;
|
|
10133
10855
|
}
|
|
10134
10856
|
function usePosterTexture(poster, onError) {
|
|
10135
|
-
const gl = (0,
|
|
10136
|
-
const [texture, setTexture] = (0,
|
|
10137
|
-
const onErrorRef = (0,
|
|
10857
|
+
const gl = (0, import_fiber17.useThree)((state) => state.gl);
|
|
10858
|
+
const [texture, setTexture] = (0, import_react40.useState)(null);
|
|
10859
|
+
const onErrorRef = (0, import_react40.useRef)(onError);
|
|
10138
10860
|
onErrorRef.current = onError;
|
|
10139
|
-
(0,
|
|
10861
|
+
(0, import_react40.useEffect)(() => {
|
|
10140
10862
|
let active = true;
|
|
10141
10863
|
setTexture(null);
|
|
10142
10864
|
if (!poster) {
|
|
@@ -10144,7 +10866,7 @@ function usePosterTexture(poster, onError) {
|
|
|
10144
10866
|
active = false;
|
|
10145
10867
|
};
|
|
10146
10868
|
}
|
|
10147
|
-
const loader = new
|
|
10869
|
+
const loader = new import_three16.TextureLoader();
|
|
10148
10870
|
loader.load(
|
|
10149
10871
|
poster,
|
|
10150
10872
|
(loadedTexture) => {
|
|
@@ -10156,9 +10878,9 @@ function usePosterTexture(poster, onError) {
|
|
|
10156
10878
|
loadedTexture,
|
|
10157
10879
|
gl.capabilities.getMaxAnisotropy()
|
|
10158
10880
|
);
|
|
10159
|
-
loadedTexture.wrapT =
|
|
10160
|
-
loadedTexture.magFilter =
|
|
10161
|
-
loadedTexture.minFilter =
|
|
10881
|
+
loadedTexture.wrapT = import_three16.RepeatWrapping;
|
|
10882
|
+
loadedTexture.magFilter = import_three16.LinearFilter;
|
|
10883
|
+
loadedTexture.minFilter = import_three16.LinearMipmapLinearFilter;
|
|
10162
10884
|
loadedTexture.generateMipmaps = true;
|
|
10163
10885
|
setTexture(loadedTexture);
|
|
10164
10886
|
},
|
|
@@ -10173,7 +10895,7 @@ function usePosterTexture(poster, onError) {
|
|
|
10173
10895
|
active = false;
|
|
10174
10896
|
};
|
|
10175
10897
|
}, [gl, poster]);
|
|
10176
|
-
(0,
|
|
10898
|
+
(0, import_react40.useEffect)(
|
|
10177
10899
|
() => () => {
|
|
10178
10900
|
texture?.dispose();
|
|
10179
10901
|
},
|
|
@@ -10231,39 +10953,39 @@ function PanoVideo({
|
|
|
10231
10953
|
onTrackChange
|
|
10232
10954
|
}) {
|
|
10233
10955
|
usePanoMediaActivationIntent(autoPlay);
|
|
10234
|
-
const gl = (0,
|
|
10235
|
-
const host = (0,
|
|
10236
|
-
const overlay = (0,
|
|
10237
|
-
const variants = (0,
|
|
10956
|
+
const gl = (0, import_fiber17.useThree)((state) => state.gl);
|
|
10957
|
+
const host = (0, import_react40.useContext)(PanoVideoHostContext);
|
|
10958
|
+
const overlay = (0, import_react40.useContext)(PanoChromeOverlayContext);
|
|
10959
|
+
const variants = (0, import_react40.useMemo)(
|
|
10238
10960
|
() => resolvePanoVideoVariants({ poster, src, variants: variantsProp }),
|
|
10239
10961
|
[poster, src, variantsProp]
|
|
10240
10962
|
);
|
|
10241
10963
|
const tracks = tracksProp ?? EMPTY_TRACKS;
|
|
10242
10964
|
const captionsEnabled = captions !== false;
|
|
10243
|
-
const captionAppearance = (0,
|
|
10965
|
+
const captionAppearance = (0, import_react40.useMemo)(
|
|
10244
10966
|
() => resolvePanoVideoCaptionAppearance(
|
|
10245
10967
|
typeof captions === "object" ? captions : void 0
|
|
10246
10968
|
),
|
|
10247
10969
|
[captions]
|
|
10248
10970
|
);
|
|
10249
|
-
const [variantId, setVariantId] = (0,
|
|
10971
|
+
const [variantId, setVariantId] = (0, import_react40.useState)(
|
|
10250
10972
|
() => resolvePanoVideoVariantId(variants, defaultVariantId)
|
|
10251
10973
|
);
|
|
10252
|
-
const [trackId, setTrackId] = (0,
|
|
10974
|
+
const [trackId, setTrackId] = (0, import_react40.useState)(
|
|
10253
10975
|
() => captionsEnabled ? defaultPanoVideoTrackId(tracks) : null
|
|
10254
10976
|
);
|
|
10255
|
-
const [ready, setReady] = (0,
|
|
10256
|
-
const autoPlayRef = (0,
|
|
10977
|
+
const [ready, setReady] = (0, import_react40.useState)(false);
|
|
10978
|
+
const autoPlayRef = (0, import_react40.useRef)(autoPlay);
|
|
10257
10979
|
autoPlayRef.current = autoPlay;
|
|
10258
|
-
const blockedRef = (0,
|
|
10259
|
-
const captionAppearanceOverrideRef = (0,
|
|
10980
|
+
const blockedRef = (0, import_react40.useRef)(false);
|
|
10981
|
+
const captionAppearanceOverrideRef = (0, import_react40.useRef)(
|
|
10260
10982
|
{}
|
|
10261
10983
|
);
|
|
10262
|
-
const mediaCapabilitiesRef = (0,
|
|
10984
|
+
const mediaCapabilitiesRef = (0, import_react40.useRef)({
|
|
10263
10985
|
volumeAdjustable: true,
|
|
10264
10986
|
playbackRates: [...DEFAULT_PANO_VIDEO_PLAYBACK_RATES]
|
|
10265
10987
|
});
|
|
10266
|
-
const storeRef = (0,
|
|
10988
|
+
const storeRef = (0, import_react40.useRef)(null);
|
|
10267
10989
|
if (!storeRef.current) {
|
|
10268
10990
|
storeRef.current = {
|
|
10269
10991
|
snapshot: {
|
|
@@ -10273,7 +10995,7 @@ function PanoVideo({
|
|
|
10273
10995
|
listeners: /* @__PURE__ */ new Set()
|
|
10274
10996
|
};
|
|
10275
10997
|
}
|
|
10276
|
-
const actionsRef = (0,
|
|
10998
|
+
const actionsRef = (0, import_react40.useRef)({
|
|
10277
10999
|
play: async () => {
|
|
10278
11000
|
},
|
|
10279
11001
|
pause: () => {
|
|
@@ -10293,19 +11015,19 @@ function PanoVideo({
|
|
|
10293
11015
|
setCaptionAppearance: (_appearance) => {
|
|
10294
11016
|
}
|
|
10295
11017
|
});
|
|
10296
|
-
const onLoadRef = (0,
|
|
10297
|
-
const onErrorRef = (0,
|
|
10298
|
-
const onPlaybackStateChangeRef = (0,
|
|
10299
|
-
const onEndedRef = (0,
|
|
10300
|
-
const onVariantChangeRef = (0,
|
|
10301
|
-
const onTrackChangeRef = (0,
|
|
11018
|
+
const onLoadRef = (0, import_react40.useRef)(onLoad);
|
|
11019
|
+
const onErrorRef = (0, import_react40.useRef)(onError);
|
|
11020
|
+
const onPlaybackStateChangeRef = (0, import_react40.useRef)(onPlaybackStateChange);
|
|
11021
|
+
const onEndedRef = (0, import_react40.useRef)(onEnded);
|
|
11022
|
+
const onVariantChangeRef = (0, import_react40.useRef)(onVariantChange);
|
|
11023
|
+
const onTrackChangeRef = (0, import_react40.useRef)(onTrackChange);
|
|
10302
11024
|
onLoadRef.current = onLoad;
|
|
10303
11025
|
onErrorRef.current = onError;
|
|
10304
11026
|
onPlaybackStateChangeRef.current = onPlaybackStateChange;
|
|
10305
11027
|
onEndedRef.current = onEnded;
|
|
10306
11028
|
onVariantChangeRef.current = onVariantChange;
|
|
10307
11029
|
onTrackChangeRef.current = onTrackChange;
|
|
10308
|
-
const resource = (0,
|
|
11030
|
+
const resource = (0, import_react40.useMemo)(() => {
|
|
10309
11031
|
if (typeof document === "undefined") {
|
|
10310
11032
|
return null;
|
|
10311
11033
|
}
|
|
@@ -10315,14 +11037,14 @@ function PanoVideo({
|
|
|
10315
11037
|
video.setAttribute("playsinline", "true");
|
|
10316
11038
|
video.setAttribute("webkit-playsinline", "true");
|
|
10317
11039
|
video.preload = "metadata";
|
|
10318
|
-
const texture = new
|
|
11040
|
+
const texture = new import_three16.VideoTexture(video);
|
|
10319
11041
|
applyEquirectangularLayout(texture, 1);
|
|
10320
|
-
texture.magFilter =
|
|
10321
|
-
texture.minFilter =
|
|
11042
|
+
texture.magFilter = import_three16.LinearFilter;
|
|
11043
|
+
texture.minFilter = import_three16.LinearFilter;
|
|
10322
11044
|
texture.generateMipmaps = false;
|
|
10323
11045
|
return { video, texture };
|
|
10324
11046
|
}, []);
|
|
10325
|
-
(0,
|
|
11047
|
+
(0, import_react40.useEffect)(
|
|
10326
11048
|
() => () => {
|
|
10327
11049
|
if (!resource) {
|
|
10328
11050
|
return;
|
|
@@ -10337,13 +11059,13 @@ function PanoVideo({
|
|
|
10337
11059
|
},
|
|
10338
11060
|
[resource]
|
|
10339
11061
|
);
|
|
10340
|
-
(0,
|
|
11062
|
+
(0, import_react40.useEffect)(() => {
|
|
10341
11063
|
if (!resource) {
|
|
10342
11064
|
return;
|
|
10343
11065
|
}
|
|
10344
11066
|
resource.texture.anisotropy = gl.capabilities.getMaxAnisotropy();
|
|
10345
11067
|
}, [gl, resource]);
|
|
10346
|
-
(0,
|
|
11068
|
+
(0, import_react40.useEffect)(() => {
|
|
10347
11069
|
if (!resource || !overlay?.overlayElement) {
|
|
10348
11070
|
return;
|
|
10349
11071
|
}
|
|
@@ -10366,7 +11088,7 @@ function PanoVideo({
|
|
|
10366
11088
|
activeVariant?.poster ?? poster,
|
|
10367
11089
|
onError
|
|
10368
11090
|
);
|
|
10369
|
-
const emitSnapshot = (0,
|
|
11091
|
+
const emitSnapshot = (0, import_react40.useCallback)(
|
|
10370
11092
|
(patch) => {
|
|
10371
11093
|
const store = storeRef.current;
|
|
10372
11094
|
const video = resource?.video;
|
|
@@ -10418,7 +11140,7 @@ function PanoVideo({
|
|
|
10418
11140
|
captionAppearance
|
|
10419
11141
|
]
|
|
10420
11142
|
);
|
|
10421
|
-
const controller = (0,
|
|
11143
|
+
const controller = (0, import_react40.useMemo)(
|
|
10422
11144
|
() => ({
|
|
10423
11145
|
subscribe: (onStoreChange) => {
|
|
10424
11146
|
const store = storeRef.current;
|
|
@@ -10470,7 +11192,7 @@ function PanoVideo({
|
|
|
10470
11192
|
}),
|
|
10471
11193
|
[]
|
|
10472
11194
|
);
|
|
10473
|
-
(0,
|
|
11195
|
+
(0, import_react40.useLayoutEffect)(() => {
|
|
10474
11196
|
if (!host || variants.length === 0) {
|
|
10475
11197
|
return;
|
|
10476
11198
|
}
|
|
@@ -10483,7 +11205,7 @@ function PanoVideo({
|
|
|
10483
11205
|
notifyPanoVideoHost(host);
|
|
10484
11206
|
};
|
|
10485
11207
|
}, [captionsEnabled, controller, controls, host, variants.length]);
|
|
10486
|
-
(0,
|
|
11208
|
+
(0, import_react40.useLayoutEffect)(() => {
|
|
10487
11209
|
if (!resource) {
|
|
10488
11210
|
return;
|
|
10489
11211
|
}
|
|
@@ -10496,10 +11218,10 @@ function PanoVideo({
|
|
|
10496
11218
|
};
|
|
10497
11219
|
emitSnapshot();
|
|
10498
11220
|
}, [emitSnapshot, playbackRates, resource]);
|
|
10499
|
-
(0,
|
|
11221
|
+
(0, import_react40.useEffect)(() => {
|
|
10500
11222
|
emitSnapshot();
|
|
10501
11223
|
}, [emitSnapshot]);
|
|
10502
|
-
(0,
|
|
11224
|
+
(0, import_react40.useEffect)(() => {
|
|
10503
11225
|
if (!resource || !activeVariant || !mediaKey) {
|
|
10504
11226
|
return;
|
|
10505
11227
|
}
|
|
@@ -10556,7 +11278,7 @@ function PanoVideo({
|
|
|
10556
11278
|
video.removeEventListener("error", handleError);
|
|
10557
11279
|
};
|
|
10558
11280
|
}, [mediaKey, resource]);
|
|
10559
|
-
(0,
|
|
11281
|
+
(0, import_react40.useEffect)(() => {
|
|
10560
11282
|
if (!resource) {
|
|
10561
11283
|
return;
|
|
10562
11284
|
}
|
|
@@ -10648,7 +11370,7 @@ function PanoVideo({
|
|
|
10648
11370
|
}
|
|
10649
11371
|
};
|
|
10650
11372
|
}, [emitSnapshot, resource]);
|
|
10651
|
-
(0,
|
|
11373
|
+
(0, import_react40.useEffect)(() => {
|
|
10652
11374
|
if (!resource) {
|
|
10653
11375
|
return;
|
|
10654
11376
|
}
|
|
@@ -10668,7 +11390,7 @@ function PanoVideo({
|
|
|
10668
11390
|
}
|
|
10669
11391
|
video.preload = preload;
|
|
10670
11392
|
}, [loop, muted, playsInline, preload, resource, volume]);
|
|
10671
|
-
(0,
|
|
11393
|
+
(0, import_react40.useEffect)(() => {
|
|
10672
11394
|
if (!resource) {
|
|
10673
11395
|
return;
|
|
10674
11396
|
}
|
|
@@ -10718,7 +11440,7 @@ function PanoVideo({
|
|
|
10718
11440
|
video.removeEventListener("ratechange", handleVolume);
|
|
10719
11441
|
};
|
|
10720
11442
|
}, [emitSnapshot, resource]);
|
|
10721
|
-
(0,
|
|
11443
|
+
(0, import_react40.useEffect)(() => {
|
|
10722
11444
|
if (!resource) {
|
|
10723
11445
|
return;
|
|
10724
11446
|
}
|
|
@@ -10753,7 +11475,7 @@ function PanoVideo({
|
|
|
10753
11475
|
video.textTracks.removeEventListener("change", applyModes);
|
|
10754
11476
|
};
|
|
10755
11477
|
}, [emitSnapshot, resource, trackId, tracks]);
|
|
10756
|
-
(0,
|
|
11478
|
+
(0, import_react40.useEffect)(() => {
|
|
10757
11479
|
if (!captionsEnabled) {
|
|
10758
11480
|
setTrackId(null);
|
|
10759
11481
|
return;
|
|
@@ -10764,33 +11486,33 @@ function PanoVideo({
|
|
|
10764
11486
|
if (variants.length === 0) {
|
|
10765
11487
|
return null;
|
|
10766
11488
|
}
|
|
10767
|
-
return /* @__PURE__ */ (0,
|
|
10768
|
-
activeTexture ? /* @__PURE__ */ (0,
|
|
11489
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
11490
|
+
activeTexture ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
10769
11491
|
"mesh",
|
|
10770
11492
|
{
|
|
10771
|
-
rotation: [0,
|
|
11493
|
+
rotation: [0, import_three16.MathUtils.degToRad(90 + yawOffset), 0],
|
|
10772
11494
|
visible,
|
|
10773
11495
|
children: [
|
|
10774
|
-
/* @__PURE__ */ (0,
|
|
10775
|
-
/* @__PURE__ */ (0,
|
|
11496
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("sphereGeometry", { args: [DEFAULT_PANORAMA_RADIUS, 128, 64] }),
|
|
11497
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
10776
11498
|
PanoBasicMaterial,
|
|
10777
11499
|
{
|
|
10778
11500
|
map: activeTexture,
|
|
10779
|
-
side:
|
|
11501
|
+
side: import_three16.BackSide,
|
|
10780
11502
|
toneMapped: false
|
|
10781
11503
|
}
|
|
10782
11504
|
)
|
|
10783
11505
|
]
|
|
10784
11506
|
}
|
|
10785
11507
|
) : null,
|
|
10786
|
-
captionsEnabled ? /* @__PURE__ */ (0,
|
|
11508
|
+
captionsEnabled ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(PanoVideoCaptions, { appearance: typeof captions === "object" ? captions : void 0 }) : null
|
|
10787
11509
|
] });
|
|
10788
11510
|
}
|
|
10789
11511
|
|
|
10790
11512
|
// src/scenes.tsx
|
|
10791
|
-
var
|
|
10792
|
-
var
|
|
10793
|
-
var
|
|
11513
|
+
var import_fiber22 = require("@react-three/fiber");
|
|
11514
|
+
var import_react45 = require("react");
|
|
11515
|
+
var import_three23 = require("three");
|
|
10794
11516
|
|
|
10795
11517
|
// src/scene-transitions/presets.ts
|
|
10796
11518
|
var TRANSITION_DEFAULTS = {
|
|
@@ -10839,9 +11561,9 @@ function isSnapshotTransition(preset) {
|
|
|
10839
11561
|
}
|
|
10840
11562
|
|
|
10841
11563
|
// src/scene-transitions/particle-overlay.tsx
|
|
10842
|
-
var
|
|
10843
|
-
var
|
|
10844
|
-
var
|
|
11564
|
+
var import_fiber18 = require("@react-three/fiber");
|
|
11565
|
+
var import_react41 = require("react");
|
|
11566
|
+
var import_three18 = require("three");
|
|
10845
11567
|
|
|
10846
11568
|
// src/scene-transitions/glsl.ts
|
|
10847
11569
|
var GLSL_COMMON = `
|
|
@@ -10874,9 +11596,9 @@ float fbm(vec2 p) {
|
|
|
10874
11596
|
`;
|
|
10875
11597
|
|
|
10876
11598
|
// src/scene-transitions/overlay-utils.ts
|
|
10877
|
-
var
|
|
11599
|
+
var import_three17 = require("three");
|
|
10878
11600
|
var OVERLAY_RENDER_ORDER = 1e4;
|
|
10879
|
-
var FULLSCREEN_PLANE = new
|
|
11601
|
+
var FULLSCREEN_PLANE = new import_three17.PlaneGeometry(1, 1);
|
|
10880
11602
|
function isPerspectiveCamera(camera) {
|
|
10881
11603
|
return camera.isPerspectiveCamera === true;
|
|
10882
11604
|
}
|
|
@@ -10895,7 +11617,7 @@ function overlayProgress(elapsedTime, duration, startTime) {
|
|
|
10895
11617
|
}
|
|
10896
11618
|
|
|
10897
11619
|
// src/scene-transitions/particle-overlay.tsx
|
|
10898
|
-
var
|
|
11620
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
10899
11621
|
var PARTICLE_GRID = 48;
|
|
10900
11622
|
var PARTICLE_COUNT = PARTICLE_GRID * PARTICLE_GRID;
|
|
10901
11623
|
var PARTICLE_VERTEX_SHADER = `
|
|
@@ -10948,8 +11670,8 @@ var PARTICLE_FRAGMENT_SHADER = `
|
|
|
10948
11670
|
}
|
|
10949
11671
|
`;
|
|
10950
11672
|
function createParticleGeometry() {
|
|
10951
|
-
const quad = new
|
|
10952
|
-
const geometry = new
|
|
11673
|
+
const quad = new import_three18.PlaneGeometry(1, 1);
|
|
11674
|
+
const geometry = new import_three18.InstancedBufferGeometry();
|
|
10953
11675
|
if (quad.index) {
|
|
10954
11676
|
geometry.setIndex(quad.index.clone());
|
|
10955
11677
|
}
|
|
@@ -10959,7 +11681,7 @@ function createParticleGeometry() {
|
|
|
10959
11681
|
for (let i = 0; i < PARTICLE_COUNT; i += 1) {
|
|
10960
11682
|
indexes[i] = i;
|
|
10961
11683
|
}
|
|
10962
|
-
geometry.setAttribute("instanceIndex", new
|
|
11684
|
+
geometry.setAttribute("instanceIndex", new import_three18.InstancedBufferAttribute(indexes, 1));
|
|
10963
11685
|
geometry.instanceCount = PARTICLE_COUNT;
|
|
10964
11686
|
quad.dispose();
|
|
10965
11687
|
return geometry;
|
|
@@ -10971,36 +11693,36 @@ function ParticleOverlay({
|
|
|
10971
11693
|
runId,
|
|
10972
11694
|
onFinish
|
|
10973
11695
|
}) {
|
|
10974
|
-
const { camera } = (0,
|
|
10975
|
-
const meshRef = (0,
|
|
10976
|
-
const startRef = (0,
|
|
10977
|
-
const finishedRef = (0,
|
|
10978
|
-
const directionRef = (0,
|
|
10979
|
-
const geometry = (0,
|
|
10980
|
-
const material = (0,
|
|
10981
|
-
() => new
|
|
11696
|
+
const { camera } = (0, import_fiber18.useThree)();
|
|
11697
|
+
const meshRef = (0, import_react41.useRef)(null);
|
|
11698
|
+
const startRef = (0, import_react41.useRef)(null);
|
|
11699
|
+
const finishedRef = (0, import_react41.useRef)(false);
|
|
11700
|
+
const directionRef = (0, import_react41.useRef)(new import_three18.Vector3());
|
|
11701
|
+
const geometry = (0, import_react41.useMemo)(() => createParticleGeometry(), []);
|
|
11702
|
+
const material = (0, import_react41.useMemo)(
|
|
11703
|
+
() => new import_three18.ShaderMaterial({
|
|
10982
11704
|
transparent: true,
|
|
10983
11705
|
depthTest: false,
|
|
10984
11706
|
depthWrite: false,
|
|
10985
|
-
side:
|
|
11707
|
+
side: import_three18.DoubleSide,
|
|
10986
11708
|
uniforms: {
|
|
10987
11709
|
map: { value: snapshot.texture },
|
|
10988
11710
|
progress: { value: 0 },
|
|
10989
|
-
grid: { value: new
|
|
11711
|
+
grid: { value: new import_three18.Vector2(PARTICLE_GRID, PARTICLE_GRID) }
|
|
10990
11712
|
},
|
|
10991
11713
|
vertexShader: PARTICLE_VERTEX_SHADER,
|
|
10992
11714
|
fragmentShader: PARTICLE_FRAGMENT_SHADER
|
|
10993
11715
|
}),
|
|
10994
11716
|
[snapshot.texture]
|
|
10995
11717
|
);
|
|
10996
|
-
(0,
|
|
10997
|
-
(0,
|
|
10998
|
-
(0,
|
|
11718
|
+
(0, import_react41.useEffect)(() => () => geometry.dispose(), [geometry]);
|
|
11719
|
+
(0, import_react41.useEffect)(() => () => material.dispose(), [material]);
|
|
11720
|
+
(0, import_react41.useEffect)(() => {
|
|
10999
11721
|
startRef.current = null;
|
|
11000
11722
|
finishedRef.current = false;
|
|
11001
11723
|
material.uniforms.progress.value = 0;
|
|
11002
11724
|
}, [material, runId]);
|
|
11003
|
-
(0,
|
|
11725
|
+
(0, import_fiber18.useFrame)((state) => {
|
|
11004
11726
|
const mesh = meshRef.current;
|
|
11005
11727
|
if (!mesh || !isPerspectiveCamera(camera)) {
|
|
11006
11728
|
return;
|
|
@@ -11017,7 +11739,7 @@ function ParticleOverlay({
|
|
|
11017
11739
|
onFinish();
|
|
11018
11740
|
}
|
|
11019
11741
|
});
|
|
11020
|
-
return /* @__PURE__ */ (0,
|
|
11742
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
11021
11743
|
"mesh",
|
|
11022
11744
|
{
|
|
11023
11745
|
ref: meshRef,
|
|
@@ -11030,12 +11752,12 @@ function ParticleOverlay({
|
|
|
11030
11752
|
}
|
|
11031
11753
|
|
|
11032
11754
|
// src/scene-transitions/snapshot-overlay.tsx
|
|
11033
|
-
var
|
|
11034
|
-
var
|
|
11035
|
-
var
|
|
11755
|
+
var import_fiber19 = require("@react-three/fiber");
|
|
11756
|
+
var import_react42 = require("react");
|
|
11757
|
+
var import_three20 = require("three");
|
|
11036
11758
|
|
|
11037
11759
|
// src/scene-transitions/snapshot-shaders.ts
|
|
11038
|
-
var
|
|
11760
|
+
var import_three19 = require("three");
|
|
11039
11761
|
var SNAPSHOT_VERTEX_SHADER = `
|
|
11040
11762
|
varying vec2 vUv;
|
|
11041
11763
|
void main() {
|
|
@@ -11295,15 +12017,15 @@ var SNAPSHOT_FRAGMENT_SHADERS = {
|
|
|
11295
12017
|
`)
|
|
11296
12018
|
};
|
|
11297
12019
|
function createSnapshotMaterial(preset, texture) {
|
|
11298
|
-
return new
|
|
12020
|
+
return new import_three19.ShaderMaterial({
|
|
11299
12021
|
transparent: true,
|
|
11300
12022
|
depthTest: false,
|
|
11301
12023
|
depthWrite: false,
|
|
11302
|
-
side:
|
|
12024
|
+
side: import_three19.DoubleSide,
|
|
11303
12025
|
uniforms: {
|
|
11304
12026
|
map: { value: texture },
|
|
11305
12027
|
progress: { value: 0 },
|
|
11306
|
-
resolution: { value: new
|
|
12028
|
+
resolution: { value: new import_three19.Vector2(1, 1) }
|
|
11307
12029
|
},
|
|
11308
12030
|
vertexShader: SNAPSHOT_VERTEX_SHADER,
|
|
11309
12031
|
fragmentShader: SNAPSHOT_FRAGMENT_SHADERS[preset]
|
|
@@ -11311,7 +12033,7 @@ function createSnapshotMaterial(preset, texture) {
|
|
|
11311
12033
|
}
|
|
11312
12034
|
|
|
11313
12035
|
// src/scene-transitions/snapshot-overlay.tsx
|
|
11314
|
-
var
|
|
12036
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
11315
12037
|
function SnapshotOverlay({
|
|
11316
12038
|
snapshot,
|
|
11317
12039
|
transition,
|
|
@@ -11319,26 +12041,26 @@ function SnapshotOverlay({
|
|
|
11319
12041
|
runId,
|
|
11320
12042
|
onFinish
|
|
11321
12043
|
}) {
|
|
11322
|
-
const { camera, gl } = (0,
|
|
11323
|
-
const meshRef = (0,
|
|
11324
|
-
const startRef = (0,
|
|
11325
|
-
const finishedRef = (0,
|
|
11326
|
-
const directionRef = (0,
|
|
11327
|
-
const material = (0,
|
|
12044
|
+
const { camera, gl } = (0, import_fiber19.useThree)();
|
|
12045
|
+
const meshRef = (0, import_react42.useRef)(null);
|
|
12046
|
+
const startRef = (0, import_react42.useRef)(null);
|
|
12047
|
+
const finishedRef = (0, import_react42.useRef)(false);
|
|
12048
|
+
const directionRef = (0, import_react42.useRef)(new import_three20.Vector3());
|
|
12049
|
+
const material = (0, import_react42.useMemo)(() => {
|
|
11328
12050
|
if (!isSnapshotTransition(transition.preset)) {
|
|
11329
12051
|
return null;
|
|
11330
12052
|
}
|
|
11331
12053
|
return createSnapshotMaterial(transition.preset, snapshot.texture);
|
|
11332
12054
|
}, [snapshot.texture, transition.preset]);
|
|
11333
|
-
(0,
|
|
11334
|
-
(0,
|
|
12055
|
+
(0, import_react42.useEffect)(() => () => material?.dispose(), [material]);
|
|
12056
|
+
(0, import_react42.useEffect)(() => {
|
|
11335
12057
|
startRef.current = null;
|
|
11336
12058
|
finishedRef.current = false;
|
|
11337
12059
|
if (material) {
|
|
11338
12060
|
material.uniforms.progress.value = 0;
|
|
11339
12061
|
}
|
|
11340
12062
|
}, [material, runId]);
|
|
11341
|
-
(0,
|
|
12063
|
+
(0, import_fiber19.useFrame)((state) => {
|
|
11342
12064
|
const mesh = meshRef.current;
|
|
11343
12065
|
if (!mesh || !material || !isPerspectiveCamera(camera)) {
|
|
11344
12066
|
return;
|
|
@@ -11360,21 +12082,21 @@ function SnapshotOverlay({
|
|
|
11360
12082
|
if (!material) {
|
|
11361
12083
|
return null;
|
|
11362
12084
|
}
|
|
11363
|
-
return /* @__PURE__ */ (0,
|
|
11364
|
-
/* @__PURE__ */ (0,
|
|
11365
|
-
/* @__PURE__ */ (0,
|
|
12085
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("mesh", { ref: meshRef, renderOrder: OVERLAY_RENDER_ORDER, frustumCulled: false, children: [
|
|
12086
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("primitive", { attach: "geometry", object: FULLSCREEN_PLANE }),
|
|
12087
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("primitive", { attach: "material", object: material })
|
|
11366
12088
|
] });
|
|
11367
12089
|
}
|
|
11368
12090
|
|
|
11369
12091
|
// src/scene-transitions/transition-overlay.tsx
|
|
11370
|
-
var
|
|
12092
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
11371
12093
|
function TransitionOverlay(props) {
|
|
11372
12094
|
const { preset } = props.transition;
|
|
11373
12095
|
switch (preset) {
|
|
11374
12096
|
case "none":
|
|
11375
12097
|
return null;
|
|
11376
12098
|
case "particles":
|
|
11377
|
-
return /* @__PURE__ */ (0,
|
|
12099
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ParticleOverlay, { ...props });
|
|
11378
12100
|
case "crossfade":
|
|
11379
12101
|
case "zoom":
|
|
11380
12102
|
case "blackout":
|
|
@@ -11402,7 +12124,7 @@ function TransitionOverlay(props) {
|
|
|
11402
12124
|
case "zoomBlur":
|
|
11403
12125
|
case "hexDissolve":
|
|
11404
12126
|
case "filmBurn":
|
|
11405
|
-
return /* @__PURE__ */ (0,
|
|
12127
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(SnapshotOverlay, { ...props });
|
|
11406
12128
|
default: {
|
|
11407
12129
|
const exhaustive = preset;
|
|
11408
12130
|
void exhaustive;
|
|
@@ -11412,233 +12134,10 @@ function TransitionOverlay(props) {
|
|
|
11412
12134
|
}
|
|
11413
12135
|
|
|
11414
12136
|
// src/tile/texture-manager-context.tsx
|
|
11415
|
-
var
|
|
11416
|
-
var
|
|
11417
|
-
|
|
11418
|
-
|
|
11419
|
-
var import_three16 = require("three");
|
|
11420
|
-
var EMPTY_TEXTURE_SNAPSHOT = {
|
|
11421
|
-
status: "idle",
|
|
11422
|
-
texture: null,
|
|
11423
|
-
error: null
|
|
11424
|
-
};
|
|
11425
|
-
var TileTextureManager = class {
|
|
11426
|
-
constructor(options) {
|
|
11427
|
-
this.loader = new import_three16.TextureLoader();
|
|
11428
|
-
this.entries = /* @__PURE__ */ new Map();
|
|
11429
|
-
this.queue = [];
|
|
11430
|
-
this.activeLoads = 0;
|
|
11431
|
-
this.totalBytes = 0;
|
|
11432
|
-
this.requested = 0;
|
|
11433
|
-
this.loaded = 0;
|
|
11434
|
-
this.failed = 0;
|
|
11435
|
-
this.disposed = false;
|
|
11436
|
-
this.generation = 0;
|
|
11437
|
-
this.options = options;
|
|
11438
|
-
}
|
|
11439
|
-
resume() {
|
|
11440
|
-
this.disposed = false;
|
|
11441
|
-
this.drain();
|
|
11442
|
-
}
|
|
11443
|
-
getSnapshot(key) {
|
|
11444
|
-
const entry = this.entries.get(key);
|
|
11445
|
-
return entry ? this.snapshot(entry) : EMPTY_TEXTURE_SNAPSHOT;
|
|
11446
|
-
}
|
|
11447
|
-
acquire(key, url, address, listener) {
|
|
11448
|
-
let entry = this.entries.get(key);
|
|
11449
|
-
if (!entry) {
|
|
11450
|
-
entry = {
|
|
11451
|
-
key,
|
|
11452
|
-
url,
|
|
11453
|
-
address,
|
|
11454
|
-
status: "idle",
|
|
11455
|
-
texture: null,
|
|
11456
|
-
error: null,
|
|
11457
|
-
refs: 0,
|
|
11458
|
-
listeners: /* @__PURE__ */ new Set(),
|
|
11459
|
-
lastUsed: performance.now(),
|
|
11460
|
-
bytes: 0
|
|
11461
|
-
};
|
|
11462
|
-
this.entries.set(key, entry);
|
|
11463
|
-
}
|
|
11464
|
-
entry.refs += 1;
|
|
11465
|
-
entry.lastUsed = performance.now();
|
|
11466
|
-
entry.listeners.add(listener);
|
|
11467
|
-
listener(this.snapshot(entry));
|
|
11468
|
-
if (entry.status === "idle") {
|
|
11469
|
-
entry.status = "queued";
|
|
11470
|
-
this.queue.push(entry);
|
|
11471
|
-
this.requested += 1;
|
|
11472
|
-
this.emitProgress();
|
|
11473
|
-
this.drain();
|
|
11474
|
-
}
|
|
11475
|
-
return () => {
|
|
11476
|
-
entry.listeners.delete(listener);
|
|
11477
|
-
entry.refs = Math.max(0, entry.refs - 1);
|
|
11478
|
-
entry.lastUsed = performance.now();
|
|
11479
|
-
if (entry.refs === 0 && entry.status === "queued") {
|
|
11480
|
-
const queueIndex = this.queue.indexOf(entry);
|
|
11481
|
-
if (queueIndex >= 0) {
|
|
11482
|
-
this.queue.splice(queueIndex, 1);
|
|
11483
|
-
}
|
|
11484
|
-
entry.status = "idle";
|
|
11485
|
-
this.entries.delete(entry.key);
|
|
11486
|
-
this.requested = Math.max(0, this.requested - 1);
|
|
11487
|
-
this.emitProgress();
|
|
11488
|
-
this.drain();
|
|
11489
|
-
return;
|
|
11490
|
-
}
|
|
11491
|
-
this.evict();
|
|
11492
|
-
};
|
|
11493
|
-
}
|
|
11494
|
-
dispose() {
|
|
11495
|
-
this.disposed = true;
|
|
11496
|
-
this.generation += 1;
|
|
11497
|
-
this.queue.length = 0;
|
|
11498
|
-
for (const entry of this.entries.values()) {
|
|
11499
|
-
entry.texture?.dispose();
|
|
11500
|
-
entry.listeners.clear();
|
|
11501
|
-
}
|
|
11502
|
-
this.entries.clear();
|
|
11503
|
-
this.totalBytes = 0;
|
|
11504
|
-
}
|
|
11505
|
-
/**
|
|
11506
|
-
* Releases textures that are no longer rendered by any Tile instance.
|
|
11507
|
-
* Scene transitions call this after the outgoing panorama has been
|
|
11508
|
-
* snapshotted, so the incoming scene never competes with stale GPU tiles.
|
|
11509
|
-
*/
|
|
11510
|
-
releaseUnused() {
|
|
11511
|
-
for (const entry of Array.from(this.entries.values())) {
|
|
11512
|
-
if (entry.refs > 0) {
|
|
11513
|
-
continue;
|
|
11514
|
-
}
|
|
11515
|
-
entry.texture?.dispose();
|
|
11516
|
-
this.totalBytes -= entry.bytes;
|
|
11517
|
-
this.entries.delete(entry.key);
|
|
11518
|
-
}
|
|
11519
|
-
this.totalBytes = Math.max(0, this.totalBytes);
|
|
11520
|
-
}
|
|
11521
|
-
snapshot(entry) {
|
|
11522
|
-
return {
|
|
11523
|
-
status: entry.status,
|
|
11524
|
-
texture: entry.texture,
|
|
11525
|
-
error: entry.error
|
|
11526
|
-
};
|
|
11527
|
-
}
|
|
11528
|
-
notify(entry) {
|
|
11529
|
-
const snapshot = this.snapshot(entry);
|
|
11530
|
-
for (const listener of entry.listeners) {
|
|
11531
|
-
listener(snapshot);
|
|
11532
|
-
}
|
|
11533
|
-
}
|
|
11534
|
-
emitProgress() {
|
|
11535
|
-
this.options.onProgress?.({
|
|
11536
|
-
requested: this.requested,
|
|
11537
|
-
loaded: this.loaded,
|
|
11538
|
-
failed: this.failed,
|
|
11539
|
-
active: this.activeLoads,
|
|
11540
|
-
queued: this.queue.length
|
|
11541
|
-
});
|
|
11542
|
-
}
|
|
11543
|
-
drain() {
|
|
11544
|
-
while (!this.disposed && this.activeLoads < this.options.concurrency && this.queue.length > 0) {
|
|
11545
|
-
const entry = this.queue.shift();
|
|
11546
|
-
if (entry.refs === 0) {
|
|
11547
|
-
entry.status = "idle";
|
|
11548
|
-
this.entries.delete(entry.key);
|
|
11549
|
-
this.requested = Math.max(0, this.requested - 1);
|
|
11550
|
-
continue;
|
|
11551
|
-
}
|
|
11552
|
-
entry.status = "loading";
|
|
11553
|
-
this.activeLoads += 1;
|
|
11554
|
-
this.notify(entry);
|
|
11555
|
-
this.emitProgress();
|
|
11556
|
-
void this.loadAndFinish(entry);
|
|
11557
|
-
}
|
|
11558
|
-
}
|
|
11559
|
-
async load(entry, generation) {
|
|
11560
|
-
let lastError = null;
|
|
11561
|
-
for (let attempt = 0; attempt <= this.options.retryCount; attempt += 1) {
|
|
11562
|
-
try {
|
|
11563
|
-
const texture = await this.loader.loadAsync(entry.url);
|
|
11564
|
-
if (this.disposed || generation !== this.generation) {
|
|
11565
|
-
texture.dispose();
|
|
11566
|
-
return;
|
|
11567
|
-
}
|
|
11568
|
-
this.configureTexture(texture);
|
|
11569
|
-
entry.texture = texture;
|
|
11570
|
-
entry.status = "loaded";
|
|
11571
|
-
entry.error = null;
|
|
11572
|
-
entry.bytes = entry.address.width * entry.address.height * 4;
|
|
11573
|
-
entry.lastUsed = performance.now();
|
|
11574
|
-
this.totalBytes += entry.bytes;
|
|
11575
|
-
this.loaded += 1;
|
|
11576
|
-
this.notify(entry);
|
|
11577
|
-
return;
|
|
11578
|
-
} catch (error) {
|
|
11579
|
-
lastError = error;
|
|
11580
|
-
}
|
|
11581
|
-
}
|
|
11582
|
-
if (!this.disposed && generation === this.generation) {
|
|
11583
|
-
entry.status = "error";
|
|
11584
|
-
entry.error = lastError;
|
|
11585
|
-
this.failed += 1;
|
|
11586
|
-
this.notify(entry);
|
|
11587
|
-
this.options.onError?.({
|
|
11588
|
-
address: entry.address,
|
|
11589
|
-
url: entry.url,
|
|
11590
|
-
error: lastError
|
|
11591
|
-
});
|
|
11592
|
-
}
|
|
11593
|
-
}
|
|
11594
|
-
configureTexture(texture) {
|
|
11595
|
-
texture.colorSpace = import_three16.SRGBColorSpace;
|
|
11596
|
-
texture.wrapS = import_three16.ClampToEdgeWrapping;
|
|
11597
|
-
texture.wrapT = import_three16.ClampToEdgeWrapping;
|
|
11598
|
-
texture.magFilter = import_three16.LinearFilter;
|
|
11599
|
-
texture.minFilter = import_three16.LinearFilter;
|
|
11600
|
-
texture.generateMipmaps = false;
|
|
11601
|
-
texture.anisotropy = Math.min(4, this.options.anisotropy);
|
|
11602
|
-
texture.needsUpdate = true;
|
|
11603
|
-
}
|
|
11604
|
-
evict() {
|
|
11605
|
-
if (this.totalBytes <= this.options.maxBytes) {
|
|
11606
|
-
return;
|
|
11607
|
-
}
|
|
11608
|
-
const candidates = Array.from(this.entries.values()).filter((entry) => entry.refs === 0 && entry.texture).sort((a, b) => a.lastUsed - b.lastUsed);
|
|
11609
|
-
for (const entry of candidates) {
|
|
11610
|
-
if (this.totalBytes <= this.options.maxBytes) {
|
|
11611
|
-
break;
|
|
11612
|
-
}
|
|
11613
|
-
entry.texture?.dispose();
|
|
11614
|
-
this.totalBytes -= entry.bytes;
|
|
11615
|
-
this.entries.delete(entry.key);
|
|
11616
|
-
}
|
|
11617
|
-
this.totalBytes = Math.max(0, this.totalBytes);
|
|
11618
|
-
}
|
|
11619
|
-
finishLoad(generation) {
|
|
11620
|
-
this.activeLoads = Math.max(0, this.activeLoads - 1);
|
|
11621
|
-
if (!this.disposed && generation === this.generation) {
|
|
11622
|
-
this.emitProgress();
|
|
11623
|
-
this.evict();
|
|
11624
|
-
}
|
|
11625
|
-
if (!this.disposed) {
|
|
11626
|
-
this.drain();
|
|
11627
|
-
}
|
|
11628
|
-
}
|
|
11629
|
-
async loadAndFinish(entry) {
|
|
11630
|
-
const generation = this.generation;
|
|
11631
|
-
try {
|
|
11632
|
-
await this.load(entry, generation);
|
|
11633
|
-
} finally {
|
|
11634
|
-
this.finishLoad(generation);
|
|
11635
|
-
}
|
|
11636
|
-
}
|
|
11637
|
-
};
|
|
11638
|
-
|
|
11639
|
-
// src/tile/texture-manager-context.tsx
|
|
11640
|
-
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
11641
|
-
var TileTextureManagerContext = (0, import_react41.createContext)(
|
|
12137
|
+
var import_fiber20 = require("@react-three/fiber");
|
|
12138
|
+
var import_react43 = require("react");
|
|
12139
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
12140
|
+
var TileTextureManagerContext = (0, import_react43.createContext)(
|
|
11642
12141
|
null
|
|
11643
12142
|
);
|
|
11644
12143
|
function TileTextureManagerProvider({
|
|
@@ -11646,9 +12145,9 @@ function TileTextureManagerProvider({
|
|
|
11646
12145
|
maxTextureMemoryMb = 128,
|
|
11647
12146
|
maxConcurrentLoads = 4
|
|
11648
12147
|
}) {
|
|
11649
|
-
const gl = (0,
|
|
12148
|
+
const gl = (0, import_fiber20.useThree)((state) => state.gl);
|
|
11650
12149
|
const anisotropy = gl.capabilities.getMaxAnisotropy();
|
|
11651
|
-
const manager = (0,
|
|
12150
|
+
const manager = (0, import_react43.useMemo)(
|
|
11652
12151
|
() => new TileTextureManager({
|
|
11653
12152
|
anisotropy,
|
|
11654
12153
|
maxBytes: Math.max(1, maxTextureMemoryMb) * 1024 * 1024,
|
|
@@ -11657,23 +12156,23 @@ function TileTextureManagerProvider({
|
|
|
11657
12156
|
}),
|
|
11658
12157
|
[anisotropy, maxConcurrentLoads, maxTextureMemoryMb]
|
|
11659
12158
|
);
|
|
11660
|
-
(0,
|
|
12159
|
+
(0, import_react43.useEffect)(() => {
|
|
11661
12160
|
manager.resume();
|
|
11662
12161
|
return () => manager.dispose();
|
|
11663
12162
|
}, [manager]);
|
|
11664
|
-
return /* @__PURE__ */ (0,
|
|
12163
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TileTextureManagerContext.Provider, { value: manager, children });
|
|
11665
12164
|
}
|
|
11666
12165
|
function useSharedTileTextureManager() {
|
|
11667
|
-
return (0,
|
|
12166
|
+
return (0, import_react43.useContext)(TileTextureManagerContext);
|
|
11668
12167
|
}
|
|
11669
12168
|
|
|
11670
12169
|
// src/tile/tile.tsx
|
|
11671
|
-
var
|
|
11672
|
-
var
|
|
11673
|
-
var
|
|
12170
|
+
var import_fiber21 = require("@react-three/fiber");
|
|
12171
|
+
var import_react44 = require("react");
|
|
12172
|
+
var import_three22 = require("three");
|
|
11674
12173
|
|
|
11675
12174
|
// src/tile/face-layout.ts
|
|
11676
|
-
var
|
|
12175
|
+
var import_three21 = require("three");
|
|
11677
12176
|
var CUBE_FACES = ["f", "r", "b", "l", "u", "d"];
|
|
11678
12177
|
var PREVIEW_FACE_ORDER = ["l", "f", "r", "b", "u", "d"];
|
|
11679
12178
|
var CUBE_RADIUS = DEFAULT_PANORAMA_RADIUS;
|
|
@@ -11724,8 +12223,8 @@ function getFaceQuaternion(face) {
|
|
|
11724
12223
|
return cached;
|
|
11725
12224
|
}
|
|
11726
12225
|
const transform = getFaceTransform(face);
|
|
11727
|
-
const quaternion = new
|
|
11728
|
-
new
|
|
12226
|
+
const quaternion = new import_three21.Quaternion().setFromEuler(
|
|
12227
|
+
new import_three21.Euler(...transform.rotation, "XYZ")
|
|
11729
12228
|
);
|
|
11730
12229
|
faceQuaternionCache.set(face, quaternion);
|
|
11731
12230
|
return quaternion;
|
|
@@ -11736,17 +12235,17 @@ function getTileBoundingBox(address, radius = CUBE_RADIUS) {
|
|
|
11736
12235
|
const halfWidth = local.width / 2;
|
|
11737
12236
|
const halfHeight = local.height / 2;
|
|
11738
12237
|
const quaternion = getFaceQuaternion(address.face);
|
|
11739
|
-
const position = new
|
|
12238
|
+
const position = new import_three21.Vector3(...transform.position);
|
|
11740
12239
|
const corners = [
|
|
11741
|
-
new
|
|
11742
|
-
new
|
|
11743
|
-
new
|
|
11744
|
-
new
|
|
12240
|
+
new import_three21.Vector3(local.x - halfWidth, local.y - halfHeight, 0),
|
|
12241
|
+
new import_three21.Vector3(local.x + halfWidth, local.y - halfHeight, 0),
|
|
12242
|
+
new import_three21.Vector3(local.x - halfWidth, local.y + halfHeight, 0),
|
|
12243
|
+
new import_three21.Vector3(local.x + halfWidth, local.y + halfHeight, 0)
|
|
11745
12244
|
];
|
|
11746
12245
|
for (const corner of corners) {
|
|
11747
12246
|
corner.applyQuaternion(quaternion).add(position);
|
|
11748
12247
|
}
|
|
11749
|
-
return new
|
|
12248
|
+
return new import_three21.Box3().setFromPoints(corners);
|
|
11750
12249
|
}
|
|
11751
12250
|
function makeTileAddress(face, level, faceSize, tileSize, col, row) {
|
|
11752
12251
|
const left = (col - 1) * tileSize;
|
|
@@ -11793,7 +12292,7 @@ function previewAtlasVRange(face, faceOrder = PREVIEW_FACE_ORDER) {
|
|
|
11793
12292
|
}
|
|
11794
12293
|
|
|
11795
12294
|
// src/tile/multires.ts
|
|
11796
|
-
function
|
|
12295
|
+
function positiveInteger2(value, name) {
|
|
11797
12296
|
if (!Number.isFinite(value) || value <= 0 || !Number.isInteger(value)) {
|
|
11798
12297
|
throw new Error(`${name} must be a positive integer, received ${String(value)}`);
|
|
11799
12298
|
}
|
|
@@ -11809,110 +12308,61 @@ function ascendingLevels(levels) {
|
|
|
11809
12308
|
}
|
|
11810
12309
|
function parseMultires(multires) {
|
|
11811
12310
|
if (typeof multires !== "string") {
|
|
11812
|
-
const tileSize2 =
|
|
12311
|
+
const tileSize2 = positiveInteger2(multires.tileSize, "multires.tileSize");
|
|
11813
12312
|
if (multires.levels.length === 0) {
|
|
11814
12313
|
throw new Error("multires.levels must contain at least one face size");
|
|
11815
12314
|
}
|
|
11816
12315
|
const levels2 = ascendingLevels(
|
|
11817
12316
|
multires.levels.map(
|
|
11818
|
-
(level, index) =>
|
|
12317
|
+
(level, index) => positiveInteger2(level, `multires.levels[${index}]`)
|
|
11819
12318
|
)
|
|
11820
12319
|
);
|
|
11821
|
-
return { tileSize: tileSize2, levels: levels2 };
|
|
11822
|
-
}
|
|
11823
|
-
const values = multires.split(",").map((part) => Number(part.trim()));
|
|
11824
|
-
if (values.length < 2 || values.some((value) => !Number.isFinite(value))) {
|
|
11825
|
-
throw new Error(
|
|
11826
|
-
"multires must contain a tile size followed by at least one face size"
|
|
11827
|
-
);
|
|
11828
|
-
}
|
|
11829
|
-
const tileSize =
|
|
11830
|
-
const levels = ascendingLevels(
|
|
11831
|
-
values.slice(1).map(
|
|
11832
|
-
(level, index) =>
|
|
11833
|
-
)
|
|
11834
|
-
);
|
|
11835
|
-
return { tileSize, levels };
|
|
11836
|
-
}
|
|
11837
|
-
var DEFAULT_TILE_URL_TEMPLATE = "tiles/%s/l%l/%v/l%l_%s_%h_%v.webp";
|
|
11838
|
-
function buildDefaultTileUrlTemplate() {
|
|
11839
|
-
return DEFAULT_TILE_URL_TEMPLATE;
|
|
11840
|
-
}
|
|
11841
|
-
function resolveRelativeTileUrl(baseUrl, relativePath) {
|
|
11842
|
-
return resolveRelativeAssetUrl(baseUrl, relativePath);
|
|
11843
|
-
}
|
|
11844
|
-
function resolveTemplateUrl(template, address) {
|
|
11845
|
-
return template.replace(/%s/g, address.face).replace(/%l/g, String(address.level)).replace(/%(0*)([hxucvywr])/g, (_match, zeroes, placeholder) => {
|
|
11846
|
-
const value = "hxuc".includes(placeholder) ? address.col : address.row;
|
|
11847
|
-
return String(value).padStart(zeroes.length + 1, "0");
|
|
11848
|
-
});
|
|
11849
|
-
}
|
|
11850
|
-
|
|
11851
|
-
// src/tile/tile.tsx
|
|
11852
|
-
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
11853
|
-
var MAX_LOD_UPDATE_INTERVAL_MS = 100;
|
|
11854
|
-
var FAST_ROTATION_THRESHOLD_RADIANS = Math.PI / 180;
|
|
11855
|
-
var FAST_FOV_THRESHOLD_DEGREES = 0.5;
|
|
11856
|
-
var VIEW_CHANGE_EPSILON = 1e-4;
|
|
11857
|
-
var VISIBILITY_FOV_PADDING_DEGREES = 8;
|
|
11858
|
-
var PREVIEW_RADIUS = CUBE_RADIUS + 0.05;
|
|
11859
|
-
var SHARED_TILE_GEOMETRY = new import_three18.PlaneGeometry(1, 1);
|
|
11860
|
-
function usePreviewTexture(url, anisotropy, onError) {
|
|
11861
|
-
const [texture, setTexture] = (0, import_react42.useState)(null);
|
|
11862
|
-
const onErrorRef = (0, import_react42.useRef)(onError);
|
|
11863
|
-
onErrorRef.current = onError;
|
|
11864
|
-
(0, import_react42.useEffect)(() => {
|
|
11865
|
-
if (!url) {
|
|
11866
|
-
setTexture(null);
|
|
11867
|
-
return;
|
|
11868
|
-
}
|
|
11869
|
-
let active = true;
|
|
11870
|
-
const loader = new import_three18.TextureLoader();
|
|
11871
|
-
setTexture(null);
|
|
11872
|
-
loader.load(
|
|
11873
|
-
url,
|
|
11874
|
-
(loadedTexture) => {
|
|
11875
|
-
if (!active) {
|
|
11876
|
-
loadedTexture.dispose();
|
|
11877
|
-
return;
|
|
11878
|
-
}
|
|
11879
|
-
loadedTexture.colorSpace = import_three18.SRGBColorSpace;
|
|
11880
|
-
loadedTexture.wrapS = import_three18.ClampToEdgeWrapping;
|
|
11881
|
-
loadedTexture.wrapT = import_three18.ClampToEdgeWrapping;
|
|
11882
|
-
loadedTexture.magFilter = import_three18.LinearFilter;
|
|
11883
|
-
loadedTexture.minFilter = import_three18.LinearFilter;
|
|
11884
|
-
loadedTexture.generateMipmaps = false;
|
|
11885
|
-
loadedTexture.anisotropy = Math.min(4, anisotropy);
|
|
11886
|
-
loadedTexture.needsUpdate = true;
|
|
11887
|
-
setTexture(loadedTexture);
|
|
11888
|
-
},
|
|
11889
|
-
void 0,
|
|
11890
|
-
(error) => {
|
|
11891
|
-
if (active) {
|
|
11892
|
-
setTexture(null);
|
|
11893
|
-
onErrorRef.current?.(error);
|
|
11894
|
-
}
|
|
11895
|
-
}
|
|
11896
|
-
);
|
|
11897
|
-
return () => {
|
|
11898
|
-
active = false;
|
|
11899
|
-
};
|
|
11900
|
-
}, [anisotropy, url]);
|
|
11901
|
-
(0, import_react42.useEffect)(
|
|
11902
|
-
() => () => {
|
|
11903
|
-
texture?.dispose();
|
|
11904
|
-
},
|
|
11905
|
-
[texture]
|
|
12320
|
+
return { tileSize: tileSize2, levels: levels2 };
|
|
12321
|
+
}
|
|
12322
|
+
const values = multires.split(",").map((part) => Number(part.trim()));
|
|
12323
|
+
if (values.length < 2 || values.some((value) => !Number.isFinite(value))) {
|
|
12324
|
+
throw new Error(
|
|
12325
|
+
"multires must contain a tile size followed by at least one face size"
|
|
12326
|
+
);
|
|
12327
|
+
}
|
|
12328
|
+
const tileSize = positiveInteger2(values[0], "multires tile size");
|
|
12329
|
+
const levels = ascendingLevels(
|
|
12330
|
+
values.slice(1).map(
|
|
12331
|
+
(level, index) => positiveInteger2(level, `multires level ${index + 1}`)
|
|
12332
|
+
)
|
|
11906
12333
|
);
|
|
11907
|
-
return
|
|
12334
|
+
return { tileSize, levels };
|
|
12335
|
+
}
|
|
12336
|
+
var DEFAULT_TILE_URL_TEMPLATE = "tiles/%s/l%l/%v/l%l_%s_%h_%v.webp";
|
|
12337
|
+
function buildDefaultTileUrlTemplate() {
|
|
12338
|
+
return DEFAULT_TILE_URL_TEMPLATE;
|
|
12339
|
+
}
|
|
12340
|
+
function resolveRelativeTileUrl(baseUrl, relativePath) {
|
|
12341
|
+
return resolveRelativeAssetUrl(baseUrl, relativePath);
|
|
12342
|
+
}
|
|
12343
|
+
function resolveTemplateUrl(template, address) {
|
|
12344
|
+
return template.replace(/%s/g, address.face).replace(/%l/g, String(address.level)).replace(/%(0*)([hxucvywr])/g, (_match, zeroes, placeholder) => {
|
|
12345
|
+
const value = "hxuc".includes(placeholder) ? address.col : address.row;
|
|
12346
|
+
return String(value).padStart(zeroes.length + 1, "0");
|
|
12347
|
+
});
|
|
11908
12348
|
}
|
|
12349
|
+
|
|
12350
|
+
// src/tile/tile.tsx
|
|
12351
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
12352
|
+
var MAX_LOD_UPDATE_INTERVAL_MS = 100;
|
|
12353
|
+
var FAST_ROTATION_THRESHOLD_RADIANS = Math.PI / 180;
|
|
12354
|
+
var FAST_FOV_THRESHOLD_DEGREES = 0.5;
|
|
12355
|
+
var VIEW_CHANGE_EPSILON = 1e-4;
|
|
12356
|
+
var VISIBILITY_FOV_PADDING_DEGREES = 8;
|
|
12357
|
+
var PREVIEW_RADIUS = CUBE_RADIUS + 0.05;
|
|
12358
|
+
var SHARED_TILE_GEOMETRY = new import_three22.PlaneGeometry(1, 1);
|
|
11909
12359
|
function PreviewFace({
|
|
11910
12360
|
face,
|
|
11911
12361
|
texture,
|
|
11912
12362
|
faceOrder
|
|
11913
12363
|
}) {
|
|
11914
|
-
const geometry = (0,
|
|
11915
|
-
const nextGeometry = new
|
|
12364
|
+
const geometry = (0, import_react44.useMemo)(() => {
|
|
12365
|
+
const nextGeometry = new import_three22.PlaneGeometry(
|
|
11916
12366
|
PREVIEW_RADIUS * 2,
|
|
11917
12367
|
PREVIEW_RADIUS * 2
|
|
11918
12368
|
);
|
|
@@ -11921,29 +12371,26 @@ function PreviewFace({
|
|
|
11921
12371
|
const inset = scale / 512;
|
|
11922
12372
|
for (let index = 0; index < uv.count; index += 1) {
|
|
11923
12373
|
const sourceV = uv.getY(index);
|
|
11924
|
-
uv.setY(
|
|
11925
|
-
index,
|
|
11926
|
-
offset + inset + sourceV * Math.max(0, scale - inset * 2)
|
|
11927
|
-
);
|
|
12374
|
+
uv.setY(index, offset + inset + sourceV * Math.max(0, scale - inset * 2));
|
|
11928
12375
|
}
|
|
11929
12376
|
uv.needsUpdate = true;
|
|
11930
12377
|
return nextGeometry;
|
|
11931
12378
|
}, [face, faceOrder]);
|
|
11932
|
-
(0,
|
|
12379
|
+
(0, import_react44.useEffect)(
|
|
11933
12380
|
() => () => {
|
|
11934
12381
|
geometry.dispose();
|
|
11935
12382
|
},
|
|
11936
12383
|
[geometry]
|
|
11937
12384
|
);
|
|
11938
12385
|
const transform = getFaceTransform(face, PREVIEW_RADIUS);
|
|
11939
|
-
return /* @__PURE__ */ (0,
|
|
12386
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
11940
12387
|
"mesh",
|
|
11941
12388
|
{
|
|
11942
12389
|
geometry,
|
|
11943
12390
|
position: transform.position,
|
|
11944
12391
|
renderOrder: -100,
|
|
11945
12392
|
rotation: transform.rotation,
|
|
11946
|
-
children: /* @__PURE__ */ (0,
|
|
12393
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
11947
12394
|
PanoBasicMaterial,
|
|
11948
12395
|
{
|
|
11949
12396
|
depthTest: false,
|
|
@@ -11959,7 +12406,7 @@ function PreviewCube({
|
|
|
11959
12406
|
texture,
|
|
11960
12407
|
faceOrder
|
|
11961
12408
|
}) {
|
|
11962
|
-
return CUBE_FACES.map((face) => /* @__PURE__ */ (0,
|
|
12409
|
+
return CUBE_FACES.map((face) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
11963
12410
|
PreviewFace,
|
|
11964
12411
|
{
|
|
11965
12412
|
face,
|
|
@@ -11969,28 +12416,7 @@ function PreviewCube({
|
|
|
11969
12416
|
face
|
|
11970
12417
|
));
|
|
11971
12418
|
}
|
|
11972
|
-
|
|
11973
|
-
const [managedState, setManagedState] = (0, import_react42.useState)(() => ({
|
|
11974
|
-
manager,
|
|
11975
|
-
key,
|
|
11976
|
-
url,
|
|
11977
|
-
snapshot: manager.getSnapshot(key)
|
|
11978
|
-
}));
|
|
11979
|
-
const snapshot = managedState.manager === manager && managedState.key === key && managedState.url === url ? managedState.snapshot : manager.getSnapshot(key);
|
|
11980
|
-
(0, import_react42.useEffect)(
|
|
11981
|
-
() => manager.acquire(key, url, address, (nextSnapshot) => {
|
|
11982
|
-
setManagedState({
|
|
11983
|
-
manager,
|
|
11984
|
-
key,
|
|
11985
|
-
url,
|
|
11986
|
-
snapshot: nextSnapshot
|
|
11987
|
-
});
|
|
11988
|
-
}),
|
|
11989
|
-
[key, manager, url]
|
|
11990
|
-
);
|
|
11991
|
-
return snapshot;
|
|
11992
|
-
}
|
|
11993
|
-
var TileMesh = (0, import_react42.memo)(function TileMesh2({
|
|
12419
|
+
var TileMesh = (0, import_react44.memo)(function TileMesh2({
|
|
11994
12420
|
address,
|
|
11995
12421
|
manager,
|
|
11996
12422
|
renderOrder,
|
|
@@ -12004,14 +12430,14 @@ var TileMesh = (0, import_react42.memo)(function TileMesh2({
|
|
|
12004
12430
|
if (!snapshot.texture) {
|
|
12005
12431
|
return null;
|
|
12006
12432
|
}
|
|
12007
|
-
return /* @__PURE__ */ (0,
|
|
12433
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("group", { position: transform.position, rotation: transform.rotation, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
12008
12434
|
"mesh",
|
|
12009
12435
|
{
|
|
12010
12436
|
geometry: SHARED_TILE_GEOMETRY,
|
|
12011
12437
|
position: [layout.x, layout.y, 0],
|
|
12012
12438
|
renderOrder,
|
|
12013
12439
|
scale: [layout.width, layout.height, 1],
|
|
12014
|
-
children: /* @__PURE__ */ (0,
|
|
12440
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
12015
12441
|
PanoBasicMaterial,
|
|
12016
12442
|
{
|
|
12017
12443
|
depthTest: false,
|
|
@@ -12023,12 +12449,12 @@ var TileMesh = (0, import_react42.memo)(function TileMesh2({
|
|
|
12023
12449
|
}
|
|
12024
12450
|
) });
|
|
12025
12451
|
});
|
|
12026
|
-
var TileLayerMeshes = (0,
|
|
12452
|
+
var TileLayerMeshes = (0, import_react44.memo)(function TileLayerMeshes2({
|
|
12027
12453
|
layer,
|
|
12028
12454
|
manager,
|
|
12029
12455
|
resolveUrl
|
|
12030
12456
|
}) {
|
|
12031
|
-
return layer.addresses.map((address) => /* @__PURE__ */ (0,
|
|
12457
|
+
return layer.addresses.map((address) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
12032
12458
|
TileMesh,
|
|
12033
12459
|
{
|
|
12034
12460
|
address,
|
|
@@ -12128,8 +12554,8 @@ function parentAddresses(child, parentLevel, parentFaceSize, tileSize) {
|
|
|
12128
12554
|
return addresses;
|
|
12129
12555
|
}
|
|
12130
12556
|
function centerFacingAddress(candidates, camera) {
|
|
12131
|
-
const direction = camera.getWorldDirection(new
|
|
12132
|
-
const center = new
|
|
12557
|
+
const direction = camera.getWorldDirection(new import_three22.Vector3());
|
|
12558
|
+
const center = new import_three22.Vector3();
|
|
12133
12559
|
let bestCandidate = candidates[0];
|
|
12134
12560
|
let bestAlignment = -Infinity;
|
|
12135
12561
|
for (const candidate of candidates) {
|
|
@@ -12174,9 +12600,7 @@ function buildLayers(targetLevel, levels, tileSize, frustum, camera, candidatesB
|
|
|
12174
12600
|
}));
|
|
12175
12601
|
}
|
|
12176
12602
|
function layerToken(layers) {
|
|
12177
|
-
return layers.map(
|
|
12178
|
-
(layer) => `${layer.level}:${layer.addresses.map(tileKey).join(",")}`
|
|
12179
|
-
).join("|");
|
|
12603
|
+
return layers.map((layer) => `${layer.level}:${layer.addresses.map(tileKey).join(",")}`).join("|");
|
|
12180
12604
|
}
|
|
12181
12605
|
function Tile({
|
|
12182
12606
|
baseUrl,
|
|
@@ -12196,11 +12620,11 @@ function Tile({
|
|
|
12196
12620
|
onTileError,
|
|
12197
12621
|
onLevelChange
|
|
12198
12622
|
}) {
|
|
12199
|
-
const { camera, gl, size } = (0,
|
|
12200
|
-
const multiresConfig = (0,
|
|
12623
|
+
const { camera, gl, size } = (0, import_fiber21.useThree)();
|
|
12624
|
+
const multiresConfig = (0, import_react44.useMemo)(() => parseMultires(multires), [multires]);
|
|
12201
12625
|
const { levels, tileSize } = multiresConfig;
|
|
12202
12626
|
const multiresToken = `${tileSize}:${levels.join(",")}`;
|
|
12203
|
-
const candidatesByLevel = (0,
|
|
12627
|
+
const candidatesByLevel = (0, import_react44.useMemo)(
|
|
12204
12628
|
() => buildTileCandidates(levels, tileSize),
|
|
12205
12629
|
[levels, tileSize]
|
|
12206
12630
|
);
|
|
@@ -12212,13 +12636,13 @@ function Tile({
|
|
|
12212
12636
|
onPreviewError
|
|
12213
12637
|
);
|
|
12214
12638
|
const sharedManager = useSharedTileTextureManager();
|
|
12215
|
-
const progressRef = (0,
|
|
12216
|
-
const errorRef = (0,
|
|
12217
|
-
const levelChangeRef = (0,
|
|
12639
|
+
const progressRef = (0, import_react44.useRef)(onLoadProgress);
|
|
12640
|
+
const errorRef = (0, import_react44.useRef)(onTileError);
|
|
12641
|
+
const levelChangeRef = (0, import_react44.useRef)(onLevelChange);
|
|
12218
12642
|
progressRef.current = onLoadProgress;
|
|
12219
12643
|
errorRef.current = onTileError;
|
|
12220
12644
|
levelChangeRef.current = onLevelChange;
|
|
12221
|
-
const ownedManager = (0,
|
|
12645
|
+
const ownedManager = (0, import_react44.useMemo)(
|
|
12222
12646
|
() => new TileTextureManager({
|
|
12223
12647
|
anisotropy,
|
|
12224
12648
|
maxBytes: Math.max(1, maxTextureMemoryMb) * 1024 * 1024,
|
|
@@ -12239,7 +12663,7 @@ function Tile({
|
|
|
12239
12663
|
]
|
|
12240
12664
|
);
|
|
12241
12665
|
const manager = sharedManager ?? ownedManager;
|
|
12242
|
-
(0,
|
|
12666
|
+
(0, import_react44.useEffect)(() => {
|
|
12243
12667
|
manager.resume();
|
|
12244
12668
|
return () => {
|
|
12245
12669
|
if (manager === ownedManager) {
|
|
@@ -12249,11 +12673,11 @@ function Tile({
|
|
|
12249
12673
|
queueMicrotask(() => manager.releaseUnused());
|
|
12250
12674
|
};
|
|
12251
12675
|
}, [manager, ownedManager]);
|
|
12252
|
-
const readyRef = (0,
|
|
12253
|
-
(0,
|
|
12676
|
+
const readyRef = (0, import_react44.useRef)(false);
|
|
12677
|
+
(0, import_react44.useEffect)(() => {
|
|
12254
12678
|
readyRef.current = false;
|
|
12255
12679
|
}, [effectivePreviewUrl]);
|
|
12256
|
-
(0,
|
|
12680
|
+
(0, import_react44.useEffect)(() => {
|
|
12257
12681
|
if (!previewTexture || readyRef.current) {
|
|
12258
12682
|
return;
|
|
12259
12683
|
}
|
|
@@ -12261,31 +12685,31 @@ function Tile({
|
|
|
12261
12685
|
onReady?.();
|
|
12262
12686
|
}, [onReady, previewTexture]);
|
|
12263
12687
|
const template = urlTemplate ?? buildDefaultTileUrlTemplate();
|
|
12264
|
-
const resolveUrl = (0,
|
|
12688
|
+
const resolveUrl = (0, import_react44.useMemo)(
|
|
12265
12689
|
() => (address) => {
|
|
12266
12690
|
const relativePath = resolveTileUrl ? resolveTileUrl(address) : resolveTemplateUrl(template, address);
|
|
12267
12691
|
return resolveRelativeTileUrl(baseUrl, relativePath);
|
|
12268
12692
|
},
|
|
12269
12693
|
[baseUrl, resolveTileUrl, template]
|
|
12270
12694
|
);
|
|
12271
|
-
const [layers, setLayers] = (0,
|
|
12272
|
-
const layerTokenRef = (0,
|
|
12273
|
-
const currentLevelRef = (0,
|
|
12274
|
-
const lastUpdateAtRef = (0,
|
|
12275
|
-
const visibilityDirtyRef = (0,
|
|
12276
|
-
const lastVisibilityQuaternionRef = (0,
|
|
12277
|
-
const lastVisibilityFovRef = (0,
|
|
12278
|
-
const lastViewportRef = (0,
|
|
12279
|
-
const frustumRef = (0,
|
|
12280
|
-
const projectionMatrixRef = (0,
|
|
12281
|
-
const visibilityCameraRef = (0,
|
|
12282
|
-
(0,
|
|
12695
|
+
const [layers, setLayers] = (0, import_react44.useState)([]);
|
|
12696
|
+
const layerTokenRef = (0, import_react44.useRef)("");
|
|
12697
|
+
const currentLevelRef = (0, import_react44.useRef)(1);
|
|
12698
|
+
const lastUpdateAtRef = (0, import_react44.useRef)(-Infinity);
|
|
12699
|
+
const visibilityDirtyRef = (0, import_react44.useRef)(true);
|
|
12700
|
+
const lastVisibilityQuaternionRef = (0, import_react44.useRef)(camera.quaternion.clone());
|
|
12701
|
+
const lastVisibilityFovRef = (0, import_react44.useRef)(Number.NaN);
|
|
12702
|
+
const lastViewportRef = (0, import_react44.useRef)({ width: 0, height: 0, dpr: 0 });
|
|
12703
|
+
const frustumRef = (0, import_react44.useRef)(new import_three22.Frustum());
|
|
12704
|
+
const projectionMatrixRef = (0, import_react44.useRef)(new import_three22.Matrix4());
|
|
12705
|
+
const visibilityCameraRef = (0, import_react44.useRef)(new import_three22.PerspectiveCamera());
|
|
12706
|
+
(0, import_react44.useEffect)(() => {
|
|
12283
12707
|
currentLevelRef.current = 1;
|
|
12284
12708
|
layerTokenRef.current = "";
|
|
12285
12709
|
visibilityDirtyRef.current = true;
|
|
12286
12710
|
setLayers([]);
|
|
12287
12711
|
}, [manager, multiresToken]);
|
|
12288
|
-
(0,
|
|
12712
|
+
(0, import_react44.useEffect)(() => {
|
|
12289
12713
|
if (loadMode !== "preview") {
|
|
12290
12714
|
return;
|
|
12291
12715
|
}
|
|
@@ -12299,11 +12723,11 @@ function Tile({
|
|
|
12299
12723
|
setLayers(nextLayers);
|
|
12300
12724
|
}
|
|
12301
12725
|
};
|
|
12302
|
-
(0,
|
|
12726
|
+
(0, import_fiber21.useFrame)(() => {
|
|
12303
12727
|
if (loadMode === "preview") {
|
|
12304
12728
|
return;
|
|
12305
12729
|
}
|
|
12306
|
-
if (!(camera instanceof
|
|
12730
|
+
if (!(camera instanceof import_three22.PerspectiveCamera)) {
|
|
12307
12731
|
return;
|
|
12308
12732
|
}
|
|
12309
12733
|
const now = performance.now();
|
|
@@ -12365,15 +12789,9 @@ function Tile({
|
|
|
12365
12789
|
};
|
|
12366
12790
|
commitLayers(nextLayers);
|
|
12367
12791
|
});
|
|
12368
|
-
return /* @__PURE__ */ (0,
|
|
12369
|
-
previewTexture ? /* @__PURE__ */ (0,
|
|
12370
|
-
|
|
12371
|
-
{
|
|
12372
|
-
texture: previewTexture,
|
|
12373
|
-
faceOrder: previewFaceOrder
|
|
12374
|
-
}
|
|
12375
|
-
) : null,
|
|
12376
|
-
layers.map((layer) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
12792
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("group", { visible, children: [
|
|
12793
|
+
previewTexture ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(PreviewCube, { texture: previewTexture, faceOrder: previewFaceOrder }) : null,
|
|
12794
|
+
layers.map((layer) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
12377
12795
|
TileLayerMeshes,
|
|
12378
12796
|
{
|
|
12379
12797
|
layer,
|
|
@@ -12386,7 +12804,7 @@ function Tile({
|
|
|
12386
12804
|
}
|
|
12387
12805
|
|
|
12388
12806
|
// src/scenes.tsx
|
|
12389
|
-
var
|
|
12807
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
12390
12808
|
function SceneSource({
|
|
12391
12809
|
scene,
|
|
12392
12810
|
visible,
|
|
@@ -12399,7 +12817,7 @@ function SceneSource({
|
|
|
12399
12817
|
}
|
|
12400
12818
|
switch (scene.type) {
|
|
12401
12819
|
case "sphere":
|
|
12402
|
-
return /* @__PURE__ */ (0,
|
|
12820
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
12403
12821
|
Sphere,
|
|
12404
12822
|
{
|
|
12405
12823
|
src: scene.src,
|
|
@@ -12412,7 +12830,7 @@ function SceneSource({
|
|
|
12412
12830
|
);
|
|
12413
12831
|
case "tile": {
|
|
12414
12832
|
const { id: _id, type: _type, ...tileProps } = scene;
|
|
12415
|
-
return /* @__PURE__ */ (0,
|
|
12833
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
12416
12834
|
Tile,
|
|
12417
12835
|
{
|
|
12418
12836
|
...tileProps,
|
|
@@ -12435,17 +12853,17 @@ function SnapshotCapture({
|
|
|
12435
12853
|
maxPixels,
|
|
12436
12854
|
onCaptured
|
|
12437
12855
|
}) {
|
|
12438
|
-
const { camera, gl, scene, size } = (0,
|
|
12439
|
-
const capturedRequestRef = (0,
|
|
12440
|
-
const renderTargetRef = (0,
|
|
12441
|
-
(0,
|
|
12856
|
+
const { camera, gl, scene, size } = (0, import_fiber22.useThree)();
|
|
12857
|
+
const capturedRequestRef = (0, import_react45.useRef)(0);
|
|
12858
|
+
const renderTargetRef = (0, import_react45.useRef)(null);
|
|
12859
|
+
(0, import_react45.useEffect)(
|
|
12442
12860
|
() => () => {
|
|
12443
12861
|
renderTargetRef.current?.dispose();
|
|
12444
12862
|
renderTargetRef.current = null;
|
|
12445
12863
|
},
|
|
12446
12864
|
[]
|
|
12447
12865
|
);
|
|
12448
|
-
(0,
|
|
12866
|
+
(0, import_fiber22.useFrame)(() => {
|
|
12449
12867
|
if (requestId === 0 || requestId === capturedRequestRef.current) {
|
|
12450
12868
|
return;
|
|
12451
12869
|
}
|
|
@@ -12455,14 +12873,14 @@ function SnapshotCapture({
|
|
|
12455
12873
|
const scale = Math.min(1, Math.sqrt(maxPixels / (sourceWidth * sourceHeight)));
|
|
12456
12874
|
const width = Math.max(1, Math.floor(sourceWidth * scale));
|
|
12457
12875
|
const height = Math.max(1, Math.floor(sourceHeight * scale));
|
|
12458
|
-
const nextTarget = new
|
|
12876
|
+
const nextTarget = new import_three23.WebGLRenderTarget(width, height, {
|
|
12459
12877
|
depthBuffer: false,
|
|
12460
12878
|
stencilBuffer: false
|
|
12461
12879
|
});
|
|
12462
|
-
nextTarget.texture.colorSpace =
|
|
12880
|
+
nextTarget.texture.colorSpace = import_three23.LinearSRGBColorSpace;
|
|
12463
12881
|
nextTarget.texture.generateMipmaps = false;
|
|
12464
|
-
nextTarget.texture.minFilter =
|
|
12465
|
-
nextTarget.texture.magFilter =
|
|
12882
|
+
nextTarget.texture.minFilter = import_three23.LinearFilter;
|
|
12883
|
+
nextTarget.texture.magFilter = import_three23.LinearFilter;
|
|
12466
12884
|
const previousTarget = gl.getRenderTarget();
|
|
12467
12885
|
gl.setRenderTarget(nextTarget);
|
|
12468
12886
|
gl.clear();
|
|
@@ -12494,50 +12912,50 @@ function ScenesController({
|
|
|
12494
12912
|
snapshotMaxPixels = 3686400,
|
|
12495
12913
|
phaseRef: externalPhaseRef
|
|
12496
12914
|
}) {
|
|
12497
|
-
const controlsRef = (0,
|
|
12915
|
+
const controlsRef = (0, import_react45.useContext)(PanoramaViewContext);
|
|
12498
12916
|
const manager = useSharedTileTextureManager();
|
|
12499
|
-
const transition = (0,
|
|
12917
|
+
const transition = (0, import_react45.useMemo)(
|
|
12500
12918
|
() => resolveTransition(transitionInput),
|
|
12501
12919
|
[transitionInput]
|
|
12502
12920
|
);
|
|
12503
|
-
const sceneMap = (0,
|
|
12921
|
+
const sceneMap = (0, import_react45.useMemo)(
|
|
12504
12922
|
() => new Map(scenes.map((scene) => [scene.id, scene])),
|
|
12505
12923
|
[scenes]
|
|
12506
12924
|
);
|
|
12507
12925
|
const initialScene = sceneMap.get(activeSceneId) ?? null;
|
|
12508
|
-
const [slots, setSlots] = (0,
|
|
12926
|
+
const [slots, setSlots] = (0, import_react45.useState)([
|
|
12509
12927
|
initialScene,
|
|
12510
12928
|
null
|
|
12511
12929
|
]);
|
|
12512
|
-
const [activeSlot, setActiveSlot] = (0,
|
|
12513
|
-
const [liveSlot, setLiveSlot] = (0,
|
|
12514
|
-
const [pendingSlot, setPendingSlot] = (0,
|
|
12515
|
-
const [phase, setPhase] = (0,
|
|
12516
|
-
const [captureRequestId, setCaptureRequestId] = (0,
|
|
12517
|
-
const [transitionRunId, setTransitionRunId] = (0,
|
|
12518
|
-
const [snapshot, setSnapshot] = (0,
|
|
12519
|
-
const [recoveryKey, setRecoveryKey] = (0,
|
|
12520
|
-
const requestedSceneIdRef = (0,
|
|
12521
|
-
const captureReasonRef = (0,
|
|
12522
|
-
const interactionReleaseRef = (0,
|
|
12523
|
-
const slotsRef = (0,
|
|
12524
|
-
const phaseRef = (0,
|
|
12525
|
-
const liveSlotRef = (0,
|
|
12526
|
-
const transitionFromRef = (0,
|
|
12930
|
+
const [activeSlot, setActiveSlot] = (0, import_react45.useState)(0);
|
|
12931
|
+
const [liveSlot, setLiveSlot] = (0, import_react45.useState)(0);
|
|
12932
|
+
const [pendingSlot, setPendingSlot] = (0, import_react45.useState)(null);
|
|
12933
|
+
const [phase, setPhase] = (0, import_react45.useState)(initialScene ? "idle" : "preloading");
|
|
12934
|
+
const [captureRequestId, setCaptureRequestId] = (0, import_react45.useState)(0);
|
|
12935
|
+
const [transitionRunId, setTransitionRunId] = (0, import_react45.useState)(0);
|
|
12936
|
+
const [snapshot, setSnapshot] = (0, import_react45.useState)(null);
|
|
12937
|
+
const [recoveryKey, setRecoveryKey] = (0, import_react45.useState)(0);
|
|
12938
|
+
const requestedSceneIdRef = (0, import_react45.useRef)(activeSceneId);
|
|
12939
|
+
const captureReasonRef = (0, import_react45.useRef)("start");
|
|
12940
|
+
const interactionReleaseRef = (0, import_react45.useRef)(null);
|
|
12941
|
+
const slotsRef = (0, import_react45.useRef)(slots);
|
|
12942
|
+
const phaseRef = (0, import_react45.useRef)(phase);
|
|
12943
|
+
const liveSlotRef = (0, import_react45.useRef)(liveSlot);
|
|
12944
|
+
const transitionFromRef = (0, import_react45.useRef)(initialScene);
|
|
12527
12945
|
slotsRef.current = slots;
|
|
12528
12946
|
phaseRef.current = phase;
|
|
12529
12947
|
if (externalPhaseRef) {
|
|
12530
12948
|
externalPhaseRef.current = phase;
|
|
12531
12949
|
}
|
|
12532
12950
|
liveSlotRef.current = liveSlot;
|
|
12533
|
-
const releaseInteraction = (0,
|
|
12951
|
+
const releaseInteraction = (0, import_react45.useCallback)(() => {
|
|
12534
12952
|
interactionReleaseRef.current?.();
|
|
12535
12953
|
interactionReleaseRef.current = null;
|
|
12536
12954
|
}, []);
|
|
12537
|
-
const reportError = (0,
|
|
12955
|
+
const reportError = (0, import_react45.useCallback)((sceneId, error) => {
|
|
12538
12956
|
onTransitionError?.({ sceneId, error });
|
|
12539
12957
|
}, [onTransitionError]);
|
|
12540
|
-
const startPreload = (0,
|
|
12958
|
+
const startPreload = (0, import_react45.useCallback)((scene) => {
|
|
12541
12959
|
const nextSlot = 1 - liveSlotRef.current;
|
|
12542
12960
|
requestedSceneIdRef.current = scene.id;
|
|
12543
12961
|
setSlots((current) => {
|
|
@@ -12548,7 +12966,7 @@ function ScenesController({
|
|
|
12548
12966
|
setPendingSlot(nextSlot);
|
|
12549
12967
|
setPhase("preloading");
|
|
12550
12968
|
}, []);
|
|
12551
|
-
(0,
|
|
12969
|
+
(0, import_react45.useEffect)(() => {
|
|
12552
12970
|
const requested = sceneMap.get(activeSceneId);
|
|
12553
12971
|
if (!requested) {
|
|
12554
12972
|
reportError(activeSceneId, new Error(`Unknown panorama scene: ${activeSceneId}`));
|
|
@@ -12572,7 +12990,7 @@ function ScenesController({
|
|
|
12572
12990
|
}
|
|
12573
12991
|
startPreload(requested);
|
|
12574
12992
|
}, [activeSceneId, pendingSlot, reportError, sceneMap, startPreload]);
|
|
12575
|
-
const handleReady = (0,
|
|
12993
|
+
const handleReady = (0, import_react45.useCallback)((slot) => {
|
|
12576
12994
|
if (slot !== pendingSlot || phaseRef.current !== "preloading") {
|
|
12577
12995
|
return;
|
|
12578
12996
|
}
|
|
@@ -12603,7 +13021,7 @@ function ScenesController({
|
|
|
12603
13021
|
setPhase("capturing");
|
|
12604
13022
|
setCaptureRequestId((current) => current + 1);
|
|
12605
13023
|
}, [controlsRef, onTransitionEnd, pendingSlot, transition.preset]);
|
|
12606
|
-
const handleCaptured = (0,
|
|
13024
|
+
const handleCaptured = (0, import_react45.useCallback)((nextSnapshot) => {
|
|
12607
13025
|
setSnapshot((current) => {
|
|
12608
13026
|
current?.dispose();
|
|
12609
13027
|
return nextSnapshot;
|
|
@@ -12625,7 +13043,7 @@ function ScenesController({
|
|
|
12625
13043
|
setPhase("transitioning");
|
|
12626
13044
|
setTransitionRunId((current) => current + 1);
|
|
12627
13045
|
}, [manager, pendingSlot, sceneMap, startPreload]);
|
|
12628
|
-
const finishTransition = (0,
|
|
13046
|
+
const finishTransition = (0, import_react45.useCallback)(() => {
|
|
12629
13047
|
const nextSlot = pendingSlot;
|
|
12630
13048
|
const previousScene = transitionFromRef.current;
|
|
12631
13049
|
const nextScene = nextSlot === null ? null : slotsRef.current[nextSlot];
|
|
@@ -12650,12 +13068,12 @@ function ScenesController({
|
|
|
12650
13068
|
});
|
|
12651
13069
|
}
|
|
12652
13070
|
}, [onTransitionEnd, pendingSlot, releaseInteraction, snapshot, transition.preset]);
|
|
12653
|
-
(0,
|
|
13071
|
+
(0, import_react45.useEffect)(() => () => {
|
|
12654
13072
|
releaseInteraction();
|
|
12655
13073
|
snapshot?.dispose();
|
|
12656
13074
|
}, [releaseInteraction, snapshot]);
|
|
12657
|
-
const { gl } = (0,
|
|
12658
|
-
(0,
|
|
13075
|
+
const { gl } = (0, import_fiber22.useThree)();
|
|
13076
|
+
(0, import_react45.useEffect)(() => {
|
|
12659
13077
|
const canvas = gl.domElement;
|
|
12660
13078
|
const onContextLost = (event) => {
|
|
12661
13079
|
event.preventDefault();
|
|
@@ -12679,8 +13097,8 @@ function ScenesController({
|
|
|
12679
13097
|
}, [gl, manager, releaseInteraction, snapshot]);
|
|
12680
13098
|
const renderedScene = slots[liveSlot];
|
|
12681
13099
|
const snapshotVisible = snapshot !== null && (phase === "transitioning" || phase === "recapturing" || phase === "preloading");
|
|
12682
|
-
return /* @__PURE__ */ (0,
|
|
12683
|
-
/* @__PURE__ */ (0,
|
|
13100
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_react45.Fragment, { children: [
|
|
13101
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
12684
13102
|
SnapshotCapture,
|
|
12685
13103
|
{
|
|
12686
13104
|
requestId: captureRequestId,
|
|
@@ -12692,7 +13110,7 @@ function ScenesController({
|
|
|
12692
13110
|
const source = slots[slot];
|
|
12693
13111
|
const isLive = slot === liveSlot;
|
|
12694
13112
|
const isPending = slot === pendingSlot;
|
|
12695
|
-
return /* @__PURE__ */ (0,
|
|
13113
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
12696
13114
|
SceneSource,
|
|
12697
13115
|
{
|
|
12698
13116
|
scene: source,
|
|
@@ -12708,7 +13126,7 @@ function ScenesController({
|
|
|
12708
13126
|
`${slot}:${source?.id ?? "empty"}:${recoveryKey}`
|
|
12709
13127
|
);
|
|
12710
13128
|
}),
|
|
12711
|
-
snapshotVisible ? /* @__PURE__ */ (0,
|
|
13129
|
+
snapshotVisible ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
12712
13130
|
TransitionOverlay,
|
|
12713
13131
|
{
|
|
12714
13132
|
snapshot,
|
|
@@ -12731,11 +13149,11 @@ function Scenes({
|
|
|
12731
13149
|
...rest
|
|
12732
13150
|
}) {
|
|
12733
13151
|
const isControlled = controlledId !== void 0;
|
|
12734
|
-
const [internalId, setInternalId] = (0,
|
|
13152
|
+
const [internalId, setInternalId] = (0, import_react45.useState)(
|
|
12735
13153
|
() => controlledId ?? defaultActiveSceneId ?? scenes[0]?.id ?? ""
|
|
12736
13154
|
);
|
|
12737
13155
|
const resolvedId = isControlled ? controlledId : internalId;
|
|
12738
|
-
const requestSceneChange = (0,
|
|
13156
|
+
const requestSceneChange = (0, import_react45.useCallback)(
|
|
12739
13157
|
(id) => {
|
|
12740
13158
|
if (isControlled) {
|
|
12741
13159
|
onActiveSceneIdChange?.(id);
|
|
@@ -12745,13 +13163,13 @@ function Scenes({
|
|
|
12745
13163
|
},
|
|
12746
13164
|
[isControlled, onActiveSceneIdChange]
|
|
12747
13165
|
);
|
|
12748
|
-
const scenesRef = (0,
|
|
13166
|
+
const scenesRef = (0, import_react45.useRef)(scenes);
|
|
12749
13167
|
scenesRef.current = scenes;
|
|
12750
|
-
const resolvedIdRef = (0,
|
|
13168
|
+
const resolvedIdRef = (0, import_react45.useRef)(resolvedId);
|
|
12751
13169
|
resolvedIdRef.current = resolvedId;
|
|
12752
|
-
const host = (0,
|
|
12753
|
-
const phaseRef = (0,
|
|
12754
|
-
(0,
|
|
13170
|
+
const host = (0, import_react45.useContext)(ScenesHostContext);
|
|
13171
|
+
const phaseRef = (0, import_react45.useRef)("idle");
|
|
13172
|
+
(0, import_react45.useEffect)(() => {
|
|
12755
13173
|
if (!host) {
|
|
12756
13174
|
return;
|
|
12757
13175
|
}
|
|
@@ -12801,12 +13219,12 @@ function Scenes({
|
|
|
12801
13219
|
}
|
|
12802
13220
|
};
|
|
12803
13221
|
}, [host, requestSceneChange]);
|
|
12804
|
-
return /* @__PURE__ */ (0,
|
|
13222
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
12805
13223
|
TileTextureManagerProvider,
|
|
12806
13224
|
{
|
|
12807
13225
|
maxTextureMemoryMb,
|
|
12808
13226
|
maxConcurrentLoads: maxConcurrentTileLoads,
|
|
12809
|
-
children: /* @__PURE__ */ (0,
|
|
13227
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
12810
13228
|
ScenesController,
|
|
12811
13229
|
{
|
|
12812
13230
|
...rest,
|
|
@@ -12820,26 +13238,26 @@ function Scenes({
|
|
|
12820
13238
|
}
|
|
12821
13239
|
|
|
12822
13240
|
// src/hotspot/image-hotspot.tsx
|
|
12823
|
-
var
|
|
12824
|
-
var
|
|
12825
|
-
var
|
|
13241
|
+
var import_fiber24 = require("@react-three/fiber");
|
|
13242
|
+
var import_react49 = require("react");
|
|
13243
|
+
var import_three26 = require("three");
|
|
12826
13244
|
|
|
12827
13245
|
// src/hotspot/hotspot-anchor.tsx
|
|
12828
|
-
var
|
|
12829
|
-
var
|
|
12830
|
-
var
|
|
13246
|
+
var import_fiber23 = require("@react-three/fiber");
|
|
13247
|
+
var import_react48 = require("react");
|
|
13248
|
+
var import_three24 = require("three");
|
|
12831
13249
|
|
|
12832
13250
|
// src/hotspot/hotspot-tooltip.tsx
|
|
12833
|
-
var
|
|
13251
|
+
var import_react47 = require("react");
|
|
12834
13252
|
|
|
12835
13253
|
// src/webvr/stereo-html.tsx
|
|
12836
13254
|
var import_drei = require("@react-three/drei");
|
|
12837
|
-
var
|
|
12838
|
-
var
|
|
13255
|
+
var import_react46 = require("react");
|
|
13256
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
12839
13257
|
function useFallbackStereoView() {
|
|
12840
|
-
const runtime = (0,
|
|
13258
|
+
const runtime = (0, import_react46.useContext)(WebVRRuntimeContext);
|
|
12841
13259
|
const host = runtime?.host ?? null;
|
|
12842
|
-
const fallback = (0,
|
|
13260
|
+
const fallback = (0, import_react46.useSyncExternalStore)(
|
|
12843
13261
|
(onStoreChange) => host ? subscribeWebVRHost(host, onStoreChange) : () => void 0,
|
|
12844
13262
|
() => isFallbackStereoMode(host?.snapshot.mode ?? null),
|
|
12845
13263
|
() => false
|
|
@@ -12860,10 +13278,10 @@ function stereoCalculatePosition(eye, stereoView) {
|
|
|
12860
13278
|
function PanoHtml({ children, ...htmlProps }) {
|
|
12861
13279
|
const stereoView = useFallbackStereoView();
|
|
12862
13280
|
if (!stereoView) {
|
|
12863
|
-
return /* @__PURE__ */ (0,
|
|
13281
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_drei.Html, { ...htmlProps, children });
|
|
12864
13282
|
}
|
|
12865
|
-
return /* @__PURE__ */ (0,
|
|
12866
|
-
/* @__PURE__ */ (0,
|
|
13283
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [
|
|
13284
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
12867
13285
|
import_drei.Html,
|
|
12868
13286
|
{
|
|
12869
13287
|
...htmlProps,
|
|
@@ -12871,7 +13289,7 @@ function PanoHtml({ children, ...htmlProps }) {
|
|
|
12871
13289
|
children
|
|
12872
13290
|
}
|
|
12873
13291
|
),
|
|
12874
|
-
/* @__PURE__ */ (0,
|
|
13292
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
12875
13293
|
import_drei.Html,
|
|
12876
13294
|
{
|
|
12877
13295
|
...htmlProps,
|
|
@@ -12884,7 +13302,7 @@ function PanoHtml({ children, ...htmlProps }) {
|
|
|
12884
13302
|
}
|
|
12885
13303
|
|
|
12886
13304
|
// src/hotspot/hotspot-tooltip.tsx
|
|
12887
|
-
var
|
|
13305
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
12888
13306
|
var DEFAULT_HOTSPOT_TOOLTIP_OFFSET = 12;
|
|
12889
13307
|
var DEFAULT_HOTSPOT_TOOLTIP_APPEARANCE = {
|
|
12890
13308
|
background: "rgba(22, 22, 22, 0.72)",
|
|
@@ -12893,7 +13311,10 @@ var DEFAULT_HOTSPOT_TOOLTIP_APPEARANCE = {
|
|
|
12893
13311
|
borderRadius: 8,
|
|
12894
13312
|
shadow: "0 8px 24px rgba(0, 0, 0, 0.35)",
|
|
12895
13313
|
padding: 8,
|
|
12896
|
-
fontSize: 12
|
|
13314
|
+
fontSize: 12,
|
|
13315
|
+
fontFamily: "inherit",
|
|
13316
|
+
lineHeight: 1.4,
|
|
13317
|
+
letterSpacing: "normal"
|
|
12897
13318
|
};
|
|
12898
13319
|
var WRAPPER_STYLE = {
|
|
12899
13320
|
pointerEvents: "none"
|
|
@@ -12953,16 +13374,16 @@ function HotspotTooltip({
|
|
|
12953
13374
|
offset = DEFAULT_HOTSPOT_TOOLTIP_OFFSET,
|
|
12954
13375
|
appearance
|
|
12955
13376
|
}) {
|
|
12956
|
-
const [imageFailed, setImageFailed] = (0,
|
|
12957
|
-
(0,
|
|
13377
|
+
const [imageFailed, setImageFailed] = (0, import_react47.useState)(false);
|
|
13378
|
+
(0, import_react47.useEffect)(() => {
|
|
12958
13379
|
setImageFailed(false);
|
|
12959
13380
|
}, [content.image]);
|
|
12960
13381
|
const showImage = Boolean(content.image) && !imageFailed;
|
|
12961
|
-
const resolvedAppearance = (0,
|
|
13382
|
+
const resolvedAppearance = (0, import_react47.useMemo)(
|
|
12962
13383
|
() => resolveHotspotTooltipAppearance(appearance),
|
|
12963
13384
|
[appearance]
|
|
12964
13385
|
);
|
|
12965
|
-
const bubbleStyle = (0,
|
|
13386
|
+
const bubbleStyle = (0, import_react47.useMemo)(
|
|
12966
13387
|
() => ({
|
|
12967
13388
|
background: resolvedAppearance.background,
|
|
12968
13389
|
border: resolvedAppearance.border,
|
|
@@ -12970,6 +13391,9 @@ function HotspotTooltip({
|
|
|
12970
13391
|
boxShadow: resolvedAppearance.shadow,
|
|
12971
13392
|
color: resolvedAppearance.color,
|
|
12972
13393
|
fontSize: toCssLength(resolvedAppearance.fontSize),
|
|
13394
|
+
fontFamily: resolvedAppearance.fontFamily,
|
|
13395
|
+
lineHeight: resolvedAppearance.lineHeight,
|
|
13396
|
+
letterSpacing: resolvedAppearance.letterSpacing,
|
|
12973
13397
|
padding: toCssLength(resolvedAppearance.padding),
|
|
12974
13398
|
transform: tooltipBubbleTransform(
|
|
12975
13399
|
placement,
|
|
@@ -12981,30 +13405,33 @@ function HotspotTooltip({
|
|
|
12981
13405
|
if (!showImage && !content.text) {
|
|
12982
13406
|
return null;
|
|
12983
13407
|
}
|
|
12984
|
-
return /* @__PURE__ */ (0,
|
|
12985
|
-
|
|
12986
|
-
|
|
12987
|
-
|
|
12988
|
-
|
|
12989
|
-
|
|
12990
|
-
|
|
12991
|
-
|
|
12992
|
-
|
|
12993
|
-
|
|
12994
|
-
|
|
12995
|
-
|
|
12996
|
-
|
|
12997
|
-
|
|
12998
|
-
|
|
12999
|
-
|
|
13000
|
-
|
|
13001
|
-
|
|
13002
|
-
|
|
13003
|
-
|
|
13408
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(PanoHtml, { pointerEvents: "none", style: WRAPPER_STYLE, zIndexRange: [20, 10], children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "pano-hotspot-tooltip", role: "tooltip", style: bubbleStyle, children: [
|
|
13409
|
+
showImage ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
13410
|
+
"img",
|
|
13411
|
+
{
|
|
13412
|
+
alt: content.imageAlt ?? content.text ?? "",
|
|
13413
|
+
className: "pano-hotspot-tooltip-image",
|
|
13414
|
+
onError: () => setImageFailed(true),
|
|
13415
|
+
src: content.image
|
|
13416
|
+
}
|
|
13417
|
+
) : null,
|
|
13418
|
+
content.text ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
13419
|
+
"p",
|
|
13420
|
+
{
|
|
13421
|
+
className: "pano-hotspot-tooltip-text",
|
|
13422
|
+
style: {
|
|
13423
|
+
lineHeight: "inherit",
|
|
13424
|
+
letterSpacing: "inherit",
|
|
13425
|
+
fontFamily: "inherit"
|
|
13426
|
+
},
|
|
13427
|
+
children: content.text
|
|
13428
|
+
}
|
|
13429
|
+
) : null
|
|
13430
|
+
] }) });
|
|
13004
13431
|
}
|
|
13005
13432
|
|
|
13006
13433
|
// src/hotspot/hotspot-anchor.tsx
|
|
13007
|
-
var
|
|
13434
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
13008
13435
|
var DEFAULT_FLOATING_DISTANCE = 10;
|
|
13009
13436
|
var PANORAMA_RADIUS = DEFAULT_PANORAMA_RADIUS;
|
|
13010
13437
|
var PANORAMA_SURFACE_INSET = 4;
|
|
@@ -13012,28 +13439,28 @@ var DEFAULT_REFERENCE_FOV = 75;
|
|
|
13012
13439
|
var MIN_ANGULAR_SIZE = 0.01;
|
|
13013
13440
|
var MAX_ANGULAR_SIZE = 179;
|
|
13014
13441
|
var DRAG_EPSILON_DEGREES = 1e-3;
|
|
13015
|
-
var LOCAL_FORWARD = new
|
|
13016
|
-
var TOOLTIP_WORLD_BOX = new
|
|
13017
|
-
var TOOLTIP_LOCAL_BOX = new
|
|
13018
|
-
var TOOLTIP_CORNER = new
|
|
13019
|
-
var TOOLTIP_INVERSE = new
|
|
13020
|
-
var TOOLTIP_WORLD_CORNER = new
|
|
13021
|
-
var TOOLTIP_PROJECTED = new
|
|
13022
|
-
var TOOLTIP_RAY_ORIGIN = new
|
|
13023
|
-
var TOOLTIP_RAY_FAR = new
|
|
13024
|
-
var TOOLTIP_RAY_DIRECTION = new
|
|
13025
|
-
var TOOLTIP_RAY = new
|
|
13026
|
-
var TOOLTIP_PLANE = new
|
|
13027
|
-
var TOOLTIP_INTERSECTION = new
|
|
13028
|
-
var TOOLTIP_PLANE_NORMAL = new
|
|
13029
|
-
var TOOLTIP_PLANE_POINT = new
|
|
13442
|
+
var LOCAL_FORWARD = new import_three24.Vector3(0, 0, 1);
|
|
13443
|
+
var TOOLTIP_WORLD_BOX = new import_three24.Box3();
|
|
13444
|
+
var TOOLTIP_LOCAL_BOX = new import_three24.Box3();
|
|
13445
|
+
var TOOLTIP_CORNER = new import_three24.Vector3();
|
|
13446
|
+
var TOOLTIP_INVERSE = new import_three24.Matrix4();
|
|
13447
|
+
var TOOLTIP_WORLD_CORNER = new import_three24.Vector3();
|
|
13448
|
+
var TOOLTIP_PROJECTED = new import_three24.Vector3();
|
|
13449
|
+
var TOOLTIP_RAY_ORIGIN = new import_three24.Vector3();
|
|
13450
|
+
var TOOLTIP_RAY_FAR = new import_three24.Vector3();
|
|
13451
|
+
var TOOLTIP_RAY_DIRECTION = new import_three24.Vector3();
|
|
13452
|
+
var TOOLTIP_RAY = new import_three24.Ray();
|
|
13453
|
+
var TOOLTIP_PLANE = new import_three24.Plane();
|
|
13454
|
+
var TOOLTIP_INTERSECTION = new import_three24.Vector3();
|
|
13455
|
+
var TOOLTIP_PLANE_NORMAL = new import_three24.Vector3();
|
|
13456
|
+
var TOOLTIP_PLANE_POINT = new import_three24.Vector3();
|
|
13030
13457
|
var HOTSPOT_MODE_RENDERING = {
|
|
13031
13458
|
surface: { orientation: "surface", placement: "surface" },
|
|
13032
13459
|
billboard: { orientation: "billboard", placement: "floating" }
|
|
13033
13460
|
};
|
|
13034
13461
|
function angularSizeToWorldSize(size, radius) {
|
|
13035
|
-
const safeSize = Number.isFinite(size) ?
|
|
13036
|
-
return 2 * radius * Math.tan(
|
|
13462
|
+
const safeSize = Number.isFinite(size) ? import_three24.MathUtils.clamp(Math.abs(size), MIN_ANGULAR_SIZE, MAX_ANGULAR_SIZE) : MIN_ANGULAR_SIZE;
|
|
13463
|
+
return 2 * radius * Math.tan(import_three24.MathUtils.degToRad(safeSize) / 2);
|
|
13037
13464
|
}
|
|
13038
13465
|
function resolveScale(scale) {
|
|
13039
13466
|
return Number.isFinite(scale) && scale > 0 ? scale : 1;
|
|
@@ -13046,7 +13473,7 @@ function resolveDistance(placement, distance, width, height) {
|
|
|
13046
13473
|
if (!Number.isFinite(distance)) {
|
|
13047
13474
|
return DEFAULT_FLOATING_DISTANCE;
|
|
13048
13475
|
}
|
|
13049
|
-
return
|
|
13476
|
+
return import_three24.MathUtils.clamp(Math.abs(distance), 0.1, maximumDistance);
|
|
13050
13477
|
}
|
|
13051
13478
|
function applyHotspotTransform(group, camera, orientation2, surfaceQuaternion3, rotation, scaleMode, referenceFov, useAngularScale, worldWidth, worldHeight) {
|
|
13052
13479
|
if (orientation2 === "billboard") {
|
|
@@ -13054,8 +13481,8 @@ function applyHotspotTransform(group, camera, orientation2, surfaceQuaternion3,
|
|
|
13054
13481
|
} else {
|
|
13055
13482
|
group.quaternion.copy(surfaceQuaternion3);
|
|
13056
13483
|
}
|
|
13057
|
-
group.rotateOnAxis(LOCAL_FORWARD,
|
|
13058
|
-
const scaleFactor = scaleMode === "fixed" && camera instanceof
|
|
13484
|
+
group.rotateOnAxis(LOCAL_FORWARD, import_three24.MathUtils.degToRad(-rotation));
|
|
13485
|
+
const scaleFactor = scaleMode === "fixed" && camera instanceof import_three24.PerspectiveCamera ? fixedScaleFactor(camera.fov, referenceFov) : 1;
|
|
13059
13486
|
group.scale.set(
|
|
13060
13487
|
(useAngularScale ? worldWidth : 1) * scaleFactor,
|
|
13061
13488
|
(useAngularScale ? worldHeight : 1) * scaleFactor,
|
|
@@ -13064,40 +13491,40 @@ function applyHotspotTransform(group, camera, orientation2, surfaceQuaternion3,
|
|
|
13064
13491
|
group.updateMatrixWorld();
|
|
13065
13492
|
}
|
|
13066
13493
|
function maximumHotspotDistance(width, height) {
|
|
13067
|
-
const safeWidth =
|
|
13494
|
+
const safeWidth = import_three24.MathUtils.clamp(
|
|
13068
13495
|
Math.abs(Number.isFinite(width) ? width : MIN_ANGULAR_SIZE),
|
|
13069
13496
|
MIN_ANGULAR_SIZE,
|
|
13070
13497
|
MAX_ANGULAR_SIZE
|
|
13071
13498
|
);
|
|
13072
|
-
const safeHeight =
|
|
13499
|
+
const safeHeight = import_three24.MathUtils.clamp(
|
|
13073
13500
|
Math.abs(Number.isFinite(height) ? height : MIN_ANGULAR_SIZE),
|
|
13074
13501
|
MIN_ANGULAR_SIZE,
|
|
13075
13502
|
MAX_ANGULAR_SIZE
|
|
13076
13503
|
);
|
|
13077
13504
|
const cornerFactor = Math.hypot(
|
|
13078
13505
|
1,
|
|
13079
|
-
Math.tan(
|
|
13080
|
-
Math.tan(
|
|
13506
|
+
Math.tan(import_three24.MathUtils.degToRad(safeWidth) / 2),
|
|
13507
|
+
Math.tan(import_three24.MathUtils.degToRad(safeHeight) / 2)
|
|
13081
13508
|
);
|
|
13082
13509
|
return (PANORAMA_RADIUS - PANORAMA_SURFACE_INSET) / cornerFactor;
|
|
13083
13510
|
}
|
|
13084
13511
|
function fixedScaleFactor(cameraFov, referenceFov) {
|
|
13085
|
-
const safeReferenceFov =
|
|
13086
|
-
return Math.tan(
|
|
13512
|
+
const safeReferenceFov = import_three24.MathUtils.clamp(referenceFov, 1, 179);
|
|
13513
|
+
return Math.tan(import_three24.MathUtils.degToRad(cameraFov) / 2) / Math.tan(import_three24.MathUtils.degToRad(safeReferenceFov) / 2);
|
|
13087
13514
|
}
|
|
13088
13515
|
function createSurfaceQuaternion(position) {
|
|
13089
13516
|
const outward = panoPositionToVector3(position).normalize();
|
|
13090
13517
|
const inward = outward.clone().negate();
|
|
13091
|
-
const pitch =
|
|
13092
|
-
const yaw =
|
|
13093
|
-
const localUp = new
|
|
13518
|
+
const pitch = import_three24.MathUtils.degToRad(position.pitch);
|
|
13519
|
+
const yaw = import_three24.MathUtils.degToRad(position.yaw);
|
|
13520
|
+
const localUp = new import_three24.Vector3(
|
|
13094
13521
|
-Math.sin(pitch) * Math.sin(yaw),
|
|
13095
13522
|
Math.cos(pitch),
|
|
13096
13523
|
Math.sin(pitch) * Math.cos(yaw)
|
|
13097
13524
|
).normalize();
|
|
13098
13525
|
const localRight = localUp.clone().cross(inward).normalize();
|
|
13099
|
-
const basis = new
|
|
13100
|
-
return new
|
|
13526
|
+
const basis = new import_three24.Matrix4().makeBasis(localRight, localUp, inward);
|
|
13527
|
+
return new import_three24.Quaternion().setFromRotationMatrix(basis);
|
|
13101
13528
|
}
|
|
13102
13529
|
function makeInteractionEvent(id, position, event) {
|
|
13103
13530
|
return {
|
|
@@ -13110,7 +13537,7 @@ function makeInteractionEvent(id, position, event) {
|
|
|
13110
13537
|
function angularDistance(a, b) {
|
|
13111
13538
|
const aVector = panoPositionToVector3(a);
|
|
13112
13539
|
const bVector = panoPositionToVector3(b);
|
|
13113
|
-
return
|
|
13540
|
+
return import_three24.MathUtils.radToDeg(aVector.angleTo(bVector));
|
|
13114
13541
|
}
|
|
13115
13542
|
function isTooltipOpen(trigger, hovered, focused, pinned) {
|
|
13116
13543
|
switch (trigger) {
|
|
@@ -13341,24 +13768,24 @@ function HotspotAnchor({
|
|
|
13341
13768
|
onPositionChange,
|
|
13342
13769
|
onDragEnd
|
|
13343
13770
|
}) {
|
|
13344
|
-
const controlsRef = (0,
|
|
13345
|
-
const hotspotTargetRegistry = (0,
|
|
13346
|
-
const eventBus = (0,
|
|
13771
|
+
const controlsRef = (0, import_react48.useContext)(PanoramaViewContext);
|
|
13772
|
+
const hotspotTargetRegistry = (0, import_react48.useContext)(HotspotTargetRegistryContext);
|
|
13773
|
+
const eventBus = (0, import_react48.useContext)(PanoEventBusContext);
|
|
13347
13774
|
const cursorApi = usePanoCursor();
|
|
13348
|
-
const { camera, size } = (0,
|
|
13349
|
-
const groupRef = (0,
|
|
13350
|
-
const tooltipAnchorRef = (0,
|
|
13351
|
-
const dragStateRef = (0,
|
|
13352
|
-
const suppressNextClickRef = (0,
|
|
13353
|
-
const [hovered, setHovered] = (0,
|
|
13354
|
-
const [dragging, setDragging] = (0,
|
|
13355
|
-
const [pinned, setPinned] = (0,
|
|
13356
|
-
const tooltipContent = (0,
|
|
13775
|
+
const { camera, size } = (0, import_fiber23.useThree)();
|
|
13776
|
+
const groupRef = (0, import_react48.useRef)(null);
|
|
13777
|
+
const tooltipAnchorRef = (0, import_react48.useRef)(null);
|
|
13778
|
+
const dragStateRef = (0, import_react48.useRef)(null);
|
|
13779
|
+
const suppressNextClickRef = (0, import_react48.useRef)(false);
|
|
13780
|
+
const [hovered, setHovered] = (0, import_react48.useState)(false);
|
|
13781
|
+
const [dragging, setDragging] = (0, import_react48.useState)(false);
|
|
13782
|
+
const [pinned, setPinned] = (0, import_react48.useState)(false);
|
|
13783
|
+
const tooltipContent = (0, import_react48.useMemo)(
|
|
13357
13784
|
() => resolveHotspotTooltipContent(tooltip),
|
|
13358
13785
|
[tooltip]
|
|
13359
13786
|
);
|
|
13360
13787
|
const normalizedPosition = normalizePanoPosition(position);
|
|
13361
|
-
(0,
|
|
13788
|
+
(0, import_react48.useEffect)(() => {
|
|
13362
13789
|
if (!hotspotTargetRegistry) {
|
|
13363
13790
|
return;
|
|
13364
13791
|
}
|
|
@@ -13375,19 +13802,19 @@ function HotspotAnchor({
|
|
|
13375
13802
|
scaledWidth,
|
|
13376
13803
|
scaledHeight
|
|
13377
13804
|
);
|
|
13378
|
-
const worldPosition = (0,
|
|
13805
|
+
const worldPosition = (0, import_react48.useMemo)(
|
|
13379
13806
|
() => panoPositionToVector3(normalizedPosition, resolvedDistance),
|
|
13380
13807
|
[normalizedPosition.pitch, normalizedPosition.yaw, resolvedDistance]
|
|
13381
13808
|
);
|
|
13382
|
-
const surfaceQuaternion3 = (0,
|
|
13809
|
+
const surfaceQuaternion3 = (0, import_react48.useMemo)(
|
|
13383
13810
|
() => createSurfaceQuaternion(normalizedPosition),
|
|
13384
13811
|
[normalizedPosition.pitch, normalizedPosition.yaw]
|
|
13385
13812
|
);
|
|
13386
13813
|
const worldWidth = angularSizeToWorldSize(scaledWidth, resolvedDistance);
|
|
13387
13814
|
const worldHeight = angularSizeToWorldSize(scaledHeight, resolvedDistance);
|
|
13388
|
-
const focusGeometry = (0,
|
|
13389
|
-
const planeGeometry = new
|
|
13390
|
-
const geometry = new
|
|
13815
|
+
const focusGeometry = (0, import_react48.useMemo)(() => {
|
|
13816
|
+
const planeGeometry = new import_three24.PlaneGeometry(1, 1);
|
|
13817
|
+
const geometry = new import_three24.EdgesGeometry(planeGeometry);
|
|
13391
13818
|
planeGeometry.dispose();
|
|
13392
13819
|
return geometry;
|
|
13393
13820
|
}, []);
|
|
@@ -13412,14 +13839,14 @@ function HotspotAnchor({
|
|
|
13412
13839
|
});
|
|
13413
13840
|
const tooltipOpen = visible && tooltipContent !== null && isTooltipOpen(tooltipTrigger, hovered, focused, pinned);
|
|
13414
13841
|
const cursorClaimId = hotspotCursorClaimId(id);
|
|
13415
|
-
(0,
|
|
13842
|
+
(0, import_react48.useEffect)(
|
|
13416
13843
|
() => () => {
|
|
13417
13844
|
dragStateRef.current?.releaseInteractionLock();
|
|
13418
13845
|
dragStateRef.current = null;
|
|
13419
13846
|
},
|
|
13420
13847
|
[]
|
|
13421
13848
|
);
|
|
13422
|
-
(0,
|
|
13849
|
+
(0, import_react48.useEffect)(() => {
|
|
13423
13850
|
if (!cursorApi) {
|
|
13424
13851
|
return;
|
|
13425
13852
|
}
|
|
@@ -13441,14 +13868,14 @@ function HotspotAnchor({
|
|
|
13441
13868
|
hovered,
|
|
13442
13869
|
visible
|
|
13443
13870
|
]);
|
|
13444
|
-
(0,
|
|
13871
|
+
(0, import_react48.useEffect)(
|
|
13445
13872
|
() => () => {
|
|
13446
13873
|
cursorApi?.release(cursorClaimId);
|
|
13447
13874
|
},
|
|
13448
13875
|
[cursorApi, cursorClaimId]
|
|
13449
13876
|
);
|
|
13450
|
-
(0,
|
|
13451
|
-
(0,
|
|
13877
|
+
(0, import_react48.useEffect)(() => () => focusGeometry.dispose(), [focusGeometry]);
|
|
13878
|
+
(0, import_react48.useEffect)(() => {
|
|
13452
13879
|
if (tooltipTrigger !== "click") {
|
|
13453
13880
|
setPinned(false);
|
|
13454
13881
|
return;
|
|
@@ -13457,12 +13884,12 @@ function HotspotAnchor({
|
|
|
13457
13884
|
setPinned(false);
|
|
13458
13885
|
});
|
|
13459
13886
|
}, [eventBus, tooltipTrigger]);
|
|
13460
|
-
(0,
|
|
13887
|
+
(0, import_react48.useEffect)(() => {
|
|
13461
13888
|
if (tooltipTrigger !== "hover") {
|
|
13462
13889
|
setHovered(false);
|
|
13463
13890
|
}
|
|
13464
13891
|
}, [tooltipTrigger]);
|
|
13465
|
-
(0,
|
|
13892
|
+
(0, import_react48.useEffect)(() => {
|
|
13466
13893
|
if (acceptsPointer) {
|
|
13467
13894
|
return;
|
|
13468
13895
|
}
|
|
@@ -13475,7 +13902,7 @@ function HotspotAnchor({
|
|
|
13475
13902
|
dragStateRef.current = null;
|
|
13476
13903
|
setDragging(false);
|
|
13477
13904
|
}, [acceptsPointer]);
|
|
13478
|
-
(0,
|
|
13905
|
+
(0, import_react48.useLayoutEffect)(() => {
|
|
13479
13906
|
const group = groupRef.current;
|
|
13480
13907
|
if (!group) {
|
|
13481
13908
|
return;
|
|
@@ -13516,7 +13943,7 @@ function HotspotAnchor({
|
|
|
13516
13943
|
worldHeight,
|
|
13517
13944
|
worldWidth
|
|
13518
13945
|
]);
|
|
13519
|
-
(0,
|
|
13946
|
+
(0, import_fiber23.useFrame)((state) => {
|
|
13520
13947
|
const group = groupRef.current;
|
|
13521
13948
|
if (!group) {
|
|
13522
13949
|
return;
|
|
@@ -13574,7 +14001,7 @@ function HotspotAnchor({
|
|
|
13574
14001
|
setHovered(true);
|
|
13575
14002
|
}
|
|
13576
14003
|
};
|
|
13577
|
-
return /* @__PURE__ */ (0,
|
|
14004
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
13578
14005
|
"group",
|
|
13579
14006
|
{
|
|
13580
14007
|
ref: groupRef,
|
|
@@ -13651,18 +14078,18 @@ function HotspotAnchor({
|
|
|
13651
14078
|
} : void 0,
|
|
13652
14079
|
onPointerUp: acceptsPointer ? (event) => releasePointer(event, true) : void 0,
|
|
13653
14080
|
children: [
|
|
13654
|
-
focused ? focusContent ?? /* @__PURE__ */ (0,
|
|
14081
|
+
focused ? focusContent ?? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
13655
14082
|
"lineSegments",
|
|
13656
14083
|
{
|
|
13657
14084
|
geometry: focusGeometry,
|
|
13658
14085
|
position: [0, 0, 0.01],
|
|
13659
14086
|
renderOrder: renderOrder + 1,
|
|
13660
14087
|
scale: [1.12, 1.12, 1],
|
|
13661
|
-
children: /* @__PURE__ */ (0,
|
|
14088
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("lineBasicMaterial", { color: "#f5fbfc", depthTest: false })
|
|
13662
14089
|
}
|
|
13663
14090
|
) : null,
|
|
13664
14091
|
children,
|
|
13665
|
-
tooltipOpen && tooltipContent ? /* @__PURE__ */ (0,
|
|
14092
|
+
tooltipOpen && tooltipContent ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("group", { ref: tooltipAnchorRef, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
13666
14093
|
HotspotTooltip,
|
|
13667
14094
|
{
|
|
13668
14095
|
appearance: tooltipAppearance,
|
|
@@ -13677,10 +14104,10 @@ function HotspotAnchor({
|
|
|
13677
14104
|
}
|
|
13678
14105
|
|
|
13679
14106
|
// src/hotspot/hotspot-plane.tsx
|
|
13680
|
-
var
|
|
13681
|
-
var
|
|
14107
|
+
var import_three25 = require("three");
|
|
14108
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
13682
14109
|
var HOTSPOT_ALPHA_CUTOFF = 0.05;
|
|
13683
|
-
var SAMPLE_UV = new
|
|
14110
|
+
var SAMPLE_UV = new import_three25.Vector2();
|
|
13684
14111
|
var RAYCAST_HITS = [];
|
|
13685
14112
|
var IMAGE_DATA_CACHE = /* @__PURE__ */ new WeakMap();
|
|
13686
14113
|
function clampOpacity(opacity) {
|
|
@@ -13754,8 +14181,8 @@ function sampleTextureAlpha(texture, u, v) {
|
|
|
13754
14181
|
}
|
|
13755
14182
|
function hotspotPlaneRaycast(raycaster, intersects2) {
|
|
13756
14183
|
const material = Array.isArray(this.material) ? this.material[0] : this.material;
|
|
13757
|
-
if (!(material instanceof
|
|
13758
|
-
|
|
14184
|
+
if (!(material instanceof import_three25.MeshBasicMaterial)) {
|
|
14185
|
+
import_three25.Mesh.prototype.raycast.call(this, raycaster, intersects2);
|
|
13759
14186
|
return;
|
|
13760
14187
|
}
|
|
13761
14188
|
const cutoff = Math.max(material.alphaTest, HOTSPOT_ALPHA_CUTOFF);
|
|
@@ -13763,7 +14190,7 @@ function hotspotPlaneRaycast(raycaster, intersects2) {
|
|
|
13763
14190
|
return;
|
|
13764
14191
|
}
|
|
13765
14192
|
RAYCAST_HITS.length = 0;
|
|
13766
|
-
|
|
14193
|
+
import_three25.Mesh.prototype.raycast.call(this, raycaster, RAYCAST_HITS);
|
|
13767
14194
|
const map = material.map;
|
|
13768
14195
|
for (const hit of RAYCAST_HITS) {
|
|
13769
14196
|
if (!map || !hit.uv) {
|
|
@@ -13780,16 +14207,17 @@ function HotspotPlane({
|
|
|
13780
14207
|
map,
|
|
13781
14208
|
opacity
|
|
13782
14209
|
}) {
|
|
13783
|
-
return /* @__PURE__ */ (0,
|
|
13784
|
-
/* @__PURE__ */ (0,
|
|
13785
|
-
/* @__PURE__ */ (0,
|
|
13786
|
-
|
|
14210
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("mesh", { raycast: hotspotPlaneRaycast, children: [
|
|
14211
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("planeGeometry", { args: [1, 1] }),
|
|
14212
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
14213
|
+
PanoBasicMaterial,
|
|
13787
14214
|
{
|
|
14215
|
+
target: "hotspot",
|
|
13788
14216
|
alphaTest: HOTSPOT_ALPHA_CUTOFF,
|
|
13789
14217
|
alphaToCoverage: true,
|
|
13790
14218
|
map,
|
|
13791
14219
|
opacity: map ? clampOpacity(opacity) : 0,
|
|
13792
|
-
side:
|
|
14220
|
+
side: import_three25.DoubleSide,
|
|
13793
14221
|
toneMapped: false,
|
|
13794
14222
|
transparent: true
|
|
13795
14223
|
}
|
|
@@ -13798,15 +14226,15 @@ function HotspotPlane({
|
|
|
13798
14226
|
}
|
|
13799
14227
|
|
|
13800
14228
|
// src/hotspot/image-hotspot.tsx
|
|
13801
|
-
var
|
|
14229
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
13802
14230
|
function useHotspotImageTexture(src, onLoad, onError) {
|
|
13803
|
-
const gl = (0,
|
|
13804
|
-
const [texture, setTexture] = (0,
|
|
13805
|
-
const onLoadRef = (0,
|
|
13806
|
-
const onErrorRef = (0,
|
|
14231
|
+
const gl = (0, import_fiber24.useThree)((state) => state.gl);
|
|
14232
|
+
const [texture, setTexture] = (0, import_react49.useState)(null);
|
|
14233
|
+
const onLoadRef = (0, import_react49.useRef)(onLoad);
|
|
14234
|
+
const onErrorRef = (0, import_react49.useRef)(onError);
|
|
13807
14235
|
onLoadRef.current = onLoad;
|
|
13808
14236
|
onErrorRef.current = onError;
|
|
13809
|
-
(0,
|
|
14237
|
+
(0, import_react49.useEffect)(() => {
|
|
13810
14238
|
let active = true;
|
|
13811
14239
|
setTexture(null);
|
|
13812
14240
|
if (!src) {
|
|
@@ -13814,7 +14242,7 @@ function useHotspotImageTexture(src, onLoad, onError) {
|
|
|
13814
14242
|
active = false;
|
|
13815
14243
|
};
|
|
13816
14244
|
}
|
|
13817
|
-
const loader = new
|
|
14245
|
+
const loader = new import_three26.TextureLoader();
|
|
13818
14246
|
loader.load(
|
|
13819
14247
|
src,
|
|
13820
14248
|
(loadedTexture) => {
|
|
@@ -13822,11 +14250,11 @@ function useHotspotImageTexture(src, onLoad, onError) {
|
|
|
13822
14250
|
loadedTexture.dispose();
|
|
13823
14251
|
return;
|
|
13824
14252
|
}
|
|
13825
|
-
loadedTexture.colorSpace =
|
|
13826
|
-
loadedTexture.wrapS =
|
|
13827
|
-
loadedTexture.wrapT =
|
|
13828
|
-
loadedTexture.magFilter =
|
|
13829
|
-
loadedTexture.minFilter =
|
|
14253
|
+
loadedTexture.colorSpace = import_three26.SRGBColorSpace;
|
|
14254
|
+
loadedTexture.wrapS = import_three26.ClampToEdgeWrapping;
|
|
14255
|
+
loadedTexture.wrapT = import_three26.ClampToEdgeWrapping;
|
|
14256
|
+
loadedTexture.magFilter = import_three26.LinearFilter;
|
|
14257
|
+
loadedTexture.minFilter = import_three26.LinearMipmapLinearFilter;
|
|
13830
14258
|
loadedTexture.generateMipmaps = true;
|
|
13831
14259
|
loadedTexture.anisotropy = gl.capabilities.getMaxAnisotropy();
|
|
13832
14260
|
loadedTexture.needsUpdate = true;
|
|
@@ -13844,7 +14272,7 @@ function useHotspotImageTexture(src, onLoad, onError) {
|
|
|
13844
14272
|
active = false;
|
|
13845
14273
|
};
|
|
13846
14274
|
}, [gl, src]);
|
|
13847
|
-
(0,
|
|
14275
|
+
(0, import_react49.useEffect)(
|
|
13848
14276
|
() => () => {
|
|
13849
14277
|
texture?.dispose();
|
|
13850
14278
|
},
|
|
@@ -13862,20 +14290,20 @@ function ImageHotspot({
|
|
|
13862
14290
|
...anchorProps
|
|
13863
14291
|
}) {
|
|
13864
14292
|
const texture = useHotspotImageTexture(src, onLoad, onError);
|
|
13865
|
-
return /* @__PURE__ */ (0,
|
|
14293
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(HotspotAnchor, { ...anchorProps, height, width, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(HotspotPlane, { map: texture, opacity }) });
|
|
13866
14294
|
}
|
|
13867
14295
|
|
|
13868
14296
|
// src/hotspot/polygon-hotspot.tsx
|
|
13869
|
-
var
|
|
13870
|
-
var
|
|
14297
|
+
var import_react51 = require("react");
|
|
14298
|
+
var import_three28 = require("three");
|
|
13871
14299
|
|
|
13872
14300
|
// src/hotspot/hotspot-stroke-line.tsx
|
|
13873
14301
|
var import_drei2 = require("@react-three/drei");
|
|
13874
|
-
var
|
|
13875
|
-
var
|
|
13876
|
-
var
|
|
13877
|
-
var
|
|
13878
|
-
var LINE_WORLD_POSITION = new
|
|
14302
|
+
var import_fiber25 = require("@react-three/fiber");
|
|
14303
|
+
var import_react50 = require("react");
|
|
14304
|
+
var import_three27 = require("three");
|
|
14305
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
14306
|
+
var LINE_WORLD_POSITION = new import_three27.Vector3();
|
|
13879
14307
|
function applyScreenSpaceDashScale(object, camera, viewportHeight) {
|
|
13880
14308
|
const material = object?.material;
|
|
13881
14309
|
if (!object || typeof material?.dashScale !== "number") {
|
|
@@ -13883,8 +14311,8 @@ function applyScreenSpaceDashScale(object, camera, viewportHeight) {
|
|
|
13883
14311
|
}
|
|
13884
14312
|
object.getWorldPosition(LINE_WORLD_POSITION);
|
|
13885
14313
|
const depth = Math.max(camera.position.distanceTo(LINE_WORLD_POSITION), 1);
|
|
13886
|
-
const fov = camera instanceof
|
|
13887
|
-
material.dashScale = viewportHeight / (2 * Math.tan(
|
|
14314
|
+
const fov = camera instanceof import_three27.PerspectiveCamera ? camera.fov : 75;
|
|
14315
|
+
material.dashScale = viewportHeight / (2 * Math.tan(import_three27.MathUtils.degToRad(fov) * 0.5) * depth);
|
|
13888
14316
|
}
|
|
13889
14317
|
function resolveDash(dashSize, gapSize) {
|
|
13890
14318
|
if (dashSize === void 0 || !Number.isFinite(dashSize) || dashSize <= 0) {
|
|
@@ -13905,22 +14333,22 @@ function HotspotStrokeLine({
|
|
|
13905
14333
|
dashSize,
|
|
13906
14334
|
gapSize
|
|
13907
14335
|
}) {
|
|
13908
|
-
const lineRef = (0,
|
|
13909
|
-
const { camera, size } = (0,
|
|
14336
|
+
const lineRef = (0, import_react50.useRef)(null);
|
|
14337
|
+
const { camera, size } = (0, import_fiber25.useThree)();
|
|
13910
14338
|
const dash = resolveDash(dashSize, gapSize);
|
|
13911
|
-
(0,
|
|
14339
|
+
(0, import_react50.useLayoutEffect)(() => {
|
|
13912
14340
|
if (!dash.dashed) {
|
|
13913
14341
|
return;
|
|
13914
14342
|
}
|
|
13915
14343
|
applyScreenSpaceDashScale(lineRef.current, camera, size.height);
|
|
13916
14344
|
}, [camera, dash.dashed, dash.dashSize, dash.gapSize, size.height]);
|
|
13917
|
-
(0,
|
|
14345
|
+
(0, import_fiber25.useFrame)((state) => {
|
|
13918
14346
|
if (!dash.dashed) {
|
|
13919
14347
|
return;
|
|
13920
14348
|
}
|
|
13921
14349
|
applyScreenSpaceDashScale(lineRef.current, state.camera, state.size.height);
|
|
13922
14350
|
});
|
|
13923
|
-
return /* @__PURE__ */ (0,
|
|
14351
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
13924
14352
|
import_drei2.Line,
|
|
13925
14353
|
{
|
|
13926
14354
|
ref: lineRef,
|
|
@@ -13942,7 +14370,7 @@ function HotspotStrokeLine({
|
|
|
13942
14370
|
}
|
|
13943
14371
|
|
|
13944
14372
|
// src/hotspot/polygon-hotspot.tsx
|
|
13945
|
-
var
|
|
14373
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
13946
14374
|
var POLYGON_RADIUS = 990;
|
|
13947
14375
|
var MAX_FILL_SEGMENT_DEGREES = 7;
|
|
13948
14376
|
function cloneVertices(vertices) {
|
|
@@ -13977,7 +14405,7 @@ function intersects(a, b, c, d) {
|
|
|
13977
14405
|
}
|
|
13978
14406
|
function hasSelfIntersection(vertices) {
|
|
13979
14407
|
const points = vertices.map(
|
|
13980
|
-
(vertex) => new
|
|
14408
|
+
(vertex) => new import_three28.Vector2(vertex.unwrappedYaw, vertex.pitch)
|
|
13981
14409
|
);
|
|
13982
14410
|
for (let index = 0; index < points.length; index += 1) {
|
|
13983
14411
|
const nextIndex = (index + 1) % points.length;
|
|
@@ -14014,7 +14442,7 @@ function polygonContainsDirection(vertices, direction) {
|
|
|
14014
14442
|
}
|
|
14015
14443
|
function fitsHemisphere(vertices) {
|
|
14016
14444
|
const directions = vertices.map((vertex) => panoPositionToVector3(vertex).normalize());
|
|
14017
|
-
const candidates = [new
|
|
14445
|
+
const candidates = [new import_three28.Vector3()];
|
|
14018
14446
|
for (const direction of directions) {
|
|
14019
14447
|
candidates[0].add(direction);
|
|
14020
14448
|
candidates.push(direction.clone());
|
|
@@ -14038,7 +14466,7 @@ function validatePolygonVertices(vertices) {
|
|
|
14038
14466
|
if (hasSelfIntersection(unwrapped)) {
|
|
14039
14467
|
issues.push({ code: "self_intersection", message: "Polygon edges cannot cross." });
|
|
14040
14468
|
}
|
|
14041
|
-
if (polygonContainsDirection(normalized, new
|
|
14469
|
+
if (polygonContainsDirection(normalized, new import_three28.Vector3(0, 1, 0)) || polygonContainsDirection(normalized, new import_three28.Vector3(0, -1, 0))) {
|
|
14042
14470
|
issues.push({ code: "contains_pole", message: "Polygons cannot contain a panorama pole." });
|
|
14043
14471
|
}
|
|
14044
14472
|
if (!fitsHemisphere(normalized)) {
|
|
@@ -14049,7 +14477,7 @@ function validatePolygonVertices(vertices) {
|
|
|
14049
14477
|
function polygonCenter(vertices) {
|
|
14050
14478
|
const sum = vertices.reduce(
|
|
14051
14479
|
(total, vertex) => total.add(panoPositionToVector3(vertex).normalize()),
|
|
14052
|
-
new
|
|
14480
|
+
new import_three28.Vector3()
|
|
14053
14481
|
);
|
|
14054
14482
|
return sum.lengthSq() > 1e-8 ? vector3ToPanoPosition(sum) : normalizePanoPosition(vertices[0]);
|
|
14055
14483
|
}
|
|
@@ -14058,20 +14486,20 @@ function surfaceQuaternion(position) {
|
|
|
14058
14486
|
const inward = outward.clone().negate();
|
|
14059
14487
|
const pitch = position.pitch * Math.PI / 180;
|
|
14060
14488
|
const yaw = position.yaw * Math.PI / 180;
|
|
14061
|
-
const localUp = new
|
|
14489
|
+
const localUp = new import_three28.Vector3(
|
|
14062
14490
|
-Math.sin(pitch) * Math.sin(yaw),
|
|
14063
14491
|
Math.cos(pitch),
|
|
14064
14492
|
Math.sin(pitch) * Math.cos(yaw)
|
|
14065
14493
|
).normalize();
|
|
14066
|
-
return new
|
|
14067
|
-
new
|
|
14494
|
+
return new import_three28.Quaternion().setFromRotationMatrix(
|
|
14495
|
+
new import_three28.Matrix4().makeBasis(localUp.clone().cross(inward).normalize(), localUp, inward)
|
|
14068
14496
|
);
|
|
14069
14497
|
}
|
|
14070
14498
|
function makeWorldToLocal(center) {
|
|
14071
|
-
return new
|
|
14499
|
+
return new import_three28.Matrix4().compose(
|
|
14072
14500
|
panoPositionToVector3(center, POLYGON_RADIUS),
|
|
14073
14501
|
surfaceQuaternion(center),
|
|
14074
|
-
new
|
|
14502
|
+
new import_three28.Vector3(1, 1, 1)
|
|
14075
14503
|
).invert();
|
|
14076
14504
|
}
|
|
14077
14505
|
function projectedPoint(a, b, c, weightB, weightC, radius, worldToLocal) {
|
|
@@ -14126,8 +14554,8 @@ function addSubdividedTriangle(positions, indices, a, b, c, worldToLocal, steps)
|
|
|
14126
14554
|
}
|
|
14127
14555
|
function makeFillGeometry(vertices, center) {
|
|
14128
14556
|
const unwrapped = unwrapPolygonVertices(vertices);
|
|
14129
|
-
const contour = unwrapped.map((vertex) => new
|
|
14130
|
-
const triangles =
|
|
14557
|
+
const contour = unwrapped.map((vertex) => new import_three28.Vector2(vertex.unwrappedYaw, vertex.pitch));
|
|
14558
|
+
const triangles = import_three28.ShapeUtils.triangulateShape(contour, []);
|
|
14131
14559
|
const positions = [];
|
|
14132
14560
|
const indices = [];
|
|
14133
14561
|
const worldToLocal = makeWorldToLocal(center);
|
|
@@ -14143,7 +14571,7 @@ function makeFillGeometry(vertices, center) {
|
|
|
14143
14571
|
steps
|
|
14144
14572
|
);
|
|
14145
14573
|
}
|
|
14146
|
-
return new
|
|
14574
|
+
return new import_three28.BufferGeometry().setAttribute("position", new import_three28.Float32BufferAttribute(positions, 3)).setIndex(indices);
|
|
14147
14575
|
}
|
|
14148
14576
|
function makeStrokePositions(vertices, center) {
|
|
14149
14577
|
const points = [];
|
|
@@ -14198,24 +14626,24 @@ function PolygonHotspot({
|
|
|
14198
14626
|
onInvalid,
|
|
14199
14627
|
...anchorProps
|
|
14200
14628
|
}) {
|
|
14201
|
-
const issues = (0,
|
|
14629
|
+
const issues = (0, import_react51.useMemo)(() => validatePolygonVertices(vertices), [vertices]);
|
|
14202
14630
|
const valid = issues.length === 0;
|
|
14203
|
-
const center = (0,
|
|
14204
|
-
const fillGeometry = (0,
|
|
14631
|
+
const center = (0, import_react51.useMemo)(() => valid ? polygonCenter(vertices) : null, [valid, vertices]);
|
|
14632
|
+
const fillGeometry = (0, import_react51.useMemo)(
|
|
14205
14633
|
() => valid && center ? makeFillGeometry(vertices, center) : null,
|
|
14206
14634
|
[center, valid, vertices]
|
|
14207
14635
|
);
|
|
14208
|
-
const strokePoints = (0,
|
|
14636
|
+
const strokePoints = (0, import_react51.useMemo)(
|
|
14209
14637
|
() => valid && center ? makeStrokePositions(vertices, center) : null,
|
|
14210
14638
|
[center, valid, vertices]
|
|
14211
14639
|
);
|
|
14212
14640
|
const resolvedStrokeOpacity = Math.max(0, Math.min(strokeOpacity, 1));
|
|
14213
|
-
const startVerticesRef = (0,
|
|
14641
|
+
const startVerticesRef = (0, import_react51.useRef)(null);
|
|
14214
14642
|
const issuesKey = issues.map((issue) => issue.code).join(",");
|
|
14215
|
-
(0,
|
|
14643
|
+
(0, import_react51.useEffect)(() => {
|
|
14216
14644
|
if (!valid) onInvalid?.(issues);
|
|
14217
14645
|
}, [issues, issuesKey, onInvalid, valid]);
|
|
14218
|
-
(0,
|
|
14646
|
+
(0, import_react51.useEffect)(() => () => fillGeometry?.dispose(), [fillGeometry]);
|
|
14219
14647
|
if (!valid || !center || !fillGeometry || !strokePoints || strokePoints.length < 2) {
|
|
14220
14648
|
return null;
|
|
14221
14649
|
}
|
|
@@ -14230,7 +14658,7 @@ function PolygonHotspot({
|
|
|
14230
14658
|
startPosition: event.startPosition
|
|
14231
14659
|
});
|
|
14232
14660
|
};
|
|
14233
|
-
return /* @__PURE__ */ (0,
|
|
14661
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
14234
14662
|
HotspotAnchor,
|
|
14235
14663
|
{
|
|
14236
14664
|
...anchorProps,
|
|
@@ -14245,7 +14673,7 @@ function PolygonHotspot({
|
|
|
14245
14673
|
draggable,
|
|
14246
14674
|
interactive,
|
|
14247
14675
|
useAngularScale: false,
|
|
14248
|
-
focusContent: /* @__PURE__ */ (0,
|
|
14676
|
+
focusContent: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
14249
14677
|
HotspotStrokeLine,
|
|
14250
14678
|
{
|
|
14251
14679
|
color: "#75cbd3",
|
|
@@ -14267,17 +14695,17 @@ function PolygonHotspot({
|
|
|
14267
14695
|
startVerticesRef.current = null;
|
|
14268
14696
|
},
|
|
14269
14697
|
children: [
|
|
14270
|
-
/* @__PURE__ */ (0,
|
|
14698
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("mesh", { geometry: fillGeometry, renderOrder, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
14271
14699
|
"meshBasicMaterial",
|
|
14272
14700
|
{
|
|
14273
14701
|
color: fill,
|
|
14274
14702
|
depthWrite: false,
|
|
14275
14703
|
opacity: Math.max(0, Math.min(fillOpacity, 1)),
|
|
14276
|
-
side:
|
|
14704
|
+
side: import_three28.DoubleSide,
|
|
14277
14705
|
transparent: true
|
|
14278
14706
|
}
|
|
14279
14707
|
) }),
|
|
14280
|
-
/* @__PURE__ */ (0,
|
|
14708
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
14281
14709
|
HotspotStrokeLine,
|
|
14282
14710
|
{
|
|
14283
14711
|
color: stroke,
|
|
@@ -14295,9 +14723,9 @@ function PolygonHotspot({
|
|
|
14295
14723
|
}
|
|
14296
14724
|
|
|
14297
14725
|
// src/hotspot/polyline-hotspot.tsx
|
|
14298
|
-
var
|
|
14299
|
-
var
|
|
14300
|
-
var
|
|
14726
|
+
var import_react52 = require("react");
|
|
14727
|
+
var import_three29 = require("three");
|
|
14728
|
+
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
14301
14729
|
var POLYLINE_RADIUS = 990;
|
|
14302
14730
|
var MAX_SEGMENT_DEGREES = 7;
|
|
14303
14731
|
function cloneVertices2(vertices) {
|
|
@@ -14322,29 +14750,29 @@ function unwrapVertices(vertices) {
|
|
|
14322
14750
|
function polylineCenter(vertices) {
|
|
14323
14751
|
const sum = vertices.reduce(
|
|
14324
14752
|
(total, vertex) => total.add(panoPositionToVector3(vertex).normalize()),
|
|
14325
|
-
new
|
|
14753
|
+
new import_three29.Vector3()
|
|
14326
14754
|
);
|
|
14327
14755
|
return sum.lengthSq() > 1e-8 ? vector3ToPanoPosition(sum) : normalizePanoPosition(vertices[0]);
|
|
14328
14756
|
}
|
|
14329
14757
|
function surfaceQuaternion2(position) {
|
|
14330
14758
|
const outward = panoPositionToVector3(position).normalize();
|
|
14331
14759
|
const inward = outward.clone().negate();
|
|
14332
|
-
const pitch =
|
|
14333
|
-
const yaw =
|
|
14334
|
-
const localUp = new
|
|
14760
|
+
const pitch = import_three29.MathUtils.degToRad(position.pitch);
|
|
14761
|
+
const yaw = import_three29.MathUtils.degToRad(position.yaw);
|
|
14762
|
+
const localUp = new import_three29.Vector3(
|
|
14335
14763
|
-Math.sin(pitch) * Math.sin(yaw),
|
|
14336
14764
|
Math.cos(pitch),
|
|
14337
14765
|
Math.sin(pitch) * Math.cos(yaw)
|
|
14338
14766
|
).normalize();
|
|
14339
|
-
return new
|
|
14340
|
-
new
|
|
14767
|
+
return new import_three29.Quaternion().setFromRotationMatrix(
|
|
14768
|
+
new import_three29.Matrix4().makeBasis(localUp.clone().cross(inward).normalize(), localUp, inward)
|
|
14341
14769
|
);
|
|
14342
14770
|
}
|
|
14343
14771
|
function makeWorldToLocal2(center) {
|
|
14344
|
-
return new
|
|
14772
|
+
return new import_three29.Matrix4().compose(
|
|
14345
14773
|
panoPositionToVector3(center, POLYLINE_RADIUS),
|
|
14346
14774
|
surfaceQuaternion2(center),
|
|
14347
|
-
new
|
|
14775
|
+
new import_three29.Vector3(1, 1, 1)
|
|
14348
14776
|
).invert();
|
|
14349
14777
|
}
|
|
14350
14778
|
function subdivisionSteps(vertices) {
|
|
@@ -14359,7 +14787,7 @@ function subdivisionSteps(vertices) {
|
|
|
14359
14787
|
}
|
|
14360
14788
|
return Math.min(
|
|
14361
14789
|
8,
|
|
14362
|
-
Math.max(1, Math.ceil(
|
|
14790
|
+
Math.max(1, Math.ceil(import_three29.MathUtils.radToDeg(maxAngle) / MAX_SEGMENT_DEGREES))
|
|
14363
14791
|
);
|
|
14364
14792
|
}
|
|
14365
14793
|
function makeLinePositions(vertices, center) {
|
|
@@ -14414,16 +14842,16 @@ function PolylineHotspot({
|
|
|
14414
14842
|
onInvalid,
|
|
14415
14843
|
...anchorProps
|
|
14416
14844
|
}) {
|
|
14417
|
-
const issues = (0,
|
|
14845
|
+
const issues = (0, import_react52.useMemo)(() => validatePolylineVertices(vertices), [vertices]);
|
|
14418
14846
|
const valid = issues.length === 0;
|
|
14419
|
-
const center = (0,
|
|
14420
|
-
const linePoints = (0,
|
|
14847
|
+
const center = (0, import_react52.useMemo)(() => valid ? polylineCenter(vertices) : null, [valid, vertices]);
|
|
14848
|
+
const linePoints = (0, import_react52.useMemo)(
|
|
14421
14849
|
() => valid && center ? makeLinePositions(vertices, center) : null,
|
|
14422
14850
|
[center, valid, vertices]
|
|
14423
14851
|
);
|
|
14424
14852
|
const opacity = Math.max(0, Math.min(strokeOpacity, 1));
|
|
14425
|
-
const startVerticesRef = (0,
|
|
14426
|
-
(0,
|
|
14853
|
+
const startVerticesRef = (0, import_react52.useRef)(null);
|
|
14854
|
+
(0, import_react52.useEffect)(() => {
|
|
14427
14855
|
if (!valid) onInvalid?.(issues);
|
|
14428
14856
|
}, [issues, onInvalid, valid]);
|
|
14429
14857
|
if (!valid || !center || !linePoints || linePoints.length < 2) return null;
|
|
@@ -14437,7 +14865,7 @@ function PolylineHotspot({
|
|
|
14437
14865
|
startPosition: event.startPosition
|
|
14438
14866
|
});
|
|
14439
14867
|
};
|
|
14440
|
-
return /* @__PURE__ */ (0,
|
|
14868
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
14441
14869
|
HotspotAnchor,
|
|
14442
14870
|
{
|
|
14443
14871
|
...anchorProps,
|
|
@@ -14451,7 +14879,7 @@ function PolylineHotspot({
|
|
|
14451
14879
|
renderOrder,
|
|
14452
14880
|
draggable,
|
|
14453
14881
|
useAngularScale: false,
|
|
14454
|
-
focusContent: /* @__PURE__ */ (0,
|
|
14882
|
+
focusContent: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
14455
14883
|
HotspotStrokeLine,
|
|
14456
14884
|
{
|
|
14457
14885
|
color: "#75cbd3",
|
|
@@ -14472,7 +14900,7 @@ function PolylineHotspot({
|
|
|
14472
14900
|
emitVerticesChange(event, onDragEnd);
|
|
14473
14901
|
startVerticesRef.current = null;
|
|
14474
14902
|
},
|
|
14475
|
-
children: /* @__PURE__ */ (0,
|
|
14903
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
14476
14904
|
HotspotStrokeLine,
|
|
14477
14905
|
{
|
|
14478
14906
|
color: stroke,
|
|
@@ -14489,9 +14917,9 @@ function PolylineHotspot({
|
|
|
14489
14917
|
}
|
|
14490
14918
|
|
|
14491
14919
|
// src/hotspot/graphic-hotspot.tsx
|
|
14492
|
-
var
|
|
14493
|
-
var
|
|
14494
|
-
var
|
|
14920
|
+
var import_react53 = require("react");
|
|
14921
|
+
var import_three30 = require("three");
|
|
14922
|
+
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
14495
14923
|
var GRAPHIC_TEXTURE_SIZE = 512;
|
|
14496
14924
|
function resolveStrokeWidth(value) {
|
|
14497
14925
|
return Number.isFinite(value) ? Math.max(value, 0) : 8;
|
|
@@ -14669,23 +15097,23 @@ function createGraphicTexture(graphic, aspectWidth, aspectHeight) {
|
|
|
14669
15097
|
throw new Error("Canvas 2D is unavailable for this graphic hotspot.");
|
|
14670
15098
|
}
|
|
14671
15099
|
drawGraphic(context, graphic, aspectWidth, aspectHeight);
|
|
14672
|
-
const texture = new
|
|
14673
|
-
texture.colorSpace =
|
|
14674
|
-
texture.wrapS =
|
|
14675
|
-
texture.wrapT =
|
|
14676
|
-
texture.magFilter =
|
|
14677
|
-
texture.minFilter =
|
|
15100
|
+
const texture = new import_three30.CanvasTexture(canvas);
|
|
15101
|
+
texture.colorSpace = import_three30.SRGBColorSpace;
|
|
15102
|
+
texture.wrapS = import_three30.ClampToEdgeWrapping;
|
|
15103
|
+
texture.wrapT = import_three30.ClampToEdgeWrapping;
|
|
15104
|
+
texture.magFilter = import_three30.LinearFilter;
|
|
15105
|
+
texture.minFilter = import_three30.LinearMipmapLinearFilter;
|
|
14678
15106
|
texture.generateMipmaps = true;
|
|
14679
15107
|
texture.needsUpdate = true;
|
|
14680
15108
|
return texture;
|
|
14681
15109
|
}
|
|
14682
15110
|
function useGraphicTexture(graphic, aspectWidth, aspectHeight, onLoad, onError) {
|
|
14683
|
-
const [texture, setTexture] = (0,
|
|
14684
|
-
const onLoadRef = (0,
|
|
14685
|
-
const onErrorRef = (0,
|
|
15111
|
+
const [texture, setTexture] = (0, import_react53.useState)(null);
|
|
15112
|
+
const onLoadRef = (0, import_react53.useRef)(onLoad);
|
|
15113
|
+
const onErrorRef = (0, import_react53.useRef)(onError);
|
|
14686
15114
|
onLoadRef.current = onLoad;
|
|
14687
15115
|
onErrorRef.current = onError;
|
|
14688
|
-
(0,
|
|
15116
|
+
(0, import_react53.useEffect)(() => {
|
|
14689
15117
|
let nextTexture = null;
|
|
14690
15118
|
try {
|
|
14691
15119
|
nextTexture = createGraphicTexture(graphic, aspectWidth, aspectHeight);
|
|
@@ -14711,22 +15139,22 @@ function CanvasGraphicHotspot({
|
|
|
14711
15139
|
...anchorProps
|
|
14712
15140
|
}) {
|
|
14713
15141
|
const texture = useGraphicTexture(graphic, width, height, onLoad, onError);
|
|
14714
|
-
return /* @__PURE__ */ (0,
|
|
15142
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(HotspotAnchor, { ...anchorProps, height, width, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(HotspotPlane, { map: texture, opacity }) });
|
|
14715
15143
|
}
|
|
14716
15144
|
function GraphicHotspot(props) {
|
|
14717
15145
|
const { graphic, ...restProps } = props;
|
|
14718
15146
|
if (graphic.kind === "svg") {
|
|
14719
15147
|
const imageProps = restProps;
|
|
14720
|
-
return /* @__PURE__ */ (0,
|
|
15148
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(ImageHotspot, { ...imageProps, src: graphic.src });
|
|
14721
15149
|
}
|
|
14722
|
-
return /* @__PURE__ */ (0,
|
|
15150
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(CanvasGraphicHotspot, { ...restProps, graphic });
|
|
14723
15151
|
}
|
|
14724
15152
|
|
|
14725
15153
|
// src/hotspot/sequence-hotspot.tsx
|
|
14726
|
-
var
|
|
14727
|
-
var
|
|
14728
|
-
var
|
|
14729
|
-
var
|
|
15154
|
+
var import_fiber26 = require("@react-three/fiber");
|
|
15155
|
+
var import_react54 = require("react");
|
|
15156
|
+
var import_three31 = require("three");
|
|
15157
|
+
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
14730
15158
|
var DEFAULT_SEQUENCE_FPS = 12;
|
|
14731
15159
|
function resolveFps(value) {
|
|
14732
15160
|
return Number.isFinite(value) && value > 0 ? value : DEFAULT_SEQUENCE_FPS;
|
|
@@ -14740,13 +15168,13 @@ function useSpriteTexture({
|
|
|
14740
15168
|
onError,
|
|
14741
15169
|
onLoadProgress
|
|
14742
15170
|
}) {
|
|
14743
|
-
const gl = (0,
|
|
14744
|
-
const [texture, setTexture] = (0,
|
|
14745
|
-
const onErrorRef = (0,
|
|
14746
|
-
const onLoadProgressRef = (0,
|
|
15171
|
+
const gl = (0, import_fiber26.useThree)((state) => state.gl);
|
|
15172
|
+
const [texture, setTexture] = (0, import_react54.useState)(null);
|
|
15173
|
+
const onErrorRef = (0, import_react54.useRef)(onError);
|
|
15174
|
+
const onLoadProgressRef = (0, import_react54.useRef)(onLoadProgress);
|
|
14747
15175
|
onErrorRef.current = onError;
|
|
14748
15176
|
onLoadProgressRef.current = onLoadProgress;
|
|
14749
|
-
(0,
|
|
15177
|
+
(0, import_react54.useEffect)(() => {
|
|
14750
15178
|
let active = true;
|
|
14751
15179
|
setTexture(null);
|
|
14752
15180
|
if (!src) {
|
|
@@ -14755,7 +15183,7 @@ function useSpriteTexture({
|
|
|
14755
15183
|
active = false;
|
|
14756
15184
|
};
|
|
14757
15185
|
}
|
|
14758
|
-
const loader = new
|
|
15186
|
+
const loader = new import_three31.TextureLoader();
|
|
14759
15187
|
loader.load(
|
|
14760
15188
|
src,
|
|
14761
15189
|
(loadedTexture) => {
|
|
@@ -14763,11 +15191,11 @@ function useSpriteTexture({
|
|
|
14763
15191
|
loadedTexture.dispose();
|
|
14764
15192
|
return;
|
|
14765
15193
|
}
|
|
14766
|
-
loadedTexture.colorSpace =
|
|
14767
|
-
loadedTexture.wrapS =
|
|
14768
|
-
loadedTexture.wrapT =
|
|
14769
|
-
loadedTexture.magFilter =
|
|
14770
|
-
loadedTexture.minFilter =
|
|
15194
|
+
loadedTexture.colorSpace = import_three31.SRGBColorSpace;
|
|
15195
|
+
loadedTexture.wrapS = import_three31.ClampToEdgeWrapping;
|
|
15196
|
+
loadedTexture.wrapT = import_three31.ClampToEdgeWrapping;
|
|
15197
|
+
loadedTexture.magFilter = import_three31.LinearFilter;
|
|
15198
|
+
loadedTexture.minFilter = import_three31.LinearMipmapLinearFilter;
|
|
14771
15199
|
loadedTexture.generateMipmaps = true;
|
|
14772
15200
|
loadedTexture.anisotropy = gl.capabilities.getMaxAnisotropy();
|
|
14773
15201
|
loadedTexture.needsUpdate = true;
|
|
@@ -14787,7 +15215,7 @@ function useSpriteTexture({
|
|
|
14787
15215
|
active = false;
|
|
14788
15216
|
};
|
|
14789
15217
|
}, [gl, id, src]);
|
|
14790
|
-
(0,
|
|
15218
|
+
(0, import_react54.useEffect)(
|
|
14791
15219
|
() => () => {
|
|
14792
15220
|
texture?.dispose();
|
|
14793
15221
|
},
|
|
@@ -14816,24 +15244,24 @@ function SequenceHotspot({
|
|
|
14816
15244
|
const texture = useSpriteTexture({ id, src, onError, onLoadProgress });
|
|
14817
15245
|
const frameCount = resolveFrameCount(requestedFrameCount);
|
|
14818
15246
|
const safeFps = resolveFps(fps);
|
|
14819
|
-
const [frameIndex, setFrameIndex] = (0,
|
|
14820
|
-
const elapsedRef = (0,
|
|
14821
|
-
const frameIndexRef = (0,
|
|
14822
|
-
const endedRef = (0,
|
|
14823
|
-
const lastPlaybackStateRef = (0,
|
|
14824
|
-
const onFrameChangeRef = (0,
|
|
14825
|
-
const onPlaybackStateChangeRef = (0,
|
|
14826
|
-
const onEndedRef = (0,
|
|
15247
|
+
const [frameIndex, setFrameIndex] = (0, import_react54.useState)(0);
|
|
15248
|
+
const elapsedRef = (0, import_react54.useRef)(0);
|
|
15249
|
+
const frameIndexRef = (0, import_react54.useRef)(0);
|
|
15250
|
+
const endedRef = (0, import_react54.useRef)(false);
|
|
15251
|
+
const lastPlaybackStateRef = (0, import_react54.useRef)(null);
|
|
15252
|
+
const onFrameChangeRef = (0, import_react54.useRef)(onFrameChange);
|
|
15253
|
+
const onPlaybackStateChangeRef = (0, import_react54.useRef)(onPlaybackStateChange);
|
|
15254
|
+
const onEndedRef = (0, import_react54.useRef)(onEnded);
|
|
14827
15255
|
onFrameChangeRef.current = onFrameChange;
|
|
14828
15256
|
onPlaybackStateChangeRef.current = onPlaybackStateChange;
|
|
14829
15257
|
onEndedRef.current = onEnded;
|
|
14830
|
-
(0,
|
|
15258
|
+
(0, import_react54.useEffect)(() => {
|
|
14831
15259
|
elapsedRef.current = 0;
|
|
14832
15260
|
frameIndexRef.current = 0;
|
|
14833
15261
|
endedRef.current = false;
|
|
14834
15262
|
setFrameIndex(0);
|
|
14835
15263
|
}, [frameCount, frameDirection, src]);
|
|
14836
|
-
(0,
|
|
15264
|
+
(0, import_react54.useEffect)(() => {
|
|
14837
15265
|
if (!texture) {
|
|
14838
15266
|
return;
|
|
14839
15267
|
}
|
|
@@ -14847,13 +15275,13 @@ function SequenceHotspot({
|
|
|
14847
15275
|
);
|
|
14848
15276
|
texture.needsUpdate = true;
|
|
14849
15277
|
}, [frameCount, frameDirection, frameIndex, texture]);
|
|
14850
|
-
(0,
|
|
15278
|
+
(0, import_react54.useEffect)(() => {
|
|
14851
15279
|
if (!texture) {
|
|
14852
15280
|
return;
|
|
14853
15281
|
}
|
|
14854
15282
|
onFrameChangeRef.current?.({ id, index: 0, src });
|
|
14855
15283
|
}, [id, src, texture]);
|
|
14856
|
-
(0,
|
|
15284
|
+
(0, import_react54.useEffect)(() => {
|
|
14857
15285
|
if (!texture) {
|
|
14858
15286
|
return;
|
|
14859
15287
|
}
|
|
@@ -14872,7 +15300,7 @@ function SequenceHotspot({
|
|
|
14872
15300
|
onPlaybackStateChangeRef.current?.(nextState);
|
|
14873
15301
|
}
|
|
14874
15302
|
}, [playing, texture]);
|
|
14875
|
-
(0,
|
|
15303
|
+
(0, import_fiber26.useFrame)((_, deltaSeconds) => {
|
|
14876
15304
|
if (!texture || !playing || endedRef.current) {
|
|
14877
15305
|
return;
|
|
14878
15306
|
}
|
|
@@ -14902,14 +15330,14 @@ function SequenceHotspot({
|
|
|
14902
15330
|
onFrameChangeRef.current?.({ id, index: nextIndex, src });
|
|
14903
15331
|
}
|
|
14904
15332
|
});
|
|
14905
|
-
return /* @__PURE__ */ (0,
|
|
15333
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(HotspotAnchor, { ...anchorProps, id, height, width, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(HotspotPlane, { map: texture, opacity }) });
|
|
14906
15334
|
}
|
|
14907
15335
|
|
|
14908
15336
|
// src/hotspot/video-hotspot.tsx
|
|
14909
|
-
var
|
|
14910
|
-
var
|
|
14911
|
-
var
|
|
14912
|
-
var
|
|
15337
|
+
var import_fiber27 = require("@react-three/fiber");
|
|
15338
|
+
var import_react55 = require("react");
|
|
15339
|
+
var import_three32 = require("three");
|
|
15340
|
+
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
14913
15341
|
function clampVolume2(volume) {
|
|
14914
15342
|
if (!Number.isFinite(volume)) {
|
|
14915
15343
|
return 1;
|
|
@@ -14917,11 +15345,11 @@ function clampVolume2(volume) {
|
|
|
14917
15345
|
return Math.max(0, Math.min(volume, 1));
|
|
14918
15346
|
}
|
|
14919
15347
|
function usePosterTexture2(id, poster, onError) {
|
|
14920
|
-
const gl = (0,
|
|
14921
|
-
const [texture, setTexture] = (0,
|
|
14922
|
-
const onErrorRef = (0,
|
|
15348
|
+
const gl = (0, import_fiber27.useThree)((state) => state.gl);
|
|
15349
|
+
const [texture, setTexture] = (0, import_react55.useState)(null);
|
|
15350
|
+
const onErrorRef = (0, import_react55.useRef)(onError);
|
|
14923
15351
|
onErrorRef.current = onError;
|
|
14924
|
-
(0,
|
|
15352
|
+
(0, import_react55.useEffect)(() => {
|
|
14925
15353
|
let active = true;
|
|
14926
15354
|
setTexture(null);
|
|
14927
15355
|
if (!poster) {
|
|
@@ -14929,7 +15357,7 @@ function usePosterTexture2(id, poster, onError) {
|
|
|
14929
15357
|
active = false;
|
|
14930
15358
|
};
|
|
14931
15359
|
}
|
|
14932
|
-
const loader = new
|
|
15360
|
+
const loader = new import_three32.TextureLoader();
|
|
14933
15361
|
loader.load(
|
|
14934
15362
|
poster,
|
|
14935
15363
|
(loadedTexture) => {
|
|
@@ -14937,11 +15365,11 @@ function usePosterTexture2(id, poster, onError) {
|
|
|
14937
15365
|
loadedTexture.dispose();
|
|
14938
15366
|
return;
|
|
14939
15367
|
}
|
|
14940
|
-
loadedTexture.colorSpace =
|
|
14941
|
-
loadedTexture.wrapS =
|
|
14942
|
-
loadedTexture.wrapT =
|
|
14943
|
-
loadedTexture.magFilter =
|
|
14944
|
-
loadedTexture.minFilter =
|
|
15368
|
+
loadedTexture.colorSpace = import_three32.SRGBColorSpace;
|
|
15369
|
+
loadedTexture.wrapS = import_three32.ClampToEdgeWrapping;
|
|
15370
|
+
loadedTexture.wrapT = import_three32.ClampToEdgeWrapping;
|
|
15371
|
+
loadedTexture.magFilter = import_three32.LinearFilter;
|
|
15372
|
+
loadedTexture.minFilter = import_three32.LinearMipmapLinearFilter;
|
|
14945
15373
|
loadedTexture.generateMipmaps = true;
|
|
14946
15374
|
loadedTexture.anisotropy = gl.capabilities.getMaxAnisotropy();
|
|
14947
15375
|
loadedTexture.needsUpdate = true;
|
|
@@ -14958,7 +15386,7 @@ function usePosterTexture2(id, poster, onError) {
|
|
|
14958
15386
|
active = false;
|
|
14959
15387
|
};
|
|
14960
15388
|
}, [gl, id, poster]);
|
|
14961
|
-
(0,
|
|
15389
|
+
(0, import_react55.useEffect)(
|
|
14962
15390
|
() => () => {
|
|
14963
15391
|
texture?.dispose();
|
|
14964
15392
|
},
|
|
@@ -14976,14 +15404,14 @@ function useVideoResource({
|
|
|
14976
15404
|
poster,
|
|
14977
15405
|
src
|
|
14978
15406
|
}) {
|
|
14979
|
-
const [resource, setResource] = (0,
|
|
14980
|
-
const onEndedRef = (0,
|
|
14981
|
-
const onErrorRef = (0,
|
|
14982
|
-
const onPlaybackStateChangeRef = (0,
|
|
15407
|
+
const [resource, setResource] = (0, import_react55.useState)(null);
|
|
15408
|
+
const onEndedRef = (0, import_react55.useRef)(onEnded);
|
|
15409
|
+
const onErrorRef = (0, import_react55.useRef)(onError);
|
|
15410
|
+
const onPlaybackStateChangeRef = (0, import_react55.useRef)(onPlaybackStateChange);
|
|
14983
15411
|
onEndedRef.current = onEnded;
|
|
14984
15412
|
onErrorRef.current = onError;
|
|
14985
15413
|
onPlaybackStateChangeRef.current = onPlaybackStateChange;
|
|
14986
|
-
(0,
|
|
15414
|
+
(0, import_react55.useEffect)(() => {
|
|
14987
15415
|
if (!src) {
|
|
14988
15416
|
setResource(null);
|
|
14989
15417
|
return;
|
|
@@ -15000,12 +15428,12 @@ function useVideoResource({
|
|
|
15000
15428
|
video.setAttribute("webkit-playsinline", "true");
|
|
15001
15429
|
}
|
|
15002
15430
|
video.poster = poster ?? "";
|
|
15003
|
-
const texture = new
|
|
15004
|
-
texture.colorSpace =
|
|
15005
|
-
texture.wrapS =
|
|
15006
|
-
texture.wrapT =
|
|
15007
|
-
texture.magFilter =
|
|
15008
|
-
texture.minFilter =
|
|
15431
|
+
const texture = new import_three32.VideoTexture(video);
|
|
15432
|
+
texture.colorSpace = import_three32.SRGBColorSpace;
|
|
15433
|
+
texture.wrapS = import_three32.ClampToEdgeWrapping;
|
|
15434
|
+
texture.wrapT = import_three32.ClampToEdgeWrapping;
|
|
15435
|
+
texture.magFilter = import_three32.LinearFilter;
|
|
15436
|
+
texture.minFilter = import_three32.LinearFilter;
|
|
15009
15437
|
texture.generateMipmaps = false;
|
|
15010
15438
|
const notifyState = (state) => {
|
|
15011
15439
|
if (active) {
|
|
@@ -15090,11 +15518,11 @@ function VideoHotspot({
|
|
|
15090
15518
|
src
|
|
15091
15519
|
});
|
|
15092
15520
|
const posterTexture = usePosterTexture2(id, poster, onError);
|
|
15093
|
-
const onPlaybackErrorRef = (0,
|
|
15094
|
-
const onPlaybackStateChangeRef = (0,
|
|
15521
|
+
const onPlaybackErrorRef = (0, import_react55.useRef)(onPlaybackError);
|
|
15522
|
+
const onPlaybackStateChangeRef = (0, import_react55.useRef)(onPlaybackStateChange);
|
|
15095
15523
|
onPlaybackErrorRef.current = onPlaybackError;
|
|
15096
15524
|
onPlaybackStateChangeRef.current = onPlaybackStateChange;
|
|
15097
|
-
(0,
|
|
15525
|
+
(0, import_react55.useEffect)(() => {
|
|
15098
15526
|
if (!resource) {
|
|
15099
15527
|
return;
|
|
15100
15528
|
}
|
|
@@ -15111,7 +15539,7 @@ function VideoHotspot({
|
|
|
15111
15539
|
}
|
|
15112
15540
|
resource.video.preload = preload;
|
|
15113
15541
|
}, [loop, muted, playsInline, preload, resource, volume]);
|
|
15114
|
-
(0,
|
|
15542
|
+
(0, import_react55.useEffect)(() => {
|
|
15115
15543
|
if (!resource) {
|
|
15116
15544
|
return;
|
|
15117
15545
|
}
|
|
@@ -15134,14 +15562,14 @@ function VideoHotspot({
|
|
|
15134
15562
|
};
|
|
15135
15563
|
}, [playing, resource]);
|
|
15136
15564
|
const activeTexture = resource?.ready ? resource.texture : posterTexture;
|
|
15137
|
-
return /* @__PURE__ */ (0,
|
|
15565
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(HotspotAnchor, { ...anchorProps, id, height, width, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(HotspotPlane, { map: activeTexture, opacity }) });
|
|
15138
15566
|
}
|
|
15139
15567
|
|
|
15140
15568
|
// src/hotspot/audio-hotspot.tsx
|
|
15141
|
-
var
|
|
15142
|
-
var
|
|
15143
|
-
var
|
|
15144
|
-
var
|
|
15569
|
+
var import_fiber28 = require("@react-three/fiber");
|
|
15570
|
+
var import_react56 = require("react");
|
|
15571
|
+
var import_three33 = require("three");
|
|
15572
|
+
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
15145
15573
|
var SPEAKER_TEXTURE_SIZE = 512;
|
|
15146
15574
|
function paintSpeakerBody(context, center) {
|
|
15147
15575
|
context.fillStyle = "#f5fbfc";
|
|
@@ -15194,19 +15622,19 @@ function createSpeakerTexture(state) {
|
|
|
15194
15622
|
return exhaustive;
|
|
15195
15623
|
}
|
|
15196
15624
|
}
|
|
15197
|
-
const texture = new
|
|
15198
|
-
texture.colorSpace =
|
|
15199
|
-
texture.wrapS =
|
|
15200
|
-
texture.wrapT =
|
|
15201
|
-
texture.magFilter =
|
|
15202
|
-
texture.minFilter =
|
|
15625
|
+
const texture = new import_three33.CanvasTexture(canvas);
|
|
15626
|
+
texture.colorSpace = import_three33.SRGBColorSpace;
|
|
15627
|
+
texture.wrapS = import_three33.ClampToEdgeWrapping;
|
|
15628
|
+
texture.wrapT = import_three33.ClampToEdgeWrapping;
|
|
15629
|
+
texture.magFilter = import_three33.LinearFilter;
|
|
15630
|
+
texture.minFilter = import_three33.LinearMipmapLinearFilter;
|
|
15203
15631
|
texture.generateMipmaps = true;
|
|
15204
15632
|
texture.needsUpdate = true;
|
|
15205
15633
|
return texture;
|
|
15206
15634
|
}
|
|
15207
15635
|
function useSpeakerTextures(enabled) {
|
|
15208
|
-
const [textures, setTextures] = (0,
|
|
15209
|
-
(0,
|
|
15636
|
+
const [textures, setTextures] = (0, import_react56.useState)({ playing: null, stopped: null });
|
|
15637
|
+
(0, import_react56.useEffect)(() => {
|
|
15210
15638
|
if (!enabled) {
|
|
15211
15639
|
setTextures({ playing: null, stopped: null });
|
|
15212
15640
|
return;
|
|
@@ -15222,11 +15650,11 @@ function useSpeakerTextures(enabled) {
|
|
|
15222
15650
|
return textures;
|
|
15223
15651
|
}
|
|
15224
15652
|
function useIconTexture(icon, enabled, onError, id) {
|
|
15225
|
-
const gl = (0,
|
|
15226
|
-
const [texture, setTexture] = (0,
|
|
15227
|
-
const onErrorRef = (0,
|
|
15653
|
+
const gl = (0, import_fiber28.useThree)((state) => state.gl);
|
|
15654
|
+
const [texture, setTexture] = (0, import_react56.useState)(null);
|
|
15655
|
+
const onErrorRef = (0, import_react56.useRef)(onError);
|
|
15228
15656
|
onErrorRef.current = onError;
|
|
15229
|
-
(0,
|
|
15657
|
+
(0, import_react56.useEffect)(() => {
|
|
15230
15658
|
let active = true;
|
|
15231
15659
|
setTexture(null);
|
|
15232
15660
|
if (!enabled || !icon) {
|
|
@@ -15234,7 +15662,7 @@ function useIconTexture(icon, enabled, onError, id) {
|
|
|
15234
15662
|
active = false;
|
|
15235
15663
|
};
|
|
15236
15664
|
}
|
|
15237
|
-
const loader = new
|
|
15665
|
+
const loader = new import_three33.TextureLoader();
|
|
15238
15666
|
loader.load(
|
|
15239
15667
|
icon,
|
|
15240
15668
|
(loadedTexture) => {
|
|
@@ -15242,11 +15670,11 @@ function useIconTexture(icon, enabled, onError, id) {
|
|
|
15242
15670
|
loadedTexture.dispose();
|
|
15243
15671
|
return;
|
|
15244
15672
|
}
|
|
15245
|
-
loadedTexture.colorSpace =
|
|
15246
|
-
loadedTexture.wrapS =
|
|
15247
|
-
loadedTexture.wrapT =
|
|
15248
|
-
loadedTexture.magFilter =
|
|
15249
|
-
loadedTexture.minFilter =
|
|
15673
|
+
loadedTexture.colorSpace = import_three33.SRGBColorSpace;
|
|
15674
|
+
loadedTexture.wrapS = import_three33.ClampToEdgeWrapping;
|
|
15675
|
+
loadedTexture.wrapT = import_three33.ClampToEdgeWrapping;
|
|
15676
|
+
loadedTexture.magFilter = import_three33.LinearFilter;
|
|
15677
|
+
loadedTexture.minFilter = import_three33.LinearMipmapLinearFilter;
|
|
15250
15678
|
loadedTexture.generateMipmaps = true;
|
|
15251
15679
|
loadedTexture.anisotropy = gl.capabilities.getMaxAnisotropy();
|
|
15252
15680
|
loadedTexture.needsUpdate = true;
|
|
@@ -15263,7 +15691,7 @@ function useIconTexture(icon, enabled, onError, id) {
|
|
|
15263
15691
|
active = false;
|
|
15264
15692
|
};
|
|
15265
15693
|
}, [enabled, gl, icon, id]);
|
|
15266
|
-
(0,
|
|
15694
|
+
(0, import_react56.useEffect)(
|
|
15267
15695
|
() => () => {
|
|
15268
15696
|
texture?.dispose();
|
|
15269
15697
|
},
|
|
@@ -15282,13 +15710,13 @@ function useAudioHowl({
|
|
|
15282
15710
|
playing,
|
|
15283
15711
|
src
|
|
15284
15712
|
}) {
|
|
15285
|
-
const [howl, setHowl] = (0,
|
|
15286
|
-
const playingRef = (0,
|
|
15287
|
-
const loopRef = (0,
|
|
15288
|
-
const onEndedRef = (0,
|
|
15289
|
-
const onErrorRef = (0,
|
|
15290
|
-
const onPlaybackErrorRef = (0,
|
|
15291
|
-
const onPlaybackStateChangeRef = (0,
|
|
15713
|
+
const [howl, setHowl] = (0, import_react56.useState)(null);
|
|
15714
|
+
const playingRef = (0, import_react56.useRef)(playing);
|
|
15715
|
+
const loopRef = (0, import_react56.useRef)(loop ?? false);
|
|
15716
|
+
const onEndedRef = (0, import_react56.useRef)(onEnded);
|
|
15717
|
+
const onErrorRef = (0, import_react56.useRef)(onError);
|
|
15718
|
+
const onPlaybackErrorRef = (0, import_react56.useRef)(onPlaybackError);
|
|
15719
|
+
const onPlaybackStateChangeRef = (0, import_react56.useRef)(onPlaybackStateChange);
|
|
15292
15720
|
playingRef.current = playing;
|
|
15293
15721
|
loopRef.current = loop ?? false;
|
|
15294
15722
|
onEndedRef.current = onEnded;
|
|
@@ -15296,7 +15724,7 @@ function useAudioHowl({
|
|
|
15296
15724
|
onPlaybackErrorRef.current = onPlaybackError;
|
|
15297
15725
|
onPlaybackStateChangeRef.current = onPlaybackStateChange;
|
|
15298
15726
|
const sourcesKey = sourceList(src).join("\0");
|
|
15299
|
-
(0,
|
|
15727
|
+
(0, import_react56.useEffect)(() => {
|
|
15300
15728
|
const sources = sourcesKey.length > 0 ? sourcesKey.split("\0") : [];
|
|
15301
15729
|
if (sources.length === 0) {
|
|
15302
15730
|
setHowl(null);
|
|
@@ -15333,7 +15761,7 @@ function useAudioHowl({
|
|
|
15333
15761
|
handle.dispose();
|
|
15334
15762
|
};
|
|
15335
15763
|
}, [crossOrigin, id, sourcesKey]);
|
|
15336
|
-
(0,
|
|
15764
|
+
(0, import_react56.useEffect)(() => {
|
|
15337
15765
|
howl?.loop(loop ?? false);
|
|
15338
15766
|
}, [howl, loop]);
|
|
15339
15767
|
return howl;
|
|
@@ -15361,7 +15789,7 @@ function AudioHotspot({
|
|
|
15361
15789
|
...anchorProps
|
|
15362
15790
|
}) {
|
|
15363
15791
|
usePanoMediaActivationIntent(playing);
|
|
15364
|
-
const camera = (0,
|
|
15792
|
+
const camera = (0, import_fiber28.useThree)((state) => state.camera);
|
|
15365
15793
|
const howl = useAudioHowl({
|
|
15366
15794
|
crossOrigin,
|
|
15367
15795
|
id,
|
|
@@ -15377,15 +15805,15 @@ function AudioHotspot({
|
|
|
15377
15805
|
const stoppedIconTexture = useIconTexture(icon, marker, onError, id);
|
|
15378
15806
|
const playingIconTexture = useIconTexture(playingIcon, marker, onError, id);
|
|
15379
15807
|
const markerTexture = playing ? playingIconTexture ?? stoppedIconTexture ?? speakerTextures.playing : stoppedIconTexture ?? speakerTextures.stopped;
|
|
15380
|
-
const playingRef = (0,
|
|
15808
|
+
const playingRef = (0, import_react56.useRef)(playing);
|
|
15381
15809
|
playingRef.current = playing;
|
|
15382
|
-
const mutedRef = (0,
|
|
15383
|
-
const volumeRef = (0,
|
|
15384
|
-
const rangeRef = (0,
|
|
15810
|
+
const mutedRef = (0, import_react56.useRef)(muted);
|
|
15811
|
+
const volumeRef = (0, import_react56.useRef)(volume);
|
|
15812
|
+
const rangeRef = (0, import_react56.useRef)(range);
|
|
15385
15813
|
mutedRef.current = muted;
|
|
15386
15814
|
volumeRef.current = volume;
|
|
15387
15815
|
rangeRef.current = range;
|
|
15388
|
-
(0,
|
|
15816
|
+
(0, import_react56.useEffect)(() => {
|
|
15389
15817
|
if (!howl) {
|
|
15390
15818
|
return;
|
|
15391
15819
|
}
|
|
@@ -15395,7 +15823,7 @@ function AudioHotspot({
|
|
|
15395
15823
|
}
|
|
15396
15824
|
howl.play();
|
|
15397
15825
|
}, [howl, playing]);
|
|
15398
|
-
(0,
|
|
15826
|
+
(0, import_react56.useEffect)(() => {
|
|
15399
15827
|
if (!howl || !pauseWhenHidden) {
|
|
15400
15828
|
return;
|
|
15401
15829
|
}
|
|
@@ -15413,7 +15841,7 @@ function AudioHotspot({
|
|
|
15413
15841
|
document.removeEventListener("visibilitychange", handleVisibility);
|
|
15414
15842
|
};
|
|
15415
15843
|
}, [howl, pauseWhenHidden]);
|
|
15416
|
-
(0,
|
|
15844
|
+
(0, import_fiber28.useFrame)(() => {
|
|
15417
15845
|
if (!howl) {
|
|
15418
15846
|
return;
|
|
15419
15847
|
}
|
|
@@ -15426,13 +15854,13 @@ function AudioHotspot({
|
|
|
15426
15854
|
howl.mute(mutedRef.current);
|
|
15427
15855
|
howl.volume(clampAudioVolume(volumeRef.current) * spatial.gain);
|
|
15428
15856
|
});
|
|
15429
|
-
return /* @__PURE__ */ (0,
|
|
15857
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(HotspotAnchor, { ...anchorProps, id, height, width, children: marker ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(HotspotPlane, { map: markerTexture, opacity }) : null });
|
|
15430
15858
|
}
|
|
15431
15859
|
|
|
15432
15860
|
// src/hotspot/text-hotspot.tsx
|
|
15433
|
-
var
|
|
15434
|
-
var
|
|
15435
|
-
var
|
|
15861
|
+
var import_react57 = require("react");
|
|
15862
|
+
var import_three34 = require("three");
|
|
15863
|
+
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
15436
15864
|
var TEXT_TEXTURE_LONG_SIDE = 1024;
|
|
15437
15865
|
var DEFAULT_FONT_FAMILY = "system-ui, sans-serif";
|
|
15438
15866
|
var DEFAULT_FONT_SIZE = 96;
|
|
@@ -15641,23 +16069,23 @@ function createTextTexture(text, width, height, style) {
|
|
|
15641
16069
|
throw new Error("Canvas 2D is unavailable for this text hotspot.");
|
|
15642
16070
|
}
|
|
15643
16071
|
drawTextHotspot(context, canvasWidth, canvasHeight, text, style);
|
|
15644
|
-
const texture = new
|
|
15645
|
-
texture.colorSpace =
|
|
15646
|
-
texture.wrapS =
|
|
15647
|
-
texture.wrapT =
|
|
15648
|
-
texture.magFilter =
|
|
15649
|
-
texture.minFilter =
|
|
16072
|
+
const texture = new import_three34.CanvasTexture(canvas);
|
|
16073
|
+
texture.colorSpace = import_three34.SRGBColorSpace;
|
|
16074
|
+
texture.wrapS = import_three34.ClampToEdgeWrapping;
|
|
16075
|
+
texture.wrapT = import_three34.ClampToEdgeWrapping;
|
|
16076
|
+
texture.magFilter = import_three34.LinearFilter;
|
|
16077
|
+
texture.minFilter = import_three34.LinearMipmapLinearFilter;
|
|
15650
16078
|
texture.generateMipmaps = true;
|
|
15651
16079
|
texture.needsUpdate = true;
|
|
15652
16080
|
return texture;
|
|
15653
16081
|
}
|
|
15654
16082
|
function useTextTexture(text, width, height, style, onLoad, onError) {
|
|
15655
|
-
const [texture, setTexture] = (0,
|
|
15656
|
-
const onLoadRef = (0,
|
|
15657
|
-
const onErrorRef = (0,
|
|
16083
|
+
const [texture, setTexture] = (0, import_react57.useState)(null);
|
|
16084
|
+
const onLoadRef = (0, import_react57.useRef)(onLoad);
|
|
16085
|
+
const onErrorRef = (0, import_react57.useRef)(onError);
|
|
15658
16086
|
onLoadRef.current = onLoad;
|
|
15659
16087
|
onErrorRef.current = onError;
|
|
15660
|
-
(0,
|
|
16088
|
+
(0, import_react57.useEffect)(() => {
|
|
15661
16089
|
let cancelled = false;
|
|
15662
16090
|
let nextTexture = null;
|
|
15663
16091
|
const run = async () => {
|
|
@@ -15750,13 +16178,13 @@ function TextHotspot({
|
|
|
15750
16178
|
whiteSpace
|
|
15751
16179
|
};
|
|
15752
16180
|
const texture = useTextTexture(text, width, height, style, onLoad, onError);
|
|
15753
|
-
return /* @__PURE__ */ (0,
|
|
16181
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(HotspotAnchor, { ...anchorProps, height, width, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(HotspotPlane, { map: texture, opacity }) });
|
|
15754
16182
|
}
|
|
15755
16183
|
|
|
15756
16184
|
// src/hotspot/iframe-hotspot.tsx
|
|
15757
16185
|
var import_drei3 = require("@react-three/drei");
|
|
15758
|
-
var
|
|
15759
|
-
var
|
|
16186
|
+
var import_three35 = require("three");
|
|
16187
|
+
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
15760
16188
|
var IFRAME_LONG_SIDE = 800;
|
|
15761
16189
|
var CSS3D_DISTANCE_FACTOR = 400;
|
|
15762
16190
|
var DEFAULT_SANDBOX = "allow-scripts allow-popups allow-forms";
|
|
@@ -15813,7 +16241,7 @@ function IframeHotspot({
|
|
|
15813
16241
|
interactive,
|
|
15814
16242
|
pointerEvents
|
|
15815
16243
|
);
|
|
15816
|
-
return /* @__PURE__ */ (0,
|
|
16244
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
|
|
15817
16245
|
HotspotAnchor,
|
|
15818
16246
|
{
|
|
15819
16247
|
...anchorProps,
|
|
@@ -15822,20 +16250,20 @@ function IframeHotspot({
|
|
|
15822
16250
|
pointerEvents,
|
|
15823
16251
|
width,
|
|
15824
16252
|
children: [
|
|
15825
|
-
/* @__PURE__ */ (0,
|
|
15826
|
-
/* @__PURE__ */ (0,
|
|
15827
|
-
/* @__PURE__ */ (0,
|
|
16253
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("mesh", { children: [
|
|
16254
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("planeGeometry", { args: [1, 1] }),
|
|
16255
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
15828
16256
|
"meshBasicMaterial",
|
|
15829
16257
|
{
|
|
15830
16258
|
depthWrite: false,
|
|
15831
16259
|
opacity: 0,
|
|
15832
|
-
side:
|
|
16260
|
+
side: import_three35.DoubleSide,
|
|
15833
16261
|
toneMapped: false,
|
|
15834
16262
|
transparent: true
|
|
15835
16263
|
}
|
|
15836
16264
|
)
|
|
15837
16265
|
] }),
|
|
15838
|
-
/* @__PURE__ */ (0,
|
|
16266
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
15839
16267
|
import_drei3.Html,
|
|
15840
16268
|
{
|
|
15841
16269
|
distanceFactor: CSS3D_DISTANCE_FACTOR,
|
|
@@ -15850,7 +16278,7 @@ function IframeHotspot({
|
|
|
15850
16278
|
},
|
|
15851
16279
|
transform: true,
|
|
15852
16280
|
zIndexRange: [10, 0],
|
|
15853
|
-
children: /* @__PURE__ */ (0,
|
|
16281
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
15854
16282
|
"iframe",
|
|
15855
16283
|
{
|
|
15856
16284
|
allow,
|
|
@@ -15903,6 +16331,7 @@ function IframeHotspot({
|
|
|
15903
16331
|
Scenes,
|
|
15904
16332
|
SequenceHotspot,
|
|
15905
16333
|
Sphere,
|
|
16334
|
+
SphereTile,
|
|
15906
16335
|
TextHotspot,
|
|
15907
16336
|
Tile,
|
|
15908
16337
|
TouchControls,
|