diff options
author | Minh Nguyễn <mxn@1ec5.org> | 2015-12-14 23:11:37 -0800 |
---|---|---|
committer | Minh Nguyễn <mxn@1ec5.org> | 2015-12-15 12:52:13 -0800 |
commit | e1854f0f2628e4808b48e01231c1a3a3a6cf9b68 (patch) | |
tree | dde998bc54115ec14fa2c905f4a3be0d1df1b854 /src/mbgl | |
parent | b75c6edbf75f6bb11f23e0d1330efee3ed3ff880 (diff) | |
download | qtlocation-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.cpp | 102 | ||||
-rw-r--r-- | src/mbgl/map/transform_state.cpp | 4 | ||||
-rw-r--r-- | src/mbgl/map/transform_state.hpp | 1 |
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; |