]> icculus.org git repositories - icculus/iodoom3.git/blob - neo/idlib/math/Extrapolate.h
Various Mac OS X tweaks to get this to build. Probably breaking things.
[icculus/iodoom3.git] / neo / idlib / math / Extrapolate.h
1 /*
2 ===========================================================================
3
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company. 
6
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).  
8
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code.  If not, see <http://www.gnu.org/licenses/>.
21
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code.  If not, please request a copy in writing from id Software at the address below.
23
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25
26 ===========================================================================
27 */
28
29 #ifndef __MATH_EXTRAPOLATE_H__
30 #define __MATH_EXTRAPOLATE_H__
31
32 /*
33 ==============================================================================================
34
35         Extrapolation
36
37 ==============================================================================================
38 */
39
40 typedef enum {
41         EXTRAPOLATION_NONE                      = 0x01, // no extrapolation, covered distance = duration * 0.001 * ( baseSpeed )
42         EXTRAPOLATION_LINEAR            = 0x02, // linear extrapolation, covered distance = duration * 0.001 * ( baseSpeed + speed )
43         EXTRAPOLATION_ACCELLINEAR       = 0x04, // linear acceleration, covered distance = duration * 0.001 * ( baseSpeed + 0.5 * speed )
44         EXTRAPOLATION_DECELLINEAR       = 0x08, // linear deceleration, covered distance = duration * 0.001 * ( baseSpeed + 0.5 * speed )
45         EXTRAPOLATION_ACCELSINE         = 0x10, // sinusoidal acceleration, covered distance = duration * 0.001 * ( baseSpeed + sqrt( 0.5 ) * speed )
46         EXTRAPOLATION_DECELSINE         = 0x20, // sinusoidal deceleration, covered distance = duration * 0.001 * ( baseSpeed + sqrt( 0.5 ) * speed )
47         EXTRAPOLATION_NOSTOP            = 0x40  // do not stop at startTime + duration
48 } extrapolation_t;
49
50 template< class type >
51 class idExtrapolate {
52 public:
53                                                 idExtrapolate();
54
55         void                            Init( const float startTime, const float duration, const type &startValue, const type &baseSpeed, const type &speed, const extrapolation_t extrapolationType );
56         type                            GetCurrentValue( float time ) const;
57         type                            GetCurrentSpeed( float time ) const;
58         bool                            IsDone( float time ) const { return ( !( extrapolationType & EXTRAPOLATION_NOSTOP ) && time >= startTime + duration ); }
59         void                            SetStartTime( float time ) { startTime = time; currentTime = -1; }
60         float                           GetStartTime( void ) const { return startTime; }
61         float                           GetEndTime( void ) const { return ( !( extrapolationType & EXTRAPOLATION_NOSTOP ) && duration > 0 ) ? startTime + duration : 0; }
62         float                           GetDuration( void ) const { return duration; }
63         void                            SetStartValue( const type &value ) { startValue = value; currentTime = -1; }
64         const type &            GetStartValue( void ) const { return startValue; }
65         const type &            GetBaseSpeed( void ) const { return baseSpeed; }
66         const type &            GetSpeed( void ) const { return speed; }
67         extrapolation_t         GetExtrapolationType( void ) const { return extrapolationType; }
68
69 private:
70         extrapolation_t         extrapolationType;
71         float                           startTime;
72         float                           duration;
73         type                            startValue;
74         type                            baseSpeed;
75         type                            speed;
76         mutable float           currentTime;
77         mutable type            currentValue;
78 };
79
80 /*
81 ====================
82 idExtrapolate::idExtrapolate
83 ====================
84 */
85 template< class type >
86 ID_INLINE idExtrapolate<type>::idExtrapolate() {
87         extrapolationType = EXTRAPOLATION_NONE;
88         startTime = duration = 0.0f;
89         memset( &startValue, 0, sizeof( startValue ) );
90         memset( &baseSpeed, 0, sizeof( baseSpeed ) );
91         memset( &speed, 0, sizeof( speed ) );
92         currentTime = -1;
93         currentValue = startValue;
94 }
95
96 /*
97 ====================
98 idExtrapolate::Init
99 ====================
100 */
101 template< class type >
102 ID_INLINE void idExtrapolate<type>::Init( const float startTime, const float duration, const type &startValue, const type &baseSpeed, const type &speed, const extrapolation_t extrapolationType ) {
103         this->extrapolationType = extrapolationType;
104         this->startTime = startTime;
105         this->duration = duration;
106         this->startValue = startValue;
107         this->baseSpeed = baseSpeed;
108         this->speed = speed;
109         currentTime = -1;
110         currentValue = startValue;
111 }
112
113 /*
114 ====================
115 idExtrapolate::GetCurrentValue
116 ====================
117 */
118 template< class type >
119 ID_INLINE type idExtrapolate<type>::GetCurrentValue( float time ) const {
120         float deltaTime, s;
121
122         if ( time == currentTime ) {
123                 return currentValue;
124         }
125
126         currentTime = time;
127
128         if ( time < startTime ) {
129                 return startValue;
130         }
131
132         if ( !( extrapolationType &     EXTRAPOLATION_NOSTOP ) && ( time > startTime + duration ) ) {
133                 time = startTime + duration;
134         }
135
136         switch( extrapolationType & ~EXTRAPOLATION_NOSTOP ) {
137                 case EXTRAPOLATION_NONE: {
138                         deltaTime = ( time - startTime ) * 0.001f;
139                         currentValue = startValue + deltaTime * baseSpeed;
140                         break;
141                 }
142                 case EXTRAPOLATION_LINEAR: {
143                         deltaTime = ( time - startTime ) * 0.001f;
144                         currentValue = startValue + deltaTime * ( baseSpeed + speed );
145                         break;
146                 }
147                 case EXTRAPOLATION_ACCELLINEAR: {
148                         if ( !duration ) {
149                                 currentValue = startValue;
150                         } else {
151                                 deltaTime = ( time - startTime ) / duration;
152                                 s = ( 0.5f * deltaTime * deltaTime ) * ( duration * 0.001f );
153                                 currentValue = startValue + deltaTime * baseSpeed + s * speed;
154                         }
155                         break;
156                 }
157                 case EXTRAPOLATION_DECELLINEAR: {
158                         if ( !duration ) {
159                                 currentValue = startValue;
160                         } else {
161                                 deltaTime = ( time - startTime ) / duration;
162                                 s = ( deltaTime - ( 0.5f * deltaTime * deltaTime ) ) * ( duration * 0.001f );
163                                 currentValue = startValue + deltaTime * baseSpeed + s * speed;
164                         }
165                         break;
166                 }
167                 case EXTRAPOLATION_ACCELSINE: {
168                         if ( !duration ) {
169                                 currentValue = startValue;
170                         } else {
171                                 deltaTime = ( time - startTime ) / duration;
172                                 s = ( 1.0f - idMath::Cos( deltaTime * idMath::HALF_PI ) ) * duration * 0.001f * idMath::SQRT_1OVER2;
173                                 currentValue = startValue + deltaTime * baseSpeed + s * speed;
174                         }
175                         break;
176                 }
177                 case EXTRAPOLATION_DECELSINE: {
178                         if ( !duration ) {
179                                 currentValue = startValue;
180                         } else {
181                                 deltaTime = ( time - startTime ) / duration;
182                                 s = idMath::Sin( deltaTime * idMath::HALF_PI ) * duration * 0.001f * idMath::SQRT_1OVER2;
183                                 currentValue = startValue + deltaTime * baseSpeed + s * speed;
184                         }
185                         break;
186                 }
187         }
188         return currentValue;
189 }
190
191 /*
192 ====================
193 idExtrapolate::GetCurrentSpeed
194 ====================
195 */
196 template< class type >
197 ID_INLINE type idExtrapolate<type>::GetCurrentSpeed( float time ) const {
198         float deltaTime, s;
199
200         if ( time < startTime || !duration ) {
201                 return ( startValue - startValue );
202         }
203
204         if ( !( extrapolationType &     EXTRAPOLATION_NOSTOP ) && ( time > startTime + duration ) ) {
205                 return ( startValue - startValue );
206         }
207
208         switch( extrapolationType & ~EXTRAPOLATION_NOSTOP ) {
209                 case EXTRAPOLATION_NONE: {
210                         return baseSpeed;
211                 }
212                 case EXTRAPOLATION_LINEAR: {
213                         return baseSpeed + speed;
214                 }
215                 case EXTRAPOLATION_ACCELLINEAR: {
216                         deltaTime = ( time - startTime ) / duration;
217                         s = deltaTime;
218                         return baseSpeed + s * speed;
219                 }
220                 case EXTRAPOLATION_DECELLINEAR: {
221                         deltaTime = ( time - startTime ) / duration;
222                         s = 1.0f - deltaTime;
223                         return baseSpeed + s * speed;
224                 }
225                 case EXTRAPOLATION_ACCELSINE: {
226                         deltaTime = ( time - startTime ) / duration;
227                         s = idMath::Sin( deltaTime * idMath::HALF_PI );
228                         return baseSpeed + s * speed;
229                 }
230                 case EXTRAPOLATION_DECELSINE: {
231                         deltaTime = ( time - startTime ) / duration;
232                         s = idMath::Cos( deltaTime * idMath::HALF_PI );
233                         return baseSpeed + s * speed;
234                 }
235                 default: {
236                         return baseSpeed;
237                 }
238         }
239 }
240
241 #endif /* !__MATH_EXTRAPOLATE_H__ */