Blender  V2.93
easing.c
Go to the documentation of this file.
1 /*
2  * Redistribution and use in source and binary forms, with or without
3  * modification, are permitted provided that the following conditions are met:
4  *
5  * * Redistributions of source code must retain the above copyright
6  * notice, this list of conditions and the following disclaimer.
7  *
8  * * Redistributions in binary form must reproduce the above copyright
9  * notice, this list of conditions and the following disclaimer in the
10  * documentation and/or other materials provided with the distribution.
11  *
12  * * Neither the name of the author nor the names of contributors may be
13  * used to endorse or promote products derived from this software without
14  * specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  * Copyright (c) 2001 Robert Penner
28  * All rights reserved.
29  */
30 
35 #include "BLI_math_base.h"
36 
37 #include "BLI_easing.h" /* own include */
38 
39 #include "BLI_strict_flags.h"
40 
41 /* blend if (amplitude < fabsf(change) */
42 #define USE_ELASTIC_BLEND
43 
45  float time, float begin, float change, float duration, float overshoot)
46 {
47  time /= duration;
48  return change * time * time * ((overshoot + 1) * time - overshoot) + begin;
49 }
50 
52  float time, float begin, float change, float duration, float overshoot)
53 {
54  time = time / duration - 1;
55  return change * (time * time * ((overshoot + 1) * time + overshoot) + 1) + begin;
56 }
57 
59  float time, float begin, float change, float duration, float overshoot)
60 {
61  overshoot *= 1.525f;
62  if ((time /= duration / 2) < 1.0f) {
63  return change / 2 * (time * time * ((overshoot + 1) * time - overshoot)) + begin;
64  }
65  time -= 2.0f;
66  return change / 2 * (time * time * ((overshoot + 1) * time + overshoot) + 2) + begin;
67 }
68 
69 float BLI_easing_bounce_ease_out(float time, float begin, float change, float duration)
70 {
71  time /= duration;
72  if (time < (1 / 2.75f)) {
73  return change * (7.5625f * time * time) + begin;
74  }
75  if (time < (2 / 2.75f)) {
76  time -= (1.5f / 2.75f);
77  return change * ((7.5625f * time) * time + 0.75f) + begin;
78  }
79  if (time < (2.5f / 2.75f)) {
80  time -= (2.25f / 2.75f);
81  return change * ((7.5625f * time) * time + 0.9375f) + begin;
82  }
83  time -= (2.625f / 2.75f);
84  return change * ((7.5625f * time) * time + 0.984375f) + begin;
85 }
86 
87 float BLI_easing_bounce_ease_in(float time, float begin, float change, float duration)
88 {
89  return change - BLI_easing_bounce_ease_out(duration - time, 0, change, duration) + begin;
90 }
91 
92 float BLI_easing_bounce_ease_in_out(float time, float begin, float change, float duration)
93 {
94  if (time < duration / 2) {
95  return BLI_easing_bounce_ease_in(time * 2, 0, change, duration) * 0.5f + begin;
96  }
97  return BLI_easing_bounce_ease_out(time * 2 - duration, 0, change, duration) * 0.5f +
98  change * 0.5f + begin;
99 }
100 
101 float BLI_easing_circ_ease_in(float time, float begin, float change, float duration)
102 {
103  time /= duration;
104  return -change * (sqrtf(1 - time * time) - 1) + begin;
105 }
106 
107 float BLI_easing_circ_ease_out(float time, float begin, float change, float duration)
108 {
109  time = time / duration - 1;
110  return change * sqrtf(1 - time * time) + begin;
111 }
112 
113 float BLI_easing_circ_ease_in_out(float time, float begin, float change, float duration)
114 {
115  if ((time /= duration / 2) < 1.0f) {
116  return -change / 2 * (sqrtf(1 - time * time) - 1) + begin;
117  }
118  time -= 2.0f;
119  return change / 2 * (sqrtf(1 - time * time) + 1) + begin;
120 }
121 
122 float BLI_easing_cubic_ease_in(float time, float begin, float change, float duration)
123 {
124  time /= duration;
125  return change * time * time * time + begin;
126 }
127 
128 float BLI_easing_cubic_ease_out(float time, float begin, float change, float duration)
129 {
130  time = time / duration - 1;
131  return change * (time * time * time + 1) + begin;
132 }
133 
134 float BLI_easing_cubic_ease_in_out(float time, float begin, float change, float duration)
135 {
136  if ((time /= duration / 2) < 1.0f) {
137  return change / 2 * time * time * time + begin;
138  }
139  time -= 2.0f;
140  return change / 2 * (time * time * time + 2) + begin;
141 }
142 
143 #ifdef USE_ELASTIC_BLEND
148 static float elastic_blend(
149  float time, float change, float duration, float amplitude, float s, float f)
150 {
151  if (change) {
152  /* Looks like a magic number,
153  * but this is a part of the sine curve we need to blend from */
154  const float t = fabsf(s);
155  if (amplitude) {
156  f *= amplitude / fabsf(change);
157  }
158  else {
159  f = 0.0f;
160  }
161 
162  if (fabsf(time * duration) < t) {
163  float l = fabsf(time * duration) / t;
164  f = (f * l) + (1.0f - l);
165  }
166  }
167 
168  return f;
169 }
170 #endif
171 
173  float time, float begin, float change, float duration, float amplitude, float period)
174 {
175  float s;
176  float f = 1.0f;
177 
178  if (time == 0.0f) {
179  return begin;
180  }
181 
182  if ((time /= duration) == 1.0f) {
183  return begin + change;
184  }
185  time -= 1.0f;
186  if (!period) {
187  period = duration * 0.3f;
188  }
189  if (!amplitude || amplitude < fabsf(change)) {
190  s = period / 4;
191 #ifdef USE_ELASTIC_BLEND
192  f = elastic_blend(time, change, duration, amplitude, s, f);
193 #endif
194  amplitude = change;
195  }
196  else {
197  s = period / (2 * (float)M_PI) * asinf(change / amplitude);
198  }
199 
200  return (-f * (amplitude * powf(2, 10 * time) *
201  sinf((time * duration - s) * (2 * (float)M_PI) / period))) +
202  begin;
203 }
204 
206  float time, float begin, float change, float duration, float amplitude, float period)
207 {
208  float s;
209  float f = 1.0f;
210 
211  if (time == 0.0f) {
212  return begin;
213  }
214  if ((time /= duration) == 1.0f) {
215  return begin + change;
216  }
217  time = -time;
218  if (!period) {
219  period = duration * 0.3f;
220  }
221  if (!amplitude || amplitude < fabsf(change)) {
222  s = period / 4;
223 #ifdef USE_ELASTIC_BLEND
224  f = elastic_blend(time, change, duration, amplitude, s, f);
225 #endif
226  amplitude = change;
227  }
228  else {
229  s = period / (2 * (float)M_PI) * asinf(change / amplitude);
230  }
231 
232  return (f * (amplitude * powf(2, 10 * time) *
233  sinf((time * duration - s) * (2 * (float)M_PI) / period))) +
234  change + begin;
235 }
236 
238  float time, float begin, float change, float duration, float amplitude, float period)
239 {
240  float s;
241  float f = 1.0f;
242 
243  if (time == 0.0f) {
244  return begin;
245  }
246  if ((time /= duration / 2) == 2.0f) {
247  return begin + change;
248  }
249  time -= 1.0f;
250  if (!period) {
251  period = duration * (0.3f * 1.5f);
252  }
253  if (!amplitude || amplitude < fabsf(change)) {
254  s = period / 4;
255 #ifdef USE_ELASTIC_BLEND
256  f = elastic_blend(time, change, duration, amplitude, s, f);
257 #endif
258  amplitude = change;
259  }
260  else {
261  s = period / (2 * (float)M_PI) * asinf(change / amplitude);
262  }
263 
264  if (time < 0.0f) {
265  f *= -0.5f;
266  return (f * (amplitude * powf(2, 10 * time) *
267  sinf((time * duration - s) * (2 * (float)M_PI) / period))) +
268  begin;
269  }
270 
271  time = -time;
272  f *= 0.5f;
273  return (f * (amplitude * powf(2, 10 * time) *
274  sinf((time * duration - s) * (2 * (float)M_PI) / period))) +
275  change + begin;
276 }
277 
278 static const float pow_min = 0.0009765625f; /* = 2^(-10) */
279 static const float pow_scale = 1.0f / (1.0f - 0.0009765625f);
280 
281 float BLI_easing_expo_ease_in(float time, float begin, float change, float duration)
282 {
283  if (time == 0.0) {
284  return begin;
285  }
286  return change * (powf(2, 10 * (time / duration - 1)) - pow_min) * pow_scale + begin;
287 }
288 
289 float BLI_easing_expo_ease_out(float time, float begin, float change, float duration)
290 {
291  if (time == 0.0) {
292  return begin;
293  }
294  return change * (1 - (powf(2, -10 * time / duration) - pow_min) * pow_scale) + begin;
295 }
296 
297 float BLI_easing_expo_ease_in_out(float time, float begin, float change, float duration)
298 {
299  float duration_half = duration / 2.0f;
300  float change_half = change / 2.0f;
301  if (time <= duration_half) {
302  return BLI_easing_expo_ease_in(time, begin, change_half, duration_half);
303  }
305  time - duration_half, begin + change_half, change_half, duration_half);
306 }
307 
308 float BLI_easing_linear_ease(float time, float begin, float change, float duration)
309 {
310  return change * time / duration + begin;
311 }
312 
313 float BLI_easing_quad_ease_in(float time, float begin, float change, float duration)
314 {
315  time /= duration;
316  return change * time * time + begin;
317 }
318 
319 float BLI_easing_quad_ease_out(float time, float begin, float change, float duration)
320 {
321  time /= duration;
322  return -change * time * (time - 2) + begin;
323 }
324 
325 float BLI_easing_quad_ease_in_out(float time, float begin, float change, float duration)
326 {
327  if ((time /= duration / 2) < 1.0f) {
328  return change / 2 * time * time + begin;
329  }
330  time -= 1.0f;
331  return -change / 2 * (time * (time - 2) - 1) + begin;
332 }
333 
334 float BLI_easing_quart_ease_in(float time, float begin, float change, float duration)
335 {
336  time /= duration;
337  return change * time * time * time * time + begin;
338 }
339 
340 float BLI_easing_quart_ease_out(float time, float begin, float change, float duration)
341 {
342  time = time / duration - 1;
343  return -change * (time * time * time * time - 1) + begin;
344 }
345 
346 float BLI_easing_quart_ease_in_out(float time, float begin, float change, float duration)
347 {
348  if ((time /= duration / 2) < 1.0f) {
349  return change / 2 * time * time * time * time + begin;
350  }
351  time -= 2.0f;
352  return -change / 2 * (time * time * time * time - 2) + begin;
353 }
354 
355 float BLI_easing_quint_ease_in(float time, float begin, float change, float duration)
356 {
357  time /= duration;
358  return change * time * time * time * time * time + begin;
359 }
360 float BLI_easing_quint_ease_out(float time, float begin, float change, float duration)
361 {
362  time = time / duration - 1;
363  return change * (time * time * time * time * time + 1) + begin;
364 }
365 float BLI_easing_quint_ease_in_out(float time, float begin, float change, float duration)
366 {
367  if ((time /= duration / 2) < 1.0f) {
368  return change / 2 * time * time * time * time * time + begin;
369  }
370  time -= 2.0f;
371  return change / 2 * (time * time * time * time * time + 2) + begin;
372 }
373 
374 float BLI_easing_sine_ease_in(float time, float begin, float change, float duration)
375 {
376  return -change * cosf(time / duration * (float)M_PI_2) + change + begin;
377 }
378 
379 float BLI_easing_sine_ease_out(float time, float begin, float change, float duration)
380 {
381  return change * sinf(time / duration * (float)M_PI_2) + begin;
382 }
383 
384 float BLI_easing_sine_ease_in_out(float time, float begin, float change, float duration)
385 {
386  return -change / 2 * (cosf((float)M_PI * time / duration) - 1) + begin;
387 }
typedef float(TangentPoint)[2]
#define M_PI_2
Definition: BLI_math_base.h:41
#define M_PI
Definition: BLI_math_base.h:38
Strict compiler flags for areas of code we want to ensure don't do conversions without us knowing abo...
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
ATTR_WARN_UNUSED_RESULT const BMLoop * l
double time
float BLI_easing_sine_ease_in(float time, float begin, float change, float duration)
Definition: easing.c:374
float BLI_easing_back_ease_out(float time, float begin, float change, float duration, float overshoot)
Definition: easing.c:51
float BLI_easing_linear_ease(float time, float begin, float change, float duration)
Definition: easing.c:308
float BLI_easing_bounce_ease_in_out(float time, float begin, float change, float duration)
Definition: easing.c:92
float BLI_easing_quint_ease_out(float time, float begin, float change, float duration)
Definition: easing.c:360
float BLI_easing_quart_ease_in_out(float time, float begin, float change, float duration)
Definition: easing.c:346
float BLI_easing_circ_ease_in_out(float time, float begin, float change, float duration)
Definition: easing.c:113
float BLI_easing_quart_ease_out(float time, float begin, float change, float duration)
Definition: easing.c:340
float BLI_easing_bounce_ease_in(float time, float begin, float change, float duration)
Definition: easing.c:87
float BLI_easing_circ_ease_in(float time, float begin, float change, float duration)
Definition: easing.c:101
float BLI_easing_expo_ease_in(float time, float begin, float change, float duration)
Definition: easing.c:281
float BLI_easing_expo_ease_out(float time, float begin, float change, float duration)
Definition: easing.c:289
float BLI_easing_elastic_ease_in(float time, float begin, float change, float duration, float amplitude, float period)
Definition: easing.c:172
float BLI_easing_quad_ease_in_out(float time, float begin, float change, float duration)
Definition: easing.c:325
float BLI_easing_elastic_ease_out(float time, float begin, float change, float duration, float amplitude, float period)
Definition: easing.c:205
float BLI_easing_cubic_ease_in(float time, float begin, float change, float duration)
Definition: easing.c:122
float BLI_easing_elastic_ease_in_out(float time, float begin, float change, float duration, float amplitude, float period)
Definition: easing.c:237
float BLI_easing_quint_ease_in(float time, float begin, float change, float duration)
Definition: easing.c:355
float BLI_easing_sine_ease_out(float time, float begin, float change, float duration)
Definition: easing.c:379
float BLI_easing_bounce_ease_out(float time, float begin, float change, float duration)
Definition: easing.c:69
float BLI_easing_quad_ease_in(float time, float begin, float change, float duration)
Definition: easing.c:313
float BLI_easing_quad_ease_out(float time, float begin, float change, float duration)
Definition: easing.c:319
float BLI_easing_circ_ease_out(float time, float begin, float change, float duration)
Definition: easing.c:107
float BLI_easing_cubic_ease_out(float time, float begin, float change, float duration)
Definition: easing.c:128
float BLI_easing_back_ease_in(float time, float begin, float change, float duration, float overshoot)
Definition: easing.c:44
static float elastic_blend(float time, float change, float duration, float amplitude, float s, float f)
Definition: easing.c:148
float BLI_easing_quint_ease_in_out(float time, float begin, float change, float duration)
Definition: easing.c:365
float BLI_easing_expo_ease_in_out(float time, float begin, float change, float duration)
Definition: easing.c:297
static const float pow_min
Definition: easing.c:278
float BLI_easing_quart_ease_in(float time, float begin, float change, float duration)
Definition: easing.c:334
static const float pow_scale
Definition: easing.c:279
float BLI_easing_back_ease_in_out(float time, float begin, float change, float duration, float overshoot)
Definition: easing.c:58
float BLI_easing_cubic_ease_in_out(float time, float begin, float change, float duration)
Definition: easing.c:134
float BLI_easing_sine_ease_in_out(float time, float begin, float change, float duration)
Definition: easing.c:384
#define sinf(x)
#define cosf(x)
#define powf(x, y)
#define asinf(x)
#define fabsf(x)
#define sqrtf(x)