summaryrefslogtreecommitdiff
path: root/src/mbgl
diff options
context:
space:
mode:
authorMinh Nguyễn <mxn@1ec5.org>2015-12-14 23:11:37 -0800
committerMinh Nguyễn <mxn@1ec5.org>2015-12-15 12:52:13 -0800
commite1854f0f2628e4808b48e01231c1a3a3a6cf9b68 (patch)
treedde998bc54115ec14fa2c905f4a3be0d1df1b854 /src/mbgl
parentb75c6edbf75f6bb11f23e0d1330efee3ed3ff880 (diff)
downloadqtlocation-mapboxgl-e1854f0f2628e4808b48e01231c1a3a3a6cf9b68.tar.gz
[core] Corrected flying trajectory; pitched flight
Corrected some fairly opaque code that was incorrectly ported from GL JS the first time around in #3171, causing the trajectory to extend far into the Earth’s orbit. Also transition pitch while flying, call transition frame/finish callback functions, and recognize the same “speed” and “curve” parameters that GL JS does. Fixes #3296, fixes #3297.
Diffstat (limited to 'src/mbgl')
-rw-r--r--src/mbgl/map/transform.cpp102
-rw-r--r--src/mbgl/map/transform_state.cpp4
-rw-r--r--src/mbgl/map/transform_state.hpp1
3 files changed, 66 insertions, 41 deletions
diff --git a/src/mbgl/map/transform.cpp b/src/mbgl/map/transform.cpp
index 4604fbb287..d08972d53f 100644
--- a/src/mbgl/map/transform.cpp
+++ b/src/mbgl/map/transform.cpp
@@ -319,6 +319,7 @@ void Transform::flyTo(const CameraOptions &options) {
LatLng startLatLng = getLatLng();
double zoom = flyOptions.zoom ? *flyOptions.zoom : getZoom();
double angle = flyOptions.angle ? *flyOptions.angle : getAngle();
+ double pitch = flyOptions.pitch ? *flyOptions.pitch : getPitch();
if (std::isnan(latLng.latitude) || std::isnan(latLng.longitude) || std::isnan(zoom)) {
return;
}
@@ -337,13 +338,14 @@ void Transform::flyTo(const CameraOptions &options) {
view.notifyMapChange(MapChangeRegionWillChangeAnimated);
- const double startS = state.scale;
+ const double startZ = state.scaleZoom(state.scale);
const double startA = state.angle;
+ const double startP = state.pitch;
state.panning = true;
state.scaling = true;
state.rotating = true;
- const double rho = 1.42;
+ double rho = flyOptions.curve ? *flyOptions.curve : 1.42;
double w0 = std::max(state.width, state.height);
double w1 = w0 / new_scale;
double u1 = ::hypot(xn, yn);
@@ -371,47 +373,65 @@ void Transform::flyTo(const CameraOptions &options) {
double S = (is_close ? (std::abs(std::log(w1 / w0)) / rho)
: ((r(1) - r0) / rho));
- if (!flyOptions.duration) {
- flyOptions.duration = Duration::zero();
+ Duration duration = flyOptions.duration ? *flyOptions.duration : Duration::zero();
+ if (flyOptions.duration) {
+ duration = *flyOptions.duration;
+ } else {
+ double speed = flyOptions.speed ? *flyOptions.speed : 1.2;
+ duration = std::chrono::duration_cast<std::chrono::steady_clock::duration>(
+ std::chrono::duration<double, std::chrono::seconds::period>(S / speed));
}
startTransition(
- [=](double t) {
- util::UnitBezier ease = flyOptions.easing ? *flyOptions.easing : util::UnitBezier(0, 0, 0.25, 1);
- return ease.solve(t, 0.001);
- },
- [=](double k) {
- double s = k * S;
- double us = u(s);
-
- //First calculate the desired latlng
- double desiredLat = startLatLng.latitude + (latLng.latitude - startLatLng.latitude) * us;
- double desiredLng = startLatLng.longitude + (latLng.longitude - startLatLng.longitude) * us;
-
- //Now calculate desired zoom
- state.scale = startS - w(s);
-
- //Now set values
- const double new_scaled_tile_size = state.scale * util::tileSize;
- state.Bc = new_scaled_tile_size / 360;
- state.Cc = new_scaled_tile_size / util::M2PI;
-
- const double f2 = ::fmin(::fmax(std::sin(util::DEG2RAD * desiredLat), -m), m);
- state.x = -desiredLng * state.Bc;
- state.y = 0.5 * state.Cc * std::log((1 + f2) / (1 - f2));
-
- if (angle != startA) {
- state.angle = util::wrap(util::interpolate(startA, angle, k), -M_PI, M_PI);
- }
-
- view.notifyMapChange(MapChangeRegionIsChanging);
- return Update::Zoom;
- },
- [=] {
- state.panning = false;
- state.scaling = false;
- state.rotating = false;
- view.notifyMapChange(MapChangeRegionDidChangeAnimated);
- }, *flyOptions.duration);
+ [=](double t) {
+ util::UnitBezier ease = flyOptions.easing ? *flyOptions.easing : util::UnitBezier(0, 0, 0.25, 1);
+ return ease.solve(t, 0.001);
+ },
+ [=](double k) {
+ double s = k * S;
+ double us = u(s);
+
+ //First calculate the desired latlng
+ double desiredLat = startLatLng.latitude + (latLng.latitude - startLatLng.latitude) * us;
+ double desiredLng = startLatLng.longitude + (latLng.longitude - startLatLng.longitude) * us;
+
+ //Now calculate desired zoom
+ double desiredZoom = startZ + state.scaleZoom(1 / w(s));
+ double desiredScale = state.zoomScale(desiredZoom);
+ state.scale = ::fmax(::fmin(desiredScale, state.max_scale), state.min_scale);
+
+ //Now set values
+ const double new_scaled_tile_size = state.scale * util::tileSize;
+ state.Bc = new_scaled_tile_size / 360;
+ state.Cc = new_scaled_tile_size / util::M2PI;
+
+ const double f2 = ::fmin(::fmax(std::sin(util::DEG2RAD * desiredLat), -m), m);
+ state.x = -desiredLng * state.Bc;
+ state.y = 0.5 * state.Cc * std::log((1 + f2) / (1 - f2));
+
+ if (angle != startA) {
+ state.angle = util::wrap(util::interpolate(startA, angle, k), -M_PI, M_PI);
+ }
+ if (pitch != startP) {
+ state.pitch = util::clamp(util::interpolate(startP, pitch, k), 0., 60.);
+ }
+ // At k = 1.0, a DidChangeAnimated notification should be sent from finish().
+ if (k < 1.0) {
+ if (options.transitionFrameFn) {
+ options.transitionFrameFn(k);
+ }
+ view.notifyMapChange(MapChangeRegionIsChanging);
+ }
+ return Update::Zoom;
+ },
+ [=] {
+ state.panning = false;
+ state.scaling = false;
+ state.rotating = false;
+ if (options.transitionFinishFn) {
+ options.transitionFinishFn();
+ }
+ view.notifyMapChange(MapChangeRegionDidChangeAnimated);
+ }, duration);
};
#pragma mark - Angle
diff --git a/src/mbgl/map/transform_state.cpp b/src/mbgl/map/transform_state.cpp
index 7153c2524b..a96f182534 100644
--- a/src/mbgl/map/transform_state.cpp
+++ b/src/mbgl/map/transform_state.cpp
@@ -243,6 +243,10 @@ double TransformState::zoomScale(double zoom) const {
return std::pow(2.0f, zoom);
}
+double TransformState::scaleZoom(double s) const {
+ return std::log2(s);
+}
+
float TransformState::worldSize() const {
return util::tileSize * scale;
}
diff --git a/src/mbgl/map/transform_state.hpp b/src/mbgl/map/transform_state.hpp
index fd9a556eb9..fa6ed8b58b 100644
--- a/src/mbgl/map/transform_state.hpp
+++ b/src/mbgl/map/transform_state.hpp
@@ -95,6 +95,7 @@ private:
double lngX(double lon) const;
double latY(double lat) const;
double zoomScale(double zoom) const;
+ double scaleZoom(double scale) const;
float worldSize() const;
mat4 coordinatePointMatrix(double z) const;