From 275219a777b37dd340eae9ae8c6d926f44ef0dcd Mon Sep 17 00:00:00 2001 From: Adam Beili Date: Fri, 10 Oct 2025 23:33:30 +0300 Subject: [PATCH] Add ScreenSpaceCameraController.collisionHeightReference --- packages/engine/Source/Scene/Scene.js | 18 ++++++++-- .../Scene/ScreenSpaceCameraController.js | 34 +++++++++++++++---- 2 files changed, 44 insertions(+), 8 deletions(-) diff --git a/packages/engine/Source/Scene/Scene.js b/packages/engine/Source/Scene/Scene.js index 16149ca8b23a..690d61e8ddb1 100644 --- a/packages/engine/Source/Scene/Scene.js +++ b/packages/engine/Source/Scene/Scene.js @@ -3831,12 +3831,26 @@ function callAfterRenderFunctions(scene) { functions.length = 0; } +/** + * Calculate the height of the globe at the camera position based on the value of {@link ScreenSpaceCameraController.collisionHeightReference}, + * or undefined if the height cannot be determined. + * + * @param {Scene} scene + * @returns {number|undefined} + */ function getGlobeHeight(scene) { - if (scene.mode === SceneMode.MORPHING) { + if ( + scene.mode === SceneMode.MORPHING || + scene._screenSpaceCameraController.collisionHeightReference === + HeightReference.NONE + ) { return; } const cartographic = scene.camera.positionCartographic; - return scene.getHeight(cartographic); + return scene.getHeight( + cartographic, + scene._screenSpaceCameraController.collisionHeightReference, + ); } function getMaxPrimitiveHeight(primitive, cartographic, scene) { diff --git a/packages/engine/Source/Scene/ScreenSpaceCameraController.js b/packages/engine/Source/Scene/ScreenSpaceCameraController.js index d4864da3e041..0e3e693f45a8 100644 --- a/packages/engine/Source/Scene/ScreenSpaceCameraController.js +++ b/packages/engine/Source/Scene/ScreenSpaceCameraController.js @@ -24,6 +24,7 @@ import MapMode2D from "./MapMode2D.js"; import SceneMode from "./SceneMode.js"; import SceneTransforms from "./SceneTransforms.js"; import TweenCollection from "./TweenCollection.js"; +import HeightReference from "./HeightReference.js"; /** * Modifies the camera position and orientation based on mouse input to a canvas. @@ -265,13 +266,13 @@ function ScreenSpaceCameraController(scene) { : ellipsoid.minimumRadius * 1.175; this._minimumTrackBallHeight = this.minimumTrackBallHeight; /** - * When disabled, the values of maximumZoomDistance and minimumZoomDistance are ignored. - * Also used in conjunction with {@link Cesium3DTileset#enableCollision} to prevent the camera from moving through or below a 3D Tileset surface. - * This may also affect clamping behavior when using {@link HeightReference.CLAMP_TO_GROUND} on 3D Tiles. - * @type {boolean} - * @default true + * This value controls the height reference for the {@link ScreenSpaceCameraController} collision, which is used to limit the camera minimum and maximum zoom. + * When set to {@link HeightReference.NONE}, the camera can go underground, and the values of maximumZoomDistance and minimumZoomDistance are ignored. + * For all other values, the camera is constrained to be above the terrain and/or 3D Tiles (depending on {@link Cesium3DTileset#enableCollision}). + * @type {HeightReference} + * @default HeightReference.CLAMP_TO_GROUND */ - this.enableCollisionDetection = true; + this.collisionHeightReference = HeightReference.CLAMP_TO_GROUND; /** * The angle, relative to the ellipsoid normal, restricting the maximum amount that the user can tilt the camera. If undefined, the angle of the camera tilt is unrestricted. * @type {number|undefined} @@ -353,6 +354,27 @@ function ScreenSpaceCameraController(scene) { this._maximumUndergroundPickDistance = 10000.0; } +Object.defineProperties(ScreenSpaceCameraController.prototype, { + /** + * When disabled, the values of maximumZoomDistance and minimumZoomDistance are ignored. + * Also used in conjunction with {@link Cesium3DTileset#enableCollision} to prevent the camera from moving through or below a 3D Tileset surface. + * This may also affect clamping behavior when using {@link HeightReference.CLAMP_TO_GROUND} on 3D Tiles. + * @type {boolean} + * @default true + * @deprecated Use {@link ScreenSpaceCameraController#collisionHeightReference} instead. + */ + enableCollisionDetection: { + get: function () { + return this.collisionHeightReference !== HeightReference.NONE; + }, + set: function (value) { + this.collisionHeightReference = value + ? HeightReference.CLAMP_TO_GROUND + : HeightReference.NONE; + }, + }, +}); + function decay(time, coefficient) { if (time < 0) { return 0.0;