[drape] animation infrastucture

model view center animation class
This commit is contained in:
ExMix 2015-05-13 20:41:42 +03:00 committed by r.kuznetsov
parent a339be2827
commit 7ee6104bc9
13 changed files with 255 additions and 3 deletions

View file

@ -0,0 +1,41 @@
#include "drape_frontend/animation/base_interpolator.hpp"
#include "drape_frontend/animation/interpolation_holder.hpp"
#include "base/assert.hpp"
#include "base/logging.hpp"
namespace df
{
BaseInterpolator::BaseInterpolator(double duration)
: m_elapsedTime(0.0)
, m_duration(duration)
{
ASSERT(m_duration > 0.0, ());
InterpolationHolder::Instance().RegisterInterpolator(this);
}
BaseInterpolator::~BaseInterpolator()
{
InterpolationHolder::Instance().DeregisterInterpolator(this);
}
bool BaseInterpolator::IsFinished() const
{
return m_elapsedTime > m_duration;
}
void BaseInterpolator::Advance(double elapsedSeconds)
{
m_elapsedTime += elapsedSeconds;
}
double BaseInterpolator::GetT() const
{
if (IsFinished())
return 1.0;
return m_elapsedTime / m_duration;
}
}

View file

@ -0,0 +1,23 @@
#pragma once
namespace df
{
class BaseInterpolator
{
public:
BaseInterpolator(double duration);
virtual ~BaseInterpolator();
bool IsFinished() const;
void Advance(double elapsedSeconds);
protected:
double GetT() const;
private:
double m_elapsedTime;
double m_duration;
};
}

View file

@ -0,0 +1,16 @@
#pragma once
#include "drape_frontend/animation/base_interpolator.hpp"
#include "drape_frontend/navigator.hpp"
namespace df
{
class BaseViewportAnimation : public BaseInterpolator
{
public:
BaseViewportAnimation(double duration) : BaseInterpolator(duration) {}
virtual void Apply(Navigator & navigator) = 0;
};
}

View file

@ -0,0 +1,49 @@
#include "drape_frontend/animation/base_interpolator.hpp"
#include "drape_frontend/animation/interpolation_holder.hpp"
#include "base/assert.hpp"
#include "std/algorithm.hpp"
#include "std/bind.hpp"
namespace df
{
InterpolationHolder & InterpolationHolder::Instance()
{
static InterpolationHolder holder;
return holder;
}
bool InterpolationHolder::Advance(double elapsedSeconds)
{
bool hasAnimations = !m_interpolations.empty();
TInterpolatorSet::iterator iter = m_interpolations.begin();
while (iter != m_interpolations.end())
{
(*iter)->Advance(elapsedSeconds);
if ((*iter)->IsFinished())
iter = m_interpolations.erase(iter);
else
++iter;
}
return hasAnimations;
}
InterpolationHolder::~InterpolationHolder()
{
ASSERT(m_interpolations.empty(), ());
}
void InterpolationHolder::RegisterInterpolator(BaseInterpolator * interpolator)
{
VERIFY(m_interpolations.insert(interpolator).second, ());
}
void InterpolationHolder::DeregisterInterpolator(BaseInterpolator * interpolator)
{
m_interpolations.erase(interpolator);
}
}

View file

@ -0,0 +1,31 @@
#pragma once
#include "base/macros.hpp"
#include "std/set.hpp"
namespace df
{
class BaseInterpolator;
class InterpolationHolder
{
public:
static InterpolationHolder & Instance();
bool Advance(double elapsedSeconds);
private:
InterpolationHolder() = default;
~InterpolationHolder();
DISALLOW_COPY_AND_MOVE(InterpolationHolder)
private:
friend class BaseInterpolator;
void RegisterInterpolator(BaseInterpolator * interpolator);
void DeregisterInterpolator(BaseInterpolator * interpolator);
using TInterpolatorSet = set<BaseInterpolator *>;
TInterpolatorSet m_interpolations;
};
}

View file

@ -0,0 +1,12 @@
#include "drape_frontend/animation/interpolations.hpp"
namespace df
{
m2::PointD Interpolate(m2::PointD const & startPt, m2::PointD const & endPt, double t)
{
m2::PointD diff = endPt - startPt;
return startPt + diff * t;
}
} // namespace df

View file

@ -0,0 +1,8 @@
#pragma once
#include "geometry/point2d.hpp"
namespace df
{
m2::PointD Interpolate(m2::PointD const & startPt, m2::PointD const & endPt, double t);
} // namespace df

View file

@ -0,0 +1,22 @@
#include "drape_frontend/animation/modelview_center_animation.hpp"
#include "drape_frontend/animation/interpolations.hpp"
namespace df
{
ModelViewCenterAnimation::ModelViewCenterAnimation(m2::PointD const & start,
m2::PointD const & end,
double duration)
: BaseViewportAnimation(duration)
, m_startPt(start)
, m_endPt(end)
{
}
void ModelViewCenterAnimation::Apply(Navigator & navigator)
{
m2::PointD center = Interpolate(m_startPt, m_endPt, GetT());
navigator.CenterViewport(center);
}
}

View file

@ -0,0 +1,20 @@
#pragma once
#include "drape_frontend/animation/base_viewport_animation.hpp"
namespace df
{
class ModelViewCenterAnimation : public BaseViewportAnimation
{
public:
ModelViewCenterAnimation(m2::PointD const & start, m2::PointD const & end, double duration);
void Apply(Navigator & navigator) override;
private:
m2::PointD m_startPt;
m2::PointD m_endPt;
};
}

View file

@ -9,6 +9,10 @@ INCLUDEPATH *= $$ROOT_DIR/3party/protobuf/src
DEFINES += DRAW_INFO
SOURCES += \
animation/base_interpolator.cpp \
animation/modelview_center_animation.cpp \
animation/interpolation_holder.cpp \
animation/interpolations.cpp \
apply_feature_functors.cpp \
area_shape.cpp \
backend_renderer.cpp \
@ -45,9 +49,14 @@ SOURCES += \
viewport.cpp \
visual_params.cpp \
my_position.cpp \
user_event_stream.cpp
user_event_stream.cpp \
HEADERS += \
animation/base_viewport_animation.hpp \
animation/modelview_center_animation.hpp \
animation/interpolation_holder.hpp \
animation/interpolations.hpp \
animation/base_interpolator.hpp \
apply_feature_functors.hpp \
area_shape.hpp \
backend_renderer.hpp \
@ -89,4 +98,4 @@ HEADERS += \
viewport.hpp \
visual_params.hpp \
my_position.hpp \
user_event_stream.hpp
user_event_stream.hpp \

View file

@ -1,3 +1,4 @@
#include "drape_frontend/animation/interpolation_holder.hpp"
#include "drape_frontend/frontend_renderer.hpp"
#include "drape_frontend/message_subclasses.hpp"
#include "drape_frontend/visual_params.hpp"
@ -457,6 +458,7 @@ void FrontendRenderer::Routine::Do()
//double processingTime = InitAvarageTimePerMessage; // By init we think that one message processed by 1ms
timer.Reset();
double frameTime = 0.0;
bool isInactiveLastFrame = false;
bool viewChanged = true;
ScreenBase modelView = m_renderer.UpdateScene(viewChanged);
@ -465,9 +467,10 @@ void FrontendRenderer::Routine::Do()
context->setDefaultFramebuffer();
m_renderer.m_texMng->UpdateDynamicTextures();
m_renderer.RenderScene(modelView);
bool const animActive = InterpolationHolder::Instance().Advance(frameTime);
modelView = m_renderer.UpdateScene(viewChanged);
bool const isInactiveCurrentFrame = (!viewChanged && m_renderer.IsQueueEmpty());
bool const isInactiveCurrentFrame = (!viewChanged && m_renderer.IsQueueEmpty() && !animActive);
if (isInactiveLastFrame && isInactiveCurrentFrame)
{
@ -494,6 +497,7 @@ void FrontendRenderer::Routine::Do()
}
context->present();
frameTime = timer.ElapsedSeconds();
timer.Reset();
m_renderer.CheckRenderingEnabled();

View file

@ -1,3 +1,4 @@
#include "drape_frontend/animation/modelview_center_animation.hpp"
#include "drape_frontend/user_event_stream.hpp"
#include "drape_frontend/visual_params.hpp"
@ -97,6 +98,19 @@ ScreenBase const & UserEventStream::ProcessEvents(bool & modelViewChange, bool &
}
}
if (m_animation != nullptr)
{
if (m_state != STATE_EMPTY)
m_animation.reset();
else
{
m_animation->Apply(m_navigator);
modelViewChange = true;
if (m_animation->IsFinished())
m_animation.reset();
}
}
if (m_state == STATE_TAP_DETECTION && m_validTouchesCount == 1)
DetectLongTap(m_touches[0]);

View file

@ -1,6 +1,7 @@
#pragma once
#include "drape_frontend/navigator.hpp"
#include "drape_frontend/animation/base_viewport_animation.hpp"
#include "geometry/point2d.hpp"
#include "geometry/rect2d.hpp"
@ -209,6 +210,8 @@ private:
array<Touch, 2> m_touches;
size_t m_validTouchesCount;
unique_ptr<BaseViewportAnimation> m_animation;
#ifdef DEBUG
TTestBridge m_testFn;
#endif