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);
26 view::inertial_camera::inertial_camera(maps_view_h view)
28 , target_zoom_factor(.0)
29 , target_rotation_angle(.0)
32 , cur_rotation_angle(.0)
38 view::inertial_camera::inertial_camera(const inertial_camera &src)
40 , target_zoom_factor(.0)
41 , target_rotation_angle(.0)
44 , cur_rotation_angle(.0)
50 view::inertial_camera &view::inertial_camera::operator=(const inertial_camera
56 view::inertial_camera::~inertial_camera()
58 maps_coordinates_destroy(target_center);
59 maps_coordinates_destroy(cur_center);
62 void view::inertial_camera::set_cur_state()
68 maps_coordinates_destroy(cur_center);
69 maps_view_get_center(_view, &cur_center);
70 maps_view_get_zoom_factor(_view, &cur_zoom_factor);
71 maps_view_get_orientation(_view, &cur_rotation_angle);
74 void view::inertial_camera::set_targets(const maps_coordinates_h center,
75 const double &zoom_factor,
76 const double &rotation_angle)
81 /* Store the targets */
83 maps_coordinates_clone(center, &target_center);
85 _maps_coordinates_copy(center, target_center);
88 target_zoom_factor = zoom_factor;
89 target_rotation_angle = rotation_angle;
91 /* Store current state */
95 /* Start transition */
99 void view::inertial_camera::set_center_target(const maps_coordinates_h center)
104 /* Store the target */
105 if (!target_center) {
106 maps_coordinates_clone(center, &target_center);
108 _maps_coordinates_copy(center, target_center);
111 /* Store current state */
115 /* Start transition */
119 void view::inertial_camera::set_zoom_target(const double &zoom_factor)
124 /* Store the target */
125 target_zoom_factor = zoom_factor;
127 /* Store current state */
131 /* Start transition */
135 void view::inertial_camera::set_rotation_target(const double &rotation_angle)
140 /* Store the target */
141 target_rotation_angle = rotation_angle;
143 /* Store current state */
147 /* Start transition */
151 double view::inertial_camera::calc_next_step(const double &start,
152 const double &finish,
153 const double step_ratio) const
158 /* Expanential transition */
159 double step = (finish - start) * step_ratio;
160 double new_pos = start + step;
161 if (finish > start) {
162 new_pos = MAX(new_pos, start);
163 new_pos = MIN(new_pos, finish);
165 new_pos = MIN(new_pos, start);
166 new_pos = MAX(new_pos, finish);
171 double view::inertial_camera::calc_next_step_lon(const double &start,
172 const double &finish,
173 const double step_ratio) const
180 if (_f < 0) _f += 360;
181 if (_s < 0) _s += 360;
183 double gap, gap1, gap2;
186 gap2 = (360 - _f) + _s;
193 gap2 = (360 - _s) + _f;
200 double step = gap * step_ratio;
201 double new_pos = start + step;
204 else if (new_pos < -180)
210 bool view::inertial_camera::next_transition_step()
217 double prev_lat = .0;
218 double prev_lon = .0;
219 double target_lat = .0;
220 double target_lon = .0;
221 maps_coordinates_get_latitude_longitude(cur_center, &prev_lat, &prev_lon);
222 maps_coordinates_get_latitude_longitude(target_center, &target_lat, &target_lon);
224 /* Transiting map center */
225 double next_lat = calc_next_step(prev_lat, target_lat, .15);
226 if (next_lat != prev_lat) transiting = true;
228 double next_lon = calc_next_step_lon(prev_lon, target_lon, .15);
229 if (next_lon != prev_lon) transiting = true;
234 maps_coordinates_s next_center_s = { next_lat, next_lon };
235 maps_view_geolocation_to_screen(_view, &next_center_s, &nx, &ny);
236 maps_view_geolocation_to_screen(_view, target_center, &tx, &ty);
237 if (nx == tx && ny == ty) {
239 next_lat = target_lat;
240 next_lon = target_lon;
244 maps_coordinates_set_latitude_longitude(cur_center, next_lat, next_lon);
246 /* Transiting zoom */
247 cur_zoom_factor = calc_next_step(cur_zoom_factor, target_zoom_factor, .2);
248 if (ABS(cur_zoom_factor - target_zoom_factor) > __ZOOM_ACCURACY)
251 cur_zoom_factor = target_zoom_factor;
253 /* Transizint orientation */
254 if (target_rotation_angle - cur_rotation_angle > 180.)
255 target_rotation_angle -= 360.;
256 else if (target_rotation_angle - cur_rotation_angle < -180.)
257 target_rotation_angle += 360.;
259 cur_rotation_angle = calc_next_step(cur_rotation_angle, target_rotation_angle, .5);
260 if (ABS(cur_rotation_angle - target_rotation_angle) > __ROTATE_ACCURACY)
263 cur_rotation_angle = target_rotation_angle;