From 05a330f347e16dc310e3dd3fbdb3b27007c18fb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Tue, 13 May 2014 16:48:23 +0200 Subject: [PATCH 01/14] make translate property zoom independent if you want a zoom-dependent translation, you can use a function refs #189 --- include/llmr/renderer/painter.hpp | 2 +- src/renderer/painter.cpp | 17 +++++++---------- src/renderer/painter_fill.cpp | 4 ++-- src/renderer/painter_line.cpp | 6 +++--- src/renderer/painter_point.cpp | 6 +++--- src/renderer/painter_text.cpp | 6 +++--- 6 files changed, 19 insertions(+), 22 deletions(-) diff --git a/include/llmr/renderer/painter.hpp b/include/llmr/renderer/painter.hpp index d236ead44..5dbc97143 100644 --- a/include/llmr/renderer/painter.hpp +++ b/include/llmr/renderer/painter.hpp @@ -88,7 +88,7 @@ public: bool needsAnimation() const; private: void setupShaders(); - void translateLayer(std::array translation, bool reverse = false); + void translateLayer(std::array translation, const Tile::ID &id, bool reverse = false); void prepareTile(const Tile& tile); void useProgram(uint32_t program); diff --git a/src/renderer/painter.cpp b/src/renderer/painter.cpp index 6adbc71c4..6d85af4be 100644 --- a/src/renderer/painter.cpp +++ b/src/renderer/painter.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -170,17 +171,13 @@ void Painter::renderTileLayer(const Tile& tile, const LayerDescription &layer_de } } -void Painter::translateLayer(std::array translation, bool reverse) { +void Painter::translateLayer(const std::array translation, const Tile::ID &id, bool reverse) { if (translation[0] || translation[1]) { - if (reverse) { - translation[0] *= -1; - translation[1] *= -1; - } - matrix::translate(matrix, - matrix, - translation[0] / map.getState().getPixelRatio(), - translation[1] / map.getState().getPixelRatio(), - 0); + const int direction = reverse ? -1 : 1; + // TODO: Get rid of the 8 (scaling from 4096 to tile size) + const double factor = direction * ((double)(1 << id.z)) / map.getState().getScale() / + map.getState().getPixelRatio() * (4096.0 / util::tileSize); + matrix::translate(matrix, matrix, translation[0] * factor, translation[1] * factor, 0); } } diff --git a/src/renderer/painter_fill.cpp b/src/renderer/painter_fill.cpp index 921947857..442f627a5 100644 --- a/src/renderer/painter_fill.cpp +++ b/src/renderer/painter_fill.cpp @@ -35,7 +35,7 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons stroke_color = fill_color; } - translateLayer(properties.translate); + translateLayer(properties.translate, id); // Because we're drawing top-to-bottom, and we update the stencil mask // below, we have to draw the outline first (!) @@ -139,5 +139,5 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons bucket.drawVertices(*outlineShader); } - translateLayer(properties.translate, true); + translateLayer(properties.translate, id, true); } diff --git a/src/renderer/painter_line.cpp b/src/renderer/painter_line.cpp index 1998e5584..ccd916c52 100644 --- a/src/renderer/painter_line.cpp +++ b/src/renderer/painter_line.cpp @@ -4,7 +4,7 @@ using namespace llmr; -void Painter::renderLine(LineBucket& bucket, const std::string& layer_name, const Tile::ID& /*id*/) { +void Painter::renderLine(LineBucket& bucket, const std::string& layer_name, const Tile::ID& id) { // Abort early. if (pass == Opaque) return; if (!bucket.hasData()) return; @@ -33,7 +33,7 @@ void Painter::renderLine(LineBucket& bucket, const std::string& layer_name, cons float dash_length = properties.dash_array[0]; float dash_gap = properties.dash_array[1]; - translateLayer(properties.translate); + translateLayer(properties.translate, id); glDepthRange(strata, 1.0f); @@ -88,5 +88,5 @@ void Painter::renderLine(LineBucket& bucket, const std::string& layer_name, cons bucket.drawLines(*lineShader); } - translateLayer(properties.translate, true); + translateLayer(properties.translate, id, true); } diff --git a/src/renderer/painter_point.cpp b/src/renderer/painter_point.cpp index d54c66be9..2bb2da672 100644 --- a/src/renderer/painter_point.cpp +++ b/src/renderer/painter_point.cpp @@ -5,7 +5,7 @@ using namespace llmr; -void Painter::renderPoint(PointBucket& bucket, const std::string& layer_name, const Tile::ID& /*id&*/) { +void Painter::renderPoint(PointBucket& bucket, const std::string& layer_name, const Tile::ID& id) { // Abort early. if (!bucket.hasData()) return; if (pass == Opaque) return; @@ -17,7 +17,7 @@ void Painter::renderPoint(PointBucket& bucket, const std::string& layer_name, co const PointProperties& properties = point_properties_it->second; if (!properties.enabled) return; - translateLayer(properties.translate); + translateLayer(properties.translate, id); Color color = properties.color; color[0] *= properties.opacity; @@ -76,5 +76,5 @@ void Painter::renderPoint(PointBucket& bucket, const std::string& layer_name, co bucket.drawPoints(*pointShader); } - translateLayer(properties.translate, true); + translateLayer(properties.translate, id, true); } diff --git a/src/renderer/painter_text.cpp b/src/renderer/painter_text.cpp index 092b74b09..7d2a2d2ae 100644 --- a/src/renderer/painter_text.cpp +++ b/src/renderer/painter_text.cpp @@ -4,7 +4,7 @@ using namespace llmr; -void Painter::renderText(TextBucket& bucket, const std::string& layer_name, const Tile::ID& /*id*/) { +void Painter::renderText(TextBucket& bucket, const std::string& layer_name, const Tile::ID& id) { // Abort early. if (pass == Opaque) return; if (!bucket.hasData()) return; @@ -16,7 +16,7 @@ void Painter::renderText(TextBucket& bucket, const std::string& layer_name, cons const TextProperties& properties = text_properties_it->second; if (!properties.enabled) return; - translateLayer(properties.translate); + translateLayer(properties.translate, id); mat4 exMatrix; matrix::copy(exMatrix, projMatrix); @@ -110,5 +110,5 @@ void Painter::renderText(TextBucket& bucket, const std::string& layer_name, cons glDepthRange(strata + strata_epsilon, 1.0f); bucket.drawGlyphs(*textShader); - translateLayer(properties.translate, true); + translateLayer(properties.translate, id, true); } From d97e8899ae2be618d5ad0f325a471428f8ebe8fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Tue, 13 May 2014 18:41:22 +0200 Subject: [PATCH 02/14] add translate-anchor property --- include/llmr/style/properties.hpp | 7 +++++++ src/style/style.cpp | 1 + src/style/style_parser.cpp | 16 ++++++++++++++++ 3 files changed, 24 insertions(+) diff --git a/include/llmr/style/properties.hpp b/include/llmr/style/properties.hpp index 9a6d6d86d..22d5cf9cc 100644 --- a/include/llmr/style/properties.hpp +++ b/include/llmr/style/properties.hpp @@ -31,6 +31,11 @@ enum class Property { Linear = 4 }; +enum class TranslateAnchor : uint8_t { + Map = 1, + Viewport = 2 +}; + namespace functions { float null(float z, const std::vector&); @@ -121,6 +126,7 @@ struct FillProperties { struct TextClass { FunctionProperty enabled = true; std::array translate = {{ 0, 0 }}; + TranslateAnchor translateAnchor = TranslateAnchor::Map; Color color = {{ 0, 0, 0, 1 }}; Color halo = {{ 1, 1, 1, 0.75 }}; FunctionProperty haloRadius = 0.25f; @@ -133,6 +139,7 @@ struct TextClass { struct TextProperties { bool enabled = true; std::array translate = {{ 0, 0 }}; + TranslateAnchor translateAnchor = TranslateAnchor::Map; Color color = {{ 0, 0, 0, 1 }}; Color halo = {{ 1, 1, 1, 0.75 }}; float haloRadius = 0.25f; diff --git a/src/style/style.cpp b/src/style/style.cpp index a49311030..ecb86108e 100644 --- a/src/style/style.cpp +++ b/src/style/style.cpp @@ -97,6 +97,7 @@ void Style::cascade(float z) { text.enabled = layer.enabled.evaluate(z); text.translate = {{ layer.translate[0].evaluate(z), layer.translate[1].evaluate(z) }}; + text.translateAnchor = layer.translateAnchor; text.color = layer.color; text.size = layer.size.evaluate(z); text.halo = layer.halo; diff --git a/src/style/style_parser.cpp b/src/style/style_parser.cpp index 081dedce1..9860f56c6 100644 --- a/src/style/style_parser.cpp +++ b/src/style/style_parser.cpp @@ -523,6 +523,18 @@ PointClass StyleParser::parsePointClass(JSVal value) { return klass; } +TranslateAnchor parseTranslateAnchor(JSVal anchor) { + if (anchor.IsString()) { + std::string a { anchor.GetString(), anchor.GetStringLength() }; + if (a == "viewport") { + return TranslateAnchor::Viewport; + } else { + return TranslateAnchor::Map; + } + } else { + throw Style::exception("translate anchor must be a string"); + } +} TextClass StyleParser::parseTextClass(JSVal value) { TextClass klass; @@ -536,6 +548,10 @@ TextClass StyleParser::parseTextClass(JSVal value) { klass.translate = std::array {{ values[0], values[1] }}; } + if (value.HasMember("translate-anchor")) { + klass.translateAnchor = parseTranslateAnchor(value["translate-anchor"]); + } + if (value.HasMember("color")) { klass.color = parseColor(value["color"]); } From 32b21b050fe66c688d9b21f86197b8ac4cfaefdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Tue, 13 May 2014 18:41:37 +0200 Subject: [PATCH 03/14] do not define variables until they're needed --- src/util/mat4.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/util/mat4.cpp b/src/util/mat4.cpp index 44bd3edd7..e86c9e35e 100644 --- a/src/util/mat4.cpp +++ b/src/util/mat4.cpp @@ -87,16 +87,16 @@ void matrix::copy(mat4& out, const mat4& a) { } void matrix::translate(mat4& out, const mat4& a, float x, float y, float z) { - float a00, a01, a02, a03, - a10, a11, a12, a13, - a20, a21, a22, a23; - if (a == out) { out[12] = a[0] * x + a[4] * y + a[8] * z + a[12]; out[13] = a[1] * x + a[5] * y + a[9] * z + a[13]; out[14] = a[2] * x + a[6] * y + a[10] * z + a[14]; out[15] = a[3] * x + a[7] * y + a[11] * z + a[15]; } else { + float a00, a01, a02, a03, + a10, a11, a12, a13, + a20, a21, a22, a23; + a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3]; a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7]; a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11]; From 351453871995fcac42fdbb02aa281e3ca9cf26f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Tue, 13 May 2014 19:02:22 +0200 Subject: [PATCH 04/14] make text layers respect the translate-anchor you can now specify "translate-anchor": "viewport" to have the text translated in screen coordinates rather than relative to the tile. The default value remains "translate-anchor": "map" refs #189 --- include/llmr/renderer/painter.hpp | 4 +++- src/renderer/painter.cpp | 28 +++++++++++++++++++++++++++- src/renderer/painter_text.cpp | 8 +++----- 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/include/llmr/renderer/painter.hpp b/include/llmr/renderer/painter.hpp index 5dbc97143..2aa0353ca 100644 --- a/include/llmr/renderer/painter.hpp +++ b/include/llmr/renderer/painter.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -88,7 +89,8 @@ public: bool needsAnimation() const; private: void setupShaders(); - void translateLayer(std::array translation, const Tile::ID &id, bool reverse = false); + void translateLayer(const std::array &translation, const Tile::ID &id, bool reverse = false); + mat4 translatedMatrix(const std::array &translation, const Tile::ID &id, TranslateAnchor anchor = TranslateAnchor::Map); void prepareTile(const Tile& tile); void useProgram(uint32_t program); diff --git a/src/renderer/painter.cpp b/src/renderer/painter.cpp index 6d85af4be..2d9606b6f 100644 --- a/src/renderer/painter.cpp +++ b/src/renderer/painter.cpp @@ -171,7 +171,7 @@ void Painter::renderTileLayer(const Tile& tile, const LayerDescription &layer_de } } -void Painter::translateLayer(const std::array translation, const Tile::ID &id, bool reverse) { +void Painter::translateLayer(const std::array &translation, const Tile::ID &id, bool reverse) { if (translation[0] || translation[1]) { const int direction = reverse ? -1 : 1; // TODO: Get rid of the 8 (scaling from 4096 to tile size) @@ -181,6 +181,32 @@ void Painter::translateLayer(const std::array translation, const Tile: } } +mat4 Painter::translatedMatrix(const std::array &translation, const Tile::ID &id, TranslateAnchor anchor) { + if (translation[0] == 0 && translation[1] == 0) { + return matrix; + } else { + // TODO: Get rid of the 8 (scaling from 4096 to tile size) + const double factor = ((double)(1 << id.z)) / map.getState().getScale() / + map.getState().getPixelRatio() * (4096.0 / util::tileSize); + + mat4 result; + if (anchor == TranslateAnchor::Viewport) { + const double sin_a = sin(-map.getState().getAngle()); + const double cos_a = cos(-map.getState().getAngle()); + matrix::translate(result, matrix, + factor * (translation[0] * cos_a - translation[1] * sin_a), + factor * (translation[0] * sin_a + translation[1] * cos_a), + 0); + } else { + matrix::translate(result, matrix, + factor * translation[0], + factor * translation[1], + 0); + } + return result; + } +} + void Painter::renderMatte() { gl::group group("matte"); glDisable(GL_DEPTH_TEST); diff --git a/src/renderer/painter_text.cpp b/src/renderer/painter_text.cpp index 7d2a2d2ae..a17f162e9 100644 --- a/src/renderer/painter_text.cpp +++ b/src/renderer/painter_text.cpp @@ -16,8 +16,6 @@ void Painter::renderText(TextBucket& bucket, const std::string& layer_name, cons const TextProperties& properties = text_properties_it->second; if (!properties.enabled) return; - translateLayer(properties.translate, id); - mat4 exMatrix; matrix::copy(exMatrix, projMatrix); if (bucket.geom_desc.path == TextPathType::Curve) { @@ -33,8 +31,10 @@ void Painter::renderText(TextBucket& bucket, const std::string& layer_name, cons float fontSize = fmin(properties.size, bucket.geom_desc.font_size); matrix::scale(exMatrix, exMatrix, fontSize / 24.0f, fontSize / 24.0f, 1.0f); + const mat4 vtxMatrix = translatedMatrix(properties.translate, id, properties.translateAnchor); + useProgram(textShader->program); - textShader->setMatrix(matrix); + textShader->setMatrix(vtxMatrix); textShader->setExtrudeMatrix(exMatrix); map.getGlyphAtlas().bind(); @@ -109,6 +109,4 @@ void Painter::renderText(TextBucket& bucket, const std::string& layer_name, cons textShader->setBuffer((256.0f - 64.0f) / 256.0f); glDepthRange(strata + strata_epsilon, 1.0f); bucket.drawGlyphs(*textShader); - - translateLayer(properties.translate, id, true); } From 164aef8b26de0ab371b03e806150c1f426e30c42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Wed, 14 May 2014 13:01:07 +0200 Subject: [PATCH 05/14] add hipchat notifications for build status --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index ead94415a..796d2f2c5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,3 +26,6 @@ script: - make llmr - make linux - make run-tests + +notifications: +- hipchat: WB52YkcbCGMbNcStsGeaoRO7cyBSK4wX2ZHo2Y4b@GL From ac9a678ce53f922fb1d6b8c6fec3bc5d912cdb5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Wed, 14 May 2014 13:41:55 +0200 Subject: [PATCH 06/14] fix lock initialization background: for non-debug builds, assert() gets compiled away, so the locks are not initialized --- include/llmr/util/uv.hpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/include/llmr/util/uv.hpp b/include/llmr/util/uv.hpp index f0b0fe392..aae5a1b05 100644 --- a/include/llmr/util/uv.hpp +++ b/include/llmr/util/uv.hpp @@ -15,7 +15,11 @@ namespace uv { class mutex { public: - inline mutex() { assert(uv_mutex_init(&mtx) == 0); } + inline mutex() { + if (uv_mutex_init(&mtx) != 0) { + throw std::runtime_error("failed to initialize mutex"); + } + } inline ~mutex() { uv_mutex_destroy(&mtx); } inline void lock() { uv_mutex_lock(&mtx); } inline void unlock() { uv_mutex_unlock(&mtx); } @@ -35,7 +39,11 @@ private: class rwlock { public: - inline rwlock() { assert(uv_rwlock_init(&mtx) == 0); } + inline rwlock() { + if (uv_rwlock_init(&mtx) != 0) { + throw std::runtime_error("failed to initialize read-write lock"); + } + } inline ~rwlock() { uv_rwlock_destroy(&mtx); } inline void rdlock() { uv_rwlock_rdlock(&mtx); } inline void wrlock() { uv_rwlock_wrlock(&mtx); } From a812f37c604805e003bec44e00b73cc982e0aff0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Wed, 14 May 2014 15:04:33 +0200 Subject: [PATCH 07/14] make sure to premultiply the colors during stylesheet parsing fixes #193 --- include/llmr/style/properties.hpp | 1 + src/style/style_parser.cpp | 19 +++++++++++++------ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/include/llmr/style/properties.hpp b/include/llmr/style/properties.hpp index 22d5cf9cc..eae2351f4 100644 --- a/include/llmr/style/properties.hpp +++ b/include/llmr/style/properties.hpp @@ -8,6 +8,7 @@ namespace llmr { +// Stores a premultiplied color, with all four channels ranging from 0..1 typedef std::array Color; enum class Winding { diff --git a/src/style/style_parser.cpp b/src/style/style_parser.cpp index 9860f56c6..83c408dd3 100644 --- a/src/style/style_parser.cpp +++ b/src/style/style_parser.cpp @@ -333,18 +333,25 @@ Color StyleParser::parseColor(JSVal value) { throw Style::exception("color values must be numbers"); } - return {{static_cast(r.GetDouble()), - static_cast(g.GetDouble()), - static_cast(b.GetDouble()), - static_cast(a.GetDouble())}}; + // Premultiply the color. + const double alpha = a.GetDouble(); + return {{static_cast(alpha * r.GetDouble()), + static_cast(alpha * g.GetDouble()), + static_cast(alpha * b.GetDouble()), + static_cast(alpha)}}; } else if (!rvalue.IsString()) { throw Style::exception("color value must be a string"); } CSSColorParser::Color css_color = CSSColorParser::parse({ rvalue.GetString(), rvalue.GetStringLength() }); - return {{(float)css_color.r / 255, (float)css_color.g / 255, - (float)css_color.b / 255, css_color.a}}; + + // Premultiply the color. + const float factor = css_color.a / 255; + return {{(float)css_color.r * factor, + (float)css_color.g * factor, + (float)css_color.b * factor, + css_color.a}}; } FunctionProperty::fn StyleParser::parseFunctionType(JSVal type) { From 24617da3ff16e814cf24dd39811d0b51d39351bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Wed, 14 May 2014 14:52:37 +0200 Subject: [PATCH 08/14] don't factor in the pixelratio to achieve the same look refs #189 --- src/renderer/painter.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/renderer/painter.cpp b/src/renderer/painter.cpp index 2d9606b6f..7c5578829 100644 --- a/src/renderer/painter.cpp +++ b/src/renderer/painter.cpp @@ -175,8 +175,7 @@ void Painter::translateLayer(const std::array &translation, const Tile if (translation[0] || translation[1]) { const int direction = reverse ? -1 : 1; // TODO: Get rid of the 8 (scaling from 4096 to tile size) - const double factor = direction * ((double)(1 << id.z)) / map.getState().getScale() / - map.getState().getPixelRatio() * (4096.0 / util::tileSize); + const double factor = direction * ((double)(1 << id.z)) / map.getState().getScale() * (4096.0 / util::tileSize); matrix::translate(matrix, matrix, translation[0] * factor, translation[1] * factor, 0); } } @@ -186,8 +185,7 @@ mat4 Painter::translatedMatrix(const std::array &translation, const Ti return matrix; } else { // TODO: Get rid of the 8 (scaling from 4096 to tile size) - const double factor = ((double)(1 << id.z)) / map.getState().getScale() / - map.getState().getPixelRatio() * (4096.0 / util::tileSize); + const double factor = ((double)(1 << id.z)) / map.getState().getScale() * (4096.0 / util::tileSize); mat4 result; if (anchor == TranslateAnchor::Viewport) { From b8d88600b81372a7544ebe420c562c4fa02592e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Wed, 14 May 2014 15:09:13 +0200 Subject: [PATCH 09/14] cemetary => cemetery --- bin/style.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/bin/style.js b/bin/style.js index 9bbe86631..0c70ffb23 100644 --- a/bin/style.js +++ b/bin/style.js @@ -77,11 +77,11 @@ module.exports = { "value": "park", "type": "fill" }, - "landuse_cemetary": { + "landuse_cemetery": { "source": "mapbox streets", "layer": "landuse", "field": "class", - "value": "cemetary", + "value": "cemetery", "type": "fill" }, "landuse_hospital": { @@ -567,7 +567,7 @@ module.exports = { "land": "#f8f4f0", "water": "#a0c8f0", "park": "#d8e8c8", - "cemetary": "#e0e4dd", + "cemetery": "#e0e4dd", "hospital": "#fde", "school": "#f0e8f8", "wood": "#6a4", @@ -610,8 +610,8 @@ module.exports = { "name": "landuse_park", "bucket": "landuse_park" }, { - "name": "landuse_cemetary", - "bucket": "landuse_cemetary" + "name": "landuse_cemetery", + "bucket": "landuse_cemetery" }, { "name": "landuse_hospital", "bucket": "landuse_hospital" @@ -943,8 +943,8 @@ module.exports = { "landuse_park": { "color": "park", }, - "landuse_cemetary": { - "color": "cemetary", + "landuse_cemetery": { + "color": "cemetery", }, "landuse_hospital": { "color": "hospital", From b167a79c22ed3e65941305a7d8e0fedb796dd11f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Wed, 14 May 2014 16:40:24 +0200 Subject: [PATCH 10/14] always use std:: namespace for math functions fixes #201 --- common/glfw_view.cpp | 4 ++-- include/llmr/map/tile.hpp | 2 +- include/llmr/map/transform.hpp | 4 ++-- include/llmr/util/math.hpp | 10 ++++---- src/csscolorparser/csscolorparser.cpp | 2 +- src/geometry/debug_font_buffer.cpp | 4 ++-- src/geometry/line_buffer.cpp | 4 ++-- src/geometry/text_buffer.cpp | 12 +++++----- src/map/source.cpp | 16 ++++++------- src/map/tile.cpp | 8 +++---- src/map/transform.cpp | 34 +++++++++++++-------------- src/map/transform_state.cpp | 14 +++++------ src/renderer/fill_bucket.cpp | 2 +- src/renderer/line_bucket.cpp | 6 ++--- src/renderer/painter.cpp | 4 ++-- src/renderer/painter_fill.cpp | 8 +++---- src/renderer/painter_line.cpp | 6 ++--- src/renderer/painter_text.cpp | 12 +++++----- src/style/properties.cpp | 6 ++--- src/text/collision.cpp | 16 ++++++------- src/text/placement.cpp | 16 ++++++------- src/text/rotation_range.cpp | 24 +++++++++---------- src/util/mat4.cpp | 4 ++-- test/rotation_range.cpp | 12 +++++----- 24 files changed, 115 insertions(+), 115 deletions(-) diff --git a/common/glfw_view.cpp b/common/glfw_view.cpp index 4bdac5f6b..7ec5d3b08 100644 --- a/common/glfw_view.cpp +++ b/common/glfw_view.cpp @@ -88,10 +88,10 @@ void GLFWView::scroll(GLFWwindow *window, double /*xoffset*/, double yoffset) { GLFWView *view = (GLFWView *)glfwGetWindowUserPointer(window); double delta = yoffset * 40; - bool is_wheel = delta != 0 && fmod(delta, 4.000244140625) == 0; + bool is_wheel = delta != 0 && std::fmod(delta, 4.000244140625) == 0; double absdelta = delta < 0 ? -delta : delta; - double scale = 2.0 / (1.0 + exp(-absdelta / 100.0)); + double scale = 2.0 / (1.0 + std::exp(-absdelta / 100.0)); // Make the scroll wheel a bit slower. if (!is_wheel) { diff --git a/include/llmr/map/tile.hpp b/include/llmr/map/tile.hpp index 76a01e04e..0f43f9df2 100644 --- a/include/llmr/map/tile.hpp +++ b/include/llmr/map/tile.hpp @@ -33,7 +33,7 @@ public: : w((x < 0 ? x - (1 << z) + 1 : x) / (1 << z)), z(z), x(x), y(y) {} inline uint64_t to_uint64() const { - return ((pow(2, z) * y + x) * 32) + z; + return ((std::pow(2, z) * y + x) * 32) + z; } inline operator std::string() const { diff --git a/include/llmr/map/transform.hpp b/include/llmr/map/transform.hpp index 6b4352130..472d01ab7 100644 --- a/include/llmr/map/transform.hpp +++ b/include/llmr/map/transform.hpp @@ -81,8 +81,8 @@ private: // Limit the amount of zooming possible on the map. // TODO: make these modifiable from outside. - const double min_scale = pow(2, 0); - const double max_scale = pow(2, 20); + const double min_scale = std::pow(2, 0); + const double max_scale = std::pow(2, 20); // cache values for spherical mercator math double zc, Bc, Cc; diff --git a/include/llmr/util/math.hpp b/include/llmr/util/math.hpp index d356cf876..531a13a1a 100644 --- a/include/llmr/util/math.hpp +++ b/include/llmr/util/math.hpp @@ -44,7 +44,7 @@ inline T min(T a, T b, T c, T d) { // a x b = |a||b|sin(θ) for θ. template inline T angle_between(S ax, S ay, S bx, S by) { - return atan2((ax * by - ay * bx), ax * bx + ay * by); + return std::atan2((ax * by - ay * bx), ax * bx + ay * by); } template @@ -54,7 +54,7 @@ inline T angle_between(const vec2& a, const vec2& b) { template inline T angle_to(const vec2& a, const vec2& b) { - return atan2(a.y - b.y, a.x - b.x); + return std::atan2(a.y - b.y, a.x - b.x); } template @@ -75,7 +75,7 @@ template inline vec2 normal(const S1& a, const S2& b) { T dx = b.x - a.x; T dy = b.y - a.y; - T c = sqrt(dx * dx + dy * dy); + T c = std::sqrt(dx * dx + dy * dy); return { dx / c, dy / c }; } @@ -83,14 +83,14 @@ template inline T dist(const S1& a, const S2& b) { T dx = b.x - a.x; T dy = b.y - a.y; - T c = sqrt(dx * dx + dy * dy); + T c = std::sqrt(dx * dx + dy * dy); return c; } // Take the magnitude of vector a. template inline T mag(const S& a) { - return sqrt(a.x * a.x + a.y * a.y); + return std::sqrt(a.x * a.x + a.y * a.y); } } diff --git a/src/csscolorparser/csscolorparser.cpp b/src/csscolorparser/csscolorparser.cpp index 6ee0ba916..d52c6280c 100644 --- a/src/csscolorparser/csscolorparser.cpp +++ b/src/csscolorparser/csscolorparser.cpp @@ -114,7 +114,7 @@ const std::map kCSSColorTable = { template uint8_t clamp_css_byte(T i) { // Clamp to integer 0 .. 255. - i = round(i); // Seems to be what Chrome does (vs truncation). + i = std::round(i); // Seems to be what Chrome does (vs truncation). return i < 0 ? 0 : i > 255 ? 255 : i; } diff --git a/src/geometry/debug_font_buffer.cpp b/src/geometry/debug_font_buffer.cpp index a91865fb8..9febbc518 100644 --- a/src/geometry/debug_font_buffer.cpp +++ b/src/geometry/debug_font_buffer.cpp @@ -31,8 +31,8 @@ void DebugFontBuffer::addText(const char *text, double left, double baseline, do if (glyph.data[j] == -1 && glyph.data[j + 1] == -1) { prev = false; } else { - int16_t x = round(left + glyph.data[j] * scale); - int16_t y = round(baseline - glyph.data[j + 1] * scale); + int16_t x = std::round(left + glyph.data[j] * scale); + int16_t y = std::round(baseline - glyph.data[j + 1] * scale); if (prev) { coords = static_cast(addElement()); coords[0] = prev_x; diff --git a/src/geometry/line_buffer.cpp b/src/geometry/line_buffer.cpp index 736235775..a80ded5fb 100644 --- a/src/geometry/line_buffer.cpp +++ b/src/geometry/line_buffer.cpp @@ -14,8 +14,8 @@ size_t LineVertexBuffer::add(vertex_type x, vertex_type y, float ex, float ey, i coords[1] = (y * 2) | ty; int8_t *extrude = static_cast(data); - extrude[4] = round(extrudeScale * ex); - extrude[5] = round(extrudeScale * ey); + extrude[4] = std::round(extrudeScale * ex); + extrude[5] = std::round(extrudeScale * ey); coords[3] = linesofar; diff --git a/src/geometry/text_buffer.cpp b/src/geometry/text_buffer.cpp index d8b2eb6ef..d3529c560 100644 --- a/src/geometry/text_buffer.cpp +++ b/src/geometry/text_buffer.cpp @@ -15,21 +15,21 @@ size_t TextVertexBuffer::add(int16_t x, int16_t y, float ox, float oy, uint16_t int16_t *shorts = static_cast(data); shorts[0] = x; shorts[1] = y; - shorts[2] = round(ox * 64); // use 1/64 pixels for placement - shorts[3] = round(oy * 64); + shorts[2] = std::round(ox * 64); // use 1/64 pixels for placement + shorts[3] = std::round(oy * 64); uint8_t *ubytes = static_cast(data); // a_data1 ubytes[8] = tx / 4; ubytes[9] = ty / 4; ubytes[10] = labelminzoom * 10; - ubytes[11] = (int16_t)round(angle * angleFactor) % 256; + ubytes[11] = (int16_t)std::round(angle * angleFactor) % 256; // a_data2 ubytes[12] = minzoom * 10; // 1/10 zoom levels: z16 == 160. - ubytes[13] = fmin(maxzoom, 25) * 10; // 1/10 zoom levels: z16 == 160. - ubytes[14] = util::max((int16_t)round(range[0] * angleFactor), (int16_t)0) % 256; - ubytes[15] = util::min((int16_t)round(range[1] * angleFactor), (int16_t)255) % 256; + ubytes[13] = std::fmin(maxzoom, 25) * 10; // 1/10 zoom levels: z16 == 160. + ubytes[14] = util::max((int16_t)std::round(range[0] * angleFactor), (int16_t)0) % 256; + ubytes[15] = util::min((int16_t)std::round(range[1] * angleFactor), (int16_t)255) % 256; return idx; } diff --git a/src/map/source.cpp b/src/map/source.cpp index a5985668f..91ccdbc9c 100644 --- a/src/map/source.cpp +++ b/src/map/source.cpp @@ -312,8 +312,8 @@ edge _edge(const llmr::vec2 a, const llmr::vec2 b) { // scan-line conversion void _scanSpans(edge e0, edge e1, int32_t ymin, int32_t ymax, ScanLine scanLine) { - double y0 = fmax(ymin, floor(e1.y0)), - y1 = fmin(ymax, ceil(e1.y1)); + double y0 = std::fmax(ymin, std::floor(e1.y0)), + y1 = std::fmin(ymax, std::ceil(e1.y1)); // sort edges by x-coordinate if ((e0.x0 == e1.x0 && e0.y0 == e1.y0) ? @@ -328,9 +328,9 @@ void _scanSpans(edge e0, edge e1, int32_t ymin, int32_t ymax, ScanLine scanLine) d0 = e0.dx > 0, // use y + 1 to compute x0 d1 = e1.dx < 0; // use y + 1 to compute x1 for (int32_t y = y0; y < y1; y++) { - double x0 = m0 * fmax(0, fmin(e0.dy, y + d0 - e0.y0)) + e0.x0, - x1 = m1 * fmax(0, fmin(e1.dy, y + d1 - e1.y0)) + e1.x0; - scanLine(floor(x1), ceil(x0), y, ymax); + double x0 = m0 * std::fmax(0, std::fmin(e0.dy, y + d0 - e0.y0)) + e0.x0, + x1 = m1 * std::fmax(0, std::fmin(e1.dy, y + d1 - e1.y0)) + e1.x0; + scanLine(std::floor(x1), std::ceil(x0), y, ymax); } } @@ -357,7 +357,7 @@ double Source::getZoom() const { } std::forward_list Source::covering_tiles(int32_t zoom, const box& points) { - int32_t dim = pow(2, zoom); + int32_t dim = std::pow(2, zoom); std::forward_list tiles; bool is_raster = (type == Type::raster); double search_zoom = getZoom(); @@ -389,8 +389,8 @@ std::forward_list Source::covering_tiles(int32_t zoom, const box const vec2& center = points.center; tiles.sort([¢er](const Tile::ID& a, const Tile::ID& b) { // Sorts by distance from the box center - return fabs(a.x - center.x) + fabs(a.y - center.y) < - fabs(b.x - center.x) + fabs(b.y - center.y); + return std::fabs(a.x - center.x) + std::fabs(a.y - center.y) < + std::fabs(b.x - center.x) + std::fabs(b.y - center.y); }); tiles.unique(); diff --git a/src/map/tile.cpp b/src/map/tile.cpp index 5e22dd0bb..45fe88ee2 100644 --- a/src/map/tile.cpp +++ b/src/map/tile.cpp @@ -12,7 +12,7 @@ Tile::Tile(const ID& id) Tile::ID Tile::ID::parent(int8_t parent_z) const { assert(parent_z < z); - int32_t dim = pow(2, z - parent_z); + int32_t dim = std::pow(2, z - parent_z); return Tile::ID{ parent_z, (x >= 0 ? x : x - dim + 1) / dim, @@ -22,7 +22,7 @@ Tile::ID Tile::ID::parent(int8_t parent_z) const { std::forward_list Tile::ID::children(int32_t child_z) const { assert(child_z > z); - int32_t factor = pow(2, child_z - z); + int32_t factor = std::pow(2, child_z - z); std::forward_list children; for (int32_t ty = y * factor, y_max = (y + 1) * factor; ty < y_max; ++ty) { @@ -34,7 +34,7 @@ std::forward_list Tile::ID::children(int32_t child_z) const { } Tile::ID Tile::ID::normalized() const { - int32_t dim = pow(2, z); + int32_t dim = std::pow(2, z); int32_t nx = x, ny = y; while (nx < 0) nx += dim; while (nx >= dim) nx -= dim; @@ -45,7 +45,7 @@ bool Tile::ID::isChildOf(const Tile::ID &parent) const { if (parent.z >= z || parent.w != w) { return false; } - int32_t scale = pow(2, z - parent.z); + int32_t scale = std::pow(2, z - parent.z); return parent.x == ((x < 0 ? x - scale + 1 : x) / scale) && parent.y == y / scale; } diff --git a/src/map/transform.cpp b/src/map/transform.cpp index d8ab9a744..fb3458ade 100644 --- a/src/map/transform.cpp +++ b/src/map/transform.cpp @@ -49,8 +49,8 @@ void Transform::moveBy(const double dx, const double dy, const time duration) { void Transform::_moveBy(const double dx, const double dy, const time duration) { // This is only called internally, so we don't need a lock here. - final.x = current.x + cos(current.angle) * dx + sin(current.angle) * dy; - final.y = current.y + cos(current.angle) * dy + sin(-current.angle) * dx; + final.x = current.x + std::cos(current.angle) * dx + std::sin(current.angle) * dy; + final.y = current.y + std::cos(current.angle) * dy + std::sin(-current.angle) * dx; if (duration == 0) { current.x = final.x; @@ -68,9 +68,9 @@ void Transform::_moveBy(const double dx, const double dy, const time duration) { void Transform::setLonLat(const double lon, const double lat, const time duration) { uv::writelock lock(mtx); - const double f = fmin(fmax(sin(D2R * lat), -0.9999), 0.9999); - double xn = -round(lon * Bc); - double yn = round(0.5 * Cc * log((1 + f) / (1 - f))); + const double f = std::fmin(std::fmax(std::sin(D2R * lat), -0.9999), 0.9999); + double xn = -std::round(lon * Bc); + double yn = std::round(0.5 * Cc * std::log((1 + f) / (1 - f))); _setScaleXY(current.scale, xn, yn, duration); } @@ -79,16 +79,16 @@ void Transform::setLonLatZoom(const double lon, const double lat, const double z const time duration) { uv::writelock lock(mtx); - double new_scale = pow(2.0, zoom); + double new_scale = std::pow(2.0, zoom); const double s = new_scale * util::tileSize; zc = s / 2; Bc = s / 360; Cc = s / (2 * M_PI); - const double f = fmin(fmax(sin(D2R * lat), -0.9999), 0.9999); - double xn = -round(lon * Bc); - double yn = round(0.5 * Cc * log((1 + f) / (1 - f))); + const double f = std::fmin(std::fmax(std::sin(D2R * lat), -0.9999), 0.9999); + double xn = -std::round(lon * Bc); + double yn = std::round(0.5 * Cc * log((1 + f) / (1 - f))); _setScaleXY(new_scale, xn, yn, duration); } @@ -97,7 +97,7 @@ void Transform::getLonLat(double &lon, double &lat) const { uv::readlock lock(mtx); lon = -final.x / Bc; - lat = R2D * (2 * atan(exp(final.y / Cc)) - 0.5 * M_PI); + lat = R2D * (2 * std::atan(std::exp(final.y / Cc)) - 0.5 * M_PI); } void Transform::getLonLatZoom(double &lon, double &lat, double &zoom) const { @@ -159,7 +159,7 @@ void Transform::setScale(const double scale, const double cx, const double cy, void Transform::setZoom(const double zoom, const time duration) { uv::writelock lock(mtx); - _setScale(pow(2.0, zoom), -1, -1, duration); + _setScale(std::pow(2.0, zoom), -1, -1, duration); } double Transform::getZoom() const { @@ -224,8 +224,8 @@ void Transform::_setScale(double new_scale, double cx, double cy, const time dur const double dy = (cy - current.height / 2) * (1.0 - factor); // Account for angle - const double angle_sin = sin(-current.angle); - const double angle_cos = cos(-current.angle); + const double angle_sin = std::sin(-current.angle); + const double angle_cos = std::cos(-current.angle); const double ax = angle_cos * dx - angle_sin * dy; const double ay = angle_sin * dx + angle_cos * dy; @@ -276,15 +276,15 @@ void Transform::rotateBy(const double start_x, const double start_y, const doubl const double begin_center_y = start_y - center_y; const double beginning_center_dist = - sqrt(begin_center_x * begin_center_x + begin_center_y * begin_center_y); + std::sqrt(begin_center_x * begin_center_x + begin_center_y * begin_center_y); // If the first click was too close to the center, move the center of rotation by 200 pixels // in the direction of the click. if (beginning_center_dist < 200) { const double offset_x = -200, offset_y = 0; - const double rotate_angle = atan2(begin_center_y, begin_center_x); - const double rotate_angle_sin = sin(rotate_angle); - const double rotate_angle_cos = cos(rotate_angle); + const double rotate_angle = std::atan2(begin_center_y, begin_center_x); + const double rotate_angle_sin = std::sin(rotate_angle); + const double rotate_angle_cos = std::cos(rotate_angle); center_x = start_x + rotate_angle_cos * offset_x - rotate_angle_sin * offset_y; center_y = start_y + rotate_angle_sin * offset_x + rotate_angle_cos * offset_y; } diff --git a/src/map/transform_state.cpp b/src/map/transform_state.cpp index c6f8be71b..b6a4e5bb2 100644 --- a/src/map/transform_state.cpp +++ b/src/map/transform_state.cpp @@ -6,7 +6,7 @@ using namespace llmr; #pragma mark - Matrix void TransformState::matrixFor(mat4& matrix, const Tile::ID& id) const { - const double tile_scale = pow(2, id.z); + const double tile_scale = std::pow(2, id.z); const double tile_size = scale * util::tileSize / tile_scale; matrix::identity(matrix); @@ -23,10 +23,10 @@ void TransformState::matrixFor(mat4& matrix, const Tile::ID& id) const { } box TransformState::cornersToBox(uint32_t z) const { - const double ref_scale = pow(2, z); + const double ref_scale = std::pow(2, z); - const double angle_sin = sin(-angle); - const double angle_cos = cos(-angle); + const double angle_sin = std::sin(-angle); + const double angle_cos = std::cos(-angle); const double w_2 = width / 2; const double h_2 = height / 2; @@ -88,15 +88,15 @@ float TransformState::getPixelRatio() const { #pragma mark - Zoom float TransformState::getNormalizedZoom() const { - return log(scale * util::tileSize / 256.0f) / M_LN2; + return std::log(scale * util::tileSize / 256.0f) / M_LN2; } int32_t TransformState::getIntegerZoom() const { - return floor(getZoom()); + return std::floor(getZoom()); } double TransformState::getZoom() const { - return log(scale) / M_LN2; + return std::log(scale) / M_LN2; } double TransformState::getScale() const { diff --git a/src/renderer/fill_bucket.cpp b/src/renderer/fill_bucket.cpp index e4783c5c3..2a4e1c78a 100644 --- a/src/renderer/fill_bucket.cpp +++ b/src/renderer/fill_bucket.cpp @@ -155,7 +155,7 @@ void FillBucket::tessellate() { for (size_t i = 0; i < vertex_count; ++i) { if (vertex_indices[i] == TESS_UNDEF) { - vertexBuffer.add(round(vertices[i * 2]), round(vertices[i * 2 + 1])); + vertexBuffer.add(std::round(vertices[i * 2]), std::round(vertices[i * 2 + 1])); vertex_indices[i] = (TESSindex)total_vertex_count; total_vertex_count++; } diff --git a/src/renderer/line_bucket.cpp b/src/renderer/line_bucket.cpp index f968c56cb..a253d495d 100644 --- a/src/renderer/line_bucket.cpp +++ b/src/renderer/line_bucket.cpp @@ -159,12 +159,12 @@ void LineBucket::addGeometry(const std::vector& vertices) { double joinAngularity = nextNormal.x * joinNormal.y - nextNormal.y * joinNormal.x; joinNormal.x /= joinAngularity; joinNormal.y /= joinAngularity; - double roundness = fmax(abs(joinNormal.x), abs(joinNormal.y)); + double roundness = std::fmax(std::abs(joinNormal.x), std::abs(joinNormal.y)); // Switch to miter joins if the angle is very low. if (currentJoin != JoinType::Miter) { - if (fabs(joinAngularity) < 0.5 && roundness < miterLimit) { + if (std::fabs(joinAngularity) < 0.5 && roundness < miterLimit) { currentJoin = JoinType::Miter; } } @@ -209,7 +209,7 @@ void LineBucket::addGeometry(const std::vector& vertices) { else if (currentJoin == JoinType::Miter) { // MITER JOIN - if (fabs(joinAngularity) < 0.01) { + if (std::fabs(joinAngularity) < 0.01) { // The two normals are almost parallel. joinNormal.x = -nextNormal.y; joinNormal.y = nextNormal.x; diff --git a/src/renderer/painter.cpp b/src/renderer/painter.cpp index 7c5578829..c6c4a7932 100644 --- a/src/renderer/painter.cpp +++ b/src/renderer/painter.cpp @@ -189,8 +189,8 @@ mat4 Painter::translatedMatrix(const std::array &translation, const Ti mat4 result; if (anchor == TranslateAnchor::Viewport) { - const double sin_a = sin(-map.getState().getAngle()); - const double cos_a = cos(-map.getState().getAngle()); + const double sin_a = std::sin(-map.getState().getAngle()); + const double cos_a = std::cos(-map.getState().getAngle()); matrix::translate(result, matrix, factor * (translation[0] * cos_a - translation[1] * sin_a), factor * (translation[0] * sin_a + translation[1] * cos_a), diff --git a/src/renderer/painter_fill.cpp b/src/renderer/painter_fill.cpp index 442f627a5..b412d8570 100644 --- a/src/renderer/painter_fill.cpp +++ b/src/renderer/painter_fill.cpp @@ -77,8 +77,8 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons // Draw texture fill ImagePosition imagePos = sprite->getPosition(properties.image, true); - float factor = 8.0 / pow(2, map.getState().getIntegerZoom() - id.z); - float mix = fmod(map.getState().getZoom(), 1.0); + float factor = 8.0 / std::pow(2, map.getState().getIntegerZoom() - id.z); + float mix = std::fmod(map.getState().getZoom(), 1.0); std::array imageSize = {{ imagePos.size.x * factor, @@ -87,8 +87,8 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons }; std::array offset = {{ - (float)fmod(id.x * 4096, imageSize[0]), - (float)fmod(id.y * 4096, imageSize[1]) + (float)std::fmod(id.x * 4096, imageSize[0]), + (float)std::fmod(id.y * 4096, imageSize[1]) } }; diff --git a/src/renderer/painter_line.cpp b/src/renderer/painter_line.cpp index ccd916c52..6856c93af 100644 --- a/src/renderer/painter_line.cpp +++ b/src/renderer/painter_line.cpp @@ -21,8 +21,8 @@ void Painter::renderLine(LineBucket& bucket, const std::string& layer_name, cons // These are the radii of the line. We are limiting it to 16, which will result // in a point size of 64 on retina. - float inset = fmin((fmax(-1, offset - width / 2 - 0.5) + 1), 16.0f); - float outset = fmin(offset + width / 2 + 0.5, 16.0f); + float inset = std::fmin((std::fmax(-1, offset - width / 2 - 0.5) + 1), 16.0f); + float outset = std::fmin(offset + width / 2 + 0.5, 16.0f); Color color = properties.color; color[0] *= properties.opacity; @@ -53,7 +53,7 @@ void Painter::renderLine(LineBucket& bucket, const std::string& layer_name, cons } }); - float pointSize = ceil(map.getState().getPixelRatio() * outset * 2.0); + float pointSize = std::ceil(map.getState().getPixelRatio() * outset * 2.0); #if defined(GL_ES_VERSION_2_0) linejoinShader->setSize(pointSize); #else diff --git a/src/renderer/painter_text.cpp b/src/renderer/painter_text.cpp index a17f162e9..d1abbb526 100644 --- a/src/renderer/painter_text.cpp +++ b/src/renderer/painter_text.cpp @@ -28,7 +28,7 @@ void Painter::renderText(TextBucket& bucket, const std::string& layer_name, cons } // If layerStyle.size > bucket.info.fontSize then labels may collide - float fontSize = fmin(properties.size, bucket.geom_desc.font_size); + float fontSize = std::fmin(properties.size, bucket.geom_desc.font_size); matrix::scale(exMatrix, exMatrix, fontSize / 24.0f, fontSize / 24.0f, 1.0f); const mat4 vtxMatrix = translatedMatrix(properties.translate, id, properties.translateAnchor); @@ -44,7 +44,7 @@ void Painter::renderText(TextBucket& bucket, const std::string& layer_name, cons textShader->setGamma(2.5f / fontSize / map.getState().getPixelRatio()); // Convert the -pi..pi to an int8 range. - float angle = round((map.getState().getAngle() + rotate) / M_PI * 128); + float angle = std::round((map.getState().getAngle() + rotate) / M_PI * 128); // adjust min/max zooms for variable font sies float zoomAdjust = log(fontSize / bucket.geom_desc.font_size) / log(2); @@ -75,8 +75,8 @@ void Painter::renderText(TextBucket& bucket, const std::string& layer_name, cons float startingZ = history.front().z; const FrameSnapshot lastFrame = history.back(); float endingZ = lastFrame.z; - float lowZ = fmin(startingZ, endingZ); - float highZ = fmax(startingZ, endingZ); + float lowZ = std::fmin(startingZ, endingZ); + float highZ = std::fmax(startingZ, endingZ); // Calculate the speed of zooming, and how far it would zoom in terms of zoom levels in one duration float zoomDiff = endingZ - history[1].z, @@ -91,8 +91,8 @@ void Painter::renderText(TextBucket& bucket, const std::string& layer_name, cons float bump = (currentTime - lastFrame.timestamp) / duration * fadedist; textShader->setFadeDist(fadedist * 10); - textShader->setMinFadeZoom(floor(lowZ * 10)); - textShader->setMaxFadeZoom(floor(highZ * 10)); + textShader->setMinFadeZoom(std::floor(lowZ * 10)); + textShader->setMaxFadeZoom(std::floor(highZ * 10)); textShader->setFadeZoom((map.getState().getZoom() + bump) * 10); // We're drawing in the translucent pass which is bottom-to-top, so we need diff --git a/src/style/properties.cpp b/src/style/properties.cpp index 46e84ce9b..6563d5431 100644 --- a/src/style/properties.cpp +++ b/src/style/properties.cpp @@ -52,7 +52,7 @@ float functions::stops(float z, const std::vector& stops) { // Linear interpolation if base is 0 if (smaller_val == 0) return factor * larger_val; // Exponential interpolation between the values - return smaller_val * pow(larger_val / smaller_val, factor); + return smaller_val * std::pow(larger_val / smaller_val, factor); } else if (larger || smaller) { // Do not draw a line. return -std::numeric_limits::infinity(); @@ -77,7 +77,7 @@ float functions::linear(float z, const std::vector& values) { const float min = values[3]; const float max = values[4]; - return fmin(fmax(min, val + (z - z_base) * slope), max); + return std::fmin(std::fmax(min, val + (z - z_base) * slope), max); } float functions::exponential(float z, const std::vector& values) { @@ -91,5 +91,5 @@ float functions::exponential(float z, const std::vector& values) { const float min = values[3]; const float max = values[4]; - return fmin(fmax(min, val + pow(1.75, (z - z_base)) * slope), max); + return std::fmin(std::fmax(min, val + std::pow(1.75, (z - z_base)) * slope), max); } diff --git a/src/text/collision.cpp b/src/text/collision.cpp index ddfa90a1d..e8bd24153 100644 --- a/src/text/collision.cpp +++ b/src/text/collision.cpp @@ -104,7 +104,7 @@ PlacementProperty Collision::place(const PlacedGlyphs &placed_glyphs, const CollisionRect &box = glyph.box; float x12 = box.tl.x * box.tl.x, y12 = box.tl.y * box.tl.y, x22 = box.br.x * box.br.x, y22 = box.br.y * box.br.y, - diag = sqrt( + diag = std::sqrt( util::max(x12 + y12, x12 + y22, x22 + y12, x22 + y22)); glyph.bbox = CollisionRect{{-diag, -diag}, {diag, diag}}; @@ -147,7 +147,7 @@ float Collision::getPlacementScale(const GlyphBoxes &glyphs, return -1; } - float minScale = fmax(minPlacementScale, glyph.minScale); + float minScale = std::fmax(minPlacementScale, glyph.minScale); float maxScale = glyph.maxScale; if (minScale >= maxScale) { @@ -184,7 +184,7 @@ float Collision::getPlacementScale(const GlyphBoxes &glyphs, } // todo: unhardcode the 8 = tileExtent/tileSize - float padding = fmax(pad, placement.padding) * 8.0f; + float padding = std::fmax(pad, placement.padding) * 8.0f; // Original algorithm: float s1 = (ob.tl.x - nb.br.x - padding) / @@ -207,7 +207,7 @@ float Collision::getPlacementScale(const GlyphBoxes &glyphs, s3 = s4 = 1; } - float collisionFreeScale = fmin(fmax(s1, s2), fmax(s3, s4)); + float collisionFreeScale = std::fmin(std::fmax(s1, s2), std::fmax(s3, s4)); // Only update label's min scale if the glyph was // restricted by a collision @@ -278,12 +278,12 @@ PlacementRange Collision::getPlacementRange(const GlyphBoxes &glyphs, if (!(intersectX && intersectY)) continue; - float scale = fmax(placementScale, b.placementScale); + float scale = std::fmax(placementScale, b.placementScale); // TODO? glyph.box or glyph.bbox? CollisionRange range = rotationRange(glyph, b, scale); - placementRange[0] = fmin(placementRange[0], range[0]); - placementRange[1] = fmax(placementRange[1], range[1]); + placementRange[0] = std::fmin(placementRange[0], range[0]); + placementRange[1] = std::fmax(placementRange[1], range[1]); } } @@ -300,7 +300,7 @@ void Collision::insert(const GlyphBoxes &glyphs, const CollisionAnchor &anchor, const CollisionRect &bbox = glyph.bbox; const CollisionRect &box = glyph.box; - float minScale = fmax(placementScale, glyph.minScale); + float minScale = std::fmax(placementScale, glyph.minScale); Box bounds{Point{anchor.x + bbox.tl.x / minScale, anchor.y + bbox.tl.y / minScale}, diff --git a/src/text/placement.cpp b/src/text/placement.cpp index 15cb78751..5c8b15474 100644 --- a/src/text/placement.cpp +++ b/src/text/placement.cpp @@ -28,7 +28,7 @@ Placement::Placement(int8_t zoom) // glyphs be placed, slowing down collision checking. Only place labels if // they will show up within the intended zoom range of the tile. // TODO make this not hardcoded to 3 - maxPlacementScale(exp(log(2) * util::min((25.5 - zoom), 3.0))) {} + maxPlacementScale(std::exp(log(2) * util::min((25.5 - zoom), 3.0))) {} bool byScale(const Anchor &a, const Anchor &b) { return a.scale < b.scale; } @@ -95,20 +95,20 @@ void getSegmentGlyphs(std::back_insert_iterator glyphs, float prevscale = std::numeric_limits::infinity(); float prevAngle = 0.0f; - offset = fabs(offset); + offset = std::fabs(offset); const float placementScale = anchor.scale; while (true) { const float dist = util::dist(newAnchor, end); const float scale = offset / dist; - float angle = -atan2(end.x - newAnchor.x, end.y - newAnchor.y) + + float angle = -std::atan2(end.x - newAnchor.x, end.y - newAnchor.y) + direction * M_PI / 2.0f; if (upsideDown) angle += M_PI; // Don't place around sharp corners - float angleDiff = fmod((angle - prevAngle), (2.0f * M_PI)); + float angleDiff = std::fmod((angle - prevAngle), (2.0f * M_PI)); if (prevAngle && angleDiff > maxAngleDelta) { anchor.scale = prevscale; break; @@ -120,7 +120,7 @@ void getSegmentGlyphs(std::back_insert_iterator glyphs, /* minScale */ scale, /* maxScale */ prevscale, /* angle */ static_cast( - fmod((angle + 2.0 * M_PI), (2.0 * M_PI)))}; + std::fmod((angle + 2.0 * M_PI), (2.0 * M_PI)))}; if (scale <= placementScale) break; @@ -228,8 +228,8 @@ PlacedGlyphs getGlyphs(Anchor &anchor, float advance, const Shaping &shaping, if (angle) { // Compute the transformation matrix. - float angle_sin = sin(angle); - float angle_cos = cos(angle); + float angle_sin = std::sin(angle); + float angle_cos = std::cos(angle); std::array matrix = { {angle_cos, -angle_sin, angle_sin, angle_cos}}; @@ -251,7 +251,7 @@ PlacedGlyphs getGlyphs(Anchor &anchor, float advance, const Shaping &shaping, glyphs.emplace_back(PlacedGlyph{ tl, tr, bl, br, glyph.rect, width, height, static_cast( - fmod((anchor.angle + rotate + instance.offset + 2 * M_PI), + std::fmod((anchor.angle + rotate + instance.offset + 2 * M_PI), (2 * M_PI))), GlyphBox{box, instance.minScale, instance.maxScale, instance.anchor, horizontal}}); diff --git a/src/text/rotation_range.cpp b/src/text/rotation_range.cpp index 3c1244763..9cbf958b7 100644 --- a/src/text/rotation_range.cpp +++ b/src/text/rotation_range.cpp @@ -54,19 +54,19 @@ rotatingRotatingCollisions(const CollisionRect &a, const CollisionRect &b, // Calculate angles at which collisions may occur const std::array c = {{ // top/bottom - /*[0]*/ static_cast(asin((float)(a.br.y - b.tl.y) / d)), - /*[1]*/ static_cast(asin((float)(a.br.y - b.tl.y) / d) + M_PI), + /*[0]*/ static_cast(std::asin((float)(a.br.y - b.tl.y) / d)), + /*[1]*/ static_cast(std::asin((float)(a.br.y - b.tl.y) / d) + M_PI), /*[2]*/ static_cast(2 * M_PI - - asin((float)(-a.tl.y + b.br.y) / d)), - /*[3]*/ static_cast(M_PI - asin((float)(-a.tl.y + b.br.y) / d)), + std::asin((float)(-a.tl.y + b.br.y) / d)), + /*[3]*/ static_cast(M_PI - std::asin((float)(-a.tl.y + b.br.y) / d)), // left/right /*[4]*/ static_cast(2 * M_PI - - acos((float)(a.br.x - b.tl.x) / d)), - /*[5]*/ static_cast(acos((float)(a.br.x - b.tl.x) / d)), - /*[6]*/ static_cast(M_PI - acos((float)(-a.tl.x + b.br.x) / d)), + std::acos((float)(a.br.x - b.tl.x) / d)), + /*[5]*/ static_cast(std::acos((float)(a.br.x - b.tl.x) / d)), + /*[6]*/ static_cast(M_PI - std::acos((float)(-a.tl.x + b.br.x) / d)), /*[7]*/ static_cast(M_PI + - acos((float)(-a.tl.x + b.br.x) / d))}}; + std::acos((float)(-a.tl.x + b.br.x) / d))}}; const float rl = a.br.x - b.tl.x; const float lr = -a.tl.x + b.br.x; @@ -98,7 +98,7 @@ rotatingRotatingCollisions(const CollisionRect &a, const CollisionRect &b, // between anchors. // Convert the angles to angles from north. f.push_back( - fmod((c[i] + angleBetweenAnchors + 2 * M_PI), (2 * M_PI))); + std::fmod((c[i] + angleBetweenAnchors + 2 * M_PI), (2 * M_PI))); } } @@ -117,7 +117,7 @@ rotatingRotatingCollisions(const CollisionRect &a, const CollisionRect &b, double getAngle(const CollisionPoint &p1, const CollisionPoint &p2, CollisionAngle d, const CollisionPoint &corner) { - return fmod(util::angle_between(util::interp(p1.x, p2.x, d), + return std::fmod(util::angle_between(util::interp(p1.x, p2.x, d), util::interp(p1.y, p2.y, d), corner.x, corner.y) + 2 * M_PI, @@ -141,8 +141,8 @@ void circleEdgeCollisions(std::back_insert_iterator angles, // a collision exists only if line intersects circle at two points if (discriminant > 0) { - CollisionAngle x1 = (-b - sqrt(discriminant)) / (2 * a); - CollisionAngle x2 = (-b + sqrt(discriminant)) / (2 * a); + CollisionAngle x1 = (-b - std::sqrt(discriminant)) / (2 * a); + CollisionAngle x2 = (-b + std::sqrt(discriminant)) / (2 * a); // only add points if within line segment // hack to handle floating point representations of 0 and 1 diff --git a/src/util/mat4.cpp b/src/util/mat4.cpp index e86c9e35e..5f9f50bcd 100644 --- a/src/util/mat4.cpp +++ b/src/util/mat4.cpp @@ -113,8 +113,8 @@ void matrix::translate(mat4& out, const mat4& a, float x, float y, float z) { } void matrix::rotate_z(mat4& out, const mat4& a, float rad) { - float s = sin(rad), - c = cos(rad), + float s = std::sin(rad), + c = std::cos(rad), a00 = a[0], a01 = a[1], a02 = a[2], diff --git a/test/rotation_range.cpp b/test/rotation_range.cpp index 41b23f1f8..cb7ee0742 100644 --- a/test/rotation_range.cpp +++ b/test/rotation_range.cpp @@ -49,8 +49,8 @@ TEST(RotationRange, rotatingFixedCollisions) { CollisionRect{CollisionPoint{1.4142, -10}, CollisionPoint{10, 10}}); EXPECT_EQ(1, collisions.size()); - EXPECT_EQ(135, round(deg(collisions.front()[0]))); - EXPECT_EQ(135, round(deg(collisions.front()[1]))); + EXPECT_EQ(135, std::round(deg(collisions.front()[0]))); + EXPECT_EQ(135, std::round(deg(collisions.front()[1]))); } TEST(RotationRange, cornerBoxCollisions) { @@ -122,10 +122,10 @@ TEST(RotationRange, rotatingRotatingCollisions) { CollisionAnchor{1, 1}); EXPECT_EQ(2, c.size()); - EXPECT_EQ(135, round(deg(c[0][0]))); - EXPECT_EQ(135, round(deg(c[0][1]))); - EXPECT_EQ(315, round(deg(c[1][0]))); - EXPECT_EQ(315, round(deg(c[1][1]))); + EXPECT_EQ(135, std::round(deg(c[0][0]))); + EXPECT_EQ(135, std::round(deg(c[0][1]))); + EXPECT_EQ(315, std::round(deg(c[1][0]))); + EXPECT_EQ(315, std::round(deg(c[1][1]))); } { From afc54b7956ca77dded9c80194954b22148258f5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Wed, 14 May 2014 16:51:27 +0200 Subject: [PATCH 11/14] add translate-anchor for fills --- include/llmr/style/properties.hpp | 2 ++ src/renderer/painter_fill.cpp | 12 +++++------- src/style/style.cpp | 1 + src/style/style_parser.cpp | 30 +++++++++++++++++------------- 4 files changed, 25 insertions(+), 20 deletions(-) diff --git a/include/llmr/style/properties.hpp b/include/llmr/style/properties.hpp index eae2351f4..c2fce21e1 100644 --- a/include/llmr/style/properties.hpp +++ b/include/llmr/style/properties.hpp @@ -105,6 +105,7 @@ struct LineProperties { struct FillClass { FunctionProperty enabled = true; std::array translate = {{ 0, 0 }}; + TranslateAnchor translateAnchor = TranslateAnchor::Map; Winding winding = Winding::NonZero; FunctionProperty antialias = true; Color fill_color = {{ 0, 0, 0, 1 }}; @@ -116,6 +117,7 @@ struct FillClass { struct FillProperties { bool enabled = true; std::array translate = {{ 0, 0 }}; + TranslateAnchor translateAnchor = TranslateAnchor::Map; Winding winding = Winding::NonZero; bool antialias = true; Color fill_color = {{ 0, 0, 0, 1 }}; diff --git a/src/renderer/painter_fill.cpp b/src/renderer/painter_fill.cpp index b412d8570..543df440d 100644 --- a/src/renderer/painter_fill.cpp +++ b/src/renderer/painter_fill.cpp @@ -35,13 +35,13 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons stroke_color = fill_color; } - translateLayer(properties.translate, id); + const mat4 vtxMatrix = translatedMatrix(properties.translate, id, properties.translateAnchor); // Because we're drawing top-to-bottom, and we update the stencil mask // below, we have to draw the outline first (!) if (outline && pass == Translucent) { useProgram(outlineShader->program); - outlineShader->setMatrix(matrix); + outlineShader->setMatrix(vtxMatrix); lineWidth(2.0f); // This is always fixed and does not depend on the pixelRatio! outlineShader->setColor(stroke_color); @@ -93,7 +93,7 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons }; useProgram(patternShader->program); - patternShader->setMatrix(matrix); + patternShader->setMatrix(vtxMatrix); patternShader->setOffset(offset); patternShader->setPatternSize(imageSize); patternShader->setPatternTopLeft({{ imagePos.tl.x, imagePos.tl.y }}); @@ -111,7 +111,7 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons // fragments // Draw filling rectangle. useProgram(plainShader->program); - plainShader->setMatrix(matrix); + plainShader->setMatrix(vtxMatrix); plainShader->setColor(fill_color); // Draw the actual triangles into the color & stencil buffer. @@ -124,7 +124,7 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons // below, we have to draw the outline first (!) if (fringeline && pass == Translucent) { useProgram(outlineShader->program); - outlineShader->setMatrix(matrix); + outlineShader->setMatrix(vtxMatrix); lineWidth(2.0f); // This is always fixed and does not depend on the pixelRatio! outlineShader->setColor(fill_color); @@ -138,6 +138,4 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons glDepthRange(strata + strata_epsilon, 1.0f); bucket.drawVertices(*outlineShader); } - - translateLayer(properties.translate, id, true); } diff --git a/src/style/style.cpp b/src/style/style.cpp index ecb86108e..b6f22ea20 100644 --- a/src/style/style.cpp +++ b/src/style/style.cpp @@ -40,6 +40,7 @@ void Style::cascade(float z) { fill.enabled = layer.enabled.evaluate(z); fill.translate = {{ layer.translate[0].evaluate(z), layer.translate[1].evaluate(z) }}; + fill.translateAnchor = layer.translateAnchor; fill.winding = layer.winding; fill.antialias = layer.antialias.evaluate(z); fill.fill_color = layer.fill_color; diff --git a/src/style/style_parser.cpp b/src/style/style_parser.cpp index 83c408dd3..3f9370919 100644 --- a/src/style/style_parser.cpp +++ b/src/style/style_parser.cpp @@ -194,6 +194,19 @@ void StyleParser::parseConstants(JSVal value) { } } +TranslateAnchor parseTranslateAnchor(JSVal anchor) { + if (anchor.IsString()) { + std::string a { anchor.GetString(), anchor.GetStringLength() }; + if (a == "viewport") { + return TranslateAnchor::Viewport; + } else { + return TranslateAnchor::Map; + } + } else { + throw Style::exception("translate anchor must be a string"); + } +} + void StyleParser::parseClasses(JSVal value, std::map& classes, std::map& buckets, std::vector& layers) { if (value.IsArray()) { for (rapidjson::SizeType i = 0; i < value.Size(); ++i) { @@ -434,6 +447,10 @@ FillClass StyleParser::parseFillClass(JSVal value) { klass.translate = std::array {{ values[0], values[1] }}; } + if (value.HasMember("translate-anchor")) { + klass.translateAnchor = parseTranslateAnchor(value["translate-anchor"]); + } + if (value.HasMember("color")) { klass.fill_color = parseColor(value["color"]); } @@ -530,19 +547,6 @@ PointClass StyleParser::parsePointClass(JSVal value) { return klass; } -TranslateAnchor parseTranslateAnchor(JSVal anchor) { - if (anchor.IsString()) { - std::string a { anchor.GetString(), anchor.GetStringLength() }; - if (a == "viewport") { - return TranslateAnchor::Viewport; - } else { - return TranslateAnchor::Map; - } - } else { - throw Style::exception("translate anchor must be a string"); - } -} - TextClass StyleParser::parseTextClass(JSVal value) { TextClass klass; From 3d84dd60c9f5457a96368712c97ecf49e3c19bd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Wed, 14 May 2014 17:10:34 +0200 Subject: [PATCH 12/14] always cast a building shadow to the bottom --- bin/style.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bin/style.js b/bin/style.js index 0c70ffb23..fa0e915f7 100644 --- a/bin/style.js +++ b/bin/style.js @@ -1005,9 +1005,10 @@ module.exports = { "building_shadow": { "color": "building_shadow", "translate": [ - 2, - 2 + 1, + 1 ], + "translate-anchor": "viewport", "opacity": [ "stops", { "z": 0, From a27f8798ff1dd254abf2e19b91f0cb50dae364ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Wed, 14 May 2014 17:17:29 +0200 Subject: [PATCH 13/14] add translate-anchor: viewport to lines + points refs #189 --- include/llmr/renderer/painter.hpp | 1 - include/llmr/style/properties.hpp | 4 ++++ src/renderer/painter.cpp | 9 --------- src/renderer/painter_line.cpp | 8 +++----- src/renderer/painter_point.cpp | 10 ++++------ src/style/style.cpp | 2 ++ src/style/style_parser.cpp | 8 ++++++++ 7 files changed, 21 insertions(+), 21 deletions(-) diff --git a/include/llmr/renderer/painter.hpp b/include/llmr/renderer/painter.hpp index 2aa0353ca..323d5016d 100644 --- a/include/llmr/renderer/painter.hpp +++ b/include/llmr/renderer/painter.hpp @@ -89,7 +89,6 @@ public: bool needsAnimation() const; private: void setupShaders(); - void translateLayer(const std::array &translation, const Tile::ID &id, bool reverse = false); mat4 translatedMatrix(const std::array &translation, const Tile::ID &id, TranslateAnchor anchor = TranslateAnchor::Map); void prepareTile(const Tile& tile); diff --git a/include/llmr/style/properties.hpp b/include/llmr/style/properties.hpp index c2fce21e1..2fd43f8f5 100644 --- a/include/llmr/style/properties.hpp +++ b/include/llmr/style/properties.hpp @@ -63,6 +63,7 @@ struct FunctionProperty { struct PointClass { FunctionProperty enabled = true; std::array translate = {{ 0, 0 }}; + TranslateAnchor translateAnchor = TranslateAnchor::Map; FunctionProperty size; Color color = {{ 0, 0, 0, 1 }}; FunctionProperty opacity = 1; @@ -74,6 +75,7 @@ struct PointClass { struct PointProperties { bool enabled = true; std::array translate = {{ 0, 0 }}; + TranslateAnchor translateAnchor = TranslateAnchor::Map; float size = 0; Color color = {{ 0, 0, 0, 1 }}; float opacity = 1.0; @@ -85,6 +87,7 @@ struct PointProperties { struct LineClass { FunctionProperty enabled = true; std::array translate = {{ 0, 0 }}; + TranslateAnchor translateAnchor = TranslateAnchor::Map; FunctionProperty width; FunctionProperty offset; Color color = {{ 0, 0, 0, 1 }}; @@ -95,6 +98,7 @@ struct LineClass { struct LineProperties { bool enabled = true; std::array translate = {{ 0, 0 }}; + TranslateAnchor translateAnchor = TranslateAnchor::Map; float width = 0; float offset = 0; Color color = {{ 0, 0, 0, 1 }}; diff --git a/src/renderer/painter.cpp b/src/renderer/painter.cpp index c6c4a7932..f214e4a59 100644 --- a/src/renderer/painter.cpp +++ b/src/renderer/painter.cpp @@ -171,15 +171,6 @@ void Painter::renderTileLayer(const Tile& tile, const LayerDescription &layer_de } } -void Painter::translateLayer(const std::array &translation, const Tile::ID &id, bool reverse) { - if (translation[0] || translation[1]) { - const int direction = reverse ? -1 : 1; - // TODO: Get rid of the 8 (scaling from 4096 to tile size) - const double factor = direction * ((double)(1 << id.z)) / map.getState().getScale() * (4096.0 / util::tileSize); - matrix::translate(matrix, matrix, translation[0] * factor, translation[1] * factor, 0); - } -} - mat4 Painter::translatedMatrix(const std::array &translation, const Tile::ID &id, TranslateAnchor anchor) { if (translation[0] == 0 && translation[1] == 0) { return matrix; diff --git a/src/renderer/painter_line.cpp b/src/renderer/painter_line.cpp index 6856c93af..8d60f4c81 100644 --- a/src/renderer/painter_line.cpp +++ b/src/renderer/painter_line.cpp @@ -33,14 +33,14 @@ void Painter::renderLine(LineBucket& bucket, const std::string& layer_name, cons float dash_length = properties.dash_array[0]; float dash_gap = properties.dash_array[1]; - translateLayer(properties.translate, id); + const mat4 vtxMatrix = translatedMatrix(properties.translate, id, properties.translateAnchor); glDepthRange(strata, 1.0f); // We're only drawing end caps + round line joins if the line is > 2px. Otherwise, they aren't visible anyway. if (bucket.hasPoints() && outset > 1.0f) { useProgram(linejoinShader->program); - linejoinShader->setMatrix(matrix); + linejoinShader->setMatrix(vtxMatrix); linejoinShader->setColor(color); linejoinShader->setWorld({{ map.getState().getFramebufferWidth() * 0.5f, @@ -79,7 +79,7 @@ void Painter::renderLine(LineBucket& bucket, const std::string& layer_name, cons } else { useProgram(lineShader->program); - lineShader->setMatrix(matrix); + lineShader->setMatrix(vtxMatrix); lineShader->setExtrudeMatrix(extrudeMatrix); lineShader->setDashArray({{ dash_length, dash_gap }}); lineShader->setLineWidth({{ outset, inset }}); @@ -87,6 +87,4 @@ void Painter::renderLine(LineBucket& bucket, const std::string& layer_name, cons lineShader->setColor(color); bucket.drawLines(*lineShader); } - - translateLayer(properties.translate, id, true); } diff --git a/src/renderer/painter_point.cpp b/src/renderer/painter_point.cpp index 2bb2da672..64e2ae77f 100644 --- a/src/renderer/painter_point.cpp +++ b/src/renderer/painter_point.cpp @@ -17,8 +17,6 @@ void Painter::renderPoint(PointBucket& bucket, const std::string& layer_name, co const PointProperties& properties = point_properties_it->second; if (!properties.enabled) return; - translateLayer(properties.translate, id); - Color color = properties.color; color[0] *= properties.opacity; color[1] *= properties.opacity; @@ -37,9 +35,11 @@ void Painter::renderPoint(PointBucket& bucket, const std::string& layer_name, co imagePos = sprite->getPosition(sized_image, false); } + const mat4 vtxMatrix = translatedMatrix(properties.translate, id, properties.translateAnchor); + if (!imagePos.size) { useProgram(dotShader->program); - dotShader->setMatrix(matrix); + dotShader->setMatrix(vtxMatrix); dotShader->setColor(color); const float pointSize = (properties.radius ? properties.radius * 2 : 8) * map.getState().getPixelRatio(); @@ -55,7 +55,7 @@ void Painter::renderPoint(PointBucket& bucket, const std::string& layer_name, co bucket.drawPoints(*dotShader); } else { useProgram(pointShader->program); - pointShader->setMatrix(matrix); + pointShader->setMatrix(vtxMatrix); pointShader->setColor(color); pointShader->setImage(0); @@ -75,6 +75,4 @@ void Painter::renderPoint(PointBucket& bucket, const std::string& layer_name, co glDepthRange(strata, 1.0f); bucket.drawPoints(*pointShader); } - - translateLayer(properties.translate, id, true); } diff --git a/src/style/style.cpp b/src/style/style.cpp index b6f22ea20..54ebe0936 100644 --- a/src/style/style.cpp +++ b/src/style/style.cpp @@ -60,6 +60,7 @@ void Style::cascade(float z) { stroke.enabled = layer.enabled.evaluate(z); stroke.translate = {{ layer.translate[0].evaluate(z), layer.translate[1].evaluate(z) }}; + stroke.translateAnchor = layer.translateAnchor; stroke.width = layer.width.evaluate(z); stroke.offset = layer.offset.evaluate(z); stroke.color = layer.color; @@ -79,6 +80,7 @@ void Style::cascade(float z) { point.enabled = layer.enabled.evaluate(z); point.translate = {{ layer.translate[0].evaluate(z), layer.translate[1].evaluate(z) }}; + point.translateAnchor = layer.translateAnchor; point.color = layer.color; point.size = layer.size.evaluate(z); point.opacity = layer.opacity.evaluate(z); diff --git a/src/style/style_parser.cpp b/src/style/style_parser.cpp index 3f9370919..e41ceba4d 100644 --- a/src/style/style_parser.cpp +++ b/src/style/style_parser.cpp @@ -488,6 +488,10 @@ LineClass StyleParser::parseLineClass(JSVal value) { klass.translate = std::array {{ values[0], values[1] }}; } + if (value.HasMember("translate-anchor")) { + klass.translateAnchor = parseTranslateAnchor(value["translate-anchor"]); + } + if (value.HasMember("color")) { klass.color = parseColor(value["color"]); } @@ -520,6 +524,10 @@ PointClass StyleParser::parsePointClass(JSVal value) { klass.translate = std::array {{ values[0], values[1] }}; } + if (value.HasMember("translate-anchor")) { + klass.translateAnchor = parseTranslateAnchor(value["translate-anchor"]); + } + if (value.HasMember("color")) { klass.color = parseColor(value["color"]); } From a9d559fe5158091f72f408dfa8d1d367f222348c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Wed, 14 May 2014 17:21:12 +0200 Subject: [PATCH 14/14] return refs to avoid matrix allocation/deallocation for untranslated layers refs #189 --- include/llmr/renderer/painter.hpp | 3 ++- src/renderer/painter.cpp | 10 +++++----- src/renderer/painter_fill.cpp | 2 +- src/renderer/painter_line.cpp | 2 +- src/renderer/painter_point.cpp | 2 +- src/renderer/painter_text.cpp | 2 +- 6 files changed, 11 insertions(+), 10 deletions(-) diff --git a/include/llmr/renderer/painter.hpp b/include/llmr/renderer/painter.hpp index 323d5016d..73281a906 100644 --- a/include/llmr/renderer/painter.hpp +++ b/include/llmr/renderer/painter.hpp @@ -89,7 +89,7 @@ public: bool needsAnimation() const; private: void setupShaders(); - mat4 translatedMatrix(const std::array &translation, const Tile::ID &id, TranslateAnchor anchor = TranslateAnchor::Map); + const mat4 &translatedMatrix(const std::array &translation, const Tile::ID &id, TranslateAnchor anchor = TranslateAnchor::Map); void prepareTile(const Tile& tile); void useProgram(uint32_t program); @@ -98,6 +98,7 @@ private: public: mat4 matrix; + mat4 vtxMatrix; mat4 projMatrix; mat4 nativeMatrix; mat4 extrudeMatrix; diff --git a/src/renderer/painter.cpp b/src/renderer/painter.cpp index f214e4a59..833f7b6a4 100644 --- a/src/renderer/painter.cpp +++ b/src/renderer/painter.cpp @@ -171,28 +171,28 @@ void Painter::renderTileLayer(const Tile& tile, const LayerDescription &layer_de } } -mat4 Painter::translatedMatrix(const std::array &translation, const Tile::ID &id, TranslateAnchor anchor) { +const mat4 &Painter::translatedMatrix(const std::array &translation, const Tile::ID &id, TranslateAnchor anchor) { if (translation[0] == 0 && translation[1] == 0) { return matrix; } else { // TODO: Get rid of the 8 (scaling from 4096 to tile size) const double factor = ((double)(1 << id.z)) / map.getState().getScale() * (4096.0 / util::tileSize); - mat4 result; if (anchor == TranslateAnchor::Viewport) { const double sin_a = std::sin(-map.getState().getAngle()); const double cos_a = std::cos(-map.getState().getAngle()); - matrix::translate(result, matrix, + matrix::translate(vtxMatrix, matrix, factor * (translation[0] * cos_a - translation[1] * sin_a), factor * (translation[0] * sin_a + translation[1] * cos_a), 0); } else { - matrix::translate(result, matrix, + matrix::translate(vtxMatrix, matrix, factor * translation[0], factor * translation[1], 0); } - return result; + + return vtxMatrix; } } diff --git a/src/renderer/painter_fill.cpp b/src/renderer/painter_fill.cpp index 543df440d..6193e3068 100644 --- a/src/renderer/painter_fill.cpp +++ b/src/renderer/painter_fill.cpp @@ -35,7 +35,7 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons stroke_color = fill_color; } - const mat4 vtxMatrix = translatedMatrix(properties.translate, id, properties.translateAnchor); + const mat4 &vtxMatrix = translatedMatrix(properties.translate, id, properties.translateAnchor); // Because we're drawing top-to-bottom, and we update the stencil mask // below, we have to draw the outline first (!) diff --git a/src/renderer/painter_line.cpp b/src/renderer/painter_line.cpp index 8d60f4c81..8dc486201 100644 --- a/src/renderer/painter_line.cpp +++ b/src/renderer/painter_line.cpp @@ -33,7 +33,7 @@ void Painter::renderLine(LineBucket& bucket, const std::string& layer_name, cons float dash_length = properties.dash_array[0]; float dash_gap = properties.dash_array[1]; - const mat4 vtxMatrix = translatedMatrix(properties.translate, id, properties.translateAnchor); + const mat4 &vtxMatrix = translatedMatrix(properties.translate, id, properties.translateAnchor); glDepthRange(strata, 1.0f); diff --git a/src/renderer/painter_point.cpp b/src/renderer/painter_point.cpp index 64e2ae77f..84861367d 100644 --- a/src/renderer/painter_point.cpp +++ b/src/renderer/painter_point.cpp @@ -35,7 +35,7 @@ void Painter::renderPoint(PointBucket& bucket, const std::string& layer_name, co imagePos = sprite->getPosition(sized_image, false); } - const mat4 vtxMatrix = translatedMatrix(properties.translate, id, properties.translateAnchor); + const mat4 &vtxMatrix = translatedMatrix(properties.translate, id, properties.translateAnchor); if (!imagePos.size) { useProgram(dotShader->program); diff --git a/src/renderer/painter_text.cpp b/src/renderer/painter_text.cpp index d1abbb526..c083da964 100644 --- a/src/renderer/painter_text.cpp +++ b/src/renderer/painter_text.cpp @@ -31,7 +31,7 @@ void Painter::renderText(TextBucket& bucket, const std::string& layer_name, cons float fontSize = std::fmin(properties.size, bucket.geom_desc.font_size); matrix::scale(exMatrix, exMatrix, fontSize / 24.0f, fontSize / 24.0f, 1.0f); - const mat4 vtxMatrix = translatedMatrix(properties.translate, id, properties.translateAnchor); + const mat4 &vtxMatrix = translatedMatrix(properties.translate, id, properties.translateAnchor); useProgram(textShader->program); textShader->setMatrix(vtxMatrix);