From 38b5cb0c7766152f7e49cce8bd6c5d3e04dd0663 Mon Sep 17 00:00:00 2001 From: Ansis Brammanis Date: Wed, 14 Dec 2016 15:17:01 -0800 Subject: [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` --- src/mbgl/map/transform_state.cpp | 34 +++++++++++++++++------------ src/mbgl/map/transform_state.hpp | 9 ++++++-- src/mbgl/programs/line_program.cpp | 2 +- src/mbgl/programs/symbol_program.cpp | 6 ++--- src/mbgl/renderer/painter_circle.cpp | 4 ++-- src/mbgl/style/layers/custom_layer_impl.cpp | 2 +- 6 files changed, 34 insertions(+), 23 deletions(-) (limited to 'src') 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( 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 {{ - 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); } -- cgit v1.2.1