1/**************************************************************************/
2/* easing_equations.h */
3/**************************************************************************/
4/* This file is part of: */
5/* GODOT ENGINE */
6/* https://godotengine.org */
7/**************************************************************************/
8/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10/* */
11/* Permission is hereby granted, free of charge, to any person obtaining */
12/* a copy of this software and associated documentation files (the */
13/* "Software"), to deal in the Software without restriction, including */
14/* without limitation the rights to use, copy, modify, merge, publish, */
15/* distribute, sublicense, and/or sell copies of the Software, and to */
16/* permit persons to whom the Software is furnished to do so, subject to */
17/* the following conditions: */
18/* */
19/* The above copyright notice and this permission notice shall be */
20/* included in all copies or substantial portions of the Software. */
21/* */
22/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29/**************************************************************************/
30
31#ifndef EASING_EQUATIONS_H
32#define EASING_EQUATIONS_H
33
34/*
35 * Derived from Robert Penner's easing equations: http://robertpenner.com/easing/
36 *
37 * Copyright (c) 2001 Robert Penner
38 *
39 * Permission is hereby granted, free of charge, to any person obtaining a copy
40 * of this software and associated documentation files (the "Software"), to deal
41 * in the Software without restriction, including without limitation the rights
42 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
43 * copies of the Software, and to permit persons to whom the Software is
44 * furnished to do so, subject to the following conditions:
45 *
46 * The above copyright notice and this permission notice shall be included in all
47 * copies or substantial portions of the Software.
48 *
49 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
50 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
51 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
52 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
53 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
54 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
55 * SOFTWARE.
56 */
57
58namespace linear {
59static real_t in(real_t t, real_t b, real_t c, real_t d) {
60 return c * t / d + b;
61}
62}; // namespace linear
63
64namespace sine {
65static real_t in(real_t t, real_t b, real_t c, real_t d) {
66 return -c * cos(t / d * (Math_PI / 2)) + c + b;
67}
68
69static real_t out(real_t t, real_t b, real_t c, real_t d) {
70 return c * sin(t / d * (Math_PI / 2)) + b;
71}
72
73static real_t in_out(real_t t, real_t b, real_t c, real_t d) {
74 return -c / 2 * (cos(Math_PI * t / d) - 1) + b;
75}
76
77static real_t out_in(real_t t, real_t b, real_t c, real_t d) {
78 if (t < d / 2) {
79 return out(t * 2, b, c / 2, d);
80 }
81 real_t h = c / 2;
82 return in(t * 2 - d, b + h, h, d);
83}
84}; // namespace sine
85
86namespace quint {
87static real_t in(real_t t, real_t b, real_t c, real_t d) {
88 return c * pow(t / d, 5) + b;
89}
90
91static real_t out(real_t t, real_t b, real_t c, real_t d) {
92 return c * (pow(t / d - 1, 5) + 1) + b;
93}
94
95static real_t in_out(real_t t, real_t b, real_t c, real_t d) {
96 t = t / d * 2;
97
98 if (t < 1) {
99 return c / 2 * pow(t, 5) + b;
100 }
101 return c / 2 * (pow(t - 2, 5) + 2) + b;
102}
103
104static real_t out_in(real_t t, real_t b, real_t c, real_t d) {
105 if (t < d / 2) {
106 return out(t * 2, b, c / 2, d);
107 }
108 real_t h = c / 2;
109 return in(t * 2 - d, b + h, h, d);
110}
111}; // namespace quint
112
113namespace quart {
114static real_t in(real_t t, real_t b, real_t c, real_t d) {
115 return c * pow(t / d, 4) + b;
116}
117
118static real_t out(real_t t, real_t b, real_t c, real_t d) {
119 return -c * (pow(t / d - 1, 4) - 1) + b;
120}
121
122static real_t in_out(real_t t, real_t b, real_t c, real_t d) {
123 t = t / d * 2;
124
125 if (t < 1) {
126 return c / 2 * pow(t, 4) + b;
127 }
128 return -c / 2 * (pow(t - 2, 4) - 2) + b;
129}
130
131static real_t out_in(real_t t, real_t b, real_t c, real_t d) {
132 if (t < d / 2) {
133 return out(t * 2, b, c / 2, d);
134 }
135 real_t h = c / 2;
136 return in(t * 2 - d, b + h, h, d);
137}
138}; // namespace quart
139
140namespace quad {
141static real_t in(real_t t, real_t b, real_t c, real_t d) {
142 return c * pow(t / d, 2) + b;
143}
144
145static real_t out(real_t t, real_t b, real_t c, real_t d) {
146 t /= d;
147 return -c * t * (t - 2) + b;
148}
149
150static real_t in_out(real_t t, real_t b, real_t c, real_t d) {
151 t = t / d * 2;
152
153 if (t < 1) {
154 return c / 2 * pow(t, 2) + b;
155 }
156 return -c / 2 * ((t - 1) * (t - 3) - 1) + b;
157}
158
159static real_t out_in(real_t t, real_t b, real_t c, real_t d) {
160 if (t < d / 2) {
161 return out(t * 2, b, c / 2, d);
162 }
163 real_t h = c / 2;
164 return in(t * 2 - d, b + h, h, d);
165}
166}; // namespace quad
167
168namespace expo {
169static real_t in(real_t t, real_t b, real_t c, real_t d) {
170 if (t == 0) {
171 return b;
172 }
173 return c * pow(2, 10 * (t / d - 1)) + b - c * 0.001;
174}
175
176static real_t out(real_t t, real_t b, real_t c, real_t d) {
177 if (t == d) {
178 return b + c;
179 }
180 return c * 1.001 * (-pow(2, -10 * t / d) + 1) + b;
181}
182
183static real_t in_out(real_t t, real_t b, real_t c, real_t d) {
184 if (t == 0) {
185 return b;
186 }
187
188 if (t == d) {
189 return b + c;
190 }
191
192 t = t / d * 2;
193
194 if (t < 1) {
195 return c / 2 * pow(2, 10 * (t - 1)) + b - c * 0.0005;
196 }
197 return c / 2 * 1.0005 * (-pow(2, -10 * (t - 1)) + 2) + b;
198}
199
200static real_t out_in(real_t t, real_t b, real_t c, real_t d) {
201 if (t < d / 2) {
202 return out(t * 2, b, c / 2, d);
203 }
204 real_t h = c / 2;
205 return in(t * 2 - d, b + h, h, d);
206}
207}; // namespace expo
208
209namespace elastic {
210static real_t in(real_t t, real_t b, real_t c, real_t d) {
211 if (t == 0) {
212 return b;
213 }
214
215 t /= d;
216 if (t == 1) {
217 return b + c;
218 }
219
220 t -= 1;
221 float p = d * 0.3f;
222 float a = c * pow(2, 10 * t);
223 float s = p / 4;
224
225 return -(a * sin((t * d - s) * (2 * Math_PI) / p)) + b;
226}
227
228static real_t out(real_t t, real_t b, real_t c, real_t d) {
229 if (t == 0) {
230 return b;
231 }
232
233 t /= d;
234 if (t == 1) {
235 return b + c;
236 }
237
238 float p = d * 0.3f;
239 float s = p / 4;
240
241 return (c * pow(2, -10 * t) * sin((t * d - s) * (2 * Math_PI) / p) + c + b);
242}
243
244static real_t in_out(real_t t, real_t b, real_t c, real_t d) {
245 if (t == 0) {
246 return b;
247 }
248
249 if ((t /= d / 2) == 2) {
250 return b + c;
251 }
252
253 float p = d * (0.3f * 1.5f);
254 float a = c;
255 float s = p / 4;
256
257 if (t < 1) {
258 t -= 1;
259 a *= pow(2, 10 * t);
260 return -0.5f * (a * sin((t * d - s) * (2 * Math_PI) / p)) + b;
261 }
262
263 t -= 1;
264 a *= pow(2, -10 * t);
265 return a * sin((t * d - s) * (2 * Math_PI) / p) * 0.5f + c + b;
266}
267
268static real_t out_in(real_t t, real_t b, real_t c, real_t d) {
269 if (t < d / 2) {
270 return out(t * 2, b, c / 2, d);
271 }
272 real_t h = c / 2;
273 return in(t * 2 - d, b + h, h, d);
274}
275}; // namespace elastic
276
277namespace cubic {
278static real_t in(real_t t, real_t b, real_t c, real_t d) {
279 t /= d;
280 return c * t * t * t + b;
281}
282
283static real_t out(real_t t, real_t b, real_t c, real_t d) {
284 t = t / d - 1;
285 return c * (t * t * t + 1) + b;
286}
287
288static real_t in_out(real_t t, real_t b, real_t c, real_t d) {
289 t /= d / 2;
290 if (t < 1) {
291 return c / 2 * t * t * t + b;
292 }
293
294 t -= 2;
295 return c / 2 * (t * t * t + 2) + b;
296}
297
298static real_t out_in(real_t t, real_t b, real_t c, real_t d) {
299 if (t < d / 2) {
300 return out(t * 2, b, c / 2, d);
301 }
302 real_t h = c / 2;
303 return in(t * 2 - d, b + h, h, d);
304}
305}; // namespace cubic
306
307namespace circ {
308static real_t in(real_t t, real_t b, real_t c, real_t d) {
309 t /= d;
310 return -c * (sqrt(1 - t * t) - 1) + b;
311}
312
313static real_t out(real_t t, real_t b, real_t c, real_t d) {
314 t = t / d - 1;
315 return c * sqrt(1 - t * t) + b;
316}
317
318static real_t in_out(real_t t, real_t b, real_t c, real_t d) {
319 t /= d / 2;
320 if (t < 1) {
321 return -c / 2 * (sqrt(1 - t * t) - 1) + b;
322 }
323
324 t -= 2;
325 return c / 2 * (sqrt(1 - t * t) + 1) + b;
326}
327
328static real_t out_in(real_t t, real_t b, real_t c, real_t d) {
329 if (t < d / 2) {
330 return out(t * 2, b, c / 2, d);
331 }
332 real_t h = c / 2;
333 return in(t * 2 - d, b + h, h, d);
334}
335}; // namespace circ
336
337namespace bounce {
338static real_t out(real_t t, real_t b, real_t c, real_t d) {
339 t /= d;
340
341 if (t < (1 / 2.75f)) {
342 return c * (7.5625f * t * t) + b;
343 }
344
345 if (t < (2 / 2.75f)) {
346 t -= 1.5f / 2.75f;
347 return c * (7.5625f * t * t + 0.75f) + b;
348 }
349
350 if (t < (2.5 / 2.75)) {
351 t -= 2.25f / 2.75f;
352 return c * (7.5625f * t * t + 0.9375f) + b;
353 }
354
355 t -= 2.625f / 2.75f;
356 return c * (7.5625f * t * t + 0.984375f) + b;
357}
358
359static real_t in(real_t t, real_t b, real_t c, real_t d) {
360 return c - out(d - t, 0, c, d) + b;
361}
362
363static real_t in_out(real_t t, real_t b, real_t c, real_t d) {
364 if (t < d / 2) {
365 return in(t * 2, b, c / 2, d);
366 }
367 real_t h = c / 2;
368 return out(t * 2 - d, b + h, h, d);
369}
370
371static real_t out_in(real_t t, real_t b, real_t c, real_t d) {
372 if (t < d / 2) {
373 return out(t * 2, b, c / 2, d);
374 }
375 real_t h = c / 2;
376 return in(t * 2 - d, b + h, h, d);
377}
378}; // namespace bounce
379
380namespace back {
381static real_t in(real_t t, real_t b, real_t c, real_t d) {
382 float s = 1.70158f;
383 t /= d;
384
385 return c * t * t * ((s + 1) * t - s) + b;
386}
387
388static real_t out(real_t t, real_t b, real_t c, real_t d) {
389 float s = 1.70158f;
390 t = t / d - 1;
391
392 return c * (t * t * ((s + 1) * t + s) + 1) + b;
393}
394
395static real_t in_out(real_t t, real_t b, real_t c, real_t d) {
396 float s = 1.70158f * 1.525f;
397 t /= d / 2;
398
399 if (t < 1) {
400 return c / 2 * (t * t * ((s + 1) * t - s)) + b;
401 }
402
403 t -= 2;
404 return c / 2 * (t * t * ((s + 1) * t + s) + 2) + b;
405}
406
407static real_t out_in(real_t t, real_t b, real_t c, real_t d) {
408 if (t < d / 2) {
409 return out(t * 2, b, c / 2, d);
410 }
411 real_t h = c / 2;
412 return in(t * 2 - d, b + h, h, d);
413}
414}; // namespace back
415
416namespace spring {
417static real_t out(real_t t, real_t b, real_t c, real_t d) {
418 t /= d;
419 real_t s = 1.0 - t;
420 t = (sin(t * Math_PI * (0.2 + 2.5 * t * t * t)) * pow(s, 2.2) + t) * (1.0 + (1.2 * s));
421 return c * t + b;
422}
423
424static real_t in(real_t t, real_t b, real_t c, real_t d) {
425 return c - out(d - t, 0, c, d) + b;
426}
427
428static real_t in_out(real_t t, real_t b, real_t c, real_t d) {
429 if (t < d / 2) {
430 return in(t * 2, b, c / 2, d);
431 }
432 real_t h = c / 2;
433 return out(t * 2 - d, b + h, h, d);
434}
435
436static real_t out_in(real_t t, real_t b, real_t c, real_t d) {
437 if (t < d / 2) {
438 return out(t * 2, b, c / 2, d);
439 }
440 real_t h = c / 2;
441 return in(t * 2 - d, b + h, h, d);
442}
443}; // namespace spring
444
445#endif // EASING_EQUATIONS_H
446