- Main Page
- Classes
- Files
- Directories
- Related Pages

# 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