From c949c0c407bbd1742a03b7189ee42c59f03dcbae Mon Sep 17 00:00:00 2001 From: Daria Volvenkova Date: Mon, 6 Jun 2016 11:54:32 +0300 Subject: [PATCH] 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);