Skip to content

Commit

Permalink
Merge pull request #1806 from AnalyticalGraphicsInc/animation-collection
Browse files Browse the repository at this point in the history
Camera flights
  • Loading branch information
bagnell committed Jun 9, 2014
2 parents 7aa3e7c + 33df73c commit bfcf803
Show file tree
Hide file tree
Showing 10 changed files with 628 additions and 604 deletions.
72 changes: 18 additions & 54 deletions Apps/Sandcastle/gallery/Camera.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,18 @@

function flyToSanDiego() {
Sandcastle.declare(flyToSanDiego); // For highlighting in Sandcastle.
var destination = Cesium.Cartesian3.fromDegrees(-117.16, 32.71, 15000.0);

var flight = Cesium.CameraFlightPath.createAnimation(scene, {
destination : destination
scene.camera.flyTo({
destination : Cesium.Cartesian3.fromDegrees(-117.16, 32.71, 15000.0)
});
scene.animations.add(flight);
}

function flyToMyLocation() {
Sandcastle.declare(flyToMyLocation); // For highlighting in Sandcastle.
function fly(position) {
var destination = Cesium.Cartesian3.fromDegrees(position.coords.longitude, position.coords.latitude, 1000.0);

var flight = Cesium.CameraFlightPath.createAnimation(scene, {
destination : destination
scene.camera.flyTo({
destination : Cesium.Cartesian3.fromDegrees(position.coords.longitude, position.coords.latitude, 1000.0)
});
scene.animations.add(flight);
}

navigator.geolocation.getCurrentPosition(fly);
Expand All @@ -62,11 +57,10 @@
var east = -72.0;
var north = 42.0;

var rectangle = Cesium.Rectangle.fromDegrees(west, south, east, north);
scene.camera.viewRectangle(rectangle, scene.globe.ellipsoid);
scene.camera.viewRectangle(Cesium.Rectangle.fromDegrees(west, south, east, north));

// Show the rectangle. Not required; just for show.
var polylines = new Cesium.PolylineCollection();
var polylines = scene.primitives.add(new Cesium.PolylineCollection());
polylines.add({
positions : Cesium.Cartesian3.fromDegreesArray([
west, south,
Expand All @@ -76,7 +70,6 @@
west, south
])
});
scene.primitives.add(polylines);
}

function flyToRectangle() {
Expand All @@ -86,15 +79,12 @@
var east = -87.0;
var north = 40.0;

var rectangle = Cesium.Rectangle.fromDegrees(west, south, east, north);

var flight = Cesium.CameraFlightPath.createAnimationRectangle(scene, {
destination : rectangle
scene.camera.flyToRectangle({
destination : Cesium.Rectangle.fromDegrees(west, south, east, north)
});
scene.animations.add(flight);

// Show the rectangle. Not required; just for show.
var polylines = new Cesium.PolylineCollection();
var polylines = scene.primitives.add(new Cesium.PolylineCollection());
polylines.add({
positions : Cesium.Cartesian3.fromDegreesArray([
west, south,
Expand All @@ -104,7 +94,6 @@
west, south
])
});
scene.primitives.add(polylines);
}

function eastNorthUp() {
Expand All @@ -128,41 +117,17 @@
Cesium.Cartesian3.UNIT_Z);

// Show reference frame. Not required.
var primitives = scene.primitives;
var polylines = new Cesium.PolylineCollection();
Cesium.Matrix4.clone(transform, polylines.modelMatrix);

var xAxis = {
color : Cesium.Color.RED,
positions : [
Cesium.Cartesian3.ZERO,
new Cesium.Cartesian3(100000.0, 0.0, 0.0)
]
};
polylines.add(xAxis);

var yAxis = {
color : Cesium.Color.LIME,
positions : [
Cesium.Cartesian3.ZERO,
new Cesium.Cartesian3(0.0, 100000.0, 0.0)
]
};
polylines.add(yAxis);

var zAxis = {
color : Cesium.Color.BLUE,
positions : [
Cesium.Cartesian3.ZERO,
new Cesium.Cartesian3(0.0, 0.0, 100000.0)
]
};
polylines.add(zAxis);

primitives.add(polylines);
scene.primitives.add(new Cesium.DebugModelMatrixPrimitive({
modelMatrix : transform,
length : 100000.0
}));
}

function icrf(scene, time) {
if (scene.sceneMode !== Cesium.SceneMode.SCENE3D) {
return;
}

var icrfToFixed = Cesium.Transforms.computeIcrfToFixedMatrix(time);
if (Cesium.defined(icrfToFixed)) {
scene.camera.transform = Cesium.Matrix4.fromRotationTranslation(icrfToFixed, Cesium.Cartesian3.ZERO);
Expand All @@ -188,8 +153,7 @@
controller.ellipsoid = ellipsoid;
controller.enableTilt = true;

var camera = scene.camera;
camera.setTransform(Cesium.Matrix4.IDENTITY);
scene.camera.setTransform(Cesium.Matrix4.IDENTITY);

clock.multiplier = 1.0;
scene.preRender.removeEventListener(icrf);
Expand Down
14 changes: 14 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,19 @@ Beta Releases
### b30 - 2014-07-01

* Breaking changes ([why so many?](https://groups.google.com/forum/#!topic/cesium-dev/Y_mG11IZD9k))
* Replaced `CameraFlightPath.createAnimation` with `Camera.flyTo` and replaced `CameraFlightPath.createAnimationRectangle` with `Camera.flyToRectangle`. Code that looked like:

scene.animations.add(Cesium.CameraFlightPath.createAnimation(scene, {
destination : Cesium.Cartesian3.fromDegrees(-117.16, 32.71, 15000.0)
}));

should now look like:

scene.camera.flyTo({
destination : Cesium.Cartesian3.fromDegrees(-117.16, 32.71, 15000.0)
});

* Renamed `options.endReferenceFrame` to `options.endTransform` in `Camera.flyTo` and `Camera.flyToRectangle`.
* Renamed `Simon1994PlanetaryPositions` functions `ComputeSunPositionInEarthInertialFrame` and `ComputeMoonPositionInEarthInertialFrame` to `computeSunPositionInEarthInertialFrame` and `computeMoonPositionInEarthInertialFrame`, respectively.
* Replaced `Scene.scene2D.projection` property with read-only `Scene.mapProjection`. Set this with the `mapProjection` option for the `Viewer`, `CesiumWidget`, or `Scene` constructors.
* `Scene` constructor function now takes an `options` parameter instead of individual parameters.
Expand All @@ -25,6 +38,7 @@ Beta Releases
* `Viewer` and `CesiumWidget` now take a new optional parameter, `creditContainer`.
* Added `PerformanceWatchdog` widget and `viewerPerformanceWatchdogMixin`.
* Fixed a problem that could rarely lead to the camera's `tilt` property being `NaN`.
* Updated third-party [Tween.js](https://github.com/sole/tween.js/) from r7 to r13.

### b29 - 2014-06-02

Expand Down
48 changes: 44 additions & 4 deletions Source/Scene/Camera.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ define([
'../Core/Ray',
'../Core/Transforms',
'../ThirdParty/Tween',
'./CameraFlightPath',
'./PerspectiveFrustum',
'./SceneMode'
], function(
Expand All @@ -37,6 +38,7 @@ define([
Ray,
Transforms,
Tween,
CameraFlightPath,
PerspectiveFrustum,
SceneMode) {
"use strict";
Expand Down Expand Up @@ -1748,8 +1750,9 @@ define([
var pickPerspXDir = new Cartesian3();
var pickPerspYDir = new Cartesian3();
function getPickRayPerspective(camera, windowPosition, result) {
var width = camera._scene.canvas.clientWidth;
var height = camera._scene.canvas.clientHeight;
var canvas = camera._scene.canvas;
var width = canvas.clientWidth;
var height = canvas.clientHeight;

var tanPhi = Math.tan(camera.frustum.fovy * 0.5);
var tanTheta = camera.frustum.aspectRatio * tanPhi;
Expand All @@ -1776,8 +1779,9 @@ define([
var scratchDirection = new Cartesian3();

function getPickRayOrthographic(camera, windowPosition, result) {
var width = camera._scene.canvas.clientWidth;
var height = camera._scene.canvas.clientHeight;
var canvas = camera._scene.canvas;
var width = canvas.clientWidth;
var height = canvas.clientHeight;

var x = (2.0 / width) * windowPosition.x - 1.0;
x *= (camera.frustum.right - camera.frustum.left) * 0.5;
Expand Down Expand Up @@ -1977,6 +1981,42 @@ define([
return undefined;
};

/**
* Flies the camera from its current position to a new position.
*
* @param {Object} options Object with the following properties:
* @param {Cartesian3} options.destination The final position of the camera in WGS84 (world) coordinates.
* @param {Cartesian3} [options.direction] The final direction of the camera in WGS84 (world) coordinates. By default, the direction will point towards the center of the frame in 3D and in the negative z direction in Columbus view or 2D.
* @param {Cartesian3} [options.up] The final up direction in WGS84 (world) coordinates. By default, the up direction will point towards local north in 3D and in the positive y direction in Columbus view or 2D.
* @param {Number} [options.duration=3000] The duration of the flight in milliseconds.
* @param {Function} [options.onComplete] The function to execute when the flight is complete.
* @param {Function} [options.onCancel] The function to execute if the flight is cancelled.
* @param {Matrix4} [options.endTransform] Transform matrix representing the reference frame the camera will be in when the flight is completed.
* @param {Boolean} [options.convert=true] When <code>true</code>, the destination is converted to the correct coordinate system for each scene mode. When <code>false</code>, the destination is expected
* to be in the correct coordinate system.
*
* @exception {DeveloperError} If either direction or up is given, then both are required.
*/
Camera.prototype.flyTo = function(options) {
var scene = this._scene;
scene.animations.add(CameraFlightPath.createAnimation(scene, options));
};

/**
* Flies the camera from its current position to a position where the entire rectangle is visible.
*
* @param {Object} options Object with the following properties:
* @param {Rectangle} options.destination The rectangle to view, in WGS84 (world) coordinates, which determines the final position of the camera.
* @param {Number} [options.duration=3000] The duration of the flight in milliseconds.
* @param {Function} [options.onComplete] The function to execute when the flight is complete.
* @param {Function} [options.onCancel] The function to execute if the flight is cancelled.
* @param {Matrix4} [endTransform] Transform matrix representing the reference frame the camera will be in when the flight is completed.
*/
Camera.prototype.flyToRectangle = function(options) {
var scene = this._scene;
scene.animations.add(CameraFlightPath.createAnimationRectangle(scene, options));
};

/**
* Returns a duplicate of a Camera instance.
*
Expand Down
61 changes: 10 additions & 51 deletions Source/Scene/CameraFlightPath.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ define([
* <br /><br />
* Mouse interaction is disabled during flights.
*
* @exports CameraFlightPath
* @private
*/
var CameraFlightPath = {
};
Expand Down Expand Up @@ -388,27 +388,6 @@ define([
var scratchCartographic = new Cartographic();
var scratchDestination = new Cartesian3();

/**
* Creates an animation to fly the camera from it's current position to a position given by a Cartesian. All arguments should
* be given in world coordinates.
*
* @param {Scene} scene The scene instance to use.
* @param {Object} options Object with the following properties:
* @param {Cartesian3} options.destination The final position of the camera.
* @param {Cartesian3} [options.direction] The final direction of the camera. By default, the direction will point towards the center of the frame in 3D and in the negative z direction in Columbus view or 2D.
* @param {Cartesian3} [options.up] The final up direction. By default, the up direction will point towards local north in 3D and in the positive y direction in Columbus view or 2D.
* @param {Number} [options.duration=3000] The duration of the animation in milliseconds.
* @param {Function} [options.onComplete] The function to execute when the animation has completed.
* @param {Function} [options.onCancel] The function to execute if the animation is cancelled.
* @param {Matrix4} [options.endReferenceFrame] The reference frame the camera will be in when the flight is completed.
* @param {Boolean} [options.convert=true] When <code>true</code>, the destination is converted to the correct coordinate system for each scene mode. When <code>false</code>, the destination is expected
* to be in the correct coordinate system.
* @returns {Object} An Object that can be added to an {@link AnimationCollection} for animation.
*
* @exception {DeveloperError} If either direction or up is given, then both are required.
*
* @see Scene#animations
*/
CameraFlightPath.createAnimation = function(scene, options) {
options = defaultValue(options, defaultValue.EMPTY_OBJECT);
var destination = options.destination;
Expand All @@ -419,15 +398,6 @@ define([
if (!defined(scene)) {
throw new DeveloperError('scene is required.');
}
//>>includeEnd('debug');

if (scene.frameState.mode === SceneMode.MORPHING) {
return {
duration : 0
};
}

//>>includeStart('debug', pragmas.debug);
if (!defined(destination)) {
throw new DeveloperError('destination is required.');
}
Expand All @@ -436,6 +406,12 @@ define([
}
//>>includeEnd('debug');

if (scene.frameState.mode === SceneMode.MORPHING) {
return {
duration : 0
};
}

var convert = defaultValue(options.convert, true);

var frameState = scene.frameState;
Expand Down Expand Up @@ -463,9 +439,9 @@ define([
var onComplete = wrapCallback(options.onComplete);
var onCancel = wrapCallback(options.onCancel);

var referenceFrame = options.endReferenceFrame;
if (defined(referenceFrame)) {
scene.camera.setTransform(referenceFrame);
var transform = options.endTransform;
if (defined(transform)) {
scene.camera.setTransform(transform);
}

var frustum = frameState.camera.frustum;
Expand Down Expand Up @@ -559,20 +535,6 @@ define([
};
};

/**
* Creates an animation to fly the camera from it's current position to a position in which the entire rectangle will be visible. All arguments should
* be given in world coordinates.
*
* @param {Scene} scene The scene instance to use.
* @param {Rectangle} options.destination The final position of the camera.
* @param {Number} [options.duration=3000] The duration of the animation in milliseconds.
* @param {Function} [onComplete] The function to execute when the animation has completed.
* @param {Function} [onCancel] The function to execute if the animation is cancelled.
* @param {Matrix4} [endReferenceFrame] The reference frame the camera will be in when the flight is completed.
* @returns {Object} An Object that can be added to an {@link AnimationCollection} for animation.
*
* @see Scene#animations
*/
CameraFlightPath.createAnimationRectangle = function(scene, options) {
options = defaultValue(options, defaultValue.EMPTY_OBJECT);
var rectangle = options.destination;
Expand All @@ -581,9 +543,6 @@ define([
if (!defined(scene)) {
throw new DeveloperError('scene is required.');
}
if (!defined(scene.frameState)) {
throw new DeveloperError('frameState is required.');
}
if (!defined(rectangle)) {
throw new DeveloperError('options.destination is required.');
}
Expand Down
Loading

0 comments on commit bfcf803

Please sign in to comment.