From 73d9f26d03810854c36a96b252885353f8ba81ce Mon Sep 17 00:00:00 2001 From: Aleksandar Stojiljkovic Date: Tue, 23 Jul 2019 17:19:52 +0300 Subject: [core] Limit pitch based on edge insets. Fix max Z calculation in getProjMatrix. Patch partly fixes #15163 in a way that it doesn't allow loading tens of thousands of tiles and attempt to show area above horizon: Limit pitch based on edge insets. It is not too bad - current limit of 60 degrees stays active until center of perspective is moved towards the bottom, to 84% of screen height. The plan is to split removal of 60 degrees limit to follow up patch. Fix max Z calculation in getProjMatrix. TransformState::getProjMatrix calculation of farZ was complex with possibility to lead to negative z values. Replacing it with simpler, precise calculation: furthestDistance = cameraToCenterDistance / (1 - tanFovAboveCenter * std::tan(getPitch())); TransformState::getProjMatrix calculation of farZ was an aproximation. Replacing it with simpler, but precise calculation. Related to: #15163 --- test/map/transform.test.cpp | 3 +++ test/util/tile_cover.test.cpp | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) (limited to 'test') diff --git a/test/map/transform.test.cpp b/test/map/transform.test.cpp index 3d37312b17..84fdb06b21 100644 --- a/test/map/transform.test.cpp +++ b/test/map/transform.test.cpp @@ -9,6 +9,7 @@ using namespace mbgl; TEST(Transform, InvalidZoom) { Transform transform; + transform.resize({1, 1}); ASSERT_DOUBLE_EQ(0, transform.getLatLng().latitude()); ASSERT_DOUBLE_EQ(0, transform.getLatLng().longitude()); @@ -56,6 +57,7 @@ TEST(Transform, InvalidZoom) { TEST(Transform, InvalidBearing) { Transform transform; + transform.resize({1, 1}); ASSERT_DOUBLE_EQ(0, transform.getLatLng().latitude()); ASSERT_DOUBLE_EQ(0, transform.getLatLng().longitude()); @@ -78,6 +80,7 @@ TEST(Transform, InvalidBearing) { TEST(Transform, IntegerZoom) { Transform transform; + transform.resize({1, 1}); auto checkIntegerZoom = [&transform](uint8_t zoomInt, double zoom) { transform.jumpTo(CameraOptions().withZoom(zoom)); diff --git a/test/util/tile_cover.test.cpp b/test/util/tile_cover.test.cpp index 3fc7681520..e35e6e2e99 100644 --- a/test/util/tile_cover.test.cpp +++ b/test/util/tile_cover.test.cpp @@ -43,6 +43,41 @@ TEST(TileCover, Pitch) { util::tileCover(transform.getState(), 2)); } +TEST(TileCover, PitchOverAllowedByContentInsets) { + Transform transform; + transform.resize({ 512, 512 }); + + transform.jumpTo(CameraOptions().withCenter(LatLng { 0.1, -0.1 }).withPadding(EdgeInsets { 376, 0, 0, 0 }) + .withZoom(8.0).withBearing(45.0).withPitch(60.0)); + // Top padding of 376 leads to capped pitch. See Transform::getMaxPitchForEdgeInsets. + EXPECT_LE(transform.getPitch() + 0.001, util::DEG2RAD * 60); + + EXPECT_EQ((std::vector{ + { 3, 4, 3 }, { 3, 3, 3 }, { 3, 4, 4 }, { 3, 3, 4 }, { 3, 4, 2 }, { 3, 5, 3 }, { 3, 5, 2 } + }), + util::tileCover(transform.getState(), 3)); +} + +TEST(TileCover, PitchWithLargerResultSet) { + Transform transform; + transform.resize({ 1024, 768 }); + + // The values used here triggered the regression with left and right edge + // selection in tile_cover.cpp scanSpans. + transform.jumpTo(CameraOptions().withCenter(LatLng { 0.1, -0.1 }).withPadding(EdgeInsets { 400, 0, 0, 0 }) + .withZoom(5).withBearing(-142.2630000003529176).withPitch(60.0)); + + auto cover = util::tileCover(transform.getState(), 5); + // Returned vector has above 100 elements, we check first 16 as there is a + // plan to return lower LOD for distant tiles. + EXPECT_EQ((std::vector { + { 5, 15, 16 }, { 5, 15, 17 }, { 5, 14, 16 }, { 5, 14, 17 }, + { 5, 16, 16 }, { 5, 16, 17 }, { 5, 15, 15 }, { 5, 14, 15 }, + { 5, 15, 18 }, { 5, 14, 18 }, { 5, 16, 15 }, { 5, 13, 16 }, + { 5, 13, 17 }, { 5, 16, 18 }, { 5, 13, 18 }, { 5, 15, 19 } + }), (std::vector { cover.begin(), cover.begin() + 16}) ); +} + TEST(TileCover, WorldZ1) { EXPECT_EQ((std::vector{ { 1, 0, 0 }, { 1, 0, 1 }, { 1, 1, 0 }, { 1, 1, 1 }, -- cgit v1.2.1