llinterp.h

Go to the documentation of this file.
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 

Generated on Thu Jul 1 06:08:44 2010 for Second Life Viewer by  doxygen 1.4.7