00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef GRINLIZ_UTIL_INCLUDED
00028 #define GRINLIZ_UTIL_INCLUDED
00029
00030 #ifdef _MSC_VER
00031 #pragma warning( disable : 4530 )
00032 #pragma warning( disable : 4786 )
00033 #endif
00034
00035 #include <math.h>
00036 #include "gldebug.h"
00037 #include "gltypes.h"
00038
00039 namespace grinliz {
00040
00042 template <class T> inline T Min( T a, T b ) { return ( a < b ) ? a : b; }
00044 template <class T> inline T Max( T a, T b ) { return ( a > b ) ? a : b; }
00046 template <class T> inline T Min( T a, T b, T c ) { return Min( a, Min( b, c ) ); }
00048 template <class T> inline T Max( T a, T b, T c ) { return Max( a, Max( b, c ) ); }
00050 template <class T> inline T Min( T a, T b, T c, T d ) { return Min( d, Min( a, b, c ) ); }
00052 template <class T> inline T Max( T a, T b, T c, T d ) { return Max( d, Max( a, b, c ) ); }
00053
00055 template <class T> inline void Swap( T* a, T* b ) { T temp; temp = *a; *a = *b; *b = temp; }
00057 template <class T> inline bool InRange( T a, T lower, T upper ) { return a >= lower && a <= upper; }
00059 template <class T> inline T Clamp( const T& a, T lower, T upper )
00060 {
00061 if ( a < lower )
00062 return lower;
00063 else if ( a > upper )
00064 return upper;
00065 return a;
00066 }
00067
00069 template <class T> inline T Mean( T t0, T t1 ) { return (t0 + t1)/static_cast<T>( 2 ); }
00071 template <class T> inline T Mean( T t0, T t1, T t2 ) { return (t0+t1+t2)/static_cast<T>( 3 ); }
00072
00074 template <class A, class B> inline B Interpolate( A x0, B q0, A x1, B q1, A x )
00075 {
00076 GLASSERT( static_cast<B>( x1 - x0 ) != 0.0f );
00077 return q0 + static_cast<B>( x - x0 ) * ( q1 - q0 ) / static_cast<B>( x1 - x0 );
00078 }
00079
00081 template< class T > inline T HermiteInterpolate( T x0, T x1, T x )
00082 {
00083 const T k0 = static_cast< T >( 0 );
00084 const T k1 = static_cast< T >( 1 );
00085 const T k2 = static_cast< T >( 2 );
00086 const T k3 = static_cast< T >( 3 );
00087
00088 T t = Clamp(( x - x0) / (x1 - x0), k0, k1 );
00089 return t * t * (k3 - k2 * t);
00090 }
00091
00093 template <class T> inline T InterpolateUnitX( T q0, T q1, T x )
00094 {
00095 GLASSERT( x >= (T)0.0 );
00096 GLASSERT( x <= (T)1.0 );
00097
00098 return q0*( static_cast<T>(1.0) - x ) + q1*x;
00099 }
00100
00103 template <class T> inline T BilinearInterpolate( T q00, T q10, T q01, T q11, T x, T y )
00104 {
00105 GLASSERT( x >= (T)0.0 );
00106 GLASSERT( x <= (T)1.0 );
00107 GLASSERT( y >= (T)0.0 );
00108 GLASSERT( y <= (T)1.0 );
00109
00110 const T one = static_cast<T>(1);
00111 return q00*(one-x)*(one-y) + q10*(x)*(one-y) + q01*(one-x)*(y) + q11*(x)*(y);
00112 }
00113
00114
00120 template <class T> inline T BilinearInterpolate( const T* q, T x, T y, const T* weight )
00121 {
00122 GLASSERT( x >= (T)0.0 );
00123 GLASSERT( x <= (T)1.0 );
00124 GLASSERT( y >= (T)0.0 );
00125 GLASSERT( y <= (T)1.0 );
00126
00127 const T one = static_cast<T>(1);
00128 const T zero = static_cast<T>(0);
00129 const T area[4] = { (one-x)*(one-y), (one-x)*(y), (x)*(one-y), x*y };
00130
00131 T totalWeight = zero;
00132 T sum = zero;
00133
00134 for ( unsigned i=0; i<4; ++i ) {
00135 totalWeight += area[i] * weight[i];
00136 sum += q[i] * area[i] * weight[i];
00137 }
00138 if ( totalWeight == zero )
00139 return zero;
00140 return sum / totalWeight;
00141 }
00142
00143
00145 inline long LRint( double val)
00146 {
00147 #if defined (__GNUC__)
00148 return lrint( val );
00149 #elif defined (_MSC_VER)
00150 long retval;
00151 __asm fld val
00152 __asm fistp retval
00153 return retval;
00154 #else
00155
00156 return (long)( val + 0.5 );
00157 #endif
00158 }
00159
00160
00162 inline long LRintf( float val)
00163 {
00164 #if defined (__GNUC__)
00165 return lrintf( val );
00166 #elif defined (_MSC_VER)
00167 long retval;
00168 __asm fld val
00169 __asm fistp retval
00170 return retval;
00171 #else
00172
00173 return (long)( val + 0.5f );
00174 #endif
00175 }
00176
00177
00178 extern float gU8ToFloat[256];
00179
00181 inline float U8ToFloat( U8 v )
00182 {
00183 return gU8ToFloat[v];
00184 }
00185
00186
00187
00188
00189
00190 template < class T >
00191 class Flag
00192 {
00193 public:
00194 Flag() { store = 0; }
00195
00196 inline void Set( T flag ) { store |= flag; }
00197 inline void Clear( T flag ) { store &= ~flag; }
00198 inline T IsSet( T flag ) const { return ( store & flag ); }
00199
00200 inline U32 ToU32() const { return store; }
00201 inline void FromU32( U32 s ) { store = (T) s; }
00202
00203 inline void ClearAll() { store = 0; }
00204
00205 private:
00206 T store;
00207 };
00208
00209
00210
00211
00212
00213
00214 template < class T >
00215 class HighBitWriter
00216 {
00217 public:
00218 enum
00219 {
00220 MAXBIT = ( sizeof(T)*8-1 ),
00221 NUMBIT = ( sizeof(T)*8 ),
00222 ALLSET = T( -1 )
00223 };
00224
00225 HighBitWriter( T* _data ) : data( _data ), bitPos( MAXBIT ) {}
00226
00227 void Skip()
00228 {
00229 if ( bitPos == 0 )
00230 {
00231 ++data;
00232 bitPos = MAXBIT;
00233 }
00234 else
00235 {
00236 --bitPos;
00237 }
00238 }
00239
00240 void Skip_N( unsigned n )
00241 {
00242 bitPos -= n % NUMBIT;
00243 if ( bitPos < 0 )
00244 {
00245 bitPos += NUMBIT;
00246 ++data;
00247 }
00248 data += n / NUMBIT;
00249 }
00250
00251 void Push_1()
00252 {
00253 *data |= ( 1 << bitPos );
00254 Skip();
00255 }
00256
00257 void Push_1N( unsigned n )
00258 {
00259
00260 while( n && bitPos != MAXBIT )
00261 {
00262 Push_1();
00263 --n;
00264 }
00265
00266
00267 while( n >= NUMBIT )
00268 {
00269 *data = ALLSET;
00270 ++data;
00271 n -= NUMBIT;
00272 }
00273
00274
00275 while ( n )
00276 {
00277 Push_1();
00278 --n;
00279 }
00280 }
00281
00282 private:
00283 T* data;
00284 int bitPos;
00285 };
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372 };
00373
00374 #endif