@@ -55,12 +55,12 @@ float CollisionIndex::approximateTileDistance(const TileDistance& tileDistance,
5555 (incidenceStretch - 1 ) * lastSegmentTile * std::abs (std::sin (lastSegmentAngle));
5656}
5757
58- bool CollisionIndex::isOffscreen (const CollisionBox& box ) const {
59- return box. px2 < viewportPadding || box. px1 >= screenRightBoundary || box. py2 < viewportPadding || box. py1 >= screenBottomBoundary;
58+ bool CollisionIndex::isOffscreen (float x1, float y1, float x2, float y2 ) const {
59+ return x2 < viewportPadding || x1 >= screenRightBoundary || y2 < viewportPadding || y1 >= screenBottomBoundary;
6060}
6161
62- bool CollisionIndex::isInsideGrid (const CollisionBox& box ) const {
63- return box. px2 >= 0 && box. px1 < gridRightBoundary && box. py2 >= 0 && box. py1 < gridBottomBoundary;
62+ bool CollisionIndex::isInsideGrid (float x1, float y1, float x2, float y2 ) const {
63+ return x2 >= 0 && x1 < gridRightBoundary && y2 >= 0 && y1 < gridBottomBoundary;
6464}
6565
6666CollisionTileBoundaries CollisionIndex::projectTileBoundaries (const mat4& posMatrix) const {
@@ -71,11 +71,11 @@ CollisionTileBoundaries CollisionIndex::projectTileBoundaries(const mat4& posMat
7171
7272}
7373
74- bool CollisionIndex::isInsideTile (const CollisionBox& box , const CollisionTileBoundaries& tileBoundaries) const {
74+ bool CollisionIndex::isInsideTile (float x1, float y1, float x2, float y2 , const CollisionTileBoundaries& tileBoundaries) const {
7575 // This check is only well defined when the tile boundaries are axis-aligned
7676 // We are relying on it only being used in MapMode::Tile, where that is always the case
7777
78- return box. px1 >= tileBoundaries[0 ] && box. py1 >= tileBoundaries[1 ] && box. px2 < tileBoundaries[2 ] && box. py2 < tileBoundaries[3 ];
78+ return x1 >= tileBoundaries[0 ] && y1 >= tileBoundaries[1 ] && x2 < tileBoundaries[2 ] && y2 < tileBoundaries[3 ];
7979}
8080
8181
@@ -96,19 +96,19 @@ std::pair<bool,bool> CollisionIndex::placeFeature(CollisionFeature& feature,
9696 CollisionBox& box = feature.boxes .front ();
9797 const auto projectedPoint = projectAndGetPerspectiveRatio (posMatrix, box.anchor );
9898 const float tileToViewport = textPixelRatio * projectedPoint.second ;
99- box. px1 = (box.x1 + shift.x ) * tileToViewport + projectedPoint.first .x ;
100- box. py1 = (box.y1 + shift.y ) * tileToViewport + projectedPoint.first .y ;
101- box. px2 = (box.x2 + shift.x ) * tileToViewport + projectedPoint.first .x ;
102- box. py2 = (box.y2 + shift.y ) * tileToViewport + projectedPoint.first .y ;
103-
104-
105- if ((avoidEdges && !isInsideTile (box , *avoidEdges)) ||
106- !isInsideGrid (box ) ||
107- (!allowOverlap && collisionGrid.hitTest ({{ box.px1 , box. py1 }, { box. px2 , box. py2 }} , collisionGroupPredicate))) {
99+ float px1 = (box.x1 + shift.x ) * tileToViewport + projectedPoint.first .x ;
100+ float py1 = (box.y1 + shift.y ) * tileToViewport + projectedPoint.first .y ;
101+ float px2 = (box.x2 + shift.x ) * tileToViewport + projectedPoint.first .x ;
102+ float py2 = (box.y2 + shift.y ) * tileToViewport + projectedPoint.first .y ;
103+ box. projected = ProjectedCollisionBox{ px1, py1, px2, py2 };
104+
105+ if ((avoidEdges && !isInsideTile (px1, py1, px2, py2 , *avoidEdges)) ||
106+ !isInsideGrid (px1, py1, px2, py2 ) ||
107+ (!allowOverlap && collisionGrid.hitTest (box.projected . box () , collisionGroupPredicate))) {
108108 return { false , false };
109109 }
110110
111- return {true , isOffscreen (box )};
111+ return {true , isOffscreen (px1, py1, px2, py2 )};
112112 } else {
113113 return placeLineFeature (feature, posMatrix, labelPlaneMatrix, textPixelRatio, symbol, scale, fontSize, allowOverlap, pitchWithMap, collisionDebug, avoidEdges, collisionGroupPredicate);
114114 }
@@ -126,7 +126,7 @@ std::pair<bool,bool> CollisionIndex::placeLineFeature(CollisionFeature& feature,
126126 const bool collisionDebug,
127127 const optional<CollisionTileBoundaries>& avoidEdges,
128128 const optional<std::function<bool (const IndexedSubfeature&)>> collisionGroupPredicate) {
129-
129+ assert (feature. alongLine );
130130 const auto tileUnitAnchorPoint = symbol.anchorPoint ;
131131 const auto projectedAnchor = projectAnchor (posMatrix, tileUnitAnchorPoint);
132132
@@ -173,7 +173,6 @@ std::pair<bool,bool> CollisionIndex::placeLineFeature(CollisionFeature& feature,
173173 // The label either doesn't fit on its line or we
174174 // don't need to use this circle because the label
175175 // doesn't extend this far. Either way, mark the circle unused.
176- circle.used = false ;
177176 previousCirclePlaced = false ;
178177 continue ;
179178 }
@@ -184,9 +183,10 @@ std::pair<bool,bool> CollisionIndex::placeLineFeature(CollisionFeature& feature,
184183
185184 if (previousCirclePlaced) {
186185 const CollisionBox& previousCircle = feature.boxes [i - 1 ];
187- assert (previousCircle.used );
188- const float dx = projectedPoint.x - previousCircle.px ;
189- const float dy = projectedPoint.y - previousCircle.py ;
186+ assert (previousCircle.projected .isCircle ());
187+ const auto & previousCenter = previousCircle.projected .circle ().center ;
188+ const float dx = projectedPoint.x - previousCenter.x ;
189+ const float dy = projectedPoint.y - previousCenter.y ;
190190 // The circle edges touch when the distance between their centers is 2x the radius
191191 // When the distance is 1x the radius, they're doubled up, and we could remove
192192 // every other circle while keeping them all in touch.
@@ -204,7 +204,6 @@ std::pair<bool,bool> CollisionIndex::placeLineFeature(CollisionFeature& feature,
204204 // Hide significantly overlapping circles, unless this is the last one we can
205205 // use, in which case we want to keep it in place even if it's tightly packed
206206 // with the one before it.
207- circle.used = false ;
208207 previousCirclePlaced = false ;
209208 continue ;
210209 }
@@ -213,22 +212,18 @@ std::pair<bool,bool> CollisionIndex::placeLineFeature(CollisionFeature& feature,
213212 }
214213
215214 previousCirclePlaced = true ;
216- circle.px1 = projectedPoint.x - radius;
217- circle.px2 = projectedPoint.x + radius;
218- circle.py1 = projectedPoint.y - radius;
219- circle.py2 = projectedPoint.y + radius;
220-
221- circle.used = true ;
222-
223- circle.px = projectedPoint.x ;
224- circle.py = projectedPoint.y ;
225- circle.radius = radius;
215+ float px1 = projectedPoint.x - radius;
216+ float px2 = projectedPoint.x + radius;
217+ float py1 = projectedPoint.y - radius;
218+ float py2 = projectedPoint.y + radius;
219+
220+ circle.projected = ProjectedCollisionBox{projectedPoint.x , projectedPoint.y , radius};
226221
227- entirelyOffscreen &= isOffscreen (circle );
228- inGrid |= isInsideGrid (circle );
222+ entirelyOffscreen &= isOffscreen (px1, py1, px2, py2 );
223+ inGrid |= isInsideGrid (px1, py1, px2, py2 );
229224
230- if ((avoidEdges && !isInsideTile (circle , *avoidEdges)) ||
231- (!allowOverlap && collisionGrid.hitTest ({{ circle.px , circle. py }, circle. radius } , collisionGroupPredicate))) {
225+ if ((avoidEdges && !isInsideTile (px1, py1, px2, py2 , *avoidEdges)) ||
226+ (!allowOverlap && collisionGrid.hitTest (circle.projected . circle () , collisionGroupPredicate))) {
232227 if (!collisionDebug) {
233228 return {false , false };
234229 } else {
@@ -246,34 +241,35 @@ std::pair<bool,bool> CollisionIndex::placeLineFeature(CollisionFeature& feature,
246241void CollisionIndex::insertFeature (CollisionFeature& feature, bool ignorePlacement, uint32_t bucketInstanceId, uint16_t collisionGroupId) {
247242 if (feature.alongLine ) {
248243 for (auto & circle : feature.boxes ) {
249- if (!circle.used ) {
244+ if (!circle.projected . isCircle () ) {
250245 continue ;
251246 }
252247
253248 if (ignorePlacement) {
254249 ignoredGrid.insert (
255250 IndexedSubfeature (feature.indexedFeature , bucketInstanceId, collisionGroupId),
256- {{ circle.px , circle. py }, circle. radius }
251+ circle.projected . circle ()
257252 );
258253 } else {
259254 collisionGrid.insert (
260255 IndexedSubfeature (feature.indexedFeature , bucketInstanceId, collisionGroupId),
261- {{ circle.px , circle. py }, circle. radius }
256+ circle.projected . circle ()
262257 );
263258 }
264259 }
265260 } else {
266261 assert (feature.boxes .size () == 1 );
267262 auto & box = feature.boxes [0 ];
263+ assert (box.projected .isBox ());
268264 if (ignorePlacement) {
269265 ignoredGrid.insert (
270266 IndexedSubfeature (feature.indexedFeature , bucketInstanceId, collisionGroupId),
271- {{ box.px1 , box. py1 }, { box. px2 , box. py2 }}
267+ box.projected . box ()
272268 );
273269 } else {
274270 collisionGrid.insert (
275271 IndexedSubfeature (feature.indexedFeature , bucketInstanceId, collisionGroupId),
276- {{ box.px1 , box. py1 }, { box. px2 , box. py2 }}
272+ box.projected . box ()
277273 );
278274 }
279275 }
0 commit comments