]> Dogcows Code - chaz/yoink/blob - src/moof/interpolator.hh
937ca8a93f28ecda6d37eba8d258c0b6ff876a2d
[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 if (!is_done_)
99 {
100 alpha_ += dt * scale_;
101 prior_ = state_;
102 state_ = function_(a_, b_, alpha_);
103
104 if (alpha_ > 1.0)
105 {
106 switch (mode_)
107 {
108 case stop:
109 alpha_ = SCALAR(1.0);
110 is_done_ = true;
111 break;
112 case repeat:
113 alpha_ -= SCALAR(1.0);
114 break;
115 case oscillate:
116 alpha_ = SCALAR(2.0) - alpha_;
117 scale_ = -scale_;
118 break;
119 }
120 }
121 else if (alpha_ < 0.0)
122 {
123 switch (mode_)
124 {
125 case stop:
126 alpha_ = SCALAR(0.0);
127 is_done_ = true;
128 break;
129 case repeat:
130 alpha_ += SCALAR(1.0);
131 break;
132 case oscillate:
133 alpha_ = -alpha_;
134 scale_ = -scale_;
135 break;
136 }
137 }
138 }
139 }
140
141
142 /**
143 * Get the interpolated value.
144 * \return The interpolated value.
145 */
146 T state() const
147 {
148 return state_;
149 }
150
151 /**
152 * Get the interpolated value interpolated between two updates.
153 * \param alpha The fraction between updates.
154 * \return The interpolated value.
155 */
156 T state(scalar alpha) const
157 {
158 return lerp(prior_, state_, alpha);
159 }
160
161 /**
162 * Get whether or not the interpolation is done. This will only return
163 * true if the interpolation mode is stop.
164 * \return True if the interpolation has finished.
165 */
166 bool is_done() const
167 {
168 return is_done_;
169 }
170
171
172 private:
173
174 T state_;
175 T prior_;
176 T a_;
177 T b_;
178
179 F function_;
180
181 scalar alpha_;
182 scalar scale_;
183 mode mode_;
184 bool is_done_;
185 };
186
187
188 struct linear_interpolation_function
189 {
190 template <class T>
191 T operator () (const T& a, const T& b, scalar alpha)
192 {
193 return lerp(a, b, alpha);
194 }
195 };
196
197
198 typedef interpolator<linear_interpolation_function> lerp_scalar;
199
200
201 } // namespace moof
202
203 #endif // _MOOF_INTERPOLATOR_HH_
204
This page took 0.037895 seconds and 3 git commands to generate.