//------------------------------------------------------------------------------
// emViewAnimator.h
//
// Copyright (C) 2014-2017 Oliver Hamann.
//
// Homepage: http://eaglemode.sourceforge.net/
//
// This program is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License version 3 as published by the
// Free Software Foundation.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License version 3 for
// more details.
//
// You should have received a copy of the GNU General Public License version 3
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//------------------------------------------------------------------------------
#ifndef emViewAnimator_h
#define emViewAnimator_h
#ifndef emView_h
#include <emCore/emView.h>
#endif
//==============================================================================
//=============================== emViewAnimator ===============================
//==============================================================================
class emViewAnimator : public emEngine {
public:
emViewAnimator(emView & view);
virtual ~emViewAnimator();
emView & GetView() const;
void SetMaster(emViewAnimator * master);
emViewAnimator * GetMaster() const;
emViewAnimator * GetActiveSlave() const;
bool IsActive() const;
virtual void Activate();
virtual void Deactivate();
bool IsDeactivatingWhenIdle() const;
void SetDeactivateWhenIdle(bool deactivateWhenIdle=true);
virtual void Input(emInputEvent & event, const emInputState & state);
virtual void Paint(const emPainter & painter) const;
protected:
virtual bool Cycle();
virtual bool CycleAnimation(double dt) = 0;
void InvalidatePainting();
private:
emView & View;
emViewAnimator * Master;
emViewAnimator * ActiveSlave;
emViewAnimator * * UpperActivePtr;
emUInt64 LastTSC;
emUInt64 LastClk;
bool DeactivateWhenIdle;
};
inline emView & emViewAnimator::GetView() const
{
return View;
}
inline emViewAnimator * emViewAnimator::GetMaster() const
{
return Master;
}
inline emViewAnimator * emViewAnimator::GetActiveSlave() const
{
return ActiveSlave;
}
inline bool emViewAnimator::IsActive() const
{
return *UpperActivePtr==this;
}
inline bool emViewAnimator::IsDeactivatingWhenIdle() const
{
return DeactivateWhenIdle;
}
inline void emViewAnimator::InvalidatePainting()
{
View.InvalidatePainting();
}
//==============================================================================
//=========================== emKineticViewAnimator ============================
//==============================================================================
class emKineticViewAnimator : public emViewAnimator {
public:
emKineticViewAnimator(emView & view);
virtual ~emKineticViewAnimator();
virtual void Activate();
virtual void Deactivate();
double GetVelocity(int dimension) const;
double GetAbsVelocity() const;
void SetVelocity(int dimension, double velocity);
void CenterZoomFixPoint();
void SetZoomFixPoint(double zoomFixX, double zoomFixY);
void SetFrictionEnabled(bool enabled);
bool IsFrictionEnabled() const;
double GetFriction() const;
void SetFriction(double friction);
protected:
virtual bool CycleAnimation(double dt);
private:
void UpdateBusyState();
void UpdateZoomFixPoint();
double Velocity[3];
bool ZoomFixPointCentered;
double ZoomFixX,ZoomFixY;
bool FrictionEnabled;
double Friction;
bool Busy;
};
inline double emKineticViewAnimator::GetVelocity(int dimension) const
{
return Velocity[dimension];
}
inline bool emKineticViewAnimator::IsFrictionEnabled() const
{
return FrictionEnabled;
}
inline double emKineticViewAnimator::GetFriction() const
{
return Friction;
}
//==============================================================================
//=========================== emSpeedingViewAnimator ===========================
//==============================================================================
class emSpeedingViewAnimator : public emKineticViewAnimator {
public:
emSpeedingViewAnimator(emView & view);
virtual ~emSpeedingViewAnimator();
virtual void Activate();
virtual void Deactivate();
double GetTargetVelocity(int dimension) const;
double GetAbsTargetVelocity() const;
void SetTargetVelocity(int dimension, double targetVelocity);
double GetAcceleration() const;
void SetAcceleration(double acceleration);
double GetReverseAcceleration() const;
void SetReverseAcceleration(double reverseAcceleration);
protected:
virtual bool CycleAnimation(double dt);
private:
void UpdateBusyState();
double TargetVelocity[3];
double Acceleration;
double ReverseAcceleration;
bool Busy;
};
inline double emSpeedingViewAnimator::GetTargetVelocity(int dimension) const
{
return TargetVelocity[dimension];
}
inline double emSpeedingViewAnimator::GetAcceleration() const
{
return Acceleration;
}
inline double emSpeedingViewAnimator::GetReverseAcceleration() const
{
return ReverseAcceleration;
}
//==============================================================================
//=========================== emSwipingViewAnimator ============================
//==============================================================================
class emSwipingViewAnimator : public emKineticViewAnimator {
public:
emSwipingViewAnimator(emView & view);
virtual ~emSwipingViewAnimator();
virtual void Activate();
virtual void Deactivate();
bool IsGripped() const;
void SetGripped(bool gripped);
void MoveGrip(int dimension, double distance);
double GetSpringConstant() const;
void SetSpringConstant(double springConstant);
double GetAbsSpringExtension() const;
protected:
virtual bool CycleAnimation(double dt);
private:
void UpdateBusyState();
bool Gripped;
double SpringExtension[3];
double InstantaneousVelocity[3];
double SpringConstant;
bool Busy;
};
inline bool emSwipingViewAnimator::IsGripped() const
{
return Gripped;
}
inline double emSwipingViewAnimator::GetSpringConstant() const
{
return SpringConstant;
}
//==============================================================================
//=========================== emMagneticViewAnimator ===========================
//==============================================================================
class emMagneticViewAnimator : public emKineticViewAnimator {
public:
emMagneticViewAnimator(emView & view);
virtual ~emMagneticViewAnimator();
virtual void Activate();
virtual void Deactivate();
protected:
virtual bool CycleAnimation(double dt);
private:
double CalculateDistance(double * pDX, double * pDY, double * pDZ) const;
void GetViewRect(double * pX, double * pY,
double * pW, double * pH) const;
emRef<emCoreConfig> CoreConfig;
bool MagnetismActive;
};
//==============================================================================
//=========================== emVisitingViewAnimator ===========================
//==============================================================================
class emVisitingViewAnimator : public emViewAnimator {
public:
emVisitingViewAnimator(emView & view);
virtual ~emVisitingViewAnimator();
bool IsAnimated() const;
void SetAnimated(bool animated=true);
double GetAcceleration() const;
void SetAcceleration(double acceleration);
double GetMaxCuspSpeed() const;
void SetMaxCuspSpeed(double maxCuspSpeed);
double GetMaxAbsoluteSpeed() const;
void SetMaxAbsoluteSpeed(double maxAbsoluteSpeed);
void SetAnimParamsByCoreConfig(const emCoreConfig & coreConfig);
void SetGoal(const char * identity, bool adherent,
const char * subject=NULL);
void SetGoal(const char * identity, double relX, double relY, double relA,
bool adherent, const char * subject=NULL);
void SetGoalFullsized(const char * identity, bool adherent,
bool utilizeView=false, const char * subject=NULL);
void ClearGoal();
bool HasGoal() const;
bool HasReachedGoal() const;
bool HasGivenUp() const;
virtual void Activate();
virtual void Deactivate();
virtual void Input(emInputEvent & event, const emInputState & state);
virtual void Paint(const emPainter & painter) const;
protected:
virtual bool CycleAnimation(double dt);
private:
enum StateEnum {
ST_NO_GOAL,
ST_CURVE,
ST_DIRECT,
ST_SEEK,
ST_GIVING_UP,
ST_GIVEN_UP,
ST_GOAL_REACHED
};
enum VisitTypeEnum {
VT_VISIT,
VT_VISIT_REL,
VT_VISIT_FULLSIZED
};
struct CurvePoint {
double X;
double Z;
};
void SetGoal(
VisitTypeEnum visitType, const char * identity, double relX, double relY,
double relA, bool adherent, bool utilizeView, const char * subject
);
void UpdateSpeed(
double pos, double dist, int panelsAfter, double distFinal, double dt
);
emPanel * GetNearestExistingPanel(
double * pRelX, double * pRelY, double * pRelA, bool * pAdherent,
int * pDepth, int * pPanelsAfter, double * pDistFinal
) const;
emPanel * GetNearestViewedPanel(emPanel * nearestExistingPanel) const;
void GetDistanceTo(
emPanel * panel, double relX, double relY, double relA,
double * pDirX, double * pDirY, double * pDistXY, double * pDistZ
) const;
void GetViewRect(
double * pX, double * pY, double * pW, double * pH
) const;
static double GetDirectDist(double x, double z);
static void GetDirectPoint(
double x, double z, double d,
double * pX, double * pZ
);
static void GetCurvePosDist(
double x, double z, double * pCurvePos, double * pCurveDist
);
static CurvePoint GetCurvePoint(double d);
bool Animated;
double Acceleration;
double MaxCuspSpeed;
double MaxAbsoluteSpeed;
StateEnum State;
VisitTypeEnum VisitType;
emString Identity;
double RelX,RelY,RelA;
bool Adherent;
bool UtilizeView;
emString Subject;
emArray<emString> Names;
int MaxDepthSeen;
double Speed;
int TimeSlicesWithoutHope;
emUInt64 GiveUpClock;
static const double CurveDeltaDist;
static const CurvePoint CurvePoints[];
static const int CurveMaxIndex;
};
inline bool emVisitingViewAnimator::IsAnimated() const
{
return Animated;
}
inline double emVisitingViewAnimator::GetAcceleration() const
{
return Acceleration;
}
inline double emVisitingViewAnimator::GetMaxCuspSpeed() const
{
return MaxCuspSpeed;
}
inline double emVisitingViewAnimator::GetMaxAbsoluteSpeed() const
{
return MaxAbsoluteSpeed;
}
inline bool emVisitingViewAnimator::HasGoal() const
{
return State!=ST_NO_GOAL;
}
inline bool emVisitingViewAnimator::HasReachedGoal() const
{
return State==ST_GOAL_REACHED;
}
inline bool emVisitingViewAnimator::HasGivenUp() const
{
return State==ST_GIVEN_UP;
}
#endif