diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index c9c0da8337..46d1a04898 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -390,7 +390,11 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) { m_myPositionController->DeactivateRouting(); if (m_enable3dInNavigation) + { + m_discardedFOV = -1.0; + m_discardedAngle = -1.0; AddUserEvent(DisablePerspectiveEvent()); + } } break; } @@ -401,13 +405,20 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) m_myPositionController->NextMode(!m_enable3dInNavigation ? msg->GetPreferredZoomLevel() : msg->GetPreferredZoomLevelIn3d()); if (m_enable3dInNavigation) - AddUserEvent(EnablePerspectiveEvent(msg->GetRotationAngle(), msg->GetAngleFOV(), true)); + AddUserEvent(EnablePerspectiveEvent(msg->GetRotationAngle(), msg->GetAngleFOV(), + true /* animated */, false /* immediately start*/)); break; } case Message::DeactivateRouteFollowing: { m_myPositionController->DeactivateRouting(); + if (m_enable3dInNavigation) + { + m_discardedFOV = -1.0; + m_discardedAngle = -1.0; + AddUserEvent(DisablePerspectiveEvent()); + } break; } @@ -486,7 +497,8 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) case Message::EnablePerspective: { ref_ptr const msg = message; - AddUserEvent(EnablePerspectiveEvent(msg->GetRotationAngle(), msg->GetAngleFOV(), false)); + AddUserEvent(EnablePerspectiveEvent(msg->GetRotationAngle(), msg->GetAngleFOV(), + false /* animated */, true /* immediately start */)); break; } @@ -517,7 +529,9 @@ void FrontendRenderer::OnResize(ScreenBase const & screen) { m2::RectD const viewportRect = screen.isPerspective() ? screen.PixelRectIn3d() : screen.PixelRect(); + m_myPositionController->UpdatePixelPosition(screen); m_myPositionController->SetPixelRect(viewportRect); + m_viewport.SetViewport(0, 0, screen.GetWidth(), screen.GetHeight()); m_contextFactory->getDrawContext()->resize(viewportRect.SizeX(), viewportRect.SizeY()); RefreshProjection(); @@ -929,6 +943,24 @@ int FrontendRenderer::GetCurrentZoomLevelForData() const void FrontendRenderer::ResolveZoomLevel(ScreenBase const & screen) { m_currentZoomLevel = GetDrawTileScale(screen); + + if (m_userEventStream.IsInPerspectiveAnimation()) + return; + LOG(LWARNING, ("m_currentZoomLevel =", m_currentZoomLevel)); + if (screen.isPerspective() && m_currentZoomLevel < m_min3dZoomLevel) + { + m_discardedFOV = screen.GetAngleFOV(); + m_discardedAngle = screen.GetRotationAngle(); + AddUserEvent(DisablePerspectiveEvent()); + } + else if (m_discardedFOV > 0.0 && + m_currentZoomLevel >= m_min3dZoomLevel) + { + AddUserEvent(EnablePerspectiveEvent(m_discardedAngle, m_discardedFOV, + true /* animated */, true /* immediately start */)); + m_discardedFOV = -1.0; + m_discardedAngle = -1.0; + } } void FrontendRenderer::OnTap(m2::PointD const & pt, bool isLongTap) @@ -1250,6 +1282,8 @@ void FrontendRenderer::PrepareScene(ScreenBase const & modelView) RefreshModelView(modelView); RefreshBgColor(); RefreshPivotTransform(modelView); + + m_myPositionController->UpdatePixelPosition(modelView); } void FrontendRenderer::UpdateScene(ScreenBase const & modelView) @@ -1258,8 +1292,6 @@ void FrontendRenderer::UpdateScene(ScreenBase const & modelView) TTilesCollection tiles; ResolveTileKeys(modelView, tiles); - m_myPositionController->UpdatePixelPosition(modelView); - m_overlayTree->ForceUpdate(); auto removePredicate = [this](drape_ptr const & group) { diff --git a/drape_frontend/frontend_renderer.hpp b/drape_frontend/frontend_renderer.hpp index dcb8ed062c..651c7b1b7f 100755 --- a/drape_frontend/frontend_renderer.hpp +++ b/drape_frontend/frontend_renderer.hpp @@ -243,6 +243,10 @@ private: unique_ptr m_tileTree; int m_currentZoomLevel = -1; + int m_min3dZoomLevel = 17; + double m_discardedFOV = -1.0; + double m_discardedAngle = -1.0; + ref_ptr m_requestedTiles; uint64_t m_maxGeneration; diff --git a/drape_frontend/user_event_stream.cpp b/drape_frontend/user_event_stream.cpp index d740325dc0..9ad72edcd6 100644 --- a/drape_frontend/user_event_stream.cpp +++ b/drape_frontend/user_event_stream.cpp @@ -161,7 +161,7 @@ ScreenBase const & UserEventStream::ProcessEvents(bool & modelViewChange, bool & case UserEvent::EVENT_SET_RECT: if (m_perspectiveAnimation != nullptr) { - m_pendingEvent.reset(new UserEvent(e.m_rectEvent)); + //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); @@ -190,6 +190,14 @@ ScreenBase const & UserEventStream::ProcessEvents(bool & modelViewChange, bool & case UserEvent::EVENT_ENABLE_PERSPECTIVE: if (e.m_enable3dMode.m_isAnim) { + if (e.m_enable3dMode.m_immediatelyStart) + { + SetEnable3dModeAnimation(e.m_enable3dMode.m_rotationAngle); + m_navigator.Enable3dMode(0.0 /* current rotation angle */, + e.m_enable3dMode.m_rotationAngle, + e.m_enable3dMode.m_angleFOV); + viewportChanged = true; + } m_pendingEvent.reset(new UserEvent(e.m_enable3dMode)); } else @@ -452,6 +460,8 @@ bool UserEventStream::FilterEventWhile3dAnimation(UserEvent::EEventType type) co void UserEventStream::SetEnable3dModeAnimation(double maxRotationAngle) { + ResetCurrentAnimation(); + double const startAngle = 0.0; double const endAngle = maxRotationAngle; double const rotateDuration = PerspectiveAnimation::GetRotateDuration(startAngle, endAngle); @@ -971,4 +981,9 @@ bool UserEventStream::IsWaitingForActionCompletion() const return m_state != STATE_EMPTY; } +bool UserEventStream::IsInPerspectiveAnimation() const +{ + return m_perspectiveAnimation != nullptr; +} + } diff --git a/drape_frontend/user_event_stream.hpp b/drape_frontend/user_event_stream.hpp index 3cb01c0934..2f16472774 100644 --- a/drape_frontend/user_event_stream.hpp +++ b/drape_frontend/user_event_stream.hpp @@ -147,13 +147,16 @@ struct FollowAndRotateEvent struct EnablePerspectiveEvent { - EnablePerspectiveEvent(double rotationAngle, double angleFOV, bool isAnim) + EnablePerspectiveEvent(double rotationAngle, double angleFOV, + bool isAnim, bool immediatelyStart) : m_isAnim(isAnim) + , m_immediatelyStart(immediatelyStart) , m_rotationAngle(rotationAngle) , m_angleFOV(angleFOV) {} bool m_isAnim; + bool m_immediatelyStart; double m_rotationAngle; double m_angleFOV; }; @@ -252,7 +255,7 @@ public: m2::AnyRectD GetTargetRect() const; bool IsInUserAction() const; - + bool IsInPerspectiveAnimation() const; bool IsWaitingForActionCompletion() const; void SetListener(ref_ptr listener) { m_listener = listener; }