Main Page | Class Hierarchy | Class List | Directories | File List | Class Members | Related Pages

glutil.h

00001 /*
00002 Copyright (c) 2000-2003 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 
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);      // 2^52
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                 // This could be better. 
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 /*      A class to store a set of bit flags, and set and get them in a standard way.
00154         Class T must be some kind of integer type.
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 /*      A strange class: it creates bitmaps used for collision detection. Given
00176         an unsigned something, this is a utility class to pack bits...starting
00177         with the highest bit.
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                 // Push bits to T boundary
00226                 while( n && bitPos != MAXBIT )
00227                 {
00228                         Push_1();
00229                         --n;
00230                 }
00231 
00232                 // Write Full T size
00233                 while( n >= NUMBIT )
00234                 {
00235                         *data = ALLSET;
00236                         ++data;
00237                         n -= NUMBIT;
00238                 }
00239 
00240                 // Write the remainder
00241                 while ( n )
00242                 {
00243                         Push_1();
00244                         --n;
00245                 }
00246         }
00247 
00248   private:
00249         T*      data;
00250         int bitPos;
00251 };
00252 
00253 
00254 };      // namespace grinliz
00255 
00256 #endif

Generated on Sun Sep 25 16:25:49 2005 for Kyra by  doxygen 1.4.3