forked from organicmaps/organicmaps
[drape] animation infrastucture
model view center animation class
This commit is contained in:
parent
a339be2827
commit
7ee6104bc9
13 changed files with 255 additions and 3 deletions
41
drape_frontend/animation/base_interpolator.cpp
Normal file
41
drape_frontend/animation/base_interpolator.cpp
Normal 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;
|
||||
}
|
||||
|
||||
}
|
23
drape_frontend/animation/base_interpolator.hpp
Normal file
23
drape_frontend/animation/base_interpolator.hpp
Normal 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;
|
||||
};
|
||||
|
||||
}
|
16
drape_frontend/animation/base_viewport_animation.hpp
Normal file
16
drape_frontend/animation/base_viewport_animation.hpp
Normal 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;
|
||||
};
|
||||
|
||||
}
|
49
drape_frontend/animation/interpolation_holder.cpp
Normal file
49
drape_frontend/animation/interpolation_holder.cpp
Normal 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);
|
||||
}
|
||||
|
||||
}
|
31
drape_frontend/animation/interpolation_holder.hpp
Normal file
31
drape_frontend/animation/interpolation_holder.hpp
Normal 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;
|
||||
};
|
||||
|
||||
}
|
12
drape_frontend/animation/interpolations.cpp
Normal file
12
drape_frontend/animation/interpolations.cpp
Normal 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
|
8
drape_frontend/animation/interpolations.hpp
Normal file
8
drape_frontend/animation/interpolations.hpp
Normal 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
|
22
drape_frontend/animation/modelview_center_animation.cpp
Normal file
22
drape_frontend/animation/modelview_center_animation.cpp
Normal 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);
|
||||
}
|
||||
|
||||
}
|
20
drape_frontend/animation/modelview_center_animation.hpp
Normal file
20
drape_frontend/animation/modelview_center_animation.hpp
Normal 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;
|
||||
};
|
||||
|
||||
}
|
|
@ -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 \
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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]);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue