Arrow's animation ported to the animation system.

This commit is contained in:
Daria Volvenkova 2016-05-17 14:55:56 +03:00
parent 152cf38bf2
commit adc8654e45
7 changed files with 160 additions and 88 deletions

View file

@ -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

View file

@ -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<PositionInterpolator> m_positionInterpolator;
drape_ptr<AngleInterpolator> m_angleInterpolator;
TAnimObjects m_objects;
TObjectProperties m_properties;
};*/
PositionInterpolator m_positionInterpolator;
AngleInterpolator m_angleInterpolator;
};
} // namespace df

View file

@ -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())

View file

@ -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;

View file

@ -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 \

View file

@ -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<Animation> 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<MyPositionAnim>(oldPos, m_position, moveDuration, oldAzimut, m_drawDirection, rotateDuration);
AnimationSystem::Instance().CombineAnimation(make_unique_dp<ArrowAnimation>(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<MyPositionAnim>(oldPos, m_position, moveDuration, oldAzimut, m_drawDirection, rotateDuration);
AnimationSystem::Instance().CombineAnimation(make_unique_dp<ArrowAnimation>(oldPos, m_position, oldAzimut,
m_drawDirection, screen));
}
}
}

View file

@ -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<MyPositionAnim> m_anim;
using TAnimationCreator = function<void()>;
TAnimationCreator m_animCreator;