fixed flickering during animation and two-fingers scaling.

This commit is contained in:
rachytski 2012-10-19 16:34:22 +03:00 committed by Alex Zolotarev
parent 877f0234a4
commit 5080d7ccfe
6 changed files with 76 additions and 22 deletions

View file

@ -1,6 +1,7 @@
#include "animator.hpp"
#include "rotate_screen_task.hpp"
#include "change_viewport_task.hpp"
#include "move_screen_task.hpp"
#include "framework.hpp"
#include "../anim/controller.hpp"
@ -67,6 +68,43 @@ void Animator::StopRotation()
m_rotateScreenTask.reset();
}
shared_ptr<MoveScreenTask> const & Animator::MoveScreen(m2::PointD const & startPt,
m2::PointD const & endPt,
double speed)
{
StopMoveScreen();
m_moveScreenTask.reset(new MoveScreenTask(m_framework,
startPt,
endPt,
speed));
m_framework->GetAnimController()->AddTask(m_moveScreenTask);
return m_moveScreenTask;
}
void Animator::StopMoveScreen()
{
if (m_moveScreenTask)
m_moveScreenTask->Lock();
if (m_moveScreenTask
&& !m_moveScreenTask->IsEnded()
&& !m_moveScreenTask->IsCancelled())
{
m_moveScreenTask->Cancel();
m_moveScreenTask->Unlock();
m_moveScreenTask.reset();
return;
}
if (m_moveScreenTask)
m_moveScreenTask->Unlock();
m_moveScreenTask.reset();
}
shared_ptr<ChangeViewportTask> const & Animator::ChangeViewport(m2::AnyRectD const & start,
m2::AnyRectD const & end,
double rotationSpeed)

View file

@ -8,6 +8,7 @@
class Framework;
class RotateScreenTask;
class ChangeViewportTask;
class MoveScreenTask;
/// Class, which is responsible for
/// tracking all map animations.
class Animator
@ -18,6 +19,7 @@ private:
shared_ptr<RotateScreenTask> m_rotateScreenTask;
shared_ptr<ChangeViewportTask> m_changeViewportTask;
shared_ptr<MoveScreenTask> m_moveScreenTask;
public:
@ -36,4 +38,10 @@ public:
void StopChangeViewport();
/// get screen rotation speed
double GetRotationSpeed() const;
/// move screen from one point to another
shared_ptr<MoveScreenTask> const & MoveScreen(m2::PointD const & startPt,
m2::PointD const & endPt,
double speed);
/// stopping screen movement
void StopMoveScreen();
};

View file

@ -3,6 +3,7 @@
#include "framework.hpp"
#include "compass_filter.hpp"
#include "change_viewport_task.hpp"
#include "move_screen_task.hpp"
#include "../yg/display_list.hpp"
#include "../yg/skin.hpp"
@ -502,12 +503,13 @@ namespace location
controller->Lock();
m2::AnyRectD startRect = m_framework->GetNavigator().Screen().GlobalRect();
m2::AnyRectD endRect = m2::AnyRectD(Position(),
startRect.Angle().val(),
m2::RectD(startRect.GetLocalRect()));
m2::PointD startPt = m_framework->GetNavigator().Screen().GetOrg();
m2::PointD endPt = Position();
m_framework->GetAnimator().ChangeViewport(startRect, endRect, 2);
ScreenBase const & s = m_framework->GetNavigator().Screen();
double speed = min(0.5, 0.5 * s.GtoP(startPt).Length(s.GtoP(endPt)) / 50.0);
m_framework->GetAnimator().MoveScreen(startPt, endPt, speed);
controller->Unlock();
}
@ -518,12 +520,12 @@ namespace location
controller->Lock();
m2::AnyRectD startRect = m_framework->GetNavigator().Screen().GlobalRect();
m2::AnyRectD endRect = m2::AnyRectD(Position(),
-m_compassFilter.GetHeadingRad(),
m2::RectD(startRect.GetLocalRect()));
m2::PointD startPt = m_framework->GetNavigator().Screen().GetOrg();
m2::PointD endPt = Position();
ScreenBase const & s = m_framework->GetNavigator().Screen();
double speed = min(0.5,0.5 * s.GtoP(startPt).Length(s.GtoP(endPt)) / 50.0);
shared_ptr<ChangeViewportTask> const & t = m_framework->GetAnimator().ChangeViewport(startRect, endRect, 2);
shared_ptr<MoveScreenTask> const & t = m_framework->GetAnimator().MoveScreen(startPt, endPt, speed);
t->Lock();
t->AddCallback(anim::Task::EEnded, bind(&State::SetIsCentered, this, true));
@ -547,6 +549,7 @@ namespace location
SetCompassProcessMode(ECompassDoNothing);
m_framework->GetAnimator().StopRotation();
m_framework->GetAnimator().StopChangeViewport();
m_framework->GetAnimator().StopMoveScreen();
setState(EActive);
}

View file

@ -15,14 +15,17 @@ MoveScreenTask::MoveScreenTask(Framework * framework,
void MoveScreenTask::OnStep(double ts)
{
m2::PointD oldPt = m_outPt;
anim::SegmentInterpolation::OnStep(ts);
m_framework->GetNavigator().SetOrg(m_outPt);
Navigator & nav = m_framework->GetNavigator();
nav.SetOrg(nav.Screen().GetOrg() + m_outPt - oldPt);
}
void MoveScreenTask::OnEnd(double ts)
{
anim::SegmentInterpolation::OnEnd(ts);
m_framework->GetNavigator().SetOrg(m_outPt);
Navigator & nav = m_framework->GetNavigator();
nav.SetOrg(m_outPt);
}
bool MoveScreenTask::IsVisual() const

View file

@ -398,8 +398,8 @@ void Navigator::StartScale(m2::PointD const & pt1, m2::PointD const & pt2, doubl
{
//LOG(LDEBUG, (pt1.x, pt1.y, pt2.x, pt2.y));
m_StartScreen = m_Screen;
m_StartPt1 = pt1;
m_StartPt2 = pt2;
m_StartPt1 = m_LastPt1 = pt1;
m_StartPt2 = m_LastPt2 = pt2;
m_DoCheckRotationThreshold = m_DoSupportRotation;
m_IsRotatingDuringScale = false;
@ -518,9 +518,9 @@ void Navigator::DoScale(m2::PointD const & pt1, m2::PointD const & pt2, double /
m_Screen = m_StartScreen;
/// Checking for rotation threshold.
if (m_DoCheckRotationThreshold)
{
//LOG(LINFO, ("checking the rotation threshold"));
double s = pt1.Length(pt2) / m_StartPt1.Length(m_StartPt2);
double a = ang::AngleTo(pt1, pt2) - ang::AngleTo(m_StartPt1, m_StartPt2);
@ -534,22 +534,22 @@ void Navigator::DoScale(m2::PointD const & pt1, m2::PointD const & pt2, double /
{
if (isRotationOutBounds)
{
//LOG(LINFO, ("rotating during scale"));
m_IsRotatingDuringScale = true;
m_DoCheckRotationThreshold = false;
}
}
else
{
//LOG(LINFO, ("not rotating during scale"));
m_IsRotatingDuringScale = false;
m_DoCheckRotationThreshold = false;
}
}
m_Screen = PrevScreen;
if (!ScaleImpl(pt1, pt2,
m_StartPt1, m_StartPt2,
pt1.Length(pt2) / m_StartPt1.Length(m_StartPt2) > 1,
m_LastPt1, m_LastPt2,
pt1.Length(pt2) / m_LastPt1.Length(m_LastPt2) > 1,
m_IsRotatingDuringScale))
m_Screen = PrevScreen;
@ -559,7 +559,6 @@ void Navigator::DoScale(m2::PointD const & pt1, m2::PointD const & pt2, double /
void Navigator::StopScale(m2::PointD const & pt1, m2::PointD const & pt2, double timeInSec)
{
// Ensure that final pos is reached.
DoScale(pt1, pt2, timeInSec);
ASSERT(m_LastPt1 == pt1, (m_LastPt1.x, m_LastPt1.y, pt1.x, pt1.y));
ASSERT(m_LastPt2 == pt2, (m_LastPt2.x, m_LastPt2.y, pt2.x, pt2.y));

View file

@ -15,14 +15,17 @@ RotateScreenTask::RotateScreenTask(Framework * framework,
void RotateScreenTask::OnStep(double ts)
{
double prevAngle = m_outAngle;
anim::AngleInterpolation::OnStep(ts);
m_framework->GetNavigator().SetAngle(m_outAngle);
Navigator & nav = m_framework->GetNavigator();
nav.SetAngle(nav.Screen().GetAngle() + m_outAngle - prevAngle);
}
void RotateScreenTask::OnEnd(double ts)
{
anim::AngleInterpolation::OnEnd(ts);
m_framework->GetNavigator().SetAngle(m_outAngle);
Navigator & nav = m_framework->GetNavigator();
nav.SetAngle(m_outAngle);
}
bool RotateScreenTask::IsVisual() const