summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAnsis Brammanis <brammanis@gmail.com>2016-12-14 15:17:01 -0800
committerJohn Firebaugh <john.firebaugh@gmail.com>2016-12-21 15:46:36 -0800
commit38b5cb0c7766152f7e49cce8bd6c5d3e04dd0663 (patch)
tree9f64568fbe56a17a0c1fcd5396bf6c9e80992843 /src
parentebd241363d5c926d471559208f391190666febb9 (diff)
downloadqtlocation-mapboxgl-38b5cb0c7766152f7e49cce8bd6c5d3e04dd0663.tar.gz
[core, ios] replace `altitude` with `fov`
ported from -js: eb6c6596c6a7a61363d30356674e0002153b1d19 `altitude` was a terribly-named variable that was used to indirectly control the fov. This should eliminate some confusion. `altitude` was equivalent to `cameraToCenterDistance / height`
Diffstat (limited to 'src')
-rw-r--r--src/mbgl/map/transform_state.cpp34
-rw-r--r--src/mbgl/map/transform_state.hpp9
-rw-r--r--src/mbgl/programs/line_program.cpp2
-rw-r--r--src/mbgl/programs/symbol_program.cpp6
-rw-r--r--src/mbgl/renderer/painter_circle.cpp4
-rw-r--r--src/mbgl/style/layers/custom_layer_impl.cpp2
6 files changed, 34 insertions, 23 deletions
diff --git a/src/mbgl/map/transform_state.cpp b/src/mbgl/map/transform_state.cpp
index 59ae129518..51ecf52e40 100644
--- a/src/mbgl/map/transform_state.cpp
+++ b/src/mbgl/map/transform_state.cpp
@@ -27,22 +27,24 @@ void TransformState::matrixFor(mat4& matrix, const UnwrappedTileID& tileID) cons
}
void TransformState::getProjMatrix(mat4& projMatrix) const {
- double halfFov = std::atan(0.5 / getAltitude());
- double topHalfSurfaceDistance = std::sin(halfFov) * getAltitude() /
- std::sin(M_PI / 2.0f - getPitch() - halfFov);
- // Calculate z value of the farthest fragment that should be rendered.
- double farZ = std::cos(M_PI / 2.0f - getPitch()) * topHalfSurfaceDistance + getAltitude();
- matrix::perspective(projMatrix, 2.0f * std::atan((size.height / 2.0f) / getAltitude()),
- double(size.width) / size.height, 0.1, farZ);
+ // Find the distance from the center point [width/2, height/2] to the
+ // center top point [width/2, 0] in Z units, using the law of sines.
+ // 1 Z unit is equivalent to 1 horizontal px at the center of the map
+ // (the distance between[width/2, height/2] and [width/2 + 1, height/2])
+ const double halfFov = getFieldOfView() / 2.0;
+ const double groundAngle = M_PI / 2.0 + getPitch();
+ const double topHalfSurfaceDistance = std::sin(halfFov) * getCameraToCenterDistance() / std::sin(M_PI - groundAngle - halfFov);
+
+ // Calculate z value of the farthest fragment that should be rendered.
+ const double farZ = std::cos(M_PI / 2.0 - getPitch()) * topHalfSurfaceDistance + getCameraToCenterDistance();
- matrix::translate(projMatrix, projMatrix, 0, 0, -getAltitude());
+ matrix::perspective(projMatrix, getFieldOfView(), double(size.width) / size.height, 0.1, farZ);
- // After the rotateX, z values are in pixel units. Convert them to
- // altitude unites. 1 altitude unit = the screen height.
const bool flippedY = viewportMode == ViewportMode::FlippedY;
- matrix::scale(projMatrix, projMatrix, 1, flippedY ? 1 : -1,
- 1.0f / (rotatedNorth() ? size.width : size.height));
+ matrix::scale(projMatrix, projMatrix, 1, flippedY ? 1 : -1, 1);
+
+ matrix::translate(projMatrix, projMatrix, 0, 0, -getCameraToCenterDistance());
using NO = NorthOrientation;
switch (getNorthOrientation()) {
@@ -164,8 +166,12 @@ float TransformState::getAngle() const {
return angle;
}
-float TransformState::getAltitude() const {
- return altitude;
+float TransformState::getFieldOfView() const {
+ return fov;
+}
+
+float TransformState::getCameraToCenterDistance() const {
+ return 0.5 * size.height / std::tan(fov / 2.0);
}
float TransformState::getPitch() const {
diff --git a/src/mbgl/map/transform_state.hpp b/src/mbgl/map/transform_state.hpp
index 6faaf4ac41..a35aa5a255 100644
--- a/src/mbgl/map/transform_state.hpp
+++ b/src/mbgl/map/transform_state.hpp
@@ -56,7 +56,8 @@ public:
// Rotation
float getAngle() const;
- float getAltitude() const;
+ float getFieldOfView() const;
+ float getCameraToCenterDistance() const;
float getPitch() const;
// State
@@ -109,7 +110,11 @@ private:
double x = 0, y = 0;
double angle = 0;
double scale = 1;
- double altitude = 1.5;
+ // This fov value is somewhat arbitrary. The altitude of the camera used
+ // to be defined as 1.5 screen heights above the ground, which was an
+ // arbitrary choice. This is the fov equivalent to that value calculated with:
+ // `fov = 2 * arctan((height / 2) / (height * 1.5))`
+ double fov = 0.6435011087932844;
double pitch = 0.0;
// cache values for spherical mercator math
diff --git a/src/mbgl/programs/line_program.cpp b/src/mbgl/programs/line_program.cpp
index 2cadaa6c11..cd53337c10 100644
--- a/src/mbgl/programs/line_program.cpp
+++ b/src/mbgl/programs/line_program.cpp
@@ -25,7 +25,7 @@ Values makeValues(const LinePaintProperties::Evaluated& properties,
// calculate how much longer the real world distance is at the top of the screen
// than at the middle of the screen.
- float topedgelength = std::sqrt(std::pow(state.getSize().height, 2.0f) / 4.0f * (1.0f + std::pow(state.getAltitude(), 2.0f)));
+ float topedgelength = std::sqrt(std::pow(state.getSize().height, 2.0f) / 4.0f * (1.0f + std::pow(state.getCameraToCenterDistance(), 2.0f)));
float x = state.getSize().height / 2.0f * std::tan(state.getPitch());
return Values {
diff --git a/src/mbgl/programs/symbol_program.cpp b/src/mbgl/programs/symbol_program.cpp
index 71b45ad4fc..d609dada8d 100644
--- a/src/mbgl/programs/symbol_program.cpp
+++ b/src/mbgl/programs/symbol_program.cpp
@@ -23,8 +23,8 @@ Values makeValues(const style::SymbolPropertyValues& values,
extrudeScale.fill(tile.id.pixelsToTileUnits(1, state.getZoom()) * scale);
} else {
extrudeScale = {{
- pixelsToGLUnits[0] * scale * state.getAltitude(),
- pixelsToGLUnits[1] * scale * state.getAltitude()
+ pixelsToGLUnits[0] * scale * state.getCameraToCenterDistance(),
+ pixelsToGLUnits[1] * scale * state.getCameraToCenterDistance()
}};
}
@@ -77,7 +77,7 @@ static SymbolSDFProgram::UniformValues makeSDFValues(const style::SymbolProperty
const float gammaBase = 0.105 * values.sdfScale / values.paintSize / pixelRatio;
const float gammaScale = (values.pitchAlignment == AlignmentType::Map
? 1.0 / std::cos(state.getPitch())
- : 1.0) / state.getAltitude();
+ : 1.0) / state.getCameraToCenterDistance();
return makeValues<SymbolSDFProgram::UniformValues>(
values,
diff --git a/src/mbgl/renderer/painter_circle.cpp b/src/mbgl/renderer/painter_circle.cpp
index 9385b7b1a3..966d58b59b 100644
--- a/src/mbgl/renderer/painter_circle.cpp
+++ b/src/mbgl/renderer/painter_circle.cpp
@@ -47,8 +47,8 @@ void Painter::renderCircle(PaintParameters& parameters,
uniforms::u_scale_with_map::Value{ scaleWithMap },
uniforms::u_extrude_scale::Value{ scaleWithMap
? std::array<float, 2> {{
- pixelsToGLUnits[0] * state.getAltitude(),
- pixelsToGLUnits[1] * state.getAltitude()
+ pixelsToGLUnits[0] * state.getCameraToCenterDistance(),
+ pixelsToGLUnits[1] * state.getCameraToCenterDistance()
}}
: pixelsToGLUnits }
},
diff --git a/src/mbgl/style/layers/custom_layer_impl.cpp b/src/mbgl/style/layers/custom_layer_impl.cpp
index 3f11943478..baf55205c4 100644
--- a/src/mbgl/style/layers/custom_layer_impl.cpp
+++ b/src/mbgl/style/layers/custom_layer_impl.cpp
@@ -57,7 +57,7 @@ void CustomLayer::Impl::render(const TransformState& state) const {
parameters.zoom = state.getZoom();
parameters.bearing = -state.getAngle() * util::RAD2DEG;
parameters.pitch = state.getPitch();
- parameters.altitude = state.getAltitude();
+ parameters.fieldOfView = state.getFieldOfView();
renderFn(context, parameters);
}