From fb39e154fe53384ddbb857681065248abb6792f4 Mon Sep 17 00:00:00 2001 From: Daria Volvenkova Date: Mon, 30 May 2016 14:51:58 +0300 Subject: [PATCH 01/18] Follow animation operates with pixel positions on viewport. --- drape_frontend/animation/follow_animation.cpp | 10 ++++++---- drape_frontend/my_position_controller.cpp | 14 ++++++-------- drape_frontend/my_position_controller.hpp | 2 -- drape_frontend/screen_animations.cpp | 2 +- drape_frontend/screen_operations.cpp | 12 ++++++++++++ drape_frontend/screen_operations.hpp | 2 ++ drape_frontend/user_event_stream.cpp | 6 ++++++ 7 files changed, 33 insertions(+), 15 deletions(-) diff --git a/drape_frontend/animation/follow_animation.cpp b/drape_frontend/animation/follow_animation.cpp index 4c387fcecd..ba708512ea 100644 --- a/drape_frontend/animation/follow_animation.cpp +++ b/drape_frontend/animation/follow_animation.cpp @@ -98,7 +98,7 @@ m2::PointD MapFollowAnimation::CalculateCenter(ScreenBase const & screen, m2::Po m2::PointD const & pixelPos, double azimuth) { double const scale = screen.GlobalRect().GetLocalRect().SizeX() / screen.PixelRect().SizeX(); - return CalculateCenter(scale, screen.PixelRect(), userPos, pixelPos, azimuth); + return CalculateCenter(scale, screen.PixelRect(), userPos, screen.P3dtoP(pixelPos), azimuth); } // static @@ -126,16 +126,18 @@ bool MapFollowAnimation::GetProperty(TObject object, TProperty property, bool ta { if (property == Animation::Position) { - m2::RectD const pixelRect = AnimationSystem::Instance().GetLastScreen().PixelRect(); + ScreenBase const & screen = AnimationSystem::Instance().GetLastScreen(); + m2::RectD const pixelRect = screen.PixelRect(); if (targetValue) { + // TODO: calculate target pixel position with corresponding scale value = PropertyValue(CalculateCenter(m_scaleInterpolator.GetTargetScale(), pixelRect, m_globalPosition, - m_pixelPosInterpolator.GetTargetPosition(), m_angleInterpolator.GetTargetAngle())); + screen.P3dtoP(m_pixelPosInterpolator.GetTargetPosition()), m_angleInterpolator.GetTargetAngle())); } else { value = PropertyValue(CalculateCenter(m_scaleInterpolator.GetScale(), pixelRect, m_globalPosition, - m_pixelPosInterpolator.GetPosition(), m_angleInterpolator.GetAngle())); + screen.P3dtoP(m_pixelPosInterpolator.GetPosition()), m_angleInterpolator.GetAngle())); } return true; } diff --git a/drape_frontend/my_position_controller.cpp b/drape_frontend/my_position_controller.cpp index 8c179fab77..5d91c921d4 100644 --- a/drape_frontend/my_position_controller.cpp +++ b/drape_frontend/my_position_controller.cpp @@ -112,8 +112,6 @@ void MyPositionController::UpdatePixelPosition(ScreenBase const & screen) { m_pixelRect = screen.isPerspective() ? screen.PixelRectIn3d() : screen.PixelRect(); m_positionYOffset = screen.isPerspective() ? kPositionOffsetYIn3D : kPositionOffsetY; - m_centerPixelPositionRouting = screen.P3dtoP(GetRoutingRotationPixelCenter()); - m_centerPixelPosition = screen.P3dtoP(m_pixelRect.Center()); } void MyPositionController::SetListener(ref_ptr listener) @@ -266,7 +264,7 @@ void MyPositionController::NextMode(ScreenBase const & screen) if (!m_isInRouting) { ChangeMode(location::Follow); - ChangeModelView(m_position, 0.0, m_centerPixelPosition, preferredZoomLevel); + ChangeModelView(m_position, 0.0, m_pixelRect.Center(), preferredZoomLevel); } } } @@ -317,7 +315,7 @@ void MyPositionController::OnLocationUpdate(location::GpsInfo const & info, bool ChangeModelView(m_position, kDoNotChangeZoom); else if (m_mode == location::FollowAndRotate) ChangeModelView(m_position, m_drawDirection, - m_isInRouting ? m_centerPixelPositionRouting : m_centerPixelPosition, kDoNotChangeZoom); + m_isInRouting ? GetRoutingRotationPixelCenter() : m_pixelRect.Center(), kDoNotChangeZoom); } } else if (m_mode == location::PendingPosition || m_mode == location::NotFollowNoPosition) @@ -525,7 +523,7 @@ void MyPositionController::OnCompassTapped() if (m_mode == location::FollowAndRotate) { ChangeMode(location::Follow); - ChangeModelView(m_position, 0.0, m_centerPixelPosition, kDoNotChangeZoom); + ChangeModelView(m_position, 0.0, m_pixelRect.Center(), kDoNotChangeZoom); } else { @@ -567,7 +565,7 @@ void MyPositionController::UpdateViewport(int zoomLevel) ChangeModelView(m_position, zoomLevel); else if (m_mode == location::FollowAndRotate) ChangeModelView(m_position, m_drawDirection, - m_isInRouting ? m_centerPixelPositionRouting : m_centerPixelPosition, zoomLevel); + m_isInRouting ? GetRoutingRotationPixelCenter() : m_pixelRect.Center(), zoomLevel); } m2::PointD MyPositionController::GetRotationPixelCenter() const @@ -658,7 +656,7 @@ void MyPositionController::ActivateRouting(int zoomLevel) if (IsRotationAvailable()) { ChangeMode(location::FollowAndRotate); - ChangeModelView(m_position, m_drawDirection, m_centerPixelPositionRouting, zoomLevel); + ChangeModelView(m_position, m_drawDirection, GetRoutingRotationPixelCenter(), zoomLevel); } else { @@ -675,7 +673,7 @@ void MyPositionController::DeactivateRouting() m_isInRouting = false; ChangeMode(location::Follow); - ChangeModelView(m_position, 0.0, m_centerPixelPosition, kDoNotChangeZoom); + ChangeModelView(m_position, 0.0, m_pixelRect.Center(), kDoNotChangeZoom); } } diff --git a/drape_frontend/my_position_controller.hpp b/drape_frontend/my_position_controller.hpp index 997daa6f0e..e93b6e9fff 100644 --- a/drape_frontend/my_position_controller.hpp +++ b/drape_frontend/my_position_controller.hpp @@ -153,8 +153,6 @@ private: double m_lastLocationTimestamp; m2::RectD m_pixelRect; - m2::PointD m_centerPixelPositionRouting; - m2::PointD m_centerPixelPosition; double m_positionYOffset; bool m_isVisible; diff --git a/drape_frontend/screen_animations.cpp b/drape_frontend/screen_animations.cpp index e4119bbdbd..0364f765d8 100644 --- a/drape_frontend/screen_animations.cpp +++ b/drape_frontend/screen_animations.cpp @@ -101,7 +101,7 @@ drape_ptr GetFollowAnimation(ScreenBase const & startScreen, { auto anim = make_unique_dp(userPos, startScreen.GetScale(), targetScale, startScreen.GetAngle(), targetAngle, - startScreen.GtoP(userPos), endPixelPos, startScreen.PixelRect()); + startScreen.PtoP3d(startScreen.GtoP(userPos)), endPixelPos, startScreen.PixelRect()); anim->SetMaxDuration(kMaxAnimationTimeSec); return anim; diff --git a/drape_frontend/screen_operations.cpp b/drape_frontend/screen_operations.cpp index acc083dedc..5060097425 100644 --- a/drape_frontend/screen_operations.cpp +++ b/drape_frontend/screen_operations.cpp @@ -272,4 +272,16 @@ bool ApplyScale(m2::PointD const & pixelScaleCenter, double factor, ScreenBase & return true; } +double CalculatePerspectiveAngle(ScreenBase const & screen) +{ + double const kStartPerspectiveScale = 0.5; + double const kMaxScale = 0.2; + double const kMaxPerspectiveAngle = math::pi4; + + double const currentScale = screen.GetScale(); + if (currentScale > kStartPerspectiveScale) + return 0.0; + return kMaxPerspectiveAngle * (kStartPerspectiveScale - currentScale) / (kStartPerspectiveScale - kMaxScale); +} + } // namespace df diff --git a/drape_frontend/screen_operations.hpp b/drape_frontend/screen_operations.hpp index dd34bdad7e..e9239180e5 100644 --- a/drape_frontend/screen_operations.hpp +++ b/drape_frontend/screen_operations.hpp @@ -28,4 +28,6 @@ m2::PointD CalculateCenter(double scale, m2::RectD const & pixelRect, bool ApplyScale(m2::PointD const & pixelScaleCenter, double factor, ScreenBase & screen); +double CalculatePerspectiveAngle(ScreenBase const & screen); + } // namespace df diff --git a/drape_frontend/user_event_stream.cpp b/drape_frontend/user_event_stream.cpp index 0a7cdc687f..622c4b6a10 100644 --- a/drape_frontend/user_event_stream.cpp +++ b/drape_frontend/user_event_stream.cpp @@ -576,6 +576,9 @@ void UserEventStream::SetEnable3dMode(double maxRotationAngle, double angleFOV, { ResetAnimationsBeforeSwitch3D(); + //m_navigator.Enable3dMode(0.0, maxRotationAngle, angleFOV); + //return; + if (immediatelyStart) InterruptFollowAnimations(true /* force */); @@ -602,6 +605,9 @@ void UserEventStream::SetDisable3dModeAnimation() ResetAnimationsBeforeSwitch3D(); InterruptFollowAnimations(true /* force */); + //m_navigator.Disable3dMode(); + //return; + if (m_discardedFOV > 0.0 && IsScaleAllowableIn3d(GetDrawTileScale(GetCurrentScreen()))) { m_discardedFOV = m_discardedAngle = 0.0; From 6cb5375879befdfd8cc7cf2f9c93e5c187149bb2 Mon Sep 17 00:00:00 2001 From: Daria Volvenkova Date: Mon, 30 May 2016 19:34:31 +0300 Subject: [PATCH 02/18] Scale animation operates with pixel positions on viewport. --- drape_frontend/animation/scale_animation.cpp | 7 ++++--- drape_frontend/animation/scale_animation.hpp | 4 ++-- drape_frontend/screen_animations.cpp | 3 +-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drape_frontend/animation/scale_animation.cpp b/drape_frontend/animation/scale_animation.cpp index 92f814df1d..e0257e953c 100644 --- a/drape_frontend/animation/scale_animation.cpp +++ b/drape_frontend/animation/scale_animation.cpp @@ -8,10 +8,10 @@ namespace df { MapScaleAnimation::MapScaleAnimation(double startScale, double endScale, m2::PointD const & globalScaleCenter, - m2::PointD const & pixelCenterOffset) + m2::PointD const & pxScaleCenter) : Animation(true /* couldBeInterrupted */, true /* couldBeBlended */) , m_scaleInterpolator(startScale, endScale) - , m_pixelCenterOffset(pixelCenterOffset) + , m_pxScaleCenter(pxScaleCenter) , m_globalScaleCenter(globalScaleCenter) { m_objects.insert(Animation::MapPlane); @@ -64,7 +64,8 @@ bool MapScaleAnimation::GetProperty(TObject object, TProperty property, bool tar { ScreenBase screen = AnimationSystem::Instance().GetLastScreen(); screen.SetScale(targetValue ? m_scaleInterpolator.GetTargetScale() : m_scaleInterpolator.GetScale()); - value = PropertyValue(screen.PtoG(screen.GtoP(m_globalScaleCenter) + m_pixelCenterOffset)); + m2::PointD const pixelOffset = screen.PixelRect().Center() - screen.P3dtoP(m_pxScaleCenter); + value = PropertyValue(screen.PtoG(screen.GtoP(m_globalScaleCenter) + pixelOffset)); return true; } if (property == Animation::Scale) diff --git a/drape_frontend/animation/scale_animation.hpp b/drape_frontend/animation/scale_animation.hpp index 07706c604a..44b53c54a8 100644 --- a/drape_frontend/animation/scale_animation.hpp +++ b/drape_frontend/animation/scale_animation.hpp @@ -10,7 +10,7 @@ class MapScaleAnimation : public Animation { public: MapScaleAnimation(double startScale, double endScale, - m2::PointD const & globalScaleCenter, m2::PointD const & pixelCenterOffset); + m2::PointD const & globalScaleCenter, m2::PointD const & pxScaleCenter); Animation::Type GetType() const override { return Animation::MapScale; } @@ -41,7 +41,7 @@ private: bool GetProperty(TObject object, TProperty property, bool targetValue, PropertyValue & value) const; ScaleInterpolator m_scaleInterpolator; - m2::PointD const m_pixelCenterOffset; + m2::PointD const m_pxScaleCenter; m2::PointD const m_globalScaleCenter; TObjectProperties m_properties; TAnimObjects m_objects; diff --git a/drape_frontend/screen_animations.cpp b/drape_frontend/screen_animations.cpp index 0364f765d8..e2076746ef 100644 --- a/drape_frontend/screen_animations.cpp +++ b/drape_frontend/screen_animations.cpp @@ -113,9 +113,8 @@ drape_ptr GetScaleAnimation(ScreenBase const & startScreen, m ScreenBase endScreen = startScreen; ApplyScale(pxScaleCenter, factor, endScreen); - m2::PointD const offset = startScreen.PixelRect().Center() - startScreen.P3dtoP(pxScaleCenter); auto anim = make_unique_dp(startScreen.GetScale(), endScreen.GetScale(), - glbScaleCenter, offset); + glbScaleCenter, pxScaleCenter); anim->SetMaxDuration(kMaxAnimationTimeSec); return anim; From c949c0c407bbd1742a03b7189ee42c59f03dcbae Mon Sep 17 00:00:00 2001 From: Daria Volvenkova Date: Mon, 6 Jun 2016 11:54:32 +0300 Subject: [PATCH 03/18] Set perspective angle automatically when the scale is changing. --- drape_frontend/navigator.cpp | 7 +++++++ drape_frontend/navigator.hpp | 1 + drape_frontend/user_event_stream.cpp | 3 +++ geometry/screenbase.cpp | 25 +++++++++++++++++++++++++ geometry/screenbase.hpp | 3 +++ 5 files changed, 39 insertions(+) diff --git a/drape_frontend/navigator.cpp b/drape_frontend/navigator.cpp index f695b9917e..b68c595e37 100644 --- a/drape_frontend/navigator.cpp +++ b/drape_frontend/navigator.cpp @@ -307,6 +307,13 @@ void Navigator::Disable3dMode() m_Screen.ResetPerspective(); } +bool Navigator::UpdatePerspective() +{ + bool const isPerspective = m_Screen.isPerspective(); + m_Screen.UpdatePerspectiveParameters(); + return isPerspective != m_Screen.isPerspective(); +} + m2::AnyRectD ToRotated(Navigator const & navigator, m2::RectD const & rect) { double const dx = rect.SizeX(); diff --git a/drape_frontend/navigator.hpp b/drape_frontend/navigator.hpp index ba6773e442..6e05419e81 100644 --- a/drape_frontend/navigator.hpp +++ b/drape_frontend/navigator.hpp @@ -46,6 +46,7 @@ public: void Enable3dMode(double currentRotationAngle, double maxRotationAngle, double angleFOV); void SetRotationIn3dMode(double rotationAngle); void Disable3dMode(); + bool UpdatePerspective(); private: // Internal screen corresponding to the state when navigation began with StartDrag or StartScale. diff --git a/drape_frontend/user_event_stream.cpp b/drape_frontend/user_event_stream.cpp index 622c4b6a10..4fe138b586 100644 --- a/drape_frontend/user_event_stream.cpp +++ b/drape_frontend/user_event_stream.cpp @@ -267,6 +267,9 @@ ScreenBase const & UserEventStream::ProcessEvents(bool & modelViewChanged, bool DetectLongTap(m_touches[0]); } + if (m_modelViewChanged) + m_viewportChanged |= m_navigator.UpdatePerspective(); + modelViewChanged = m_modelViewChanged; viewportChanged = m_viewportChanged; m_modelViewChanged = false; diff --git a/geometry/screenbase.cpp b/geometry/screenbase.cpp index b46a6da78c..fd5ce38f9b 100644 --- a/geometry/screenbase.cpp +++ b/geometry/screenbase.cpp @@ -75,6 +75,31 @@ void ScreenBase::UpdateDependentParameters() m_ClipRect = m_GlobalRect.GetGlobalRect(); } +double ScreenBase::CalculatePerspectiveAngle(double scale) +{ + double const kStartPerspectiveScale = 0.13e-4; + double const kMaxScale = 0.13e-5; + double const kMaxPerspectiveAngle = math::pi4; + + if (scale > kStartPerspectiveScale) + return 0.0; + return kMaxPerspectiveAngle * (kStartPerspectiveScale - scale) / (kStartPerspectiveScale - kMaxScale); +} + +void ScreenBase::UpdatePerspectiveParameters() +{ + double const angle = CalculatePerspectiveAngle(m_Scale); + if (angle > 0.0) + { + if (m_isPerspective) + SetRotationAngle(angle); + else + ApplyPerspective(angle, math::pi4, math::pi / 3); + } + else if (m_isPerspective) + ResetPerspective(); +} + void ScreenBase::SetFromRects(m2::AnyRectD const & glbRect, m2::RectD const & pxRect) { double hScale = glbRect.GetLocalRect().SizeX() / pxRect.SizeX(); diff --git a/geometry/screenbase.hpp b/geometry/screenbase.hpp index 93959d9998..ef5125d9e4 100644 --- a/geometry/screenbase.hpp +++ b/geometry/screenbase.hpp @@ -126,6 +126,7 @@ public: m2::AnyRectD const & GlobalRect() const { return m_GlobalRect; } m2::RectD const & ClipRect() const { return m_ClipRect; } + void UpdatePerspectiveParameters(); void ApplyPerspective(double currentRotationAngle, double maxRotationAngle, double angleFOV); void ResetPerspective(); @@ -156,6 +157,8 @@ public: m2::PointD const & newPt1, m2::PointD const & newPt2, bool allowRotate); + static double CalculatePerspectiveAngle(double scale); + /// Setting GtoP matrix extracts the Angle and m_Org parameters, leaving PixelRect intact void SetGtoPMatrix(MatrixT const & m); From 2ac8539d73b9502c5ca05b85f2a05c019f393a84 Mon Sep 17 00:00:00 2001 From: Daria Volvenkova Date: Thu, 9 Jun 2016 16:30:39 +0300 Subject: [PATCH 04/18] Calculate current rotation angle in perspective mode. --- drape_frontend/frontend_renderer.cpp | 6 ++++- drape_frontend/navigator.cpp | 4 ++-- drape_frontend/rule_drawer.cpp | 4 ++-- geometry/screenbase.cpp | 35 ++++++++++++++++++++-------- geometry/screenbase.hpp | 2 +- 5 files changed, 35 insertions(+), 16 deletions(-) diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index 3b06a0adbf..9b826a08c7 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -1232,7 +1232,11 @@ void FrontendRenderer::RefreshModelView(ScreenBase const & screen) m_generalUniforms.SetMatrix4x4Value("modelView", mv.m_data); - float const zScale = 2.0f / (screen.GetHeight() * screen.GetScale()); + // TODO: Calculate exact value of zScale + double const averageScale3d = 3.0; + float const zScale = 2.0f / (screen.PixelRectIn3d().SizeY() * averageScale3d * screen.GetScale()); + //float const zScale = 2.0f / (screen.GetHeight() * screen.GetScale()); + m_generalUniforms.SetFloatValue("zScale", zScale); } diff --git a/drape_frontend/navigator.cpp b/drape_frontend/navigator.cpp index b68c595e37..a2e2034ec1 100644 --- a/drape_frontend/navigator.cpp +++ b/drape_frontend/navigator.cpp @@ -309,9 +309,9 @@ void Navigator::Disable3dMode() bool Navigator::UpdatePerspective() { - bool const isPerspective = m_Screen.isPerspective(); + double const maxPerspAngle = m_Screen.GetMaxRotationAngle(); m_Screen.UpdatePerspectiveParameters(); - return isPerspective != m_Screen.isPerspective(); + return maxPerspAngle != m_Screen.GetMaxRotationAngle(); } m2::AnyRectD ToRotated(Navigator const & navigator, m2::RectD const & rect) diff --git a/drape_frontend/rule_drawer.cpp b/drape_frontend/rule_drawer.cpp index a3b2ba949a..2a7a3a8102 100644 --- a/drape_frontend/rule_drawer.cpp +++ b/drape_frontend/rule_drawer.cpp @@ -203,10 +203,10 @@ void RuleDrawer::operator()(FeatureType const & f) double const lat = MercatorBounds::YToLat(featureCenter.y); m2::RectD rectMercator = MercatorBounds::MetresToXY(lon, lat, heightInMeters); - areaHeight = m2::PointD(rectMercator.SizeX(), rectMercator.SizeY()).Length(); + areaHeight = (rectMercator.SizeX() + rectMercator.SizeY()) / 2.0; rectMercator = MercatorBounds::MetresToXY(lon, lat, minHeigthInMeters); - areaMinHeight = m2::PointD(rectMercator.SizeX(), rectMercator.SizeY()).Length(); + areaMinHeight = (rectMercator.SizeX() + rectMercator.SizeY()) / 2.0; } bool applyPointStyle = s.PointStyleExists(); diff --git a/geometry/screenbase.cpp b/geometry/screenbase.cpp index fd5ce38f9b..7dc94b4efd 100644 --- a/geometry/screenbase.cpp +++ b/geometry/screenbase.cpp @@ -7,6 +7,13 @@ #include "std/cmath.hpp" +double constexpr kPerspectiveAngleFOV = math::pi / 3.0; +double constexpr kMaxPerspectiveAngle1 = math::pi4; +double constexpr kMaxPerspectiveAngle2 = math::pi * 55.0 / 180.0; + +double constexpr kStartPerspectiveScale1 = 1.7e-5; +double constexpr kEndPerspectiveScale1 = 0.3e-5; +double constexpr kEndPerspectiveScale2 = 0.13e-5; ScreenBase::ScreenBase() : m_PixelRect(0, 0, 640, 480), @@ -26,7 +33,6 @@ ScreenBase::ScreenBase() : { m_GtoP = math::Identity(); m_PtoG = math::Identity(); -// UpdateDependentParameters(); } ScreenBase::ScreenBase(m2::RectI const & pxRect, m2::AnyRectD const & glbRect) @@ -77,13 +83,20 @@ void ScreenBase::UpdateDependentParameters() double ScreenBase::CalculatePerspectiveAngle(double scale) { - double const kStartPerspectiveScale = 0.13e-4; - double const kMaxScale = 0.13e-5; - double const kMaxPerspectiveAngle = math::pi4; - - if (scale > kStartPerspectiveScale) + if (scale > kStartPerspectiveScale1) return 0.0; - return kMaxPerspectiveAngle * (kStartPerspectiveScale - scale) / (kStartPerspectiveScale - kMaxScale); + else if (scale > kEndPerspectiveScale1) + { + double const k = (kStartPerspectiveScale1 - scale) / (kStartPerspectiveScale1 - kEndPerspectiveScale1); + return kMaxPerspectiveAngle1 * k; + } + else if (scale > kEndPerspectiveScale2) + { + double const k = (kEndPerspectiveScale1 - scale) / (kEndPerspectiveScale1 - kEndPerspectiveScale2); + return kMaxPerspectiveAngle1 + (kMaxPerspectiveAngle2 - kMaxPerspectiveAngle1) * k; + } + else + return kMaxPerspectiveAngle2 * 0.99; } void ScreenBase::UpdatePerspectiveParameters() @@ -91,10 +104,12 @@ void ScreenBase::UpdatePerspectiveParameters() double const angle = CalculatePerspectiveAngle(m_Scale); if (angle > 0.0) { - if (m_isPerspective) - SetRotationAngle(angle); + if (!m_isPerspective || (angle < kMaxPerspectiveAngle1 && m_3dMaxAngleX > kMaxPerspectiveAngle1)) + ApplyPerspective(angle, kMaxPerspectiveAngle1, kPerspectiveAngleFOV); + else if (angle > m_3dMaxAngleX) + ApplyPerspective(angle, kMaxPerspectiveAngle2, kPerspectiveAngleFOV); else - ApplyPerspective(angle, math::pi4, math::pi / 3); + SetRotationAngle(angle); } else if (m_isPerspective) ResetPerspective(); diff --git a/geometry/screenbase.hpp b/geometry/screenbase.hpp index ef5125d9e4..24b4076643 100644 --- a/geometry/screenbase.hpp +++ b/geometry/screenbase.hpp @@ -132,7 +132,7 @@ public: void SetRotationAngle(double rotationAngle); double GetRotationAngle() const { return m_3dAngleX; } - + double GetMaxRotationAngle() const { return m_3dMaxAngleX; } double GetAngleFOV() const { return m_3dFOV; } m2::PointD P3dtoP(m2::PointD const & pt) const; From c8285a867a6cc43c06843fb696a6a64db59399da Mon Sep 17 00:00:00 2001 From: Daria Volvenkova Date: Thu, 9 Jun 2016 19:12:46 +0300 Subject: [PATCH 05/18] Assert on tap fixed. --- drape_frontend/user_event_stream.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drape_frontend/user_event_stream.cpp b/drape_frontend/user_event_stream.cpp index 4fe138b586..eab529320f 100644 --- a/drape_frontend/user_event_stream.cpp +++ b/drape_frontend/user_event_stream.cpp @@ -1178,7 +1178,7 @@ void UserEventStream::EndTapDetector(Touch const & touch) void UserEventStream::CancelTapDetector() { TEST_CALL(CANCEL_TAP_DETECTOR); - ASSERT(m_state == STATE_TAP_DETECTION || m_state == STATE_WAIT_DOUBLE_TAP, ()); + ASSERT(m_state == STATE_TAP_DETECTION || m_state == STATE_WAIT_DOUBLE_TAP || m_state == STATE_WAIT_DOUBLE_TAP_HOLD, ()); m_state = STATE_EMPTY; } From eb300949c0f0a17b14976fac3ed047a3ae3e43df Mon Sep 17 00:00:00 2001 From: Daria Volvenkova Date: Tue, 14 Jun 2016 18:44:59 +0300 Subject: [PATCH 06/18] Global rect checks corrected in perspective mode. --- drape_frontend/navigator.cpp | 25 +++++++++++++++---------- drape_frontend/navigator.hpp | 10 ++++++---- drape_frontend/user_event_stream.cpp | 20 ++++++++++++-------- geometry/screenbase.hpp | 1 + map/framework.cpp | 5 +---- 5 files changed, 35 insertions(+), 26 deletions(-) diff --git a/drape_frontend/navigator.cpp b/drape_frontend/navigator.cpp index a2e2034ec1..273e8c1194 100644 --- a/drape_frontend/navigator.cpp +++ b/drape_frontend/navigator.cpp @@ -19,6 +19,8 @@ namespace df { +double const kDefault3dScale = 1.0; + Navigator::Navigator() : m_InAction(false) { @@ -56,8 +58,9 @@ void Navigator::SetFromRect(m2::AnyRectD const & r, uint32_t tileSize, double vi { int const scale = scales::GetUpperStyleScale() - 1; m2::RectD newRect = df::GetRectForDrawScale(scale, r.Center()); - CheckMinMaxVisibleScale(newRect, scale); - tmp = m_Screen; + newRect.Scale(m_Screen.GetScale3d()); + CheckMinMaxVisibleScale(newRect, scale, m_Screen.GetScale3d()); + tmp = m_Screen; tmp.SetFromRect(m2::AnyRectD(newRect)); ASSERT(CheckMaxScale(tmp, tileSize, visualScale), ()); } @@ -324,36 +327,38 @@ m2::AnyRectD ToRotated(Navigator const & navigator, m2::RectD const & rect) m2::RectD(-dx/2, -dy/2, dx/2, dy/2)); } -void CheckMinGlobalRect(m2::RectD & rect, uint32_t tileSize, double visualScale) +void CheckMinGlobalRect(m2::RectD & rect, uint32_t tileSize, double visualScale, double scale3d) { - m2::RectD const minRect = df::GetRectForDrawScale(scales::GetUpperStyleScale(), rect.Center(), tileSize, visualScale); + m2::RectD minRect = df::GetRectForDrawScale(scales::GetUpperStyleScale(), rect.Center(), tileSize, visualScale); + minRect.Scale(scale3d); if (minRect.IsRectInside(rect)) rect = minRect; } -void CheckMinGlobalRect(m2::RectD & rect) +void CheckMinGlobalRect(m2::RectD & rect, double scale3d) { VisualParams const & p = VisualParams::Instance(); - CheckMinGlobalRect(rect, p.GetTileSize(), p.GetVisualScale()); + CheckMinGlobalRect(rect, p.GetTileSize(), p.GetVisualScale(), scale3d); } void CheckMinMaxVisibleScale(m2::RectD & rect, int maxScale, - uint32_t tileSize, double visualScale) + uint32_t tileSize, double visualScale, double scale3d) { - CheckMinGlobalRect(rect, tileSize, visualScale); + CheckMinGlobalRect(rect, tileSize, visualScale, scale3d); int scale = df::GetDrawTileScale(rect, tileSize, visualScale); if (maxScale != -1 && scale > maxScale) { // limit on passed maximal scale m2::PointD const c = rect.Center(); rect = df::GetRectForDrawScale(maxScale, c, tileSize, visualScale); + rect.Scale(scale3d); } } -void CheckMinMaxVisibleScale(m2::RectD & rect, int maxScale) +void CheckMinMaxVisibleScale(m2::RectD & rect, int maxScale, double scale3d) { VisualParams const & p = VisualParams::Instance(); - CheckMinMaxVisibleScale(rect, maxScale, p.GetTileSize(), p.GetVisualScale()); + CheckMinMaxVisibleScale(rect, maxScale, p.GetTileSize(), p.GetVisualScale(), scale3d); } } // namespace df diff --git a/drape_frontend/navigator.hpp b/drape_frontend/navigator.hpp index 6e05419e81..01c3272d95 100644 --- a/drape_frontend/navigator.hpp +++ b/drape_frontend/navigator.hpp @@ -10,6 +10,8 @@ namespace df { +extern double const kDefault3dScale; + /// Calculates screen parameters in navigation (dragging, scaling, etc.). class Navigator { @@ -76,10 +78,10 @@ private: }; m2::AnyRectD ToRotated(Navigator const & navigator, m2::RectD const & rect); -void CheckMinGlobalRect(m2::RectD & rect, uint32_t tileSize, double visualScale); -void CheckMinGlobalRect(m2::RectD & rect); +void CheckMinGlobalRect(m2::RectD & rect, uint32_t tileSize, double visualScale, double scale3d = kDefault3dScale); +void CheckMinGlobalRect(m2::RectD & rect, double scale3d = kDefault3dScale); -void CheckMinMaxVisibleScale(m2::RectD & rect, int maxScale/* = -1*/, uint32_t tileSize, double visualScale); -void CheckMinMaxVisibleScale(m2::RectD & rect, int maxScale/* = -1*/); +void CheckMinMaxVisibleScale(m2::RectD & rect, int maxScale/* = -1*/, uint32_t tileSize, double visualScale, double scale3d = kDefault3dScale); +void CheckMinMaxVisibleScale(m2::RectD & rect, int maxScale/* = -1*/, double scale3d = kDefault3dScale); } diff --git a/drape_frontend/user_event_stream.cpp b/drape_frontend/user_event_stream.cpp index eab529320f..d5d7e10092 100644 --- a/drape_frontend/user_event_stream.cpp +++ b/drape_frontend/user_event_stream.cpp @@ -385,7 +385,7 @@ bool UserEventStream::SetCenter(m2::PointD const & center, int zoom, bool isAnim screen.ResetPerspective(); } - double const scale3d = screen.PixelRect().SizeX() / screen.PixelRectIn3d().SizeX(); + double const scale3d = screen.GetScale3d(); if (zoom == kDoNotChangeZoom) { @@ -398,11 +398,12 @@ bool UserEventStream::SetCenter(m2::PointD const & center, int zoom, bool isAnim angle = screen.GlobalRect().Angle(); localRect = df::GetRectForDrawScale(zoom, center); - CheckMinGlobalRect(localRect); - CheckMinMaxVisibleScale(localRect, zoom); + localRect.Scale(scale3d); + + CheckMinGlobalRect(localRect, scale3d); + CheckMinMaxVisibleScale(localRect, zoom, scale3d); localRect.Offset(-center); - localRect.Scale(scale3d); double const aspectRatio = screen.PixelRect().SizeY() / screen.PixelRect().SizeX(); if (aspectRatio > 1.0) @@ -433,8 +434,9 @@ bool UserEventStream::SetCenter(m2::PointD const & center, int zoom, bool isAnim bool UserEventStream::SetRect(m2::RectD rect, int zoom, bool applyRotation, bool isAnim) { - CheckMinGlobalRect(rect); - CheckMinMaxVisibleScale(rect, zoom); + ScreenBase const & screen = GetCurrentScreen(); + CheckMinGlobalRect(rect, screen.GetScale3d()); + CheckMinMaxVisibleScale(rect, zoom, screen.GetScale3d()); m2::AnyRectD targetRect = applyRotation ? ToRotated(m_navigator, rect) : m2::AnyRectD(rect); return SetRect(targetRect, isAnim); } @@ -506,9 +508,11 @@ bool UserEventStream::SetFollowAndRotate(m2::PointD const & userPos, m2::PointD if (preferredZoomLevel != kDoNotChangeZoom) { ScreenBase newScreen = GetCurrentScreen(); + double const scale3d = newScreen.GetScale3d(); m2::RectD r = df::GetRectForDrawScale(preferredZoomLevel, m2::PointD::Zero()); - CheckMinGlobalRect(r); - CheckMinMaxVisibleScale(r, preferredZoomLevel); + r.Scale(scale3d); + CheckMinGlobalRect(r, scale3d); + CheckMinMaxVisibleScale(r, preferredZoomLevel, scale3d); newScreen.SetFromRect(m2::AnyRectD(r)); targetLocalRect = newScreen.GlobalRect().GetLocalRect(); } diff --git a/geometry/screenbase.hpp b/geometry/screenbase.hpp index 24b4076643..8f99f76dbd 100644 --- a/geometry/screenbase.hpp +++ b/geometry/screenbase.hpp @@ -134,6 +134,7 @@ public: double GetRotationAngle() const { return m_3dAngleX; } double GetMaxRotationAngle() const { return m_3dMaxAngleX; } double GetAngleFOV() const { return m_3dFOV; } + double GetScale3d() const { return m_3dScaleX; } m2::PointD P3dtoP(m2::PointD const & pt) const; diff --git a/map/framework.cpp b/map/framework.cpp index 2f5fdf7978..d5c9aa01f5 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -1370,10 +1370,7 @@ void Framework::ShowSearchResult(search::Result const & res) } m2::PointD const center = info.GetMercator(); - if (m_currentModelView.isPerspective()) - CallDrapeFunction(bind(&df::DrapeEngine::SetModelViewCenter, _1, center, scale, true)); - else - ShowRect(df::GetRectForDrawScale(scale, center)); + CallDrapeFunction(bind(&df::DrapeEngine::SetModelViewCenter, _1, center, scale, true)); UserMarkContainer::UserMarkForPoi()->SetPtOrg(center); ActivateMapSelection(false, df::SelectionShape::OBJECT_POI, info); From fdf4f75816a9ba288d3d0d5108f13054890ad555 Mon Sep 17 00:00:00 2001 From: Daria Volvenkova Date: Mon, 20 Jun 2016 15:09:09 +0300 Subject: [PATCH 07/18] Automatic perspective angle calculation in ScreenBase. --- drape_frontend/animation_system.cpp | 21 ++-- drape_frontend/animation_system.hpp | 7 +- drape_frontend/frontend_renderer.cpp | 18 ++- drape_frontend/navigator.cpp | 60 +++++----- drape_frontend/navigator.hpp | 4 +- drape_frontend/screen_operations.cpp | 12 -- drape_frontend/screen_operations.hpp | 2 - drape_frontend/user_event_stream.cpp | 43 ++++--- drape_frontend/user_event_stream.hpp | 1 - geometry/rect2d.hpp | 6 + geometry/screenbase.cpp | 164 +++++++++++++++++++-------- geometry/screenbase.hpp | 20 +++- 12 files changed, 220 insertions(+), 138 deletions(-) diff --git a/drape_frontend/animation_system.cpp b/drape_frontend/animation_system.cpp index 886441d148..76d113ecdf 100644 --- a/drape_frontend/animation_system.cpp +++ b/drape_frontend/animation_system.cpp @@ -75,17 +75,22 @@ private: } // namespace -bool AnimationSystem::GetRect(ScreenBase const & currentScreen, m2::AnyRectD & rect) +void AnimationSystem::UpdateLastScreen(ScreenBase const & currentScreen) { - return GetRect(currentScreen, bind(&AnimationSystem::GetProperty, this, _1, _2, _3), rect); + m_lastScreen = currentScreen; } -void AnimationSystem::GetTargetRect(ScreenBase const & currentScreen, m2::AnyRectD & rect) +bool AnimationSystem::GetScreen(ScreenBase const & currentScreen, ScreenBase & screen) { - GetRect(currentScreen, bind(&AnimationSystem::GetTargetProperty, this, _1, _2, _3), rect); + return GetScreen(currentScreen, bind(&AnimationSystem::GetProperty, this, _1, _2, _3), screen); } -bool AnimationSystem::GetRect(ScreenBase const & currentScreen, TGetPropertyFn const & getPropertyFn, m2::AnyRectD & rect) +void AnimationSystem::GetTargetScreen(ScreenBase const & currentScreen, ScreenBase & screen) +{ + GetScreen(currentScreen, bind(&AnimationSystem::GetTargetProperty, this, _1, _2, _3), screen); +} + +bool AnimationSystem::GetScreen(ScreenBase const & currentScreen, TGetPropertyFn const & getPropertyFn, ScreenBase & screen) { ASSERT(getPropertyFn != nullptr, ()); @@ -105,10 +110,8 @@ bool AnimationSystem::GetRect(ScreenBase const & currentScreen, TGetPropertyFn c if (getPropertyFn(Animation::MapPlane, Animation::Position, value)) pos = value.m_valuePointD; - m2::RectD localRect = currentScreen.PixelRect(); - localRect.Offset(-localRect.Center()); - localRect.Scale(scale); - rect = m2::AnyRectD(pos, angle, localRect); + screen = currentScreen; + screen.SetFromParams(pos, angle, scale); return true; } diff --git a/drape_frontend/animation_system.hpp b/drape_frontend/animation_system.hpp index 7a23337e1a..c989da99f2 100644 --- a/drape_frontend/animation_system.hpp +++ b/drape_frontend/animation_system.hpp @@ -19,8 +19,9 @@ class AnimationSystem : private noncopyable public: static AnimationSystem & Instance(); - bool GetRect(ScreenBase const & currentScreen, m2::AnyRectD & rect); - void GetTargetRect(ScreenBase const & currentScreen, m2::AnyRectD & rect); + void UpdateLastScreen(ScreenBase const & currentScreen); + bool GetScreen(ScreenBase const & currentScreen, ScreenBase & screen); + void GetTargetScreen(ScreenBase const & currentScreen, ScreenBase & screen); bool SwitchPerspective(Animation::SwitchPerspectiveParams & params); bool GetPerspectiveAngle(double & angle); @@ -66,7 +67,7 @@ private: using TGetPropertyFn = function; - bool GetRect(ScreenBase const & currentScreen, TGetPropertyFn const & getPropertyFn, m2::AnyRectD & rect); + bool GetScreen(ScreenBase const & currentScreen, TGetPropertyFn const & getPropertyFn, ScreenBase & screen); bool GetProperty(Animation::TObject object, Animation::TProperty property, Animation::PropertyValue & value) const; diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index 9b826a08c7..d8c9010db5 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -811,17 +811,24 @@ void FrontendRenderer::InvalidateRect(m2::RectD const & gRect) void FrontendRenderer::OnResize(ScreenBase const & screen) { - m2::RectD const viewportRect = screen.isPerspective() ? screen.PixelRectIn3d() : screen.PixelRect(); + m2::RectD const viewportRect = screen.PixelRectIn3d(); + double const kEps = 1e-5; + bool const viewportChanged = !m2::IsEqualSize(m_lastReadedModelView.PixelRectIn3d(), viewportRect, kEps, kEps); m_myPositionController->UpdatePixelPosition(screen); m_myPositionController->OnNewPixelRect(); - m_viewport.SetViewport(0, 0, viewportRect.SizeX(), viewportRect.SizeY()); - m_contextFactory->getDrawContext()->resize(viewportRect.SizeX(), viewportRect.SizeY()); + if (viewportChanged) + { + m_viewport.SetViewport(0, 0, viewportRect.SizeX(), viewportRect.SizeY()); + m_contextFactory->getDrawContext()->resize(viewportRect.SizeX(), viewportRect.SizeY()); + m_framebuffer->SetSize(viewportRect.SizeX(), viewportRect.SizeY()); + } + RefreshProjection(screen); RefreshPivotTransform(screen); - m_framebuffer->SetSize(viewportRect.SizeX(), viewportRect.SizeY()); + } void FrontendRenderer::AddToRenderGroup(dp::GLState const & state, @@ -1647,7 +1654,8 @@ void FrontendRenderer::PositionChanged(m2::PointD const & position) void FrontendRenderer::ChangeModelView(m2::PointD const & center, int zoomLevel) { - AddUserEvent(SetCenterEvent(center, zoomLevel, true)); + AddUserEvent(FollowAndRotateEvent(center, m_userEventStream.GetCurrentScreen().PixelRectIn3d().Center(), -m_userEventStream.GetCurrentScreen().GetAngle(), zoomLevel, true)); + //AddUserEvent(SetCenterEvent(center, zoomLevel, true)); } void FrontendRenderer::ChangeModelView(double azimuth) diff --git a/drape_frontend/navigator.cpp b/drape_frontend/navigator.cpp index 273e8c1194..ecaefccea2 100644 --- a/drape_frontend/navigator.cpp +++ b/drape_frontend/navigator.cpp @@ -26,18 +26,45 @@ Navigator::Navigator() { } -void Navigator::SetFromRects(m2::AnyRectD const & glbRect, m2::RectD const & pxRect) +void Navigator::SetFromRect2(m2::AnyRectD const & r) { + ScreenBase tmp = m_Screen; + m2::RectD const & worldR = df::GetWorldRect(); - m_Screen.SetFromRects(glbRect, pxRect); - m_Screen = ScaleInto(m_Screen, worldR); + tmp.SetFromRect2d(r); + tmp = ScaleInto(tmp, worldR); + + m_Screen = tmp; if (!m_InAction) + m_StartScreen = tmp; +} + +void Navigator::SetScreen(ScreenBase const & screen) +{ + m2::RectD const & worldR = df::GetWorldRect(); + ScreenBase tmp = screen; + tmp = ScaleInto(tmp, worldR); + + VisualParams const & p = VisualParams::Instance(); + + if (!CheckMaxScale(tmp, p.GetTileSize(), p.GetVisualScale())) { - m_StartScreen.SetFromRects(glbRect, pxRect); - m_StartScreen = ScaleInto(m_StartScreen, worldR); + int const scale = scales::GetUpperStyleScale() - 1; + m2::RectD newRect = df::GetRectForDrawScale(scale, screen.GetOrg()); + newRect.Scale(m_Screen.GetScale3d()); + CheckMinMaxVisibleScale(newRect, scale, m_Screen.GetScale3d()); + tmp = m_Screen; + tmp.SetFromRect(m2::AnyRectD(newRect)); + + ASSERT(CheckMaxScale(tmp, p.GetTileSize(), p.GetVisualScale()), ()); } + + m_Screen = tmp; + + if (!m_InAction) + m_StartScreen = tmp; } void Navigator::SetFromRect(m2::AnyRectD const & r) @@ -88,25 +115,11 @@ void Navigator::OnSize(int w, int h) { m2::RectD const & worldR = df::GetWorldRect(); - double const fov = m_Screen.GetAngleFOV(); - double const rotation = m_Screen.GetRotationAngle(); - if (m_Screen.isPerspective()) - { - m_Screen.ResetPerspective(); - m_StartScreen.ResetPerspective(); - } - m_Screen.OnSize(0, 0, w, h); m_Screen = ShrinkAndScaleInto(m_Screen, worldR); m_StartScreen.OnSize(0, 0, w, h); m_StartScreen = ShrinkAndScaleInto(m_StartScreen, worldR); - - if (fov != 0.0) - { - m_Screen.ApplyPerspective(rotation, rotation, fov); - m_StartScreen.ApplyPerspective(rotation, rotation, fov); - } } m2::PointD Navigator::GtoP(m2::PointD const & pt) const @@ -197,6 +210,7 @@ bool Navigator::ScaleImpl(m2::PointD const & newPt1, m2::PointD const & newPt2, { m2::PointD const center3d = oldPt1; m2::PointD const center2d = screen.P3dtoP(center3d); + m2::PointD const centerG = screen.PtoG(center2d); m2::PointD const offset = center2d - center3d; math::Matrix const newM = screen.GtoPMatrix() * ScreenBase::CalcTransform(oldPt1 + offset, oldPt2 + offset, @@ -204,6 +218,7 @@ bool Navigator::ScaleImpl(m2::PointD const & newPt1, m2::PointD const & newPt2, doRotateScreen); ScreenBase tmp = screen; tmp.SetGtoPMatrix(newM); + tmp.MatchGandP3d(centerG, center3d); if (!skipMinScaleAndBordersCheck && !CheckMinScale(tmp)) return false; @@ -310,13 +325,6 @@ void Navigator::Disable3dMode() m_Screen.ResetPerspective(); } -bool Navigator::UpdatePerspective() -{ - double const maxPerspAngle = m_Screen.GetMaxRotationAngle(); - m_Screen.UpdatePerspectiveParameters(); - return maxPerspAngle != m_Screen.GetMaxRotationAngle(); -} - m2::AnyRectD ToRotated(Navigator const & navigator, m2::RectD const & rect) { double const dx = rect.SizeX(); diff --git a/drape_frontend/navigator.hpp b/drape_frontend/navigator.hpp index 01c3272d95..25d9ea0fbb 100644 --- a/drape_frontend/navigator.hpp +++ b/drape_frontend/navigator.hpp @@ -18,9 +18,10 @@ class Navigator public: Navigator(); + void SetScreen(ScreenBase const & screen); void SetFromRect(m2::AnyRectD const & r); + void SetFromRect2(m2::AnyRectD const & r); void CenterViewport(m2::PointD const & p); - void SetFromRects(m2::AnyRectD const & glbRect, m2::RectD const & pxRect); void SetFromRect(m2::AnyRectD const & r, uint32_t tileSize, double visualScale); void OnSize(int w, int h); @@ -48,7 +49,6 @@ public: void Enable3dMode(double currentRotationAngle, double maxRotationAngle, double angleFOV); void SetRotationIn3dMode(double rotationAngle); void Disable3dMode(); - bool UpdatePerspective(); private: // Internal screen corresponding to the state when navigation began with StartDrag or StartScale. diff --git a/drape_frontend/screen_operations.cpp b/drape_frontend/screen_operations.cpp index 5060097425..acc083dedc 100644 --- a/drape_frontend/screen_operations.cpp +++ b/drape_frontend/screen_operations.cpp @@ -272,16 +272,4 @@ bool ApplyScale(m2::PointD const & pixelScaleCenter, double factor, ScreenBase & return true; } -double CalculatePerspectiveAngle(ScreenBase const & screen) -{ - double const kStartPerspectiveScale = 0.5; - double const kMaxScale = 0.2; - double const kMaxPerspectiveAngle = math::pi4; - - double const currentScale = screen.GetScale(); - if (currentScale > kStartPerspectiveScale) - return 0.0; - return kMaxPerspectiveAngle * (kStartPerspectiveScale - currentScale) / (kStartPerspectiveScale - kMaxScale); -} - } // namespace df diff --git a/drape_frontend/screen_operations.hpp b/drape_frontend/screen_operations.hpp index e9239180e5..dd34bdad7e 100644 --- a/drape_frontend/screen_operations.hpp +++ b/drape_frontend/screen_operations.hpp @@ -28,6 +28,4 @@ m2::PointD CalculateCenter(double scale, m2::RectD const & pixelRect, bool ApplyScale(m2::PointD const & pixelScaleCenter, double factor, ScreenBase & screen); -double CalculatePerspectiveAngle(ScreenBase const & screen); - } // namespace df diff --git a/drape_frontend/user_event_stream.cpp b/drape_frontend/user_event_stream.cpp index d5d7e10092..0f7c91dbbd 100644 --- a/drape_frontend/user_event_stream.cpp +++ b/drape_frontend/user_event_stream.cpp @@ -147,6 +147,8 @@ ScreenBase const & UserEventStream::ProcessEvents(bool & modelViewChanged, bool swap(m_events, events); } + m2::RectD const prevPixelRect = GetCurrentScreen().PixelRect(); + m_modelViewChanged = !events.empty() || m_state == STATE_SCALE || m_state == STATE_DRAG; for (UserEvent const & e : events) { @@ -163,7 +165,6 @@ ScreenBase const & UserEventStream::ProcessEvents(bool & modelViewChanged, bool break; case UserEvent::EVENT_RESIZE: m_navigator.OnSize(e.m_resize.m_width, e.m_resize.m_height); - m_viewportChanged = true; breakAnim = true; TouchCancel(m_touches); if (m_state == STATE_DOUBLE_TAP_HOLD) @@ -268,12 +269,13 @@ ScreenBase const & UserEventStream::ProcessEvents(bool & modelViewChanged, bool } if (m_modelViewChanged) - m_viewportChanged |= m_navigator.UpdatePerspective(); + m_animationSystem.UpdateLastScreen(GetCurrentScreen()); modelViewChanged = m_modelViewChanged; - viewportChanged = m_viewportChanged; + + double const kEps = 1e-5; + viewportChanged = !m2::IsEqualSize(prevPixelRect, GetCurrentScreen().PixelRect(), kEps, kEps); m_modelViewChanged = false; - m_viewportChanged = false; return m_navigator.Screen(); } @@ -282,9 +284,9 @@ void UserEventStream::ApplyAnimations() { if (m_animationSystem.AnimationExists(Animation::MapPlane)) { - m2::AnyRectD rect; - if (m_animationSystem.GetRect(GetCurrentScreen(), rect)) - m_navigator.SetFromRect(rect); + ScreenBase screen; + if (m_animationSystem.GetScreen(GetCurrentScreen(), screen)) + m_navigator.SetScreen(screen); Animation::SwitchPerspectiveParams switchPerspective; if (m_animationSystem.SwitchPerspective(switchPerspective)) @@ -298,7 +300,6 @@ void UserEventStream::ApplyAnimations() { m_navigator.Disable3dMode(); } - m_viewportChanged = true; } double perspectiveAngle; @@ -434,15 +435,15 @@ bool UserEventStream::SetCenter(m2::PointD const & center, int zoom, bool isAnim bool UserEventStream::SetRect(m2::RectD rect, int zoom, bool applyRotation, bool isAnim) { - ScreenBase const & screen = GetCurrentScreen(); - CheckMinGlobalRect(rect, screen.GetScale3d()); - CheckMinMaxVisibleScale(rect, zoom, screen.GetScale3d()); + CheckMinGlobalRect(rect, kDefault3dScale); + CheckMinMaxVisibleScale(rect, zoom, kDefault3dScale); m2::AnyRectD targetRect = applyRotation ? ToRotated(m_navigator, rect) : m2::AnyRectD(rect); return SetRect(targetRect, isAnim); } bool UserEventStream::SetRect(m2::AnyRectD const & rect, bool isAnim) { + isAnim = false; if (isAnim) { auto onStartHandler = [this](ref_ptr animation) @@ -473,7 +474,7 @@ bool UserEventStream::SetRect(m2::AnyRectD const & rect, bool isAnim) } ResetMapPlaneAnimations(); - m_navigator.SetFromRect(rect); + m_navigator.SetFromRect2(rect); return true; } @@ -581,10 +582,9 @@ bool UserEventStream::FilterEventWhile3dAnimation(UserEvent::EEventType type) co void UserEventStream::SetEnable3dMode(double maxRotationAngle, double angleFOV, bool isAnim, bool immediatelyStart) { - ResetAnimationsBeforeSwitch3D(); + return; - //m_navigator.Enable3dMode(0.0, maxRotationAngle, angleFOV); - //return; + ResetAnimationsBeforeSwitch3D(); if (immediatelyStart) InterruptFollowAnimations(true /* force */); @@ -609,12 +609,11 @@ void UserEventStream::SetEnable3dMode(double maxRotationAngle, double angleFOV, void UserEventStream::SetDisable3dModeAnimation() { + return; + ResetAnimationsBeforeSwitch3D(); InterruptFollowAnimations(true /* force */); - //m_navigator.Disable3dMode(); - //return; - if (m_discardedFOV > 0.0 && IsScaleAllowableIn3d(GetDrawTileScale(GetCurrentScreen()))) { m_discardedFOV = m_discardedAngle = 0.0; @@ -676,9 +675,9 @@ m2::AnyRectD UserEventStream::GetCurrentRect() const m2::AnyRectD UserEventStream::GetTargetRect() const { - m2::AnyRectD targetRect; - m_animationSystem.GetTargetRect(m_navigator.Screen(), targetRect); - return targetRect; + ScreenBase targetScreen; + m_animationSystem.GetTargetScreen(m_navigator.Screen(), targetScreen); + return targetScreen.GlobalRect(); } bool UserEventStream::ProcessTouch(TouchEvent const & touch) @@ -1232,7 +1231,7 @@ void UserEventStream::UpdateDoubleTapAndHold(Touch const & touch) TEST_CALL(DOUBLE_TAP_AND_HOLD); ASSERT_EQUAL(m_state, STATE_DOUBLE_TAP_HOLD, ()); float const kPowerModifier = 10.0f; - float const scaleFactor = exp(kPowerModifier * (touch.m_location.y - m_startDoubleTapAndHold.y) / GetCurrentScreen().PixelRect().SizeY()); + float const scaleFactor = exp(kPowerModifier * (touch.m_location.y - m_startDoubleTapAndHold.y) / GetCurrentScreen().PixelRectIn3d().SizeY()); m_startDoubleTapAndHold = touch.m_location; m2::PointD scaleCenter = m_startDragOrg; diff --git a/drape_frontend/user_event_stream.hpp b/drape_frontend/user_event_stream.hpp index ebb5cab618..28d926f428 100644 --- a/drape_frontend/user_event_stream.hpp +++ b/drape_frontend/user_event_stream.hpp @@ -383,7 +383,6 @@ private: AnimationSystem & m_animationSystem; bool m_modelViewChanged = false; - bool m_viewportChanged = false; bool m_perspectiveAnimation = false; unique_ptr m_pendingEvent; diff --git a/geometry/rect2d.hpp b/geometry/rect2d.hpp index d49fa049d0..57f7b676b3 100644 --- a/geometry/rect2d.hpp +++ b/geometry/rect2d.hpp @@ -287,6 +287,12 @@ namespace m2 return true; } + template + inline bool IsEqualSize(Rect const & r1, Rect const & r2, double epsX, double epsY) + { + return fabs(r1.SizeX() - r2.SizeX()) < epsX && fabs(r1.SizeY() - r2.SizeY()) < epsY; + } + template inline m2::Rect const Add(m2::Rect const & r, m2::Point const & p) { diff --git a/geometry/screenbase.cpp b/geometry/screenbase.cpp index 7dc94b4efd..fb462fe11c 100644 --- a/geometry/screenbase.cpp +++ b/geometry/screenbase.cpp @@ -16,18 +16,19 @@ double constexpr kEndPerspectiveScale1 = 0.3e-5; double constexpr kEndPerspectiveScale2 = 0.13e-5; ScreenBase::ScreenBase() : - m_PixelRect(0, 0, 640, 480), + m_ViewportRect(0, 0, 640, 480), + m_PixelRect(m_ViewportRect), m_Scale(0.1), m_Angle(0.0), m_Org(320, 240), - m_3dFOV(0.0), + m_3dFOV(kPerspectiveAngleFOV), m_3dNearZ(0.001), m_3dFarZ(0.0), m_3dAngleX(0.0), m_3dMaxAngleX(0.0), - m_3dScaleX(1.0), - m_3dScaleY(1.0), + m_3dScale(1.0), m_isPerspective(false), + m_isAutoPerspective(true), m_GlobalRect(m_Org, ang::AngleD(0), m2::RectD(-320, -240, 320, 240)), m_ClipRect(m2::RectD(0, 0, 640, 480)) { @@ -43,7 +44,7 @@ ScreenBase::ScreenBase(m2::RectI const & pxRect, m2::AnyRectD const & glbRect) ScreenBase::ScreenBase(ScreenBase const & s, m2::PointD const & org, double scale, double angle) - : m_PixelRect(s.m_PixelRect), + : m_ViewportRect(s.m_ViewportRect), m_Scale(scale), m_Angle(angle), m_Org(org) { UpdateDependentParameters(); @@ -51,6 +52,8 @@ ScreenBase::ScreenBase(ScreenBase const & s, void ScreenBase::UpdateDependentParameters() { + m_PixelRect = CalculatePixelRect(m_Scale); + m_PtoG = math::Shift( /// 5. shifting on (E0, N0) math::Rotate( /// 4. rotating on the screen angle math::Scale( /// 3. scaling to translate pixel sizes to global @@ -79,38 +82,46 @@ void ScreenBase::UpdateDependentParameters() m_GlobalRect = m2::AnyRectD(m_Org, m_Angle, m2::RectD(-szX, -szY, szX, szY)); m_ClipRect = m_GlobalRect.GetGlobalRect(); + + double const kEps = 1e-5; + double angle = CalculatePerspectiveAngle(m_Scale); + m_isPerspective = angle > 0.0; + if (fabs(angle - m_3dAngleX) > kEps) + { + m_3dMaxAngleX = angle; + m_3dScale = CalculateScale3d(angle); + SetRotationAngle(angle); + } } -double ScreenBase::CalculatePerspectiveAngle(double scale) +double ScreenBase::CalculatePerspectiveAngle(double scale) const { + if (!m_isAutoPerspective) + return m_3dAngleX; + if (scale > kStartPerspectiveScale1) return 0.0; - else if (scale > kEndPerspectiveScale1) + + if (scale > kEndPerspectiveScale1) { double const k = (kStartPerspectiveScale1 - scale) / (kStartPerspectiveScale1 - kEndPerspectiveScale1); return kMaxPerspectiveAngle1 * k; } - else if (scale > kEndPerspectiveScale2) + + if (scale > kEndPerspectiveScale2) { double const k = (kEndPerspectiveScale1 - scale) / (kEndPerspectiveScale1 - kEndPerspectiveScale2); return kMaxPerspectiveAngle1 + (kMaxPerspectiveAngle2 - kMaxPerspectiveAngle1) * k; } - else - return kMaxPerspectiveAngle2 * 0.99; + + return kMaxPerspectiveAngle2 * 0.99; } void ScreenBase::UpdatePerspectiveParameters() { double const angle = CalculatePerspectiveAngle(m_Scale); if (angle > 0.0) - { - if (!m_isPerspective || (angle < kMaxPerspectiveAngle1 && m_3dMaxAngleX > kMaxPerspectiveAngle1)) - ApplyPerspective(angle, kMaxPerspectiveAngle1, kPerspectiveAngleFOV); - else if (angle > m_3dMaxAngleX) - ApplyPerspective(angle, kMaxPerspectiveAngle2, kPerspectiveAngleFOV); - else - SetRotationAngle(angle); - } + ApplyPerspective(angle, angle, kPerspectiveAngleFOV); else if (m_isPerspective) ResetPerspective(); } @@ -132,6 +143,48 @@ void ScreenBase::SetFromRect(m2::AnyRectD const & glbRect) SetFromRects(glbRect, m_PixelRect); } +void ScreenBase::SetFromRect2d(m2::AnyRectD const & glbRect) +{ + double hScale = glbRect.GetLocalRect().SizeX() / PixelRectIn3d().SizeX(); + double vScale = glbRect.GetLocalRect().SizeY() / PixelRectIn3d().SizeY(); + double scale = max(hScale, vScale); + + m_Scale = scale; + m_Angle = glbRect.Angle(); + m_Org = glbRect.GlobalCenter(); + + UpdateDependentParameters(); + UpdatePerspectiveParameters(); + +/* m2::PointD g_target(0.0, -glbRect.GetLocalRect().SizeY() * scale / vScale / 2.0); + g_target.Rotate(glbRect.Angle().val()); + g_target = glbRect.GlobalCenter() + g_target; + m2::PointD p_target(m_PixelRect.SizeX() / 2.0, m_PixelRect.SizeY()); + MatchGandP(g_target, p_target);*/ + + MatchGandP3d(glbRect.GlobalCenter(), PixelRectIn3d().Center()); +} + +void ScreenBase::SetFromParams(m2::PointD const & org, double angle, double scale) +{ + m_Scale = scale; + m_Angle = angle; + m_Org = org; + UpdateDependentParameters(); +} + +void ScreenBase::MatchGandP(m2::PointD const & g, m2::PointD const & p) +{ + m2::PointD g_current = PtoG(p); + SetOrg(m_Org - g_current + g); +} + +void ScreenBase::MatchGandP3d(m2::PointD const & g, m2::PointD const &p3d) +{ + m2::PointD g_current = PtoG(P3dtoP(p3d)); + SetOrg(m_Org - g_current + g); +} + void ScreenBase::SetOrg(m2::PointD const & p) { m_Org = p; @@ -164,7 +217,7 @@ void ScreenBase::Rotate(double angle) void ScreenBase::OnSize(m2::RectI const & r) { - m_PixelRect = m2::RectD(r); + m_ViewportRect = m2::RectD(r); UpdateDependentParameters(); } @@ -173,11 +226,6 @@ void ScreenBase::OnSize(int x0, int y0, int w, int h) OnSize(m2::RectI(x0, y0, x0 + w, y0 + h)); } -double ScreenBase::GetMinPixelRectSize() const -{ - return min(m_PixelRect.SizeX(), m_PixelRect.SizeY()); -} - void ScreenBase::SetScale(double scale) { m_Scale = scale; @@ -294,6 +342,32 @@ void ScreenBase::ExtractGtoPParams(MatrixT const & m, dy = m(2, 1); } +double ScreenBase::CalculateScale3d(double rotationAngle) const +{ + double const halfFOV = m_3dFOV / 2.0; + double const cameraZ = 1.0 / tan(halfFOV); + + // Ratio of the expanded plane's size to the original size. + double const y3dScale = cos(rotationAngle) + sin(rotationAngle) * tan(halfFOV + rotationAngle); + double const x3dScale = 1.0 + 2 * sin(rotationAngle) * cos(halfFOV) / (cameraZ * cos(halfFOV + rotationAngle)); + + return max(x3dScale, y3dScale); +} + +m2::RectD ScreenBase::CalculatePixelRect(double scale) const +{ + double const angle = CalculatePerspectiveAngle(scale); + if (angle > 0.0) + { + double const scale3d = CalculateScale3d(angle); + + return m2::RectD(m2::PointD(0.0, 0.0), + m2::PointD(m_ViewportRect.maxX(), m_ViewportRect.maxY()) * scale3d); + } + + return m_ViewportRect; +} + // Place the camera at the distance, where it gives the same view of plane as the // orthogonal projection does. Calculate what part of the map would be visible, // when it is rotated through maxRotationAngle around its near horizontal side. @@ -304,31 +378,21 @@ void ScreenBase::ApplyPerspective(double currentRotationAngle, double maxRotatio ASSERT_GREATER_OR_EQUAL(maxRotationAngle, 0.0, ()); ASSERT_LESS(maxRotationAngle, math::pi2, ()); - if (m_isPerspective) - ResetPerspective(); +// if (m_isPerspective) +// ResetPerspective(); m_isPerspective = true; m_3dMaxAngleX = maxRotationAngle; m_3dFOV = angleFOV; - double const halfFOV = m_3dFOV / 2.0; - double const cameraZ = 1.0 / tan(halfFOV); - - // Ratio of the expanded plane's size to the original size. - m_3dScaleY = cos(m_3dMaxAngleX) + sin(m_3dMaxAngleX) * tan(halfFOV + m_3dMaxAngleX); - m_3dScaleX = 1.0 + 2 * sin(m_3dMaxAngleX) * cos(halfFOV) / (cameraZ * cos(halfFOV + m_3dMaxAngleX)); - - m_3dScaleX = m_3dScaleY = max(m_3dScaleX, m_3dScaleY); - - double const dy = m_PixelRect.SizeY() * (m_3dScaleX - 1.0); - - m_PixelRect.setMaxX(m_PixelRect.maxX() * m_3dScaleX); - m_PixelRect.setMaxY(m_PixelRect.maxY() * m_3dScaleY); - - Move(0.0, dy / 2.0); + double const old_dy = m_ViewportRect.SizeY() * (m_3dScale - 1.0); + m_3dScale = CalculateScale3d(m_3dMaxAngleX); + double const new_dy = m_ViewportRect.SizeY() * (CalculateScale3d(m_3dMaxAngleX) - 1.0); SetRotationAngle(currentRotationAngle); + + Move(0.0, (new_dy - old_dy) / 2.0); } // Place the camera at the distance, where it gives the same view of plane as the @@ -347,12 +411,12 @@ void ScreenBase::SetRotationAngle(double rotationAngle) double const halfFOV = m_3dFOV / 2.0; double const cameraZ = 1.0 / tan(halfFOV); - double const offsetZ = cameraZ + sin(m_3dAngleX) * m_3dScaleY; - double const offsetY = cos(m_3dAngleX) * m_3dScaleX - 1.0; + double const offsetZ = cameraZ + sin(m_3dAngleX) * m_3dScale; + double const offsetY = cos(m_3dAngleX) * m_3dScale - 1.0; Matrix3dT scaleM = math::Identity(); - scaleM(0, 0) = m_3dScaleX; - scaleM(1, 1) = m_3dScaleY; + scaleM(0, 0) = m_3dScale; + scaleM(1, 1) = m_3dScale; Matrix3dT rotateM = math::Identity(); rotateM(1, 1) = cos(m_3dAngleX); @@ -365,7 +429,7 @@ void ScreenBase::SetRotationAngle(double rotationAngle) translateM(3, 2) = offsetZ; Matrix3dT projectionM = math::Zero(); - m_3dFarZ = cameraZ + 2.0 * sin(m_3dAngleX) * m_3dScaleY; + m_3dFarZ = cameraZ + 2.0 * sin(m_3dAngleX) * m_3dScale; projectionM(0, 0) = projectionM(1, 1) = cameraZ; projectionM(2, 2) = m_3dAngleX != 0.0 ? (m_3dFarZ + m_3dNearZ) / (m_3dFarZ - m_3dNearZ) : 0.0; @@ -381,14 +445,14 @@ void ScreenBase::ResetPerspective() { m_isPerspective = false; - double const dy = m_PixelRect.SizeY() * (1.0 - 1.0 / m_3dScaleX); + double const dy = m_PixelRect.SizeY() * (1.0 - 1.0 / m_3dScale); - m_PixelRect.setMaxX(m_PixelRect.maxX() / m_3dScaleX); - m_PixelRect.setMaxY(m_PixelRect.maxY() / m_3dScaleY); + m_PixelRect.setMaxX(m_PixelRect.maxX() / m_3dScale); + m_PixelRect.setMaxY(m_PixelRect.maxY() / m_3dScale); Move(0, -dy / 2.0); - m_3dScaleX = m_3dScaleY = 1.0; + m_3dScale = 1.0; m_3dAngleX = 0.0; m_3dMaxAngleX = 0.0; m_3dFOV = 0.0; diff --git a/geometry/screenbase.hpp b/geometry/screenbase.hpp index 8f99f76dbd..c3cf5eefe2 100644 --- a/geometry/screenbase.hpp +++ b/geometry/screenbase.hpp @@ -15,6 +15,7 @@ public: using Vector3dT = math::Matrix; private: + m2::RectD m_ViewportRect; m2::RectD m_PixelRect; double m_Scale; @@ -26,9 +27,9 @@ private: double m_3dFarZ; double m_3dAngleX; double m_3dMaxAngleX; - double m_3dScaleX; - double m_3dScaleY; + double m_3dScale; bool m_isPerspective; + bool m_isAutoPerspective; protected: /// @group Dependent parameters @@ -64,6 +65,9 @@ public: m2::PointD const & org, double scale, double angle); void SetFromRect(m2::AnyRectD const & rect); + void SetFromRect2d(m2::AnyRectD const & glbRect); + + void SetFromParams(m2::PointD const & org, double angle, double scale); void SetFromRects(m2::AnyRectD const & glbRect, m2::RectD const & pxRect); void SetOrg(m2::PointD const & p); @@ -115,6 +119,9 @@ public: void GtoP(m2::RectD const & gr, m2::RectD & sr) const; void PtoG(m2::RectD const & pr, m2::RectD & gr) const; + void MatchGandP(m2::PointD const & g, m2::PointD const & p); + void MatchGandP3d(m2::PointD const & g, m2::PointD const & p3d); + void GetTouchRect(m2::PointD const & pixPoint, double pixRadius, m2::AnyRectD & glbRect) const; void GetTouchRect(m2::PointD const & pixPoint, double const pxWidth, double const pxHeight, m2::AnyRectD & glbRect) const; @@ -134,7 +141,7 @@ public: double GetRotationAngle() const { return m_3dAngleX; } double GetMaxRotationAngle() const { return m_3dMaxAngleX; } double GetAngleFOV() const { return m_3dFOV; } - double GetScale3d() const { return m_3dScaleX; } + double GetScale3d() const { return m_3dScale; } m2::PointD P3dtoP(m2::PointD const & pt) const; @@ -148,17 +155,18 @@ public: m2::RectD PixelRectIn3d() const { - return m2::RectD(0.0, 0.0, m_PixelRect.maxX() / m_3dScaleX, m_PixelRect.maxY() / m_3dScaleY); + return m_ViewportRect; } - double GetMinPixelRectSize() const; + double CalculateScale3d(double rotationAngle) const; + m2::RectD CalculatePixelRect(double scale) const; + double CalculatePerspectiveAngle(double scale) const; /// Compute arbitrary pixel transformation, that translates the (oldPt1, oldPt2) -> (newPt1, newPt2) static MatrixT const CalcTransform(m2::PointD const & oldPt1, m2::PointD const & oldPt2, m2::PointD const & newPt1, m2::PointD const & newPt2, bool allowRotate); - static double CalculatePerspectiveAngle(double scale); /// Setting GtoP matrix extracts the Angle and m_Org parameters, leaving PixelRect intact void SetGtoPMatrix(MatrixT const & m); From 500c4a0e51272e651c01a23d5f016d3bdf4b23c5 Mon Sep 17 00:00:00 2001 From: Daria Volvenkova Date: Mon, 20 Jun 2016 17:02:44 +0300 Subject: [PATCH 08/18] Fixed manual scaling in follow and follow-and-rotate modes. --- drape_frontend/frontend_renderer.cpp | 2 +- drape_frontend/my_position_controller.cpp | 2 +- drape_frontend/my_position_controller.hpp | 2 +- drape_frontend/screen_operations.cpp | 5 +---- 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index d8c9010db5..7260363d4e 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -816,10 +816,10 @@ void FrontendRenderer::OnResize(ScreenBase const & screen) bool const viewportChanged = !m2::IsEqualSize(m_lastReadedModelView.PixelRectIn3d(), viewportRect, kEps, kEps); m_myPositionController->UpdatePixelPosition(screen); - m_myPositionController->OnNewPixelRect(); if (viewportChanged) { + m_myPositionController->OnNewViewportRect(); m_viewport.SetViewport(0, 0, viewportRect.SizeX(), viewportRect.SizeY()); m_contextFactory->getDrawContext()->resize(viewportRect.SizeX(), viewportRect.SizeY()); m_framebuffer->SetSize(viewportRect.SizeX(), viewportRect.SizeY()); diff --git a/drape_frontend/my_position_controller.cpp b/drape_frontend/my_position_controller.cpp index 5d91c921d4..29bbf6e6c4 100644 --- a/drape_frontend/my_position_controller.cpp +++ b/drape_frontend/my_position_controller.cpp @@ -103,7 +103,7 @@ MyPositionController::~MyPositionController() { } -void MyPositionController::OnNewPixelRect() +void MyPositionController::OnNewViewportRect() { UpdateViewport(kDoNotChangeZoom); } diff --git a/drape_frontend/my_position_controller.hpp b/drape_frontend/my_position_controller.hpp index e93b6e9fff..f8516cdd88 100644 --- a/drape_frontend/my_position_controller.hpp +++ b/drape_frontend/my_position_controller.hpp @@ -47,7 +47,7 @@ public: bool isFirstLaunch, bool isRoutingActive); ~MyPositionController(); - void OnNewPixelRect(); + void OnNewViewportRect(); void UpdatePixelPosition(ScreenBase const & screen); void SetListener(ref_ptr listener); diff --git a/drape_frontend/screen_operations.cpp b/drape_frontend/screen_operations.cpp index acc083dedc..7e5dd93133 100644 --- a/drape_frontend/screen_operations.cpp +++ b/drape_frontend/screen_operations.cpp @@ -240,13 +240,10 @@ ScreenBase const ShrinkAndScaleInto(ScreenBase const & screen, m2::RectD boundRe bool ApplyScale(m2::PointD const & pixelScaleCenter, double factor, ScreenBase & screen) { m2::PointD const globalScaleCenter = screen.PtoG(screen.P3dtoP(pixelScaleCenter)); - m2::PointD const pixelCenterOffset = screen.PixelRect().Center() - screen.P3dtoP(pixelScaleCenter); ScreenBase tmp = screen; tmp.Scale(factor); - - m2::PointD newCenter = tmp.PtoG(tmp.GtoP(globalScaleCenter) + pixelCenterOffset); - tmp.SetOrg(newCenter); + tmp.MatchGandP3d(globalScaleCenter, pixelScaleCenter); if (!CheckMinScale(tmp)) return false; From 74e5ac5cb9a8a5ba0b0aa9d84dfb17d410610373 Mon Sep 17 00:00:00 2001 From: Daria Volvenkova Date: Mon, 20 Jun 2016 20:04:01 +0300 Subject: [PATCH 09/18] GUI rendering fixed in perspective mode. --- drape_frontend/frontend_renderer.cpp | 2 -- geometry/screenbase.cpp | 21 ++++++++------------- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index 7260363d4e..565b4d4505 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -827,8 +827,6 @@ void FrontendRenderer::OnResize(ScreenBase const & screen) RefreshProjection(screen); RefreshPivotTransform(screen); - - } void FrontendRenderer::AddToRenderGroup(dp::GLState const & state, diff --git a/geometry/screenbase.cpp b/geometry/screenbase.cpp index fb462fe11c..01e55db869 100644 --- a/geometry/screenbase.cpp +++ b/geometry/screenbase.cpp @@ -378,17 +378,17 @@ void ScreenBase::ApplyPerspective(double currentRotationAngle, double maxRotatio ASSERT_GREATER_OR_EQUAL(maxRotationAngle, 0.0, ()); ASSERT_LESS(maxRotationAngle, math::pi2, ()); -// if (m_isPerspective) -// ResetPerspective(); - m_isPerspective = true; + m_isAutoPerspective = false; m_3dMaxAngleX = maxRotationAngle; + m_3dAngleX = currentRotationAngle; m_3dFOV = angleFOV; double const old_dy = m_ViewportRect.SizeY() * (m_3dScale - 1.0); + m_3dScale = CalculateScale3d(m_3dMaxAngleX); - double const new_dy = m_ViewportRect.SizeY() * (CalculateScale3d(m_3dMaxAngleX) - 1.0); + double const new_dy = m_ViewportRect.SizeY() * (m_3dScale - 1.0); SetRotationAngle(currentRotationAngle); @@ -444,18 +444,13 @@ void ScreenBase::SetRotationAngle(double rotationAngle) void ScreenBase::ResetPerspective() { m_isPerspective = false; + m_isAutoPerspective = false; - double const dy = m_PixelRect.SizeY() * (1.0 - 1.0 / m_3dScale); - - m_PixelRect.setMaxX(m_PixelRect.maxX() / m_3dScale); - m_PixelRect.setMaxY(m_PixelRect.maxY() / m_3dScale); - - Move(0, -dy / 2.0); - - m_3dScale = 1.0; m_3dAngleX = 0.0; m_3dMaxAngleX = 0.0; - m_3dFOV = 0.0; + + double const old_dy = m_ViewportRect.SizeY() * (m_3dScale - 1.0); + Move(0.0, -old_dy / 2.0); } m2::PointD ScreenBase::PtoP3d(m2::PointD const & pt) const From e2543477a6425ec36a4fe4088bd255d6f916becc Mon Sep 17 00:00:00 2001 From: Daria Volvenkova Date: Tue, 21 Jun 2016 13:18:50 +0300 Subject: [PATCH 10/18] Set center fixed. --- drape_frontend/user_event_stream.cpp | 34 +--------------------------- geometry/screenbase.cpp | 1 - 2 files changed, 1 insertion(+), 34 deletions(-) diff --git a/drape_frontend/user_event_stream.cpp b/drape_frontend/user_event_stream.cpp index 0f7c91dbbd..64169b209a 100644 --- a/drape_frontend/user_event_stream.cpp +++ b/drape_frontend/user_event_stream.cpp @@ -372,22 +372,6 @@ bool UserEventStream::SetCenter(m2::PointD const & center, int zoom, bool isAnim ScreenBase const & currentScreen = GetCurrentScreen(); ScreenBase screen = currentScreen; - bool finishIn2d = false; - bool finishIn3d = false; - if (zoom != kDoNotChangeZoom) - { - bool const isScaleAllowableIn3d = IsScaleAllowableIn3d(zoom); - finishIn3d = m_discardedFOV > 0.0 && isScaleAllowableIn3d; - finishIn2d = currentScreen.isPerspective() && !isScaleAllowableIn3d; - - if (finishIn3d) - screen.ApplyPerspective(m_discardedAngle, m_discardedAngle, m_discardedFOV); - else if (finishIn2d) - screen.ResetPerspective(); - } - - double const scale3d = screen.GetScale3d(); - if (zoom == kDoNotChangeZoom) { m2::AnyRectD const r = GetTargetRect(); @@ -398,6 +382,7 @@ bool UserEventStream::SetCenter(m2::PointD const & center, int zoom, bool isAnim { angle = screen.GlobalRect().Angle(); + double scale3d = kDefault3dScale;//screen.CalculateScale3d(screen.CalculatePerspectiveAngle()); localRect = df::GetRectForDrawScale(zoom, center); localRect.Scale(scale3d); @@ -413,23 +398,6 @@ bool UserEventStream::SetCenter(m2::PointD const & center, int zoom, bool isAnim localRect.Inflate(localRect.SizeX() * 0.5 / aspectRatio, 0.0); } - if (screen.isPerspective()) - { - double const centerOffset3d = localRect.SizeY() * (1.0 - 1.0 / (scale3d * cos(screen.GetRotationAngle()))) * 0.5; - targetCenter = targetCenter.Move(centerOffset3d, angle.cos(), -angle.sin()); - } - - if (finishIn2d || finishIn3d) - { - double const scale = currentScreen.PixelRect().SizeX() / currentScreen.PixelRectIn3d().SizeX(); - double const scaleToCurrent = finishIn2d ? scale : 1.0 / scale3d; - - double const currentGSizeY = localRect.SizeY() * scaleToCurrent; - targetCenter = targetCenter.Move((currentGSizeY - localRect.SizeY()) * 0.5, - angle.cos(), -angle.sin()); - localRect.Scale(scaleToCurrent); - } - return SetRect(m2::AnyRectD(targetCenter, angle, localRect), isAnim); } diff --git a/geometry/screenbase.cpp b/geometry/screenbase.cpp index 01e55db869..a6ee53227b 100644 --- a/geometry/screenbase.cpp +++ b/geometry/screenbase.cpp @@ -154,7 +154,6 @@ void ScreenBase::SetFromRect2d(m2::AnyRectD const & glbRect) m_Org = glbRect.GlobalCenter(); UpdateDependentParameters(); - UpdatePerspectiveParameters(); /* m2::PointD g_target(0.0, -glbRect.GetLocalRect().SizeY() * scale / vScale / 2.0); g_target.Rotate(glbRect.Angle().val()); From 97d1cfd6605875821fb1886e6d9db2b463554089 Mon Sep 17 00:00:00 2001 From: Daria Volvenkova Date: Wed, 22 Jun 2016 15:10:56 +0300 Subject: [PATCH 11/18] Debug labels rendering. --- drape_frontend/backend_renderer.cpp | 13 +++ drape_frontend/backend_renderer.hpp | 4 + drape_frontend/drape_frontend.pro | 2 + drape_frontend/frontend_renderer.cpp | 13 +-- drape_frontend/gui/choose_position_mark.cpp | 2 +- drape_frontend/gui/debug_label.cpp | 94 ++++++++++++++++++++ drape_frontend/gui/debug_label.hpp | 28 ++++++ drape_frontend/gui/layer_render.cpp | 97 +++++++++++++++++++++ drape_frontend/gui/layer_render.hpp | 4 + drape_frontend/gui/shape.cpp | 2 +- drape_frontend/gui/skin.hpp | 12 ++- geometry/screenbase.cpp | 2 +- 12 files changed, 256 insertions(+), 17 deletions(-) create mode 100644 drape_frontend/gui/debug_label.cpp create mode 100644 drape_frontend/gui/debug_label.hpp diff --git a/drape_frontend/backend_renderer.cpp b/drape_frontend/backend_renderer.cpp index cf0c5818b2..e022e72bab 100644 --- a/drape_frontend/backend_renderer.cpp +++ b/drape_frontend/backend_renderer.cpp @@ -76,6 +76,15 @@ void BackendRenderer::RecacheGui(gui::TWidgetsInitInfo const & initInfo, bool ne m_commutator->PostMessage(ThreadsCommutator::RenderThread, move(outputMsg), MessagePriority::Normal); } +#ifdef RENRER_DEBUG_INFO_LABELS +void BackendRenderer::RecacheDebugLabels() +{ + drape_ptr layerRenderer = m_guiCacher.RecacheDebugLabels(m_texMng); + drape_ptr outputMsg = make_unique_dp(move(layerRenderer), false); + m_commutator->PostMessage(ThreadsCommutator::RenderThread, move(outputMsg), MessagePriority::Normal); +} +#endif + void BackendRenderer::RecacheChoosePositionMark() { drape_ptr layerRenderer = m_guiCacher.RecacheChoosePositionMark(m_texMng); @@ -117,6 +126,10 @@ void BackendRenderer::AcceptMessage(ref_ptr message) { ref_ptr msg = message; RecacheGui(msg->GetInitInfo(), msg->NeedResetOldGui()); + +#ifdef RENRER_DEBUG_INFO_LABELS + RecacheDebugLabels(); +#endif break; } case Message::GuiLayerLayout: diff --git a/drape_frontend/backend_renderer.hpp b/drape_frontend/backend_renderer.hpp index 3c92d9d5a5..8222f674a7 100644 --- a/drape_frontend/backend_renderer.hpp +++ b/drape_frontend/backend_renderer.hpp @@ -63,6 +63,10 @@ private: void RecacheChoosePositionMark(); void RecacheMapShapes(); +#ifdef RENRER_DEBUG_INFO_LABELS + void RecacheDebugLabels(); +#endif + void AcceptMessage(ref_ptr message) override; class Routine : public threads::IRoutine diff --git a/drape_frontend/drape_frontend.pro b/drape_frontend/drape_frontend.pro index 137ae99d4e..246a71d272 100755 --- a/drape_frontend/drape_frontend.pro +++ b/drape_frontend/drape_frontend.pro @@ -29,6 +29,7 @@ SOURCES += \ gui/choose_position_mark.cpp \ gui/compass.cpp \ gui/copyright_label.cpp \ + gui/debug_label.cpp \ gui/drape_gui.cpp \ gui/gui_text.cpp \ gui/layer_render.cpp \ @@ -122,6 +123,7 @@ HEADERS += \ gui/choose_position_mark.hpp \ gui/compass.hpp \ gui/copyright_label.hpp \ + gui/debug_label.hpp \ gui/drape_gui.hpp \ gui/gui_text.hpp \ gui/layer_render.hpp \ diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index 565b4d4505..a74d31f9c3 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -1074,18 +1074,7 @@ void FrontendRenderer::RenderScene(ScreenBase const & modelView) modelView, make_ref(m_gpuProgramManager), m_generalUniforms); if (m_guiRenderer != nullptr) - { - if (isPerspective) - { - ScreenBase modelView2d = modelView; - modelView2d.ResetPerspective(); - m_guiRenderer->Render(make_ref(m_gpuProgramManager), modelView2d); - } - else - { - m_guiRenderer->Render(make_ref(m_gpuProgramManager), modelView); - } - } + m_guiRenderer->Render(make_ref(m_gpuProgramManager), modelView); GLFunctions::glEnable(gl_const::GLDepthTest); diff --git a/drape_frontend/gui/choose_position_mark.cpp b/drape_frontend/gui/choose_position_mark.cpp index 5c7b87d20d..e08c350d28 100644 --- a/drape_frontend/gui/choose_position_mark.cpp +++ b/drape_frontend/gui/choose_position_mark.cpp @@ -37,7 +37,7 @@ public: bool Update(ScreenBase const & screen) override { - SetPivot(glsl::ToVec2(m2::PointF(screen.PixelRect().Center()))); + SetPivot(glsl::ToVec2(m2::PointF(screen.PixelRectIn3d().Center()))); return TBase::Update(screen); } }; diff --git a/drape_frontend/gui/debug_label.cpp b/drape_frontend/gui/debug_label.cpp new file mode 100644 index 0000000000..7b8c5116ef --- /dev/null +++ b/drape_frontend/gui/debug_label.cpp @@ -0,0 +1,94 @@ +#include "debug_label.hpp" + +#include "drape_gui.hpp" + +#include "std/bind.hpp" + +namespace gui +{ + +class DebugLabelHandle : public MutableLabelHandle +{ + using TBase = MutableLabelHandle; + +public: + DebugLabelHandle(uint32_t id, dp::Anchor anchor, m2::PointF const & pivot, + ref_ptr tex, TUpdateDebugLabelFn const & onUpdateFn) + : MutableLabelHandle(id, anchor, pivot) + , m_onUpdateFn(onUpdateFn) + { + SetTextureManager(tex); + } + + bool Update(ScreenBase const & screen) override + { + string content; + bool const isVisible = m_onUpdateFn(screen, content); + + SetIsVisible(isVisible); + SetContent(content); + + return TBase::Update(screen); + } + +private: + TUpdateDebugLabelFn m_onUpdateFn; +}; + +void AddSymbols(string const & str, set & symbols) +{ + for (size_t i = 0, sz = str.length(); i < sz; ++i) + symbols.insert(str[i]); +} + +void DebugInfoLabels::AddLabel(ref_ptr tex, string const & caption, TUpdateDebugLabelFn const & onUpdateFn) +{ + string alphabet; + set symbols; + AddSymbols(caption, symbols); + AddSymbols("0123456789.-e", symbols); + + alphabet.reserve(symbols.size()); + for (auto const & ch : symbols) + alphabet.push_back(ch); + + MutableLabelDrawer::Params params; + params.m_anchor = dp::LeftTop; + params.m_alphabet = alphabet; + params.m_maxLength = 100; + params.m_font = DrapeGui::GetGuiTextFont(); + params.m_font.m_color = dp::Color(0, 0, 255, 255); + params.m_font.m_size *= 1.2; + params.m_pivot = m_position.m_pixelPivot; + +#ifdef RENRER_DEBUG_INFO_LABELS + uint32_t const id = GuiHandleDebugLabel + m_labelsCount; + + params.m_handleCreator = [id, onUpdateFn, tex](dp::Anchor anchor, m2::PointF const & pivot) + { + return make_unique_dp(id, anchor, pivot, tex, onUpdateFn); + }; +#endif + m_labelsParams.push_back(params); + ++m_labelsCount; +} + +drape_ptr DebugInfoLabels::Draw(ref_ptr tex) +{ + drape_ptr renderer = make_unique_dp(); + + m2::PointF pos = m_position.m_pixelPivot; + + for (auto & params : m_labelsParams) + { + params.m_pivot.y = pos.y; + m2::PointF textSize = MutableLabelDrawer::Draw(params, tex, bind(&ShapeRenderer::AddShape, renderer.get(), _1, _2)); + pos.y += 2 * textSize.y; + } + + m_labelsParams.clear(); + + return renderer; +} + +} // namespace gui diff --git a/drape_frontend/gui/debug_label.hpp b/drape_frontend/gui/debug_label.hpp new file mode 100644 index 0000000000..b4cf4917cb --- /dev/null +++ b/drape_frontend/gui/debug_label.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include "gui_text.hpp" +#include "shape.hpp" + +#include "std/vector.hpp" + +namespace gui +{ + +using TUpdateDebugLabelFn = function; + +class DebugInfoLabels : public Shape +{ +public: + DebugInfoLabels(gui::Position const & position) + : Shape(position) + {} + + void AddLabel(ref_ptr tex, string const & caption, TUpdateDebugLabelFn const & onUpdateFn); + drape_ptr Draw(ref_ptr tex); + +private: + vector m_labelsParams; + uint32_t m_labelsCount = 0; +}; + +} // namespace gui diff --git a/drape_frontend/gui/layer_render.cpp b/drape_frontend/gui/layer_render.cpp index c2521dd38b..4406c04b01 100644 --- a/drape_frontend/gui/layer_render.cpp +++ b/drape_frontend/gui/layer_render.cpp @@ -1,6 +1,7 @@ #include "choose_position_mark.hpp" #include "compass.hpp" #include "copyright_label.hpp" +#include "debug_label.hpp" #include "drape_gui.hpp" #include "gui_text.hpp" #include "layer_render.hpp" @@ -12,6 +13,8 @@ #include "drape/batcher.hpp" #include "drape/render_bucket.hpp" +#include "geometry/mercator.hpp" + #include "base/stl_add.hpp" #include "std/bind.hpp" @@ -212,6 +215,100 @@ drape_ptr LayerCacher::RecacheChoosePositionMark(ref_ptr LayerCacher::RecacheDebugLabels(ref_ptr textures) +{ + drape_ptr renderer = make_unique_dp(); + + float const vs = df::VisualParams::Instance().GetVisualScale(); + DebugInfoLabels debugLabels = DebugInfoLabels(Position(m2::PointF(10.0f * vs, 50.0f * vs), dp::Center)); + + debugLabels.AddLabel(textures, "visible: km2, readed: km2, ratio:", + [](ScreenBase const & screen, string & content) -> bool + { + double const sizeX = screen.PixelRectIn3d().SizeX(); + double const sizeY = screen.PixelRectIn3d().SizeY(); + + m2::PointD const p0 = screen.PtoG(screen.P3dtoP(m2::PointD(0.0, 0.0))); + m2::PointD const p1 = screen.PtoG(screen.P3dtoP(m2::PointD(0.0, sizeY))); + m2::PointD const p2 = screen.PtoG(screen.P3dtoP(m2::PointD(sizeX, sizeY))); + m2::PointD const p3 = screen.PtoG(screen.P3dtoP(m2::PointD(sizeX, 0.0))); + + double const areaG = MercatorBounds::AreaOnEarth(p0, p1, p2) + + MercatorBounds::AreaOnEarth(p2, p3, p0); + + double const sizeX_2d = screen.PixelRect().SizeX(); + double const sizeY_2d = screen.PixelRect().SizeY(); + + m2::PointD const p0_2d = screen.PtoG(m2::PointD(0.0, 0.0)); + m2::PointD const p1_2d = screen.PtoG(m2::PointD(0.0, sizeY_2d)); + m2::PointD const p2_2d = screen.PtoG(m2::PointD(sizeX_2d, sizeY_2d)); + m2::PointD const p3_2d = screen.PtoG(m2::PointD(sizeX_2d, 0.0)); + + double const areaGTotal = MercatorBounds::AreaOnEarth(p0_2d, p1_2d, p2_2d) + + MercatorBounds::AreaOnEarth(p2_2d, p3_2d, p0_2d); + + ostringstream out; + out << fixed << setprecision(2) + << "visible: " << areaG / 1000000.0 << " km2" + << ", readed: " << areaGTotal / 1000000.0 << " km2" + << ", ratio: " << areaGTotal / areaG; + content.assign(out.str()); + return true; + }); + + debugLabels.AddLabel(textures, "scale2d: m/px, scale2d * vs: m/px", + [](ScreenBase const & screen, string & content) -> bool + { + double const distanceG = MercatorBounds::DistanceOnEarth(screen.PtoG(screen.PixelRect().LeftBottom()), + screen.PtoG(screen.PixelRect().RightBottom())); + + double const vs = df::VisualParams::Instance().GetVisualScale(); + double const scale = distanceG / screen.PixelRect().SizeX(); + + ostringstream out; + out << fixed << setprecision(2) + << "scale2d: " << scale << " m/px" + << ", scale2d * vs: " << scale * vs << " m/px"; + content.assign(out.str()); + return true; + }); + + debugLabels.AddLabel(textures, "distance: m", + [](ScreenBase const & screen, string & content) -> bool + { + double const sizeX = screen.PixelRectIn3d().SizeX(); + double const sizeY = screen.PixelRectIn3d().SizeY(); + + double const distance = MercatorBounds::DistanceOnEarth(screen.PtoG(screen.P3dtoP(m2::PointD(sizeX / 2.0, 0.0))), + screen.PtoG(screen.P3dtoP(m2::PointD(sizeX / 2.0, sizeY)))); + + ostringstream out; + out << fixed << setprecision(2) + << "distance: " << distance << " m"; + content.assign(out.str()); + return true; + }); + + debugLabels.AddLabel(textures, "angle: ", + [](ScreenBase const & screen, string & content) -> bool + { + ostringstream out; + out << fixed << setprecision(2) + << "angle: " << screen.GetRotationAngle() * 180.0 / math::pi; + content.assign(out.str()); + return true; + }); + + renderer->AddShapeRenderer(WIDGET_DEBUG_INFO, debugLabels.Draw(textures)); + + // Flush gui geometry. + GLFunctions::glFlush(); + + return renderer; +} +#endif + m2::PointF LayerCacher::CacheCompass(Position const & position, ref_ptr renderer, ref_ptr textures) { diff --git a/drape_frontend/gui/layer_render.hpp b/drape_frontend/gui/layer_render.hpp index f48cf76c0c..fdd24e9575 100644 --- a/drape_frontend/gui/layer_render.hpp +++ b/drape_frontend/gui/layer_render.hpp @@ -58,6 +58,10 @@ public: ref_ptr textures); drape_ptr RecacheChoosePositionMark(ref_ptr textures); +#ifdef RENRER_DEBUG_INFO_LABELS + drape_ptr RecacheDebugLabels(ref_ptr textures); +#endif + private: m2::PointF CacheCompass(Position const & position, ref_ptr renderer, ref_ptr textures); m2::PointF CacheRuler(Position const & position, ref_ptr renderer, ref_ptr textures); diff --git a/drape_frontend/gui/shape.cpp b/drape_frontend/gui/shape.cpp index 794405dc26..3499b32b31 100644 --- a/drape_frontend/gui/shape.cpp +++ b/drape_frontend/gui/shape.cpp @@ -91,7 +91,7 @@ void ShapeRenderer::Build(ref_ptr mng) void ShapeRenderer::Render(ScreenBase const & screen, ref_ptr mng) { array m; - m2::RectD const & pxRect = screen.PixelRect(); + m2::RectD const & pxRect = screen.PixelRectIn3d(); dp::MakeProjection(m, 0.0f, pxRect.SizeX(), pxRect.SizeY(), 0.0f); dp::UniformValuesStorage uniformStorage; diff --git a/drape_frontend/gui/skin.hpp b/drape_frontend/gui/skin.hpp index c34965a026..d326a8e1d0 100644 --- a/drape_frontend/gui/skin.hpp +++ b/drape_frontend/gui/skin.hpp @@ -6,6 +6,8 @@ #include "std/map.hpp" +//#define RENRER_DEBUG_INFO_LABELS + namespace gui { @@ -16,7 +18,10 @@ enum EWidget WIDGET_COPYRIGHT = 0x4, WIDGET_SCALE_LABEL = 0x8, /// Following widgets controlled by rendering kernel. Don't use them in platform code - WIDGET_CHOOSE_POSITION_MARK = 0x8000 + WIDGET_CHOOSE_POSITION_MARK = 0x8000, +#ifdef RENRER_DEBUG_INFO_LABELS + WIDGET_DEBUG_INFO +#endif }; enum EGuiHandle @@ -34,7 +39,10 @@ enum EGuiHandle GuiHandleRetryButtonLabel, GuiHandleCancelButton, GuiHandleCancelButtonLabel, - GuiHandleChoosePositionMark + GuiHandleChoosePositionMark, +#ifdef RENRER_DEBUG_INFO_LABELS + GuiHandleDebugLabel = 100 +#endif }; struct Position diff --git a/geometry/screenbase.cpp b/geometry/screenbase.cpp index a6ee53227b..1bb0855914 100644 --- a/geometry/screenbase.cpp +++ b/geometry/screenbase.cpp @@ -398,7 +398,7 @@ void ScreenBase::ApplyPerspective(double currentRotationAngle, double maxRotatio // orthogonal projection does and rotate the map plane around its near horizontal side. void ScreenBase::SetRotationAngle(double rotationAngle) { - ASSERT(m_isPerspective, ()); + ASSERT(rotationAngle == 0.0 || (rotationAngle > 0.0 && m_isPerspective), ()); ASSERT_GREATER_OR_EQUAL(rotationAngle, 0.0, ()); ASSERT_LESS_OR_EQUAL(rotationAngle, m_3dMaxAngleX, ()); From 599063085a467816be63fc93ba505150e7d67281 Mon Sep 17 00:00:00 2001 From: Daria Volvenkova Date: Mon, 27 Jun 2016 18:19:22 +0300 Subject: [PATCH 12/18] Rotate event fixed in perspective mode. --- drape_frontend/user_event_stream.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drape_frontend/user_event_stream.cpp b/drape_frontend/user_event_stream.cpp index 64169b209a..d611b20e3d 100644 --- a/drape_frontend/user_event_stream.cpp +++ b/drape_frontend/user_event_stream.cpp @@ -195,8 +195,9 @@ ScreenBase const & UserEventStream::ProcessEvents(bool & modelViewChanged, bool ScreenBase const & screen = m_navigator.Screen(); if (screen.isPerspective()) { - m2::PointD pt = screen.P3dtoP(screen.PixelRectIn3d().Center()); - breakAnim = SetFollowAndRotate(screen.PtoG(pt), pt, e.m_rotate.m_targetAzimut, kDoNotChangeZoom, true); + m2::PointD pt = screen.PixelRectIn3d().Center(); + breakAnim = SetFollowAndRotate(screen.PtoG(screen.P3dtoP(pt)), pt, + e.m_rotate.m_targetAzimut, kDoNotChangeZoom, true); } else { From 5bd3d26105c12dc662d0b6e118e9b436abb093bd Mon Sep 17 00:00:00 2001 From: Daria Volvenkova Date: Tue, 28 Jun 2016 12:54:31 +0300 Subject: [PATCH 13/18] Set center fixed. --- drape_frontend/my_position_controller.cpp | 4 +- drape_frontend/screen_animations.cpp | 18 ++++++ drape_frontend/screen_animations.hpp | 2 + drape_frontend/user_event_stream.cpp | 76 +++++++++++++++-------- drape_frontend/user_event_stream.hpp | 2 + drape_frontend/visual_params.cpp | 12 ++++ drape_frontend/visual_params.hpp | 3 + geometry/screenbase.cpp | 17 +---- 8 files changed, 92 insertions(+), 42 deletions(-) diff --git a/drape_frontend/my_position_controller.cpp b/drape_frontend/my_position_controller.cpp index 29bbf6e6c4..0feaf86a64 100644 --- a/drape_frontend/my_position_controller.cpp +++ b/drape_frontend/my_position_controller.cpp @@ -52,7 +52,7 @@ string LocationModeStatisticsName(location::EMyPositionMode mode) int GetZoomLevel(ScreenBase const & screen) { - return my::clamp(fabs(log(screen.GetScale()) / log(2.0)), 1, scales::GetUpperStyleScale()); + return df::GetZoomLevel(screen.GetScale()); } int GetZoomLevel(ScreenBase const & screen, m2::PointD const & position, double errorRadius) @@ -63,6 +63,8 @@ int GetZoomLevel(ScreenBase const & screen, m2::PointD const & position, double return GetZoomLevel(s); } + + } // namespace MyPositionController::MyPositionController(location::EMyPositionMode initMode, double timeInBackground, diff --git a/drape_frontend/screen_animations.cpp b/drape_frontend/screen_animations.cpp index e2076746ef..8a68748a8c 100644 --- a/drape_frontend/screen_animations.cpp +++ b/drape_frontend/screen_animations.cpp @@ -13,6 +13,12 @@ namespace df string const kPrettyMoveAnim = "PrettyMove"; string const kPrettyFollowAnim = "PrettyFollow"; +drape_ptr GetPrettyMoveAnimation(ScreenBase const & startScreen, ScreenBase const & endScreen) +{ + return GetPrettyMoveAnimation(startScreen, startScreen.GetScale(), endScreen.GetScale(), + startScreen.GetOrg(), endScreen.GetOrg()); +} + drape_ptr GetPrettyMoveAnimation(ScreenBase const & screen, m2::AnyRectD const & startRect, m2::AnyRectD const & endRect) { @@ -80,6 +86,18 @@ drape_ptr GetPrettyFollowAnimation(ScreenBase const & screen, return sequenceAnim; } +drape_ptr GetRectAnimation(ScreenBase const & startScreen, ScreenBase const & endScreen) +{ + auto anim = make_unique_dp(); + + anim->SetRotate(startScreen.GetAngle(), endScreen.GetAngle()); + anim->SetMove(startScreen.GetOrg(), endScreen.GetOrg(), startScreen); + anim->SetScale(startScreen.GetScale(), endScreen.GetScale()); + anim->SetMaxScaleDuration(kMaxAnimationTimeSec); + + return anim; +} + drape_ptr GetSetRectAnimation(ScreenBase const & screen, m2::AnyRectD const & startRect, m2::AnyRectD const & endRect) { diff --git a/drape_frontend/screen_animations.hpp b/drape_frontend/screen_animations.hpp index b8a6d83622..15dfa758da 100644 --- a/drape_frontend/screen_animations.hpp +++ b/drape_frontend/screen_animations.hpp @@ -15,6 +15,7 @@ class MapLinearAnimation; class MapFollowAnimation; class MapScaleAnimation; +drape_ptr GetPrettyMoveAnimation(ScreenBase const & startScreen, ScreenBase const & endScreen); drape_ptr GetPrettyMoveAnimation(ScreenBase const & screen, m2::AnyRectD const & startRect, m2::AnyRectD const & endRect); drape_ptr GetPrettyMoveAnimation(ScreenBase const & screen, double startScale, double endScale, @@ -24,6 +25,7 @@ drape_ptr GetPrettyFollowAnimation(ScreenBase const & screen, m2::PointD const & startPt, m2::PointD const & userPos, double targetAngle, m2::PointD const & endPixelPos); +drape_ptr GetRectAnimation(ScreenBase const & startScreen, ScreenBase const & endScreen); drape_ptr GetSetRectAnimation(ScreenBase const & screen, m2::AnyRectD const & startRect, m2::AnyRectD const & endRect); diff --git a/drape_frontend/user_event_stream.cpp b/drape_frontend/user_event_stream.cpp index d611b20e3d..c7049d8f45 100644 --- a/drape_frontend/user_event_stream.cpp +++ b/drape_frontend/user_event_stream.cpp @@ -366,40 +366,26 @@ bool UserEventStream::SetScale(m2::PointD const & pxScaleCenter, double factor, bool UserEventStream::SetCenter(m2::PointD const & center, int zoom, bool isAnim) { - m2::PointD targetCenter = center; - ang::AngleD angle; - m2::RectD localRect; - ScreenBase const & currentScreen = GetCurrentScreen(); ScreenBase screen = currentScreen; if (zoom == kDoNotChangeZoom) { - m2::AnyRectD const r = GetTargetRect(); - angle = r.Angle(); - localRect = r.GetLocalRect(); + GetTargetScreen(screen); + screen.MatchGandP3d(center, screen.PixelRectIn3d().Center()); } else { - angle = screen.GlobalRect().Angle(); - - double scale3d = kDefault3dScale;//screen.CalculateScale3d(screen.CalculatePerspectiveAngle()); - localRect = df::GetRectForDrawScale(zoom, center); - localRect.Scale(scale3d); - - CheckMinGlobalRect(localRect, scale3d); - CheckMinMaxVisibleScale(localRect, zoom, scale3d); - - localRect.Offset(-center); - - double const aspectRatio = screen.PixelRect().SizeY() / screen.PixelRect().SizeX(); - if (aspectRatio > 1.0) - localRect.Inflate(0.0, localRect.SizeY() * 0.5 * aspectRatio); - else - localRect.Inflate(localRect.SizeX() * 0.5 / aspectRatio, 0.0); + screen.SetFromParams(center, screen.GetAngle(), GetScale(zoom)); + screen.MatchGandP3d(center, screen.PixelRectIn3d().Center()); } - return SetRect(m2::AnyRectD(targetCenter, angle, localRect), isAnim); + ASSERT_GREATER_OR_EQUAL(zoom, scales::GetUpperWorldScale(), ()); + ASSERT_LESS_OR_EQUAL(zoom, scales::GetUpperStyleScale(), ()); + + ShrinkAndScaleInto(screen, df::GetWorldRect()); + + return SetScreen(screen, isAnim); } bool UserEventStream::SetRect(m2::RectD rect, int zoom, bool applyRotation, bool isAnim) @@ -410,9 +396,44 @@ bool UserEventStream::SetRect(m2::RectD rect, int zoom, bool applyRotation, bool return SetRect(targetRect, isAnim); } +bool UserEventStream::SetScreen(ScreenBase const & endScreen, bool isAnim) +{ + if (isAnim) + { + auto onStartHandler = [this](ref_ptr animation) + { + if (m_listener) + m_listener->OnAnimationStarted(animation); + }; + + ScreenBase const & screen = GetCurrentScreen(); + + drape_ptr anim = GetRectAnimation(screen, endScreen); + if (!df::IsAnimationAllowed(anim->GetDuration(), screen)) + { + anim.reset(); + double const moveDuration = PositionInterpolator::GetMoveDuration(screen.GetOrg(), + endScreen.GetOrg(), screen); + if (moveDuration > kMaxAnimationTimeSec) + anim = GetPrettyMoveAnimation(screen, endScreen); + } + + if (anim != nullptr) + { + anim->SetOnStartAction(onStartHandler); + m_animationSystem.CombineAnimation(move(anim)); + return false; + } + } + + ResetMapPlaneAnimations(); + m_navigator.SetScreen(endScreen); + return true; +} + bool UserEventStream::SetRect(m2::AnyRectD const & rect, bool isAnim) { - isAnim = false; + //isAnim = false; if (isAnim) { auto onStartHandler = [this](ref_ptr animation) @@ -642,6 +663,11 @@ m2::AnyRectD UserEventStream::GetCurrentRect() const return m_navigator.Screen().GlobalRect(); } +void UserEventStream::GetTargetScreen(ScreenBase & screen) const +{ + m_animationSystem.GetTargetScreen(m_navigator.Screen(), screen); +} + m2::AnyRectD UserEventStream::GetTargetRect() const { ScreenBase targetScreen; diff --git a/drape_frontend/user_event_stream.hpp b/drape_frontend/user_event_stream.hpp index 28d926f428..b8d8133536 100644 --- a/drape_frontend/user_event_stream.hpp +++ b/drape_frontend/user_event_stream.hpp @@ -269,6 +269,7 @@ public: ScreenBase const & ProcessEvents(bool & modelViewChanged, bool & viewportChanged); ScreenBase const & GetCurrentScreen() const; + void GetTargetScreen(ScreenBase & screen) const; m2::AnyRectD GetTargetRect() const; bool IsInUserAction() const; bool IsInPerspectiveAnimation() const; @@ -306,6 +307,7 @@ private: bool SetCenter(m2::PointD const & center, int zoom, bool isAnim); bool SetRect(m2::RectD rect, int zoom, bool applyRotation, bool isAnim); bool SetRect(m2::AnyRectD const & rect, bool isAnim); + bool SetScreen(ScreenBase const & screen, bool isAnim); bool SetFollowAndRotate(m2::PointD const & userPos, m2::PointD const & pixelPos, double azimuth, int preferredZoomLevel, bool isAnim); diff --git a/drape_frontend/visual_params.cpp b/drape_frontend/visual_params.cpp index cf0de06c78..9f134ba03c 100644 --- a/drape_frontend/visual_params.cpp +++ b/drape_frontend/visual_params.cpp @@ -6,6 +6,8 @@ #include "geometry/mercator.hpp" +#include "indexer/scales.hpp" + #include "std/limits.hpp" #include "std/algorithm.hpp" @@ -270,4 +272,14 @@ int GetDrawTileScale(m2::RectD const & r) return GetDrawTileScale(r, p.GetTileSize(), p.GetVisualScale()); } +double GetZoomLevel(double scale) +{ + return my::clamp(fabs(log(scale) / log(2.0)), 1, scales::GetUpperStyleScale()); +} + +double GetScale(double zoomLevel) +{ + return pow(2.0, -zoomLevel); +} + } // namespace df diff --git a/drape_frontend/visual_params.hpp b/drape_frontend/visual_params.hpp index 5e912843d4..b61c723040 100644 --- a/drape_frontend/visual_params.hpp +++ b/drape_frontend/visual_params.hpp @@ -75,4 +75,7 @@ m2::RectD GetRectForDrawScale(double drawScale, m2::PointD const & center); int CalculateTileSize(int screenWidth, int screenHeight); +double GetZoomLevel(double scale); +double GetScale(double zoomLevel); + } // namespace df diff --git a/geometry/screenbase.cpp b/geometry/screenbase.cpp index 1bb0855914..93693b167b 100644 --- a/geometry/screenbase.cpp +++ b/geometry/screenbase.cpp @@ -145,22 +145,7 @@ void ScreenBase::SetFromRect(m2::AnyRectD const & glbRect) void ScreenBase::SetFromRect2d(m2::AnyRectD const & glbRect) { - double hScale = glbRect.GetLocalRect().SizeX() / PixelRectIn3d().SizeX(); - double vScale = glbRect.GetLocalRect().SizeY() / PixelRectIn3d().SizeY(); - double scale = max(hScale, vScale); - - m_Scale = scale; - m_Angle = glbRect.Angle(); - m_Org = glbRect.GlobalCenter(); - - UpdateDependentParameters(); - -/* m2::PointD g_target(0.0, -glbRect.GetLocalRect().SizeY() * scale / vScale / 2.0); - g_target.Rotate(glbRect.Angle().val()); - g_target = glbRect.GlobalCenter() + g_target; - m2::PointD p_target(m_PixelRect.SizeX() / 2.0, m_PixelRect.SizeY()); - MatchGandP(g_target, p_target);*/ - + SetFromRects(glbRect, PixelRectIn3d()); MatchGandP3d(glbRect.GlobalCenter(), PixelRectIn3d().Center()); } From c21f80c1dea70f58c3acc2c8ba0a9235dd590476 Mon Sep 17 00:00:00 2001 From: Daria Volvenkova Date: Fri, 1 Jul 2016 19:04:09 +0300 Subject: [PATCH 14/18] Follow and pretty-follow animations fixed. --- drape_frontend/animation/follow_animation.cpp | 80 ++++++++----------- drape_frontend/animation/follow_animation.hpp | 20 ++--- drape_frontend/animation/interpolators.cpp | 76 +++++++++--------- drape_frontend/animation/interpolators.hpp | 40 +++++----- drape_frontend/animation/linear_animation.cpp | 8 ++ drape_frontend/animation/linear_animation.hpp | 1 + drape_frontend/screen_animations.cpp | 40 ++++++---- drape_frontend/screen_animations.hpp | 5 +- drape_frontend/user_event_stream.cpp | 46 +++++------ 9 files changed, 156 insertions(+), 160 deletions(-) diff --git a/drape_frontend/animation/follow_animation.cpp b/drape_frontend/animation/follow_animation.cpp index ba708512ea..0ddc6016ed 100644 --- a/drape_frontend/animation/follow_animation.cpp +++ b/drape_frontend/animation/follow_animation.cpp @@ -1,28 +1,31 @@ #include "follow_animation.hpp" +#include "animation_constants.hpp" #include "animation_system.hpp" #include "base/assert.hpp" +#include "base/logging.hpp" namespace df { -MapFollowAnimation::MapFollowAnimation(m2::PointD const & globalPosition, - double startScale, double endScale, - double startAngle, double endAngle, - m2::PointD const & startPixelPosition, +MapFollowAnimation::MapFollowAnimation(ScreenBase const & screen, + m2::PointD const & globalUserPosition, m2::PointD const & endPixelPosition, - m2::RectD const & pixelRect) + double startScale, double endScale, + double startAngle, double endAngle) : Animation(true /* couldBeInterrupted */, true /* couldBeBlended */) , m_scaleInterpolator(startScale, endScale) - , m_pixelPosInterpolator(startPixelPosition, endPixelPosition, pixelRect) , m_angleInterpolator(startAngle, endAngle) - , m_globalPosition(globalPosition) + , m_globalPosition(globalUserPosition) + , m_endPixelPosition(endPixelPosition) { double const duration = CalculateDuration(); m_scaleInterpolator.SetMinDuration(duration); m_angleInterpolator.SetMinDuration(duration); - m_pixelPosInterpolator.SetMinDuration(duration); + + m_offset = screen.PtoG(screen.P3dtoP(m_endPixelPosition)) - m_globalPosition; + m_offsetInterpolator = PositionInterpolator(duration, 0.0, m_offset, m2::PointD(0.0, 0.0)); m_objects.insert(Animation::MapPlane); @@ -30,7 +33,7 @@ MapFollowAnimation::MapFollowAnimation(m2::PointD const & globalPosition, m_properties.insert(Animation::Scale); if (m_angleInterpolator.IsActive()) m_properties.insert(Animation::Angle); - if (m_pixelPosInterpolator.IsActive()) + //if (m_offsetInterpolator.IsActive()) m_properties.insert(Animation::Position); } @@ -51,8 +54,8 @@ void MapFollowAnimation::Advance(double elapsedSeconds) m_angleInterpolator.Advance(elapsedSeconds); if (m_scaleInterpolator.IsActive()) m_scaleInterpolator.Advance(elapsedSeconds); - if (m_pixelPosInterpolator.IsActive()) - m_pixelPosInterpolator.Advance(elapsedSeconds); + if (m_offsetInterpolator.IsActive()) + m_offsetInterpolator.Advance(elapsedSeconds); } void MapFollowAnimation::Finish() @@ -61,8 +64,8 @@ void MapFollowAnimation::Finish() m_angleInterpolator.Finish(); if (m_scaleInterpolator.IsActive()) m_scaleInterpolator.Finish(); - if (m_pixelPosInterpolator.IsActive()) - m_pixelPosInterpolator.Finish(); + if (m_offsetInterpolator.IsActive()) + m_offsetInterpolator.Finish(); Animation::Finish(); } @@ -72,8 +75,8 @@ void MapFollowAnimation::SetMaxDuration(double maxDuration) m_angleInterpolator.SetMaxDuration(maxDuration); if (m_scaleInterpolator.IsActive()) m_scaleInterpolator.SetMaxDuration(maxDuration); - if (m_pixelPosInterpolator.IsActive()) - m_pixelPosInterpolator.SetMaxDuration(maxDuration); + if (m_offsetInterpolator.IsActive()) + m_offsetInterpolator.SetMaxDuration(maxDuration); } double MapFollowAnimation::GetDuration() const @@ -83,33 +86,13 @@ double MapFollowAnimation::GetDuration() const double MapFollowAnimation::CalculateDuration() const { - return max(max(m_pixelPosInterpolator.GetDuration(), - m_angleInterpolator.GetDuration()), m_scaleInterpolator.GetDuration()); + return max(m_offsetInterpolator.GetDuration(), + max(m_angleInterpolator.GetDuration(), m_scaleInterpolator.GetDuration())); } bool MapFollowAnimation::IsFinished() const { - return m_pixelPosInterpolator.IsFinished() && m_angleInterpolator.IsFinished() && - m_scaleInterpolator.IsFinished(); -} - -// static -m2::PointD MapFollowAnimation::CalculateCenter(ScreenBase const & screen, m2::PointD const & userPos, - m2::PointD const & pixelPos, double azimuth) -{ - double const scale = screen.GlobalRect().GetLocalRect().SizeX() / screen.PixelRect().SizeX(); - return CalculateCenter(scale, screen.PixelRect(), userPos, screen.P3dtoP(pixelPos), azimuth); -} - -// static -m2::PointD MapFollowAnimation::CalculateCenter(double scale, m2::RectD const & pixelRect, - m2::PointD const & userPos, m2::PointD const & pixelPos, - double azimuth) -{ - m2::PointD formingVector = (pixelRect.Center() - pixelPos) * scale; - formingVector.y = -formingVector.y; - formingVector.Rotate(azimuth); - return userPos + formingVector; + return m_angleInterpolator.IsFinished() && m_scaleInterpolator.IsFinished() && m_offsetInterpolator.IsFinished(); } bool MapFollowAnimation::GetProperty(TObject object, TProperty property, PropertyValue & value) const @@ -126,19 +109,24 @@ bool MapFollowAnimation::GetProperty(TObject object, TProperty property, bool ta { if (property == Animation::Position) { - ScreenBase const & screen = AnimationSystem::Instance().GetLastScreen(); - m2::RectD const pixelRect = screen.PixelRect(); + ScreenBase tmp = AnimationSystem::Instance().GetLastScreen(); if (targetValue) { - // TODO: calculate target pixel position with corresponding scale - value = PropertyValue(CalculateCenter(m_scaleInterpolator.GetTargetScale(), pixelRect, m_globalPosition, - screen.P3dtoP(m_pixelPosInterpolator.GetTargetPosition()), m_angleInterpolator.GetTargetAngle())); + tmp.SetFromParams(m_globalPosition, m_angleInterpolator.GetTargetAngle(), m_scaleInterpolator.GetTargetScale()); + tmp.MatchGandP3d(m_globalPosition, m_endPixelPosition); } else { - value = PropertyValue(CalculateCenter(m_scaleInterpolator.GetScale(), pixelRect, m_globalPosition, - screen.P3dtoP(m_pixelPosInterpolator.GetPosition()), m_angleInterpolator.GetAngle())); + double scale = m_scaleInterpolator.GetScale() / m_scaleInterpolator.GetStartScale(); + double angle = m_angleInterpolator.GetAngle() - m_angleInterpolator.GetStartAngle(); + m2::PointD offset = m_offsetInterpolator.GetPosition() * scale; + offset.Rotate(angle); + m2::PointD pos = m_globalPosition + offset; + + tmp.SetFromParams(m_globalPosition, m_angleInterpolator.GetAngle(), m_scaleInterpolator.GetScale()); + tmp.MatchGandP3d(pos, m_endPixelPosition); } + value = PropertyValue(tmp.GetOrg()); return true; } if (property == Animation::Angle) @@ -162,7 +150,7 @@ bool MapFollowAnimation::HasScale() const bool MapFollowAnimation::HasPixelOffset() const { - return m_pixelPosInterpolator.IsActive(); + return m_offsetInterpolator.IsActive(); } } // namespace df diff --git a/drape_frontend/animation/follow_animation.hpp b/drape_frontend/animation/follow_animation.hpp index fdfd38634b..a1da305f19 100644 --- a/drape_frontend/animation/follow_animation.hpp +++ b/drape_frontend/animation/follow_animation.hpp @@ -9,18 +9,11 @@ namespace df class MapFollowAnimation : public Animation { public: - MapFollowAnimation(m2::PointD const & globalPosition, - double startScale, double endScale, - double startAngle, double endAngle, - m2::PointD const & startPixelPosition, + MapFollowAnimation(ScreenBase const & screen, + m2::PointD const & globalUserPosition, m2::PointD const & endPixelPosition, - m2::RectD const & pixelRect); - - static m2::PointD CalculateCenter(ScreenBase const & screen, m2::PointD const & userPos, - m2::PointD const & pixelPos, double azimuth); - - static m2::PointD CalculateCenter(double scale, m2::RectD const & pixelRect, - m2::PointD const & userPos, m2::PointD const & pixelPos, double azimuth); + double startScale, double endScale, + double startAngle, double endAngle); Animation::Type GetType() const override { return Animation::MapFollow; } @@ -55,10 +48,13 @@ private: double CalculateDuration() const; ScaleInterpolator m_scaleInterpolator; - PositionInterpolator m_pixelPosInterpolator; AngleInterpolator m_angleInterpolator; + PositionInterpolator m_offsetInterpolator; m2::PointD const m_globalPosition; + m2::PointD const m_endPixelPosition; + + m2::PointD m_offset; TObjectProperties m_properties; TAnimObjects m_objects; diff --git a/drape_frontend/animation/interpolators.cpp b/drape_frontend/animation/interpolators.cpp index 7570d5ee20..c427a5f090 100644 --- a/drape_frontend/animation/interpolators.cpp +++ b/drape_frontend/animation/interpolators.cpp @@ -87,8 +87,7 @@ PositionInterpolator::PositionInterpolator() {} PositionInterpolator::PositionInterpolator(double duration, double delay, - m2::PointD const & startPosition, - m2::PointD const & endPosition) + m2::PointD const & startPosition, m2::PointD const & endPosition) : Interpolator(duration, delay) , m_startPosition(startPosition) , m_endPosition(endPosition) @@ -97,14 +96,13 @@ PositionInterpolator::PositionInterpolator(double duration, double delay, SetActive(m_startPosition != m_endPosition); } -PositionInterpolator::PositionInterpolator(m2::PointD const & startPosition, - m2::PointD const & endPosition, +PositionInterpolator::PositionInterpolator(m2::PointD const & startPosition, m2::PointD const & endPosition, ScreenBase const & convertor) : PositionInterpolator(0.0 /* delay */, startPosition, endPosition, convertor) {} -PositionInterpolator::PositionInterpolator(double delay, m2::PointD const & startPosition, - m2::PointD const & endPosition, +PositionInterpolator::PositionInterpolator(double delay, + m2::PointD const & startPosition, m2::PointD const & endPosition, ScreenBase const & convertor) : Interpolator(PositionInterpolator::GetMoveDuration(startPosition, endPosition, convertor), delay) , m_startPosition(startPosition) @@ -114,52 +112,52 @@ PositionInterpolator::PositionInterpolator(double delay, m2::PointD const & star SetActive(m_startPosition != m_endPosition); } -PositionInterpolator::PositionInterpolator(m2::PointD const & startPxPosition, - m2::PointD const & endPxPosition, - m2::RectD const & pixelRect) - : PositionInterpolator(0.0 /* delay */, startPxPosition, endPxPosition, pixelRect) +PositionInterpolator::PositionInterpolator(m2::PointD const & startPosition, m2::PointD const & endPosition, + m2::RectD const & viewportRect, double scale) + : PositionInterpolator(0.0 /* delay */, startPosition, endPosition, viewportRect, scale) {} -PositionInterpolator::PositionInterpolator(double delay, m2::PointD const & startPxPosition, - m2::PointD const & endPxPosition, m2::RectD const & pixelRect) - : Interpolator(PositionInterpolator::GetPixelMoveDuration(startPxPosition, endPxPosition, pixelRect), delay) - , m_startPosition(startPxPosition) - , m_endPosition(endPxPosition) - , m_position(startPxPosition) +PositionInterpolator::PositionInterpolator(double delay, + m2::PointD const & startPosition, m2::PointD const & endPosition, + m2::RectD const & viewportRect, double scale) + : Interpolator(PositionInterpolator::GetMoveDuration(startPosition, endPosition, viewportRect, scale), delay) + , m_startPosition(startPosition) + , m_endPosition(endPosition) + , m_position(startPosition) { SetActive(m_startPosition != m_endPosition); } +//static +double PositionInterpolator::GetMoveDuration(m2::PointD const & startPosition, m2::PointD const & endPosition, + m2::RectD const & viewportRect, double scale) +{ + double const kMinMoveDuration = 0.2; + double const kMinSpeedScalar = 0.2; + double const kMaxSpeedScalar = 7.0; + double const kEps = 1e-5; + + double const pixelLength = endPosition.Length(startPosition) / scale; + if (pixelLength < kEps) + return 0.0; + + double const minSize = min(viewportRect.SizeX(), viewportRect.SizeY()); + if (pixelLength < kMinSpeedScalar * minSize) + return kMinMoveDuration; + + double const pixelSpeed = kMaxSpeedScalar * minSize; + return CalcAnimSpeedDuration(pixelLength, pixelSpeed); + +} + //static double PositionInterpolator::GetMoveDuration(m2::PointD const & startPosition, m2::PointD const & endPosition, ScreenBase const & convertor) { - return GetPixelMoveDuration(convertor.GtoP(startPosition), - convertor.GtoP(endPosition), - convertor.PixelRect()); + return GetMoveDuration(startPosition, endPosition, convertor.PixelRectIn3d(), convertor.GetScale()); } -double PositionInterpolator::GetPixelMoveDuration(m2::PointD const & startPosition, - m2::PointD const & endPosition, - m2::RectD const & pixelRect) -{ - double const kMinMoveDuration = 0.2; - double const kMinSpeedScalar = 0.2; - double const kMaxSpeedScalar = 7.0; - double const kEps = 1e-5; - - double const pixelLength = endPosition.Length(startPosition); - if (pixelLength < kEps) - return 0.0; - - double const minSize = min(pixelRect.SizeX(), pixelRect.SizeY()); - if (pixelLength < kMinSpeedScalar * minSize) - return kMinMoveDuration; - - double const pixelSpeed = kMaxSpeedScalar * minSize; - return CalcAnimSpeedDuration(pixelLength, pixelSpeed); -} void PositionInterpolator::Advance(double elapsedSeconds) { diff --git a/drape_frontend/animation/interpolators.hpp b/drape_frontend/animation/interpolators.hpp index 501cda1017..66892f2c4e 100644 --- a/drape_frontend/animation/interpolators.hpp +++ b/drape_frontend/animation/interpolators.hpp @@ -40,25 +40,27 @@ class PositionInterpolator: public Interpolator public: PositionInterpolator(); PositionInterpolator(double duration, double delay, - m2::PointD const & startPosition, - m2::PointD const & endPosition); - PositionInterpolator(m2::PointD const & startPosition, - m2::PointD const & endPosition, - ScreenBase const & convertor); - PositionInterpolator(double delay, m2::PointD const & startPosition, - m2::PointD const & endPosition, - ScreenBase const & convertor); - PositionInterpolator(m2::PointD const & startPxPosition, - m2::PointD const & endPxPosition, - m2::RectD const & pixelRect); - PositionInterpolator(double delay, m2::PointD const & startPxPosition, - m2::PointD const & endPxPosition, - m2::RectD const & pixelRect); + m2::PointD const & startPosition, m2::PointD const & endPosition); - static double GetMoveDuration(m2::PointD const & startPosition, - m2::PointD const & endPosition, ScreenBase const & convertor); - static double GetPixelMoveDuration(m2::PointD const & startPosition, - m2::PointD const & endPosition, m2::RectD const & pixelRect); + PositionInterpolator(m2::PointD const & startPosition, m2::PointD const & endPosition, + ScreenBase const & convertor); + + PositionInterpolator(double delay, + m2::PointD const & startPosition, m2::PointD const & endPosition, + ScreenBase const & convertor); + + PositionInterpolator(m2::PointD const & startPosition, m2::PointD const & endPosition, + m2::RectD const & viewportRect, double scale); + + PositionInterpolator(double delay, + m2::PointD const & startPosition, m2::PointD const & endPosition, + m2::RectD const & viewportRect, double scale); + + static double GetMoveDuration(m2::PointD const & startPosition, m2::PointD const & endPosition, + m2::RectD const & viewportRect, double scale); + + static double GetMoveDuration(m2::PointD const & startPosition, m2::PointD const & endPosition, + ScreenBase const & convertor); // Interpolator overrides: void Advance(double elapsedSeconds) override; @@ -89,6 +91,7 @@ public: void Finish() override; double GetScale() const { return m_scale; } + double GetStartScale() const { return m_startScale; } double GetTargetScale() const { return m_endScale; } private: @@ -114,6 +117,7 @@ public: void Finish() override; double GetAngle() const { return m_angle; } + double GetStartAngle() const { return m_startAngle; } double GetTargetAngle() const { return m_endAngle; } private: diff --git a/drape_frontend/animation/linear_animation.cpp b/drape_frontend/animation/linear_animation.cpp index 7ff23dcdb0..048196cfc8 100644 --- a/drape_frontend/animation/linear_animation.cpp +++ b/drape_frontend/animation/linear_animation.cpp @@ -39,6 +39,14 @@ void MapLinearAnimation::SetMove(m2::PointD const & startPos, m2::PointD const & m_properties.insert(Animation::Position); } +void MapLinearAnimation::SetMove(m2::PointD const & startPos, m2::PointD const & endPos, + m2::RectD const & viewportRect, double scale) +{ + m_positionInterpolator = PositionInterpolator(startPos, endPos, viewportRect, scale); + if (m_positionInterpolator.IsActive()) + m_properties.insert(Animation::Position); +} + void MapLinearAnimation::SetRotate(double startAngle, double endAngle) { m_angleInterpolator = AngleInterpolator(startAngle, endAngle); diff --git a/drape_frontend/animation/linear_animation.hpp b/drape_frontend/animation/linear_animation.hpp index 2fadc13e9c..61e3e0ba59 100644 --- a/drape_frontend/animation/linear_animation.hpp +++ b/drape_frontend/animation/linear_animation.hpp @@ -15,6 +15,7 @@ public: MapLinearAnimation(); void SetMove(m2::PointD const & startPos, m2::PointD const & endPos, ScreenBase const & convertor); + void SetMove(m2::PointD const & startPos, m2::PointD const & endPos, m2::RectD const & viewportRect, double scale); void SetRotate(double startAngle, double endAngle); void SetScale(double startScale, double endScale); diff --git a/drape_frontend/screen_animations.cpp b/drape_frontend/screen_animations.cpp index 8a68748a8c..3f8dcb7824 100644 --- a/drape_frontend/screen_animations.cpp +++ b/drape_frontend/screen_animations.cpp @@ -31,7 +31,7 @@ drape_ptr GetPrettyMoveAnimation(ScreenBase const & screen, drape_ptr GetPrettyMoveAnimation(ScreenBase const & screen, double startScale, double endScale, m2::PointD const & startPt, m2::PointD const & endPt) { - double const moveDuration = PositionInterpolator::GetMoveDuration(startPt, endPt, screen); + double const moveDuration = PositionInterpolator::GetMoveDuration(startPt, endPt, screen.PixelRectIn3d(), startScale); double const scaleFactor = moveDuration / kMaxAnimationTimeSec * 2.0; auto sequenceAnim = make_unique_dp(); @@ -56,28 +56,36 @@ drape_ptr GetPrettyMoveAnimation(ScreenBase const & screen, d return sequenceAnim; } -drape_ptr GetPrettyFollowAnimation(ScreenBase const & screen, double startScale, double endScale, - m2::PointD const & startPt, m2::PointD const & userPos, +drape_ptr GetPrettyFollowAnimation(ScreenBase const & startScreen, m2::PointD const & userPos, double targetScale, double targetAngle, m2::PointD const & endPixelPos) { - double const moveDuration = PositionInterpolator::GetMoveDuration(startPt, userPos, screen); - double const scaleFactor = moveDuration / kMaxAnimationTimeSec * 2.0; - auto sequenceAnim = make_unique_dp(); sequenceAnim->SetCustomType(kPrettyFollowAnim); + m2::RectD const viewportRect = startScreen.PixelRectIn3d(); + + ScreenBase tmp = startScreen; + tmp.MatchGandP3d(userPos, viewportRect.Center()); + + double const moveDuration = PositionInterpolator::GetMoveDuration(startScreen.GetOrg(), tmp.GetOrg(), startScreen); + double const scaleFactor = moveDuration / kMaxAnimationTimeSec * 2.0; + + tmp = startScreen; + tmp.SetScale(startScreen.GetScale() * scaleFactor); + auto zoomOutAnim = make_unique_dp(); - zoomOutAnim->SetScale(startScale, startScale * scaleFactor); + zoomOutAnim->SetScale(startScreen.GetScale(), tmp.GetScale()); zoomOutAnim->SetMaxDuration(kMaxAnimationTimeSec * 0.5); - //TODO (in future): Pass fixed duration instead of screen. + tmp.MatchGandP3d(userPos, viewportRect.Center()); + auto moveAnim = make_unique_dp(); - moveAnim->SetMove(startPt, userPos, screen); + moveAnim->SetMove(startScreen.GetOrg(), tmp.GetOrg(), viewportRect, tmp.GetScale()); moveAnim->SetMaxDuration(kMaxAnimationTimeSec); - auto followAnim = make_unique_dp(userPos, startScale * scaleFactor, endScale, - screen.GetAngle(), targetAngle, - screen.PixelRect().Center(), endPixelPos, screen.PixelRect()); + auto followAnim = make_unique_dp(tmp, userPos, endPixelPos, + tmp.GetScale(), targetScale, + tmp.GetAngle(), targetAngle); followAnim->SetMaxDuration(kMaxAnimationTimeSec * 0.5); sequenceAnim->AddAnimation(move(zoomOutAnim)); @@ -91,7 +99,8 @@ drape_ptr GetRectAnimation(ScreenBase const & startScreen, S auto anim = make_unique_dp(); anim->SetRotate(startScreen.GetAngle(), endScreen.GetAngle()); - anim->SetMove(startScreen.GetOrg(), endScreen.GetOrg(), startScreen); + anim->SetMove(startScreen.GetOrg(), endScreen.GetOrg(), + startScreen.PixelRectIn3d(), (startScreen.GetScale() + endScreen.GetScale()) / 2.0); anim->SetScale(startScreen.GetScale(), endScreen.GetScale()); anim->SetMaxScaleDuration(kMaxAnimationTimeSec); @@ -117,9 +126,8 @@ drape_ptr GetSetRectAnimation(ScreenBase const & screen, drape_ptr GetFollowAnimation(ScreenBase const & startScreen, m2::PointD const & userPos, double targetScale, double targetAngle, m2::PointD const & endPixelPos) { - auto anim = make_unique_dp(userPos, startScreen.GetScale(), targetScale, - startScreen.GetAngle(), targetAngle, - startScreen.PtoP3d(startScreen.GtoP(userPos)), endPixelPos, startScreen.PixelRect()); + auto anim = make_unique_dp(startScreen, userPos, endPixelPos, startScreen.GetScale(), targetScale, + startScreen.GetAngle(), targetAngle); anim->SetMaxDuration(kMaxAnimationTimeSec); return anim; diff --git a/drape_frontend/screen_animations.hpp b/drape_frontend/screen_animations.hpp index 15dfa758da..9ccda398c1 100644 --- a/drape_frontend/screen_animations.hpp +++ b/drape_frontend/screen_animations.hpp @@ -21,9 +21,8 @@ drape_ptr GetPrettyMoveAnimation(ScreenBase const & screen, drape_ptr GetPrettyMoveAnimation(ScreenBase const & screen, double startScale, double endScale, m2::PointD const & startPt, m2::PointD const & endPt); -drape_ptr GetPrettyFollowAnimation(ScreenBase const & screen, double startScale, double endScale, - m2::PointD const & startPt, m2::PointD const & userPos, - double targetAngle, m2::PointD const & endPixelPos); +drape_ptr GetPrettyFollowAnimation(ScreenBase const & startScreen, m2::PointD const & userPos, + double targetScale, double targetAngle, m2::PointD const & endPixelPos); drape_ptr GetRectAnimation(ScreenBase const & startScreen, ScreenBase const & endScreen); drape_ptr GetSetRectAnimation(ScreenBase const & screen, diff --git a/drape_frontend/user_event_stream.cpp b/drape_frontend/user_event_stream.cpp index c7049d8f45..9678e51629 100644 --- a/drape_frontend/user_event_stream.cpp +++ b/drape_frontend/user_event_stream.cpp @@ -493,24 +493,24 @@ bool UserEventStream::InterruptFollowAnimations(bool force) bool UserEventStream::SetFollowAndRotate(m2::PointD const & userPos, m2::PointD const & pixelPos, double azimuth, int preferredZoomLevel, bool isAnim) { - // Extract target local rect from current animation or calculate it from preferredZoomLevel - // to preserve final scale. - m2::RectD targetLocalRect; - if (preferredZoomLevel != kDoNotChangeZoom) + ScreenBase const & currentScreen = GetCurrentScreen(); + ScreenBase screen = currentScreen; + + if (preferredZoomLevel == kDoNotChangeZoom) { - ScreenBase newScreen = GetCurrentScreen(); - double const scale3d = newScreen.GetScale3d(); - m2::RectD r = df::GetRectForDrawScale(preferredZoomLevel, m2::PointD::Zero()); - r.Scale(scale3d); - CheckMinGlobalRect(r, scale3d); - CheckMinMaxVisibleScale(r, preferredZoomLevel, scale3d); - newScreen.SetFromRect(m2::AnyRectD(r)); - targetLocalRect = newScreen.GlobalRect().GetLocalRect(); + GetTargetScreen(screen); + screen.SetAngle(-azimuth); } else { - targetLocalRect = GetTargetRect().GetLocalRect(); + screen.SetFromParams(userPos, -azimuth, GetScale(preferredZoomLevel)); } + screen.MatchGandP3d(userPos, pixelPos); + + ASSERT_GREATER_OR_EQUAL(zoom, scales::GetUpperWorldScale(), ()); + ASSERT_LESS_OR_EQUAL(zoom, scales::GetUpperStyleScale(), ()); + + ShrinkAndScaleInto(screen, df::GetWorldRect()); if (isAnim) { @@ -525,26 +525,21 @@ bool UserEventStream::SetFollowAndRotate(m2::PointD const & userPos, m2::PointD }; drape_ptr anim; - - ScreenBase const & screen = m_navigator.Screen(); - double const targetScale = CalculateScale(screen.PixelRect(), targetLocalRect); - m2::PointD const startPt = GetCurrentRect().GlobalCenter(); - bool const changeZoom = preferredZoomLevel != kDoNotChangeZoom; - - double const moveDuration = PositionInterpolator::GetMoveDuration(startPt, userPos, screen); + double const moveDuration = PositionInterpolator::GetMoveDuration(currentScreen.GetOrg(), screen.GetOrg(), + currentScreen.PixelRectIn3d(), + (currentScreen.GetScale() + screen.GetScale()) / 2.0); if (moveDuration > kMaxAnimationTimeSec) { // Run pretty move animation if we are far from userPos. - double const startScale = CalculateScale(screen.PixelRect(), GetCurrentRect().GetLocalRect()); - anim = GetPrettyFollowAnimation(screen, startScale, targetScale, startPt, userPos, -azimuth, pixelPos); + anim = GetPrettyFollowAnimation(currentScreen, userPos, screen.GetScale(), -azimuth, pixelPos); } else { // Run follow-and-rotate animation. - anim = GetFollowAnimation(screen, userPos, targetScale, -azimuth, pixelPos); + anim = GetFollowAnimation(currentScreen, userPos, screen.GetScale(), -azimuth, pixelPos); } - if (changeZoom) + if (preferredZoomLevel != kDoNotChangeZoom) { anim->SetCouldBeInterrupted(false); anim->SetCouldBeBlended(false); @@ -556,8 +551,7 @@ bool UserEventStream::SetFollowAndRotate(m2::PointD const & userPos, m2::PointD } ResetMapPlaneAnimations(); - m2::PointD const center = MapFollowAnimation::CalculateCenter(m_navigator.Screen(), userPos, pixelPos, -azimuth); - m_navigator.SetFromRect(m2::AnyRectD(center, -azimuth, targetLocalRect)); + m_navigator.SetScreen(screen); return true; } From 67fafc616e350f4e680f85fc423145f837b3c231 Mon Sep 17 00:00:00 2001 From: Daria Volvenkova Date: Mon, 4 Jul 2016 15:48:27 +0300 Subject: [PATCH 15/18] Set rect event processing fixed. --- drape_frontend/navigator.cpp | 44 +++++--------------------- drape_frontend/navigator.hpp | 6 ++-- drape_frontend/user_event_stream.cpp | 46 +++++----------------------- geometry/screenbase.cpp | 6 ---- geometry/screenbase.hpp | 1 - 5 files changed, 18 insertions(+), 85 deletions(-) diff --git a/drape_frontend/navigator.cpp b/drape_frontend/navigator.cpp index ecaefccea2..3c01342cf1 100644 --- a/drape_frontend/navigator.cpp +++ b/drape_frontend/navigator.cpp @@ -26,30 +26,17 @@ Navigator::Navigator() { } -void Navigator::SetFromRect2(m2::AnyRectD const & r) +void Navigator::SetFromScreen(ScreenBase const & screen) { - ScreenBase tmp = m_Screen; - - m2::RectD const & worldR = df::GetWorldRect(); - - tmp.SetFromRect2d(r); - tmp = ScaleInto(tmp, worldR); - - m_Screen = tmp; - - if (!m_InAction) - m_StartScreen = tmp; + VisualParams const & p = VisualParams::Instance(); + SetFromScreen(screen, p.GetTileSize(), p.GetVisualScale()); } -void Navigator::SetScreen(ScreenBase const & screen) +void Navigator::SetFromScreen(ScreenBase const & screen, uint32_t tileSize, double visualScale) { - m2::RectD const & worldR = df::GetWorldRect(); - ScreenBase tmp = screen; - tmp = ScaleInto(tmp, worldR); + ScreenBase tmp = ScaleInto(screen, df::GetWorldRect()); - VisualParams const & p = VisualParams::Instance(); - - if (!CheckMaxScale(tmp, p.GetTileSize(), p.GetVisualScale())) + if (!CheckMaxScale(tmp, tileSize, visualScale)) { int const scale = scales::GetUpperStyleScale() - 1; m2::RectD newRect = df::GetRectForDrawScale(scale, screen.GetOrg()); @@ -75,26 +62,9 @@ void Navigator::SetFromRect(m2::AnyRectD const & r) void Navigator::SetFromRect(m2::AnyRectD const & r, uint32_t tileSize, double visualScale) { - m2::RectD const & worldR = df::GetWorldRect(); - ScreenBase tmp = m_Screen; - tmp.SetFromRect(r); - tmp = ScaleInto(tmp, worldR); - if (!CheckMaxScale(tmp, tileSize, visualScale)) - { - int const scale = scales::GetUpperStyleScale() - 1; - m2::RectD newRect = df::GetRectForDrawScale(scale, r.Center()); - newRect.Scale(m_Screen.GetScale3d()); - CheckMinMaxVisibleScale(newRect, scale, m_Screen.GetScale3d()); - tmp = m_Screen; - tmp.SetFromRect(m2::AnyRectD(newRect)); - ASSERT(CheckMaxScale(tmp, tileSize, visualScale), ()); - } - m_Screen = tmp; - - if (!m_InAction) - m_StartScreen = tmp; + SetFromScreen(tmp, tileSize, visualScale); } void Navigator::CenterViewport(m2::PointD const & p) diff --git a/drape_frontend/navigator.hpp b/drape_frontend/navigator.hpp index 25d9ea0fbb..0155a4dd9f 100644 --- a/drape_frontend/navigator.hpp +++ b/drape_frontend/navigator.hpp @@ -18,11 +18,11 @@ class Navigator public: Navigator(); - void SetScreen(ScreenBase const & screen); void SetFromRect(m2::AnyRectD const & r); - void SetFromRect2(m2::AnyRectD const & r); - void CenterViewport(m2::PointD const & p); void SetFromRect(m2::AnyRectD const & r, uint32_t tileSize, double visualScale); + void SetFromScreen(ScreenBase const & screen); + void SetFromScreen(ScreenBase const & screen, uint32_t tileSize, double visualScale); + void CenterViewport(m2::PointD const & p); void OnSize(int w, int h); diff --git a/drape_frontend/user_event_stream.cpp b/drape_frontend/user_event_stream.cpp index 9678e51629..2e983e78f4 100644 --- a/drape_frontend/user_event_stream.cpp +++ b/drape_frontend/user_event_stream.cpp @@ -287,7 +287,7 @@ void UserEventStream::ApplyAnimations() { ScreenBase screen; if (m_animationSystem.GetScreen(GetCurrentScreen(), screen)) - m_navigator.SetScreen(screen); + m_navigator.SetFromScreen(screen); Animation::SwitchPerspectiveParams switchPerspective; if (m_animationSystem.SwitchPerspective(switchPerspective)) @@ -366,9 +366,7 @@ bool UserEventStream::SetScale(m2::PointD const & pxScaleCenter, double factor, bool UserEventStream::SetCenter(m2::PointD const & center, int zoom, bool isAnim) { - ScreenBase const & currentScreen = GetCurrentScreen(); - - ScreenBase screen = currentScreen; + ScreenBase screen = GetCurrentScreen(); if (zoom == kDoNotChangeZoom) { GetTargetScreen(screen); @@ -427,45 +425,17 @@ bool UserEventStream::SetScreen(ScreenBase const & endScreen, bool isAnim) } ResetMapPlaneAnimations(); - m_navigator.SetScreen(endScreen); + m_navigator.SetFromScreen(endScreen); return true; } bool UserEventStream::SetRect(m2::AnyRectD const & rect, bool isAnim) { - //isAnim = false; - if (isAnim) - { - auto onStartHandler = [this](ref_ptr animation) - { - if (m_listener) - m_listener->OnAnimationStarted(animation); - }; + ScreenBase tmp = GetCurrentScreen(); + tmp.SetFromRects(rect, tmp.PixelRectIn3d()); + tmp.MatchGandP3d(rect.GlobalCenter(), tmp.PixelRectIn3d().Center()); - m2::AnyRectD const startRect = GetCurrentRect(); - ScreenBase const & screen = GetCurrentScreen(); - - drape_ptr anim = GetSetRectAnimation(screen, startRect, rect); - if (!df::IsAnimationAllowed(anim->GetDuration(), screen)) - { - anim.reset(); - double const moveDuration = PositionInterpolator::GetMoveDuration(startRect.GlobalCenter(), - rect.GlobalCenter(), screen); - if (moveDuration > kMaxAnimationTimeSec) - anim = GetPrettyMoveAnimation(screen, startRect, rect); - } - - if (anim != nullptr) - { - anim->SetOnStartAction(onStartHandler); - m_animationSystem.CombineAnimation(move(anim)); - return false; - } - } - - ResetMapPlaneAnimations(); - m_navigator.SetFromRect2(rect); - return true; + return SetScreen(tmp, isAnim); } bool UserEventStream::InterruptFollowAnimations(bool force) @@ -551,7 +521,7 @@ bool UserEventStream::SetFollowAndRotate(m2::PointD const & userPos, m2::PointD } ResetMapPlaneAnimations(); - m_navigator.SetScreen(screen); + m_navigator.SetFromScreen(screen); return true; } diff --git a/geometry/screenbase.cpp b/geometry/screenbase.cpp index 93693b167b..f28eaf412c 100644 --- a/geometry/screenbase.cpp +++ b/geometry/screenbase.cpp @@ -143,12 +143,6 @@ void ScreenBase::SetFromRect(m2::AnyRectD const & glbRect) SetFromRects(glbRect, m_PixelRect); } -void ScreenBase::SetFromRect2d(m2::AnyRectD const & glbRect) -{ - SetFromRects(glbRect, PixelRectIn3d()); - MatchGandP3d(glbRect.GlobalCenter(), PixelRectIn3d().Center()); -} - void ScreenBase::SetFromParams(m2::PointD const & org, double angle, double scale) { m_Scale = scale; diff --git a/geometry/screenbase.hpp b/geometry/screenbase.hpp index c3cf5eefe2..1fc667bbf9 100644 --- a/geometry/screenbase.hpp +++ b/geometry/screenbase.hpp @@ -65,7 +65,6 @@ public: m2::PointD const & org, double scale, double angle); void SetFromRect(m2::AnyRectD const & rect); - void SetFromRect2d(m2::AnyRectD const & glbRect); void SetFromParams(m2::PointD const & org, double angle, double scale); void SetFromRects(m2::AnyRectD const & glbRect, m2::RectD const & pxRect); From 502db7d3e167e30571b4e3abafe9f6403d3cb569 Mon Sep 17 00:00:00 2001 From: Daria Volvenkova Date: Mon, 4 Jul 2016 16:19:27 +0300 Subject: [PATCH 16/18] Perspective switching removed. --- .../user_event_stream_tests.cpp | 1 - drape_frontend/frontend_renderer.cpp | 21 ---------------- drape_frontend/frontend_renderer.hpp | 2 -- drape_frontend/user_event_stream.cpp | 25 +------------------ drape_frontend/user_event_stream.hpp | 15 +---------- 5 files changed, 2 insertions(+), 62 deletions(-) diff --git a/drape_frontend/drape_frontend_tests/user_event_stream_tests.cpp b/drape_frontend/drape_frontend_tests/user_event_stream_tests.cpp index 8ce2d76bab..4858841d20 100644 --- a/drape_frontend/drape_frontend_tests/user_event_stream_tests.cpp +++ b/drape_frontend/drape_frontend_tests/user_event_stream_tests.cpp @@ -37,7 +37,6 @@ public: void CorrectGlobalScalePoint(m2::PointD & pt) const override {} void OnScaleEnded() override {} void OnAnimationStarted(ref_ptr /* anim */) override {} - void OnPerspectiveSwitchRejected() override {} void OnTouchMapAction() override {} void OnAnimatedScaleEnded() override {} diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index a74d31f9c3..bac2bb33a8 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -1279,20 +1279,6 @@ void FrontendRenderer::CheckIsometryMinScale(ScreenBase const & screen) } } -void FrontendRenderer::CheckPerspectiveMinScale() -{ - if (!m_enablePerspectiveInNavigation || m_userEventStream.IsInPerspectiveAnimation()) - return; - - bool const switchTo2d = !IsScaleAllowableIn3d(m_currentZoomLevel); - if ((!switchTo2d && !m_perspectiveDiscarded) || - (switchTo2d && !m_userEventStream.GetCurrentScreen().isPerspective())) - return; - - m_perspectiveDiscarded = switchTo2d; - AddUserEvent(SwitchViewModeEvent(switchTo2d)); -} - void FrontendRenderer::ResolveZoomLevel(ScreenBase const & screen) { int const prevZoomLevel = m_currentZoomLevel; @@ -1302,7 +1288,6 @@ void FrontendRenderer::ResolveZoomLevel(ScreenBase const & screen) UpdateCanBeDeletedStatus(); CheckIsometryMinScale(screen); - CheckPerspectiveMinScale(); UpdateDisplacementEnabled(); } @@ -1430,12 +1415,6 @@ void FrontendRenderer::OnAnimationStarted(ref_ptr anim) m_myPositionController->AnimationStarted(anim); } -void FrontendRenderer::OnPerspectiveSwitchRejected() -{ - if (m_perspectiveDiscarded) - m_perspectiveDiscarded = false; -} - void FrontendRenderer::OnTouchMapAction() { m_myPositionController->ResetRoutingNotFollowTimer(); diff --git a/drape_frontend/frontend_renderer.hpp b/drape_frontend/frontend_renderer.hpp index d4adc101f2..873a774b87 100755 --- a/drape_frontend/frontend_renderer.hpp +++ b/drape_frontend/frontend_renderer.hpp @@ -174,7 +174,6 @@ private: TTilesCollection ResolveTileKeys(ScreenBase const & screen); void ResolveZoomLevel(ScreenBase const & screen); void UpdateDisplacementEnabled(); - void CheckPerspectiveMinScale(); void CheckIsometryMinScale(ScreenBase const & screen); void DisablePerspective(); @@ -195,7 +194,6 @@ private: void OnScaleEnded() override; void OnAnimatedScaleEnded() override; void OnAnimationStarted(ref_ptr anim) override; - void OnPerspectiveSwitchRejected() override; void OnTouchMapAction() override; class Routine : public threads::IRoutine diff --git a/drape_frontend/user_event_stream.cpp b/drape_frontend/user_event_stream.cpp index 2e983e78f4..21b431f215 100644 --- a/drape_frontend/user_event_stream.cpp +++ b/drape_frontend/user_event_stream.cpp @@ -216,24 +216,9 @@ ScreenBase const & UserEventStream::ProcessEvents(bool & modelViewChanged, bool case UserEvent::EVENT_ENABLE_PERSPECTIVE: SetEnable3dMode(e.m_enable3dMode.m_rotationAngle, e.m_enable3dMode.m_angleFOV, e.m_enable3dMode.m_isAnim, e.m_enable3dMode.m_immediatelyStart); - m_discardedFOV = m_discardedAngle = 0.0; break; case UserEvent::EVENT_DISABLE_PERSPECTIVE: SetDisable3dModeAnimation(); - m_discardedFOV = m_discardedAngle = 0.0; - break; - case UserEvent::EVENT_SWITCH_VIEW_MODE: - if (e.m_switchViewMode.m_to2d) - { - m_discardedFOV = m_navigator.Screen().GetAngleFOV(); - m_discardedAngle = m_navigator.Screen().GetRotationAngle(); - SetDisable3dModeAnimation(); - } - else if (m_discardedFOV > 0.0) - { - SetEnable3dMode(m_discardedAngle, m_discardedFOV, true /* isAnim */, true /* immediatelyStart */); - m_discardedFOV = m_discardedAngle = 0.0; - } break; default: ASSERT(false, ()); @@ -529,8 +514,7 @@ bool UserEventStream::FilterEventWhile3dAnimation(UserEvent::EEventType type) co { return type != UserEvent::EVENT_RESIZE && type != UserEvent::EVENT_SET_RECT && type != UserEvent::EVENT_ENABLE_PERSPECTIVE && - type != UserEvent::EVENT_DISABLE_PERSPECTIVE && - type != UserEvent::EVENT_SWITCH_VIEW_MODE; + type != UserEvent::EVENT_DISABLE_PERSPECTIVE; } void UserEventStream::SetEnable3dMode(double maxRotationAngle, double angleFOV, @@ -568,13 +552,6 @@ void UserEventStream::SetDisable3dModeAnimation() ResetAnimationsBeforeSwitch3D(); InterruptFollowAnimations(true /* force */); - if (m_discardedFOV > 0.0 && IsScaleAllowableIn3d(GetDrawTileScale(GetCurrentScreen()))) - { - m_discardedFOV = m_discardedAngle = 0.0; - m_listener->OnPerspectiveSwitchRejected(); - return; - } - double const startAngle = m_navigator.Screen().GetRotationAngle(); double const endAngle = 0.0; diff --git a/drape_frontend/user_event_stream.hpp b/drape_frontend/user_event_stream.hpp index b8d8133536..aa02aca90d 100644 --- a/drape_frontend/user_event_stream.hpp +++ b/drape_frontend/user_event_stream.hpp @@ -166,13 +166,6 @@ struct DisablePerspectiveEvent DisablePerspectiveEvent() {} }; -struct SwitchViewModeEvent -{ - SwitchViewModeEvent(bool to2d): m_to2d(to2d) {} - - bool m_to2d; -}; - struct RotateEvent { RotateEvent(double targetAzimut) : m_targetAzimut(targetAzimut) {} @@ -201,8 +194,7 @@ struct UserEvent EVENT_ROTATE, EVENT_FOLLOW_AND_ROTATE, EVENT_ENABLE_PERSPECTIVE, - EVENT_DISABLE_PERSPECTIVE, - EVENT_SWITCH_VIEW_MODE + EVENT_DISABLE_PERSPECTIVE }; UserEvent(TouchEvent const & e) : m_type(EVENT_TOUCH) { m_touchEvent = e; } @@ -215,7 +207,6 @@ struct UserEvent UserEvent(FollowAndRotateEvent const & e) : m_type(EVENT_FOLLOW_AND_ROTATE) { m_followAndRotate = e; } UserEvent(EnablePerspectiveEvent const & e) : m_type(EVENT_ENABLE_PERSPECTIVE) { m_enable3dMode = e; } UserEvent(DisablePerspectiveEvent const & e) : m_type(EVENT_DISABLE_PERSPECTIVE) { m_disable3dMode = e; } - UserEvent(SwitchViewModeEvent const & e) : m_type(EVENT_SWITCH_VIEW_MODE) { m_switchViewMode = e; } EEventType m_type; union @@ -230,7 +221,6 @@ struct UserEvent FollowAndRotateEvent m_followAndRotate; EnablePerspectiveEvent m_enable3dMode; DisablePerspectiveEvent m_disable3dMode; - SwitchViewModeEvent m_switchViewMode; }; }; @@ -259,7 +249,6 @@ public: virtual void OnAnimatedScaleEnded() = 0; virtual void OnAnimationStarted(ref_ptr anim) = 0; - virtual void OnPerspectiveSwitchRejected() = 0; virtual void OnTouchMapAction() = 0; }; @@ -388,8 +377,6 @@ private: bool m_perspectiveAnimation = false; unique_ptr m_pendingEvent; - double m_discardedFOV = 0.0; - double m_discardedAngle = 0.0; ref_ptr m_listener; From 7ab8f049ed68092129f96de13940afab01adfbf6 Mon Sep 17 00:00:00 2001 From: Daria Volvenkova Date: Tue, 5 Jul 2016 01:02:00 +0300 Subject: [PATCH 17/18] Perspective animation removed. --- drape_frontend/animation/animation.hpp | 34 +---- .../animation/perspective_animation.cpp | 121 ----------------- .../animation/perspective_animation.hpp | 58 --------- drape_frontend/animation_system.cpp | 30 ----- drape_frontend/animation_system.hpp | 3 - drape_frontend/drape_engine.cpp | 14 +- drape_frontend/drape_engine.hpp | 6 +- drape_frontend/drape_frontend.pro | 2 - drape_frontend/frontend_renderer.cpp | 58 +++------ drape_frontend/frontend_renderer.hpp | 13 +- drape_frontend/message_subclasses.hpp | 28 +--- drape_frontend/navigator.cpp | 5 + drape_frontend/navigator.hpp | 1 + drape_frontend/user_event_stream.cpp | 123 +----------------- drape_frontend/user_event_stream.hpp | 38 ++---- geometry/screenbase.cpp | 11 +- geometry/screenbase.hpp | 3 +- map/framework.cpp | 9 +- 18 files changed, 66 insertions(+), 491 deletions(-) delete mode 100644 drape_frontend/animation/perspective_animation.cpp delete mode 100644 drape_frontend/animation/perspective_animation.hpp diff --git a/drape_frontend/animation/animation.hpp b/drape_frontend/animation/animation.hpp index 57c96764df..3153dcf37b 100644 --- a/drape_frontend/animation/animation.hpp +++ b/drape_frontend/animation/animation.hpp @@ -19,7 +19,6 @@ public: MapLinear, MapScale, MapFollow, - MapPerspective, Arrow, KineticScroll }; @@ -35,28 +34,7 @@ public: { Position, Scale, - Angle, - AnglePerspective, - SwitchPerspective - }; - - struct SwitchPerspectiveParams - { - SwitchPerspectiveParams() = default; - - SwitchPerspectiveParams(bool enable, - double startAngle, double endAngle, - double angleFOV) - : m_enable(enable) - , m_startAngle(startAngle) - , m_endAngle(endAngle) - , m_angleFOV(angleFOV) - {} - - bool m_enable = false; - double m_startAngle = 0.0; - double m_endAngle = 0.0; - double m_angleFOV = 0.0; + Angle }; struct PropertyValue @@ -64,8 +42,7 @@ public: enum Type { ValueD, - ValuePointD, - ValuePerspectiveParams + ValuePointD }; PropertyValue() @@ -81,18 +58,11 @@ public: , m_valuePointD(value) {} - explicit PropertyValue(SwitchPerspectiveParams const & params) - : m_type(ValuePerspectiveParams) - { - m_valuePerspectiveParams = params; - } - Type m_type; union { m2::PointD m_valuePointD; double m_valueD; - SwitchPerspectiveParams m_valuePerspectiveParams; }; }; diff --git a/drape_frontend/animation/perspective_animation.cpp b/drape_frontend/animation/perspective_animation.cpp deleted file mode 100644 index 73feabbaba..0000000000 --- a/drape_frontend/animation/perspective_animation.cpp +++ /dev/null @@ -1,121 +0,0 @@ -#include "perspective_animation.hpp" - -namespace df -{ - -PerspectiveSwitchAnimation::PerspectiveSwitchAnimation(double startAngle, double endAngle, double angleFOV) - : Animation(false /* couldBeInterrupted */, false /* couldBeBlended */) - , m_angleInterpolator(GetRotateDuration(startAngle, endAngle), startAngle, endAngle) - , m_startAngle(startAngle) - , m_endAngle(endAngle) - , m_angleFOV(angleFOV) - , m_isEnablePerspectiveAnim(m_endAngle > 0.0) - , m_needPerspectiveSwitch(false) -{ - m_objects.insert(Animation::MapPlane); - m_properties.insert(Animation::AnglePerspective); - m_properties.insert(Animation::SwitchPerspective); -} - -// static -double PerspectiveSwitchAnimation::GetRotateDuration(double startAngle, double endAngle) -{ - double const kScalar = 0.5; - return kScalar * fabs(endAngle - startAngle) / math::pi4; -} - -Animation::TObjectProperties const & PerspectiveSwitchAnimation::GetProperties(TObject object) const -{ - ASSERT_EQUAL(object, Animation::MapPlane, ()); - return m_properties; -} - -bool PerspectiveSwitchAnimation::HasProperty(TObject object, TProperty property) const -{ - return HasObject(object) && m_properties.find(property) != m_properties.end(); -} - -bool PerspectiveSwitchAnimation::HasTargetProperty(TObject object, TProperty property) const -{ - return HasObject(object) && property == Animation::SwitchPerspective; -} - -void PerspectiveSwitchAnimation::Advance(double elapsedSeconds) -{ - m_angleInterpolator.Advance(elapsedSeconds); -} - -void PerspectiveSwitchAnimation::Finish() -{ - m_angleInterpolator.Finish(); - Animation::Finish(); -} - -void PerspectiveSwitchAnimation::OnStart() -{ - if (m_isEnablePerspectiveAnim) - m_needPerspectiveSwitch = true; - Animation::OnStart(); -} - -void PerspectiveSwitchAnimation::OnFinish() -{ - if (!m_isEnablePerspectiveAnim) - m_needPerspectiveSwitch = true; - Animation::OnFinish(); -} - -void PerspectiveSwitchAnimation::SetMaxDuration(double maxDuration) -{ - m_angleInterpolator.SetMaxDuration(maxDuration); -} - -double PerspectiveSwitchAnimation::GetDuration() const -{ - return m_angleInterpolator.GetDuration(); -} - -bool PerspectiveSwitchAnimation::IsFinished() const -{ - return m_angleInterpolator.IsFinished(); -} - -bool PerspectiveSwitchAnimation::GetTargetProperty(TObject object, TProperty property, PropertyValue & value) const -{ - ASSERT_EQUAL(object, Animation::MapPlane, ()); - - if (property == Animation::SwitchPerspective) - { - value = PropertyValue(SwitchPerspectiveParams(m_isEnablePerspectiveAnim, m_endAngle, m_endAngle, m_angleFOV)); - return true; - } - - ASSERT(false, ("Wrong property:", property)); - return false; -} - -bool PerspectiveSwitchAnimation::GetProperty(TObject object, TProperty property, PropertyValue & value) const -{ - ASSERT_EQUAL(object, Animation::MapPlane, ()); - - switch (property) - { - case Animation::AnglePerspective: - value = PropertyValue(m_angleInterpolator.GetAngle()); - return true; - case Animation::SwitchPerspective: - if (m_needPerspectiveSwitch) - { - m_needPerspectiveSwitch = false; - value = PropertyValue(SwitchPerspectiveParams(m_isEnablePerspectiveAnim, m_startAngle, m_endAngle, m_angleFOV)); - return true; - } - return false; - default: - ASSERT(false, ("Wrong property:", property)); - } - - return false; -} - -} // namespace df diff --git a/drape_frontend/animation/perspective_animation.hpp b/drape_frontend/animation/perspective_animation.hpp deleted file mode 100644 index 00671a450d..0000000000 --- a/drape_frontend/animation/perspective_animation.hpp +++ /dev/null @@ -1,58 +0,0 @@ -#pragma once - -#include "animation.hpp" -#include "interpolators.hpp" - -namespace df -{ - -class PerspectiveSwitchAnimation : public Animation -{ -public: - PerspectiveSwitchAnimation(double startAngle, double endAngle, double angleFOV); - - static double GetRotateDuration(double startAngle, double endAngle); - - Animation::Type GetType() const override { return Animation::MapPerspective; } - - TAnimObjects const & GetObjects() const override - { - return m_objects; - } - - bool HasObject(TObject object) const override - { - return m_objects.find(object) != m_objects.end(); - } - - TObjectProperties const & GetProperties(TObject object) const override; - bool HasProperty(TObject object, TProperty property) const override; - bool HasTargetProperty(TObject object, TProperty property) const override; - - void Advance(double elapsedSeconds) override; - void Finish() override; - - void OnStart() override; - void OnFinish() override; - - void SetMaxDuration(double maxDuration) override; - double GetDuration() const override; - bool IsFinished() const override; - - bool GetProperty(TObject object, TProperty property, PropertyValue & value) const override; - bool GetTargetProperty(TObject object, TProperty property, PropertyValue & value) const override; - -private: - AngleInterpolator m_angleInterpolator; - double m_startAngle; - double m_endAngle; - double m_angleFOV; - - bool m_isEnablePerspectiveAnim; - mutable bool m_needPerspectiveSwitch; - TAnimObjects m_objects; - TObjectProperties m_properties; -}; - -} // namespace df - diff --git a/drape_frontend/animation_system.cpp b/drape_frontend/animation_system.cpp index 76d113ecdf..fd8e6b039b 100644 --- a/drape_frontend/animation_system.cpp +++ b/drape_frontend/animation_system.cpp @@ -18,14 +18,6 @@ public: void Blend(Animation::PropertyValue const & value) { - // Now perspective parameters can't be blended. - if (value.m_type == Animation::PropertyValue::ValuePerspectiveParams) - { - m_value = value; - m_counter = 1; - return; - } - if (m_counter != 0) { // New value type resets current blended value. @@ -116,28 +108,6 @@ bool AnimationSystem::GetScreen(ScreenBase const & currentScreen, TGetPropertyFn return true; } -bool AnimationSystem::GetPerspectiveAngle(double & angle) -{ - Animation::PropertyValue value; - if (GetProperty(Animation::MapPlane, Animation::AnglePerspective, value)) - { - angle = value.m_valueD; - return true; - } - return false; -} - -bool AnimationSystem::SwitchPerspective(Animation::SwitchPerspectiveParams & params) -{ - Animation::PropertyValue value; - if (GetProperty(Animation::MapPlane, Animation::SwitchPerspective, value)) - { - params = value.m_valuePerspectiveParams; - return true; - } - return false; -} - bool AnimationSystem::GetArrowPosition(m2::PointD & position) { Animation::PropertyValue value; diff --git a/drape_frontend/animation_system.hpp b/drape_frontend/animation_system.hpp index c989da99f2..d92982d6ed 100644 --- a/drape_frontend/animation_system.hpp +++ b/drape_frontend/animation_system.hpp @@ -23,9 +23,6 @@ public: bool GetScreen(ScreenBase const & currentScreen, ScreenBase & screen); void GetTargetScreen(ScreenBase const & currentScreen, ScreenBase & screen); - bool SwitchPerspective(Animation::SwitchPerspectiveParams & params); - bool GetPerspectiveAngle(double & angle); - bool GetArrowPosition(m2::PointD & position); bool GetArrowAngle(double & angle); diff --git a/drape_frontend/drape_engine.cpp b/drape_frontend/drape_engine.cpp index d45db5ef08..8ad2631e88 100644 --- a/drape_frontend/drape_engine.cpp +++ b/drape_frontend/drape_engine.cpp @@ -265,11 +265,10 @@ void DrapeEngine::StopLocationFollow() MessagePriority::High); } -void DrapeEngine::FollowRoute(int preferredZoomLevel, int preferredZoomLevel3d, double rotationAngle, double angleFOV) +void DrapeEngine::FollowRoute(int preferredZoomLevel, int preferredZoomLevel3d) { m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, - make_unique_dp(preferredZoomLevel, preferredZoomLevel3d, - rotationAngle, angleFOV), + make_unique_dp(preferredZoomLevel, preferredZoomLevel3d), MessagePriority::High); } @@ -380,22 +379,21 @@ void DrapeEngine::SetWidgetLayout(gui::TWidgetsLayoutInfo && info) MessagePriority::Normal); } -void DrapeEngine::Allow3dMode(bool allowPerspectiveInNavigation, bool allow3dBuildings, double rotationAngle, double angleFOV) +void DrapeEngine::Allow3dMode(bool allowPerspectiveInNavigation, bool allow3dBuildings) { m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, make_unique_dp(allow3dBuildings), MessagePriority::Normal); m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, - make_unique_dp(allowPerspectiveInNavigation, allow3dBuildings, - rotationAngle, angleFOV), + make_unique_dp(allowPerspectiveInNavigation, allow3dBuildings), MessagePriority::Normal); } -void DrapeEngine::EnablePerspective(double rotationAngle, double angleFOV) +void DrapeEngine::EnablePerspective() { m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, - make_unique_dp(rotationAngle, angleFOV), + make_unique_dp(), MessagePriority::Normal); } diff --git a/drape_frontend/drape_engine.hpp b/drape_frontend/drape_engine.hpp index 421509a1ea..b48cdb9d2d 100644 --- a/drape_frontend/drape_engine.hpp +++ b/drape_frontend/drape_engine.hpp @@ -124,14 +124,14 @@ public: void AddRoute(m2::PolylineD const & routePolyline, vector const & turns, df::ColorConstant color, df::RoutePattern pattern = df::RoutePattern()); void RemoveRoute(bool deactivateFollowing); - void FollowRoute(int preferredZoomLevel, int preferredZoomLevel3d, double rotationAngle, double angleFOV); + void FollowRoute(int preferredZoomLevel, int preferredZoomLevel3d); void DeactivateRouteFollowing(); void SetRoutePoint(m2::PointD const & position, bool isStart, bool isValid); void SetWidgetLayout(gui::TWidgetsLayoutInfo && info); - void Allow3dMode(bool allowPerspectiveInNavigation, bool allow3dBuildings, double rotationAngle, double angleFOV); - void EnablePerspective(double rotationAngle, double angleFOV); + void Allow3dMode(bool allowPerspectiveInNavigation, bool allow3dBuildings); + void EnablePerspective(); void UpdateGpsTrackPoints(vector && toAdd, vector && toRemove); void ClearGpsTrackPoints(); diff --git a/drape_frontend/drape_frontend.pro b/drape_frontend/drape_frontend.pro index 246a71d272..514f82d1ab 100755 --- a/drape_frontend/drape_frontend.pro +++ b/drape_frontend/drape_frontend.pro @@ -23,7 +23,6 @@ SOURCES += \ animation/scale_animation.cpp \ animation/sequence_animation.cpp \ animation/parallel_animation.cpp \ - animation/perspective_animation.cpp \ animation/opacity_animation.cpp \ animation/show_hide_animation.cpp \ gui/choose_position_mark.cpp \ @@ -116,7 +115,6 @@ HEADERS += \ animation/scale_animation.hpp \ animation/sequence_animation.hpp \ animation/parallel_animation.hpp \ - animation/perspective_animation.hpp \ animation/opacity_animation.hpp \ animation/show_hide_animation.hpp \ animation/value_mapping.hpp \ diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index bac2bb33a8..560fe7a4b6 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -484,8 +484,7 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) if (m_pendingFollowRoute != nullptr) { - FollowRoute(m_pendingFollowRoute->m_preferredZoomLevel, m_pendingFollowRoute->m_preferredZoomLevelIn3d, - m_pendingFollowRoute->m_rotationAngle, m_pendingFollowRoute->m_angleFOV); + FollowRoute(m_pendingFollowRoute->m_preferredZoomLevel, m_pendingFollowRoute->m_preferredZoomLevelIn3d); m_pendingFollowRoute.reset(); } break; @@ -522,13 +521,11 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) if (m_routeRenderer->GetRouteData() == nullptr) { m_pendingFollowRoute.reset( - new FollowRouteData(msg->GetPreferredZoomLevel(), msg->GetPreferredZoomLevelIn3d(), - msg->GetRotationAngle(), msg->GetAngleFOV())); + new FollowRouteData(msg->GetPreferredZoomLevel(), msg->GetPreferredZoomLevelIn3d())); break; } - FollowRoute(msg->GetPreferredZoomLevel(), msg->GetPreferredZoomLevelIn3d(), - msg->GetRotationAngle(), msg->GetAngleFOV()); + FollowRoute(msg->GetPreferredZoomLevel(), msg->GetPreferredZoomLevelIn3d()); break; } @@ -613,9 +610,7 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) case Message::EnablePerspective: { - ref_ptr const msg = message; - AddUserEvent(EnablePerspectiveEvent(msg->GetRotationAngle(), msg->GetAngleFOV(), - false /* animated */, true /* immediately start */)); + AddUserEvent(SetAutoPerspectiveEvent(true /* isAutoPerspective */)); break; } @@ -628,11 +623,7 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) if (m_enablePerspectiveInNavigation == msg->AllowPerspective() && m_enablePerspectiveInNavigation != screen.isPerspective()) { - if (m_enablePerspectiveInNavigation) - AddUserEvent(EnablePerspectiveEvent(msg->GetRotationAngle(), msg->GetAngleFOV(), - false /* animated */, true /* immediately start */)); - else - AddUserEvent(DisablePerspectiveEvent()); + AddUserEvent(SetAutoPerspectiveEvent(m_enablePerspectiveInNavigation)); } #endif @@ -648,15 +639,7 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) m_enablePerspectiveInNavigation = msg->AllowPerspective(); if (m_myPositionController->IsInRouting()) { - if (m_enablePerspectiveInNavigation && !screen.isPerspective() && !m_perspectiveDiscarded) - { - AddUserEvent(EnablePerspectiveEvent(msg->GetRotationAngle(), msg->GetAngleFOV(), - true /* animated */, true /* immediately start */)); - } - else if (!m_enablePerspectiveInNavigation && (screen.isPerspective() || m_perspectiveDiscarded)) - { - DisablePerspective(); - } + AddUserEvent(SetAutoPerspectiveEvent(m_enablePerspectiveInNavigation)); } } break; @@ -750,18 +733,14 @@ unique_ptr FrontendRenderer::CreateRoutine() return make_unique(*this); } -void FrontendRenderer::FollowRoute(int preferredZoomLevel, int preferredZoomLevelIn3d, - double rotationAngle, double angleFOV) +void FrontendRenderer::FollowRoute(int preferredZoomLevel, int preferredZoomLevelIn3d) { m_myPositionController->ActivateRouting(!m_enablePerspectiveInNavigation ? preferredZoomLevel : preferredZoomLevelIn3d); if (m_enablePerspectiveInNavigation) - { - bool immediatelyStart = !m_myPositionController->IsRotationAvailable(); - AddUserEvent(EnablePerspectiveEvent(rotationAngle, angleFOV, true /* animated */, immediatelyStart)); - } + AddUserEvent(SetAutoPerspectiveEvent(true /* isAutoPerspective */)); m_overlayTree->SetFollowingMode(true); } @@ -1226,10 +1205,17 @@ void FrontendRenderer::RefreshModelView(ScreenBase const & screen) m_generalUniforms.SetMatrix4x4Value("modelView", mv.m_data); - // TODO: Calculate exact value of zScale - double const averageScale3d = 3.0; - float const zScale = 2.0f / (screen.PixelRectIn3d().SizeY() * averageScale3d * screen.GetScale()); - //float const zScale = 2.0f / (screen.GetHeight() * screen.GetScale()); + float zScale; + if (screen.isPerspective()) + { + // TODO: Calculate exact value of zScale + double const averageScale3d = 3.0; + zScale = 2.0f / (screen.PixelRectIn3d().SizeY() * averageScale3d * screen.GetScale()); + } + else + { + zScale = 2.0f / (screen.GetHeight() * screen.GetScale()); + } m_generalUniforms.SetFloatValue("zScale", zScale); } @@ -1264,8 +1250,7 @@ void FrontendRenderer::RefreshBgColor() void FrontendRenderer::DisablePerspective() { - m_perspectiveDiscarded = false; - AddUserEvent(DisablePerspectiveEvent()); + AddUserEvent(SetAutoPerspectiveEvent(false /* isAutoPerspective */)); } void FrontendRenderer::CheckIsometryMinScale(ScreenBase const & screen) @@ -1620,8 +1605,7 @@ void FrontendRenderer::PositionChanged(m2::PointD const & position) void FrontendRenderer::ChangeModelView(m2::PointD const & center, int zoomLevel) { - AddUserEvent(FollowAndRotateEvent(center, m_userEventStream.GetCurrentScreen().PixelRectIn3d().Center(), -m_userEventStream.GetCurrentScreen().GetAngle(), zoomLevel, true)); - //AddUserEvent(SetCenterEvent(center, zoomLevel, true)); + AddUserEvent(SetCenterEvent(center, zoomLevel, true)); } void FrontendRenderer::ChangeModelView(double azimuth) diff --git a/drape_frontend/frontend_renderer.hpp b/drape_frontend/frontend_renderer.hpp index 873a774b87..5f7459c7bb 100755 --- a/drape_frontend/frontend_renderer.hpp +++ b/drape_frontend/frontend_renderer.hpp @@ -221,8 +221,7 @@ private: using TRenderGroupRemovePredicate = function const &)>; void RemoveRenderGroupsLater(TRenderGroupRemovePredicate const & predicate); - void FollowRoute(int preferredZoomLevel, int preferredZoomLevelIn3d, - double rotationAngle, double angleFOV); + void FollowRoute(int preferredZoomLevel, int preferredZoomLevelIn3d); void InvalidateRect(m2::RectD const & gRect); bool CheckTileGenerations(TileKey const & tileKey); void UpdateCanBeDeletedStatus(); @@ -294,8 +293,6 @@ private: TTilesCollection m_notFinishedTiles; int m_currentZoomLevel = -1; - - bool m_perspectiveDiscarded = false; ref_ptr m_requestedTiles; uint64_t m_maxGeneration; @@ -304,19 +301,13 @@ private: struct FollowRouteData { FollowRouteData(int preferredZoomLevel, - int preferredZoomLevelIn3d, - double rotationAngle, - double angleFOV) + int preferredZoomLevelIn3d) : m_preferredZoomLevel(preferredZoomLevel) , m_preferredZoomLevelIn3d(preferredZoomLevelIn3d) - , m_rotationAngle(rotationAngle) - , m_angleFOV(angleFOV) {} int m_preferredZoomLevel; int m_preferredZoomLevelIn3d; - double m_rotationAngle; - double m_angleFOV; }; unique_ptr m_pendingFollowRoute; diff --git a/drape_frontend/message_subclasses.hpp b/drape_frontend/message_subclasses.hpp index 49e327af05..67da3f47dd 100644 --- a/drape_frontend/message_subclasses.hpp +++ b/drape_frontend/message_subclasses.hpp @@ -645,24 +645,18 @@ public: class FollowRouteMessage : public Message { public: - FollowRouteMessage(int preferredZoomLevel, int preferredZoomLevelIn3d, double rotationAngle, double angleFOV) + FollowRouteMessage(int preferredZoomLevel, int preferredZoomLevelIn3d) : m_preferredZoomLevel(preferredZoomLevel) , m_preferredZoomLevelIn3d(preferredZoomLevelIn3d) - , m_rotationAngle(rotationAngle) - , m_angleFOV(angleFOV) {} Type GetType() const override { return Message::FollowRoute; } int GetPreferredZoomLevel() const { return m_preferredZoomLevel; } int GetPreferredZoomLevelIn3d() const { return m_preferredZoomLevelIn3d; } - double GetRotationAngle() const { return m_rotationAngle; } - double GetAngleFOV() const { return m_angleFOV; } private: int const m_preferredZoomLevel; int const m_preferredZoomLevelIn3d; - double const m_rotationAngle; - double const m_angleFOV; }; class InvalidateTexturesMessage : public BaseBlockingMessage @@ -694,24 +688,18 @@ public: class Allow3dModeMessage : public Message { public: - Allow3dModeMessage(bool allowPerspective, bool allow3dBuildings, double rotationAngle, double angleFOV) + Allow3dModeMessage(bool allowPerspective, bool allow3dBuildings) : m_allowPerspective(allowPerspective) , m_allow3dBuildings(allow3dBuildings) - , m_rotationAngle(rotationAngle) - , m_angleFOV(angleFOV) {} Type GetType() const override { return Message::Allow3dMode; } bool AllowPerspective() const { return m_allowPerspective; } bool Allow3dBuildings() const { return m_allow3dBuildings; } - double GetRotationAngle() const { return m_rotationAngle; } - double GetAngleFOV() const { return m_angleFOV; } private: bool const m_allowPerspective; bool const m_allow3dBuildings; - double const m_rotationAngle; - double const m_angleFOV; }; class Allow3dBuildingsMessage : public Message @@ -731,19 +719,9 @@ private: class EnablePerspectiveMessage : public Message { public: - EnablePerspectiveMessage(double rotationAngle, double angleFOV) - : m_rotationAngle(rotationAngle) - , m_angleFOV(angleFOV) - {} + EnablePerspectiveMessage() = default; Type GetType() const override { return Message::EnablePerspective; } - - double GetRotationAngle() const { return m_rotationAngle; } - double GetAngleFOV() const { return m_angleFOV; } - -private: - double const m_rotationAngle; - double const m_angleFOV; }; class CacheGpsTrackPointsMessage : public Message diff --git a/drape_frontend/navigator.cpp b/drape_frontend/navigator.cpp index 3c01342cf1..3ef11b1a32 100644 --- a/drape_frontend/navigator.cpp +++ b/drape_frontend/navigator.cpp @@ -279,6 +279,11 @@ bool Navigator::IsRotatingDuringScale() const return m_IsRotatingDuringScale; } +void Navigator::SetAutoPerspective(bool enable) +{ + m_Screen.SetAutoPerspective(enable); +} + void Navigator::Enable3dMode(double currentRotationAngle, double maxRotationAngle, double angleFOV) { m_Screen.ApplyPerspective(currentRotationAngle, maxRotationAngle, angleFOV); diff --git a/drape_frontend/navigator.hpp b/drape_frontend/navigator.hpp index 0155a4dd9f..e285e9c34d 100644 --- a/drape_frontend/navigator.hpp +++ b/drape_frontend/navigator.hpp @@ -46,6 +46,7 @@ public: void Scale(m2::PointD const & pixelScaleCenter, double factor); bool InAction() const; + void SetAutoPerspective(bool enable); void Enable3dMode(double currentRotationAngle, double maxRotationAngle, double angleFOV); void SetRotationIn3dMode(double rotationAngle); void Disable3dMode(); diff --git a/drape_frontend/user_event_stream.cpp b/drape_frontend/user_event_stream.cpp index 21b431f215..106bd58023 100644 --- a/drape_frontend/user_event_stream.cpp +++ b/drape_frontend/user_event_stream.cpp @@ -2,7 +2,6 @@ #include "drape_frontend/animation/linear_animation.hpp" #include "drape_frontend/animation/scale_animation.hpp" #include "drape_frontend/animation/follow_animation.hpp" -#include "drape_frontend/animation/perspective_animation.hpp" #include "drape_frontend/animation/sequence_animation.hpp" #include "drape_frontend/animation_constants.hpp" #include "drape_frontend/animation_system.hpp" @@ -152,9 +151,6 @@ ScreenBase const & UserEventStream::ProcessEvents(bool & modelViewChanged, bool m_modelViewChanged = !events.empty() || m_state == STATE_SCALE || m_state == STATE_DRAG; for (UserEvent const & e : events) { - if (m_perspectiveAnimation && FilterEventWhile3dAnimation(e.m_type)) - continue; - bool breakAnim = false; switch (e.m_type) @@ -175,11 +171,6 @@ ScreenBase const & UserEventStream::ProcessEvents(bool & modelViewChanged, bool TouchCancel(m_touches); break; case UserEvent::EVENT_SET_RECT: - if (m_perspectiveAnimation) - { - m_pendingEvent.reset(new UserEvent(e.m_rectEvent)); - break; - } breakAnim = SetRect(e.m_rectEvent.m_rect, e.m_rectEvent.m_zoom, e.m_rectEvent.m_applyRotation, e.m_rectEvent.m_isAnim); TouchCancel(m_touches); break; @@ -213,12 +204,8 @@ ScreenBase const & UserEventStream::ProcessEvents(bool & modelViewChanged, bool e.m_followAndRotate.m_isAnim); TouchCancel(m_touches); break; - case UserEvent::EVENT_ENABLE_PERSPECTIVE: - SetEnable3dMode(e.m_enable3dMode.m_rotationAngle, e.m_enable3dMode.m_angleFOV, - e.m_enable3dMode.m_isAnim, e.m_enable3dMode.m_immediatelyStart); - break; - case UserEvent::EVENT_DISABLE_PERSPECTIVE: - SetDisable3dModeAnimation(); + case UserEvent::EVENT_AUTO_PERSPECTIVE: + SetAutoPerspective(e.m_autoPerspective.m_isAutoPerspective); break; default: ASSERT(false, ()); @@ -231,21 +218,6 @@ ScreenBase const & UserEventStream::ProcessEvents(bool & modelViewChanged, bool ApplyAnimations(); - if (m_perspectiveAnimation) - { - TouchCancel(m_touches); - } - else - { - if (m_pendingEvent != nullptr && m_pendingEvent->m_type == UserEvent::EVENT_SET_RECT) - { - SetRect(m_pendingEvent->m_rectEvent.m_rect, m_pendingEvent->m_rectEvent.m_zoom, - m_pendingEvent->m_rectEvent.m_applyRotation, m_pendingEvent->m_rectEvent.m_isAnim); - m_pendingEvent.reset(); - m_modelViewChanged = true; - } - } - if (GetValidTouchesCount(m_touches) == 1) { if (m_state == STATE_WAIT_DOUBLE_TAP) @@ -274,27 +246,6 @@ void UserEventStream::ApplyAnimations() if (m_animationSystem.GetScreen(GetCurrentScreen(), screen)) m_navigator.SetFromScreen(screen); - Animation::SwitchPerspectiveParams switchPerspective; - if (m_animationSystem.SwitchPerspective(switchPerspective)) - { - if (switchPerspective.m_enable) - { - m_navigator.Enable3dMode(switchPerspective.m_startAngle, switchPerspective.m_endAngle, - switchPerspective.m_angleFOV); - } - else - { - m_navigator.Disable3dMode(); - } - } - - double perspectiveAngle; - if (m_animationSystem.GetPerspectiveAngle(perspectiveAngle) && - GetCurrentScreen().isPerspective()) - { - m_navigator.SetRotationIn3dMode(perspectiveAngle); - } - m_modelViewChanged = true; } } @@ -510,61 +461,12 @@ bool UserEventStream::SetFollowAndRotate(m2::PointD const & userPos, m2::PointD return true; } -bool UserEventStream::FilterEventWhile3dAnimation(UserEvent::EEventType type) const -{ - return type != UserEvent::EVENT_RESIZE && type != UserEvent::EVENT_SET_RECT && - type != UserEvent::EVENT_ENABLE_PERSPECTIVE && - type != UserEvent::EVENT_DISABLE_PERSPECTIVE; -} - -void UserEventStream::SetEnable3dMode(double maxRotationAngle, double angleFOV, - bool isAnim, bool immediatelyStart) +void UserEventStream::SetAutoPerspective(bool isAutoPerspective) { + if (!isAutoPerspective) + m_navigator.Disable3dMode(); + m_navigator.SetAutoPerspective(isAutoPerspective); return; - - ResetAnimationsBeforeSwitch3D(); - - if (immediatelyStart) - InterruptFollowAnimations(true /* force */); - - double const startAngle = isAnim ? 0.0 : maxRotationAngle; - double const endAngle = maxRotationAngle; - - auto anim = make_unique_dp(startAngle, endAngle, angleFOV); - anim->SetOnStartAction([this, startAngle, endAngle, angleFOV](ref_ptr) - { - m_perspectiveAnimation = true; - }); - anim->SetOnFinishAction([this](ref_ptr) - { - m_perspectiveAnimation = false; - }); - if (immediatelyStart) - m_animationSystem.CombineAnimation(move(anim)); - else - m_animationSystem.PushAnimation(move(anim)); -} - -void UserEventStream::SetDisable3dModeAnimation() -{ - return; - - ResetAnimationsBeforeSwitch3D(); - InterruptFollowAnimations(true /* force */); - - double const startAngle = m_navigator.Screen().GetRotationAngle(); - double const endAngle = 0.0; - - auto anim = make_unique_dp(startAngle, endAngle, m_navigator.Screen().GetAngleFOV()); - anim->SetOnStartAction([this](ref_ptr) - { - m_perspectiveAnimation = true; - }); - anim->SetOnFinishAction([this](ref_ptr) - { - m_perspectiveAnimation = false; - }); - m_animationSystem.CombineAnimation(move(anim)); } void UserEventStream::ResetAnimations(Animation::Type animType, bool finishAll) @@ -591,14 +493,6 @@ void UserEventStream::ResetMapPlaneAnimations() ApplyAnimations(); } -void UserEventStream::ResetAnimationsBeforeSwitch3D() -{ - ResetAnimations(Animation::MapLinear); - ResetAnimations(Animation::Sequence, kPrettyMoveAnim); - ResetAnimations(Animation::MapScale); - ResetAnimations(Animation::MapPerspective, true /* finishAll */); -} - m2::AnyRectD UserEventStream::GetCurrentRect() const { return m_navigator.Screen().GlobalRect(); @@ -1195,11 +1089,6 @@ bool UserEventStream::IsWaitingForActionCompletion() const return m_state != STATE_EMPTY; } -bool UserEventStream::IsInPerspectiveAnimation() const -{ - return m_perspectiveAnimation; -} - void UserEventStream::SetKineticScrollEnabled(bool enabled) { m_kineticScrollEnabled = enabled; diff --git a/drape_frontend/user_event_stream.hpp b/drape_frontend/user_event_stream.hpp index aa02aca90d..c3ad87d6a2 100644 --- a/drape_frontend/user_event_stream.hpp +++ b/drape_frontend/user_event_stream.hpp @@ -145,25 +145,13 @@ struct FollowAndRotateEvent bool m_isAnim; }; -struct EnablePerspectiveEvent +struct SetAutoPerspectiveEvent { - EnablePerspectiveEvent(double rotationAngle, double angleFOV, - bool isAnim, bool immediatelyStart) - : m_isAnim(isAnim) - , m_immediatelyStart(immediatelyStart) - , m_rotationAngle(rotationAngle) - , m_angleFOV(angleFOV) + SetAutoPerspectiveEvent(bool isAutoPerspective) + : m_isAutoPerspective(isAutoPerspective) {} - bool m_isAnim; - bool m_immediatelyStart; - double m_rotationAngle; - double m_angleFOV; -}; - -struct DisablePerspectiveEvent -{ - DisablePerspectiveEvent() {} + bool m_isAutoPerspective; }; struct RotateEvent @@ -193,8 +181,7 @@ struct UserEvent EVENT_RESIZE, EVENT_ROTATE, EVENT_FOLLOW_AND_ROTATE, - EVENT_ENABLE_PERSPECTIVE, - EVENT_DISABLE_PERSPECTIVE + EVENT_AUTO_PERSPECTIVE }; UserEvent(TouchEvent const & e) : m_type(EVENT_TOUCH) { m_touchEvent = e; } @@ -205,8 +192,7 @@ struct UserEvent UserEvent(ResizeEvent const & e) : m_type(EVENT_RESIZE) { m_resize = e; } UserEvent(RotateEvent const & e) : m_type(EVENT_ROTATE) { m_rotate = e; } UserEvent(FollowAndRotateEvent const & e) : m_type(EVENT_FOLLOW_AND_ROTATE) { m_followAndRotate = e; } - UserEvent(EnablePerspectiveEvent const & e) : m_type(EVENT_ENABLE_PERSPECTIVE) { m_enable3dMode = e; } - UserEvent(DisablePerspectiveEvent const & e) : m_type(EVENT_DISABLE_PERSPECTIVE) { m_disable3dMode = e; } + UserEvent(SetAutoPerspectiveEvent const & e) : m_type(EVENT_AUTO_PERSPECTIVE) { m_autoPerspective = e; } EEventType m_type; union @@ -219,8 +205,7 @@ struct UserEvent ResizeEvent m_resize; RotateEvent m_rotate; FollowAndRotateEvent m_followAndRotate; - EnablePerspectiveEvent m_enable3dMode; - DisablePerspectiveEvent m_disable3dMode; + SetAutoPerspectiveEvent m_autoPerspective; }; }; @@ -261,7 +246,6 @@ public: void GetTargetScreen(ScreenBase & screen) const; m2::AnyRectD GetTargetRect() const; bool IsInUserAction() const; - bool IsInPerspectiveAnimation() const; bool IsWaitingForActionCompletion() const; void SetListener(ref_ptr listener) { m_listener = listener; } @@ -299,11 +283,7 @@ private: bool SetScreen(ScreenBase const & screen, bool isAnim); bool SetFollowAndRotate(m2::PointD const & userPos, m2::PointD const & pixelPos, double azimuth, int preferredZoomLevel, bool isAnim); - - bool FilterEventWhile3dAnimation(UserEvent::EEventType type) const; - void SetEnable3dMode(double maxRotationAngle, double angleFOV, - bool isAnim, bool immediatelyStart); - void SetDisable3dModeAnimation(); + void SetAutoPerspective(bool isAutoPerspective); m2::AnyRectD GetCurrentRect() const; @@ -348,7 +328,6 @@ private: void ResetAnimations(Animation::Type animType, bool finishAll = false); void ResetAnimations(Animation::Type animType, string const & customType, bool finishAll = false); void ResetMapPlaneAnimations(); - void ResetAnimationsBeforeSwitch3D(); bool InterruptFollowAnimations(bool force); list m_events; @@ -375,7 +354,6 @@ private: bool m_modelViewChanged = false; - bool m_perspectiveAnimation = false; unique_ptr m_pendingEvent; ref_ptr m_listener; diff --git a/geometry/screenbase.cpp b/geometry/screenbase.cpp index f28eaf412c..1c4503ac5c 100644 --- a/geometry/screenbase.cpp +++ b/geometry/screenbase.cpp @@ -28,7 +28,7 @@ ScreenBase::ScreenBase() : m_3dMaxAngleX(0.0), m_3dScale(1.0), m_isPerspective(false), - m_isAutoPerspective(true), + m_isAutoPerspective(false), m_GlobalRect(m_Org, ang::AngleD(0), m2::RectD(-320, -240, 320, 240)), m_ClipRect(m2::RectD(0, 0, 640, 480)) { @@ -117,13 +117,10 @@ double ScreenBase::CalculatePerspectiveAngle(double scale) const return kMaxPerspectiveAngle2 * 0.99; } -void ScreenBase::UpdatePerspectiveParameters() +void ScreenBase::SetAutoPerspective(bool isAutoPerspective) { - double const angle = CalculatePerspectiveAngle(m_Scale); - if (angle > 0.0) - ApplyPerspective(angle, angle, kPerspectiveAngleFOV); - else if (m_isPerspective) - ResetPerspective(); + m_isAutoPerspective = isAutoPerspective; + UpdateDependentParameters(); } void ScreenBase::SetFromRects(m2::AnyRectD const & glbRect, m2::RectD const & pxRect) diff --git a/geometry/screenbase.hpp b/geometry/screenbase.hpp index 1fc667bbf9..d3fbc6fc99 100644 --- a/geometry/screenbase.hpp +++ b/geometry/screenbase.hpp @@ -132,7 +132,6 @@ public: m2::AnyRectD const & GlobalRect() const { return m_GlobalRect; } m2::RectD const & ClipRect() const { return m_ClipRect; } - void UpdatePerspectiveParameters(); void ApplyPerspective(double currentRotationAngle, double maxRotationAngle, double angleFOV); void ResetPerspective(); @@ -146,6 +145,8 @@ public: Matrix3dT const & Pto3dMatrix() const { return m_Pto3d; } bool isPerspective() const { return m_isPerspective; } + bool isAutoPerspective() const { return m_isAutoPerspective; } + void SetAutoPerspective(bool isAutoPerspective); bool IsReverseProjection3d(m2::PointD const & pt) const; diff --git a/map/framework.cpp b/map/framework.cpp index d5c9aa01f5..261b0809ab 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -111,9 +111,6 @@ char const kAllow3dBuildingsKey[] = "Buildings3d"; double const kDistEqualQuery = 100.0; -double const kRotationAngle = math::pi4; -double const kAngleFOV = math::pi / 3.0; - // TODO! // To adjust GpsTrackFilter was added secret command "?gpstrackaccuracy:xxx;" // where xxx is a new value for horizontal accuracy. @@ -1592,7 +1589,7 @@ void Framework::CreateDrapeEngine(ref_ptr contextFactory, { InsertRoute(m_routingSession.GetRoute()); if (allow3d && m_routingSession.IsFollowing()) - m_drapeEngine->EnablePerspective(kRotationAngle, kAngleFOV); + m_drapeEngine->EnablePerspective(); } if (m_connectToGpsTrack) @@ -2276,7 +2273,7 @@ void Framework::FollowRoute() : scales::GetNavigationScale(); int const scale3d = (m_currentRouterType == RouterType::Pedestrian) ? scales::GetPedestrianNavigation3dScale() : scales::GetNavigation3dScale(); - m_drapeEngine->FollowRoute(scale, scale3d, kRotationAngle, kAngleFOV); + m_drapeEngine->FollowRoute(scale, scale3d); m_drapeEngine->SetRoutePoint(m2::PointD(), true /* isStart */, false /* isValid */); } @@ -2519,7 +2516,7 @@ void Framework::SetRouteFinishPoint(m2::PointD const & pt, bool isValid) void Framework::Allow3dMode(bool allow3d, bool allow3dBuildings) { - CallDrapeFunction(bind(&df::DrapeEngine::Allow3dMode, _1, allow3d, allow3dBuildings, kRotationAngle, kAngleFOV)); + CallDrapeFunction(bind(&df::DrapeEngine::Allow3dMode, _1, allow3d, allow3dBuildings)); } void Framework::Save3dMode(bool allow3d, bool allow3dBuildings) From 6c6ff08f9dd685135cff652c966cabb9dcf99879 Mon Sep 17 00:00:00 2001 From: Daria Volvenkova Date: Thu, 7 Jul 2016 18:46:19 +0300 Subject: [PATCH 18/18] Review fixes. --- drape_frontend/animation/follow_animation.cpp | 6 +++--- drape_frontend/animation/interpolators.cpp | 1 - drape_frontend/navigator.cpp | 10 +++++++--- drape_frontend/navigator.hpp | 2 +- drape_frontend/user_event_stream.cpp | 8 +++++--- geometry/screenbase.cpp | 17 ++++++++++++----- geometry/screenbase.hpp | 2 ++ 7 files changed, 30 insertions(+), 16 deletions(-) diff --git a/drape_frontend/animation/follow_animation.cpp b/drape_frontend/animation/follow_animation.cpp index 0ddc6016ed..ccf359c87e 100644 --- a/drape_frontend/animation/follow_animation.cpp +++ b/drape_frontend/animation/follow_animation.cpp @@ -33,7 +33,7 @@ MapFollowAnimation::MapFollowAnimation(ScreenBase const & screen, m_properties.insert(Animation::Scale); if (m_angleInterpolator.IsActive()) m_properties.insert(Animation::Angle); - //if (m_offsetInterpolator.IsActive()) + if (m_offsetInterpolator.IsActive() || m_scaleInterpolator.IsActive() || m_angleInterpolator.IsActive()) m_properties.insert(Animation::Position); } @@ -117,8 +117,8 @@ bool MapFollowAnimation::GetProperty(TObject object, TProperty property, bool ta } else { - double scale = m_scaleInterpolator.GetScale() / m_scaleInterpolator.GetStartScale(); - double angle = m_angleInterpolator.GetAngle() - m_angleInterpolator.GetStartAngle(); + double const scale = m_scaleInterpolator.GetScale() / m_scaleInterpolator.GetStartScale(); + double const angle = m_angleInterpolator.GetAngle() - m_angleInterpolator.GetStartAngle(); m2::PointD offset = m_offsetInterpolator.GetPosition() * scale; offset.Rotate(angle); m2::PointD pos = m_globalPosition + offset; diff --git a/drape_frontend/animation/interpolators.cpp b/drape_frontend/animation/interpolators.cpp index c427a5f090..f933953be7 100644 --- a/drape_frontend/animation/interpolators.cpp +++ b/drape_frontend/animation/interpolators.cpp @@ -147,7 +147,6 @@ double PositionInterpolator::GetMoveDuration(m2::PointD const & startPosition, m double const pixelSpeed = kMaxSpeedScalar * minSize; return CalcAnimSpeedDuration(pixelLength, pixelSpeed); - } //static diff --git a/drape_frontend/navigator.cpp b/drape_frontend/navigator.cpp index 3ef11b1a32..08e7685980 100644 --- a/drape_frontend/navigator.cpp +++ b/drape_frontend/navigator.cpp @@ -45,7 +45,7 @@ void Navigator::SetFromScreen(ScreenBase const & screen, uint32_t tileSize, doub tmp = m_Screen; tmp.SetFromRect(m2::AnyRectD(newRect)); - ASSERT(CheckMaxScale(tmp, p.GetTileSize(), p.GetVisualScale()), ()); + ASSERT(CheckMaxScale(tmp, tileSize, visualScale), ()); } m_Screen = tmp; @@ -284,9 +284,13 @@ void Navigator::SetAutoPerspective(bool enable) m_Screen.SetAutoPerspective(enable); } -void Navigator::Enable3dMode(double currentRotationAngle, double maxRotationAngle, double angleFOV) +void Navigator::Enable3dMode() { - m_Screen.ApplyPerspective(currentRotationAngle, maxRotationAngle, angleFOV); + if (m_Screen.isPerspective()) + return; + double const angle = m_Screen.CalculateAutoPerspectiveAngle(m_Screen.GetScale()); + if (angle > 0) + m_Screen.ApplyPerspective(angle, angle, m_Screen.GetAngleFOV()); } void Navigator::SetRotationIn3dMode(double rotationAngle) diff --git a/drape_frontend/navigator.hpp b/drape_frontend/navigator.hpp index e285e9c34d..209a7f8e8c 100644 --- a/drape_frontend/navigator.hpp +++ b/drape_frontend/navigator.hpp @@ -47,7 +47,7 @@ public: bool InAction() const; void SetAutoPerspective(bool enable); - void Enable3dMode(double currentRotationAngle, double maxRotationAngle, double angleFOV); + void Enable3dMode(); void SetRotationIn3dMode(double rotationAngle); void Disable3dMode(); diff --git a/drape_frontend/user_event_stream.cpp b/drape_frontend/user_event_stream.cpp index 106bd58023..6ad6f1c6c2 100644 --- a/drape_frontend/user_event_stream.cpp +++ b/drape_frontend/user_event_stream.cpp @@ -413,8 +413,8 @@ bool UserEventStream::SetFollowAndRotate(m2::PointD const & userPos, m2::PointD } screen.MatchGandP3d(userPos, pixelPos); - ASSERT_GREATER_OR_EQUAL(zoom, scales::GetUpperWorldScale(), ()); - ASSERT_LESS_OR_EQUAL(zoom, scales::GetUpperStyleScale(), ()); + ASSERT_GREATER_OR_EQUAL(preferredZoomLevel, scales::GetUpperWorldScale(), ()); + ASSERT_LESS_OR_EQUAL(preferredZoomLevel, scales::GetUpperStyleScale(), ()); ShrinkAndScaleInto(screen, df::GetWorldRect()); @@ -463,7 +463,9 @@ bool UserEventStream::SetFollowAndRotate(m2::PointD const & userPos, m2::PointD void UserEventStream::SetAutoPerspective(bool isAutoPerspective) { - if (!isAutoPerspective) + if (isAutoPerspective) + m_navigator.Enable3dMode(); + else m_navigator.Disable3dMode(); m_navigator.SetAutoPerspective(isAutoPerspective); return; diff --git a/geometry/screenbase.cpp b/geometry/screenbase.cpp index 1c4503ac5c..89455ae424 100644 --- a/geometry/screenbase.cpp +++ b/geometry/screenbase.cpp @@ -94,11 +94,8 @@ void ScreenBase::UpdateDependentParameters() } } -double ScreenBase::CalculatePerspectiveAngle(double scale) const +double ScreenBase::CalculateAutoPerspectiveAngle(double scale) { - if (!m_isAutoPerspective) - return m_3dAngleX; - if (scale > kStartPerspectiveScale1) return 0.0; @@ -117,6 +114,14 @@ double ScreenBase::CalculatePerspectiveAngle(double scale) const return kMaxPerspectiveAngle2 * 0.99; } +double ScreenBase::CalculatePerspectiveAngle(double scale) const +{ + if (!m_isAutoPerspective) + return m_3dAngleX; + + return CalculateAutoPerspectiveAngle(scale); +} + void ScreenBase::SetAutoPerspective(bool isAutoPerspective) { m_isAutoPerspective = isAutoPerspective; @@ -421,10 +426,12 @@ void ScreenBase::ResetPerspective() m_isPerspective = false; m_isAutoPerspective = false; + double const old_dy = m_ViewportRect.SizeY() * (m_3dScale - 1.0); + + m_3dScale = 1.0; m_3dAngleX = 0.0; m_3dMaxAngleX = 0.0; - double const old_dy = m_ViewportRect.SizeY() * (m_3dScale - 1.0); Move(0.0, -old_dy / 2.0); } diff --git a/geometry/screenbase.hpp b/geometry/screenbase.hpp index d3fbc6fc99..b5f43a1562 100644 --- a/geometry/screenbase.hpp +++ b/geometry/screenbase.hpp @@ -162,6 +162,8 @@ public: m2::RectD CalculatePixelRect(double scale) const; double CalculatePerspectiveAngle(double scale) const; + static double CalculateAutoPerspectiveAngle(double scale); + /// Compute arbitrary pixel transformation, that translates the (oldPt1, oldPt2) -> (newPt1, newPt2) static MatrixT const CalcTransform(m2::PointD const & oldPt1, m2::PointD const & oldPt2, m2::PointD const & newPt1, m2::PointD const & newPt2,