summaryrefslogtreecommitdiff
path: root/src/mbgl/map/transform.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/map/transform.cpp')
-rw-r--r--src/mbgl/map/transform.cpp34
1 files changed, 19 insertions, 15 deletions
diff --git a/src/mbgl/map/transform.cpp b/src/mbgl/map/transform.cpp
index 4004b29431..462d2462fb 100644
--- a/src/mbgl/map/transform.cpp
+++ b/src/mbgl/map/transform.cpp
@@ -82,6 +82,11 @@ void Transform::jumpTo(const CameraOptions& camera) {
* values for any options not included in `options`.
*/
void Transform::easeTo(const CameraOptions& camera, const AnimationOptions& animation) {
+ Duration duration = animation.duration ? *animation.duration : Duration::zero();
+ if (state.bounds == LatLngBounds::unbounded() && !isGestureInProgress() && duration != Duration::zero()) {
+ // reuse flyTo, without exaggerated animation, to achieve constant ground speed.
+ return flyTo(camera, animation, true);
+ }
const EdgeInsets& padding = camera.padding.value_or(state.edgeInsets);
LatLng startLatLng = getLatLng(LatLng::Unwrapped);
const LatLng& unwrappedLatLng = camera.center.value_or(startLatLng);
@@ -118,8 +123,6 @@ void Transform::easeTo(const CameraOptions& camera, const AnimationOptions& anim
bearing = _normalizeAngle(bearing, state.bearing);
state.bearing = _normalizeAngle(state.bearing, bearing);
- Duration duration = animation.duration ? *animation.duration : Duration::zero();
-
const double startZoom = state.getZoom();
const double startBearing = state.bearing;
const double startPitch = state.pitch;
@@ -161,7 +164,7 @@ void Transform::easeTo(const CameraOptions& camera, const AnimationOptions& anim
Where applicable, local variable documentation begins with the associated
variable or function in van Wijk (2003). */
-void Transform::flyTo(const CameraOptions &camera, const AnimationOptions &animation) {
+void Transform::flyTo(const CameraOptions &camera, const AnimationOptions &animation, bool linearZoomInterpolation) {
const EdgeInsets& padding = camera.padding.value_or(state.edgeInsets);
const LatLng& latLng = camera.center.value_or(getLatLng(LatLng::Unwrapped)).wrapped();
double zoom = camera.zoom.value_or(getZoom());
@@ -208,16 +211,16 @@ void Transform::flyTo(const CameraOptions &camera, const AnimationOptions &anima
1.42 is the average value selected by participants in the user study in
van Wijk (2003). A value of 6<sup>¼</sup> would be equivalent to the
- root mean squared average velocity, V<sub>RMS</sub>. A value of 1 would
- produce a circular motion. */
+ root mean squared average velocity, V<sub>RMS</sub>. A value of 1
+ produces a circular motion. */
double rho = 1.42;
- if (animation.minZoom) {
- double minZoom = util::min(*animation.minZoom, startZoom, zoom);
+ if (animation.minZoom || linearZoomInterpolation) {
+ double minZoom = util::min(animation.minZoom.value_or(startZoom), startZoom, zoom);
minZoom = util::clamp(minZoom, state.getMinZoom(), state.getMaxZoom());
/// w<sub>m</sub>: Maximum visible span, measured in pixels with respect
/// to the initial scale.
double wMax = w0 / state.zoomScale(minZoom - startZoom);
- rho = std::sqrt(wMax / u1 * 2);
+ rho = u1 != 0 ? std::sqrt(wMax / u1 * 2) : 1.0;
}
/// ρ²
double rho2 = rho * rho;
@@ -232,8 +235,8 @@ void Transform::flyTo(const CameraOptions &camera, const AnimationOptions &anima
};
/// r₀: Zoom-out factor during ascent.
- double r0 = r(0);
- double r1 = r(1);
+ double r0 = u1 != 0 ? r(0) : INFINITY; // Silence division by 0 on sanitize bot.
+ double r1 = u1 != 0 ? r(1) : INFINITY;
// When u₀ = u₁, the optimal path doesn’t require both ascent and descent.
bool isClose = std::abs(u1) < 0.000001 || !std::isfinite(r0) || !std::isfinite(r1);
@@ -288,7 +291,8 @@ void Transform::flyTo(const CameraOptions &camera, const AnimationOptions &anima
// Calculate the current point and zoom level along the flight path.
Point<double> framePoint = util::interpolate(startPoint, endPoint, us);
- double frameZoom = startZoom + state.scaleZoom(1 / w(s));
+ double frameZoom = linearZoomInterpolation ? util::interpolate(startZoom, zoom, k)
+ : startZoom + state.scaleZoom(1 / w(s));
// Zoom can be NaN if size is empty.
if (std::isnan(frameZoom)) {
@@ -305,10 +309,10 @@ void Transform::flyTo(const CameraOptions &camera, const AnimationOptions &anima
if (padding != startEdgeInsets) {
// Interpolate edge insets
state.edgeInsets = {
- util::interpolate(startEdgeInsets.top(), padding.top(), us),
- util::interpolate(startEdgeInsets.left(), padding.left(), us),
- util::interpolate(startEdgeInsets.bottom(), padding.bottom(), us),
- util::interpolate(startEdgeInsets.right(), padding.right(), us)
+ util::interpolate(startEdgeInsets.top(), padding.top(), k),
+ util::interpolate(startEdgeInsets.left(), padding.left(), k),
+ util::interpolate(startEdgeInsets.bottom(), padding.bottom(), k),
+ util::interpolate(startEdgeInsets.right(), padding.right(), k)
};
}
auto maxPitch = getMaxPitchForEdgeInsets(state.edgeInsets);