]> Dogcows Code - chaz/yoink/blob - src/moof/interpolator.hh
0a7aa012b480747e69c7e3577c1c6f3c8546f9f8
[chaz/yoink] / src / moof / interpolator.hh
1
2 /*] Copyright (c) 2009-2010, Charles McGarvey [**************************
3 **] All rights reserved.
4 *
5 * vi:ts=4 sw=4 tw=75
6 *
7 * Distributable under the terms and conditions of the 2-clause BSD license;
8 * see the file COPYING for a complete text of the license.
9 *
10 **************************************************************************/
11
12 #ifndef _MOOF_INTERPOLATOR_HH_
13 #define _MOOF_INTERPOLATOR_HH_
14
15 /**
16 * \file interpolator.hh
17 * Functions and classes concerning interpolations between values.
18 */
19
20 #include <moof/math.hh>
21
22
23 namespace moof {
24
25
26 /**
27 * Interpolators should inherit from this base class to get some free
28 * functionality. Subclasses of this base class will implement their own
29 * interpolation functions.
30 */
31 template <class F, class T = scalar>
32 class interpolator
33 {
34 public:
35
36 /**
37 * Interpolation mode.
38 */
39 enum mode
40 {
41 stop = 0, /// Interpolator will stop when done.
42 repeat = 1, /// Interpolator will go back to the beginning.
43 oscillate = 2 /// Interpolator will reverse direction.
44 };
45
46
47 /**
48 * Construct an uninitialized interpolator.
49 */
50 interpolator() :
51 is_done_(true) {}
52
53 /**
54 * Construct an interpolator.
55 * \param a The initial value.
56 * \param b The target value.
57 * \param t The duration of the interpolation.
58 * \param mode The interpolation mode.
59 */
60 interpolator(const T& a, const T& b, scalar t = 1.0, mode mode = stop) :
61 state_(a),
62 prior_(a),
63 a_(a),
64 b_(b),
65 alpha_(SCALAR(0.0)),
66 scale_(SCALAR(1.0) / t),
67 mode_(mode),
68 is_done_(false) {}
69
70 /**
71 * Initialize the interpolator. Any interpolation already being
72 * tracked by this object will be replaced with a new interpolation
73 * based on the initialization arguments.
74 * \param a The initial value.
75 * \param b The target value.
76 * \param t The duration of the interpolation.
77 * \param mode The interpolation mode.
78 */
79 void init(const T& a, const T& b, scalar t = 1.0, mode mode = stop)
80 {
81 a_ = a;
82 b_ = b;
83 alpha_ = 0.0;
84 scale_ = 1.0 / t;
85 mode_ = mode;
86 is_done_ = false;
87 }
88
89
90 /**
91 * Update the interpolation state with a timeslice.
92 * \param t The total time in seconds.
93 * \param dt The number of seconds passed since the last call to
94 * update.
95 */
96 void update(scalar t, scalar dt)
97 {
98 prior_ = state_;
99
100 if (!is_done_)
101 {
102 alpha_ += dt * scale_;
103 if (alpha_ > 1.0)
104 {
105 switch (mode_)
106 {
107 case stop:
108 alpha_ = SCALAR(1.0);
109 is_done_ = true;
110 break;
111 case repeat:
112 alpha_ -= SCALAR(1.0);
113 break;
114 case oscillate:
115 alpha_ = SCALAR(2.0) - alpha_;
116 scale_ = -scale_;
117 break;
118 }
119 }
120 else if (alpha_ < 0.0)
121 {
122 switch (mode_)
123 {
124 case stop:
125 alpha_ = SCALAR(0.0);
126 is_done_ = true;
127 break;
128 case repeat:
129 alpha_ += SCALAR(1.0);
130 break;
131 case oscillate:
132 alpha_ = -alpha_;
133 scale_ = -scale_;
134 break;
135 }
136 }
137
138 state_ = function_(a_, b_, alpha_);
139 }
140 }
141
142
143 /**
144 * Get the interpolated value.
145 * \return The interpolated value.
146 */
147 T state() const
148 {
149 return state_;
150 }
151
152 /**
153 * Get the interpolated value interpolated between two updates.
154 * \param alpha The fraction between updates.
155 * \return The interpolated value.
156 */
157 T state(scalar alpha) const
158 {
159 return lerp(prior_, state_, alpha);
160 }
161
162 /**
163 * Get whether or not the interpolation is done. This will only return
164 * true if the interpolation mode is stop.
165 * \return True if the interpolation has finished.
166 */
167 bool is_done() const
168 {
169 return is_done_;
170 }
171
172
173 private:
174
175 T state_;
176 T prior_;
177 T a_;
178 T b_;
179
180 F function_;
181
182 scalar alpha_;
183 scalar scale_;
184 mode mode_;
185 bool is_done_;
186 };
187
188
189 struct linear_interpolation_function
190 {
191 template <class T>
192 T operator () (const T& a, const T& b, scalar alpha)
193 {
194 return lerp(a, b, alpha);
195 }
196 };
197
198
199 typedef interpolator<linear_interpolation_function> lerp_scalar;
200
201
202 } // namespace moof
203
204 #endif // _MOOF_INTERPOLATOR_HH_
205
This page took 0.0363790000000001 seconds and 3 git commands to generate.