1 /* Copyright (c) 2010-2014 Samsung Electronics Co., Ltd. All rights reserved.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include "inertial_camera.h"
19 #include "maps_util.h"
20 #include "maps_view_plugin.h"
23 int _maps_coordinates_copy(maps_coordinates_h orig, maps_coordinates_h dest);
25 view::inertial_camera::inertial_camera(maps_view_h view)
27 , target_zoom_factor(.0)
28 , target_rotation_angle(.0)
31 , cur_rotation_angle(.0)
37 view::inertial_camera::inertial_camera(const inertial_camera &src)
39 , target_zoom_factor(.0)
40 , target_rotation_angle(.0)
43 , cur_rotation_angle(.0)
49 view::inertial_camera &view::inertial_camera::operator=(const inertial_camera
55 view::inertial_camera::~inertial_camera()
57 maps_coordinates_destroy(target_center);
58 maps_coordinates_destroy(cur_center);
61 void view::inertial_camera::set_cur_state()
67 maps_coordinates_destroy(cur_center);
68 maps_view_get_center(_view, &cur_center);
69 maps_view_get_zoom_factor(_view, &cur_zoom_factor);
70 maps_view_get_orientation(_view, &cur_rotation_angle);
73 void view::inertial_camera::set_targets(const maps_coordinates_h center,
74 const double &zoom_factor,
75 const double &rotation_angle)
80 /* Store the targets */
82 maps_coordinates_clone(center, &target_center);
84 _maps_coordinates_copy(center, target_center);
87 target_zoom_factor = zoom_factor;
88 target_rotation_angle = rotation_angle;
90 /* Store current state */
94 /* Start transition */
98 void view::inertial_camera::set_center_target(const maps_coordinates_h center)
103 /* Store the target */
104 if (!target_center) {
105 maps_coordinates_clone(center, &target_center);
107 _maps_coordinates_copy(center, target_center);
110 /* Store current state */
114 /* Start transition */
118 void view::inertial_camera::set_zoom_target(const double &zoom_factor)
123 /* Store the target */
124 target_zoom_factor = zoom_factor;
126 /* Store current state */
130 /* Start transition */
134 void view::inertial_camera::set_rotation_target(const double &rotation_angle)
139 /* Store the target */
140 target_rotation_angle = rotation_angle;
142 /* Store current state */
146 /* Start transition */
150 double view::inertial_camera::calc_next_step(const double &start,
151 const double &finish,
152 const double step_ratio) const
157 /* Expanential transition */
158 double step = (finish - start) * step_ratio;
159 double new_pos = start + step;
160 if (finish > start) {
161 new_pos = MAX(new_pos, start);
162 new_pos = MIN(new_pos, finish);
164 new_pos = MIN(new_pos, start);
165 new_pos = MAX(new_pos, finish);
170 double view::inertial_camera::calc_next_step_lon(const double &start,
171 const double &finish,
172 const double step_ratio) const
179 if (_f < 0) _f += 360;
180 if (_s < 0) _s += 360;
182 double gap, gap1, gap2;
185 gap2 = (360 - _f) + _s;
192 gap2 = (360 - _s) + _f;
199 double step = gap * step_ratio;
200 double new_pos = start + step;
203 else if (new_pos < -180)
209 bool view::inertial_camera::next_transition_step()
216 double prev_lat = .0;
217 double prev_lon = .0;
218 double target_lat = .0;
219 double target_lon = .0;
220 maps_coordinates_get_latitude_longitude(cur_center, &prev_lat, &prev_lon);
221 maps_coordinates_get_latitude_longitude(target_center, &target_lat, &target_lon);
223 /* Transiting map center */
224 double next_lat = calc_next_step(prev_lat, target_lat, .15);
225 if (next_lat != prev_lat) transiting = true;
227 double next_lon = calc_next_step_lon(prev_lon, target_lon, .15);
228 if (next_lon != prev_lon) transiting = true;
233 maps_coordinates_s next_center_s = { next_lat, next_lon };
234 maps_view_geolocation_to_screen(_view, &next_center_s, &nx, &ny);
235 maps_view_geolocation_to_screen(_view, target_center, &tx, &ty);
236 if (nx == tx && ny == ty) {
238 next_lat = target_lat;
239 next_lon = target_lon;
243 maps_coordinates_set_latitude_longitude(cur_center, next_lat, next_lon);
245 /* Transiting zoom */
246 cur_zoom_factor = calc_next_step(cur_zoom_factor, target_zoom_factor, .2);
247 if (ABS(cur_zoom_factor - target_zoom_factor) > __ZOOM_ACCURACY)
250 cur_zoom_factor = target_zoom_factor;
252 /* Transizint orientation */
253 if (target_rotation_angle - cur_rotation_angle > 180.)
254 target_rotation_angle -= 360.;
255 else if (target_rotation_angle - cur_rotation_angle < -180.)
256 target_rotation_angle += 360.;
258 cur_rotation_angle = calc_next_step(cur_rotation_angle, target_rotation_angle, .5);
259 if (ABS(cur_rotation_angle - target_rotation_angle) > __ROTATE_ACCURACY)
262 cur_rotation_angle = target_rotation_angle;