summaryrefslogtreecommitdiff
path: root/src/mbgl/map/transform.cpp
diff options
context:
space:
mode:
authorAleksandar Stojiljkovic <aleksandar.stojiljkovic@mapbox.com>2019-07-23 17:19:52 +0300
committerAleksandar Stojiljkovic <aleksandar.stojiljkovic@mapbox.com>2019-07-24 17:52:43 +0300
commit5955610356cf405b7cb698a899b05f305021d41e (patch)
tree5835d61a2676307c1b24f7a9775071ab6891766b /src/mbgl/map/transform.cpp
parent1aa4776dc1d7e60989fa7524a816e7db1b92056b (diff)
downloadqtlocation-mapboxgl-5955610356cf405b7cb698a899b05f305021d41e.tar.gz
[core] Limit pitch based on edge insets. Fix max Z calculation in getProjMatrix.
Patch partly fixes #15163 in a way that it doesn't allow loading tens of thousands of tiles and attempt to show area above horizon: Limit pitch based on edge insets. It is not too bad - current limit of 60 degrees stays active until center of perspective is moved towards the bottom, to 84% of screen height. The plan is to split removal of 60 degrees limit to follow up patch. Fix max Z calculation in getProjMatrix. TransformState::getProjMatrix calculation of farZ was complex with possibility to lead to negative z values. Replacing it with simpler, precise calculation: furthestDistance = cameraToCenterDistance / (1 - tanFovAboveCenter * std::tan(getPitch())); TransformState::getProjMatrix calculation of farZ was an aproximation. Replacing it with simpler, but precise calculation. Related to: #15163
Diffstat (limited to 'src/mbgl/map/transform.cpp')
-rw-r--r--src/mbgl/map/transform.cpp26
1 files changed, 20 insertions, 6 deletions
diff --git a/src/mbgl/map/transform.cpp b/src/mbgl/map/transform.cpp
index a51d4dd4ff..0651cfd284 100644
--- a/src/mbgl/map/transform.cpp
+++ b/src/mbgl/map/transform.cpp
@@ -138,9 +138,6 @@ void Transform::easeTo(const CameraOptions& camera, const AnimationOptions& anim
if (bearing != startBearing) {
state.bearing = util::wrap(util::interpolate(startBearing, bearing, t), -M_PI, M_PI);
}
- if (pitch != startPitch) {
- state.pitch = util::interpolate(startPitch, pitch, t);
- }
if (padding != startEdgeInsets) {
// Interpolate edge insets
state.edgeInsets = {
@@ -150,6 +147,10 @@ void Transform::easeTo(const CameraOptions& camera, const AnimationOptions& anim
util::interpolate(startEdgeInsets.right(), padding.right(), t)
};
}
+ auto maxPitch = getMaxPitchForEdgeInsets(state.edgeInsets);
+ if (pitch != startPitch || maxPitch < startPitch) {
+ state.pitch = std::min(maxPitch, util::interpolate(startPitch, pitch, t));
+ }
}, duration);
}
@@ -302,9 +303,6 @@ void Transform::flyTo(const CameraOptions &camera, const AnimationOptions &anima
if (bearing != startBearing) {
state.bearing = util::wrap(util::interpolate(startBearing, bearing, k), -M_PI, M_PI);
}
- if (pitch != startPitch) {
- state.pitch = util::interpolate(startPitch, pitch, k);
- }
if (padding != startEdgeInsets) {
// Interpolate edge insets
state.edgeInsets = {
@@ -314,6 +312,10 @@ void Transform::flyTo(const CameraOptions &camera, const AnimationOptions &anima
util::interpolate(startEdgeInsets.right(), padding.right(), us)
};
}
+ auto maxPitch = getMaxPitchForEdgeInsets(state.edgeInsets);
+ if (pitch != startPitch || maxPitch < startPitch) {
+ state.pitch = std::min(maxPitch, util::interpolate(startPitch, pitch, k));
+ }
}, duration);
}
@@ -576,4 +578,16 @@ LatLng Transform::screenCoordinateToLatLng(const ScreenCoordinate& point, LatLng
return state.screenCoordinateToLatLng(flippedPoint, wrapMode);
}
+double Transform::getMaxPitchForEdgeInsets(const EdgeInsets &insets) const
+{
+ double centerOffsetY = 0.5 * (insets.top() - insets.bottom()); // See TransformState::getCenterOffset.
+
+ const auto height = state.size.height;
+ assert(height);
+ // See TransformState::fov description: fov = 2 * arctan((height / 2) / (height * 1.5)).
+ const double fovAboveCenter = std::atan((0.666666 + 0.02) * (0.5 + centerOffsetY / height));
+ return M_PI * 0.5 - fovAboveCenter; // 0.02 added ^^^^ to prevent parallel ground to viewport clipping plane.
+ // e.g. Maximum pitch of 60 degrees is when perspective center's offset from the top is 84% of screen height.
+}
+
} // namespace mbgl