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 "gltypes.h"
00037 #include "gldebug.h"
00038
00039 namespace grinliz {
00040
00041 template <class T> inline T Min( T a, T b ) { return ( a < b ) ? a : b; }
00042 template <class T> inline T Max( T a, T b ) { return ( a > b ) ? a : b; }
00043 template <class T> inline T Min( T a, T b, T c ) { return Min( a, Min( b, c ) ); }
00044 template <class T> inline T Max( T a, T b, T c ) { return Max( a, Max( b, c ) ); }
00045 template <class T> inline T Min( T a, T b, T c, T d ) { return Min( d, Min( a, b, c ) ); }
00046 template <class T> inline T Max( T a, T b, T c, T d ) { return Max( d, Max( a, b, c ) ); }
00047
00048
00049 template <class T> inline void Swap( T* a, T* b ) { T temp; temp = *a; *a = *b; *b = temp; }
00050 template <class T> inline bool InRange( T a, T lower, T upper ) { return a >= lower && a <= upper; }
00051 template <class T> inline T Clamp( const T& a, T lower, T upper )
00052 {
00053 if ( a < lower )
00054 return lower;
00055 else if ( a > upper )
00056 return upper;
00057 return a;
00058 }
00059
00061 template <class A, class B> inline B Interpolate( A x0, B q0, A x1, B q1, A x )
00062 {
00063 GLASSERT( static_cast<B>( x1 - x0 ) != 0.0f );
00064 return q0 + static_cast<B>( x - x0 ) * ( q1 - q0 ) / static_cast<B>( x1 - x0 );
00065 }
00066
00067
00069 template <class T> inline T InterpolateUnitX( T q0, T q1, T x )
00070 {
00071 GLASSERT( x >= (T)0.0 );
00072 GLASSERT( x <= (T)1.0 );
00073
00074 return q0*( static_cast<T>(1.0) - x ) + q1*x;
00075 }
00076
00079 template <class T> inline T BilinearInterpolate( T q00, T q10, T q01, T q11, T x, T y )
00080 {
00081 GLASSERT( x >= (T)0.0 );
00082 GLASSERT( x <= (T)1.0 );
00083 GLASSERT( y >= (T)0.0 );
00084 GLASSERT( y <= (T)1.0 );
00085
00086 const T one = static_cast<T>(1);
00087 return q00*(one-x)*(one-y) + q10*(x)*(one-y) + q01*(one-x)*(y) + q11*(x)*(y);
00088 }
00089
00090
00096 template <class T> inline T BilinearInterpolate( const T* q, T x, T y, const T* weight )
00097 {
00098 GLASSERT( x >= (T)0.0 );
00099 GLASSERT( x <= (T)1.0 );
00100 GLASSERT( y >= (T)0.0 );
00101 GLASSERT( y <= (T)1.0 );
00102
00103 const T one = static_cast<T>(1);
00104 const T zero = static_cast<T>(0);
00105 const T area[4] = { (one-x)*(one-y), (one-x)*(y), (x)*(one-y), x*y };
00106
00107 T totalWeight = zero;
00108 T sum = zero;
00109
00110 for ( unsigned i=0; i<4; ++i ) {
00111 totalWeight += area[i] * weight[i];
00112 sum += q[i] * area[i] * weight[i];
00113 }
00114 if ( totalWeight == zero )
00115 return zero;
00116 return sum / totalWeight;
00117 }
00118
00119
00121 inline long LRint( double val)
00122 {
00123 #ifdef __GNUC__
00124 return lrint( val );
00125 #else
00126 double v = val + (4503599627370496.0*1.5);
00127 return ((int*)&v)[0];
00128 #endif
00129 }
00130
00131
00133 inline long LRintf( float val)
00134 {
00135 #ifdef __GNUC__
00136 return lrintf( val );
00137 #else
00138
00139 return LRint( (double) val);
00140 #endif
00141 }
00142
00143
00144 extern float gU8ToFloat[256];
00145
00147 inline float U8ToFloat( U8 v )
00148 {
00149 return gU8ToFloat[v];
00150 }
00151
00152
00153
00154
00155
00156 template < class T >
00157 class Flag
00158 {
00159 public:
00160 Flag() { store = 0; }
00161
00162 inline void Set( T flag ) { store |= flag; }
00163 inline void Clear( T flag ) { store &= ~flag; }
00164 inline T IsSet( T flag ) const { return ( store & flag ); }
00165
00166 inline U32 ToU32() const { return store; }
00167 inline void FromU32( U32 s ) { store = (T) s; }
00168
00169 inline void ClearAll() { store = 0; }
00170
00171 private:
00172 T store;
00173 };
00174
00175
00176
00177
00178
00179
00180 template < class T >
00181 class HighBitWriter
00182 {
00183 public:
00184 enum
00185 {
00186 MAXBIT = ( sizeof(T)*8-1 ),
00187 NUMBIT = ( sizeof(T)*8 ),
00188 ALLSET = T( -1 )
00189 };
00190
00191 HighBitWriter( T* _data ) : data( _data ), bitPos( MAXBIT ) {}
00192
00193 void Skip()
00194 {
00195 if ( bitPos == 0 )
00196 {
00197 ++data;
00198 bitPos = MAXBIT;
00199 }
00200 else
00201 {
00202 --bitPos;
00203 }
00204 }
00205
00206 void Skip_N( unsigned n )
00207 {
00208 bitPos -= n % NUMBIT;
00209 if ( bitPos < 0 )
00210 {
00211 bitPos += NUMBIT;
00212 ++data;
00213 }
00214 data += n / NUMBIT;
00215 }
00216
00217 void Push_1()
00218 {
00219 *data |= ( 1 << bitPos );
00220 Skip();
00221 }
00222
00223 void Push_1N( unsigned n )
00224 {
00225
00226 while( n && bitPos != MAXBIT )
00227 {
00228 Push_1();
00229 --n;
00230 }
00231
00232
00233 while( n >= NUMBIT )
00234 {
00235 *data = ALLSET;
00236 ++data;
00237 n -= NUMBIT;
00238 }
00239
00240
00241 while ( n )
00242 {
00243 Push_1();
00244 --n;
00245 }
00246 }
00247
00248 private:
00249 T* data;
00250 int bitPos;
00251 };
00252
00253
00254 };
00255
00256 #endif