From 4ba78b6bcfea756c274a05cba61352cd4681ae86 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Wed, 22 Apr 2015 16:10:31 -0700 Subject: Transform needs only a single TransformState --- src/mbgl/map/transform.cpp | 164 ++++++++++++++++++++++----------------------- src/mbgl/map/transform.hpp | 11 +-- test/ios/MapViewTests.m | 10 ++- 3 files changed, 85 insertions(+), 100 deletions(-) diff --git a/src/mbgl/map/transform.cpp b/src/mbgl/map/transform.cpp index 182e534295..cca0c2a580 100644 --- a/src/mbgl/map/transform.cpp +++ b/src/mbgl/map/transform.cpp @@ -37,17 +37,17 @@ bool Transform::resize(const uint16_t w, const uint16_t h, const float ratio, const uint16_t fb_w, const uint16_t fb_h) { std::lock_guard lock(mtx); - if (final.width != w || final.height != h || final.pixelRatio != ratio || - final.framebuffer[0] != fb_w || final.framebuffer[1] != fb_h) { + if (state.width != w || state.height != h || state.pixelRatio != ratio || + state.framebuffer[0] != fb_w || state.framebuffer[1] != fb_h) { view.notifyMapChange(MapChangeRegionWillChange); - current.width = final.width = w; - current.height = final.height = h; - current.pixelRatio = final.pixelRatio = ratio; - current.framebuffer[0] = final.framebuffer[0] = fb_w; - current.framebuffer[1] = final.framebuffer[1] = fb_h; - constrain(current.scale, current.y); + state.width = w; + state.height = h; + state.pixelRatio = ratio; + state.framebuffer[0] = fb_w; + state.framebuffer[1] = fb_h; + constrain(state.scale, state.y); view.notifyMapChange(MapChangeRegionDidChange); @@ -76,27 +76,27 @@ void Transform::_moveBy(const double dx, const double dy, const Duration duratio MapChangeRegionWillChangeAnimated : MapChangeRegionWillChange); - final.x = current.x + std::cos(current.angle) * dx + std::sin(current.angle) * dy; - final.y = current.y + std::cos(current.angle) * dy + std::sin(-current.angle) * dx; + double x = state.x + std::cos(state.angle) * dx + std::sin( state.angle) * dy; + double y = state.y + std::cos(state.angle) * dy + std::sin(-state.angle) * dx; - constrain(final.scale, final.y); + constrain(state.scale, y); if (duration == Duration::zero()) { - current.x = final.x; - current.y = final.y; + state.x = x; + state.y = y; } else { - const double startX = current.x; - const double startY = current.y; - current.panning = true; + const double startX = state.x; + const double startY = state.y; + state.panning = true; startTransition( [=](double t) { - current.x = util::interpolate(startX, final.x, t); - current.y = util::interpolate(startY, final.y, t); + state.x = util::interpolate(startX, x, t); + state.y = util::interpolate(startY, y, t); return Update::Nothing; }, [=] { - current.panning = false; + state.panning = false; }, duration); } @@ -116,10 +116,10 @@ void Transform::setLatLng(const LatLng latLng, const Duration duration) { const double m = 1 - 1e-15; const double f = std::fmin(std::fmax(std::sin(util::DEG2RAD * latLng.latitude), -m), m); - double xn = -latLng.longitude * current.Bc; - double yn = 0.5 * current.Cc * std::log((1 + f) / (1 - f)); + double xn = -latLng.longitude * state.Bc; + double yn = 0.5 * state.Cc * std::log((1 + f) / (1 - f)); - _setScaleXY(current.scale, xn, yn, duration); + _setScaleXY(state.scale, xn, yn, duration); } void Transform::setLatLngZoom(const LatLng latLng, const double zoom, const Duration duration) { @@ -132,14 +132,14 @@ void Transform::setLatLngZoom(const LatLng latLng, const double zoom, const Dura double new_scale = std::pow(2.0, zoom); const double s = new_scale * util::tileSize; - current.Bc = s / 360; - current.Cc = s / util::M2PI; + state.Bc = s / 360; + state.Cc = s / util::M2PI; const double m = 1 - 1e-15; const double f = std::fmin(std::fmax(std::sin(util::DEG2RAD * latLng.latitude), -m), m); - double xn = -latLng.longitude * current.Bc; - double yn = 0.5 * current.Cc * std::log((1 + f) / (1 - f)); + double xn = -latLng.longitude * state.Bc; + double yn = 0.5 * state.Cc * std::log((1 + f) / (1 - f)); _setScaleXY(new_scale, xn, yn, duration); } @@ -155,7 +155,7 @@ void Transform::scaleBy(const double ds, const double cx, const double cy, const std::lock_guard lock(mtx); // clamp scale to min/max values - double new_scale = current.scale * ds; + double new_scale = state.scale * ds; if (new_scale < min_scale) { new_scale = min_scale; } else if (new_scale > max_scale) { @@ -189,18 +189,18 @@ void Transform::setZoom(const double zoom, const Duration duration) { double Transform::getZoom() const { std::lock_guard lock(mtx); - return final.getZoom(); + return state.getZoom(); } double Transform::getScale() const { std::lock_guard lock(mtx); - return final.scale; + return state.scale; } double Transform::getMinZoom() const { - double test_scale = current.scale; - double test_y = current.y; + double test_scale = state.scale; + double test_y = state.y; constrain(test_scale, test_y); return std::log2(std::fmin(min_scale, test_scale)); @@ -222,23 +222,23 @@ void Transform::_setScale(double new_scale, double cx, double cy, const Duration // Zoom in on the center if we don't have click or gesture anchor coordinates. if (cx < 0 || cy < 0) { - cx = static_cast(current.width) / 2.0; - cy = static_cast(current.height) / 2.0; + cx = static_cast(state.width) / 2.0; + cy = static_cast(state.height) / 2.0; } // Account for the x/y offset from the center (= where the user clicked or pinched) - const double factor = new_scale / current.scale; - const double dx = (cx - static_cast(current.width) / 2.0) * (1.0 - factor); - const double dy = (cy - static_cast(current.height) / 2.0) * (1.0 - factor); + const double factor = new_scale / state.scale; + const double dx = (cx - static_cast(state.width) / 2.0) * (1.0 - factor); + const double dy = (cy - static_cast(state.height) / 2.0) * (1.0 - factor); // Account for angle - const double angle_sin = std::sin(-current.angle); - const double angle_cos = std::cos(-current.angle); + const double angle_sin = std::sin(-state.angle); + const double angle_cos = std::cos(-state.angle); const double ax = angle_cos * dx - angle_sin * dy; const double ay = angle_sin * dx + angle_cos * dy; - const double xn = current.x * factor + ax; - const double yn = current.y * factor + ay; + const double xn = state.x * factor + ax; + const double yn = state.y * factor + ay; _setScaleXY(new_scale, xn, yn, duration); } @@ -251,39 +251,39 @@ void Transform::_setScaleXY(const double new_scale, const double xn, const doubl MapChangeRegionWillChangeAnimated : MapChangeRegionWillChange); - final.scale = new_scale; - final.x = xn; - final.y = yn; + double scale = new_scale; + double x = xn; + double y = yn; - constrain(final.scale, final.y); + constrain(scale, y); if (duration == Duration::zero()) { - current.scale = final.scale; - current.x = final.x; - current.y = final.y; - const double s = current.scale * util::tileSize; - current.Bc = s / 360; - current.Cc = s / util::M2PI; + state.scale = scale; + state.x = x; + state.y = y; + const double s = state.scale * util::tileSize; + state.Bc = s / 360; + state.Cc = s / util::M2PI; } else { - const double startS = current.scale; - const double startX = current.x; - const double startY = current.y; - current.panning = true; - current.scaling = true; + const double startS = state.scale; + const double startX = state.x; + const double startY = state.y; + state.panning = true; + state.scaling = true; startTransition( [=](double t) { - current.scale = util::interpolate(startS, final.scale, t); - current.x = util::interpolate(startX, final.x, t); - current.y = util::interpolate(startY, final.y, t); - const double s = current.scale * util::tileSize; - current.Bc = s / 360; - current.Cc = s / util::M2PI; + state.scale = util::interpolate(startS, scale, t); + state.x = util::interpolate(startX, x, t); + state.y = util::interpolate(startY, y, t); + const double s = state.scale * util::tileSize; + state.Bc = s / 360; + state.Cc = s / util::M2PI; return Update::Zoom; }, [=] { - current.panning = false; - current.scaling = false; + state.panning = false; + state.scaling = false; }, duration); } @@ -297,10 +297,10 @@ void Transform::_setScaleXY(const double new_scale, const double xn, const doubl void Transform::constrain(double& scale, double& y) const { // Constrain minimum zoom to avoid zooming out far enough to show off-world areas. - if (scale < (current.height / util::tileSize)) scale = (current.height / util::tileSize); + if (scale < (state.height / util::tileSize)) scale = (state.height / util::tileSize); // Constrain min/max vertical pan to avoid showing off-world areas. - double max_y = ((scale * util::tileSize) - current.height) / 2; + double max_y = ((scale * util::tileSize) - state.height) / 2; if (y > max_y) y = max_y; if (y < -max_y) y = -max_y; @@ -316,7 +316,7 @@ void Transform::rotateBy(const double start_x, const double start_y, const doubl std::lock_guard lock(mtx); - double center_x = static_cast(current.width) / 2.0, center_y = static_cast(current.height) / 2.0; + double center_x = static_cast(state.width) / 2.0, center_y = static_cast(state.height) / 2.0; const double begin_center_x = start_x - center_x; const double begin_center_y = start_y - center_y; @@ -338,7 +338,7 @@ void Transform::rotateBy(const double start_x, const double start_y, const doubl const double first_x = start_x - center_x, first_y = start_y - center_y; const double second_x = end_x - center_x, second_y = end_y - center_y; - const double ang = current.angle + util::angle_between(first_x, first_y, second_x, second_y); + const double ang = state.angle + util::angle_between(first_x, first_y, second_x, second_y); _setAngle(ang, duration); } @@ -363,8 +363,8 @@ void Transform::setAngle(const double new_angle, const double cx, const double c double dx = 0, dy = 0; if (cx >= 0 && cy >= 0) { - dx = (static_cast(final.width) / 2.0) - cx; - dy = (static_cast(final.height) / 2.0) - cy; + dx = (static_cast(state.width) / 2.0) - cx; + dy = (static_cast(state.height) / 2.0) - cy; _moveBy(dx, dy, Duration::zero()); } @@ -382,22 +382,22 @@ void Transform::_setAngle(double new_angle, const Duration duration) { MapChangeRegionWillChangeAnimated : MapChangeRegionWillChange); - final.angle = _normalizeAngle(new_angle, current.angle); - current.angle = _normalizeAngle(current.angle, final.angle); + double angle = _normalizeAngle(new_angle, state.angle); + state.angle = _normalizeAngle(state.angle, angle); if (duration == Duration::zero()) { - current.angle = final.angle; + state.angle = angle; } else { - const double startA = current.angle; - current.rotating = true; + const double startA = state.angle; + state.rotating = true; startTransition( [=](double t) { - current.angle = util::interpolate(startA, final.angle, t); + state.angle = util::interpolate(startA, angle, t); return Update::Nothing; }, [=] { - current.rotating = false; + state.rotating = false; }, duration); } @@ -410,7 +410,7 @@ void Transform::_setAngle(double new_angle, const Duration duration) { double Transform::getAngle() const { std::lock_guard lock(mtx); - return final.angle; + return state.angle; } @@ -467,7 +467,7 @@ void Transform::cancelTransitions() { void Transform::setGestureInProgress(bool inProgress) { std::lock_guard lock(mtx); - current.gestureInProgress = inProgress; + state.gestureInProgress = inProgress; } #pragma mark - Transform state @@ -475,11 +475,5 @@ void Transform::setGestureInProgress(bool inProgress) { const TransformState Transform::currentState() const { std::lock_guard lock(mtx); - return current; -} - -const TransformState Transform::finalState() const { - std::lock_guard lock(mtx); - - return final; + return state; } diff --git a/src/mbgl/map/transform.hpp b/src/mbgl/map/transform.hpp index ef89a4eefa..d7660d5381 100644 --- a/src/mbgl/map/transform.hpp +++ b/src/mbgl/map/transform.hpp @@ -31,7 +31,7 @@ public: void moveBy(double dx, double dy, Duration = Duration::zero()); void setLatLng(LatLng latLng, Duration = Duration::zero()); void setLatLngZoom(LatLng latLng, double zoom, Duration = Duration::zero()); - inline const LatLng getLatLng() const { return current.getLatLng(); } + inline const LatLng getLatLng() const { return state.getLatLng(); } // Zoom void scaleBy(double ds, double cx = -1, double cy = -1, Duration = Duration::zero()); @@ -58,7 +58,6 @@ public: // Transform state const TransformState currentState() const; - const TransformState finalState() const; private: // Functions prefixed with underscores will *not* perform any locks. It is the caller's @@ -74,13 +73,7 @@ private: mutable std::recursive_mutex mtx; - // This reflects the current state of the transform, representing the actual position of the - // map. After calling a transform function with a timer, this will likely remain the same until - // you render a new frame. - TransformState current; - - // This reflects the final position of the transform, after all possible transition took place. - TransformState final; + TransformState state; // Limit the amount of zooming possible on the map. const double min_scale = std::pow(2, 0); diff --git a/test/ios/MapViewTests.m b/test/ios/MapViewTests.m index 3755da0bcd..ed378877c8 100644 --- a/test/ios/MapViewTests.m +++ b/test/ios/MapViewTests.m @@ -76,9 +76,8 @@ 0, @"compass should not be visible when map is unrotated"); - XCTAssertEqualObjects([NSValue valueWithCGAffineTransform:tester.compass.transform], - [NSValue valueWithCGAffineTransform:CGAffineTransformIdentity], - @"compass rotation should indicate map rotation"); + XCTAssert(CGAffineTransformEqualToTransform(tester.compass.transform, CGAffineTransformIdentity), + @"compass rotation should indicate map rotation"); } - (void)testDirectionReset { @@ -100,9 +99,8 @@ 0, @"compass should not be visible when map is unrotated"); - XCTAssertEqualObjects([NSValue valueWithCGAffineTransform:tester.compass.transform], - [NSValue valueWithCGAffineTransform:CGAffineTransformIdentity], - @"compass rotation should indicate map rotation"); + XCTAssert(CGAffineTransformEqualToTransform(tester.compass.transform, CGAffineTransformIdentity), + @"compass rotation should indicate map rotation"); } - (void)testZoom { -- cgit v1.2.1