glbitarray.h

00001 /*
00002 Copyright (c) 2000-2007 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 #ifndef GRINLIZ_BITARRAY_INCLUDED
00026 #define GRINLIZ_BITARRAY_INCLUDED
00027 
00028 
00029 #include "gltypes.h"
00030 
00031 namespace grinliz {
00032 
00038 template< int WIDTH, int HEIGHT >
00039 class BitArray
00040 {
00041   public:
00042         enum {
00043                 ROW_WIDTH  = ( ( WIDTH+31 ) / 32 ),     
00044                 WORDSIZE = ROW_WIDTH * HEIGHT,
00045         };
00046 
00047         BitArray()                                      { memset( array, 0, WORDSIZE*4 ); cache = 0; }  
00048 
00050         U32 IsSet( int x, int y ) const { 
00051                 GLASSERT( x >= 0 && x < WIDTH );
00052                 GLASSERT( y >= 0 && y < HEIGHT );
00053                 return array[ y*ROW_WIDTH + (x>>5) ] & ( 0x1 << (x & 31)); 
00054         }
00056         void Set( int x, int y )        { 
00057                 GLASSERT( x >= 0 && x < WIDTH );
00058                 GLASSERT( y >= 0 && y < HEIGHT );
00059                 array[ y*ROW_WIDTH + (x>>5) ] |=   ( 0x1 << ( x & 31 ) ); 
00060         }
00062         void Clear( int x, int y )      { 
00063                 GLASSERT( x >= 0 && x < WIDTH );
00064                 GLASSERT( y >= 0 && y < HEIGHT );       
00065                 array[ y*ROW_WIDTH + (x>>5) ] &= (~( 0x1 << ( x & 31 ) ) ); 
00066         }
00068         void ClearRect( const Rectangle2I& rect )       {
00069                                                                                                         // FIXME: use a mask to make this more efficient.
00070                                                                                                         for( int j=rect.min.y; j<=rect.max.y; ++j )
00071                                                                                                                 for( int i=rect.min.x; i<=rect.max.x; ++i )
00072                                                                                                                         Clear( i, j );
00073                                                                                                 }
00075         void SetRect( const Rectangle2I& rect ) {
00076                                                                                                         // FIXME: use a mask to make this more efficient.
00077                                                                                                         for( int j=rect.min.y; j<=rect.max.y; ++j )
00078                                                                                                                 for( int i=rect.min.x; i<=rect.max.x; ++i )
00079                                                                                                                         Set( i, j );
00080                                                                                                 }
00082         bool IsRectEmpty( const Rectangle2I& rect ) const {
00083                                                                                                         // FIXME: use a mask to make this more efficient.
00084                                                                                                         for( int j=rect.min.y; j<=rect.max.y; ++j )
00085                                                                                                                 for( int i=rect.min.x; i<=rect.max.x; ++i )
00086                                                                                                                         if ( IsSet( i, j ) )
00087                                                                                                                                 return false;
00088                                                                                                         return true;
00089                                                                                                 }
00090 
00092         bool IsRectSet( const Rectangle2I& rect ) const {
00093                                                                                                         // FIXME: use a mask to make this more efficient.
00094                                                                                                         for( int j=rect.min.y; j<=rect.max.y; ++j )
00095                                                                                                                 for( int i=rect.min.x; i<=rect.max.x; ++i )
00096                                                                                                                         if ( !IsSet( i, j ) )
00097                                                                                                                                 return false;
00098                                                                                                         return true;
00099                                                                                                 }
00101         void ClearAll()                         { memset( array, 0, WORDSIZE*4 ); }
00103         void SetAll()                           { memset( array, 0xff, WORDSIZE*4 ); }
00104 
00106         void CacheY( int y )            { cache = &array[ROW_WIDTH*y]; }
00108         U32 IsSetCache( int x )         { return cache[ x>>5 ] & ( 0x1 << (x & 31)); }
00109 
00110         // Private. (But friend iterators are no fun.)
00111         U32 array[ WORDSIZE ];
00112         U32* cache;
00113 };
00114 
00118 template< int WIDTH, int HEIGHT >
00119 class BitArrayRowIterator
00120 {
00121   public:
00122         BitArrayRowIterator( const BitArray<WIDTH, HEIGHT>& _array ) : bitArray( _array ), mask( 0 ), loc( 0 )  {}
00123 
00125         void Begin( int x, int y)       {       loc = &bitArray.array[ y*bitArray.ROW_WIDTH + (x/32) ];
00126                                                                         U32 bit = x & 31;
00127                                                                         mask = 0x01 << bit;
00128                                                                 }
00130         void Next()                                     {       mask <<= 1;
00131                                                                         if ( !mask ) {
00132                                                                                 mask = 0x01;
00133                                                                                 ++loc;
00134                                                                         }
00135                                                                 }
00137         U32 IsSet()                                     {       return ( *loc ) & ( mask ); }
00139         bool WordEmpty()                        {       return !(*loc); }
00140 
00141   private:
00142         const BitArray<WIDTH, HEIGHT>& bitArray;
00143         U32 mask;
00144         const U32 *loc;
00145 };
00146 };
00147 #endif
00148 

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