Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

[core] easeTo: linear interpolation over zoom instead of scale #15281

Merged
merged 3 commits into from
Aug 8, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions platform/android/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Mapbox welcomes participation and contributions from everyone. If you'd like to
### Bug fixes
- Fixed an issue where it was possible to set the map’s content insets then tilt the map enough to see the horizon, causing performance issues [#15195](https://github.com/mapbox/mapbox-gl-native/pull/15195)
- Allow loading of a map without a Style URI or Style JSON [#15293](https://github.com/mapbox/mapbox-gl-native/pull/15293)
- Fixed an issue where animated camera transitions zoomed in or out too dramatically [#15281](https://github.com/mapbox/mapbox-gl-native/pull/15281)

## 8.3.0-alpha.2 - August 7, 2019
[Changes](https://github.com/mapbox/mapbox-gl-native/compare/android-v8.3.0-alpha.1...android-v8.3.0-alpha.2) since [Mapbox Maps SDK for Android v8.3.0-alpha.1](https://github.com/mapbox/mapbox-gl-native/releases/tag/android-v8.3.0-alpha.1):
Expand Down
6 changes: 6 additions & 0 deletions platform/ios/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

Mapbox welcomes participation and contributions from everyone. Please read [CONTRIBUTING.md](../../CONTRIBUTING.md) to get started.

## master

### Styles and rendering

* Fixed an issue where animated camera transitions zoomed in or out too dramatically. ([#15281](https://github.com/mapbox/mapbox-gl-native/pull/15281))

## 5.3.0

### Styles and rendering
Expand Down
1 change: 1 addition & 0 deletions platform/macos/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
* Performance improvements for queryRenderedFeatures API and optimization that allocates containers based on a number of rendered layers. ([#14930](https://github.com/mapbox/mapbox-gl-native/pull/14930))
* Fixed rendering layers after fill-extrusion regression caused by optimization of fill-extrusion rendering. ([#15065](https://github.com/mapbox/mapbox-gl-native/pull/15065))
* `MGLLoggingLevel` has been updated for better matching core log levels. Now can use `[MGLLoggingConfiguration sharedConfiguration].loggingLevel` to filter logs from core . [#15120](https://github.com/mapbox/mapbox-gl-native/pull/15120)
* Fixed an issue where animated camera transitions zoomed in or out too dramatically. [#15281](https://github.com/mapbox/mapbox-gl-native/pull/15281)

### Styles and rendering

Expand Down
45 changes: 24 additions & 21 deletions src/mbgl/map/transform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.value_or(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);
Expand Down Expand Up @@ -112,28 +117,25 @@ void Transform::easeTo(const CameraOptions& camera, const AnimationOptions& anim

// Constrain camera options.
zoom = util::clamp(zoom, state.getMinZoom(), state.getMaxZoom());
const double scale = state.zoomScale(zoom);
pitch = util::clamp(pitch, util::PITCH_MIN, util::PITCH_MAX);

// Minimize rotation by taking the shorter path around the circle.
bearing = _normalizeAngle(bearing, state.bearing);
state.bearing = _normalizeAngle(state.bearing, bearing);

Duration duration = animation.duration ? *animation.duration : Duration::zero();

const double startScale = state.scale;
const double startZoom = state.getZoom();
const double startBearing = state.bearing;
const double startPitch = state.pitch;
state.panning = unwrappedLatLng != startLatLng;
state.scaling = scale != startScale;
state.scaling = zoom != startZoom;
state.rotating = bearing != startBearing;
const EdgeInsets startEdgeInsets = state.edgeInsets;

startTransition(camera, animation, [=](double t) {
Point<double> framePoint = util::interpolate(startPoint, endPoint, t);
LatLng frameLatLng = Projection::unproject(framePoint, startScale);
double frameScale = util::interpolate(startScale, scale, t);
state.setLatLngZoom(frameLatLng, state.scaleZoom(frameScale));
LatLng frameLatLng = Projection::unproject(framePoint, state.zoomScale(startZoom));
double frameZoom = util::interpolate(startZoom, zoom, t);
state.setLatLngZoom(frameLatLng, frameZoom);

if (bearing != startBearing) {
state.bearing = util::wrap(util::interpolate(startBearing, bearing, t), -M_PI, M_PI);
Expand Down Expand Up @@ -162,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());
Expand Down Expand Up @@ -209,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;
Expand All @@ -233,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);
Expand Down Expand Up @@ -289,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)) {
Expand All @@ -306,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);
Expand Down
10 changes: 7 additions & 3 deletions src/mbgl/map/transform.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,16 @@ class Transform : private util::noncopyable {
/** Instantaneously, synchronously applies the given camera options. */
void jumpTo(const CameraOptions&);
/** Asynchronously transitions all specified camera options linearly along
an optional time curve. */
an optional time curve. However, center coordinate is not transitioned
linearly as, instead, ground speed is kept linear.*/
void easeTo(const CameraOptions&, const AnimationOptions& = {});
/** Asynchronously zooms out, pans, and zooms back into the given camera
along a great circle, as though the viewer is riding a supersonic
jetcopter. */
void flyTo(const CameraOptions&, const AnimationOptions& = {});
jetcopter.
Parameter linearZoomInterpolation: when true, there is no additional
zooming out as zoom is linearly interpolated from current to given
camera zoom. This is used for easeTo.*/
void flyTo(const CameraOptions&, const AnimationOptions& = {}, bool linearZoomInterpolation = false);

// Position

Expand Down