Fix distant collision perspective ratios (#10794).

Analog of GL JS issue #5911.
Add native ignore for tilejson-bounds.
This commit is contained in:
Chris Loer
2018-01-04 13:37:41 -08:00
committed by Chris Loer
parent c62b0af24f
commit 5bfa20d71d
5 changed files with 19 additions and 13 deletions

View File

@@ -85,6 +85,7 @@
"render-tests/text-pitch-alignment/map-text-rotation-alignment-map": "https://github.com/mapbox/mapbox-gl-native/issues/9732",
"render-tests/text-pitch-alignment/viewport-text-rotation-alignment-map": "https://github.com/mapbox/mapbox-gl-native/issues/9732",
"render-tests/text-pitch-scaling/line-half": "https://github.com/mapbox/mapbox-gl-native/issues/9732",
"render-tests/tilejson-bounds/default": "https://github.com/mapbox/mapbox-gl-native/pull/10701",
"render-tests/video/default": "skip - https://github.com/mapbox/mapbox-gl-native/issues/601",
"render-tests/background-color/colorSpace-hcl": "needs issue",
"render-tests/hillshade-accent-color/default": "skip - https://github.com/mapbox/mapbox-gl-native/pull/10642",

View File

@@ -26,19 +26,19 @@ varying vec2 v_extrude_scale;
void main() {
vec4 projectedPoint = u_matrix * vec4(a_anchor_pos, 0, 1);
highp float camera_to_anchor_distance = projectedPoint.w;
highp float collision_perspective_ratio = 0.5 + 0.5 * (camera_to_anchor_distance / u_camera_to_center_distance);
highp float collision_perspective_ratio = 0.5 + 0.5 * (u_camera_to_center_distance / camera_to_anchor_distance);
gl_Position = u_matrix * vec4(a_pos, 0.0, 1.0);
highp float padding_factor = 1.2; // Pad the vertices slightly to make room for anti-alias blur
gl_Position.xy += a_extrude * u_extrude_scale * padding_factor * gl_Position.w / collision_perspective_ratio;
gl_Position.xy += a_extrude * u_extrude_scale * padding_factor * gl_Position.w * collision_perspective_ratio;
v_placed = a_placed.x;
v_notUsed = a_placed.y;
v_radius = abs(a_extrude.y); // We don't pitch the circles, so both units of the extrusion vector are equal in magnitude to the radius
v_extrude = a_extrude * padding_factor;
v_extrude_scale = u_extrude_scale * u_camera_to_center_distance / collision_perspective_ratio;
v_extrude_scale = u_extrude_scale * u_camera_to_center_distance * collision_perspective_ratio;
}
)MBGL_SHADER";

View File

@@ -78,10 +78,10 @@ std::pair<bool,bool> CollisionIndex::placeFeature(CollisionFeature& feature,
CollisionBox& box = feature.boxes.front();
const auto projectedPoint = projectAndGetPerspectiveRatio(posMatrix, box.anchor);
const float tileToViewport = textPixelRatio * projectedPoint.second;
box.px1 = box.x1 / tileToViewport + projectedPoint.first.x;
box.py1 = box.y1 / tileToViewport + projectedPoint.first.y;
box.px2 = box.x2 / tileToViewport + projectedPoint.first.x;
box.py2 = box.y2 / tileToViewport + projectedPoint.first.y;
box.px1 = box.x1 * tileToViewport + projectedPoint.first.x;
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) ||
(!allowOverlap && collisionGrid.hitTest({{ box.px1, box.py1 }, { box.px2, box.py2 }}))) {
@@ -130,8 +130,10 @@ std::pair<bool,bool> CollisionIndex::placeLineFeature(CollisionFeature& feature,
bool entirelyOffscreen = true;
const auto tileToViewport = projectedAnchor.first * textPixelRatio;
// pixelsToTileUnits is used for translating line geometry to tile units
// ... so we care about 'scale' but not 'perspectiveRatio'
// equivalent to pixel_to_tile_units
const auto pixelsToTileUnits = tileToViewport / scale;
const auto pixelsToTileUnits = 1 / (textPixelRatio * scale);
float firstTileDistance = 0, lastTileDistance = 0;
if (firstAndLastGlyph) {
@@ -155,7 +157,7 @@ std::pair<bool,bool> CollisionIndex::placeLineFeature(CollisionFeature& feature,
const auto projectedPoint = projectPoint(posMatrix, circle.anchor);
const float tileUnitRadius = (circle.x2 - circle.x1) / 2;
const float radius = tileUnitRadius / tileToViewport;
const float radius = tileUnitRadius * tileToViewport;
if (atLeastOneCirclePlaced) {
const CollisionBox& previousCircle = feature.boxes[i - 1];
@@ -330,7 +332,7 @@ std::pair<float,float> CollisionIndex::projectAnchor(const mat4& posMatrix, cons
vec4 p = {{ point.x, point.y, 0, 1 }};
matrix::transformMat4(p, p, posMatrix);
return std::make_pair(
0.5 + 0.5 * (p[3] / transformState.getCameraToCenterDistance()),
0.5 + 0.5 * (transformState.getCameraToCenterDistance() / p[3]),
p[3]
);
}
@@ -343,7 +345,10 @@ std::pair<Point<float>,float> CollisionIndex::projectAndGetPerspectiveRatio(cons
(((p[0] / p[3] + 1) / 2) * transformState.getSize().width) + viewportPadding,
(((-p[1] / p[3] + 1) / 2) * transformState.getSize().height) + viewportPadding
),
0.5 + 0.5 * (p[3] / transformState.getCameraToCenterDistance())
// See perspective ratio comment in symbol_sdf.vertex
// We're doing collision detection in viewport space so we need
// to scale down boxes in the distance
0.5 + 0.5 * (transformState.getCameraToCenterDistance() / p[3])
);
}

View File

@@ -59,7 +59,7 @@ void Placement::placeLayer(RenderSymbolLayer& symbolLayer, const mat4& projMatri
const float pixelsToTileUnits = renderTile.id.pixelsToTileUnits(1, state.getZoom());
const float scale = std::pow(2, state.getZoom() - renderTile.tile.id.overscaledZ);
const float textPixelRatio = util::EXTENT / (util::tileSize * renderTile.tile.id.overscaleFactor());
const float textPixelRatio = (util::tileSize * renderTile.tile.id.overscaleFactor()) / util::EXTENT;
mat4 posMatrix;
state.matrixFor(posMatrix, renderTile.id);