Repo created
This commit is contained in:
parent
4af19165ec
commit
68073add76
12458 changed files with 12350765 additions and 2 deletions
232
libs/drape_frontend/animation/follow_animation.cpp
Normal file
232
libs/drape_frontend/animation/follow_animation.cpp
Normal file
|
|
@ -0,0 +1,232 @@
|
|||
#include "drape_frontend/animation/follow_animation.hpp"
|
||||
|
||||
#include "drape_frontend/animation_constants.hpp"
|
||||
#include "drape_frontend/animation_system.hpp"
|
||||
|
||||
#include "base/assert.hpp"
|
||||
#include "base/logging.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace df
|
||||
{
|
||||
|
||||
MapFollowAnimation::MapFollowAnimation(ScreenBase const & screen, m2::PointD const & globalUserPosition,
|
||||
m2::PointD const & endPixelPosition, double endScale, double endAngle,
|
||||
bool isAutoZoom)
|
||||
: Animation(true /* couldBeInterrupted */, true /* couldBeBlended */)
|
||||
, m_isAutoZoom(isAutoZoom)
|
||||
, m_globalPosition(globalUserPosition)
|
||||
, m_endPixelPosition(endPixelPosition)
|
||||
, m_endScale(endScale)
|
||||
, m_endAngle(endAngle)
|
||||
{
|
||||
TPropertyCache properties;
|
||||
Init(screen, properties);
|
||||
}
|
||||
|
||||
void MapFollowAnimation::Init(ScreenBase const & screen, TPropertyCache const & properties)
|
||||
{
|
||||
ScreenBase currentScreen;
|
||||
GetCurrentScreen(properties, screen, currentScreen);
|
||||
|
||||
double minDuration = m_offsetInterpolator.GetMinDuration();
|
||||
double maxDuration = m_offsetInterpolator.GetMaxDuration();
|
||||
|
||||
m_offset = currentScreen.PtoG(currentScreen.P3dtoP(m_endPixelPosition)) - m_globalPosition;
|
||||
double const averageScale = m_isAutoZoom ? currentScreen.GetScale() : (currentScreen.GetScale() + m_endScale) / 2.0;
|
||||
double const moveDuration =
|
||||
PositionInterpolator::GetMoveDuration(m_offset.Length(), screen.PixelRectIn3d(), averageScale);
|
||||
m_offsetInterpolator = PositionInterpolator(moveDuration, 0.0, m_offset, m2::PointD(0.0, 0.0));
|
||||
|
||||
m_offsetInterpolator.SetMinDuration(minDuration);
|
||||
m_offsetInterpolator.SetMaxDuration(maxDuration);
|
||||
|
||||
maxDuration = m_scaleInterpolator.GetMaxDuration();
|
||||
m_scaleInterpolator = ScaleInterpolator(currentScreen.GetScale(), m_endScale, m_isAutoZoom);
|
||||
m_scaleInterpolator.SetMaxDuration(maxDuration);
|
||||
|
||||
maxDuration = m_angleInterpolator.GetMaxDuration();
|
||||
m_angleInterpolator = AngleInterpolator(currentScreen.GetAngle(), m_endAngle);
|
||||
m_angleInterpolator.SetMaxDuration(maxDuration);
|
||||
|
||||
double const duration = CalculateDuration();
|
||||
|
||||
m_scaleInterpolator.SetMinDuration(duration);
|
||||
m_angleInterpolator.SetMinDuration(duration);
|
||||
|
||||
m_objects.insert(Animation::Object::MapPlane);
|
||||
|
||||
if (m_scaleInterpolator.IsActive())
|
||||
m_properties.insert(Animation::ObjectProperty::Scale);
|
||||
if (m_angleInterpolator.IsActive())
|
||||
m_properties.insert(Animation::ObjectProperty::Angle);
|
||||
if (m_offsetInterpolator.IsActive() || m_scaleInterpolator.IsActive() || m_angleInterpolator.IsActive())
|
||||
m_properties.insert(Animation::ObjectProperty::Position);
|
||||
|
||||
// If MapFollowAnimation affects only angles, disable rewinding.
|
||||
SetCouldBeRewinded(!m_angleInterpolator.IsActive() || m_scaleInterpolator.IsActive() ||
|
||||
m_offsetInterpolator.IsActive());
|
||||
}
|
||||
|
||||
Animation::TObjectProperties const & MapFollowAnimation::GetProperties(Object object) const
|
||||
{
|
||||
ASSERT_EQUAL(static_cast<int>(object), static_cast<int>(Animation::Object::MapPlane), ());
|
||||
return m_properties;
|
||||
}
|
||||
|
||||
bool MapFollowAnimation::HasProperty(Object object, ObjectProperty property) const
|
||||
{
|
||||
return HasObject(object) && m_properties.find(property) != m_properties.end();
|
||||
}
|
||||
|
||||
void MapFollowAnimation::Advance(double elapsedSeconds)
|
||||
{
|
||||
if (m_angleInterpolator.IsActive())
|
||||
m_angleInterpolator.Advance(elapsedSeconds);
|
||||
if (m_scaleInterpolator.IsActive())
|
||||
m_scaleInterpolator.Advance(elapsedSeconds);
|
||||
if (m_offsetInterpolator.IsActive())
|
||||
m_offsetInterpolator.Advance(elapsedSeconds);
|
||||
}
|
||||
|
||||
void MapFollowAnimation::Finish()
|
||||
{
|
||||
if (m_angleInterpolator.IsActive())
|
||||
m_angleInterpolator.Finish();
|
||||
if (m_scaleInterpolator.IsActive())
|
||||
{
|
||||
if (m_isAutoZoom)
|
||||
m_scaleInterpolator.SetActive(false);
|
||||
else
|
||||
m_scaleInterpolator.Finish();
|
||||
}
|
||||
if (m_offsetInterpolator.IsActive())
|
||||
m_offsetInterpolator.Finish();
|
||||
Animation::Finish();
|
||||
}
|
||||
|
||||
void MapFollowAnimation::SetMaxDuration(double maxDuration)
|
||||
{
|
||||
if (m_angleInterpolator.IsActive())
|
||||
m_angleInterpolator.SetMaxDuration(maxDuration);
|
||||
if (!m_isAutoZoom && m_scaleInterpolator.IsActive())
|
||||
m_scaleInterpolator.SetMaxDuration(maxDuration);
|
||||
if (m_offsetInterpolator.IsActive())
|
||||
m_offsetInterpolator.SetMaxDuration(maxDuration);
|
||||
}
|
||||
|
||||
void MapFollowAnimation::SetMinDuration(double minDuration)
|
||||
{
|
||||
if (m_angleInterpolator.IsActive())
|
||||
m_angleInterpolator.SetMinDuration(minDuration);
|
||||
if (!m_isAutoZoom && m_scaleInterpolator.IsActive())
|
||||
m_scaleInterpolator.SetMinDuration(minDuration);
|
||||
if (m_offsetInterpolator.IsActive())
|
||||
m_offsetInterpolator.SetMinDuration(minDuration);
|
||||
}
|
||||
|
||||
double MapFollowAnimation::GetDuration() const
|
||||
{
|
||||
return CalculateDuration();
|
||||
}
|
||||
|
||||
double MapFollowAnimation::GetMaxDuration() const
|
||||
{
|
||||
double maxDuration = Animation::kInvalidAnimationDuration;
|
||||
|
||||
if (!Animation::GetMaxDuration(m_angleInterpolator, maxDuration) ||
|
||||
(!m_isAutoZoom && !Animation::GetMaxDuration(m_scaleInterpolator, maxDuration)) ||
|
||||
!Animation::GetMaxDuration(m_offsetInterpolator, maxDuration))
|
||||
return Animation::kInvalidAnimationDuration;
|
||||
|
||||
return maxDuration;
|
||||
}
|
||||
|
||||
double MapFollowAnimation::GetMinDuration() const
|
||||
{
|
||||
double minDuration = Animation::kInvalidAnimationDuration;
|
||||
|
||||
if (!Animation::GetMinDuration(m_angleInterpolator, minDuration) ||
|
||||
(!m_isAutoZoom && !Animation::GetMinDuration(m_scaleInterpolator, minDuration)) ||
|
||||
!Animation::GetMinDuration(m_offsetInterpolator, minDuration))
|
||||
return Animation::kInvalidAnimationDuration;
|
||||
|
||||
return minDuration;
|
||||
}
|
||||
|
||||
double MapFollowAnimation::CalculateDuration() const
|
||||
{
|
||||
double duration = std::max(m_angleInterpolator.GetDuration(), m_offsetInterpolator.GetDuration());
|
||||
if (!m_isAutoZoom)
|
||||
duration = std::max(duration, m_scaleInterpolator.GetDuration());
|
||||
return duration;
|
||||
}
|
||||
|
||||
bool MapFollowAnimation::IsFinished() const
|
||||
{
|
||||
return m_angleInterpolator.IsFinished() && m_scaleInterpolator.IsFinished() && m_offsetInterpolator.IsFinished();
|
||||
}
|
||||
|
||||
bool MapFollowAnimation::GetProperty(Object object, ObjectProperty property, PropertyValue & value) const
|
||||
{
|
||||
return GetProperty(object, property, false /* targetValue */, value);
|
||||
}
|
||||
|
||||
bool MapFollowAnimation::GetTargetProperty(Object object, ObjectProperty property, PropertyValue & value) const
|
||||
{
|
||||
return GetProperty(object, property, true /* targetValue */, value);
|
||||
}
|
||||
|
||||
bool MapFollowAnimation::GetProperty(Object object, ObjectProperty property, bool targetValue,
|
||||
PropertyValue & value) const
|
||||
{
|
||||
if (property == Animation::ObjectProperty::Position)
|
||||
{
|
||||
ScreenBase tmp = AnimationSystem::Instance().GetLastScreen();
|
||||
if (targetValue)
|
||||
{
|
||||
tmp.SetFromParams(m_globalPosition, m_angleInterpolator.GetTargetAngle(),
|
||||
m_isAutoZoom ? m_scaleInterpolator.GetScale() : m_scaleInterpolator.GetTargetScale());
|
||||
tmp.MatchGandP3d(m_globalPosition, m_endPixelPosition);
|
||||
}
|
||||
else
|
||||
{
|
||||
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::ObjectProperty::Angle)
|
||||
{
|
||||
value = PropertyValue(targetValue ? m_angleInterpolator.GetTargetAngle() : m_angleInterpolator.GetAngle());
|
||||
return true;
|
||||
}
|
||||
if (property == Animation::ObjectProperty::Scale)
|
||||
{
|
||||
value = PropertyValue((targetValue && !m_isAutoZoom) ? m_scaleInterpolator.GetTargetScale()
|
||||
: m_scaleInterpolator.GetScale());
|
||||
return true;
|
||||
}
|
||||
ASSERT(false, ("Wrong property:", static_cast<int>(property)));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MapFollowAnimation::HasScale() const
|
||||
{
|
||||
return m_scaleInterpolator.IsActive();
|
||||
}
|
||||
|
||||
bool MapFollowAnimation::HasPixelOffset() const
|
||||
{
|
||||
return m_offsetInterpolator.IsActive();
|
||||
}
|
||||
|
||||
} // namespace df
|
||||
Loading…
Add table
Add a link
Reference in a new issue