Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correct Camera.computeViewRectangle when IDL is in view #3728

Merged
merged 1 commit into from
Mar 21, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ Change Log
* Fix a race condition that would cause the terrain to continue loading and unloading or cause a crash when changing terrain providers. [#3690](https://github.com/AnalyticalGraphicsInc/cesium/issues/3690)
* All external urls are now https by default to make Cesium work better with non-server-based applications. [#3650](https://github.com/AnalyticalGraphicsInc/cesium/issues/3650)
* Fix issue where the `GroundPrimitive` volume was being clipped by the far plane. [#3706](https://github.com/AnalyticalGraphicsInc/cesium/issues/3706)
* Fixed issue where `Camera.computeViewRectangle` was incorrect when crossing the international date line [#3717](https://github.com/AnalyticalGraphicsInc/cesium/issues/3717)
* Added `Rectangle` result parameter to `Camera.computeViewRectangle`

### 1.19 - 2016-03-01

Expand Down
71 changes: 27 additions & 44 deletions Source/Scene/Camera.js
Original file line number Diff line number Diff line change
Expand Up @@ -2800,17 +2800,29 @@ define([
}

var scratchPickCartesian2 = new Cartesian2();

var scratchRectCartesian = new Cartesian3();
var cartoArray = [new Cartographic(), new Cartographic(), new Cartographic(), new Cartographic()];
function addToResult(x, y, index, camera, ellipsoid, computedHorizonQuad) {
scratchPickCartesian2.x = x;
scratchPickCartesian2.y = y;
var r = camera.pickEllipsoid(scratchPickCartesian2, ellipsoid, scratchRectCartesian);
if (defined(r)) {
cartoArray[index] = ellipsoid.cartesianToCartographic(r, cartoArray[index]);
return 1;
}
cartoArray[index] = ellipsoid.cartesianToCartographic(computedHorizonQuad[index], cartoArray[index]);
return 0;
}
/**
* Computes the approximate visible rectangle on the ellipsoid.
*
* @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid that you want to know the visible region.
* @param {Rectangle} [result] The rectangle in which to store the result
*
* @returns {Rectangle|undefined} The visible rectangle or undefined if the ellipsoid isn't visible at all.
*/
Camera.prototype.computeViewRectangle = function(ellipsoid) {
Camera.prototype.computeViewRectangle = function(ellipsoid, result) {
ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84);

var cullingVolume = this.frustum.computeCullingVolume(this.positionWC, this.directionWC, this.upWC);
var boundingSphere = new BoundingSphere(Cartesian3.ZERO, ellipsoid.maximumRadius);
var visibility = cullingVolume.computeVisibility(boundingSphere);
Expand All @@ -2822,45 +2834,27 @@ define([
var width = canvas.clientWidth;
var height = canvas.clientHeight;

var that = this;
var computedHorizonQuad;
var cartographics = [];
var successfulPickCount = 0;
function addToResult(x, y, index) {
scratchPickCartesian2.x = x;
scratchPickCartesian2.y = y;
var r = that.pickEllipsoid(scratchPickCartesian2, ellipsoid, new Cartesian3());
if (defined(r)) {
cartographics.push(ellipsoid.cartesianToCartographic(r));
++successfulPickCount;
} else {
if (!defined(computedHorizonQuad)) {
computedHorizonQuad = computeHorizonQuad(that, ellipsoid);
}
cartographics.push(ellipsoid.cartesianToCartographic(computedHorizonQuad[index]));
}
}

addToResult(0, 0, 0);
addToResult(0, height, 1);
addToResult(width, height, 2);
addToResult(width, 0, 3);
var computedHorizonQuad = computeHorizonQuad(this, ellipsoid);

successfulPickCount += addToResult(0, 0, 0, this, ellipsoid, computedHorizonQuad);
successfulPickCount += addToResult(0, height, 1, this, ellipsoid, computedHorizonQuad);
successfulPickCount += addToResult(width, height, 2, this, ellipsoid, computedHorizonQuad);
successfulPickCount += addToResult(width, 0, 3, this, ellipsoid, computedHorizonQuad);

if (successfulPickCount === 0 || successfulPickCount === 1) {
if (successfulPickCount < 2) {
// If we have space non-globe in 3 or 4 corners then return the whole globe
return Rectangle.MAX_VALUE;
}

var i;
var point;
var cartographicsCount = cartographics.length;
result = Rectangle.fromCartographicArray(cartoArray, result);

// Detect if we go over the poles
var distance = 0;
var lastLon = cartographics[cartographicsCount-1].longitude;
for (i=0;i<cartographicsCount;++i) {
point = cartographics[i];
var lon = point.longitude;
var lastLon = cartoArray[3].longitude;
for (var i = 0; i < 4; ++i) {
var lon = cartoArray[i].longitude;
var diff = Math.abs(lon - lastLon);
if (diff > CesiumMath.PI) {
// Crossed the dateline
Expand All @@ -2872,22 +2866,11 @@ define([
lastLon = lon;
}

var result;
for(i=0;i<cartographicsCount;++i) {
point = cartographics[i];
if (!defined(result)) {
result = new Rectangle(point.longitude, point.latitude,
point.longitude, point.latitude);
} else {
Rectangle.expand(result, point, result);
}
}

// We are over one of the poles so adjust the rectangle accordingly
if (CesiumMath.equalsEpsilon(Math.abs(distance), CesiumMath.TWO_PI, CesiumMath.EPSILON9)) {
result.west = -CesiumMath.PI;
result.east = CesiumMath.PI;
if (cartographics[0].latitude >= 0.0) {
if (cartoArray[0].latitude >= 0.0) {
result.north = CesiumMath.PI_OVER_TWO;
} else {
result.south = -CesiumMath.PI_OVER_TWO;
Expand Down
27 changes: 23 additions & 4 deletions Specs/Scene/CameraSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2350,7 +2350,7 @@ defineSuite([
}).toThrowDeveloperError();
});

it('computeViewRegion when zoomed in', function() {
it('computeViewRectangle when zoomed in', function() {
scene.mode = SceneMode.SCENE3D;

var position = Cartesian3.clone(Cartesian3.UNIT_X);
Expand All @@ -2367,20 +2367,39 @@ defineSuite([
expect(rect).toEqual(correctResult);
});

it('computeViewRegion when zoomed in to pole', function() {
it('computeViewRectangle when zoomed in to pole', function() {
scene.mode = SceneMode.SCENE3D;

var position = Cartesian3.clone(Cartesian3.UNIT_Z);
Cartesian3.multiplyByScalar(position, 7000000, position);
camera.position = position;
camera.up = Cartesian3.clone(Cartesian3.UNIT_Y);
camera.direction = Cartesian3.negate(Cartesian3.UNIT_Z, new Cartesian3());
camera.right = Cartesian3.cross(camera.direction, camera.up, new Cartesian3());

var correctResult = new Rectangle(-CesiumMath.PI, 1.4961779388065022, CesiumMath.PI, CesiumMath.PI_OVER_TWO);

var rect = camera.computeViewRectangle();
expect(rect).toEqual(correctResult);
});

it('computeViewRegion when zoomed out', function() {
it('computeViewRectangle when zoomed in to IDL', function() {
scene.mode = SceneMode.SCENE3D;

var position = Cartesian3.negate(Cartesian3.UNIT_X, new Cartesian3());
Cartesian3.multiplyByScalar(position, 7000000, position);
camera.position = position;
camera.up = Cartesian3.clone(Cartesian3.UNIT_Z);
camera.direction = Cartesian3.clone(Cartesian3.UNIT_X, new Cartesian3());
camera.right = Cartesian3.cross(camera.direction, camera.up, new Cartesian3());

var correctResult = new Rectangle(3.0837016481160435, -0.04365869998457809, -3.0837016481160435, 0.04365869998457809);

var rect = camera.computeViewRectangle();
expect(rect).toEqual(correctResult);
});

it('computeViewRectangle when zoomed out', function() {
scene.mode = SceneMode.SCENE3D;

var position = Cartesian3.clone(Cartesian3.UNIT_X);
Expand All @@ -2395,7 +2414,7 @@ defineSuite([
expect(rect).toEqual(Rectangle.MAX_VALUE);
});

it('computeViewRegion when globe isn\'t visible', function() {
it('computeViewRectangle when globe isn\'t visible', function() {
scene.mode = SceneMode.SCENE3D;

var position = Cartesian3.clone(Cartesian3.UNIT_X);
Expand Down