mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 02:14:01 +00:00
fix(camera): let a two-finger tilt win over finger-spacing drift
Above 300 km the guard treated any shrinking pinch distance as an outward zoom, so a two-finger tilt whose fingers drifted slightly closer had its pitch overwritten. A two-finger gesture now counts as a zoom only when the spacing changes more than the fingers' midpoint moves.
This commit is contained in:
1 parent
e4b3933166
commit
b817d5802b
3 files changed
+44
-5
No files matched your search
@@ -54,8 +54,10 @@ Above 300 km, outward movement from the controller's configured zoom bindings
|
||||
down towards 8° below the Earth's limb. Large steps reach the limb immediately;
|
||||
the remaining margin eases into place, including after zooming stops or reaches
|
||||
the ceiling. Continuous outward inertia remains guarded without a time cutoff.
|
||||
Parallel two-finger tilts, modifier-specific tilts and other camera gestures
|
||||
cancel the correction. Explicit navigation handoffs, including toolbar tilt,
|
||||
Two-finger tilts, modifier-specific tilts and other camera gestures cancel the
|
||||
correction. A two-finger gesture counts as a pinch zoom only while the finger
|
||||
spacing changes more than the fingers move up or down, so spacing drift during
|
||||
a tilt is ignored. Explicit navigation handoffs, including toolbar tilt,
|
||||
cancel it before animation begins. Zooming in, disabled zoom/input, non-3D modes, tracked
|
||||
transforms and flights also cancel it; external pose changes cancel stationary
|
||||
settling. Oblique views below 300 km are left alone.
|
||||
|
||||
+13
-3
@@ -47,10 +47,20 @@ function readInput(aggregator, bindings) {
|
||||
for (const { type, modifier } of INPUT_BINDINGS) {
|
||||
if (!aggregator.isMoving(type, modifier)) continue;
|
||||
const movement = aggregator.getMovement(type, modifier);
|
||||
const distance =
|
||||
type === Cesium.CameraEventType.PINCH ? movement.distance : movement;
|
||||
const pinch = type === Cesium.CameraEventType.PINCH;
|
||||
const distance = pinch ? movement.distance : movement;
|
||||
const delta = distance.endPosition.y - distance.startPosition.y;
|
||||
if (matchesZoomBinding(bindings, type, modifier) && delta !== 0) {
|
||||
// Cesium tilts by the fingers' midpoint while zooming by their spacing,
|
||||
// both in the same quarter-pixel units. Fingers rarely keep a perfectly
|
||||
// even spacing, so the larger of the two movements decides the gesture.
|
||||
const tilt = pinch
|
||||
? movement.angleAndHeight.endPosition.y -
|
||||
movement.angleAndHeight.startPosition.y
|
||||
: 0;
|
||||
if (
|
||||
matchesZoomBinding(bindings, type, modifier) &&
|
||||
Math.abs(delta) > Math.abs(tilt)
|
||||
) {
|
||||
outward ||= delta < 0;
|
||||
cancel ||= delta > 0;
|
||||
} else {
|
||||
|
||||
@@ -245,6 +245,33 @@ test('parallel two-finger tilt is not mistaken for pinch zoom', () => {
|
||||
assert.equal(f.camera.views.length, 0);
|
||||
});
|
||||
|
||||
test('two-finger tilt with finger-spacing drift is left to Cesium', () => {
|
||||
for (const [spacing, tilt] of [
|
||||
[-0.01, 3],
|
||||
[-2, 3],
|
||||
[-3, -3],
|
||||
]) {
|
||||
const f = guardFixture();
|
||||
f.frame(500_000);
|
||||
f.movement(PINCH, spacing, { tiltDeltaY: tilt });
|
||||
// Real Cesium's two-finger tilt climbs and picks its own pitch.
|
||||
f.camera.pitch = Cesium.Math.toRadians(-26.07746);
|
||||
f.frame(529_406);
|
||||
assert.equal(f.camera.views.length, 0, `${spacing}, ${tilt}`);
|
||||
f.dispose();
|
||||
}
|
||||
});
|
||||
|
||||
test('a pinch that closes the fingers more than it moves them still zooms out', () => {
|
||||
// One finger still, the other sliding towards it: the midpoint moves half as far.
|
||||
const f = guardFixture();
|
||||
f.frame(500_000);
|
||||
f.movement(PINCH, -10, { tiltDeltaY: -5 });
|
||||
f.frame(700_000);
|
||||
assert.equal(f.camera.views.length, 1);
|
||||
f.dispose();
|
||||
});
|
||||
|
||||
test('unconfigured wheel modifiers and one-finger drag do not enable the guard', () => {
|
||||
for (const [type, modifier] of [[WHEEL, SHIFT], [WHEEL, ALT], [LEFT_DRAG]]) {
|
||||
const f = guardFixture();
|
||||
|
||||
Reference in new issue
Block a user