diff --git a/CHANGES.md b/CHANGES.md index 52c342efdb0c..863df63890e3 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -12,6 +12,7 @@ Change Log * 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) * Added `Matrix4.setScale` for setting the scale on an affine transformation matrix [#6888](https://github.com/AnalyticalGraphicsInc/cesium/pull/6888) * Added `GeocoderViewModel.destinationFound` for specifying a function that is called upon a successful geocode. The default behavior is to fly to the destination found by the geocoder. [#6915](https://github.com/AnalyticalGraphicsInc/cesium/pull/6915) +* Added optional `width` and `height` to `Scene.drillPick` for specifying a search area. ##### Fixes :wrench: * The Geocoder widget now takes terrain altitude into account when calculating its final destination. diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 8f16aefef198..18bdbd35a1f4 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -3751,14 +3751,19 @@ define([ * * @param {Cartesian2} windowPosition Window coordinates to perform picking on. * @param {Number} [limit] If supplied, stop drilling after collecting this many picks. + * @param {Number} [width=3] Width of the pick rectangle. + * @param {Number} [height=3] Height of the pick rectangle. * @returns {Object[]} Array of objects, each containing 1 picked primitives. * * @exception {DeveloperError} windowPosition is undefined. * * @example * var pickedObjects = scene.drillPick(new Cesium.Cartesian2(100.0, 200.0)); + * + * @see Scene#pick + * */ - Scene.prototype.drillPick = function(windowPosition, limit) { + Scene.prototype.drillPick = function(windowPosition, limit, width, height) { // PERFORMANCE_IDEA: This function calls each primitive's update for each pass. Instead // we could update the primitive once, and then just execute their commands for each pass, // and cull commands for picked primitives. e.g., base on the command's owner. @@ -3778,7 +3783,7 @@ define([ limit = Number.MAX_VALUE; } - var pickedResult = this.pick(windowPosition); + var pickedResult = this.pick(windowPosition, width, height); while (defined(pickedResult) && defined(pickedResult.primitive)) { result.push(pickedResult); if (0 >= --limit) { @@ -3806,7 +3811,7 @@ define([ pickedPrimitives.push(primitive); } - pickedResult = this.pick(windowPosition); + pickedResult = this.pick(windowPosition, width, height); } // unhide everything we hid while drill picking diff --git a/Specs/Scene/PickSpec.js b/Specs/Scene/PickSpec.js index 638b8e51b7f7..73fb644f65a0 100644 --- a/Specs/Scene/PickSpec.js +++ b/Specs/Scene/PickSpec.js @@ -114,6 +114,22 @@ defineSuite([ expect(scene).notToPick(7, 7, 3); }); + it('drill picks a primitive with a modified pick search area', function() { + if (FeatureDetection.isInternetExplorer()) { + // Workaround IE 11.0.9. This test fails when all tests are ran without a breakpoint here. + return; + } + + camera.setView({ + destination : Rectangle.fromDegrees(-10.0, -10.0, 10.0, 10.0) + }); + + var rectangle = createRectangle(); + + expect(scene).toDrillPickPrimitive(rectangle, 7, 7, 5); + expect(scene).notToDrillPick(7, 7, 3); + }); + it('does not pick primitives when show is false', function() { var rectangle = createRectangle(); rectangle.show = false; diff --git a/Specs/addDefaultMatchers.js b/Specs/addDefaultMatchers.js index 775b3f3e996e..9903852787d9 100644 --- a/Specs/addDefaultMatchers.js +++ b/Specs/addDefaultMatchers.js @@ -297,6 +297,22 @@ define([ }; }, + toDrillPickPrimitive : function(util, customEqualityTesters) { + return { + compare : function(actual, expected, x, y, width, height) { + return drillPickPrimitiveEquals(actual, 1, x, y, width, height); + } + }; + }, + + notToDrillPick : function(util, customEqualityTesters) { + return { + compare : function(actual, expected, x, y, width, height) { + return drillPickPrimitiveEquals(actual, 0, x, y, width, height); + } + }; + }, + toPickAndCall : function(util, customEqualityTesters) { return { compare : function(actual, expected) { @@ -532,6 +548,36 @@ define([ }; } + function drillPickPrimitiveEquals(actual, expected, x, y, width, height) { + var scene = actual; + var windowPosition = new Cartesian2(x, y); + var result = scene.drillPick(windowPosition, undefined, width, height); + + if (!!window.webglStub) { + return { + pass : true + }; + } + + var pass = true; + var message; + + if (defined(expected)) { + pass = (result.length === expected); + } else { + pass = !defined(result); + } + + if (!pass) { + message = 'Expected to pick ' + expected + ', but picked: ' + result; + } + + return { + pass : pass, + message : message + }; + } + function expectContextToRender(actual, expected, expectEqual) { var options = actual; var context = options.context;