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.cpp125
1 files changed, 66 insertions, 59 deletions
diff --git a/src/mbgl/text/collision_index.cpp b/src/mbgl/text/collision_index.cpp
index cbb1502428..d92fd27003 100644
--- a/src/mbgl/text/collision_index.cpp
+++ b/src/mbgl/text/collision_index.cpp
@@ -65,66 +65,72 @@ float CollisionIndex::approximateTileDistance(const TileDistance& tileDistance,
(incidenceStretch - 1) * lastSegmentTile * std::abs(std::sin(lastSegmentAngle));
}
-bool CollisionIndex::isOffscreen(float x1, float y1, float x2, float y2) const {
- return x2 < viewportPadding || x1 >= screenRightBoundary || y2 < viewportPadding || y1 >= screenBottomBoundary;
+bool CollisionIndex::isOffscreen(const CollisionBoundaries& boundaries) const {
+ return boundaries[2] < viewportPadding || boundaries[0] >= screenRightBoundary || boundaries[3] < viewportPadding ||
+ boundaries[1] >= screenBottomBoundary;
}
-bool CollisionIndex::isInsideGrid(float x1, float y1, float x2, float y2) const {
- return x2 >= 0 && x1 < gridRightBoundary && y2 >= 0 && y1 < gridBottomBoundary;
+bool CollisionIndex::isInsideGrid(const CollisionBoundaries& boundaries) const {
+ return boundaries[2] >= 0 && boundaries[0] < gridRightBoundary && boundaries[3] >= 0 &&
+ boundaries[1] < gridBottomBoundary;
}
-
-CollisionTileBoundaries CollisionIndex::projectTileBoundaries(const mat4& posMatrix) const {
+
+CollisionBoundaries 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 }};
-
}
// The tile border checks below are 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
-inline bool CollisionIndex::isInsideTile(
- float x1, float y1, float x2, float y2, const CollisionTileBoundaries& tileBoundaries) const {
- return x1 >= tileBoundaries[0] && y1 >= tileBoundaries[1] && x2 < tileBoundaries[2] && y2 < tileBoundaries[3];
+inline bool CollisionIndex::isInsideTile(const CollisionBoundaries& boundaries,
+ const CollisionBoundaries& tileBoundaries) const {
+ return boundaries[0] >= tileBoundaries[0] && boundaries[1] >= tileBoundaries[1] &&
+ boundaries[2] < tileBoundaries[2] && boundaries[3] < tileBoundaries[3];
}
-inline bool CollisionIndex::overlapsTile(
- float x1, float y1, float x2, float y2, const CollisionTileBoundaries& tileBoundaries) const {
- return x1 < tileBoundaries[2] && x2 > tileBoundaries[0] && y1 < tileBoundaries[3] && y2 > tileBoundaries[1];
+inline bool CollisionIndex::overlapsTile(const CollisionBoundaries& boundaries,
+ const CollisionBoundaries& tileBoundaries) const {
+ return boundaries[0] < tileBoundaries[2] && boundaries[2] > tileBoundaries[0] &&
+ boundaries[1] < tileBoundaries[3] && boundaries[3] > tileBoundaries[1];
}
bool CollisionIndex::featureIntersectsTileBorders(const CollisionFeature& feature,
Point<float> shift,
const mat4& posMatrix,
const float textPixelRatio,
- const CollisionTileBoundaries& tileEdges) const {
+ const CollisionBoundaries& tileEdges) const {
assert(!feature.alongLine);
assert(!feature.boxes.empty());
const CollisionBox& box = feature.boxes.front();
const auto projectedPoint = projectAndGetPerspectiveRatio(posMatrix, box.anchor);
const float tileToViewport = textPixelRatio * projectedPoint.second;
- float px1 = (box.x1 + shift.x) * tileToViewport + projectedPoint.first.x;
- float py1 = (box.y1 + shift.y) * tileToViewport + projectedPoint.first.y;
- float px2 = (box.x2 + shift.x) * tileToViewport + projectedPoint.first.x;
- float py2 = (box.y2 + shift.y) * tileToViewport + projectedPoint.first.y;
-
- return overlapsTile(px1, py1, px2, py2, tileEdges) && !isInsideTile(px1, py1, px2, py2, tileEdges);
+ CollisionBoundaries collisionBoundaries{{
+ (box.x1 + shift.x) * tileToViewport + projectedPoint.first.x,
+ (box.y1 + shift.y) * tileToViewport + projectedPoint.first.y,
+ (box.x2 + shift.x) * tileToViewport + projectedPoint.first.x,
+ (box.y2 + shift.y) * tileToViewport + projectedPoint.first.y,
+ }};
+
+ return overlapsTile(collisionBoundaries, tileEdges) && !isInsideTile(collisionBoundaries, tileEdges);
}
-std::pair<bool,bool> CollisionIndex::placeFeature(const CollisionFeature& feature,
- Point<float> shift,
- const mat4& posMatrix,
- const mat4& labelPlaneMatrix,
- const float textPixelRatio,
- const PlacedSymbol& symbol,
- const float scale,
- const float fontSize,
- const bool allowOverlap,
- const bool pitchWithMap,
- const bool collisionDebug,
- const optional<CollisionTileBoundaries>& avoidEdges,
- const optional<std::function<bool(const IndexedSubfeature&)>> collisionGroupPredicate,
- std::vector<ProjectedCollisionBox>& projectedBoxes) {
+std::pair<bool, bool> CollisionIndex::placeFeature(
+ const CollisionFeature& feature,
+ Point<float> shift,
+ const mat4& posMatrix,
+ const mat4& labelPlaneMatrix,
+ const float textPixelRatio,
+ const PlacedSymbol& symbol,
+ const float scale,
+ const float fontSize,
+ const bool allowOverlap,
+ const bool pitchWithMap,
+ const bool collisionDebug,
+ const optional<CollisionBoundaries>& avoidEdges,
+ const optional<std::function<bool(const IndexedSubfeature&)>> collisionGroupPredicate,
+ std::vector<ProjectedCollisionBox>& projectedBoxes) {
assert(projectedBoxes.empty());
if (!feature.alongLine) {
const CollisionBox& box = feature.boxes.front();
@@ -136,31 +142,32 @@ std::pair<bool,bool> CollisionIndex::placeFeature(const CollisionFeature& featur
float py2 = (box.y2 + shift.y) * tileToViewport + projectedPoint.first.y;
projectedBoxes.emplace_back(px1, py1, px2, py2);
- if ((avoidEdges && !isInsideTile(px1, py1, px2, py2, *avoidEdges)) ||
- !isInsideGrid(px1, py1, px2, py2) ||
+ CollisionBoundaries collisionBoundaries{{px1, py1, px2, py2}};
+ if ((avoidEdges && !isInsideTile(collisionBoundaries, *avoidEdges)) || !isInsideGrid(collisionBoundaries) ||
(!allowOverlap && collisionGrid.hitTest(projectedBoxes.back().box(), collisionGroupPredicate))) {
return { false, false };
}
- return {true, isOffscreen(px1, py1, px2, py2)};
+ return {true, isOffscreen(collisionBoundaries)};
} else {
return placeLineFeature(feature, posMatrix, labelPlaneMatrix, textPixelRatio, symbol, scale, fontSize, allowOverlap, pitchWithMap, collisionDebug, avoidEdges, collisionGroupPredicate, projectedBoxes);
}
}
-std::pair<bool,bool> CollisionIndex::placeLineFeature(const CollisionFeature& feature,
- const mat4& posMatrix,
- const mat4& labelPlaneMatrix,
- const float textPixelRatio,
- const PlacedSymbol& symbol,
- const float scale,
- const float fontSize,
- const bool allowOverlap,
- const bool pitchWithMap,
- const bool collisionDebug,
- const optional<CollisionTileBoundaries>& avoidEdges,
- const optional<std::function<bool(const IndexedSubfeature&)>> collisionGroupPredicate,
- std::vector<ProjectedCollisionBox>& projectedBoxes) {
+std::pair<bool, bool> CollisionIndex::placeLineFeature(
+ const CollisionFeature& feature,
+ const mat4& posMatrix,
+ const mat4& labelPlaneMatrix,
+ const float textPixelRatio,
+ const PlacedSymbol& symbol,
+ const float scale,
+ const float fontSize,
+ const bool allowOverlap,
+ const bool pitchWithMap,
+ const bool collisionDebug,
+ const optional<CollisionBoundaries>& avoidEdges,
+ const optional<std::function<bool(const IndexedSubfeature&)>> collisionGroupPredicate,
+ std::vector<ProjectedCollisionBox>& projectedBoxes) {
assert(feature.alongLine);
assert(projectedBoxes.empty());
const auto tileUnitAnchorPoint = symbol.anchorPoint;
@@ -249,17 +256,18 @@ std::pair<bool,bool> CollisionIndex::placeLineFeature(const CollisionFeature& fe
}
previousCirclePlaced = true;
- float px1 = projectedPoint.x - radius;
- float px2 = projectedPoint.x + radius;
- float py1 = projectedPoint.y - radius;
- float py2 = projectedPoint.y + radius;
+
+ CollisionBoundaries collisionBoundaries{{projectedPoint.x - radius,
+ projectedPoint.y - radius,
+ projectedPoint.x + radius,
+ projectedPoint.y + radius}};
projectedBoxes[i] = ProjectedCollisionBox{projectedPoint.x, projectedPoint.y, radius};
-
- entirelyOffscreen &= isOffscreen(px1, py1, px2, py2);
- inGrid |= isInsideGrid(px1, py1, px2, py2);
- if ((avoidEdges && !isInsideTile(px1, py1, px2, py2, *avoidEdges)) ||
+ entirelyOffscreen &= isOffscreen(collisionBoundaries);
+ inGrid |= isInsideGrid(collisionBoundaries);
+
+ if ((avoidEdges && !isInsideTile(collisionBoundaries, *avoidEdges)) ||
(!allowOverlap && collisionGrid.hitTest(projectedBoxes[i].circle(), collisionGroupPredicate))) {
if (!collisionDebug) {
return {false, false};
@@ -274,7 +282,6 @@ std::pair<bool,bool> CollisionIndex::placeLineFeature(const CollisionFeature& fe
return {!collisionDetected && firstAndLastGlyph && inGrid, entirelyOffscreen};
}
-
void CollisionIndex::insertFeature(const CollisionFeature& feature, const std::vector<ProjectedCollisionBox>& projectedBoxes, bool ignorePlacement, uint32_t bucketInstanceId, uint16_t collisionGroupId) {
if (feature.alongLine) {
for (auto& circle : projectedBoxes) {