mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-06 11:24:00 +00:00
fix(camera): read zoom input at the ceiling when the scene is idle
The guard reads its input in preRender, which Cesium only fires on frames that draw. In request-render mode, wheel input at the ceiling doesn't move the camera, so nothing drew and the input was applied later by an unrelated frame. The guard now requests a frame through the render governor whenever it has unread input.
This commit is contained in:
1 parent
08ff7f3e9d
commit
e4b3933166
2 files changed
+32
-3
No files matched your search
+12
-2
@@ -194,8 +194,18 @@ export function installZoomOutGuard(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
const removePreRender = scene.preRender.addEventListener(guard);
|
const removePreRender = scene.preRender.addEventListener(guard);
|
||||||
// Fires every frame, after Cesium has applied this frame's input.
|
// Fires every frame, after Cesium has applied this frame's input, while
|
||||||
const removePostUpdate = scene.postUpdate.addEventListener(followCeiling);
|
// preRender fires only on frames that draw. Input that didn't move the camera
|
||||||
|
// (such as wheel at the ceiling) would otherwise wait for an unrelated frame.
|
||||||
|
const removePostUpdate = scene.postUpdate.addEventListener(() => {
|
||||||
|
followCeiling();
|
||||||
|
if (
|
||||||
|
INPUT_BINDINGS.some(({ type, modifier }) =>
|
||||||
|
aggregator.isMoving(type, modifier),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
requestRender('zoom-out-guard');
|
||||||
|
});
|
||||||
const removeCameraHandoff = subscribeCameraHandoff?.(() => {
|
const removeCameraHandoff = subscribeCameraHandoff?.(() => {
|
||||||
cancel();
|
cancel();
|
||||||
// Discard input queued before an explicit navigation action took ownership.
|
// Discard input queued before an explicit navigation action took ownership.
|
||||||
|
|||||||
@@ -130,9 +130,13 @@ function guardFixture({ maximumZoomDistance = Infinity } = {}) {
|
|||||||
requestRender: (reason) => renders.push(reason),
|
requestRender: (reason) => renders.push(reason),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
// A frame Cesium skips drawing in request-render mode: no preRender.
|
||||||
|
const idleFrame = () => {
|
||||||
|
for (const handler of postUpdate) handler();
|
||||||
|
};
|
||||||
const frame = (height = camera.height) => {
|
const frame = (height = camera.height) => {
|
||||||
camera.height = height;
|
camera.height = height;
|
||||||
for (const handler of postUpdate) handler();
|
idleFrame();
|
||||||
for (const handler of preRender) handler();
|
for (const handler of preRender) handler();
|
||||||
};
|
};
|
||||||
const movement = (type, deltaY, { modifier, tiltDeltaY = 0 } = {}) => {
|
const movement = (type, deltaY, { modifier, tiltDeltaY = 0 } = {}) => {
|
||||||
@@ -179,6 +183,7 @@ function guardFixture({ maximumZoomDistance = Infinity } = {}) {
|
|||||||
renders,
|
renders,
|
||||||
dispose,
|
dispose,
|
||||||
frame,
|
frame,
|
||||||
|
idleFrame,
|
||||||
movement,
|
movement,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -454,6 +459,20 @@ test('outward input at the ceiling reframes a deliberately tilted camera', () =>
|
|||||||
f.dispose();
|
f.dispose();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('input that leaves the camera still requests a frame to read it', () => {
|
||||||
|
const f = guardFixture();
|
||||||
|
f.frame(MAXIMUM_ZOOM_DISTANCE_M);
|
||||||
|
f.idleFrame();
|
||||||
|
assert.deepEqual(f.renders, [], 'an idle scene stays idle');
|
||||||
|
// At the ceiling Cesium doesn't move the camera, so nothing would draw.
|
||||||
|
f.movement(WHEEL, -10);
|
||||||
|
f.idleFrame();
|
||||||
|
assert.deepEqual(f.renders, ['zoom-out-guard']);
|
||||||
|
f.frame();
|
||||||
|
assert.ok(f.camera.pitch < Cesium.Math.toRadians(-25), 'read that frame');
|
||||||
|
f.dispose();
|
||||||
|
});
|
||||||
|
|
||||||
test('equivalent heading and roll wraps do not cancel stationary settling', () => {
|
test('equivalent heading and roll wraps do not cancel stationary settling', () => {
|
||||||
const f = guardFixture();
|
const f = guardFixture();
|
||||||
f.frame(500_000);
|
f.frame(500_000);
|
||||||
|
|||||||
Reference in new issue
Block a user