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
00060 template <class T> inline T Mean( T t0, T t1 ) { return (t0 + t1)/static_cast<T>( 2 ); }
00061 template <class T> inline T Mean( T t0, T t1, T t2 ) { return (t0+t1+t2)/static_cast<T>( 3 ); }
00062
00064 template <class A, class B> inline B Interpolate( A x0, B q0, A x1, B q1, A x )
00065 {
00066 GLASSERT( static_cast<B>( x1 - x0 ) != 0.0f );
00067 return q0 + static_cast<B>( x - x0 ) * ( q1 - q0 ) / static_cast<B>( x1 - x0 );
00068 }
00069
00070 template< class T > inline T HermiteInterpolate( T x0, T x1, T x )
00071 {
00072 const T k0 = static_cast< T >( 0 );
00073 const T k1 = static_cast< T >( 1 );
00074 const T k2 = static_cast< T >( 2 );
00075 const T k3 = static_cast< T >( 3 );
00076
00077 T t = Clamp(( x - x0) / (x1 - x0), k0, k1 );
00078 return t * t * (k3 - k2 * t);
00079 }
00080
00082 template <class T> inline T InterpolateUnitX( T q0, T q1, T x )
00083 {
00084 GLASSERT( x >= (T)0.0 );
00085 GLASSERT( x <= (T)1.0 );
00086
00087 return q0*( static_cast<T>(1.0) - x ) + q1*x;
00088 }
00089
00092 template <class T> inline T BilinearInterpolate( T q00, T q10, T q01, T q11, T x, T y )
00093 {
00094 GLASSERT( x >= (T)0.0 );
00095 GLASSERT( x <= (T)1.0 );
00096 GLASSERT( y >= (T)0.0 );
00097 GLASSERT( y <= (T)1.0 );
00098
00099 const T one = static_cast<T>(1);
00100 return q00*(one-x)*(one-y) + q10*(x)*(one-y) + q01*(one-x)*(y) + q11*(x)*(y);
00101 }
00102
00103
00109 template <class T> inline T BilinearInterpolate( const T* q, T x, T y, const T* weight )
00110 {
00111 GLASSERT( x >= (T)0.0 );
00112 GLASSERT( x <= (T)1.0 );
00113 GLASSERT( y >= (T)0.0 );
00114 GLASSERT( y <= (T)1.0 );
00115
00116 const T one = static_cast<T>(1);
00117 const T zero = static_cast<T>(0);
00118 const T area[4] = { (one-x)*(one-y), (one-x)*(y), (x)*(one-y), x*y };
00119
00120 T totalWeight = zero;
00121 T sum = zero;
00122
00123 for ( unsigned i=0; i<4; ++i ) {
00124 totalWeight += area[i] * weight[i];
00125 sum += q[i] * area[i] * weight[i];
00126 }
00127 if ( totalWeight == zero )
00128 return zero;
00129 return sum / totalWeight;
00130 }
00131
00132
00134 inline long LRint( double val)
00135 {
00136 #if defined (__GNUC__)
00137 return lrint( val );
00138 #elif defined (_MSC_VER)
00139 long retval;
00140 __asm fld val
00141 __asm fistp retval
00142 return retval;
00143 #else
00144
00145 return (long)( val + 0.5 );
00146 #endif
00147 }
00148
00149
00151 inline long LRintf( float val)
00152 {
00153 #if defined (__GNUC__)
00154 return lrintf( val );
00155 #elif defined (_MSC_VER)
00156 long retval;
00157 __asm fld val
00158 __asm fistp retval
00159 return retval;
00160 #else
00161
00162 return (long)( val + 0.5f );
00163 #endif
00164 }
00165
00166
00167 extern float gU8ToFloat[256];
00168
00170 inline float U8ToFloat( U8 v )
00171 {
00172 return gU8ToFloat[v];
00173 }
00174
00175
00176
00177
00178
00179 template < class T >
00180 class Flag
00181 {
00182 public:
00183 Flag() { store = 0; }
00184
00185 inline void Set( T flag ) { store |= flag; }
00186 inline void Clear( T flag ) { store &= ~flag; }
00187 inline T IsSet( T flag ) const { return ( store & flag ); }
00188
00189 inline U32 ToU32() const { return store; }
00190 inline void FromU32( U32 s ) { store = (T) s; }
00191
00192 inline void ClearAll() { store = 0; }
00193
00194 private:
00195 T store;
00196 };
00197
00198
00199
00200
00201
00202
00203 template < class T >
00204 class HighBitWriter
00205 {
00206 public:
00207 enum
00208 {
00209 MAXBIT = ( sizeof(T)*8-1 ),
00210 NUMBIT = ( sizeof(T)*8 ),
00211 ALLSET = T( -1 )
00212 };
00213
00214 HighBitWriter( T* _data ) : data( _data ), bitPos( MAXBIT ) {}
00215
00216 void Skip()
00217 {
00218 if ( bitPos == 0 )
00219 {
00220 ++data;
00221 bitPos = MAXBIT;
00222 }
00223 else
00224 {
00225 --bitPos;
00226 }
00227 }
00228
00229 void Skip_N( unsigned n )
00230 {
00231 bitPos -= n % NUMBIT;
00232 if ( bitPos < 0 )
00233 {
00234 bitPos += NUMBIT;
00235 ++data;
00236 }
00237 data += n / NUMBIT;
00238 }
00239
00240 void Push_1()
00241 {
00242 *data |= ( 1 << bitPos );
00243 Skip();
00244 }
00245
00246 void Push_1N( unsigned n )
00247 {
00248
00249 while( n && bitPos != MAXBIT )
00250 {
00251 Push_1();
00252 --n;
00253 }
00254
00255
00256 while( n >= NUMBIT )
00257 {
00258 *data = ALLSET;
00259 ++data;
00260 n -= NUMBIT;
00261 }
00262
00263
00264 while ( n )
00265 {
00266 Push_1();
00267 --n;
00268 }
00269 }
00270
00271 private:
00272 T* data;
00273 int bitPos;
00274 };
00275
00276 };
00277
00278 #endif