[core] increase padding in CollisionIndex for MapMode::Tile (#15880)

* [core] fix cutoff cross-tile labels in MapMode::Tile

Increase the CollisionIndex's padding so that more of a tile's data gets
considered when checking for collisions. This should fix clipped
variable placement text labels.
This commit is contained in:
Ansis Brammanis
2019-12-06 18:11:25 -05:00
committed by GitHub
parent 1ac3e9e9c2
commit cdee5b8249
3 changed files with 25 additions and 14 deletions

View File

@@ -22,20 +22,30 @@ namespace mbgl {
// the viewport for collision detection so that the bulk of the changes
// occur offscreen. Making this constant greater increases label
// stability, but it's expensive.
static const float viewportPadding = 100;
static const float viewportPaddingDefault = 100;
// Viewport padding must be much larger for static tiles to avoid clipped labels.
static const float viewportPaddingForStaticTiles = 1024;
CollisionIndex::CollisionIndex(const TransformState& transformState_)
: transformState(transformState_)
, collisionGrid(transformState.getSize().width + 2 * viewportPadding, transformState.getSize().height + 2 * viewportPadding, 25)
, ignoredGrid(transformState.getSize().width + 2 * viewportPadding, transformState.getSize().height + 2 * viewportPadding, 25)
, screenRightBoundary(transformState.getSize().width + viewportPadding)
, screenBottomBoundary(transformState.getSize().height + viewportPadding)
, gridRightBoundary(transformState.getSize().width + 2 * viewportPadding)
, gridBottomBoundary(transformState.getSize().height + 2 * viewportPadding)
, pitchFactor(std::cos(transformState.getPitch()) * transformState.getCameraToCenterDistance())
{}
CollisionIndex::CollisionIndex(const TransformState& transformState_, MapMode& mapMode)
: transformState(transformState_),
viewportPadding(mapMode == MapMode::Tile ? viewportPaddingForStaticTiles : viewportPaddingDefault),
collisionGrid(transformState.getSize().width + 2 * viewportPadding,
transformState.getSize().height + 2 * viewportPadding,
25),
ignoredGrid(transformState.getSize().width + 2 * viewportPadding,
transformState.getSize().height + 2 * viewportPadding,
25),
screenRightBoundary(transformState.getSize().width + viewportPadding),
screenBottomBoundary(transformState.getSize().height + viewportPadding),
gridRightBoundary(transformState.getSize().width + 2 * viewportPadding),
gridBottomBoundary(transformState.getSize().height + 2 * viewportPadding),
pitchFactor(std::cos(transformState.getPitch()) * transformState.getCameraToCenterDistance()) {}
float CollisionIndex::approximateTileDistance(const TileDistance& tileDistance, const float lastSegmentAngle, const float pixelsToTileUnits, const float cameraToAnchorDistance, const bool pitchWithMap) {
float CollisionIndex::approximateTileDistance(const TileDistance& tileDistance,
const float lastSegmentAngle,
const float pixelsToTileUnits,
const float cameraToAnchorDistance,
const bool pitchWithMap) {
// This is a quick and dirty solution for chosing which collision circles to use (since collision circles are
// laid out in tile units). Ideally, I think we should generate collision circles on the fly in viewport coordinates
// at the time we do collision detection.

View File

@@ -20,7 +20,7 @@ class CollisionIndex {
public:
using CollisionGrid = GridIndex<IndexedSubfeature>;
explicit CollisionIndex(const TransformState&);
explicit CollisionIndex(const TransformState&, MapMode&);
std::pair<bool,bool> placeFeature(const CollisionFeature& feature,
Point<float> shift,
@@ -72,6 +72,7 @@ private:
const TransformState transformState;
const float viewportPadding;
CollisionGrid collisionGrid;
CollisionGrid ignoredGrid;

View File

@@ -95,7 +95,7 @@ Placement::Placement(const TransformState& state_,
style::TransitionOptions transitionOptions_,
const bool crossSourceCollisions,
optional<Immutable<Placement>> prevPlacement_)
: collisionIndex(state_),
: collisionIndex(state_, mapMode_),
mapMode(mapMode_),
transitionOptions(std::move(transitionOptions_)),
placementZoom(state_.getZoom()),