From adc8654e4583d8b55924331efd7fde3bb161584a Mon Sep 17 00:00:00 2001 From: Daria Volvenkova Date: Tue, 17 May 2016 14:55:56 +0300 Subject: [PATCH] Arrow's animation ported to the animation system. --- drape_frontend/animation/arrow_animation.cpp | 109 +++++++++++++++++++ drape_frontend/animation/arrow_animation.hpp | 37 +++---- drape_frontend/animation_system.cpp | 22 ++++ drape_frontend/animation_system.hpp | 3 + drape_frontend/drape_frontend.pro | 1 + drape_frontend/my_position_controller.cpp | 72 ++---------- drape_frontend/my_position_controller.hpp | 4 - 7 files changed, 160 insertions(+), 88 deletions(-) create mode 100644 drape_frontend/animation/arrow_animation.cpp diff --git a/drape_frontend/animation/arrow_animation.cpp b/drape_frontend/animation/arrow_animation.cpp new file mode 100644 index 0000000000..ce7aafa4e5 --- /dev/null +++ b/drape_frontend/animation/arrow_animation.cpp @@ -0,0 +1,109 @@ +#include "arrow_animation.hpp" + +namespace df +{ + +ArrowAnimation::ArrowAnimation(m2::PointD const & startPos, m2::PointD const & endPos, + double startAngle, double endAngle, ScreenBase const & convertor) + : Animation(true /* couldBeInterrupted */, true /* couldBeBlended */) + , m_positionInterpolator(startPos, endPos, convertor) + , m_angleInterpolator(startAngle, endAngle) +{ + m_objects.insert(Animation::MyPositionArrow); + if (m_positionInterpolator.IsActive()) + m_properties.insert(Animation::Position); + if (m_angleInterpolator.IsActive()) + m_properties.insert(Animation::Angle); +} + +Animation::TAnimObjects const & ArrowAnimation::GetObjects() const +{ + return m_objects; +} + +bool ArrowAnimation::HasObject(TObject object) const +{ + return object == Animation::MyPositionArrow; +} + +Animation::TObjectProperties const & ArrowAnimation::GetProperties(TObject object) const +{ + return m_properties; +} + +bool ArrowAnimation::HasProperty(TObject object, TProperty property) const +{ + return HasObject(object) && m_properties.find(property) != m_properties.end(); +} + +void ArrowAnimation::Advance(double elapsedSeconds) +{ + if (m_positionInterpolator.IsActive()) + m_positionInterpolator.Advance(elapsedSeconds); + + if (m_angleInterpolator.IsActive()) + m_angleInterpolator.Advance(elapsedSeconds); +} + +void ArrowAnimation::Finish() +{ + if (m_positionInterpolator.IsActive()) + m_positionInterpolator.Finish(); + + if (m_angleInterpolator.IsActive()) + m_angleInterpolator.Finish(); +} + +void ArrowAnimation::SetMaxDuration(double maxDuration) +{ + if (m_positionInterpolator.IsActive()) + m_positionInterpolator.SetMaxDuration(maxDuration); + + if (m_angleInterpolator.IsActive()) + m_angleInterpolator.SetMaxDuration(maxDuration); +} + +double ArrowAnimation::GetDuration() const +{ + double duration = 0.0; + if (m_angleInterpolator.IsActive()) + duration = m_angleInterpolator.GetDuration(); + if (m_positionInterpolator.IsActive()) + duration = max(duration, m_positionInterpolator.GetDuration()); + return duration; +} + +bool ArrowAnimation::IsFinished() const +{ + return m_positionInterpolator.IsFinished() && m_angleInterpolator.IsFinished(); +} + +bool ArrowAnimation::GetProperty(TObject object, TProperty property, PropertyValue & value) const +{ + ASSERT_EQUAL(object, Animation::MyPositionArrow, ()); + + switch (property) + { + case Animation::Position: + if (m_positionInterpolator.IsActive()) + { + value = PropertyValue(m_positionInterpolator.GetPosition()); + return true; + } + return false; + case Animation::Angle: + if (m_angleInterpolator.IsActive()) + { + value = PropertyValue(m_angleInterpolator.GetAngle()); + return true; + } + return false; + default: + ASSERT(false, ("Wrong property:", property)); + } + + return false; +} + + +} // namespace df diff --git a/drape_frontend/animation/arrow_animation.hpp b/drape_frontend/animation/arrow_animation.hpp index cbb6140246..e7a73a9a4c 100644 --- a/drape_frontend/animation/arrow_animation.hpp +++ b/drape_frontend/animation/arrow_animation.hpp @@ -6,44 +6,33 @@ namespace df { -//TODO (in future): implement arrow animation on new animation system. -/*class ArrowAnimation : public Animation +class ArrowAnimation : public Animation { public: ArrowAnimation(m2::PointD const & startPos, m2::PointD const & endPos, - double startAngle, double endAngle, ScreenBase const & convertor) - : Animation(false, false) - { - m_positionInterpolator.reset(new PositionInterpolator(startPos, endPos, convertor)); - m_angleInterpolator.reset(new AngleInterpolator(startAngle, endAngle)); - m_objects.insert(Animation::MyPositionArrow); - m_properties.insert(Animation::Position); - m_properties.insert(Animation::Angle); - } + double startAngle, double endAngle, ScreenBase const & convertor); Animation::Type GetType() const override { return Animation::Arrow; } - TAnimObjects const & GetObjects() const override - { - return m_objects; - } - - bool HasObject(TObject object) const override - { - return object == Animation::MyPositionArrow; - } - + TAnimObjects const & GetObjects() const override; + bool HasObject(TObject object) const override; TObjectProperties const & GetProperties(TObject object) const override; bool HasProperty(TObject object, TProperty property) const override; + void SetMaxDuration(double maxDuration) override; + double GetDuration() const override; + bool IsFinished() const override; + void Advance(double elapsedSeconds) override; void Finish() override; + bool GetProperty(TObject object, TProperty property, PropertyValue & value) const override; + private: - drape_ptr m_positionInterpolator; - drape_ptr m_angleInterpolator; TAnimObjects m_objects; TObjectProperties m_properties; -};*/ + PositionInterpolator m_positionInterpolator; + AngleInterpolator m_angleInterpolator; +}; } // namespace df diff --git a/drape_frontend/animation_system.cpp b/drape_frontend/animation_system.cpp index fc418e9eaa..0fd9b861f0 100644 --- a/drape_frontend/animation_system.cpp +++ b/drape_frontend/animation_system.cpp @@ -122,6 +122,28 @@ bool AnimationSystem::SwitchPerspective(Animation::SwitchPerspectiveParams & par return false; } +bool AnimationSystem::GetArrowPosition(m2::PointD & position) +{ + Animation::PropertyValue value; + if (GetProperty(Animation::Arrow, Animation::Position, value)) + { + position = value.m_valuePointD; + return true; + } + return false; +} + +bool AnimationSystem::GetArrowAngle(double & angle) +{ + Animation::PropertyValue value; + if (GetProperty(Animation::Arrow, Animation::Angle, value)) + { + angle = value.m_valueD; + return true; + } + return false; +} + bool AnimationSystem::AnimationExists(Animation::TObject object) const { if (!m_animationChain.empty()) diff --git a/drape_frontend/animation_system.hpp b/drape_frontend/animation_system.hpp index 2f8a2c17d1..481ac89781 100644 --- a/drape_frontend/animation_system.hpp +++ b/drape_frontend/animation_system.hpp @@ -22,6 +22,9 @@ public: bool SwitchPerspective(Animation::SwitchPerspectiveParams & params); bool GetPerspectiveAngle(double & angle); + bool GetArrowPosition(m2::PointD & position); + bool GetArrowAngle(double & angle); + bool AnimationExists(Animation::TObject object) const; bool HasAnimations() const; diff --git a/drape_frontend/drape_frontend.pro b/drape_frontend/drape_frontend.pro index 71595a4335..332b9e4344 100755 --- a/drape_frontend/drape_frontend.pro +++ b/drape_frontend/drape_frontend.pro @@ -13,6 +13,7 @@ INCLUDEPATH *= $$ROOT_DIR/3party/freetype/include SOURCES += \ $$ROOT_DIR/3party/agg/agg_curves.cpp \ animation/animation.cpp \ + animation/arrow_animation.cpp \ animation/base_interpolator.cpp \ animation/follow_animation.cpp \ animation/interpolation_holder.cpp \ diff --git a/drape_frontend/my_position_controller.cpp b/drape_frontend/my_position_controller.cpp index 874b476023..9e489f1a15 100644 --- a/drape_frontend/my_position_controller.cpp +++ b/drape_frontend/my_position_controller.cpp @@ -3,9 +3,7 @@ #include "drape_frontend/animation_utils.hpp" #include "drape_frontend/visual_params.hpp" #include "drape_frontend/user_event_stream.hpp" -#include "drape_frontend/animation/base_interpolator.hpp" -#include "drape_frontend/animation/interpolations.hpp" -#include "drape_frontend/animation/interpolators.hpp" +#include "drape_frontend/animation/arrow_animation.hpp" #include "indexer/scales.hpp" @@ -67,47 +65,6 @@ int GetZoomLevel(ScreenBase const & screen, m2::PointD const & position, double } // namespace -class MyPositionController::MyPositionAnim : public BaseInterpolator -{ - using TBase = BaseInterpolator; -public: - MyPositionAnim(m2::PointD const & startPt, m2::PointD const & endPt, double moveDuration, - double startAzimut, double endAzimut, double rotationDuration) - : TBase(max(moveDuration, rotationDuration)) - , m_startPt(startPt) - , m_endPt(endPt) - , m_startAzimut(startAzimut) - , m_endAzimut(endAzimut) - , m_moveDuration(moveDuration) - , m_rotateDuration(rotationDuration) - { - } - - m2::PointD GetCurrentPosition() const - { - return InterpolatePoint(m_startPt, m_endPt, - my::clamp(GetElapsedTime() / m_moveDuration, 0.0, 1.0)); - } - - bool IsMovingActive() const { return m_moveDuration > 0.0; } - - double GetCurrentAzimut() const - { - return InterpolateAngle(m_startAzimut, m_endAzimut, - my::clamp(GetElapsedTime() / m_rotateDuration, 0.0, 1.0)); - } - - bool IsRotatingActive() const { return m_rotateDuration > 0.0; } - -private: - m2::PointD m_startPt; - m2::PointD m_endPt; - double m_startAzimut; - double m_endAzimut; - double m_moveDuration; - double m_rotateDuration; -}; - MyPositionController::MyPositionController(location::EMyPositionMode initMode, double timeInBackground, bool isFirstLaunch, bool isRoutingActive) : m_mode(location::PendingPosition) @@ -144,7 +101,6 @@ MyPositionController::MyPositionController(location::EMyPositionMode initMode, d MyPositionController::~MyPositionController() { - m_anim.reset(); } void MyPositionController::OnNewPixelRect() @@ -492,8 +448,6 @@ void MyPositionController::Render(uint32_t renderMode, ScreenBase const & screen if ((renderMode & RenderMyPosition) != 0) m_shape->RenderMyPosition(screen, mng, commonUniforms); } - - CheckAnimFinished(); } bool MyPositionController::IsRouteFollowingActive() const @@ -635,8 +589,9 @@ m2::PointD MyPositionController::GetRoutingRotationPixelCenter() const m2::PointD MyPositionController::GetDrawablePosition() const { - if (m_anim != nullptr && m_anim->IsMovingActive()) - return m_anim->GetCurrentPosition(); + m2::PointD position; + if (AnimationSystem::Instance().GetArrowPosition(position)) + return position; if (m_isPendingAnimation) return m_oldPosition; @@ -646,8 +601,9 @@ m2::PointD MyPositionController::GetDrawablePosition() const double MyPositionController::GetDrawableAzimut() const { - if (m_anim != nullptr && m_anim->IsRotatingActive()) - return m_anim->GetCurrentAzimut(); + double angle; + if (AnimationSystem::Instance().GetArrowAngle(angle)) + return angle; if (m_isPendingAnimation) return m_oldDrawDirection; @@ -655,12 +611,6 @@ double MyPositionController::GetDrawableAzimut() const return m_drawDirection; } -void MyPositionController::CheckAnimFinished() const -{ - if (m_anim && m_anim->IsFinished()) - m_anim.reset(); -} - void MyPositionController::AnimationStarted(ref_ptr anim) { if (m_isPendingAnimation && m_animCreator != nullptr && anim != nullptr && @@ -680,9 +630,10 @@ void MyPositionController::CreateAnim(m2::PointD const & oldPos, double oldAzimu { if (IsModeChangeViewport()) { - m_animCreator = [this, oldPos, moveDuration, oldAzimut, rotateDuration]() + m_animCreator = [this, oldPos, oldAzimut, screen]() { - m_anim = make_unique_dp(oldPos, m_position, moveDuration, oldAzimut, m_drawDirection, rotateDuration); + AnimationSystem::Instance().CombineAnimation(make_unique_dp(oldPos, m_position, oldAzimut, + m_drawDirection, screen)); }; m_oldPosition = oldPos; m_oldDrawDirection = oldAzimut; @@ -690,7 +641,8 @@ void MyPositionController::CreateAnim(m2::PointD const & oldPos, double oldAzimu } else { - m_anim = make_unique_dp(oldPos, m_position, moveDuration, oldAzimut, m_drawDirection, rotateDuration); + AnimationSystem::Instance().CombineAnimation(make_unique_dp(oldPos, m_position, oldAzimut, + m_drawDirection, screen)); } } } diff --git a/drape_frontend/my_position_controller.hpp b/drape_frontend/my_position_controller.hpp index 3d350dc302..df7d0d049d 100644 --- a/drape_frontend/my_position_controller.hpp +++ b/drape_frontend/my_position_controller.hpp @@ -121,7 +121,6 @@ private: m2::PointD GetRoutingRotationPixelCenter() const; double GetDrawableAzimut() const; - void CheckAnimFinished() const; void CreateAnim(m2::PointD const & oldPos, double oldAzimut, ScreenBase const & screen); bool AlmostCurrentPosition(m2::PointD const & pos) const; @@ -162,9 +161,6 @@ private: bool m_isDirtyViewport; bool m_isPendingAnimation; - class MyPositionAnim; - mutable drape_ptr m_anim; - using TAnimationCreator = function; TAnimationCreator m_animCreator;