]> Dogcows Code - chaz/yoink/blob - src/Moof/Interpolator.hh
cleaned up interpolator classes
[chaz/yoink] / src / Moof / Interpolator.hh
1
2 /*******************************************************************************
3
4 Copyright (c) 2009, Charles McGarvey
5 All rights reserved.
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9
10 * Redistributions of source code must retain the above copyright notice,
11 this list of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above copyright notice,
13 this list of conditions and the following disclaimer in the documentation
14 and/or other materials provided with the distribution.
15
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
20 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27 *******************************************************************************/
28
29 #ifndef _MOOF_INTERPOLATOR_HH_
30 #define _MOOF_INTERPOLATOR_HH_
31
32 #include <Moof/Log.hh>
33 #include <Moof/Math.hh>
34
35
36 namespace Mf {
37
38
39 namespace Interp {
40
41 typedef enum
42 {
43 STOP = 0,
44 REPEAT = 1,
45 OSCILLATE = 2
46 } Mode;
47
48 } // namespace Interp
49
50
51 template <class T>
52 class Interpolator : public T
53 {
54 public:
55
56 Interpolator(Scalar t = 1.0, Interp::Mode mode = Interp::STOP)
57 {
58 reset(t, mode);
59 }
60
61 void reset(Scalar t = 1.0, Interp::Mode mode = Interp::STOP)
62 {
63 mAlpha = 0.0;
64 mScale = 1.0 / t;
65 mMode = mode;
66 mIsDone = false;
67 }
68
69 void update(Scalar t, Scalar dt)
70 {
71 if (!mIsDone)
72 {
73 mPrevState = T::getValue();
74 mAlpha += dt * mScale;
75 clamp();
76 if (mPrevState == T::calculate(mAlpha)) mIsDone = true;
77 }
78 }
79
80 typename T::Type getState(Scalar alpha) const
81 {
82 return cml::lerp(mPrevState, T::getValue(), alpha);
83 }
84
85 bool isDone() const
86 {
87 return mIsDone;
88 }
89
90 private:
91
92 void clamp()
93 {
94 if (mAlpha > 1.0)
95 {
96 switch (mMode)
97 {
98 case Interp::STOP:
99 mAlpha = SCALAR(1.0);
100 break;
101 case Interp::REPEAT:
102 mAlpha -= SCALAR(1.0);
103 break;
104 case Interp::OSCILLATE:
105 mAlpha = SCALAR(2.0) - mAlpha;
106 mScale = -mScale;
107 break;
108 }
109 }
110 else if (mAlpha < 0.0)
111 {
112 switch (mMode)
113 {
114 case Interp::STOP:
115 mAlpha = SCALAR(0.0);
116 break;
117 case Interp::REPEAT:
118 mAlpha += SCALAR(1.0);
119 break;
120 case Interp::OSCILLATE:
121 mAlpha = -mAlpha;
122 mScale = -mScale;
123 break;
124 }
125 }
126 }
127
128 Scalar mAlpha;
129 Scalar mScale;
130 Interp::Mode mMode;
131 bool mIsDone;
132
133 typename T::Type mPrevState;
134 };
135
136
137 template <typename T = Scalar>
138 class Linear
139 {
140 public:
141
142 typedef T Type;
143
144 void init(const Type& a, const Type& b)
145 {
146 mStart = a;
147 mFinish = b;
148 }
149
150 const Type& calculate(Scalar alpha)
151 {
152 mState = cml::lerp(mStart, mFinish, alpha);
153 return mState;
154 }
155
156 const Type& getValue() const
157 {
158 return mState;
159 }
160
161 private:
162
163 Type mState;
164 Type mStart;
165 Type mFinish;
166 };
167
168
169 typedef Interpolator< Linear<Scalar> > Lerp;
170
171
172 } // namespace Mf
173
174 #endif // _MOOF_INTERPOLATOR_HH_
175
176 /** vim: set ts=4 sw=4 tw=80: *************************************************/
177
This page took 0.039928 seconds and 5 git commands to generate.