mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 02:14:01 +00:00
fix(camera): keep the zoom ceiling fixed while tracking a target
While the camera tracks an entity or looks at a point, Cesium measures zoom distance from the target, not the Earth. Raising the ceiling to the camera's altitude then lifted it with every outward step, so a tracked camera could zoom out without limit. The guard now follows the altitude only for an untracked 3D camera and otherwise keeps its 40,000 km ceiling.
This commit is contained in:
1 parent
9e3786716d
commit
cc3d61a960
2 files changed
+27
-1
No files matched your search
@@ -111,7 +111,12 @@ export function installZoomOutGuard(
|
||||
const followCeiling = () => {
|
||||
if (!ownsCeiling || controller.maximumZoomDistance !== maximumZoomDistance)
|
||||
return;
|
||||
const height = camera.positionCartographic?.height;
|
||||
// While tracking, Cesium measures zoom from the target, not the Earth, so
|
||||
// the camera's altitude would lift the ceiling with every outward step.
|
||||
const untracked =
|
||||
scene.mode === Cesium.SceneMode.SCENE3D &&
|
||||
Cesium.Matrix4.equals(camera.transform, Cesium.Matrix4.IDENTITY);
|
||||
const height = untracked ? camera.positionCartographic?.height : undefined;
|
||||
maximumZoomDistance =
|
||||
height > MAXIMUM_ZOOM_DISTANCE_M ? height : MAXIMUM_ZOOM_DISTANCE_M;
|
||||
controller.maximumZoomDistance = maximumZoomDistance;
|
||||
|
||||
@@ -741,3 +741,24 @@ test('a share-link view restored above the ceiling is honoured by later frames',
|
||||
s.dispose();
|
||||
}
|
||||
});
|
||||
|
||||
test('a tracked camera cannot climb past the ceiling from its target', () => {
|
||||
const s = realControllerScene(1_000_000);
|
||||
try {
|
||||
s.frame();
|
||||
// In look-at mode Cesium measures zoom from the target, not the Earth.
|
||||
s.camera.lookAt(
|
||||
Cesium.Cartesian3.fromDegrees(0, 0, 35_786_000),
|
||||
new Cesium.HeadingPitchRange(0, -0.5, 5_000_000),
|
||||
);
|
||||
for (let i = 0; i < 20; i++) {
|
||||
s.wheel(100);
|
||||
s.frame();
|
||||
}
|
||||
const range = Cesium.Cartesian3.magnitude(s.camera.position);
|
||||
assert.ok(range <= MAXIMUM_ZOOM_DISTANCE_M + 1_000, `${range} m`);
|
||||
assert.equal(s.controller.maximumZoomDistance, MAXIMUM_ZOOM_DISTANCE_M);
|
||||
} finally {
|
||||
s.dispose();
|
||||
}
|
||||
});
|
||||
Reference in new issue
Block a user