00001 00031 #ifndef LL_LLINTERP_H 00032 #define LL_LLINTERP_H 00033 00034 #include "math.h" 00035 00036 // Class from which different types of interpolators can be derived 00037 00038 class LLInterpVal 00039 { 00040 public: 00041 virtual ~LLInterpVal() {} 00042 virtual void interp(LLInterpVal &target, const F32 frac); // Linear interpolation for each type 00043 }; 00044 00045 template <typename Type> 00046 class LLInterp 00047 { 00048 public: 00049 LLInterp(); 00050 virtual ~LLInterp() {} 00051 00052 virtual void start(); 00053 void update(const F32 time); 00054 const Type &getCurVal() const; 00055 00056 void setStartVal(const Type &start_val); 00057 const Type &getStartVal() const; 00058 00059 void setEndVal(const Type &target_val); 00060 const Type &getEndVal() const; 00061 00062 void setStartTime(const F32 time); 00063 F32 getStartTime() const; 00064 00065 void setEndTime(const F32 time); 00066 F32 getEndTime() const; 00067 00068 BOOL isActive() const; 00069 BOOL isDone() const; 00070 00071 protected: 00072 F32 mStartTime; 00073 F32 mEndTime; 00074 F32 mDuration; 00075 BOOL mActive; 00076 BOOL mDone; 00077 00078 Type mStartVal; 00079 Type mEndVal; 00080 00081 F32 mCurTime; 00082 Type mCurVal; 00083 }; 00084 00085 template <typename Type> 00086 class LLInterpLinear : public LLInterp<Type> 00087 { 00088 public: 00089 /*virtual*/ void start(); 00090 void update(const F32 time); 00091 F32 getCurFrac() const; 00092 protected: 00093 F32 mCurFrac; 00094 }; 00095 00096 template <typename Type> 00097 class LLInterpExp : public LLInterpLinear<Type> 00098 { 00099 public: 00100 void update(const F32 time); 00101 protected: 00102 }; 00103 00104 template <typename Type> 00105 class LLInterpAttractor : public LLInterp<Type> 00106 { 00107 public: 00108 LLInterpAttractor(); 00109 /*virtual*/ void start(); 00110 void setStartVel(const Type &vel); 00111 void setForce(const F32 force); 00112 void update(const F32 time); 00113 protected: 00114 F32 mForce; 00115 Type mStartVel; 00116 Type mVelocity; 00117 }; 00118 00119 template <typename Type> 00120 class LLInterpFunc : public LLInterp<Type> 00121 { 00122 public: 00123 LLInterpFunc(); 00124 void update(const F32 time); 00125 00126 void setFunc(Type (*)(const F32, void *data), void *data); 00127 protected: 00128 Type (*mFunc)(const F32 time, void *data); 00129 void *mData; 00130 }; 00131 00132 00134 // 00135 // Implementation 00136 // 00137 // 00138 00140 // 00141 // LLInterp base class implementation 00142 // 00143 00144 template <typename Type> 00145 LLInterp<Type>::LLInterp() 00146 { 00147 mStartTime = 0.f; 00148 mEndTime = 1.f; 00149 mDuration = 1.f; 00150 mCurTime = 0.f; 00151 mDone = FALSE; 00152 mActive = FALSE; 00153 } 00154 00155 template <class Type> 00156 void LLInterp<Type>::setStartVal(const Type &start_val) 00157 { 00158 mStartVal = start_val; 00159 } 00160 00161 template <class Type> 00162 void LLInterp<Type>::start() 00163 { 00164 mCurVal = mStartVal; 00165 mCurTime = mStartTime; 00166 mDone = FALSE; 00167 mActive = FALSE; 00168 } 00169 00170 template <class Type> 00171 const Type &LLInterp<Type>::getStartVal() const 00172 { 00173 return mStartVal; 00174 } 00175 00176 template <class Type> 00177 void LLInterp<Type>::setEndVal(const Type &end_val) 00178 { 00179 mEndVal = end_val; 00180 } 00181 00182 template <class Type> 00183 const Type &LLInterp<Type>::getEndVal() const 00184 { 00185 return mEndVal; 00186 } 00187 00188 template <class Type> 00189 const Type &LLInterp<Type>::getCurVal() const 00190 { 00191 return mCurVal; 00192 } 00193 00194 00195 template <class Type> 00196 void LLInterp<Type>::setStartTime(const F32 start_time) 00197 { 00198 mStartTime = start_time; 00199 mDuration = mEndTime - mStartTime; 00200 } 00201 00202 template <class Type> 00203 F32 LLInterp<Type>::getStartTime() const 00204 { 00205 return mStartTime; 00206 } 00207 00208 00209 template <class Type> 00210 void LLInterp<Type>::setEndTime(const F32 end_time) 00211 { 00212 mEndTime = end_time; 00213 mDuration = mEndTime - mStartTime; 00214 } 00215 00216 00217 template <class Type> 00218 F32 LLInterp<Type>::getEndTime() const 00219 { 00220 return mEndTime; 00221 } 00222 00223 00224 template <class Type> 00225 BOOL LLInterp<Type>::isDone() const 00226 { 00227 return mDone; 00228 } 00229 00230 template <class Type> 00231 BOOL LLInterp<Type>::isActive() const 00232 { 00233 return mActive; 00234 } 00235 00237 // 00238 // LLInterpLinear derived class implementation. 00239 // 00240 template <typename Type> 00241 void LLInterpLinear<Type>::start() 00242 { 00243 LLInterp<Type>::start(); 00244 mCurFrac = 0.f; 00245 } 00246 00247 template <typename Type> 00248 void LLInterpLinear<Type>::update(const F32 time) 00249 { 00250 F32 target_frac = (time - this->mStartTime) / this->mDuration; 00251 F32 dfrac = target_frac - this->mCurFrac; 00252 if (target_frac >= 0.f) 00253 { 00254 this->mActive = TRUE; 00255 } 00256 00257 if (target_frac > 1.f) 00258 { 00259 this->mCurVal = this->mEndVal; 00260 this->mCurFrac = 1.f; 00261 this->mCurTime = time; 00262 this->mDone = TRUE; 00263 return; 00264 } 00265 00266 target_frac = llmin(1.f, target_frac); 00267 target_frac = llmax(0.f, target_frac); 00268 00269 if (dfrac >= 0.f) 00270 { 00271 F32 total_frac = 1.f - this->mCurFrac; 00272 F32 inc_frac = dfrac / total_frac; 00273 this->mCurVal = inc_frac * this->mEndVal + (1.f - inc_frac) * this->mCurVal; 00274 this->mCurTime = time; 00275 } 00276 else 00277 { 00278 F32 total_frac = this->mCurFrac - 1.f; 00279 F32 inc_frac = dfrac / total_frac; 00280 this->mCurVal = inc_frac * this->mStartVal + (1.f - inc_frac) * this->mCurVal; 00281 this->mCurTime = time; 00282 } 00283 mCurFrac = target_frac; 00284 } 00285 00286 template <class Type> 00287 F32 LLInterpLinear<Type>::getCurFrac() const 00288 { 00289 return mCurFrac; 00290 } 00291 00292 00294 // 00295 // LLInterpAttractor derived class implementation. 00296 // 00297 00298 00299 template <class Type> 00300 LLInterpAttractor<Type>::LLInterpAttractor() : LLInterp<Type>() 00301 { 00302 mForce = 0.1f; 00303 mVelocity *= 0.f; 00304 mStartVel *= 0.f; 00305 } 00306 00307 template <class Type> 00308 void LLInterpAttractor<Type>::start() 00309 { 00310 LLInterp<Type>::start(); 00311 mVelocity = mStartVel; 00312 } 00313 00314 00315 template <class Type> 00316 void LLInterpAttractor<Type>::setStartVel(const Type &vel) 00317 { 00318 mStartVel = vel; 00319 } 00320 00321 template <class Type> 00322 void LLInterpAttractor<Type>::setForce(const F32 force) 00323 { 00324 mForce = force; 00325 } 00326 00327 template <class Type> 00328 void LLInterpAttractor<Type>::update(const F32 time) 00329 { 00330 if (time > this->mStartTime) 00331 { 00332 this->mActive = TRUE; 00333 } 00334 else 00335 { 00336 return; 00337 } 00338 if (time > this->mEndTime) 00339 { 00340 this->mDone = TRUE; 00341 return; 00342 } 00343 00344 F32 dt = time - this->mCurTime; 00345 Type dist_val = this->mEndVal - this->mCurVal; 00346 Type dv = 0.5*dt*dt*this->mForce*dist_val; 00347 this->mVelocity += dv; 00348 this->mCurVal += this->mVelocity * dt; 00349 this->mCurTime = time; 00350 } 00351 00352 00354 // 00355 // LLInterpFucn derived class implementation. 00356 // 00357 00358 00359 template <class Type> 00360 LLInterpFunc<Type>::LLInterpFunc() : LLInterp<Type>() 00361 { 00362 mFunc = NULL; 00363 mData = NULL; 00364 } 00365 00366 template <class Type> 00367 void LLInterpFunc<Type>::setFunc(Type (*func)(const F32, void *data), void *data) 00368 { 00369 mFunc = func; 00370 mData = data; 00371 } 00372 00373 template <class Type> 00374 void LLInterpFunc<Type>::update(const F32 time) 00375 { 00376 if (time > this->mStartTime) 00377 { 00378 this->mActive = TRUE; 00379 } 00380 else 00381 { 00382 return; 00383 } 00384 if (time > this->mEndTime) 00385 { 00386 this->mDone = TRUE; 00387 return; 00388 } 00389 00390 this->mCurVal = (*mFunc)(time - this->mStartTime, mData); 00391 this->mCurTime = time; 00392 } 00393 00395 // 00396 // LLInterpExp derived class implementation. 00397 // 00398 00399 template <class Type> 00400 void LLInterpExp<Type>::update(const F32 time) 00401 { 00402 F32 target_frac = (time - this->mStartTime) / this->mDuration; 00403 if (target_frac >= 0.f) 00404 { 00405 this->mActive = TRUE; 00406 } 00407 00408 if (target_frac > 1.f) 00409 { 00410 this->mCurVal = this->mEndVal; 00411 this->mCurFrac = 1.f; 00412 this->mCurTime = time; 00413 this->mDone = TRUE; 00414 return; 00415 } 00416 00417 this->mCurFrac = 1.f - (F32)(exp(-2.f*target_frac)); 00418 this->mCurVal = this->mStartVal + this->mCurFrac * (this->mEndVal - this->mStartVal); 00419 this->mCurTime = time; 00420 } 00421 00422 #endif // LL_LLINTERP_H 00423