From 71683d622f38d5e7cb1a031d6d0d8e2e14b57a94 Mon Sep 17 00:00:00 2001 From: Erik Andersson Date: Tue, 17 May 2016 15:00:57 +0200 Subject: [PATCH 1/4] added zoom algorithm that better maintains target point in 3D --- Source/Scene/ScreenSpaceCameraController.js | 106 +++++++++++++++++++- 1 file changed, 105 insertions(+), 1 deletion(-) diff --git a/Source/Scene/ScreenSpaceCameraController.js b/Source/Scene/ScreenSpaceCameraController.js index 07516af37da1..23af144ee69d 100644 --- a/Source/Scene/ScreenSpaceCameraController.js +++ b/Source/Scene/ScreenSpaceCameraController.js @@ -430,6 +430,21 @@ define([ var scratchZoomAxis = new Cartesian3(); var scratchCameraPositionNormal = new Cartesian3(); + // Scratch variables used in zooming algorithm + var scratchTargetNormal = new Cartesian3(); + var scratchCameraPosition = new Cartesian3(); + var scratchCameraUpNormal = new Cartesian3(); + var scratchCameraRightNormal = new Cartesian3(); + var scratchForwardNormal = new Cartesian3(); + var scratchPositionToTarget = new Cartesian3(); + var scratchPositionToTargetNormal = new Cartesian3(); + var scratchPan = new Cartesian3(); + var scratchCenterMovement = new Cartesian3(); + var scratchCenter = new Cartesian3(); + var scratchCartesian = new Cartesian3(); + var scratchCartesianTwo = new Cartesian3(); + var scratchCartesianThree = new Cartesian3(); + function handleZoom(object, startPosition, movement, zoomFactor, distanceMeasure, unitPositionDotDirection) { var percentage = 1.0; if (defined(unitPositionDotDirection)) { @@ -492,6 +507,10 @@ define([ var zoomOnVector = mode === SceneMode.COLUMBUS_VIEW; + if (camera.positionCartographic.height < 2000000) { + rotatingZoom = true; + } + if (!sameStartPosition || rotatingZoom) { if (mode === SceneMode.SCENE2D) { var worldPosition = object._zoomWorldPosition; @@ -522,7 +541,92 @@ define([ centerPixel.x = canvas.clientWidth / 2; centerPixel.y = canvas.clientHeight / 2; var centerPosition = pickGlobe(object, centerPixel, scratchCenterPosition); - if (defined(centerPosition)) { + // 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; + } + + 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); + + Cartesian3.normalize(positionToTarget, positionToTargetNormal); + + var alpha = Math.acos( -Cartesian3.dot( cameraPositionNormal, positionToTargetNormal ) ); + 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 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 ); + + // 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), + scratchCartesian + ), remainingDistance, pMid); + Cartesian3.add(cameraPosition, pMid, cameraPosition); + + 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), + scratchCartesian + ), Cartesian3.magnitude(center), cMid); + Cartesian3.add(center, cMid, center); + + // Update camera + + // Set new position + Cartesian3.clone(cameraPosition, camera.position); + + // Set new direction + Cartesian3.normalize(Cartesian3.subtract(center, cameraPosition, scratchCartesian), camera.direction); + Cartesian3.clone(camera.direction, camera.direction); + + // Set new right & up vectors + Cartesian3.cross(camera.direction, camera.up, camera.right); + Cartesian3.cross(camera.right, camera.direction, camera.up); + + return; + } else if (defined(centerPosition)) { var positionNormal = Cartesian3.normalize(centerPosition, scratchPositionNormal); var pickedNormal = Cartesian3.normalize(object._zoomWorldPosition, scratchPickNormal); var dotProduct = Cartesian3.dot(pickedNormal, positionNormal); From 30b9742d798133b168fc33f6272cd6bac51fe8a9 Mon Sep 17 00:00:00 2001 From: Erik Andersson Date: Mon, 13 Jun 2016 13:44:41 +0200 Subject: [PATCH 2/4] updated CHANGES.md to reflect new zoom behavior --- CHANGES.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 465e85390cc7..61307e8f82e0 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -9,6 +9,7 @@ Change Log * Fix some large polygon triangulations. [#2788](https://github.com/AnalyticalGraphicsInc/cesium/issues/2788) * Improved performance and accuracy of polygon triangulation by using the [earcut](https://github.com/mapbox/earcut) library. Loading a GeoJSON with polygons for each country was 2x faster. * Added CZML support for Box, Corridor and Cylinder +* Zooming in toward some target point now keeps the target point at the same screen position ### 1.22 - 2016-06-01 @@ -32,7 +33,7 @@ Change Log * Fixed exaggerated terrain tiles disappearing. [#3676](https://github.com/AnalyticalGraphicsInc/cesium/issues/3676) * Fixed a bug that could cause incorrect normals to be computed for exaggerated terrain, especially for low-detail tiles. [#3904](https://github.com/AnalyticalGraphicsInc/cesium/pull/3904) * Fixed a bug that was causing errors to be thrown when picking and terrain was enabled. [#3779](https://github.com/AnalyticalGraphicsInc/cesium/issues/3779) -* Fixed a bug that was causing the atmosphere to disappear when only atmosphere is visible. [#3347](https://github.com/AnalyticalGraphicsInc/cesium/issues/3347) +* Fixed a bug that was causing the atmosphere to disappear when only atmosphere is visible. [#3347](https://github.com/AnalyticalGraphicsInc/cesium/issues/3347) * Fixed infinite horizontal 2D scrolling in IE/Edge. [#3893](https://github.com/AnalyticalGraphicsInc/cesium/issues/3893) * Fixed a bug that would cause a crash is the camera was on the IDL in 2D. [#3951](https://github.com/AnalyticalGraphicsInc/cesium/issues/3951) * Fixed issue where a repeating model animation doesn't play when the clock is set to a time before the model was created. [#3932](https://github.com/AnalyticalGraphicsInc/cesium/issues/3932) From 81a5a7c8883bdc0eb00a4998d1b22b96f084b565 Mon Sep 17 00:00:00 2001 From: Erik Andersson Date: Mon, 13 Jun 2016 13:44:41 +0200 Subject: [PATCH 3/4] updated CHANGES.md to reflect new zoom behavior --- CHANGES.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 465e85390cc7..06cbbea5087f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -9,6 +9,7 @@ Change Log * Fix some large polygon triangulations. [#2788](https://github.com/AnalyticalGraphicsInc/cesium/issues/2788) * Improved performance and accuracy of polygon triangulation by using the [earcut](https://github.com/mapbox/earcut) library. Loading a GeoJSON with polygons for each country was 2x faster. * Added CZML support for Box, Corridor and Cylinder +* Zooming in toward some target point now keeps the target point at the same screen position. [#4016](https://github.com/AnalyticalGraphicsInc/cesium/pull/4016) ### 1.22 - 2016-06-01 @@ -32,7 +33,7 @@ Change Log * Fixed exaggerated terrain tiles disappearing. [#3676](https://github.com/AnalyticalGraphicsInc/cesium/issues/3676) * Fixed a bug that could cause incorrect normals to be computed for exaggerated terrain, especially for low-detail tiles. [#3904](https://github.com/AnalyticalGraphicsInc/cesium/pull/3904) * Fixed a bug that was causing errors to be thrown when picking and terrain was enabled. [#3779](https://github.com/AnalyticalGraphicsInc/cesium/issues/3779) -* Fixed a bug that was causing the atmosphere to disappear when only atmosphere is visible. [#3347](https://github.com/AnalyticalGraphicsInc/cesium/issues/3347) +* Fixed a bug that was causing the atmosphere to disappear when only atmosphere is visible. [#3347](https://github.com/AnalyticalGraphicsInc/cesium/issues/3347) * Fixed infinite horizontal 2D scrolling in IE/Edge. [#3893](https://github.com/AnalyticalGraphicsInc/cesium/issues/3893) * Fixed a bug that would cause a crash is the camera was on the IDL in 2D. [#3951](https://github.com/AnalyticalGraphicsInc/cesium/issues/3951) * Fixed issue where a repeating model animation doesn't play when the clock is set to a time before the model was created. [#3932](https://github.com/AnalyticalGraphicsInc/cesium/issues/3932) From 03ae248e59907c01232548465570a6fd729d27af Mon Sep 17 00:00:00 2001 From: Erik Andersson Date: Mon, 13 Jun 2016 16:49:48 +0200 Subject: [PATCH 4/4] added myself to CONTRIBUTORS.md --- CONTRIBUTORS.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index a2925adcecad..5e8bb620950e 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -55,6 +55,8 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute to Cesiu * [Sergio Flores](https://github.com/relfos) * [CubeWerx Inc.](http://www.cubewerx.com/) * [Keith Pomakis](https://github.com/pomakis) +* [Vricon](https://www.vricon.com/) + * [Erik Andersson](https://github.com/e-andersson) ## [Individual CLA](http://www.agi.com/licenses/individual-cla-agi-v1.0.txt) * [Victor Berchet](https://github.com/vicb)