summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Loer <chris.loer@gmail.com>2017-10-26 11:36:25 -0700
committerChris Loer <chris.loer@gmail.com>2017-10-31 10:25:57 -0700
commit27ec6fd20e049bf2c241f253bededd78f0275743 (patch)
treea0c7e241954d194a520bc2c756c28d86030c4f93
parent18871964b19212840ee366c3623e5c997e9e4419 (diff)
downloadqtlocation-mapboxgl-27ec6fd20e049bf2c241f253bededd78f0275743.tar.gz
Stop doing collision detection in background.
Remove CollisionTile. "Placement" in background is now just "layout for symbol buckets" (as opposed to layout for non-symbol buckets, which finishes in "redoLayout").
-rw-r--r--cmake/core-files.cmake2
-rw-r--r--src/mbgl/geometry/feature_index.cpp8
-rw-r--r--src/mbgl/geometry/feature_index.hpp4
-rw-r--r--src/mbgl/layout/symbol_layout.cpp100
-rw-r--r--src/mbgl/layout/symbol_layout.hpp7
-rw-r--r--src/mbgl/renderer/buckets/symbol_bucket.hpp5
-rw-r--r--src/mbgl/text/collision_feature.hpp6
-rw-r--r--src/mbgl/text/collision_tile.cpp267
-rw-r--r--src/mbgl/text/collision_tile.hpp71
-rw-r--r--src/mbgl/tile/geometry_tile.cpp36
-rw-r--r--src/mbgl/tile/geometry_tile.hpp10
-rw-r--r--src/mbgl/tile/geometry_tile_worker.cpp31
-rw-r--r--src/mbgl/tile/geometry_tile_worker.hpp2
-rw-r--r--src/mbgl/tile/tile.hpp2
14 files changed, 35 insertions, 516 deletions
diff --git a/cmake/core-files.cmake b/cmake/core-files.cmake
index d578c652ac..59697b41a5 100644
--- a/cmake/core-files.cmake
+++ b/cmake/core-files.cmake
@@ -479,8 +479,6 @@ set(MBGL_CORE_FILES
src/mbgl/text/collision_feature.hpp
src/mbgl/text/collision_index.cpp
src/mbgl/text/collision_index.hpp
- src/mbgl/text/collision_tile.cpp
- src/mbgl/text/collision_tile.hpp
src/mbgl/text/cross_tile_symbol_index.cpp
src/mbgl/text/cross_tile_symbol_index.hpp
src/mbgl/text/get_anchors.cpp
diff --git a/src/mbgl/geometry/feature_index.cpp b/src/mbgl/geometry/feature_index.cpp
index cef531f1fd..447fe508e2 100644
--- a/src/mbgl/geometry/feature_index.cpp
+++ b/src/mbgl/geometry/feature_index.cpp
@@ -2,7 +2,7 @@
#include <mbgl/renderer/render_layer.hpp>
#include <mbgl/renderer/query.hpp>
#include <mbgl/renderer/layers/render_symbol_layer.hpp>
-#include <mbgl/text/collision_tile.hpp>
+#include <mbgl/text/collision_index.hpp>
#include <mbgl/util/constants.hpp>
#include <mbgl/util/math.hpp>
#include <mbgl/math/minmax.hpp>
@@ -51,7 +51,7 @@ void FeatureIndex::query(
const GeometryTileData& geometryTileData,
const CanonicalTileID& tileID,
const std::vector<const RenderLayer*>& layers,
- const CollisionTile* collisionTile,
+ const CollisionIndex* collisionIndex,
const float additionalQueryRadius) const {
// Determine query radius
@@ -76,11 +76,11 @@ void FeatureIndex::query(
}
// Query symbol features, if they've been placed.
- if (!collisionTile) {
+ if (!collisionIndex) {
return;
}
- std::vector<IndexedSubfeature> symbolFeatures = collisionTile->queryRenderedSymbols(queryGeometry, scale);
+ std::vector<IndexedSubfeature> symbolFeatures;// = collisionIndex->queryRenderedSymbols(queryGeometry, UnwrappedTileID(), scale); // TODO: hook up
std::sort(symbolFeatures.begin(), symbolFeatures.end(), topDownSymbols);
for (const auto& symbolFeature : symbolFeatures) {
addFeature(result, symbolFeature, queryGeometry, queryOptions, geometryTileData, tileID, layers, bearing, pixelsToTileUnits);
diff --git a/src/mbgl/geometry/feature_index.hpp b/src/mbgl/geometry/feature_index.hpp
index 2ae7da33df..f998ab12b8 100644
--- a/src/mbgl/geometry/feature_index.hpp
+++ b/src/mbgl/geometry/feature_index.hpp
@@ -14,7 +14,7 @@ namespace mbgl {
class RenderedQueryOptions;
class RenderLayer;
-class CollisionTile;
+class CollisionIndex;
class CanonicalTileID;
class IndexedSubfeature {
@@ -42,7 +42,7 @@ public:
const GeometryTileData&,
const CanonicalTileID&,
const std::vector<const RenderLayer*>&,
- const CollisionTile*,
+ const CollisionIndex*,
const float additionalQueryRadius) const;
static optional<GeometryCoordinates> translateQueryGeometry(
diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp
index 3f4abe59f6..b9f3bb8f8d 100644
--- a/src/mbgl/layout/symbol_layout.cpp
+++ b/src/mbgl/layout/symbol_layout.cpp
@@ -8,7 +8,6 @@
#include <mbgl/renderer/image_atlas.hpp>
#include <mbgl/style/layers/symbol_layer_impl.hpp>
#include <mbgl/text/get_anchors.hpp>
-#include <mbgl/text/collision_tile.hpp>
#include <mbgl/text/shaping.hpp>
#include <mbgl/util/constants.hpp>
#include <mbgl/util/utf.hpp>
@@ -392,7 +391,7 @@ bool SymbolLayout::anchorIsTooClose(const std::u16string& text, const float repe
return false;
}
-std::unique_ptr<SymbolBucket> SymbolLayout::place(CollisionTile& collisionTile) {
+std::unique_ptr<SymbolBucket> SymbolLayout::place() {
auto bucket = std::make_unique<SymbolBucket>(layout, layerPaintProperties, textSize, iconSize, zoom, sdfIcons, iconsNeedLinear, symbolInstances);
// Calculate which labels can be shown and when they can be shown and
@@ -405,94 +404,37 @@ std::unique_ptr<SymbolBucket> SymbolLayout::place(CollisionTile& collisionTile)
? SymbolPlacementType::Point
: layout.get<SymbolPlacement>();
- const bool mayOverlap = layout.get<TextAllowOverlap>() || layout.get<IconAllowOverlap>() ||
- layout.get<TextIgnorePlacement>() || layout.get<IconIgnorePlacement>();
-
const bool keepUpright = layout.get<TextKeepUpright>();
- // Sort symbols by their y position on the canvas so that they lower symbols
- // are drawn on top of higher symbols.
- // 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) {
- const float sin = std::sin(collisionTile.config.angle);
- const float cos = std::cos(collisionTile.config.angle);
-
- std::sort(symbolInstances.begin(), symbolInstances.end(), [sin, cos](SymbolInstance &a, SymbolInstance &b) {
- const int32_t aRotated = sin * a.anchor.point.x + cos * a.anchor.point.y;
- const int32_t bRotated = sin * b.anchor.point.x + cos * b.anchor.point.y;
- return aRotated != bRotated ?
- aRotated < bRotated :
- a.index > b.index;
- });
- }
-
// this iterates over the *bucket's* symbol instances so that it can set the placedsymbol index. TODO cleanup
for (SymbolInstance &symbolInstance : bucket->symbolInstances) {
const bool hasText = symbolInstance.hasText;
const bool hasIcon = symbolInstance.hasIcon;
- const bool iconWithoutText = layout.get<TextOptional>() || !hasText;
- const bool textWithoutIcon = layout.get<IconOptional>() || !hasIcon;
-
- // Calculate the scales at which the text and icon can be placed without collision.
-
- float glyphScale = hasText ?
- collisionTile.placeFeature(symbolInstance.textCollisionFeature,
- layout.get<TextAllowOverlap>(), layout.get<SymbolAvoidEdges>()) :
- collisionTile.minScale;
- float iconScale = hasIcon ?
- collisionTile.placeFeature(symbolInstance.iconCollisionFeature,
- layout.get<IconAllowOverlap>(), layout.get<SymbolAvoidEdges>()) :
- collisionTile.minScale;
-
-
- // Combine the scales for icons and text.
-
- if (!iconWithoutText && !textWithoutIcon) {
- iconScale = glyphScale = util::max(iconScale, glyphScale);
- } else if (!textWithoutIcon && glyphScale) {
- glyphScale = util::max(iconScale, glyphScale);
- } else if (!iconWithoutText && iconScale) {
- iconScale = util::max(iconScale, glyphScale);
- }
-
const auto& feature = features.at(symbolInstance.featureIndex);
// Insert final placement into collision tree and add glyphs/icons to buffers
if (hasText) {
- const float placementZoom = util::max(util::log2(glyphScale) + zoom, 0.0f);
- collisionTile.insertFeature(symbolInstance.textCollisionFeature, glyphScale, layout.get<TextIgnorePlacement>());
- if (glyphScale < collisionTile.maxScale) {
-
- const float labelAngle = std::fmod((symbolInstance.anchor.angle + collisionTile.config.angle) + 2 * M_PI, 2 * M_PI);
- const bool inVerticalRange = (
- (labelAngle > M_PI * 1.0 / 4.0 && labelAngle <= M_PI * 3.0 / 4) ||
- (labelAngle > M_PI * 5.0 / 4.0 && labelAngle <= M_PI * 7.0 / 4));
- const bool useVerticalMode = symbolInstance.writingModes & WritingModeType::Vertical && inVerticalRange;
-
- const Range<float> sizeData = bucket->textSizeBinder->getVertexSizeData(feature);
- bucket->text.placedSymbols.emplace_back(symbolInstance.anchor.point, symbolInstance.anchor.segment, sizeData.min, sizeData.max,
- symbolInstance.textOffset, placementZoom, useVerticalMode, symbolInstance.line);
- symbolInstance.placedTextIndices.push_back(bucket->text.placedSymbols.size() - 1);
-
- for (const auto& symbol : symbolInstance.glyphQuads) {
- addSymbol(
- bucket->text, sizeData, symbol,
- keepUpright, textPlacement, symbolInstance.anchor, bucket->text.placedSymbols.back());
- }
+ const bool useVerticalMode = false; // TODO: Add both versions of glyphs to buckets
+ const Range<float> sizeData = bucket->textSizeBinder->getVertexSizeData(feature);
+ bucket->text.placedSymbols.emplace_back(symbolInstance.anchor.point, symbolInstance.anchor.segment, sizeData.min, sizeData.max,
+ symbolInstance.textOffset, useVerticalMode, symbolInstance.line);
+ symbolInstance.placedTextIndices.push_back(bucket->text.placedSymbols.size() - 1);
+
+ for (const auto& symbol : symbolInstance.glyphQuads) {
+ addSymbol(
+ bucket->text, sizeData, symbol,
+ keepUpright, textPlacement, symbolInstance.anchor, bucket->text.placedSymbols.back());
}
}
if (hasIcon) {
- const float placementZoom = util::max(util::log2(iconScale) + zoom, 0.0f);
- collisionTile.insertFeature(symbolInstance.iconCollisionFeature, iconScale, layout.get<IconIgnorePlacement>());
- if (iconScale < collisionTile.maxScale && symbolInstance.iconQuad) {
+ if (symbolInstance.iconQuad) {
const Range<float> sizeData = bucket->iconSizeBinder->getVertexSizeData(feature);
bucket->icon.placedSymbols.emplace_back(symbolInstance.anchor.point, symbolInstance.anchor.segment, sizeData.min, sizeData.max,
- symbolInstance.iconOffset, placementZoom, false, symbolInstance.line);
+ symbolInstance.iconOffset, false, symbolInstance.line);
symbolInstance.placedIconIndices.push_back(bucket->icon.placedSymbols.size() - 1);
addSymbol(
bucket->icon, sizeData, *symbolInstance.iconQuad,
@@ -506,8 +448,8 @@ std::unique_ptr<SymbolBucket> SymbolLayout::place(CollisionTile& collisionTile)
}
}
- if (collisionTile.config.debug) {
- addToDebugBuffers(collisionTile, *bucket);
+ if (true) { // TODO: hook up showCollisionBoxes
+ addToDebugBuffers(*bucket);
}
return bucket;
@@ -572,14 +514,12 @@ void SymbolLayout::addSymbol(Buffer& buffer,
placedSymbol.glyphOffsets.push_back(symbol.glyphOffset.x);
}
-void SymbolLayout::addToDebugBuffers(CollisionTile& collisionTile, SymbolBucket& bucket) {
+void SymbolLayout::addToDebugBuffers(SymbolBucket& bucket) {
if (!hasSymbolInstances()) {
return;
}
- const float yStretch = collisionTile.yStretch;
-
for (const SymbolInstance &symbolInstance : symbolInstances) {
auto populateCollisionBox = [&](const auto& feature) {
SymbolBucket::CollisionBuffer& collisionBuffer = feature.alongLine ?
@@ -588,10 +528,10 @@ void SymbolLayout::addToDebugBuffers(CollisionTile& collisionTile, SymbolBucket&
for (const CollisionBox &box : feature.boxes) {
auto& anchor = box.anchor;
- Point<float> tl{box.x1, box.y1 * yStretch};
- Point<float> tr{box.x2, box.y1 * yStretch};
- Point<float> bl{box.x1, box.y2 * yStretch};
- Point<float> br{box.x2, box.y2 * yStretch};
+ Point<float> tl{box.x1, box.y1};
+ Point<float> tr{box.x2, box.y1};
+ Point<float> bl{box.x1, box.y2};
+ Point<float> br{box.x2, box.y2};
static constexpr std::size_t vertexLength = 4;
const std::size_t indexLength = feature.alongLine ? 4 : 8;
diff --git a/src/mbgl/layout/symbol_layout.hpp b/src/mbgl/layout/symbol_layout.hpp
index 8cd5e7ec05..b9b11f26b9 100644
--- a/src/mbgl/layout/symbol_layout.hpp
+++ b/src/mbgl/layout/symbol_layout.hpp
@@ -16,7 +16,6 @@
namespace mbgl {
class BucketParameters;
-class CollisionTile;
class SymbolBucket;
class Anchor;
class RenderLayer;
@@ -35,9 +34,9 @@ public:
GlyphDependencies&);
void prepare(const GlyphMap&, const GlyphPositions&,
- const ImageMap&, const ImagePositions&);
+ const ImageMap&, const ImagePositions&);
- std::unique_ptr<SymbolBucket> place(CollisionTile&);
+ std::unique_ptr<SymbolBucket> place();
bool hasSymbolInstances() const;
@@ -57,7 +56,7 @@ private:
bool anchorIsTooClose(const std::u16string& text, const float repeatDistance, const Anchor&);
std::map<std::u16string, std::vector<Anchor>> compareText;
- void addToDebugBuffers(CollisionTile&, SymbolBucket&);
+ void addToDebugBuffers(SymbolBucket&);
// Adds placed items to the buffer.
template <typename Buffer>
diff --git a/src/mbgl/renderer/buckets/symbol_bucket.hpp b/src/mbgl/renderer/buckets/symbol_bucket.hpp
index c2292d45f1..f57d2ff7ed 100644
--- a/src/mbgl/renderer/buckets/symbol_bucket.hpp
+++ b/src/mbgl/renderer/buckets/symbol_bucket.hpp
@@ -19,9 +19,9 @@ namespace mbgl {
class PlacedSymbol {
public:
PlacedSymbol(Point<float> anchorPoint_, uint16_t segment_, float lowerSize_, float upperSize_,
- std::array<float, 2> lineOffset_, float placementZoom_, bool useVerticalMode_, GeometryCoordinates line_) :
+ std::array<float, 2> lineOffset_, bool useVerticalMode_, GeometryCoordinates line_) :
anchorPoint(anchorPoint_), segment(segment_), lowerSize(lowerSize_), upperSize(upperSize_),
- lineOffset(lineOffset_), placementZoom(placementZoom_), useVerticalMode(useVerticalMode_), line(std::move(line_))
+ lineOffset(lineOffset_), useVerticalMode(useVerticalMode_), line(std::move(line_))
{
// TODO WIP hook these up
writingMode = WritingModeType::None;
@@ -33,7 +33,6 @@ public:
float lowerSize;
float upperSize;
std::array<float, 2> lineOffset;
- float placementZoom;
bool useVerticalMode;
GeometryCoordinates line;
std::vector<float> tileDistances;
diff --git a/src/mbgl/text/collision_feature.hpp b/src/mbgl/text/collision_feature.hpp
index edfaa924c9..8094f13a54 100644
--- a/src/mbgl/text/collision_feature.hpp
+++ b/src/mbgl/text/collision_feature.hpp
@@ -38,12 +38,6 @@ public:
float tileUnitDistanceToAnchor;
float radius;
-
- // TODO Placeholders for old collision tiles
- float maxScale;
- float placementScale;
- float adjustedMaxScale(const std::array<float, 4>& , const float) const { return 1; }
-
};
class CollisionFeature {
diff --git a/src/mbgl/text/collision_tile.cpp b/src/mbgl/text/collision_tile.cpp
deleted file mode 100644
index cc9b602f08..0000000000
--- a/src/mbgl/text/collision_tile.cpp
+++ /dev/null
@@ -1,267 +0,0 @@
-#include <mbgl/text/collision_tile.hpp>
-#include <mbgl/geometry/feature_index.hpp>
-#include <mbgl/math/log2.hpp>
-#include <mbgl/util/constants.hpp>
-#include <mbgl/util/math.hpp>
-#include <mbgl/math/minmax.hpp>
-#include <mbgl/util/intersection_tests.hpp>
-
-#include <mapbox/geometry/envelope.hpp>
-#include <mapbox/geometry/multi_point.hpp>
-
-#include <cmath>
-
-namespace mbgl {
-
-CollisionTile::CollisionTile(PlacementConfig config_) : config(std::move(config_)) {
- // Compute the transformation matrix.
- const float angle_sin = std::sin(config.angle);
- const float angle_cos = std::cos(config.angle);
- rotationMatrix = { { angle_cos, -angle_sin, angle_sin, angle_cos } };
- reverseRotationMatrix = { { angle_cos, angle_sin, -angle_sin, angle_cos } };
-
- perspectiveRatio =
- 1.0f +
- 0.5f * (util::division(config.cameraToTileDistance, config.cameraToCenterDistance, 1.0f) -
- 1.0f);
-
- minScale /= perspectiveRatio;
- maxScale /= perspectiveRatio;
-
- // We can only approximate here based on the y position of the tile
- // The shaders calculate a more accurate "incidence_stretch"
- // at render time to calculate an effective scale for collision
- // purposes, but we still want to use the yStretch approximation
- // here because we can't adjust the aspect ratio of the collision
- // boxes at render time.
- yStretch = util::max(
- 1.0f, util::division(config.cameraToTileDistance,
- config.cameraToCenterDistance * std::cos(config.pitch), 1.0f));
-}
-
-float CollisionTile::findPlacementScale(const Point<float>& anchor, const CollisionBox& box, const float boxMaxScale, const Point<float>& blockingAnchor, const CollisionBox& blocking) {
- float minPlacementScale = minScale;
-
- // Find the lowest scale at which the two boxes can fit side by side without overlapping.
- // Original algorithm:
-
- const float s1 = util::division(blocking.x1 - box.x2, anchor.x - blockingAnchor.x,
- 1.0f); // scale at which new box is to the left of old box
- const float s2 = util::division(blocking.x2 - box.x1, anchor.x - blockingAnchor.x,
- 1.0f); // scale at which new box is to the right of old box
- const float s3 = util::division((blocking.y1 - box.y2) * yStretch, anchor.y - blockingAnchor.y,
- 1.0f); // scale at which new box is to the top of old box
- const float s4 = util::division((blocking.y2 - box.y1) * yStretch, anchor.y - blockingAnchor.y,
- 1.0f); // scale at which new box is to the bottom of old box
-
- float collisionFreeScale = util::min(util::max(s1, s2), util::max(s3, s4));
-
- if (collisionFreeScale > blocking.maxScale) {
- // After a box's maxScale the label has shrunk enough that the box is no longer needed to cover it,
- // so unblock the new box at the scale that the old box disappears.
- collisionFreeScale = blocking.maxScale;
- }
-
- if (collisionFreeScale > boxMaxScale) {
- // If the box can only be shown after it is visible, then the box can never be shown.
- // But the label can be shown after this box is not visible.
- collisionFreeScale = boxMaxScale;
- }
-
- if (collisionFreeScale > minPlacementScale &&
- collisionFreeScale >= blocking.placementScale) {
- // If this collision occurs at a lower scale than previously found collisions
- // and the collision occurs while the other label is visible
-
- // this this is the lowest scale at which the label won't collide with anything
- minPlacementScale = collisionFreeScale;
- }
-
- return minPlacementScale;
-}
-
-float CollisionTile::placeFeature(const CollisionFeature& feature, bool allowOverlap, bool avoidEdges) {
- static const float infinity = std::numeric_limits<float>::infinity();
- static const std::array<CollisionBox, 4> edges {{
- // left
- CollisionBox(Point<float>(0, 0), { 0, 0 }, 0, -infinity, 0, infinity, infinity),
- // right
- CollisionBox(Point<float>(util::EXTENT, 0), { 0, 0 }, 0, -infinity, 0, infinity, infinity),
- // top
- CollisionBox(Point<float>(0, 0), { 0, 0 }, -infinity, 0, infinity, 0, infinity),
- // bottom
- CollisionBox(Point<float>(0, util::EXTENT), { 0, 0 }, -infinity, 0, infinity, 0, infinity)
- }};
-
- float minPlacementScale = minScale;
-
- for (auto& box : feature.boxes) {
- const auto anchor = util::matrixMultiply(rotationMatrix, box.anchor);
-
- const float boxMaxScale = box.adjustedMaxScale(rotationMatrix, yStretch);
-
- if (!allowOverlap) {
- for (auto it = tree.qbegin(bgi::intersects(getTreeBox(anchor, box))); it != tree.qend(); ++it) {
- const CollisionBox& blocking = std::get<1>(*it);
- Point<float> blockingAnchor = util::matrixMultiply(rotationMatrix, blocking.anchor);
-
- minPlacementScale = util::max(minPlacementScale, findPlacementScale(anchor, box, boxMaxScale, blockingAnchor, blocking));
- if (minPlacementScale >= maxScale) return minPlacementScale;
- }
- }
-
- if (avoidEdges) {
- const Point<float> rtl = util::matrixMultiply(reverseRotationMatrix, { box.x1, box.y1 });
- const Point<float> rtr = util::matrixMultiply(reverseRotationMatrix, { box.x2, box.y1 });
- const Point<float> rbl = util::matrixMultiply(reverseRotationMatrix, { box.x1, box.y2 });
- const Point<float> rbr = util::matrixMultiply(reverseRotationMatrix, { box.x2, box.y2 });
- CollisionBox rotatedBox(box.anchor,
- box.offset,
- util::min(rtl.x, rtr.x, rbl.x, rbr.x),
- util::min(rtl.y, rtr.y, rbl.y, rbr.y),
- util::max(rtl.x, rtr.x, rbl.x, rbr.x),
- util::max(rtl.y, rtr.y, rbl.y, rbr.y),
- boxMaxScale);
-
- for (auto& blocking : edges) {
- minPlacementScale = util::max(minPlacementScale, findPlacementScale(box.anchor, rotatedBox, boxMaxScale, blocking.anchor, blocking));
- if (minPlacementScale >= maxScale) return minPlacementScale;
- }
- }
- }
-
- return minPlacementScale;
-}
-
-void CollisionTile::insertFeature(CollisionFeature& feature, float minPlacementScale, bool ignorePlacement) {
- for (auto& box : feature.boxes) {
- box.placementScale = minPlacementScale;
- }
-
- if (minPlacementScale < maxScale) {
- std::vector<CollisionTreeBox> treeBoxes;
- for (auto& box : feature.boxes) {
- CollisionBox adjustedBox = box;
- box.maxScale = box.adjustedMaxScale(rotationMatrix, yStretch);
- treeBoxes.emplace_back(getTreeBox(util::matrixMultiply(rotationMatrix, box.anchor), box), std::move(adjustedBox), feature.indexedFeature);
- }
- if (ignorePlacement) {
- ignoredTree.insert(treeBoxes.begin(), treeBoxes.end());
- } else {
- tree.insert(treeBoxes.begin(), treeBoxes.end());
- }
- }
-
-}
-
-// +---------------------------+ As you zoom, the size of the symbol changes
-// |(x1,y1) | | relative to the tile e.g. when zooming in,
-// | | | the symbol gets smaller relative to the tile.
-// | (x1',y1') v |
-// | +-------+-------+ | The boxes inserted into the tree represents
-// | | | | | the bounds at the integer zoom level (where
-// | | | | | the symbol is biggest relative to the tile).
-// | | | | |
-// |---->+-------+-------+<----| This happens because placement is updated
-// | | |(xa,ya)| | once every new integer zoom level e.g.
-// | | | | | std::floor(oldZoom) != std::floor(newZoom).
-// | | | | |
-// | +-------+-------+ | Thus, they don't represent the exact bounds
-// | ^ (x2',y2') | of the symbol at the current zoom level. For
-// | | | calculating the bounds at current zoom level
-// | | (x2,y2)| we must unscale the box using its center as
-// +---------------------------+ transform origin.
-Box CollisionTile::getTreeBox(const Point<float>& anchor, const CollisionBox& box, const float scale) {
- assert(box.x1 <= box.x2 && box.y1 <= box.y2);
- return Box{
- // When the 'perspectiveRatio' is high, we're effectively underzooming
- // the tile because it's in the distance.
- // In order to detect collisions that only happen while underzoomed,
- // we have to query a larger portion of the grid.
- // This extra work is offset by having a lower 'maxScale' bound
- // Note that this adjustment ONLY affects the bounding boxes
- // in the grid. It doesn't affect the boxes used for the
- // minPlacementScale calculations.
- CollisionPoint{
- anchor.x + box.x1 / scale * perspectiveRatio,
- anchor.y + box.y1 / scale * yStretch * perspectiveRatio,
- },
- CollisionPoint{
- anchor.x + box.x2 / scale * perspectiveRatio,
- anchor.y + box.y2 / scale * yStretch * perspectiveRatio
- }
- };
-}
-
-std::vector<IndexedSubfeature> CollisionTile::queryRenderedSymbols(const GeometryCoordinates& queryGeometry, float scale) const {
- std::vector<IndexedSubfeature> result;
- if (queryGeometry.empty() || (tree.empty() && ignoredTree.empty())) {
- return result;
- }
-
- // Generate a rotated geometry out of the original query geometry.
- // Scale has already been handled by the prior conversions.
- GeometryCoordinates polygon;
- for (const auto& point : queryGeometry) {
- auto rotated = util::matrixMultiply(rotationMatrix, convertPoint<float>(point));
- polygon.push_back(convertPoint<int16_t>(rotated));
- }
-
- // Predicate for ruling out already seen features.
- std::unordered_map<std::string, std::unordered_set<std::size_t>> sourceLayerFeatures;
- auto seenFeature = [&] (const CollisionTreeBox& treeBox) -> bool {
- const IndexedSubfeature& feature = std::get<2>(treeBox);
- const auto& seenFeatures = sourceLayerFeatures[feature.sourceLayerName];
- return seenFeatures.find(feature.index) == seenFeatures.end();
- };
-
- // "perspectiveRatio" is a tile-based approximation of how much larger symbols will
- // be in the distance. It won't line up exactly with the actually rendered symbols
- // Being exact would require running the collision detection logic in symbol_sdf.vertex
- // in the CPU
- const float perspectiveScale = scale / perspectiveRatio;
-
- // Account for the rounding done when updating symbol shader variables.
- const float roundedScale = std::pow(2.0f, std::ceil(util::log2(perspectiveScale) * 10.0f) / 10.0f);
-
- // Check if feature is rendered (collision free) at current scale.
- auto visibleAtScale = [&] (const CollisionTreeBox& treeBox) -> bool {
- const CollisionBox& box = std::get<1>(treeBox);
- return roundedScale >= box.placementScale && roundedScale <= box.adjustedMaxScale(rotationMatrix, yStretch);
- };
-
- // Check if query polygon intersects with the feature box at current scale.
- auto intersectsAtScale = [&] (const CollisionTreeBox& treeBox) -> bool {
- const CollisionBox& collisionBox = std::get<1>(treeBox);
- const auto anchor = util::matrixMultiply(rotationMatrix, collisionBox.anchor);
-
- const int16_t x1 = anchor.x + (collisionBox.x1 / perspectiveScale);
- const int16_t y1 = anchor.y + (collisionBox.y1 / perspectiveScale) * yStretch;
- const int16_t x2 = anchor.x + (collisionBox.x2 / perspectiveScale);
- const int16_t y2 = anchor.y + (collisionBox.y2 / perspectiveScale) * yStretch;
- auto bbox = GeometryCoordinates {
- { x1, y1 }, { x2, y1 }, { x2, y2 }, { x1, y2 }
- };
- return util::polygonIntersectsPolygon(polygon, bbox);
- };
-
- auto predicates = bgi::satisfies(seenFeature)
- && bgi::satisfies(visibleAtScale)
- && bgi::satisfies(intersectsAtScale);
-
- auto queryTree = [&](const auto& tree_) {
- for (auto it = tree_.qbegin(predicates); it != tree_.qend(); ++it) {
- const IndexedSubfeature& feature = std::get<2>(*it);
- auto& seenFeatures = sourceLayerFeatures[feature.sourceLayerName];
- seenFeatures.insert(feature.index);
- result.push_back(feature);
- }
- };
-
- queryTree(tree);
- queryTree(ignoredTree);
-
- return result;
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/text/collision_tile.hpp b/src/mbgl/text/collision_tile.hpp
deleted file mode 100644
index 9868266aa2..0000000000
--- a/src/mbgl/text/collision_tile.hpp
+++ /dev/null
@@ -1,71 +0,0 @@
-#pragma once
-
-#include <mbgl/text/collision_feature.hpp>
-#include <mbgl/text/placement_config.hpp>
-#include <mbgl/tile/geometry_tile_data.hpp>
-
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-function"
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#pragma GCC diagnostic ignored "-Wunused-variable"
-#pragma GCC diagnostic ignored "-Wshadow"
-#ifdef __clang__
-#pragma GCC diagnostic ignored "-Wunknown-pragmas"
-#endif
-#pragma GCC diagnostic ignored "-Wpragmas"
-#pragma GCC diagnostic ignored "-Wdeprecated-register"
-#pragma GCC diagnostic ignored "-Wshorten-64-to-32"
-#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
-#ifndef __clang__
-#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
-#pragma GCC diagnostic ignored "-Wmisleading-indentation"
-#endif
-#include <boost/geometry.hpp>
-#include <boost/geometry/geometries/point.hpp>
-#include <boost/geometry/geometries/box.hpp>
-#include <boost/geometry/index/rtree.hpp>
-#pragma GCC diagnostic pop
-
-namespace mbgl {
-
-namespace bg = boost::geometry;
-namespace bgm = bg::model;
-namespace bgi = bg::index;
-using CollisionPoint = bgm::point<float, 2, bg::cs::cartesian>;
-using Box = bgm::box<CollisionPoint>;
-using CollisionTreeBox = std::tuple<Box, CollisionBox, IndexedSubfeature>;
-using Tree = bgi::rtree<CollisionTreeBox, bgi::linear<16, 4>>;
-
-class IndexedSubfeature;
-
-class CollisionTile {
-public:
- explicit CollisionTile(PlacementConfig);
-
- float placeFeature(const CollisionFeature&, bool allowOverlap, bool avoidEdges);
- void insertFeature(CollisionFeature&, float minPlacementScale, bool ignorePlacement);
-
- std::vector<IndexedSubfeature> queryRenderedSymbols(const GeometryCoordinates&, float scale) const;
-
- const PlacementConfig config;
-
- float minScale = 0.5f;
- float maxScale = 2.0f;
- float yStretch;
-
- std::array<float, 4> rotationMatrix;
- std::array<float, 4> reverseRotationMatrix;
-
-private:
- float findPlacementScale(
- const Point<float>& anchor, const CollisionBox& box, const float boxMaxScale,
- const Point<float>& blockingAnchor, const CollisionBox& blocking);
- Box getTreeBox(const Point<float>& anchor, const CollisionBox& box, const float scale = 1.0);
-
- Tree tree;
- Tree ignoredTree;
-
- float perspectiveRatio;
-};
-
-} // namespace mbgl
diff --git a/src/mbgl/tile/geometry_tile.cpp b/src/mbgl/tile/geometry_tile.cpp
index 8c018ce3aa..6afd5b5e2f 100644
--- a/src/mbgl/tile/geometry_tile.cpp
+++ b/src/mbgl/tile/geometry_tile.cpp
@@ -15,7 +15,6 @@
#include <mbgl/renderer/image_atlas.hpp>
#include <mbgl/storage/file_source.hpp>
#include <mbgl/geometry/feature_index.hpp>
-#include <mbgl/text/collision_tile.hpp>
#include <mbgl/map/transform_state.hpp>
#include <mbgl/style/filter_evaluator.hpp>
#include <mbgl/util/logging.hpp>
@@ -57,7 +56,6 @@ GeometryTile::GeometryTile(const OverscaledTileID& id_,
parameters.pixelRatio),
glyphManager(parameters.glyphManager),
imageManager(parameters.imageManager),
- lastYStretch(1.0f),
mode(parameters.mode) {
}
@@ -89,25 +87,6 @@ void GeometryTile::setData(std::unique_ptr<const GeometryTileData> data_) {
worker.invoke(&GeometryTileWorker::setData, std::move(data_), correlationID);
}
-void GeometryTile::setPlacementConfig(const PlacementConfig& desiredConfig) {
- if (requestedConfig == desiredConfig) {
- return;
- }
-
- // Mark the tile as pending again if it was complete before to prevent signaling a complete
- // state despite pending parse operations.
- pending = true;
-
- ++correlationID;
- requestedConfig = desiredConfig;
- invokePlacement();
-}
-
-void GeometryTile::invokePlacement() {
- if (requestedConfig) {
- worker.invoke(&GeometryTileWorker::setPlacementConfig, *requestedConfig, correlationID);
- }
-}
void GeometryTile::setLayers(const std::vector<Immutable<Layer::Impl>>& layers) {
// Mark the tile as pending again if it was complete before to prevent signaling a complete
@@ -141,7 +120,6 @@ void GeometryTile::onLayout(LayoutResult result, const uint64_t resultCorrelatio
nonSymbolBuckets = std::move(result.nonSymbolBuckets);
featureIndex = std::move(result.featureIndex);
data = std::move(result.tileData);
- collisionTile.reset();
observer->onTileChanged(*this);
}
@@ -152,16 +130,13 @@ void GeometryTile::onPlacement(PlacementResult result, const uint64_t resultCorr
pending = false;
}
symbolBuckets = std::move(result.symbolBuckets);
- collisionTile = std::move(result.collisionTile);
if (result.glyphAtlasImage) {
glyphAtlasImage = std::move(*result.glyphAtlasImage);
}
if (result.iconAtlasImage) {
iconAtlasImage = std::move(*result.iconAtlasImage);
}
- if (collisionTile.get()) {
- lastYStretch = collisionTile->yStretch;
- }
+
observer->onTileChanged(*this);
}
@@ -253,7 +228,7 @@ void GeometryTile::queryRenderedFeatures(
*data,
id.canonical,
layers,
- collisionTile.get(),
+ 0, // TODO: hook up to global CollisionIndex
additionalRadius);
}
@@ -293,11 +268,4 @@ void GeometryTile::querySourceFeatures(
}
}
-float GeometryTile::yStretch() const {
- // collisionTile gets reset in onLayout but we don't clear the symbolBuckets
- // until a new placement result comes along, so keep the yStretch value in
- // case we need to render them.
- return lastYStretch;
-}
-
} // namespace mbgl
diff --git a/src/mbgl/tile/geometry_tile.hpp b/src/mbgl/tile/geometry_tile.hpp
index 23a68c0a1c..37c697d399 100644
--- a/src/mbgl/tile/geometry_tile.hpp
+++ b/src/mbgl/tile/geometry_tile.hpp
@@ -5,7 +5,6 @@
#include <mbgl/renderer/image_manager.hpp>
#include <mbgl/text/glyph_manager.hpp>
#include <mbgl/text/placement_config.hpp>
-#include <mbgl/text/collision_tile.hpp>
#include <mbgl/util/feature.hpp>
#include <mbgl/util/throttler.hpp>
#include <mbgl/actor/actor.hpp>
@@ -37,7 +36,6 @@ public:
void setError(std::exception_ptr);
void setData(std::unique_ptr<const GeometryTileData>);
- void setPlacementConfig(const PlacementConfig&) override;
void setLayers(const std::vector<Immutable<style::Layer::Impl>>&) override;
void onGlyphsAvailable(GlyphMap) override;
@@ -83,16 +81,13 @@ public:
class PlacementResult {
public:
std::unordered_map<std::string, std::shared_ptr<Bucket>> symbolBuckets;
- std::unique_ptr<CollisionTile> collisionTile;
optional<AlphaImage> glyphAtlasImage;
optional<PremultipliedImage> iconAtlasImage;
PlacementResult(std::unordered_map<std::string, std::shared_ptr<Bucket>> symbolBuckets_,
- std::unique_ptr<CollisionTile> collisionTile_,
optional<AlphaImage> glyphAtlasImage_,
optional<PremultipliedImage> iconAtlasImage_)
: symbolBuckets(std::move(symbolBuckets_)),
- collisionTile(std::move(collisionTile_)),
glyphAtlasImage(std::move(glyphAtlasImage_)),
iconAtlasImage(std::move(iconAtlasImage_)) {}
};
@@ -100,8 +95,6 @@ public:
void onError(std::exception_ptr, uint64_t correlationID);
- float yStretch() const override;
-
protected:
const GeometryTileData* getData() {
return data.get();
@@ -109,7 +102,6 @@ protected:
private:
void markObsolete();
- void invokePlacement();
const std::string sourceID;
@@ -134,9 +126,7 @@ private:
std::unordered_map<std::string, std::shared_ptr<Bucket>> symbolBuckets;
std::unordered_map<std::string, std::unique_ptr<SymbolLayout>> symbolLayouts;
- std::unique_ptr<CollisionTile> collisionTile;
- float lastYStretch;
const MapMode mode;
public:
diff --git a/src/mbgl/tile/geometry_tile_worker.cpp b/src/mbgl/tile/geometry_tile_worker.cpp
index 1d3c200c8a..01c5f074e6 100644
--- a/src/mbgl/tile/geometry_tile_worker.cpp
+++ b/src/mbgl/tile/geometry_tile_worker.cpp
@@ -1,7 +1,6 @@
#include <mbgl/tile/geometry_tile_worker.hpp>
#include <mbgl/tile/geometry_tile_data.hpp>
#include <mbgl/tile/geometry_tile.hpp>
-#include <mbgl/text/collision_tile.hpp>
#include <mbgl/layout/symbol_layout.hpp>
#include <mbgl/renderer/bucket_parameters.hpp>
#include <mbgl/renderer/group_by_layout.hpp>
@@ -116,30 +115,6 @@ void GeometryTileWorker::setLayers(std::vector<Immutable<Layer::Impl>> layers_,
}
}
-void GeometryTileWorker::setPlacementConfig(PlacementConfig placementConfig_, uint64_t correlationID_) {
- try {
- placementConfig = std::move(placementConfig_);
- correlationID = correlationID_;
-
- switch (state) {
- case Idle:
- //attemptPlacement();
- coalesce();
- break;
-
- case Coalescing:
- //state = NeedPlacement;
- break;
-
- case NeedPlacement:
- case NeedLayout:
- break;
- }
- } catch (...) {
- parent.invoke(&GeometryTile::onError, std::current_exception(), correlationID);
- }
-}
-
void GeometryTileWorker::symbolDependenciesChanged() {
try {
switch (state) {
@@ -372,7 +347,7 @@ bool GeometryTileWorker::hasPendingSymbolDependencies() const {
}
void GeometryTileWorker::attemptPlacement() {
- if (!data || !layers || !placementConfig || hasPendingSymbolDependencies()) {
+ if (!data || !layers || hasPendingSymbolDependencies()) {
return;
}
@@ -398,7 +373,6 @@ void GeometryTileWorker::attemptPlacement() {
symbolLayoutsNeedPreparation = false;
}
- auto collisionTile = std::make_unique<CollisionTile>(*placementConfig);
std::unordered_map<std::string, std::shared_ptr<Bucket>> buckets;
for (auto& symbolLayout : symbolLayouts) {
@@ -410,7 +384,7 @@ void GeometryTileWorker::attemptPlacement() {
continue;
}
- std::shared_ptr<Bucket> bucket = symbolLayout->place(*collisionTile);
+ std::shared_ptr<Bucket> bucket = symbolLayout->place();
for (const auto& pair : symbolLayout->layerPaintProperties) {
buckets.emplace(pair.first, bucket);
}
@@ -418,7 +392,6 @@ void GeometryTileWorker::attemptPlacement() {
parent.invoke(&GeometryTile::onPlacement, GeometryTile::PlacementResult {
std::move(buckets),
- std::move(collisionTile),
std::move(glyphAtlasImage),
std::move(iconAtlasImage),
}, correlationID);
diff --git a/src/mbgl/tile/geometry_tile_worker.hpp b/src/mbgl/tile/geometry_tile_worker.hpp
index 1425daa7a1..89a51cfad0 100644
--- a/src/mbgl/tile/geometry_tile_worker.hpp
+++ b/src/mbgl/tile/geometry_tile_worker.hpp
@@ -35,7 +35,6 @@ public:
void setLayers(std::vector<Immutable<style::Layer::Impl>>, uint64_t correlationID);
void setData(std::unique_ptr<const GeometryTileData>, uint64_t correlationID);
- void setPlacementConfig(PlacementConfig, uint64_t correlationID);
void onGlyphsAvailable(GlyphMap glyphs);
void onImagesAvailable(ImageMap images, uint64_t imageCorrelationID);
@@ -75,7 +74,6 @@ private:
// Outer optional indicates whether we've received it or not.
optional<std::vector<Immutable<style::Layer::Impl>>> layers;
optional<std::unique_ptr<const GeometryTileData>> data;
- optional<PlacementConfig> placementConfig;
bool symbolLayoutsNeedPreparation = false;
std::vector<std::unique_ptr<SymbolLayout>> symbolLayouts;
diff --git a/src/mbgl/tile/tile.hpp b/src/mbgl/tile/tile.hpp
index 4b725a4a84..0ce814890e 100644
--- a/src/mbgl/tile/tile.hpp
+++ b/src/mbgl/tile/tile.hpp
@@ -108,8 +108,6 @@ public:
// Contains the tile ID string for painting debug information.
std::unique_ptr<DebugBucket> debugBucket;
-
- virtual float yStretch() const { return 1.0f; }
protected:
bool triedOptional = false;