@ericchen1990/pano-view 3.6.5 → 3.6.7
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/dist/index.cjs +599 -425
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +430 -256
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -2537,7 +2537,136 @@ import {
|
|
|
2537
2537
|
useLayoutEffect,
|
|
2538
2538
|
useRef
|
|
2539
2539
|
} from "react";
|
|
2540
|
-
import { Euler, MathUtils, PerspectiveCamera } from "three";
|
|
2540
|
+
import { Euler as Euler2, MathUtils as MathUtils2, PerspectiveCamera } from "three";
|
|
2541
|
+
|
|
2542
|
+
// src/gyro-orientation.ts
|
|
2543
|
+
import { Euler, MathUtils, Quaternion, Vector3 } from "three";
|
|
2544
|
+
|
|
2545
|
+
// src/gyro-types.ts
|
|
2546
|
+
var GYRO_POSE_EPSILON = 0.02;
|
|
2547
|
+
var GYRO_DISCONTINUITY_ANGLE_DEG = 15;
|
|
2548
|
+
var GYRO_DISCONTINUITY_SPEED_DEG_PER_S = 1200;
|
|
2549
|
+
|
|
2550
|
+
// src/gyro-orientation.ts
|
|
2551
|
+
var DEVICE_FORWARD_CORRECTION = new Quaternion().setFromAxisAngle(
|
|
2552
|
+
new Vector3(1, 0, 0),
|
|
2553
|
+
-Math.PI / 2
|
|
2554
|
+
);
|
|
2555
|
+
var SCREEN_AXIS = new Vector3(0, 0, 1);
|
|
2556
|
+
var LOOK_LOCAL = new Vector3(0, 0, -1);
|
|
2557
|
+
var UP_LOCAL = new Vector3(0, 1, 0);
|
|
2558
|
+
var scratchEuler = new Euler(0, 0, 0, "YXZ");
|
|
2559
|
+
var scratchScreenCorrection = new Quaternion();
|
|
2560
|
+
var scratchInvert = new Quaternion();
|
|
2561
|
+
var scratchWithoutRoll = new Quaternion();
|
|
2562
|
+
var scratchForward = new Vector3();
|
|
2563
|
+
var scratchUp = new Vector3();
|
|
2564
|
+
var scratchExpectedUp = new Vector3();
|
|
2565
|
+
var ZENITH_PITCH_DEG = 89;
|
|
2566
|
+
function getScreenOrientationAngle() {
|
|
2567
|
+
if (typeof window === "undefined") {
|
|
2568
|
+
return 0;
|
|
2569
|
+
}
|
|
2570
|
+
const angle = window.screen.orientation?.angle;
|
|
2571
|
+
if (Number.isFinite(angle)) {
|
|
2572
|
+
return angle;
|
|
2573
|
+
}
|
|
2574
|
+
const legacyAngle = window.orientation;
|
|
2575
|
+
return Number.isFinite(legacyAngle) ? legacyAngle : 0;
|
|
2576
|
+
}
|
|
2577
|
+
function normalizeGyroYaw(value) {
|
|
2578
|
+
return ((value + 180) % 360 + 360) % 360 - 180;
|
|
2579
|
+
}
|
|
2580
|
+
function shortestGyroYawDelta(from, to) {
|
|
2581
|
+
return normalizeGyroYaw(to - from);
|
|
2582
|
+
}
|
|
2583
|
+
function deviceOrientationToQuaternion(sample, screenOrientation, target) {
|
|
2584
|
+
const alpha = Number.isFinite(sample.compassHeading) ? 360 - sample.compassHeading : sample.alpha;
|
|
2585
|
+
scratchEuler.set(
|
|
2586
|
+
MathUtils.degToRad(sample.beta),
|
|
2587
|
+
MathUtils.degToRad(alpha),
|
|
2588
|
+
MathUtils.degToRad(-sample.gamma),
|
|
2589
|
+
"YXZ"
|
|
2590
|
+
);
|
|
2591
|
+
scratchScreenCorrection.setFromAxisAngle(
|
|
2592
|
+
SCREEN_AXIS,
|
|
2593
|
+
-MathUtils.degToRad(screenOrientation)
|
|
2594
|
+
);
|
|
2595
|
+
return target.setFromEuler(scratchEuler).multiply(DEVICE_FORWARD_CORRECTION).multiply(scratchScreenCorrection).normalize();
|
|
2596
|
+
}
|
|
2597
|
+
function quaternionToGyroPose(quaternion, previousYaw) {
|
|
2598
|
+
scratchForward.copy(LOOK_LOCAL).applyQuaternion(quaternion);
|
|
2599
|
+
const pitchRad = Math.asin(MathUtils.clamp(scratchForward.y, -1, 1));
|
|
2600
|
+
const pitch = MathUtils.radToDeg(pitchRad);
|
|
2601
|
+
const nearZenith = Math.abs(pitch) >= ZENITH_PITCH_DEG;
|
|
2602
|
+
const yaw = nearZenith && previousYaw !== void 0 ? previousYaw : MathUtils.radToDeg(Math.atan2(scratchForward.x, -scratchForward.z));
|
|
2603
|
+
scratchEuler.set(pitchRad, -MathUtils.degToRad(yaw), 0, "YXZ");
|
|
2604
|
+
scratchWithoutRoll.setFromEuler(scratchEuler);
|
|
2605
|
+
scratchUp.copy(UP_LOCAL).applyQuaternion(quaternion);
|
|
2606
|
+
scratchExpectedUp.copy(UP_LOCAL).applyQuaternion(scratchWithoutRoll);
|
|
2607
|
+
const look = scratchForward;
|
|
2608
|
+
const crossX = scratchUp.y * scratchExpectedUp.z - scratchUp.z * scratchExpectedUp.y;
|
|
2609
|
+
const crossY = scratchUp.z * scratchExpectedUp.x - scratchUp.x * scratchExpectedUp.z;
|
|
2610
|
+
const crossZ = scratchUp.x * scratchExpectedUp.y - scratchUp.y * scratchExpectedUp.x;
|
|
2611
|
+
const sinTwist = crossX * look.x + crossY * look.y + crossZ * look.z;
|
|
2612
|
+
const cosTwist = MathUtils.clamp(scratchExpectedUp.dot(scratchUp), -1, 1);
|
|
2613
|
+
const roll = MathUtils.radToDeg(Math.atan2(sinTwist, cosTwist));
|
|
2614
|
+
return {
|
|
2615
|
+
yaw: normalizeGyroYaw(yaw),
|
|
2616
|
+
pitch,
|
|
2617
|
+
roll
|
|
2618
|
+
};
|
|
2619
|
+
}
|
|
2620
|
+
function createRelativeCalibration(deviceQuaternion, yaw, pitch, target) {
|
|
2621
|
+
scratchInvert.copy(deviceQuaternion).invert();
|
|
2622
|
+
scratchEuler.set(
|
|
2623
|
+
MathUtils.degToRad(pitch),
|
|
2624
|
+
MathUtils.degToRad(-yaw),
|
|
2625
|
+
0,
|
|
2626
|
+
"YXZ"
|
|
2627
|
+
);
|
|
2628
|
+
return target.setFromEuler(scratchEuler).multiply(scratchInvert).normalize();
|
|
2629
|
+
}
|
|
2630
|
+
function applyGyroCalibration(deviceQuaternion, calibration, target, previousYaw) {
|
|
2631
|
+
return quaternionToGyroPose(
|
|
2632
|
+
target.copy(calibration).multiply(deviceQuaternion).normalize(),
|
|
2633
|
+
previousYaw
|
|
2634
|
+
);
|
|
2635
|
+
}
|
|
2636
|
+
function reduceGyroPitchOffset(offset, pitchDelta) {
|
|
2637
|
+
if (offset === 0 || pitchDelta === 0) {
|
|
2638
|
+
return offset;
|
|
2639
|
+
}
|
|
2640
|
+
const absDelta = Math.abs(pitchDelta);
|
|
2641
|
+
if (offset > 0) {
|
|
2642
|
+
return Math.max(0, offset - absDelta);
|
|
2643
|
+
}
|
|
2644
|
+
return Math.min(0, offset + absDelta);
|
|
2645
|
+
}
|
|
2646
|
+
function reclaimGyroOffsets(poseYaw, posePitch, constrainedYaw, constrainedPitch) {
|
|
2647
|
+
return {
|
|
2648
|
+
yaw: shortestGyroYawDelta(poseYaw, constrainedYaw),
|
|
2649
|
+
pitch: constrainedPitch - posePitch
|
|
2650
|
+
};
|
|
2651
|
+
}
|
|
2652
|
+
function gyroPoseAngleDelta(from, to) {
|
|
2653
|
+
return Math.max(
|
|
2654
|
+
Math.abs(shortestGyroYawDelta(from.yaw, to.yaw)),
|
|
2655
|
+
Math.abs(to.pitch - from.pitch),
|
|
2656
|
+
Math.abs(shortestGyroYawDelta(from.roll, to.roll))
|
|
2657
|
+
);
|
|
2658
|
+
}
|
|
2659
|
+
function shouldReanchorGyro(angleDeltaDegrees, deltaSeconds) {
|
|
2660
|
+
if (!(deltaSeconds > 0) || angleDeltaDegrees <= GYRO_DISCONTINUITY_ANGLE_DEG) {
|
|
2661
|
+
return false;
|
|
2662
|
+
}
|
|
2663
|
+
return angleDeltaDegrees / deltaSeconds >= GYRO_DISCONTINUITY_SPEED_DEG_PER_S;
|
|
2664
|
+
}
|
|
2665
|
+
function posesNearlyEqual(a, b, epsilon = GYRO_POSE_EPSILON) {
|
|
2666
|
+
return Math.abs(shortestGyroYawDelta(a.yaw, b.yaw)) < epsilon && Math.abs(a.pitch - b.pitch) < epsilon && Math.abs(a.roll - b.roll) < epsilon;
|
|
2667
|
+
}
|
|
2668
|
+
|
|
2669
|
+
// src/panorama-view-runtime.tsx
|
|
2541
2670
|
var MAX_PITCH = 90;
|
|
2542
2671
|
var BOUNCE_OVERSHOOT_PITCH = 12;
|
|
2543
2672
|
var BOUNCE_OVERSHOOT_FOV_RATIO = 0.15;
|
|
@@ -2554,7 +2683,7 @@ function clamp(value, min, max) {
|
|
|
2554
2683
|
return Math.max(min, Math.min(max, value));
|
|
2555
2684
|
}
|
|
2556
2685
|
function normalizeYaw(yaw) {
|
|
2557
|
-
return
|
|
2686
|
+
return MathUtils2.euclideanModulo(yaw + 180, 360) - 180;
|
|
2558
2687
|
}
|
|
2559
2688
|
function shortestYawDelta(from, to) {
|
|
2560
2689
|
return normalizeYaw(to - from);
|
|
@@ -2602,6 +2731,7 @@ var PanoramaViewRuntime = forwardRef(function PanoramaViewRuntime2({ initialView
|
|
|
2602
2731
|
const interactionLockCountRef = useRef(0);
|
|
2603
2732
|
const keyboardActiveRef = useRef(false);
|
|
2604
2733
|
const gyroActiveRef = useRef(false);
|
|
2734
|
+
const gyroPoseDrivingRef = useRef(false);
|
|
2605
2735
|
const gyroPoseRef = useRef({ yaw: 0, pitch: 0, roll: 0 });
|
|
2606
2736
|
const gyroOffsetRef = useRef({ yaw: 0, pitch: 0 });
|
|
2607
2737
|
const gyroTouchModeRef = useRef("full");
|
|
@@ -2610,8 +2740,8 @@ var PanoramaViewRuntime = forwardRef(function PanoramaViewRuntime2({ initialView
|
|
|
2610
2740
|
const optionsRef = useRef(options);
|
|
2611
2741
|
const eventBusRef = useRef(eventBus);
|
|
2612
2742
|
const lastEmittedViewRef = useRef(null);
|
|
2613
|
-
const eulerRef = useRef(new
|
|
2614
|
-
const xrEulerRef = useRef(new
|
|
2743
|
+
const eulerRef = useRef(new Euler2(0, 0, 0, "YXZ"));
|
|
2744
|
+
const xrEulerRef = useRef(new Euler2(0, 0, 0, "YXZ"));
|
|
2615
2745
|
const baseLimitsRef = useRef(viewLimits);
|
|
2616
2746
|
const sceneLimitsRef = useRef(void 0);
|
|
2617
2747
|
const legacyFovRef = useRef({ minFov, maxFov });
|
|
@@ -2940,6 +3070,7 @@ var PanoramaViewRuntime = forwardRef(function PanoramaViewRuntime2({ initialView
|
|
|
2940
3070
|
gyroOffsetRef.current = { yaw: 0, pitch: 0 };
|
|
2941
3071
|
stopVelocity();
|
|
2942
3072
|
if (!active) {
|
|
3073
|
+
gyroPoseDrivingRef.current = false;
|
|
2943
3074
|
cameraRollRef.current = 0;
|
|
2944
3075
|
dirtyRef.current = true;
|
|
2945
3076
|
}
|
|
@@ -2949,18 +3080,35 @@ var PanoramaViewRuntime = forwardRef(function PanoramaViewRuntime2({ initialView
|
|
|
2949
3080
|
return;
|
|
2950
3081
|
}
|
|
2951
3082
|
const previous = gyroPoseRef.current;
|
|
2952
|
-
const
|
|
3083
|
+
const pitchDelta = pose.pitch - previous.pitch;
|
|
3084
|
+
const viewMovement = Math.abs(shortestYawDelta(previous.yaw, pose.yaw)) + Math.abs(pitchDelta);
|
|
2953
3085
|
const movement = viewMovement + Math.abs(previous.roll - pose.roll);
|
|
2954
|
-
if (movement <
|
|
3086
|
+
if (movement < GYRO_POSE_EPSILON) {
|
|
2955
3087
|
return;
|
|
2956
3088
|
}
|
|
3089
|
+
if (gyroTouchModeRef.current === "full") {
|
|
3090
|
+
gyroOffsetRef.current.pitch = reduceGyroPitchOffset(
|
|
3091
|
+
gyroOffsetRef.current.pitch,
|
|
3092
|
+
pitchDelta
|
|
3093
|
+
);
|
|
3094
|
+
}
|
|
2957
3095
|
gyroPoseRef.current = { ...pose };
|
|
2958
|
-
|
|
3096
|
+
gyroPoseDrivingRef.current = true;
|
|
3097
|
+
const constrained = hardConstrainView({
|
|
2959
3098
|
yaw: pose.yaw + gyroOffsetRef.current.yaw,
|
|
2960
3099
|
pitch: pose.pitch + gyroOffsetRef.current.pitch
|
|
2961
3100
|
});
|
|
3101
|
+
targetViewRef.current = constrained;
|
|
3102
|
+
const reclaimed = reclaimGyroOffsets(
|
|
3103
|
+
pose.yaw,
|
|
3104
|
+
pose.pitch,
|
|
3105
|
+
constrained.yaw,
|
|
3106
|
+
constrained.pitch
|
|
3107
|
+
);
|
|
3108
|
+
gyroOffsetRef.current.yaw = reclaimed.yaw;
|
|
3109
|
+
gyroOffsetRef.current.pitch = reclaimed.pitch;
|
|
2962
3110
|
cameraRollRef.current = pose.roll;
|
|
2963
|
-
if (viewMovement >=
|
|
3111
|
+
if (viewMovement >= GYRO_POSE_EPSILON) {
|
|
2964
3112
|
markDirty();
|
|
2965
3113
|
} else {
|
|
2966
3114
|
dirtyRef.current = true;
|
|
@@ -3006,9 +3154,9 @@ var PanoramaViewRuntime = forwardRef(function PanoramaViewRuntime2({ initialView
|
|
|
3006
3154
|
const xrCamera = gl.xr.getCamera();
|
|
3007
3155
|
xrEulerRef.current.setFromQuaternion(xrCamera.quaternion, "YXZ");
|
|
3008
3156
|
const nextView2 = {
|
|
3009
|
-
yaw: normalizeYaw(-
|
|
3157
|
+
yaw: normalizeYaw(-MathUtils2.radToDeg(xrEulerRef.current.y)),
|
|
3010
3158
|
pitch: clamp(
|
|
3011
|
-
|
|
3159
|
+
MathUtils2.radToDeg(xrEulerRef.current.x),
|
|
3012
3160
|
-MAX_PITCH,
|
|
3013
3161
|
MAX_PITCH
|
|
3014
3162
|
),
|
|
@@ -3038,14 +3186,16 @@ var PanoramaViewRuntime = forwardRef(function PanoramaViewRuntime2({ initialView
|
|
|
3038
3186
|
const completed = progress === 1;
|
|
3039
3187
|
viewRef.current = completed ? { ...navigation.target } : nextView2;
|
|
3040
3188
|
eulerRef.current.set(
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3189
|
+
MathUtils2.degToRad(viewRef.current.pitch),
|
|
3190
|
+
MathUtils2.degToRad(-viewRef.current.yaw),
|
|
3191
|
+
MathUtils2.degToRad(cameraRollRef.current),
|
|
3044
3192
|
"YXZ"
|
|
3045
3193
|
);
|
|
3046
3194
|
camera.quaternion.setFromEuler(eulerRef.current);
|
|
3047
|
-
camera.fov
|
|
3048
|
-
|
|
3195
|
+
if (camera.fov !== viewRef.current.fov) {
|
|
3196
|
+
camera.fov = viewRef.current.fov;
|
|
3197
|
+
camera.updateProjectionMatrix();
|
|
3198
|
+
}
|
|
3049
3199
|
camera.updateMatrixWorld();
|
|
3050
3200
|
const emittedView = { ...viewRef.current };
|
|
3051
3201
|
const lastEmitted2 = lastEmittedViewRef.current;
|
|
@@ -3114,7 +3264,7 @@ var PanoramaViewRuntime = forwardRef(function PanoramaViewRuntime2({ initialView
|
|
|
3114
3264
|
optionsRef.current.zoomDamping,
|
|
3115
3265
|
DEFAULT_ZOOM_DAMPING
|
|
3116
3266
|
);
|
|
3117
|
-
const rotationFactor = dampingFactor(rotateDamping, deltaSeconds);
|
|
3267
|
+
const rotationFactor = gyroPoseDrivingRef.current ? 1 : dampingFactor(rotateDamping, deltaSeconds);
|
|
3118
3268
|
const zoomFactor = dampingFactor(zoomDamping, deltaSeconds);
|
|
3119
3269
|
const yawDelta = limitedYawDelta(viewRef.current.yaw, targetView.yaw, limitsRef.current.yaw);
|
|
3120
3270
|
const smoothedView = {
|
|
@@ -3125,14 +3275,16 @@ var PanoramaViewRuntime = forwardRef(function PanoramaViewRuntime2({ initialView
|
|
|
3125
3275
|
const hasSettled = Math.abs(shortestYawDelta(smoothedView.yaw, targetView.yaw)) < VIEW_SETTLE_EPSILON && Math.abs(smoothedView.pitch - targetView.pitch) < VIEW_SETTLE_EPSILON && Math.abs(smoothedView.fov - targetView.fov) < VIEW_SETTLE_EPSILON;
|
|
3126
3276
|
viewRef.current = hasSettled ? { ...targetView } : smoothedView;
|
|
3127
3277
|
eulerRef.current.set(
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3278
|
+
MathUtils2.degToRad(viewRef.current.pitch),
|
|
3279
|
+
MathUtils2.degToRad(-viewRef.current.yaw),
|
|
3280
|
+
MathUtils2.degToRad(cameraRollRef.current),
|
|
3131
3281
|
"YXZ"
|
|
3132
3282
|
);
|
|
3133
3283
|
camera.quaternion.setFromEuler(eulerRef.current);
|
|
3134
|
-
camera.fov
|
|
3135
|
-
|
|
3284
|
+
if (camera.fov !== viewRef.current.fov) {
|
|
3285
|
+
camera.fov = viewRef.current.fov;
|
|
3286
|
+
camera.updateProjectionMatrix();
|
|
3287
|
+
}
|
|
3136
3288
|
camera.updateMatrixWorld();
|
|
3137
3289
|
const nextView = { ...viewRef.current };
|
|
3138
3290
|
const lastEmitted = lastEmittedViewRef.current;
|
|
@@ -3692,7 +3844,7 @@ import { useFrame as useFrame4, useThree as useThree3 } from "@react-three/fiber
|
|
|
3692
3844
|
import { useContext as useContext5, useEffect as useEffect5, useRef as useRef5 } from "react";
|
|
3693
3845
|
|
|
3694
3846
|
// src/pointer-drag.ts
|
|
3695
|
-
import { Euler as
|
|
3847
|
+
import { Euler as Euler3, MathUtils as MathUtils3, PerspectiveCamera as PerspectiveCamera2, Vector3 as Vector32 } from "three";
|
|
3696
3848
|
var DEFAULT_POINTER_DRAG_SPEED = 0.35;
|
|
3697
3849
|
var POINTER_FOLLOW_TIME_SECONDS = 0.01;
|
|
3698
3850
|
var MIN_VELOCITY_SAMPLE_SECONDS = 1 / 120;
|
|
@@ -3721,18 +3873,18 @@ var PointerDragAnchor = class {
|
|
|
3721
3873
|
this.origin = origin;
|
|
3722
3874
|
this.rect = rect;
|
|
3723
3875
|
this.projection = projection;
|
|
3724
|
-
this.local = new
|
|
3725
|
-
this.rotation = new
|
|
3876
|
+
this.local = new Vector32();
|
|
3877
|
+
this.rotation = new Euler3(0, 0, 0, "YXZ");
|
|
3726
3878
|
const startRay = this.ray(start).clone();
|
|
3727
3879
|
this.baseAzimuth = Math.atan2(startRay.x, -startRay.z);
|
|
3728
3880
|
this.baseElevation = Math.atan2(startRay.y, -startRay.z);
|
|
3729
3881
|
this.anchor = startRay.clone().applyEuler(this.rotation.set(
|
|
3730
|
-
|
|
3731
|
-
|
|
3882
|
+
MathUtils3.degToRad(origin.pitch),
|
|
3883
|
+
MathUtils3.degToRad(-origin.yaw),
|
|
3732
3884
|
0,
|
|
3733
3885
|
"YXZ"
|
|
3734
3886
|
));
|
|
3735
|
-
const originPitch =
|
|
3887
|
+
const originPitch = MathUtils3.degToRad(origin.pitch);
|
|
3736
3888
|
const roots = this.pitchRoots(startRay, originPitch);
|
|
3737
3889
|
this.useSupplementary = Math.abs(roots.supplementary - originPitch) + 1e-6 < Math.abs(roots.principal - originPitch);
|
|
3738
3890
|
}
|
|
@@ -3745,7 +3897,7 @@ var PointerDragAnchor = class {
|
|
|
3745
3897
|
}
|
|
3746
3898
|
/** Pitch roots of the level-camera constraint. The supplementary root is unwrapped toward the press. */
|
|
3747
3899
|
pitchRoots(ray, originPitch) {
|
|
3748
|
-
const latitude = Math.asin(
|
|
3900
|
+
const latitude = Math.asin(MathUtils3.clamp(
|
|
3749
3901
|
this.anchor.y / Math.max(Math.hypot(ray.y, ray.z), 1e-12),
|
|
3750
3902
|
-1,
|
|
3751
3903
|
1
|
|
@@ -3765,28 +3917,28 @@ var PointerDragAnchor = class {
|
|
|
3765
3917
|
x: this.start.x + (point.x - this.start.x) * multiplier,
|
|
3766
3918
|
y: this.start.y + (point.y - this.start.y) * multiplier
|
|
3767
3919
|
});
|
|
3768
|
-
const originPitch =
|
|
3920
|
+
const originPitch = MathUtils3.degToRad(this.origin.pitch);
|
|
3769
3921
|
const roots = this.pitchRoots(ray, originPitch);
|
|
3770
|
-
const exactPitch =
|
|
3922
|
+
const exactPitch = MathUtils3.clamp(
|
|
3771
3923
|
this.useSupplementary ? roots.supplementary : roots.principal,
|
|
3772
3924
|
-Math.PI / 2,
|
|
3773
3925
|
Math.PI / 2
|
|
3774
3926
|
);
|
|
3775
3927
|
const stablePitch = originPitch - (Math.atan2(ray.y, -ray.z) - this.baseElevation);
|
|
3776
3928
|
const fromPole = Math.asin(Math.min(1, Math.hypot(this.anchor.x, this.anchor.z)));
|
|
3777
|
-
const pointerLock =
|
|
3929
|
+
const pointerLock = MathUtils3.smoothstep(fromPole, MathUtils3.degToRad(8), MathUtils3.degToRad(18));
|
|
3778
3930
|
const pitchTurn = Math.atan2(Math.sin(exactPitch - stablePitch), Math.cos(exactPitch - stablePitch));
|
|
3779
|
-
const pitch =
|
|
3931
|
+
const pitch = MathUtils3.clamp(
|
|
3780
3932
|
pointerLock >= 1 ? exactPitch : stablePitch + pointerLock * pitchTurn,
|
|
3781
3933
|
-Math.PI / 2,
|
|
3782
3934
|
Math.PI / 2
|
|
3783
3935
|
);
|
|
3784
3936
|
const pitchedZ = Math.sin(exactPitch) * ray.y + Math.cos(exactPitch) * ray.z;
|
|
3785
3937
|
const exactYaw = Math.atan2(this.anchor.x, -this.anchor.z) - Math.atan2(ray.x, -pitchedZ);
|
|
3786
|
-
const stableYaw =
|
|
3938
|
+
const stableYaw = MathUtils3.degToRad(this.origin.yaw) + Math.atan2(ray.x, -ray.z) - this.baseAzimuth;
|
|
3787
3939
|
const yawTurn = Math.atan2(Math.sin(exactYaw - stableYaw), Math.cos(exactYaw - stableYaw));
|
|
3788
|
-
const yaw =
|
|
3789
|
-
return { yaw: normalizeViewYaw(yaw - this.origin.yaw), pitch:
|
|
3940
|
+
const yaw = MathUtils3.radToDeg(stableYaw + pointerLock * yawTurn);
|
|
3941
|
+
return { yaw: normalizeViewYaw(yaw - this.origin.yaw), pitch: MathUtils3.radToDeg(pitch) - this.origin.pitch };
|
|
3790
3942
|
}
|
|
3791
3943
|
};
|
|
3792
3944
|
function createPointerDrag(camera, element, runtime, source) {
|
|
@@ -5561,10 +5713,10 @@ function usePanoOverlayHost(isFullscreen) {
|
|
|
5561
5713
|
// src/panorama-event-surface.tsx
|
|
5562
5714
|
import { useThree as useThree6 } from "@react-three/fiber";
|
|
5563
5715
|
import { useContext as useContext12, useEffect as useEffect10 } from "react";
|
|
5564
|
-
import { BackSide, Raycaster, Vector2, Vector3 as
|
|
5716
|
+
import { BackSide, Raycaster, Vector2, Vector3 as Vector34 } from "three";
|
|
5565
5717
|
|
|
5566
5718
|
// src/hotspot/coordinates.ts
|
|
5567
|
-
import { MathUtils as
|
|
5719
|
+
import { MathUtils as MathUtils4, Vector3 as Vector33 } from "three";
|
|
5568
5720
|
|
|
5569
5721
|
// src/hotspot/types.ts
|
|
5570
5722
|
var MAX_HOTSPOT_PITCH = 90;
|
|
@@ -5587,13 +5739,13 @@ function normalizePanoYaw(yaw) {
|
|
|
5587
5739
|
if (!Number.isFinite(yaw)) {
|
|
5588
5740
|
return 0;
|
|
5589
5741
|
}
|
|
5590
|
-
return
|
|
5742
|
+
return MathUtils4.euclideanModulo(yaw + 180, 360) - 180;
|
|
5591
5743
|
}
|
|
5592
5744
|
function clampPanoPitch(pitch) {
|
|
5593
5745
|
if (!Number.isFinite(pitch)) {
|
|
5594
5746
|
return 0;
|
|
5595
5747
|
}
|
|
5596
|
-
const clamped =
|
|
5748
|
+
const clamped = MathUtils4.clamp(
|
|
5597
5749
|
pitch,
|
|
5598
5750
|
-MAX_HOTSPOT_PITCH,
|
|
5599
5751
|
MAX_HOTSPOT_PITCH
|
|
@@ -5610,10 +5762,10 @@ function normalizePanoPosition(position) {
|
|
|
5610
5762
|
function panoPositionToVector3(position, radius = 1) {
|
|
5611
5763
|
const normalized = normalizePanoPosition(position);
|
|
5612
5764
|
const safeRadius = Number.isFinite(radius) ? Math.max(0, radius) : 1;
|
|
5613
|
-
const yaw =
|
|
5614
|
-
const pitch =
|
|
5765
|
+
const yaw = MathUtils4.degToRad(normalized.yaw);
|
|
5766
|
+
const pitch = MathUtils4.degToRad(normalized.pitch);
|
|
5615
5767
|
const cosPitch = Math.cos(pitch);
|
|
5616
|
-
return new
|
|
5768
|
+
return new Vector33(
|
|
5617
5769
|
cosPitch * Math.sin(yaw) * safeRadius,
|
|
5618
5770
|
Math.sin(pitch) * safeRadius,
|
|
5619
5771
|
-cosPitch * Math.cos(yaw) * safeRadius
|
|
@@ -5625,9 +5777,9 @@ function vector3ToPanoPosition(vector) {
|
|
|
5625
5777
|
return { yaw: 0, pitch: 0 };
|
|
5626
5778
|
}
|
|
5627
5779
|
return normalizePanoPosition({
|
|
5628
|
-
yaw:
|
|
5629
|
-
pitch:
|
|
5630
|
-
Math.asin(
|
|
5780
|
+
yaw: MathUtils4.radToDeg(Math.atan2(vector.x, -vector.z)),
|
|
5781
|
+
pitch: MathUtils4.radToDeg(
|
|
5782
|
+
Math.asin(MathUtils4.clamp(vector.y / length, -1, 1))
|
|
5631
5783
|
)
|
|
5632
5784
|
});
|
|
5633
5785
|
}
|
|
@@ -5668,7 +5820,7 @@ function PanoramaEventSurface() {
|
|
|
5668
5820
|
const element = gl.domElement;
|
|
5669
5821
|
const ndc = new Vector2();
|
|
5670
5822
|
const raycaster = new Raycaster();
|
|
5671
|
-
const direction = new
|
|
5823
|
+
const direction = new Vector34();
|
|
5672
5824
|
const handleContextMenu = (nativeEvent) => {
|
|
5673
5825
|
const rect = element.getBoundingClientRect();
|
|
5674
5826
|
if (rect.width <= 0 || rect.height <= 0) {
|
|
@@ -7558,8 +7710,8 @@ function WebVRChromeBridge({ host }) {
|
|
|
7558
7710
|
}
|
|
7559
7711
|
|
|
7560
7712
|
// src/webvr/stereo-view.ts
|
|
7561
|
-
import { StereoCamera, Vector3 as
|
|
7562
|
-
var PROJECT = new
|
|
7713
|
+
import { StereoCamera, Vector3 as Vector35 } from "three";
|
|
7714
|
+
var PROJECT = new Vector35();
|
|
7563
7715
|
function createWebVRStereoView() {
|
|
7564
7716
|
return {
|
|
7565
7717
|
active: false,
|
|
@@ -7587,11 +7739,11 @@ function projectStereoHtmlPosition(el, camera, size, eye) {
|
|
|
7587
7739
|
import { useFrame as useFrame7, useThree as useThree8 } from "@react-three/fiber";
|
|
7588
7740
|
import { useXR as useXR2, XROrigin } from "@react-three/xr";
|
|
7589
7741
|
import { useRef as useRef12 } from "react";
|
|
7590
|
-
import { Vector3 as
|
|
7742
|
+
import { Vector3 as Vector36 } from "three";
|
|
7591
7743
|
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
7592
7744
|
function PanoramaXROrigin() {
|
|
7593
7745
|
const originRef = useRef12(null);
|
|
7594
|
-
const localHeadPositionRef = useRef12(new
|
|
7746
|
+
const localHeadPositionRef = useRef12(new Vector36());
|
|
7595
7747
|
const session2 = useXR2((state) => state.session);
|
|
7596
7748
|
const gl = useThree8((state) => state.gl);
|
|
7597
7749
|
useFrame7(() => {
|
|
@@ -8429,7 +8581,7 @@ function isSnapshotTransition(preset) {
|
|
|
8429
8581
|
// src/scene-transitions/snapshot-hold.tsx
|
|
8430
8582
|
import { useFrame as useFrame8, useThree as useThree9 } from "@react-three/fiber";
|
|
8431
8583
|
import { useEffect as useEffect14, useMemo as useMemo9, useRef as useRef14 } from "react";
|
|
8432
|
-
import { Vector3 as
|
|
8584
|
+
import { Vector3 as Vector38 } from "three";
|
|
8433
8585
|
|
|
8434
8586
|
// src/scene-transitions/overlay-utils.ts
|
|
8435
8587
|
import { PlaneGeometry } from "three";
|
|
@@ -8765,7 +8917,7 @@ import { jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
|
8765
8917
|
function SnapshotHold({ snapshot }) {
|
|
8766
8918
|
const { camera, gl } = useThree9();
|
|
8767
8919
|
const meshRef = useRef14(null);
|
|
8768
|
-
const directionRef = useRef14(new
|
|
8920
|
+
const directionRef = useRef14(new Vector38());
|
|
8769
8921
|
const material = useMemo9(
|
|
8770
8922
|
() => createSnapshotMaterial("crossfade", snapshot.texture),
|
|
8771
8923
|
[snapshot.texture]
|
|
@@ -8856,7 +9008,7 @@ import {
|
|
|
8856
9008
|
PlaneGeometry as PlaneGeometry2,
|
|
8857
9009
|
ShaderMaterial as ShaderMaterial2,
|
|
8858
9010
|
Vector2 as Vector23,
|
|
8859
|
-
Vector3 as
|
|
9011
|
+
Vector3 as Vector39
|
|
8860
9012
|
} from "three";
|
|
8861
9013
|
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
8862
9014
|
var PARTICLE_GRID = 48;
|
|
@@ -8938,7 +9090,7 @@ function ParticleOverlay({
|
|
|
8938
9090
|
const meshRef = useRef15(null);
|
|
8939
9091
|
const startRef = useRef15(null);
|
|
8940
9092
|
const finishedRef = useRef15(false);
|
|
8941
|
-
const directionRef = useRef15(new
|
|
9093
|
+
const directionRef = useRef15(new Vector39());
|
|
8942
9094
|
const geometry = useMemo10(() => createParticleGeometry(), []);
|
|
8943
9095
|
const material = useMemo10(
|
|
8944
9096
|
() => new ShaderMaterial2({
|
|
@@ -8995,7 +9147,7 @@ function ParticleOverlay({
|
|
|
8995
9147
|
// src/scene-transitions/snapshot-overlay.tsx
|
|
8996
9148
|
import { useFrame as useFrame10, useThree as useThree11 } from "@react-three/fiber";
|
|
8997
9149
|
import { useEffect as useEffect16, useMemo as useMemo11, useRef as useRef16 } from "react";
|
|
8998
|
-
import { Vector3 as
|
|
9150
|
+
import { Vector3 as Vector310 } from "three";
|
|
8999
9151
|
import { jsx as jsx15, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
9000
9152
|
function SnapshotOverlay({
|
|
9001
9153
|
snapshot,
|
|
@@ -9008,7 +9160,7 @@ function SnapshotOverlay({
|
|
|
9008
9160
|
const meshRef = useRef16(null);
|
|
9009
9161
|
const startRef = useRef16(null);
|
|
9010
9162
|
const finishedRef = useRef16(false);
|
|
9011
|
-
const directionRef = useRef16(new
|
|
9163
|
+
const directionRef = useRef16(new Vector310());
|
|
9012
9164
|
const material = useMemo11(() => {
|
|
9013
9165
|
if (!isSnapshotTransition(transition.preset)) {
|
|
9014
9166
|
return null;
|
|
@@ -9103,7 +9255,7 @@ import {
|
|
|
9103
9255
|
BackSide as BackSide2,
|
|
9104
9256
|
LinearFilter,
|
|
9105
9257
|
LinearMipmapLinearFilter,
|
|
9106
|
-
MathUtils as
|
|
9258
|
+
MathUtils as MathUtils5,
|
|
9107
9259
|
RepeatWrapping,
|
|
9108
9260
|
SRGBColorSpace,
|
|
9109
9261
|
TextureLoader
|
|
@@ -9469,7 +9621,7 @@ function Sphere({
|
|
|
9469
9621
|
return /* @__PURE__ */ jsxs9(
|
|
9470
9622
|
"mesh",
|
|
9471
9623
|
{
|
|
9472
|
-
rotation: [0,
|
|
9624
|
+
rotation: [0, MathUtils5.degToRad(90 + yawOffset2), 0],
|
|
9473
9625
|
visible,
|
|
9474
9626
|
children: [
|
|
9475
9627
|
/* @__PURE__ */ jsx18("sphereGeometry", { args: [DEFAULT_PANORAMA_RADIUS, 128, 64] }),
|
|
@@ -9841,8 +9993,8 @@ import {
|
|
|
9841
9993
|
Box3,
|
|
9842
9994
|
BufferGeometry,
|
|
9843
9995
|
Float32BufferAttribute,
|
|
9844
|
-
MathUtils as
|
|
9845
|
-
Vector3 as
|
|
9996
|
+
MathUtils as MathUtils6,
|
|
9997
|
+
Vector3 as Vector311
|
|
9846
9998
|
} from "three";
|
|
9847
9999
|
function positiveInteger2(value, name) {
|
|
9848
10000
|
if (!Number.isSafeInteger(value) || value <= 0) {
|
|
@@ -9914,9 +10066,9 @@ function sphereTileRange(address) {
|
|
|
9914
10066
|
};
|
|
9915
10067
|
}
|
|
9916
10068
|
function spherePoint(u, v, yawOffset2 = 0, radius = DEFAULT_PANORAMA_RADIUS) {
|
|
9917
|
-
const yaw = (u - 0.5) * Math.PI * 2 +
|
|
10069
|
+
const yaw = (u - 0.5) * Math.PI * 2 + MathUtils6.degToRad(yawOffset2);
|
|
9918
10070
|
const pitch = (0.5 - v) * Math.PI;
|
|
9919
|
-
return new
|
|
10071
|
+
return new Vector311(
|
|
9920
10072
|
Math.sin(yaw) * Math.cos(pitch) * radius,
|
|
9921
10073
|
Math.sin(pitch) * radius,
|
|
9922
10074
|
-Math.cos(yaw) * Math.cos(pitch) * radius
|
|
@@ -10272,15 +10424,15 @@ import {
|
|
|
10272
10424
|
Matrix4 as Matrix43,
|
|
10273
10425
|
PlaneGeometry as PlaneGeometry3,
|
|
10274
10426
|
PerspectiveCamera as PerspectiveCamera5,
|
|
10275
|
-
Vector3 as
|
|
10427
|
+
Vector3 as Vector313
|
|
10276
10428
|
} from "three";
|
|
10277
10429
|
|
|
10278
10430
|
// src/tile/face-layout.ts
|
|
10279
10431
|
import {
|
|
10280
10432
|
Box3 as Box32,
|
|
10281
|
-
Euler as
|
|
10282
|
-
Quaternion,
|
|
10283
|
-
Vector3 as
|
|
10433
|
+
Euler as Euler4,
|
|
10434
|
+
Quaternion as Quaternion2,
|
|
10435
|
+
Vector3 as Vector312
|
|
10284
10436
|
} from "three";
|
|
10285
10437
|
var CUBE_FACES = ["f", "r", "b", "l", "u", "d"];
|
|
10286
10438
|
var PREVIEW_FACE_ORDER = ["l", "f", "r", "b", "u", "d"];
|
|
@@ -10332,8 +10484,8 @@ function getFaceQuaternion(face) {
|
|
|
10332
10484
|
return cached;
|
|
10333
10485
|
}
|
|
10334
10486
|
const transform = getFaceTransform(face);
|
|
10335
|
-
const quaternion = new
|
|
10336
|
-
new
|
|
10487
|
+
const quaternion = new Quaternion2().setFromEuler(
|
|
10488
|
+
new Euler4(...transform.rotation, "XYZ")
|
|
10337
10489
|
);
|
|
10338
10490
|
faceQuaternionCache.set(face, quaternion);
|
|
10339
10491
|
return quaternion;
|
|
@@ -10344,12 +10496,12 @@ function getTileBoundingBox(address, radius = CUBE_RADIUS) {
|
|
|
10344
10496
|
const halfWidth = local.width / 2;
|
|
10345
10497
|
const halfHeight = local.height / 2;
|
|
10346
10498
|
const quaternion = getFaceQuaternion(address.face);
|
|
10347
|
-
const position = new
|
|
10499
|
+
const position = new Vector312(...transform.position);
|
|
10348
10500
|
const corners = [
|
|
10349
|
-
new
|
|
10350
|
-
new
|
|
10351
|
-
new
|
|
10352
|
-
new
|
|
10501
|
+
new Vector312(local.x - halfWidth, local.y - halfHeight, 0),
|
|
10502
|
+
new Vector312(local.x + halfWidth, local.y - halfHeight, 0),
|
|
10503
|
+
new Vector312(local.x - halfWidth, local.y + halfHeight, 0),
|
|
10504
|
+
new Vector312(local.x + halfWidth, local.y + halfHeight, 0)
|
|
10353
10505
|
];
|
|
10354
10506
|
for (const corner of corners) {
|
|
10355
10507
|
corner.applyQuaternion(quaternion).add(position);
|
|
@@ -10623,8 +10775,8 @@ function parentAddresses(child, parentLevel, parentFaceSize, tileSize) {
|
|
|
10623
10775
|
return addresses;
|
|
10624
10776
|
}
|
|
10625
10777
|
function centerFacingAddress(candidates, camera) {
|
|
10626
|
-
const direction = camera.getWorldDirection(new
|
|
10627
|
-
const center = new
|
|
10778
|
+
const direction = camera.getWorldDirection(new Vector313());
|
|
10779
|
+
const center = new Vector313();
|
|
10628
10780
|
let bestCandidate = candidates[0];
|
|
10629
10781
|
let bestAlignment = -Infinity;
|
|
10630
10782
|
for (const candidate of candidates) {
|
|
@@ -11557,16 +11709,16 @@ import {
|
|
|
11557
11709
|
import {
|
|
11558
11710
|
Box3 as Box34,
|
|
11559
11711
|
EdgesGeometry,
|
|
11560
|
-
MathUtils as
|
|
11712
|
+
MathUtils as MathUtils9,
|
|
11561
11713
|
Matrix4 as Matrix44,
|
|
11562
11714
|
PerspectiveCamera as PerspectiveCamera8,
|
|
11563
11715
|
Plane,
|
|
11564
11716
|
PlaneGeometry as PlaneGeometry4,
|
|
11565
|
-
Quaternion as
|
|
11717
|
+
Quaternion as Quaternion4,
|
|
11566
11718
|
Ray,
|
|
11567
11719
|
Raycaster as Raycaster2,
|
|
11568
11720
|
Vector2 as Vector24,
|
|
11569
|
-
Vector3 as
|
|
11721
|
+
Vector3 as Vector317
|
|
11570
11722
|
} from "three";
|
|
11571
11723
|
|
|
11572
11724
|
// src/hotspot/drag-session.ts
|
|
@@ -11669,7 +11821,7 @@ import {
|
|
|
11669
11821
|
useSyncExternalStore as useSyncExternalStore7
|
|
11670
11822
|
} from "react";
|
|
11671
11823
|
import { createRoot } from "react-dom/client";
|
|
11672
|
-
import { Vector3 as
|
|
11824
|
+
import { Vector3 as Vector314 } from "three";
|
|
11673
11825
|
import { Fragment as Fragment5, jsx as jsx23, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
11674
11826
|
function useFallbackStereoView() {
|
|
11675
11827
|
const runtime = useContext20(WebVRRuntimeContext);
|
|
@@ -11692,7 +11844,7 @@ function ProjectedHtml({
|
|
|
11692
11844
|
const { camera, gl, events, size } = useThree17();
|
|
11693
11845
|
const group = useRef23(null);
|
|
11694
11846
|
const overlay = useRef23(null);
|
|
11695
|
-
const scratch = useRef23(new
|
|
11847
|
+
const scratch = useRef23(new Vector314());
|
|
11696
11848
|
const target = events.connected || gl.domElement.parentElement;
|
|
11697
11849
|
const updatePosition = () => {
|
|
11698
11850
|
const anchor = group.current;
|
|
@@ -11893,19 +12045,19 @@ function HotspotTooltip({
|
|
|
11893
12045
|
|
|
11894
12046
|
// src/hotspot/transform.ts
|
|
11895
12047
|
import {
|
|
11896
|
-
MathUtils as
|
|
12048
|
+
MathUtils as MathUtils7,
|
|
11897
12049
|
PerspectiveCamera as PerspectiveCamera6,
|
|
11898
|
-
Vector3 as
|
|
12050
|
+
Vector3 as Vector315
|
|
11899
12051
|
} from "three";
|
|
11900
|
-
var LOCAL_FORWARD = new
|
|
11901
|
-
var CAMERA_POSITION = new
|
|
12052
|
+
var LOCAL_FORWARD = new Vector315(0, 0, 1);
|
|
12053
|
+
var CAMERA_POSITION = new Vector315();
|
|
11902
12054
|
function applyHotspotTransform(group, camera, orientation2, surfaceQuaternion3, rotation, scaleMode, referenceFov, useAngularScale, worldWidth, worldHeight, distance) {
|
|
11903
12055
|
if (orientation2 === "billboard") {
|
|
11904
12056
|
group.quaternion.copy(camera.quaternion);
|
|
11905
12057
|
} else {
|
|
11906
12058
|
group.quaternion.copy(surfaceQuaternion3);
|
|
11907
12059
|
}
|
|
11908
|
-
group.rotateOnAxis(LOCAL_FORWARD,
|
|
12060
|
+
group.rotateOnAxis(LOCAL_FORWARD, MathUtils7.degToRad(-rotation));
|
|
11909
12061
|
let scaleFactor = scaleMode === "fixed" && camera instanceof PerspectiveCamera6 ? fixedScaleFactor(camera.fov, referenceFov) : 1;
|
|
11910
12062
|
if (scaleMode === "fixed" && orientation2 === "billboard" && useAngularScale && camera instanceof PerspectiveCamera6) {
|
|
11911
12063
|
group.updateWorldMatrix(true, false);
|
|
@@ -11922,15 +12074,15 @@ function applyHotspotTransform(group, camera, orientation2, surfaceQuaternion3,
|
|
|
11922
12074
|
group.updateMatrixWorld();
|
|
11923
12075
|
}
|
|
11924
12076
|
function fixedScaleFactor(cameraFov, referenceFov) {
|
|
11925
|
-
const safeReferenceFov =
|
|
11926
|
-
return Math.tan(
|
|
12077
|
+
const safeReferenceFov = MathUtils7.clamp(referenceFov, 1, 179);
|
|
12078
|
+
return Math.tan(MathUtils7.degToRad(cameraFov) / 2) / Math.tan(MathUtils7.degToRad(safeReferenceFov) / 2);
|
|
11927
12079
|
}
|
|
11928
12080
|
function selectionFrameScale(worldScaleX, worldScaleY, cameraSpaceDepth, fovDegrees, viewportHeight, outsetPixels) {
|
|
11929
12081
|
const pixels = Number.isFinite(outsetPixels) && outsetPixels > 0 ? outsetPixels : 0;
|
|
11930
12082
|
const depth = Number.isFinite(cameraSpaceDepth) ? Math.max(cameraSpaceDepth, 1e-4) : 1e-4;
|
|
11931
12083
|
const height = Number.isFinite(viewportHeight) ? Math.max(viewportHeight, 1) : 1;
|
|
11932
|
-
const fov = Number.isFinite(fovDegrees) ?
|
|
11933
|
-
const pixelsPerWorldUnit = height / (2 * Math.tan(
|
|
12084
|
+
const fov = Number.isFinite(fovDegrees) ? MathUtils7.clamp(fovDegrees, 1, 179) : 75;
|
|
12085
|
+
const pixelsPerWorldUnit = height / (2 * Math.tan(MathUtils7.degToRad(fov) * 0.5) * depth);
|
|
11934
12086
|
const axis = (worldScale) => {
|
|
11935
12087
|
const pixelsPerLocalUnit = pixelsPerWorldUnit * Math.abs(worldScale);
|
|
11936
12088
|
if (pixelsPerLocalUnit < 1e-4) {
|
|
@@ -11946,12 +12098,12 @@ import { Line } from "@react-three/drei";
|
|
|
11946
12098
|
import { useFrame as useFrame15, useThree as useThree18 } from "@react-three/fiber";
|
|
11947
12099
|
import { useLayoutEffect as useLayoutEffect6, useRef as useRef24 } from "react";
|
|
11948
12100
|
import {
|
|
11949
|
-
MathUtils as
|
|
12101
|
+
MathUtils as MathUtils8,
|
|
11950
12102
|
PerspectiveCamera as PerspectiveCamera7,
|
|
11951
|
-
Vector3 as
|
|
12103
|
+
Vector3 as Vector316
|
|
11952
12104
|
} from "three";
|
|
11953
12105
|
import { jsx as jsx25 } from "react/jsx-runtime";
|
|
11954
|
-
var LINE_WORLD_POSITION = new
|
|
12106
|
+
var LINE_WORLD_POSITION = new Vector316();
|
|
11955
12107
|
function applyScreenSpaceDashScale(object, camera, viewportHeight) {
|
|
11956
12108
|
const material = object?.material;
|
|
11957
12109
|
if (!object || typeof material?.dashScale !== "number") {
|
|
@@ -11960,7 +12112,7 @@ function applyScreenSpaceDashScale(object, camera, viewportHeight) {
|
|
|
11960
12112
|
object.getWorldPosition(LINE_WORLD_POSITION);
|
|
11961
12113
|
const depth = Math.max(camera.position.distanceTo(LINE_WORLD_POSITION), 1);
|
|
11962
12114
|
const fov = camera instanceof PerspectiveCamera7 ? camera.fov : 75;
|
|
11963
|
-
material.dashScale = viewportHeight / (2 * Math.tan(
|
|
12115
|
+
material.dashScale = viewportHeight / (2 * Math.tan(MathUtils8.degToRad(fov) * 0.5) * depth);
|
|
11964
12116
|
}
|
|
11965
12117
|
function resolveDash(dashSize, gapSize) {
|
|
11966
12118
|
if (dashSize === void 0 || !Number.isFinite(dashSize) || dashSize <= 0) {
|
|
@@ -12029,8 +12181,8 @@ var DRAG_EPSILON_DEGREES = 1e-3;
|
|
|
12029
12181
|
var SELECTION_BORDER_WIDTH = 3;
|
|
12030
12182
|
var SELECTION_BORDER_GAP = 3;
|
|
12031
12183
|
var SELECTION_BORDER_OUTSET = SELECTION_BORDER_GAP + SELECTION_BORDER_WIDTH / 2;
|
|
12032
|
-
var SELECTION_CAMERA_POSITION = new
|
|
12033
|
-
var SELECTION_WORLD_SCALE = new
|
|
12184
|
+
var SELECTION_CAMERA_POSITION = new Vector317();
|
|
12185
|
+
var SELECTION_WORLD_SCALE = new Vector317();
|
|
12034
12186
|
var SELECTION_BORDER_POINTS = [
|
|
12035
12187
|
[-0.5, -0.5, 1e-3],
|
|
12036
12188
|
[0.5, -0.5, 1e-3],
|
|
@@ -12040,25 +12192,25 @@ var SELECTION_BORDER_POINTS = [
|
|
|
12040
12192
|
];
|
|
12041
12193
|
var TOOLTIP_WORLD_BOX = new Box34();
|
|
12042
12194
|
var TOOLTIP_LOCAL_BOX = new Box34();
|
|
12043
|
-
var TOOLTIP_CORNER = new
|
|
12195
|
+
var TOOLTIP_CORNER = new Vector317();
|
|
12044
12196
|
var TOOLTIP_INVERSE = new Matrix44();
|
|
12045
|
-
var TOOLTIP_WORLD_CORNER = new
|
|
12046
|
-
var TOOLTIP_PROJECTED = new
|
|
12047
|
-
var TOOLTIP_RAY_ORIGIN = new
|
|
12048
|
-
var TOOLTIP_RAY_FAR = new
|
|
12049
|
-
var TOOLTIP_RAY_DIRECTION = new
|
|
12197
|
+
var TOOLTIP_WORLD_CORNER = new Vector317();
|
|
12198
|
+
var TOOLTIP_PROJECTED = new Vector317();
|
|
12199
|
+
var TOOLTIP_RAY_ORIGIN = new Vector317();
|
|
12200
|
+
var TOOLTIP_RAY_FAR = new Vector317();
|
|
12201
|
+
var TOOLTIP_RAY_DIRECTION = new Vector317();
|
|
12050
12202
|
var TOOLTIP_RAY = new Ray();
|
|
12051
12203
|
var TOOLTIP_PLANE = new Plane();
|
|
12052
|
-
var TOOLTIP_INTERSECTION = new
|
|
12053
|
-
var TOOLTIP_PLANE_NORMAL = new
|
|
12054
|
-
var TOOLTIP_PLANE_POINT = new
|
|
12204
|
+
var TOOLTIP_INTERSECTION = new Vector317();
|
|
12205
|
+
var TOOLTIP_PLANE_NORMAL = new Vector317();
|
|
12206
|
+
var TOOLTIP_PLANE_POINT = new Vector317();
|
|
12055
12207
|
var HOTSPOT_MODE_RENDERING = {
|
|
12056
12208
|
surface: { orientation: "surface", placement: "surface" },
|
|
12057
12209
|
billboard: { orientation: "billboard", placement: "floating" }
|
|
12058
12210
|
};
|
|
12059
12211
|
function angularSizeToWorldSize(size, radius) {
|
|
12060
|
-
const safeSize = Number.isFinite(size) ?
|
|
12061
|
-
return 2 * radius * Math.tan(
|
|
12212
|
+
const safeSize = Number.isFinite(size) ? MathUtils9.clamp(Math.abs(size), MIN_ANGULAR_SIZE, MAX_ANGULAR_SIZE) : MIN_ANGULAR_SIZE;
|
|
12213
|
+
return 2 * radius * Math.tan(MathUtils9.degToRad(safeSize) / 2);
|
|
12062
12214
|
}
|
|
12063
12215
|
function resolveScale(scale) {
|
|
12064
12216
|
return Number.isFinite(scale) && scale > 0 ? scale : 1;
|
|
@@ -12071,39 +12223,39 @@ function resolveDistance(placement, distance, width, height) {
|
|
|
12071
12223
|
if (!Number.isFinite(distance)) {
|
|
12072
12224
|
return DEFAULT_FLOATING_DISTANCE;
|
|
12073
12225
|
}
|
|
12074
|
-
return
|
|
12226
|
+
return MathUtils9.clamp(Math.abs(distance), 0.1, maximumDistance);
|
|
12075
12227
|
}
|
|
12076
12228
|
function maximumHotspotDistance(width, height) {
|
|
12077
|
-
const safeWidth =
|
|
12229
|
+
const safeWidth = MathUtils9.clamp(
|
|
12078
12230
|
Math.abs(Number.isFinite(width) ? width : MIN_ANGULAR_SIZE),
|
|
12079
12231
|
MIN_ANGULAR_SIZE,
|
|
12080
12232
|
MAX_ANGULAR_SIZE
|
|
12081
12233
|
);
|
|
12082
|
-
const safeHeight =
|
|
12234
|
+
const safeHeight = MathUtils9.clamp(
|
|
12083
12235
|
Math.abs(Number.isFinite(height) ? height : MIN_ANGULAR_SIZE),
|
|
12084
12236
|
MIN_ANGULAR_SIZE,
|
|
12085
12237
|
MAX_ANGULAR_SIZE
|
|
12086
12238
|
);
|
|
12087
12239
|
const cornerFactor = Math.hypot(
|
|
12088
12240
|
1,
|
|
12089
|
-
Math.tan(
|
|
12090
|
-
Math.tan(
|
|
12241
|
+
Math.tan(MathUtils9.degToRad(safeWidth) / 2),
|
|
12242
|
+
Math.tan(MathUtils9.degToRad(safeHeight) / 2)
|
|
12091
12243
|
);
|
|
12092
12244
|
return (PANORAMA_RADIUS - PANORAMA_SURFACE_INSET) / cornerFactor;
|
|
12093
12245
|
}
|
|
12094
12246
|
function createSurfaceQuaternion(position) {
|
|
12095
12247
|
const outward = panoPositionToVector3(position).normalize();
|
|
12096
12248
|
const inward = outward.clone().negate();
|
|
12097
|
-
const pitch =
|
|
12098
|
-
const yaw =
|
|
12099
|
-
const localUp = new
|
|
12249
|
+
const pitch = MathUtils9.degToRad(position.pitch);
|
|
12250
|
+
const yaw = MathUtils9.degToRad(position.yaw);
|
|
12251
|
+
const localUp = new Vector317(
|
|
12100
12252
|
-Math.sin(pitch) * Math.sin(yaw),
|
|
12101
12253
|
Math.cos(pitch),
|
|
12102
12254
|
Math.sin(pitch) * Math.cos(yaw)
|
|
12103
12255
|
).normalize();
|
|
12104
12256
|
const localRight = localUp.clone().cross(inward).normalize();
|
|
12105
12257
|
const basis = new Matrix44().makeBasis(localRight, localUp, inward);
|
|
12106
|
-
return new
|
|
12258
|
+
return new Quaternion4().setFromRotationMatrix(basis);
|
|
12107
12259
|
}
|
|
12108
12260
|
function makeInteractionEvent(id, position, event) {
|
|
12109
12261
|
return {
|
|
@@ -12116,7 +12268,7 @@ function makeInteractionEvent(id, position, event) {
|
|
|
12116
12268
|
function angularDistance(a, b) {
|
|
12117
12269
|
const aVector = panoPositionToVector3(a);
|
|
12118
12270
|
const bVector = panoPositionToVector3(b);
|
|
12119
|
-
return
|
|
12271
|
+
return MathUtils9.radToDeg(aVector.angleTo(bVector));
|
|
12120
12272
|
}
|
|
12121
12273
|
var DRAG_POINTER = new Vector24();
|
|
12122
12274
|
var DRAG_RAYCASTER = new Raycaster2();
|
|
@@ -13761,10 +13913,10 @@ import {
|
|
|
13761
13913
|
} from "three";
|
|
13762
13914
|
|
|
13763
13915
|
// src/hotspot/audio-spatial.ts
|
|
13764
|
-
import { MathUtils as
|
|
13765
|
-
var LOOK_DIR = new
|
|
13766
|
-
var SOURCE_DIR = new
|
|
13767
|
-
var RIGHT_DIR = new
|
|
13916
|
+
import { MathUtils as MathUtils10, Vector3 as Vector318 } from "three";
|
|
13917
|
+
var LOOK_DIR = new Vector318();
|
|
13918
|
+
var SOURCE_DIR = new Vector318();
|
|
13919
|
+
var RIGHT_DIR = new Vector318();
|
|
13768
13920
|
function clampAudioVolume(volume) {
|
|
13769
13921
|
if (!Number.isFinite(volume)) {
|
|
13770
13922
|
return 1;
|
|
@@ -13789,11 +13941,11 @@ function lookRangeGain(angleDegrees, range) {
|
|
|
13789
13941
|
function audioSpatialFromView(camera, position, range) {
|
|
13790
13942
|
camera.getWorldDirection(LOOK_DIR);
|
|
13791
13943
|
SOURCE_DIR.copy(panoPositionToVector3(position)).normalize();
|
|
13792
|
-
const angleDegrees =
|
|
13793
|
-
Math.acos(
|
|
13944
|
+
const angleDegrees = MathUtils10.radToDeg(
|
|
13945
|
+
Math.acos(MathUtils10.clamp(LOOK_DIR.dot(SOURCE_DIR), -1, 1))
|
|
13794
13946
|
);
|
|
13795
13947
|
RIGHT_DIR.set(1, 0, 0).applyQuaternion(camera.quaternion);
|
|
13796
|
-
const pan =
|
|
13948
|
+
const pan = MathUtils10.clamp(
|
|
13797
13949
|
Math.atan2(SOURCE_DIR.dot(RIGHT_DIR), SOURCE_DIR.dot(LOOK_DIR)) / (Math.PI / 2),
|
|
13798
13950
|
-1,
|
|
13799
13951
|
1
|
|
@@ -14105,7 +14257,7 @@ import {
|
|
|
14105
14257
|
CanvasTexture as CanvasTexture3,
|
|
14106
14258
|
ClampToEdgeWrapping as ClampToEdgeWrapping8,
|
|
14107
14259
|
LinearFilter as LinearFilter10,
|
|
14108
|
-
MathUtils as
|
|
14260
|
+
MathUtils as MathUtils11,
|
|
14109
14261
|
PerspectiveCamera as PerspectiveCamera9,
|
|
14110
14262
|
SRGBColorSpace as SRGBColorSpace9
|
|
14111
14263
|
} from "three";
|
|
@@ -14180,7 +14332,7 @@ function projectedDevicePixels(angleDeg, fovDeg, viewportHeight) {
|
|
|
14180
14332
|
}
|
|
14181
14333
|
const fov = Math.min(179, Math.max(1, resolvePositive(fovDeg, DEFAULT_REFERENCE_FOV2)));
|
|
14182
14334
|
const angle = Math.min(179, Math.max(0.01, Math.abs(angleDeg)));
|
|
14183
|
-
return Math.tan(
|
|
14335
|
+
return Math.tan(MathUtils11.degToRad(angle) / 2) / Math.tan(MathUtils11.degToRad(fov) / 2) * viewportHeight;
|
|
14184
14336
|
}
|
|
14185
14337
|
function snapRasterLongSide(screenLong, layoutLong) {
|
|
14186
14338
|
if (!(screenLong > 0)) {
|
|
@@ -14655,10 +14807,10 @@ import {
|
|
|
14655
14807
|
DoubleSide as DoubleSide5,
|
|
14656
14808
|
Float32BufferAttribute as Float32BufferAttribute2,
|
|
14657
14809
|
Matrix4 as Matrix45,
|
|
14658
|
-
Quaternion as
|
|
14810
|
+
Quaternion as Quaternion5,
|
|
14659
14811
|
ShapeUtils,
|
|
14660
14812
|
Vector2 as Vector26,
|
|
14661
|
-
Vector3 as
|
|
14813
|
+
Vector3 as Vector319
|
|
14662
14814
|
} from "three";
|
|
14663
14815
|
import { jsx as jsx35, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
14664
14816
|
var POLYGON_RADIUS = 990;
|
|
@@ -14732,7 +14884,7 @@ function polygonContainsDirection(vertices, direction) {
|
|
|
14732
14884
|
}
|
|
14733
14885
|
function fitsHemisphere(vertices) {
|
|
14734
14886
|
const directions = vertices.map((vertex) => panoPositionToVector3(vertex).normalize());
|
|
14735
|
-
const candidates = [new
|
|
14887
|
+
const candidates = [new Vector319()];
|
|
14736
14888
|
for (const direction of directions) {
|
|
14737
14889
|
candidates[0].add(direction);
|
|
14738
14890
|
candidates.push(direction.clone());
|
|
@@ -14756,7 +14908,7 @@ function validatePolygonVertices(vertices) {
|
|
|
14756
14908
|
if (hasSelfIntersection(unwrapped)) {
|
|
14757
14909
|
issues.push({ code: "self_intersection", message: "Polygon edges cannot cross." });
|
|
14758
14910
|
}
|
|
14759
|
-
if (polygonContainsDirection(normalized, new
|
|
14911
|
+
if (polygonContainsDirection(normalized, new Vector319(0, 1, 0)) || polygonContainsDirection(normalized, new Vector319(0, -1, 0))) {
|
|
14760
14912
|
issues.push({ code: "contains_pole", message: "Polygons cannot contain a panorama pole." });
|
|
14761
14913
|
}
|
|
14762
14914
|
if (!fitsHemisphere(normalized)) {
|
|
@@ -14767,7 +14919,7 @@ function validatePolygonVertices(vertices) {
|
|
|
14767
14919
|
function polygonCenter(vertices) {
|
|
14768
14920
|
const sum = vertices.reduce(
|
|
14769
14921
|
(total, vertex) => total.add(panoPositionToVector3(vertex).normalize()),
|
|
14770
|
-
new
|
|
14922
|
+
new Vector319()
|
|
14771
14923
|
);
|
|
14772
14924
|
return sum.lengthSq() > 1e-8 ? vector3ToPanoPosition(sum) : normalizePanoPosition(vertices[0]);
|
|
14773
14925
|
}
|
|
@@ -14776,12 +14928,12 @@ function surfaceQuaternion(position) {
|
|
|
14776
14928
|
const inward = outward.clone().negate();
|
|
14777
14929
|
const pitch = position.pitch * Math.PI / 180;
|
|
14778
14930
|
const yaw = position.yaw * Math.PI / 180;
|
|
14779
|
-
const localUp = new
|
|
14931
|
+
const localUp = new Vector319(
|
|
14780
14932
|
-Math.sin(pitch) * Math.sin(yaw),
|
|
14781
14933
|
Math.cos(pitch),
|
|
14782
14934
|
Math.sin(pitch) * Math.cos(yaw)
|
|
14783
14935
|
).normalize();
|
|
14784
|
-
return new
|
|
14936
|
+
return new Quaternion5().setFromRotationMatrix(
|
|
14785
14937
|
new Matrix45().makeBasis(localUp.clone().cross(inward).normalize(), localUp, inward)
|
|
14786
14938
|
);
|
|
14787
14939
|
}
|
|
@@ -14789,7 +14941,7 @@ function makeWorldToLocal(center) {
|
|
|
14789
14941
|
return new Matrix45().compose(
|
|
14790
14942
|
panoPositionToVector3(center, POLYGON_RADIUS),
|
|
14791
14943
|
surfaceQuaternion(center),
|
|
14792
|
-
new
|
|
14944
|
+
new Vector319(1, 1, 1)
|
|
14793
14945
|
).invert();
|
|
14794
14946
|
}
|
|
14795
14947
|
function projectedPoint(a, b, c, weightB, weightC, radius, worldToLocal) {
|
|
@@ -15015,10 +15167,10 @@ function PolygonHotspot({
|
|
|
15015
15167
|
// src/hotspot/polyline-hotspot.tsx
|
|
15016
15168
|
import { useEffect as useEffect32, useMemo as useMemo21, useRef as useRef33 } from "react";
|
|
15017
15169
|
import {
|
|
15018
|
-
MathUtils as
|
|
15170
|
+
MathUtils as MathUtils12,
|
|
15019
15171
|
Matrix4 as Matrix46,
|
|
15020
|
-
Quaternion as
|
|
15021
|
-
Vector3 as
|
|
15172
|
+
Quaternion as Quaternion6,
|
|
15173
|
+
Vector3 as Vector320
|
|
15022
15174
|
} from "three";
|
|
15023
15175
|
import { jsx as jsx36 } from "react/jsx-runtime";
|
|
15024
15176
|
var POLYLINE_RADIUS = 990;
|
|
@@ -15045,21 +15197,21 @@ function unwrapVertices(vertices) {
|
|
|
15045
15197
|
function polylineCenter(vertices) {
|
|
15046
15198
|
const sum = vertices.reduce(
|
|
15047
15199
|
(total, vertex) => total.add(panoPositionToVector3(vertex).normalize()),
|
|
15048
|
-
new
|
|
15200
|
+
new Vector320()
|
|
15049
15201
|
);
|
|
15050
15202
|
return sum.lengthSq() > 1e-8 ? vector3ToPanoPosition(sum) : normalizePanoPosition(vertices[0]);
|
|
15051
15203
|
}
|
|
15052
15204
|
function surfaceQuaternion2(position) {
|
|
15053
15205
|
const outward = panoPositionToVector3(position).normalize();
|
|
15054
15206
|
const inward = outward.clone().negate();
|
|
15055
|
-
const pitch =
|
|
15056
|
-
const yaw =
|
|
15057
|
-
const localUp = new
|
|
15207
|
+
const pitch = MathUtils12.degToRad(position.pitch);
|
|
15208
|
+
const yaw = MathUtils12.degToRad(position.yaw);
|
|
15209
|
+
const localUp = new Vector320(
|
|
15058
15210
|
-Math.sin(pitch) * Math.sin(yaw),
|
|
15059
15211
|
Math.cos(pitch),
|
|
15060
15212
|
Math.sin(pitch) * Math.cos(yaw)
|
|
15061
15213
|
).normalize();
|
|
15062
|
-
return new
|
|
15214
|
+
return new Quaternion6().setFromRotationMatrix(
|
|
15063
15215
|
new Matrix46().makeBasis(localUp.clone().cross(inward).normalize(), localUp, inward)
|
|
15064
15216
|
);
|
|
15065
15217
|
}
|
|
@@ -15067,7 +15219,7 @@ function makeWorldToLocal2(center) {
|
|
|
15067
15219
|
return new Matrix46().compose(
|
|
15068
15220
|
panoPositionToVector3(center, POLYLINE_RADIUS),
|
|
15069
15221
|
surfaceQuaternion2(center),
|
|
15070
|
-
new
|
|
15222
|
+
new Vector320(1, 1, 1)
|
|
15071
15223
|
).invert();
|
|
15072
15224
|
}
|
|
15073
15225
|
function subdivisionSteps(vertices) {
|
|
@@ -15082,7 +15234,7 @@ function subdivisionSteps(vertices) {
|
|
|
15082
15234
|
}
|
|
15083
15235
|
return Math.min(
|
|
15084
15236
|
8,
|
|
15085
|
-
Math.max(1, Math.ceil(
|
|
15237
|
+
Math.max(1, Math.ceil(MathUtils12.radToDeg(maxAngle) / MAX_SEGMENT_DEGREES))
|
|
15086
15238
|
);
|
|
15087
15239
|
}
|
|
15088
15240
|
function makeLinePositions(vertices, center) {
|
|
@@ -15855,65 +16007,7 @@ import {
|
|
|
15855
16007
|
useRef as useRef35,
|
|
15856
16008
|
useState as useState22
|
|
15857
16009
|
} from "react";
|
|
15858
|
-
|
|
15859
|
-
// src/gyro-orientation.ts
|
|
15860
|
-
import { Euler as Euler4, MathUtils as MathUtils12, Quaternion as Quaternion6, Vector3 as Vector320 } from "three";
|
|
15861
|
-
var DEVICE_FORWARD_CORRECTION = new Quaternion6().setFromAxisAngle(
|
|
15862
|
-
new Vector320(1, 0, 0),
|
|
15863
|
-
-Math.PI / 2
|
|
15864
|
-
);
|
|
15865
|
-
var SCREEN_AXIS = new Vector320(0, 0, 1);
|
|
15866
|
-
function getScreenOrientationAngle() {
|
|
15867
|
-
if (typeof window === "undefined") {
|
|
15868
|
-
return 0;
|
|
15869
|
-
}
|
|
15870
|
-
const angle = window.screen.orientation?.angle;
|
|
15871
|
-
if (Number.isFinite(angle)) {
|
|
15872
|
-
return angle;
|
|
15873
|
-
}
|
|
15874
|
-
const legacyAngle = window.orientation;
|
|
15875
|
-
return Number.isFinite(legacyAngle) ? legacyAngle : 0;
|
|
15876
|
-
}
|
|
15877
|
-
function deviceOrientationToQuaternion(sample, screenOrientation) {
|
|
15878
|
-
const alpha = Number.isFinite(sample.compassHeading) ? 360 - sample.compassHeading : sample.alpha;
|
|
15879
|
-
const deviceEuler = new Euler4(
|
|
15880
|
-
MathUtils12.degToRad(sample.beta),
|
|
15881
|
-
MathUtils12.degToRad(alpha),
|
|
15882
|
-
MathUtils12.degToRad(-sample.gamma),
|
|
15883
|
-
"YXZ"
|
|
15884
|
-
);
|
|
15885
|
-
const screenCorrection = new Quaternion6().setFromAxisAngle(
|
|
15886
|
-
SCREEN_AXIS,
|
|
15887
|
-
-MathUtils12.degToRad(screenOrientation)
|
|
15888
|
-
);
|
|
15889
|
-
return new Quaternion6().setFromEuler(deviceEuler).multiply(DEVICE_FORWARD_CORRECTION).multiply(screenCorrection).normalize();
|
|
15890
|
-
}
|
|
15891
|
-
function quaternionToGyroPose(quaternion) {
|
|
15892
|
-
const euler = new Euler4().setFromQuaternion(quaternion, "YXZ");
|
|
15893
|
-
return {
|
|
15894
|
-
yaw: MathUtils12.radToDeg(-euler.y),
|
|
15895
|
-
pitch: MathUtils12.radToDeg(euler.x),
|
|
15896
|
-
roll: MathUtils12.radToDeg(euler.z)
|
|
15897
|
-
};
|
|
15898
|
-
}
|
|
15899
|
-
function createRelativeCalibration(deviceQuaternion, yaw, pitch) {
|
|
15900
|
-
const targetQuaternion = new Quaternion6().setFromEuler(
|
|
15901
|
-
new Euler4(
|
|
15902
|
-
MathUtils12.degToRad(pitch),
|
|
15903
|
-
MathUtils12.degToRad(-yaw),
|
|
15904
|
-
0,
|
|
15905
|
-
"YXZ"
|
|
15906
|
-
)
|
|
15907
|
-
);
|
|
15908
|
-
return targetQuaternion.multiply(deviceQuaternion.clone().invert()).normalize();
|
|
15909
|
-
}
|
|
15910
|
-
function applyGyroCalibration(deviceQuaternion, calibration) {
|
|
15911
|
-
return quaternionToGyroPose(
|
|
15912
|
-
calibration.clone().multiply(deviceQuaternion).normalize()
|
|
15913
|
-
);
|
|
15914
|
-
}
|
|
15915
|
-
|
|
15916
|
-
// src/gyro.tsx
|
|
16010
|
+
import { Quaternion as Quaternion7 } from "three";
|
|
15917
16011
|
var deviceOrientationPermissionState = "unknown";
|
|
15918
16012
|
function isMobileDevice() {
|
|
15919
16013
|
if (typeof navigator === "undefined") {
|
|
@@ -15921,12 +16015,6 @@ function isMobileDevice() {
|
|
|
15921
16015
|
}
|
|
15922
16016
|
return /Android|iPad|iPhone|iPod|Mobile/i.test(navigator.userAgent) || navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1;
|
|
15923
16017
|
}
|
|
15924
|
-
function normalizeYaw2(value) {
|
|
15925
|
-
return ((value + 180) % 360 + 360) % 360 - 180;
|
|
15926
|
-
}
|
|
15927
|
-
function shortestYawDelta2(from, to) {
|
|
15928
|
-
return normalizeYaw2(to - from);
|
|
15929
|
-
}
|
|
15930
16018
|
function finiteOr(value, fallback) {
|
|
15931
16019
|
return Number.isFinite(value) ? value : fallback;
|
|
15932
16020
|
}
|
|
@@ -15936,9 +16024,6 @@ function resolveFriction(value) {
|
|
|
15936
16024
|
function resolveSoftstart(value) {
|
|
15937
16025
|
return Math.max(finiteOr(value, 0.5), 0);
|
|
15938
16026
|
}
|
|
15939
|
-
function posesNearlyEqual(a, b) {
|
|
15940
|
-
return Math.abs(shortestYawDelta2(a.yaw, b.yaw)) < 1e-4 && Math.abs(a.pitch - b.pitch) < 1e-4 && Math.abs(a.roll - b.roll) < 1e-4;
|
|
15941
|
-
}
|
|
15942
16027
|
var Gyro = forwardRef3(function Gyro2({
|
|
15943
16028
|
enabled = false,
|
|
15944
16029
|
camroll = true,
|
|
@@ -15958,19 +16043,30 @@ var Gyro = forwardRef3(function Gyro2({
|
|
|
15958
16043
|
const eventBus = useContext25(PanoEventBusContext);
|
|
15959
16044
|
const { gl } = useThree25();
|
|
15960
16045
|
const [internallyDisabled, setInternallyDisabled] = useState22(false);
|
|
16046
|
+
const [available, setAvailableState] = useState22(false);
|
|
15961
16047
|
const availableRef = useRef35(false);
|
|
15962
16048
|
const availabilityReportedRef = useRef35(null);
|
|
15963
16049
|
const activeRef = useRef35(false);
|
|
15964
16050
|
const permissionRef = useRef35(deviceOrientationPermissionState);
|
|
15965
16051
|
const absoluteEventSourceRef = useRef35(null);
|
|
15966
|
-
const rawQuaternionRef = useRef35(
|
|
15967
|
-
const
|
|
16052
|
+
const rawQuaternionRef = useRef35(new Quaternion7());
|
|
16053
|
+
const hasRawQuaternionRef = useRef35(false);
|
|
16054
|
+
const calibrationRef = useRef35(new Quaternion7());
|
|
16055
|
+
const hasCalibrationRef = useRef35(false);
|
|
16056
|
+
const calibratedQuaternionRef = useRef35(new Quaternion7());
|
|
15968
16057
|
const absoluteOffsetRef = useRef35({ yaw: 0, pitch: 0 });
|
|
15969
16058
|
const screenAngleRef = useRef35(getScreenOrientationAngle());
|
|
15970
16059
|
const startPoseRef = useRef35(null);
|
|
15971
16060
|
const enabledAtRef = useRef35(0);
|
|
15972
16061
|
const filteredPoseRef = useRef35(null);
|
|
15973
16062
|
const lastAppliedPoseRef = useRef35(null);
|
|
16063
|
+
const lastSamplePoseRef = useRef35(null);
|
|
16064
|
+
const lastSampleAtRef = useRef35(null);
|
|
16065
|
+
const previousYawRef = useRef35(void 0);
|
|
16066
|
+
const absoluteRef = useRef35(absolute);
|
|
16067
|
+
const northRef = useRef35(north);
|
|
16068
|
+
absoluteRef.current = absolute;
|
|
16069
|
+
northRef.current = north;
|
|
15974
16070
|
const callbacksRef = useRef35({
|
|
15975
16071
|
onAvailable,
|
|
15976
16072
|
onUnavailable,
|
|
@@ -16016,13 +16112,14 @@ var Gyro = forwardRef3(function Gyro2({
|
|
|
16016
16112
|
[eventBus]
|
|
16017
16113
|
);
|
|
16018
16114
|
const setAvailable = useCallback9(
|
|
16019
|
-
(
|
|
16020
|
-
availableRef.current =
|
|
16021
|
-
|
|
16115
|
+
(nextAvailable) => {
|
|
16116
|
+
availableRef.current = nextAvailable;
|
|
16117
|
+
setAvailableState(nextAvailable);
|
|
16118
|
+
if (availabilityReportedRef.current === nextAvailable) {
|
|
16022
16119
|
return;
|
|
16023
16120
|
}
|
|
16024
|
-
availabilityReportedRef.current =
|
|
16025
|
-
emit(
|
|
16121
|
+
availabilityReportedRef.current = nextAvailable;
|
|
16122
|
+
emit(nextAvailable ? "gyroavailable" : "gyrounavailable");
|
|
16026
16123
|
},
|
|
16027
16124
|
[emit]
|
|
16028
16125
|
);
|
|
@@ -16065,37 +16162,54 @@ var Gyro = forwardRef3(function Gyro2({
|
|
|
16065
16162
|
controlsRef.current?.setGyroActive(false);
|
|
16066
16163
|
emit("gyrodisable");
|
|
16067
16164
|
}
|
|
16068
|
-
|
|
16165
|
+
hasRawQuaternionRef.current = false;
|
|
16069
16166
|
absoluteEventSourceRef.current = null;
|
|
16070
|
-
|
|
16167
|
+
hasCalibrationRef.current = false;
|
|
16071
16168
|
filteredPoseRef.current = null;
|
|
16072
16169
|
lastAppliedPoseRef.current = null;
|
|
16170
|
+
lastSamplePoseRef.current = null;
|
|
16171
|
+
lastSampleAtRef.current = null;
|
|
16172
|
+
previousYawRef.current = void 0;
|
|
16073
16173
|
}, [controlsRef, emit]);
|
|
16074
|
-
const
|
|
16174
|
+
const anchorToView = useCallback9(
|
|
16075
16175
|
(yaw, pitch) => {
|
|
16076
|
-
|
|
16077
|
-
if (!rawQuaternion) {
|
|
16176
|
+
if (!hasRawQuaternionRef.current) {
|
|
16078
16177
|
return;
|
|
16079
16178
|
}
|
|
16080
|
-
|
|
16081
|
-
|
|
16082
|
-
|
|
16083
|
-
|
|
16084
|
-
|
|
16179
|
+
if (absoluteRef.current) {
|
|
16180
|
+
const rawPose = quaternionToGyroPose(
|
|
16181
|
+
rawQuaternionRef.current,
|
|
16182
|
+
previousYawRef.current
|
|
16183
|
+
);
|
|
16184
|
+
previousYawRef.current = rawPose.yaw;
|
|
16085
16185
|
absoluteOffsetRef.current = {
|
|
16086
|
-
yaw:
|
|
16087
|
-
rawPose.yaw + finiteOr(
|
|
16088
|
-
|
|
16186
|
+
yaw: shortestGyroYawDelta(
|
|
16187
|
+
rawPose.yaw + finiteOr(northRef.current, 0),
|
|
16188
|
+
yaw
|
|
16089
16189
|
),
|
|
16090
|
-
pitch:
|
|
16190
|
+
pitch: pitch - rawPose.pitch
|
|
16091
16191
|
};
|
|
16092
16192
|
} else {
|
|
16093
|
-
|
|
16094
|
-
|
|
16095
|
-
|
|
16096
|
-
|
|
16193
|
+
createRelativeCalibration(
|
|
16194
|
+
rawQuaternionRef.current,
|
|
16195
|
+
yaw,
|
|
16196
|
+
pitch,
|
|
16197
|
+
calibrationRef.current
|
|
16097
16198
|
);
|
|
16199
|
+
hasCalibrationRef.current = true;
|
|
16098
16200
|
}
|
|
16201
|
+
},
|
|
16202
|
+
[]
|
|
16203
|
+
);
|
|
16204
|
+
const resetSensor = useCallback9(
|
|
16205
|
+
(yaw, pitch) => {
|
|
16206
|
+
if (!hasRawQuaternionRef.current) {
|
|
16207
|
+
return;
|
|
16208
|
+
}
|
|
16209
|
+
const view = controlsRef.current?.getTargetView();
|
|
16210
|
+
const targetYaw = finiteOr(yaw, view?.yaw ?? 0);
|
|
16211
|
+
const targetPitch = finiteOr(pitch, view?.pitch ?? 0);
|
|
16212
|
+
anchorToView(targetYaw, targetPitch);
|
|
16099
16213
|
startPoseRef.current = {
|
|
16100
16214
|
yaw: targetYaw,
|
|
16101
16215
|
pitch: targetPitch,
|
|
@@ -16103,8 +16217,10 @@ var Gyro = forwardRef3(function Gyro2({
|
|
|
16103
16217
|
};
|
|
16104
16218
|
enabledAtRef.current = performance.now();
|
|
16105
16219
|
filteredPoseRef.current = null;
|
|
16220
|
+
lastSamplePoseRef.current = null;
|
|
16221
|
+
lastSampleAtRef.current = null;
|
|
16106
16222
|
},
|
|
16107
|
-
[
|
|
16223
|
+
[anchorToView, controlsRef]
|
|
16108
16224
|
);
|
|
16109
16225
|
useImperativeHandle3(
|
|
16110
16226
|
ref,
|
|
@@ -16124,9 +16240,6 @@ var Gyro = forwardRef3(function Gyro2({
|
|
|
16124
16240
|
useEffect35(() => {
|
|
16125
16241
|
const supported = typeof window !== "undefined" && window.isSecureContext && typeof DeviceOrientationEvent !== "undefined" && (desktopSupport || isMobileDevice());
|
|
16126
16242
|
setAvailable(supported);
|
|
16127
|
-
return () => {
|
|
16128
|
-
availableRef.current = false;
|
|
16129
|
-
};
|
|
16130
16243
|
}, [desktopSupport, setAvailable]);
|
|
16131
16244
|
useEffect35(() => {
|
|
16132
16245
|
controlsRef.current?.setGyroTouchMode(touchMode);
|
|
@@ -16146,7 +16259,7 @@ var Gyro = forwardRef3(function Gyro2({
|
|
|
16146
16259
|
};
|
|
16147
16260
|
}, [enabled, gl, internallyDisabled, touchMode]);
|
|
16148
16261
|
useEffect35(() => {
|
|
16149
|
-
if (!enabled || internallyDisabled || !
|
|
16262
|
+
if (!enabled || internallyDisabled || !available) {
|
|
16150
16263
|
deactivate();
|
|
16151
16264
|
return;
|
|
16152
16265
|
}
|
|
@@ -16175,10 +16288,12 @@ var Gyro = forwardRef3(function Gyro2({
|
|
|
16175
16288
|
gamma: event.gamma,
|
|
16176
16289
|
compassHeading: absolute && hasCompassHeading ? compassEvent.webkitCompassHeading : void 0
|
|
16177
16290
|
};
|
|
16178
|
-
|
|
16291
|
+
deviceOrientationToQuaternion(
|
|
16179
16292
|
sample,
|
|
16180
|
-
screenAngleRef.current
|
|
16293
|
+
screenAngleRef.current,
|
|
16294
|
+
rawQuaternionRef.current
|
|
16181
16295
|
);
|
|
16296
|
+
hasRawQuaternionRef.current = true;
|
|
16182
16297
|
if (!activeRef.current) {
|
|
16183
16298
|
const view = controlsRef.current?.getTargetView() ?? {
|
|
16184
16299
|
yaw: 0,
|
|
@@ -16186,11 +16301,13 @@ var Gyro = forwardRef3(function Gyro2({
|
|
|
16186
16301
|
fov: 75
|
|
16187
16302
|
};
|
|
16188
16303
|
if (!absolute) {
|
|
16189
|
-
|
|
16304
|
+
createRelativeCalibration(
|
|
16190
16305
|
rawQuaternionRef.current,
|
|
16191
16306
|
view.yaw,
|
|
16192
|
-
view.pitch
|
|
16307
|
+
view.pitch,
|
|
16308
|
+
calibrationRef.current
|
|
16193
16309
|
);
|
|
16310
|
+
hasCalibrationRef.current = true;
|
|
16194
16311
|
}
|
|
16195
16312
|
absoluteOffsetRef.current = { yaw: 0, pitch: 0 };
|
|
16196
16313
|
startPoseRef.current = { ...view, roll: 0 };
|
|
@@ -16238,6 +16355,7 @@ var Gyro = forwardRef3(function Gyro2({
|
|
|
16238
16355
|
};
|
|
16239
16356
|
}, [
|
|
16240
16357
|
absolute,
|
|
16358
|
+
available,
|
|
16241
16359
|
controlsRef,
|
|
16242
16360
|
deactivate,
|
|
16243
16361
|
emit,
|
|
@@ -16246,28 +16364,84 @@ var Gyro = forwardRef3(function Gyro2({
|
|
|
16246
16364
|
requestPermission
|
|
16247
16365
|
]);
|
|
16248
16366
|
useFrame20((_, deltaSeconds) => {
|
|
16249
|
-
|
|
16250
|
-
if (!activeRef.current || !rawQuaternion) {
|
|
16367
|
+
if (!activeRef.current || !hasRawQuaternionRef.current) {
|
|
16251
16368
|
return;
|
|
16252
16369
|
}
|
|
16253
16370
|
let targetPose;
|
|
16254
16371
|
if (absolute) {
|
|
16255
|
-
const rawPose = quaternionToGyroPose(
|
|
16372
|
+
const rawPose = quaternionToGyroPose(
|
|
16373
|
+
rawQuaternionRef.current,
|
|
16374
|
+
previousYawRef.current
|
|
16375
|
+
);
|
|
16376
|
+
previousYawRef.current = rawPose.yaw;
|
|
16256
16377
|
targetPose = {
|
|
16257
16378
|
yaw: rawPose.yaw + finiteOr(north, 0) + absoluteOffsetRef.current.yaw,
|
|
16258
16379
|
pitch: rawPose.pitch + absoluteOffsetRef.current.pitch,
|
|
16259
16380
|
roll: rawPose.roll
|
|
16260
16381
|
};
|
|
16261
16382
|
} else {
|
|
16262
|
-
|
|
16263
|
-
if (!calibration) {
|
|
16383
|
+
if (!hasCalibrationRef.current) {
|
|
16264
16384
|
return;
|
|
16265
16385
|
}
|
|
16266
|
-
targetPose = applyGyroCalibration(
|
|
16386
|
+
targetPose = applyGyroCalibration(
|
|
16387
|
+
rawQuaternionRef.current,
|
|
16388
|
+
calibrationRef.current,
|
|
16389
|
+
calibratedQuaternionRef.current,
|
|
16390
|
+
previousYawRef.current
|
|
16391
|
+
);
|
|
16392
|
+
previousYawRef.current = targetPose.yaw;
|
|
16267
16393
|
}
|
|
16268
16394
|
if (!camroll) {
|
|
16269
16395
|
targetPose.roll = 0;
|
|
16270
16396
|
}
|
|
16397
|
+
const sampleAt = performance.now();
|
|
16398
|
+
const previousSample = lastSamplePoseRef.current;
|
|
16399
|
+
const previousSampleAt = lastSampleAtRef.current;
|
|
16400
|
+
if (previousSample && previousSampleAt !== null) {
|
|
16401
|
+
const angleDelta = gyroPoseAngleDelta(previousSample, targetPose);
|
|
16402
|
+
const sampleDeltaSeconds = Math.max(
|
|
16403
|
+
(sampleAt - previousSampleAt) / 1e3,
|
|
16404
|
+
deltaSeconds
|
|
16405
|
+
);
|
|
16406
|
+
if (shouldReanchorGyro(angleDelta, sampleDeltaSeconds)) {
|
|
16407
|
+
const view = controlsRef.current?.getTargetView() ?? {
|
|
16408
|
+
yaw: targetPose.yaw,
|
|
16409
|
+
pitch: targetPose.pitch,
|
|
16410
|
+
fov: 75
|
|
16411
|
+
};
|
|
16412
|
+
anchorToView(view.yaw, view.pitch);
|
|
16413
|
+
if (absolute) {
|
|
16414
|
+
const rawPose = quaternionToGyroPose(
|
|
16415
|
+
rawQuaternionRef.current,
|
|
16416
|
+
previousYawRef.current
|
|
16417
|
+
);
|
|
16418
|
+
previousYawRef.current = rawPose.yaw;
|
|
16419
|
+
targetPose = {
|
|
16420
|
+
yaw: rawPose.yaw + finiteOr(north, 0) + absoluteOffsetRef.current.yaw,
|
|
16421
|
+
pitch: rawPose.pitch + absoluteOffsetRef.current.pitch,
|
|
16422
|
+
roll: rawPose.roll
|
|
16423
|
+
};
|
|
16424
|
+
} else {
|
|
16425
|
+
targetPose = applyGyroCalibration(
|
|
16426
|
+
rawQuaternionRef.current,
|
|
16427
|
+
calibrationRef.current,
|
|
16428
|
+
calibratedQuaternionRef.current,
|
|
16429
|
+
previousYawRef.current
|
|
16430
|
+
);
|
|
16431
|
+
previousYawRef.current = targetPose.yaw;
|
|
16432
|
+
}
|
|
16433
|
+
if (!camroll) {
|
|
16434
|
+
targetPose.roll = 0;
|
|
16435
|
+
}
|
|
16436
|
+
filteredPoseRef.current = {
|
|
16437
|
+
yaw: view.yaw,
|
|
16438
|
+
pitch: view.pitch,
|
|
16439
|
+
roll: targetPose.roll
|
|
16440
|
+
};
|
|
16441
|
+
}
|
|
16442
|
+
}
|
|
16443
|
+
lastSamplePoseRef.current = { ...targetPose };
|
|
16444
|
+
lastSampleAtRef.current = sampleAt;
|
|
16271
16445
|
const softstartMs = resolveSoftstart(softstart) * 1e3;
|
|
16272
16446
|
const startPose = startPoseRef.current;
|
|
16273
16447
|
if (startPose && softstartMs > 0) {
|
|
@@ -16276,9 +16450,9 @@ var Gyro = forwardRef3(function Gyro2({
|
|
|
16276
16450
|
1
|
|
16277
16451
|
);
|
|
16278
16452
|
targetPose = {
|
|
16279
|
-
yaw: startPose.yaw +
|
|
16453
|
+
yaw: startPose.yaw + shortestGyroYawDelta(startPose.yaw, targetPose.yaw) * progress,
|
|
16280
16454
|
pitch: startPose.pitch + (targetPose.pitch - startPose.pitch) * progress,
|
|
16281
|
-
roll: startPose.roll +
|
|
16455
|
+
roll: startPose.roll + shortestGyroYawDelta(startPose.roll, targetPose.roll) * progress
|
|
16282
16456
|
};
|
|
16283
16457
|
if (progress === 1) {
|
|
16284
16458
|
startPoseRef.current = null;
|
|
@@ -16288,9 +16462,9 @@ var Gyro = forwardRef3(function Gyro2({
|
|
|
16288
16462
|
const retention = resolveFriction(friction);
|
|
16289
16463
|
const follow = retention === 0 ? 1 : 1 - Math.pow(retention, deltaSeconds * 60);
|
|
16290
16464
|
const filteredPose = previous ? {
|
|
16291
|
-
yaw: previous.yaw +
|
|
16465
|
+
yaw: previous.yaw + shortestGyroYawDelta(previous.yaw, targetPose.yaw) * follow,
|
|
16292
16466
|
pitch: previous.pitch + (targetPose.pitch - previous.pitch) * follow,
|
|
16293
|
-
roll: previous.roll +
|
|
16467
|
+
roll: previous.roll + shortestGyroYawDelta(previous.roll, targetPose.roll) * follow
|
|
16294
16468
|
} : targetPose;
|
|
16295
16469
|
filteredPoseRef.current = filteredPose;
|
|
16296
16470
|
if (controlsRef.current?.isInteractionLocked()) {
|
|
@@ -16301,7 +16475,7 @@ var Gyro = forwardRef3(function Gyro2({
|
|
|
16301
16475
|
lastAppliedPoseRef.current = { ...filteredPose };
|
|
16302
16476
|
controlsRef.current?.setGyroPose(filteredPose);
|
|
16303
16477
|
}
|
|
16304
|
-
});
|
|
16478
|
+
}, -1);
|
|
16305
16479
|
return null;
|
|
16306
16480
|
});
|
|
16307
16481
|
|