From 03969580de0275f5bf4e4e1d3bc9785f5c560116 Mon Sep 17 00:00:00 2001 From: hpinkos Date: Tue, 31 Jul 2018 16:04:00 -0400 Subject: [PATCH 1/5] globe pick wc --- Source/Scene/Camera.js | 2 +- Source/Scene/Globe.js | 34 +++++++++++++++---- Source/Scene/SceneTransitioner.js | 4 +-- Source/Scene/ScreenSpaceCameraController.js | 2 +- .../Scene/ScreenSpaceCameraControllerSpec.js | 2 +- 5 files changed, 33 insertions(+), 11 deletions(-) diff --git a/Source/Scene/Camera.js b/Source/Scene/Camera.js index 50b48178c9d3..fcefe4ad9aff 100644 --- a/Source/Scene/Camera.js +++ b/Source/Scene/Camera.js @@ -1013,7 +1013,7 @@ define([ mousePosition.y = scene.drawingBufferHeight / 2.0; var ray = this.getPickRay(mousePosition, pickGlobeScratchRay); - rayIntersection = globe.pick(ray, scene, scratchRayIntersection); + rayIntersection = globe.pickWorldCoordinates(ray, scene, scratchRayIntersection); if (scene.pickPositionSupported) { depthIntersection = scene.pickPositionWorldCoordinates(mousePosition, scratchDepthIntersection); diff --git a/Source/Scene/Globe.js b/Source/Scene/Globe.js index 29b77bbac8f5..5acc74e2413f 100644 --- a/Source/Scene/Globe.js +++ b/Source/Scene/Globe.js @@ -407,14 +407,11 @@ define([ * @param {Ray} ray The ray to test for intersection. * @param {Scene} scene The scene. * @param {Cartesian3} [result] The object onto which to store the result. - * @returns {Cartesian3|undefined} The intersection or undefined if none was found. + * @returns {Cartesian3|undefined} The intersection or undefined if none was found. The returned position is in projected coordinates for 2D and Columbus View. * - * @example - * // find intersection of ray through a pixel and the globe - * var ray = viewer.camera.getPickRay(windowCoordinates); - * var intersection = globe.pick(ray, scene); + * @private */ - Globe.prototype.pick = function(ray, scene, result) { + Globe.prototype.pickWorldCoordinates = function(ray, scene, result) { //>>includeStart('debug', pragmas.debug); if (!defined(ray)) { throw new DeveloperError('ray is required'); @@ -472,6 +469,31 @@ define([ return intersection; }; + var cartoScratch = new Cartographic(); + /** + * Find an intersection between a ray and the globe surface that was rendered. The ray must be given in world coordinates. + * + * @param {Ray} ray The ray to test for intersection. + * @param {Scene} scene The scene. + * @param {Cartesian3} [result] The object onto which to store the result. + * @returns {Cartesian3|undefined} The intersection or undefined if none was found. + * + * @example + * // find intersection of ray through a pixel and the globe + * var ray = viewer.camera.getPickRay(windowCoordinates); + * var intersection = globe.pick(ray, scene); + */ + Globe.prototype.pick = function(ray, scene, result) { + result = this.pickWorldCoordinates(ray, scene, result); + if (defined(result) && scene.mode !== SceneMode.SCENE3D) { + result = Cartesian3.fromElements(result.y, result.z, result.x, result); + var carto = scene.mapProjection.unproject(result, cartoScratch); + result = scene.globe.ellipsoid.cartographicToCartesian(carto, result); + } + + return result; + }; + var scratchGetHeightCartesian = new Cartesian3(); var scratchGetHeightIntersection = new Cartesian3(); var scratchGetHeightCartographic = new Cartographic(); diff --git a/Source/Scene/SceneTransitioner.js b/Source/Scene/SceneTransitioner.js index b69d36c93c8d..457e16bedbde 100644 --- a/Source/Scene/SceneTransitioner.js +++ b/Source/Scene/SceneTransitioner.js @@ -530,7 +530,7 @@ define([ var globe = scene.globe; if (defined(globe)) { - var pickPos = globe.pick(ray, scene, scratchCVTo2DPickPos); + var pickPos = globe.pickWorldCoordinates(ray, scene, scratchCVTo2DPickPos); if (defined(pickPos)) { Matrix4.multiplyByPoint(Camera.TRANSFORM_2D_INVERSE, pickPos, endPos); endPos.z += Cartesian3.distance(startPos, endPos); @@ -634,7 +634,7 @@ define([ var globe = scene.globe; if (defined(globe)) { - var pickedPos = globe.pick(ray, scene, scratch3DTo2DPickPosition); + var pickedPos = globe.pickWorldCoordinates(ray, scene, scratch3DTo2DPickPosition); if (defined(pickedPos)) { var height = Cartesian3.distance(camera2D.position2D, pickedPos); pickedPos.x += height; diff --git a/Source/Scene/ScreenSpaceCameraController.js b/Source/Scene/ScreenSpaceCameraController.js index 02037bbbb2e7..319e30b9c811 100644 --- a/Source/Scene/ScreenSpaceCameraController.js +++ b/Source/Scene/ScreenSpaceCameraController.js @@ -832,7 +832,7 @@ define([ } var ray = camera.getPickRay(mousePosition, pickGlobeScratchRay); - var rayIntersection = globe.pick(ray, scene, scratchRayIntersection); + var rayIntersection = globe.pickWorldCoordinates(ray, scene, scratchRayIntersection); var pickDistance = defined(depthIntersection) ? Cartesian3.distance(depthIntersection, camera.positionWC) : Number.POSITIVE_INFINITY; var rayDistance = defined(rayIntersection) ? Cartesian3.distance(rayIntersection, camera.positionWC) : Number.POSITIVE_INFINITY; diff --git a/Specs/Scene/ScreenSpaceCameraControllerSpec.js b/Specs/Scene/ScreenSpaceCameraControllerSpec.js index 6b71846515ae..c83d06b879f4 100644 --- a/Specs/Scene/ScreenSpaceCameraControllerSpec.js +++ b/Specs/Scene/ScreenSpaceCameraControllerSpec.js @@ -64,7 +64,7 @@ defineSuite([ this.getHeight = function(cartographic) { return 0.0; }; - this.pick = function() { + this.pickWorldCoordinates = function() { return new Cartesian3(0.0, 0.0, 1.0); }; this._surface = { From 0c9903fd71074366bc402bb267f2ea60fde1f2ad Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 8 Aug 2018 16:10:57 -0400 Subject: [PATCH 2/5] Fix get pick ray in 2D. --- Source/Scene/Camera.js | 2 +- Source/Scene/ScreenSpaceCameraController.js | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Source/Scene/Camera.js b/Source/Scene/Camera.js index fcefe4ad9aff..248a7c72888a 100644 --- a/Source/Scene/Camera.js +++ b/Source/Scene/Camera.js @@ -2536,7 +2536,7 @@ define([ Cartesian3.clone(camera.directionWC, result.direction); - if (camera._mode === SceneMode.COLUMBUS_VIEW) { + if (camera._mode === SceneMode.COLUMBUS_VIEW || camera._mode === SceneMode.SCENE2D) { Cartesian3.fromElements(result.origin.z, result.origin.x, result.origin.y, result.origin); } diff --git a/Source/Scene/ScreenSpaceCameraController.js b/Source/Scene/ScreenSpaceCameraController.js index 319e30b9c811..3e8600ce0c06 100644 --- a/Source/Scene/ScreenSpaceCameraController.js +++ b/Source/Scene/ScreenSpaceCameraController.js @@ -512,7 +512,12 @@ define([ object._zoomMouseStart = Cartesian2.clone(startPosition, object._zoomMouseStart); if (defined(object._globe)) { - pickedPosition = mode !== SceneMode.SCENE2D ? pickGlobe(object, startPosition, scratchPickCartesian) : camera.getPickRay(startPosition, scratchZoomPickRay).origin; + if (mode === SceneMode.SCENE2D) { + pickedPosition = camera.getPickRay(startPosition, scratchZoomPickRay).origin; + pickedPosition = Cartesian3.fromElements(pickedPosition.y, pickedPosition.z, pickedPosition.x); + } else { + pickedPosition = pickGlobe(object, startPosition, scratchPickCartesian); + } } if (defined(pickedPosition)) { object._useZoomWorldPosition = true; @@ -552,6 +557,7 @@ define([ if ((camera.position.x < 0.0 && savedX > 0.0) || (camera.position.x > 0.0 && savedX < 0.0)) { pickedPosition = camera.getPickRay(startPosition, scratchZoomPickRay).origin; + pickedPosition = Cartesian3.fromElements(pickedPosition.y, pickedPosition.z, pickedPosition.x); object._zoomWorldPosition = Cartesian3.clone(pickedPosition, object._zoomWorldPosition); } } @@ -692,7 +698,7 @@ define([ } var rayDirection = ray.direction; - if (mode === SceneMode.COLUMBUS_VIEW) { + if (mode === SceneMode.COLUMBUS_VIEW || mode === SceneMode.SCENE2D) { Cartesian3.fromElements(rayDirection.y, rayDirection.z, rayDirection.x, rayDirection); } @@ -716,6 +722,9 @@ define([ var start = camera.getPickRay(movement.startPosition, translate2DStart).origin; var end = camera.getPickRay(movement.endPosition, translate2DEnd).origin; + start = Cartesian3.fromElements(start.y, start.z, start.x, start); + end = Cartesian3.fromElements(end.y, end.z, end.x, end); + var direction = Cartesian3.subtract(start, end, scratchTranslateP0); var distance = Cartesian3.magnitude(direction); From 7ba08a574f6b493959a4a19e5172c7d5a17af603 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 8 Aug 2018 16:21:21 -0400 Subject: [PATCH 3/5] Fix tests. --- Source/Scene/Camera.js | 2 +- Specs/Scene/CameraSpec.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Scene/Camera.js b/Source/Scene/Camera.js index 248a7c72888a..5ab8934670ae 100644 --- a/Source/Scene/Camera.js +++ b/Source/Scene/Camera.js @@ -2414,7 +2414,7 @@ define([ function pickMap2D(camera, windowPosition, projection, result) { var ray = camera.getPickRay(windowPosition, pickEllipsoid2DRay); var position = ray.origin; - position.z = 0.0; + position = Cartesian3.fromElements(position.y, position.z, 0.0, position); var cart = projection.unproject(position); if (cart.latitude < -CesiumMath.PI_OVER_TWO || cart.latitude > CesiumMath.PI_OVER_TWO) { diff --git a/Specs/Scene/CameraSpec.js b/Specs/Scene/CameraSpec.js index 535eb9188f4a..819ba609bf02 100644 --- a/Specs/Scene/CameraSpec.js +++ b/Specs/Scene/CameraSpec.js @@ -2261,7 +2261,7 @@ defineSuite([ var ray = camera.getPickRay(windowCoord); var cameraPosition = camera.position; - var expectedPosition = new Cartesian3(cameraPosition.x + 2.0, cameraPosition.y + 2, cameraPosition.z); + var expectedPosition = new Cartesian3(cameraPosition.z, cameraPosition.x + 2.0, cameraPosition.y + 2.0); expect(ray.origin).toEqualEpsilon(expectedPosition, CesiumMath.EPSILON14); expect(ray.direction).toEqual(camera.directionWC); }); From d72c767106734d2ed58ea77f2546449045670a87 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 8 Aug 2018 16:23:30 -0400 Subject: [PATCH 4/5] Update CHANGES.md. --- CHANGES.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index d3f4c24cf1eb..7fb533b752bd 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,11 @@ Change Log ========== +### 1.49 - 2018-09-03 + +#### Fixes :wrench: +* Fixed `getPickRay` in 2D. [#2480](https://github.com/AnalyticalGraphicsInc/cesium/issues/2480) + ### 1.48 - 2018-08-01 ##### Additions :tada: From 0570dde2a58e6f95559c2cd5a36efc1de6455a93 Mon Sep 17 00:00:00 2001 From: hpinkos Date: Wed, 8 Aug 2018 16:57:17 -0400 Subject: [PATCH 5/5] CHANGES.md --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index e2ff903eae9f..05b4ffabd271 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -14,6 +14,7 @@ Change Log * The Geocoder widget now takes terrain altitude into account when calculating its final destination. * The Viewer widget now takes terrain altitude into account when zooming or flying to imagery layers. * Fixed `getPickRay` in 2D. [#2480](https://github.com/AnalyticalGraphicsInc/cesium/issues/2480) +* Fixed `Globe.pick` for 2D and Columbus View [#6859](https://github.com/AnalyticalGraphicsInc/cesium/pull/6859) * Fixed imagery layer feature picking in 2D and Columbus view [#6859](https://github.com/AnalyticalGraphicsInc/cesium/pull/6859) * Fixed bug that caused a new `ClippingPlaneCollection` to be created every frame when used with a model entity [#6872](https://github.com/AnalyticalGraphicsInc/cesium/pull/6872) * Fixed crash when rendering translucent objects when all shadow maps in the scene set `fromLightSource` to false. [#6883](https://github.com/AnalyticalGraphicsInc/cesium/pull/6883)