1 /**
2 * Flies the camera from its current position to a new position.
3 *
4 * @param {Object} options Object with the following properties:
5 * @param {Cartesian3|Rectangle} options.destination The final position of the camera in WGS84 (world) coordinates or a rectangle that would be visible from a top-down view.
6 * @param {Object} [options.orientation] An object that contains either direction and up properties or heading, pitch and roll properties. By default, the direction will point
7 * towards the center of the frame in 3D and in the negative z direction in Columbus view. The up direction will point towards local north in 3D and in the positive
8 * y direction in Columbus view. Orientation is not used in 2D when in infinite scrolling mode.
9 * @param {Number} [options.duration] The duration of the flight in seconds. If omitted, Cesium attempts to calculate an ideal duration based on the distance to be traveled by the flight.
10 * @param {Camera.FlightCompleteCallback} [options.complete] The function to execute when the flight is complete.
11 * @param {Camera.FlightCancelledCallback} [options.cancel] The function to execute if the flight is cancelled.
12 * @param {Matrix4} [options.endTransform] Transform matrix representing the reference frame the camera will be in when the flight is completed.
13 * @param {Number} [options.maximumHeight] The maximum height at the peak of the flight.
14 * @param {Number} [options.pitchAdjustHeight] If camera flyes higher than that value, adjust pitch duiring the flight to look down, and keep Earth in viewport.
15 * @param {Number} [options.flyOverLongitude] There are always two ways between 2 points on globe. This option force camera to choose fight direction to fly over that longitude.
16 * @param {Number} [options.flyOverLongitudeWeight] Fly over the lon specifyed via flyOverLongitude only if that way is not longer than short way times flyOverLongitudeWeight.
17 * @param {Boolean} [options.convert] Whether to convert the destination from world coordinates to scene coordinates (only relevant when not using 3D). Defaults to <code>true</code>.
18 * @param {EasingFunction.Callback} [options.easingFunction] Controls how the time is interpolated over the duration of the flight.
19 *
20 * @exception {DeveloperError} If either direction or up is given, then both are required.
21 *
22 * @example
23 * // 1. Fly to a position with a top-down view
24 * viewer.camera.flyTo({
25 * destination : Cesium.Cartesian3.fromDegrees(-117.16, 32.71, 15000.0)
26 * });
27 *
28 * // 2. Fly to a Rectangle with a top-down view
29 * viewer.camera.flyTo({
30 * destination : Cesium.Rectangle.fromDegrees(west, south, east, north)
31 * });
32 *
33 * // 3. Fly to a position with an orientation using unit vectors.
34 * viewer.camera.flyTo({
35 * destination : Cesium.Cartesian3.fromDegrees(-122.19, 46.25, 5000.0),
36 * orientation : {
37 * direction : new Cesium.Cartesian3(-0.04231243104240401, -0.20123236049443421, -0.97862924300734),
38 * up : new Cesium.Cartesian3(-0.47934589305293746, -0.8553216253114552, 0.1966022179118339)
39 * }
40 * });
41 *
42 * // 4. Fly to a position with an orientation using heading, pitch and roll.
43 * viewer.camera.flyTo({
44 * destination : Cesium.Cartesian3.fromDegrees(-122.19, 46.25, 5000.0),
45 * orientation : {
46 * heading : Cesium.Math.toRadians(175.0),
47 * pitch : Cesium.Math.toRadians(-35.0),
48 * roll : 0.0
49 * }
50 * });
51 */
52 Camera.prototype.flyTo = function (options) {
53 options = defaultValue(options, defaultValue.EMPTY_OBJECT);
54 var destination = options.destination;
55 //>>includeStart('debug', pragmas.debug);
56
57 //如果没设置目的地报错
58 if (!defined(destination)) {
59 throw new DeveloperError("destination is required.");
60 }
61 //>>includeEnd('debug');
62
63 var mode = this._mode;
64
65 //如果当前scene正在变化中
66 if (mode === SceneMode.MORPHING) {
67 return;
68 }
69
70 this.cancelFlight();
71
72 var orientation = defaultValue(
73 options.orientation,
74 defaultValue.EMPTY_OBJECT
75 );
76
77 //如果定义了方向,则将方向转换为HeadingPitchRoll这种格式
78 if (defined(orientation.direction)) {
79 orientation = directionUpToHeadingPitchRoll(
80 this,
81 destination,
82 orientation,
83 scratchSetViewOptions.orientation
84 );
85 }
86
87 //如果设置的持续时间小于0,则用setView方法直接改变view,也就是0秒、没动画
88 if (defined(options.duration) && options.duration <= 0.0) {
89 var setViewOptions = scratchSetViewOptions;
90 setViewOptions.destination = options.destination;
91 setViewOptions.orientation.heading = orientation.heading;
92 setViewOptions.orientation.pitch = orientation.pitch;
93 setViewOptions.orientation.roll = orientation.roll;
94 setViewOptions.convert = options.convert;
95 setViewOptions.endTransform = options.endTransform;
96 this.setView(setViewOptions);
97
98 //如果原来的options里还说了在视角转到目的地之后要做什么,则现在setview之后做
99 if (typeof options.complete === "function") {
100 options.complete();
101 }
102 return;
103 }
104
105 //如果是通过设置需要看到的矩形区域的四个坐标
106 var isRectangle = defined(destination.west);
107 if (isRectangle) {
108 //通过矩形的位置计算返回camera的位置
109 destination = this.getRectangleCameraCoordinates(
110 destination,
111 scratchFlyToDestination
112 );
113 }
114
115 var that = this;
116 var flightTween;
117
118 newOptions.destination = destination;
119 newOptions.heading = orientation.heading;
120 newOptions.pitch = orientation.pitch;
121 newOptions.roll = orientation.roll;
122 newOptions.duration = options.duration;
123 newOptions.complete = function () {
124 if (flightTween === that._currentFlight) {
125 that._currentFlight = undefined;
126 }
127 if (defined(options.complete)) {
128 options.complete();
129 }
130 };
131 newOptions.cancel = options.cancel;
132 newOptions.endTransform = options.endTransform;
133 newOptions.convert = isRectangle ? false : options.convert;
134 newOptions.maximumHeight = options.maximumHeight;
135 newOptions.pitchAdjustHeight = options.pitchAdjustHeight;
136 newOptions.flyOverLongitude = options.flyOverLongitude;
137 newOptions.flyOverLongitudeWeight = options.flyOverLongitudeWeight;
138 newOptions.easingFunction = options.easingFunction;
139
140 var scene = this._scene;
141 var tweenOptions = CameraFlightPath.createTween(scene, newOptions);
142 // If the camera doesn't actually need to go anywhere, duration
143 // will be 0 and we can just complete the current flight.
144 if (tweenOptions.duration === 0) {
145 if (typeof tweenOptions.complete === "function") {
146 tweenOptions.complete();
147 }
148 return;
149 }
150 flightTween = scene.tweens.add(tweenOptions);
151 this._currentFlight = flightTween;
152
153 // Save the final destination view information for the PRELOAD_FLIGHT pass.
154 var preloadFlightCamera = this._scene.preloadFlightCamera;
155 if (this._mode !== SceneMode.SCENE2D) {
156 if (!defined(preloadFlightCamera)) {
157 preloadFlightCamera = Camera.clone(this);
158 }
159 preloadFlightCamera.setView({
160 destination: destination,
161 orientation: orientation,
162 });
163
164 this._scene.preloadFlightCullingVolume = preloadFlightCamera.frustum.computeCullingVolume(
165 preloadFlightCamera.positionWC,
166 preloadFlightCamera.directionWC,
167 preloadFlightCamera.upWC
168 );
169 }
170 };