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 "gldebug.h"
00037 #include "gltypes.h"
00038 
00039 namespace grinliz {
00040 
00042 template <class T> inline T             Min( T a, T b )         { return ( a < b ) ? a : b; }
00044 template <class T> inline T             Max( T a, T b )         { return ( a > b ) ? a : b; }
00046 template <class T> inline T             Min( T a, T b, T c )    { return Min( a, Min( b, c ) ); }
00048 template <class T> inline T             Max( T a, T b, T c )    { return Max( a, Max( b, c ) ); }
00050 template <class T> inline T             Min( T a, T b, T c, T d )       { return Min( d, Min( a, b, c ) ); }
00052 template <class T> inline T             Max( T a, T b, T c, T d )       { return Max( d, Max( a, b, c ) ); }
00053 
00055 template <class T> inline void  Swap( T* a, T* b )      { T temp; temp = *a; *a = *b; *b = temp; }
00057 template <class T> inline bool  InRange( T a, T lower, T upper )        { return a >= lower && a <= upper; }
00059 template <class T> inline T             Clamp( const T& a, T lower, T upper )   
00060                                                                 { 
00061                                                                         if ( a < lower )
00062                                                                                 return lower;
00063                                                                         else if ( a > upper )
00064                                                                                 return upper;
00065                                                                         return a;
00066                                                                 }
00067 
00069 template <class T> inline T             Mean( T t0, T t1 )      { return (t0 + t1)/static_cast<T>( 2 ); }
00071 template <class T> inline T             Mean( T t0, T t1, T t2 )        { return (t0+t1+t2)/static_cast<T>( 3 ); }
00072 
00074 template <class A, class B> inline B Interpolate( A x0, B q0, A x1, B q1, A x )
00075 {
00076         GLASSERT( static_cast<B>( x1 - x0 ) != 0.0f );
00077         return q0 + static_cast<B>( x - x0 ) * ( q1 - q0 ) / static_cast<B>( x1 - x0 );
00078 }
00079 
00081 template< class T > inline T HermiteInterpolate( T x0, T x1, T x )
00082 {
00083         const T k0 = static_cast< T >( 0 );
00084         const T k1 = static_cast< T >( 1 );
00085         const T k2 = static_cast< T >( 2 );
00086         const T k3 = static_cast< T >( 3 );
00087 
00088         T t = Clamp(( x - x0) / (x1 - x0), k0, k1 );
00089         return t * t * (k3 - k2 * t);
00090 }
00091 
00093 template <class T> inline T InterpolateUnitX( T q0, T q1, T x )
00094 {
00095         GLASSERT( x >= (T)0.0 );
00096         GLASSERT( x <= (T)1.0 );
00097 
00098         return q0*( static_cast<T>(1.0) - x ) + q1*x;
00099 }
00100 
00103 template <class T> inline T BilinearInterpolate( T q00, T q10, T q01, T q11, T x, T y )
00104 {
00105         GLASSERT( x >= (T)0.0 );
00106         GLASSERT( x <= (T)1.0 );
00107         GLASSERT( y >= (T)0.0 );
00108         GLASSERT( y <= (T)1.0 );
00109 
00110         const T one = static_cast<T>(1);
00111         return q00*(one-x)*(one-y) + q10*(x)*(one-y) + q01*(one-x)*(y) + q11*(x)*(y);
00112 }
00113 
00114 
00120 template <class T> inline T BilinearInterpolate( const T* q, T x, T y, const T* weight )
00121 {
00122         GLASSERT( x >= (T)0.0 );
00123         GLASSERT( x <= (T)1.0 );
00124         GLASSERT( y >= (T)0.0 );
00125         GLASSERT( y <= (T)1.0 );
00126 
00127         const T one = static_cast<T>(1);
00128         const T zero = static_cast<T>(0);
00129         const T area[4] = { (one-x)*(one-y), (one-x)*(y), (x)*(one-y), x*y };
00130 
00131         T totalWeight = zero;
00132         T sum = zero;
00133 
00134         for ( unsigned i=0; i<4; ++i ) {
00135                 totalWeight += area[i] * weight[i];
00136                 sum += q[i] * area[i] * weight[i];
00137         }
00138         if ( totalWeight == zero )
00139                 return zero;
00140         return sum / totalWeight;
00141 }
00142 
00143 
00145 inline long LRint( double val)
00146 {
00147         #if defined (__GNUC__)
00148                 return lrint( val );
00149         #elif defined (_MSC_VER)
00150                 long retval;
00151                 __asm fld val
00152                 __asm fistp retval
00153                 return retval;
00154         #else
00155                 // This could be better. 
00156                 return (long)( val + 0.5 );
00157         #endif
00158 }
00159 
00160 
00162 inline long LRintf( float val)
00163 {
00164         #if defined (__GNUC__)
00165                 return lrintf( val );
00166         #elif defined (_MSC_VER)
00167                 long retval;
00168                 __asm fld val
00169                 __asm fistp retval
00170                 return retval;
00171         #else
00172                 // This could be better. 
00173                 return (long)( val + 0.5f );
00174         #endif
00175 }
00176 
00177 
00178 extern float gU8ToFloat[256];
00179 
00181 inline float U8ToFloat( U8 v )
00182 {
00183         return gU8ToFloat[v];
00184 }
00185 
00186 
00187 /*      A class to store a set of bit flags, and set and get them in a standard way.
00188         Class T must be some kind of integer type.
00189 */
00190 template < class T >
00191 class Flag
00192 {
00193   public:
00194         Flag()                                                          { store = 0; }
00195         
00196         inline void Set( T flag )                       { store |= flag; }
00197         inline void Clear( T flag )                     { store &= ~flag; }
00198         inline T IsSet( T flag ) const          { return ( store & flag ); }
00199 
00200         inline U32  ToU32() const                       { return store; }
00201         inline void FromU32( U32 s )            { store = (T) s; }
00202 
00203         inline void ClearAll()                          { store = 0; }
00204 
00205   private:
00206         T store;
00207 };      
00208 
00209 /*      A strange class: it creates bitmaps used for collision detection. Given
00210         an unsigned something, this is a utility class to pack bits...starting
00211         with the highest bit.
00212 */
00213 
00214 template < class T >
00215 class HighBitWriter 
00216 {
00217   public:
00218         enum
00219         {
00220                 MAXBIT = ( sizeof(T)*8-1 ),
00221                 NUMBIT = ( sizeof(T)*8 ),
00222                 ALLSET = T( -1 )
00223         };
00224 
00225         HighBitWriter( T* _data ) : data( _data ), bitPos( MAXBIT )     {}
00226 
00227         void Skip()
00228         {
00229                 if ( bitPos == 0 )
00230                 {
00231                         ++data;
00232                         bitPos = MAXBIT;
00233                 }
00234                 else
00235                 {
00236                         --bitPos;
00237                 }
00238         }
00239 
00240         void Skip_N( unsigned n )
00241         {
00242                 bitPos -= n % NUMBIT;
00243                 if ( bitPos < 0 )
00244                 {
00245                         bitPos += NUMBIT;
00246                         ++data;
00247                 }
00248                 data += n / NUMBIT;
00249         }
00250         
00251         void Push_1()   
00252         {
00253                 *data |= ( 1 << bitPos );
00254                 Skip();
00255         }
00256 
00257         void Push_1N( unsigned n )
00258         {
00259                 // Push bits to T boundary
00260                 while( n && bitPos != MAXBIT )
00261                 {
00262                         Push_1();
00263                         --n;
00264                 }
00265 
00266                 // Write Full T size
00267                 while( n >= NUMBIT )
00268                 {
00269                         *data = ALLSET;
00270                         ++data;
00271                         n -= NUMBIT;
00272                 }
00273 
00274                 // Write the remainder
00275                 while ( n )
00276                 {
00277                         Push_1();
00278                         --n;
00279                 }
00280         }
00281 
00282   private:
00283         T*      data;
00284         int bitPos;
00285 };
00286 
00287 /*
00288 template< class T > class WeakPtr;
00289 
00290 struct WeakPtrHolder
00291 {
00292         WeakPtrHolder() {
00293                 next = prev = this;
00294         }
00295         ~WeakPtrHolder() {
00296                 while ( next != prev ) {
00297                         next
00298                 }
00299         }
00300         WeakPtr< T >* next;
00301         WeakPtr< T >* prev;
00302 };
00303 */
00304 
00310 /*
00311 template< class T > 
00312 class WeakPtr
00313 {
00314 public:
00315         enum Sentinel { SENTINEL };
00316 
00317         WeakPtr( Sentinel ) { prev = next = this; ptr = (T)(1); }
00318 
00319         WeakPtr()                               { prev = next = this; ptr = 0; }
00320         WeakPtr( T t )                  { Init( t ); }
00321         void operator=( T t )   { GLASSERT( ptr != (T)(1) );
00322                                                           Unlink();
00323                                                           Init( t );
00324         }
00325 
00326         ~WeakPtr()
00327         {
00328                 if ( ptr == (T)(1) ) 
00329                 {
00330                         // We are the holder. Unlink everything.
00331                         while( next != prev ) {
00332                                 next->Unlink();
00333                         }
00334                         GLASSERT( next == prev );
00335                         GLASSERT( next == this );
00336                         ptr = 0;
00337                 }
00338                 else {
00339                         // We are not a sentinel: unlink ourselves.
00340                         Unlink();
00341                 }
00342         }
00343 
00344         T Ptr() { return ( ptr == (T)(1) ) ? 0 : ptr; }
00345 
00346 private:
00347         WeakPtr( const WeakPtr& );
00348         void operator=( const WeakPtr& );
00349 
00350         void Init( T t )
00351         {
00352                 GLASSERT( t );
00353                 ptr = t;
00354 
00355                 next = t->weakPtrHolder.next;
00356                 prev = &t->weakPtrHolder;
00357                 t->weakPtrHolder.next->prev = this;
00358                 t->weakPtrHolder.next = this;
00359         }
00360         void Unlink()
00361         {
00362                 prev->next = next;
00363                 next->prev = prev;
00364                 ptr = 0;
00365         }
00366 
00367         T ptr;
00368         WeakPtr<T>* next;
00369         WeakPtr<T>* prev;
00370 };
00371 */
00372 };      // namespace grinliz
00373 
00374 #endif

Generated on Fri Mar 23 19:36:21 2007 for Lilith3D by  doxygen 1.5.1-p1