Pioneer
Loading...
Searching...
No Matches
AnimationCurves.h
Go to the documentation of this file.
1// Copyright © 2008-2023 Pioneer Developers. See AUTHORS.txt for details
2// Licensed under the terms of the GPL v3. See licenses/GPL-3.txt
3
4#ifndef ANIMATIONCURVES_H
5#define ANIMATIONCURVES_H
6
7#include "FloatComparison.h"
8#include <cmath>
9
10namespace AnimationCurves {
11
12 // Animates a value with "approach style" over time (zooming).
13 // The speeds must be positive. Function will not go further than target.
14 template <class T>
15 inline void Approach(T &cur, const T target, float frameTime, const T exponentialFactor = 10, T linearFactor = 1)
16 {
17 //static_assert(static_cast<T>(-1) <0); // Assert type is signed
18 if (frameTime > 1) frameTime = 1; // Clamp in case game hangs for a second
19 assert(exponentialFactor >= 0 && linearFactor >= 0);
20 if (is_equal_exact(target, cur))
21 return;
22 const T delta(target - cur);
23 if (delta < 0) linearFactor = -linearFactor;
24 cur += (delta * exponentialFactor + linearFactor) * frameTime;
25 // clamp to target (independent of the direction of motion)
26 const T newDelta(target - cur);
27 if (newDelta * delta < 0) cur = target;
28 }
29
30 // easing from https://github.com/Michaelangel007/easing#tldr-shut-up-and-show-me-the-code
31 // p should go from 0.0 to 1.0
32 inline float InOutQuadraticEasing(float p)
33 {
34 float m = p - 1.0;
35 float t = p * 2.0;
36 if (t < 1)
37 return p * t;
38 else
39 return 1.0 - m * m * 2.0;
40 }
41
42 // easing from https://github.com/Michaelangel007/easing#tldr-shut-up-and-show-me-the-code
43 // p should go from 0.0 to 1.0
44 inline float InOutCubicEasing(float p)
45 {
46 float m = p - 1.0;
47 float t = p * 2.0;
48 if (t < 1)
49 return p * t * t;
50 else
51 return 1.0 + m * m * m * 4.0;
52 }
53
54 // easing from https://github.com/Michaelangel007/easing#tldr-shut-up-and-show-me-the-code
55 // p should go from 0.0 to 1.0
56 inline float InOutSineEasing(float p)
57 {
58 return 0.5 * (1.0 - std::cos(p * M_PI));
59 }
60
61 // Based on http://blog.moagrius.com/actionscript/jsas-understanding-easing/
62 // and observations from Godot Engine and Star Citizen
63 // This supports four different easing functions encoded in a single float:
64 // e == 1.0|-1.0: linear easing, returns p
65 // e > 1.0: in-quadratic, in-cubic etc. for e = 2.0, e = 3.0 ...
66 // e < 1.0: out-quadratic, out-cubic etc. for e = 0.5, e = 0.33_ ...
67 // e == 0.0: returns zero
68 // e > -1.0: reverse inout-quadratic, inout-cubic for e = -0.5, e = -0.33_ ...
69 // e < -1.0: inout-quadratic, inout-cubic etc. for e = -2.0, e = -3.0 ...
70 inline float SmoothEasing(double p, double e)
71 {
72 // e > 0.0 = ease in or out / e < 0.0 = ease in-out
73 if (e > 0.0) {
74 // e < 1.0 = ease out / e > 1.0 = ease in
75 return e < 1.0 ? (1.0 - pow(1.0 - p, 1.0 / e)) : (pow(p, e));
76 } else if (e < 0) {
77 // Ease in-out at arbirary exponents (the e term is negated to get positive exponent)
78 float m = (p - 0.5) * 2.0;
79 float t = p * 2.0;
80 if (t < 1)
81 return pow(t, -e) * 0.5;
82 else
83 return (1.0 - pow(1.0 - m, -e)) * 0.5 + 0.5;
84 } else // completely flat at 0.0
85 return 0.0;
86 }
87
88} // namespace AnimationCurves
89
90#endif
bool is_equal_exact(float a, float b)
Definition FloatComparison.h:112
Definition AnimationCurves.h:10
float InOutQuadraticEasing(float p)
Definition AnimationCurves.h:32
float InOutSineEasing(float p)
Definition AnimationCurves.h:56
float SmoothEasing(double p, double e)
Definition AnimationCurves.h:70
float InOutCubicEasing(float p)
Definition AnimationCurves.h:44
void Approach(T &cur, const T target, float frameTime, const T exponentialFactor=10, T linearFactor=1)
Definition AnimationCurves.h:15