From e6d6aa8ea9c19f792e4694acfd179de54b815574 Mon Sep 17 00:00:00 2001 From: Kangning Li Date: Fri, 27 May 2016 14:52:13 -0400 Subject: [PATCH 01/33] Added HSB color shifting to the atmosphere and a demo in sandbox. Updated CHANGES.md --- .../gallery/Atmosphere HSB Color.html | 108 ++++++++++++++++++ .../gallery/Atmosphere HSB Color.jpg | Bin 0 -> 9202 bytes CHANGES.md | 1 + Source/Scene/SkyAtmosphere.js | 31 +++++ Source/Shaders/SkyAtmosphereFS.glsl | 35 +++++- 5 files changed, 174 insertions(+), 1 deletion(-) create mode 100644 Apps/Sandcastle/gallery/Atmosphere HSB Color.html create mode 100644 Apps/Sandcastle/gallery/Atmosphere HSB Color.jpg diff --git a/Apps/Sandcastle/gallery/Atmosphere HSB Color.html b/Apps/Sandcastle/gallery/Atmosphere HSB Color.html new file mode 100644 index 000000000000..38667ba8183d --- /dev/null +++ b/Apps/Sandcastle/gallery/Atmosphere HSB Color.html @@ -0,0 +1,108 @@ + + + + + + + + + Cesium Demo + + + + + + +
+

Loading...

+
+ + + + + + + + + + + + + +
hueShift + + +
saturationShift + + +
brightnessShift + + +
+
+
+ + + diff --git a/Apps/Sandcastle/gallery/Atmosphere HSB Color.jpg b/Apps/Sandcastle/gallery/Atmosphere HSB Color.jpg new file mode 100644 index 0000000000000000000000000000000000000000..81efb03aaf2aa8014edd33df69691b0b18d4c7f3 GIT binary patch literal 9202 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 literal 0 HcmV?d00001 diff --git a/CHANGES.md b/CHANGES.md index 8913bcf7cd08..22d772ef9f72 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -27,6 +27,7 @@ Change Log * Added `Scene.nearToFarDistance2D` that determines the size of each frustum of the multifrustum in 2D. * Added support for rendering models in 2D and Columbus view. * Fixed a bug that was causing the atmosphere to disappear when only atmosphere is visible. [#3347](https://github.com/AnalyticalGraphicsInc/cesium/issues/3347) +* Added support for hue, saturation, and brightness color shifts in the atmosphere in `SkyAtmosphere` [3439](https://github.com/AnalyticalGraphicsInc/cesium/issues/3439) ### 1.21 - 2016-05-02 diff --git a/Source/Scene/SkyAtmosphere.js b/Source/Scene/SkyAtmosphere.js index 6c28879bd86d..10e503f40e38 100644 --- a/Source/Scene/SkyAtmosphere.js +++ b/Source/Scene/SkyAtmosphere.js @@ -80,6 +80,31 @@ define([ }); this._spSkyFromSpace = undefined; this._spSkyFromAtmosphere = undefined; + + // hue, saturation, and brightness shift values for color adjustment + /** + * The hue shift to apply to the atmosphere. Defaults to 0.0 (no shift). + * @type {Number} + * @default 0.0 + */ + this.hueShift = 0.0; + + /** + * The saturation shift to apply to the atmosphere. Defaults to 0.0 (no shift). + * @type {Number} + * @default 0.0 + */ + this.saturationShift = 0.0; + + /** + * The brightness shift to apply to the atmosphere. Defaults to 0.0 (no shift). + * @type {Number} + * @default 0.0 + */ + this.brightnessShift = 0.0; + + var hsbScratch = new Cartesian3(this.hueShift, this.saturationShift, this.brightnessShift); + this._hsbScratch = hsbScratch; // camera height, outer radius, inner radius, dynamic atmosphere color flag var cameraAndRadiiAndDynamicAtmosphereColor = new Cartesian4(); @@ -96,6 +121,12 @@ define([ this._command.uniformMap = { cameraAndRadiiAndDynamicAtmosphereColor : function() { return that._cameraAndRadiiAndDynamicAtmosphereColor; + }, + u_hsvShift : function() { + hsbScratch.x = that.hueShift; + hsbScratch.y = that.saturationShift; + hsbScratch.z = that.brightnessShift; + return that._hsbScratch; } }; } diff --git a/Source/Shaders/SkyAtmosphereFS.glsl b/Source/Shaders/SkyAtmosphereFS.glsl index 5e9b75eab92c..9fbc3dab360b 100644 --- a/Source/Shaders/SkyAtmosphereFS.glsl +++ b/Source/Shaders/SkyAtmosphereFS.glsl @@ -32,15 +32,38 @@ // Code: http://sponeil.net/ // GPU Gems 2 Article: http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter16.html - + // HSV <-> RGB conversion with minimal branching: http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl + +uniform vec3 u_hsvShift; // hue, saturation, value + const float g = -0.95; const float g2 = g * g; +const float epsilon = 1.0e-10; +const vec4 K_RGB2HSB = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); +const vec4 K_HSB2RGB = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + varying vec3 v_rayleighColor; varying vec3 v_mieColor; varying vec3 v_toCamera; varying vec3 v_positionEC; +vec3 rgb2hsb(vec3 rgbColor) +{ + vec4 p = mix(vec4(rgbColor.bg, K_RGB2HSB.wz), vec4(rgbColor.gb, K_RGB2HSB.xy), step(rgbColor.b, rgbColor.g)); + vec4 q = mix(vec4(p.xyw, rgbColor.r), vec4(rgbColor.r, p.yzx), step(p.x, rgbColor.r)); + + float d = q.x - min(q.w, q.y); + float e = 1.0e-10; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); +} + +vec3 hsb2rgb(vec3 hsbColor) +{ + vec3 p = abs(fract(hsbColor.xxx + K_HSB2RGB.xyz) * 6.0 - K_HSB2RGB.www); + return hsbColor.z * mix(K_HSB2RGB.xxx, clamp(p - K_HSB2RGB.xxx, 0.0, 1.0), hsbColor.y); +} + void main (void) { // Extra normalize added for Android @@ -52,6 +75,16 @@ void main (void) vec3 rgb = rayleighPhase * v_rayleighColor + miePhase * v_mieColor; rgb = vec3(1.0) - exp(-exposure * rgb); + + // convert rgb color to hsv + vec3 hsv = rgb2hsb(rgb); + // perform hsv shift + hsv.x += u_hsvShift.x; // hue + hsv.y = clamp(hsv.y + u_hsvShift.y, 0.0, 1.0); // saturation + hsv.z += u_hsvShift.z; // brightness + // convert shifted hsv back to rgb + rgb = hsb2rgb(hsv); + float l = czm_luminance(rgb); gl_FragColor = vec4(rgb, min(smoothstep(0.0, 0.1, l), 1.0) * smoothstep(0.0, 1.0, czm_morphTime)); } From 8d6d235a1ec863b0e7a3bae809e3f4e48791c44d Mon Sep 17 00:00:00 2001 From: Kangning Li Date: Fri, 27 May 2016 15:23:24 -0400 Subject: [PATCH 02/33] Moved luminance calculation to prevent weird night skies with brightness shift. --- Source/Shaders/SkyAtmosphereFS.glsl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Source/Shaders/SkyAtmosphereFS.glsl b/Source/Shaders/SkyAtmosphereFS.glsl index 9fbc3dab360b..52b1f1fdddcc 100644 --- a/Source/Shaders/SkyAtmosphereFS.glsl +++ b/Source/Shaders/SkyAtmosphereFS.glsl @@ -75,16 +75,17 @@ void main (void) vec3 rgb = rayleighPhase * v_rayleighColor + miePhase * v_mieColor; rgb = vec3(1.0) - exp(-exposure * rgb); + // compute luminance before color correction to avoid strangely gray night skies + float l = czm_luminance(rgb); // convert rgb color to hsv vec3 hsv = rgb2hsb(rgb); // perform hsv shift hsv.x += u_hsvShift.x; // hue hsv.y = clamp(hsv.y + u_hsvShift.y, 0.0, 1.0); // saturation - hsv.z += u_hsvShift.z; // brightness + hsv.z = hsv.z > epsilon ? hsv.z + u_hsvShift.z : 0.0; // brightness // convert shifted hsv back to rgb rgb = hsb2rgb(hsv); - float l = czm_luminance(rgb); gl_FragColor = vec4(rgb, min(smoothstep(0.0, 0.1, l), 1.0) * smoothstep(0.0, 1.0, czm_morphTime)); } From 078a0b594a02955e96ab63e7353a6fa0bb5a2046 Mon Sep 17 00:00:00 2001 From: Kangning Li Date: Sat, 28 May 2016 03:09:28 -0400 Subject: [PATCH 03/33] Addressed some pull request items: changed some names, updated some documentation, added some shader defines, added a test case --- ...e HSB Color.html => Atmosphere Color.html} | 29 ++++++++-- Apps/Sandcastle/gallery/Atmosphere Color.jpg | Bin 0 -> 9151 bytes .../gallery/Atmosphere HSB Color.jpg | Bin 9202 -> 0 bytes CHANGES.md | 2 +- Source/Scene/SkyAtmosphere.js | 51 ++++++++++++++---- Source/Shaders/SkyAtmosphereFS.glsl | 33 +++++++----- Specs/Scene/SkyAtmosphereSpec.js | 34 ++++++++++++ 7 files changed, 120 insertions(+), 29 deletions(-) rename Apps/Sandcastle/gallery/{Atmosphere HSB Color.html => Atmosphere Color.html} (78%) create mode 100644 Apps/Sandcastle/gallery/Atmosphere Color.jpg delete mode 100644 Apps/Sandcastle/gallery/Atmosphere HSB Color.jpg diff --git a/Apps/Sandcastle/gallery/Atmosphere HSB Color.html b/Apps/Sandcastle/gallery/Atmosphere Color.html similarity index 78% rename from Apps/Sandcastle/gallery/Atmosphere HSB Color.html rename to Apps/Sandcastle/gallery/Atmosphere Color.html index 38667ba8183d..bbe7db3c4e0b 100644 --- a/Apps/Sandcastle/gallery/Atmosphere HSB Color.html +++ b/Apps/Sandcastle/gallery/Atmosphere Color.html @@ -4,7 +4,7 @@ - + Cesium Demo @@ -56,14 +56,17 @@ +
+
diff --git a/Apps/Sandcastle/gallery/CZML Circles and Ellipses.html b/Apps/Sandcastle/gallery/CZML Circles and Ellipses.html index 44869d48ee57..e9fd0a46f533 100644 --- a/Apps/Sandcastle/gallery/CZML Circles and Ellipses.html +++ b/Apps/Sandcastle/gallery/CZML Circles and Ellipses.html @@ -1,20 +1,20 @@ - - - - - - Cesium Demo - - - + + + + + + Cesium Demo + + + +
+

Loading...

+
+ + + \ No newline at end of file diff --git a/Source/Scene/Camera.js b/Source/Scene/Camera.js index c7982733b399..2d76de818390 100644 --- a/Source/Scene/Camera.js +++ b/Source/Scene/Camera.js @@ -24,6 +24,7 @@ define([ '../Core/Rectangle', '../Core/Transforms', './CameraFlightPath', + './MapMode2D', './PerspectiveFrustum', './SceneMode' ], function( @@ -51,6 +52,7 @@ define([ Rectangle, Transforms, CameraFlightPath, + MapMode2D, PerspectiveFrustum, SceneMode) { 'use strict'; @@ -1158,7 +1160,7 @@ define([ }; function clampMove2D(camera, position) { - var rotatable2D = camera._scene.rotatable2D; + var rotatable2D = camera._scene.mapMode2D === MapMode2D.ROTATE; var maxProjectedX = camera._maxCoord.x; var maxProjectedY = camera._maxCoord.y; @@ -1541,7 +1543,7 @@ define([ var newLeft = frustum.left + amount; var maxRight = camera._maxCoord.x; - if (camera._scene.rotatable2D) { + if (camera._scene.mapMode2D === MapMode2D.ROTATE) { maxRight *= camera.maximumZoomFactor; } diff --git a/Source/Scene/MapMode2D.js b/Source/Scene/MapMode2D.js new file mode 100644 index 000000000000..235f2aa274a6 --- /dev/null +++ b/Source/Scene/MapMode2D.js @@ -0,0 +1,32 @@ +/*global define*/ +define([ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + + /** + * Describes how the map will operate in 2D. + * + * @exports MapMode2D + */ + var MapMode2D = { + /** + * The 2D map can be rotated about the z axis. + * + * @type {Number} + * @constant + */ + ROTATE : 0, + + /** + * The 2D map can be scrolled infinitely in the horizontal direction. + * + * @type {Number} + * @constant + */ + INFINITE_SCROLL : 1 + }; + + return freezeObject(MapMode2D); +}); diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 90254b25a727..4372c8f2af92 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -48,6 +48,7 @@ define([ './FrustumCommands', './FXAA', './GlobeDepth', + './MapMode2D', './OIT', './OrthographicFrustum', './Pass', @@ -114,6 +115,7 @@ define([ FrustumCommands, FXAA, GlobeDepth, + MapMode2D, OIT, OrthographicFrustum, Pass, @@ -185,7 +187,7 @@ define([ * @param {Boolean} [options.scene3DOnly=false] If true, optimizes memory use and performance for 3D mode but disables the ability to use 2D or Columbus View. * @param {Number} [options.terrainExaggeration=1.0] A scalar used to exaggerate the terrain. Note that terrain exaggeration will not modify any other primitive as they are positioned relative to the ellipsoid. * @param {Boolean} [options.shadows=false] Determines if shadows are cast by the sun. - * @param {Boolean} [options.rotatable2D=false] Determines if the 2D map is rotatable or can be scrolled infinitely in the horizontal direction. + * @param {MapMode2D} [options.mapMode2D=MapMode2D.INFINITE_SCROLL] Determines if the 2D map is rotatable or can be scrolled infinitely in the horizontal direction. * * @see CesiumWidget * @see {@link http://www.khronos.org/registry/webgl/specs/latest/#5.2|WebGLContextAttributes} @@ -574,7 +576,7 @@ define([ this._camera = camera; this._cameraClone = Camera.clone(camera); this._screenSpaceCameraController = new ScreenSpaceCameraController(this); - this._rotatable2D = defaultValue(options.rotatable2D, false); + this._mapMode2D = defaultValue(options.mapMode2D, MapMode2D.INFINITE_SCROLL); // Keeps track of the state of a frame. FrameState is the state across // the primitives of the scene. This state is for internally keeping track @@ -1071,9 +1073,9 @@ define([ * @memberof Scene.prototype * @type {Boolean} */ - rotatable2D : { + mapMode2D : { get : function() { - return this._rotatable2D; + return this._mapMode2D; } } }); @@ -1953,7 +1955,7 @@ define([ viewport.width = context.drawingBufferWidth; viewport.height = context.drawingBufferHeight; - if (mode !== SceneMode.SCENE2D || scene._rotatable2D) { + if (mode !== SceneMode.SCENE2D || scene._mapMode2D === MapMode2D.ROTATE) { executeCommandsInViewport(true, scene, passState, backgroundColor, picking); } else { execute2DViewportCommands(scene, passState, backgroundColor, picking); diff --git a/Source/Scene/ScreenSpaceCameraController.js b/Source/Scene/ScreenSpaceCameraController.js index 751483f81376..07516af37da1 100644 --- a/Source/Scene/ScreenSpaceCameraController.js +++ b/Source/Scene/ScreenSpaceCameraController.js @@ -21,6 +21,7 @@ define([ '../Core/Transforms', './CameraEventAggregator', './CameraEventType', + './MapMode2D', './SceneMode', './SceneTransforms', './TweenCollection' @@ -46,6 +47,7 @@ define([ Transforms, CameraEventAggregator, CameraEventType, + MapMode2D, SceneMode, SceneTransforms, TweenCollection) { @@ -656,7 +658,7 @@ define([ } function update2D(controller) { - var rotatable2D = controller._scene.rotatable2D; + var rotatable2D = controller._scene.mapMode2D === MapMode2D.ROTATE; if (!Matrix4.equals(Matrix4.IDENTITY, controller._scene.camera.transform)) { reactToInput(controller, controller.enableZoom, controller.zoomEventTypes, zoom2D, controller.inertiaZoom, '_lastInertiaZoomMovement'); if (rotatable2D) { diff --git a/Source/Widgets/CesiumWidget/CesiumWidget.js b/Source/Widgets/CesiumWidget/CesiumWidget.js index f0f499cc8ac5..aab48545dc10 100644 --- a/Source/Widgets/CesiumWidget/CesiumWidget.js +++ b/Source/Widgets/CesiumWidget/CesiumWidget.js @@ -161,7 +161,7 @@ define([ * @param {Number} [options.terrainExaggeration=1.0] A scalar used to exaggerate the terrain. Note that terrain exaggeration will not modify any other primitive as they are positioned relative to the ellipsoid. * @param {Boolean} [options.shadows=false] Determines if shadows are cast by the sun. * @param {Boolean} [options.terrainShadows=false] Determines if the terrain casts shadows from the sun. - * @param {Boolean} [options.rotatable2D=false] Determines if the 2D map is rotatable or can be scrolled infinitely in the horizontal direction. + * @param {MapMode2D} [options.mapMode2D=MapMode2D.INFINITE_SCROLL] Determines if the 2D map is rotatable or can be scrolled infinitely in the horizontal direction. * * @exception {DeveloperError} Element with id "container" does not exist in the document. * @@ -260,7 +260,7 @@ define([ scene3DOnly : defaultValue(options.scene3DOnly, false), terrainExaggeration : options.terrainExaggeration, shadows : options.shadows, - rotatable2D : options.rotatable2D + mapMode2D : options.mapMode2D }); this._scene = scene; diff --git a/Source/Widgets/Viewer/Viewer.js b/Source/Widgets/Viewer/Viewer.js index 5f7f24d5159b..1c41d711080a 100644 --- a/Source/Widgets/Viewer/Viewer.js +++ b/Source/Widgets/Viewer/Viewer.js @@ -278,7 +278,7 @@ define([ * @param {Number} [options.terrainExaggeration=1.0] A scalar used to exaggerate the terrain. Note that terrain exaggeration will not modify any other primitive as they are positioned relative to the ellipsoid. * @param {Boolean} [options.shadows=false] Determines if shadows are cast by the sun. * @param {Boolean} [options.terrainShadows=false] Determines if the terrain casts shadows from the sun. - * @param {Boolean} [options.rotatable2D=false] Determines if the 2D map is rotatable or can be scrolled infinitely in the horizontal direction. + * @param {MapMode2D} [options.mapMode2D=MapMode2D.INFINITE_SCROLL] Determines if the 2D map is rotatable or can be scrolled infinitely in the horizontal direction. * * @exception {DeveloperError} Element with id "container" does not exist in the document. * @exception {DeveloperError} options.imageryProvider is not available when using the BaseLayerPicker widget, specify options.selectedImageryProviderViewModel instead. @@ -414,7 +414,7 @@ Either specify options.terrainProvider instead or set options.baseLayerPicker to terrainExaggeration : options.terrainExaggeration, shadows : options.shadows, terrainShadows : options.terrainShadows, - rotatable2D : options.rotatable2D + mapMode2D : options.mapMode2D }); var dataSourceCollection = options.dataSources; diff --git a/Specs/Scene/ScreenSpaceCameraControllerSpec.js b/Specs/Scene/ScreenSpaceCameraControllerSpec.js index 551e52717c04..015875efd384 100644 --- a/Specs/Scene/ScreenSpaceCameraControllerSpec.js +++ b/Specs/Scene/ScreenSpaceCameraControllerSpec.js @@ -14,6 +14,7 @@ defineSuite([ 'Core/Ray', 'Core/Transforms', 'Scene/CameraEventType', + 'Scene/MapMode2D', 'Scene/OrthographicFrustum', 'Scene/SceneMode', 'Specs/createCamera', @@ -35,6 +36,7 @@ defineSuite([ Ray, Transforms, CameraEventType, + MapMode2D, OrthographicFrustum, SceneMode, createCamera, @@ -87,7 +89,7 @@ defineSuite([ }); afterEach(function() { - scene.rotatable2D = false; + scene.mapMode2D = MapMode2D.INFINITE_SCROLL; controller = controller && !controller.isDestroyed() && controller.destroy(); }); @@ -449,7 +451,7 @@ defineSuite([ it('rotate counter-clockwise in 2D', function() { setUp2D(); - scene.rotatable2D = true; + scene.mapMode2D = MapMode2D.ROTATE; var position = Cartesian3.clone(camera.position); var startPosition = new Cartesian2(canvas.clientWidth / 4, canvas.clientHeight / 2); @@ -468,7 +470,7 @@ defineSuite([ it('rotate clockwise in 2D', function() { setUp2D(); - scene.rotatable2D = true; + scene.mapMode2D = MapMode2D.ROTATE; var position = Cartesian3.clone(camera.position); var startPosition = new Cartesian2(canvas.clientWidth / 2, canvas.clientHeight / 4); @@ -487,7 +489,7 @@ defineSuite([ it('rotates counter-clockwise with mouse position at bottom of the screen', function() { setUp2D(); - scene.rotatable2D = true; + scene.mapMode2D = MapMode2D.ROTATE; var position = Cartesian3.clone(camera.position); var startPosition = new Cartesian2(3 * canvas.clientWidth / 4, 3 * canvas.clientHeight / 4); From 67433c1e7855840d5e55ea84e04dff73a67a13b1 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Wed, 1 Jun 2016 16:43:16 -0400 Subject: [PATCH 20/33] Simplify --- Source/Scene/Model.js | 34 +++++++--------------------------- 1 file changed, 7 insertions(+), 27 deletions(-) diff --git a/Source/Scene/Model.js b/Source/Scene/Model.js index 4dfd27e7e1bc..c4a415413edf 100644 --- a/Source/Scene/Model.js +++ b/Source/Scene/Model.js @@ -1493,41 +1493,21 @@ define([ } } - function getPositionAttribute(model) { - var techniques = model.gltf.techniques; - for (var techniqueId in techniques) { - if (techniques.hasOwnProperty(techniqueId)) { - var technique = techniques[techniqueId]; - var attributes = technique.attributes; - for (var attributeId in attributes) { - if (attributes.hasOwnProperty(attributeId)) { - var attribute = attributes[attributeId]; - var semantic = technique.parameters[attribute].semantic; - if (defined(semantic) && semantic === 'POSITION') { - return attributeId; - } - } - } - } - } - return undefined; - } - function createAttributeLocations(model, attributes) { var attributeLocations = {}; var length = attributes.length; + var i; // Set the position attribute to the 0th index - var positionAttribute = getPositionAttribute(model); - if (defined(positionAttribute)) { - var index = attributes.indexOf(positionAttribute); - if (index > 0) { - attributes[index] = attributes[0]; - attributes[0] = positionAttribute; + for (i = 1; i < length; ++i) { + var attribute = attributes[i]; + if (attribute.toLowerCase().indexOf('position') > -1) { + attributes[i] = attributes[0]; + attributes[0] = attribute; } } - for (var i = 0; i < length; ++i) { + for (i = 0; i < length; ++i) { attributeLocations[attributes[i]] = i; } From ad5111ebcdd07362e82c6c0f591e6227978918ea Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Wed, 1 Jun 2016 16:48:30 -0400 Subject: [PATCH 21/33] Fix --- Source/Scene/Model.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/Scene/Model.js b/Source/Scene/Model.js index c4a415413edf..6b209ad39173 100644 --- a/Source/Scene/Model.js +++ b/Source/Scene/Model.js @@ -1504,6 +1504,7 @@ define([ if (attribute.toLowerCase().indexOf('position') > -1) { attributes[i] = attributes[0]; attributes[0] = attribute; + break; } } From b5a85604e5f6dbe1e5f85fb35c189ac10fb821f5 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 1 Jun 2016 16:54:39 -0400 Subject: [PATCH 22/33] Revert Camera setView and flyTo so the heading can be changed. --- Source/Scene/Camera.js | 53 +++++++++++++++++++------------- Source/Scene/CameraFlightPath.js | 7 +++++ 2 files changed, 39 insertions(+), 21 deletions(-) diff --git a/Source/Scene/Camera.js b/Source/Scene/Camera.js index 2d76de818390..a0caa86cc700 100644 --- a/Source/Scene/Camera.js +++ b/Source/Scene/Camera.js @@ -619,7 +619,7 @@ define([ * @readonly */ heading : { - get : function () { + get : function() { if (this._mode !== SceneMode.MORPHING) { var ellipsoid = this._projection.ellipsoid; @@ -738,8 +738,7 @@ define([ var frustum = this._max2Dfrustum = this.frustum.clone(); //>>includeStart('debug', pragmas.debug); - if (!defined(frustum.left) || !defined(frustum.right) || - !defined(frustum.top) || !defined(frustum.bottom)) { + if (!defined(frustum.left) || !defined(frustum.right) || !defined(frustum.top) || !defined(frustum.bottom)) { throw new DeveloperError('The camera frustum is expected to be orthographic for 2D camera control.'); } //>>includeEnd('debug'); @@ -826,7 +825,10 @@ define([ camera._setTransform(currentTransform); } - function setView2D(camera, position, convert) { + function setView2D(camera, position, heading, convert) { + var pitch = -CesiumMath.PI_OVER_TWO; + var roll = 0.0; + var currentTransform = Matrix4.clone(camera.transform, scratchSetViewTransform1); camera._setTransform(Matrix4.IDENTITY); @@ -852,6 +854,12 @@ define([ } } + var rotQuat = Quaternion.fromHeadingPitchRoll(heading - CesiumMath.PI_OVER_TWO, pitch, roll, scratchSetViewQuaternion); + var rotMat = Matrix3.fromQuaternion(rotQuat, scratchSetViewMatrix3); + + Matrix3.getColumn(rotMat, 2, camera.up); + Cartesian3.cross(camera.direction, camera.up, camera.right); + camera._setTransform(currentTransform); } @@ -890,7 +898,7 @@ define([ pitch : undefined, roll : undefined }, - convert: undefined, + convert : undefined, endTransform : undefined }; @@ -901,7 +909,7 @@ define([ * @param {Cartesian3|Rectangle} [options.destination] The final position of the camera in WGS84 (world) coordinates or a rectangle that would be visible from a top-down view. * @param {Object} [options.orientation] An object that contains either direction and up properties or heading, pith and roll properties. By default, the direction will point * towards the center of the frame in 3D and in the negative z direction in Columbus view. The up direction will point towards local north in 3D and in the positive - * y direction in Columbus view. Orientation is not used in 2D. + * y direction in Columbus view. Orientation is not used in 2D when in infinite scrolling mode. * @param {Matrix4} [options.endTransform] Transform matrix representing the reference frame of the camera. * * @example @@ -975,7 +983,7 @@ define([ if (mode === SceneMode.SCENE3D) { setView3D(this, destination, heading, pitch, roll); } else if (mode === SceneMode.SCENE2D) { - setView2D(this, destination, convert); + setView2D(this, destination, heading, convert); } else { setViewCV(this, destination, heading, pitch, roll, convert); } @@ -1047,7 +1055,7 @@ define([ } //>>includeEnd('debug'); - if (!defined(result)){ + if (!defined(result)) { result = new Cartesian4(); } updateMembers(this); @@ -1068,7 +1076,7 @@ define([ } //>>includeEnd('debug'); - if (!defined(result)){ + if (!defined(result)) { result = new Cartesian3(); } updateMembers(this); @@ -1089,7 +1097,7 @@ define([ } //>>includeEnd('debug'); - if (!defined(result)){ + if (!defined(result)) { result = new Cartesian3(); } updateMembers(this); @@ -1110,7 +1118,7 @@ define([ } //>>includeEnd('debug'); - if (!defined(result)){ + if (!defined(result)) { result = new Cartesian4(); } updateMembers(this); @@ -1131,7 +1139,7 @@ define([ } //>>includeEnd('debug'); - if (!defined(result)){ + if (!defined(result)) { result = new Cartesian3(); } updateMembers(this); @@ -1152,7 +1160,7 @@ define([ } //>>includeEnd('debug'); - if (!defined(result)){ + if (!defined(result)) { result = new Cartesian3(); } updateMembers(this); @@ -1613,7 +1621,7 @@ define([ } else if (this._mode === SceneMode.COLUMBUS_VIEW) { return Math.abs(this.position.z); } else if (this._mode === SceneMode.SCENE2D) { - return Math.max(this.frustum.right - this.frustum.left, this.frustum.top - this.frustum.bottom); + return Math.max(this.frustum.right - this.frustum.left, this.frustum.top - this.frustum.bottom); } }; @@ -1790,7 +1798,11 @@ define([ var viewRectangle3DSouthCenter = new Cartesian3(); var viewRectangle3DCenter = new Cartesian3(); var viewRectangle3DEquator = new Cartesian3(); - var defaultRF = {direction: new Cartesian3(), right: new Cartesian3(), up: new Cartesian3()}; + var defaultRF = { + direction : new Cartesian3(), + right : new Cartesian3(), + up : new Cartesian3() + }; var viewRectangle3DEllipsoidGeodesic; function computeD(direction, upOrRight, corner, tanThetaOrPhi) { @@ -1798,7 +1810,7 @@ define([ return opposite / tanThetaOrPhi - Cartesian3.dot(direction, corner); } - function rectangleCameraPosition3D (camera, rectangle, result, updateCamera) { + function rectangleCameraPosition3D(camera, rectangle, result, updateCamera) { var ellipsoid = camera._projection.ellipsoid; var cameraRF = updateCamera ? camera : defaultRF; @@ -1955,7 +1967,7 @@ define([ var viewRectangle2DCartographic = new Cartographic(); var viewRectangle2DNorthEast = new Cartesian3(); var viewRectangle2DSouthWest = new Cartesian3(); - function rectangleCameraPosition2D (camera, rectangle, result) { + function rectangleCameraPosition2D(camera, rectangle, result) { var projection = camera._projection; if (rectangle.west > rectangle.east) { rectangle = Rectangle.MAX_VALUE; @@ -2061,7 +2073,7 @@ define([ var cart = projection.unproject(new Cartesian3(result.y, result.z, 0.0)); if (cart.latitude < -CesiumMath.PI_OVER_TWO || cart.latitude > CesiumMath.PI_OVER_TWO || - cart.longitude < - Math.PI || cart.longitude > Math.PI) { + cart.longitude < -Math.PI || cart.longitude > Math.PI) { return undefined; } @@ -2327,7 +2339,6 @@ define([ return undefined; }; - var scratchFlyToDestination = new Cartesian3(); var scratchFlyToCarto = new Cartographic(); var newOptions = { @@ -2350,7 +2361,7 @@ define([ * @param {Cartesian3|Rectangle} options.destination The final position of the camera in WGS84 (world) coordinates or a rectangle that would be visible from a top-down view. * @param {Object} [options.orientation] An object that contains either direction and up properties or heading, pith and roll properties. By default, the direction will point * towards the center of the frame in 3D and in the negative z direction in Columbus view. The up direction will point towards local north in 3D and in the positive - * y direction in Columbus view. Orientation is not used in 2D. + * y direction in Columbus view. Orientation is not used in 2D when in infinite scrolling mode. * @param {Number} [options.duration] The duration of the flight in seconds. If omitted, Cesium attempts to calculate an ideal duration based on the distance to be traveled by the flight. * @param {Camera~FlightCompleteCallback} [options.complete] The function to execute when the flight is complete. * @param {Camera~FlightCancelledCallback} [options.cancel] The function to execute if the flight is cancelled. @@ -2418,7 +2429,7 @@ define([ setViewOptions.convert = options.convert; setViewOptions.endTransform = options.endTransform; this.setView(setViewOptions); - if (typeof options.complete === 'function'){ + if (typeof options.complete === 'function') { options.complete(); } return; diff --git a/Source/Scene/CameraFlightPath.js b/Source/Scene/CameraFlightPath.js index 570f8547dfb8..4b7b28df3e94 100644 --- a/Source/Scene/CameraFlightPath.js +++ b/Source/Scene/CameraFlightPath.js @@ -192,6 +192,7 @@ define([ var camera = scene.camera; var start = Cartesian3.clone(camera.position, scratchStart); + var startHeading = adjustAngleForLERP(camera.heading, heading); var startHeight = camera.frustum.right - camera.frustum.left; var heightFunction = createHeightFunction(camera, destination, startHeight, destination.z, optionAltitude); @@ -199,6 +200,12 @@ define([ function update(value) { var time = value.time / duration; + camera.setView({ + orientation: { + heading : CesiumMath.lerp(startHeading, heading, time) + } + }); + Cartesian2.lerp(start, destination, time, camera.position); var zoom = heightFunction(time); From 6e5f9ff440d4cdfd083449ec3ec6ffe24bc00e5b Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Wed, 1 Jun 2016 16:59:24 -0400 Subject: [PATCH 23/33] Add comment and use regex --- Source/Scene/Model.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Source/Scene/Model.js b/Source/Scene/Model.js index 6b209ad39173..16ec0524ce1a 100644 --- a/Source/Scene/Model.js +++ b/Source/Scene/Model.js @@ -1498,10 +1498,13 @@ define([ var length = attributes.length; var i; - // Set the position attribute to the 0th index + // Set the position attribute to the 0th index. In some WebGL implementations the shader + // will not work correctly if the 0th attribute is not active. For example, some glTF models + // list the normal attribute first but derived shaders like the cast-shadows shader do not use + // the normal attribute. for (i = 1; i < length; ++i) { var attribute = attributes[i]; - if (attribute.toLowerCase().indexOf('position') > -1) { + if (/position/i.test(attribute)) { attributes[i] = attributes[0]; attributes[0] = attribute; break; From 3f3f53ffc713119d4a14ad6e2936e1b5e8b16fa5 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 1 Jun 2016 17:10:35 -0400 Subject: [PATCH 24/33] Only rotate heading during setView when map mode is not infinte scrolling. --- Source/Scene/Camera.js | 10 ++++++---- Specs/Scene/CameraSpec.js | 26 +++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/Source/Scene/Camera.js b/Source/Scene/Camera.js index a0caa86cc700..ce2afd082abe 100644 --- a/Source/Scene/Camera.js +++ b/Source/Scene/Camera.js @@ -854,11 +854,13 @@ define([ } } - var rotQuat = Quaternion.fromHeadingPitchRoll(heading - CesiumMath.PI_OVER_TWO, pitch, roll, scratchSetViewQuaternion); - var rotMat = Matrix3.fromQuaternion(rotQuat, scratchSetViewMatrix3); + if (camera._scene.mapMode2D === MapMode2D.ROTATE) { + var rotQuat = Quaternion.fromHeadingPitchRoll(heading - CesiumMath.PI_OVER_TWO, pitch, roll, scratchSetViewQuaternion); + var rotMat = Matrix3.fromQuaternion(rotQuat, scratchSetViewMatrix3); - Matrix3.getColumn(rotMat, 2, camera.up); - Cartesian3.cross(camera.direction, camera.up, camera.right); + Matrix3.getColumn(rotMat, 2, camera.up); + Cartesian3.cross(camera.direction, camera.up, camera.right); + } camera._setTransform(currentTransform); } diff --git a/Specs/Scene/CameraSpec.js b/Specs/Scene/CameraSpec.js index c3c14097fa1b..2eac95a5f730 100644 --- a/Specs/Scene/CameraSpec.js +++ b/Specs/Scene/CameraSpec.js @@ -17,6 +17,7 @@ defineSuite([ 'Core/Transforms', 'Core/WebMercatorProjection', 'Scene/CameraFlightPath', + 'Scene/MapMode2D', 'Scene/OrthographicFrustum', 'Scene/PerspectiveFrustum', 'Scene/SceneMode', @@ -39,6 +40,7 @@ defineSuite([ Transforms, WebMercatorProjection, CameraFlightPath, + MapMode2D, OrthographicFrustum, PerspectiveFrustum, SceneMode, @@ -76,7 +78,9 @@ defineSuite([ drawingBufferWidth : 1024, drawingBufferHeight : 768 }; + this.mapMode2D = MapMode2D.INFINITE_2D } + beforeEach(function() { position = Cartesian3.clone(Cartesian3.UNIT_Z); up = Cartesian3.clone(Cartesian3.UNIT_Y); @@ -94,6 +98,7 @@ defineSuite([ camera.minimumZoomDistance = 0.0; scene.camera = camera; + scene.mapMode2D = MapMode2D.INFINITE_2D }); it('constructor throws an exception when there is no canvas', function() { @@ -218,7 +223,26 @@ defineSuite([ expect(camera.right).toEqualEpsilon(right, CesiumMath.EPSILON8); }); - it('does not set heading in 2D', function() { + it('sets heading in 2D when the map can be rotated', function() { + scene.mapMode2D = MapMode2D.ROTATE; + camera._mode = SceneMode.SCENE2D; + + var heading = camera.heading; + var positionCartographic = camera.positionCartographic; + + var newHeading = CesiumMath.toRadians(45.0); + camera.setView({ + orientation: { + heading : newHeading + } + }); + + expect(camera.positionCartographic).toEqual(positionCartographic); + expect(camera.heading).not.toEqual(heading); + expect(camera.heading).toEqualEpsilon(newHeading, CesiumMath.EPSILON14); + }); + + it('does not set heading in 2D for infinite scrolling mode', function() { camera._mode = SceneMode.SCENE2D; var heading = camera.heading; From 3efb378ccdea4471b963a464d3b578d087e2bcb5 Mon Sep 17 00:00:00 2001 From: Tom Fili Date: Wed, 1 Jun 2016 17:18:16 -0400 Subject: [PATCH 25/33] Bumped version in package.json and reordered CHANGES.md --- CHANGES.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index d7dc9ffcb996..152326c8f0ac 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -19,6 +19,7 @@ Change Log * Added `VelocityVectorProperty` so billboard's aligned axis can follow the velocity vector. [#3908](https://github.com/AnalyticalGraphicsInc/cesium/issues/3908) * Improve memory management for entity billboard/label/point/path visualization. * Added `terrainProviderChanged` event to `Scene` and `Globe` +* Added support for hue, saturation, and brightness color shifts in the atmosphere in `SkyAtmosphere`. See the new Sandcastle example: [Atmosphere Color](http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Atmosphere%20Color.html&label=Showcases). [#3439](https://github.com/AnalyticalGraphicsInc/cesium/issues/3439) * Fixed exaggerated terrain tiles disappearing. [#3676](https://github.com/AnalyticalGraphicsInc/cesium/issues/3676) * Fixed a bug that could cause incorrect normals to be computed for exaggerated terrain, especially for low-detail tiles. [#3904](https://github.com/AnalyticalGraphicsInc/cesium/pull/3904) * Fixed a bug that was causing errors to be thrown when picking and terrain was enabled. [#3779](https://github.com/AnalyticalGraphicsInc/cesium/issues/3779) @@ -31,7 +32,6 @@ Change Log * Fixed issue where billboards on terrain didn't always update when the terrain provider was changed. [#3921](https://github.com/AnalyticalGraphicsInc/cesium/issues/3921) * Fixed issue where `Matrix4.fromCamera` was taking eye/target instead of position/direction. [#3927](https://github.com/AnalyticalGraphicsInc/cesium/issues/3927) * Added `Scene.nearToFarDistance2D` that determines the size of each frustum of the multifrustum in 2D. -* Added support for hue, saturation, and brightness color shifts in the atmosphere in `SkyAtmosphere`. See the new Sandcastle example: [Atmosphere Color](http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Atmosphere%20Color.html&label=Showcases). [#3439](https://github.com/AnalyticalGraphicsInc/cesium/issues/3439) * Added `Matrix4.computeView`. * Added `CullingVolume.fromBoundingSphere`. * Added `debugShowShadowVolume` to `GroundPrimitive`. diff --git a/package.json b/package.json index 266b4208cbd4..df1bd745b7c0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cesium", - "version": "1.21.0", + "version": "1.22.0", "description": "Cesium is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.", "homepage": "http://cesiumjs.org", "license": "Apache-2.0", From 5d92be8c19deb6d28aa80fb912b35f3a69cb483f Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 1 Jun 2016 17:28:14 -0400 Subject: [PATCH 26/33] Cap the near plane when computing the frustums. --- Source/Scene/Scene.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 4372c8f2af92..e2098f111754 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -1188,7 +1188,7 @@ define([ curNear = Math.max(near, Math.pow(farToNearRatio, m) * near); curFar = Math.min(far, farToNearRatio * curNear); } else { - curNear = near + m * nearToFarDistance2D; + curNear = Math.min(far - nearToFarDistance2D, near + m * nearToFarDistance2D); curFar = Math.min(far, curNear + nearToFarDistance2D); } From 227029d584af03bbc9570ac53ec61da6e68ed46b Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 1 Jun 2016 17:49:19 -0400 Subject: [PATCH 27/33] Update Sandcastle example. --- Apps/Sandcastle/gallery/Rotatable 2D Map.html | 10 ++++++++-- Apps/Sandcastle/gallery/Rotatable 2D Map.jpg | Bin 0 -> 10428 bytes 2 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 Apps/Sandcastle/gallery/Rotatable 2D Map.jpg diff --git a/Apps/Sandcastle/gallery/Rotatable 2D Map.html b/Apps/Sandcastle/gallery/Rotatable 2D Map.html index 620d224fbdad..76f0184b4584 100644 --- a/Apps/Sandcastle/gallery/Rotatable 2D Map.html +++ b/Apps/Sandcastle/gallery/Rotatable 2D Map.html @@ -28,10 +28,16 @@ 'use strict'; //Sandcastle_Begin var viewer = new Cesium.Viewer('cesiumContainer', { - //sceneMode : Cesium.SceneMode.SCENE2D, + sceneMode : Cesium.SceneMode.SCENE2D, mapMode2D : Cesium.MapMode2D.ROTATE }); -// Middle mouse button drag or left mouse button drag while holding the contol key to rotate the map. + +viewer.scene.camera.setView({ + destination : Cesium.Cartesian3.fromDegrees(-73.0, 42.0, 50000000.0), + orientation : { + heading : Cesium.Math.toRadians(-45.0) + } +}); //Sandcastle_End Sandcastle.finishedLoading(); } diff --git a/Apps/Sandcastle/gallery/Rotatable 2D Map.jpg b/Apps/Sandcastle/gallery/Rotatable 2D Map.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3d3d8f591522052e998e6327fb25db93947a6b86 GIT binary patch literal 10428 zcmb7p18`-{x9>TzZB5LHZQHhOb7Es+PB^h9$s`j@II(R_Y}fJu; zbocJHx@%YMh2L8JzWBZYK#`GLaL^tINLWZn zSPVpXM2!D+d+!FI!T{0$o8UlH02nF|92NN93m^ml0YJzaLD&%00KA=0EPmN0$RzKx18V2B6O6n@eWg3RLWNggGNzT z6mmIAY6XT><|NWL5ZoGU_in)HsD&;q%CkDv^XRFZ0asx;Y#}^y< z-0yQW$Ltj=TEG2f%c+T>|9m;7`h9n1$jv!)=Z5+5_Rry#d9LpJeY|^HeqQsMl~Q?Z zgDf{WkNn(@ts`(V=X__GXQsJz!>-4KeFu*k8=wuaXad*AhIzcZn}ps^@-$#R(CIav z!NhA5FdbjY)3vj9Ya$f<8zU`sC7GT$!~;P)(3j#{cr(hq*7G0RkF^4y z2)y3`g~I{y-=49m2!C3*=HW~7-}#O~vP)k2U`PRg&LV+?{!@2h+uJ!@-cOW|RaFXn zy}B|(?&lvQg~u8{{9tHlyMKJPZm^7g(%Pt9k&T}O04MEb>1??yLht8xfH&gDH>ZVR z?qk;zzKcldM9z-dB?0)J0q~Q{QTU@85 z0WupChO8=nf5Y#c-pHJ(L|=lALX-%ARdg%2I8}+=eoXWz)`?gM-+a14V4$#-^U13j!UGoR>I#Nye%i5?u%!~wZ9ikTdM~=_2d3sCX)7*|9`Ol zT{gxwU#eIWPa)UJNukR~veWmkKzMvu_tbxOqPwrF&qR{N=l|8ojg)aj$ST&f!jkq# zwrq}{Y9MjAq>`l!FN%h{D z!j{rC%dt|4S^pfJaAVDkjJ!pPbNsd8_weDOc7j;AtvT4><*+`w#LpwvZ^>eErG_dv z74AP~Y~D7r%(!H8=3AY0%Fg{idrT)ma6F+5$UWT?khv&V(b+UWlMb8cS;(VWJT&yF z&Q1H>;Xvv5pu7XvZoZ{Y$-5N^=aD{!Beu>8Xd(qn6(mE z_~5Z?HqJ)gEq`Y_^BzVSFJgls1qHLAt8|75Z&Gdqp&vdwp(>5_aQ*1#oMGv&ucLx= z0hqP1l>GGsBgj4_PD0-XVyEAVN(TF7aiV^Z#7{S|amM$W%cfJ3KO$6!NY@?a+M4W% zP2yUgSXth@2#%%3j=Ui^WSOj!d=IWO(HjlAMcVhp5~iSbpW`VYn<4U}3!ZL}kjK2H z{HPL{XWqop+)P0cekT)qJMrD5ySc*L+7Vb!-#=FT^uj*wgE^DIs}9E+YL^*f zoqkIm!VhU$%}yU7g=<4HO9E@H=RhOqosdXfBBBdT6I*(-z}){cfg^i(hk(kIq)%#~ z@@afMzM@R~&`g~s|KgchcXa<|z*ev9SjvNTh!8#s8aOq@MQybv+8ZLW>TK80;B2cS z`)Q{p)%uO3ADyNxx_(LY)Lt+@J=mgOw*Qjw6I3p_gSFVvw2Ytd?=zY(ZbJ7)){+Ke z+?vS`ahs0hspedifXm15LEVc)(v&j7y!?yhRtK1S-aS1_ITiy9@1+{XFd*zS3 z>V>B`b&iJqTPn*QY?2fgqlwGChi77xB~_m+4jgX%mUI(8+C)lko7l)K)H|fsj(Bct zH(xNYUCg6<;GCF&oi^xFS_%EA;h>F zmDhutDtrvv;Mkg-#(2Wwp)LNMpDC-AymGpDgu=Zs1Bl8DC zh#lrruZf~)q-~{(>sjhI)E9%sE*fl?mkf~#89CR-!$`<+^@%WsAMFa9tHs`MFOgALFMxsa*QV)|c%y{(3 zuyi)x+;swoxJ^G?^9H2*vUqKOU|!5QSd6hPV43Dx5X^VFBPr0D4bSBqilMl8h1W-H za5HsrzV=5L!=}Cvhh>wJl@k7a*j(g_1539mn_N9sA)DmvHR{^&VXH%iMTU+nek^5W zqad2PAOa&=oHS9Y>SHa2MyytuUJAb;NKfcc0ibXK0+RpH6A%zX1xF)+Kw&0k5=JK# zQpO--ab{IA{;Mfqe>6qp`V}csDPJTE4ukrC42+J!)x^3@_!3mFA4=?VPpH-Pw7VU| z?rGvZJjzB~c&GULSzPh}`Zwh^4DQuSC-pDkjXO+{shWyL31u3$5JbvoB;1V|4`bLE z5JnDOs>W)^xC+2cRGf!E8C!coBrj950&}o1#p39yfnHPl!#QM&ZoWdH?>*>}jhDlu zmrf6AOSt?xd7D3!tL*`_^u%8@wN9w&QC0P+z*&SKw&aB&poYW~$|hb!$sJMj!dQ6VS3gQaU{qev%XC1WvdU_7 z%BJF&S=(j44w!EzcG1ESVi-mHU!d)<6tjx6m+&z@YP?qk%t+9 z;IR#Wi1B4lPI?!28gI0pv^gfD7}E;s5(<)f z531R~MHiBh6+O`I?8l7w4tK(Vq>5#bREo-J)xyXQb*f+|G2)9!q=YAn324?qS|f@A z(i$KLcECeHLjDCJAguvMh4|}TScH`!*^QG@rcf}5$(UG0RGeKBg-n9-Yd0~;O}j3j zC`5ykFaHajKna4GC$>QSL{Q+ql#fbg;n1@svmbRbXo_5fyG*UI8pUcr0S6ucb&;EAm)7s_zk7ovT6ASz!^Ghx7fV$g8$5%mfeTvLH?tf%- zmE7Z9mP5XMN}DA#U2Xh&Otjkot#wad#xu}tFFembVuMtB_Wuwfmb=qf0BQ@GH(4I% z?lMgcl^vG^K_Bcw20l~s$bM{2mb6!zuTxcVt6n+*-`Qx(m&$hELeP$pU5PUnnS zg%t(#E}gL*ePE+Tr@F26VU}N0byjzqFTuI}DU#m*y3>3I#H@7Sd3siRHr_=r{I5G= z!I+g+(bO*&SL@UQ+~myb90kI~?B56Rc5~r-SKjiQxHCy#NwW8t$OPCme*TKpT`y>r zgqID+zpwP97EEszuM;^GDlYnMKU#VD_w8>iCSQWSI^OHUU3>UZvi$l60#06Q5+~Cf z%~Jyydr?J*9+Pd(H}1SNwe{0?)n1q-aV1%Dv=J2dipv!OF+z9KHpcg<4+CHP$qMuJ zUGksV`6Ab5B-uNI8?t<^ZQTiVo1DsC)fbS1)VN=hf>a0X?C|>VK3g~Q;$DU^v`xv*@x~Mq3z0jdr~QUKOmZ z(KsWE{rfcS9S$yTymat?u?2{ue@SGd2Z2z1b}$7PlWmX$yRq`b@}%{w%uRQpVL z#r8=POl9m^%qT80@?KnRCoc_Fb{jnsID-efGH{}Xwxl>pRta@j-bC^>B&RxcMhL<5VM9MkW%+HA(xcZ#@F7x}OR^jP(mz;)yM_~+X7 zY$`CN`&hgveO;QUz`m5&U+w*_-gm3w_{_ZTaHepmPn1R{pR>nZ$Zi|#e#bNjxgwsk z67Q0BbC2d}Fl*S=JG3s)|=_Di*?r^wZ&}`m7?QAzBTaz_RgG3EidD1kz=ehs={<^Y0@*M4Mf3 z|5z$e;FP%VCqiW}sfu6S%ESXFvlzrr-Hwj7i*=akDy}~o_z51R z`L&W__2i(QBdu<`(O{J}WYg($;v-cbvvUucvqJ1j`hg#3jE{_B!kVN>>JxksvpDuvXG|m}6c(7hCW(7pCs^&dvKHGqy%E z;sI(pGDJV8#st0Z5*#nN$t!LY6>&w>Pxx`{_Bj`c$usIqrE?-xrhcyTfW_TMN-q1g z!q}IYvXz4HmN^Z3@=QuxHpPUq!zT=FXxe_#`=ZwHDz7&j%7B(72Nc;HFPqJ9%omKh zrWCtI z0i#L@B}ZhK6QuwpMw4vEP!8tjP1s$q)8ERU*neE85DZ$AAh2&+Xm5*AnTj7F8n<(= zjPH0-!9qTrDa!}l(Q?kvz5}vSB@E;gK3s_il8T@|G<<>tS6v>-`|G{f26^R`W*S_+c&v|FwI+Qr zpy7LvOfUV$8x|aYSbAdv-xeW_vy;_KWv{bx*Q5t3V}Q2$=AI*#ZjPb1J;$zr`9afc zS|9Fc=eTOsb5J$jTJ9HP2;wh<&*LF;ff&Fk-{0v_0^iEN^L{LZR(Jiu%lbcwStPRz zHu?f8{&M>l>wv#y+{*;vV=nJCpXZ*}`RL{Pmw%UgwDAuH|J(EbP0Zve3>k~^u>Nbg z9Re0sX!Um@JER${%n?K;{h`vk*UD1A%*;&C#wX8>@}FmiACXMnu2&ADL#;VO(rD`D zYbk2`Wn&nQ@z0{`Pi*|;-!j6Zp>)|*^Xa1T2W^OD7MPhVh2H@pH}@$_7^2$aI&!@l z9da!G=D&z2d~i(p>2m`{Z}OSgGM|`I&UTh?%JPMeqWoJVWQ>4{;_H%CvXV%fD1^vY zsC3%0=`0Nr8`}@9U_S2Qvoj_$j*%*0pOYmKjPBMbvhv%F@6I3)KeM^$n|@X54v3^L z@H@=q5oI^-mHEQNpv2w2*M@zuRE?q z*!&JaLx6*oJBqa?J%bCOu~}R!y$61uHddLj4IR6=ww5+N)3?;t?gJ)P@v2%?rx$RqVcCo>B+XU)HlCTkHhJ)XzZhe-EFegfB|L?7$oVGkQdRwd%%Dx4zgHdc zCz}H`1dMJ}tW||E)1bqOKpK2EQbaE(&Jg$FeQkOMtv)POpQvea}>kKi!lWsI4)PuB5{lvPPn6;m>L)9NTMp3#+4j?F#ROVnzv}tPt_)N37W(YFhsIK5}P~YSgeeF3x-!BZ7Lh=O-%) zv2j0VzgSD`O2XIsw-9?&owQvNTG-Qb?j@naH zLHZLDc{_AfaJh5yjNGWlO3xmBldKgG%xqRfXP^2t_3*{0TpMXb*JYXBCft$h=PlNr zvZevXns@kD3UhL@MuxtMOhQ4iUfD`Nck?iZ1@g+?&K6bHf2i)S(!ah-+rd$`Qym+?tCE~dFI?53 zSf?WRJ3kkrV z(g_N@bKdJaV8y<1#r_nA;jJF-Pdx>K;7=b2`U6ixlcdR`qR5k^!LNqMlcc(;r9tyQ z^kv)TpGlImCiPm;KlAVo+{os?0#e&tE!Qf4B@>Om*}?p?i#VJ;(_8{{zYPK(9~wvKUvzJ z>JZAF(pqSMYSu}!U(6Z&1pvUHr-5q73_MAN$DMk42XqBM+l&0o8dLwIn8h-Ghn8RU zem)gvu=SXvfFrea9^*W3*`Vv$a{Uyym4t|&6B&i3gTiAaFT%*$4swvA;&MZHrb+uf zk*s!-b}-9gDPlW&KIVSU$MoO(<6-Oz$eP_2%x8tTg|>$KalTT9B|Sd|!}FodYhBgC z9K>gj4j2bP>g5L^7bNc)f0E#P2i&pFY-F&#ZLFFfkI}4}bOleQ^(nF|3kORaMmyN* z4y-Q(R=)$%fXu)URD*@n$S4HxP;o5)DjAWs?Gx9-QWvW6rPq23YeLlzR6+BNQ)e`=5Ne7 zf<-vopV<=$jUru%(pLMxWiAm$aYetT9c`Nq-G3g59N`Iu=P7rcikEKuif8UrF5Syg z`V!U}DFIec#}n7F%3P=uMv;Kel*dHY)6?u4bG!br*_n&BDzj9`Stsj^{Hsvf9NwTS zwVq8s0{qYKMzCI^sFDn%-)aaG>9kY3X#Lt-dpt%`Ia~n+zmsOIZ_bcGQ7s*H*hs1= z<55r8g0di@o~;pu4cDA4d|5nDn}CQw<|SvUwC0&n-5J7aVyif~!7%>Yy=PEDxtR#c z4|D=lI+rL0SHdlVYR;fuk_?EhMa(6TDpI3@tn3dCg9P0T{;?^LMg4(cD9Xl6&OyXN zAShOQaXIy$>Jv&vFhy^htRQ2PY1A~rzm>}Wlq^$gEgFBskH10mv5i2jDmcHr1Ee!F z#%@f_X~Z^VR8op*{&crG?dk=jv1nZMM@9-)(fWNyDzO|Q{n(}URz9*nuNpI^ZI~Au z?vVq)$RlNhQ;sk-k=GL)jOYD+7=_Y8PSF)qWLsy4UA{alUrs9cJWH^N5Ni$P#^EW; zi+u>XZ4VG{g$mDfeofK@OCF-3l2F|<{)n9#CnHjteIY8&xv0r~r*sW7d1VyZglCO1 z!;6(ic1_-Ah%^A!(ftl6o016oT!&BZy5T3xc)gLaN~xTBy<;MECeaqL5*Kh|Xz^;x zBCN~b-$LOsB2ToX)YkaMA7$%@iNa1MD&yxwnS<0I){yU}M`|EgCpPscqM3E7lCu+uZES3v8jL z=gS+>%>r>VZ(=Mwf=@vDI5s?!F!pM?oA_jz9@J{-R@KKwoQ}klVKgx*$x(dwn)5V|M+ zw#zp5l_bq2C2rpVp&+lP%LZO1vM;w;U-VWe0u4U%*>r8N|YTMUO$ zAHLmU#)lyc=cYAjb3&$y2RX&LAKRVS$s{DMib(v`{wZ3WS=Ut@%!}lFwgTYbs-U^( z`3}e{*+CWRbrNDG@9K8UY3;6nk%6{$L>Me>{fLskik%%QrEIbyu3nRVGl7+r-HgxP z9W4{zKgLC-V?&t8i&*j;jYAopY`RTjYddgw|Jn-;ZTo6O_;J!b1_q|Syr&wyXeq6M z6auq(WsqAjws0|dRbf47p(X;ULv?!_IcDTrfSu~8FD`L*#KbrlN|1DRJkBp|jD*;y zUIQ`8K>JCzHrg2=ql6U+{Q`XgKG@cB(x{ka06L@7tH8u5t+i11e0y6qjh8JRm(JQs z(6edpJgd;I4>N0|2+&GA8;0-2xb~2Xd@f1AA{n4RUFdQ+{#_IQ0@}1a9#&=B zYA2vh1X3RumjE2g-+XL?)~ph3vtciN*}7s9g%%6rod)o#!EU-}E39@xZr-?EHNpEx zUwxg%xL&hA-=3K&CWMM~H-7pdi*lybH7F;cf+qgNu1i+B-S7MwtBds8H{QFVi9%`~ z%wvF2fi8h01#iKd=t5Czz4pa;IB?!B4PWrHU^ZZR5v+i?2GY-kq!v>ngv)^9Huemh zn;Kk<^E;0uQmNeVu%f<)uigx+fV|QpD*o9!z^F1_`nk@x_Y2g;k)2YB` ziZ1F5ZSEv((YC=*>7H#mUsg~)0pp4gReU*l{Ng?Ujnf;`6R19T4xoQxf~j(5TbWUf zif%h2p^ZSuM${KVpzR30;u9kzcBBdNPo8-y^;>-hfKkC=NJ>(LQWPjf*Xm;hBmUtiDth$nOA9e)Ywga75<1KA1=jO zK?1u9e}T%D!D1on4ROl8bHrY{WzB5dV!}~jx(h$ot5#A=TtmWh>dUR0gzOTD{L*I0 zpo*cT_K9nKoC1CT3R=y+gw$g^z2V^MHq07MUnC}%N>ZTq6buKR><1XMg5q}(kp&aX zdq%AXF)oF#Q)uCBmXETG0TomjfziVUE!B7RJ7h;da?m%j6O%V7Bd!O1{?lFfUVyNL zJ z8YAd6p1tlcH1-dYzUL9_E`!rfyk!s`-tMyb(YuQ^#6|1=o*}5}9HO7}d7qrr(M*FT zZxTOvg`y=m@d;-3+C|12E};B?DS6V9fb>#4Ko$O>iuM3>!B{0 z8>?g&;fShF#;{Xyp_v5+ic%7!l7w|Tg1;}Z5ww5S%mSaWHY~hJ_I4Pd5G-3eweZG1 zjNph!51iPhm)ja{zMnrf8uR{Bq*k3&aQ9>lT-b7zW}@^cRJ;FX8aMy}rj)d?PIGo3 z#Ysi=>BHA@NNfFL*%l-JN~lvT9Gv)Muq8;kx~b1$$U@+3gM<+oC#5;tK{m8!rUlB2 z3IxXDNKO?1uUBGZFEb$r|pIztc5F2M1BK_I`BP5E7kv(d-Im9`l%1sKY2=Ufyr_Wa-&qZ3cM4B}4L@}Te zTwn`v;^fKB7?Ab@u>p%o^8ntrHp>J_3oOsi{tl6D3JtvTNS}w*67?I;2Wq(eJMVC* z1*y)DITi9X(^>s)zgf-Ie_jwAeYRj)g`th=dKQf5uE!%0GH{dmc-?;~z|r1Td?w`)uPV`MvSlX+l;Zekz8}rc@P`r3g_{vi{fbnK)KDZU6;|riCnkMwC8I71tZtmg~v**mWo& z10hB%!ZrVFlR7if{A*+kgbR7#c_zAjRB?jKmC=pY_B&lahZq9u7t#GM>B`lqzcj@P z?_@R6%QSdh%oK*Vfa`72LIN_0=OG}{DOX_IJ)Ju%-NLL|Y~rD6%e7Q)K5_Q!fUn`e zRWKhMJapnFh5g*frrYYpXI%N+ mTUd69o}tXw2=RM3B0Kkb+Tls}+!mD5h6@snk}A*p(*FUvV?D(H literal 0 HcmV?d00001 From 4734a4e8aa44c2f435b99629907235f7ac794939 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 1 Jun 2016 17:53:55 -0400 Subject: [PATCH 28/33] Fix jsHint warnings. --- Specs/Scene/CameraSpec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Specs/Scene/CameraSpec.js b/Specs/Scene/CameraSpec.js index 2eac95a5f730..a15c8ffc8419 100644 --- a/Specs/Scene/CameraSpec.js +++ b/Specs/Scene/CameraSpec.js @@ -78,7 +78,7 @@ defineSuite([ drawingBufferWidth : 1024, drawingBufferHeight : 768 }; - this.mapMode2D = MapMode2D.INFINITE_2D + this.mapMode2D = MapMode2D.INFINITE_2D; } beforeEach(function() { @@ -98,7 +98,7 @@ defineSuite([ camera.minimumZoomDistance = 0.0; scene.camera = camera; - scene.mapMode2D = MapMode2D.INFINITE_2D + scene.mapMode2D = MapMode2D.INFINITE_2D; }); it('constructor throws an exception when there is no canvas', function() { From 8259db900795a7219a993a9c67999a8d344bfd61 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 1 Jun 2016 17:57:57 -0400 Subject: [PATCH 29/33] Update CHANGES.md. --- CHANGES.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 0fb0b814d4e0..82401d0f9306 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,11 @@ Change Log ========== +### 1.23 - 2016-07-01 + +* Add a `rotatable2D` option to to `Scene`, `CesiumWidget` and `Viewer` to enable a rotatable map in 2D. [#3897](https://github.com/AnalyticalGraphicsInc/cesium/issues/3897) +* `Camera.setView` and `Camera.flyTo` will now use the `orientation.heading` parameter in 2D if the map is rotatable. + ### 1.22 - 2016-06-01 * Breaking changes @@ -36,7 +41,6 @@ Change Log * Added `CullingVolume.fromBoundingSphere`. * Added `debugShowShadowVolume` to `GroundPrimitive`. * Fix issue with disappearing tiles on Linux. [#3889](https://github.com/AnalyticalGraphicsInc/cesium/issues/3889) -* Add a `rotatable2D` option to to `Scene`, `CesiumWidget` and `Viewer` to enable a rotatable map in 2D. [#3897](https://github.com/AnalyticalGraphicsInc/cesium/issues/3897) ### 1.21 - 2016-05-02 From 2509205efe9e35d30833ca4af02423d8c9093731 Mon Sep 17 00:00:00 2001 From: hpinkos Date: Thu, 2 Jun 2016 17:16:50 -0400 Subject: [PATCH 30/33] init fix --- Source/Core/OrientedBoundingBox.js | 45 ++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/Source/Core/OrientedBoundingBox.js b/Source/Core/OrientedBoundingBox.js index ed9ab60ae96d..848d6c7af790 100644 --- a/Source/Core/OrientedBoundingBox.js +++ b/Source/Core/OrientedBoundingBox.js @@ -51,7 +51,7 @@ define([ * var halfAxes = Cesium.Matrix3.fromScale(new Cesium.Cartesian3(1.0, 3.0, 2.0), new Cesium.Matrix3()); * * var obb = new Cesium.OrientedBoundingBox(center, halfAxes); - * + * * @see BoundingSphere * @see BoundingRectangle */ @@ -152,25 +152,40 @@ define([ covarianceMatrix[8] = ezz; var eigenDecomposition = Matrix3.computeEigenDecomposition(covarianceMatrix, scratchEigenResult); - var rotation = Matrix3.transpose(eigenDecomposition.unitary, result.halfAxes); + var rotation = Matrix3.clone(eigenDecomposition.unitary, result.halfAxes); - p = Cartesian3.subtract(positions[0], meanPoint, scratchCartesian2); - var tempPoint = Matrix3.multiplyByVector(rotation, p, scratchCartesian3); - var maxPoint = Cartesian3.clone(tempPoint, scratchCartesian4); - var minPoint = Cartesian3.clone(tempPoint, scratchCartesian5); + var v1 = Matrix3.getColumn(rotation, 0, new Cartesian3()); + var v2 = Matrix3.getColumn(rotation, 1, new Cartesian3()); + var v3 = Matrix3.getColumn(rotation, 2, new Cartesian3()); - for (i = 1; i < length; i++) { - p = Cartesian3.subtract(positions[i], meanPoint, p); - Matrix3.multiplyByVector(rotation, p, tempPoint); - Cartesian3.minimumByComponent(minPoint, tempPoint, minPoint); - Cartesian3.maximumByComponent(maxPoint, tempPoint, maxPoint); + var u1 = -Number.MAX_VALUE; + var u2 = -Number.MAX_VALUE; + var u3 = -Number.MAX_VALUE; + var l1 = Number.MAX_VALUE; + var l2 = Number.MAX_VALUE; + var l3 = Number.MAX_VALUE; + + for (i = 0; i < length; i++) { + p = positions[i]; + u1 = Math.max(Cartesian3.dot(v1, p), u1); + u2 = Math.max(Cartesian3.dot(v2, p), u2); + u3 = Math.max(Cartesian3.dot(v3, p), u3); + + l1 = Math.min(Cartesian3.dot(v1, p), l1); + l2 = Math.min(Cartesian3.dot(v2, p), l2); + l3 = Math.min(Cartesian3.dot(v3, p), l3); } - var center = Cartesian3.add(minPoint, maxPoint, scratchCartesian3); - Cartesian3.multiplyByScalar(center, 0.5, center); - Matrix3.multiplyByVector(rotation, center, center); - Cartesian3.add(meanPoint, center, result.center); + v1 = Cartesian3.multiplyByScalar(v1, 0.5*(l1 + u1), v1); + v2 = Cartesian3.multiplyByScalar(v2, 0.5*(l2 + u2), v2); + v3 = Cartesian3.multiplyByScalar(v3, 0.5*(l3 + u3), v3); + + var center = Cartesian3.add(v1, v2, new Cartesian3()); + center = Cartesian3.add(center, v3, center); + Cartesian3.clone(center, result.center); + var maxPoint = new Cartesian3(u1, u2, u3); + var minPoint = new Cartesian3(l1, l2, l3); var scale = Cartesian3.subtract(maxPoint, minPoint, scratchCartesian3); Cartesian3.multiplyByScalar(scale, 0.5, scale); Matrix3.multiplyByScale(result.halfAxes, scale, result.halfAxes); From 70c7b2039baf8a25cd2b56f8029433a52b7ca2ca Mon Sep 17 00:00:00 2001 From: hpinkos Date: Thu, 2 Jun 2016 17:59:23 -0400 Subject: [PATCH 31/33] cleanup --- Source/Core/OrientedBoundingBox.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/Source/Core/OrientedBoundingBox.js b/Source/Core/OrientedBoundingBox.js index 848d6c7af790..0fb5ef88fc27 100644 --- a/Source/Core/OrientedBoundingBox.js +++ b/Source/Core/OrientedBoundingBox.js @@ -75,6 +75,7 @@ define([ var scratchCartesian3 = new Cartesian3(); var scratchCartesian4 = new Cartesian3(); var scratchCartesian5 = new Cartesian3(); + var scratchCartesian6 = new Cartesian3(); var scratchCovarianceResult = new Matrix3(); var scratchEigenResult = { unitary : new Matrix3(), @@ -154,9 +155,9 @@ define([ var eigenDecomposition = Matrix3.computeEigenDecomposition(covarianceMatrix, scratchEigenResult); var rotation = Matrix3.clone(eigenDecomposition.unitary, result.halfAxes); - var v1 = Matrix3.getColumn(rotation, 0, new Cartesian3()); - var v2 = Matrix3.getColumn(rotation, 1, new Cartesian3()); - var v3 = Matrix3.getColumn(rotation, 2, new Cartesian3()); + var v1 = Matrix3.getColumn(rotation, 0, scratchCartesian4); + var v2 = Matrix3.getColumn(rotation, 1, scratchCartesian5); + var v3 = Matrix3.getColumn(rotation, 2, scratchCartesian6); var u1 = -Number.MAX_VALUE; var u2 = -Number.MAX_VALUE; @@ -180,13 +181,13 @@ define([ v2 = Cartesian3.multiplyByScalar(v2, 0.5*(l2 + u2), v2); v3 = Cartesian3.multiplyByScalar(v3, 0.5*(l3 + u3), v3); - var center = Cartesian3.add(v1, v2, new Cartesian3()); + var center = Cartesian3.add(v1, v2, result.center); center = Cartesian3.add(center, v3, center); - Cartesian3.clone(center, result.center); - var maxPoint = new Cartesian3(u1, u2, u3); - var minPoint = new Cartesian3(l1, l2, l3); - var scale = Cartesian3.subtract(maxPoint, minPoint, scratchCartesian3); + var scale = scratchCartesian3; + scale.x = u1 - l1; + scale.y = u2 - l2; + scale.z = u3 - l3; Cartesian3.multiplyByScalar(scale, 0.5, scale); Matrix3.multiplyByScale(result.halfAxes, scale, result.halfAxes); From f6ed349784738e10204123ba4a2704db6ce8d0db Mon Sep 17 00:00:00 2001 From: hpinkos Date: Thu, 2 Jun 2016 18:31:56 -0400 Subject: [PATCH 32/33] fix specs --- Specs/Core/OrientedBoundingBoxSpec.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Specs/Core/OrientedBoundingBoxSpec.js b/Specs/Core/OrientedBoundingBoxSpec.js index 3c120b26e626..ae73533c6ab0 100644 --- a/Specs/Core/OrientedBoundingBoxSpec.js +++ b/Specs/Core/OrientedBoundingBoxSpec.js @@ -101,6 +101,8 @@ defineSuite([ var result = rotatePositions(positions, Cartesian3.UNIT_Z, CesiumMath.PI_OVER_FOUR); var points = result.points; var rotation = result.rotation; + rotation[1] = -rotation[1]; + rotation[3] = -rotation[3]; var box = OrientedBoundingBox.fromPoints(points); expect(box.halfAxes).toEqualEpsilon(Matrix3.multiplyByScale(rotation, new Cartesian3(3.0, 2.0, 4.0), new Matrix3()), CesiumMath.EPSILON15); @@ -111,6 +113,8 @@ defineSuite([ var result = rotatePositions(positions, Cartesian3.UNIT_Y, CesiumMath.PI_OVER_FOUR); var points = result.points; var rotation = result.rotation; + rotation[2] = -rotation[2]; + rotation[6] = -rotation[6]; var box = OrientedBoundingBox.fromPoints(points); expect(box.halfAxes).toEqualEpsilon(Matrix3.multiplyByScale(rotation, new Cartesian3(4.0, 3.0, 2.0), new Matrix3()), CesiumMath.EPSILON15); @@ -121,6 +125,8 @@ defineSuite([ var result = rotatePositions(positions, Cartesian3.UNIT_X, CesiumMath.PI_OVER_FOUR); var points = result.points; var rotation = result.rotation; + rotation[5] = -rotation[5]; + rotation[7] = -rotation[7]; var box = OrientedBoundingBox.fromPoints(points); expect(box.halfAxes).toEqualEpsilon(Matrix3.multiplyByScale(rotation, new Cartesian3(2.0, 4.0, 3.0), new Matrix3()), CesiumMath.EPSILON15); @@ -131,6 +137,8 @@ defineSuite([ var result = rotatePositions(positions, Cartesian3.UNIT_Z, CesiumMath.PI_OVER_FOUR); var points = result.points; var rotation = result.rotation; + rotation[1] = -rotation[1]; + rotation[3] = -rotation[3]; var translation = new Cartesian3(-40.0, 20.0, -30.0); points = translatePositions(points, translation); From e9e1cbad0a847a41c748a73525ba974e1ea2589d Mon Sep 17 00:00:00 2001 From: hpinkos Date: Thu, 2 Jun 2016 19:21:23 -0400 Subject: [PATCH 33/33] whitespace --- Source/Core/OrientedBoundingBox.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/Core/OrientedBoundingBox.js b/Source/Core/OrientedBoundingBox.js index 0fb5ef88fc27..15c6b332ee08 100644 --- a/Source/Core/OrientedBoundingBox.js +++ b/Source/Core/OrientedBoundingBox.js @@ -177,9 +177,9 @@ define([ l3 = Math.min(Cartesian3.dot(v3, p), l3); } - v1 = Cartesian3.multiplyByScalar(v1, 0.5*(l1 + u1), v1); - v2 = Cartesian3.multiplyByScalar(v2, 0.5*(l2 + u2), v2); - v3 = Cartesian3.multiplyByScalar(v3, 0.5*(l3 + u3), v3); + v1 = Cartesian3.multiplyByScalar(v1, 0.5 * (l1 + u1), v1); + v2 = Cartesian3.multiplyByScalar(v2, 0.5 * (l2 + u2), v2); + v3 = Cartesian3.multiplyByScalar(v3, 0.5 * (l3 + u3), v3); var center = Cartesian3.add(v1, v2, result.center); center = Cartesian3.add(center, v3, center);