Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaria Volvenkova <d.volvenkova@corp.mail.ru>2016-07-01 19:04:09 +0300
committerDaria Volvenkova <d.volvenkova@corp.mail.ru>2016-07-07 15:31:10 +0300
commitc21f80c1dea70f58c3acc2c8ba0a9235dd590476 (patch)
tree10a04b3973884fdde7ac5ddf96ea6dcb1833d339 /drape_frontend
parent5bd3d26105c12dc662d0b6e118e9b436abb093bd (diff)
Follow and pretty-follow animations fixed.
Diffstat (limited to 'drape_frontend')
-rw-r--r--drape_frontend/animation/follow_animation.cpp80
-rw-r--r--drape_frontend/animation/follow_animation.hpp20
-rw-r--r--drape_frontend/animation/interpolators.cpp58
-rw-r--r--drape_frontend/animation/interpolators.hpp38
-rw-r--r--drape_frontend/animation/linear_animation.cpp8
-rw-r--r--drape_frontend/animation/linear_animation.hpp1
-rw-r--r--drape_frontend/screen_animations.cpp40
-rw-r--r--drape_frontend/screen_animations.hpp5
-rw-r--r--drape_frontend/user_event_stream.cpp46
9 files changed, 146 insertions, 150 deletions
diff --git a/drape_frontend/animation/follow_animation.cpp b/drape_frontend/animation/follow_animation.cpp
index ba708512ea..0ddc6016ed 100644
--- a/drape_frontend/animation/follow_animation.cpp
+++ b/drape_frontend/animation/follow_animation.cpp
@@ -1,28 +1,31 @@
#include "follow_animation.hpp"
+#include "animation_constants.hpp"
#include "animation_system.hpp"
#include "base/assert.hpp"
+#include "base/logging.hpp"
namespace df
{
-MapFollowAnimation::MapFollowAnimation(m2::PointD const & globalPosition,
- double startScale, double endScale,
- double startAngle, double endAngle,
- m2::PointD const & startPixelPosition,
+MapFollowAnimation::MapFollowAnimation(ScreenBase const & screen,
+ m2::PointD const & globalUserPosition,
m2::PointD const & endPixelPosition,
- m2::RectD const & pixelRect)
+ double startScale, double endScale,
+ double startAngle, double endAngle)
: Animation(true /* couldBeInterrupted */, true /* couldBeBlended */)
, m_scaleInterpolator(startScale, endScale)
- , m_pixelPosInterpolator(startPixelPosition, endPixelPosition, pixelRect)
, m_angleInterpolator(startAngle, endAngle)
- , m_globalPosition(globalPosition)
+ , m_globalPosition(globalUserPosition)
+ , m_endPixelPosition(endPixelPosition)
{
double const duration = CalculateDuration();
m_scaleInterpolator.SetMinDuration(duration);
m_angleInterpolator.SetMinDuration(duration);
- m_pixelPosInterpolator.SetMinDuration(duration);
+
+ m_offset = screen.PtoG(screen.P3dtoP(m_endPixelPosition)) - m_globalPosition;
+ m_offsetInterpolator = PositionInterpolator(duration, 0.0, m_offset, m2::PointD(0.0, 0.0));
m_objects.insert(Animation::MapPlane);
@@ -30,7 +33,7 @@ MapFollowAnimation::MapFollowAnimation(m2::PointD const & globalPosition,
m_properties.insert(Animation::Scale);
if (m_angleInterpolator.IsActive())
m_properties.insert(Animation::Angle);
- if (m_pixelPosInterpolator.IsActive())
+ //if (m_offsetInterpolator.IsActive())
m_properties.insert(Animation::Position);
}
@@ -51,8 +54,8 @@ void MapFollowAnimation::Advance(double elapsedSeconds)
m_angleInterpolator.Advance(elapsedSeconds);
if (m_scaleInterpolator.IsActive())
m_scaleInterpolator.Advance(elapsedSeconds);
- if (m_pixelPosInterpolator.IsActive())
- m_pixelPosInterpolator.Advance(elapsedSeconds);
+ if (m_offsetInterpolator.IsActive())
+ m_offsetInterpolator.Advance(elapsedSeconds);
}
void MapFollowAnimation::Finish()
@@ -61,8 +64,8 @@ void MapFollowAnimation::Finish()
m_angleInterpolator.Finish();
if (m_scaleInterpolator.IsActive())
m_scaleInterpolator.Finish();
- if (m_pixelPosInterpolator.IsActive())
- m_pixelPosInterpolator.Finish();
+ if (m_offsetInterpolator.IsActive())
+ m_offsetInterpolator.Finish();
Animation::Finish();
}
@@ -72,8 +75,8 @@ void MapFollowAnimation::SetMaxDuration(double maxDuration)
m_angleInterpolator.SetMaxDuration(maxDuration);
if (m_scaleInterpolator.IsActive())
m_scaleInterpolator.SetMaxDuration(maxDuration);
- if (m_pixelPosInterpolator.IsActive())
- m_pixelPosInterpolator.SetMaxDuration(maxDuration);
+ if (m_offsetInterpolator.IsActive())
+ m_offsetInterpolator.SetMaxDuration(maxDuration);
}
double MapFollowAnimation::GetDuration() const
@@ -83,33 +86,13 @@ double MapFollowAnimation::GetDuration() const
double MapFollowAnimation::CalculateDuration() const
{
- return max(max(m_pixelPosInterpolator.GetDuration(),
- m_angleInterpolator.GetDuration()), m_scaleInterpolator.GetDuration());
+ return max(m_offsetInterpolator.GetDuration(),
+ max(m_angleInterpolator.GetDuration(), m_scaleInterpolator.GetDuration()));
}
bool MapFollowAnimation::IsFinished() const
{
- return m_pixelPosInterpolator.IsFinished() && m_angleInterpolator.IsFinished() &&
- m_scaleInterpolator.IsFinished();
-}
-
-// static
-m2::PointD MapFollowAnimation::CalculateCenter(ScreenBase const & screen, m2::PointD const & userPos,
- m2::PointD const & pixelPos, double azimuth)
-{
- double const scale = screen.GlobalRect().GetLocalRect().SizeX() / screen.PixelRect().SizeX();
- return CalculateCenter(scale, screen.PixelRect(), userPos, screen.P3dtoP(pixelPos), azimuth);
-}
-
-// static
-m2::PointD MapFollowAnimation::CalculateCenter(double scale, m2::RectD const & pixelRect,
- m2::PointD const & userPos, m2::PointD const & pixelPos,
- double azimuth)
-{
- m2::PointD formingVector = (pixelRect.Center() - pixelPos) * scale;
- formingVector.y = -formingVector.y;
- formingVector.Rotate(azimuth);
- return userPos + formingVector;
+ return m_angleInterpolator.IsFinished() && m_scaleInterpolator.IsFinished() && m_offsetInterpolator.IsFinished();
}
bool MapFollowAnimation::GetProperty(TObject object, TProperty property, PropertyValue & value) const
@@ -126,19 +109,24 @@ bool MapFollowAnimation::GetProperty(TObject object, TProperty property, bool ta
{
if (property == Animation::Position)
{
- ScreenBase const & screen = AnimationSystem::Instance().GetLastScreen();
- m2::RectD const pixelRect = screen.PixelRect();
+ ScreenBase tmp = AnimationSystem::Instance().GetLastScreen();
if (targetValue)
{
- // TODO: calculate target pixel position with corresponding scale
- value = PropertyValue(CalculateCenter(m_scaleInterpolator.GetTargetScale(), pixelRect, m_globalPosition,
- screen.P3dtoP(m_pixelPosInterpolator.GetTargetPosition()), m_angleInterpolator.GetTargetAngle()));
+ tmp.SetFromParams(m_globalPosition, m_angleInterpolator.GetTargetAngle(), m_scaleInterpolator.GetTargetScale());
+ tmp.MatchGandP3d(m_globalPosition, m_endPixelPosition);
}
else
{
- value = PropertyValue(CalculateCenter(m_scaleInterpolator.GetScale(), pixelRect, m_globalPosition,
- screen.P3dtoP(m_pixelPosInterpolator.GetPosition()), m_angleInterpolator.GetAngle()));
+ double scale = m_scaleInterpolator.GetScale() / m_scaleInterpolator.GetStartScale();
+ double angle = m_angleInterpolator.GetAngle() - m_angleInterpolator.GetStartAngle();
+ m2::PointD offset = m_offsetInterpolator.GetPosition() * scale;
+ offset.Rotate(angle);
+ m2::PointD pos = m_globalPosition + offset;
+
+ tmp.SetFromParams(m_globalPosition, m_angleInterpolator.GetAngle(), m_scaleInterpolator.GetScale());
+ tmp.MatchGandP3d(pos, m_endPixelPosition);
}
+ value = PropertyValue(tmp.GetOrg());
return true;
}
if (property == Animation::Angle)
@@ -162,7 +150,7 @@ bool MapFollowAnimation::HasScale() const
bool MapFollowAnimation::HasPixelOffset() const
{
- return m_pixelPosInterpolator.IsActive();
+ return m_offsetInterpolator.IsActive();
}
} // namespace df
diff --git a/drape_frontend/animation/follow_animation.hpp b/drape_frontend/animation/follow_animation.hpp
index fdfd38634b..a1da305f19 100644
--- a/drape_frontend/animation/follow_animation.hpp
+++ b/drape_frontend/animation/follow_animation.hpp
@@ -9,18 +9,11 @@ namespace df
class MapFollowAnimation : public Animation
{
public:
- MapFollowAnimation(m2::PointD const & globalPosition,
- double startScale, double endScale,
- double startAngle, double endAngle,
- m2::PointD const & startPixelPosition,
+ MapFollowAnimation(ScreenBase const & screen,
+ m2::PointD const & globalUserPosition,
m2::PointD const & endPixelPosition,
- m2::RectD const & pixelRect);
-
- static m2::PointD CalculateCenter(ScreenBase const & screen, m2::PointD const & userPos,
- m2::PointD const & pixelPos, double azimuth);
-
- static m2::PointD CalculateCenter(double scale, m2::RectD const & pixelRect,
- m2::PointD const & userPos, m2::PointD const & pixelPos, double azimuth);
+ double startScale, double endScale,
+ double startAngle, double endAngle);
Animation::Type GetType() const override { return Animation::MapFollow; }
@@ -55,10 +48,13 @@ private:
double CalculateDuration() const;
ScaleInterpolator m_scaleInterpolator;
- PositionInterpolator m_pixelPosInterpolator;
AngleInterpolator m_angleInterpolator;
+ PositionInterpolator m_offsetInterpolator;
m2::PointD const m_globalPosition;
+ m2::PointD const m_endPixelPosition;
+
+ m2::PointD m_offset;
TObjectProperties m_properties;
TAnimObjects m_objects;
diff --git a/drape_frontend/animation/interpolators.cpp b/drape_frontend/animation/interpolators.cpp
index 7570d5ee20..c427a5f090 100644
--- a/drape_frontend/animation/interpolators.cpp
+++ b/drape_frontend/animation/interpolators.cpp
@@ -87,8 +87,7 @@ PositionInterpolator::PositionInterpolator()
{}
PositionInterpolator::PositionInterpolator(double duration, double delay,
- m2::PointD const & startPosition,
- m2::PointD const & endPosition)
+ m2::PointD const & startPosition, m2::PointD const & endPosition)
: Interpolator(duration, delay)
, m_startPosition(startPosition)
, m_endPosition(endPosition)
@@ -97,14 +96,13 @@ PositionInterpolator::PositionInterpolator(double duration, double delay,
SetActive(m_startPosition != m_endPosition);
}
-PositionInterpolator::PositionInterpolator(m2::PointD const & startPosition,
- m2::PointD const & endPosition,
+PositionInterpolator::PositionInterpolator(m2::PointD const & startPosition, m2::PointD const & endPosition,
ScreenBase const & convertor)
: PositionInterpolator(0.0 /* delay */, startPosition, endPosition, convertor)
{}
-PositionInterpolator::PositionInterpolator(double delay, m2::PointD const & startPosition,
- m2::PointD const & endPosition,
+PositionInterpolator::PositionInterpolator(double delay,
+ m2::PointD const & startPosition, m2::PointD const & endPosition,
ScreenBase const & convertor)
: Interpolator(PositionInterpolator::GetMoveDuration(startPosition, endPosition, convertor), delay)
, m_startPosition(startPosition)
@@ -114,53 +112,53 @@ PositionInterpolator::PositionInterpolator(double delay, m2::PointD const & star
SetActive(m_startPosition != m_endPosition);
}
-PositionInterpolator::PositionInterpolator(m2::PointD const & startPxPosition,
- m2::PointD const & endPxPosition,
- m2::RectD const & pixelRect)
- : PositionInterpolator(0.0 /* delay */, startPxPosition, endPxPosition, pixelRect)
+PositionInterpolator::PositionInterpolator(m2::PointD const & startPosition, m2::PointD const & endPosition,
+ m2::RectD const & viewportRect, double scale)
+ : PositionInterpolator(0.0 /* delay */, startPosition, endPosition, viewportRect, scale)
{}
-PositionInterpolator::PositionInterpolator(double delay, m2::PointD const & startPxPosition,
- m2::PointD const & endPxPosition, m2::RectD const & pixelRect)
- : Interpolator(PositionInterpolator::GetPixelMoveDuration(startPxPosition, endPxPosition, pixelRect), delay)
- , m_startPosition(startPxPosition)
- , m_endPosition(endPxPosition)
- , m_position(startPxPosition)
+PositionInterpolator::PositionInterpolator(double delay,
+ m2::PointD const & startPosition, m2::PointD const & endPosition,
+ m2::RectD const & viewportRect, double scale)
+ : Interpolator(PositionInterpolator::GetMoveDuration(startPosition, endPosition, viewportRect, scale), delay)
+ , m_startPosition(startPosition)
+ , m_endPosition(endPosition)
+ , m_position(startPosition)
{
SetActive(m_startPosition != m_endPosition);
}
//static
-double PositionInterpolator::GetMoveDuration(m2::PointD const & startPosition,
- m2::PointD const & endPosition,
- ScreenBase const & convertor)
-{
- return GetPixelMoveDuration(convertor.GtoP(startPosition),
- convertor.GtoP(endPosition),
- convertor.PixelRect());
-}
-
-double PositionInterpolator::GetPixelMoveDuration(m2::PointD const & startPosition,
- m2::PointD const & endPosition,
- m2::RectD const & pixelRect)
+double PositionInterpolator::GetMoveDuration(m2::PointD const & startPosition, m2::PointD const & endPosition,
+ m2::RectD const & viewportRect, double scale)
{
double const kMinMoveDuration = 0.2;
double const kMinSpeedScalar = 0.2;
double const kMaxSpeedScalar = 7.0;
double const kEps = 1e-5;
- double const pixelLength = endPosition.Length(startPosition);
+ double const pixelLength = endPosition.Length(startPosition) / scale;
if (pixelLength < kEps)
return 0.0;
- double const minSize = min(pixelRect.SizeX(), pixelRect.SizeY());
+ double const minSize = min(viewportRect.SizeX(), viewportRect.SizeY());
if (pixelLength < kMinSpeedScalar * minSize)
return kMinMoveDuration;
double const pixelSpeed = kMaxSpeedScalar * minSize;
return CalcAnimSpeedDuration(pixelLength, pixelSpeed);
+
}
+//static
+double PositionInterpolator::GetMoveDuration(m2::PointD const & startPosition,
+ m2::PointD const & endPosition,
+ ScreenBase const & convertor)
+{
+ return GetMoveDuration(startPosition, endPosition, convertor.PixelRectIn3d(), convertor.GetScale());
+}
+
+
void PositionInterpolator::Advance(double elapsedSeconds)
{
TBase::Advance(elapsedSeconds);
diff --git a/drape_frontend/animation/interpolators.hpp b/drape_frontend/animation/interpolators.hpp
index 501cda1017..66892f2c4e 100644
--- a/drape_frontend/animation/interpolators.hpp
+++ b/drape_frontend/animation/interpolators.hpp
@@ -40,25 +40,27 @@ class PositionInterpolator: public Interpolator
public:
PositionInterpolator();
PositionInterpolator(double duration, double delay,
- m2::PointD const & startPosition,
- m2::PointD const & endPosition);
- PositionInterpolator(m2::PointD const & startPosition,
- m2::PointD const & endPosition,
+ m2::PointD const & startPosition, m2::PointD const & endPosition);
+
+ PositionInterpolator(m2::PointD const & startPosition, m2::PointD const & endPosition,
ScreenBase const & convertor);
- PositionInterpolator(double delay, m2::PointD const & startPosition,
- m2::PointD const & endPosition,
+
+ PositionInterpolator(double delay,
+ m2::PointD const & startPosition, m2::PointD const & endPosition,
ScreenBase const & convertor);
- PositionInterpolator(m2::PointD const & startPxPosition,
- m2::PointD const & endPxPosition,
- m2::RectD const & pixelRect);
- PositionInterpolator(double delay, m2::PointD const & startPxPosition,
- m2::PointD const & endPxPosition,
- m2::RectD const & pixelRect);
-
- static double GetMoveDuration(m2::PointD const & startPosition,
- m2::PointD const & endPosition, ScreenBase const & convertor);
- static double GetPixelMoveDuration(m2::PointD const & startPosition,
- m2::PointD const & endPosition, m2::RectD const & pixelRect);
+
+ PositionInterpolator(m2::PointD const & startPosition, m2::PointD const & endPosition,
+ m2::RectD const & viewportRect, double scale);
+
+ PositionInterpolator(double delay,
+ m2::PointD const & startPosition, m2::PointD const & endPosition,
+ m2::RectD const & viewportRect, double scale);
+
+ static double GetMoveDuration(m2::PointD const & startPosition, m2::PointD const & endPosition,
+ m2::RectD const & viewportRect, double scale);
+
+ static double GetMoveDuration(m2::PointD const & startPosition, m2::PointD const & endPosition,
+ ScreenBase const & convertor);
// Interpolator overrides:
void Advance(double elapsedSeconds) override;
@@ -89,6 +91,7 @@ public:
void Finish() override;
double GetScale() const { return m_scale; }
+ double GetStartScale() const { return m_startScale; }
double GetTargetScale() const { return m_endScale; }
private:
@@ -114,6 +117,7 @@ public:
void Finish() override;
double GetAngle() const { return m_angle; }
+ double GetStartAngle() const { return m_startAngle; }
double GetTargetAngle() const { return m_endAngle; }
private:
diff --git a/drape_frontend/animation/linear_animation.cpp b/drape_frontend/animation/linear_animation.cpp
index 7ff23dcdb0..048196cfc8 100644
--- a/drape_frontend/animation/linear_animation.cpp
+++ b/drape_frontend/animation/linear_animation.cpp
@@ -39,6 +39,14 @@ void MapLinearAnimation::SetMove(m2::PointD const & startPos, m2::PointD const &
m_properties.insert(Animation::Position);
}
+void MapLinearAnimation::SetMove(m2::PointD const & startPos, m2::PointD const & endPos,
+ m2::RectD const & viewportRect, double scale)
+{
+ m_positionInterpolator = PositionInterpolator(startPos, endPos, viewportRect, scale);
+ if (m_positionInterpolator.IsActive())
+ m_properties.insert(Animation::Position);
+}
+
void MapLinearAnimation::SetRotate(double startAngle, double endAngle)
{
m_angleInterpolator = AngleInterpolator(startAngle, endAngle);
diff --git a/drape_frontend/animation/linear_animation.hpp b/drape_frontend/animation/linear_animation.hpp
index 2fadc13e9c..61e3e0ba59 100644
--- a/drape_frontend/animation/linear_animation.hpp
+++ b/drape_frontend/animation/linear_animation.hpp
@@ -15,6 +15,7 @@ public:
MapLinearAnimation();
void SetMove(m2::PointD const & startPos, m2::PointD const & endPos, ScreenBase const & convertor);
+ void SetMove(m2::PointD const & startPos, m2::PointD const & endPos, m2::RectD const & viewportRect, double scale);
void SetRotate(double startAngle, double endAngle);
void SetScale(double startScale, double endScale);
diff --git a/drape_frontend/screen_animations.cpp b/drape_frontend/screen_animations.cpp
index 8a68748a8c..3f8dcb7824 100644
--- a/drape_frontend/screen_animations.cpp
+++ b/drape_frontend/screen_animations.cpp
@@ -31,7 +31,7 @@ drape_ptr<SequenceAnimation> GetPrettyMoveAnimation(ScreenBase const & screen,
drape_ptr<SequenceAnimation> GetPrettyMoveAnimation(ScreenBase const & screen, double startScale, double endScale,
m2::PointD const & startPt, m2::PointD const & endPt)
{
- double const moveDuration = PositionInterpolator::GetMoveDuration(startPt, endPt, screen);
+ double const moveDuration = PositionInterpolator::GetMoveDuration(startPt, endPt, screen.PixelRectIn3d(), startScale);
double const scaleFactor = moveDuration / kMaxAnimationTimeSec * 2.0;
auto sequenceAnim = make_unique_dp<SequenceAnimation>();
@@ -56,28 +56,36 @@ drape_ptr<SequenceAnimation> GetPrettyMoveAnimation(ScreenBase const & screen, d
return sequenceAnim;
}
-drape_ptr<SequenceAnimation> GetPrettyFollowAnimation(ScreenBase const & screen, double startScale, double endScale,
- m2::PointD const & startPt, m2::PointD const & userPos,
+drape_ptr<SequenceAnimation> GetPrettyFollowAnimation(ScreenBase const & startScreen, m2::PointD const & userPos, double targetScale,
double targetAngle, m2::PointD const & endPixelPos)
{
- double const moveDuration = PositionInterpolator::GetMoveDuration(startPt, userPos, screen);
- double const scaleFactor = moveDuration / kMaxAnimationTimeSec * 2.0;
-
auto sequenceAnim = make_unique_dp<SequenceAnimation>();
sequenceAnim->SetCustomType(kPrettyFollowAnim);
+ m2::RectD const viewportRect = startScreen.PixelRectIn3d();
+
+ ScreenBase tmp = startScreen;
+ tmp.MatchGandP3d(userPos, viewportRect.Center());
+
+ double const moveDuration = PositionInterpolator::GetMoveDuration(startScreen.GetOrg(), tmp.GetOrg(), startScreen);
+ double const scaleFactor = moveDuration / kMaxAnimationTimeSec * 2.0;
+
+ tmp = startScreen;
+ tmp.SetScale(startScreen.GetScale() * scaleFactor);
+
auto zoomOutAnim = make_unique_dp<MapLinearAnimation>();
- zoomOutAnim->SetScale(startScale, startScale * scaleFactor);
+ zoomOutAnim->SetScale(startScreen.GetScale(), tmp.GetScale());
zoomOutAnim->SetMaxDuration(kMaxAnimationTimeSec * 0.5);
- //TODO (in future): Pass fixed duration instead of screen.
+ tmp.MatchGandP3d(userPos, viewportRect.Center());
+
auto moveAnim = make_unique_dp<MapLinearAnimation>();
- moveAnim->SetMove(startPt, userPos, screen);
+ moveAnim->SetMove(startScreen.GetOrg(), tmp.GetOrg(), viewportRect, tmp.GetScale());
moveAnim->SetMaxDuration(kMaxAnimationTimeSec);
- auto followAnim = make_unique_dp<MapFollowAnimation>(userPos, startScale * scaleFactor, endScale,
- screen.GetAngle(), targetAngle,
- screen.PixelRect().Center(), endPixelPos, screen.PixelRect());
+ auto followAnim = make_unique_dp<MapFollowAnimation>(tmp, userPos, endPixelPos,
+ tmp.GetScale(), targetScale,
+ tmp.GetAngle(), targetAngle);
followAnim->SetMaxDuration(kMaxAnimationTimeSec * 0.5);
sequenceAnim->AddAnimation(move(zoomOutAnim));
@@ -91,7 +99,8 @@ drape_ptr<MapLinearAnimation> GetRectAnimation(ScreenBase const & startScreen, S
auto anim = make_unique_dp<MapLinearAnimation>();
anim->SetRotate(startScreen.GetAngle(), endScreen.GetAngle());
- anim->SetMove(startScreen.GetOrg(), endScreen.GetOrg(), startScreen);
+ anim->SetMove(startScreen.GetOrg(), endScreen.GetOrg(),
+ startScreen.PixelRectIn3d(), (startScreen.GetScale() + endScreen.GetScale()) / 2.0);
anim->SetScale(startScreen.GetScale(), endScreen.GetScale());
anim->SetMaxScaleDuration(kMaxAnimationTimeSec);
@@ -117,9 +126,8 @@ drape_ptr<MapLinearAnimation> GetSetRectAnimation(ScreenBase const & screen,
drape_ptr<MapFollowAnimation> GetFollowAnimation(ScreenBase const & startScreen, m2::PointD const & userPos,
double targetScale, double targetAngle, m2::PointD const & endPixelPos)
{
- auto anim = make_unique_dp<MapFollowAnimation>(userPos, startScreen.GetScale(), targetScale,
- startScreen.GetAngle(), targetAngle,
- startScreen.PtoP3d(startScreen.GtoP(userPos)), endPixelPos, startScreen.PixelRect());
+ auto anim = make_unique_dp<MapFollowAnimation>(startScreen, userPos, endPixelPos, startScreen.GetScale(), targetScale,
+ startScreen.GetAngle(), targetAngle);
anim->SetMaxDuration(kMaxAnimationTimeSec);
return anim;
diff --git a/drape_frontend/screen_animations.hpp b/drape_frontend/screen_animations.hpp
index 15dfa758da..9ccda398c1 100644
--- a/drape_frontend/screen_animations.hpp
+++ b/drape_frontend/screen_animations.hpp
@@ -21,9 +21,8 @@ drape_ptr<SequenceAnimation> GetPrettyMoveAnimation(ScreenBase const & screen,
drape_ptr<SequenceAnimation> GetPrettyMoveAnimation(ScreenBase const & screen, double startScale, double endScale,
m2::PointD const & startPt, m2::PointD const & endPt);
-drape_ptr<SequenceAnimation> GetPrettyFollowAnimation(ScreenBase const & screen, double startScale, double endScale,
- m2::PointD const & startPt, m2::PointD const & userPos,
- double targetAngle, m2::PointD const & endPixelPos);
+drape_ptr<SequenceAnimation> GetPrettyFollowAnimation(ScreenBase const & startScreen, m2::PointD const & userPos,
+ double targetScale, double targetAngle, m2::PointD const & endPixelPos);
drape_ptr<MapLinearAnimation> GetRectAnimation(ScreenBase const & startScreen, ScreenBase const & endScreen);
drape_ptr<MapLinearAnimation> GetSetRectAnimation(ScreenBase const & screen,
diff --git a/drape_frontend/user_event_stream.cpp b/drape_frontend/user_event_stream.cpp
index c7049d8f45..9678e51629 100644
--- a/drape_frontend/user_event_stream.cpp
+++ b/drape_frontend/user_event_stream.cpp
@@ -493,24 +493,24 @@ bool UserEventStream::InterruptFollowAnimations(bool force)
bool UserEventStream::SetFollowAndRotate(m2::PointD const & userPos, m2::PointD const & pixelPos,
double azimuth, int preferredZoomLevel, bool isAnim)
{
- // Extract target local rect from current animation or calculate it from preferredZoomLevel
- // to preserve final scale.
- m2::RectD targetLocalRect;
- if (preferredZoomLevel != kDoNotChangeZoom)
+ ScreenBase const & currentScreen = GetCurrentScreen();
+ ScreenBase screen = currentScreen;
+
+ if (preferredZoomLevel == kDoNotChangeZoom)
{
- ScreenBase newScreen = GetCurrentScreen();
- double const scale3d = newScreen.GetScale3d();
- m2::RectD r = df::GetRectForDrawScale(preferredZoomLevel, m2::PointD::Zero());
- r.Scale(scale3d);
- CheckMinGlobalRect(r, scale3d);
- CheckMinMaxVisibleScale(r, preferredZoomLevel, scale3d);
- newScreen.SetFromRect(m2::AnyRectD(r));
- targetLocalRect = newScreen.GlobalRect().GetLocalRect();
+ GetTargetScreen(screen);
+ screen.SetAngle(-azimuth);
}
else
{
- targetLocalRect = GetTargetRect().GetLocalRect();
+ screen.SetFromParams(userPos, -azimuth, GetScale(preferredZoomLevel));
}
+ screen.MatchGandP3d(userPos, pixelPos);
+
+ ASSERT_GREATER_OR_EQUAL(zoom, scales::GetUpperWorldScale(), ());
+ ASSERT_LESS_OR_EQUAL(zoom, scales::GetUpperStyleScale(), ());
+
+ ShrinkAndScaleInto(screen, df::GetWorldRect());
if (isAnim)
{
@@ -525,26 +525,21 @@ bool UserEventStream::SetFollowAndRotate(m2::PointD const & userPos, m2::PointD
};
drape_ptr<Animation> anim;
-
- ScreenBase const & screen = m_navigator.Screen();
- double const targetScale = CalculateScale(screen.PixelRect(), targetLocalRect);
- m2::PointD const startPt = GetCurrentRect().GlobalCenter();
- bool const changeZoom = preferredZoomLevel != kDoNotChangeZoom;
-
- double const moveDuration = PositionInterpolator::GetMoveDuration(startPt, userPos, screen);
+ double const moveDuration = PositionInterpolator::GetMoveDuration(currentScreen.GetOrg(), screen.GetOrg(),
+ currentScreen.PixelRectIn3d(),
+ (currentScreen.GetScale() + screen.GetScale()) / 2.0);
if (moveDuration > kMaxAnimationTimeSec)
{
// Run pretty move animation if we are far from userPos.
- double const startScale = CalculateScale(screen.PixelRect(), GetCurrentRect().GetLocalRect());
- anim = GetPrettyFollowAnimation(screen, startScale, targetScale, startPt, userPos, -azimuth, pixelPos);
+ anim = GetPrettyFollowAnimation(currentScreen, userPos, screen.GetScale(), -azimuth, pixelPos);
}
else
{
// Run follow-and-rotate animation.
- anim = GetFollowAnimation(screen, userPos, targetScale, -azimuth, pixelPos);
+ anim = GetFollowAnimation(currentScreen, userPos, screen.GetScale(), -azimuth, pixelPos);
}
- if (changeZoom)
+ if (preferredZoomLevel != kDoNotChangeZoom)
{
anim->SetCouldBeInterrupted(false);
anim->SetCouldBeBlended(false);
@@ -556,8 +551,7 @@ bool UserEventStream::SetFollowAndRotate(m2::PointD const & userPos, m2::PointD
}
ResetMapPlaneAnimations();
- m2::PointD const center = MapFollowAnimation::CalculateCenter(m_navigator.Screen(), userPos, pixelPos, -azimuth);
- m_navigator.SetFromRect(m2::AnyRectD(center, -azimuth, targetLocalRect));
+ m_navigator.SetScreen(screen);
return true;
}