Documentation


morphingEngine.inl

Go to the documentation of this file.
00001 #ifndef MORPHING_ENGINE_INL
00002 #define MORPHING_ENGINE_INL
00003 
00004 #include <iostream>
00005 #include <GL/gl.h>
00006 
00007 #include "morphingEngine.h"
00008 #include <animal/linear.h>
00009 
00010 using std::cerr; using std::endl;
00011 
00012 namespace animal
00013 {
00014 
00016   template< class Morphings, class Real >
00017   MorphingEngine< Morphings, Real >
00018   ::MorphingEngine()
00019       : _positions(0)
00020       , _morphings(0)
00021       , _interpolationID(0)
00022       , _currentKey(0)
00023       , _initialKey(0)
00024       , _velocity(1.0)
00025   {}
00026 
00028   template< class Morphings, class Real >
00029   MorphingEngine< Morphings, Real >
00030   ::~MorphingEngine()
00031   {
00032     //std::cerr << " Destructeur() " << std::endl;
00033   }
00034 
00035   //===============================================================
00036   // Virtual methods
00037   //===============================================================
00038 
00040   template< class Morphings, class Real >
00041   void MorphingEngine< Morphings, Real >
00042   ::reset()
00043   {
00044     // Init the current key
00045     _currentKey = _initialKey ;
00046     if (_positions && _morphings )
00047       computeInterpolatedValues(_currentKey);
00048   }
00049 
00051   template< class Morphings, class Real >
00052   void MorphingEngine< Morphings, Real >
00053   ::move(double dt)
00054   {
00055     _currentKey += _velocity*dt;
00056     if (_positions && _morphings )
00057       computeInterpolatedValues(_currentKey);
00058   }
00059 
00060   //===============================================================
00061 
00063   template< class Morphings, class Real >
00064   void MorphingEngine< Morphings, Real >
00065   ::setCurrentKey(Key k)
00066   {
00067     _currentKey = k;
00068   }
00069 
00070 
00072   template< class Morphings, class Real >
00073   void MorphingEngine< Morphings, Real >
00074   ::toggleCatmullRomMethod(bool b)
00075   {
00076     if (b)
00077     {
00078       _interpolationID = 1;
00079     }
00080   }
00081 
00083   template< class Morphings, class Real >
00084   void MorphingEngine< Morphings, Real >
00085   ::toggleLinearMethod(bool b)
00086   {
00087     if (b)
00088     {
00089       _interpolationID = 0;
00090     }
00091   }
00092 
00093   //===============================================================
00094   // Methods to access to class members
00095   //===============================================================
00096 
00098   template< class Morphings, class Real >
00099   void MorphingEngine< Morphings, Real >
00100   ::printMorphings()
00101   {
00102     std::cerr << " Elements in the _morphings: " << std::endl;
00103     for (typename Morphings::iterator it = _morphings->begin();
00104          it != _morphings->end();
00105          ++it)
00106       std::cerr << "  [" << (*it).first << ", " << (*it).second << "]" << std::endl;
00107   }
00108 
00109 
00113   template< class Morphings, class Real >
00114   bool MorphingEngine< Morphings, Real >
00115   ::begin(Key & key)
00116   {
00117     typename Morphings::iterator it = _morphings->begin();
00118 
00119     if (_interpolationID == 0 &&  _morphings->size()>0)
00120     {
00121       key = (*it).first;
00122       return true;
00123     }
00124     else if (_interpolationID == 1 &&  _morphings->size()>1)
00125     {
00126       key = (*(++it)).first;
00127       return true;
00128     }
00129     else
00130       return false;
00131   }
00132 
00137   template< class Morphings, class Real >
00138   bool MorphingEngine< Morphings, Real >
00139   ::computeInterpolatedValues(Key key)
00140   {
00141     // Tmp values in order to not change interpolatedValues if the interpolation
00142     // doesn't work.
00143     //Values tmpValues;
00144 
00145     // Init valuesTmp in order it has the same size of values in _keyValues
00146     /*if (!(_morphings).empty())
00147       tmpValues = ((_morphings).begin())->second;
00148     else 
00149       return false;*/
00150 
00151     // Compute the interpolation and change interpolatedValues if it works
00152     if   (  (_interpolationID == 0 && computeLinearInterpolation(key))
00153             || (_interpolationID == 1 && computeCatmullRomInterpolation(key)))
00154     {
00155       return true;
00156     }
00157     else
00158       return false;
00159   }
00160 
00161   //===============================================================
00162   // Private Methods
00163   //===============================================================
00164 
00165 
00171   template< class Morphings, class Real >
00172   bool MorphingEngine< Morphings, Real >
00173   :: searchRange(const Key key, Key & key0, Key & key1)
00174   {
00175     if (_morphings->size()>=2)
00176     {
00177       typename Morphings::iterator it1 = _morphings->upper_bound(key);
00178 
00179       if (it1 == _morphings->begin())
00180       {
00181         //std::cerr <<" The key "<< key << " is too small."<< std::endl;
00182         return false;
00183       }
00184       else if (it1 == _morphings->end())
00185       {
00186         //std::cerr <<" The key "<< key << " is too big."<< std::endl;
00187         return false;
00188       }
00189       else
00190       {
00191         key1 = (*it1).first;
00192         typename Morphings::iterator it0 = it1;it0--;
00193         key0 = (*it0).first;
00194         //std::cerr<< " Range of the key "<< key << " : [" << key0
00195         //    << ", " << key1 << "]" << std::endl;
00196         return true;
00197       }
00198     }
00199     else
00200     {
00201       std::cerr<<" Warning: animal::MorphingEngine::searchRange() has failed." << std::endl;
00202       std::cerr<<"  The size of animal::MorphingEngine::_morphings is lesser than 2." << std::endl;
00203       return false;
00204     }
00205   }
00206 
00214   template< class Morphings, class Real >
00215   bool MorphingEngine< Morphings, Real >
00216   :: searchKeys(const Key key, Key & key0, Key & key1, Key & key2, Key & key3)
00217   {
00218     if (_morphings->size()>=4)
00219     {
00220       if (searchRange(key, key1, key2))
00221       {
00222         // Search key0
00223         typename Morphings::iterator it1 = _morphings->find(key1);
00224         if (it1 == _morphings->begin())
00225           return false;
00226         else
00227           key0 = (*(--it1)).first;
00228 
00229         // Search key3
00230         typename Morphings::iterator it2 =
00231           _morphings->find(key2);++it2;
00232         if (it2 == _morphings->end())
00233           return false;
00234         else
00235           key3 = (*it2).first;
00236 
00237         //std::cerr << " Keys for "<< key << " : "
00238         //<< key0 << ", " << key1 << ", " << key2 <<", " << key3 << std::endl;
00239 
00240         return true;
00241 
00242       }
00243       else
00244         return false;
00245     }
00246     else
00247     {
00248       std::cerr<<" Warning: animal::MorphingEngine::searchKeys() has failed." << std::endl;
00249       std::cerr<<"  The size of animal::MorphingEngine::_morphings is lesser than 4." << std::endl;
00250       return false;
00251     }
00252   }
00253 
00259   template< class Morphings, class Real >
00260   bool MorphingEngine< Morphings, Real >
00261   ::computeLinearInterpolation(const Key key)
00262   {
00263     Key key0, key1;
00264     bool successful;
00265 
00266     typename Morphings::iterator it = _morphings->end();--it;
00267     if ( _morphings->size()>0 && key == (*it).first ) // the key is the last one
00268     {
00269       successful = true;
00270       //interpolatedValues = _keyValues[key]
00271       v_eq(*(_positions), (*_morphings)[key]);
00272     }
00273     else if (successful = searchRange(key, key0, key1))
00274     {
00275       //std::cerr << " ComputeLinearInterpolation() " << std::endl;
00276       Real a = (Real)(key-key0)/(Real)(key1-key0);
00277 
00278       //interpolatedValues = (1-a)*_keyValues[key0]
00279       v_eq_ab(*(_positions), 1-a, (*_morphings)[key0]);
00280 
00281       //interpolatedValues += a*_keyValues[key1]
00282       v_peq_ab(*(_positions), a, (*_morphings)[key1]);
00283 
00284       //std::cerr << "  Interpolated values : "<< key0<<":["
00285       //    << _keyValues[key0] << "] and "<< key1<<":["
00286       //    << _keyValues[key1] << "]" << std::endl;
00287       //std::cerr << "  Result : ["<< interpolatedValues << "]" << std::endl;
00288     }
00289 
00290     return successful;
00291   }
00292 
00298   template< class Morphings, class Real >
00299   bool MorphingEngine< Morphings, Real >
00300   ::computeCatmullRomInterpolation(const Key key)
00301   {
00302     bool successful;
00303     Key key0, key1, key2, key3;
00304 
00305     typename Morphings::iterator it = _morphings->end();--it;--it;
00306     if ( _morphings->size()>=2 && key == (*it).first ) // the key is the last one
00307     {
00308       successful = true;
00309       //interpolatedValues = _keyValues[key]
00310       animal::v_eq(*(_positions), (*_morphings)[key]);
00311 
00312     }
00313     else if (successful = searchKeys(key, key0, key1, key2, key3))
00314     {
00315       //std::cerr << " ComputeCatmullRomInterpolation() " << std::endl;
00316 
00317       Real t = (Real)(key-key1)/(Real)(key2-key1);
00318 
00319       // Catmull Rom weighted functions
00320       Real a0, a1, a2, a3;
00321       a3 =    t*t*t -   t*t ;   a3 *= 0.5;
00322       a2 = -3*t*t*t + 4*t*t + t;  a2 *= 0.5;
00323       a1 = 3*  t*t*t - 5*t*t +  2;  a1 *= 0.5;
00324       a0 = -  t*t*t + 2*t*t - t;  a0 *= 0.5;
00325 
00326       //interpolatedValues = a0*_keyValues[key0]
00327       animal::v_eq_ab(*(_positions), a0, (*_morphings)[key0]);
00328 
00329       //interpolatedValues += a1*_keyValues[key1]
00330       animal::v_peq_ab(*(_positions), a1, (*_morphings)[key1]);
00331 
00332       //interpolatedValues += a2*_keyValues[key2]
00333       animal::v_peq_ab(*(_positions), a2, (*_morphings)[key2]);
00334 
00335       //interpolatedValues += a3*_keyValues[key3]
00336       animal::v_peq_ab(*(_positions), a3, (*_morphings)[key3]);
00337     }
00338 
00339     return successful;
00340   }
00341 
00342 
00343 }// animal
00344 
00345 #endif //MORPHING_ENGINE_INL

Generated on Thu Dec 23 13:52:26 2004 by doxygen 1.3.6