summaryrefslogtreecommitdiff
path: root/src/mbgl/text/collision_index.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/text/collision_index.cpp')
-rw-r--r--src/mbgl/text/collision_index.cpp44
1 files changed, 31 insertions, 13 deletions
diff --git a/src/mbgl/text/collision_index.cpp b/src/mbgl/text/collision_index.cpp
index 091840a371..dae789a196 100644
--- a/src/mbgl/text/collision_index.cpp
+++ b/src/mbgl/text/collision_index.cpp
@@ -62,6 +62,21 @@ bool CollisionIndex::isOffscreen(const CollisionBox& box) const {
bool CollisionIndex::isInsideGrid(const CollisionBox& box) const {
return box.px2 >= 0 && box.px1 < gridRightBoundary && box.py2 >= 0 && box.py1 < gridBottomBoundary;
}
+
+CollisionTileBoundaries CollisionIndex::projectTileBoundaries(const mat4& posMatrix) const {
+ Point<float> topLeft = projectPoint(posMatrix, { 0, 0 });
+ Point<float> bottomRight = projectPoint(posMatrix, { util::EXTENT, util::EXTENT });
+
+ return {{ topLeft.x, topLeft.y, bottomRight.x, bottomRight.y }};
+
+}
+
+bool CollisionIndex::isInsideTile(const CollisionBox& box, const CollisionTileBoundaries& tileBoundaries) const {
+ // This check is only well defined when the tile boundaries are axis-aligned
+ // We are relying on it only being used in MapMode::Tile, where that is always the case
+
+ return box.px1 >= tileBoundaries[0] && box.py1 >= tileBoundaries[1] && box.px2 < tileBoundaries[2] && box.py2 < tileBoundaries[3];
+}
std::pair<bool,bool> CollisionIndex::placeFeature(CollisionFeature& feature,
@@ -73,7 +88,8 @@ std::pair<bool,bool> CollisionIndex::placeFeature(CollisionFeature& feature,
const float fontSize,
const bool allowOverlap,
const bool pitchWithMap,
- const bool collisionDebug) {
+ const bool collisionDebug,
+ const optional<CollisionTileBoundaries>& avoidEdges) {
if (!feature.alongLine) {
CollisionBox& box = feature.boxes.front();
const auto projectedPoint = projectAndGetPerspectiveRatio(posMatrix, box.anchor);
@@ -82,15 +98,17 @@ std::pair<bool,bool> CollisionIndex::placeFeature(CollisionFeature& feature,
box.py1 = box.y1 * tileToViewport + projectedPoint.first.y;
box.px2 = box.x2 * tileToViewport + projectedPoint.first.x;
box.py2 = box.y2 * tileToViewport + projectedPoint.first.y;
+
- if (!isInsideGrid(box) ||
+ if ((avoidEdges && !isInsideTile(box, *avoidEdges)) ||
+ !isInsideGrid(box) ||
(!allowOverlap && collisionGrid.hitTest({{ box.px1, box.py1 }, { box.px2, box.py2 }}))) {
return { false, false };
}
return {true, isOffscreen(box)};
} else {
- return placeLineFeature(feature, posMatrix, labelPlaneMatrix, textPixelRatio, symbol, scale, fontSize, allowOverlap, pitchWithMap, collisionDebug);
+ return placeLineFeature(feature, posMatrix, labelPlaneMatrix, textPixelRatio, symbol, scale, fontSize, allowOverlap, pitchWithMap, collisionDebug, avoidEdges);
}
}
@@ -103,7 +121,8 @@ std::pair<bool,bool> CollisionIndex::placeLineFeature(CollisionFeature& feature,
const float fontSize,
const bool allowOverlap,
const bool pitchWithMap,
- const bool collisionDebug) {
+ const bool collisionDebug,
+ const optional<CollisionTileBoundaries>& avoidEdges) {
const auto tileUnitAnchorPoint = symbol.anchorPoint;
const auto projectedAnchor = projectAnchor(posMatrix, tileUnitAnchorPoint);
@@ -202,15 +221,14 @@ std::pair<bool,bool> CollisionIndex::placeLineFeature(CollisionFeature& feature,
entirelyOffscreen &= isOffscreen(circle);
inGrid |= isInsideGrid(circle);
- if (!allowOverlap) {
- if (collisionGrid.hitTest({{circle.px, circle.py}, circle.radius})) {
- if (!collisionDebug) {
- return {false, false};
- } else {
- // Don't early exit if we're showing the debug circles because we still want to calculate
- // which circles are in use
- collisionDetected = true;
- }
+ if ((avoidEdges && !isInsideTile(circle, *avoidEdges)) ||
+ (!allowOverlap && collisionGrid.hitTest({{circle.px, circle.py}, circle.radius}))) {
+ if (!collisionDebug) {
+ return {false, false};
+ } else {
+ // Don't early exit if we're showing the debug circles because we still want to calculate
+ // which circles are in use
+ collisionDetected = true;
}
}
}