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