Commit 9f51e032 authored by Ole Untzelmann's avatar Ole Untzelmann

[Animations] Added Speed Animations/Interpolator

parent 3b09b419
......@@ -222,8 +222,8 @@ public:
AnimationVariable(T& _data, uint_t _duration, const SharedEaseFunction& _ease_function, const Interpolator& _interpolator = Interpolator()) :
mpEaseFunction(_ease_function),
mInterpolator(_interpolator),
mDuration(_duration),
mCurrentTime(0),
mDuration(_duration),
mpData(_data) { }
virtual ~AnimationVariable()
......@@ -302,14 +302,96 @@ private:
typedef std::vector<blend_interpolator_t> BlendInterpolators;
BlendInterpolators mBlendInterpolators;
};
typedef AnimationVariable<float, LinearInterpolatorFloat > AnimationFloatLinear;
ACGL_SHARED_TYPEDEF(AnimationFloatLinear)
typedef AnimationVariable<glm::vec2, LinearInterpolatorVec2 > AnimationVec2Linear;
ACGL_SHARED_TYPEDEF(AnimationVec2Linear)
typedef AnimationVariable<glm::vec3, LinearInterpolatorVec3 > AnimationVec3Linear;
ACGL_SHARED_TYPEDEF(AnimationVec3Linear)
template <class T, class SpeedInterpolator>
class AnimationSpeed : public Animation{
public:
AnimationSpeed(T& _data, float _targetSpeed, float _acceleration = 1.0f, float _decceleration = 1.0f, float _startSpeed = 0.0f, const SpeedInterpolator& _interpolator = SpeedInterpolator()) :
mCurrentSpeed(_startSpeed),
mTargetSpeed(_targetSpeed),
mAcceleration(_acceleration),
mDecceleration(_decceleration),
mpData(_data),
mInterpolator(_interpolator){ }
virtual void init()
{
mInterpolator.init(mpData);
mInited = true;
}
virtual long update(uint_t _msec)
{
//Calculate the distance
float distance = mCurrentSpeed*((float)_msec)/1000.0f;
if(distance > 10.0f)
distance = 1000.0f;
//Move on that distance
float realDistance = mInterpolator.interpolate(mpData, distance);
long msecLeft = (uint_t)((distance-realDistance)*1000.0f/mCurrentSpeed);
//Adjust the speed
if(mCurrentSpeed > mTargetSpeed)
mCurrentSpeed -= fmin(mCurrentSpeed-mTargetSpeed, mDecceleration*((float)_msec)/1000.0f);
else
mCurrentSpeed += fmin(mTargetSpeed-mCurrentSpeed, mAcceleration*((float)_msec)/1000.0f);
return 0;//msecLeft;
}
virtual bool finished()
{
if(mInterpolator.finished())
mInited = false;
return mInterpolator.finished();
}
SpeedInterpolator& getSpeedInterpolator(){return mInterpolator;}
void setTargetSpeed(float _value)
{
mTargetSpeed = _value;
}
void setSpeed(float _value)
{
mCurrentSpeed = _value;
}
void setAcceleration(float _value)
{
mAcceleration = _value;
}
void setDecceleration(float _value)
{
mDecceleration = _value;
}
private:
float mCurrentSpeed;
float mTargetSpeed;
float mAcceleration;
float mDecceleration;
T& mpData;
SpeedInterpolator mInterpolator;
};
}
}
......
......@@ -76,7 +76,7 @@ public:
}
}
inline const T& interpolate(const float _progress)
inline const T interpolate(const float _progress)
{
return mStartValue + _progress*mDiffValue;
}
......@@ -104,10 +104,8 @@ private:
};
typedef LinearInterpolator<float> LinearInterpolatorFloat;
ACGL_SHARED_TYPEDEF(LinearInterpolatorFloat)
typedef LinearInterpolator<glm::vec2> LinearInterpolatorVec2;
typedef LinearInterpolator<glm::vec3> LinearInterpolatorVec3;
ACGL_SHARED_TYPEDEF(LinearInterpolatorVec3)
template <class T>
......@@ -123,7 +121,7 @@ public:
{
}
inline const T& interpolate(float _progress)
inline const T interpolate(float _progress)
{
//TODO: This es very UGLY, implement a better way to find the current keypoint.
unsigned int i = 0;
......@@ -165,10 +163,9 @@ private:
};
typedef LinearPathInterpolator<float> LinearPathInterpolatorFloat;
ACGL_SHARED_TYPEDEF(LinearPathInterpolatorFloat)
typedef LinearPathInterpolator<glm::vec2> LinearPathInterpolatorVec2;
typedef LinearPathInterpolator<glm::vec3> LinearPathInterpolatorVec3;
ACGL_SHARED_TYPEDEF(LinearPathInterpolatorVec3)
template<class T, ACGL::uint_t DATA_DIMENSION>
class NURBSPathInterpolator
......@@ -184,7 +181,7 @@ public:
// insert_control_point(data, 0.0f);
}
const T& interpolate(float progress)
const T interpolate(float progress)
{
curve.insertKnot(progress);
// TODO: Interpolation code is missing
......@@ -206,6 +203,90 @@ private:
ACGL::Scene::NURBSCurve<DATA_DIMENSION> curve;
};
template <class T, class OffsetType, class DataOperations>
class LinearPathSpeedInterpolator
{
public:
LinearPathSpeedInterpolator() :
mKeypoints(),
mOffset(0.0f, 0.0f),
mCurrentPosition(1)
{
}
inline void init(const T& init_value)
{
mCurrentPosition = 0;
}
inline float interpolate(T& _data, const float _distance)
{
if(mCurrentPosition == mKeypoints.size())
return 0.0f;
//Get the next target point
T source, target;
if(mCurrentPosition == 0)
{
source = _data;
target = DataOperations::applyStartOffset(mKeypoints[mCurrentPosition], mKeypoints[mCurrentPosition+1], mOffset);
}else{
source = DataOperations::applyStartOffset(mKeypoints[mCurrentPosition-1], mKeypoints[mCurrentPosition], mOffset);
if(mCurrentPosition == mKeypoints.size()-1)
{
target = DataOperations::applyOffset(mKeypoints[mCurrentPosition-1], mKeypoints[mCurrentPosition], mOffset);
}else{
target = DataOperations::applyOffset(mKeypoints[mCurrentPosition-1], mKeypoints[mCurrentPosition], mKeypoints[mCurrentPosition+1], mOffset);
}
}
bool next;
T newPosition = DataOperations::getNewPosition(_data, source, target, _distance, next);
float realDistance = DataOperations::distance(_data, newPosition);
_data = newPosition;
//If we reached the next control point and there are keypoints left
if(next)
{
mCurrentPosition++;
return realDistance+interpolate(_data, _distance-realDistance);
}else
{
return realDistance;
}
}
inline const bool finished()
{
return mCurrentPosition == mKeypoints.size();
}
inline OffsetType& getOffset()
{
return mOffset;
}
void appendControlPoint(const T& _data)
{
mKeypoints.push_back(_data);
}
protected:
private:
std::vector<T> mKeypoints;
OffsetType mOffset;
unsigned int mCurrentPosition;
};
}
}
......
#include <ACGL/Animations/Animation.hh>
namespace ACGL
{
namespace Animations
{
using namespace ACGL;
using namespace ACGL::Animations;
AnimationList AnimationManager::mAnimations;
......@@ -265,7 +263,4 @@ void AnimationParallel::push_animation(const SharedAnimation& _animation)
mAnimations.push_back(_animation);
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment