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