1 | /******************************************************************************************* |
2 | * |
3 | * raylib easings (header only file) |
4 | * |
5 | * Useful easing functions for values animation |
6 | * |
7 | * This header uses: |
8 | * #define EASINGS_STATIC_INLINE // Inlines all functions code, so it runs faster. |
9 | * // This requires lots of memory on system. |
10 | * How to use: |
11 | * The four inputs t,b,c,d are defined as follows: |
12 | * t = current time (in any unit measure, but same unit as duration) |
13 | * b = starting value to interpolate |
14 | * c = the total change in value of b that needs to occur |
15 | * d = total time it should take to complete (duration) |
16 | * |
17 | * Example: |
18 | * |
19 | * int currentTime = 0; |
20 | * int duration = 100; |
21 | * float startPositionX = 0.0f; |
22 | * float finalPositionX = 30.0f; |
23 | * float currentPositionX = startPositionX; |
24 | * |
25 | * while (currentPositionX < finalPositionX) |
26 | * { |
27 | * currentPositionX = EaseSineIn(currentTime, startPositionX, finalPositionX - startPositionX, duration); |
28 | * currentTime++; |
29 | * } |
30 | * |
31 | * A port of Robert Penner's easing equations to C (http://robertpenner.com/easing/) |
32 | * |
33 | * Robert Penner License |
34 | * --------------------------------------------------------------------------------- |
35 | * Open source under the BSD License. |
36 | * |
37 | * Copyright (c) 2001 Robert Penner. All rights reserved. |
38 | * |
39 | * Redistribution and use in source and binary forms, with or without modification, |
40 | * are permitted provided that the following conditions are met: |
41 | * |
42 | * - Redistributions of source code must retain the above copyright notice, |
43 | * this list of conditions and the following disclaimer. |
44 | * - Redistributions in binary form must reproduce the above copyright notice, |
45 | * this list of conditions and the following disclaimer in the documentation |
46 | * and/or other materials provided with the distribution. |
47 | * - Neither the name of the author nor the names of contributors may be used |
48 | * to endorse or promote products derived from this software without specific |
49 | * prior written permission. |
50 | * |
51 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
52 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
53 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
54 | * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
55 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
56 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
57 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
58 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE |
59 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
60 | * OF THE POSSIBILITY OF SUCH DAMAGE. |
61 | * --------------------------------------------------------------------------------- |
62 | * |
63 | * Copyright (c) 2015 Ramon Santamaria |
64 | * |
65 | * This software is provided "as-is", without any express or implied warranty. In no event |
66 | * will the authors be held liable for any damages arising from the use of this software. |
67 | * |
68 | * Permission is granted to anyone to use this software for any purpose, including commercial |
69 | * applications, and to alter it and redistribute it freely, subject to the following restrictions: |
70 | * |
71 | * 1. The origin of this software must not be misrepresented; you must not claim that you |
72 | * wrote the original software. If you use this software in a product, an acknowledgment |
73 | * in the product documentation would be appreciated but is not required. |
74 | * |
75 | * 2. Altered source versions must be plainly marked as such, and must not be misrepresented |
76 | * as being the original software. |
77 | * |
78 | * 3. This notice may not be removed or altered from any source distribution. |
79 | * |
80 | **********************************************************************************************/ |
81 | |
82 | #ifndef EASINGS_H |
83 | #define EASINGS_H |
84 | |
85 | #define EASINGS_STATIC_INLINE // NOTE: By default, compile functions as static inline |
86 | |
87 | #if defined(EASINGS_STATIC_INLINE) |
88 | #define EASEDEF static inline |
89 | #else |
90 | #define EASEDEF extern |
91 | #endif |
92 | |
93 | #include <math.h> // Required for: sin(), cos(), sqrt(), pow() |
94 | |
95 | #ifndef PI |
96 | #define PI 3.14159265358979323846f //Required as PI is not always defined in math.h |
97 | #endif |
98 | |
99 | #ifdef __cplusplus |
100 | extern "C" { // Prevents name mangling of functions |
101 | #endif |
102 | |
103 | // Linear Easing functions |
104 | EASEDEF float EaseLinearNone(float t, float b, float c, float d) { return (c*t/d + b); } |
105 | EASEDEF float EaseLinearIn(float t, float b, float c, float d) { return (c*t/d + b); } |
106 | EASEDEF float EaseLinearOut(float t, float b, float c, float d) { return (c*t/d + b); } |
107 | EASEDEF float EaseLinearInOut(float t,float b, float c, float d) { return (c*t/d + b); } |
108 | |
109 | // Sine Easing functions |
110 | EASEDEF float EaseSineIn(float t, float b, float c, float d) { return (-c*cos(t/d*(PI/2)) + c + b); } |
111 | EASEDEF float EaseSineOut(float t, float b, float c, float d) { return (c*sin(t/d*(PI/2)) + b); } |
112 | EASEDEF float EaseSineInOut(float t, float b, float c, float d) { return (-c/2*(cos(PI*t/d) - 1) + b); } |
113 | |
114 | // Circular Easing functions |
115 | EASEDEF float EaseCircIn(float t, float b, float c, float d) { t /= d; return (-c*(sqrt(1 - t*t) - 1) + b); } |
116 | EASEDEF float EaseCircOut(float t, float b, float c, float d) { t = t/d - 1; return (c*sqrt(1 - t*t) + b); } |
117 | EASEDEF float EaseCircInOut(float t, float b, float c, float d) |
118 | { |
119 | if ((t/=d/2) < 1) return (-c/2*(sqrt(1 - t*t) - 1) + b); |
120 | t -= 2; return (c/2*(sqrt(1 - t*t) + 1) + b); |
121 | } |
122 | |
123 | // Cubic Easing functions |
124 | EASEDEF float EaseCubicIn(float t, float b, float c, float d) { t /= d; return (c*t*t*t + b); } |
125 | EASEDEF float EaseCubicOut(float t, float b, float c, float d) { t = t/d-1; return (c*(t*t*t + 1) + b); } |
126 | EASEDEF float EaseCubicInOut(float t, float b, float c, float d) |
127 | { |
128 | if ((t/=d/2) < 1) return (c/2*t*t*t + b); |
129 | t -= 2; return (c/2*(t*t*t + 2) + b); |
130 | } |
131 | |
132 | // Quadratic Easing functions |
133 | EASEDEF float EaseQuadIn(float t, float b, float c, float d) { t /= d; return (c*t*t + b); } |
134 | EASEDEF float EaseQuadOut(float t, float b, float c, float d) { t /= d; return (-c*t*(t - 2) + b); } |
135 | EASEDEF float EaseQuadInOut(float t, float b, float c, float d) |
136 | { |
137 | if ((t/=d/2) < 1) return (((c/2)*(t*t)) + b); |
138 | t--; return (-c/2*(((t - 2)*t) - 1) + b); |
139 | } |
140 | |
141 | // Exponential Easing functions |
142 | EASEDEF float EaseExpoIn(float t, float b, float c, float d) { return (t == 0) ? b : (c*pow(2, 10*(t/d - 1)) + b); } |
143 | EASEDEF float EaseExpoOut(float t, float b, float c, float d) { return (t == d) ? (b + c) : (c*(-pow(2, -10*t/d) + 1) + b); } |
144 | EASEDEF float EaseExpoInOut(float t, float b, float c, float d) |
145 | { |
146 | if (t == 0) return b; |
147 | if (t == d) return (b + c); |
148 | if ((t/=d/2) < 1) return (c/2*pow(2, 10*(t - 1)) + b); |
149 | |
150 | return (c/2*(-pow(2, -10*--t) + 2) + b); |
151 | } |
152 | |
153 | // Back Easing functions |
154 | EASEDEF float EaseBackIn(float t, float b, float c, float d) |
155 | { |
156 | float s = 1.70158f; |
157 | float postFix = t/=d; |
158 | return (c*(postFix)*t*((s + 1)*t - s) + b); |
159 | } |
160 | |
161 | EASEDEF float EaseBackOut(float t, float b, float c, float d) |
162 | { |
163 | float s = 1.70158f; |
164 | t = t/d - 1; |
165 | return (c*(t*t*((s + 1)*t + s) + 1) + b); |
166 | } |
167 | |
168 | EASEDEF float EaseBackInOut(float t, float b, float c, float d) |
169 | { |
170 | float s = 1.70158f; |
171 | if ((t/=d/2) < 1) |
172 | { |
173 | s *= 1.525f; |
174 | return (c/2*(t*t*((s + 1)*t - s)) + b); |
175 | } |
176 | |
177 | float postFix = t-=2; |
178 | s *= 1.525f; |
179 | return (c/2*((postFix)*t*((s + 1)*t + s) + 2) + b); |
180 | } |
181 | |
182 | // Bounce Easing functions |
183 | EASEDEF float EaseBounceOut(float t, float b, float c, float d) |
184 | { |
185 | if ((t/=d) < (1/2.75f)) |
186 | { |
187 | return (c*(7.5625f*t*t) + b); |
188 | } |
189 | else if (t < (2/2.75f)) |
190 | { |
191 | float postFix = t-=(1.5f/2.75f); |
192 | return (c*(7.5625f*(postFix)*t + 0.75f) + b); |
193 | } |
194 | else if (t < (2.5/2.75)) |
195 | { |
196 | float postFix = t-=(2.25f/2.75f); |
197 | return (c*(7.5625f*(postFix)*t + 0.9375f) + b); |
198 | } |
199 | else |
200 | { |
201 | float postFix = t-=(2.625f/2.75f); |
202 | return (c*(7.5625f*(postFix)*t + 0.984375f) + b); |
203 | } |
204 | } |
205 | |
206 | EASEDEF float EaseBounceIn(float t, float b, float c, float d) { return (c - EaseBounceOut(d-t, 0, c, d) + b); } |
207 | EASEDEF float EaseBounceInOut(float t, float b, float c, float d) |
208 | { |
209 | if (t < d/2) return (EaseBounceIn(t*2, 0, c, d)*0.5f + b); |
210 | else return (EaseBounceOut(t*2-d, 0, c, d)*0.5f + c*0.5f + b); |
211 | } |
212 | |
213 | // Elastic Easing functions |
214 | EASEDEF float EaseElasticIn(float t, float b, float c, float d) |
215 | { |
216 | if (t == 0) return b; |
217 | if ((t/=d) == 1) return (b + c); |
218 | |
219 | float p = d*0.3f; |
220 | float a = c; |
221 | float s = p/4; |
222 | float postFix = a*pow(2, 10*(t-=1)); |
223 | |
224 | return (-(postFix*sin((t*d-s)*(2*PI)/p )) + b); |
225 | } |
226 | |
227 | EASEDEF float EaseElasticOut(float t, float b, float c, float d) |
228 | { |
229 | if (t == 0) return b; |
230 | if ((t/=d) == 1) return (b + c); |
231 | |
232 | float p = d*0.3f; |
233 | float a = c; |
234 | float s = p/4; |
235 | |
236 | return (a*pow(2,-10*t)*sin((t*d-s)*(2*PI)/p) + c + b); |
237 | } |
238 | |
239 | EASEDEF float EaseElasticInOut(float t, float b, float c, float d) |
240 | { |
241 | if (t == 0) return b; |
242 | if ((t/=d/2) == 2) return (b + c); |
243 | |
244 | float p = d*(0.3f*1.5f); |
245 | float a = c; |
246 | float s = p/4; |
247 | |
248 | if (t < 1) |
249 | { |
250 | float postFix = a*pow(2, 10*(t-=1)); |
251 | return -0.5f*(postFix*sin((t*d-s)*(2*PI)/p)) + b; |
252 | } |
253 | |
254 | float postFix = a*pow(2, -10*(t-=1)); |
255 | |
256 | return (postFix*sin((t*d-s)*(2*PI)/p)*0.5f + c + b); |
257 | } |
258 | |
259 | #ifdef __cplusplus |
260 | } |
261 | #endif |
262 | |
263 | #endif // EASINGS_H |
264 | |