00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #pragma once
00026
00027 #include "cinder/Cinder.h"
00028 #include "cinder/TimelineItem.h"
00029 #include "cinder/CinderMath.h"
00030 #include "cinder/Easing.h"
00031 #include "cinder/Function.h"
00032 #include "cinder/Quaternion.h"
00033
00034 #include <list>
00035
00036 namespace cinder {
00037
00038 class Timeline;
00039 typedef std::shared_ptr<Timeline> TimelineRef;
00040
00041 template<typename T>
00042 class Tween;
00043 typedef std::function<float (float)> EaseFn;
00044
00045 template<typename T>
00046 class Anim;
00047
00048 template<typename T>
00049 T tweenLerp( const T &start, const T &end, float time )
00050 {
00051 return start * ( 1 - time ) + end * time;
00052 }
00053
00054
00055 template<>
00056 inline Quatf tweenLerp( const Quatf &start, const Quatf &end, float time )
00057 {
00058 Quatf val = start.slerp( time, end ).normalized();
00059 if( std::isfinite( val.getAxis().x ) && std::isfinite( val.getAxis().y ) && std::isfinite( val.getAxis().z ) )
00060 return val;
00061 else
00062 return Quatf::identity();
00063 }
00064
00065 template<>
00066 inline Quatd tweenLerp( const Quatd &start, const Quatd &end, float time )
00067 {
00068 Quatd val = start.slerp( time, end ).normalized();
00069 if( std::isfinite( val.getAxis().x ) && std::isfinite( val.getAxis().y ) && std::isfinite( val.getAxis().z ) )
00070 return val;
00071 else
00072 return Quatd::identity();
00073 }
00074
00075
00076 class TweenBase : public TimelineItem {
00077 public:
00078 typedef std::function<void ()> StartFn;
00079 typedef std::function<void ()> FinishFn;
00080 typedef std::function<void ()> UpdateFn;
00081
00082 TweenBase( void *target, bool copyStartValue, float startTime, float duration, EaseFn easeFunction = easeNone );
00083 virtual ~TweenBase() {}
00084
00086 void setEaseFn( EaseFn easeFunction ) { mEaseFunction = easeFunction; }
00087 EaseFn getEaseFn() const { return mEaseFunction; }
00088
00089 void setStartFn( StartFn startFunction ) { mStartFunction = startFunction; }
00090 StartFn getStartFn() const { return mStartFunction; }
00091
00092 void setReverseStartFn( StartFn reverseStartFunction ) { mReverseStartFunction = reverseStartFunction; }
00093 StartFn getReverseStartFn() const { return mReverseStartFunction; }
00094
00095 void setUpdateFn( UpdateFn updateFunction ) { mUpdateFunction = updateFunction; }
00096 UpdateFn getUpdateFn() const { return mUpdateFunction; }
00097
00098 void setFinishFn( FinishFn finishFn ) { mFinishFunction = finishFn; }
00099 FinishFn getFinishFn() const { return mFinishFunction; }
00100
00101 void setReverseFinishFn( FinishFn reverseFinishFn ) { mReverseFinishFunction = reverseFinishFn; }
00102 FinishFn getReverseFinishFn() const { return mReverseFinishFunction; }
00103
00104 class Options {
00105 protected:
00106 Options( TimelineRef timeline )
00107 : mTimeline( timeline )
00108 {}
00109
00110 void appendTo( TweenBase &tweenBase, void *target, float offset );
00111 void timelineEnd( TweenBase &tweenBase, float offset );
00112
00113 TimelineRef mTimeline;
00114 };
00115
00116 protected:
00117 virtual void reset( bool unsetStarted )
00118 {
00119 TimelineItem::reset( unsetStarted );
00120 }
00121
00122 virtual void complete( bool reverse )
00123 {
00124 if( reverse && mReverseFinishFunction )
00125 mReverseFinishFunction();
00126 else if( ( ! reverse ) && mFinishFunction )
00127 mFinishFunction();
00128 }
00129
00130
00131 StartFn mStartFunction, mReverseStartFunction;
00132 UpdateFn mUpdateFunction;
00133 FinishFn mFinishFunction, mReverseFinishFunction;
00134
00135 EaseFn mEaseFunction;
00136 float mDuration;
00137 bool mCopyStartValue;
00138 };
00139
00140 template<typename T>
00141 class TweenRef : public std::shared_ptr<Tween<T> > {
00142 public:
00143 TweenRef( const std::shared_ptr<Tween<T> > &sp )
00144 : std::shared_ptr<Tween<T> >( sp )
00145 {}
00146 TweenRef( Tween<T> *tween )
00147 : std::shared_ptr<Tween<T> >( tween )
00148 {}
00149 TweenRef()
00150 : std::shared_ptr<Tween<T> >()
00151 {}
00152 };
00153
00154 template<typename T>
00155 class Tween : public TweenBase {
00156 public:
00157 typedef std::function<T (const T&, const T&, float)> LerpFn;
00158
00159
00160 Tween( T *target, T endValue, float startTime, float duration,
00161 EaseFn easeFunction = easeNone, LerpFn lerpFunction = &tweenLerp<T> )
00162 : TweenBase( target, true, startTime, duration, easeFunction ), mStartValue( *target ), mEndValue( endValue ), mLerpFunction( lerpFunction )
00163 {
00164 }
00165
00166 Tween( T *target, T startValue, T endValue, float startTime, float duration,
00167 EaseFn easeFunction = easeNone, LerpFn lerpFunction = &tweenLerp<T> )
00168 : TweenBase( target, false, startTime, duration, easeFunction ), mStartValue( startValue ), mEndValue( endValue ), mLerpFunction( lerpFunction )
00169 {
00170 }
00171
00172 virtual ~Tween() {}
00173
00175 T getStartValue() const { return mStartValue; }
00176 T getEndValue() const { return mEndValue; }
00177 T* getTarget() const { return reinterpret_cast<T*>( mTarget ); }
00178
00180 bool isCopyStartValue() { return mCopyStartValue; }
00181
00182 void setLerpFn( const LerpFn &lerpFn ) { mLerpFunction = lerpFn; }
00183
00185 TweenRef<T> getThisRef(){ return TweenRef<T>( std::static_pointer_cast<Tween<T> >( shared_from_this() ) ); }
00186
00187
00188 class Options : public TweenBase::Options {
00189 public:
00190 Options& startFn( const TweenBase::StartFn &startFn ) { mTweenRef->setStartFn( startFn ); return *this; }
00191 Options& reverseStartFn( const TweenBase::StartFn &reverseStartFn ) { mTweenRef->setReverseStartFn( reverseStartFn ); return *this; }
00192 Options& updateFn( const TweenBase::UpdateFn &updateFn ) { mTweenRef->setUpdateFn( updateFn ); return *this; }
00193 Options& finishFn( const TweenBase::FinishFn &finishFn ) { mTweenRef->setFinishFn( finishFn ); return *this; }
00194 Options& reverseFinishFn( const TweenBase::FinishFn &reverseFinishFn ) { mTweenRef->setReverseFinishFn( reverseFinishFn ); return *this; }
00195 Options& easeFn( const EaseFn &easeFunc ) { mTweenRef->setEaseFn( easeFunc ); return *this; }
00196 Options& delay( float delayAmt ) { mTweenRef->setStartTime( mTweenRef->getStartTime() + delayAmt ); return *this; }
00197 Options& startTime( float time ) { mTweenRef->setStartTime( time ); return *this; }
00198 Options& autoRemove( bool remove = true ) { mTweenRef->setAutoRemove( remove ); return *this; }
00199 Options& loop( bool doLoop = true ) { mTweenRef->setLoop( doLoop ); return *this; }
00200 Options& pingPong( bool doPingPong = true ) { mTweenRef->setPingPong( doPingPong ); return *this; }
00201 Options& infinite( bool doInfinite = true ) { mTweenRef->setInfinite( doInfinite ); return *this; }
00202 Options& timelineEnd( float offset = 0 ) { TweenBase::Options::timelineEnd( *mTweenRef, offset ); return *this; }
00203 template<typename Y>
00204 Options& appendTo( Anim<Y> *endTarget, float offset = 0 ) { TweenBase::Options::appendTo( *mTweenRef, endTarget->ptr(), offset ); return *this; }
00205 Options& appendTo( void *endTarget, float offset = 0 ) { TweenBase::Options::appendTo( *mTweenRef, endTarget, offset ); return *this; }
00206 Options& lerpFn( const typename Tween<T>::LerpFn &lerpFn ) { mTweenRef->setLerpFn( lerpFn ); return *this; }
00207
00208 operator TweenRef<T>() { return mTweenRef; }
00209
00210 protected:
00211 Options( TweenRef<T> tweenRef, TimelineRef timeline )
00212 : TweenBase::Options( timeline ), mTweenRef( tweenRef )
00213 {}
00214
00215 TweenRef<T> mTweenRef;
00216
00217 friend class Timeline;
00218 };
00219
00220
00221 protected:
00222 virtual void reverse()
00223 {
00224 std::swap( mStartValue, mEndValue );
00225 }
00226
00227 virtual TimelineItemRef clone() const
00228 {
00229 std::shared_ptr<Tween<T> > result( new Tween<T>( *this ) );
00230 result->mCopyStartValue = false;
00231 return result;
00232 }
00233
00234 virtual TimelineItemRef cloneReverse() const
00235 {
00236 std::shared_ptr<Tween<T> > result( new Tween<T>( *this ) );
00237 std::swap( result->mStartValue, result->mEndValue );
00238 result->mCopyStartValue = false;
00239 return result;
00240 }
00241
00242 virtual void start( bool reverse )
00243 {
00244 if( mCopyStartValue )
00245 mStartValue = *(reinterpret_cast<T*>( mTarget ) );
00246 if( reverse && mReverseStartFunction )
00247 mReverseStartFunction();
00248 else if( ( ! reverse ) && mStartFunction )
00249 mStartFunction();
00250 }
00251
00252 virtual void update( float relativeTime )
00253 {
00254 *reinterpret_cast<T*>(mTarget) = mLerpFunction( mStartValue, mEndValue, mEaseFunction( relativeTime ) );
00255 if( mUpdateFunction )
00256 mUpdateFunction();
00257 }
00258
00259
00260 T mStartValue, mEndValue;
00261
00262 LerpFn mLerpFunction;
00263 };
00264
00265 template<typename T>
00266 class FnTween : public Tween<T> {
00267 public:
00268 FnTween( std::function<void (T)> fn, T startValue, T endValue, float startTime, float duration, EaseFn easeFunction = easeNone, typename Tween<T>::LerpFn lerpFunction = &tweenLerp<T> )
00269 : Tween<T>( &mValue, startValue, endValue, startTime, duration, easeFunction, lerpFunction ), mFn( fn ), mValue( startValue )
00270 {
00271 }
00272
00273 virtual void update( float relativeTime )
00274 {
00275 Tween<T>::update( relativeTime );
00276 if( mFn )
00277 mFn( mValue );
00278 }
00279
00280 std::function<void (T)> mFn;
00281 T mValue;
00282 };
00283
00284 template<typename T>
00285 class FnTweenRef : public TweenRef<T> {
00286 public:
00287 FnTweenRef( const std::shared_ptr<FnTween<T> > &sp )
00288 : TweenRef<T>( sp )
00289 {}
00290 FnTweenRef( FnTween<T> *fnTween )
00291 : TweenRef<T>( fnTween )
00292 {}
00293 FnTweenRef()
00294 : TweenRef<T>()
00295 {}
00296 };
00297
00298 class AnimBase {
00299 public:
00301 void stop();
00302
00304 bool isComplete() const;
00305
00307 TimelineRef getParent() const { return mParentTimeline; }
00308
00309 protected:
00310 AnimBase( void *voidPtr ) : mVoidPtr( voidPtr ) {}
00311 AnimBase( const AnimBase &rhs, void *voidPtr );
00312 ~AnimBase();
00313
00314 void set( const AnimBase &rhs );
00315 void setReplace( const AnimBase &rhs );
00316
00317 void setParentTimeline( TimelineRef parentTimeline );
00318
00319 void *mVoidPtr;
00320 TimelineRef mParentTimeline;
00321 };
00322
00323 template<typename T>
00324 class Anim : public AnimBase {
00325 public:
00326 Anim()
00327 : AnimBase( &mValue )
00328 {}
00329 Anim( T value )
00330 : AnimBase( &mValue), mValue( value )
00331 {}
00332 Anim( const Anim<T> &rhs )
00333 : AnimBase( rhs, &mValue ), mValue( rhs.mValue )
00334 {}
00335
00336 const T& operator()() const { return mValue; }
00337 T& operator()() { return mValue; }
00338
00339 operator const T&() const { return mValue; }
00340 Anim<T>& operator=( const Anim &rhs ) {
00341 if( this != &rhs ) {
00342 set( rhs );
00343 mValue = rhs.mValue;
00344 }
00345 return *this;
00346 }
00347
00348 Anim( Anim &&rhs )
00349 : AnimBase( &mValue )
00350 {
00351 setReplace( rhs );
00352 rhs.mParentTimeline.reset();
00353 mValue = rhs.mValue;
00354 }
00355 Anim<T>& operator=( Anim &&rhs ) {
00356 if( this != &rhs ) {
00357 setReplace( rhs );
00358 rhs.mParentTimeline.reset();
00359 mValue = rhs.mValue;
00360 }
00361 return *this;
00362 }
00363
00364 Anim<T>& operator=( T value ) { mValue = value; return *this; }
00365
00366 const T& value() const { return mValue; }
00367 T& value() { return mValue; }
00368
00369 const T* ptr() const { return &mValue; }
00370 T* ptr() { return &mValue; }
00371
00372 protected:
00373
00374 friend class Timeline;
00375
00376 T mValue;
00377 };
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395 }