home *** CD-ROM | disk | FTP | other *** search
/ GameStar 2006 March / Gamestar_82_2006-03_dvd.iso / DVDStar / Editace / quake4_sdkv10.exe / source / idlib / math / Interpolate.h < prev    next >
C/C++ Source or Header  |  2005-11-14  |  15KB  |  467 lines

  1.  
  2. #ifndef __MATH_INTERPOLATE_H__
  3. #define __MATH_INTERPOLATE_H__
  4.  
  5. /*
  6. ==============================================================================================
  7.  
  8.     Linear interpolation.
  9.  
  10. ==============================================================================================
  11. */
  12.  
  13. template< class type >
  14. class idInterpolate {
  15. public:
  16.                         idInterpolate();
  17.  
  18.     void                Init( const float startTime, const float duration, const type &startValue, const type &endValue );
  19.     void                SetStartTime( float time ) { this->startTime = time; }
  20.     void                SetDuration( float duration ) { this->duration = duration; }
  21.     void                SetStartValue( const type &startValue ) { this->startValue = startValue; }
  22.     void                SetEndValue( const type &endValue ) { this->endValue = endValue; }
  23.  
  24. // RAVEN BEGIN
  25. // abahr: made virtual
  26.     virtual type        GetCurrentValue( float time ) const;
  27.     virtual type        GetDeltaValue( float startTime, float endTime ) const;
  28. // RAVEN END
  29.     bool                IsDone( float time ) const { return ( time >= startTime + duration ); }
  30.  
  31.     float                GetStartTime( void ) const { return startTime; }
  32.     float                GetEndTime( void ) const { return startTime + duration; }
  33.     float                GetDuration( void ) const { return duration; }
  34.     const type &        GetStartValue( void ) const { return startValue; }
  35.     const type &        GetEndValue( void ) const { return endValue; }
  36.  
  37. // RAVEN BEGIN
  38. // abahr: changed to protected
  39. protected:
  40. // RAVEN END
  41.     float                startTime;
  42.     float                duration;
  43.     type                startValue;
  44.     type                endValue;
  45.     mutable float        currentTime;
  46.     mutable type        currentValue;
  47. };
  48.  
  49. /*
  50. ====================
  51. idInterpolate::idInterpolate
  52. ====================
  53. */
  54. template< class type >
  55. ID_INLINE idInterpolate<type>::idInterpolate() {
  56.     currentTime = startTime = duration = 0;
  57.     memset( ¤tValue, 0, sizeof( currentValue ) );
  58.     startValue = endValue = currentValue;
  59. }
  60.  
  61. /*
  62. ====================
  63. idInterpolate::Init
  64. ====================
  65. */
  66. template< class type >
  67. ID_INLINE void idInterpolate<type>::Init( const float startTime, const float duration, const type &startValue, const type &endValue ) {
  68.     this->startTime = startTime;
  69.     this->duration = duration;
  70.     this->startValue = startValue;
  71.     this->endValue = endValue;
  72.     this->currentTime = startTime - 1;
  73.     this->currentValue = startValue;
  74. }
  75.  
  76. /*
  77. ====================
  78. idInterpolate::GetCurrentValue
  79. ====================
  80. */
  81. template< class type >
  82. ID_INLINE type idInterpolate<type>::GetCurrentValue( float time ) const {
  83.     float deltaTime;
  84.  
  85.     deltaTime = time - startTime;
  86.     if ( time != currentTime ) {
  87.         currentTime = time;
  88.         if ( deltaTime <= 0 ) {
  89.             currentValue = startValue;
  90.         } else if ( deltaTime >= duration ) {
  91.             currentValue = endValue;
  92.         } else {
  93.             currentValue = startValue + ( endValue - startValue ) * ( (float) deltaTime / duration );
  94.         }
  95.     }
  96.     return currentValue;
  97. }
  98.  
  99. // RAVEN BEGIN
  100. // abahr
  101. /*
  102. ====================
  103. idInterpolate::GetDeltaValue
  104. ====================
  105. */
  106. template< class type >
  107. ID_INLINE type idInterpolate<type>::GetDeltaValue( float startTime, float endTime ) const {
  108.     return GetCurrentValue(endTime) - GetCurrentValue(startTime);
  109. }
  110.  
  111. ID_INLINE float Linear( float frac ) {
  112.     return frac;
  113. }
  114.  
  115. ID_INLINE float SinusoidalMidPoint( float frac ) {
  116.     return idMath::Sin( DEG2RAD(idMath::MidPointLerp(0.0f, 60.0f, 90.0f, frac)) ); 
  117. }
  118.  
  119. /*
  120. ==============================================================================================
  121.  
  122.     Spherical interpolation.
  123.  
  124. ==============================================================================================
  125. */
  126. typedef float (*TimeManipFunc) ( float );
  127. class rvSphericalInterpolate : public idInterpolate<idQuat> {
  128. public:
  129.                         rvSphericalInterpolate();
  130.     virtual idQuat        GetCurrentValue( float time ) const;
  131.  
  132.     void                SetTimeFunction( TimeManipFunc func ) { timeFunc = func; }
  133.  
  134. protected:
  135.     TimeManipFunc        timeFunc;
  136. };
  137.  
  138. /*
  139. ====================
  140. rvSphericalInterpolate::rvSphericalInterpolate
  141. ====================
  142. */
  143. ID_INLINE rvSphericalInterpolate::rvSphericalInterpolate() :
  144.     idInterpolate<idQuat>() {
  145.     SetTimeFunction( SinusoidalMidPoint );
  146. }
  147.  
  148. /*
  149. ====================
  150. rvSphericalInterpolate::GetCurrentValue
  151. ====================
  152. */
  153. ID_INLINE idQuat rvSphericalInterpolate::GetCurrentValue( float time ) const {
  154.     float deltaTime;
  155.  
  156.     deltaTime = time - startTime;
  157.     if ( time != currentTime ) {
  158.         currentTime = time;
  159.         if( duration == 0.0f ) {
  160.             currentValue = endValue;
  161.         } else {
  162.             currentValue.Slerp( startValue, endValue, timeFunc((float)deltaTime / duration) );
  163.         }
  164.     }
  165.     return currentValue;
  166. }
  167. // RAVEN END
  168.  
  169. /*
  170. ==============================================================================================
  171.  
  172.     Continuous interpolation with linear acceleration and deceleration phase.
  173.     The velocity is continuous but the acceleration is not.
  174.  
  175. ==============================================================================================
  176. */
  177.  
  178. template< class type >
  179. class idInterpolateAccelDecelLinear  {
  180. public:
  181.                         idInterpolateAccelDecelLinear();
  182.  
  183.     void                Init( const float startTime, const float accelTime, const float decelTime, const float duration, const type &startValue, const type &endValue );
  184.     void                SetStartTime( float time ) { startTime = time; Invalidate(); }
  185.     void                SetStartValue( const type &startValue ) { this->startValue = startValue; Invalidate(); }
  186.     void                SetEndValue( const type &endValue ) { this->endValue = endValue; Invalidate(); }
  187.  
  188.     type                GetCurrentValue( float time ) const;
  189.     type                GetCurrentSpeed( float time ) const;
  190.     bool                IsDone( float time ) const { return ( time >= startTime + accelTime + linearTime + decelTime ); }
  191.  
  192.     float                GetStartTime( void ) const { return startTime; }
  193.     float                GetEndTime( void ) const { return startTime + accelTime + linearTime + decelTime; }
  194.     float                GetDuration( void ) const { return accelTime + linearTime + decelTime; }
  195.     float                GetAcceleration( void ) const { return accelTime; }
  196.     float                GetDeceleration( void ) const { return decelTime; }
  197.     const type &        GetStartValue( void ) const { return startValue; }
  198.     const type &        GetEndValue( void ) const { return endValue; }
  199.  
  200. private:
  201.     float                startTime;
  202.     float                accelTime;
  203.     float                linearTime;
  204.     float                decelTime;
  205.     type                startValue;
  206.     type                endValue;
  207.     mutable idExtrapolate<type> extrapolate;
  208.  
  209.     void                Invalidate( void );
  210.     void                SetPhase( float time ) const;
  211. };
  212.  
  213. /*
  214. ====================
  215. idInterpolateAccelDecelLinear::idInterpolateAccelDecelLinear
  216. ====================
  217. */
  218. template< class type >
  219. ID_INLINE idInterpolateAccelDecelLinear<type>::idInterpolateAccelDecelLinear() {
  220.     startTime = accelTime = linearTime = decelTime = 0;
  221.     memset( &startValue, 0, sizeof( startValue ) );
  222.     endValue = startValue;
  223. }
  224.  
  225. /*
  226. ====================
  227. idInterpolateAccelDecelLinear::Init
  228. ====================
  229. */
  230. template< class type >
  231. ID_INLINE void idInterpolateAccelDecelLinear<type>::Init( const float startTime, const float accelTime, const float decelTime, const float duration, const type &startValue, const type &endValue ) {
  232.     type speed;
  233.  
  234.     this->startTime = startTime;
  235.     this->accelTime = accelTime;
  236.     this->decelTime = decelTime;
  237.     this->startValue = startValue;
  238.     this->endValue = endValue;
  239.  
  240.     if ( duration <= 0.0f ) {
  241.         return;
  242.     }
  243.  
  244.     if ( this->accelTime + this->decelTime > duration ) {
  245.         this->accelTime = this->accelTime * duration / ( this->accelTime + this->decelTime );
  246.         this->decelTime = duration - this->accelTime;
  247.     }
  248.     this->linearTime = duration - this->accelTime - this->decelTime;
  249.     speed = ( endValue - startValue ) * ( 1000.0f / ( (float) this->linearTime + ( this->accelTime + this->decelTime ) * 0.5f ) );
  250.  
  251.     if ( this->accelTime ) {
  252.         extrapolate.Init( startTime, this->accelTime, startValue, ( startValue - startValue ), speed, EXTRAPOLATION_ACCELLINEAR );
  253.     } else if ( this->linearTime ) {
  254.         extrapolate.Init( startTime, this->linearTime, startValue, ( startValue - startValue ), speed, EXTRAPOLATION_LINEAR );
  255.     } else {
  256.         extrapolate.Init( startTime, this->decelTime, startValue, ( startValue - startValue ), speed, EXTRAPOLATION_DECELLINEAR );
  257.     }
  258. }
  259.  
  260. /*
  261. ====================
  262. idInterpolateAccelDecelLinear::Invalidate
  263. ====================
  264. */
  265. template< class type >
  266. ID_INLINE void idInterpolateAccelDecelLinear<type>::Invalidate( void ) {
  267.     extrapolate.Init( 0, 0, extrapolate.GetStartValue(), extrapolate.GetBaseSpeed(), extrapolate.GetSpeed(), EXTRAPOLATION_NONE );
  268. }
  269.  
  270. /*
  271. ====================
  272. idInterpolateAccelDecelLinear::SetPhase
  273. ====================
  274. */
  275. template< class type >
  276. ID_INLINE void idInterpolateAccelDecelLinear<type>::SetPhase( float time ) const {
  277.     float deltaTime;
  278.  
  279.     deltaTime = time - startTime;
  280.     if ( deltaTime < accelTime ) {
  281.         if ( extrapolate.GetExtrapolationType() != EXTRAPOLATION_ACCELLINEAR ) {
  282.             extrapolate.Init( startTime, accelTime, startValue, extrapolate.GetBaseSpeed(), extrapolate.GetSpeed(), EXTRAPOLATION_ACCELLINEAR );
  283.         }
  284.     } else if ( deltaTime < accelTime + linearTime ) {
  285.         if ( extrapolate.GetExtrapolationType() != EXTRAPOLATION_LINEAR ) {
  286.             extrapolate.Init( startTime + accelTime, linearTime, startValue + extrapolate.GetSpeed() * ( accelTime * 0.001f * 0.5f ), extrapolate.GetBaseSpeed(), extrapolate.GetSpeed(), EXTRAPOLATION_LINEAR );
  287.         }
  288.     } else {
  289.         if ( extrapolate.GetExtrapolationType() != EXTRAPOLATION_DECELLINEAR ) {
  290.             extrapolate.Init( startTime + accelTime + linearTime, decelTime, endValue - ( extrapolate.GetSpeed() * ( decelTime * 0.001f * 0.5f ) ), extrapolate.GetBaseSpeed(), extrapolate.GetSpeed(), EXTRAPOLATION_DECELLINEAR );
  291.         }
  292.     }
  293. }
  294.  
  295. /*
  296. ====================
  297. idInterpolateAccelDecelLinear::GetCurrentValue
  298. ====================
  299. */
  300. template< class type >
  301. ID_INLINE type idInterpolateAccelDecelLinear<type>::GetCurrentValue( float time ) const {
  302.     SetPhase( time );
  303.     return extrapolate.GetCurrentValue( time );
  304. }
  305.  
  306. /*
  307. ====================
  308. idInterpolateAccelDecelLinear::GetCurrentSpeed
  309. ====================
  310. */
  311. template< class type >
  312. ID_INLINE type idInterpolateAccelDecelLinear<type>::GetCurrentSpeed( float time ) const {
  313.     SetPhase( time );
  314.     return extrapolate.GetCurrentSpeed( time );
  315. }
  316.  
  317.  
  318. /*
  319. ==============================================================================================
  320.  
  321.     Continuous interpolation with sinusoidal acceleration and deceleration phase.
  322.     Both the velocity and acceleration are continuous.
  323.  
  324. ==============================================================================================
  325. */
  326.  
  327. template< class type >
  328. class idInterpolateAccelDecelSine  {
  329. public:
  330.                         idInterpolateAccelDecelSine();
  331.  
  332.     void                Init( const float startTime, const float accelTime, const float decelTime, const float duration, const type &startValue, const type &endValue );
  333.     void                SetStartTime( float time ) { startTime = time; Invalidate(); }
  334.     void                SetStartValue( const type &startValue ) { this->startValue = startValue; Invalidate(); }
  335.     void                SetEndValue( const type &endValue ) { this->endValue = endValue; Invalidate(); }
  336.  
  337.     type                GetCurrentValue( float time ) const;
  338.     type                GetCurrentSpeed( float time ) const;
  339.     bool                IsDone( float time ) const { return ( time >= startTime + accelTime + linearTime + decelTime ); }
  340.  
  341.     float                GetStartTime( void ) const { return startTime; }
  342.     float                GetEndTime( void ) const { return startTime + accelTime + linearTime + decelTime; }
  343.     float                GetDuration( void ) const { return accelTime + linearTime + decelTime; }
  344.     float                GetAcceleration( void ) const { return accelTime; }
  345.     float                GetDeceleration( void ) const { return decelTime; }
  346.     const type &        GetStartValue( void ) const { return startValue; }
  347.     const type &        GetEndValue( void ) const { return endValue; }
  348.  
  349. private:
  350.     float                startTime;
  351.     float                accelTime;
  352.     float                linearTime;
  353.     float                decelTime;
  354.     type                startValue;
  355.     type                endValue;
  356.     mutable idExtrapolate<type> extrapolate;
  357.  
  358.     void                Invalidate( void );
  359.     void                SetPhase( float time ) const;
  360. };
  361.  
  362. /*
  363. ====================
  364. idInterpolateAccelDecelSine::idInterpolateAccelDecelSine
  365. ====================
  366. */
  367. template< class type >
  368. ID_INLINE idInterpolateAccelDecelSine<type>::idInterpolateAccelDecelSine() {
  369.     startTime = accelTime = linearTime = decelTime = 0;
  370.     memset( &startValue, 0, sizeof( startValue ) );
  371.     endValue = startValue;
  372. }
  373.  
  374. /*
  375. ====================
  376. idInterpolateAccelDecelSine::Init
  377. ====================
  378. */
  379. template< class type >
  380. ID_INLINE void idInterpolateAccelDecelSine<type>::Init( const float startTime, const float accelTime, const float decelTime, const float duration, const type &startValue, const type &endValue ) {
  381.     type speed;
  382.  
  383.     this->startTime = startTime;
  384.     this->accelTime = accelTime;
  385.     this->decelTime = decelTime;
  386.     this->startValue = startValue;
  387.     this->endValue = endValue;
  388.  
  389.     if ( duration <= 0.0f ) {
  390.         return;
  391.     }
  392.  
  393.     if ( this->accelTime + this->decelTime > duration ) {
  394.         this->accelTime = this->accelTime * duration / ( this->accelTime + this->decelTime );
  395.         this->decelTime = duration - this->accelTime;
  396.     }
  397.     this->linearTime = duration - this->accelTime - this->decelTime;
  398.     speed = ( endValue - startValue ) * ( 1000.0f / ( (float) this->linearTime + ( this->accelTime + this->decelTime ) * idMath::SQRT_1OVER2 ) );
  399.  
  400.     if ( this->accelTime ) {
  401.         extrapolate.Init( startTime, this->accelTime, startValue, ( startValue - startValue ), speed, EXTRAPOLATION_ACCELSINE );
  402.     } else if ( this->linearTime ) {
  403.         extrapolate.Init( startTime, this->linearTime, startValue, ( startValue - startValue ), speed, EXTRAPOLATION_LINEAR );
  404.     } else {
  405.         extrapolate.Init( startTime, this->decelTime, startValue, ( startValue - startValue ), speed, EXTRAPOLATION_DECELSINE );
  406.     }
  407. }
  408.  
  409. /*
  410. ====================
  411. idInterpolateAccelDecelSine::Invalidate
  412. ====================
  413. */
  414. template< class type >
  415. ID_INLINE void idInterpolateAccelDecelSine<type>::Invalidate( void ) {
  416.     extrapolate.Init( 0, 0, extrapolate.GetStartValue(), extrapolate.GetBaseSpeed(), extrapolate.GetSpeed(), EXTRAPOLATION_NONE );
  417. }
  418.  
  419. /*
  420. ====================
  421. idInterpolateAccelDecelSine::SetPhase
  422. ====================
  423. */
  424. template< class type >
  425. ID_INLINE void idInterpolateAccelDecelSine<type>::SetPhase( float time ) const {
  426.     float deltaTime;
  427.  
  428.     deltaTime = time - startTime;
  429.     if ( deltaTime < accelTime ) {
  430.         if ( extrapolate.GetExtrapolationType() != EXTRAPOLATION_ACCELSINE ) {
  431.             extrapolate.Init( startTime, accelTime, startValue, extrapolate.GetBaseSpeed(), extrapolate.GetSpeed(), EXTRAPOLATION_ACCELSINE );
  432.         }
  433.     } else if ( deltaTime < accelTime + linearTime ) {
  434.         if ( extrapolate.GetExtrapolationType() != EXTRAPOLATION_LINEAR ) {
  435.             extrapolate.Init( startTime + accelTime, linearTime, startValue + extrapolate.GetSpeed() * ( accelTime * 0.001f * idMath::SQRT_1OVER2 ), extrapolate.GetBaseSpeed(), extrapolate.GetSpeed(), EXTRAPOLATION_LINEAR );
  436.         }
  437.     } else {
  438.         if ( extrapolate.GetExtrapolationType() != EXTRAPOLATION_DECELSINE ) {
  439.             extrapolate.Init( startTime + accelTime + linearTime, decelTime, endValue - ( extrapolate.GetSpeed() * ( decelTime * 0.001f * idMath::SQRT_1OVER2 ) ), extrapolate.GetBaseSpeed(), extrapolate.GetSpeed(), EXTRAPOLATION_DECELSINE );
  440.         }
  441.     }
  442. }
  443.  
  444. /*
  445. ====================
  446. idInterpolateAccelDecelSine::GetCurrentValue
  447. ====================
  448. */
  449. template< class type >
  450. ID_INLINE type idInterpolateAccelDecelSine<type>::GetCurrentValue( float time ) const {
  451.     SetPhase( time );
  452.     return extrapolate.GetCurrentValue( time );
  453. }
  454.  
  455. /*
  456. ====================
  457. idInterpolateAccelDecelSine::GetCurrentSpeed
  458. ====================
  459. */
  460. template< class type >
  461. ID_INLINE type idInterpolateAccelDecelSine<type>::GetCurrentSpeed( float time ) const {
  462.     SetPhase( time );
  463.     return extrapolate.GetCurrentSpeed( time );
  464. }
  465.  
  466. #endif /* !__MATH_INTERPOLATE_H__ */
  467.