From 22a5d631a2c306dd41eeca1a73951f441167ceac Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 20 Jun 2012 14:08:23 -0400 Subject: [PATCH 01/36] Change default mouse handling. --- Source/Scene/Camera2DController.js | 4 ++-- Source/Scene/CameraColumbusViewController.js | 7 ++++--- Source/Scene/CameraSpindleController.js | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Source/Scene/Camera2DController.js b/Source/Scene/Camera2DController.js index 22e4d370c5a6..9cc3f1c40f73 100644 --- a/Source/Scene/Camera2DController.js +++ b/Source/Scene/Camera2DController.js @@ -73,9 +73,9 @@ define([ this._maximumZoomRate = FAR; this._translateHandler = new CameraEventHandler(canvas, CameraEventType.LEFT_DRAG); - this._zoomHandler = new CameraEventHandler(canvas, CameraEventType.RIGHT_DRAG); + this._zoomHandler = new CameraEventHandler(canvas, CameraEventType.MIDDLE_DRAG); this._zoomWheel = new CameraEventHandler(canvas, CameraEventType.WHEEL); - this._twistHandler = new CameraEventHandler(canvas, CameraEventType.MIDDLE_DRAG); + this._twistHandler = new CameraEventHandler(canvas, CameraEventType.RIGHT_DRAG); this._lastInertiaTranslateMovement = undefined; this._lastInertiaZoomMovement = undefined; diff --git a/Source/Scene/CameraColumbusViewController.js b/Source/Scene/CameraColumbusViewController.js index 2c9451aae83a..ed91768adc3d 100644 --- a/Source/Scene/CameraColumbusViewController.js +++ b/Source/Scene/CameraColumbusViewController.js @@ -56,12 +56,13 @@ define([ // TODO: Shouldn't change private variables like this, need to be able to change event modifiers // on controllers. this._spindleController._spinHandler = this._spindleController._spinHandler && this._spindleController._spinHandler.destroy(); + this._spindleController._spinHandler = new CameraEventHandler(canvas, CameraEventType.RIGHT_DRAG); + this._spindleController.mouseConstrainedZAxis = true; this._freeLookController = new CameraFreeLookController(canvas, camera); this._freeLookController.horizontalRotationAxis = Cartesian3.UNIT_Z; this._transform = this._camera.transform.clone(); - this._lastInertiaTranslateMovement = undefined; } @@ -83,6 +84,8 @@ define([ this._spindleController.update(); this._freeLookController.update(); + this._updateReferenceFrame(); + return true; }; @@ -99,8 +102,6 @@ define([ var diff = startPlanePos.subtract(endPlanePos); camera.position = camera.position.add(diff); - - this._updateReferenceFrame(); }; CameraColumbusViewController.prototype._updateReferenceFrame = function() { diff --git a/Source/Scene/CameraSpindleController.js b/Source/Scene/CameraSpindleController.js index c49b3ac1ef56..a30b192ac755 100644 --- a/Source/Scene/CameraSpindleController.js +++ b/Source/Scene/CameraSpindleController.js @@ -98,7 +98,7 @@ define([ this._minimumRotateRate = 1.0 / 5000.0; this._spinHandler = new CameraEventHandler(canvas, CameraEventType.LEFT_DRAG); - this._zoomHandler = new CameraEventHandler(canvas, CameraEventType.RIGHT_DRAG); + this._zoomHandler = new CameraEventHandler(canvas, CameraEventType.MIDDLE_DRAG); this._zoomWheel = new CameraEventHandler(canvas, CameraEventType.WHEEL); this._lastInertiaSpinMovement = undefined; From b54795b727783e98ad4cd8c6934bf0c86da954ec Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 20 Jun 2012 15:56:12 -0400 Subject: [PATCH 02/36] Mapped rotating around the last clicked point to the right mouse button in 3D. Temporarily add keyboard bindings that morph to different modes to the Skeleton. --- Examples/Skeleton/Skeleton.js | 27 ++-- Source/Scene/Camera.js | 2 +- Source/Scene/CameraCentralBodyController.js | 153 +++++++++++++++++++ Source/Scene/CameraColumbusViewController.js | 6 - Source/Scene/CameraControllerCollection.js | 12 +- Source/Scene/CameraSpindleController.js | 4 +- Source/Scene/SceneTransitioner.js | 3 +- 7 files changed, 183 insertions(+), 24 deletions(-) create mode 100644 Source/Scene/CameraCentralBodyController.js diff --git a/Examples/Skeleton/Skeleton.js b/Examples/Skeleton/Skeleton.js index 4220d03ace20..4c05099bd6e7 100644 --- a/Examples/Skeleton/Skeleton.js +++ b/Examples/Skeleton/Skeleton.js @@ -25,18 +25,18 @@ require({ cb.dayTileProvider = bing; cb.nightImageSource = '../../Images/land_ocean_ice_lights_2048.jpg'; cb.specularMapSource = '../../Images/earthspec1k.jpg'; - if (scene.getContext().getMaximumTextureSize() > 2048) { - cb.cloudsMapSource = '../../Images/earthcloudmaptrans.jpg'; - cb.bumpMapSource = '../../Images/earthbump1k.jpg'; - } - cb.showSkyAtmosphere = true; - cb.showGroundAtmosphere = true; + //if (scene.getContext().getMaximumTextureSize() > 2048) { + // cb.cloudsMapSource = '../../Images/earthcloudmaptrans.jpg'; + // cb.bumpMapSource = '../../Images/earthbump1k.jpg'; + //} + //cb.showSkyAtmosphere = true; + //cb.showGroundAtmosphere = true; primitives.setCentralBody(cb); scene.getCamera().frustum.near = 1.0; + scene.getCamera().getControllers().addCentralBody(); - scene.getCamera().getControllers().addSpindle(); - scene.getCamera().getControllers().addFreeLook(); + var transitioner = new Cesium.SceneTransitioner(scene, ellipsoid); /////////////////////////////////////////////////////////////////////////// // Add examples from the Sandbox here: @@ -58,12 +58,17 @@ require({ /////////////////////////////////////////////////////////////////////////// // Example keyboard and Mouse handlers - var handler = new Cesium.EventHandler(canvas); + var handler = new Cesium.EventHandler(document); handler.setKeyAction(function() { - /* ... */ - // Handler for key press + transitioner.morphTo2D(); }, '1'); + handler.setKeyAction(function() { + transitioner.morphToColumbusView(); + }, '2'); + handler.setKeyAction(function() { + transitioner.morphTo3D(); + }, '3'); handler.setMouseAction(function(movement) { /* ... */ diff --git a/Source/Scene/Camera.js b/Source/Scene/Camera.js index 65a019e2bb06..7d46ae5fce0e 100644 --- a/Source/Scene/Camera.js +++ b/Source/Scene/Camera.js @@ -437,7 +437,7 @@ define([ var ray = this.getPickRay(windowPosition); var intersection = IntersectionTests.rayEllipsoid(ray.position, ray.direction, ellipsoid); if (!intersection) { - return null; + return undefined; } var iPt = ray.position.add(ray.direction.multiplyWithScalar(intersection.start)); diff --git a/Source/Scene/CameraCentralBodyController.js b/Source/Scene/CameraCentralBodyController.js new file mode 100644 index 000000000000..cc479a7b766b --- /dev/null +++ b/Source/Scene/CameraCentralBodyController.js @@ -0,0 +1,153 @@ +/*global define*/ +define([ + '../Core/destroyObject', + '../Core/Ellipsoid', + '../Core/Cartesian3', + '../Core/Cartesian4', + '../Core/Matrix4', + '../Core/Transforms', + './CameraEventHandler', + './CameraEventType', + './CameraSpindleController', + './CameraFreeLookController' + ], function( + destroyObject, + Ellipsoid, + Cartesian3, + Cartesian4, + Matrix4, + Transforms, + CameraEventHandler, + CameraEventType, + CameraSpindleController, + CameraFreeLookController) { + "use strict"; + + /** + * DOC_TBD + * @name CameraCentralBodyController + * @constructor + */ + function CameraCentralBodyController(canvas, camera, ellipsoid) { + this._canvas = canvas; + this._camera = camera; + + this._spindleController = new CameraSpindleController(canvas, camera, ellipsoid); + this._freeLookController = new CameraFreeLookController(canvas, camera); + this._freeLookController.horizontalRotationAxis = Cartesian3.UNIT_Z; + + this._rotateHandler = new CameraEventHandler(canvas, CameraEventType.RIGHT_DRAG); + + this._transform = Matrix4.IDENTITY; + } + + /** + * @private + */ + CameraCentralBodyController.prototype.update = function() { + var rotate = this._rotateHandler; + var rotating = rotate.isMoving() && rotate.getMovement(); + + if (rotating) { + var movement = rotate.getMovement(); + var press = rotate.getButtonPressTime(); + var release = rotate.getButtonReleaseTime(); + + if (typeof press !== 'undefined' && (typeof release === 'undefined' || press.greaterThan(release))) { + var center = this._camera.pickEllipsoid(this._spindleController.getEllipsoid(), movement.startPosition); + if (typeof center === 'undefined') { + this._transform = Matrix4.IDENTITY; + } else { + this._transform = Transforms.eastNorthUpToFixedFrame(center); + } + } + + this._rotate(movement); + } + + this._spindleController.update(); + this._freeLookController.update(); + + return true; + }; + + CameraCentralBodyController.prototype._rotate = function(movement) { + var transform = this._transform; + var camera = this._camera; + var position = camera.position; + var up = camera.up; + var right = camera.right; + var direction = camera.direction; + + var oldTransform = camera.transform; + var oldEllipsoid = this._spindleController.getEllipsoid(); + var oldConstrainedZ = this._spindleController.mouseConstrainedZAxis; + + this._spindleController.setReferenceFrame(transform, Ellipsoid.UNIT_SPHERE); + this._spindleController.mouseConstrainedZAxis = true; + + var invTransform = camera.getInverseTransform(); + camera.position = invTransform.multiplyWithVector(new Cartesian4(position.x, position.y, position.z, 1.0)).getXYZ(); + camera.up = invTransform.multiplyWithVector(new Cartesian4(up.x, up.y, up.z, 0.0)).getXYZ(); + camera.right = invTransform.multiplyWithVector(new Cartesian4(right.x, right.y, right.z, 0.0)).getXYZ(); + camera.direction = invTransform.multiplyWithVector(new Cartesian4(direction.x, direction.y, direction.z, 0.0)).getXYZ(); + + this._spindleController._rotate(movement); + + position = camera.position; + up = camera.up; + right = camera.right; + direction = camera.direction; + + this._spindleController.setReferenceFrame(oldTransform, oldEllipsoid); + this._spindleController.mouseConstrainedZAxis = oldConstrainedZ; + + camera.position = transform.multiplyWithVector(new Cartesian4(position.x, position.y, position.z, 1.0)).getXYZ(); + camera.up = transform.multiplyWithVector(new Cartesian4(up.x, up.y, up.z, 0.0)).getXYZ(); + camera.right = transform.multiplyWithVector(new Cartesian4(right.x, right.y, right.z, 0.0)).getXYZ(); + camera.direction = transform.multiplyWithVector(new Cartesian4(direction.x, direction.y, direction.z, 0.0)).getXYZ(); + }; + + /** + * Returns true if this object was destroyed; otherwise, false. + *

+ * If this object was destroyed, it should not be used; calling any function other than + * isDestroyed will result in a {@link DeveloperError} exception. + * + * @memberof CameraCentralBodyController + * + * @return {Boolean} true if this object was destroyed; otherwise, false. + * + * @see CameraCentralBodyController#destroy + */ + CameraCentralBodyController.prototype.isDestroyed = function() { + return false; + }; + + /** + * Removes mouse and keyboard listeners held by this object. + *

+ * Once an object is destroyed, it should not be used; calling any function other than + * isDestroyed will result in a {@link DeveloperError} exception. Therefore, + * assign the return value (undefined) to the object as done in the example. + * + * @memberof CameraCentralBodyController + * + * @return {undefined} + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * @see CameraCentralBodyController#isDestroyed + * + * @example + * controller = controller && controller.destroy(); + */ + CameraCentralBodyController.prototype.destroy = function() { + this._rotateHandler = this._rotateHandler && this._rotateHandler.destroy(); + this._spindleController = this._spindleController && this._spindleController.destroy(); + this._freeLookController = this._freeLookController && this._freeLookController.destroy(); + return destroyObject(this); + }; + + return CameraCentralBodyController; +}); \ No newline at end of file diff --git a/Source/Scene/CameraColumbusViewController.js b/Source/Scene/CameraColumbusViewController.js index ed91768adc3d..f853d06e1753 100644 --- a/Source/Scene/CameraColumbusViewController.js +++ b/Source/Scene/CameraColumbusViewController.js @@ -1,7 +1,6 @@ /*global define*/ define([ '../Core/destroyObject', - '../Core/FAR', '../Core/Ellipsoid', '../Core/Cartesian3', '../Core/Cartesian4', @@ -13,7 +12,6 @@ define([ './CameraHelpers' ], function( destroyObject, - FAR, Ellipsoid, Cartesian3, Cartesian4, @@ -45,10 +43,6 @@ define([ */ this.inertiaTranslate = 0.9; - this._translateFactor = 1.0; - this._minimumZoomRate = 20.0; - this._maximumZoomRate = FAR; - this._translateHandler = new CameraEventHandler(canvas, CameraEventType.LEFT_DRAG); this._spindleController = new CameraSpindleController(canvas, camera, Ellipsoid.UNIT_SPHERE); diff --git a/Source/Scene/CameraControllerCollection.js b/Source/Scene/CameraControllerCollection.js index 9f0abfa3cc83..e44f8b49e496 100644 --- a/Source/Scene/CameraControllerCollection.js +++ b/Source/Scene/CameraControllerCollection.js @@ -8,7 +8,8 @@ define([ './CameraFlightController', './CameraSpindleController', './CameraFreeLookController', - './CameraColumbusViewController' + './CameraColumbusViewController', + './CameraCentralBodyController' ], function( DeveloperError, destroyObject, @@ -18,7 +19,8 @@ define([ CameraFlightController, CameraSpindleController, CameraFreeLookController, - CameraColumbusViewController) { + CameraColumbusViewController, + CameraCentralBodyController) { "use strict"; /** @@ -120,6 +122,12 @@ define([ return flightController; }; + CameraControllerCollection.prototype.addCentralBody = function() { + var cb = new CameraCentralBodyController(this._canvas, this._camera); + this._controllers.push(cb); + return cb; + }; + /** * DOC_TBA * diff --git a/Source/Scene/CameraSpindleController.js b/Source/Scene/CameraSpindleController.js index a30b192ac755..260a3103dc7b 100644 --- a/Source/Scene/CameraSpindleController.js +++ b/Source/Scene/CameraSpindleController.js @@ -404,7 +404,7 @@ define([ CameraSpindleController.prototype._spin = function(movement) { if (this.mode === CameraSpindleControllerMode.AUTO) { var point = this._camera.pickEllipsoid(this._ellipsoid, movement.startPosition); - if (point) { + if (typeof point !== 'undefined') { this._pan(movement); } else { this._rotate(movement); @@ -449,7 +449,7 @@ define([ var p0 = camera.pickEllipsoid(this._ellipsoid, movement.startPosition); var p1 = camera.pickEllipsoid(this._ellipsoid, movement.endPosition); - if (!p0 || !p1) { + if (typeof p0 === 'undefined' || typeof p1 === 'undefined') { return; } diff --git a/Source/Scene/SceneTransitioner.js b/Source/Scene/SceneTransitioner.js index 34e0552890ff..a96b1f5d41d5 100644 --- a/Source/Scene/SceneTransitioner.js +++ b/Source/Scene/SceneTransitioner.js @@ -255,8 +255,7 @@ define([ var camera = scene.getCamera(); var controllers = camera.getControllers(); controllers.removeAll(); - controllers.addSpindle(); - controllers.addFreeLook(); + controllers.addCentralBody(); camera.frustum = this._camera3D.frustum.clone(); camera.transform = Matrix4.IDENTITY; From 6f75f715264206a3d61bb03d1531dd010e148aac Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 21 Jun 2012 14:48:09 -0400 Subject: [PATCH 03/36] Swap default zoom and rotate mouse buttons. --- Source/Scene/Camera2DController.js | 4 ++-- Source/Scene/CameraCentralBodyController.js | 2 +- Source/Scene/CameraColumbusViewController.js | 2 +- Source/Scene/CameraSpindleController.js | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Source/Scene/Camera2DController.js b/Source/Scene/Camera2DController.js index 9cc3f1c40f73..22e4d370c5a6 100644 --- a/Source/Scene/Camera2DController.js +++ b/Source/Scene/Camera2DController.js @@ -73,9 +73,9 @@ define([ this._maximumZoomRate = FAR; this._translateHandler = new CameraEventHandler(canvas, CameraEventType.LEFT_DRAG); - this._zoomHandler = new CameraEventHandler(canvas, CameraEventType.MIDDLE_DRAG); + this._zoomHandler = new CameraEventHandler(canvas, CameraEventType.RIGHT_DRAG); this._zoomWheel = new CameraEventHandler(canvas, CameraEventType.WHEEL); - this._twistHandler = new CameraEventHandler(canvas, CameraEventType.RIGHT_DRAG); + this._twistHandler = new CameraEventHandler(canvas, CameraEventType.MIDDLE_DRAG); this._lastInertiaTranslateMovement = undefined; this._lastInertiaZoomMovement = undefined; diff --git a/Source/Scene/CameraCentralBodyController.js b/Source/Scene/CameraCentralBodyController.js index cc479a7b766b..e8f653f82ebb 100644 --- a/Source/Scene/CameraCentralBodyController.js +++ b/Source/Scene/CameraCentralBodyController.js @@ -36,7 +36,7 @@ define([ this._freeLookController = new CameraFreeLookController(canvas, camera); this._freeLookController.horizontalRotationAxis = Cartesian3.UNIT_Z; - this._rotateHandler = new CameraEventHandler(canvas, CameraEventType.RIGHT_DRAG); + this._rotateHandler = new CameraEventHandler(canvas, CameraEventType.MIDDLE_DRAG); this._transform = Matrix4.IDENTITY; } diff --git a/Source/Scene/CameraColumbusViewController.js b/Source/Scene/CameraColumbusViewController.js index f853d06e1753..9e42908f58de 100644 --- a/Source/Scene/CameraColumbusViewController.js +++ b/Source/Scene/CameraColumbusViewController.js @@ -50,7 +50,7 @@ define([ // TODO: Shouldn't change private variables like this, need to be able to change event modifiers // on controllers. this._spindleController._spinHandler = this._spindleController._spinHandler && this._spindleController._spinHandler.destroy(); - this._spindleController._spinHandler = new CameraEventHandler(canvas, CameraEventType.RIGHT_DRAG); + this._spindleController._spinHandler = new CameraEventHandler(canvas, CameraEventType.MIDDLE_DRAG); this._spindleController.mouseConstrainedZAxis = true; this._freeLookController = new CameraFreeLookController(canvas, camera); diff --git a/Source/Scene/CameraSpindleController.js b/Source/Scene/CameraSpindleController.js index 260a3103dc7b..496a16a2e733 100644 --- a/Source/Scene/CameraSpindleController.js +++ b/Source/Scene/CameraSpindleController.js @@ -98,7 +98,7 @@ define([ this._minimumRotateRate = 1.0 / 5000.0; this._spinHandler = new CameraEventHandler(canvas, CameraEventType.LEFT_DRAG); - this._zoomHandler = new CameraEventHandler(canvas, CameraEventType.MIDDLE_DRAG); + this._zoomHandler = new CameraEventHandler(canvas, CameraEventType.RIGHT_DRAG); this._zoomWheel = new CameraEventHandler(canvas, CameraEventType.WHEEL); this._lastInertiaSpinMovement = undefined; From d5bbd5a7908e536cb1fbdc605efbc91bea7a00fb Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 21 Jun 2012 15:10:57 -0400 Subject: [PATCH 04/36] Constrain Camera to map in 2D controller. --- Source/Scene/Camera2DController.js | 32 ++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/Source/Scene/Camera2DController.js b/Source/Scene/Camera2DController.js index 22e4d370c5a6..2c9875215c9c 100644 --- a/Source/Scene/Camera2DController.js +++ b/Source/Scene/Camera2DController.js @@ -297,12 +297,40 @@ define([ end.y = (2.0 / height) * (height - movement.endPosition.y) - 1.0; end.y = (end.y * (frustum.top - frustum.bottom) + frustum.top + frustum.bottom) * 0.5; + var camera = this._camera; + var right = camera.right; + var up = camera.up; + var position; + var newPosition; + var distance = start.subtract(end); if (distance.x !== 0) { - this.moveRight(distance.x); + position = camera.position; + newPosition = position.add(right.multiplyWithScalar(distance.x)); + + var maxX = this._ellipsoid.getRadii().x * Math.PI; + if (newPosition.x > maxX) { + newPosition.x = maxX; + } + if (newPosition.x < -maxX) { + newPosition.x = -maxX; + } + + camera.position = newPosition; } if (distance.y !== 0) { - this.moveUp(distance.y); + position = camera.position; + newPosition = position.add(up.multiplyWithScalar(distance.y)); + + var maxY = this._ellipsoid.getRadii().z * CesiumMath.PI_OVER_TWO; + if (newPosition.y > maxY) { + newPosition.y = maxY; + } + if (newPosition.y < -maxY) { + newPosition.y = -maxY; + } + + camera.position = newPosition; } }; From 0124587eb0b3bd13e329ec8ad680fed2475a537d Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 21 Jun 2012 16:11:39 -0400 Subject: [PATCH 05/36] Constrain camera to viewing the map in Columbus View. --- Source/Scene/CameraColumbusViewController.js | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/Source/Scene/CameraColumbusViewController.js b/Source/Scene/CameraColumbusViewController.js index 9e42908f58de..7c16e8790759 100644 --- a/Source/Scene/CameraColumbusViewController.js +++ b/Source/Scene/CameraColumbusViewController.js @@ -4,6 +4,7 @@ define([ '../Core/Ellipsoid', '../Core/Cartesian3', '../Core/Cartesian4', + '../Core/Math', '../Core/Matrix4', './CameraEventHandler', './CameraEventType', @@ -15,6 +16,7 @@ define([ Ellipsoid, Cartesian3, Cartesian4, + CesiumMath, Matrix4, CameraEventHandler, CameraEventType, @@ -30,9 +32,10 @@ define([ * @name CameraColumbusViewController * @constructor */ - function CameraColumbusViewController(canvas, camera) { + function CameraColumbusViewController(canvas, camera, ellipsoid) { this._canvas = canvas; this._camera = camera; + this._ellipsoid = ellipsoid || Ellipsoid.WGS84; /** * A parameter in the range [0, 1] used to determine how long @@ -113,6 +116,21 @@ define([ var cameraPosition = new Cartesian4(camera.position.x, camera.position.y, camera.position.z, 1.0); var positionWC = camera.transform.multiplyWithVector(cameraPosition); camera.transform = this._transform.clone(); + + var maxX = this._ellipsoid.getRadii().x * Math.PI; + if (centerWC.y > maxX) { + positionWC.y -= centerWC.y - maxX; + } else if (centerWC.y < -maxX) { + positionWC.y += -maxX - centerWC.y; + } + + var maxY = this._ellipsoid.getRadii().z * CesiumMath.PI_OVER_TWO; + if (centerWC.z > maxY) { + positionWC.z -= centerWC.z - maxY; + } else if (centerWC.z < -maxY) { + positionWC.z += -maxY - centerWC.z; + } + camera.position = camera.getInverseTransform().multiplyWithVector(positionWC).getXYZ(); }; From 70dd455c15097e658d6d988ac8f3afa51b56a873 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 21 Jun 2012 16:44:29 -0400 Subject: [PATCH 06/36] Constrain 2D zoom level so that the map width is never less than the width of the window. --- Source/Scene/Camera2DController.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Source/Scene/Camera2DController.js b/Source/Scene/Camera2DController.js index 2c9875215c9c..bf939954217b 100644 --- a/Source/Scene/Camera2DController.js +++ b/Source/Scene/Camera2DController.js @@ -212,6 +212,13 @@ define([ var newRight = frustum.right - moveRate; var newLeft = frustum.left + moveRate; + + var maxRight = this._ellipsoid.getRadii().x * Math.PI; + if (newRight > maxRight) { + newRight = maxRight; + newLeft = -newRight; + } + if (newRight > newLeft) { var ratio = frustum.top / frustum.right; frustum.right = newRight; From 081c4e6ad7e208c55419020c19af6bb74d7d0db0 Mon Sep 17 00:00:00 2001 From: Ed Mackey Date: Thu, 21 Jun 2012 16:57:30 -0400 Subject: [PATCH 07/36] Works better times two! --- Source/Scene/Camera2DController.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Scene/Camera2DController.js b/Source/Scene/Camera2DController.js index bf939954217b..9c2ccb3174f0 100644 --- a/Source/Scene/Camera2DController.js +++ b/Source/Scene/Camera2DController.js @@ -213,7 +213,7 @@ define([ var newRight = frustum.right - moveRate; var newLeft = frustum.left + moveRate; - var maxRight = this._ellipsoid.getRadii().x * Math.PI; + var maxRight = this._ellipsoid.getRadii().x * Math.PI * 2; if (newRight > maxRight) { newRight = maxRight; newLeft = -newRight; From d6b93a23c26196b7c0adaf9d7c1a3b832569b830 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 21 Jun 2012 20:40:45 -0400 Subject: [PATCH 08/36] Add bounce-back inertia to 2D map when you zoom too far out. --- Source/Scene/Camera2DController.js | 67 ++++++++++++++++++++++++++++-- Source/Scene/SceneTransitioner.js | 6 +-- 2 files changed, 66 insertions(+), 7 deletions(-) diff --git a/Source/Scene/Camera2DController.js b/Source/Scene/Camera2DController.js index 9c2ccb3174f0..386afd6835e7 100644 --- a/Source/Scene/Camera2DController.js +++ b/Source/Scene/Camera2DController.js @@ -7,9 +7,12 @@ define([ '../Core/Quaternion', '../Core/Ellipsoid', '../Core/Cartesian2', + '../Core/JulianDate', './CameraEventHandler', './CameraEventType', - './CameraHelpers' + './CameraHelpers', + './AnimationCollection', + '../ThirdParty/Tween' ], function( DeveloperError, destroyObject, @@ -18,9 +21,12 @@ define([ Quaternion, Ellipsoid, Cartesian2, + JulianDate, CameraEventHandler, CameraEventType, - CameraHelpers) { + CameraHelpers, + AnimationCollection, + Tween) { "use strict"; var move = CameraHelpers.move; @@ -77,9 +83,12 @@ define([ this._zoomWheel = new CameraEventHandler(canvas, CameraEventType.WHEEL); this._twistHandler = new CameraEventHandler(canvas, CameraEventType.MIDDLE_DRAG); - this._lastInertiaTranslateMovement = undefined; this._lastInertiaZoomMovement = undefined; + this._lastInertiaTranslateMovement = undefined; this._lastInertiaWheelZoomMovement = undefined; + + this._frustum = this._camera.frustum.clone(); + this._animationCollection = new AnimationCollection(); } /** @@ -213,7 +222,7 @@ define([ var newRight = frustum.right - moveRate; var newLeft = frustum.left + moveRate; - var maxRight = this._ellipsoid.getRadii().x * Math.PI * 2; + var maxRight = this._ellipsoid.getRadii().x * Math.PI * 2.0; if (newRight > maxRight) { newRight = maxRight; newLeft = -newRight; @@ -241,6 +250,35 @@ define([ this.zoomIn(-rate || -this._zoomRate); }; + Camera2DController.prototype._addCorrectFrustumAnimation = function() { + var camera = this._camera; + var frustum = camera.frustum; + var top = frustum.top; + var bottom = frustum.bottom; + var right = frustum.right; + var left = frustum.left; + + var startFrustum = this._frustum; + + var update2D = function(value) { + camera.frustum.top = CesiumMath.lerp(top, startFrustum.top, value.time); + camera.frustum.bottom = CesiumMath.lerp(bottom, startFrustum.bottom, value.time); + camera.frustum.right = CesiumMath.lerp(right, startFrustum.right, value.time); + camera.frustum.left = CesiumMath.lerp(left, startFrustum.left, value.time); + }; + + this._animationCollection.add({ + easingFunction : Tween.Easing.Exponential.EaseOut, + startValue : { + time : 0.0 + }, + stopValue : { + time : 1.0 + }, + onUpdate : update2D + }); + }; + /** * @private */ @@ -252,6 +290,10 @@ define([ var rightZooming = rightZoom.isMoving(); var wheelZooming = wheelZoom.isMoving(); + if (translate.isButtonDown() || rightZoom.isButtonDown() || wheelZooming) { + this._animationCollection.removeAll(); + } + if (translating) { this._translate(translate.getMovement()); } @@ -278,6 +320,23 @@ define([ this._twist(this._twistHandler.getMovement()); } + var ts = rightZoom.getButtonPressTime(); + var tr = rightZoom.getButtonReleaseTime(); + var threshold = ts && tr && ts.getSecondsDifference(tr); + var now = new JulianDate(); + var fromNow = tr && tr.getSecondsDifference(now); + if ((ts && tr && threshold > 0.4) || fromNow > 2.0) { // TODO: These two magic numbers come from CameraHelpers.maintainInertia + this._lastInertiaZoomMovement = undefined; + } + + if (!translate.isButtonDown() && !rightZoom.isButtonDown() && + this._camera.frustum.right > this._ellipsoid.getRadii().x * Math.PI && + !this._lastInertiaZoomMovement && Tween.getAll().length == 0) { + this._addCorrectFrustumAnimation(); + } + + this._animationCollection.update(); + return true; }; diff --git a/Source/Scene/SceneTransitioner.js b/Source/Scene/SceneTransitioner.js index a96b1f5d41d5..3849aef368a3 100644 --- a/Source/Scene/SceneTransitioner.js +++ b/Source/Scene/SceneTransitioner.js @@ -190,13 +190,13 @@ define([ this._destroyMorphHandler(); var camera = scene.getCamera(); + camera.frustum = this._camera2D.frustum.clone(); + camera.transform = this._camera2D.transform.clone(); + var controllers = camera.getControllers(); controllers.removeAll(); controllers.add2D(this._ellipsoid); - camera.frustum = this._camera2D.frustum.clone(); - camera.transform = this._camera2D.transform.clone(); - // TODO: Match incoming columbus-view or 3D position camera.position = this._camera2D.position.clone(); camera.direction = this._camera2D.direction.clone(); From 29940eb2e107c065b3469ec6c15693078495a0fd Mon Sep 17 00:00:00 2001 From: Ed Mackey Date: Fri, 22 Jun 2012 11:12:13 -0400 Subject: [PATCH 09/36] Tweaking the new zoom bounce. --- Source/Scene/Camera2DController.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Source/Scene/Camera2DController.js b/Source/Scene/Camera2DController.js index 386afd6835e7..be4ddb84958b 100644 --- a/Source/Scene/Camera2DController.js +++ b/Source/Scene/Camera2DController.js @@ -89,6 +89,12 @@ define([ this._frustum = this._camera.frustum.clone(); this._animationCollection = new AnimationCollection(); + + this._maxZoomOut = 2.0; + this._frustum.right *= this._maxZoomOut; + this._frustum.left *= this._maxZoomOut; + this._frustum.top *= this._maxZoomOut; + this._frustum.bottom *= this._maxZoomOut; } /** @@ -222,7 +228,7 @@ define([ var newRight = frustum.right - moveRate; var newLeft = frustum.left + moveRate; - var maxRight = this._ellipsoid.getRadii().x * Math.PI * 2.0; + var maxRight = this._ellipsoid.getRadii().x * Math.PI * 2.5; if (newRight > maxRight) { newRight = maxRight; newLeft = -newRight; @@ -330,8 +336,8 @@ define([ } if (!translate.isButtonDown() && !rightZoom.isButtonDown() && - this._camera.frustum.right > this._ellipsoid.getRadii().x * Math.PI && - !this._lastInertiaZoomMovement && Tween.getAll().length == 0) { + this._camera.frustum.right > this._frustum.right && + !this._lastInertiaZoomMovement && Tween.getAll().length === 0) { this._addCorrectFrustumAnimation(); } From 39d6b2397f3d09ef845f181c37a6b06a724c09b5 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 22 Jun 2012 14:53:12 -0400 Subject: [PATCH 10/36] Add bounce-back along the viewport edges to the 2D camera controller. --- Source/Scene/Camera2DController.js | 93 ++++++++++++++++++++++-------- Source/Scene/CameraHelpers.js | 12 ++-- 2 files changed, 73 insertions(+), 32 deletions(-) diff --git a/Source/Scene/Camera2DController.js b/Source/Scene/Camera2DController.js index be4ddb84958b..c6ede8aa254e 100644 --- a/Source/Scene/Camera2DController.js +++ b/Source/Scene/Camera2DController.js @@ -7,7 +7,7 @@ define([ '../Core/Quaternion', '../Core/Ellipsoid', '../Core/Cartesian2', - '../Core/JulianDate', + '../Core/Cartesian3', './CameraEventHandler', './CameraEventType', './CameraHelpers', @@ -21,7 +21,7 @@ define([ Quaternion, Ellipsoid, Cartesian2, - JulianDate, + Cartesian3, CameraEventHandler, CameraEventType, CameraHelpers, @@ -89,12 +89,20 @@ define([ this._frustum = this._camera.frustum.clone(); this._animationCollection = new AnimationCollection(); + this._zoomAnimation = undefined; + this._translateAnimation = undefined; - this._maxZoomOut = 2.0; - this._frustum.right *= this._maxZoomOut; - this._frustum.left *= this._maxZoomOut; - this._frustum.top *= this._maxZoomOut; - this._frustum.bottom *= this._maxZoomOut; + var maxZoomOut = 2.0; + this._frustum.right *= maxZoomOut; + this._frustum.left *= maxZoomOut; + this._frustum.top *= maxZoomOut; + this._frustum.bottom *= maxZoomOut; + + this._cameraMaxX = this._ellipsoid.getRadii().x * Math.PI; + this._cameraMaxY = this._ellipsoid.getRadii().y * CesiumMath.PI_OVER_TWO; + + this._maxZoomFactor = 2.5; + this._maxTranslateFactor = 1.5; } /** @@ -228,7 +236,7 @@ define([ var newRight = frustum.right - moveRate; var newLeft = frustum.left + moveRate; - var maxRight = this._ellipsoid.getRadii().x * Math.PI * 2.5; + var maxRight = this._cameraMaxX * this._maxZoomFactor; if (newRight > maxRight) { newRight = maxRight; newLeft = -newRight; @@ -256,7 +264,7 @@ define([ this.zoomIn(-rate || -this._zoomRate); }; - Camera2DController.prototype._addCorrectFrustumAnimation = function() { + Camera2DController.prototype._addCorrectZoomAnimation = function() { var camera = this._camera; var frustum = camera.frustum; var top = frustum.top; @@ -273,7 +281,40 @@ define([ camera.frustum.left = CesiumMath.lerp(left, startFrustum.left, value.time); }; - this._animationCollection.add({ + this._zoomAnimation = this._animationCollection.add({ + easingFunction : Tween.Easing.Exponential.EaseOut, + startValue : { + time : 0.0 + }, + stopValue : { + time : 1.0 + }, + onUpdate : update2D + }); + }; + + Camera2DController.prototype._addCorrectTranslateAnimation = function() { + var camera = this._camera; + var currentPosition = camera.position; + var translatedPosition = currentPosition.clone(); + + if (translatedPosition.x > this._cameraMaxX) { + translatedPosition.x = this._cameraMaxX; + } else if (translatedPosition.x < -this._cameraMaxX) { + translatedPosition.x = -this._cameraMaxX; + } + + if (translatedPosition.y > this._cameraMaxY) { + translatedPosition.y = this._cameraMaxY; + } else if (translatedPosition.y < -this._cameraMaxY) { + translatedPosition.y = -this._cameraMaxY; + } + + var update2D = function(value) { + camera.position = currentPosition.lerp(translatedPosition, value.time); + }; + + this._translateAnimation = this._animationCollection.add({ easingFunction : Tween.Easing.Exponential.EaseOut, startValue : { time : 0.0 @@ -326,19 +367,21 @@ define([ this._twist(this._twistHandler.getMovement()); } - var ts = rightZoom.getButtonPressTime(); - var tr = rightZoom.getButtonReleaseTime(); - var threshold = ts && tr && ts.getSecondsDifference(tr); - var now = new JulianDate(); - var fromNow = tr && tr.getSecondsDifference(now); - if ((ts && tr && threshold > 0.4) || fromNow > 2.0) { // TODO: These two magic numbers come from CameraHelpers.maintainInertia - this._lastInertiaZoomMovement = undefined; - } - - if (!translate.isButtonDown() && !rightZoom.isButtonDown() && - this._camera.frustum.right > this._frustum.right && - !this._lastInertiaZoomMovement && Tween.getAll().length === 0) { - this._addCorrectFrustumAnimation(); + if (!translate.isButtonDown() && !rightZoom.isButtonDown()) { + var animations = Tween.getAll(); + + if (this._camera.frustum.right > this._frustum.right && + !this._lastInertiaZoomMovement && animations.indexOf(this._zoomAnimation) === -1) { + this._addCorrectZoomAnimation(); + } + + var position = this._camera.position; + var translateX = position.x < -this._cameraMaxX || position.x > this._cameraMaxX; + var translateY = position.y < -this._cameraMaxY || position.y > this._cameraMaxY; + if ((translateX || translateY) && !this._lastInertiaTranslateMovement && + animations.indexOf(this._translateAnimation) === -1) { + this._addCorrectTranslateAnimation(); + } } this._animationCollection.update(); @@ -380,7 +423,7 @@ define([ position = camera.position; newPosition = position.add(right.multiplyWithScalar(distance.x)); - var maxX = this._ellipsoid.getRadii().x * Math.PI; + var maxX = this._cameraMaxX * this._maxTranslateFactor; if (newPosition.x > maxX) { newPosition.x = maxX; } @@ -394,7 +437,7 @@ define([ position = camera.position; newPosition = position.add(up.multiplyWithScalar(distance.y)); - var maxY = this._ellipsoid.getRadii().z * CesiumMath.PI_OVER_TWO; + var maxY = this._cameraMaxY * this._maxTranslateFactor; if (newPosition.y > maxY) { newPosition.y = maxY; } diff --git a/Source/Scene/CameraHelpers.js b/Source/Scene/CameraHelpers.js index 181858ae19ec..ff25162cf910 100644 --- a/Source/Scene/CameraHelpers.js +++ b/Source/Scene/CameraHelpers.js @@ -39,13 +39,9 @@ define([ var ts = handler.getButtonPressTime(); var tr = handler.getButtonReleaseTime(); var threshold = ts && tr && ts.getSecondsDifference(tr); - if (ts && tr && threshold < inertiaMaxClickTimeThreshold) { - var now = new JulianDate(); - var fromNow = tr.getSecondsDifference(now); - if (fromNow > inertiaMaxTimeThreshold) { - return; - } - + var now = new JulianDate(); + var fromNow = tr && tr.getSecondsDifference(now); + if (ts && tr && threshold < inertiaMaxClickTimeThreshold && fromNow <= inertiaMaxTimeThreshold) { var d = decay(fromNow, decayCoef); if (!object[lastMovementName]) { @@ -81,6 +77,8 @@ define([ if (!handler.isButtonDown()) { action.apply(object, [object[lastMovementName]]); } + } else { + object[lastMovementName] = undefined; } } From 19927471f3927b9959eb6bae8c945939871c4f7c Mon Sep 17 00:00:00 2001 From: Ed Mackey Date: Fri, 22 Jun 2012 18:14:07 -0400 Subject: [PATCH 11/36] Trying to get new mouse stuff working in Viewer. Known issue is right-click to follow object is broken in this commit. @bagnell is on the case. --- Apps/CesiumViewer/CesiumViewer.js | 5 ++++- Source/DojoWidgets/CesiumWidget.js | 8 ++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/Apps/CesiumViewer/CesiumViewer.js b/Apps/CesiumViewer/CesiumViewer.js index 6e9278a35766..ff765b0ee1ca 100644 --- a/Apps/CesiumViewer/CesiumViewer.js +++ b/Apps/CesiumViewer/CesiumViewer.js @@ -147,7 +147,10 @@ function(dom, } var transform = Transforms.eastNorthUpToFixedFrame(cameraCenteredObjectIDPosition, widget.ellipsoid); - this.spindleCameraController.setReferenceFrame(transform, Ellipsoid.UNIT_SPHERE); + var controllers = widget.scene.getCamera().getControllers(); + controllers.removeAll(); + var spindleController = controllers.addSpindle(); + spindleController.setReferenceFrame(transform, Ellipsoid.UNIT_SPHERE); } } } diff --git a/Source/DojoWidgets/CesiumWidget.js b/Source/DojoWidgets/CesiumWidget.js index 2b832b8988a6..6a45d514d0d8 100644 --- a/Source/DojoWidgets/CesiumWidget.js +++ b/Source/DojoWidgets/CesiumWidget.js @@ -215,9 +215,7 @@ define([ camera.frustum.near = 0.0002 * maxRadii; camera.frustum.far = 50.0 * maxRadii; - this.spindleCameraController = camera.getControllers().addSpindle(ellipsoid); - this.spindleCameraController.mouseConstrainedZAxis = true; - this.freelookCameraController = camera.getControllers().addFreeLook(ellipsoid); + this.centralBodyCameraController = camera.getControllers().addCentralBody(); var handler = new EventHandler(canvas); handler.setMouseAction(lang.hitch(this, '_handleLeftClick'), MouseEventType.LEFT_CLICK); @@ -248,9 +246,7 @@ define([ var controllers = camera.getControllers(); controllers.removeAll(); - this.spindleCameraController = controllers.addSpindle(this.ellipsoid); - this.spindleCameraController.constrainedZAxis = true; - this.freelookCameraController = controllers.addFreeLook(this.ellipsoid); + this.centralBodyCameraController = controllers.addCentralBody(); }, areCloudsAvailable : function() { From 5d5c4360cd5a7ae557234c4096f57072c2285827 Mon Sep 17 00:00:00 2001 From: Ed Mackey Date: Fri, 22 Jun 2012 18:15:41 -0400 Subject: [PATCH 12/36] Reduce zoom speed. --- Source/Scene/Camera2DController.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Scene/Camera2DController.js b/Source/Scene/Camera2DController.js index c6ede8aa254e..fefe7796ec3e 100644 --- a/Source/Scene/Camera2DController.js +++ b/Source/Scene/Camera2DController.js @@ -73,7 +73,7 @@ define([ */ this.inertiaZoom = 0.8; - this._zoomFactor = 5.0; + this._zoomFactor = 1.5; this._translateFactor = 1.0; this._minimumZoomRate = 20.0; this._maximumZoomRate = FAR; From 278b3b9b2165f657c44de12cbe199e488a4d2092 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 22 Jun 2012 19:55:25 -0400 Subject: [PATCH 13/36] Fix spindle controller following an object in the Viewer. --- Apps/CesiumViewer/CesiumViewer.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Apps/CesiumViewer/CesiumViewer.js b/Apps/CesiumViewer/CesiumViewer.js index ff765b0ee1ca..99e92248e30f 100644 --- a/Apps/CesiumViewer/CesiumViewer.js +++ b/Apps/CesiumViewer/CesiumViewer.js @@ -144,13 +144,16 @@ function(dom, lastCameraCenteredObjectID = cameraCenteredObjectID; var camera = widget.scene.getCamera(); camera.position = camera.position.normalize().multiplyWithScalar(5000.0); + + var controllers = camera.getControllers(); + controllers.removeAll(); + this.spindleController = controllers.addSpindle(); } - var transform = Transforms.eastNorthUpToFixedFrame(cameraCenteredObjectIDPosition, widget.ellipsoid); - var controllers = widget.scene.getCamera().getControllers(); - controllers.removeAll(); - var spindleController = controllers.addSpindle(); - spindleController.setReferenceFrame(transform, Ellipsoid.UNIT_SPHERE); + if (typeof this.spindleController !== 'undefined' && !this.spindleController.isDestroyed()) { + var transform = Transforms.eastNorthUpToFixedFrame(cameraCenteredObjectIDPosition, widget.ellipsoid); + this.spindleController.setReferenceFrame(transform, Ellipsoid.UNIT_SPHERE); + } } } } From 2abb22b1b9211de94be21bc3eee3b7516c019552 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 22 Jun 2012 20:18:55 -0400 Subject: [PATCH 14/36] Tweak spindle camera to be able to be constrained on any axis. --- Examples/Sandbox/CodeSnippets/Camera.js | 3 +- Examples/Sandbox/Sandbox.js | 2 +- Source/Scene/CameraCentralBodyController.js | 6 ++-- Source/Scene/CameraColumbusViewController.js | 2 +- Source/Scene/CameraSpindleController.js | 30 ++++++++++---------- 5 files changed, 21 insertions(+), 22 deletions(-) diff --git a/Examples/Sandbox/CodeSnippets/Camera.js b/Examples/Sandbox/CodeSnippets/Camera.js index d3c6aa651993..0e96b7651dd8 100644 --- a/Examples/Sandbox/CodeSnippets/Camera.js +++ b/Examples/Sandbox/CodeSnippets/Camera.js @@ -32,7 +32,7 @@ var transform = Cesium.Transforms.eastNorthUpToFixedFrame(center); var spindle = scene.getCamera().getControllers().get(0); - spindle.mouseConstrainedZAxis = true; + spindle.constrainedAxis = Cesium.Cartesian3.UNIT_Z; spindle.setReferenceFrame(transform, Cesium.Ellipsoid.UNIT_SPHERE); // draw x axis in red @@ -75,7 +75,6 @@ this.clear = function() { var spindle = scene.getCamera().getControllers().get(0); spindle.setReferenceFrame(Cesium.Matrix4.IDENTITY); - spindle.mouseConstrainedZAxis = false; }; }; diff --git a/Examples/Sandbox/Sandbox.js b/Examples/Sandbox/Sandbox.js index c21488af7ecf..cdcfd89712df 100644 --- a/Examples/Sandbox/Sandbox.js +++ b/Examples/Sandbox/Sandbox.js @@ -33,7 +33,7 @@ var Sandbox = Sandbox || {}; primitives.setCentralBody(cb); scene.getCamera().getControllers().addSpindle(); - scene.getCamera().getControllers().get(0).mouseConstrainedZAxis = true; + scene.getCamera().getControllers().get(0).constrainedAxis = Cesium.Cartesian3.UNIT_Z; scene.getCamera().getControllers().addFreeLook(); diff --git a/Source/Scene/CameraCentralBodyController.js b/Source/Scene/CameraCentralBodyController.js index e8f653f82ebb..b98d74789b74 100644 --- a/Source/Scene/CameraCentralBodyController.js +++ b/Source/Scene/CameraCentralBodyController.js @@ -81,10 +81,10 @@ define([ var oldTransform = camera.transform; var oldEllipsoid = this._spindleController.getEllipsoid(); - var oldConstrainedZ = this._spindleController.mouseConstrainedZAxis; + var oldConstrainedZ = this._spindleController.constrainedAxis; this._spindleController.setReferenceFrame(transform, Ellipsoid.UNIT_SPHERE); - this._spindleController.mouseConstrainedZAxis = true; + this._spindleController.constrainedAxis = Cartesian3.UNIT_Z; var invTransform = camera.getInverseTransform(); camera.position = invTransform.multiplyWithVector(new Cartesian4(position.x, position.y, position.z, 1.0)).getXYZ(); @@ -100,7 +100,7 @@ define([ direction = camera.direction; this._spindleController.setReferenceFrame(oldTransform, oldEllipsoid); - this._spindleController.mouseConstrainedZAxis = oldConstrainedZ; + this._spindleController.constrainedAxis = oldConstrainedZ; camera.position = transform.multiplyWithVector(new Cartesian4(position.x, position.y, position.z, 1.0)).getXYZ(); camera.up = transform.multiplyWithVector(new Cartesian4(up.x, up.y, up.z, 0.0)).getXYZ(); diff --git a/Source/Scene/CameraColumbusViewController.js b/Source/Scene/CameraColumbusViewController.js index 6919053458c1..b7842ce7294f 100644 --- a/Source/Scene/CameraColumbusViewController.js +++ b/Source/Scene/CameraColumbusViewController.js @@ -54,7 +54,7 @@ define([ // on controllers. this._spindleController._spinHandler = this._spindleController._spinHandler && this._spindleController._spinHandler.destroy(); this._spindleController._spinHandler = new CameraEventHandler(canvas, CameraEventType.MIDDLE_DRAG); - this._spindleController.mouseConstrainedZAxis = true; + this._spindleController.constrainedAxis = Cartesian3.UNIT_Z; this._freeLookController = new CameraFreeLookController(canvas, camera); this._freeLookController.horizontalRotationAxis = Cartesian3.UNIT_Z; diff --git a/Source/Scene/CameraSpindleController.js b/Source/Scene/CameraSpindleController.js index 496a16a2e733..b186d78d3315 100644 --- a/Source/Scene/CameraSpindleController.js +++ b/Source/Scene/CameraSpindleController.js @@ -69,15 +69,15 @@ define([ this.inertiaZoom = 0.8; /** - * If set to true, the camera will not be able to rotate past the poles. - * If this is set to true while in pan mode, the position clicked on the ellipsoid - * while not always map directly to the cursor. + * If set, the camera will not be able to rotate past this axis in either direction. + * If this is set while in pan mode, the position clicked on the ellipsoid + * will not always map directly to the cursor. * - * @type Boolean + * @type Cartesian3 * * @see CameraSpindleController#mode */ - this.mouseConstrainedZAxis = false; + this.constrainedAxis = undefined; /** * Determines the rotation behavior on mouse events. @@ -86,8 +86,6 @@ define([ */ this.mode = CameraSpindleControllerMode.AUTO; - this._zAxis = Cartesian3.UNIT_Z; - var radius = this._ellipsoid.getRadii().getMaximumComponent(); this._zoomFactor = 5.0; this._minimumZoomRate = 20.0; @@ -255,7 +253,7 @@ define([ CameraSpindleController.prototype._moveVertical = function(angle, constrainedZ) { if (constrainedZ) { var p = this._camera.position.normalize(); - var dot = p.dot(this._zAxis); + var dot = p.dot(this.constrainedAxis.normalize()); if (CesiumMath.equalsEpsilon(1.0, Math.abs(dot), CesiumMath.EPSILON3) && dot * angle < 0.0) { return; } @@ -332,7 +330,7 @@ define([ CameraSpindleController.prototype._moveHorizontal = function(angle, constrainedZ) { if (constrainedZ) { - this.rotate(this._zAxis, angle); + this.rotate(this.constrainedAxis.normalize(), angle); } else { this.rotate(this._camera.up, angle); } @@ -435,13 +433,14 @@ define([ var deltaPhi = -rotateRate * phiWindowRatio * Math.PI * 2.0; var deltaTheta = -rotateRate * thetaWindowRatio * Math.PI; + var constrainedAxis = typeof this.constrainedAxis !== 'undefined'; var theta = Math.acos(position.z / rho) + deltaTheta; - if (this.mouseConstrainedZAxis && (theta < 0 || theta > Math.PI)) { + if (constrainedAxis && (theta < 0 || theta > Math.PI)) { deltaTheta = 0; } - this._moveHorizontal(deltaPhi, this.mouseConstrainedZAxis); - this._moveVertical(deltaTheta, this.mouseConstrainedZAxis); + this._moveHorizontal(deltaPhi, constrainedAxis); + this._moveVertical(deltaTheta, constrainedAxis); }; CameraSpindleController.prototype._pan = function(movement) { @@ -453,7 +452,7 @@ define([ return; } - if (!this.mouseConstrainedZAxis) { + if (typeof this.constrainedAxis === 'undefined') { p0 = p0.normalize(); p1 = p1.normalize(); var dot = p0.dot(p1); @@ -480,8 +479,9 @@ define([ deltaTheta = 0; } - this._moveHorizontal(deltaPhi, this.mouseConstrainedZAxis); - this._moveVertical(deltaTheta, this.mouseConstrainedZAxis); + var constrainedAxis = typeof this.constrainedAxis !== 'undefined'; + this._moveHorizontal(deltaPhi, constrainedAxis); + this._moveVertical(deltaTheta, constrainedAxis); } }; From 9e19d6045d2669f3b278661e128fabfd4c7ed06e Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 22 Jun 2012 20:29:21 -0400 Subject: [PATCH 15/36] Remove spindle controller methods that no longer make sense. Update tests. --- Source/Scene/CameraSpindleController.js | 101 +++------------------ Specs/Scene/CameraSpindleControllerSpec.js | 12 ++- 2 files changed, 23 insertions(+), 90 deletions(-) diff --git a/Source/Scene/CameraSpindleController.js b/Source/Scene/CameraSpindleController.js index b186d78d3315..68158c5dd403 100644 --- a/Source/Scene/CameraSpindleController.js +++ b/Source/Scene/CameraSpindleController.js @@ -200,7 +200,7 @@ define([ */ CameraSpindleController.prototype.moveDown = function(angle) { angle = (typeof angle !== 'undefined') ? -angle : -this._moveRate; - this._moveVertical(angle, false); + this._moveVertical(angle); }; /** @@ -215,52 +215,20 @@ define([ */ CameraSpindleController.prototype.moveUp = function(angle) { angle = (typeof angle !== 'undefined') ? angle : this._moveRate; - this._moveVertical(angle, false); + this._moveVertical(angle); }; - /** - * Rotates the camera around the center of the camera's reference frame by angle downwards - * and keeps the camera's up vector pointing towards the z-axis. - * - * @memberof CameraSpindleController - * - * @param {Number} angle The angle to rotate in radians. - * - * @see CameraSpindleController#moveUp - * @see CameraSpindleController#rotate - */ - CameraSpindleController.prototype.moveDownWithConstrainedZ = function(angle) { - angle = (typeof angle !== 'undefined') ? -angle : -this._moveRate; - this._moveVertical(angle, true); - }; - - /** - * Rotates the camera around the center of the camera's reference frame by angle upwards - * and keeps the camera's up vector pointing towards the z-axis. - * - * @memberof CameraSpindleController - * - * @param {Number} angle The angle to rotate in radians. - * - * @see CameraSpindleController#moveDown - * @see CameraSpindleController#rotate - */ - CameraSpindleController.prototype.moveUpWithConstrainedZ = function(angle) { - angle = (typeof angle !== 'undefined') ? angle : this._moveRate; - this._moveVertical(angle, true); - }; - - CameraSpindleController.prototype._moveVertical = function(angle, constrainedZ) { - if (constrainedZ) { + CameraSpindleController.prototype._moveVertical = function(angle) { + if (typeof this.constrainedAxis !== 'undefined') { var p = this._camera.position.normalize(); var dot = p.dot(this.constrainedAxis.normalize()); if (CesiumMath.equalsEpsilon(1.0, Math.abs(dot), CesiumMath.EPSILON3) && dot * angle < 0.0) { return; } - var angleToZ = Math.acos(dot); - if (Math.abs(angle) > Math.abs(angleToZ)) { - angle = angleToZ; + var angleToAxis = Math.acos(dot); + if (Math.abs(angle) > Math.abs(angleToAxis)) { + angle = angleToAxis; } } this.rotate(this._camera.right, angle); @@ -278,7 +246,7 @@ define([ */ CameraSpindleController.prototype.moveRight = function(angle) { angle = (typeof angle !== 'undefined') ? angle : this._moveRate; - this._moveHorizontal(angle, false); + this._moveHorizontal(angle); }; /** @@ -293,43 +261,11 @@ define([ */ CameraSpindleController.prototype.moveLeft = function(angle) { angle = (typeof angle !== 'undefined') ? -angle : -this._moveRate; - this._moveHorizontal(angle, false); - }; - - /** - * Rotates the camera around the center of the camera's reference frame by angle to the right - * and keeps the camera's up vector pointing towards the z-axis. - * - * @memberof CameraSpindleController - * - * @param {Number} angle The angle to rotate in radians. - * - * @see CameraSpindleController#moveLeft - * @see CameraSpindleController#rotate - */ - CameraSpindleController.prototype.moveRightWithConstrainedZ = function(angle) { - angle = (typeof angle !== 'undefined') ? angle : this._moveRate; - this._moveHorizontal(angle, true); - }; - - /** - * Rotates the camera around the center of the camera's reference frame by angle to the left - * and keeps the camera's up vector pointing towards the z-axis. - * - * @memberof CameraSpindleController - * - * @param {Number} angle The angle to rotate in radians. - * - * @see CameraSpindleController#moveRight - * @see CameraSpindleController#rotate - */ - CameraSpindleController.prototype.moveLeftWithConstrainedZ = function(angle) { - angle = (typeof angle !== 'undefined') ? -angle : -this._moveRate; - this._moveHorizontal(angle, true); + this._moveHorizontal(angle); }; - CameraSpindleController.prototype._moveHorizontal = function(angle, constrainedZ) { - if (constrainedZ) { + CameraSpindleController.prototype._moveHorizontal = function(angle) { + if (typeof this.constrainedAxis !== 'undefined') { this.rotate(this.constrainedAxis.normalize(), angle); } else { this.rotate(this._camera.up, angle); @@ -433,14 +369,8 @@ define([ var deltaPhi = -rotateRate * phiWindowRatio * Math.PI * 2.0; var deltaTheta = -rotateRate * thetaWindowRatio * Math.PI; - var constrainedAxis = typeof this.constrainedAxis !== 'undefined'; - var theta = Math.acos(position.z / rho) + deltaTheta; - if (constrainedAxis && (theta < 0 || theta > Math.PI)) { - deltaTheta = 0; - } - - this._moveHorizontal(deltaPhi, constrainedAxis); - this._moveVertical(deltaTheta, constrainedAxis); + this._moveHorizontal(deltaPhi); + this._moveVertical(deltaTheta); }; CameraSpindleController.prototype._pan = function(movement) { @@ -479,9 +409,8 @@ define([ deltaTheta = 0; } - var constrainedAxis = typeof this.constrainedAxis !== 'undefined'; - this._moveHorizontal(deltaPhi, constrainedAxis); - this._moveVertical(deltaTheta, constrainedAxis); + this._moveHorizontal(deltaPhi); + this._moveVertical(deltaTheta); } }; diff --git a/Specs/Scene/CameraSpindleControllerSpec.js b/Specs/Scene/CameraSpindleControllerSpec.js index 6e5adf787256..8905d8223075 100644 --- a/Specs/Scene/CameraSpindleControllerSpec.js +++ b/Specs/Scene/CameraSpindleControllerSpec.js @@ -84,7 +84,8 @@ defineSuite([ }); it('move up with constrained Z', function() { - csc.moveUpWithConstrainedZ(rotaterate); + csc.constrainedAxis = Cartesian3.UNIT_Z; + csc.moveUp(rotaterate); expect(camera.up.equalsEpsilon(up, CesiumMath.EPSILON15)).toEqual(true); expect(camera.direction.equalsEpsilon(dir, CesiumMath.EPSILON15)).toEqual(true); expect(camera.right.equalsEpsilon(right, CesiumMath.EPSILON15)).toEqual(true); @@ -100,7 +101,8 @@ defineSuite([ }); it('move down with constrained Z', function() { - csc.moveDownWithConstrainedZ(-rotaterate); + csc.constrainedAxis = Cartesian3.UNIT_Z; + csc.moveDown(-rotaterate); expect(camera.up.equalsEpsilon(up, CesiumMath.EPSILON15)).toEqual(true); expect(camera.direction.equalsEpsilon(dir, CesiumMath.EPSILON15)).toEqual(true); expect(camera.right.equalsEpsilon(right, CesiumMath.EPSILON15)).toEqual(true); @@ -116,7 +118,8 @@ defineSuite([ }); it('move left with contrained Z', function() { - csc.moveLeftWithConstrainedZ(rotaterate); + csc.constrainedAxis = Cartesian3.UNIT_Z; + csc.moveLeft(rotaterate); expect(camera.up.equalsEpsilon(Cartesian3.UNIT_X, CesiumMath.EPSILON15)).toEqual(true); expect(camera.direction.equalsEpsilon(Cartesian3.UNIT_Z.negate(), CesiumMath.EPSILON15)).toEqual(true); expect(camera.right.equalsEpsilon(Cartesian3.UNIT_Y.negate(), CesiumMath.EPSILON15)).toEqual(true); @@ -132,7 +135,8 @@ defineSuite([ }); it('move right with contrained Z', function() { - csc.moveRightWithConstrainedZ(rotaterate); + csc.constrainedAxis = Cartesian3.UNIT_Z; + csc.moveRight(rotaterate); expect(camera.up.equalsEpsilon(Cartesian3.UNIT_X.negate(), CesiumMath.EPSILON15)).toEqual(true); expect(camera.direction.equalsEpsilon(Cartesian3.UNIT_Z.negate(), CesiumMath.EPSILON15)).toEqual(true); expect(camera.right.equalsEpsilon(Cartesian3.UNIT_Y, CesiumMath.EPSILON15)).toEqual(true); From 128ea43fe0cf2e401c9f8daf8929a0816db3c6de Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 22 Jun 2012 21:10:19 -0400 Subject: [PATCH 16/36] Fix 2D controller tests. --- Specs/Scene/Camera2DControllerSpec.js | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/Specs/Scene/Camera2DControllerSpec.js b/Specs/Scene/Camera2DControllerSpec.js index 02180d47bbee..05dc994e0540 100644 --- a/Specs/Scene/Camera2DControllerSpec.js +++ b/Specs/Scene/Camera2DControllerSpec.js @@ -33,10 +33,19 @@ defineSuite([ var ellipsoid; var controller; var controller2; + var canvas; + + var FakeCanvas = function() { + this.addEventListener = function() {}; + this.removeEventListener = function() {}; + + this.clientWidth = 1024; + this.clientHeight = 768; + }; beforeEach(function() { + canvas = new FakeCanvas(); ellipsoid = Ellipsoid.WGS84; - camera = new Camera(document); moverate = 3.0; zoomrate = 1.0; @@ -53,14 +62,14 @@ defineSuite([ frustum.top = 1.0; frustum.bottom = -1.0; - camera = new Camera(document); + camera = new Camera(canvas); camera.position = position; camera.up = up; camera.direction = dir; camera.right = right; camera.frustum = frustum; - controller = new Camera2DController(document, camera, ellipsoid); + controller = new Camera2DController(canvas, camera, ellipsoid); }); afterEach(function() { @@ -103,9 +112,9 @@ defineSuite([ it('translate', function() { controller._translate({ startPosition : new Cartesian2(0.0, 0.0), - endPosition : new Cartesian2(10.0, 10.0) + endPosition : new Cartesian2(1000.0, 1000.0) }); - expect(camera.position.equalsEpsilon(new Cartesian3(100000.0, 100000.0, 0.0))).toEqual(true); + expect(camera.position.equalsEpsilon(new Cartesian3(-3.9, 2.6, 0.0), CesiumMath.EPSILON2)).toEqual(true); }); it('zoom', function() { @@ -115,10 +124,10 @@ defineSuite([ startPosition : new Cartesian2(0.0, 0.0), endPosition : new Cartesian2(0.0, 1.0) }); - expect(frustum.right).toEqualEpsilon(controller._zoomRate + offset, CesiumMath.EPSILON10); - expect(frustum.left).toEqual(-(controller._zoomRate + offset), CesiumMath.EPSILON10); - expect(frustum.top).toEqual(ratio * (controller._zoomRate + offset), CesiumMath.EPSILON10); - expect(frustum.bottom).toEqual(-ratio * (controller._zoomRate + offset), CesiumMath.EPSILON10); + expect(frustum.right).toEqualEpsilon(offset, CesiumMath.EPSILON1); + expect(frustum.left).toEqualEpsilon(-offset, CesiumMath.EPSILON1); + expect(frustum.top).toEqualEpsilon(ratio * offset, CesiumMath.EPSILON1); + expect(frustum.bottom).toEqualEpsilon(-ratio * offset, CesiumMath.EPSILON1); }); it('zoomOut', function() { From 9db626f7eec60af9d1863bffd237beb05f290006 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 25 Jun 2012 15:22:36 -0400 Subject: [PATCH 17/36] Tweak middle mouse control. --- Source/Scene/CameraCentralBodyController.js | 23 +++++++++------------ 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/Source/Scene/CameraCentralBodyController.js b/Source/Scene/CameraCentralBodyController.js index b98d74789b74..5535c0ad5429 100644 --- a/Source/Scene/CameraCentralBodyController.js +++ b/Source/Scene/CameraCentralBodyController.js @@ -48,21 +48,18 @@ define([ var rotate = this._rotateHandler; var rotating = rotate.isMoving() && rotate.getMovement(); - if (rotating) { - var movement = rotate.getMovement(); - var press = rotate.getButtonPressTime(); - var release = rotate.getButtonReleaseTime(); - - if (typeof press !== 'undefined' && (typeof release === 'undefined' || press.greaterThan(release))) { - var center = this._camera.pickEllipsoid(this._spindleController.getEllipsoid(), movement.startPosition); - if (typeof center === 'undefined') { - this._transform = Matrix4.IDENTITY; - } else { - this._transform = Transforms.eastNorthUpToFixedFrame(center); - } + var rotateMovement = rotate.getMovement(); + if (rotate.isButtonDown() && typeof this._transform === 'undefined' && rotateMovement) { + var center = this._camera.pickEllipsoid(this._spindleController.getEllipsoid(), rotateMovement.startPosition); + if (typeof center !== 'undefined') { + this._transform = Transforms.eastNorthUpToFixedFrame(center); } + } else if (!rotate.isButtonDown()) { + this._transform = undefined; + } - this._rotate(movement); + if (rotating && typeof this._transform !== 'undefined') { + this._rotate(rotateMovement); } this._spindleController.update(); From 23d66db3f7c6d9cdf353eea0239d7021fb99f65b Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 25 Jun 2012 19:07:15 -0400 Subject: [PATCH 18/36] Add bounce-back from the edges of the screen to Columbus View Controller. --- Source/Scene/CameraColumbusViewController.js | 85 ++++++++++++++++++-- 1 file changed, 78 insertions(+), 7 deletions(-) diff --git a/Source/Scene/CameraColumbusViewController.js b/Source/Scene/CameraColumbusViewController.js index b7842ce7294f..09ff11aa15a9 100644 --- a/Source/Scene/CameraColumbusViewController.js +++ b/Source/Scene/CameraColumbusViewController.js @@ -10,7 +10,9 @@ define([ './CameraEventType', './CameraSpindleController', './CameraFreeLookController', - './CameraHelpers' + './CameraHelpers', + './AnimationCollection', + '../ThirdParty/Tween' ], function( destroyObject, Ellipsoid, @@ -22,7 +24,9 @@ define([ CameraEventType, CameraSpindleController, CameraFreeLookController, - CameraHelpers) { + CameraHelpers, + AnimationCollection, + Tween) { "use strict"; var maintainInertia = CameraHelpers.maintainInertia; @@ -61,6 +65,12 @@ define([ this._transform = this._camera.transform.clone(); this._lastInertiaTranslateMovement = undefined; + + this._animationCollection = new AnimationCollection(); + this._translateAnimation = undefined; + + this._mapWidth = this._ellipsoid.getRadii().x * Math.PI; + this._mapHeight = this._ellipsoid.getRadii().y * CesiumMath.PI_OVER_TWO; } /** @@ -70,6 +80,10 @@ define([ var translate = this._translateHandler; var translating = translate.isMoving() && translate.getMovement(); + if (translate.isButtonDown() || this._spindleController._zoomHandler.isButtonDown() || this._spindleController._spinHandler.isButtonDown()) { + this._animationCollection.removeAll(); + } + if (translating) { this._translate(translate.getMovement()); } @@ -81,11 +95,46 @@ define([ this._spindleController.update(); this._freeLookController.update(); - this._updateReferenceFrame(); + this._correctPosition(); + this._animationCollection.update(); return true; }; + CameraColumbusViewController.prototype._addCorrectTranslateAnimation = function(position, center, maxX, maxY) { + var newPosition = position.clone(); + + if (center.y > maxX) { + newPosition.y -= center.y - maxX; + } else if (center.y < -maxX) { + newPosition.y += -maxX - center.y; + } + + if (center.z > maxY) { + newPosition.z -= center.z - maxY; + } else if (center.z < -maxY) { + newPosition.z += -maxY - center.z; + } + + var camera = this._camera; + var updateCV = function(value) { + var interp = position.lerp(newPosition, value.time); + var pos = new Cartesian4(interp.x, interp.y, interp.z, 1.0); + camera.position = camera.getInverseTransform().multiplyWithVector(pos).getXYZ(); + }; + + this._translateAnimation = this._animationCollection.add({ + easingFunction : Tween.Easing.Exponential.EaseOut, + startValue : { + time : 0.0 + }, + stopValue : { + time : 1.0 + }, + onUpdate : updateCV + }); + }; + CameraColumbusViewController.prototype._translate = function(movement) { var camera = this._camera; @@ -101,9 +150,9 @@ define([ camera.position = camera.position.add(diff); }; - CameraColumbusViewController.prototype._updateReferenceFrame = function() { + CameraColumbusViewController.prototype._correctPosition = function() + { var camera = this._camera; - var position = camera.position; var direction = camera.direction; @@ -117,14 +166,36 @@ define([ var positionWC = camera.transform.multiplyWithVector(cameraPosition); camera.transform = this._transform.clone(); - var maxX = this._ellipsoid.getRadii().x * Math.PI; + var tanPhi = Math.tan(this._camera.frustum.fovy * 0.5); + var tanTheta = this._camera.frustum.aspectRatio * tanPhi; + var distToC = positionWC.subtract(centerWC).magnitude(); + var dWidth = tanTheta * distToC; + var dHeight = tanPhi * distToC; + + var maxX = Math.max(dWidth - this._mapWidth, this._mapWidth); + var maxY = Math.max(dHeight - this._mapHeight, this._mapHeight); + + if (!this._translateHandler.isButtonDown()) { + var animations = Tween.getAll(); + + var translateX = centerWC.y < -maxX || centerWC.y > maxX; + var translateY = centerWC.z < -maxY || centerWC.z > maxY; + if ((translateX || translateY) && !this._lastInertiaTranslateMovement) { + if (animations.indexOf(this._translateAnimation) === -1) { + this._animationCollection.removeAll(); + } + this._addCorrectTranslateAnimation(positionWC.getXYZ(), centerWC.getXYZ(), maxX, maxY); + } + } + + maxX = maxX + this._mapWidth * 0.5; if (centerWC.y > maxX) { positionWC.y -= centerWC.y - maxX; } else if (centerWC.y < -maxX) { positionWC.y += -maxX - centerWC.y; } - var maxY = this._ellipsoid.getRadii().z * CesiumMath.PI_OVER_TWO; + maxY = maxY + this._mapHeight * 0.5; if (centerWC.z > maxY) { positionWC.z -= centerWC.z - maxY; } else if (centerWC.z < -maxY) { From 1c66314db078da6cccaea1b302ec32d535396ff1 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 26 Jun 2012 14:15:00 -0400 Subject: [PATCH 19/36] Do not constrain camera in columbus view if it is over the map. --- Source/Scene/CameraColumbusViewController.js | 44 ++++++++++---------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/Source/Scene/CameraColumbusViewController.js b/Source/Scene/CameraColumbusViewController.js index 09ff11aa15a9..3426f98e20cf 100644 --- a/Source/Scene/CameraColumbusViewController.js +++ b/Source/Scene/CameraColumbusViewController.js @@ -175,31 +175,33 @@ define([ var maxX = Math.max(dWidth - this._mapWidth, this._mapWidth); var maxY = Math.max(dHeight - this._mapHeight, this._mapHeight); - if (!this._translateHandler.isButtonDown()) { - var animations = Tween.getAll(); - - var translateX = centerWC.y < -maxX || centerWC.y > maxX; - var translateY = centerWC.z < -maxY || centerWC.z > maxY; - if ((translateX || translateY) && !this._lastInertiaTranslateMovement) { - if (animations.indexOf(this._translateAnimation) === -1) { - this._animationCollection.removeAll(); + if (positionWC.x < -maxX || positionWC.x > maxX || positionWC.y < -maxY || positionWC.y > maxY) { + if (!this._translateHandler.isButtonDown()) { + var animations = Tween.getAll(); + + var translateX = centerWC.y < -maxX || centerWC.y > maxX; + var translateY = centerWC.z < -maxY || centerWC.z > maxY; + if ((translateX || translateY) && !this._lastInertiaTranslateMovement) { + if (animations.indexOf(this._translateAnimation) === -1) { + this._animationCollection.removeAll(); + } + this._addCorrectTranslateAnimation(positionWC.getXYZ(), centerWC.getXYZ(), maxX, maxY); } - this._addCorrectTranslateAnimation(positionWC.getXYZ(), centerWC.getXYZ(), maxX, maxY); } - } - maxX = maxX + this._mapWidth * 0.5; - if (centerWC.y > maxX) { - positionWC.y -= centerWC.y - maxX; - } else if (centerWC.y < -maxX) { - positionWC.y += -maxX - centerWC.y; - } + maxX = maxX + this._mapWidth * 0.5; + if (centerWC.y > maxX) { + positionWC.y -= centerWC.y - maxX; + } else if (centerWC.y < -maxX) { + positionWC.y += -maxX - centerWC.y; + } - maxY = maxY + this._mapHeight * 0.5; - if (centerWC.z > maxY) { - positionWC.z -= centerWC.z - maxY; - } else if (centerWC.z < -maxY) { - positionWC.z += -maxY - centerWC.z; + maxY = maxY + this._mapHeight * 0.5; + if (centerWC.z > maxY) { + positionWC.z -= centerWC.z - maxY; + } else if (centerWC.z < -maxY) { + positionWC.z += -maxY - centerWC.z; + } } camera.position = camera.getInverseTransform().multiplyWithVector(positionWC).getXYZ(); From 902287554cd5355bc59d6bcae77f47f3b1f61b28 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 29 Jun 2012 14:19:47 -0400 Subject: [PATCH 20/36] Fix break after merge. --- Source/Scene/CameraCentralBodyController.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Scene/CameraCentralBodyController.js b/Source/Scene/CameraCentralBodyController.js index 5535c0ad5429..b842cb61a7ff 100644 --- a/Source/Scene/CameraCentralBodyController.js +++ b/Source/Scene/CameraCentralBodyController.js @@ -50,7 +50,7 @@ define([ var rotateMovement = rotate.getMovement(); if (rotate.isButtonDown() && typeof this._transform === 'undefined' && rotateMovement) { - var center = this._camera.pickEllipsoid(this._spindleController.getEllipsoid(), rotateMovement.startPosition); + var center = this._camera.pickEllipsoid(rotateMovement.startPosition, this._spindleController.getEllipsoid()); if (typeof center !== 'undefined') { this._transform = Transforms.eastNorthUpToFixedFrame(center); } From a1926808658e76d82bc564990c0c5f8345db5849 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 29 Jun 2012 14:25:12 -0400 Subject: [PATCH 21/36] Fix free look in normal 3D. --- Source/Scene/CameraCentralBodyController.js | 1 - 1 file changed, 1 deletion(-) diff --git a/Source/Scene/CameraCentralBodyController.js b/Source/Scene/CameraCentralBodyController.js index b842cb61a7ff..96b6d49e8b22 100644 --- a/Source/Scene/CameraCentralBodyController.js +++ b/Source/Scene/CameraCentralBodyController.js @@ -34,7 +34,6 @@ define([ this._spindleController = new CameraSpindleController(canvas, camera, ellipsoid); this._freeLookController = new CameraFreeLookController(canvas, camera); - this._freeLookController.horizontalRotationAxis = Cartesian3.UNIT_Z; this._rotateHandler = new CameraEventHandler(canvas, CameraEventType.MIDDLE_DRAG); From 61f18f628457354ab7e0baf6d46f04439898539e Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 29 Jun 2012 15:30:44 -0400 Subject: [PATCH 22/36] Keep track of when event modifiers are pressed in EventHandler. Add tests. --- Source/Core/EventHandler.js | 48 ++++++++++++++++++++++- Specs/Core/EventHandlerSpec.js | 71 ++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+), 2 deletions(-) diff --git a/Source/Core/EventHandler.js b/Source/Core/EventHandler.js index 5d0f8c78ec24..b111de147520 100644 --- a/Source/Core/EventHandler.js +++ b/Source/Core/EventHandler.js @@ -53,6 +53,9 @@ define([ this._rightMouseButtonDown = false; this._rightPressTime = undefined; this._rightReleaseTime = undefined; + this._shiftDown = false; + this._ctrlDown = false; + this._altDown = false; this._seenAnyTouchEvents = false; this._lastMouseX = 0; this._lastMouseY = 0; @@ -214,6 +217,27 @@ define([ return this._rightReleaseTime; }; + /** + * Returns true if the given modifier is pressed and false otherwise. + * + * @memberof EventHandler + * + * @param {EventModifier} modifier The event modifier. + * + * @returns {Boolean} true if the given modifier is pressed and false otherwise. + */ + EventHandler.prototype.isModifierDown = function(modifier) { + switch (modifier) { + case EventModifier.SHIFT: + return this._shiftDown; + case EventModifier.CTRL: + return this._ctrlDown; + case EventModifier.ALT: + return this._altDown; + } + return false; + }; + /** * Set a function to be executed on a mouse event. * @@ -281,7 +305,7 @@ define([ return mouseEvents[type.name]; } - return null; + return undefined; }; /** @@ -324,7 +348,21 @@ define([ return EventModifier.ALT; } - return null; + return undefined; + }; + + EventHandler.prototype._setModifierDown = function(modifier) { + switch (modifier) { + case EventModifier.SHIFT: + this._shiftDown = true; + break; + case EventModifier.CTRL: + this._ctrlDown = true; + break; + case EventModifier.ALT: + this._altDown = true; + break; + } }; EventHandler.prototype._handleMouseDown = function(event) { @@ -337,6 +375,8 @@ define([ } var modifier = this._getModifier(event); + this._setModifierDown(modifier); + var action; // IE_TODO: On some versions of IE, the left-button is 1, and the right-button is 4. @@ -410,6 +450,10 @@ define([ position : new Cartesian2(pos.x, pos.y) }); } + + this._shiftDown = false; + this._ctrlDown = false; + this._altDown = false; }; EventHandler.prototype._handleMouseMove = function(event) { diff --git a/Specs/Core/EventHandlerSpec.js b/Specs/Core/EventHandlerSpec.js index b308c72451b1..f63b1e623fd0 100644 --- a/Specs/Core/EventHandlerSpec.js +++ b/Specs/Core/EventHandlerSpec.js @@ -145,6 +145,7 @@ defineSuite([ clientY : 1 }); expect(actualCoords).toEqual(expectedCoords); + expect(handler.isRightMouseButtonDown()).toEqual(true); expect(handler.getMouseAction(MouseEventType.RIGHT_DOWN) === mouseDown).toEqual(true); @@ -173,6 +174,7 @@ defineSuite([ clientY : 1 }); expect(actualCoords).toEqual(expectedCoords); + expect(handler.isRightMouseButtonDown()).toEqual(false); expect(handler.getMouseAction(MouseEventType.RIGHT_UP) === mouseDown).toEqual(true); @@ -184,6 +186,7 @@ defineSuite([ }); expect(actualCoords).toEqual(expectedCoords); + expect(handler.isRightMouseButtonDown()).toEqual(true); }); it('mouse right click', function() { @@ -239,6 +242,7 @@ defineSuite([ clientY : 1 }); expect(actualCoords).toEqual(expectedCoords); + expect(handler.isLeftMouseButtonDown()).toEqual(true); expect(handler.getMouseAction(MouseEventType.LEFT_DOWN) === mouseDown).toEqual(true); @@ -267,6 +271,7 @@ defineSuite([ clientY : 1 }); expect(actualCoords).toEqual(expectedCoords); + expect(handler.isLeftMouseButtonDown()).toEqual(false); expect(handler.getMouseAction(MouseEventType.LEFT_UP) === mouseDown).toEqual(true); @@ -278,6 +283,7 @@ defineSuite([ }); expect(actualCoords).toEqual(expectedCoords); + expect(handler.isLeftMouseButtonDown()).toEqual(true); }); it('mouse left click', function() { @@ -333,6 +339,7 @@ defineSuite([ clientY : 1 }); expect(actualCoords).toEqual(expectedCoords); + expect(handler.isMiddleMouseButtonDown()).toEqual(true); expect(handler.getMouseAction(MouseEventType.MIDDLE_DOWN) === mouseDown).toEqual(true); @@ -361,6 +368,7 @@ defineSuite([ clientY : 1 }); expect(actualCoords).toEqual(expectedCoords); + expect(handler.isMiddleMouseButtonDown()).toEqual(false); expect(handler.getMouseAction(MouseEventType.MIDDLE_UP) === mouseDown).toEqual(true); @@ -372,6 +380,7 @@ defineSuite([ }); expect(actualCoords).toEqual(expectedCoords); + expect(handler.isMiddleMouseButtonDown()).toEqual(true); }); it('mouse middle click', function() { @@ -581,6 +590,8 @@ defineSuite([ shiftKey : true }); expect(actualCoords).toEqual(expectedCoords); + expect(handler.isRightMouseButtonDown()).toEqual(true); + expect(handler.isModifierDown(EventModifier.SHIFT)).toEqual(true); expect(handler.getMouseAction(MouseEventType.RIGHT_DOWN, EventModifier.SHIFT) === mouseDown).toEqual(true); @@ -611,6 +622,8 @@ defineSuite([ shiftKey : true }); expect(actualCoords).toEqual(expectedCoords); + expect(handler.isRightMouseButtonDown()).toEqual(false); + expect(handler.isModifierDown(EventModifier.SHIFT)).toEqual(false); expect(handler.getMouseAction(MouseEventType.RIGHT_UP, EventModifier.SHIFT) === mouseDown).toEqual(true); @@ -623,6 +636,8 @@ defineSuite([ }); expect(actualCoords).toEqual(expectedCoords); + expect(handler.isRightMouseButtonDown()).toEqual(true); + expect(handler.isModifierDown(EventModifier.SHIFT)).toEqual(true); }); it('modified mouse right click', function() { @@ -683,6 +698,8 @@ defineSuite([ altKey : true }); expect(actualCoords).toEqual(expectedCoords); + expect(handler.isLeftMouseButtonDown()).toEqual(true); + expect(handler.isModifierDown(EventModifier.ALT)).toEqual(true); expect(handler.getMouseAction(MouseEventType.LEFT_DOWN, EventModifier.ALT) === mouseDown).toEqual(true); @@ -713,6 +730,8 @@ defineSuite([ altKey : true }); expect(actualCoords).toEqual(expectedCoords); + expect(handler.isLeftMouseButtonDown()).toEqual(false); + expect(handler.isModifierDown(EventModifier.ALT)).toEqual(false); expect(handler.getMouseAction(MouseEventType.LEFT_UP, EventModifier.ALT) === mouseDown).toEqual(true); @@ -725,6 +744,8 @@ defineSuite([ }); expect(actualCoords).toEqual(expectedCoords); + expect(handler.isLeftMouseButtonDown()).toEqual(true); + expect(handler.isModifierDown(EventModifier.ALT)).toEqual(true); }); it('modified mouse left click', function() { @@ -785,6 +806,8 @@ defineSuite([ ctrlKey : true }); expect(actualCoords).toEqual(expectedCoords); + expect(handler.isMiddleMouseButtonDown()).toEqual(true); + expect(handler.isModifierDown(EventModifier.CTRL)).toEqual(true); expect(handler.getMouseAction(MouseEventType.MIDDLE_DOWN, EventModifier.CTRL) === mouseDown).toEqual(true); @@ -815,6 +838,8 @@ defineSuite([ ctrlKey : true }); expect(actualCoords).toEqual(expectedCoords); + expect(handler.isMiddleMouseButtonDown()).toEqual(false); + expect(handler.isModifierDown(EventModifier.CTRL)).toEqual(false); expect(handler.getMouseAction(MouseEventType.MIDDLE_UP, EventModifier.CTRL) === mouseDown).toEqual(true); @@ -827,6 +852,8 @@ defineSuite([ }); expect(actualCoords).toEqual(expectedCoords); + expect(handler.isMiddleMouseButtonDown()).toEqual(true); + expect(handler.isModifierDown(EventModifier.CTRL)).toEqual(true); }); it('modified mouse middle click', function() { @@ -961,6 +988,50 @@ defineSuite([ expect(actualCoords).toEqual(expectedCoords); }); + it('get left press time', function() { + handler.setMouseAction(function(event) {}, MouseEventType.LEFT_DOWN); + element.fireEvents('mousedown', { + button : 0, + clientX : 1, + clientY : 1 + }); + + expect(handler.getLeftPressTime()).toBeDefined(); + }); + + it('get left release time', function() { + handler.setMouseAction(function(event) {}, MouseEventType.LEFT_DOWN); + element.fireEvents('mouseup', { + button : 0, + clientX : 1, + clientY : 1 + }); + + expect(handler.getLeftReleaseTime()).toBeDefined(); + }); + + it('get right press time', function() { + handler.setMouseAction(function(event) {}, MouseEventType.RIGHT_DOWN); + element.fireEvents('mousedown', { + button : 2, + clientX : 1, + clientY : 1 + }); + + expect(handler.getRightPressTime()).toBeDefined(); + }); + + it('get right release time', function() { + handler.setMouseAction(function(event) {}, MouseEventType.RIGHT_DOWN); + element.fireEvents('mouseup', { + button : 2, + clientX : 1, + clientY : 1 + }); + + expect(handler.getRightReleaseTime()).toBeDefined(); + }); + it('get middle press time', function() { handler.setMouseAction(function(event) {}, MouseEventType.MIDDLE_DOWN); element.fireEvents('mousedown', { From 26949851c2c8cb449b0fa757c59440a5a1a8d182 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 29 Jun 2012 16:56:18 -0400 Subject: [PATCH 23/36] Prevent inertia when two actions are mapped to a single mouse button but one has a key modifier. --- Source/Core/EventHandler.js | 190 ------------------ Source/Scene/CameraColumbusViewController.js | 5 +- Source/Scene/CameraEventHandler.js | 74 +++---- Specs/Core/EventHandlerSpec.js | 93 --------- .../Scene/CameraColumbusViewControllerSpec.js | 4 +- 5 files changed, 34 insertions(+), 332 deletions(-) diff --git a/Source/Core/EventHandler.js b/Source/Core/EventHandler.js index b111de147520..64ef25ad7328 100644 --- a/Source/Core/EventHandler.js +++ b/Source/Core/EventHandler.js @@ -45,17 +45,8 @@ define([ } this._leftMouseButtonDown = false; - this._leftPressTime = undefined; - this._leftReleaseTime = undefined; this._middleMouseButtonDown = false; - this._middlePressTime = undefined; - this._middleReleaseTime = undefined; this._rightMouseButtonDown = false; - this._rightPressTime = undefined; - this._rightReleaseTime = undefined; - this._shiftDown = false; - this._ctrlDown = false; - this._altDown = false; this._seenAnyTouchEvents = false; this._lastMouseX = 0; this._lastMouseY = 0; @@ -85,159 +76,6 @@ define([ }; }; - /** - * Returns true if the left mouse button is pressed and false otherwise. - * - * @memberof EventHandler - * - * @return {Boolean} true if the left mouse button is pressed and false otherwise. - * - * @see EventHandler#isMiddleMouseButtonDown - * @see EventHandler#isRightMouseButtonDown - */ - EventHandler.prototype.isLeftMouseButtonDown = function() { - return this._leftMouseButtonDown; - }; - - /** - * Returns the last time that the left mouse button was pressed. - * - * @memberof EventHandler - * - * @return {JulianDate} The time the left mouse button was pressed. - * - * @see EventHandler#getLeftReleaseTime - * @see EventHandler#getRightPressTime - * @see EventHandler#getMiddlePressTime - */ - EventHandler.prototype.getLeftPressTime = function() { - return this._leftPressTime; - }; - - /** - * Returns the last time that the left mouse button was released. - * - * @memberof EventHandler - * - * @return {JulianDate} The time the left mouse button was released. - * - * @see EventHandler#getLeftPressTime - * @see EventHandler#getRightReleaseTime - * @see EventHandler#getMiddleReleaseTime - */ - EventHandler.prototype.getLeftReleaseTime = function() { - return this._leftReleaseTime; - }; - - /** - * Returns true if the middle mouse button is pressed and false otherwise. - * - * @memberof EventHandler - * - * @return {Boolean} true if the middle mouse button is pressed and false otherwise. - * - * @see EventHandler#isMiddleMouseButtonDown - * @see EventHandler#isLeftMouseButtonDown - */ - EventHandler.prototype.isMiddleMouseButtonDown = function() { - return this._middleMouseButtonDown; - }; - - /** - * Returns the last time that the middle mouse button was pressed. - * - * @memberof EventHandler - * - * @return {JulianDate} The time the middle mouse button was pressed. - * - * @see EventHandler#getMiddleReleaseTime - * @see EventHandler#getRightPressTime - * @see EventHandler#getLeftPressTime - */ - EventHandler.prototype.getMiddlePressTime = function() { - return this._middlePressTime; - }; - - /** - * Returns the last time that the middle mouse button was released. - * - * @memberof EventHandler - * - * @return {JulianDate} The time the middle mouse button was released. - * - * @see EventHandler#getMiddlePressTime - * @see EventHandler#getRightReleaseTime - * @see EventHandler#getLeftReleaseTime - */ - EventHandler.prototype.getMiddleReleaseTime = function() { - return this._middleReleaseTime; - }; - - /** - * Returns true if the right mouse button is pressed and false otherwise. - * - * @memberof EventHandler - * - * @return {Boolean} true if the right mouse button is pressed and false otherwise. - * - * @see EventHandler#isMiddleMouseButtonDown - * @see EventHandler#isLeftMouseButtonDown - */ - EventHandler.prototype.isRightMouseButtonDown = function() { - return this._rightMouseButtonDown; - }; - - /** - * Returns the last time that the right mouse button was pressed. - * - * @memberof EventHandler - * - * @return {JulianDate} The time the right mouse button was pressed. - * - * @see EventHandler#getRightReleaseTime - * @see EventHandler#getLeftPressTime - * @see EventHandler#getMiddlePressTime - */ - EventHandler.prototype.getRightPressTime = function() { - return this._rightPressTime; - }; - - /** - * Returns the last time that the right mouse button was released. - * - * @memberof EventHandler - * - * @return {JulianDate} The time the right mouse button was released. - * - * @see EventHandler#getRightPressTime - * @see EventHandler#getLeftReleaseTime - * @see EventHandler#getMiddleReleaseTime - */ - EventHandler.prototype.getRightReleaseTime = function() { - return this._rightReleaseTime; - }; - - /** - * Returns true if the given modifier is pressed and false otherwise. - * - * @memberof EventHandler - * - * @param {EventModifier} modifier The event modifier. - * - * @returns {Boolean} true if the given modifier is pressed and false otherwise. - */ - EventHandler.prototype.isModifierDown = function(modifier) { - switch (modifier) { - case EventModifier.SHIFT: - return this._shiftDown; - case EventModifier.CTRL: - return this._ctrlDown; - case EventModifier.ALT: - return this._altDown; - } - return false; - }; - /** * Set a function to be executed on a mouse event. * @@ -351,20 +189,6 @@ define([ return undefined; }; - EventHandler.prototype._setModifierDown = function(modifier) { - switch (modifier) { - case EventModifier.SHIFT: - this._shiftDown = true; - break; - case EventModifier.CTRL: - this._ctrlDown = true; - break; - case EventModifier.ALT: - this._altDown = true; - break; - } - }; - EventHandler.prototype._handleMouseDown = function(event) { var pos = this._getPosition(event); this._lastMouseX = pos.x; @@ -375,8 +199,6 @@ define([ } var modifier = this._getModifier(event); - this._setModifierDown(modifier); - var action; // IE_TODO: On some versions of IE, the left-button is 1, and the right-button is 4. @@ -385,15 +207,12 @@ define([ // constants somewhere? if (event.button === 0) { this._leftMouseButtonDown = true; - this._leftPressTime = new JulianDate(); action = this.getMouseAction(MouseEventType.LEFT_DOWN, modifier); } else if (event.button === 1) { this._middleMouseButtonDown = true; - this._middlePressTime = new JulianDate(); action = this.getMouseAction(MouseEventType.MIDDLE_DOWN, modifier); } else if (event.button === 2) { this._rightMouseButtonDown = true; - this._rightPressTime = new JulianDate(); action = this.getMouseAction(MouseEventType.RIGHT_DOWN, modifier); } @@ -418,17 +237,14 @@ define([ // constants somewhere? if (event.button === 0) { this._leftMouseButtonDown = false; - this._leftReleaseTime = new JulianDate(); action = this.getMouseAction(MouseEventType.LEFT_UP, modifier); clickAction = this.getMouseAction(MouseEventType.LEFT_CLICK, modifier); } else if (event.button === 1) { this._middleMouseButtonDown = false; - this._middleReleaseTime = new JulianDate(); action = this.getMouseAction(MouseEventType.MIDDLE_UP, modifier); clickAction = this.getMouseAction(MouseEventType.MIDDLE_CLICK, modifier); } else if (event.button === 2) { this._rightMouseButtonDown = false; - this._rightReleaseTime = new JulianDate(); action = this.getMouseAction(MouseEventType.RIGHT_UP, modifier); clickAction = this.getMouseAction(MouseEventType.RIGHT_CLICK, modifier); } @@ -450,10 +266,6 @@ define([ position : new Cartesian2(pos.x, pos.y) }); } - - this._shiftDown = false; - this._ctrlDown = false; - this._altDown = false; }; EventHandler.prototype._handleMouseMove = function(event) { @@ -500,7 +312,6 @@ define([ var action; this._leftMouseButtonDown = true; - this._leftPressTime = new JulianDate(); action = this.getMouseAction(MouseEventType.LEFT_DOWN, modifier); if (action) { @@ -522,7 +333,6 @@ define([ if (this._leftMouseButtonDown) { this._leftMouseButtonDown = false; - this._leftReleaseTime = new JulianDate(); action = this.getMouseAction(MouseEventType.LEFT_UP, modifier); clickAction = this.getMouseAction(MouseEventType.LEFT_CLICK, modifier); } diff --git a/Source/Scene/CameraColumbusViewController.js b/Source/Scene/CameraColumbusViewController.js index f44e0e1c5f8a..ce8a46b35706 100644 --- a/Source/Scene/CameraColumbusViewController.js +++ b/Source/Scene/CameraColumbusViewController.js @@ -88,7 +88,10 @@ define([ this._translate(translate.getMovement()); } - if (!translating && this.inertiaTranslate < 1.0) { + var killInertia = this._spindleController._spinHandler.isButtonDown() || this._spindleController._zoomHandler.isButtonDown() || + this._spindleController._zoomWheel.isButtonDown() || this._freeLookController._handler.isButtonDown(); + + if (!killInertia && !translating && this.inertiaTranslate < 1.0) { maintainInertia(translate, this.inertiaTranslate, this._translate, this, '_lastInertiaTranslateMovement'); } diff --git a/Source/Scene/CameraEventHandler.js b/Source/Scene/CameraEventHandler.js index eb46273c1713..c8919f4ff429 100644 --- a/Source/Scene/CameraEventHandler.js +++ b/Source/Scene/CameraEventHandler.js @@ -36,46 +36,37 @@ define([ * @see EventHandler */ var CameraEventHandler = function(canvas, moveType, moveModifier) { - if (!canvas) { + if (typeof canvas === 'undefined') { throw new DeveloperError('description.canvas is required.'); } - if (!moveType) { + if (typeof moveType === 'undefined') { throw new DeveloperError('moveType is required.'); } this._eventHandler = new EventHandler(canvas); - this._eventDownFunc = null; - this._eventPressTimeFunc = null; - this._eventReleaseTimeFunc = null; - this._update = true; - this._movement = null; - this._lastMovement = null; + this._movement = undefined; + this._lastMovement = undefined; + this._isDown = false; + this._pressTime = undefined; + this._releaseTime = undefined; var that = this; if (moveType !== CameraEventType.WHEEL) { var down; + var up; if (moveType === CameraEventType.LEFT_DRAG) { down = MouseEventType.LEFT_DOWN; - - this._eventDownFunc = this._eventHandler.isLeftMouseButtonDown; - this._eventPressTimeFunc = this._eventHandler.getLeftPressTime; - this._eventReleaseTimeFunc = this._eventHandler.getLeftReleaseTime; + up = MouseEventType.LEFT_UP; } else if (moveType === CameraEventType.RIGHT_DRAG) { down = MouseEventType.RIGHT_DOWN; - - this._eventDownFunc = this._eventHandler.isRightMouseButtonDown; - this._eventPressTimeFunc = this._eventHandler.getRightPressTime; - this._eventReleaseTimeFunc = this._eventHandler.getRightReleaseTime; + up = MouseEventType.RIGHT_UP; } else if (moveType === CameraEventType.MIDDLE_DRAG) { down = MouseEventType.MIDDLE_DOWN; - - this._eventDownFunc = this._eventHandler.isMiddleMouseButtonDown; - this._eventPressTimeFunc = this._eventHandler.getMiddlePressTime; - this._eventReleaseTimeFunc = this._eventHandler.getRightReleaseTime; + up = MouseEventType.MIDDLE_UP; } else { this._eventHandler = this._eventHandler && this._eventHandler.destroy(); throw new DeveloperError('moveType must be of type CameraEventType.'); @@ -83,10 +74,17 @@ define([ this._eventHandler.setMouseAction(function(movement) { that._lastMovement = null; + that._isDown = true; + that._pressTime = new JulianDate(); }, down, moveModifier); this._eventHandler.setMouseAction(function(movement) { - if (that._eventDownFunc.call(that._eventHandler)) { + that._isDown = false; + that._releaseTime = new JulianDate(); + }, up, moveModifier); + + this._eventHandler.setMouseAction(function(movement) { + if (that._isDown) { if (!that._update) { that._movement.endPosition = movement.endPosition.clone(); } else { @@ -97,9 +95,6 @@ define([ } }, MouseEventType.MOVE, moveModifier); } else { - this._wheelStart = null; - this._wheelEnd = null; - this._eventHandler.setMouseAction(function(delta) { // TODO: magic numbers var arcLength = 2 * CesiumMath.toRadians(delta); @@ -114,8 +109,8 @@ define([ that._lastMovement = that._movement; // This looks unusual, but its needed for wheel inertia. that._update = false; } - that._wheelStart = new JulianDate(); - that._wheelEnd = that._wheelStart.addSeconds(Math.abs(arcLength) * 0.005); + that._pressTime = new JulianDate(); + that._releaseTime = that._wheelStart.addSeconds(Math.abs(arcLength) * 0.005); }, MouseEventType.WHEEL, moveModifier); } }; @@ -125,7 +120,7 @@ define([ * * @memberof CameraEventHandler * - * @return {boolean} DOC_TBA + * @return {Boolean} DOC_TBA */ CameraEventHandler.prototype.isMoving = function() { return !this._update; @@ -160,14 +155,11 @@ define([ * * @memberof CameraEventHandler * - * @return {Object} DOC_TBA + * @return {Boolean} DOC_TBA * */ CameraEventHandler.prototype.isButtonDown = function() { - if (this._eventDownFunc) { - return this._eventDownFunc.call(this._eventHandler); - } - return false; + return this._isDown; }; /** @@ -175,16 +167,11 @@ define([ * * @memberof CameraEventHandler * - * @return {Object} DOC_TBA + * @return {JulianDate} DOC_TBA * */ CameraEventHandler.prototype.getButtonPressTime = function() { - if (this._eventPressTimeFunc) { - return this._eventPressTimeFunc.call(this._eventHandler); - } else if (this._wheelStart) { - return this._wheelStart; - } - return null; + return this._pressTime; }; /** @@ -192,16 +179,11 @@ define([ * * @memberof CameraEventHandler * - * @return {Object} DOC_TBA + * @return {JulianDate} DOC_TBA * */ CameraEventHandler.prototype.getButtonReleaseTime = function() { - if (this._eventReleaseTimeFunc) { - return this._eventReleaseTimeFunc.call(this._eventHandler); - } else if (this._wheelEnd) { - return this._wheelEnd; - } - return null; + return this._releaseTime; }; /** diff --git a/Specs/Core/EventHandlerSpec.js b/Specs/Core/EventHandlerSpec.js index f63b1e623fd0..2133bcdc8328 100644 --- a/Specs/Core/EventHandlerSpec.js +++ b/Specs/Core/EventHandlerSpec.js @@ -145,7 +145,6 @@ defineSuite([ clientY : 1 }); expect(actualCoords).toEqual(expectedCoords); - expect(handler.isRightMouseButtonDown()).toEqual(true); expect(handler.getMouseAction(MouseEventType.RIGHT_DOWN) === mouseDown).toEqual(true); @@ -174,7 +173,6 @@ defineSuite([ clientY : 1 }); expect(actualCoords).toEqual(expectedCoords); - expect(handler.isRightMouseButtonDown()).toEqual(false); expect(handler.getMouseAction(MouseEventType.RIGHT_UP) === mouseDown).toEqual(true); @@ -186,7 +184,6 @@ defineSuite([ }); expect(actualCoords).toEqual(expectedCoords); - expect(handler.isRightMouseButtonDown()).toEqual(true); }); it('mouse right click', function() { @@ -242,7 +239,6 @@ defineSuite([ clientY : 1 }); expect(actualCoords).toEqual(expectedCoords); - expect(handler.isLeftMouseButtonDown()).toEqual(true); expect(handler.getMouseAction(MouseEventType.LEFT_DOWN) === mouseDown).toEqual(true); @@ -271,7 +267,6 @@ defineSuite([ clientY : 1 }); expect(actualCoords).toEqual(expectedCoords); - expect(handler.isLeftMouseButtonDown()).toEqual(false); expect(handler.getMouseAction(MouseEventType.LEFT_UP) === mouseDown).toEqual(true); @@ -283,7 +278,6 @@ defineSuite([ }); expect(actualCoords).toEqual(expectedCoords); - expect(handler.isLeftMouseButtonDown()).toEqual(true); }); it('mouse left click', function() { @@ -339,7 +333,6 @@ defineSuite([ clientY : 1 }); expect(actualCoords).toEqual(expectedCoords); - expect(handler.isMiddleMouseButtonDown()).toEqual(true); expect(handler.getMouseAction(MouseEventType.MIDDLE_DOWN) === mouseDown).toEqual(true); @@ -368,7 +361,6 @@ defineSuite([ clientY : 1 }); expect(actualCoords).toEqual(expectedCoords); - expect(handler.isMiddleMouseButtonDown()).toEqual(false); expect(handler.getMouseAction(MouseEventType.MIDDLE_UP) === mouseDown).toEqual(true); @@ -380,7 +372,6 @@ defineSuite([ }); expect(actualCoords).toEqual(expectedCoords); - expect(handler.isMiddleMouseButtonDown()).toEqual(true); }); it('mouse middle click', function() { @@ -590,8 +581,6 @@ defineSuite([ shiftKey : true }); expect(actualCoords).toEqual(expectedCoords); - expect(handler.isRightMouseButtonDown()).toEqual(true); - expect(handler.isModifierDown(EventModifier.SHIFT)).toEqual(true); expect(handler.getMouseAction(MouseEventType.RIGHT_DOWN, EventModifier.SHIFT) === mouseDown).toEqual(true); @@ -622,8 +611,6 @@ defineSuite([ shiftKey : true }); expect(actualCoords).toEqual(expectedCoords); - expect(handler.isRightMouseButtonDown()).toEqual(false); - expect(handler.isModifierDown(EventModifier.SHIFT)).toEqual(false); expect(handler.getMouseAction(MouseEventType.RIGHT_UP, EventModifier.SHIFT) === mouseDown).toEqual(true); @@ -636,8 +623,6 @@ defineSuite([ }); expect(actualCoords).toEqual(expectedCoords); - expect(handler.isRightMouseButtonDown()).toEqual(true); - expect(handler.isModifierDown(EventModifier.SHIFT)).toEqual(true); }); it('modified mouse right click', function() { @@ -698,8 +683,6 @@ defineSuite([ altKey : true }); expect(actualCoords).toEqual(expectedCoords); - expect(handler.isLeftMouseButtonDown()).toEqual(true); - expect(handler.isModifierDown(EventModifier.ALT)).toEqual(true); expect(handler.getMouseAction(MouseEventType.LEFT_DOWN, EventModifier.ALT) === mouseDown).toEqual(true); @@ -730,8 +713,6 @@ defineSuite([ altKey : true }); expect(actualCoords).toEqual(expectedCoords); - expect(handler.isLeftMouseButtonDown()).toEqual(false); - expect(handler.isModifierDown(EventModifier.ALT)).toEqual(false); expect(handler.getMouseAction(MouseEventType.LEFT_UP, EventModifier.ALT) === mouseDown).toEqual(true); @@ -744,8 +725,6 @@ defineSuite([ }); expect(actualCoords).toEqual(expectedCoords); - expect(handler.isLeftMouseButtonDown()).toEqual(true); - expect(handler.isModifierDown(EventModifier.ALT)).toEqual(true); }); it('modified mouse left click', function() { @@ -806,8 +785,6 @@ defineSuite([ ctrlKey : true }); expect(actualCoords).toEqual(expectedCoords); - expect(handler.isMiddleMouseButtonDown()).toEqual(true); - expect(handler.isModifierDown(EventModifier.CTRL)).toEqual(true); expect(handler.getMouseAction(MouseEventType.MIDDLE_DOWN, EventModifier.CTRL) === mouseDown).toEqual(true); @@ -838,8 +815,6 @@ defineSuite([ ctrlKey : true }); expect(actualCoords).toEqual(expectedCoords); - expect(handler.isMiddleMouseButtonDown()).toEqual(false); - expect(handler.isModifierDown(EventModifier.CTRL)).toEqual(false); expect(handler.getMouseAction(MouseEventType.MIDDLE_UP, EventModifier.CTRL) === mouseDown).toEqual(true); @@ -852,8 +827,6 @@ defineSuite([ }); expect(actualCoords).toEqual(expectedCoords); - expect(handler.isMiddleMouseButtonDown()).toEqual(true); - expect(handler.isModifierDown(EventModifier.CTRL)).toEqual(true); }); it('modified mouse middle click', function() { @@ -988,72 +961,6 @@ defineSuite([ expect(actualCoords).toEqual(expectedCoords); }); - it('get left press time', function() { - handler.setMouseAction(function(event) {}, MouseEventType.LEFT_DOWN); - element.fireEvents('mousedown', { - button : 0, - clientX : 1, - clientY : 1 - }); - - expect(handler.getLeftPressTime()).toBeDefined(); - }); - - it('get left release time', function() { - handler.setMouseAction(function(event) {}, MouseEventType.LEFT_DOWN); - element.fireEvents('mouseup', { - button : 0, - clientX : 1, - clientY : 1 - }); - - expect(handler.getLeftReleaseTime()).toBeDefined(); - }); - - it('get right press time', function() { - handler.setMouseAction(function(event) {}, MouseEventType.RIGHT_DOWN); - element.fireEvents('mousedown', { - button : 2, - clientX : 1, - clientY : 1 - }); - - expect(handler.getRightPressTime()).toBeDefined(); - }); - - it('get right release time', function() { - handler.setMouseAction(function(event) {}, MouseEventType.RIGHT_DOWN); - element.fireEvents('mouseup', { - button : 2, - clientX : 1, - clientY : 1 - }); - - expect(handler.getRightReleaseTime()).toBeDefined(); - }); - - it('get middle press time', function() { - handler.setMouseAction(function(event) {}, MouseEventType.MIDDLE_DOWN); - element.fireEvents('mousedown', { - button : 1, - clientX : 1, - clientY : 1 - }); - - expect(handler.getMiddlePressTime()).toBeDefined(); - }); - - it('get middle release time', function() { - handler.setMouseAction(function(event) {}, MouseEventType.MIDDLE_DOWN); - element.fireEvents('mouseup', { - button : 1, - clientX : 1, - clientY : 1 - }); - - expect(handler.getMiddleReleaseTime()).toBeDefined(); - }); - it('modified mouse move', function() { var actualMove = { startPosition : new Cartesian2(0, 0), diff --git a/Specs/Scene/CameraColumbusViewControllerSpec.js b/Specs/Scene/CameraColumbusViewControllerSpec.js index d22ed6cd5986..4dba560b813a 100644 --- a/Specs/Scene/CameraColumbusViewControllerSpec.js +++ b/Specs/Scene/CameraColumbusViewControllerSpec.js @@ -28,8 +28,8 @@ defineSuite([ controller = controller && !controller.isDestroyed() && controller.destroy(); }); - it('updateReferenceFrame', function() { - controller._updateReferenceFrame(); + it('correct position', function() { + controller._correctPosition(); expect(camera.position.equalsEpsilon(Cartesian3.ZERO, CesiumMath.EPSILON10)).toEqual(true); }); From 3edac72598ee50c42369045c98bad0c6d98c93ed Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 29 Jun 2012 17:39:19 -0400 Subject: [PATCH 24/36] Remove free-look controller by default in columbus view. --- Source/Scene/CameraColumbusViewController.js | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/Source/Scene/CameraColumbusViewController.js b/Source/Scene/CameraColumbusViewController.js index ce8a46b35706..57e980469c6c 100644 --- a/Source/Scene/CameraColumbusViewController.js +++ b/Source/Scene/CameraColumbusViewController.js @@ -60,9 +60,6 @@ define([ this._spindleController._spinHandler = new CameraEventHandler(canvas, CameraEventType.MIDDLE_DRAG); this._spindleController.constrainedAxis = Cartesian3.UNIT_Z; - this._freeLookController = new CameraFreeLookController(canvas, camera); - this._freeLookController.horizontalRotationAxis = Cartesian3.UNIT_Z; - this._transform = this._camera.transform.clone(); this._lastInertiaTranslateMovement = undefined; @@ -88,15 +85,11 @@ define([ this._translate(translate.getMovement()); } - var killInertia = this._spindleController._spinHandler.isButtonDown() || this._spindleController._zoomHandler.isButtonDown() || - this._spindleController._zoomWheel.isButtonDown() || this._freeLookController._handler.isButtonDown(); - - if (!killInertia && !translating && this.inertiaTranslate < 1.0) { + if (!translating && this.inertiaTranslate < 1.0) { maintainInertia(translate, this.inertiaTranslate, this._translate, this, '_lastInertiaTranslateMovement'); } this._spindleController.update(); - this._freeLookController.update(); this._correctPosition(); this._animationCollection.update(); @@ -256,7 +249,6 @@ define([ CameraColumbusViewController.prototype.destroy = function() { this._translateHandler = this._translateHandler && this._translateHandler.destroy(); this._spindleController = this._spindleController && this._spindleController.destroy(); - this._freeLookController = this._freeLookController && this._freeLookController.destroy(); return destroyObject(this); }; From e7daabd7b493e658d436f5af902f750bd2c32f90 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Sat, 30 Jun 2012 00:15:17 -0400 Subject: [PATCH 25/36] Tweak free look controller. --- Source/Scene/CameraFreeLookController.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Scene/CameraFreeLookController.js b/Source/Scene/CameraFreeLookController.js index 99dddaa53840..80de2fdf6790 100644 --- a/Source/Scene/CameraFreeLookController.js +++ b/Source/Scene/CameraFreeLookController.js @@ -262,7 +262,7 @@ define([ var dot = startX.dot(endX); var angle = 0.0; - var axis = (this.horizontalRotationAxis) ? this.horizontalRotationAxis : camera.position; + var axis = (typeof this.horizontalRotationAxis !== 'undefined') ? this.horizontalRotationAxis : camera.up; axis = (movement.startPosition.x > movement.endPosition.x) ? axis : axis.negate(); axis = axis.normalize(); if (dot < 1.0) { // dot is in [0, 1] From 0e92db865f3dd285ea0b253b4af92205de311b54 Mon Sep 17 00:00:00 2001 From: Ed Mackey Date: Mon, 2 Jul 2012 11:18:10 -0400 Subject: [PATCH 26/36] Make spindleController a local variable. Using 'this.' was incorrect in this location, the correct notation would be 'widget.', but the widget doesn't know or need to know about the particular controller being used here. So, it's local now. --- Apps/CesiumViewer/CesiumViewer.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Apps/CesiumViewer/CesiumViewer.js b/Apps/CesiumViewer/CesiumViewer.js index 3da459bacd0a..d736116473c0 100644 --- a/Apps/CesiumViewer/CesiumViewer.js +++ b/Apps/CesiumViewer/CesiumViewer.js @@ -59,6 +59,7 @@ define([ multiplier : 1 }); var animationController = new AnimationController(clock); + var spindleController; var timeline; var transitioner; var dynamicObjectCollection = new DynamicObjectCollection(); @@ -162,12 +163,12 @@ define([ var controllers = camera.getControllers(); controllers.removeAll(); - this.spindleController = controllers.addSpindle(); + spindleController = controllers.addSpindle(); } - if (typeof this.spindleController !== 'undefined' && !this.spindleController.isDestroyed()) { + if (typeof spindleController !== 'undefined' && !spindleController.isDestroyed()) { var transform = Transforms.eastNorthUpToFixedFrame(cameraCenteredObjectIDPosition, widget.ellipsoid); - this.spindleController.setReferenceFrame(transform, Ellipsoid.UNIT_SPHERE); + spindleController.setReferenceFrame(transform, Ellipsoid.UNIT_SPHERE); } } } From 31805194b4ddd94fecb47df2f4de0a948effe8a2 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 2 Jul 2012 14:01:06 -0400 Subject: [PATCH 27/36] Update CHANGES.md. --- CHANGES.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index b447a983bf62..d400fe986d54 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -24,6 +24,15 @@ Beta Releases var position = scene.pickEllipsoid(windowPosition, ellipsoid); * `Camera.getPickRay` now returns the new `Ray` type instead of an object with position and direction properties. + * `CameraSpindleController.mouseConstrainedZAxis` has been removed. Instead, use `CameraSpindleController.constrainedAxis`. Code that previously looked like: + + spindleController.mouseConstrainedZAxis = true; + + should now look like: + + spindleController.constrainedAxis = Cartesian3.UNIT_Z; + + * The free look feature has been removed from `CameraColumbusViewController` in favor of rotating about the point clicked on the map with the middle mouse button. * Added `addImage` to `TextureAtlas` so images can be added to a texture atlas after it is constructed. * Added `Scene.pickEllipsoid`, which picks either the ellipsoid or the map depending on the current `SceneMode`. @@ -39,6 +48,10 @@ Beta Releases * Added a new Timeline control to the widgets directory. * Added a new DojoWidgets directory, to contain dojo-specific widgets. * Added new Timeline and Cesium dojo widgets. +* Added `CameraCentralBodyController` as the new default controller to handle mouse input. + * The left mouse button rotates around the central body. + * The right mouse button and mouse wheel zoom in and out. + * The middle mouse button rotates around the point clicked on the central body. ### b6a - 06/20/2012 From ed06baca9039b12a2b0522dbe1e8a4b3c78a1eeb Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 2 Jul 2012 14:29:09 -0400 Subject: [PATCH 28/36] Constrain z axis of camera in viewer when zooming to a satellite. --- Apps/CesiumViewer/CesiumViewer.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Apps/CesiumViewer/CesiumViewer.js b/Apps/CesiumViewer/CesiumViewer.js index d736116473c0..4045e6c88b5a 100644 --- a/Apps/CesiumViewer/CesiumViewer.js +++ b/Apps/CesiumViewer/CesiumViewer.js @@ -17,6 +17,7 @@ define([ 'Core/FullScreen', 'Core/Ellipsoid', 'Core/Transforms', + 'Core/Cartesian3', 'Core/requestAnimationFrame', 'Scene/SceneTransitioner', 'Scene/BingMapsStyle', @@ -42,6 +43,7 @@ define([ FullScreen, Ellipsoid, Transforms, + Cartesian3, requestAnimationFrame, SceneTransitioner, BingMapsStyle, @@ -164,6 +166,7 @@ define([ var controllers = camera.getControllers(); controllers.removeAll(); spindleController = controllers.addSpindle(); + spindleController.constrainedAxis = Cartesian3.UNIT_Z; } if (typeof spindleController !== 'undefined' && !spindleController.isDestroyed()) { From 5027d57bee91fee1cd7670be6f89d773830c2c98 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 2 Jul 2012 15:50:26 -0400 Subject: [PATCH 29/36] Add contains method to AnimationCollection and update 2D/Columbus View controllers. --- Source/Scene/AnimationCollection.js | 13 ++++++++++++- Source/Scene/Camera2DController.js | 6 ++---- Source/Scene/CameraColumbusViewController.js | 8 ++------ 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/Source/Scene/AnimationCollection.js b/Source/Scene/AnimationCollection.js index 6316521eee34..d29ec61d3b02 100644 --- a/Source/Scene/AnimationCollection.js +++ b/Source/Scene/AnimationCollection.js @@ -198,7 +198,7 @@ define([ * @memberof AnimationCollection */ AnimationCollection.prototype.remove = function(animation) { - if (animation) { + if (typeof animation !== 'undefined') { var count = Tween.getAll().length; Tween.remove(animation._tween); @@ -216,6 +216,17 @@ define([ Tween.removeAll(); }; + /** + * DOC_TBA + * @memberof Animationcollection + */ + AnimationCollection.prototype.contains = function(animation) { + if (typeof animation !== 'undefined') { + return Tween.getAll().indexOf(animation) !== -1; + } + return false; + }; + /** * DOC_TBA * @memberof AnimationCollection diff --git a/Source/Scene/Camera2DController.js b/Source/Scene/Camera2DController.js index 52fa53b5e608..3cbd745c99fd 100644 --- a/Source/Scene/Camera2DController.js +++ b/Source/Scene/Camera2DController.js @@ -368,10 +368,8 @@ define([ } if (!translate.isButtonDown() && !rightZoom.isButtonDown()) { - var animations = Tween.getAll(); - if (this._camera.frustum.right > this._frustum.right && - !this._lastInertiaZoomMovement && animations.indexOf(this._zoomAnimation) === -1) { + !this._lastInertiaZoomMovement && !this._animationCollection.contains(this._zoomAnimation)) { this._addCorrectZoomAnimation(); } @@ -379,7 +377,7 @@ define([ var translateX = position.x < -this._cameraMaxX || position.x > this._cameraMaxX; var translateY = position.y < -this._cameraMaxY || position.y > this._cameraMaxY; if ((translateX || translateY) && !this._lastInertiaTranslateMovement && - animations.indexOf(this._translateAnimation) === -1) { + !this._animationCollection.contains(this._translateAnimation)) { this._addCorrectTranslateAnimation(); } } diff --git a/Source/Scene/CameraColumbusViewController.js b/Source/Scene/CameraColumbusViewController.js index 57e980469c6c..d73dc8508969 100644 --- a/Source/Scene/CameraColumbusViewController.js +++ b/Source/Scene/CameraColumbusViewController.js @@ -182,14 +182,10 @@ define([ if (positionWC.x < -maxX || positionWC.x > maxX || positionWC.y < -maxY || positionWC.y > maxY) { if (!this._translateHandler.isButtonDown()) { - var animations = Tween.getAll(); - var translateX = centerWC.y < -maxX || centerWC.y > maxX; var translateY = centerWC.z < -maxY || centerWC.z > maxY; - if ((translateX || translateY) && !this._lastInertiaTranslateMovement) { - if (animations.indexOf(this._translateAnimation) === -1) { - this._animationCollection.removeAll(); - } + if ((translateX || translateY) && !this._lastInertiaTranslateMovement && + !this._animationCollection.contains(this._translateAnimation)) { this._addCorrectTranslateAnimation(positionWC.getXYZ(), centerWC.getXYZ(), maxX, maxY); } } From 6f3214992446fdbee2c2caab326357f6be85f55a Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 2 Jul 2012 17:48:12 -0400 Subject: [PATCH 30/36] Fix inertia and exception on mouse wheel zoom. --- Source/Scene/CameraEventHandler.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Scene/CameraEventHandler.js b/Source/Scene/CameraEventHandler.js index c8919f4ff429..6c3faa6261bb 100644 --- a/Source/Scene/CameraEventHandler.js +++ b/Source/Scene/CameraEventHandler.js @@ -110,7 +110,7 @@ define([ that._update = false; } that._pressTime = new JulianDate(); - that._releaseTime = that._wheelStart.addSeconds(Math.abs(arcLength) * 0.005); + that._releaseTime = that._pressTime.addSeconds(Math.abs(arcLength) * 0.005); }, MouseEventType.WHEEL, moveModifier); } }; From 226db25bb1310692c8391d6ba57122cbd9925264 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 2 Jul 2012 19:02:27 -0400 Subject: [PATCH 31/36] Use Date instead of JulianDate in the camera controllers. --- Source/Scene/CameraEventHandler.js | 14 ++++++-------- Source/Scene/CameraFlightController.js | 16 +++++++--------- Source/Scene/CameraHelpers.js | 12 +++++------- 3 files changed, 18 insertions(+), 24 deletions(-) diff --git a/Source/Scene/CameraEventHandler.js b/Source/Scene/CameraEventHandler.js index 6c3faa6261bb..267b075cdf8c 100644 --- a/Source/Scene/CameraEventHandler.js +++ b/Source/Scene/CameraEventHandler.js @@ -6,7 +6,6 @@ define([ '../Core/EventHandler', '../Core/MouseEventType', '../Core/Cartesian2', - '../Core/JulianDate', './CameraEventType' ], function( DeveloperError, @@ -15,7 +14,6 @@ define([ EventHandler, MouseEventType, Cartesian2, - JulianDate, CameraEventType) { "use strict"; @@ -75,12 +73,12 @@ define([ this._eventHandler.setMouseAction(function(movement) { that._lastMovement = null; that._isDown = true; - that._pressTime = new JulianDate(); + that._pressTime = new Date(); }, down, moveModifier); this._eventHandler.setMouseAction(function(movement) { that._isDown = false; - that._releaseTime = new JulianDate(); + that._releaseTime = new Date(); }, up, moveModifier); this._eventHandler.setMouseAction(function(movement) { @@ -109,8 +107,8 @@ define([ that._lastMovement = that._movement; // This looks unusual, but its needed for wheel inertia. that._update = false; } - that._pressTime = new JulianDate(); - that._releaseTime = that._pressTime.addSeconds(Math.abs(arcLength) * 0.005); + that._pressTime = new Date(); + that._releaseTime = new Date(that._pressTime.getTime() + Math.abs(arcLength) * 5.0); }, MouseEventType.WHEEL, moveModifier); } }; @@ -167,7 +165,7 @@ define([ * * @memberof CameraEventHandler * - * @return {JulianDate} DOC_TBA + * @return {Date} DOC_TBA * */ CameraEventHandler.prototype.getButtonPressTime = function() { @@ -179,7 +177,7 @@ define([ * * @memberof CameraEventHandler * - * @return {JulianDate} DOC_TBA + * @return {Date} DOC_TBA * */ CameraEventHandler.prototype.getButtonReleaseTime = function() { diff --git a/Source/Scene/CameraFlightController.js b/Source/Scene/CameraFlightController.js index c6bc3f3659f1..3d5e33a096d3 100644 --- a/Source/Scene/CameraFlightController.js +++ b/Source/Scene/CameraFlightController.js @@ -5,16 +5,14 @@ define([ '../Core/MouseEventType', '../Core/Quaternion', '../Core/Cartesian3', - '../Core/HermiteSpline', - '../Core/JulianDate' + '../Core/HermiteSpline' ], function( destroyObject, EventHandler, MouseEventType, Quaternion, Cartesian3, - HermiteSpline, - JulianDate) { + HermiteSpline) { "use strict"; /** @@ -47,8 +45,8 @@ define([ var altitude = dm - radius; this._camera = camera; - this._start = new JulianDate(); - this._end = this._start.addSeconds(duration); + this._start = new Date(); + this._end = new Date(this._start.getTime() + duration * 1000); this._path = this._createPath(ellipsoid, altitude, destination, duration); this._canceled = false; this._complete = complete; @@ -135,16 +133,16 @@ define([ * @private */ CameraFlightController.prototype.update = function() { - var time = new JulianDate(), + var time = new Date(), diff, position, normal, tangent, target; - var now = time.greaterThan(this._end) ? this._end : time; + var now = (time.getTime() > this._end.getTime()) ? this._end : time; - diff = this._start.getSecondsDifference(now); + diff = ( now.getTime() - this._start.getTime()) / 1000.0; position = this._path.evaluate(diff); normal = Cartesian3.UNIT_Z.cross(position).normalize(); tangent = position.cross(normal).normalize(); diff --git a/Source/Scene/CameraHelpers.js b/Source/Scene/CameraHelpers.js index ff25162cf910..8fbcfe71e176 100644 --- a/Source/Scene/CameraHelpers.js +++ b/Source/Scene/CameraHelpers.js @@ -1,12 +1,10 @@ /*global define*/ define([ '../Core/Math', - '../Core/Cartesian2', - '../Core/JulianDate' + '../Core/Cartesian2' ], function( CesiumMath, - Cartesian2, - JulianDate) { + Cartesian2) { "use strict"; function move(camera, direction, rate) { @@ -38,9 +36,9 @@ define([ function maintainInertia(handler, decayCoef, action, object, lastMovementName) { var ts = handler.getButtonPressTime(); var tr = handler.getButtonReleaseTime(); - var threshold = ts && tr && ts.getSecondsDifference(tr); - var now = new JulianDate(); - var fromNow = tr && tr.getSecondsDifference(now); + var threshold = ts && tr && ((tr.getTime() - ts.getTime()) / 1000.0); + var now = new Date(); + var fromNow = tr && ((now.getTime() - tr.getTime()) / 1000.0); if (ts && tr && threshold < inertiaMaxClickTimeThreshold && fromNow <= inertiaMaxTimeThreshold) { var d = decay(fromNow, decayCoef); From 21d182f2c506ae2598afd68fa5342616d26a4f22 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 3 Jul 2012 14:02:50 -0400 Subject: [PATCH 32/36] Find map bounds using the current projection instead of estimating them. --- Source/Scene/Camera2DController.js | 49 +++++++++---------- Source/Scene/CameraControllerCollection.js | 4 +- Source/Scene/SceneTransitioner.js | 2 +- Specs/Scene/CameraControllerCollectionSpec.js | 4 -- 4 files changed, 25 insertions(+), 34 deletions(-) diff --git a/Source/Scene/Camera2DController.js b/Source/Scene/Camera2DController.js index 3cbd745c99fd..3710cb8e22bb 100644 --- a/Source/Scene/Camera2DController.js +++ b/Source/Scene/Camera2DController.js @@ -8,6 +8,7 @@ define([ '../Core/Ellipsoid', '../Core/Cartesian2', '../Core/Cartesian3', + '../Core/Cartographic3', './CameraEventHandler', './CameraEventType', './CameraHelpers', @@ -22,6 +23,7 @@ define([ Ellipsoid, Cartesian2, Cartesian3, + Cartographic3, CameraEventHandler, CameraEventType, CameraHelpers, @@ -46,12 +48,10 @@ define([ * * @internalConstructor */ - var Camera2DController = function(canvas, camera, ellipsoid) { - ellipsoid = ellipsoid || Ellipsoid.WGS84; - + var Camera2DController = function(canvas, camera, projection) { this._canvas = canvas; this._camera = camera; - this._ellipsoid = ellipsoid; + this._ellipsoid = projection.getEllipsoid(); this._zoomRate = 100000.0; this._moveRate = 100000.0; @@ -98,8 +98,7 @@ define([ this._frustum.top *= maxZoomOut; this._frustum.bottom *= maxZoomOut; - this._cameraMaxX = this._ellipsoid.getRadii().x * Math.PI; - this._cameraMaxY = this._ellipsoid.getRadii().y * CesiumMath.PI_OVER_TWO; + this._maxCoord = projection.project(new Cartographic3(Math.PI, CesiumMath.toRadians(85.05112878))); this._maxZoomFactor = 2.5; this._maxTranslateFactor = 1.5; @@ -236,7 +235,7 @@ define([ var newRight = frustum.right - moveRate; var newLeft = frustum.left + moveRate; - var maxRight = this._cameraMaxX * this._maxZoomFactor; + var maxRight = this._maxCoord.x * this._maxZoomFactor; if (newRight > maxRight) { newRight = maxRight; newLeft = -newRight; @@ -298,16 +297,16 @@ define([ var currentPosition = camera.position; var translatedPosition = currentPosition.clone(); - if (translatedPosition.x > this._cameraMaxX) { - translatedPosition.x = this._cameraMaxX; - } else if (translatedPosition.x < -this._cameraMaxX) { - translatedPosition.x = -this._cameraMaxX; + if (translatedPosition.x > this._maxCoord.x) { + translatedPosition.x = this._maxCoord.x; + } else if (translatedPosition.x < -this._maxCoord.x) { + translatedPosition.x = -this._maxCoord.x; } - if (translatedPosition.y > this._cameraMaxY) { - translatedPosition.y = this._cameraMaxY; - } else if (translatedPosition.y < -this._cameraMaxY) { - translatedPosition.y = -this._cameraMaxY; + if (translatedPosition.y > this._maxCoord.y) { + translatedPosition.y = this._maxCoord.y; + } else if (translatedPosition.y < -this._maxCoord.y) { + translatedPosition.y = -this._maxCoord.y; } var update2D = function(value) { @@ -374,8 +373,8 @@ define([ } var position = this._camera.position; - var translateX = position.x < -this._cameraMaxX || position.x > this._cameraMaxX; - var translateY = position.y < -this._cameraMaxY || position.y > this._cameraMaxY; + var translateX = position.x < -this._maxCoord.x || position.x > this._maxCoord.x; + var translateY = position.y < -this._maxCoord.y || position.y > this._maxCoord.y; if ((translateX || translateY) && !this._lastInertiaTranslateMovement && !this._animationCollection.contains(this._translateAnimation)) { this._addCorrectTranslateAnimation(); @@ -399,16 +398,12 @@ define([ var height = this._canvas.clientHeight; var start = new Cartesian2(); - start.x = (2.0 / width) * movement.startPosition.x - 1.0; - start.x = (start.x * (frustum.right - frustum.left) + frustum.right + frustum.left) * 0.5; - start.y = (2.0 / height) * (height - movement.startPosition.y) - 1.0; - start.y = (start.y * (frustum.top - frustum.bottom) + frustum.top + frustum.bottom) * 0.5; + start.x = (movement.startPosition.x / width) * (frustum.right - frustum.left) + frustum.left; + start.y = ((height - movement.startPosition.y) / height) * (frustum.top - frustum.bottom) + frustum.bottom; var end = new Cartesian2(); - end.x = (2.0 / width) * movement.endPosition.x - 1.0; - end.x = (end.x * (frustum.right - frustum.left) + frustum.right + frustum.left) * 0.5; - end.y = (2.0 / height) * (height - movement.endPosition.y) - 1.0; - end.y = (end.y * (frustum.top - frustum.bottom) + frustum.top + frustum.bottom) * 0.5; + end.x = (movement.endPosition.x / width) * (frustum.right - frustum.left) + frustum.left; + end.y = ((height - movement.endPosition.y) / height) * (frustum.top - frustum.bottom) + frustum.bottom; var camera = this._camera; var right = camera.right; @@ -421,7 +416,7 @@ define([ position = camera.position; newPosition = position.add(right.multiplyWithScalar(distance.x)); - var maxX = this._cameraMaxX * this._maxTranslateFactor; + var maxX = this._maxCoord.x * this._maxTranslateFactor; if (newPosition.x > maxX) { newPosition.x = maxX; } @@ -435,7 +430,7 @@ define([ position = camera.position; newPosition = position.add(up.multiplyWithScalar(distance.y)); - var maxY = this._cameraMaxY * this._maxTranslateFactor; + var maxY = this._maxCoord.y * this._maxTranslateFactor; if (newPosition.y > maxY) { newPosition.y = maxY; } diff --git a/Source/Scene/CameraControllerCollection.js b/Source/Scene/CameraControllerCollection.js index 591a5ba5fbaa..39b17e14ec8e 100644 --- a/Source/Scene/CameraControllerCollection.js +++ b/Source/Scene/CameraControllerCollection.js @@ -47,8 +47,8 @@ define([ * @see CameraControllerCollection#addSpindle * @see CameraControllerCollection#addColumbusView */ - CameraControllerCollection.prototype.add2D = function(ellipsoid) { - var twoD = new Camera2DController(this._canvas, this._camera, ellipsoid); + CameraControllerCollection.prototype.add2D = function(projection) { + var twoD = new Camera2DController(this._canvas, this._camera, projection); this._controllers.push(twoD); return twoD; }; diff --git a/Source/Scene/SceneTransitioner.js b/Source/Scene/SceneTransitioner.js index a8e2042e3b40..0b7499e0ddfc 100644 --- a/Source/Scene/SceneTransitioner.js +++ b/Source/Scene/SceneTransitioner.js @@ -195,7 +195,7 @@ define([ var controllers = camera.getControllers(); controllers.removeAll(); - controllers.add2D(this._ellipsoid); + controllers.add2D(scene.scene2D.projection); // TODO: Match incoming columbus-view or 3D position camera.position = this._camera2D.position.clone(); diff --git a/Specs/Scene/CameraControllerCollectionSpec.js b/Specs/Scene/CameraControllerCollectionSpec.js index 3cfcd9443400..de9c66640583 100644 --- a/Specs/Scene/CameraControllerCollectionSpec.js +++ b/Specs/Scene/CameraControllerCollectionSpec.js @@ -2,17 +2,13 @@ defineSuite([ 'Scene/CameraControllerCollection', 'Scene/Camera', - 'Scene/Camera2DController', 'Scene/CameraFreeLookController', - 'Scene/CameraSpindleController', 'Core/Cartographic3', 'Core/Ellipsoid' ], function( CameraControllerCollection, Camera, - Camera2DController, CameraFreeLookController, - CameraSpindleController, Cartographic3, Ellipsoid) { "use strict"; From db75bde7c5bb35bc3d3a2e46b04951be47ccd2c8 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 3 Jul 2012 14:29:28 -0400 Subject: [PATCH 33/36] Update doc and tests. Add error checking. Remove unused includes, variables and functions. --- CHANGES.md | 1 + Source/Scene/Camera2DController.js | 77 ++++++++----------- Specs/Scene/Camera2DControllerSpec.js | 45 ++++++++--- Specs/Scene/CameraControllerCollectionSpec.js | 13 ++-- 4 files changed, 77 insertions(+), 59 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index d400fe986d54..5011c6e875ca 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -33,6 +33,7 @@ Beta Releases spindleController.constrainedAxis = Cartesian3.UNIT_Z; * The free look feature has been removed from `CameraColumbusViewController` in favor of rotating about the point clicked on the map with the middle mouse button. + * The `Camera2DController` constructor and `CameraControllerCollection.add2D` now require a projection instead of an ellipsoid. * Added `addImage` to `TextureAtlas` so images can be added to a texture atlas after it is constructed. * Added `Scene.pickEllipsoid`, which picks either the ellipsoid or the map depending on the current `SceneMode`. diff --git a/Source/Scene/Camera2DController.js b/Source/Scene/Camera2DController.js index 3710cb8e22bb..8a8fde4f63ce 100644 --- a/Source/Scene/Camera2DController.js +++ b/Source/Scene/Camera2DController.js @@ -5,9 +5,7 @@ define([ '../Core/FAR', '../Core/Math', '../Core/Quaternion', - '../Core/Ellipsoid', '../Core/Cartesian2', - '../Core/Cartesian3', '../Core/Cartographic3', './CameraEventHandler', './CameraEventType', @@ -20,9 +18,7 @@ define([ FAR, CesiumMath, Quaternion, - Ellipsoid, Cartesian2, - Cartesian3, Cartographic3, CameraEventHandler, CameraEventType, @@ -44,14 +40,30 @@ define([ * @param {HTMLCanvasElement} canvas An HTML canvas element used for its dimensions * and for listening on user events. * @param {Camera} camera The camera to use. - * @param {Ellipsoid} [ellipsoid=WGS84 Ellipsoid] DOC_TBA. + * @param {DOC_TBA} projection The projection of the map the camera is moving around.. + * + * @exception {DeveloperError} canvas is required. + * @exception {DeveloperError} camera is required. + * @exception {DeveloperError} projection is required. * * @internalConstructor */ var Camera2DController = function(canvas, camera, projection) { + if (typeof canvas === 'undefined') { + throw new DeveloperError('canvas is required.'); + } + + if (typeof camera === 'undefined') { + throw new DeveloperError('camera is required.'); + } + + if (typeof projection === 'undefined') { + throw new DeveloperError('projection is required.'); + } + this._canvas = canvas; this._camera = camera; - this._ellipsoid = projection.getEllipsoid(); + this._projection = projection; this._zoomRate = 100000.0; this._moveRate = 100000.0; @@ -105,59 +117,36 @@ define([ }; /** - * DOC_TBA + * Returns the projection of the map that the camera is moving around. * * @memberof Camera2DController * - * @param {Matrix4} transform DOC_TBA - * @param {Ellipsoid} ellipsoid DOC_TBA - * - * @example - * // Example 1. - * // Change the reference frame to one centered at a point on the ellipsoid's surface. - * // Set the 2D controller's ellipsoid to a unit sphere for easy rotation around that point. - * var center = ellipsoid.cartographicDegreesToCartesian(new Cartographic2(-75.59777, 40.03883)); - * var transform = Transforms.eastNorthUpToFixedFrame(center); - * scene.getCamera().getControllers().get(0).setReferenceFrame(transform, Ellipsoid.UNIT_SPHERE); - * - * // Example 2. - * // Reset to the defaults. - * scene.getCamera().getControllers().get(0).setReferenceFrame(Matrix4.IDENTITY); + * @returns {DOC_TBA} The projection of the map that the camera is moving around. * + * @see Camera2DController#setProjection */ - Camera2DController.prototype.setReferenceFrame = function (transform, ellipsoid) { - this._camera.transform = transform; - this.setEllipsoid(ellipsoid); + Camera2DController.prototype.getProjection = function() { + return this._projection; }; /** - * Returns the ellipsoid that the camera is moving around. + * Sets the projection of the map that the camera is moving around. * * @memberof Camera2DController * - * @returns {Ellipsoid} The ellipsoid that the camera is moving around. - * - * @see Camera2DController#setEllipsoid - */ - Camera2DController.prototype.getEllipsoid = function() { - return this._ellipsoid; - }; - - /** - * Sets the ellipsoid that the camera is moving around. - * - * @memberof Camera2DController + * @param {DOC_TBA} projection The projection of the map that the camera is moving around. * - * @param {Ellipsoid} [ellipsoid] The ellipsoid that the camera is moving around. + * @exception {DeveloperError} projection is required. * - * @see Camera2DController#getEllipsoid + * @see Camera2DController#getProjection */ - Camera2DController.prototype.setEllipsoid = function(ellipsoid) { - ellipsoid = ellipsoid || Ellipsoid.WGS84; + Camera2DController.prototype.setProjection = function(projection) { + if (typeof projection === 'undefined') { + throw new DeveloperError('projection is required.'); + } - var radius = ellipsoid.getRadii().getMaximumComponent(); - this._ellipsoid = ellipsoid; - this._rateAdjustment = radius; + this._projection = projection; + this._maxCoord = projection.project(new Cartographic3(Math.PI, CesiumMath.toRadians(85.05112878))); }; /** diff --git a/Specs/Scene/Camera2DControllerSpec.js b/Specs/Scene/Camera2DControllerSpec.js index 05dc994e0540..cec2f7948144 100644 --- a/Specs/Scene/Camera2DControllerSpec.js +++ b/Specs/Scene/Camera2DControllerSpec.js @@ -7,6 +7,8 @@ defineSuite([ 'Core/Cartesian2', 'Core/Cartesian3', 'Core/Ellipsoid', + 'Core/EquidistantCylindricalProjection', + 'Core/MercatorProjection', 'Core/Math', 'Core/Transforms' ], function( @@ -17,6 +19,8 @@ defineSuite([ Cartesian2, Cartesian3, Ellipsoid, + EquidistantCylindricalProjection, + MercatorProjection, CesiumMath, Transforms) { "use strict"; @@ -31,6 +35,7 @@ defineSuite([ var moverate; var zoomrate; var ellipsoid; + var projection; var controller; var controller2; var canvas; @@ -69,7 +74,9 @@ defineSuite([ camera.right = right; camera.frustum = frustum; - controller = new Camera2DController(canvas, camera, ellipsoid); + projection = new EquidistantCylindricalProjection(ellipsoid); + + controller = new Camera2DController(canvas, camera, projection); }); afterEach(function() { @@ -77,16 +84,34 @@ defineSuite([ controller2 = controller2 && !controller2.isDestroyed() && controller2.destroy(); }); - it('setReferenceFrame', function() { - var transform = Transforms.eastNorthUpToFixedFrame(ellipsoid.cartographicDegreesToCartesian(new Cartographic2(-75.0, 40.0))); - controller.setReferenceFrame(transform, ellipsoid); - expect(controller.getEllipsoid()).toBe(ellipsoid); - expect(controller._camera.transform).toBe(transform); + it('constructor throws without a canvas', function() { + expect(function() { + return new Camera2DController(); + }).toThrow(); + }); + + it('constructor throws without a camera', function() { + expect(function() { + return new Camera2DController(canvas); + }).toThrow(); + }); + + it('constructor throws without a projection', function() { + expect(function() { + return new Camera2DController(canvas, camera); + }).toThrow(); + }); + + it('setProjection throws without a projection', function() { + expect(function() { + controller.setProjection(); + }).toThrow(); }); - it('setEllipsoid', function() { - controller.setEllipsoid(Ellipsoid.UNIT_SPHERE); - expect(controller.getEllipsoid().equals(Ellipsoid.UNIT_SPHERE)).toEqual(true); + it('setProjection', function() { + var mercator = new MercatorProjection(ellipsoid); + controller.setProjection(mercator); + expect(controller.getProjection()).toEqual(mercator); }); it('moveUp', function() { @@ -149,7 +174,7 @@ defineSuite([ it('zoomIn throws with null OrthogrphicFrustum properties', function() { var camera = new Camera(document); camera.frustum = new OrthographicFrustum(); - controller2 = new Camera2DController(document, camera, ellipsoid); + controller2 = new Camera2DController(document, camera, projection); expect(function () { controller2.zoomIn(moverate); }).toThrow(); diff --git a/Specs/Scene/CameraControllerCollectionSpec.js b/Specs/Scene/CameraControllerCollectionSpec.js index de9c66640583..3fc87d3133ad 100644 --- a/Specs/Scene/CameraControllerCollectionSpec.js +++ b/Specs/Scene/CameraControllerCollectionSpec.js @@ -4,13 +4,15 @@ defineSuite([ 'Scene/Camera', 'Scene/CameraFreeLookController', 'Core/Cartographic3', - 'Core/Ellipsoid' + 'Core/Ellipsoid', + 'Core/MercatorProjection' ], function( CameraControllerCollection, Camera, CameraFreeLookController, Cartographic3, - Ellipsoid) { + Ellipsoid, + MercatorProjection) { "use strict"; /*global document,describe,it,expect,beforeEach,afterEach*/ @@ -28,7 +30,8 @@ defineSuite([ it('add2D', function() { expect(function() { - collection.add2D(); + var mercator = new MercatorProjection(); + collection.add2D(mercator); }).not.toThrow(); expect(collection.getLength()).toEqual(1); }); @@ -87,8 +90,8 @@ defineSuite([ }); it('update', function() { - collection.add2D(); - collection.addColumbusView(); + collection.addSpindle(); + collection.addFreeLook(); expect(function() { collection.update(); }).not.toThrow(); From e36b0125eb5333553c40995a11af74237d568c37 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 3 Jul 2012 15:17:22 -0400 Subject: [PATCH 34/36] Add free look back to Columbus view. Attempt to loosen constraints when map is not visible. --- Source/Scene/CameraColumbusViewController.js | 37 +++++++++++++++----- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/Source/Scene/CameraColumbusViewController.js b/Source/Scene/CameraColumbusViewController.js index d73dc8508969..2d8d92c3d808 100644 --- a/Source/Scene/CameraColumbusViewController.js +++ b/Source/Scene/CameraColumbusViewController.js @@ -60,6 +60,9 @@ define([ this._spindleController._spinHandler = new CameraEventHandler(canvas, CameraEventType.MIDDLE_DRAG); this._spindleController.constrainedAxis = Cartesian3.UNIT_Z; + this._freeLookController = new CameraFreeLookController(canvas, camera); + this._freeLookController.horizontalRotationAxis = Cartesian3.UNIT_Z; + this._transform = this._camera.transform.clone(); this._lastInertiaTranslateMovement = undefined; @@ -77,7 +80,8 @@ define([ var translate = this._translateHandler; var translating = translate.isMoving() && translate.getMovement(); - if (translate.isButtonDown() || this._spindleController._zoomHandler.isButtonDown() || this._spindleController._spinHandler.isButtonDown()) { + if (translate.isButtonDown() || this._spindleController._zoomHandler.isButtonDown() || + this._spindleController._spinHandler.isButtonDown() || this._freeLookController._handler.isButtonDown()) { this._animationCollection.removeAll(); } @@ -90,6 +94,7 @@ define([ } this._spindleController.update(); + this._freeLookController.update(); this._correctPosition(); this._animationCollection.update(); @@ -161,15 +166,28 @@ define([ var position = camera.position; var direction = camera.direction; - var scalar = -position.z / direction.z; - var center = position.add(direction.multiplyWithScalar(scalar)); - center = new Cartesian4(center.x, center.y, center.z, 1.0); - var centerWC = camera.transform.multiplyWithVector(center); - this._transform.setColumn3(centerWC); + var centerWC; + var positionWC; + + if (direction.dot(Cartesian3.UNIT_Z) >= 0) { + centerWC = Cartesian4.UNIT_W; + this._transform.setColumn3(centerWC); - var cameraPosition = new Cartesian4(camera.position.x, camera.position.y, camera.position.z, 1.0); - var positionWC = camera.transform.multiplyWithVector(cameraPosition); - camera.transform = this._transform.clone(); + var cameraPosition = new Cartesian4(camera.position.x, camera.position.y, camera.position.z, 1.0); + positionWC = camera.transform.multiplyWithVector(cameraPosition); + + camera.transform = this._transform.clone(); + } else { + var scalar = -position.z / direction.z; + var center = position.add(direction.multiplyWithScalar(scalar)); + center = new Cartesian4(center.x, center.y, center.z, 1.0); + centerWC = camera.transform.multiplyWithVector(center); + this._transform.setColumn3(centerWC); + + var cameraPosition = new Cartesian4(camera.position.x, camera.position.y, camera.position.z, 1.0); + positionWC = camera.transform.multiplyWithVector(cameraPosition); + camera.transform = this._transform.clone(); + } var tanPhi = Math.tan(this._camera.frustum.fovy * 0.5); var tanTheta = this._camera.frustum.aspectRatio * tanPhi; @@ -245,6 +263,7 @@ define([ CameraColumbusViewController.prototype.destroy = function() { this._translateHandler = this._translateHandler && this._translateHandler.destroy(); this._spindleController = this._spindleController && this._spindleController.destroy(); + this._freeLookController = this._freeLookController && this._freeLookController.destroy(); return destroyObject(this); }; From 18ca3dda43657002f132abb89eac09e699568845 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 3 Jul 2012 15:32:23 -0400 Subject: [PATCH 35/36] Reverse Cloumbus view mouse left click when looking away from the map. --- Source/Scene/CameraColumbusViewController.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Source/Scene/CameraColumbusViewController.js b/Source/Scene/CameraColumbusViewController.js index 2d8d92c3d808..2f6e4e13a9a2 100644 --- a/Source/Scene/CameraColumbusViewController.js +++ b/Source/Scene/CameraColumbusViewController.js @@ -138,6 +138,7 @@ define([ CameraColumbusViewController.prototype._translate = function(movement) { var camera = this._camera; + var sign = (camera.direction.dot(Cartesian3.UNIT_Z) >= 0) ? 1.0 : -1.0; var startRay = camera.getPickRay(movement.startPosition); var endRay = camera.getPickRay(movement.endPosition); @@ -146,14 +147,14 @@ define([ position = camera.getInverseTransform().multiplyWithVector(position).getXYZ(); var direction = new Cartesian4(startRay.direction.x, startRay.direction.y, startRay.direction.z, 0.0); direction = camera.getInverseTransform().multiplyWithVector(direction).getXYZ(); - var scalar = -position.z / direction.z; + var scalar = sign * position.z / direction.z; var startPlanePos = position.add(direction.multiplyWithScalar(scalar)); position = new Cartesian4(endRay.origin.x, endRay.origin.y, endRay.origin.z, 1.0); position = camera.getInverseTransform().multiplyWithVector(position).getXYZ(); direction = new Cartesian4(endRay.direction.x, endRay.direction.y, endRay.direction.z, 0.0); direction = camera.getInverseTransform().multiplyWithVector(direction).getXYZ(); - scalar = -position.z / direction.z; + scalar = sign * position.z / direction.z; var endPlanePos = position.add(direction.multiplyWithScalar(scalar)); var diff = startPlanePos.subtract(endPlanePos); From 36ded681ea04e140d04a365a9c2ca5aa852efc39 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 5 Jul 2012 15:12:59 -0400 Subject: [PATCH 36/36] Change the 2D max latitude. --- Source/Scene/Camera2DController.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Scene/Camera2DController.js b/Source/Scene/Camera2DController.js index 8a8fde4f63ce..9bc503eb6df7 100644 --- a/Source/Scene/Camera2DController.js +++ b/Source/Scene/Camera2DController.js @@ -110,7 +110,7 @@ define([ this._frustum.top *= maxZoomOut; this._frustum.bottom *= maxZoomOut; - this._maxCoord = projection.project(new Cartographic3(Math.PI, CesiumMath.toRadians(85.05112878))); + this._maxCoord = projection.project(new Cartographic3(Math.PI, CesiumMath.PI_OVER_TWO, 0.0)); this._maxZoomFactor = 2.5; this._maxTranslateFactor = 1.5;