glutil.h

00001 /*
00002 Copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com)
00003 Grinning Lizard Utilities.
00004 
00005 This software is provided 'as-is', without any express or implied 
00006 warranty. In no event will the authors be held liable for any 
00007 damages arising from the use of this software.
00008 
00009 Permission is granted to anyone to use this software for any 
00010 purpose, including commercial applications, and to alter it and 
00011 redistribute it freely, subject to the following restrictions:
00012 
00013 1. The origin of this software must not be misrepresented; you must 
00014 not claim that you wrote the original software. If you use this 
00015 software in a product, an acknowledgment in the product documentation 
00016 would be appreciated but is not required.
00017 
00018 2. Altered source versions must be plainly marked as such, and 
00019 must not be misrepresented as being the original software.
00020 
00021 3. This notice may not be removed or altered from any source 
00022 distribution.
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                 // This could be better. 
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                 // This could be better. 
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 /*      A class to store a set of bit flags, and set and get them in a standard way.
00177         Class T must be some kind of integer type.
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 /*      A strange class: it creates bitmaps used for collision detection. Given
00199         an unsigned something, this is a utility class to pack bits...starting
00200         with the highest bit.
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                 // Push bits to T boundary
00249                 while( n && bitPos != MAXBIT )
00250                 {
00251                         Push_1();
00252                         --n;
00253                 }
00254 
00255                 // Write Full T size
00256                 while( n >= NUMBIT )
00257                 {
00258                         *data = ALLSET;
00259                         ++data;
00260                         n -= NUMBIT;
00261                 }
00262 
00263                 // Write the remainder
00264                 while ( n )
00265                 {
00266                         Push_1();
00267                         --n;
00268                 }
00269         }
00270 
00271   private:
00272         T*      data;
00273         int bitPos;
00274 };
00275 
00276 };      // namespace grinliz
00277 
00278 #endif

Generated on Thu Jul 20 20:45:32 2006 for Kyra by  doxygen 1.4.7