diff --git a/CHANGES.md b/CHANGES.md index fed1bfdf8063..92c974dbf306 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -9,6 +9,7 @@ Change Log * Added `CoplanarPolygonGeometry` and `CoplanarPolygonGeometryOutline` for drawing polygons composed of coplanar positions that are not necessarily on the ellipsoid surface. [#6769](https://github.com/AnalyticalGraphicsInc/cesium/pull/6769) * Improved support for polygon entities using `perPositionHeight`, including supporting vertical polygons. This also improves KML compatibility. [#6791](https://github.com/AnalyticalGraphicsInc/cesium/pull/6791) * Added `Cartesian3.midpoint` to compute the midpoint between two `Cartesian3` positions [#6836](https://github.com/AnalyticalGraphicsInc/cesium/pull/6836) +* Added `equalsEpsilon` methods to `OrthographicFrustum`, `PerspectiveFrustum`, `OrthographicOffCenterFrustum` and `PerspectiveOffCenterFrustum`. ##### Deprecated :hourglass_flowing_sand: * Support for 3D Tiles `content.url` is deprecated to reflect updates to the [3D Tiles spec](https://github.com/AnalyticalGraphicsInc/3d-tiles/pull/301). Use `content.uri instead`. Support for `content.url` will remain for backwards compatibility. [#6744](https://github.com/AnalyticalGraphicsInc/cesium/pull/6744) @@ -31,6 +32,7 @@ Change Log * Fixed a bug that caused billboard positions to be set incorrectly when using a `CallbackProperty`. [#6815](https://github.com/AnalyticalGraphicsInc/cesium/pull/6815) * Improved support for generating a TypeScript typings file using `tsd-jsdoc` [#6767](https://github.com/AnalyticalGraphicsInc/cesium/pull/6767) * Updated viewBoundingSphere to use correct zoomOptions [#6848](https://github.com/AnalyticalGraphicsInc/cesium/issues/6848) +* Fixed a bug that caused the scene to continuously render after resizing the viewer when `requestRenderMode` was enabled. [#6812](https://github.com/AnalyticalGraphicsInc/cesium/issues/6812) ### 1.47 - 2018-07-02 diff --git a/Source/Core/OrthographicFrustum.js b/Source/Core/OrthographicFrustum.js index b2dd5ef7e074..f3c38bd6e30e 100644 --- a/Source/Core/OrthographicFrustum.js +++ b/Source/Core/OrthographicFrustum.js @@ -4,6 +4,7 @@ define([ './defined', './defineProperties', './DeveloperError', + './Math', './OrthographicOffCenterFrustum' ], function( Check, @@ -11,6 +12,7 @@ define([ defined, defineProperties, DeveloperError, + CesiumMath, OrthographicOffCenterFrustum) { 'use strict'; @@ -268,10 +270,31 @@ define([ return (this.width === other.width && this.aspectRatio === other.aspectRatio && - this.near === other.near && - this.far === other.far && this._offCenterFrustum.equals(other._offCenterFrustum)); }; + /** + * Compares the provided OrthographicFrustum componentwise and returns + * true if they pass an absolute or relative tolerance test, + * false otherwise. + * + * @param {OrthographicFrustum} other The right hand side OrthographicFrustum. + * @param {Number} relativeEpsilon The relative epsilon tolerance to use for equality testing. + * @param {Number} [absoluteEpsilon=relativeEpsilon] The absolute epsilon tolerance to use for equality testing. + * @returns {Boolean} true if this and other are within the provided epsilon, false otherwise. + */ + OrthographicFrustum.prototype.equalsEpsilon = function(other, relativeEpsilon, absoluteEpsilon) { + if (!defined(other) || !(other instanceof OrthographicFrustum)) { + return false; + } + + update(this); + update(other); + + return (CesiumMath.equalsEpsilon(this.width, other.width, relativeEpsilon, absoluteEpsilon) && + CesiumMath.equalsEpsilon(this.aspectRatio, other.aspectRatio, relativeEpsilon, absoluteEpsilon) && + this._offCenterFrustum.equalsEpsilon(other._offCenterFrustum, relativeEpsilon, absoluteEpsilon)); + }; + return OrthographicFrustum; }); diff --git a/Source/Core/OrthographicOffCenterFrustum.js b/Source/Core/OrthographicOffCenterFrustum.js index 09877fba03b2..f66f76595cd0 100644 --- a/Source/Core/OrthographicOffCenterFrustum.js +++ b/Source/Core/OrthographicOffCenterFrustum.js @@ -6,6 +6,7 @@ define([ './defined', './defineProperties', './DeveloperError', + './Math', './Matrix4' ], function( Cartesian3, @@ -15,6 +16,7 @@ define([ defined, defineProperties, DeveloperError, + CesiumMath, Matrix4) { 'use strict'; @@ -370,5 +372,27 @@ define([ this.far === other.far); }; + /** + * Compares the provided OrthographicOffCenterFrustum componentwise and returns + * true if they pass an absolute or relative tolerance test, + * false otherwise. + * + * @param {OrthographicOffCenterFrustum} other The right hand side OrthographicOffCenterFrustum. + * @param {Number} relativeEpsilon The relative epsilon tolerance to use for equality testing. + * @param {Number} [absoluteEpsilon=relativeEpsilon] The absolute epsilon tolerance to use for equality testing. + * @returns {Boolean} true if this and other are within the provided epsilon, false otherwise. + */ + OrthographicOffCenterFrustum.prototype.equalsEpsilon = function(other, relativeEpsilon, absoluteEpsilon) { + return (other === this) || + (defined(other) && + other instanceof OrthographicOffCenterFrustum && + CesiumMath.equalsEpsilon(this.right, other.right, relativeEpsilon, absoluteEpsilon) && + CesiumMath.equalsEpsilon(this.left, other.left, relativeEpsilon, absoluteEpsilon) && + CesiumMath.equalsEpsilon(this.top, other.top, relativeEpsilon, absoluteEpsilon) && + CesiumMath.equalsEpsilon(this.bottom, other.bottom, relativeEpsilon, absoluteEpsilon) && + CesiumMath.equalsEpsilon(this.near, other.near, relativeEpsilon, absoluteEpsilon) && + CesiumMath.equalsEpsilon(this.far, other.far, relativeEpsilon, absoluteEpsilon)); + }; + return OrthographicOffCenterFrustum; }); diff --git a/Source/Core/PerspectiveFrustum.js b/Source/Core/PerspectiveFrustum.js index 3186170bbd77..a992c0ddfc57 100644 --- a/Source/Core/PerspectiveFrustum.js +++ b/Source/Core/PerspectiveFrustum.js @@ -4,6 +4,7 @@ define([ './defined', './defineProperties', './DeveloperError', + './Math', './PerspectiveOffCenterFrustum' ], function( Check, @@ -11,6 +12,7 @@ define([ defined, defineProperties, DeveloperError, + CesiumMath, PerspectiveOffCenterFrustum) { 'use strict'; @@ -363,10 +365,31 @@ define([ return (this.fov === other.fov && this.aspectRatio === other.aspectRatio && - this.near === other.near && - this.far === other.far && this._offCenterFrustum.equals(other._offCenterFrustum)); }; + /** + * Compares the provided PerspectiveFrustum componentwise and returns + * true if they pass an absolute or relative tolerance test, + * false otherwise. + * + * @param {PerspectiveFrustum} other The right hand side PerspectiveFrustum. + * @param {Number} relativeEpsilon The relative epsilon tolerance to use for equality testing. + * @param {Number} [absoluteEpsilon=relativeEpsilon] The absolute epsilon tolerance to use for equality testing. + * @returns {Boolean} true if this and other are within the provided epsilon, false otherwise. + */ + PerspectiveFrustum.prototype.equalsEpsilon = function(other, relativeEpsilon, absoluteEpsilon) { + if (!defined(other) || !(other instanceof PerspectiveFrustum)) { + return false; + } + + update(this); + update(other); + + return (CesiumMath.equalsEpsilon(this.fov, other.fov, relativeEpsilon, absoluteEpsilon) && + CesiumMath.equalsEpsilon(this.aspectRatio, other.aspectRatio, relativeEpsilon, absoluteEpsilon) && + this._offCenterFrustum.equalsEpsilon(other._offCenterFrustum, relativeEpsilon, absoluteEpsilon)); + }; + return PerspectiveFrustum; }); diff --git a/Source/Core/PerspectiveOffCenterFrustum.js b/Source/Core/PerspectiveOffCenterFrustum.js index 30319a5b2556..fd8d5c0aec93 100644 --- a/Source/Core/PerspectiveOffCenterFrustum.js +++ b/Source/Core/PerspectiveOffCenterFrustum.js @@ -6,6 +6,7 @@ define([ './defined', './defineProperties', './DeveloperError', + './Math', './Matrix4' ], function( Cartesian3, @@ -15,6 +16,7 @@ define([ defined, defineProperties, DeveloperError, + CesiumMath, Matrix4) { 'use strict'; @@ -421,5 +423,27 @@ define([ this.far === other.far); }; + /** + * Compares the provided PerspectiveOffCenterFrustum componentwise and returns + * true if they pass an absolute or relative tolerance test, + * false otherwise. + * + * @param {PerspectiveOffCenterFrustum} other The right hand side PerspectiveOffCenterFrustum. + * @param {Number} relativeEpsilon The relative epsilon tolerance to use for equality testing. + * @param {Number} [absoluteEpsilon=relativeEpsilon] The absolute epsilon tolerance to use for equality testing. + * @returns {Boolean} true if this and other are within the provided epsilon, false otherwise. + */ + PerspectiveOffCenterFrustum.prototype.equalsEpsilon = function(other, relativeEpsilon, absoluteEpsilon) { + return (other === this) || + (defined(other) && + other instanceof PerspectiveOffCenterFrustum && + CesiumMath.equalsEpsilon(this.right, other.right, relativeEpsilon, absoluteEpsilon) && + CesiumMath.equalsEpsilon(this.left, other.left, relativeEpsilon, absoluteEpsilon) && + CesiumMath.equalsEpsilon(this.top, other.top, relativeEpsilon, absoluteEpsilon) && + CesiumMath.equalsEpsilon(this.bottom, other.bottom, relativeEpsilon, absoluteEpsilon) && + CesiumMath.equalsEpsilon(this.near, other.near, relativeEpsilon, absoluteEpsilon) && + CesiumMath.equalsEpsilon(this.far, other.far, relativeEpsilon, absoluteEpsilon)); + }; + return PerspectiveOffCenterFrustum; }); diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 3aa69baa88e6..e2d7458bad5c 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -1488,7 +1488,8 @@ define([ Cartesian3.equalsEpsilon(camera0.direction, camera1.direction, epsilon) && Cartesian3.equalsEpsilon(camera0.up, camera1.up, epsilon) && Cartesian3.equalsEpsilon(camera0.right, camera1.right, epsilon) && - Matrix4.equalsEpsilon(camera0.transform, camera1.transform, epsilon); + Matrix4.equalsEpsilon(camera0.transform, camera1.transform, epsilon) && + camera0.frustum.equalsEpsilon(camera1.frustum, epsilon); } function updateDerivedCommands(scene, command) { @@ -3172,13 +3173,17 @@ define([ function checkForCameraUpdates(scene) { var camera = scene._camera; - if (!cameraEqual(camera, scene._cameraClone, CesiumMath.EPSILON15)) { + var cameraClone = scene._cameraClone; + + scene._frustumChanged = !camera.frustum.equals(cameraClone.frustum); + + if (!cameraEqual(camera, cameraClone, CesiumMath.EPSILON15)) { if (!scene._cameraStartFired) { camera.moveStart.raiseEvent(); scene._cameraStartFired = true; } scene._cameraMovedTime = getTimestamp(); - Camera.clone(camera, scene._cameraClone); + Camera.clone(camera, cameraClone); return true; } @@ -3310,10 +3315,8 @@ define([ tryAndCatchError(this, time, update); this._postUpdate.raiseEvent(this, time); - this._frustumChanged = !this._camera.frustum.equals(this._cameraClone.frustum); - var cameraChanged = checkForCameraUpdates(this); - var shouldRender = !this.requestRenderMode || this._renderRequested || cameraChanged || this._frustumChanged || this._logDepthBufferDirty || (this.mode === SceneMode.MORPHING); + var shouldRender = !this.requestRenderMode || this._renderRequested || cameraChanged || this._logDepthBufferDirty || (this.mode === SceneMode.MORPHING); if (!shouldRender && defined(this.maximumRenderTimeChange) && defined(this._lastRenderTime)) { var difference = Math.abs(JulianDate.secondsDifference(this._lastRenderTime, time)); shouldRender = shouldRender || difference > this.maximumRenderTimeChange; diff --git a/Specs/Core/OrthographicFrustumSpec.js b/Specs/Core/OrthographicFrustumSpec.js index 4ac99bd4e0ec..d3b6c786650f 100644 --- a/Specs/Core/OrthographicFrustumSpec.js +++ b/Specs/Core/OrthographicFrustumSpec.js @@ -175,6 +175,42 @@ defineSuite([ expect(pixelSize.y).toEqual(2.0); }); + it('equals', function() { + var frustum2 = new OrthographicFrustum(); + frustum2.near = 1.0; + frustum2.far = 3.0; + frustum2.width = 2.0; + frustum2.aspectRatio = 1.0; + expect(frustum.equals(frustum2)).toEqual(true); + }); + + it('equals epsilon', function() { + var frustum2 = new OrthographicFrustum(); + frustum2.near = 1.0; + frustum2.far = 3.0; + frustum2.width = 2.0; + frustum2.aspectRatio = 1.0; + expect(frustum.equalsEpsilon(frustum2, CesiumMath.EPSILON7)).toEqual(true); + + var frustum3 = new OrthographicFrustum(); + frustum3.near = 1.01; + frustum3.far = 3.01; + frustum3.width = 2.01; + frustum3.aspectRatio = 1.01; + expect(frustum.equalsEpsilon(frustum3, CesiumMath.EPSILON1)).toEqual(true); + + var frustum4 = new OrthographicFrustum(); + frustum4.near = 1.0; + frustum4.far = 3.0; + frustum4.width = 2.0; + frustum4.aspectRatio = 1.1; + expect(frustum.equalsEpsilon(frustum4, CesiumMath.EPSILON2)).toEqual(false); + }); + + it('equals undefined', function() { + expect(frustum.equals()).toEqual(false); + }); + it('throws with undefined frustum parameters', function() { var frustum = new OrthographicFrustum(); expect(function() { diff --git a/Specs/Core/OrthographicOffCenterFrustumSpec.js b/Specs/Core/OrthographicOffCenterFrustumSpec.js index a81c88f087dc..856ac0dcc121 100644 --- a/Specs/Core/OrthographicOffCenterFrustumSpec.js +++ b/Specs/Core/OrthographicOffCenterFrustumSpec.js @@ -176,6 +176,51 @@ defineSuite([ expect(pixelSize.y).toEqual(2.0); }); + it('equals', function() { + var frustum2 = new OrthographicOffCenterFrustum(); + frustum2.near = 1.0; + frustum2.far = 3.0; + frustum2.right = 1.0; + frustum2.left = -1.0; + frustum2.top = 1.0; + frustum2.bottom = -1.0; + + expect(frustum).toEqual(frustum2); + }); + + it('equals epsilon', function() { + var frustum2 = new OrthographicOffCenterFrustum(); + frustum2.near = 1.0; + frustum2.far = 3.0; + frustum2.right = 1.0; + frustum2.left = -1.0; + frustum2.top = 1.0; + frustum2.bottom = -1.0; + expect(frustum.equalsEpsilon(frustum2, CesiumMath.EPSILON7)).toEqual(true); + + var frustum3 = new OrthographicOffCenterFrustum(); + frustum3.near = 1.01; + frustum3.far = 2.98; + frustum3.right = 1.02; + frustum3.left = -0.99; + frustum3.top = 0.99; + frustum3.bottom = -1.05; + expect(frustum.equalsEpsilon(frustum3, CesiumMath.EPSILON1)).toEqual(true); + + var frustum4 = new OrthographicOffCenterFrustum(); + frustum4.near = 1.1; + frustum4.far = 2.9; + frustum4.right = 0.0; + frustum4.left = -1.02; + frustum4.top = 1.02; + frustum4.bottom = -1.005; + expect(frustum.equalsEpsilon(frustum4, CesiumMath.EPSILON2)).toEqual(false); + }); + + it('equals undefined', function() { + expect(frustum.equals()).toEqual(false); + }); + it('throws with undefined frustum parameters', function() { var frustum = new OrthographicOffCenterFrustum(); expect(function() { diff --git a/Specs/Core/PerspectiveFrustumSpec.js b/Specs/Core/PerspectiveFrustumSpec.js index 7682b09d6ffc..4ec7d5a17f64 100644 --- a/Specs/Core/PerspectiveFrustumSpec.js +++ b/Specs/Core/PerspectiveFrustumSpec.js @@ -180,6 +180,29 @@ defineSuite([ expect(frustum.equals(frustum2)).toEqual(true); }); + it('equals epsilon', function() { + var frustum2 = new PerspectiveFrustum(); + frustum2.near = 1.0; + frustum2.far = 2.0; + frustum2.fov = (Math.PI) / 3.0; + frustum2.aspectRatio = 1.0; + expect(frustum.equalsEpsilon(frustum2, CesiumMath.EPSILON7)).toEqual(true); + + var frustum3 = new PerspectiveFrustum(); + frustum3.near = 1.01; + frustum3.far = 2.01; + frustum3.fov = ((Math.PI) / 3.0) + 0.01; + frustum3.aspectRatio = 1.01; + expect(frustum.equalsEpsilon(frustum3, CesiumMath.EPSILON1)).toEqual(true); + + var frustum4 = new PerspectiveFrustum(); + frustum4.near = 1.0; + frustum4.far = 2.0; + frustum4.fov = (Math.PI) / 3.0; + frustum4.aspectRatio = 1.1; + expect(frustum.equalsEpsilon(frustum4, CesiumMath.EPSILON2)).toEqual(false); + }); + it('equals undefined', function() { expect(frustum.equals()).toEqual(false); }); diff --git a/Specs/Core/PerspectiveOffCenterFrustumSpec.js b/Specs/Core/PerspectiveOffCenterFrustumSpec.js index 937f0d2a499f..39d49da802c7 100644 --- a/Specs/Core/PerspectiveOffCenterFrustumSpec.js +++ b/Specs/Core/PerspectiveOffCenterFrustumSpec.js @@ -195,6 +195,39 @@ defineSuite([ expect(frustum).toEqual(frustum2); }); + it('equals epsilon', function() { + var frustum2 = new PerspectiveOffCenterFrustum(); + frustum2.right = 1.0; + frustum2.left = -frustum.right; + frustum2.top = 1.0; + frustum2.bottom = -frustum.top; + frustum2.near = 1.0; + frustum2.far = 2.0; + expect(frustum.equalsEpsilon(frustum2, CesiumMath.EPSILON7)).toEqual(true); + + var frustum3 = new PerspectiveOffCenterFrustum(); + frustum3.right = 1.01; + frustum3.left = -frustum.right; + frustum3.top = 1.01; + frustum3.bottom = -frustum.top; + frustum3.near = 1.01; + frustum3.far = 1.99; + expect(frustum.equalsEpsilon(frustum3, CesiumMath.EPSILON1)).toEqual(true); + + var frustum4 = new PerspectiveOffCenterFrustum(); + frustum4.right = 1.1; + frustum4.left = -frustum.right; + frustum4.top = 1.0; + frustum4.bottom = -frustum.top; + frustum4.near = 1.0; + frustum4.far = 2.0; + expect(frustum.equalsEpsilon(frustum4, CesiumMath.EPSILON2)).toEqual(false); + }); + + it('equals undefined', function() { + expect(frustum.equals()).toEqual(false); + }); + it('throws with undefined frustum parameters', function() { var frustum = new PerspectiveOffCenterFrustum(); expect(function() { diff --git a/Specs/Scene/SceneSpec.js b/Specs/Scene/SceneSpec.js index c9bbbb8073a8..3faf61d56441 100644 --- a/Specs/Scene/SceneSpec.js +++ b/Specs/Scene/SceneSpec.js @@ -1357,6 +1357,32 @@ defineSuite([ scene.destroyForSpecs(); }); + it('changing the camera frustum does not cause continuous rendering in requestRenderMode', function() { + var scene = createScene(); + + scene.renderForSpecs(); + + var lastRenderTime = JulianDate.clone(scene.lastRenderTime, scratchTime); + expect(lastRenderTime).toBeDefined(); + expect(scene._renderRequested).toBe(false); + + scene.requestRenderMode = true; + scene.maximumRenderTimeChange = undefined; + + scene.camera.frustum.near *= 1.1; + + // Render once properly + scene.renderForSpecs(); + expect(scene.lastRenderTime).not.toEqual(lastRenderTime); + + // Render again - but this time nothing should happen. + lastRenderTime = JulianDate.clone(scene.lastRenderTime, scratchTime); + scene.renderForSpecs(); + expect(scene.lastRenderTime).toEqual(lastRenderTime); + + scene.destroyForSpecs(); + }); + it('successful completed requests causes a new frame to be rendered in requestRenderMode', function() { var scene = createScene();