forked from organicmaps/organicmaps
Merge pull request #3734 from darina/smooth-perspective
Smooth perspective
This commit is contained in:
commit
55857f993f
45 changed files with 809 additions and 937 deletions
|
@ -19,7 +19,6 @@ public:
|
|||
MapLinear,
|
||||
MapScale,
|
||||
MapFollow,
|
||||
MapPerspective,
|
||||
Arrow,
|
||||
KineticScroll
|
||||
};
|
||||
|
@ -35,28 +34,7 @@ public:
|
|||
{
|
||||
Position,
|
||||
Scale,
|
||||
Angle,
|
||||
AnglePerspective,
|
||||
SwitchPerspective
|
||||
};
|
||||
|
||||
struct SwitchPerspectiveParams
|
||||
{
|
||||
SwitchPerspectiveParams() = default;
|
||||
|
||||
SwitchPerspectiveParams(bool enable,
|
||||
double startAngle, double endAngle,
|
||||
double angleFOV)
|
||||
: m_enable(enable)
|
||||
, m_startAngle(startAngle)
|
||||
, m_endAngle(endAngle)
|
||||
, m_angleFOV(angleFOV)
|
||||
{}
|
||||
|
||||
bool m_enable = false;
|
||||
double m_startAngle = 0.0;
|
||||
double m_endAngle = 0.0;
|
||||
double m_angleFOV = 0.0;
|
||||
Angle
|
||||
};
|
||||
|
||||
struct PropertyValue
|
||||
|
@ -64,8 +42,7 @@ public:
|
|||
enum Type
|
||||
{
|
||||
ValueD,
|
||||
ValuePointD,
|
||||
ValuePerspectiveParams
|
||||
ValuePointD
|
||||
};
|
||||
|
||||
PropertyValue()
|
||||
|
@ -81,18 +58,11 @@ public:
|
|||
, m_valuePointD(value)
|
||||
{}
|
||||
|
||||
explicit PropertyValue(SwitchPerspectiveParams const & params)
|
||||
: m_type(ValuePerspectiveParams)
|
||||
{
|
||||
m_valuePerspectiveParams = params;
|
||||
}
|
||||
|
||||
Type m_type;
|
||||
union
|
||||
{
|
||||
m2::PointD m_valuePointD;
|
||||
double m_valueD;
|
||||
SwitchPerspectiveParams m_valuePerspectiveParams;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -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_scaleInterpolator.IsActive() || m_angleInterpolator.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, 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,17 +109,24 @@ bool MapFollowAnimation::GetProperty(TObject object, TProperty property, bool ta
|
|||
{
|
||||
if (property == Animation::Position)
|
||||
{
|
||||
m2::RectD const pixelRect = AnimationSystem::Instance().GetLastScreen().PixelRect();
|
||||
ScreenBase tmp = AnimationSystem::Instance().GetLastScreen();
|
||||
if (targetValue)
|
||||
{
|
||||
value = PropertyValue(CalculateCenter(m_scaleInterpolator.GetTargetScale(), pixelRect, m_globalPosition,
|
||||
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,
|
||||
m_pixelPosInterpolator.GetPosition(), m_angleInterpolator.GetAngle()));
|
||||
double const scale = m_scaleInterpolator.GetScale() / m_scaleInterpolator.GetStartScale();
|
||||
double const 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)
|
||||
|
@ -160,7 +150,7 @@ bool MapFollowAnimation::HasScale() const
|
|||
|
||||
bool MapFollowAnimation::HasPixelOffset() const
|
||||
{
|
||||
return m_pixelPosInterpolator.IsActive();
|
||||
return m_offsetInterpolator.IsActive();
|
||||
}
|
||||
|
||||
} // namespace df
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,52 +112,51 @@ 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,
|
||||
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) / scale;
|
||||
if (pixelLength < kEps)
|
||||
return 0.0;
|
||||
|
||||
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 GetPixelMoveDuration(convertor.GtoP(startPosition),
|
||||
convertor.GtoP(endPosition),
|
||||
convertor.PixelRect());
|
||||
return GetMoveDuration(startPosition, endPosition, convertor.PixelRectIn3d(), convertor.GetScale());
|
||||
}
|
||||
|
||||
double PositionInterpolator::GetPixelMoveDuration(m2::PointD const & startPosition,
|
||||
m2::PointD const & endPosition,
|
||||
m2::RectD const & pixelRect)
|
||||
{
|
||||
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);
|
||||
if (pixelLength < kEps)
|
||||
return 0.0;
|
||||
|
||||
double const minSize = min(pixelRect.SizeX(), pixelRect.SizeY());
|
||||
if (pixelLength < kMinSpeedScalar * minSize)
|
||||
return kMinMoveDuration;
|
||||
|
||||
double const pixelSpeed = kMaxSpeedScalar * minSize;
|
||||
return CalcAnimSpeedDuration(pixelLength, pixelSpeed);
|
||||
}
|
||||
|
||||
void PositionInterpolator::Advance(double elapsedSeconds)
|
||||
{
|
||||
|
|
|
@ -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,
|
||||
ScreenBase const & convertor);
|
||||
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);
|
||||
m2::PointD const & startPosition, m2::PointD const & endPosition);
|
||||
|
||||
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,
|
||||
ScreenBase const & convertor);
|
||||
|
||||
PositionInterpolator(double delay,
|
||||
m2::PointD const & startPosition, m2::PointD const & endPosition,
|
||||
ScreenBase const & convertor);
|
||||
|
||||
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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -1,121 +0,0 @@
|
|||
#include "perspective_animation.hpp"
|
||||
|
||||
namespace df
|
||||
{
|
||||
|
||||
PerspectiveSwitchAnimation::PerspectiveSwitchAnimation(double startAngle, double endAngle, double angleFOV)
|
||||
: Animation(false /* couldBeInterrupted */, false /* couldBeBlended */)
|
||||
, m_angleInterpolator(GetRotateDuration(startAngle, endAngle), startAngle, endAngle)
|
||||
, m_startAngle(startAngle)
|
||||
, m_endAngle(endAngle)
|
||||
, m_angleFOV(angleFOV)
|
||||
, m_isEnablePerspectiveAnim(m_endAngle > 0.0)
|
||||
, m_needPerspectiveSwitch(false)
|
||||
{
|
||||
m_objects.insert(Animation::MapPlane);
|
||||
m_properties.insert(Animation::AnglePerspective);
|
||||
m_properties.insert(Animation::SwitchPerspective);
|
||||
}
|
||||
|
||||
// static
|
||||
double PerspectiveSwitchAnimation::GetRotateDuration(double startAngle, double endAngle)
|
||||
{
|
||||
double const kScalar = 0.5;
|
||||
return kScalar * fabs(endAngle - startAngle) / math::pi4;
|
||||
}
|
||||
|
||||
Animation::TObjectProperties const & PerspectiveSwitchAnimation::GetProperties(TObject object) const
|
||||
{
|
||||
ASSERT_EQUAL(object, Animation::MapPlane, ());
|
||||
return m_properties;
|
||||
}
|
||||
|
||||
bool PerspectiveSwitchAnimation::HasProperty(TObject object, TProperty property) const
|
||||
{
|
||||
return HasObject(object) && m_properties.find(property) != m_properties.end();
|
||||
}
|
||||
|
||||
bool PerspectiveSwitchAnimation::HasTargetProperty(TObject object, TProperty property) const
|
||||
{
|
||||
return HasObject(object) && property == Animation::SwitchPerspective;
|
||||
}
|
||||
|
||||
void PerspectiveSwitchAnimation::Advance(double elapsedSeconds)
|
||||
{
|
||||
m_angleInterpolator.Advance(elapsedSeconds);
|
||||
}
|
||||
|
||||
void PerspectiveSwitchAnimation::Finish()
|
||||
{
|
||||
m_angleInterpolator.Finish();
|
||||
Animation::Finish();
|
||||
}
|
||||
|
||||
void PerspectiveSwitchAnimation::OnStart()
|
||||
{
|
||||
if (m_isEnablePerspectiveAnim)
|
||||
m_needPerspectiveSwitch = true;
|
||||
Animation::OnStart();
|
||||
}
|
||||
|
||||
void PerspectiveSwitchAnimation::OnFinish()
|
||||
{
|
||||
if (!m_isEnablePerspectiveAnim)
|
||||
m_needPerspectiveSwitch = true;
|
||||
Animation::OnFinish();
|
||||
}
|
||||
|
||||
void PerspectiveSwitchAnimation::SetMaxDuration(double maxDuration)
|
||||
{
|
||||
m_angleInterpolator.SetMaxDuration(maxDuration);
|
||||
}
|
||||
|
||||
double PerspectiveSwitchAnimation::GetDuration() const
|
||||
{
|
||||
return m_angleInterpolator.GetDuration();
|
||||
}
|
||||
|
||||
bool PerspectiveSwitchAnimation::IsFinished() const
|
||||
{
|
||||
return m_angleInterpolator.IsFinished();
|
||||
}
|
||||
|
||||
bool PerspectiveSwitchAnimation::GetTargetProperty(TObject object, TProperty property, PropertyValue & value) const
|
||||
{
|
||||
ASSERT_EQUAL(object, Animation::MapPlane, ());
|
||||
|
||||
if (property == Animation::SwitchPerspective)
|
||||
{
|
||||
value = PropertyValue(SwitchPerspectiveParams(m_isEnablePerspectiveAnim, m_endAngle, m_endAngle, m_angleFOV));
|
||||
return true;
|
||||
}
|
||||
|
||||
ASSERT(false, ("Wrong property:", property));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PerspectiveSwitchAnimation::GetProperty(TObject object, TProperty property, PropertyValue & value) const
|
||||
{
|
||||
ASSERT_EQUAL(object, Animation::MapPlane, ());
|
||||
|
||||
switch (property)
|
||||
{
|
||||
case Animation::AnglePerspective:
|
||||
value = PropertyValue(m_angleInterpolator.GetAngle());
|
||||
return true;
|
||||
case Animation::SwitchPerspective:
|
||||
if (m_needPerspectiveSwitch)
|
||||
{
|
||||
m_needPerspectiveSwitch = false;
|
||||
value = PropertyValue(SwitchPerspectiveParams(m_isEnablePerspectiveAnim, m_startAngle, m_endAngle, m_angleFOV));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
default:
|
||||
ASSERT(false, ("Wrong property:", property));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace df
|
|
@ -1,58 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "animation.hpp"
|
||||
#include "interpolators.hpp"
|
||||
|
||||
namespace df
|
||||
{
|
||||
|
||||
class PerspectiveSwitchAnimation : public Animation
|
||||
{
|
||||
public:
|
||||
PerspectiveSwitchAnimation(double startAngle, double endAngle, double angleFOV);
|
||||
|
||||
static double GetRotateDuration(double startAngle, double endAngle);
|
||||
|
||||
Animation::Type GetType() const override { return Animation::MapPerspective; }
|
||||
|
||||
TAnimObjects const & GetObjects() const override
|
||||
{
|
||||
return m_objects;
|
||||
}
|
||||
|
||||
bool HasObject(TObject object) const override
|
||||
{
|
||||
return m_objects.find(object) != m_objects.end();
|
||||
}
|
||||
|
||||
TObjectProperties const & GetProperties(TObject object) const override;
|
||||
bool HasProperty(TObject object, TProperty property) const override;
|
||||
bool HasTargetProperty(TObject object, TProperty property) const override;
|
||||
|
||||
void Advance(double elapsedSeconds) override;
|
||||
void Finish() override;
|
||||
|
||||
void OnStart() override;
|
||||
void OnFinish() override;
|
||||
|
||||
void SetMaxDuration(double maxDuration) override;
|
||||
double GetDuration() const override;
|
||||
bool IsFinished() const override;
|
||||
|
||||
bool GetProperty(TObject object, TProperty property, PropertyValue & value) const override;
|
||||
bool GetTargetProperty(TObject object, TProperty property, PropertyValue & value) const override;
|
||||
|
||||
private:
|
||||
AngleInterpolator m_angleInterpolator;
|
||||
double m_startAngle;
|
||||
double m_endAngle;
|
||||
double m_angleFOV;
|
||||
|
||||
bool m_isEnablePerspectiveAnim;
|
||||
mutable bool m_needPerspectiveSwitch;
|
||||
TAnimObjects m_objects;
|
||||
TObjectProperties m_properties;
|
||||
};
|
||||
|
||||
} // namespace df
|
||||
|
|
@ -8,10 +8,10 @@ namespace df
|
|||
{
|
||||
|
||||
MapScaleAnimation::MapScaleAnimation(double startScale, double endScale, m2::PointD const & globalScaleCenter,
|
||||
m2::PointD const & pixelCenterOffset)
|
||||
m2::PointD const & pxScaleCenter)
|
||||
: Animation(true /* couldBeInterrupted */, true /* couldBeBlended */)
|
||||
, m_scaleInterpolator(startScale, endScale)
|
||||
, m_pixelCenterOffset(pixelCenterOffset)
|
||||
, m_pxScaleCenter(pxScaleCenter)
|
||||
, m_globalScaleCenter(globalScaleCenter)
|
||||
{
|
||||
m_objects.insert(Animation::MapPlane);
|
||||
|
@ -64,7 +64,8 @@ bool MapScaleAnimation::GetProperty(TObject object, TProperty property, bool tar
|
|||
{
|
||||
ScreenBase screen = AnimationSystem::Instance().GetLastScreen();
|
||||
screen.SetScale(targetValue ? m_scaleInterpolator.GetTargetScale() : m_scaleInterpolator.GetScale());
|
||||
value = PropertyValue(screen.PtoG(screen.GtoP(m_globalScaleCenter) + m_pixelCenterOffset));
|
||||
m2::PointD const pixelOffset = screen.PixelRect().Center() - screen.P3dtoP(m_pxScaleCenter);
|
||||
value = PropertyValue(screen.PtoG(screen.GtoP(m_globalScaleCenter) + pixelOffset));
|
||||
return true;
|
||||
}
|
||||
if (property == Animation::Scale)
|
||||
|
|
|
@ -10,7 +10,7 @@ class MapScaleAnimation : public Animation
|
|||
{
|
||||
public:
|
||||
MapScaleAnimation(double startScale, double endScale,
|
||||
m2::PointD const & globalScaleCenter, m2::PointD const & pixelCenterOffset);
|
||||
m2::PointD const & globalScaleCenter, m2::PointD const & pxScaleCenter);
|
||||
|
||||
Animation::Type GetType() const override { return Animation::MapScale; }
|
||||
|
||||
|
@ -41,7 +41,7 @@ private:
|
|||
bool GetProperty(TObject object, TProperty property, bool targetValue, PropertyValue & value) const;
|
||||
|
||||
ScaleInterpolator m_scaleInterpolator;
|
||||
m2::PointD const m_pixelCenterOffset;
|
||||
m2::PointD const m_pxScaleCenter;
|
||||
m2::PointD const m_globalScaleCenter;
|
||||
TObjectProperties m_properties;
|
||||
TAnimObjects m_objects;
|
||||
|
|
|
@ -18,14 +18,6 @@ public:
|
|||
|
||||
void Blend(Animation::PropertyValue const & value)
|
||||
{
|
||||
// Now perspective parameters can't be blended.
|
||||
if (value.m_type == Animation::PropertyValue::ValuePerspectiveParams)
|
||||
{
|
||||
m_value = value;
|
||||
m_counter = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_counter != 0)
|
||||
{
|
||||
// New value type resets current blended value.
|
||||
|
@ -75,17 +67,22 @@ private:
|
|||
|
||||
} // namespace
|
||||
|
||||
bool AnimationSystem::GetRect(ScreenBase const & currentScreen, m2::AnyRectD & rect)
|
||||
void AnimationSystem::UpdateLastScreen(ScreenBase const & currentScreen)
|
||||
{
|
||||
return GetRect(currentScreen, bind(&AnimationSystem::GetProperty, this, _1, _2, _3), rect);
|
||||
m_lastScreen = currentScreen;
|
||||
}
|
||||
|
||||
void AnimationSystem::GetTargetRect(ScreenBase const & currentScreen, m2::AnyRectD & rect)
|
||||
bool AnimationSystem::GetScreen(ScreenBase const & currentScreen, ScreenBase & screen)
|
||||
{
|
||||
GetRect(currentScreen, bind(&AnimationSystem::GetTargetProperty, this, _1, _2, _3), rect);
|
||||
return GetScreen(currentScreen, bind(&AnimationSystem::GetProperty, this, _1, _2, _3), screen);
|
||||
}
|
||||
|
||||
bool AnimationSystem::GetRect(ScreenBase const & currentScreen, TGetPropertyFn const & getPropertyFn, m2::AnyRectD & rect)
|
||||
void AnimationSystem::GetTargetScreen(ScreenBase const & currentScreen, ScreenBase & screen)
|
||||
{
|
||||
GetScreen(currentScreen, bind(&AnimationSystem::GetTargetProperty, this, _1, _2, _3), screen);
|
||||
}
|
||||
|
||||
bool AnimationSystem::GetScreen(ScreenBase const & currentScreen, TGetPropertyFn const & getPropertyFn, ScreenBase & screen)
|
||||
{
|
||||
ASSERT(getPropertyFn != nullptr, ());
|
||||
|
||||
|
@ -105,36 +102,12 @@ bool AnimationSystem::GetRect(ScreenBase const & currentScreen, TGetPropertyFn c
|
|||
if (getPropertyFn(Animation::MapPlane, Animation::Position, value))
|
||||
pos = value.m_valuePointD;
|
||||
|
||||
m2::RectD localRect = currentScreen.PixelRect();
|
||||
localRect.Offset(-localRect.Center());
|
||||
localRect.Scale(scale);
|
||||
rect = m2::AnyRectD(pos, angle, localRect);
|
||||
screen = currentScreen;
|
||||
screen.SetFromParams(pos, angle, scale);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AnimationSystem::GetPerspectiveAngle(double & angle)
|
||||
{
|
||||
Animation::PropertyValue value;
|
||||
if (GetProperty(Animation::MapPlane, Animation::AnglePerspective, value))
|
||||
{
|
||||
angle = value.m_valueD;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AnimationSystem::SwitchPerspective(Animation::SwitchPerspectiveParams & params)
|
||||
{
|
||||
Animation::PropertyValue value;
|
||||
if (GetProperty(Animation::MapPlane, Animation::SwitchPerspective, value))
|
||||
{
|
||||
params = value.m_valuePerspectiveParams;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AnimationSystem::GetArrowPosition(m2::PointD & position)
|
||||
{
|
||||
Animation::PropertyValue value;
|
||||
|
|
|
@ -19,11 +19,9 @@ class AnimationSystem : private noncopyable
|
|||
public:
|
||||
static AnimationSystem & Instance();
|
||||
|
||||
bool GetRect(ScreenBase const & currentScreen, m2::AnyRectD & rect);
|
||||
void GetTargetRect(ScreenBase const & currentScreen, m2::AnyRectD & rect);
|
||||
|
||||
bool SwitchPerspective(Animation::SwitchPerspectiveParams & params);
|
||||
bool GetPerspectiveAngle(double & angle);
|
||||
void UpdateLastScreen(ScreenBase const & currentScreen);
|
||||
bool GetScreen(ScreenBase const & currentScreen, ScreenBase & screen);
|
||||
void GetTargetScreen(ScreenBase const & currentScreen, ScreenBase & screen);
|
||||
|
||||
bool GetArrowPosition(m2::PointD & position);
|
||||
bool GetArrowAngle(double & angle);
|
||||
|
@ -66,7 +64,7 @@ private:
|
|||
|
||||
using TGetPropertyFn = function<bool (Animation::TObject object, Animation::TProperty property,
|
||||
Animation::PropertyValue & value)>;
|
||||
bool GetRect(ScreenBase const & currentScreen, TGetPropertyFn const & getPropertyFn, m2::AnyRectD & rect);
|
||||
bool GetScreen(ScreenBase const & currentScreen, TGetPropertyFn const & getPropertyFn, ScreenBase & screen);
|
||||
|
||||
bool GetProperty(Animation::TObject object, Animation::TProperty property,
|
||||
Animation::PropertyValue & value) const;
|
||||
|
|
|
@ -76,6 +76,15 @@ void BackendRenderer::RecacheGui(gui::TWidgetsInitInfo const & initInfo, bool ne
|
|||
m_commutator->PostMessage(ThreadsCommutator::RenderThread, move(outputMsg), MessagePriority::Normal);
|
||||
}
|
||||
|
||||
#ifdef RENRER_DEBUG_INFO_LABELS
|
||||
void BackendRenderer::RecacheDebugLabels()
|
||||
{
|
||||
drape_ptr<gui::LayerRenderer> layerRenderer = m_guiCacher.RecacheDebugLabels(m_texMng);
|
||||
drape_ptr<Message> outputMsg = make_unique_dp<GuiLayerRecachedMessage>(move(layerRenderer), false);
|
||||
m_commutator->PostMessage(ThreadsCommutator::RenderThread, move(outputMsg), MessagePriority::Normal);
|
||||
}
|
||||
#endif
|
||||
|
||||
void BackendRenderer::RecacheChoosePositionMark()
|
||||
{
|
||||
drape_ptr<gui::LayerRenderer> layerRenderer = m_guiCacher.RecacheChoosePositionMark(m_texMng);
|
||||
|
@ -117,6 +126,10 @@ void BackendRenderer::AcceptMessage(ref_ptr<Message> message)
|
|||
{
|
||||
ref_ptr<GuiRecacheMessage> msg = message;
|
||||
RecacheGui(msg->GetInitInfo(), msg->NeedResetOldGui());
|
||||
|
||||
#ifdef RENRER_DEBUG_INFO_LABELS
|
||||
RecacheDebugLabels();
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case Message::GuiLayerLayout:
|
||||
|
|
|
@ -63,6 +63,10 @@ private:
|
|||
void RecacheChoosePositionMark();
|
||||
void RecacheMapShapes();
|
||||
|
||||
#ifdef RENRER_DEBUG_INFO_LABELS
|
||||
void RecacheDebugLabels();
|
||||
#endif
|
||||
|
||||
void AcceptMessage(ref_ptr<Message> message) override;
|
||||
|
||||
class Routine : public threads::IRoutine
|
||||
|
|
|
@ -265,11 +265,10 @@ void DrapeEngine::StopLocationFollow()
|
|||
MessagePriority::High);
|
||||
}
|
||||
|
||||
void DrapeEngine::FollowRoute(int preferredZoomLevel, int preferredZoomLevel3d, double rotationAngle, double angleFOV)
|
||||
void DrapeEngine::FollowRoute(int preferredZoomLevel, int preferredZoomLevel3d)
|
||||
{
|
||||
m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread,
|
||||
make_unique_dp<FollowRouteMessage>(preferredZoomLevel, preferredZoomLevel3d,
|
||||
rotationAngle, angleFOV),
|
||||
make_unique_dp<FollowRouteMessage>(preferredZoomLevel, preferredZoomLevel3d),
|
||||
MessagePriority::High);
|
||||
}
|
||||
|
||||
|
@ -380,22 +379,21 @@ void DrapeEngine::SetWidgetLayout(gui::TWidgetsLayoutInfo && info)
|
|||
MessagePriority::Normal);
|
||||
}
|
||||
|
||||
void DrapeEngine::Allow3dMode(bool allowPerspectiveInNavigation, bool allow3dBuildings, double rotationAngle, double angleFOV)
|
||||
void DrapeEngine::Allow3dMode(bool allowPerspectiveInNavigation, bool allow3dBuildings)
|
||||
{
|
||||
m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread,
|
||||
make_unique_dp<Allow3dBuildingsMessage>(allow3dBuildings),
|
||||
MessagePriority::Normal);
|
||||
|
||||
m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread,
|
||||
make_unique_dp<Allow3dModeMessage>(allowPerspectiveInNavigation, allow3dBuildings,
|
||||
rotationAngle, angleFOV),
|
||||
make_unique_dp<Allow3dModeMessage>(allowPerspectiveInNavigation, allow3dBuildings),
|
||||
MessagePriority::Normal);
|
||||
}
|
||||
|
||||
void DrapeEngine::EnablePerspective(double rotationAngle, double angleFOV)
|
||||
void DrapeEngine::EnablePerspective()
|
||||
{
|
||||
m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread,
|
||||
make_unique_dp<EnablePerspectiveMessage>(rotationAngle, angleFOV),
|
||||
make_unique_dp<EnablePerspectiveMessage>(),
|
||||
MessagePriority::Normal);
|
||||
}
|
||||
|
||||
|
|
|
@ -124,14 +124,14 @@ public:
|
|||
void AddRoute(m2::PolylineD const & routePolyline, vector<double> const & turns,
|
||||
df::ColorConstant color, df::RoutePattern pattern = df::RoutePattern());
|
||||
void RemoveRoute(bool deactivateFollowing);
|
||||
void FollowRoute(int preferredZoomLevel, int preferredZoomLevel3d, double rotationAngle, double angleFOV);
|
||||
void FollowRoute(int preferredZoomLevel, int preferredZoomLevel3d);
|
||||
void DeactivateRouteFollowing();
|
||||
void SetRoutePoint(m2::PointD const & position, bool isStart, bool isValid);
|
||||
|
||||
void SetWidgetLayout(gui::TWidgetsLayoutInfo && info);
|
||||
|
||||
void Allow3dMode(bool allowPerspectiveInNavigation, bool allow3dBuildings, double rotationAngle, double angleFOV);
|
||||
void EnablePerspective(double rotationAngle, double angleFOV);
|
||||
void Allow3dMode(bool allowPerspectiveInNavigation, bool allow3dBuildings);
|
||||
void EnablePerspective();
|
||||
|
||||
void UpdateGpsTrackPoints(vector<df::GpsTrackPoint> && toAdd, vector<uint32_t> && toRemove);
|
||||
void ClearGpsTrackPoints();
|
||||
|
|
|
@ -23,12 +23,12 @@ SOURCES += \
|
|||
animation/scale_animation.cpp \
|
||||
animation/sequence_animation.cpp \
|
||||
animation/parallel_animation.cpp \
|
||||
animation/perspective_animation.cpp \
|
||||
animation/opacity_animation.cpp \
|
||||
animation/show_hide_animation.cpp \
|
||||
gui/choose_position_mark.cpp \
|
||||
gui/compass.cpp \
|
||||
gui/copyright_label.cpp \
|
||||
gui/debug_label.cpp \
|
||||
gui/drape_gui.cpp \
|
||||
gui/gui_text.cpp \
|
||||
gui/layer_render.cpp \
|
||||
|
@ -115,13 +115,13 @@ HEADERS += \
|
|||
animation/scale_animation.hpp \
|
||||
animation/sequence_animation.hpp \
|
||||
animation/parallel_animation.hpp \
|
||||
animation/perspective_animation.hpp \
|
||||
animation/opacity_animation.hpp \
|
||||
animation/show_hide_animation.hpp \
|
||||
animation/value_mapping.hpp \
|
||||
gui/choose_position_mark.hpp \
|
||||
gui/compass.hpp \
|
||||
gui/copyright_label.hpp \
|
||||
gui/debug_label.hpp \
|
||||
gui/drape_gui.hpp \
|
||||
gui/gui_text.hpp \
|
||||
gui/layer_render.hpp \
|
||||
|
|
|
@ -37,7 +37,6 @@ public:
|
|||
void CorrectGlobalScalePoint(m2::PointD & pt) const override {}
|
||||
void OnScaleEnded() override {}
|
||||
void OnAnimationStarted(ref_ptr<df::Animation> /* anim */) override {}
|
||||
void OnPerspectiveSwitchRejected() override {}
|
||||
void OnTouchMapAction() override {}
|
||||
void OnAnimatedScaleEnded() override {}
|
||||
|
||||
|
|
|
@ -484,8 +484,7 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message)
|
|||
|
||||
if (m_pendingFollowRoute != nullptr)
|
||||
{
|
||||
FollowRoute(m_pendingFollowRoute->m_preferredZoomLevel, m_pendingFollowRoute->m_preferredZoomLevelIn3d,
|
||||
m_pendingFollowRoute->m_rotationAngle, m_pendingFollowRoute->m_angleFOV);
|
||||
FollowRoute(m_pendingFollowRoute->m_preferredZoomLevel, m_pendingFollowRoute->m_preferredZoomLevelIn3d);
|
||||
m_pendingFollowRoute.reset();
|
||||
}
|
||||
break;
|
||||
|
@ -522,13 +521,11 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message)
|
|||
if (m_routeRenderer->GetRouteData() == nullptr)
|
||||
{
|
||||
m_pendingFollowRoute.reset(
|
||||
new FollowRouteData(msg->GetPreferredZoomLevel(), msg->GetPreferredZoomLevelIn3d(),
|
||||
msg->GetRotationAngle(), msg->GetAngleFOV()));
|
||||
new FollowRouteData(msg->GetPreferredZoomLevel(), msg->GetPreferredZoomLevelIn3d()));
|
||||
break;
|
||||
}
|
||||
|
||||
FollowRoute(msg->GetPreferredZoomLevel(), msg->GetPreferredZoomLevelIn3d(),
|
||||
msg->GetRotationAngle(), msg->GetAngleFOV());
|
||||
FollowRoute(msg->GetPreferredZoomLevel(), msg->GetPreferredZoomLevelIn3d());
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -613,9 +610,7 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message)
|
|||
|
||||
case Message::EnablePerspective:
|
||||
{
|
||||
ref_ptr<EnablePerspectiveMessage> const msg = message;
|
||||
AddUserEvent(EnablePerspectiveEvent(msg->GetRotationAngle(), msg->GetAngleFOV(),
|
||||
false /* animated */, true /* immediately start */));
|
||||
AddUserEvent(SetAutoPerspectiveEvent(true /* isAutoPerspective */));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -628,11 +623,7 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message)
|
|||
if (m_enablePerspectiveInNavigation == msg->AllowPerspective() &&
|
||||
m_enablePerspectiveInNavigation != screen.isPerspective())
|
||||
{
|
||||
if (m_enablePerspectiveInNavigation)
|
||||
AddUserEvent(EnablePerspectiveEvent(msg->GetRotationAngle(), msg->GetAngleFOV(),
|
||||
false /* animated */, true /* immediately start */));
|
||||
else
|
||||
AddUserEvent(DisablePerspectiveEvent());
|
||||
AddUserEvent(SetAutoPerspectiveEvent(m_enablePerspectiveInNavigation));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -648,15 +639,7 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message)
|
|||
m_enablePerspectiveInNavigation = msg->AllowPerspective();
|
||||
if (m_myPositionController->IsInRouting())
|
||||
{
|
||||
if (m_enablePerspectiveInNavigation && !screen.isPerspective() && !m_perspectiveDiscarded)
|
||||
{
|
||||
AddUserEvent(EnablePerspectiveEvent(msg->GetRotationAngle(), msg->GetAngleFOV(),
|
||||
true /* animated */, true /* immediately start */));
|
||||
}
|
||||
else if (!m_enablePerspectiveInNavigation && (screen.isPerspective() || m_perspectiveDiscarded))
|
||||
{
|
||||
DisablePerspective();
|
||||
}
|
||||
AddUserEvent(SetAutoPerspectiveEvent(m_enablePerspectiveInNavigation));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -750,18 +733,14 @@ unique_ptr<threads::IRoutine> FrontendRenderer::CreateRoutine()
|
|||
return make_unique<Routine>(*this);
|
||||
}
|
||||
|
||||
void FrontendRenderer::FollowRoute(int preferredZoomLevel, int preferredZoomLevelIn3d,
|
||||
double rotationAngle, double angleFOV)
|
||||
void FrontendRenderer::FollowRoute(int preferredZoomLevel, int preferredZoomLevelIn3d)
|
||||
{
|
||||
|
||||
m_myPositionController->ActivateRouting(!m_enablePerspectiveInNavigation ? preferredZoomLevel
|
||||
: preferredZoomLevelIn3d);
|
||||
|
||||
if (m_enablePerspectiveInNavigation)
|
||||
{
|
||||
bool immediatelyStart = !m_myPositionController->IsRotationAvailable();
|
||||
AddUserEvent(EnablePerspectiveEvent(rotationAngle, angleFOV, true /* animated */, immediatelyStart));
|
||||
}
|
||||
AddUserEvent(SetAutoPerspectiveEvent(true /* isAutoPerspective */));
|
||||
|
||||
m_overlayTree->SetFollowingMode(true);
|
||||
}
|
||||
|
@ -811,17 +790,22 @@ void FrontendRenderer::InvalidateRect(m2::RectD const & gRect)
|
|||
|
||||
void FrontendRenderer::OnResize(ScreenBase const & screen)
|
||||
{
|
||||
m2::RectD const viewportRect = screen.isPerspective() ? screen.PixelRectIn3d() : screen.PixelRect();
|
||||
m2::RectD const viewportRect = screen.PixelRectIn3d();
|
||||
double const kEps = 1e-5;
|
||||
bool const viewportChanged = !m2::IsEqualSize(m_lastReadedModelView.PixelRectIn3d(), viewportRect, kEps, kEps);
|
||||
|
||||
m_myPositionController->UpdatePixelPosition(screen);
|
||||
m_myPositionController->OnNewPixelRect();
|
||||
|
||||
m_viewport.SetViewport(0, 0, viewportRect.SizeX(), viewportRect.SizeY());
|
||||
m_contextFactory->getDrawContext()->resize(viewportRect.SizeX(), viewportRect.SizeY());
|
||||
if (viewportChanged)
|
||||
{
|
||||
m_myPositionController->OnNewViewportRect();
|
||||
m_viewport.SetViewport(0, 0, viewportRect.SizeX(), viewportRect.SizeY());
|
||||
m_contextFactory->getDrawContext()->resize(viewportRect.SizeX(), viewportRect.SizeY());
|
||||
m_framebuffer->SetSize(viewportRect.SizeX(), viewportRect.SizeY());
|
||||
}
|
||||
|
||||
RefreshProjection(screen);
|
||||
RefreshPivotTransform(screen);
|
||||
|
||||
m_framebuffer->SetSize(viewportRect.SizeX(), viewportRect.SizeY());
|
||||
}
|
||||
|
||||
void FrontendRenderer::AddToRenderGroup(dp::GLState const & state,
|
||||
|
@ -1069,18 +1053,7 @@ void FrontendRenderer::RenderScene(ScreenBase const & modelView)
|
|||
modelView, make_ref(m_gpuProgramManager), m_generalUniforms);
|
||||
|
||||
if (m_guiRenderer != nullptr)
|
||||
{
|
||||
if (isPerspective)
|
||||
{
|
||||
ScreenBase modelView2d = modelView;
|
||||
modelView2d.ResetPerspective();
|
||||
m_guiRenderer->Render(make_ref(m_gpuProgramManager), modelView2d);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_guiRenderer->Render(make_ref(m_gpuProgramManager), modelView);
|
||||
}
|
||||
}
|
||||
m_guiRenderer->Render(make_ref(m_gpuProgramManager), modelView);
|
||||
|
||||
GLFunctions::glEnable(gl_const::GLDepthTest);
|
||||
|
||||
|
@ -1232,7 +1205,18 @@ void FrontendRenderer::RefreshModelView(ScreenBase const & screen)
|
|||
|
||||
m_generalUniforms.SetMatrix4x4Value("modelView", mv.m_data);
|
||||
|
||||
float const zScale = 2.0f / (screen.GetHeight() * screen.GetScale());
|
||||
float zScale;
|
||||
if (screen.isPerspective())
|
||||
{
|
||||
// TODO: Calculate exact value of zScale
|
||||
double const averageScale3d = 3.0;
|
||||
zScale = 2.0f / (screen.PixelRectIn3d().SizeY() * averageScale3d * screen.GetScale());
|
||||
}
|
||||
else
|
||||
{
|
||||
zScale = 2.0f / (screen.GetHeight() * screen.GetScale());
|
||||
}
|
||||
|
||||
m_generalUniforms.SetFloatValue("zScale", zScale);
|
||||
}
|
||||
|
||||
|
@ -1266,8 +1250,7 @@ void FrontendRenderer::RefreshBgColor()
|
|||
|
||||
void FrontendRenderer::DisablePerspective()
|
||||
{
|
||||
m_perspectiveDiscarded = false;
|
||||
AddUserEvent(DisablePerspectiveEvent());
|
||||
AddUserEvent(SetAutoPerspectiveEvent(false /* isAutoPerspective */));
|
||||
}
|
||||
|
||||
void FrontendRenderer::CheckIsometryMinScale(ScreenBase const & screen)
|
||||
|
@ -1281,20 +1264,6 @@ void FrontendRenderer::CheckIsometryMinScale(ScreenBase const & screen)
|
|||
}
|
||||
}
|
||||
|
||||
void FrontendRenderer::CheckPerspectiveMinScale()
|
||||
{
|
||||
if (!m_enablePerspectiveInNavigation || m_userEventStream.IsInPerspectiveAnimation())
|
||||
return;
|
||||
|
||||
bool const switchTo2d = !IsScaleAllowableIn3d(m_currentZoomLevel);
|
||||
if ((!switchTo2d && !m_perspectiveDiscarded) ||
|
||||
(switchTo2d && !m_userEventStream.GetCurrentScreen().isPerspective()))
|
||||
return;
|
||||
|
||||
m_perspectiveDiscarded = switchTo2d;
|
||||
AddUserEvent(SwitchViewModeEvent(switchTo2d));
|
||||
}
|
||||
|
||||
void FrontendRenderer::ResolveZoomLevel(ScreenBase const & screen)
|
||||
{
|
||||
int const prevZoomLevel = m_currentZoomLevel;
|
||||
|
@ -1304,7 +1273,6 @@ void FrontendRenderer::ResolveZoomLevel(ScreenBase const & screen)
|
|||
UpdateCanBeDeletedStatus();
|
||||
|
||||
CheckIsometryMinScale(screen);
|
||||
CheckPerspectiveMinScale();
|
||||
UpdateDisplacementEnabled();
|
||||
}
|
||||
|
||||
|
@ -1432,12 +1400,6 @@ void FrontendRenderer::OnAnimationStarted(ref_ptr<Animation> anim)
|
|||
m_myPositionController->AnimationStarted(anim);
|
||||
}
|
||||
|
||||
void FrontendRenderer::OnPerspectiveSwitchRejected()
|
||||
{
|
||||
if (m_perspectiveDiscarded)
|
||||
m_perspectiveDiscarded = false;
|
||||
}
|
||||
|
||||
void FrontendRenderer::OnTouchMapAction()
|
||||
{
|
||||
m_myPositionController->ResetRoutingNotFollowTimer();
|
||||
|
|
|
@ -174,7 +174,6 @@ private:
|
|||
TTilesCollection ResolveTileKeys(ScreenBase const & screen);
|
||||
void ResolveZoomLevel(ScreenBase const & screen);
|
||||
void UpdateDisplacementEnabled();
|
||||
void CheckPerspectiveMinScale();
|
||||
void CheckIsometryMinScale(ScreenBase const & screen);
|
||||
|
||||
void DisablePerspective();
|
||||
|
@ -195,7 +194,6 @@ private:
|
|||
void OnScaleEnded() override;
|
||||
void OnAnimatedScaleEnded() override;
|
||||
void OnAnimationStarted(ref_ptr<Animation> anim) override;
|
||||
void OnPerspectiveSwitchRejected() override;
|
||||
void OnTouchMapAction() override;
|
||||
|
||||
class Routine : public threads::IRoutine
|
||||
|
@ -223,8 +221,7 @@ private:
|
|||
using TRenderGroupRemovePredicate = function<bool(drape_ptr<RenderGroup> const &)>;
|
||||
void RemoveRenderGroupsLater(TRenderGroupRemovePredicate const & predicate);
|
||||
|
||||
void FollowRoute(int preferredZoomLevel, int preferredZoomLevelIn3d,
|
||||
double rotationAngle, double angleFOV);
|
||||
void FollowRoute(int preferredZoomLevel, int preferredZoomLevelIn3d);
|
||||
void InvalidateRect(m2::RectD const & gRect);
|
||||
bool CheckTileGenerations(TileKey const & tileKey);
|
||||
void UpdateCanBeDeletedStatus();
|
||||
|
@ -296,8 +293,6 @@ private:
|
|||
TTilesCollection m_notFinishedTiles;
|
||||
|
||||
int m_currentZoomLevel = -1;
|
||||
|
||||
bool m_perspectiveDiscarded = false;
|
||||
|
||||
ref_ptr<RequestedTiles> m_requestedTiles;
|
||||
uint64_t m_maxGeneration;
|
||||
|
@ -306,19 +301,13 @@ private:
|
|||
struct FollowRouteData
|
||||
{
|
||||
FollowRouteData(int preferredZoomLevel,
|
||||
int preferredZoomLevelIn3d,
|
||||
double rotationAngle,
|
||||
double angleFOV)
|
||||
int preferredZoomLevelIn3d)
|
||||
: m_preferredZoomLevel(preferredZoomLevel)
|
||||
, m_preferredZoomLevelIn3d(preferredZoomLevelIn3d)
|
||||
, m_rotationAngle(rotationAngle)
|
||||
, m_angleFOV(angleFOV)
|
||||
{}
|
||||
|
||||
int m_preferredZoomLevel;
|
||||
int m_preferredZoomLevelIn3d;
|
||||
double m_rotationAngle;
|
||||
double m_angleFOV;
|
||||
};
|
||||
|
||||
unique_ptr<FollowRouteData> m_pendingFollowRoute;
|
||||
|
|
|
@ -37,7 +37,7 @@ public:
|
|||
|
||||
bool Update(ScreenBase const & screen) override
|
||||
{
|
||||
SetPivot(glsl::ToVec2(m2::PointF(screen.PixelRect().Center())));
|
||||
SetPivot(glsl::ToVec2(m2::PointF(screen.PixelRectIn3d().Center())));
|
||||
return TBase::Update(screen);
|
||||
}
|
||||
};
|
||||
|
|
94
drape_frontend/gui/debug_label.cpp
Normal file
94
drape_frontend/gui/debug_label.cpp
Normal file
|
@ -0,0 +1,94 @@
|
|||
#include "debug_label.hpp"
|
||||
|
||||
#include "drape_gui.hpp"
|
||||
|
||||
#include "std/bind.hpp"
|
||||
|
||||
namespace gui
|
||||
{
|
||||
|
||||
class DebugLabelHandle : public MutableLabelHandle
|
||||
{
|
||||
using TBase = MutableLabelHandle;
|
||||
|
||||
public:
|
||||
DebugLabelHandle(uint32_t id, dp::Anchor anchor, m2::PointF const & pivot,
|
||||
ref_ptr<dp::TextureManager> tex, TUpdateDebugLabelFn const & onUpdateFn)
|
||||
: MutableLabelHandle(id, anchor, pivot)
|
||||
, m_onUpdateFn(onUpdateFn)
|
||||
{
|
||||
SetTextureManager(tex);
|
||||
}
|
||||
|
||||
bool Update(ScreenBase const & screen) override
|
||||
{
|
||||
string content;
|
||||
bool const isVisible = m_onUpdateFn(screen, content);
|
||||
|
||||
SetIsVisible(isVisible);
|
||||
SetContent(content);
|
||||
|
||||
return TBase::Update(screen);
|
||||
}
|
||||
|
||||
private:
|
||||
TUpdateDebugLabelFn m_onUpdateFn;
|
||||
};
|
||||
|
||||
void AddSymbols(string const & str, set<char> & symbols)
|
||||
{
|
||||
for (size_t i = 0, sz = str.length(); i < sz; ++i)
|
||||
symbols.insert(str[i]);
|
||||
}
|
||||
|
||||
void DebugInfoLabels::AddLabel(ref_ptr<dp::TextureManager> tex, string const & caption, TUpdateDebugLabelFn const & onUpdateFn)
|
||||
{
|
||||
string alphabet;
|
||||
set<char> symbols;
|
||||
AddSymbols(caption, symbols);
|
||||
AddSymbols("0123456789.-e", symbols);
|
||||
|
||||
alphabet.reserve(symbols.size());
|
||||
for (auto const & ch : symbols)
|
||||
alphabet.push_back(ch);
|
||||
|
||||
MutableLabelDrawer::Params params;
|
||||
params.m_anchor = dp::LeftTop;
|
||||
params.m_alphabet = alphabet;
|
||||
params.m_maxLength = 100;
|
||||
params.m_font = DrapeGui::GetGuiTextFont();
|
||||
params.m_font.m_color = dp::Color(0, 0, 255, 255);
|
||||
params.m_font.m_size *= 1.2;
|
||||
params.m_pivot = m_position.m_pixelPivot;
|
||||
|
||||
#ifdef RENRER_DEBUG_INFO_LABELS
|
||||
uint32_t const id = GuiHandleDebugLabel + m_labelsCount;
|
||||
|
||||
params.m_handleCreator = [id, onUpdateFn, tex](dp::Anchor anchor, m2::PointF const & pivot)
|
||||
{
|
||||
return make_unique_dp<DebugLabelHandle>(id, anchor, pivot, tex, onUpdateFn);
|
||||
};
|
||||
#endif
|
||||
m_labelsParams.push_back(params);
|
||||
++m_labelsCount;
|
||||
}
|
||||
|
||||
drape_ptr<ShapeRenderer> DebugInfoLabels::Draw(ref_ptr<dp::TextureManager> tex)
|
||||
{
|
||||
drape_ptr<ShapeRenderer> renderer = make_unique_dp<ShapeRenderer>();
|
||||
|
||||
m2::PointF pos = m_position.m_pixelPivot;
|
||||
|
||||
for (auto & params : m_labelsParams)
|
||||
{
|
||||
params.m_pivot.y = pos.y;
|
||||
m2::PointF textSize = MutableLabelDrawer::Draw(params, tex, bind(&ShapeRenderer::AddShape, renderer.get(), _1, _2));
|
||||
pos.y += 2 * textSize.y;
|
||||
}
|
||||
|
||||
m_labelsParams.clear();
|
||||
|
||||
return renderer;
|
||||
}
|
||||
|
||||
} // namespace gui
|
28
drape_frontend/gui/debug_label.hpp
Normal file
28
drape_frontend/gui/debug_label.hpp
Normal file
|
@ -0,0 +1,28 @@
|
|||
#pragma once
|
||||
|
||||
#include "gui_text.hpp"
|
||||
#include "shape.hpp"
|
||||
|
||||
#include "std/vector.hpp"
|
||||
|
||||
namespace gui
|
||||
{
|
||||
|
||||
using TUpdateDebugLabelFn = function<bool(ScreenBase const & screen, string & content)>;
|
||||
|
||||
class DebugInfoLabels : public Shape
|
||||
{
|
||||
public:
|
||||
DebugInfoLabels(gui::Position const & position)
|
||||
: Shape(position)
|
||||
{}
|
||||
|
||||
void AddLabel(ref_ptr<dp::TextureManager> tex, string const & caption, TUpdateDebugLabelFn const & onUpdateFn);
|
||||
drape_ptr<ShapeRenderer> Draw(ref_ptr<dp::TextureManager> tex);
|
||||
|
||||
private:
|
||||
vector<MutableLabelDrawer::Params> m_labelsParams;
|
||||
uint32_t m_labelsCount = 0;
|
||||
};
|
||||
|
||||
} // namespace gui
|
|
@ -1,6 +1,7 @@
|
|||
#include "choose_position_mark.hpp"
|
||||
#include "compass.hpp"
|
||||
#include "copyright_label.hpp"
|
||||
#include "debug_label.hpp"
|
||||
#include "drape_gui.hpp"
|
||||
#include "gui_text.hpp"
|
||||
#include "layer_render.hpp"
|
||||
|
@ -12,6 +13,8 @@
|
|||
#include "drape/batcher.hpp"
|
||||
#include "drape/render_bucket.hpp"
|
||||
|
||||
#include "geometry/mercator.hpp"
|
||||
|
||||
#include "base/stl_add.hpp"
|
||||
|
||||
#include "std/bind.hpp"
|
||||
|
@ -212,6 +215,100 @@ drape_ptr<LayerRenderer> LayerCacher::RecacheChoosePositionMark(ref_ptr<dp::Text
|
|||
return renderer;
|
||||
}
|
||||
|
||||
#ifdef RENRER_DEBUG_INFO_LABELS
|
||||
drape_ptr<LayerRenderer> LayerCacher::RecacheDebugLabels(ref_ptr<dp::TextureManager> textures)
|
||||
{
|
||||
drape_ptr<LayerRenderer> renderer = make_unique_dp<LayerRenderer>();
|
||||
|
||||
float const vs = df::VisualParams::Instance().GetVisualScale();
|
||||
DebugInfoLabels debugLabels = DebugInfoLabels(Position(m2::PointF(10.0f * vs, 50.0f * vs), dp::Center));
|
||||
|
||||
debugLabels.AddLabel(textures, "visible: km2, readed: km2, ratio:",
|
||||
[](ScreenBase const & screen, string & content) -> bool
|
||||
{
|
||||
double const sizeX = screen.PixelRectIn3d().SizeX();
|
||||
double const sizeY = screen.PixelRectIn3d().SizeY();
|
||||
|
||||
m2::PointD const p0 = screen.PtoG(screen.P3dtoP(m2::PointD(0.0, 0.0)));
|
||||
m2::PointD const p1 = screen.PtoG(screen.P3dtoP(m2::PointD(0.0, sizeY)));
|
||||
m2::PointD const p2 = screen.PtoG(screen.P3dtoP(m2::PointD(sizeX, sizeY)));
|
||||
m2::PointD const p3 = screen.PtoG(screen.P3dtoP(m2::PointD(sizeX, 0.0)));
|
||||
|
||||
double const areaG = MercatorBounds::AreaOnEarth(p0, p1, p2) +
|
||||
MercatorBounds::AreaOnEarth(p2, p3, p0);
|
||||
|
||||
double const sizeX_2d = screen.PixelRect().SizeX();
|
||||
double const sizeY_2d = screen.PixelRect().SizeY();
|
||||
|
||||
m2::PointD const p0_2d = screen.PtoG(m2::PointD(0.0, 0.0));
|
||||
m2::PointD const p1_2d = screen.PtoG(m2::PointD(0.0, sizeY_2d));
|
||||
m2::PointD const p2_2d = screen.PtoG(m2::PointD(sizeX_2d, sizeY_2d));
|
||||
m2::PointD const p3_2d = screen.PtoG(m2::PointD(sizeX_2d, 0.0));
|
||||
|
||||
double const areaGTotal = MercatorBounds::AreaOnEarth(p0_2d, p1_2d, p2_2d) +
|
||||
MercatorBounds::AreaOnEarth(p2_2d, p3_2d, p0_2d);
|
||||
|
||||
ostringstream out;
|
||||
out << fixed << setprecision(2)
|
||||
<< "visible: " << areaG / 1000000.0 << " km2"
|
||||
<< ", readed: " << areaGTotal / 1000000.0 << " km2"
|
||||
<< ", ratio: " << areaGTotal / areaG;
|
||||
content.assign(out.str());
|
||||
return true;
|
||||
});
|
||||
|
||||
debugLabels.AddLabel(textures, "scale2d: m/px, scale2d * vs: m/px",
|
||||
[](ScreenBase const & screen, string & content) -> bool
|
||||
{
|
||||
double const distanceG = MercatorBounds::DistanceOnEarth(screen.PtoG(screen.PixelRect().LeftBottom()),
|
||||
screen.PtoG(screen.PixelRect().RightBottom()));
|
||||
|
||||
double const vs = df::VisualParams::Instance().GetVisualScale();
|
||||
double const scale = distanceG / screen.PixelRect().SizeX();
|
||||
|
||||
ostringstream out;
|
||||
out << fixed << setprecision(2)
|
||||
<< "scale2d: " << scale << " m/px"
|
||||
<< ", scale2d * vs: " << scale * vs << " m/px";
|
||||
content.assign(out.str());
|
||||
return true;
|
||||
});
|
||||
|
||||
debugLabels.AddLabel(textures, "distance: m",
|
||||
[](ScreenBase const & screen, string & content) -> bool
|
||||
{
|
||||
double const sizeX = screen.PixelRectIn3d().SizeX();
|
||||
double const sizeY = screen.PixelRectIn3d().SizeY();
|
||||
|
||||
double const distance = MercatorBounds::DistanceOnEarth(screen.PtoG(screen.P3dtoP(m2::PointD(sizeX / 2.0, 0.0))),
|
||||
screen.PtoG(screen.P3dtoP(m2::PointD(sizeX / 2.0, sizeY))));
|
||||
|
||||
ostringstream out;
|
||||
out << fixed << setprecision(2)
|
||||
<< "distance: " << distance << " m";
|
||||
content.assign(out.str());
|
||||
return true;
|
||||
});
|
||||
|
||||
debugLabels.AddLabel(textures, "angle: ",
|
||||
[](ScreenBase const & screen, string & content) -> bool
|
||||
{
|
||||
ostringstream out;
|
||||
out << fixed << setprecision(2)
|
||||
<< "angle: " << screen.GetRotationAngle() * 180.0 / math::pi;
|
||||
content.assign(out.str());
|
||||
return true;
|
||||
});
|
||||
|
||||
renderer->AddShapeRenderer(WIDGET_DEBUG_INFO, debugLabels.Draw(textures));
|
||||
|
||||
// Flush gui geometry.
|
||||
GLFunctions::glFlush();
|
||||
|
||||
return renderer;
|
||||
}
|
||||
#endif
|
||||
|
||||
m2::PointF LayerCacher::CacheCompass(Position const & position, ref_ptr<LayerRenderer> renderer,
|
||||
ref_ptr<dp::TextureManager> textures)
|
||||
{
|
||||
|
|
|
@ -58,6 +58,10 @@ public:
|
|||
ref_ptr<dp::TextureManager> textures);
|
||||
drape_ptr<LayerRenderer> RecacheChoosePositionMark(ref_ptr<dp::TextureManager> textures);
|
||||
|
||||
#ifdef RENRER_DEBUG_INFO_LABELS
|
||||
drape_ptr<LayerRenderer> RecacheDebugLabels(ref_ptr<dp::TextureManager> textures);
|
||||
#endif
|
||||
|
||||
private:
|
||||
m2::PointF CacheCompass(Position const & position, ref_ptr<LayerRenderer> renderer, ref_ptr<dp::TextureManager> textures);
|
||||
m2::PointF CacheRuler(Position const & position, ref_ptr<LayerRenderer> renderer, ref_ptr<dp::TextureManager> textures);
|
||||
|
|
|
@ -91,7 +91,7 @@ void ShapeRenderer::Build(ref_ptr<dp::GpuProgramManager> mng)
|
|||
void ShapeRenderer::Render(ScreenBase const & screen, ref_ptr<dp::GpuProgramManager> mng)
|
||||
{
|
||||
array<float, 16> m;
|
||||
m2::RectD const & pxRect = screen.PixelRect();
|
||||
m2::RectD const & pxRect = screen.PixelRectIn3d();
|
||||
dp::MakeProjection(m, 0.0f, pxRect.SizeX(), pxRect.SizeY(), 0.0f);
|
||||
|
||||
dp::UniformValuesStorage uniformStorage;
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#include "std/map.hpp"
|
||||
|
||||
//#define RENRER_DEBUG_INFO_LABELS
|
||||
|
||||
namespace gui
|
||||
{
|
||||
|
||||
|
@ -16,7 +18,10 @@ enum EWidget
|
|||
WIDGET_COPYRIGHT = 0x4,
|
||||
WIDGET_SCALE_LABEL = 0x8,
|
||||
/// Following widgets controlled by rendering kernel. Don't use them in platform code
|
||||
WIDGET_CHOOSE_POSITION_MARK = 0x8000
|
||||
WIDGET_CHOOSE_POSITION_MARK = 0x8000,
|
||||
#ifdef RENRER_DEBUG_INFO_LABELS
|
||||
WIDGET_DEBUG_INFO
|
||||
#endif
|
||||
};
|
||||
|
||||
enum EGuiHandle
|
||||
|
@ -34,7 +39,10 @@ enum EGuiHandle
|
|||
GuiHandleRetryButtonLabel,
|
||||
GuiHandleCancelButton,
|
||||
GuiHandleCancelButtonLabel,
|
||||
GuiHandleChoosePositionMark
|
||||
GuiHandleChoosePositionMark,
|
||||
#ifdef RENRER_DEBUG_INFO_LABELS
|
||||
GuiHandleDebugLabel = 100
|
||||
#endif
|
||||
};
|
||||
|
||||
struct Position
|
||||
|
|
|
@ -645,24 +645,18 @@ public:
|
|||
class FollowRouteMessage : public Message
|
||||
{
|
||||
public:
|
||||
FollowRouteMessage(int preferredZoomLevel, int preferredZoomLevelIn3d, double rotationAngle, double angleFOV)
|
||||
FollowRouteMessage(int preferredZoomLevel, int preferredZoomLevelIn3d)
|
||||
: m_preferredZoomLevel(preferredZoomLevel)
|
||||
, m_preferredZoomLevelIn3d(preferredZoomLevelIn3d)
|
||||
, m_rotationAngle(rotationAngle)
|
||||
, m_angleFOV(angleFOV)
|
||||
{}
|
||||
|
||||
Type GetType() const override { return Message::FollowRoute; }
|
||||
int GetPreferredZoomLevel() const { return m_preferredZoomLevel; }
|
||||
int GetPreferredZoomLevelIn3d() const { return m_preferredZoomLevelIn3d; }
|
||||
double GetRotationAngle() const { return m_rotationAngle; }
|
||||
double GetAngleFOV() const { return m_angleFOV; }
|
||||
|
||||
private:
|
||||
int const m_preferredZoomLevel;
|
||||
int const m_preferredZoomLevelIn3d;
|
||||
double const m_rotationAngle;
|
||||
double const m_angleFOV;
|
||||
};
|
||||
|
||||
class InvalidateTexturesMessage : public BaseBlockingMessage
|
||||
|
@ -694,24 +688,18 @@ public:
|
|||
class Allow3dModeMessage : public Message
|
||||
{
|
||||
public:
|
||||
Allow3dModeMessage(bool allowPerspective, bool allow3dBuildings, double rotationAngle, double angleFOV)
|
||||
Allow3dModeMessage(bool allowPerspective, bool allow3dBuildings)
|
||||
: m_allowPerspective(allowPerspective)
|
||||
, m_allow3dBuildings(allow3dBuildings)
|
||||
, m_rotationAngle(rotationAngle)
|
||||
, m_angleFOV(angleFOV)
|
||||
{}
|
||||
|
||||
Type GetType() const override { return Message::Allow3dMode; }
|
||||
bool AllowPerspective() const { return m_allowPerspective; }
|
||||
bool Allow3dBuildings() const { return m_allow3dBuildings; }
|
||||
double GetRotationAngle() const { return m_rotationAngle; }
|
||||
double GetAngleFOV() const { return m_angleFOV; }
|
||||
|
||||
private:
|
||||
bool const m_allowPerspective;
|
||||
bool const m_allow3dBuildings;
|
||||
double const m_rotationAngle;
|
||||
double const m_angleFOV;
|
||||
};
|
||||
|
||||
class Allow3dBuildingsMessage : public Message
|
||||
|
@ -731,19 +719,9 @@ private:
|
|||
class EnablePerspectiveMessage : public Message
|
||||
{
|
||||
public:
|
||||
EnablePerspectiveMessage(double rotationAngle, double angleFOV)
|
||||
: m_rotationAngle(rotationAngle)
|
||||
, m_angleFOV(angleFOV)
|
||||
{}
|
||||
EnablePerspectiveMessage() = default;
|
||||
|
||||
Type GetType() const override { return Message::EnablePerspective; }
|
||||
|
||||
double GetRotationAngle() const { return m_rotationAngle; }
|
||||
double GetAngleFOV() const { return m_angleFOV; }
|
||||
|
||||
private:
|
||||
double const m_rotationAngle;
|
||||
double const m_angleFOV;
|
||||
};
|
||||
|
||||
class CacheGpsTrackPointsMessage : public Message
|
||||
|
|
|
@ -52,7 +52,7 @@ string LocationModeStatisticsName(location::EMyPositionMode mode)
|
|||
|
||||
int GetZoomLevel(ScreenBase const & screen)
|
||||
{
|
||||
return my::clamp(fabs(log(screen.GetScale()) / log(2.0)), 1, scales::GetUpperStyleScale());
|
||||
return df::GetZoomLevel(screen.GetScale());
|
||||
}
|
||||
|
||||
int GetZoomLevel(ScreenBase const & screen, m2::PointD const & position, double errorRadius)
|
||||
|
@ -63,6 +63,8 @@ int GetZoomLevel(ScreenBase const & screen, m2::PointD const & position, double
|
|||
return GetZoomLevel(s);
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
MyPositionController::MyPositionController(location::EMyPositionMode initMode, double timeInBackground,
|
||||
|
@ -103,7 +105,7 @@ MyPositionController::~MyPositionController()
|
|||
{
|
||||
}
|
||||
|
||||
void MyPositionController::OnNewPixelRect()
|
||||
void MyPositionController::OnNewViewportRect()
|
||||
{
|
||||
UpdateViewport(kDoNotChangeZoom);
|
||||
}
|
||||
|
@ -112,8 +114,6 @@ void MyPositionController::UpdatePixelPosition(ScreenBase const & screen)
|
|||
{
|
||||
m_pixelRect = screen.isPerspective() ? screen.PixelRectIn3d() : screen.PixelRect();
|
||||
m_positionYOffset = screen.isPerspective() ? kPositionOffsetYIn3D : kPositionOffsetY;
|
||||
m_centerPixelPositionRouting = screen.P3dtoP(GetRoutingRotationPixelCenter());
|
||||
m_centerPixelPosition = screen.P3dtoP(m_pixelRect.Center());
|
||||
}
|
||||
|
||||
void MyPositionController::SetListener(ref_ptr<MyPositionController::Listener> listener)
|
||||
|
@ -266,7 +266,7 @@ void MyPositionController::NextMode(ScreenBase const & screen)
|
|||
if (!m_isInRouting)
|
||||
{
|
||||
ChangeMode(location::Follow);
|
||||
ChangeModelView(m_position, 0.0, m_centerPixelPosition, preferredZoomLevel);
|
||||
ChangeModelView(m_position, 0.0, m_pixelRect.Center(), preferredZoomLevel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -317,7 +317,7 @@ void MyPositionController::OnLocationUpdate(location::GpsInfo const & info, bool
|
|||
ChangeModelView(m_position, kDoNotChangeZoom);
|
||||
else if (m_mode == location::FollowAndRotate)
|
||||
ChangeModelView(m_position, m_drawDirection,
|
||||
m_isInRouting ? m_centerPixelPositionRouting : m_centerPixelPosition, kDoNotChangeZoom);
|
||||
m_isInRouting ? GetRoutingRotationPixelCenter() : m_pixelRect.Center(), kDoNotChangeZoom);
|
||||
}
|
||||
}
|
||||
else if (m_mode == location::PendingPosition || m_mode == location::NotFollowNoPosition)
|
||||
|
@ -525,7 +525,7 @@ void MyPositionController::OnCompassTapped()
|
|||
if (m_mode == location::FollowAndRotate)
|
||||
{
|
||||
ChangeMode(location::Follow);
|
||||
ChangeModelView(m_position, 0.0, m_centerPixelPosition, kDoNotChangeZoom);
|
||||
ChangeModelView(m_position, 0.0, m_pixelRect.Center(), kDoNotChangeZoom);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -567,7 +567,7 @@ void MyPositionController::UpdateViewport(int zoomLevel)
|
|||
ChangeModelView(m_position, zoomLevel);
|
||||
else if (m_mode == location::FollowAndRotate)
|
||||
ChangeModelView(m_position, m_drawDirection,
|
||||
m_isInRouting ? m_centerPixelPositionRouting : m_centerPixelPosition, zoomLevel);
|
||||
m_isInRouting ? GetRoutingRotationPixelCenter() : m_pixelRect.Center(), zoomLevel);
|
||||
}
|
||||
|
||||
m2::PointD MyPositionController::GetRotationPixelCenter() const
|
||||
|
@ -658,7 +658,7 @@ void MyPositionController::ActivateRouting(int zoomLevel)
|
|||
if (IsRotationAvailable())
|
||||
{
|
||||
ChangeMode(location::FollowAndRotate);
|
||||
ChangeModelView(m_position, m_drawDirection, m_centerPixelPositionRouting, zoomLevel);
|
||||
ChangeModelView(m_position, m_drawDirection, GetRoutingRotationPixelCenter(), zoomLevel);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -675,7 +675,7 @@ void MyPositionController::DeactivateRouting()
|
|||
m_isInRouting = false;
|
||||
|
||||
ChangeMode(location::Follow);
|
||||
ChangeModelView(m_position, 0.0, m_centerPixelPosition, kDoNotChangeZoom);
|
||||
ChangeModelView(m_position, 0.0, m_pixelRect.Center(), kDoNotChangeZoom);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ public:
|
|||
bool isFirstLaunch, bool isRoutingActive);
|
||||
~MyPositionController();
|
||||
|
||||
void OnNewPixelRect();
|
||||
void OnNewViewportRect();
|
||||
void UpdatePixelPosition(ScreenBase const & screen);
|
||||
void SetListener(ref_ptr<Listener> listener);
|
||||
|
||||
|
@ -153,8 +153,6 @@ private:
|
|||
double m_lastLocationTimestamp;
|
||||
|
||||
m2::RectD m_pixelRect;
|
||||
m2::PointD m_centerPixelPositionRouting;
|
||||
m2::PointD m_centerPixelPosition;
|
||||
double m_positionYOffset;
|
||||
|
||||
bool m_isVisible;
|
||||
|
|
|
@ -19,23 +19,39 @@
|
|||
namespace df
|
||||
{
|
||||
|
||||
double const kDefault3dScale = 1.0;
|
||||
|
||||
Navigator::Navigator()
|
||||
: m_InAction(false)
|
||||
{
|
||||
}
|
||||
|
||||
void Navigator::SetFromRects(m2::AnyRectD const & glbRect, m2::RectD const & pxRect)
|
||||
void Navigator::SetFromScreen(ScreenBase const & screen)
|
||||
{
|
||||
m2::RectD const & worldR = df::GetWorldRect();
|
||||
VisualParams const & p = VisualParams::Instance();
|
||||
SetFromScreen(screen, p.GetTileSize(), p.GetVisualScale());
|
||||
}
|
||||
|
||||
m_Screen.SetFromRects(glbRect, pxRect);
|
||||
m_Screen = ScaleInto(m_Screen, worldR);
|
||||
void Navigator::SetFromScreen(ScreenBase const & screen, uint32_t tileSize, double visualScale)
|
||||
{
|
||||
ScreenBase tmp = ScaleInto(screen, df::GetWorldRect());
|
||||
|
||||
if (!CheckMaxScale(tmp, tileSize, visualScale))
|
||||
{
|
||||
int const scale = scales::GetUpperStyleScale() - 1;
|
||||
m2::RectD newRect = df::GetRectForDrawScale(scale, screen.GetOrg());
|
||||
newRect.Scale(m_Screen.GetScale3d());
|
||||
CheckMinMaxVisibleScale(newRect, scale, m_Screen.GetScale3d());
|
||||
tmp = m_Screen;
|
||||
tmp.SetFromRect(m2::AnyRectD(newRect));
|
||||
|
||||
ASSERT(CheckMaxScale(tmp, tileSize, visualScale), ());
|
||||
}
|
||||
|
||||
m_Screen = tmp;
|
||||
|
||||
if (!m_InAction)
|
||||
{
|
||||
m_StartScreen.SetFromRects(glbRect, pxRect);
|
||||
m_StartScreen = ScaleInto(m_StartScreen, worldR);
|
||||
}
|
||||
m_StartScreen = tmp;
|
||||
}
|
||||
|
||||
void Navigator::SetFromRect(m2::AnyRectD const & r)
|
||||
|
@ -46,25 +62,9 @@ void Navigator::SetFromRect(m2::AnyRectD const & r)
|
|||
|
||||
void Navigator::SetFromRect(m2::AnyRectD const & r, uint32_t tileSize, double visualScale)
|
||||
{
|
||||
m2::RectD const & worldR = df::GetWorldRect();
|
||||
|
||||
ScreenBase tmp = m_Screen;
|
||||
|
||||
tmp.SetFromRect(r);
|
||||
tmp = ScaleInto(tmp, worldR);
|
||||
if (!CheckMaxScale(tmp, tileSize, visualScale))
|
||||
{
|
||||
int const scale = scales::GetUpperStyleScale() - 1;
|
||||
m2::RectD newRect = df::GetRectForDrawScale(scale, r.Center());
|
||||
CheckMinMaxVisibleScale(newRect, scale);
|
||||
tmp = m_Screen;
|
||||
tmp.SetFromRect(m2::AnyRectD(newRect));
|
||||
ASSERT(CheckMaxScale(tmp, tileSize, visualScale), ());
|
||||
}
|
||||
m_Screen = tmp;
|
||||
|
||||
if (!m_InAction)
|
||||
m_StartScreen = tmp;
|
||||
SetFromScreen(tmp, tileSize, visualScale);
|
||||
}
|
||||
|
||||
void Navigator::CenterViewport(m2::PointD const & p)
|
||||
|
@ -85,25 +85,11 @@ void Navigator::OnSize(int w, int h)
|
|||
{
|
||||
m2::RectD const & worldR = df::GetWorldRect();
|
||||
|
||||
double const fov = m_Screen.GetAngleFOV();
|
||||
double const rotation = m_Screen.GetRotationAngle();
|
||||
if (m_Screen.isPerspective())
|
||||
{
|
||||
m_Screen.ResetPerspective();
|
||||
m_StartScreen.ResetPerspective();
|
||||
}
|
||||
|
||||
m_Screen.OnSize(0, 0, w, h);
|
||||
m_Screen = ShrinkAndScaleInto(m_Screen, worldR);
|
||||
|
||||
m_StartScreen.OnSize(0, 0, w, h);
|
||||
m_StartScreen = ShrinkAndScaleInto(m_StartScreen, worldR);
|
||||
|
||||
if (fov != 0.0)
|
||||
{
|
||||
m_Screen.ApplyPerspective(rotation, rotation, fov);
|
||||
m_StartScreen.ApplyPerspective(rotation, rotation, fov);
|
||||
}
|
||||
}
|
||||
|
||||
m2::PointD Navigator::GtoP(m2::PointD const & pt) const
|
||||
|
@ -194,6 +180,7 @@ bool Navigator::ScaleImpl(m2::PointD const & newPt1, m2::PointD const & newPt2,
|
|||
{
|
||||
m2::PointD const center3d = oldPt1;
|
||||
m2::PointD const center2d = screen.P3dtoP(center3d);
|
||||
m2::PointD const centerG = screen.PtoG(center2d);
|
||||
m2::PointD const offset = center2d - center3d;
|
||||
math::Matrix<double, 3, 3> const newM =
|
||||
screen.GtoPMatrix() * ScreenBase::CalcTransform(oldPt1 + offset, oldPt2 + offset,
|
||||
|
@ -201,6 +188,7 @@ bool Navigator::ScaleImpl(m2::PointD const & newPt1, m2::PointD const & newPt2,
|
|||
doRotateScreen);
|
||||
ScreenBase tmp = screen;
|
||||
tmp.SetGtoPMatrix(newM);
|
||||
tmp.MatchGandP3d(centerG, center3d);
|
||||
|
||||
if (!skipMinScaleAndBordersCheck && !CheckMinScale(tmp))
|
||||
return false;
|
||||
|
@ -291,9 +279,18 @@ bool Navigator::IsRotatingDuringScale() const
|
|||
return m_IsRotatingDuringScale;
|
||||
}
|
||||
|
||||
void Navigator::Enable3dMode(double currentRotationAngle, double maxRotationAngle, double angleFOV)
|
||||
void Navigator::SetAutoPerspective(bool enable)
|
||||
{
|
||||
m_Screen.ApplyPerspective(currentRotationAngle, maxRotationAngle, angleFOV);
|
||||
m_Screen.SetAutoPerspective(enable);
|
||||
}
|
||||
|
||||
void Navigator::Enable3dMode()
|
||||
{
|
||||
if (m_Screen.isPerspective())
|
||||
return;
|
||||
double const angle = m_Screen.CalculateAutoPerspectiveAngle(m_Screen.GetScale());
|
||||
if (angle > 0)
|
||||
m_Screen.ApplyPerspective(angle, angle, m_Screen.GetAngleFOV());
|
||||
}
|
||||
|
||||
void Navigator::SetRotationIn3dMode(double rotationAngle)
|
||||
|
@ -317,36 +314,38 @@ m2::AnyRectD ToRotated(Navigator const & navigator, m2::RectD const & rect)
|
|||
m2::RectD(-dx/2, -dy/2, dx/2, dy/2));
|
||||
}
|
||||
|
||||
void CheckMinGlobalRect(m2::RectD & rect, uint32_t tileSize, double visualScale)
|
||||
void CheckMinGlobalRect(m2::RectD & rect, uint32_t tileSize, double visualScale, double scale3d)
|
||||
{
|
||||
m2::RectD const minRect = df::GetRectForDrawScale(scales::GetUpperStyleScale(), rect.Center(), tileSize, visualScale);
|
||||
m2::RectD minRect = df::GetRectForDrawScale(scales::GetUpperStyleScale(), rect.Center(), tileSize, visualScale);
|
||||
minRect.Scale(scale3d);
|
||||
if (minRect.IsRectInside(rect))
|
||||
rect = minRect;
|
||||
}
|
||||
|
||||
void CheckMinGlobalRect(m2::RectD & rect)
|
||||
void CheckMinGlobalRect(m2::RectD & rect, double scale3d)
|
||||
{
|
||||
VisualParams const & p = VisualParams::Instance();
|
||||
CheckMinGlobalRect(rect, p.GetTileSize(), p.GetVisualScale());
|
||||
CheckMinGlobalRect(rect, p.GetTileSize(), p.GetVisualScale(), scale3d);
|
||||
}
|
||||
|
||||
void CheckMinMaxVisibleScale(m2::RectD & rect, int maxScale,
|
||||
uint32_t tileSize, double visualScale)
|
||||
uint32_t tileSize, double visualScale, double scale3d)
|
||||
{
|
||||
CheckMinGlobalRect(rect, tileSize, visualScale);
|
||||
CheckMinGlobalRect(rect, tileSize, visualScale, scale3d);
|
||||
int scale = df::GetDrawTileScale(rect, tileSize, visualScale);
|
||||
if (maxScale != -1 && scale > maxScale)
|
||||
{
|
||||
// limit on passed maximal scale
|
||||
m2::PointD const c = rect.Center();
|
||||
rect = df::GetRectForDrawScale(maxScale, c, tileSize, visualScale);
|
||||
rect.Scale(scale3d);
|
||||
}
|
||||
}
|
||||
|
||||
void CheckMinMaxVisibleScale(m2::RectD & rect, int maxScale)
|
||||
void CheckMinMaxVisibleScale(m2::RectD & rect, int maxScale, double scale3d)
|
||||
{
|
||||
VisualParams const & p = VisualParams::Instance();
|
||||
CheckMinMaxVisibleScale(rect, maxScale, p.GetTileSize(), p.GetVisualScale());
|
||||
CheckMinMaxVisibleScale(rect, maxScale, p.GetTileSize(), p.GetVisualScale(), scale3d);
|
||||
}
|
||||
|
||||
} // namespace df
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
namespace df
|
||||
{
|
||||
|
||||
extern double const kDefault3dScale;
|
||||
|
||||
/// Calculates screen parameters in navigation (dragging, scaling, etc.).
|
||||
class Navigator
|
||||
{
|
||||
|
@ -17,9 +19,10 @@ public:
|
|||
Navigator();
|
||||
|
||||
void SetFromRect(m2::AnyRectD const & r);
|
||||
void CenterViewport(m2::PointD const & p);
|
||||
void SetFromRects(m2::AnyRectD const & glbRect, m2::RectD const & pxRect);
|
||||
void SetFromRect(m2::AnyRectD const & r, uint32_t tileSize, double visualScale);
|
||||
void SetFromScreen(ScreenBase const & screen);
|
||||
void SetFromScreen(ScreenBase const & screen, uint32_t tileSize, double visualScale);
|
||||
void CenterViewport(m2::PointD const & p);
|
||||
|
||||
void OnSize(int w, int h);
|
||||
|
||||
|
@ -43,7 +46,8 @@ public:
|
|||
void Scale(m2::PointD const & pixelScaleCenter, double factor);
|
||||
bool InAction() const;
|
||||
|
||||
void Enable3dMode(double currentRotationAngle, double maxRotationAngle, double angleFOV);
|
||||
void SetAutoPerspective(bool enable);
|
||||
void Enable3dMode();
|
||||
void SetRotationIn3dMode(double rotationAngle);
|
||||
void Disable3dMode();
|
||||
|
||||
|
@ -75,10 +79,10 @@ private:
|
|||
};
|
||||
|
||||
m2::AnyRectD ToRotated(Navigator const & navigator, m2::RectD const & rect);
|
||||
void CheckMinGlobalRect(m2::RectD & rect, uint32_t tileSize, double visualScale);
|
||||
void CheckMinGlobalRect(m2::RectD & rect);
|
||||
void CheckMinGlobalRect(m2::RectD & rect, uint32_t tileSize, double visualScale, double scale3d = kDefault3dScale);
|
||||
void CheckMinGlobalRect(m2::RectD & rect, double scale3d = kDefault3dScale);
|
||||
|
||||
void CheckMinMaxVisibleScale(m2::RectD & rect, int maxScale/* = -1*/, uint32_t tileSize, double visualScale);
|
||||
void CheckMinMaxVisibleScale(m2::RectD & rect, int maxScale/* = -1*/);
|
||||
void CheckMinMaxVisibleScale(m2::RectD & rect, int maxScale/* = -1*/, uint32_t tileSize, double visualScale, double scale3d = kDefault3dScale);
|
||||
void CheckMinMaxVisibleScale(m2::RectD & rect, int maxScale/* = -1*/, double scale3d = kDefault3dScale);
|
||||
|
||||
}
|
||||
|
|
|
@ -203,10 +203,10 @@ void RuleDrawer::operator()(FeatureType const & f)
|
|||
double const lat = MercatorBounds::YToLat(featureCenter.y);
|
||||
|
||||
m2::RectD rectMercator = MercatorBounds::MetresToXY(lon, lat, heightInMeters);
|
||||
areaHeight = m2::PointD(rectMercator.SizeX(), rectMercator.SizeY()).Length();
|
||||
areaHeight = (rectMercator.SizeX() + rectMercator.SizeY()) / 2.0;
|
||||
|
||||
rectMercator = MercatorBounds::MetresToXY(lon, lat, minHeigthInMeters);
|
||||
areaMinHeight = m2::PointD(rectMercator.SizeX(), rectMercator.SizeY()).Length();
|
||||
areaMinHeight = (rectMercator.SizeX() + rectMercator.SizeY()) / 2.0;
|
||||
}
|
||||
|
||||
bool applyPointStyle = s.PointStyleExists();
|
||||
|
|
|
@ -13,6 +13,12 @@ namespace df
|
|||
string const kPrettyMoveAnim = "PrettyMove";
|
||||
string const kPrettyFollowAnim = "PrettyFollow";
|
||||
|
||||
drape_ptr<SequenceAnimation> GetPrettyMoveAnimation(ScreenBase const & startScreen, ScreenBase const & endScreen)
|
||||
{
|
||||
return GetPrettyMoveAnimation(startScreen, startScreen.GetScale(), endScreen.GetScale(),
|
||||
startScreen.GetOrg(), endScreen.GetOrg());
|
||||
}
|
||||
|
||||
drape_ptr<SequenceAnimation> GetPrettyMoveAnimation(ScreenBase const & screen,
|
||||
m2::AnyRectD const & startRect, m2::AnyRectD const & endRect)
|
||||
{
|
||||
|
@ -25,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>();
|
||||
|
@ -50,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));
|
||||
|
@ -80,6 +94,19 @@ drape_ptr<SequenceAnimation> GetPrettyFollowAnimation(ScreenBase const & screen,
|
|||
return sequenceAnim;
|
||||
}
|
||||
|
||||
drape_ptr<MapLinearAnimation> GetRectAnimation(ScreenBase const & startScreen, ScreenBase const & endScreen)
|
||||
{
|
||||
auto anim = make_unique_dp<MapLinearAnimation>();
|
||||
|
||||
anim->SetRotate(startScreen.GetAngle(), endScreen.GetAngle());
|
||||
anim->SetMove(startScreen.GetOrg(), endScreen.GetOrg(),
|
||||
startScreen.PixelRectIn3d(), (startScreen.GetScale() + endScreen.GetScale()) / 2.0);
|
||||
anim->SetScale(startScreen.GetScale(), endScreen.GetScale());
|
||||
anim->SetMaxScaleDuration(kMaxAnimationTimeSec);
|
||||
|
||||
return anim;
|
||||
}
|
||||
|
||||
drape_ptr<MapLinearAnimation> GetSetRectAnimation(ScreenBase const & screen,
|
||||
m2::AnyRectD const & startRect, m2::AnyRectD const & endRect)
|
||||
{
|
||||
|
@ -99,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.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;
|
||||
|
@ -113,9 +139,8 @@ drape_ptr<MapScaleAnimation> GetScaleAnimation(ScreenBase const & startScreen, m
|
|||
ScreenBase endScreen = startScreen;
|
||||
ApplyScale(pxScaleCenter, factor, endScreen);
|
||||
|
||||
m2::PointD const offset = startScreen.PixelRect().Center() - startScreen.P3dtoP(pxScaleCenter);
|
||||
auto anim = make_unique_dp<MapScaleAnimation>(startScreen.GetScale(), endScreen.GetScale(),
|
||||
glbScaleCenter, offset);
|
||||
glbScaleCenter, pxScaleCenter);
|
||||
anim->SetMaxDuration(kMaxAnimationTimeSec);
|
||||
|
||||
return anim;
|
||||
|
|
|
@ -15,15 +15,16 @@ class MapLinearAnimation;
|
|||
class MapFollowAnimation;
|
||||
class MapScaleAnimation;
|
||||
|
||||
drape_ptr<SequenceAnimation> GetPrettyMoveAnimation(ScreenBase const & startScreen, ScreenBase const & endScreen);
|
||||
drape_ptr<SequenceAnimation> GetPrettyMoveAnimation(ScreenBase const & screen,
|
||||
m2::AnyRectD const & startRect, m2::AnyRectD const & endRect);
|
||||
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,
|
||||
m2::AnyRectD const & startRect, m2::AnyRectD const & endRect);
|
||||
|
||||
|
|
|
@ -240,13 +240,10 @@ ScreenBase const ShrinkAndScaleInto(ScreenBase const & screen, m2::RectD boundRe
|
|||
bool ApplyScale(m2::PointD const & pixelScaleCenter, double factor, ScreenBase & screen)
|
||||
{
|
||||
m2::PointD const globalScaleCenter = screen.PtoG(screen.P3dtoP(pixelScaleCenter));
|
||||
m2::PointD const pixelCenterOffset = screen.PixelRect().Center() - screen.P3dtoP(pixelScaleCenter);
|
||||
|
||||
ScreenBase tmp = screen;
|
||||
tmp.Scale(factor);
|
||||
|
||||
m2::PointD newCenter = tmp.PtoG(tmp.GtoP(globalScaleCenter) + pixelCenterOffset);
|
||||
tmp.SetOrg(newCenter);
|
||||
tmp.MatchGandP3d(globalScaleCenter, pixelScaleCenter);
|
||||
|
||||
if (!CheckMinScale(tmp))
|
||||
return false;
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#include "drape_frontend/animation/linear_animation.hpp"
|
||||
#include "drape_frontend/animation/scale_animation.hpp"
|
||||
#include "drape_frontend/animation/follow_animation.hpp"
|
||||
#include "drape_frontend/animation/perspective_animation.hpp"
|
||||
#include "drape_frontend/animation/sequence_animation.hpp"
|
||||
#include "drape_frontend/animation_constants.hpp"
|
||||
#include "drape_frontend/animation_system.hpp"
|
||||
|
@ -147,12 +146,11 @@ ScreenBase const & UserEventStream::ProcessEvents(bool & modelViewChanged, bool
|
|||
swap(m_events, events);
|
||||
}
|
||||
|
||||
m2::RectD const prevPixelRect = GetCurrentScreen().PixelRect();
|
||||
|
||||
m_modelViewChanged = !events.empty() || m_state == STATE_SCALE || m_state == STATE_DRAG;
|
||||
for (UserEvent const & e : events)
|
||||
{
|
||||
if (m_perspectiveAnimation && FilterEventWhile3dAnimation(e.m_type))
|
||||
continue;
|
||||
|
||||
bool breakAnim = false;
|
||||
|
||||
switch (e.m_type)
|
||||
|
@ -163,7 +161,6 @@ ScreenBase const & UserEventStream::ProcessEvents(bool & modelViewChanged, bool
|
|||
break;
|
||||
case UserEvent::EVENT_RESIZE:
|
||||
m_navigator.OnSize(e.m_resize.m_width, e.m_resize.m_height);
|
||||
m_viewportChanged = true;
|
||||
breakAnim = true;
|
||||
TouchCancel(m_touches);
|
||||
if (m_state == STATE_DOUBLE_TAP_HOLD)
|
||||
|
@ -174,11 +171,6 @@ ScreenBase const & UserEventStream::ProcessEvents(bool & modelViewChanged, bool
|
|||
TouchCancel(m_touches);
|
||||
break;
|
||||
case UserEvent::EVENT_SET_RECT:
|
||||
if (m_perspectiveAnimation)
|
||||
{
|
||||
m_pendingEvent.reset(new UserEvent(e.m_rectEvent));
|
||||
break;
|
||||
}
|
||||
breakAnim = SetRect(e.m_rectEvent.m_rect, e.m_rectEvent.m_zoom, e.m_rectEvent.m_applyRotation, e.m_rectEvent.m_isAnim);
|
||||
TouchCancel(m_touches);
|
||||
break;
|
||||
|
@ -194,8 +186,9 @@ ScreenBase const & UserEventStream::ProcessEvents(bool & modelViewChanged, bool
|
|||
ScreenBase const & screen = m_navigator.Screen();
|
||||
if (screen.isPerspective())
|
||||
{
|
||||
m2::PointD pt = screen.P3dtoP(screen.PixelRectIn3d().Center());
|
||||
breakAnim = SetFollowAndRotate(screen.PtoG(pt), pt, e.m_rotate.m_targetAzimut, kDoNotChangeZoom, true);
|
||||
m2::PointD pt = screen.PixelRectIn3d().Center();
|
||||
breakAnim = SetFollowAndRotate(screen.PtoG(screen.P3dtoP(pt)), pt,
|
||||
e.m_rotate.m_targetAzimut, kDoNotChangeZoom, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -211,27 +204,8 @@ ScreenBase const & UserEventStream::ProcessEvents(bool & modelViewChanged, bool
|
|||
e.m_followAndRotate.m_isAnim);
|
||||
TouchCancel(m_touches);
|
||||
break;
|
||||
case UserEvent::EVENT_ENABLE_PERSPECTIVE:
|
||||
SetEnable3dMode(e.m_enable3dMode.m_rotationAngle, e.m_enable3dMode.m_angleFOV,
|
||||
e.m_enable3dMode.m_isAnim, e.m_enable3dMode.m_immediatelyStart);
|
||||
m_discardedFOV = m_discardedAngle = 0.0;
|
||||
break;
|
||||
case UserEvent::EVENT_DISABLE_PERSPECTIVE:
|
||||
SetDisable3dModeAnimation();
|
||||
m_discardedFOV = m_discardedAngle = 0.0;
|
||||
break;
|
||||
case UserEvent::EVENT_SWITCH_VIEW_MODE:
|
||||
if (e.m_switchViewMode.m_to2d)
|
||||
{
|
||||
m_discardedFOV = m_navigator.Screen().GetAngleFOV();
|
||||
m_discardedAngle = m_navigator.Screen().GetRotationAngle();
|
||||
SetDisable3dModeAnimation();
|
||||
}
|
||||
else if (m_discardedFOV > 0.0)
|
||||
{
|
||||
SetEnable3dMode(m_discardedAngle, m_discardedFOV, true /* isAnim */, true /* immediatelyStart */);
|
||||
m_discardedFOV = m_discardedAngle = 0.0;
|
||||
}
|
||||
case UserEvent::EVENT_AUTO_PERSPECTIVE:
|
||||
SetAutoPerspective(e.m_autoPerspective.m_isAutoPerspective);
|
||||
break;
|
||||
default:
|
||||
ASSERT(false, ());
|
||||
|
@ -244,21 +218,6 @@ ScreenBase const & UserEventStream::ProcessEvents(bool & modelViewChanged, bool
|
|||
|
||||
ApplyAnimations();
|
||||
|
||||
if (m_perspectiveAnimation)
|
||||
{
|
||||
TouchCancel(m_touches);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_pendingEvent != nullptr && m_pendingEvent->m_type == UserEvent::EVENT_SET_RECT)
|
||||
{
|
||||
SetRect(m_pendingEvent->m_rectEvent.m_rect, m_pendingEvent->m_rectEvent.m_zoom,
|
||||
m_pendingEvent->m_rectEvent.m_applyRotation, m_pendingEvent->m_rectEvent.m_isAnim);
|
||||
m_pendingEvent.reset();
|
||||
m_modelViewChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (GetValidTouchesCount(m_touches) == 1)
|
||||
{
|
||||
if (m_state == STATE_WAIT_DOUBLE_TAP)
|
||||
|
@ -267,10 +226,14 @@ ScreenBase const & UserEventStream::ProcessEvents(bool & modelViewChanged, bool
|
|||
DetectLongTap(m_touches[0]);
|
||||
}
|
||||
|
||||
if (m_modelViewChanged)
|
||||
m_animationSystem.UpdateLastScreen(GetCurrentScreen());
|
||||
|
||||
modelViewChanged = m_modelViewChanged;
|
||||
viewportChanged = m_viewportChanged;
|
||||
|
||||
double const kEps = 1e-5;
|
||||
viewportChanged = !m2::IsEqualSize(prevPixelRect, GetCurrentScreen().PixelRect(), kEps, kEps);
|
||||
m_modelViewChanged = false;
|
||||
m_viewportChanged = false;
|
||||
|
||||
return m_navigator.Screen();
|
||||
}
|
||||
|
@ -279,31 +242,9 @@ void UserEventStream::ApplyAnimations()
|
|||
{
|
||||
if (m_animationSystem.AnimationExists(Animation::MapPlane))
|
||||
{
|
||||
m2::AnyRectD rect;
|
||||
if (m_animationSystem.GetRect(GetCurrentScreen(), rect))
|
||||
m_navigator.SetFromRect(rect);
|
||||
|
||||
Animation::SwitchPerspectiveParams switchPerspective;
|
||||
if (m_animationSystem.SwitchPerspective(switchPerspective))
|
||||
{
|
||||
if (switchPerspective.m_enable)
|
||||
{
|
||||
m_navigator.Enable3dMode(switchPerspective.m_startAngle, switchPerspective.m_endAngle,
|
||||
switchPerspective.m_angleFOV);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_navigator.Disable3dMode();
|
||||
}
|
||||
m_viewportChanged = true;
|
||||
}
|
||||
|
||||
double perspectiveAngle;
|
||||
if (m_animationSystem.GetPerspectiveAngle(perspectiveAngle) &&
|
||||
GetCurrentScreen().isPerspective())
|
||||
{
|
||||
m_navigator.SetRotationIn3dMode(perspectiveAngle);
|
||||
}
|
||||
ScreenBase screen;
|
||||
if (m_animationSystem.GetScreen(GetCurrentScreen(), screen))
|
||||
m_navigator.SetFromScreen(screen);
|
||||
|
||||
m_modelViewChanged = true;
|
||||
}
|
||||
|
@ -361,82 +302,35 @@ bool UserEventStream::SetScale(m2::PointD const & pxScaleCenter, double factor,
|
|||
|
||||
bool UserEventStream::SetCenter(m2::PointD const & center, int zoom, bool isAnim)
|
||||
{
|
||||
m2::PointD targetCenter = center;
|
||||
ang::AngleD angle;
|
||||
m2::RectD localRect;
|
||||
|
||||
ScreenBase const & currentScreen = GetCurrentScreen();
|
||||
|
||||
ScreenBase screen = currentScreen;
|
||||
bool finishIn2d = false;
|
||||
bool finishIn3d = false;
|
||||
if (zoom != kDoNotChangeZoom)
|
||||
{
|
||||
bool const isScaleAllowableIn3d = IsScaleAllowableIn3d(zoom);
|
||||
finishIn3d = m_discardedFOV > 0.0 && isScaleAllowableIn3d;
|
||||
finishIn2d = currentScreen.isPerspective() && !isScaleAllowableIn3d;
|
||||
|
||||
if (finishIn3d)
|
||||
screen.ApplyPerspective(m_discardedAngle, m_discardedAngle, m_discardedFOV);
|
||||
else if (finishIn2d)
|
||||
screen.ResetPerspective();
|
||||
}
|
||||
|
||||
double const scale3d = screen.PixelRect().SizeX() / screen.PixelRectIn3d().SizeX();
|
||||
|
||||
ScreenBase screen = GetCurrentScreen();
|
||||
if (zoom == kDoNotChangeZoom)
|
||||
{
|
||||
m2::AnyRectD const r = GetTargetRect();
|
||||
angle = r.Angle();
|
||||
localRect = r.GetLocalRect();
|
||||
GetTargetScreen(screen);
|
||||
screen.MatchGandP3d(center, screen.PixelRectIn3d().Center());
|
||||
}
|
||||
else
|
||||
{
|
||||
angle = screen.GlobalRect().Angle();
|
||||
|
||||
localRect = df::GetRectForDrawScale(zoom, center);
|
||||
CheckMinGlobalRect(localRect);
|
||||
CheckMinMaxVisibleScale(localRect, zoom);
|
||||
|
||||
localRect.Offset(-center);
|
||||
localRect.Scale(scale3d);
|
||||
|
||||
double const aspectRatio = screen.PixelRect().SizeY() / screen.PixelRect().SizeX();
|
||||
if (aspectRatio > 1.0)
|
||||
localRect.Inflate(0.0, localRect.SizeY() * 0.5 * aspectRatio);
|
||||
else
|
||||
localRect.Inflate(localRect.SizeX() * 0.5 / aspectRatio, 0.0);
|
||||
screen.SetFromParams(center, screen.GetAngle(), GetScale(zoom));
|
||||
screen.MatchGandP3d(center, screen.PixelRectIn3d().Center());
|
||||
}
|
||||
|
||||
if (screen.isPerspective())
|
||||
{
|
||||
double const centerOffset3d = localRect.SizeY() * (1.0 - 1.0 / (scale3d * cos(screen.GetRotationAngle()))) * 0.5;
|
||||
targetCenter = targetCenter.Move(centerOffset3d, angle.cos(), -angle.sin());
|
||||
}
|
||||
ASSERT_GREATER_OR_EQUAL(zoom, scales::GetUpperWorldScale(), ());
|
||||
ASSERT_LESS_OR_EQUAL(zoom, scales::GetUpperStyleScale(), ());
|
||||
|
||||
if (finishIn2d || finishIn3d)
|
||||
{
|
||||
double const scale = currentScreen.PixelRect().SizeX() / currentScreen.PixelRectIn3d().SizeX();
|
||||
double const scaleToCurrent = finishIn2d ? scale : 1.0 / scale3d;
|
||||
ShrinkAndScaleInto(screen, df::GetWorldRect());
|
||||
|
||||
double const currentGSizeY = localRect.SizeY() * scaleToCurrent;
|
||||
targetCenter = targetCenter.Move((currentGSizeY - localRect.SizeY()) * 0.5,
|
||||
angle.cos(), -angle.sin());
|
||||
localRect.Scale(scaleToCurrent);
|
||||
}
|
||||
|
||||
return SetRect(m2::AnyRectD(targetCenter, angle, localRect), isAnim);
|
||||
return SetScreen(screen, isAnim);
|
||||
}
|
||||
|
||||
bool UserEventStream::SetRect(m2::RectD rect, int zoom, bool applyRotation, bool isAnim)
|
||||
{
|
||||
CheckMinGlobalRect(rect);
|
||||
CheckMinMaxVisibleScale(rect, zoom);
|
||||
CheckMinGlobalRect(rect, kDefault3dScale);
|
||||
CheckMinMaxVisibleScale(rect, zoom, kDefault3dScale);
|
||||
m2::AnyRectD targetRect = applyRotation ? ToRotated(m_navigator, rect) : m2::AnyRectD(rect);
|
||||
return SetRect(targetRect, isAnim);
|
||||
}
|
||||
|
||||
bool UserEventStream::SetRect(m2::AnyRectD const & rect, bool isAnim)
|
||||
bool UserEventStream::SetScreen(ScreenBase const & endScreen, bool isAnim)
|
||||
{
|
||||
if (isAnim)
|
||||
{
|
||||
|
@ -446,17 +340,16 @@ bool UserEventStream::SetRect(m2::AnyRectD const & rect, bool isAnim)
|
|||
m_listener->OnAnimationStarted(animation);
|
||||
};
|
||||
|
||||
m2::AnyRectD const startRect = GetCurrentRect();
|
||||
ScreenBase const & screen = GetCurrentScreen();
|
||||
|
||||
drape_ptr<Animation> anim = GetSetRectAnimation(screen, startRect, rect);
|
||||
drape_ptr<Animation> anim = GetRectAnimation(screen, endScreen);
|
||||
if (!df::IsAnimationAllowed(anim->GetDuration(), screen))
|
||||
{
|
||||
anim.reset();
|
||||
double const moveDuration = PositionInterpolator::GetMoveDuration(startRect.GlobalCenter(),
|
||||
rect.GlobalCenter(), screen);
|
||||
double const moveDuration = PositionInterpolator::GetMoveDuration(screen.GetOrg(),
|
||||
endScreen.GetOrg(), screen);
|
||||
if (moveDuration > kMaxAnimationTimeSec)
|
||||
anim = GetPrettyMoveAnimation(screen, startRect, rect);
|
||||
anim = GetPrettyMoveAnimation(screen, endScreen);
|
||||
}
|
||||
|
||||
if (anim != nullptr)
|
||||
|
@ -468,10 +361,19 @@ bool UserEventStream::SetRect(m2::AnyRectD const & rect, bool isAnim)
|
|||
}
|
||||
|
||||
ResetMapPlaneAnimations();
|
||||
m_navigator.SetFromRect(rect);
|
||||
m_navigator.SetFromScreen(endScreen);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UserEventStream::SetRect(m2::AnyRectD const & rect, bool isAnim)
|
||||
{
|
||||
ScreenBase tmp = GetCurrentScreen();
|
||||
tmp.SetFromRects(rect, tmp.PixelRectIn3d());
|
||||
tmp.MatchGandP3d(rect.GlobalCenter(), tmp.PixelRectIn3d().Center());
|
||||
|
||||
return SetScreen(tmp, isAnim);
|
||||
}
|
||||
|
||||
bool UserEventStream::InterruptFollowAnimations(bool force)
|
||||
{
|
||||
Animation const * followAnim = m_animationSystem.FindAnimation<MapFollowAnimation>(Animation::MapFollow);
|
||||
|
@ -497,22 +399,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();
|
||||
m2::RectD r = df::GetRectForDrawScale(preferredZoomLevel, m2::PointD::Zero());
|
||||
CheckMinGlobalRect(r);
|
||||
CheckMinMaxVisibleScale(r, preferredZoomLevel);
|
||||
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(preferredZoomLevel, scales::GetUpperWorldScale(), ());
|
||||
ASSERT_LESS_OR_EQUAL(preferredZoomLevel, scales::GetUpperStyleScale(), ());
|
||||
|
||||
ShrinkAndScaleInto(screen, df::GetWorldRect());
|
||||
|
||||
if (isAnim)
|
||||
{
|
||||
|
@ -527,26 +431,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);
|
||||
|
@ -558,70 +457,18 @@ 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.SetFromScreen(screen);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UserEventStream::FilterEventWhile3dAnimation(UserEvent::EEventType type) const
|
||||
void UserEventStream::SetAutoPerspective(bool isAutoPerspective)
|
||||
{
|
||||
return type != UserEvent::EVENT_RESIZE && type != UserEvent::EVENT_SET_RECT &&
|
||||
type != UserEvent::EVENT_ENABLE_PERSPECTIVE &&
|
||||
type != UserEvent::EVENT_DISABLE_PERSPECTIVE &&
|
||||
type != UserEvent::EVENT_SWITCH_VIEW_MODE;
|
||||
}
|
||||
|
||||
void UserEventStream::SetEnable3dMode(double maxRotationAngle, double angleFOV,
|
||||
bool isAnim, bool immediatelyStart)
|
||||
{
|
||||
ResetAnimationsBeforeSwitch3D();
|
||||
|
||||
if (immediatelyStart)
|
||||
InterruptFollowAnimations(true /* force */);
|
||||
|
||||
double const startAngle = isAnim ? 0.0 : maxRotationAngle;
|
||||
double const endAngle = maxRotationAngle;
|
||||
|
||||
auto anim = make_unique_dp<PerspectiveSwitchAnimation>(startAngle, endAngle, angleFOV);
|
||||
anim->SetOnStartAction([this, startAngle, endAngle, angleFOV](ref_ptr<Animation>)
|
||||
{
|
||||
m_perspectiveAnimation = true;
|
||||
});
|
||||
anim->SetOnFinishAction([this](ref_ptr<Animation>)
|
||||
{
|
||||
m_perspectiveAnimation = false;
|
||||
});
|
||||
if (immediatelyStart)
|
||||
m_animationSystem.CombineAnimation(move(anim));
|
||||
if (isAutoPerspective)
|
||||
m_navigator.Enable3dMode();
|
||||
else
|
||||
m_animationSystem.PushAnimation(move(anim));
|
||||
}
|
||||
|
||||
void UserEventStream::SetDisable3dModeAnimation()
|
||||
{
|
||||
ResetAnimationsBeforeSwitch3D();
|
||||
InterruptFollowAnimations(true /* force */);
|
||||
|
||||
if (m_discardedFOV > 0.0 && IsScaleAllowableIn3d(GetDrawTileScale(GetCurrentScreen())))
|
||||
{
|
||||
m_discardedFOV = m_discardedAngle = 0.0;
|
||||
m_listener->OnPerspectiveSwitchRejected();
|
||||
return;
|
||||
}
|
||||
|
||||
double const startAngle = m_navigator.Screen().GetRotationAngle();
|
||||
double const endAngle = 0.0;
|
||||
|
||||
auto anim = make_unique_dp<PerspectiveSwitchAnimation>(startAngle, endAngle, m_navigator.Screen().GetAngleFOV());
|
||||
anim->SetOnStartAction([this](ref_ptr<Animation>)
|
||||
{
|
||||
m_perspectiveAnimation = true;
|
||||
});
|
||||
anim->SetOnFinishAction([this](ref_ptr<Animation>)
|
||||
{
|
||||
m_perspectiveAnimation = false;
|
||||
});
|
||||
m_animationSystem.CombineAnimation(move(anim));
|
||||
m_navigator.Disable3dMode();
|
||||
m_navigator.SetAutoPerspective(isAutoPerspective);
|
||||
return;
|
||||
}
|
||||
|
||||
void UserEventStream::ResetAnimations(Animation::Type animType, bool finishAll)
|
||||
|
@ -648,24 +495,21 @@ void UserEventStream::ResetMapPlaneAnimations()
|
|||
ApplyAnimations();
|
||||
}
|
||||
|
||||
void UserEventStream::ResetAnimationsBeforeSwitch3D()
|
||||
{
|
||||
ResetAnimations(Animation::MapLinear);
|
||||
ResetAnimations(Animation::Sequence, kPrettyMoveAnim);
|
||||
ResetAnimations(Animation::MapScale);
|
||||
ResetAnimations(Animation::MapPerspective, true /* finishAll */);
|
||||
}
|
||||
|
||||
m2::AnyRectD UserEventStream::GetCurrentRect() const
|
||||
{
|
||||
return m_navigator.Screen().GlobalRect();
|
||||
}
|
||||
|
||||
void UserEventStream::GetTargetScreen(ScreenBase & screen) const
|
||||
{
|
||||
m_animationSystem.GetTargetScreen(m_navigator.Screen(), screen);
|
||||
}
|
||||
|
||||
m2::AnyRectD UserEventStream::GetTargetRect() const
|
||||
{
|
||||
m2::AnyRectD targetRect;
|
||||
m_animationSystem.GetTargetRect(m_navigator.Screen(), targetRect);
|
||||
return targetRect;
|
||||
ScreenBase targetScreen;
|
||||
m_animationSystem.GetTargetScreen(m_navigator.Screen(), targetScreen);
|
||||
return targetScreen.GlobalRect();
|
||||
}
|
||||
|
||||
bool UserEventStream::ProcessTouch(TouchEvent const & touch)
|
||||
|
@ -1169,7 +1013,7 @@ void UserEventStream::EndTapDetector(Touch const & touch)
|
|||
void UserEventStream::CancelTapDetector()
|
||||
{
|
||||
TEST_CALL(CANCEL_TAP_DETECTOR);
|
||||
ASSERT(m_state == STATE_TAP_DETECTION || m_state == STATE_WAIT_DOUBLE_TAP, ());
|
||||
ASSERT(m_state == STATE_TAP_DETECTION || m_state == STATE_WAIT_DOUBLE_TAP || m_state == STATE_WAIT_DOUBLE_TAP_HOLD, ());
|
||||
m_state = STATE_EMPTY;
|
||||
}
|
||||
|
||||
|
@ -1219,7 +1063,7 @@ void UserEventStream::UpdateDoubleTapAndHold(Touch const & touch)
|
|||
TEST_CALL(DOUBLE_TAP_AND_HOLD);
|
||||
ASSERT_EQUAL(m_state, STATE_DOUBLE_TAP_HOLD, ());
|
||||
float const kPowerModifier = 10.0f;
|
||||
float const scaleFactor = exp(kPowerModifier * (touch.m_location.y - m_startDoubleTapAndHold.y) / GetCurrentScreen().PixelRect().SizeY());
|
||||
float const scaleFactor = exp(kPowerModifier * (touch.m_location.y - m_startDoubleTapAndHold.y) / GetCurrentScreen().PixelRectIn3d().SizeY());
|
||||
m_startDoubleTapAndHold = touch.m_location;
|
||||
|
||||
m2::PointD scaleCenter = m_startDragOrg;
|
||||
|
@ -1247,11 +1091,6 @@ bool UserEventStream::IsWaitingForActionCompletion() const
|
|||
return m_state != STATE_EMPTY;
|
||||
}
|
||||
|
||||
bool UserEventStream::IsInPerspectiveAnimation() const
|
||||
{
|
||||
return m_perspectiveAnimation;
|
||||
}
|
||||
|
||||
void UserEventStream::SetKineticScrollEnabled(bool enabled)
|
||||
{
|
||||
m_kineticScrollEnabled = enabled;
|
||||
|
|
|
@ -145,32 +145,13 @@ struct FollowAndRotateEvent
|
|||
bool m_isAnim;
|
||||
};
|
||||
|
||||
struct EnablePerspectiveEvent
|
||||
struct SetAutoPerspectiveEvent
|
||||
{
|
||||
EnablePerspectiveEvent(double rotationAngle, double angleFOV,
|
||||
bool isAnim, bool immediatelyStart)
|
||||
: m_isAnim(isAnim)
|
||||
, m_immediatelyStart(immediatelyStart)
|
||||
, m_rotationAngle(rotationAngle)
|
||||
, m_angleFOV(angleFOV)
|
||||
SetAutoPerspectiveEvent(bool isAutoPerspective)
|
||||
: m_isAutoPerspective(isAutoPerspective)
|
||||
{}
|
||||
|
||||
bool m_isAnim;
|
||||
bool m_immediatelyStart;
|
||||
double m_rotationAngle;
|
||||
double m_angleFOV;
|
||||
};
|
||||
|
||||
struct DisablePerspectiveEvent
|
||||
{
|
||||
DisablePerspectiveEvent() {}
|
||||
};
|
||||
|
||||
struct SwitchViewModeEvent
|
||||
{
|
||||
SwitchViewModeEvent(bool to2d): m_to2d(to2d) {}
|
||||
|
||||
bool m_to2d;
|
||||
bool m_isAutoPerspective;
|
||||
};
|
||||
|
||||
struct RotateEvent
|
||||
|
@ -200,9 +181,7 @@ struct UserEvent
|
|||
EVENT_RESIZE,
|
||||
EVENT_ROTATE,
|
||||
EVENT_FOLLOW_AND_ROTATE,
|
||||
EVENT_ENABLE_PERSPECTIVE,
|
||||
EVENT_DISABLE_PERSPECTIVE,
|
||||
EVENT_SWITCH_VIEW_MODE
|
||||
EVENT_AUTO_PERSPECTIVE
|
||||
};
|
||||
|
||||
UserEvent(TouchEvent const & e) : m_type(EVENT_TOUCH) { m_touchEvent = e; }
|
||||
|
@ -213,9 +192,7 @@ struct UserEvent
|
|||
UserEvent(ResizeEvent const & e) : m_type(EVENT_RESIZE) { m_resize = e; }
|
||||
UserEvent(RotateEvent const & e) : m_type(EVENT_ROTATE) { m_rotate = e; }
|
||||
UserEvent(FollowAndRotateEvent const & e) : m_type(EVENT_FOLLOW_AND_ROTATE) { m_followAndRotate = e; }
|
||||
UserEvent(EnablePerspectiveEvent const & e) : m_type(EVENT_ENABLE_PERSPECTIVE) { m_enable3dMode = e; }
|
||||
UserEvent(DisablePerspectiveEvent const & e) : m_type(EVENT_DISABLE_PERSPECTIVE) { m_disable3dMode = e; }
|
||||
UserEvent(SwitchViewModeEvent const & e) : m_type(EVENT_SWITCH_VIEW_MODE) { m_switchViewMode = e; }
|
||||
UserEvent(SetAutoPerspectiveEvent const & e) : m_type(EVENT_AUTO_PERSPECTIVE) { m_autoPerspective = e; }
|
||||
|
||||
EEventType m_type;
|
||||
union
|
||||
|
@ -228,9 +205,7 @@ struct UserEvent
|
|||
ResizeEvent m_resize;
|
||||
RotateEvent m_rotate;
|
||||
FollowAndRotateEvent m_followAndRotate;
|
||||
EnablePerspectiveEvent m_enable3dMode;
|
||||
DisablePerspectiveEvent m_disable3dMode;
|
||||
SwitchViewModeEvent m_switchViewMode;
|
||||
SetAutoPerspectiveEvent m_autoPerspective;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -259,7 +234,6 @@ public:
|
|||
virtual void OnAnimatedScaleEnded() = 0;
|
||||
|
||||
virtual void OnAnimationStarted(ref_ptr<Animation> anim) = 0;
|
||||
virtual void OnPerspectiveSwitchRejected() = 0;
|
||||
|
||||
virtual void OnTouchMapAction() = 0;
|
||||
};
|
||||
|
@ -269,9 +243,9 @@ public:
|
|||
ScreenBase const & ProcessEvents(bool & modelViewChanged, bool & viewportChanged);
|
||||
ScreenBase const & GetCurrentScreen() const;
|
||||
|
||||
void GetTargetScreen(ScreenBase & screen) const;
|
||||
m2::AnyRectD GetTargetRect() const;
|
||||
bool IsInUserAction() const;
|
||||
bool IsInPerspectiveAnimation() const;
|
||||
bool IsWaitingForActionCompletion() const;
|
||||
|
||||
void SetListener(ref_ptr<Listener> listener) { m_listener = listener; }
|
||||
|
@ -306,13 +280,10 @@ private:
|
|||
bool SetCenter(m2::PointD const & center, int zoom, bool isAnim);
|
||||
bool SetRect(m2::RectD rect, int zoom, bool applyRotation, bool isAnim);
|
||||
bool SetRect(m2::AnyRectD const & rect, bool isAnim);
|
||||
bool SetScreen(ScreenBase const & screen, bool isAnim);
|
||||
bool SetFollowAndRotate(m2::PointD const & userPos, m2::PointD const & pixelPos,
|
||||
double azimuth, int preferredZoomLevel, bool isAnim);
|
||||
|
||||
bool FilterEventWhile3dAnimation(UserEvent::EEventType type) const;
|
||||
void SetEnable3dMode(double maxRotationAngle, double angleFOV,
|
||||
bool isAnim, bool immediatelyStart);
|
||||
void SetDisable3dModeAnimation();
|
||||
void SetAutoPerspective(bool isAutoPerspective);
|
||||
|
||||
m2::AnyRectD GetCurrentRect() const;
|
||||
|
||||
|
@ -357,7 +328,6 @@ private:
|
|||
void ResetAnimations(Animation::Type animType, bool finishAll = false);
|
||||
void ResetAnimations(Animation::Type animType, string const & customType, bool finishAll = false);
|
||||
void ResetMapPlaneAnimations();
|
||||
void ResetAnimationsBeforeSwitch3D();
|
||||
bool InterruptFollowAnimations(bool force);
|
||||
|
||||
list<UserEvent> m_events;
|
||||
|
@ -383,12 +353,8 @@ private:
|
|||
AnimationSystem & m_animationSystem;
|
||||
|
||||
bool m_modelViewChanged = false;
|
||||
bool m_viewportChanged = false;
|
||||
|
||||
bool m_perspectiveAnimation = false;
|
||||
unique_ptr<UserEvent> m_pendingEvent;
|
||||
double m_discardedFOV = 0.0;
|
||||
double m_discardedAngle = 0.0;
|
||||
|
||||
ref_ptr<Listener> m_listener;
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#include "geometry/mercator.hpp"
|
||||
|
||||
#include "indexer/scales.hpp"
|
||||
|
||||
#include "std/limits.hpp"
|
||||
#include "std/algorithm.hpp"
|
||||
|
||||
|
@ -270,4 +272,14 @@ int GetDrawTileScale(m2::RectD const & r)
|
|||
return GetDrawTileScale(r, p.GetTileSize(), p.GetVisualScale());
|
||||
}
|
||||
|
||||
double GetZoomLevel(double scale)
|
||||
{
|
||||
return my::clamp(fabs(log(scale) / log(2.0)), 1, scales::GetUpperStyleScale());
|
||||
}
|
||||
|
||||
double GetScale(double zoomLevel)
|
||||
{
|
||||
return pow(2.0, -zoomLevel);
|
||||
}
|
||||
|
||||
} // namespace df
|
||||
|
|
|
@ -75,4 +75,7 @@ m2::RectD GetRectForDrawScale(double drawScale, m2::PointD const & center);
|
|||
|
||||
int CalculateTileSize(int screenWidth, int screenHeight);
|
||||
|
||||
double GetZoomLevel(double scale);
|
||||
double GetScale(double zoomLevel);
|
||||
|
||||
} // namespace df
|
||||
|
|
|
@ -287,6 +287,12 @@ namespace m2
|
|||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool IsEqualSize(Rect<T> const & r1, Rect<T> const & r2, double epsX, double epsY)
|
||||
{
|
||||
return fabs(r1.SizeX() - r2.SizeX()) < epsX && fabs(r1.SizeY() - r2.SizeY()) < epsY;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline m2::Rect<T> const Add(m2::Rect<T> const & r, m2::Point<T> const & p)
|
||||
{
|
||||
|
|
|
@ -7,26 +7,33 @@
|
|||
|
||||
#include "std/cmath.hpp"
|
||||
|
||||
double constexpr kPerspectiveAngleFOV = math::pi / 3.0;
|
||||
double constexpr kMaxPerspectiveAngle1 = math::pi4;
|
||||
double constexpr kMaxPerspectiveAngle2 = math::pi * 55.0 / 180.0;
|
||||
|
||||
double constexpr kStartPerspectiveScale1 = 1.7e-5;
|
||||
double constexpr kEndPerspectiveScale1 = 0.3e-5;
|
||||
double constexpr kEndPerspectiveScale2 = 0.13e-5;
|
||||
|
||||
ScreenBase::ScreenBase() :
|
||||
m_PixelRect(0, 0, 640, 480),
|
||||
m_ViewportRect(0, 0, 640, 480),
|
||||
m_PixelRect(m_ViewportRect),
|
||||
m_Scale(0.1),
|
||||
m_Angle(0.0),
|
||||
m_Org(320, 240),
|
||||
m_3dFOV(0.0),
|
||||
m_3dFOV(kPerspectiveAngleFOV),
|
||||
m_3dNearZ(0.001),
|
||||
m_3dFarZ(0.0),
|
||||
m_3dAngleX(0.0),
|
||||
m_3dMaxAngleX(0.0),
|
||||
m_3dScaleX(1.0),
|
||||
m_3dScaleY(1.0),
|
||||
m_3dScale(1.0),
|
||||
m_isPerspective(false),
|
||||
m_isAutoPerspective(false),
|
||||
m_GlobalRect(m_Org, ang::AngleD(0), m2::RectD(-320, -240, 320, 240)),
|
||||
m_ClipRect(m2::RectD(0, 0, 640, 480))
|
||||
{
|
||||
m_GtoP = math::Identity<double, 3>();
|
||||
m_PtoG = math::Identity<double, 3>();
|
||||
// UpdateDependentParameters();
|
||||
}
|
||||
|
||||
ScreenBase::ScreenBase(m2::RectI const & pxRect, m2::AnyRectD const & glbRect)
|
||||
|
@ -37,7 +44,7 @@ ScreenBase::ScreenBase(m2::RectI const & pxRect, m2::AnyRectD const & glbRect)
|
|||
|
||||
ScreenBase::ScreenBase(ScreenBase const & s,
|
||||
m2::PointD const & org, double scale, double angle)
|
||||
: m_PixelRect(s.m_PixelRect),
|
||||
: m_ViewportRect(s.m_ViewportRect),
|
||||
m_Scale(scale), m_Angle(angle), m_Org(org)
|
||||
{
|
||||
UpdateDependentParameters();
|
||||
|
@ -45,6 +52,8 @@ ScreenBase::ScreenBase(ScreenBase const & s,
|
|||
|
||||
void ScreenBase::UpdateDependentParameters()
|
||||
{
|
||||
m_PixelRect = CalculatePixelRect(m_Scale);
|
||||
|
||||
m_PtoG = math::Shift( /// 5. shifting on (E0, N0)
|
||||
math::Rotate( /// 4. rotating on the screen angle
|
||||
math::Scale( /// 3. scaling to translate pixel sizes to global
|
||||
|
@ -73,6 +82,50 @@ void ScreenBase::UpdateDependentParameters()
|
|||
|
||||
m_GlobalRect = m2::AnyRectD(m_Org, m_Angle, m2::RectD(-szX, -szY, szX, szY));
|
||||
m_ClipRect = m_GlobalRect.GetGlobalRect();
|
||||
|
||||
double const kEps = 1e-5;
|
||||
double angle = CalculatePerspectiveAngle(m_Scale);
|
||||
m_isPerspective = angle > 0.0;
|
||||
if (fabs(angle - m_3dAngleX) > kEps)
|
||||
{
|
||||
m_3dMaxAngleX = angle;
|
||||
m_3dScale = CalculateScale3d(angle);
|
||||
SetRotationAngle(angle);
|
||||
}
|
||||
}
|
||||
|
||||
double ScreenBase::CalculateAutoPerspectiveAngle(double scale)
|
||||
{
|
||||
if (scale > kStartPerspectiveScale1)
|
||||
return 0.0;
|
||||
|
||||
if (scale > kEndPerspectiveScale1)
|
||||
{
|
||||
double const k = (kStartPerspectiveScale1 - scale) / (kStartPerspectiveScale1 - kEndPerspectiveScale1);
|
||||
return kMaxPerspectiveAngle1 * k;
|
||||
}
|
||||
|
||||
if (scale > kEndPerspectiveScale2)
|
||||
{
|
||||
double const k = (kEndPerspectiveScale1 - scale) / (kEndPerspectiveScale1 - kEndPerspectiveScale2);
|
||||
return kMaxPerspectiveAngle1 + (kMaxPerspectiveAngle2 - kMaxPerspectiveAngle1) * k;
|
||||
}
|
||||
|
||||
return kMaxPerspectiveAngle2 * 0.99;
|
||||
}
|
||||
|
||||
double ScreenBase::CalculatePerspectiveAngle(double scale) const
|
||||
{
|
||||
if (!m_isAutoPerspective)
|
||||
return m_3dAngleX;
|
||||
|
||||
return CalculateAutoPerspectiveAngle(scale);
|
||||
}
|
||||
|
||||
void ScreenBase::SetAutoPerspective(bool isAutoPerspective)
|
||||
{
|
||||
m_isAutoPerspective = isAutoPerspective;
|
||||
UpdateDependentParameters();
|
||||
}
|
||||
|
||||
void ScreenBase::SetFromRects(m2::AnyRectD const & glbRect, m2::RectD const & pxRect)
|
||||
|
@ -92,6 +145,26 @@ void ScreenBase::SetFromRect(m2::AnyRectD const & glbRect)
|
|||
SetFromRects(glbRect, m_PixelRect);
|
||||
}
|
||||
|
||||
void ScreenBase::SetFromParams(m2::PointD const & org, double angle, double scale)
|
||||
{
|
||||
m_Scale = scale;
|
||||
m_Angle = angle;
|
||||
m_Org = org;
|
||||
UpdateDependentParameters();
|
||||
}
|
||||
|
||||
void ScreenBase::MatchGandP(m2::PointD const & g, m2::PointD const & p)
|
||||
{
|
||||
m2::PointD g_current = PtoG(p);
|
||||
SetOrg(m_Org - g_current + g);
|
||||
}
|
||||
|
||||
void ScreenBase::MatchGandP3d(m2::PointD const & g, m2::PointD const &p3d)
|
||||
{
|
||||
m2::PointD g_current = PtoG(P3dtoP(p3d));
|
||||
SetOrg(m_Org - g_current + g);
|
||||
}
|
||||
|
||||
void ScreenBase::SetOrg(m2::PointD const & p)
|
||||
{
|
||||
m_Org = p;
|
||||
|
@ -124,7 +197,7 @@ void ScreenBase::Rotate(double angle)
|
|||
|
||||
void ScreenBase::OnSize(m2::RectI const & r)
|
||||
{
|
||||
m_PixelRect = m2::RectD(r);
|
||||
m_ViewportRect = m2::RectD(r);
|
||||
UpdateDependentParameters();
|
||||
}
|
||||
|
||||
|
@ -133,11 +206,6 @@ void ScreenBase::OnSize(int x0, int y0, int w, int h)
|
|||
OnSize(m2::RectI(x0, y0, x0 + w, y0 + h));
|
||||
}
|
||||
|
||||
double ScreenBase::GetMinPixelRectSize() const
|
||||
{
|
||||
return min(m_PixelRect.SizeX(), m_PixelRect.SizeY());
|
||||
}
|
||||
|
||||
void ScreenBase::SetScale(double scale)
|
||||
{
|
||||
m_Scale = scale;
|
||||
|
@ -254,6 +322,32 @@ void ScreenBase::ExtractGtoPParams(MatrixT const & m,
|
|||
dy = m(2, 1);
|
||||
}
|
||||
|
||||
double ScreenBase::CalculateScale3d(double rotationAngle) const
|
||||
{
|
||||
double const halfFOV = m_3dFOV / 2.0;
|
||||
double const cameraZ = 1.0 / tan(halfFOV);
|
||||
|
||||
// Ratio of the expanded plane's size to the original size.
|
||||
double const y3dScale = cos(rotationAngle) + sin(rotationAngle) * tan(halfFOV + rotationAngle);
|
||||
double const x3dScale = 1.0 + 2 * sin(rotationAngle) * cos(halfFOV) / (cameraZ * cos(halfFOV + rotationAngle));
|
||||
|
||||
return max(x3dScale, y3dScale);
|
||||
}
|
||||
|
||||
m2::RectD ScreenBase::CalculatePixelRect(double scale) const
|
||||
{
|
||||
double const angle = CalculatePerspectiveAngle(scale);
|
||||
if (angle > 0.0)
|
||||
{
|
||||
double const scale3d = CalculateScale3d(angle);
|
||||
|
||||
return m2::RectD(m2::PointD(0.0, 0.0),
|
||||
m2::PointD(m_ViewportRect.maxX(), m_ViewportRect.maxY()) * scale3d);
|
||||
}
|
||||
|
||||
return m_ViewportRect;
|
||||
}
|
||||
|
||||
// Place the camera at the distance, where it gives the same view of plane as the
|
||||
// orthogonal projection does. Calculate what part of the map would be visible,
|
||||
// when it is rotated through maxRotationAngle around its near horizontal side.
|
||||
|
@ -264,38 +358,28 @@ void ScreenBase::ApplyPerspective(double currentRotationAngle, double maxRotatio
|
|||
ASSERT_GREATER_OR_EQUAL(maxRotationAngle, 0.0, ());
|
||||
ASSERT_LESS(maxRotationAngle, math::pi2, ());
|
||||
|
||||
if (m_isPerspective)
|
||||
ResetPerspective();
|
||||
|
||||
m_isPerspective = true;
|
||||
m_isAutoPerspective = false;
|
||||
|
||||
m_3dMaxAngleX = maxRotationAngle;
|
||||
m_3dAngleX = currentRotationAngle;
|
||||
m_3dFOV = angleFOV;
|
||||
|
||||
double const halfFOV = m_3dFOV / 2.0;
|
||||
double const cameraZ = 1.0 / tan(halfFOV);
|
||||
double const old_dy = m_ViewportRect.SizeY() * (m_3dScale - 1.0);
|
||||
|
||||
// Ratio of the expanded plane's size to the original size.
|
||||
m_3dScaleY = cos(m_3dMaxAngleX) + sin(m_3dMaxAngleX) * tan(halfFOV + m_3dMaxAngleX);
|
||||
m_3dScaleX = 1.0 + 2 * sin(m_3dMaxAngleX) * cos(halfFOV) / (cameraZ * cos(halfFOV + m_3dMaxAngleX));
|
||||
|
||||
m_3dScaleX = m_3dScaleY = max(m_3dScaleX, m_3dScaleY);
|
||||
|
||||
double const dy = m_PixelRect.SizeY() * (m_3dScaleX - 1.0);
|
||||
|
||||
m_PixelRect.setMaxX(m_PixelRect.maxX() * m_3dScaleX);
|
||||
m_PixelRect.setMaxY(m_PixelRect.maxY() * m_3dScaleY);
|
||||
|
||||
Move(0.0, dy / 2.0);
|
||||
m_3dScale = CalculateScale3d(m_3dMaxAngleX);
|
||||
double const new_dy = m_ViewportRect.SizeY() * (m_3dScale - 1.0);
|
||||
|
||||
SetRotationAngle(currentRotationAngle);
|
||||
|
||||
Move(0.0, (new_dy - old_dy) / 2.0);
|
||||
}
|
||||
|
||||
// Place the camera at the distance, where it gives the same view of plane as the
|
||||
// orthogonal projection does and rotate the map plane around its near horizontal side.
|
||||
void ScreenBase::SetRotationAngle(double rotationAngle)
|
||||
{
|
||||
ASSERT(m_isPerspective, ());
|
||||
ASSERT(rotationAngle == 0.0 || (rotationAngle > 0.0 && m_isPerspective), ());
|
||||
ASSERT_GREATER_OR_EQUAL(rotationAngle, 0.0, ());
|
||||
ASSERT_LESS_OR_EQUAL(rotationAngle, m_3dMaxAngleX, ());
|
||||
|
||||
|
@ -307,12 +391,12 @@ void ScreenBase::SetRotationAngle(double rotationAngle)
|
|||
double const halfFOV = m_3dFOV / 2.0;
|
||||
double const cameraZ = 1.0 / tan(halfFOV);
|
||||
|
||||
double const offsetZ = cameraZ + sin(m_3dAngleX) * m_3dScaleY;
|
||||
double const offsetY = cos(m_3dAngleX) * m_3dScaleX - 1.0;
|
||||
double const offsetZ = cameraZ + sin(m_3dAngleX) * m_3dScale;
|
||||
double const offsetY = cos(m_3dAngleX) * m_3dScale - 1.0;
|
||||
|
||||
Matrix3dT scaleM = math::Identity<double, 4>();
|
||||
scaleM(0, 0) = m_3dScaleX;
|
||||
scaleM(1, 1) = m_3dScaleY;
|
||||
scaleM(0, 0) = m_3dScale;
|
||||
scaleM(1, 1) = m_3dScale;
|
||||
|
||||
Matrix3dT rotateM = math::Identity<double, 4>();
|
||||
rotateM(1, 1) = cos(m_3dAngleX);
|
||||
|
@ -325,7 +409,7 @@ void ScreenBase::SetRotationAngle(double rotationAngle)
|
|||
translateM(3, 2) = offsetZ;
|
||||
|
||||
Matrix3dT projectionM = math::Zero<double, 4>();
|
||||
m_3dFarZ = cameraZ + 2.0 * sin(m_3dAngleX) * m_3dScaleY;
|
||||
m_3dFarZ = cameraZ + 2.0 * sin(m_3dAngleX) * m_3dScale;
|
||||
projectionM(0, 0) = projectionM(1, 1) = cameraZ;
|
||||
projectionM(2, 2) = m_3dAngleX != 0.0 ? (m_3dFarZ + m_3dNearZ) / (m_3dFarZ - m_3dNearZ)
|
||||
: 0.0;
|
||||
|
@ -340,18 +424,15 @@ void ScreenBase::SetRotationAngle(double rotationAngle)
|
|||
void ScreenBase::ResetPerspective()
|
||||
{
|
||||
m_isPerspective = false;
|
||||
m_isAutoPerspective = false;
|
||||
|
||||
double const dy = m_PixelRect.SizeY() * (1.0 - 1.0 / m_3dScaleX);
|
||||
double const old_dy = m_ViewportRect.SizeY() * (m_3dScale - 1.0);
|
||||
|
||||
m_PixelRect.setMaxX(m_PixelRect.maxX() / m_3dScaleX);
|
||||
m_PixelRect.setMaxY(m_PixelRect.maxY() / m_3dScaleY);
|
||||
|
||||
Move(0, -dy / 2.0);
|
||||
|
||||
m_3dScaleX = m_3dScaleY = 1.0;
|
||||
m_3dScale = 1.0;
|
||||
m_3dAngleX = 0.0;
|
||||
m_3dMaxAngleX = 0.0;
|
||||
m_3dFOV = 0.0;
|
||||
|
||||
Move(0.0, -old_dy / 2.0);
|
||||
}
|
||||
|
||||
m2::PointD ScreenBase::PtoP3d(m2::PointD const & pt) const
|
||||
|
|
|
@ -15,6 +15,7 @@ public:
|
|||
using Vector3dT = math::Matrix<double, 1, 4>;
|
||||
|
||||
private:
|
||||
m2::RectD m_ViewportRect;
|
||||
m2::RectD m_PixelRect;
|
||||
|
||||
double m_Scale;
|
||||
|
@ -26,9 +27,9 @@ private:
|
|||
double m_3dFarZ;
|
||||
double m_3dAngleX;
|
||||
double m_3dMaxAngleX;
|
||||
double m_3dScaleX;
|
||||
double m_3dScaleY;
|
||||
double m_3dScale;
|
||||
bool m_isPerspective;
|
||||
bool m_isAutoPerspective;
|
||||
|
||||
protected:
|
||||
/// @group Dependent parameters
|
||||
|
@ -64,6 +65,8 @@ public:
|
|||
m2::PointD const & org, double scale, double angle);
|
||||
|
||||
void SetFromRect(m2::AnyRectD const & rect);
|
||||
|
||||
void SetFromParams(m2::PointD const & org, double angle, double scale);
|
||||
void SetFromRects(m2::AnyRectD const & glbRect, m2::RectD const & pxRect);
|
||||
void SetOrg(m2::PointD const & p);
|
||||
|
||||
|
@ -115,6 +118,9 @@ public:
|
|||
void GtoP(m2::RectD const & gr, m2::RectD & sr) const;
|
||||
void PtoG(m2::RectD const & pr, m2::RectD & gr) const;
|
||||
|
||||
void MatchGandP(m2::PointD const & g, m2::PointD const & p);
|
||||
void MatchGandP3d(m2::PointD const & g, m2::PointD const & p3d);
|
||||
|
||||
void GetTouchRect(m2::PointD const & pixPoint, double pixRadius, m2::AnyRectD & glbRect) const;
|
||||
void GetTouchRect(m2::PointD const & pixPoint, double const pxWidth,
|
||||
double const pxHeight, m2::AnyRectD & glbRect) const;
|
||||
|
@ -131,13 +137,16 @@ public:
|
|||
|
||||
void SetRotationAngle(double rotationAngle);
|
||||
double GetRotationAngle() const { return m_3dAngleX; }
|
||||
|
||||
double GetMaxRotationAngle() const { return m_3dMaxAngleX; }
|
||||
double GetAngleFOV() const { return m_3dFOV; }
|
||||
double GetScale3d() const { return m_3dScale; }
|
||||
|
||||
m2::PointD P3dtoP(m2::PointD const & pt) const;
|
||||
|
||||
Matrix3dT const & Pto3dMatrix() const { return m_Pto3d; }
|
||||
bool isPerspective() const { return m_isPerspective; }
|
||||
bool isAutoPerspective() const { return m_isAutoPerspective; }
|
||||
void SetAutoPerspective(bool isAutoPerspective);
|
||||
|
||||
bool IsReverseProjection3d(m2::PointD const & pt) const;
|
||||
|
||||
|
@ -146,16 +155,21 @@ public:
|
|||
|
||||
m2::RectD PixelRectIn3d() const
|
||||
{
|
||||
return m2::RectD(0.0, 0.0, m_PixelRect.maxX() / m_3dScaleX, m_PixelRect.maxY() / m_3dScaleY);
|
||||
return m_ViewportRect;
|
||||
}
|
||||
|
||||
double GetMinPixelRectSize() const;
|
||||
double CalculateScale3d(double rotationAngle) const;
|
||||
m2::RectD CalculatePixelRect(double scale) const;
|
||||
double CalculatePerspectiveAngle(double scale) const;
|
||||
|
||||
static double CalculateAutoPerspectiveAngle(double scale);
|
||||
|
||||
/// Compute arbitrary pixel transformation, that translates the (oldPt1, oldPt2) -> (newPt1, newPt2)
|
||||
static MatrixT const CalcTransform(m2::PointD const & oldPt1, m2::PointD const & oldPt2,
|
||||
m2::PointD const & newPt1, m2::PointD const & newPt2,
|
||||
bool allowRotate);
|
||||
|
||||
|
||||
/// Setting GtoP matrix extracts the Angle and m_Org parameters, leaving PixelRect intact
|
||||
void SetGtoPMatrix(MatrixT const & m);
|
||||
|
||||
|
|
|
@ -111,9 +111,6 @@ char const kAllow3dBuildingsKey[] = "Buildings3d";
|
|||
|
||||
double const kDistEqualQuery = 100.0;
|
||||
|
||||
double const kRotationAngle = math::pi4;
|
||||
double const kAngleFOV = math::pi / 3.0;
|
||||
|
||||
// TODO!
|
||||
// To adjust GpsTrackFilter was added secret command "?gpstrackaccuracy:xxx;"
|
||||
// where xxx is a new value for horizontal accuracy.
|
||||
|
@ -1386,10 +1383,7 @@ void Framework::ShowSearchResult(search::Result const & res)
|
|||
}
|
||||
|
||||
m2::PointD const center = info.GetMercator();
|
||||
if (m_currentModelView.isPerspective())
|
||||
CallDrapeFunction(bind(&df::DrapeEngine::SetModelViewCenter, _1, center, scale, true));
|
||||
else
|
||||
ShowRect(df::GetRectForDrawScale(scale, center));
|
||||
CallDrapeFunction(bind(&df::DrapeEngine::SetModelViewCenter, _1, center, scale, true));
|
||||
|
||||
UserMarkContainer::UserMarkForPoi()->SetPtOrg(center);
|
||||
ActivateMapSelection(false, df::SelectionShape::OBJECT_POI, info);
|
||||
|
@ -1611,7 +1605,7 @@ void Framework::CreateDrapeEngine(ref_ptr<dp::OGLContextFactory> contextFactory,
|
|||
{
|
||||
InsertRoute(m_routingSession.GetRoute());
|
||||
if (allow3d && m_routingSession.IsFollowing())
|
||||
m_drapeEngine->EnablePerspective(kRotationAngle, kAngleFOV);
|
||||
m_drapeEngine->EnablePerspective();
|
||||
}
|
||||
|
||||
if (m_connectToGpsTrack)
|
||||
|
@ -2294,7 +2288,7 @@ void Framework::FollowRoute()
|
|||
: scales::GetNavigationScale();
|
||||
int const scale3d = (m_currentRouterType == RouterType::Pedestrian) ? scales::GetPedestrianNavigation3dScale()
|
||||
: scales::GetNavigation3dScale();
|
||||
m_drapeEngine->FollowRoute(scale, scale3d, kRotationAngle, kAngleFOV);
|
||||
m_drapeEngine->FollowRoute(scale, scale3d);
|
||||
m_drapeEngine->SetRoutePoint(m2::PointD(), true /* isStart */, false /* isValid */);
|
||||
}
|
||||
|
||||
|
@ -2537,7 +2531,7 @@ void Framework::SetRouteFinishPoint(m2::PointD const & pt, bool isValid)
|
|||
|
||||
void Framework::Allow3dMode(bool allow3d, bool allow3dBuildings)
|
||||
{
|
||||
CallDrapeFunction(bind(&df::DrapeEngine::Allow3dMode, _1, allow3d, allow3dBuildings, kRotationAngle, kAngleFOV));
|
||||
CallDrapeFunction(bind(&df::DrapeEngine::Allow3dMode, _1, allow3d, allow3dBuildings));
|
||||
}
|
||||
|
||||
void Framework::Save3dMode(bool allow3d, bool allow3dBuildings)
|
||||
|
|
Loading…
Add table
Reference in a new issue