Commit bbc298a2 authored by Ole Untzelmann's avatar Ole Untzelmann

[Animations] Polishing #7

[Animations] Changed data structure from vector->list
[Animations] Added function to stop a running Animation
parent 6a1d9283
////////////////////////////////////////////////////////////////////////////////
// Ole Untzelmann <ole.untzelmann@rwth-aachen.de> //
// Animation classes //
// Copyright (c) 2011, Computer Graphics Group RWTH Aachen University //
// All rights reserved. //
////////////////////////////////////////////////////////////////////////////////
#ifndef ANIMATION_HH
#define ANIMATION_HH
#ifndef ACGL_ANIMATIONS_ANIMATION_HH
#define ACGL_ANIMATIONS_ANIMATION_HH
#include <math.h>
#include <vector>
#include <queue>
#include "Interpolator.hh"
#include "EaseFunctions.hh"
#include <ACGL/Utils/Log.hh>
#include <tr1/memory>
#include <ACGL/Base/Macros.hh>
#include <ACGL/Types.hh>
#include <ACGL/Base/Macros.hh>
#include <ACGL/Base/Interfaces.hh>
#include <ACGL/Animations/EaseFunctions.hh>
#include <ACGL/Animations/Interpolator.hh>
using namespace ACGL::Base;
#include <list>
#include <queue>
namespace ACGL{
namespace Animations{
// Animation *************************************************************************************
class Animation
{
public:
Animation() : mInited(false) {};
virtual ~Animation() {};
/**
Excecute an animation
enum RepeatMode {Endless = -1, EndlessNoRepeat = -2};
@param msec The time in millicesonds to move on
Animation() :
mInited(false),
mStopped(false) {};
virtual ~Animation() {};
@return Time left after the update
*/
virtual void init() = 0;
virtual long update(uint_t msec) = 0;
virtual bool finished() = 0;
virtual void init() = 0;
/**
Returns if an animation has finished.
inline const bool& isInited() const;
inline const bool& isStopped() const;
@return True if animation is finished
*/
virtual bool finished() = 0;
inline void restart();
inline void stop();
protected:
bool mInited;
bool mStopped;
private:
};
ACGL_SHARED_TYPEDEF(Animation)
typedef std::vector<SharedAnimation> AnimationList;
typedef std::list<SharedAnimation> AnimationList;
typedef std::queue<SharedAnimation> AnimationQueue;
class AnimationManager
{
public:
static void push(const SharedAnimation& _animation);
static void update(uint_t _msec);
......@@ -84,14 +69,17 @@ private:
class AnimationEvent : public Animation
{
public:
AnimationEvent(const uint_t _id, const SharedINotifiable& _event);
AnimationEvent(const uint_t _id, const ACGL::Base::SharedINotifiable& _event);
virtual void init();
virtual long update(uint_t _msec);
virtual bool finished();
private:
SharedINotifiable mEvent;
ACGL::Base::SharedINotifiable mEvent;
uint_t mId;
bool mEventCalled;
};
ACGL_SHARED_TYPEDEF(AnimationEvent)
......@@ -119,7 +107,7 @@ ACGL_SHARED_TYPEDEF(AnimationWait)
class AnimationSequential : public Animation
{
public:
AnimationSequential(const uint_t _loops = 0);
AnimationSequential(const int_t _loops = 0);
virtual ~AnimationSequential();
virtual void init();
......@@ -129,13 +117,10 @@ public:
void push_animation(const SharedAnimation& _animation);
private:
uint_t mLoops;
int_t mLoops;
bool mFrontInited;
uint_t mCurrentPosition;
AnimationList::iterator mCurrentPosition;
AnimationList mAnimations;
//AnimationQueue mFinishedAnimations;
};
ACGL_SHARED_TYPEDEF(AnimationSequential)
......@@ -145,7 +130,7 @@ ACGL_SHARED_TYPEDEF(AnimationSequential)
class AnimationParallel : public Animation
{
public:
AnimationParallel(const uint_t _loops = 0);
AnimationParallel(const int_t _loops = 0);
virtual ~AnimationParallel();
virtual void init();
......@@ -155,12 +140,10 @@ public:
void push_animation(const SharedAnimation& animation);
private:
uint_t mLoops;
std::queue<uint_t> mAnimationsToInit;
int_t mLoops;
AnimationList mAnimations;
AnimationList mFinishedAnimations;
uint_t mRunningAnimations;
};
ACGL_SHARED_TYPEDEF(AnimationParallel)
......@@ -188,6 +171,8 @@ public:
{
mCurrentTime = 0;
mInterpolator.init(mpData);
mInited = true;
}
virtual long update(uint_t _msec)
......@@ -266,4 +251,4 @@ ACGL_SHARED_TYPEDEF(AnimationVec3Linear)
#endif // ANIMATION_HH
#endif // ACGL_ANIMATIONS_ANIMATION_HH
////////////////////////////////////////////////////////////////////////////////
// Ole Untzelmann <ole.untzelmann@rwth-aachen.de> //
// Interpolation Example //
// Copyright (c) 2011, Computer Graphics Group RWTH Aachen University //
// All rights reserved. //
////////////////////////////////////////////////////////////////////////////////
#ifndef EASEFUNCTIONS_HH
#define EASEFUNCTIONS_HH
#ifndef ACGL_ANIMATIONS_EASEFUNCTIONS_HH
#define ACGL_ANIMATIONS_EASEFUNCTIONS_HH
#include <math.h>
#include <ACGL/Math/Math.hh>
#include <ACGL/Base/Macros.hh>
#include <tr1/memory>
#include <ACGL/Base/Macros.hh>
namespace ACGL
{
......@@ -151,4 +151,4 @@ public:
}
}
#endif // EASEFUNCTIONS_HH
#endif // ACGL_ANIMATIONS_EASEFUNCTIONS_HH
////////////////////////////////////////////////////////////////////////////////
// Ole Untzelmann <ole.untzelmann@rwth-aachen.de> //
// Interpolation Example //
// Copyright (c) 2011, Computer Graphics Group RWTH Aachen University //
// All rights reserved. //
////////////////////////////////////////////////////////////////////////////////
#ifndef INTERPOLATOR_HH
#define INTERPOLATOR_HH
#ifndef ACGL_ANIMATIONS_INTERPOLATOR_HH
#define ACGL_ANIMATIONS_INTERPOLATOR_HH
#include "EaseFunctions.hh"
#include <ACGL/Utils/Log.hh>
#include <ACGL/Animations/EaseFunctions.hh>
#include <ACGL/Scene/NURBSCurve.hh>
#include <vector>
#include <ACGL/Types.hh>
#include <ACGL/Base/Macros.hh>
#include <vector>
#include <tr1/memory>
#include <ACGL/Base/Macros.hh>
namespace ACGL
{
......@@ -78,10 +76,8 @@ public:
}
}
inline const T interpolate(const float _progress)
inline const T& interpolate(const float _progress)
{
//std::cout << "[LinearInterpolator] progress: "<<_progress<<std::endl;
return mStartValue + _progress*mDiffValue;
}
......@@ -127,8 +123,9 @@ 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;
for(i = 0 ;i < mKeypoints.size();i++)
{
......@@ -187,7 +184,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
......
......@@ -7,6 +7,26 @@ namespace Animations
AnimationList AnimationManager::mAnimations;
const bool& Animation::isInited() const
{
return mInited;
}
const bool& Animation::isStopped() const
{
return mStopped;
}
void Animation::restart()
{
mInited = false;
}
void Animation::stop()
{
mStopped = true;
}
void AnimationManager::push(const SharedAnimation& _animation)
{
mAnimations.push_back(_animation);
......@@ -16,19 +36,26 @@ void AnimationManager::push(const SharedAnimation& _animation)
void AnimationManager::update(uint_t _msec)
{
uint_t id = 0;
AnimationList::iterator current = mAnimations.begin();
while(id < mAnimations.size())
while(current != mAnimations.end())
{
if((*current)->isStopped())
{
mAnimations[id]->update(_msec);
AnimationList::iterator toDelete = current;
current++;
mAnimations.erase(toDelete);
continue;
}
(*current)->update(_msec);
if(mAnimations[id]->finished())
if((*current)->finished())
{
mAnimations.erase(mAnimations.begin()+id);
/*mAnimations[id].reset();
mAnimations[id] = mAnimations[mAnimations.size()-1];
mAnimations.erase(mAnimations.end()-1);*/
} else id++;
AnimationList::iterator toDelete = current;
current++;
mAnimations.erase(toDelete);
}else current++;
}
}
......@@ -37,24 +64,34 @@ void AnimationManager::cleanUp()
mAnimations.clear();
}
AnimationEvent::AnimationEvent(const uint_t _id, const SharedINotifiable& _event) :
AnimationEvent::AnimationEvent(const uint_t _id, const ACGL::Base::SharedINotifiable& _event) :
Animation(),
mEvent(_event),
mId(_id)
mId(_id),
mEventCalled(false)
{
}
long AnimationEvent::update(uint_t _msec)
void AnimationEvent::init()
{
return _msec;
mEventCalled = false;
mInited = true;
}
bool AnimationEvent::finished()
long AnimationEvent::update(uint_t _msec)
{
if(mEvent)
mEvent->notify(mId);
return true;
mEventCalled = true;
return _msec;
}
bool AnimationEvent::finished()
{
return mEventCalled;
}
AnimationWait::AnimationWait(const uint_t _duration) :
......@@ -66,6 +103,8 @@ AnimationWait::AnimationWait(const uint_t _duration) :
void AnimationWait::init()
{
mTimeLeft = mDuration;
mInited = true;
}
long AnimationWait::update(uint_t _msec)
......@@ -89,9 +128,8 @@ bool AnimationWait::finished()
return mTimeLeft == 0;
}
AnimationSequential::AnimationSequential(const uint_t _loops) :
AnimationSequential::AnimationSequential(const int_t _loops) :
mLoops(_loops),
mFrontInited(false),
mCurrentPosition(0),
mAnimations()
{
......@@ -100,44 +138,52 @@ AnimationSequential::AnimationSequential(const uint_t _loops) :
AnimationSequential::~AnimationSequential()
{
mAnimations.clear();
//while(!mAnimations.empty()) mAnimations.pop();
//while(!mFinishedAnimations.empty()) mFinishedAnimations.pop();
}
void AnimationSequential::init()
{
mCurrentPosition = 0;
mCurrentPosition = mAnimations.begin();
mInited = true;
mFrontInited = false;
for(AnimationList::iterator current = mAnimations.begin(); current != mAnimations.end(); current++)
(*current)->restart();
}
long AnimationSequential::update(uint_t _msec)
{
while(!(mCurrentPosition >= mAnimations.size()) && _msec > 0)
while(mCurrentPosition != mAnimations.end() && _msec > 0)
{
if(!mFrontInited)
if((*mCurrentPosition)->isStopped())
{
mAnimations[mCurrentPosition]->init();
mFrontInited = true;
AnimationList::iterator toDelete = mCurrentPosition;
mCurrentPosition++;
mAnimations.erase(toDelete);
continue;
}
_msec = mAnimations[mCurrentPosition]->update(_msec);
if(!(*mCurrentPosition)->isInited())
{
(*mCurrentPosition)->init();
}
if(mAnimations[mCurrentPosition]->finished())
_msec = (*mCurrentPosition)->update(_msec);
if((*mCurrentPosition)->finished())
{
if(mLoops == Animation::EndlessNoRepeat)
{
//mFinishedAnimations.push(mAnimations.front());
//mAnimations.pop();
AnimationList::iterator toDelete = mCurrentPosition;
mCurrentPosition++;
mAnimations.erase(toDelete);
}else mCurrentPosition++;
if(mCurrentPosition >= mAnimations.size() && mLoops != 0)
if(mCurrentPosition == mAnimations.end() && mLoops != 0)
{
if(mLoops > 0)
mLoops--;
init();
}
mFrontInited = false;
}
}
......@@ -147,7 +193,7 @@ long AnimationSequential::update(uint_t _msec)
bool AnimationSequential::finished()
{
if(mLoops != 0) return false;
else return mCurrentPosition >= mAnimations.size();
else return mCurrentPosition == mAnimations.end();
}
void AnimationSequential::push_animation(const SharedAnimation& _animation)
......@@ -155,7 +201,7 @@ void AnimationSequential::push_animation(const SharedAnimation& _animation)
mAnimations.push_back(_animation);
}
AnimationParallel::AnimationParallel(const uint_t _loops) :
AnimationParallel::AnimationParallel(const int_t _loops) :
mLoops(_loops)
{
......@@ -164,56 +210,73 @@ AnimationParallel::AnimationParallel(const uint_t _loops) :
AnimationParallel::~AnimationParallel()
{
mAnimations.clear();
mFinishedAnimations.clear();
}
void AnimationParallel::init()
{
if(mFinishedAnimations.size() > 0)
{
mAnimations.insert(mAnimations.end(), mFinishedAnimations.begin(), mFinishedAnimations.end());
mFinishedAnimations.clear();
}
mRunningAnimations = mAnimations.size();
while(!mAnimationsToInit.empty()) mAnimationsToInit.pop();
for(unsigned int i = 0;i < mAnimations.size();i++)
for(AnimationList::iterator it = mAnimations.begin(); it != mAnimations.end(); it++)
{
mAnimationsToInit.push(i);
(*it)->restart();
}
mInited = true;
}
long AnimationParallel::update(uint_t _msec)
{
while(!mAnimationsToInit.empty())
uint_t timeLeftMin = _msec;
AnimationList::iterator current = mAnimations.begin();
while(current != mAnimations.end())
{
mAnimations[mAnimationsToInit.front()]->init();
mAnimationsToInit.pop();
if((*current)->isStopped())
{
if( !(*current)->finished() )
mRunningAnimations--;
AnimationList::iterator toDelete = current;
current++;
mAnimations.erase(toDelete);
continue;
}
uint_t time_left_min = _msec;
if(!(*current)->isInited())
{
(*current)->init();
}
unsigned int i = 0;
while(i < mAnimations.size())
if(!(*current)->finished())
{
uint_t time_left = mAnimations[i]->update(_msec);
uint_t timeLeft = (*current)->update(_msec);
if(time_left < time_left_min)
time_left_min = time_left;
if(timeLeft < timeLeftMin)
timeLeftMin = timeLeft;
if(mAnimations[i]->finished())
if((*current)->finished())
{
if(mLoops == Animation::EndlessNoRepeat)
{
mFinishedAnimations.push_back(mAnimations[i]);
mAnimations[i] = mAnimations[mAnimations.size()-1];
mAnimations.erase(mAnimations.end()-1);
}else i++;
AnimationList::iterator toDelete = current;
current++;
mAnimations.erase(toDelete);
current--;
}
return time_left_min;
mRunningAnimations--;
}
}
current++;
}
return timeLeftMin;
}
bool AnimationParallel::finished()
{
if(mAnimations.empty() && mLoops != 0)
if(mRunningAnimations == 0 && mLoops != 0)
{
if(mLoops > 0)
mLoops--;
......@@ -223,13 +286,12 @@ bool AnimationParallel::finished()
return false;
}
return mAnimations.empty();
return mRunningAnimations == 0;
}
void AnimationParallel::push_animation(const SharedAnimation& _animation)
{
mAnimationsToInit.push(mAnimations.size());
mRunningAnimations++;
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