From bbb54f68c25b7b6fa9e103cb2ecebf4e7a54ffd2 Mon Sep 17 00:00:00 2001 From: Bao Date: Sun, 30 Aug 2020 02:25:04 -0400 Subject: [PATCH 1/4] make sure the camera points toward the earth when zooming --- Source/Scene/ScreenSpaceCameraController.js | 283 ++++++++++---------- 1 file changed, 143 insertions(+), 140 deletions(-) diff --git a/Source/Scene/ScreenSpaceCameraController.js b/Source/Scene/ScreenSpaceCameraController.js index 9866dde783a2..e264833ab57c 100644 --- a/Source/Scene/ScreenSpaceCameraController.js +++ b/Source/Scene/ScreenSpaceCameraController.js @@ -705,161 +705,166 @@ function handleZoom( ); // If centerPosition is not defined, it means the globe does not cover the center position of screen - if ( - defined(centerPosition) && - camera.positionCartographic.height < 1000000 - ) { - var cameraPosition = scratchCameraPosition; - Cartesian3.clone(camera.position, cameraPosition); - var target = object._zoomWorldPosition; - - var targetNormal = scratchTargetNormal; - - targetNormal = Cartesian3.normalize(target, targetNormal); - - if (Cartesian3.dot(targetNormal, cameraPositionNormal) < 0.0) { - return; - } + if (!defined(centerPosition)) { + zoomOnVector = true; + } else if (camera.positionCartographic.height < 1000000) { + // The math in the else block assumes the camera + // points toward the earth surface, so we check it here + if (Cartesian3.dot(camera.direction, cameraPositionNormal) >= -0.5) { + zoomOnVector = true; + } else { + var cameraPosition = scratchCameraPosition; + Cartesian3.clone(camera.position, cameraPosition); + var target = object._zoomWorldPosition; + + var targetNormal = scratchTargetNormal; + + targetNormal = Cartesian3.normalize(target, targetNormal); + + if (Cartesian3.dot(targetNormal, cameraPositionNormal) < 0.0) { + return; + } + + var center = scratchCenter; + var forward = scratchForwardNormal; + Cartesian3.clone(camera.direction, forward); + Cartesian3.add( + cameraPosition, + Cartesian3.multiplyByScalar(forward, 1000, scratchCartesian), + center + ); - var center = scratchCenter; - var forward = scratchForwardNormal; - Cartesian3.clone(camera.direction, forward); - Cartesian3.add( - cameraPosition, - Cartesian3.multiplyByScalar(forward, 1000, scratchCartesian), - center - ); + var positionToTarget = scratchPositionToTarget; + var positionToTargetNormal = scratchPositionToTargetNormal; + Cartesian3.subtract(target, cameraPosition, positionToTarget); - var positionToTarget = scratchPositionToTarget; - var positionToTargetNormal = scratchPositionToTargetNormal; - Cartesian3.subtract(target, cameraPosition, positionToTarget); + Cartesian3.normalize(positionToTarget, positionToTargetNormal); - Cartesian3.normalize(positionToTarget, positionToTargetNormal); + var alphaDot = Cartesian3.dot( + cameraPositionNormal, + positionToTargetNormal + ); + if (alphaDot >= 0.0) { + // We zoomed past the target, and this zoom is not valid anymore. + // This line causes the next zoom movement to pick a new starting point. + object._zoomMouseStart.x = -1; + return; + } + var alpha = Math.acos(-alphaDot); + var cameraDistance = Cartesian3.magnitude(cameraPosition); + var targetDistance = Cartesian3.magnitude(target); + var remainingDistance = cameraDistance - distance; + var positionToTargetDistance = Cartesian3.magnitude( + positionToTarget + ); - var alphaDot = Cartesian3.dot( - cameraPositionNormal, - positionToTargetNormal - ); - if (alphaDot >= 0.0) { - // We zoomed past the target, and this zoom is not valid anymore. - // This line causes the next zoom movement to pick a new starting point. - object._zoomMouseStart.x = -1; - return; - } - var alpha = Math.acos(-alphaDot); - var cameraDistance = Cartesian3.magnitude(cameraPosition); - var targetDistance = Cartesian3.magnitude(target); - var remainingDistance = cameraDistance - distance; - var positionToTargetDistance = Cartesian3.magnitude(positionToTarget); - - var gamma = Math.asin( - CesiumMath.clamp( - (positionToTargetDistance / targetDistance) * Math.sin(alpha), - -1.0, - 1.0 - ) - ); - var delta = Math.asin( - CesiumMath.clamp( - (remainingDistance / targetDistance) * Math.sin(alpha), - -1.0, - 1.0 - ) - ); - var beta = gamma - delta + alpha; + var gamma = Math.asin( + CesiumMath.clamp( + (positionToTargetDistance / targetDistance) * Math.sin(alpha), + -1.0, + 1.0 + ) + ); + var delta = Math.asin( + CesiumMath.clamp( + (remainingDistance / targetDistance) * Math.sin(alpha), + -1.0, + 1.0 + ) + ); + var beta = gamma - delta + alpha; - var up = scratchCameraUpNormal; - Cartesian3.normalize(cameraPosition, up); - var right = scratchCameraRightNormal; - right = Cartesian3.cross(positionToTargetNormal, up, right); - right = Cartesian3.normalize(right, right); + var up = scratchCameraUpNormal; + Cartesian3.normalize(cameraPosition, up); + var right = scratchCameraRightNormal; + right = Cartesian3.cross(positionToTargetNormal, up, right); + right = Cartesian3.normalize(right, right); - Cartesian3.normalize( - Cartesian3.cross(up, right, scratchCartesian), - forward - ); + Cartesian3.normalize( + Cartesian3.cross(up, right, scratchCartesian), + forward + ); - // Calculate new position to move to - Cartesian3.multiplyByScalar( - Cartesian3.normalize(center, scratchCartesian), - Cartesian3.magnitude(center) - distance, - center - ); - Cartesian3.normalize(cameraPosition, cameraPosition); - Cartesian3.multiplyByScalar( - cameraPosition, - remainingDistance, - cameraPosition - ); + // Calculate new position to move to + Cartesian3.multiplyByScalar( + Cartesian3.normalize(center, scratchCartesian), + Cartesian3.magnitude(center) - distance, + center + ); + Cartesian3.normalize(cameraPosition, cameraPosition); + Cartesian3.multiplyByScalar( + cameraPosition, + remainingDistance, + cameraPosition + ); - // Pan - var pMid = scratchPan; - Cartesian3.multiplyByScalar( - Cartesian3.add( - Cartesian3.multiplyByScalar( - up, - Math.cos(beta) - 1, - scratchCartesianTwo - ), - Cartesian3.multiplyByScalar( - forward, - Math.sin(beta), - scratchCartesianThree + // Pan + var pMid = scratchPan; + Cartesian3.multiplyByScalar( + Cartesian3.add( + Cartesian3.multiplyByScalar( + up, + Math.cos(beta) - 1, + scratchCartesianTwo + ), + Cartesian3.multiplyByScalar( + forward, + Math.sin(beta), + scratchCartesianThree + ), + scratchCartesian ), - scratchCartesian - ), - remainingDistance, - pMid - ); - Cartesian3.add(cameraPosition, pMid, cameraPosition); + remainingDistance, + pMid + ); + Cartesian3.add(cameraPosition, pMid, cameraPosition); - Cartesian3.normalize(center, up); - Cartesian3.normalize( - Cartesian3.cross(up, right, scratchCartesian), - forward - ); + Cartesian3.normalize(center, up); + Cartesian3.normalize( + Cartesian3.cross(up, right, scratchCartesian), + forward + ); - var cMid = scratchCenterMovement; - Cartesian3.multiplyByScalar( - Cartesian3.add( - Cartesian3.multiplyByScalar( - up, - Math.cos(beta) - 1, - scratchCartesianTwo - ), - Cartesian3.multiplyByScalar( - forward, - Math.sin(beta), - scratchCartesianThree + var cMid = scratchCenterMovement; + Cartesian3.multiplyByScalar( + Cartesian3.add( + Cartesian3.multiplyByScalar( + up, + Math.cos(beta) - 1, + scratchCartesianTwo + ), + Cartesian3.multiplyByScalar( + forward, + Math.sin(beta), + scratchCartesianThree + ), + scratchCartesian ), - scratchCartesian - ), - Cartesian3.magnitude(center), - cMid - ); - Cartesian3.add(center, cMid, center); - - // Update camera + Cartesian3.magnitude(center), + cMid + ); + Cartesian3.add(center, cMid, center); - // Set new position - Cartesian3.clone(cameraPosition, camera.position); + // Update camera - // Set new direction - Cartesian3.normalize( - Cartesian3.subtract(center, cameraPosition, scratchCartesian), - camera.direction - ); - Cartesian3.clone(camera.direction, camera.direction); + // Set new position + Cartesian3.clone(cameraPosition, camera.position); - // Set new right & up vectors - Cartesian3.cross(camera.direction, camera.up, camera.right); - Cartesian3.cross(camera.right, camera.direction, camera.up); + // Set new direction + Cartesian3.normalize( + Cartesian3.subtract(center, cameraPosition, scratchCartesian), + camera.direction + ); + Cartesian3.clone(camera.direction, camera.direction); - camera.setView(scratchZoomViewOptions); - return; - } + // Set new right & up vectors + Cartesian3.cross(camera.direction, camera.up, camera.right); + Cartesian3.cross(camera.right, camera.direction, camera.up); - if (defined(centerPosition)) { + camera.setView(scratchZoomViewOptions); + return; + } + } else { var positionNormal = Cartesian3.normalize( centerPosition, scratchPositionNormal @@ -885,8 +890,6 @@ function handleZoom( var scalar = distance / denom; camera.rotate(axis, angle * scalar); } - } else { - zoomOnVector = true; } } } From 456b208bafe250e5cbe665d8ec0fc6111c4e685d Mon Sep 17 00:00:00 2001 From: Bao Date: Sun, 30 Aug 2020 11:13:36 -0400 Subject: [PATCH 2/4] modify CHANGES.md --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 6f1b49605ccb..0f5edfa4c669 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -13,6 +13,7 @@ - Fixed an issue where the boundary rectangles in `TileAvailability` are not sorted correctly, causing terrain to sometimes fail to achieve its maximum detail. [#9098](https://github.com/CesiumGS/cesium/pull/9098) - Fixed an issue where a request for an availability tile of the reference layer is delayed because the throttle option is on. [#9099](https://github.com/CesiumGS/cesium/pull/9099) - Fixed an issue where Node.js tooling could not resolve package.json. [#9105](https://github.com/CesiumGS/cesium/pull/9105) +- Fixed an issue where the camera zooming is stuck when looking up. [#9126](https://github.com/CesiumGS/cesium/pull/9126) ### 1.72 - 2020-08-03 From 2e62edbb24eab18ffcb9c3e4073f2b83986ad34a Mon Sep 17 00:00:00 2001 From: Bao Date: Sun, 30 Aug 2020 11:17:33 -0400 Subject: [PATCH 3/4] add comment to the fix --- Source/Scene/ScreenSpaceCameraController.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Source/Scene/ScreenSpaceCameraController.js b/Source/Scene/ScreenSpaceCameraController.js index e264833ab57c..a55ee9a03110 100644 --- a/Source/Scene/ScreenSpaceCameraController.js +++ b/Source/Scene/ScreenSpaceCameraController.js @@ -709,7 +709,9 @@ function handleZoom( zoomOnVector = true; } else if (camera.positionCartographic.height < 1000000) { // The math in the else block assumes the camera - // points toward the earth surface, so we check it here + // points toward the earth surface, so we check it here. + // Theoretically, we should check for 90 degree, but it doesn't behave well when parallel + // to the earth surface if (Cartesian3.dot(camera.direction, cameraPositionNormal) >= -0.5) { zoomOnVector = true; } else { From 89282e29c6b73c133fb8a40236c1805e5ce032ea Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Tue, 1 Sep 2020 16:02:08 -0400 Subject: [PATCH 4/4] Move CHANGES.md [skip ci] --- CHANGES.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 0f5edfa4c669..a496f51056b2 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,11 @@ # Change Log +### 1.74 - 2020-10-01 + +##### Fixes :wrench: + +- Fixed an issue where the camera zooming is stuck when looking up. [#9126](https://github.com/CesiumGS/cesium/pull/9126) + ### 1.73 - 2020-09-01 ##### Additions :tada: @@ -13,7 +19,6 @@ - Fixed an issue where the boundary rectangles in `TileAvailability` are not sorted correctly, causing terrain to sometimes fail to achieve its maximum detail. [#9098](https://github.com/CesiumGS/cesium/pull/9098) - Fixed an issue where a request for an availability tile of the reference layer is delayed because the throttle option is on. [#9099](https://github.com/CesiumGS/cesium/pull/9099) - Fixed an issue where Node.js tooling could not resolve package.json. [#9105](https://github.com/CesiumGS/cesium/pull/9105) -- Fixed an issue where the camera zooming is stuck when looking up. [#9126](https://github.com/CesiumGS/cesium/pull/9126) ### 1.72 - 2020-08-03