Cinder  0.8.6
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
Tween.h
Go to the documentation of this file.
1 /*
2  Copyright (c) 2011, The Cinder Project, All rights reserved.
3  This code is intended for use with the Cinder C++ library: http://libcinder.org
4 
5  Based on the sc-Choreograph CinderBlock by David Wicks: http://sansumbrella.com/
6 
7  Redistribution and use in source and binary forms, with or without modification, are permitted provided that
8  the following conditions are met:
9 
10  * Redistributions of source code must retain the above copyright notice, this list of conditions and
11  the following disclaimer.
12  * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
13  the following disclaimer in the documentation and/or other materials provided with the distribution.
14 
15  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
16  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
17  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
18  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
19  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
22  POSSIBILITY OF SUCH DAMAGE.
23 */
24 
25 #pragma once
26 
27 #include "cinder/Cinder.h"
28 #include "cinder/TimelineItem.h"
29 #include "cinder/CinderMath.h"
30 #include "cinder/Easing.h"
31 #include "cinder/Function.h"
32 #include "cinder/Quaternion.h"
33 
34 #include <list>
35 
36 namespace cinder {
37 
38 class Timeline;
39 typedef std::shared_ptr<Timeline> TimelineRef;
40 
41 template<typename T>
42 class Tween;
43 typedef std::function<float (float)> EaseFn;
44 
45 template<typename T>
46 class Anim;
47 
48 template<typename T>
49 T tweenLerp( const T &start, const T &end, float time )
50 {
51  return start * ( 1 - time ) + end * time;
52 }
53 
54 // Specialization of tweenLerp for Quaternions to use slerping
55 template<>
56 inline Quatf tweenLerp( const Quatf &start, const Quatf &end, float time )
57 {
58  Quatf val = start.slerp( time, end ).normalized();
59  if( std::isfinite( val.getAxis().x ) && std::isfinite( val.getAxis().y ) && std::isfinite( val.getAxis().z ) )
60  return val;
61  else
62  return Quatf::identity();
63 }
64 
65 template<>
66 inline Quatd tweenLerp( const Quatd &start, const Quatd &end, float time )
67 {
68  Quatd val = start.slerp( time, end ).normalized();
69  if( std::isfinite( val.getAxis().x ) && std::isfinite( val.getAxis().y ) && std::isfinite( val.getAxis().z ) )
70  return val;
71  else
72  return Quatd::identity();
73 }
74 
75 
76 class TweenBase : public TimelineItem {
77  public:
78  typedef std::function<void ()> StartFn;
79  typedef std::function<void ()> FinishFn;
80  typedef std::function<void ()> UpdateFn;
81 
82  TweenBase( void *target, bool copyStartValue, float startTime, float duration, EaseFn easeFunction = easeNone );
83  virtual ~TweenBase() {}
84 
86  void setEaseFn( EaseFn easeFunction ) { mEaseFunction = easeFunction; }
87  EaseFn getEaseFn() const { return mEaseFunction; }
88 
89  void setStartFn( StartFn startFunction ) { mStartFunction = startFunction; }
90  StartFn getStartFn() const { return mStartFunction; }
91 
92  void setReverseStartFn( StartFn reverseStartFunction ) { mReverseStartFunction = reverseStartFunction; }
94 
95  void setUpdateFn( UpdateFn updateFunction ) { mUpdateFunction = updateFunction; }
96  UpdateFn getUpdateFn() const { return mUpdateFunction; }
97 
98  void setFinishFn( FinishFn finishFn ) { mFinishFunction = finishFn; }
99  FinishFn getFinishFn() const { return mFinishFunction; }
100 
101  void setReverseFinishFn( FinishFn reverseFinishFn ) { mReverseFinishFunction = reverseFinishFn; }
103 
104  class Options {
105  protected:
107  : mTimeline( timeline )
108  {}
109 
110  void appendTo( TweenBase &tweenBase, void *target, float offset );
111  void timelineEnd( TweenBase &tweenBase, float offset );
112 
114  };
115 
116  protected:
117  virtual void reset( bool unsetStarted )
118  {
119  TimelineItem::reset( unsetStarted );
120  }
121 
122  virtual void complete( bool reverse )
123  {
124  if( reverse && mReverseFinishFunction )
126  else if( ( ! reverse ) && mFinishFunction )
127  mFinishFunction();
128  }
129 
130 
134 
136  float mDuration;
138 };
139 
140 template<typename T>
141 class TweenRef : public std::shared_ptr<Tween<T> > {
142  public:
143  TweenRef( const std::shared_ptr<Tween<T> > &sp )
144  : std::shared_ptr<Tween<T> >( sp )
145  {}
146  TweenRef( Tween<T> *tween )
147  : std::shared_ptr<Tween<T> >( tween )
148  {}
150  : std::shared_ptr<Tween<T> >()
151  {}
152 };
153 
154 template<typename T>
155 class Tween : public TweenBase {
156  public:
157  typedef std::function<T (const T&, const T&, float)> LerpFn;
158 
159  // build a tween with a target, target value, duration, and optional ease function
160  Tween( T *target, T endValue, float startTime, float duration,
161  EaseFn easeFunction = easeNone, LerpFn lerpFunction = &tweenLerp<T> )
162  : TweenBase( target, true, startTime, duration, easeFunction ), mStartValue( *target ), mEndValue( endValue ), mLerpFunction( lerpFunction )
163  {
164  }
165 
166  Tween( T *target, T startValue, T endValue, float startTime, float duration,
167  EaseFn easeFunction = easeNone, LerpFn lerpFunction = &tweenLerp<T> )
168  : TweenBase( target, false, startTime, duration, easeFunction ), mStartValue( startValue ), mEndValue( endValue ), mLerpFunction( lerpFunction )
169  {
170  }
171 
172  virtual ~Tween() {}
173 
175  T getStartValue() const { return mStartValue; }
176  T getEndValue() const { return mEndValue; }
177  T* getTarget() const { return reinterpret_cast<T*>( mTarget ); }
178 
181 
182  void setLerpFn( const LerpFn &lerpFn ) { mLerpFunction = lerpFn; }
183 
185  TweenRef<T> getThisRef(){ return TweenRef<T>( std::static_pointer_cast<Tween<T> >( shared_from_this() ) ); }
186 
187 
188  class Options : public TweenBase::Options {
189  public:
190  Options& startFn( const TweenBase::StartFn &startFn ) { mTweenRef->setStartFn( startFn ); return *this; }
191  Options& reverseStartFn( const TweenBase::StartFn &reverseStartFn ) { mTweenRef->setReverseStartFn( reverseStartFn ); return *this; }
192  Options& updateFn( const TweenBase::UpdateFn &updateFn ) { mTweenRef->setUpdateFn( updateFn ); return *this; }
193  Options& finishFn( const TweenBase::FinishFn &finishFn ) { mTweenRef->setFinishFn( finishFn ); return *this; }
194  Options& reverseFinishFn( const TweenBase::FinishFn &reverseFinishFn ) { mTweenRef->setReverseFinishFn( reverseFinishFn ); return *this; }
195  Options& easeFn( const EaseFn &easeFunc ) { mTweenRef->setEaseFn( easeFunc ); return *this; }
196  Options& delay( float delayAmt ) { mTweenRef->setStartTime( mTweenRef->getStartTime() + delayAmt ); return *this; }
197  Options& startTime( float time ) { mTweenRef->setStartTime( time ); return *this; }
198  Options& autoRemove( bool remove = true ) { mTweenRef->setAutoRemove( remove ); return *this; }
199  Options& loop( bool doLoop = true ) { mTweenRef->setLoop( doLoop ); return *this; }
200  Options& pingPong( bool doPingPong = true ) { mTweenRef->setPingPong( doPingPong ); return *this; }
201  Options& infinite( bool doInfinite = true ) { mTweenRef->setInfinite( doInfinite ); return *this; }
203  template<typename Y>
204  Options& appendTo( Anim<Y> *endTarget, float offset = 0 ) { TweenBase::Options::appendTo( *mTweenRef, endTarget->ptr(), offset ); return *this; }
205  Options& appendTo( void *endTarget, float offset = 0 ) { TweenBase::Options::appendTo( *mTweenRef, endTarget, offset ); return *this; }
206  Options& lerpFn( const typename Tween<T>::LerpFn &lerpFn ) { mTweenRef->setLerpFn( lerpFn ); return *this; }
207 
208  operator TweenRef<T>() { return mTweenRef; }
209 
210  protected:
212  : TweenBase::Options( timeline ), mTweenRef( tweenRef )
213  {}
214 
216 
217  friend class Timeline;
218  };
219 
220 
221  protected:
222  virtual void reverse()
223  {
224  std::swap( mStartValue, mEndValue );
225  }
226 
227  virtual TimelineItemRef clone() const
228  {
229  std::shared_ptr<Tween<T> > result( new Tween<T>( *this ) );
230  result->mCopyStartValue = false;
231  return result;
232  }
233 
235  {
236  std::shared_ptr<Tween<T> > result( new Tween<T>( *this ) );
237  std::swap( result->mStartValue, result->mEndValue );
238  result->mCopyStartValue = false;
239  return result;
240  }
241 
242  virtual void start( bool reverse )
243  {
244  if( mCopyStartValue )
245  mStartValue = *(reinterpret_cast<T*>( mTarget ) );
246  if( reverse && mReverseStartFunction )
248  else if( ( ! reverse ) && mStartFunction )
249  mStartFunction();
250  }
251 
252  virtual void update( float relativeTime )
253  {
254  *reinterpret_cast<T*>(mTarget) = mLerpFunction( mStartValue, mEndValue, mEaseFunction( relativeTime ) );
255  if( mUpdateFunction )
256  mUpdateFunction();
257  }
258 
259 
261 
263 };
264 
265 template<typename T>
266 class FnTween : public Tween<T> {
267  public:
268  FnTween( std::function<void (T)> fn, T startValue, T endValue, float startTime, float duration, EaseFn easeFunction = easeNone, typename Tween<T>::LerpFn lerpFunction = &tweenLerp<T> )
269  : Tween<T>( &mValue, startValue, endValue, startTime, duration, easeFunction, lerpFunction ), mFn( fn ), mValue( startValue )
270  {
271  }
272 
273  virtual void update( float relativeTime )
274  {
275  Tween<T>::update( relativeTime );
276  if( mFn )
277  mFn( mValue );
278  }
279 
280  std::function<void (T)> mFn;
282 };
283 
284 template<typename T>
285 class FnTweenRef : public TweenRef<T> {
286  public:
287  FnTweenRef( const std::shared_ptr<FnTween<T> > &sp )
288  : TweenRef<T>( sp )
289  {}
290  FnTweenRef( FnTween<T> *fnTween )
291  : TweenRef<T>( fnTween )
292  {}
294  : TweenRef<T>()
295  {}
296 };
297 
298 class AnimBase {
299  public:
301  void stop();
302 
304  bool isComplete() const;
305 
308 
309  protected:
310  AnimBase( void *voidPtr ) : mVoidPtr( voidPtr ) {}
311  AnimBase( const AnimBase &rhs, void *voidPtr );
312  ~AnimBase();
313 
314  void set( const AnimBase &rhs );
315  void setReplace( const AnimBase &rhs );
316 
317  void setParentTimeline( TimelineRef parentTimeline );
318 
319  void *mVoidPtr;
321 };
322 
323 template<typename T>
324 class Anim : public AnimBase {
325  public:
327  : AnimBase( &mValue )
328  {}
329  Anim( T value )
330  : AnimBase( &mValue), mValue( value )
331  {}
332  Anim( const Anim<T> &rhs ) // normal copy constructor
333  : AnimBase( rhs, &mValue ), mValue( rhs.mValue )
334  {}
335 
336  const T& operator()() const { return mValue; }
337  T& operator()() { return mValue; }
338 
339  operator const T&() const { return mValue; }
340  Anim<T>& operator=( const Anim &rhs ) { // copy assignment
341  if( this != &rhs ) {
342  set( rhs );
343  mValue = rhs.mValue;
344  }
345  return *this;
346  }
347 
348  Anim( Anim &&rhs ) // move constructor
349  : AnimBase( &mValue )
350  {
351  setReplace( rhs );
352  rhs.mParentTimeline.reset(); // blow away rhs's tweens due to move semantics
353  mValue = rhs.mValue;
354  }
355  Anim<T>& operator=( Anim &&rhs ) { // move assignment
356  if( this != &rhs ) {
357  setReplace( rhs );
358  rhs.mParentTimeline.reset(); // blow away rhs's tweens due to move semantics
359  mValue = rhs.mValue;
360  }
361  return *this;
362  }
363 
364  Anim<T>& operator=( T value ) { mValue = value; return *this; }
365 
366  const T& value() const { return mValue; }
367  T& value() { return mValue; }
368 
369  const T* ptr() const { return &mValue; }
370  T* ptr() { return &mValue; }
371 
372  protected:
373 
374  friend class Timeline;
375 
377 };
378 
379 //typedef boost::instrusive_ptr<TweenBase> TweenBaseRef;
380 
381 /*class TweenScope {
382  public:
383  TweenScope() {}
384  TweenScope( const TweenScope &rhs ) {} // do nothing for copy; these are our tweens alone
385  TweenScope& operator=( const TweenScope &rhs ) { return *this; } // do nothing for copy; these are our tweens alone
386  ~TweenScope();
387 
388  TweenScope& operator+=( TimelineItemRef item );
389  void add( TimelineItemRef item );
390 
391  private:
392  std::list<std::weak_ptr<TimelineItem> > mItems;
393 };*/
394 
395 } //namespace cinder
std::function< T(const T &, const T &, float)> LerpFn
Definition: Tween.h:157
bool mCopyStartValue
Definition: Tween.h:137
Quaternion< T > slerp(T t, const Quaternion< T > &end) const
Definition: Quaternion.h:465
StartFn mStartFunction
Definition: Tween.h:131
FnTweenRef(FnTween< T > *fnTween)
Definition: Tween.h:290
Definition: Tween.h:42
void setLerpFn(const LerpFn &lerpFn)
Definition: Tween.h:182
Options & finishFn(const TweenBase::FinishFn &finishFn)
Definition: Tween.h:193
virtual void update(float relativeTime)
Definition: Tween.h:273
Options & lerpFn(const typename Tween< T >::LerpFn &lerpFn)
Definition: Tween.h:206
EaseFn mEaseFunction
Definition: Tween.h:135
void setFinishFn(FinishFn finishFn)
Definition: Tween.h:98
GLuint start
Definition: GLee.h:963
Definition: Tween.h:188
Options(TweenRef< T > tweenRef, TimelineRef timeline)
Definition: Tween.h:211
float mDuration
Definition: Tween.h:136
Definition: Tween.h:76
virtual TimelineItemRef clone() const
Creates a clone of the item.
Definition: Tween.h:227
TimelineRef mTimeline
Definition: Tween.h:113
Options & appendTo(void *endTarget, float offset=0)
Definition: Tween.h:205
T mEndValue
Definition: Tween.h:260
T getStartValue() const
Returns the starting value for the tween. If the tween will copy its target's value upon starting (is...
Definition: Tween.h:175
void setReverseFinishFn(FinishFn reverseFinishFn)
Definition: Tween.h:101
const T & value() const
Definition: Tween.h:366
EaseFn getEaseFn() const
Definition: Tween.h:87
FinishFn mReverseFinishFunction
Definition: Tween.h:133
Definition: Tween.h:141
std::function< void()> StartFn
Definition: Tween.h:78
T z
Definition: Vector.h:321
Vec3< T > getAxis() const
Definition: Quaternion.h:68
virtual void start(bool reverse)
Definition: Tween.h:242
T x
Definition: Vector.h:321
static Quaternion< float > identity()
Definition: Quaternion.h:733
virtual void reset(bool unsetStarted=false)
Marks the item as not completed, and if unsetStarted, marks the item as not started.
Definition: TimelineItem.h:77
FnTweenRef(const std::shared_ptr< FnTween< T > > &sp)
Definition: Tween.h:287
T * ptr()
Definition: Tween.h:370
std::shared_ptr< class Timeline > TimelineRef
Definition: Timeline.h:40
Options & reverseStartFn(const TweenBase::StartFn &reverseStartFn)
Definition: Tween.h:191
UpdateFn mUpdateFunction
Definition: Tween.h:132
Anim(Anim &&rhs)
Definition: Tween.h:348
Options & pingPong(bool doPingPong=true)
Definition: Tween.h:200
T & value()
Definition: Tween.h:367
Anim< T > & operator=(T value)
Definition: Tween.h:364
GLenum target
Definition: GLee.h:13607
T y
Definition: Vector.h:321
void setStartFn(StartFn startFunction)
Definition: Tween.h:89
TweenRef(Tween< T > *tween)
Definition: Tween.h:146
Options & autoRemove(bool remove=true)
Definition: Tween.h:198
TweenRef(const std::shared_ptr< Tween< T > > &sp)
Definition: Tween.h:143
Tween(T *target, T endValue, float startTime, float duration, EaseFn easeFunction=easeNone, LerpFn lerpFunction=&tweenLerp< T >)
Definition: Tween.h:160
Options & loop(bool doLoop=true)
Definition: Tween.h:199
Definition: Tween.h:104
std::function< void(T)> mFn
Definition: Tween.h:280
FnTween(std::function< void(T)> fn, T startValue, T endValue, float startTime, float duration, EaseFn easeFunction=easeNone, typename Tween< T >::LerpFn lerpFunction=&tweenLerp< T >)
Definition: Tween.h:268
virtual void reset(bool unsetStarted)
Marks the item as not completed, and if unsetStarted, marks the item as not started.
Definition: Tween.h:117
void setEaseFn(EaseFn easeFunction)
change how the tween moves through time
Definition: Tween.h:86
~AnimBase()
Definition: Tween.cpp:66
void appendTo(TweenBase &tweenBase, void *target, float offset)
Definition: Tween.cpp:118
Definition: Tween.h:266
void stop()
removes self from Timeline
Definition: Tween.cpp:102
virtual void reverse()=0
void setReplace(const AnimBase &rhs)
Definition: Tween.cpp:81
GLuint GLfloat * val
Definition: GLee.h:14636
FinishFn mFinishFunction
Definition: Tween.h:133
std::function< void()> FinishFn
Definition: Tween.h:79
Anim(const Anim< T > &rhs)
Definition: Tween.h:332
T mValue
Definition: Tween.h:376
void setReverseStartFn(StartFn reverseStartFunction)
Definition: Tween.h:92
bool isCopyStartValue()
Returns whether the tween will copy its target's value upon starting.
Definition: Tween.h:180
void timelineEnd(TweenBase &tweenBase, float offset)
Definition: Tween.cpp:123
Base interface for anything that can go on a Timeline.
Definition: TimelineItem.h:34
Anim< T > & operator=(Anim &&rhs)
Definition: Tween.h:355
TweenBase(void *target, bool copyStartValue, float startTime, float duration, EaseFn easeFunction=easeNone)
Definition: Tween.cpp:32
Options & startTime(float time)
Definition: Tween.h:197
T tweenLerp(const T &start, const T &end, float time)
Definition: Tween.h:49
Options & startFn(const TweenBase::StartFn &startFn)
Definition: Tween.h:190
GLintptr offset
Definition: GLee.h:2095
Options & easeFn(const EaseFn &easeFunc)
Definition: Tween.h:195
Options & delay(float delayAmt)
Definition: Tween.h:196
T & operator()()
Definition: Tween.h:337
Quaternion< T > normalized() const
Definition: Quaternion.h:137
Options & reverseFinishFn(const TweenBase::FinishFn &reverseFinishFn)
Definition: Tween.h:194
const T & operator()() const
Definition: Tween.h:336
StartFn mReverseStartFunction
Definition: Tween.h:131
Anim< T > & operator=(const Anim &rhs)
Definition: Tween.h:340
float easeNone(float t)
Easing equation for a simple linear tweening with no easing.
Definition: Easing.h:49
Anim()
Definition: Tween.h:326
bool isComplete() const
returns false if any tweens are active on 'this', otherwise true
Definition: Tween.cpp:89
Options & updateFn(const TweenBase::UpdateFn &updateFn)
Definition: Tween.h:192
Options & appendTo(Anim< Y > *endTarget, float offset=0)
Definition: Tween.h:204
GLsizei const GLfloat * value
Definition: GLee.h:2487
Options & infinite(bool doInfinite=true)
Definition: Tween.h:201
void setParentTimeline(TimelineRef parentTimeline)
Definition: Tween.cpp:109
GLuint GLuint end
Definition: GLee.h:963
AnimBase(void *voidPtr)
Definition: Tween.h:310
TimelineRef getParent() const
returns the parent timeline for the Anim<> or NULL if there is none
Definition: Tween.h:307
void * mTarget
Definition: TimelineItem.h:115
TweenRef< T > getThisRef()
Returns a TweenRef to this.
Definition: Tween.h:185
T getEndValue() const
Definition: Tween.h:176
T mValue
Definition: Tween.h:281
void set(const AnimBase &rhs)
Definition: Tween.cpp:72
Timeline & timeline()
Returns a reference to the active App's Timeline.
Definition: App.h:685
const T * ptr() const
Definition: Tween.h:369
virtual ~TweenBase()
Definition: Tween.h:83
Definition: Tween.h:46
Options(TimelineRef timeline)
Definition: Tween.h:106
std::function< void()> UpdateFn
Definition: Tween.h:80
std::shared_ptr< class TimelineItem > TimelineItemRef
Definition: TimelineItem.h:31
virtual TimelineItemRef cloneReverse() const
Creates a cloned item which runs in reverse relative to a timeline of duration timelineDuration.
Definition: Tween.h:234
TweenRef()
Definition: Tween.h:149
virtual void complete(bool reverse)
Definition: Tween.h:122
TweenRef< T > mTweenRef
Definition: Tween.h:215
StartFn getReverseStartFn() const
Definition: Tween.h:93
FinishFn getReverseFinishFn() const
Definition: Tween.h:102
std::function< float(float)> EaseFn
Definition: Tween.h:42
virtual void update(float relativeTime)
Definition: Tween.h:252
Definition: Tween.h:285
void setUpdateFn(UpdateFn updateFunction)
Definition: Tween.h:95
Tween(T *target, T startValue, T endValue, float startTime, float duration, EaseFn easeFunction=easeNone, LerpFn lerpFunction=&tweenLerp< T >)
Definition: Tween.h:166
void * mVoidPtr
Definition: Tween.h:319
Definition: Timeline.h:42
FnTweenRef()
Definition: Tween.h:293
Options & timelineEnd(float offset=0)
Definition: Tween.h:202
virtual ~Tween()
Definition: Tween.h:172
T mStartValue
Definition: Tween.h:260
TimelineRef mParentTimeline
Definition: Tween.h:320
UpdateFn getUpdateFn() const
Definition: Tween.h:96
virtual void reverse()
Definition: Tween.h:222
FinishFn getFinishFn() const
Definition: Tween.h:99
StartFn getStartFn() const
Definition: Tween.h:90
Anim(T value)
Definition: Tween.h:329
T * getTarget() const
Definition: Tween.h:177
LerpFn mLerpFunction
Definition: Tween.h:262
Definition: Tween.h:298