Skip to content

Commit 535877f

Browse files
committed
Configurable frustum width for ray-pick functions
1 parent 05c44f4 commit 535877f

File tree

2 files changed

+66
-38
lines changed

2 files changed

+66
-38
lines changed

CHANGES.md

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ Change Log
66
##### Breaking Changes :mega:
77
* `TerrainProviders` that implement `availability` must now also implement the `loadTileDataAvailability` method.
88

9+
##### Deprecated :hourglass_flowing_sand:
10+
* `Scene.clampToHeight` now takes an optional `width` argument before the `result` argument. The previous function definition will no longer work in 1.53.
11+
912
##### Additions :tada:
1013
* Added functions to get the most detailed height of 3D Tiles on-screen or off-screen. [#7115](https://github.com/AnalyticalGraphicsInc/cesium/pull/7115)
1114
* Added `Scene.sampleHeightMostDetailed`, an asynchronous version of `Scene.sampleHeight` that uses the maximum level of detail for 3D Tiles.
@@ -15,6 +18,7 @@ Change Log
1518
* Added `computeLineSegmentLineSegmentIntersection` to `Intersections2D`. [#7228](https://github.com/AnalyticalGraphicsInc/Cesium/pull/7228)
1619
* Added ability to load availability progressively from a quantized mesh extension instead of upfront. This will speed up load time and reduce memory usage. [#7196](https://github.com/AnalyticalGraphicsInc/cesium/pull/7196)
1720
* Added the ability to apply styles to 3D Tilesets that don't contain features. [#7255](https://github.com/AnalyticalGraphicsInc/Cesium/pull/7255)
21+
* Added the ability to specify the width of the intersection rectangle for `Scene.sampleHeight`, `Scene.clampToHeight`, `Scene.sampleHeightMostDetailed`, and `Scene.clampToHeightMostDetailed`.
1822

1923
##### Fixes :wrench:
2024
* Fixed issue causing polyline to look wavy depending on the position of the camera [#7209](https://github.com/AnalyticalGraphicsInc/cesium/pull/7209)

Source/Scene/Scene.js

+62-38
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,9 @@ define([
170170
};
171171
};
172172

173-
function AsyncRayPick(ray, primitives) {
173+
function AsyncRayPick(ray, width, primitives) {
174174
this.ray = ray;
175+
this.width = width;
175176
this.primitives = primitives;
176177
this.ready = false;
177178
this.deferred = when.defer();
@@ -775,16 +776,18 @@ define([
775776
camera.frustum.far = 10000000000.0;
776777
}
777778

779+
var pickOffscreenDefaultWidth = 0.1;
778780
var pickOffscreenViewport = new BoundingRectangle(0, 0, 1, 1);
779781
var pickOffscreenCamera = new Camera(this);
780782
pickOffscreenCamera.frustum = new OrthographicFrustum({
781-
width: 0.01,
783+
width: pickOffscreenDefaultWidth,
782784
aspectRatio: 1.0,
783785
near: 0.1
784786
});
785787

786788
this._view = new View(this, camera, viewport);
787789
this._pickOffscreenView = new View(this, pickOffscreenCamera, pickOffscreenViewport);
790+
this._pickOffscreenDefaultWidth = pickOffscreenDefaultWidth;
788791

789792
this._defaultView = new View(this, camera, viewport);
790793
this._view = this._defaultView;
@@ -3758,7 +3761,7 @@ define([
37583761
var scratchRight = new Cartesian3();
37593762
var scratchUp = new Cartesian3();
37603763

3761-
function updateCameraFromRay(ray, camera) {
3764+
function updateCameraFromRay(ray, width, camera) {
37623765
var direction = ray.direction;
37633766
var orthogonalAxis = Cartesian3.mostOrthogonalAxis(direction, scratchRight);
37643767
var right = Cartesian3.cross(direction, orthogonalAxis, scratchRight);
@@ -3768,6 +3771,10 @@ define([
37683771
camera.direction = direction;
37693772
camera.up = up;
37703773
camera.right = right;
3774+
3775+
if (camera.frustum instanceof OrthographicFrustum) {
3776+
camera.frustum.width = width;
3777+
}
37713778
}
37723779

37733780
function updateAsyncRayPick(scene, asyncRayPick) {
@@ -3779,9 +3786,10 @@ define([
37793786
scene._view = view;
37803787

37813788
var ray = asyncRayPick.ray;
3789+
var width = defaultValue(asyncRayPick.width, scene._pickOffscreenDefaultWidth);
37823790
var primitives = asyncRayPick.primitives;
37833791

3784-
updateCameraFromRay(ray, view.camera);
3792+
updateCameraFromRay(ray, width, view.camera);
37853793

37863794
updateFrameState(scene);
37873795
frameState.passes.offscreen = true;
@@ -3826,7 +3834,7 @@ define([
38263834
}
38273835
}
38283836

3829-
function launchAsyncRayPick(scene, ray, objectsToExclude, callback) {
3837+
function launchAsyncRayPick(scene, ray, objectsToExclude, width, callback) {
38303838
var asyncPrimitives = [];
38313839
var primitives = scene.primitives;
38323840
var length = primitives.length;
@@ -3842,7 +3850,7 @@ define([
38423850
return when.resolve(callback());
38433851
}
38443852

3845-
var asyncRayPick = new AsyncRayPick(ray, asyncPrimitives);
3853+
var asyncRayPick = new AsyncRayPick(ray, width, asyncPrimitives);
38463854
scene._asyncRayPicks.push(asyncRayPick);
38473855
return asyncRayPick.promise.then(function() {
38483856
return callback();
@@ -3858,15 +3866,16 @@ define([
38583866
(objectsToExclude.indexOf(object.id) > -1);
38593867
}
38603868

3861-
function getRayIntersection(scene, ray, objectsToExclude, requirePosition, async) {
3869+
function getRayIntersection(scene, ray, objectsToExclude, width, requirePosition, async) {
38623870
var context = scene._context;
38633871
var uniformState = context.uniformState;
38643872
var frameState = scene._frameState;
38653873

38663874
var view = scene._pickOffscreenView;
38673875
scene._view = view;
38683876

3869-
updateCameraFromRay(ray, view.camera);
3877+
width = defaultValue(width, scene._pickOffscreenDefaultWidth);
3878+
updateCameraFromRay(ray, width, view.camera);
38703879

38713880
scratchRectangle = BoundingRectangle.clone(view.viewport, scratchRectangle);
38723881

@@ -3917,22 +3926,22 @@ define([
39173926
}
39183927
}
39193928

3920-
function getRayIntersections(scene, ray, limit, objectsToExclude, requirePosition, async) {
3929+
function getRayIntersections(scene, ray, limit, objectsToExclude, width, requirePosition, async) {
39213930
var pickCallback = function() {
3922-
return getRayIntersection(scene, ray, objectsToExclude, requirePosition, async);
3931+
return getRayIntersection(scene, ray, objectsToExclude, width, requirePosition, async);
39233932
};
39243933
return drillPick(limit, pickCallback);
39253934
}
39263935

3927-
function pickFromRay(scene, ray, objectsToExclude, requirePosition, async) {
3928-
var results = getRayIntersections(scene, ray, 1, objectsToExclude, requirePosition, async);
3936+
function pickFromRay(scene, ray, objectsToExclude, width, requirePosition, async) {
3937+
var results = getRayIntersections(scene, ray, 1, objectsToExclude, width, requirePosition, async);
39293938
if (results.length > 0) {
39303939
return results[0];
39313940
}
39323941
}
39333942

3934-
function drillPickFromRay(scene, ray, limit, objectsToExclude, requirePosition, async) {
3935-
return getRayIntersections(scene, ray, limit, objectsToExclude, requirePosition, async);
3943+
function drillPickFromRay(scene, ray, limit, objectsToExclude, width, requirePosition, async) {
3944+
return getRayIntersections(scene, ray, limit, objectsToExclude, width, requirePosition, async);
39363945
}
39373946

39383947
/**
@@ -3949,18 +3958,19 @@ define([
39493958
*
39503959
* @param {Ray} ray The ray.
39513960
* @param {Object[]} [objectsToExclude] A list of primitives, entities, or 3D Tiles features to exclude from the ray intersection.
3961+
* @param {Number} [width=0.1] Width of the intersection rectangle in meters.
39523962
* @returns {Object} An object containing the object and position of the first intersection.
39533963
*
39543964
* @exception {DeveloperError} Ray intersections are only supported in 3D mode.
39553965
*/
3956-
Scene.prototype.pickFromRay = function(ray, objectsToExclude) {
3966+
Scene.prototype.pickFromRay = function(ray, objectsToExclude, width) {
39573967
//>>includeStart('debug', pragmas.debug);
39583968
Check.defined('ray', ray);
39593969
if (this._mode !== SceneMode.SCENE3D) {
39603970
throw new DeveloperError('Ray intersections are only supported in 3D mode.');
39613971
}
39623972
//>>includeEnd('debug');
3963-
return pickFromRay(this, ray, objectsToExclude, false, false);
3973+
return pickFromRay(this, ray, objectsToExclude, width, false, false);
39643974
};
39653975

39663976
/**
@@ -3979,18 +3989,19 @@ define([
39793989
* @param {Ray} ray The ray.
39803990
* @param {Number} [limit=Number.MAX_VALUE] If supplied, stop finding intersections after this many intersections.
39813991
* @param {Object[]} [objectsToExclude] A list of primitives, entities, or 3D Tiles features to exclude from the ray intersection.
3992+
* @param {Number} [width=0.1] Width of the intersection rectangle in meters.
39823993
* @returns {Object[]} List of objects containing the object and position of each intersection.
39833994
*
39843995
* @exception {DeveloperError} Ray intersections are only supported in 3D mode.
39853996
*/
3986-
Scene.prototype.drillPickFromRay = function(ray, limit, objectsToExclude) {
3997+
Scene.prototype.drillPickFromRay = function(ray, limit, objectsToExclude, width) {
39873998
//>>includeStart('debug', pragmas.debug);
39883999
Check.defined('ray', ray);
39894000
if (this._mode !== SceneMode.SCENE3D) {
39904001
throw new DeveloperError('Ray intersections are only supported in 3D mode.');
39914002
}
39924003
//>>includeEnd('debug');
3993-
return drillPickFromRay(this, ray, limit, objectsToExclude, false, false);
4004+
return drillPickFromRay(this, ray, limit, objectsToExclude, width,false, false);
39944005
};
39954006

39964007
/**
@@ -4001,11 +4012,12 @@ define([
40014012
*
40024013
* @param {Ray} ray The ray.
40034014
* @param {Object[]} [objectsToExclude] A list of primitives, entities, or 3D Tiles features to exclude from the ray intersection.
4015+
* @param {Number} [width=0.1] Width of the intersection rectangle in meters.
40044016
* @returns {Promise.<Object>} A promise that resolves to an object containing the object and position of the first intersection.
40054017
*
40064018
* @exception {DeveloperError} Ray intersections are only supported in 3D mode.
40074019
*/
4008-
Scene.prototype.pickFromRayMostDetailed = function(ray, objectsToExclude) {
4020+
Scene.prototype.pickFromRayMostDetailed = function(ray, objectsToExclude, width) {
40094021
//>>includeStart('debug', pragmas.debug);
40104022
Check.defined('ray', ray);
40114023
if (this._mode !== SceneMode.SCENE3D) {
@@ -4015,8 +4027,8 @@ define([
40154027
var that = this;
40164028
ray = Ray.clone(ray);
40174029
objectsToExclude = defined(objectsToExclude) ? objectsToExclude.slice() : objectsToExclude;
4018-
return launchAsyncRayPick(this, ray, objectsToExclude, function() {
4019-
return pickFromRay(that, ray, objectsToExclude, false, true);
4030+
return launchAsyncRayPick(this, ray, objectsToExclude, width, function() {
4031+
return pickFromRay(that, ray, objectsToExclude, width, false, true);
40204032
});
40214033
};
40224034

@@ -4029,11 +4041,12 @@ define([
40294041
* @param {Ray} ray The ray.
40304042
* @param {Number} [limit=Number.MAX_VALUE] If supplied, stop finding intersections after this many intersections.
40314043
* @param {Object[]} [objectsToExclude] A list of primitives, entities, or 3D Tiles features to exclude from the ray intersection.
4044+
* @param {Number} [width=0.1] Width of the intersection rectangle in meters.
40324045
* @returns {Promise.<Object[]>} A promise that resolves to a list of objects containing the object and position of each intersection.
40334046
*
40344047
* @exception {DeveloperError} Ray intersections are only supported in 3D mode.
40354048
*/
4036-
Scene.prototype.drillPickFromRayMostDetailed = function(ray, limit, objectsToExclude) {
4049+
Scene.prototype.drillPickFromRayMostDetailed = function(ray, limit, objectsToExclude, width) {
40374050
//>>includeStart('debug', pragmas.debug);
40384051
Check.defined('ray', ray);
40394052
if (this._mode !== SceneMode.SCENE3D) {
@@ -4043,8 +4056,8 @@ define([
40434056
var that = this;
40444057
ray = Ray.clone(ray);
40454058
objectsToExclude = defined(objectsToExclude) ? objectsToExclude.slice() : objectsToExclude;
4046-
return launchAsyncRayPick(this, ray, objectsToExclude, function() {
4047-
return drillPickFromRay(that, ray, limit, objectsToExclude, false, true);
4059+
return launchAsyncRayPick(this, ray, objectsToExclude, width, function() {
4060+
return drillPickFromRay(that, ray, limit, objectsToExclude, width, false, true);
40484061
});
40494062
};
40504063

@@ -4082,20 +4095,20 @@ define([
40824095
return cartographic.height;
40834096
}
40844097

4085-
function sampleHeightMostDetailed(scene, cartographic, objectsToExclude) {
4098+
function sampleHeightMostDetailed(scene, cartographic, objectsToExclude, width) {
40864099
var ray = getRayForSampleHeight(scene, cartographic);
4087-
return launchAsyncRayPick(scene, ray, objectsToExclude, function() {
4088-
var pickResult = pickFromRay(scene, ray, objectsToExclude, true, true);
4100+
return launchAsyncRayPick(scene, ray, objectsToExclude, width, function() {
4101+
var pickResult = pickFromRay(scene, ray, objectsToExclude, width, true, true);
40894102
if (defined(pickResult)) {
40904103
return getHeightFromCartesian(scene, pickResult.position);
40914104
}
40924105
});
40934106
}
40944107

4095-
function clampToHeightMostDetailed(scene, cartesian, objectsToExclude, result) {
4108+
function clampToHeightMostDetailed(scene, cartesian, objectsToExclude, width, result) {
40964109
var ray = getRayForClampToHeight(scene, cartesian);
4097-
return launchAsyncRayPick(scene, ray, objectsToExclude, function() {
4098-
var pickResult = pickFromRay(scene, ray, objectsToExclude, true, true);
4110+
return launchAsyncRayPick(scene, ray, objectsToExclude, width, function() {
4111+
var pickResult = pickFromRay(scene, ray, objectsToExclude, width, true, true);
40994112
if (defined(pickResult)) {
41004113
return Cartesian3.clone(pickResult.position, result);
41014114
}
@@ -4113,6 +4126,7 @@ define([
41134126
*
41144127
* @param {Cartographic} position The cartographic position to sample height from.
41154128
* @param {Object[]} [objectsToExclude] A list of primitives, entities, or 3D Tiles features to not sample height from.
4129+
* @param {Number} [width=0.1] Width of the intersection rectangle in meters.
41164130
* @returns {Number} The height. This may be <code>undefined</code> if there was no scene geometry to sample height from.
41174131
*
41184132
* @example
@@ -4127,7 +4141,7 @@ define([
41274141
* @exception {DeveloperError} sampleHeight is only supported in 3D mode.
41284142
* @exception {DeveloperError} sampleHeight requires depth texture support. Check sampleHeightSupported.
41294143
*/
4130-
Scene.prototype.sampleHeight = function(position, objectsToExclude) {
4144+
Scene.prototype.sampleHeight = function(position, objectsToExclude, width) {
41314145
//>>includeStart('debug', pragmas.debug);
41324146
Check.defined('position', position);
41334147
if (this._mode !== SceneMode.SCENE3D) {
@@ -4138,7 +4152,7 @@ define([
41384152
}
41394153
//>>includeEnd('debug');
41404154
var ray = getRayForSampleHeight(this, position);
4141-
var pickResult = pickFromRay(this, ray, objectsToExclude, true, false);
4155+
var pickResult = pickFromRay(this, ray, objectsToExclude, width, true, false);
41424156
if (defined(pickResult)) {
41434157
return getHeightFromCartesian(this, pickResult.position);
41444158
}
@@ -4155,6 +4169,7 @@ define([
41554169
*
41564170
* @param {Cartesian3} cartesian The cartesian position.
41574171
* @param {Object[]} [objectsToExclude] A list of primitives, entities, or 3D Tiles features to not clamp to.
4172+
* @param {Number} [width=0.1] Width of the intersection rectangle in meters.
41584173
* @param {Cartesian3} [result] An optional object to return the clamped position.
41594174
* @returns {Cartesian3} The modified result parameter or a new Cartesian3 instance if one was not provided. This may be <code>undefined</code> if there was no scene geometry to clamp to.
41604175
*
@@ -4170,7 +4185,7 @@ define([
41704185
* @exception {DeveloperError} clampToHeight is only supported in 3D mode.
41714186
* @exception {DeveloperError} clampToHeight requires depth texture support. Check clampToHeightSupported.
41724187
*/
4173-
Scene.prototype.clampToHeight = function(cartesian, objectsToExclude, result) {
4188+
Scene.prototype.clampToHeight = function(cartesian, objectsToExclude, width, result) {
41744189
//>>includeStart('debug', pragmas.debug);
41754190
Check.defined('cartesian', cartesian);
41764191
if (this._mode !== SceneMode.SCENE3D) {
@@ -4180,8 +4195,15 @@ define([
41804195
throw new DeveloperError('clampToHeight requires depth texture support. Check clampToHeightSupported.');
41814196
}
41824197
//>>includeEnd('debug');
4198+
4199+
if (width instanceof Cartesian3) {
4200+
result = width;
4201+
width = undefined;
4202+
deprecationWarning('clampToHeight-parameter-change', 'clampToHeight now takes an optional width argument before the result argument in Cesium 1.52. The previous function definition will no longer work in 1.53.');
4203+
}
4204+
41834205
var ray = getRayForClampToHeight(this, cartesian);
4184-
var pickResult = pickFromRay(this, ray, objectsToExclude, true, false);
4206+
var pickResult = pickFromRay(this, ray, objectsToExclude, width, true, false);
41854207
if (defined(pickResult)) {
41864208
return Cartesian3.clone(pickResult.position, result);
41874209
}
@@ -4196,6 +4218,7 @@ define([
41964218
*
41974219
* @param {Cartographic[]} positions The cartographic positions to update with sampled heights.
41984220
* @param {Object[]} [objectsToExclude] A list of primitives, entities, or 3D Tiles features to not sample height from.
4221+
* @param {Number} [width=0.1] Width of the intersection rectangle in meters.
41994222
* @returns {Promise.<Number[]>} A promise that resolves to the provided list of positions when the query has completed.
42004223
*
42014224
* @example
@@ -4214,7 +4237,7 @@ define([
42144237
* @exception {DeveloperError} sampleHeightMostDetailed is only supported in 3D mode.
42154238
* @exception {DeveloperError} sampleHeightMostDetailed requires depth texture support. Check sampleHeightSupported.
42164239
*/
4217-
Scene.prototype.sampleHeightMostDetailed = function(positions, objectsToExclude) {
4240+
Scene.prototype.sampleHeightMostDetailed = function(positions, objectsToExclude, width) {
42184241
//>>includeStart('debug', pragmas.debug);
42194242
Check.defined('positions', positions);
42204243
if (this._mode !== SceneMode.SCENE3D) {
@@ -4228,7 +4251,7 @@ define([
42284251
var length = positions.length;
42294252
var promises = new Array(length);
42304253
for (var i = 0; i < length; ++i) {
4231-
promises[i] = sampleHeightMostDetailed(this, positions[i], objectsToExclude);
4254+
promises[i] = sampleHeightMostDetailed(this, positions[i], objectsToExclude, width);
42324255
}
42334256
return when.all(promises).then(function(heights) {
42344257
var length = heights.length;
@@ -4247,6 +4270,7 @@ define([
42474270
*
42484271
* @param {Cartesian3[]} cartesians The cartesian positions to update with clamped positions.
42494272
* @param {Object[]} [objectsToExclude] A list of primitives, entities, or 3D Tiles features to not clamp to.
4273+
* @param {Number} [width=0.1] Width of the intersection rectangle in meters.
42504274
* @returns {Promise.<Cartesian3[]>} A promise that resolves to the provided list of positions when the query has completed.
42514275
*
42524276
* @example
@@ -4265,7 +4289,7 @@ define([
42654289
* @exception {DeveloperError} clampToHeightMostDetailed is only supported in 3D mode.
42664290
* @exception {DeveloperError} clampToHeightMostDetailed requires depth texture support. Check clampToHeightSupported.
42674291
*/
4268-
Scene.prototype.clampToHeightMostDetailed = function(cartesians, objectsToExclude) {
4292+
Scene.prototype.clampToHeightMostDetailed = function(cartesians, objectsToExclude, width) {
42694293
//>>includeStart('debug', pragmas.debug);
42704294
Check.defined('cartesians', cartesians);
42714295
if (this._mode !== SceneMode.SCENE3D) {
@@ -4279,7 +4303,7 @@ define([
42794303
var length = cartesians.length;
42804304
var promises = new Array(length);
42814305
for (var i = 0; i < length; ++i) {
4282-
promises[i] = clampToHeightMostDetailed(this, cartesians[i], objectsToExclude, cartesians[i]);
4306+
promises[i] = clampToHeightMostDetailed(this, cartesians[i], objectsToExclude, width, cartesians[i]);
42834307
}
42844308
return when.all(promises).then(function(clampedCartesians) {
42854309
var length = clampedCartesians.length;

0 commit comments

Comments
 (0)