animation for my position mark moving and rotating

This commit is contained in:
ExMix 2015-08-03 17:13:44 +03:00 committed by r.kuznetsov
parent 0fbd73e52c
commit 4c2e61330a
4 changed files with 117 additions and 16 deletions

View file

@ -128,8 +128,6 @@ void Extract(::LineDefProto const * lineRule,
ASSERT(false, ());
}
params.m_cap = dp::ButtCap;
switch (lineRule->join())
{
case ::NOJOIN : params.m_join = dp::MiterJoin;
@ -436,6 +434,10 @@ void ApplyLineFeature::ProcessRule(Stylist::TRuleWrapper const & rule)
Extract(pLineRule, params);
params.m_depth = depth;
params.m_baseGtoPScale = m_currentScaleGtoP;
if (m_simplify)
params.m_cap = dp::ButtCap;
m_insertShape(make_unique_dp<LineShape>(m_spline, params));
}
}

View file

@ -257,14 +257,15 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message)
case Message::CompassInfo:
{
ref_ptr<CompassInfoMessage> msg = message;
m_myPositionController->OnCompassUpdate(msg->GetInfo());
m_myPositionController->OnCompassUpdate(msg->GetInfo(), m_userEventStream.GetCurrentScreen());
break;
}
case Message::GpsInfo:
{
ref_ptr<GpsInfoMessage> msg = message;
m_myPositionController->OnLocationUpdate(msg->GetInfo(), msg->IsNavigable());
m_myPositionController->OnLocationUpdate(msg->GetInfo(), msg->IsNavigable(),
m_userEventStream.GetCurrentScreen());
location::RouteMatchingInfo const & info = msg->GetRouteInfo();
if (info.HasDistanceFromBegin())

View file

@ -1,5 +1,8 @@
#include "my_position_controller.hpp"
#include "visual_params.hpp"
#include "animation/base_interpolator.hpp"
#include "animation/interpolations.hpp"
#include "animation/model_view_animation.hpp"
#include "indexer/mercator.hpp"
@ -42,6 +45,41 @@ bool TestModeBit(uint32_t mode, uint32_t bit)
} // 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_moveDuration(moveDuration)
, m_angleInterpolator(startAzimut, endAzimut)
, m_rotateDuration(rotationDuration)
{
}
m2::PointD GetCurrentPosition() const
{
return InterpolatePoint(m_startPt, m_endPt,
my::clamp(GetElapsedTime() / m_moveDuration, 0.0, 1.0));
}
double GetCurrentAzimut() const
{
return m_angleInterpolator.Interpolate(my::clamp(GetElapsedTime() / m_rotateDuration, 0.0, 1.0));
}
private:
m2::PointD m_startPt;
m2::PointD m_endPt;
double m_moveDuration;
InerpolateAngle m_angleInterpolator;
double m_rotateDuration;
};
MyPositionController::MyPositionController(location::EMyPositionMode initMode)
: m_modeInfo(location::MODE_PENDING_POSITION)
, m_afterPendingMode(location::MODE_FOLLOW)
@ -58,6 +96,11 @@ MyPositionController::MyPositionController(location::EMyPositionMode initMode)
m_modeInfo = location::MODE_UNKNOWN_POSITION;
}
MyPositionController::~MyPositionController()
{
m_anim.reset();
}
void MyPositionController::SetPixelRect(m2::RectD const & pixelRect)
{
m_pixelRect = pixelRect;
@ -225,9 +268,10 @@ void MyPositionController::Invalidate()
}
}
void MyPositionController::OnLocationUpdate(location::GpsInfo const & info, bool isNavigable)
void MyPositionController::OnLocationUpdate(location::GpsInfo const & info, bool isNavigable,
ScreenBase const & screen)
{
Assign(info, isNavigable);
Assign(info, isNavigable, screen);
SetIsVisible(true);
@ -238,9 +282,10 @@ void MyPositionController::OnLocationUpdate(location::GpsInfo const & info, bool
}
}
void MyPositionController::OnCompassUpdate(location::CompassInfo const & info)
void MyPositionController::OnCompassUpdate(location::CompassInfo const & info,
ScreenBase const & screen)
{
Assign(info);
Assign(info, screen);
}
void MyPositionController::SetModeListener(location::TMyPositionModeChanged const & fn)
@ -261,8 +306,8 @@ void MyPositionController::Render(uint32_t renderMode, ScreenBase const & screen
m_isDirtyViewport = false;
}
m_shape->SetPosition(m_position);
m_shape->SetAzimuth(m_drawDirection);
m_shape->SetPosition(GetDrawablePosition());
m_shape->SetAzimuth(GetDrawableAzimut());
m_shape->SetIsValidAzimuth(IsRotationActive());
m_shape->SetAccuracy(m_errorRadius);
m_shape->SetRoutingMode(IsInRouting());
@ -273,6 +318,8 @@ void MyPositionController::Render(uint32_t renderMode, ScreenBase const & screen
if ((renderMode & RenderMyPosition) != 0)
m_shape->RenderMyPosition(screen, mng, commonUniforms);
}
CheckAnimFinished();
}
void MyPositionController::AnimateStateTransition(location::EMyPositionMode oldMode, location::EMyPositionMode newMode)
@ -296,8 +343,11 @@ void MyPositionController::AnimateStateTransition(location::EMyPositionMode oldM
}
}
void MyPositionController::Assign(location::GpsInfo const & info, bool isNavigable)
void MyPositionController::Assign(location::GpsInfo const & info, bool isNavigable, ScreenBase const & screen)
{
m2::PointD oldPos = GetDrawablePosition();
double oldAzimut = GetDrawableAzimut();
m2::RectD rect = MercatorBounds::MetresToXY(info.m_longitude,
info.m_latitude,
info.m_horizontalAccuracy);
@ -315,11 +365,16 @@ void MyPositionController::Assign(location::GpsInfo const & info, bool isNavigab
if (m_listener)
m_listener->PositionChanged(Position());
CreateAnim(oldPos, oldAzimut, screen);
m_isDirtyViewport = true;
}
void MyPositionController::Assign(location::CompassInfo const & info)
void MyPositionController::Assign(location::CompassInfo const & info, ScreenBase const & screen)
{
m2::PointD oldPos = GetDrawablePosition();
double oldAzimut = GetDrawableAzimut();
if ((IsInRouting() && GetMode() >= location::MODE_FOLLOW) ||
(m_lastGPSBearing.ElapsedSeconds() < GPS_BEARING_LIFETIME_S))
{
@ -327,6 +382,8 @@ void MyPositionController::Assign(location::CompassInfo const & info)
}
SetDirection(info.m_bearing);
CreateAnim(oldPos, oldAzimut, screen);
m_isDirtyViewport = true;
}
@ -440,6 +497,38 @@ m2::PointD MyPositionController::GetCurrentPixelBinding() const
return m2::PointD::Zero();
}
m2::PointD MyPositionController::GetDrawablePosition() const
{
if (m_anim)
return m_anim->GetCurrentPosition();
return Position();
}
double MyPositionController::GetDrawableAzimut() const
{
if (m_anim)
return m_anim->GetCurrentAzimut();
return m_drawDirection;
}
void MyPositionController::CheckAnimFinished() const
{
if (m_anim && m_anim->IsFinished())
m_anim.reset();
}
void MyPositionController::CreateAnim(m2::PointD const & oldPos, double oldAzimut, ScreenBase const & screen)
{
double moveDuration = ModelViewAnimation::GetMoveDuration(oldPos, m_position, screen);
double rotateDuration = ModelViewAnimation::GetRotateDuration(oldAzimut, m_drawDirection);
double maxDuration = max(moveDuration, rotateDuration);
double MAX_MY_POSITION_DURATION = 2.0; // in seconds
if (maxDuration > 0.0 && maxDuration < MAX_MY_POSITION_DURATION)
m_anim.reset(new MyPositionAnim(oldPos, m_position, moveDuration, oldAzimut, m_drawDirection, rotateDuration));
}
void MyPositionController::ActivateRouting()
{
if (!IsInRouting())

View file

@ -40,6 +40,7 @@ public:
};
MyPositionController(location::EMyPositionMode initMode);
~MyPositionController();
void SetPixelRect(m2::RectD const & pixelRect);
void SetListener(ref_ptr<Listener> listener);
@ -72,8 +73,8 @@ public:
void TurnOff();
void Invalidate();
void OnLocationUpdate(location::GpsInfo const & info, bool isNavigable);
void OnCompassUpdate(location::CompassInfo const & info);
void OnLocationUpdate(location::GpsInfo const & info, bool isNavigable, ScreenBase const & screen);
void OnCompassUpdate(location::CompassInfo const & info, ScreenBase const & screen);
void SetModeListener(location::TMyPositionModeChanged const & fn);
@ -83,8 +84,8 @@ public:
private:
void AnimateStateTransition(location::EMyPositionMode oldMode, location::EMyPositionMode newMode);
void Assign(location::GpsInfo const & info, bool isNavigable);
void Assign(location::CompassInfo const & info);
void Assign(location::GpsInfo const & info, bool isNavigable, ScreenBase const & screen);
void Assign(location::CompassInfo const & info, ScreenBase const & screen);
void SetDirection(double bearing);
void SetModeInfo(uint32_t modeInfo, bool force = false);
@ -106,6 +107,11 @@ private:
m2::PointD GetRaFPixelBinding() const;
m2::PointD GetCurrentPixelBinding() const;
m2::PointD GetDrawablePosition() const;
double GetDrawableAzimut() const;
void CheckAnimFinished() const;
void CreateAnim(m2::PointD const & oldPos, double oldAzimut, ScreenBase const & screen);
private:
// Mode bits
// {
@ -132,6 +138,9 @@ private:
bool m_isVisible;
bool m_isDirtyViewport;
class MyPositionAnim;
mutable drape_ptr<MyPositionAnim> m_anim;
};
}