From 99c5976498f09ca2dffd46dd6e26d2a26b9efc13 Mon Sep 17 00:00:00 2001 From: Ansis Brammanis Date: Thu, 20 Aug 2015 13:18:48 -0400 Subject: [PATCH] port minor collision code cleanup, fix #1705 https://github.com/mapbox/mapbox-gl-js/pull/1261 --- src/mbgl/map/live_tile_data.cpp | 4 +- src/mbgl/map/tile_worker.cpp | 11 ++--- src/mbgl/map/tile_worker.hpp | 2 +- src/mbgl/map/vector_tile_data.cpp | 4 +- src/mbgl/renderer/bucket.hpp | 3 +- src/mbgl/renderer/symbol_bucket.cpp | 71 ++++++++++++++--------------- src/mbgl/renderer/symbol_bucket.hpp | 21 ++++++--- src/mbgl/text/collision_tile.cpp | 8 ++-- src/mbgl/text/collision_tile.hpp | 9 +--- src/mbgl/text/quads.cpp | 42 ++++++++--------- src/mbgl/text/quads.hpp | 6 +-- 11 files changed, 89 insertions(+), 92 deletions(-) diff --git a/src/mbgl/map/live_tile_data.cpp b/src/mbgl/map/live_tile_data.cpp index 9ac9c730f..0b73b52f3 100644 --- a/src/mbgl/map/live_tile_data.cpp +++ b/src/mbgl/map/live_tile_data.cpp @@ -25,9 +25,7 @@ LiveTileData::LiveTileData(const TileID& id_, style_, style_.layers, state, - std::make_unique(id_.z, 4096, - source_.tile_size * id.overscaling, - 0, 0, false)) { + std::make_unique(0, 0, false)) { state = State::loaded; if (!tile) { diff --git a/src/mbgl/map/tile_worker.cpp b/src/mbgl/map/tile_worker.cpp index 0b9175c53..06de585a3 100644 --- a/src/mbgl/map/tile_worker.cpp +++ b/src/mbgl/map/tile_worker.cpp @@ -25,7 +25,7 @@ TileWorker::TileWorker(TileID id_, maxZoom(maxZoom_), style(style_), state(state_), - collision(std::move(collision_)) { + collisionTile(std::move(collision_)) { assert(style.sprite); } @@ -56,12 +56,11 @@ TileParseResult TileWorker::parse(const GeometryTile& geometryTile) { } void TileWorker::redoPlacement(float angle, float pitch, bool collisionDebug) { - collision->reset(angle, pitch); - collision->setDebug(collisionDebug); + collisionTile = std::make_unique(angle, pitch, collisionDebug); for (auto i = layers.rbegin(); i != layers.rend(); i++) { auto bucket = getBucket(**i); if (bucket) { - bucket->placeFeatures(); + bucket->placeFeatures(*collisionTile); } } } @@ -224,7 +223,7 @@ std::unique_ptr TileWorker::createCircleBucket(const GeometryTileLayer& std::unique_ptr TileWorker::createSymbolBucket(const GeometryTileLayer& layer, const StyleBucket& bucket_desc) { - auto bucket = std::make_unique(*collision, id.overscaling); + auto bucket = std::make_unique(id.overscaling, id.z); const float z = id.z; auto& layout = bucket->layout; @@ -283,7 +282,7 @@ std::unique_ptr TileWorker::createSymbolBucket(const GeometryTileLayer& } bucket->addFeatures(reinterpret_cast(this), *style.spriteAtlas, *style.glyphAtlas, - *style.glyphStore); + *style.glyphStore, *collisionTile); return bucket->hasData() ? std::move(bucket) : nullptr; } diff --git a/src/mbgl/map/tile_worker.hpp b/src/mbgl/map/tile_worker.hpp index b8a93011e..62527b9fd 100644 --- a/src/mbgl/map/tile_worker.hpp +++ b/src/mbgl/map/tile_worker.hpp @@ -75,7 +75,7 @@ private: TriangleElementsBuffer triangleElementsBuffer; LineElementsBuffer lineElementsBuffer; - std::unique_ptr collision; + std::unique_ptr collisionTile; // Contains all the Bucket objects for the tile. Buckets are render // objects and they get added to this map as they get processed. diff --git a/src/mbgl/map/vector_tile_data.cpp b/src/mbgl/map/vector_tile_data.cpp index 60297396e..678a3867c 100644 --- a/src/mbgl/map/vector_tile_data.cpp +++ b/src/mbgl/map/vector_tile_data.cpp @@ -26,9 +26,7 @@ VectorTileData::VectorTileData(const TileID& id_, style_, style_.layers, state, - std::make_unique(id_.z, 4096, - source_.tile_size * id.overscaling, - angle, pitch, collisionDebug)), + std::make_unique(angle, pitch, collisionDebug)), source(source_), lastAngle(angle), currentAngle(angle) { diff --git a/src/mbgl/renderer/bucket.hpp b/src/mbgl/renderer/bucket.hpp index 4bdb766a7..c6a7b788d 100644 --- a/src/mbgl/renderer/bucket.hpp +++ b/src/mbgl/renderer/bucket.hpp @@ -12,6 +12,7 @@ namespace mbgl { class Painter; class StyleLayer; class TileID; +class CollisionTile; class Bucket : private util::noncopyable { public: @@ -29,7 +30,7 @@ public: return !uploaded; } - virtual void placeFeatures() {} + virtual void placeFeatures(CollisionTile&) {} virtual void swapRenderData() {} protected: diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp index 16ba3cf1a..7665fd9a6 100644 --- a/src/mbgl/renderer/symbol_bucket.cpp +++ b/src/mbgl/renderer/symbol_bucket.cpp @@ -53,8 +53,8 @@ SymbolInstance::SymbolInstance(Anchor &anchor, const std::vector &li iconCollisionFeature(line, anchor, shapedIcon, iconBoxScale, iconPadding, iconAlongLine) {}; -SymbolBucket::SymbolBucket(CollisionTile &collision_, float overscaling_) - : collision(collision_), overscaling(overscaling_) { +SymbolBucket::SymbolBucket(float overscaling_, float zoom_) + : overscaling(overscaling_), zoom(zoom_), tileSize(512 * overscaling_), tilePixelRatio(tileExtent / tileSize) { } SymbolBucket::~SymbolBucket() { @@ -174,7 +174,8 @@ bool SymbolBucket::needsDependencies(const GeometryTileLayer& layer, void SymbolBucket::addFeatures(uintptr_t tileUID, SpriteAtlas& spriteAtlas, GlyphAtlas& glyphAtlas, - GlyphStore& glyphStore) { + GlyphStore& glyphStore, + CollisionTile& collisionTile) { float horizontalAlign = 0.5; float verticalAlign = 0.5; @@ -264,7 +265,7 @@ void SymbolBucket::addFeatures(uintptr_t tileUID, features.clear(); - placeFeatures(true); + placeFeatures(collisionTile, true); } @@ -275,13 +276,13 @@ void SymbolBucket::addFeature(const std::vector> &lines, const float glyphSize = 24.0f; const float fontScale = layout.text.size / glyphSize; - const float textBoxScale = collision.tilePixelRatio * fontScale; - const float textMaxBoxScale = collision.tilePixelRatio * layout.text.max_size / glyphSize; - const float iconBoxScale = collision.tilePixelRatio * layout.icon.size; - const float symbolSpacing = collision.tilePixelRatio * layout.spacing; + const float textBoxScale = tilePixelRatio * fontScale; + const float textMaxBoxScale = tilePixelRatio * layout.text.max_size / glyphSize; + const float iconBoxScale = tilePixelRatio * layout.icon.size; + const float symbolSpacing = tilePixelRatio * layout.spacing; const bool avoidEdges = layout.avoid_edges && layout.placement != PlacementType::Line; - const float textPadding = layout.text.padding * collision.tilePixelRatio; - const float iconPadding = layout.icon.padding * collision.tilePixelRatio; + const float textPadding = layout.text.padding * tilePixelRatio; + const float iconPadding = layout.icon.padding * tilePixelRatio; const float textMaxAngle = layout.text.max_angle * M_PI / 180; const bool textAlongLine = layout.text.rotation_alignment == RotationAlignmentType::Map && @@ -354,11 +355,11 @@ bool SymbolBucket::anchorIsTooClose(const std::u32string &text, const float repe return false; } -void SymbolBucket::placeFeatures() { - placeFeatures(false); +void SymbolBucket::placeFeatures(CollisionTile& collisionTile) { + placeFeatures(collisionTile, false); } -void SymbolBucket::placeFeatures(bool swapImmediately) { +void SymbolBucket::placeFeatures(CollisionTile& collisionTile, bool swapImmediately) { renderDataInProgress = std::make_unique(); @@ -380,8 +381,8 @@ void SymbolBucket::placeFeatures(bool swapImmediately) { // Don't sort symbols that won't overlap because it isn't necessary and // because it causes more labels to pop in and out when rotating. if (mayOverlap) { - float sin = std::sin(collision.angle); - float cos = std::cos(collision.angle); + float sin = std::sin(collisionTile.angle); + float cos = std::cos(collisionTile.angle); std::sort(symbolInstances.begin(), symbolInstances.end(), [sin, cos](SymbolInstance &a, SymbolInstance &b) { const float aRotated = sin * a.x + cos * a.y; @@ -401,9 +402,9 @@ void SymbolBucket::placeFeatures(bool swapImmediately) { // Calculate the scales at which the text and icon can be placed without collision. float glyphScale = hasText && !layout.text.allow_overlap ? - collision.placeFeature(symbolInstance.textCollisionFeature) : collision.minScale; + collisionTile.placeFeature(symbolInstance.textCollisionFeature) : collisionTile.minScale; float iconScale = hasIcon && !layout.icon.allow_overlap ? - collision.placeFeature(symbolInstance.iconCollisionFeature) : collision.minScale; + collisionTile.placeFeature(symbolInstance.iconCollisionFeature) : collisionTile.minScale; // Combine the scales for icons and text. @@ -421,33 +422,32 @@ void SymbolBucket::placeFeatures(bool swapImmediately) { if (hasText) { if (!layout.text.ignore_placement) { - collision.insertFeature(symbolInstance.textCollisionFeature, glyphScale); + collisionTile.insertFeature(symbolInstance.textCollisionFeature, glyphScale); } - if (glyphScale < collision.maxScale) { + if (glyphScale < collisionTile.maxScale) { addSymbols(renderDataInProgress->text, - symbolInstance.glyphQuads, glyphScale, layout.text.keep_upright, textAlongLine); + symbolInstance.glyphQuads, glyphScale, layout.text.keep_upright, textAlongLine, collisionTile.angle); } } if (hasIcon) { if (!layout.icon.ignore_placement) { - collision.insertFeature(symbolInstance.iconCollisionFeature, iconScale); + collisionTile.insertFeature(symbolInstance.iconCollisionFeature, iconScale); } - if (iconScale < collision.maxScale) { + if (iconScale < collisionTile.maxScale) { addSymbols(renderDataInProgress->icon, - symbolInstance.iconQuads, iconScale, layout.icon.keep_upright, iconAlongLine); + symbolInstance.iconQuads, iconScale, layout.icon.keep_upright, iconAlongLine, collisionTile.angle); } } } - if (collision.getDebug()) addToDebugBuffers(); + if (collisionTile.getDebug()) addToDebugBuffers(collisionTile); if (swapImmediately) swapRenderData(); } template -void SymbolBucket::addSymbols(Buffer &buffer, const SymbolQuads &symbols, float scale, const bool keepUpright, const bool alongLine) { - const float zoom = collision.zoom; +void SymbolBucket::addSymbols(Buffer &buffer, const SymbolQuads &symbols, float scale, const bool keepUpright, const bool alongLine, const float placementAngle) { const float placementZoom = ::fmax(std::log(scale) / std::log(2) + zoom, 0); @@ -461,10 +461,10 @@ void SymbolBucket::addSymbols(Buffer &buffer, const SymbolQuads &symbols, float float minZoom = util::max(static_cast(zoom + log(symbol.minScale) / log(2)), placementZoom); float maxZoom = util::min(static_cast(zoom + log(symbol.maxScale) / log(2)), 25.0f); - const auto &glyphAnchor = symbol.anchor; + const auto &anchorPoint = symbol.anchorPoint; // drop upside down versions of glyphs - const float a = std::fmod(symbol.angle + collision.angle + M_PI, M_PI * 2); + const float a = std::fmod(symbol.angle + placementAngle + M_PI, M_PI * 2); if (keepUpright && alongLine && (a <= M_PI / 2 || a > M_PI * 3 / 2)) continue; @@ -491,13 +491,13 @@ void SymbolBucket::addSymbols(Buffer &buffer, const SymbolQuads &symbols, float uint32_t triangleIndex = triangleGroup.vertex_length; // coordinates (2 triangles) - buffer.vertices.add(glyphAnchor.x, glyphAnchor.y, tl.x, tl.y, tex.x, tex.y, minZoom, + buffer.vertices.add(anchorPoint.x, anchorPoint.y, tl.x, tl.y, tex.x, tex.y, minZoom, maxZoom, placementZoom); - buffer.vertices.add(glyphAnchor.x, glyphAnchor.y, tr.x, tr.y, tex.x + tex.w, tex.y, + buffer.vertices.add(anchorPoint.x, anchorPoint.y, tr.x, tr.y, tex.x + tex.w, tex.y, minZoom, maxZoom, placementZoom); - buffer.vertices.add(glyphAnchor.x, glyphAnchor.y, bl.x, bl.y, tex.x, tex.y + tex.h, + buffer.vertices.add(anchorPoint.x, anchorPoint.y, bl.x, bl.y, tex.x, tex.y + tex.h, minZoom, maxZoom, placementZoom); - buffer.vertices.add(glyphAnchor.x, glyphAnchor.y, br.x, br.y, tex.x + tex.w, tex.y + tex.h, + buffer.vertices.add(anchorPoint.x, anchorPoint.y, br.x, br.y, tex.x + tex.w, tex.y + tex.h, minZoom, maxZoom, placementZoom); // add the two triangles, referencing the four coordinates we just inserted. @@ -509,11 +509,10 @@ void SymbolBucket::addSymbols(Buffer &buffer, const SymbolQuads &symbols, float } } -void SymbolBucket::addToDebugBuffers() { +void SymbolBucket::addToDebugBuffers(CollisionTile &collisionTile) { - const float yStretch = collision.yStretch; - const float angle = collision.angle; - const float zoom = collision.zoom; + const float yStretch = collisionTile.yStretch; + const float angle = collisionTile.angle; float angle_sin = std::sin(-angle); float angle_cos = std::cos(-angle); std::array matrix = {{angle_cos, -angle_sin, angle_sin, angle_cos}}; diff --git a/src/mbgl/renderer/symbol_bucket.hpp b/src/mbgl/renderer/symbol_bucket.hpp index 3a181be55..c8264bc43 100644 --- a/src/mbgl/renderer/symbol_bucket.hpp +++ b/src/mbgl/renderer/symbol_bucket.hpp @@ -64,7 +64,7 @@ class SymbolBucket : public Bucket { typedef ElementGroup<1> CollisionBoxElementGroup; public: - SymbolBucket(CollisionTile &collision, float overscaling); + SymbolBucket(float overscaling, float zoom); ~SymbolBucket() override; void upload() override; @@ -77,7 +77,8 @@ public: void addFeatures(uintptr_t tileUID, SpriteAtlas&, GlyphAtlas&, - GlyphStore&); + GlyphStore&, + CollisionTile&); void drawGlyphs(SDFShader& shader); void drawIcons(SDFShader& shader); @@ -88,7 +89,7 @@ public: const FilterExpression&, GlyphStore&, Sprite&); - void placeFeatures() override; + void placeFeatures(CollisionTile&) override; private: void addFeature(const std::vector> &lines, @@ -97,22 +98,28 @@ private: bool anchorIsTooClose(const std::u32string &text, const float repeatDistance, Anchor &anchor); std::map> compareText; - void addToDebugBuffers(); + void addToDebugBuffers(CollisionTile &collisionTile); - void placeFeatures(bool swapImmediately); + void placeFeatures(CollisionTile& collisionTile, bool swapImmediately); void swapRenderData() override; // Adds placed items to the buffer. template - void addSymbols(Buffer &buffer, const SymbolQuads &symbols, float scale, const bool keepUpright, const bool alongLine); + void addSymbols(Buffer &buffer, const SymbolQuads &symbols, float scale, + const bool keepUpright, const bool alongLine, const float placementAngle); public: StyleLayoutSymbol layout; bool sdfIcons = false; private: - CollisionTile &collision; + const float overscaling; + const float zoom; + const float tileSize; + const float tileExtent = 4096.0f; + const float tilePixelRatio; + std::vector symbolInstances; std::vector features; diff --git a/src/mbgl/text/collision_tile.cpp b/src/mbgl/text/collision_tile.cpp index b80d756c3..d18860ccf 100644 --- a/src/mbgl/text/collision_tile.cpp +++ b/src/mbgl/text/collision_tile.cpp @@ -3,13 +3,13 @@ namespace mbgl { -void CollisionTile::reset(const float _angle, const float pitch) { +CollisionTile::CollisionTile(const float angle_, const float pitch, bool debug_) : + angle(angle_), debug(debug_) { tree.clear(); - angle = _angle; // Compute the transformation matrix. - float angle_sin = std::sin(_angle); - float angle_cos = std::cos(_angle); + float angle_sin = std::sin(angle); + float angle_cos = std::cos(angle); rotationMatrix = {{angle_cos, -angle_sin, angle_sin, angle_cos}}; // Stretch boxes in y direction to account for the map tilt. diff --git a/src/mbgl/text/collision_tile.hpp b/src/mbgl/text/collision_tile.hpp index 632652256..3fd1b0a4c 100644 --- a/src/mbgl/text/collision_tile.hpp +++ b/src/mbgl/text/collision_tile.hpp @@ -35,19 +35,14 @@ namespace mbgl { class CollisionTile { public: - inline explicit CollisionTile(float _zoom, float tileExtent, float tileSize, float angle_, float pitch_, bool debug_) : - zoom(_zoom), tilePixelRatio(tileExtent / tileSize), debug(debug_) { reset(angle_, pitch_); } + explicit CollisionTile(float angle_, float pitch_, bool debug_); - void reset(const float angle, const float pitch); float placeFeature(const CollisionFeature &feature); void insertFeature(CollisionFeature &feature, const float minPlacementScale); - void setDebug(bool debug_) { debug = debug_; } bool getDebug() { return debug; } - const float zoom; - const float tilePixelRatio; - float angle = 0; + const float angle = 0; const float minScale = 0.5f; const float maxScale = 2.0f; diff --git a/src/mbgl/text/quads.cpp b/src/mbgl/text/quads.cpp index 943439615..19c48d731 100644 --- a/src/mbgl/text/quads.cpp +++ b/src/mbgl/text/quads.cpp @@ -50,12 +50,12 @@ SymbolQuads getIconQuads(Anchor &anchor, const PositionedIcon &shapedIcon, } struct GlyphInstance { - explicit GlyphInstance(const vec2 &anchor_) : anchor(anchor_) {} - explicit GlyphInstance(const vec2 &anchor_, float offset_, float minScale_, float maxScale_, + explicit GlyphInstance(const vec2 &anchorPoint_) : anchorPoint(anchorPoint_) {} + explicit GlyphInstance(const vec2 &anchorPoint_, float offset_, float minScale_, float maxScale_, float angle_) - : anchor(anchor_), offset(offset_), minScale(minScale_), maxScale(maxScale_), angle(angle_) {} + : anchorPoint(anchorPoint_), offset(offset_), minScale(minScale_), maxScale(maxScale_), angle(angle_) {} - const vec2 anchor; + const vec2 anchorPoint; const float offset = 0.0f; const float minScale = globalMinScale; const float maxScale = std::numeric_limits::infinity(); @@ -65,19 +65,19 @@ struct GlyphInstance { typedef std::vector GlyphInstances; void getSegmentGlyphs(std::back_insert_iterator glyphs, Anchor &anchor, - float offset, const std::vector &line, int segment, int8_t direction) { + float offset, const std::vector &line, int segment, bool forward) { - const bool upsideDown = direction < 0; + const bool upsideDown = !forward; if (offset < 0) - direction *= -1; + forward = !forward; - if (direction > 0) + if (forward) segment++; assert((int)line.size() > segment); vec2 end = line[segment]; - vec2 newAnchor = anchor; + vec2 newAnchorPoint = anchor; float prevscale = std::numeric_limits::infinity(); offset = std::fabs(offset); @@ -85,16 +85,16 @@ void getSegmentGlyphs(std::back_insert_iterator glyphs, Anchor & const float placementScale = anchor.scale; while (true) { - const float dist = util::dist(newAnchor, end); + const float dist = util::dist(newAnchorPoint, end); const float scale = offset / dist; - float angle = std::atan2(end.y - newAnchor.y, end.x - newAnchor.x); - if (direction < 0) + float angle = std::atan2(end.y - newAnchorPoint.y, end.x - newAnchorPoint.x); + if (!forward) angle += M_PI; if (upsideDown) angle += M_PI; glyphs = GlyphInstance{ - /* anchor */ newAnchor, + /* anchor */ newAnchorPoint, /* offset */ static_cast(upsideDown ? M_PI : 0.0), /* minScale */ scale, /* maxScale */ prevscale, @@ -103,11 +103,11 @@ void getSegmentGlyphs(std::back_insert_iterator glyphs, Anchor & if (scale <= placementScale) break; - newAnchor = end; + newAnchorPoint = end; // skip duplicate nodes - while (newAnchor == end) { - segment += direction; + while (newAnchorPoint == end) { + segment += forward ? 1 : -1; if ((int)line.size() <= segment || segment < 0) { anchor.scale = scale; return; @@ -115,8 +115,8 @@ void getSegmentGlyphs(std::back_insert_iterator glyphs, Anchor & end = line[segment]; } - vec2 normal = util::normal(newAnchor, end) * dist; - newAnchor = newAnchor - normal; + vec2 normal = util::normal(newAnchorPoint, end) * dist; + newAnchorPoint = newAnchorPoint - normal; prevscale = scale; } @@ -148,9 +148,9 @@ SymbolQuads getGlyphQuads(Anchor &anchor, const Shaping &shapedText, GlyphInstances glyphInstances; if (alongLine) { - getSegmentGlyphs(std::back_inserter(glyphInstances), anchor, centerX, line, anchor.segment, 1); + getSegmentGlyphs(std::back_inserter(glyphInstances), anchor, centerX, line, anchor.segment, true); if (keepUpright) - getSegmentGlyphs(std::back_inserter(glyphInstances), anchor, centerX, line, anchor.segment, -1); + getSegmentGlyphs(std::back_inserter(glyphInstances), anchor, centerX, line, anchor.segment, false); } else { glyphInstances.emplace_back(GlyphInstance{anchor}); @@ -194,7 +194,7 @@ SymbolQuads getGlyphQuads(Anchor &anchor, const Shaping &shapedText, const float glyphMinScale = std::max(instance.minScale, anchor.scale); const float glyphAngle = std::fmod((anchor.angle + textRotate + instance.offset + 2 * M_PI), (2 * M_PI)); - quads.emplace_back(tl, tr, bl, br, rect, glyphAngle, instance.anchor, glyphMinScale, instance.maxScale); + quads.emplace_back(tl, tr, bl, br, rect, glyphAngle, instance.anchorPoint, glyphMinScale, instance.maxScale); } diff --git a/src/mbgl/text/quads.hpp b/src/mbgl/text/quads.hpp index b47cc718b..97fdb6a1f 100644 --- a/src/mbgl/text/quads.hpp +++ b/src/mbgl/text/quads.hpp @@ -11,7 +11,7 @@ namespace mbgl { struct SymbolQuad { explicit SymbolQuad(const vec2 &tl_, const vec2 &tr_, const vec2 &bl_, const vec2 &br_, - const Rect &tex_, float angle_, const vec2 &anchor_, + const Rect &tex_, float angle_, const vec2 &anchorPoint_, float minScale_, float maxScale_) : tl(tl_), tr(tr_), @@ -19,14 +19,14 @@ namespace mbgl { br(br_), tex(tex_), angle(angle_), - anchor(anchor_), + anchorPoint(anchorPoint_), minScale(minScale_), maxScale(maxScale_) {} vec2 tl, tr, bl, br; Rect tex; float angle; - vec2 anchor; + vec2 anchorPoint; float minScale, maxScale; };