diff --git a/CHANGES.md b/CHANGES.md index cf8dd7208595..05b4ffabd271 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,7 +4,8 @@ Change Log ### 1.49 - 2018-09-03 ##### Breaking Changes :mega: -* Removed `ClippingPlaneCollection.clone` +* Removed `ClippingPlaneCollection.clone` [#6872](https://github.com/AnalyticalGraphicsInc/cesium/pull/6872) +* Changed `Globe.pick` to return a position in ECEF coordinates regardless of the current scene mode. This will only effect you if you were working around a bug to make `Globe.pick` work in 2D and Columbus View. Use `Globe.pickWorldCoordinates` to get the position in world coordinates that correlate to the current scene mode. [#6859](https://github.com/AnalyticalGraphicsInc/cesium/pull/6859) ##### Additions :tada: * Added `ClippingPlaneCollection.planeAdded` and `ClippingPlaneCollection.planeRemoved` events. `planeAdded` is raised when a new plane is added to the collection and `planeRemoved` is raised when a plane is removed. [#6875](https://github.com/AnalyticalGraphicsInc/cesium/pull/6875) @@ -12,6 +13,9 @@ Change Log ##### Fixes :wrench: * 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) diff --git a/Source/Scene/Camera.js b/Source/Scene/Camera.js index 50b48178c9d3..5ab8934670ae 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); @@ -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) { @@ -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/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..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); @@ -832,7 +841,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/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); }); diff --git a/Specs/Scene/ScreenSpaceCameraControllerSpec.js b/Specs/Scene/ScreenSpaceCameraControllerSpec.js index 52c08f7c4397..80e2cf935922 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 = {