From 24834ce40c571ef6021991350bc0863279f71497 Mon Sep 17 00:00:00 2001 From: Daria Volvenkova Date: Mon, 5 Sep 2016 13:17:07 +0300 Subject: Positioning in visible viewport. --- drape_frontend/drape_engine.cpp | 7 +++ drape_frontend/drape_engine.hpp | 2 + .../user_event_stream_tests.cpp | 5 ++ drape_frontend/frontend_renderer.cpp | 60 ++++++++++++++++++++-- drape_frontend/frontend_renderer.hpp | 1 + drape_frontend/message.hpp | 3 +- drape_frontend/message_subclasses.hpp | 14 +++++ drape_frontend/my_position_controller.cpp | 29 +++++++---- drape_frontend/my_position_controller.hpp | 9 ++-- drape_frontend/selection_shape.cpp | 22 ++++++-- drape_frontend/selection_shape.hpp | 4 ++ drape_frontend/user_event_stream.cpp | 33 ++++++++++-- drape_frontend/user_event_stream.hpp | 23 ++++++++- 13 files changed, 185 insertions(+), 27 deletions(-) (limited to 'drape_frontend') diff --git a/drape_frontend/drape_engine.cpp b/drape_frontend/drape_engine.cpp index 42b4b554a2..402a9d732a 100644 --- a/drape_frontend/drape_engine.cpp +++ b/drape_frontend/drape_engine.cpp @@ -111,6 +111,13 @@ void DrapeEngine::Resize(int w, int h) ResizeImpl(w, h); } +void DrapeEngine::SetVisibleViewport(m2::RectD const & rect) const +{ + m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, + make_unique_dp(rect), + MessagePriority::Normal); +} + void DrapeEngine::Invalidate() { m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, diff --git a/drape_frontend/drape_engine.hpp b/drape_frontend/drape_engine.hpp index 8eacbbde71..c908b64dec 100644 --- a/drape_frontend/drape_engine.hpp +++ b/drape_frontend/drape_engine.hpp @@ -89,6 +89,8 @@ public: void Resize(int w, int h); void Invalidate(); + void SetVisibleViewport(m2::RectD const & rect) const; + void AddTouchEvent(TouchEvent const & event); void Scale(double factor, m2::PointD const & pxPoint, bool isAnim); 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 036019ea90..e79148ff47 100644 --- a/drape_frontend/drape_frontend_tests/user_event_stream_tests.cpp +++ b/drape_frontend/drape_frontend_tests/user_event_stream_tests.cpp @@ -38,6 +38,11 @@ public: void OnScaleEnded() override {} void OnTouchMapAction() override {} void OnAnimatedScaleEnded() override {} + bool OnNewVisibleViewport(m2::RectD const & oldViewport, m2::RectD const & newViewport, + m2::PointD & gOffset) override + { + return false; + } void AddUserEvent(df::TouchEvent const & event) { diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index 61182eee24..e9bf267a5e 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -387,6 +387,7 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) { ProcessSelection(make_ref(m_selectObjectMessage)); m_selectObjectMessage.reset(); + AddUserEvent(make_unique_dp(m_userEventStream.GetVisibleViewport())); } } break; @@ -452,6 +453,8 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) break; } ProcessSelection(msg); + AddUserEvent(make_unique_dp(m_userEventStream.GetVisibleViewport())); + break; } @@ -718,6 +721,15 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) break; } + case Message::SetVisibleViewport: + { + ref_ptr msg = message; + AddUserEvent(make_unique_dp(msg->GetRect())); + m_myPositionController->SetVisibleViewport(msg->GetRect()); + m_myPositionController->UpdatePosition(); + break; + } + case Message::Invalidate: { m_myPositionController->ResetRoutingNotFollowTimer(); @@ -843,11 +855,11 @@ void FrontendRenderer::OnResize(ScreenBase const & screen) double const kEps = 1e-5; bool const viewportChanged = !m2::IsEqualSize(m_lastReadedModelView.PixelRectIn3d(), viewportRect, kEps, kEps); - m_myPositionController->UpdatePixelPosition(screen); + m_myPositionController->OnUpdateScreen(screen); if (viewportChanged) { - m_myPositionController->OnNewViewportRect(); + m_myPositionController->UpdatePosition(); m_viewport.SetViewport(0, 0, viewportRect.SizeX(), viewportRect.SizeY()); } @@ -1438,6 +1450,48 @@ void FrontendRenderer::OnTouchMapAction() m_myPositionController->ResetRoutingNotFollowTimer(); } +bool FrontendRenderer::OnNewVisibleViewport(m2::RectD const & oldViewport, m2::RectD const & newViewport, m2::PointD & gOffset) +{ + gOffset = m2::PointD(0, 0); + if (m_myPositionController->IsModeChangeViewport() || m_selectionShape == nullptr) + return false; + + ScreenBase const & screen = m_userEventStream.GetCurrentScreen(); + m2::PointD pos; + + double const vs = VisualParams::Instance().GetVisualScale(); + if (m_selectionShape->IsVisible(screen, pos)) + { + m2::RectD rect(pos, pos); + if (!(m_selectionShape->GetSelectedObject() == SelectionShape::OBJECT_POI && + m_overlayTree->GetSelectedFeatureRect(screen, rect))) + { + double const r = m_selectionShape->GetRadius(); + rect.Inflate(r, r); + } + + if (oldViewport.IsIntersect(rect) && !newViewport.IsRectInside(rect)) + { + double const kOffset = 50 * vs; + m2::PointD pOffset(0.0, 0.0); + if (rect.minX() < newViewport.minX()) + pOffset.x = newViewport.minX() - rect.minX() + kOffset; + else if (rect.maxX() > newViewport.maxX()) + pOffset.x = newViewport.maxX() - rect.maxX() - kOffset; + + if (rect.minY() < newViewport.minY()) + pOffset.y = newViewport.minY() - rect.minY() + kOffset; + else if (rect.maxY() > newViewport.maxY()) + pOffset.y = newViewport.maxY() - rect.maxY() - kOffset; + + gOffset = screen.PtoG(screen.P3dtoP(pos + pOffset)) - screen.PtoG(screen.P3dtoP(pos)); + + } + return true; + } + return false; +} + TTilesCollection FrontendRenderer::ResolveTileKeys(ScreenBase const & screen) { m2::RectD const & rect = screen.ClipRect(); @@ -1726,7 +1780,7 @@ void FrontendRenderer::PrepareScene(ScreenBase const & modelView) RefreshZScale(modelView); RefreshPivotTransform(modelView); - m_myPositionController->UpdatePixelPosition(modelView); + m_myPositionController->OnUpdateScreen(modelView); m_routeRenderer->UpdateRoute(modelView, bind(&FrontendRenderer::OnCacheRouteArrows, this, _1, _2)); } diff --git a/drape_frontend/frontend_renderer.hpp b/drape_frontend/frontend_renderer.hpp index 47c443e668..cccc8e4578 100755 --- a/drape_frontend/frontend_renderer.hpp +++ b/drape_frontend/frontend_renderer.hpp @@ -203,6 +203,7 @@ private: void OnScaleEnded() override; void OnAnimatedScaleEnded() override; void OnTouchMapAction() override; + bool OnNewVisibleViewport(m2::RectD const & oldViewport, m2::RectD const & newViewport, m2::PointD & gOffset) override; class Routine : public threads::IRoutine { diff --git a/drape_frontend/message.hpp b/drape_frontend/message.hpp index e237b93c6c..851608e968 100644 --- a/drape_frontend/message.hpp +++ b/drape_frontend/message.hpp @@ -63,7 +63,8 @@ public: SetDisplacementMode, AllowAutoZoom, RequestSymbolsSize, - RecoverGLResources + RecoverGLResources, + SetVisibleViewport }; virtual ~Message() {} diff --git a/drape_frontend/message_subclasses.hpp b/drape_frontend/message_subclasses.hpp index 67ad21e1f1..03c418a634 100644 --- a/drape_frontend/message_subclasses.hpp +++ b/drape_frontend/message_subclasses.hpp @@ -794,6 +794,20 @@ public: bool IsGLContextDependent() const override { return true; } }; +class SetVisibleViewportMessage : public Message +{ +public: + SetVisibleViewportMessage(m2::RectD const & rect) + : m_rect(rect) + {} + + Type GetType() const override { return Message::SetVisibleViewport; } + m2::RectD const & GetRect() const { return m_rect; } + +private: + m2::RectD m_rect; +}; + class DeactivateRouteFollowingMessage : public Message { public: diff --git a/drape_frontend/my_position_controller.cpp b/drape_frontend/my_position_controller.cpp index 592ea95390..ea2fc4befe 100644 --- a/drape_frontend/my_position_controller.cpp +++ b/drape_frontend/my_position_controller.cpp @@ -167,15 +167,22 @@ MyPositionController::~MyPositionController() { } -void MyPositionController::OnNewViewportRect() +void MyPositionController::UpdatePosition() { UpdateViewport(kDoNotChangeZoom); } -void MyPositionController::UpdatePixelPosition(ScreenBase const & screen) +void MyPositionController::OnUpdateScreen(ScreenBase const & screen) { m_pixelRect = screen.isPerspective() ? screen.PixelRectIn3d() : screen.PixelRect(); m_positionYOffset = screen.isPerspective() ? kPositionOffsetYIn3D : kPositionOffsetY; + if (m_visiblePixelRect.IsEmptyInterior()) + m_visiblePixelRect = m_pixelRect; +} + +void MyPositionController::SetVisibleViewport(const m2::RectD &rect) +{ + m_visiblePixelRect = rect; } void MyPositionController::SetListener(ref_ptr listener) @@ -344,7 +351,7 @@ void MyPositionController::NextMode(ScreenBase const & screen) if (!m_isInRouting) { ChangeMode(location::Follow); - ChangeModelView(m_position, 0.0, m_pixelRect.Center(), preferredZoomLevel); + ChangeModelView(m_position, 0.0, m_visiblePixelRect.Center(), preferredZoomLevel); } } } @@ -399,7 +406,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 ? GetRoutingRotationPixelCenter() : m_pixelRect.Center(), kDoNotChangeZoom); + m_isInRouting ? GetRoutingRotationPixelCenter() : m_visiblePixelRect.Center(), kDoNotChangeZoom); } } else if (m_mode == location::PendingPosition || m_mode == location::NotFollowNoPosition) @@ -635,7 +642,7 @@ void MyPositionController::OnCompassTapped() if (m_mode == location::FollowAndRotate) { ChangeMode(location::Follow); - ChangeModelView(m_position, 0.0, m_pixelRect.Center(), kDoNotChangeZoom); + ChangeModelView(m_position, 0.0, m_visiblePixelRect.Center(), kDoNotChangeZoom); } else { @@ -688,24 +695,24 @@ void MyPositionController::UpdateViewport(int zoomLevel) ChangeModelView(m_position, zoomLevel); else if (m_mode == location::FollowAndRotate) ChangeModelView(m_position, m_drawDirection, - m_isInRouting ? GetRoutingRotationPixelCenter() : m_pixelRect.Center(), zoomLevel); + m_isInRouting ? GetRoutingRotationPixelCenter() : m_visiblePixelRect.Center(), zoomLevel); } m2::PointD MyPositionController::GetRotationPixelCenter() const { if (m_mode == location::Follow) - return m_pixelRect.Center(); + return m_visiblePixelRect.Center(); if (m_mode == location::FollowAndRotate) - return m_isInRouting ? GetRoutingRotationPixelCenter() : m_pixelRect.Center(); + return m_isInRouting ? GetRoutingRotationPixelCenter() : m_visiblePixelRect.Center(); return m2::PointD::Zero(); } m2::PointD MyPositionController::GetRoutingRotationPixelCenter() const { - return m2::PointD(m_pixelRect.Center().x, - m_pixelRect.maxY() - m_positionYOffset * VisualParams::Instance().GetVisualScale()); + return m2::PointD(m_visiblePixelRect.Center().x, + m_visiblePixelRect.maxY() - m_positionYOffset * VisualParams::Instance().GetVisualScale()); } m2::PointD MyPositionController::GetDrawablePosition() @@ -806,7 +813,7 @@ void MyPositionController::DeactivateRouting() m_isInRouting = false; ChangeMode(location::Follow); - ChangeModelView(m_position, 0.0, m_pixelRect.Center(), kDoNotChangeZoom); + ChangeModelView(m_position, 0.0, m_visiblePixelRect.Center(), kDoNotChangeZoom); } } diff --git a/drape_frontend/my_position_controller.hpp b/drape_frontend/my_position_controller.hpp index 51d9ff75ef..1f11c1e7b7 100644 --- a/drape_frontend/my_position_controller.hpp +++ b/drape_frontend/my_position_controller.hpp @@ -44,8 +44,10 @@ public: bool isFirstLaunch, bool isRoutingActive, bool isAutozoomEnabled); ~MyPositionController(); - void OnNewViewportRect(); - void UpdatePixelPosition(ScreenBase const & screen); + void UpdatePosition(); + void OnUpdateScreen(ScreenBase const & screen); + void SetVisibleViewport(m2::RectD const & rect); + void SetListener(ref_ptr listener); m2::PointD const & Position() const; @@ -97,12 +99,12 @@ public: bool IsInRouting() const { return m_isInRouting; } bool IsRouteFollowingActive() const; bool IsWaitingForTimers() const; + bool IsModeChangeViewport() const; bool IsWaitingForLocation() const; m2::PointD GetDrawablePosition(); private: - bool IsModeChangeViewport() const; void ChangeMode(location::EMyPositionMode newMode); void SetDirection(double bearing); @@ -161,6 +163,7 @@ private: double m_lastLocationTimestamp; m2::RectD m_pixelRect; + m2::RectD m_visiblePixelRect; double m_positionYOffset; bool m_isVisible; diff --git a/drape_frontend/selection_shape.cpp b/drape_frontend/selection_shape.cpp index caafa84566..715cb73460 100644 --- a/drape_frontend/selection_shape.cpp +++ b/drape_frontend/selection_shape.cpp @@ -104,10 +104,10 @@ SelectionShape::SelectionShape(ref_ptr mng) batcher.InsertTriangleList(state, make_ref(&provider), nullptr); } - double r = 15.0f * VisualParams::Instance().GetVisualScale(); - m_mapping.AddRangePoint(0.6, 1.3 * r); - m_mapping.AddRangePoint(0.85, 0.8 * r); - m_mapping.AddRangePoint(1.0, r); + m_radius = 15.0f * VisualParams::Instance().GetVisualScale(); + m_mapping.AddRangePoint(0.6, 1.3 * m_radius); + m_mapping.AddRangePoint(0.85, 0.8 * m_radius); + m_mapping.AddRangePoint(1.0, m_radius); } void SelectionShape::Show(ESelectedObject obj, m2::PointD const & position, double positionZ, bool isAnimate) @@ -128,6 +128,20 @@ void SelectionShape::Hide() m_selectedObject = OBJECT_EMPTY; } +bool SelectionShape::IsVisible(ScreenBase const & screen, m2::PointD & pxPos) const +{ + m2::PointD const pt = screen.GtoP(m_position); + ShowHideAnimation::EState state = m_animation.GetState(); + + if ((state == ShowHideAnimation::STATE_VISIBLE || state == ShowHideAnimation::STATE_SHOW_DIRECTION) && + !screen.IsReverseProjection3d(pt)) + { + pxPos = screen.PtoP3d(pt, -m_positionZ); + return true; + } + return false; +} + void SelectionShape::Render(ScreenBase const & screen, int zoomLevel, ref_ptr mng, dp::UniformValuesStorage const & commonUniforms) { diff --git a/drape_frontend/selection_shape.hpp b/drape_frontend/selection_shape.hpp index 3f47a10c3a..5655033ae1 100644 --- a/drape_frontend/selection_shape.hpp +++ b/drape_frontend/selection_shape.hpp @@ -38,6 +38,9 @@ public: void Render(ScreenBase const & screen, int zoomLevel, ref_ptr mng, dp::UniformValuesStorage const & commonUniforms); + bool IsVisible(ScreenBase const & screen, m2::PointD & pxPos) const; + double GetRadius() const { return m_radius; } + ESelectedObject GetSelectedObject() const; private: @@ -46,6 +49,7 @@ private: private: m2::PointD m_position; double m_positionZ; + double m_radius; ShowHideAnimation m_animation; ESelectedObject m_selectedObject; diff --git a/drape_frontend/user_event_stream.cpp b/drape_frontend/user_event_stream.cpp index 4108da46e1..0d3ed4c5b5 100644 --- a/drape_frontend/user_event_stream.cpp +++ b/drape_frontend/user_event_stream.cpp @@ -180,6 +180,8 @@ ScreenBase const & UserEventStream::ProcessEvents(bool & modelViewChanged, bool { ref_ptr resizeEvent = make_ref(e); m_navigator.OnSize(resizeEvent->GetWidth(), resizeEvent->GetHeight()); + if (m_visibleViewport.IsEmptyInterior()) + m_visibleViewport = m2::RectD(0, 0, resizeEvent->GetWidth(), resizeEvent->GetHeight()); viewportChanged = true; breakAnim = true; TouchCancel(m_touches); @@ -236,6 +238,21 @@ ScreenBase const & UserEventStream::ProcessEvents(bool & modelViewChanged, bool SetAutoPerspective(perspectiveEvent->IsAutoPerspective()); } break; + case UserEvent::EventType::VisibleViewport: + { + ref_ptr viewportEvent = make_ref(e); + m2::RectD prevVisibleViewport = m_visibleViewport; + m_visibleViewport = viewportEvent->GetRect(); + m2::PointD gOffset; + if (m_listener->OnNewVisibleViewport(prevVisibleViewport, m_visibleViewport, gOffset)) + { + ScreenBase screen = GetCurrentScreen(); + screen.MoveG(gOffset); + SetScreen(screen, true /* isAnim */); + } + } + break; + default: ASSERT(false, ()); break; @@ -284,6 +301,11 @@ ScreenBase const & UserEventStream::GetCurrentScreen() const return m_navigator.Screen(); } +m2::RectD const & UserEventStream::GetVisibleViewport() const +{ + return m_visibleViewport; +} + bool UserEventStream::OnSetScale(ref_ptr scaleEvent) { double factor = scaleEvent->GetFactor(); @@ -359,12 +381,12 @@ bool UserEventStream::OnSetCenter(ref_ptr centerEvent) if (zoom == kDoNotChangeZoom) { GetTargetScreen(screen); - screen.MatchGandP3d(center, screen.PixelRectIn3d().Center()); + screen.MatchGandP3d(center, m_visibleViewport.Center()); } else { screen.SetFromParams(center, screen.GetAngle(), GetScale(zoom)); - screen.MatchGandP3d(center, screen.PixelRectIn3d().Center()); + screen.MatchGandP3d(center, m_visibleViewport.Center()); } ShrinkAndScaleInto(screen, df::GetWorldRect()); @@ -381,16 +403,19 @@ bool UserEventStream::SetAngle(double azimuth, TAnimationCreator const & paralle { ScreenBase screen; GetTargetScreen(screen); + m2::PointD pt = m_visibleViewport.Center(); + m2::PointD gPt = screen.PtoG(screen.P3dtoP(pt)); + if (screen.isPerspective()) { - m2::PointD pt = screen.PixelRectIn3d().Center(); - return SetFollowAndRotate(screen.PtoG(screen.P3dtoP(pt)), pt, + return SetFollowAndRotate(gPt, pt, azimuth, kDoNotChangeZoom, kDoNotAutoZoom, true /* isAnim */, false /* isAutoScale */, parallelAnimCreator); } screen.SetAngle(azimuth); + screen.MatchGandP3d(gPt, pt); return SetScreen(screen, true /* isAnim */, parallelAnimCreator); } diff --git a/drape_frontend/user_event_stream.hpp b/drape_frontend/user_event_stream.hpp index cdf2e04382..98d2fc482c 100644 --- a/drape_frontend/user_event_stream.hpp +++ b/drape_frontend/user_event_stream.hpp @@ -38,7 +38,8 @@ public: Resize, Rotate, FollowAndRotate, - AutoPerspective + AutoPerspective, + VisibleViewport }; virtual ~UserEvent() {} @@ -306,6 +307,21 @@ private: uint32_t m_height; }; +class SetVisibleViewportEvent : public UserEvent +{ +public: + SetVisibleViewportEvent(m2::RectD const & rect) + : m_rect(rect) + {} + + EventType GetType() const override { return UserEvent::EventType::VisibleViewport; } + + m2::RectD const & GetRect() const { return m_rect; } + +private: + m2::RectD m_rect; +}; + class UserEventStream { public: @@ -331,12 +347,15 @@ public: virtual void OnAnimatedScaleEnded() = 0; virtual void OnTouchMapAction() = 0; + + virtual bool OnNewVisibleViewport(m2::RectD const & oldViewport, m2::RectD const & newViewport, m2::PointD & gOffset) = 0; }; UserEventStream(); void AddEvent(drape_ptr && event); ScreenBase const & ProcessEvents(bool & modelViewChanged, bool & viewportChanged); ScreenBase const & GetCurrentScreen() const; + m2::RectD const & GetVisibleViewport() const; void GetTargetScreen(ScreenBase & screen); m2::AnyRectD GetTargetRect(); @@ -444,6 +463,8 @@ private: TEventsList m_events; mutable mutex m_lock; + m2::RectD m_visibleViewport; + Navigator m_navigator; my::Timer m_touchTimer; enum ERecognitionState -- cgit v1.2.3 From 28f41e9792827508f63027415d48ce2fa9c0e5e8 Mon Sep 17 00:00:00 2001 From: Daria Volvenkova Date: Mon, 26 Sep 2016 20:27:54 +0300 Subject: Review fixes. --- drape_frontend/frontend_renderer.cpp | 1 - drape_frontend/user_event_stream.cpp | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'drape_frontend') diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index e9bf267a5e..bb14a24a5c 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -1485,7 +1485,6 @@ bool FrontendRenderer::OnNewVisibleViewport(m2::RectD const & oldViewport, m2::R pOffset.y = newViewport.maxY() - rect.maxY() - kOffset; gOffset = screen.PtoG(screen.P3dtoP(pos + pOffset)) - screen.PtoG(screen.P3dtoP(pos)); - } return true; } diff --git a/drape_frontend/user_event_stream.cpp b/drape_frontend/user_event_stream.cpp index 0d3ed4c5b5..1f10bebd42 100644 --- a/drape_frontend/user_event_stream.cpp +++ b/drape_frontend/user_event_stream.cpp @@ -180,7 +180,7 @@ ScreenBase const & UserEventStream::ProcessEvents(bool & modelViewChanged, bool { ref_ptr resizeEvent = make_ref(e); m_navigator.OnSize(resizeEvent->GetWidth(), resizeEvent->GetHeight()); - if (m_visibleViewport.IsEmptyInterior()) + if (!m_visibleViewport.IsValid()) m_visibleViewport = m2::RectD(0, 0, resizeEvent->GetWidth(), resizeEvent->GetHeight()); viewportChanged = true; breakAnim = true; @@ -241,7 +241,7 @@ ScreenBase const & UserEventStream::ProcessEvents(bool & modelViewChanged, bool case UserEvent::EventType::VisibleViewport: { ref_ptr viewportEvent = make_ref(e); - m2::RectD prevVisibleViewport = m_visibleViewport; + m2::RectD const prevVisibleViewport = m_visibleViewport; m_visibleViewport = viewportEvent->GetRect(); m2::PointD gOffset; if (m_listener->OnNewVisibleViewport(prevVisibleViewport, m_visibleViewport, gOffset)) -- cgit v1.2.3