mEase.h

Engine/source/math/mEase.h

More...

Classes:

class
class

Public Functions

Detailed Description

Public Functions

mEaseInBack(F32 t, F32 b, F32 c, F32 d, F32 s)

mEaseInBounce(F32 t, F32 b, F32 c, F32 d)

mEaseInCirc(F32 t, F32 b, F32 c, F32 d)

mEaseInCubic(F32 t, F32 b, F32 c, F32 d)

mEaseInElastic(F32 t, F32 b, F32 c, F32 d, F32 a, F32 p)

mEaseInExpo(F32 t, F32 b, F32 c, F32 d)

mEaseInOutBack(F32 t, F32 b, F32 c, F32 d, F32 s)

mEaseInOutBounce(F32 t, F32 b, F32 c, F32 d)

mEaseInOutCirc(F32 t, F32 b, F32 c, F32 d)

mEaseInOutCubic(F32 t, F32 b, F32 c, F32 d)

mEaseInOutElastic(F32 t, F32 b, F32 c, F32 d, F32 a, F32 p)

mEaseInOutExpo(F32 t, F32 b, F32 c, F32 d)

mEaseInOutQuad(F32 t, F32 b, F32 c, F32 d)

mEaseInOutQuart(F32 t, F32 b, F32 c, F32 d)

mEaseInOutQuint(F32 t, F32 b, F32 c, F32 d)

mEaseInOutSine(F32 t, F32 b, F32 c, F32 d)

mEaseInQuad(F32 t, F32 b, F32 c, F32 d)

mEaseInQuart(F32 t, F32 b, F32 c, F32 d)

mEaseInQuint(F32 t, F32 b, F32 c, F32 d)

mEaseInSine(F32 t, F32 b, F32 c, F32 d)

mEaseOutBack(F32 t, F32 b, F32 c, F32 d, F32 s)

mEaseOutBounce(F32 t, F32 b, F32 c, F32 d)

mEaseOutCirc(F32 t, F32 b, F32 c, F32 d)

mEaseOutCubic(F32 t, F32 b, F32 c, F32 d)

mEaseOutElastic(F32 t, F32 b, F32 c, F32 d, F32 a, F32 p)

mEaseOutExpo(F32 t, F32 b, F32 c, F32 d)

mEaseOutQuad(F32 t, F32 b, F32 c, F32 d)

mEaseOutQuart(F32 t, F32 b, F32 c, F32 d)

mEaseOutQuint(F32 t, F32 b, F32 c, F32 d)

mEaseOutSine(F32 t, F32 b, F32 c, F32 d)

mLinearTween(F32 t, F32 b, F32 c, F32 d)

  1
  2/*
  3  ROBERT PENNER'S MOST EXCELLENT EASING METHODS - ported to Torque C++ by Paul Dana
  4
  5  Easing Equations v1.5
  6  May 1, 2003
  7  (c) 2003 Robert Penner, all rights reserved. 
  8  This work is subject to the terms in http://www.robertpenner.com/easing_terms_of_use.html.  
  9  
 10  These tweening functions provide different flavors of 
 11  math-based motion under a consistent API. 
 12  
 13  Types of easing:
 14  
 15     Linear
 16     Quadratic
 17     Cubic
 18     Quartic
 19     Quintic
 20     Sinusoidal
 21     Exponential
 22     Circular
 23     Elastic
 24     Back
 25     Bounce
 26
 27  Changes:
 28  1.5 - added bounce easing
 29  1.4 - added elastic and back easing
 30  1.3 - tweaked the exponential easing functions to make endpoints exact
 31  1.2 - inline optimizations (changing t and multiplying in one step)--thanks to Tatsuo Kato for the idea
 32  
 33  Discussed in Chapter 7 of 
 34  Robert Penner's Programming Macromedia Flash MX
 35  (including graphs of the easing equations)
 36  
 37  http://www.robertpenner.com/profmx
 38  http://www.amazon.com/exec/obidos/ASIN/0072223561/robertpennerc-20
 39*/
 40
 41#ifndef _MEASE_H_
 42#define _MEASE_H_
 43
 44// the ease methods below all are static and take atomic types as params
 45// so they are the most generally useful. for convenience, define here
 46// a type that can contain all the params needed for below to make 
 47// data structures that use these methods cleaner...
 48//------------------------------------------------------------------------------
 49class Ease
 50{
 51   //-------------------------------------- Public data
 52  public:
 53   enum enumDirection
 54   {
 55      InOut=0,
 56      In,
 57      Out
 58   };
 59
 60   enum enumType
 61   {
 62     Linear=0,
 63     Quadratic,
 64     Cubic,
 65     Quartic,
 66     Quintic,
 67     Sinusoidal,
 68     Exponential,
 69     Circular,
 70     Elastic,
 71     Back,
 72     Bounce,
 73   };
 74};
 75
 76class EaseF : public Ease
 77{
 78   //-------------------------------------- Public data
 79  public:
 80   S32 mDir;       // inout, in, out
 81   S32 mType;      // linear, etc...
 82   F32 mParam[2];  // optional params
 83
 84   //-------------------------------------- Public interface
 85  public:
 86   EaseF();
 87   EaseF(const EaseF &ease);
 88   EaseF(const S32 dir, const S32 type);
 89   EaseF(const S32 dir, const S32 type, F32 param[2]);
 90
 91   //-------------------------------------- Non-math mutators and misc functions
 92   void set(const S32 dir, const S32 type);
 93   void set(const S32 dir, const S32 type, F32 param[2]);
 94   void set(const S32 dir, const S32 type, F32 param0, F32 param1);
 95   void set(const char *s);
 96
 97   F32 getValue(F32 t, F32 b, F32 c, F32 d) const;
 98   F32 getUnitValue(F32 t, bool noExtrapolation) const
 99   {
100       F32 v = getValue(t,0.0f,1.0f,1.0f);
101       if (noExtrapolation)
102           v = mClampF(v,0.0f,1.0f);
103       return v;
104   }
105   F32 getUnitValue(F32 t) const
106   {
107       return getValue(t,0.0f,1.0f,1.0f);
108   }
109};
110
111
112// simple linear tweening - no easing
113// t: current time, b: beginning value, c: change in value, d: duration
114inline F32 mLinearTween(F32 t, F32 b, F32 c, F32 d) 
115{
116   return c*t/d + b;
117}
118
119
120 ///////////// QUADRATIC EASING: t^2 ///////////////////
121
122// quadratic easing in - accelerating from zero velocity
123// t: current time, b: beginning value, c: change in value, d: duration
124// t and d can be in frames or seconds/milliseconds
125inline F32 mEaseInQuad(F32 t, F32 b, F32 c, F32 d) 
126{
127   t /= d;
128   return c*t*t + b;
129};
130
131// quadratic easing out - decelerating to zero velocity
132inline F32 mEaseOutQuad(F32 t, F32 b, F32 c, F32 d) 
133{
134   t /= d;
135   return -c * t*(t-2) + b;
136};
137
138// quadratic easing in/out - acceleration until halfway, then deceleration
139inline F32 mEaseInOutQuad(F32 t, F32 b, F32 c, F32 d) 
140{
141   t /= d/2;
142   if (t < 1) 
143      return c/2*t*t + b;
144   t--;
145   return -c/2 * (t*(t-2) - 1) + b;
146};
147
148 ///////////// CUBIC EASING: t^3 ///////////////////////
149
150// cubic easing in - accelerating from zero velocity
151// t: current time, b: beginning value, c: change in value, d: duration
152// t and d can be frames or seconds/milliseconds
153inline F32 mEaseInCubic(F32 t, F32 b, F32 c, F32 d) 
154{
155   t /= d;
156   return c*t*t*t + b;
157};
158
159// cubic easing out - decelerating to zero velocity
160inline F32 mEaseOutCubic(F32 t, F32 b, F32 c, F32 d) 
161{
162   t /= d;
163   t--;
164   return c*(t*t*t + 1) + b;
165};
166
167// cubic easing in/out - acceleration until halfway, then deceleration
168inline F32 mEaseInOutCubic(F32 t, F32 b, F32 c, F32 d) 
169{
170   t /= d/2;
171   if (t < 1) 
172      return c/2*t*t*t + b;
173   t -= 2;
174   return c/2*(t*t*t + 2) + b;
175};
176
177
178 ///////////// QUARTIC EASING: t^4 /////////////////////
179
180// quartic easing in - accelerating from zero velocity
181// t: current time, b: beginning value, c: change in value, d: duration
182// t and d can be frames or seconds/milliseconds
183inline F32 mEaseInQuart(F32 t, F32 b, F32 c, F32 d) 
184{
185   t /= d;
186   return c*t*t*t*t + b;
187};
188
189// quartic easing out - decelerating to zero velocity
190inline F32 mEaseOutQuart(F32 t, F32 b, F32 c, F32 d) 
191{
192   t /= d;
193   t--;
194   return -c * (t*t*t*t - 1) + b;
195};
196
197// quartic easing in/out - acceleration until halfway, then deceleration
198inline F32 mEaseInOutQuart(F32 t, F32 b, F32 c, F32 d) 
199{
200   t /= d/2;
201   if (t < 1) 
202      return c/2*t*t*t*t + b;
203   t -= 2;
204   return -c/2 * (t*t*t*t - 2) + b;
205};
206
207
208 ///////////// QUINTIC EASING: t^5  ////////////////////
209
210// quintic easing in - accelerating from zero velocity
211// t: current time, b: beginning value, c: change in value, d: duration
212// t and d can be frames or seconds/milliseconds
213inline F32 mEaseInQuint(F32 t, F32 b, F32 c, F32 d) 
214{
215   t /= d;
216   return c*t*t*t*t*t + b;
217};
218
219// quintic easing out - decelerating to zero velocity
220inline F32 mEaseOutQuint(F32 t, F32 b, F32 c, F32 d) 
221{
222   t /= d;
223   t--;
224   return c*(t*t*t*t*t + 1) + b;
225};
226
227// quintic easing in/out - acceleration until halfway, then deceleration
228inline F32 mEaseInOutQuint(F32 t, F32 b, F32 c, F32 d) 
229{
230   t /= d/2;
231   if (t < 1) 
232      return c/2*t*t*t*t*t + b;
233   t -= 2;
234   return c/2*(t*t*t*t*t + 2) + b;
235};
236
237
238
239 ///////////// SINUSOIDAL EASING: sin(t) ///////////////
240
241// sinusoidal easing in - accelerating from zero velocity
242// t: current time, b: beginning value, c: change in position, d: duration
243inline F32 mEaseInSine(F32 t, F32 b, F32 c, F32 d) 
244{
245   return -c * mCos(t/d * (M_PI_F/2)) + c + b;
246};
247
248// sinusoidal easing out - decelerating to zero velocity
249inline F32 mEaseOutSine(F32 t, F32 b, F32 c, F32 d) 
250{
251   return c * mSin(t/d * (M_PI_F/2)) + b;
252};
253
254// sinusoidal easing in/out - accelerating until halfway, then decelerating
255inline F32 mEaseInOutSine(F32 t, F32 b, F32 c, F32 d) 
256{
257   return -c/2 * (mCos(M_PI_F*t/d) - 1) + b;
258};
259
260
261 ///////////// EXPONENTIAL EASING: 2^t /////////////////
262
263// exponential easing in - accelerating from zero velocity
264// t: current time, b: beginning value, c: change in position, d: duration
265inline F32 mEaseInExpo(F32 t, F32 b, F32 c, F32 d) 
266{
267   return c * mPow( 2, 10 * (t/d - 1) ) + b;
268};
269
270// exponential easing out - decelerating to zero velocity
271inline F32 mEaseOutExpo(F32 t, F32 b, F32 c, F32 d) 
272{
273   return c * ( -mPow( 2, -10 * t/d ) + 1 ) + b;
274};
275
276// exponential easing in/out - accelerating until halfway, then decelerating
277inline F32 mEaseInOutExpo(F32 t, F32 b, F32 c, F32 d) 
278{
279   t /= d/2;
280   if (t < 1) 
281      return c/2 * mPow( 2, 10 * (t - 1) ) + b;
282   t--;
283   return c/2 * ( -mPow( 2, -10 * t) + 2 ) + b;
284};
285
286
287 /////////// CIRCULAR EASING: sqrt(1-t^2) //////////////
288
289// circular easing in - accelerating from zero velocity
290// t: current time, b: beginning value, c: change in position, d: duration
291inline F32 mEaseInCirc (F32 t, F32 b, F32 c, F32 d) 
292{
293   t/=d;
294   return -c * (mSqrt(1 - (t)*t) - 1) + b;
295};
296
297// circular easing out - decelerating to zero velocity
298inline F32 mEaseOutCirc (F32 t, F32 b, F32 c, F32 d) 
299{
300   t/=d;
301   t--;
302   return c * mSqrt(1 - (t)*t) + b;
303};
304
305// circular easing in/out - acceleration until halfway, then deceleration
306inline F32 mEaseInOutCirc(F32 t, F32 b, F32 c, F32 d) 
307{
308   if ((t/=d/2) < 1) 
309      return -c/2 * (mSqrt(1 - t*t) - 1) + b;
310   t-=2;
311   return c/2 * (mSqrt(1 - (t)*t) + 1) + b;
312};
313
314
315 /////////// ELASTIC EASING: exponentially decaying sine wave  //////////////
316
317// t: current time, b: beginning value, c: change in value, d: duration, a: amplitude (optional), p: period (optional)
318// t and d can be in frames or seconds/milliseconds
319
320inline F32 mEaseInElastic(F32 t, F32 b, F32 c, F32 d, F32 a, F32 p) 
321{
322   if (t==0) 
323      return b;  
324   
325   F32 dt = t /= d;
326   if (dt == 1)
327      return b+c;  
328   
329   if (p<=0) 
330      p=d*.3f;
331
332   F32 s;
333   if (a < mFabs(c))
334   {
335      a=c; 
336      s=p/4;
337   }
338   else 
339      s = p/(2*M_PI_F) * mAsin (c/<a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a>);
340
341   t -= 1;
342   return -(a*mPow(2,10*t) * mSin( (t*d-s)*(2*M_PI_F)/p )) + b;
343};
344
345inline F32 mEaseOutElastic(F32 t, F32 b, F32 c, F32 d, F32 a, F32 p) 
346{
347   if (t==0) 
348      return b; 
349
350   F32 dt = t /= d;
351   if (dt == 1)
352      return b+c; 
353
354   if (p<=0) 
355      p=d*.3f;
356
357   F32 s;
358   if (a < mFabs(c))
359   {
360      a=c; 
361      s=p/4;
362   }
363   else 
364      s = p/(2*M_PI_F) * mAsin (c/<a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a>);
365
366   return a*mPow(2,-10*t) * mSin( (t*d-s)*(2*M_PI_F)/p ) + c + b;
367};
368
369inline F32 mEaseInOutElastic(F32 t, F32 b, F32 c, F32 d, F32 a, F32 p) 
370{
371   if (t==0) 
372      return b;  
373   
374   F32 dt = t /= d / 2;
375   if (dt == 2)
376      return b+c;  
377   
378   if (p<=0) 
379      p=d*(.3f*1.5f);
380
381   F32 s;
382   if (a < mFabs(c))
383   {
384      a=c; 
385      s=p/4;
386   }
387   else 
388      s = p/(2*M_PI_F) * mAsin (c/<a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a>);
389
390   if (t < 1)
391   {
392      t -= 1;
393      return -.5f*(a*mPow(2, 10 * t) * mSin((t*d - s)*(2 * M_PI_F) / p)) + b;
394   }
395
396   t -= 1;
397   return a*mPow(2,-10*t) * mSin( (t*d-s)*(2*M_PI_F)/p )*.5f + c + b;
398};
399
400
401 /////////// BACK EASING: overshooting cubic easing: (s+1)*t^3 - s*t^2  //////////////
402
403// back easing in - backtracking slightly, then reversing direction and moving to target
404// t: current time, b: beginning value, c: change in value, d: duration, s: overshoot amount (optional)
405// t and d can be in frames or seconds/milliseconds
406// s controls the amount of overshoot: higher s means greater overshoot
407// s has a default value of 1.70158, which produces an overshoot of 10 percent
408// s==0 produces cubic easing with no overshoot
409inline F32 mEaseInBack(F32 t, F32 b, F32 c, F32 d, F32 s) 
410{
411   if (s < 0) 
412      s = 1.70158f;
413
414   F32 td = t /= d;
415   return c*td*t*((s + 1)*t - s) + b;
416};
417
418// back easing out - moving towards target, overshooting it slightly, then reversing and coming back to target
419inline F32 mEaseOutBack(F32 t, F32 b, F32 c, F32 d, F32 s) 
420{
421   if (s < 0) 
422      s = 1.70158f;
423
424   F32 td = t / d - 1;
425   t = td;
426   return c*(td*t*((s + 1)*t + s) + 1) + b;
427};
428
429// back easing in/out - backtracking slightly, then reversing direction and moving to target,
430// then overshooting target, reversing, and finally coming back to target
431inline F32 mEaseInOutBack(F32 t, F32 b, F32 c, F32 d, F32 s) 
432{
433   if (s < 0) 
434      s = 1.70158f; 
435
436   F32 td = t /= d / 2;
437   if (td < 1)
438   {
439      s *= 1.525f;
440      return c / 2 * (t*t*((s + 1)*t - s)) + b;
441   }
442
443   s *= 1.525f;
444   t -= 2;
445   return c/2*(t*t*((s+1)*t + s) + 2) + b;
446};
447
448
449 /////////// BOUNCE EASING: exponentially decaying parabolic bounce  //////////////
450
451// bounce easing out
452inline F32 mEaseOutBounce(F32 t, F32 b, F32 c, F32 d) 
453{
454   if ((t/=d) < (1/2.75f)) 
455   {
456      return c*(7.5625f*t*t) + b;
457   } 
458   else if (t < (2/2.75)) 
459   {
460      t -= 1.5f / 2.75f;
461      return c*(7.5625f*t*t + .75f) + b;
462   } 
463   else if (t < (2.5/2.75)) 
464   {
465      t -= 2.25f / 2.75f;
466      return c*(7.5625f*t*t + .9375f) + b;
467   } 
468   else 
469   {
470      t -= 2.625f / 2.75f;
471      return c*(7.5625f*t*t + .984375f) + b;
472   }
473};
474
475// bounce easing in
476// t: current time, b: beginning value, c: change in position, d: duration
477inline F32 mEaseInBounce(F32 t, F32 b, F32 c, F32 d) 
478{
479   return c - mEaseOutBounce (d-t, 0, c, d) + b;
480};
481
482// bounce easing in/out
483inline F32 mEaseInOutBounce(F32 t, F32 b, F32 c, F32 d) 
484{
485   if (t < d/2) 
486      return mEaseInBounce (t*2, 0, c, d) * .5f + b;
487
488   return mEaseOutBounce (t*2-d, 0, c, d) * .5f + c*.5f + b;
489};
490
491#endif // _MEASE_H_
492