vee_interpolators.h

Go to the documentation of this file.
00001 /* -*- C++ -*- */
00002 
00003 /* COPYRIGHT
00004  *
00005  * This file is part of the Visual Effects Engine - VEE
00006  *
00007  * Read the "VEE-LICENSE" file for the license.
00008  *
00009  * Authors & Copyright:   
00010  *
00011  * Tommi Ilmonen, Tuukka Heikura, Marko Myllymaa and 
00012  * Janne Kontkanen 2001-2004
00013  *
00014  * Additional copyrights: Tekes 2003-2004
00015  *
00016  * firstname.lastname@hut.fi
00017  *
00018  */
00019 
00020 #ifndef VEE_INTERPOLATORS_H
00021 #define VEE_INTERPOLATORS_H
00022 
00023 #include <vector>
00024 
00025 #include <string.h>  // bzero for Linux
00026 #include <strings.h> // bzero for SGI
00027 
00030 template <typename T>
00031 class VEE_InterpolationPoint
00032 {
00033 public:
00034   VEE_InterpolationPoint() {}
00035 
00036   VEE_InterpolationPoint(const T &value, float time)
00037     : m_value(value), m_time(time) {}
00038 
00039   T     m_value;
00040   float m_time;
00041 };
00042 
00045 template <typename T>
00046 class VEE_LinearInterpolation
00047 {
00048 public:
00049   VEE_LinearInterpolation() : m_index(0) {}
00050   ~VEE_LinearInterpolation() {}
00051 
00053   void clear() { m_index = 0; m_points.resize(0); }
00054 
00056   inline T getValue(float t)
00057   {
00058     T res;
00059 
00060     seekInterval(t);
00061     
00062     if(m_index >= m_points.size()) {
00063       bzero(&res, sizeof(res));
00064       return res;
00065     }
00066 
00067     if(m_index + 1 == m_points.size()) {
00068       return m_points[m_index].m_value;
00069     }
00070 
00071     return interpolate(m_points[m_index], m_points[m_index + 1], t);  
00072   }
00073 
00076   inline T getValueBisect(float t) const
00077   {
00078     T res;
00079 
00080     if(!m_points.size()) {
00081       bzero(&res, sizeof(res));
00082       return res;      
00083     }
00084 
00085     uint higher = m_points.size() - 1;
00086     uint lower = 0;
00087 
00088     while(higher > lower + 1) {
00089       uint center = (higher + lower) >> 1;
00090       if(m_points[center].m_time > t)
00091   higher = center;
00092       else
00093   lower = center;
00094     }
00095     
00096     if(m_points[higher].m_time <= t)
00097       return m_points[higher].m_value;
00098 
00099     return interpolate(m_points[lower], m_points[higher], t); 
00100   }
00101 
00103   inline T getValueFast(float t)
00104   {
00105     T res;
00106 
00107     seekInterval(t);
00108     
00109     if(m_index >= m_points.size()) {
00110       bzero(&res, sizeof(res));
00111       return res;
00112     }
00113 
00114     return m_points[m_index].m_value;
00115   }
00116 
00118   void appendPoint(const T & v, float t)
00119   { 
00120     unsigned s = m_points.size();
00121     if(s) {
00122       if(m_points[s - 1].m_time == t) {
00123   m_points[s - 1].m_value = v;
00124   return;
00125       }
00126   
00127     }
00128     m_points.push_back(VEE_InterpolationPoint<T>(v, t)); 
00129   }
00130 
00131   bool atEnd() const 
00132   {
00133     if(!m_points.size())
00134       return true;
00135     return m_index + 1 >= m_points.size();
00136   }
00137 
00139   unsigned size() { return m_points.size(); }
00140 
00141   VEE_InterpolationPoint<T> & getPoint(uint i) { return m_points[i]; }
00142 
00144   static inline T interpolate(const VEE_InterpolationPoint<T> & p1, 
00145             const VEE_InterpolationPoint<T> & p2, 
00146             float t)
00147   { 
00148     float diff = p2.m_time - p1.m_time;
00149 
00150     if(diff < 1.0e-8)
00151       return p2.m_value;
00152 
00153     float mix  = (t - p1.m_time) / diff;
00154     return interpolate(p2.m_value, p1.m_value, mix);
00155   }
00156   
00161   static inline T interpolate(const T & v1, const T & v2, float mix)
00162   { return v1 * mix + v2 * (1.0 - mix); }
00163 
00164   float endTime() const 
00165   { return m_points.size() ? m_points[m_points.size()-1].m_time : 0.0f; }
00166 
00167   void moveTime(float offset)
00168   { for(uint i=0; i < m_points.size(); i++) m_points[i].m_time += offset; }
00169 
00170 protected:
00171 
00172   void seekInterval(float t)
00173   {
00174     unsigned n = m_points.size();
00175 
00176     while(m_index < n) {
00177 
00178       VEE_InterpolationPoint<T> *p = & m_points[m_index];
00179 
00180       if(p->m_time < t) {
00181   // Moving forward
00182 
00183   if(m_index + 1 >= n)  // At end
00184     return;
00185   if(m_points[m_index + 1].m_time < t) // Go forward
00186     m_index++;
00187   else // Found the correct interval
00188     return;
00189       }
00190       else if(p->m_time > t) {
00191   // Moving backward
00192   if(!m_index) return; // At beginning
00193   m_index--;
00194       }
00195       else // p->m_time == t
00196   return;
00197     }
00198   }
00199 
00200   std::vector<VEE_InterpolationPoint<T> > m_points;
00201   unsigned m_index;
00202 };
00203 
00204 /* template <>
00205 VEE_Matrix3 VEE_LinearInterpolation<VEE_Matrix3>::interpolate
00206 (const VEE_Matrix3 & v1, const VEE_Matrix3 & v2, float mix)
00207 {
00208   float xa1, ya1, za1;
00209   float xa2, ya2, za2;
00210   
00211   v1.getRotationXYZ(xa1, ya1, za1);
00212   v2.getRotationXYZ(xa2, ya2, za2);
00213   
00214   }*/
00215 
00218 
00219 template <typename T>
00220 class VEE_LinearInterpolation2 : public VEE_LinearInterpolation<T>
00221 {
00222 public:
00223   VEE_LinearInterpolation2() : m_time(0.0) {}
00224   ~VEE_LinearInterpolation2() {}
00225 
00226   void move(float dt) { m_time += dt; }
00227   void reset(float time = 0.0) 
00228   { m_time = time; m_index = 0; seekInterval(time); }
00229 
00230   float time() const { return m_time; }
00231   
00232   T getValue2() { return getValue(m_time); }
00233 
00234 protected:
00235   float m_time;
00236 };
00237 
00238 #endif

Generated on Mon Mar 12 21:09:00 2007 for VEE - The Visual Effects Engine by  doxygen 1.4.6