Main Page | Modules | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

bitmask.h

00001 /*
00002  *                         bitmask.c 1.0 
00003  *                         -------------
00004  *    Simple and efficient bitmask collision detection routines
00005  *  Copyright (C) 2002 Ulf Ekstrom except for the bitcount function.
00006  *
00007  *  A bitmask is a simple array of bits, which can be used for 
00008  *  2d collision detection. Set 'unoccupied' area to zero and
00009  *  occupies areas to one and use the bitmask_overlap*() functions
00010  *  to check for collisions.
00011  *  The current implementation uses 32 bit wide stripes to hold  
00012  *  the masks, but should work just as well with 64 bit sizes.
00013  *  (Note that the current bitcount function is 32 bit only!)
00014  *
00015  *  The overlap tests uses the following offsets (which may be negative):
00016  *
00017  *   +----+----------..
00018  *   |A   | yoffset   
00019  *   |  +-+----------..
00020  *   +--|B        
00021  *   |xoffset      
00022  *   |  |
00023  *   :  :  
00024  *
00025  *  For optimal collision detection performance combine these functions
00026  *  with some kind of pre-sorting to avoid comparing objects far from 
00027  *  each other.
00028  *
00029  *  BUGS: No known bugs, even though they may certainly be in here somewhere.
00030  *  Possible performance improvements could be to remove the div in 
00031  *  bitmask_overlap_pos() and to implement wider stripes if the masks used
00032  *  are wider than 64 bits on the average.
00033  *
00034  *  Performance of the various functions goes something like: 
00035  *  (relative timings, smaller is better)
00036  * 
00037  *  bitmask_overlap()        1.0
00038  *  bitmask_overlap_pos()    1.3
00039  *  bitmask_overlap_area()   1.6
00040  *
00041  *  For maximum performance on my machine I use gcc with
00042  *  -O2 -fomit-frame-pointer -funroll-loops 
00043  *
00044  *
00045  *  If you can make these functions faster or have found any bugs please
00046  *  email Ulf Ekstrom, ulfek@ifm.liu.se 
00047  *
00048  *
00049  *
00050  * This program is free software; you can redistribute it and/or
00051  * modify it under the terms of the GNU General Public License
00052  * as published by the Free Software Foundation; either version 2
00053  * of the License, or (at your option) any later version.
00054  *
00055  * This program is distributed in the hope that it will be useful,
00056  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00057  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00058  * GNU General Public License for more details.
00059  *
00060  * You should have received a copy of the GNU General Public License
00061  * along with this program; if not, write to the Free Software
00062  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00063  */
00064 #ifndef BITMASK_H
00065 #define BITMASK_H
00066 
00067 #include <SDL/begin_code.h>
00068 
00069 /* Define INLINE for different compilers. */
00070 #ifndef INLINE
00071 # ifdef __GNUC__
00072 #  define INLINE __inline__
00073 # else
00074 #  ifdef _MSC_VER
00075 #   define INLINE __inline
00076 #  else
00077 #   define INLINE
00078 #  endif
00079 # endif
00080 #endif
00081 
00082 #define BITW unsigned long int
00083 #define BITW_LEN 32
00084 #define BITW_MASK 31
00085 #define BITN(n) ((BITW)1 << (n))
00086 
00087 #ifdef __cplusplus
00088 extern "C" {
00089 #endif
00090 
00091 typedef struct bitmask
00092 {
00093   int w,h;
00094   BITW *bits;
00095 } bitmask;
00096 
00097 /* Creates a bitmask of width w and height h.
00098  * The mask is automatically cleared when created.
00099  */
00100 bitmask *bitmask_create(int w, int h);
00101 void bitmask_free(bitmask *m);
00102 
00103 /* Returns nonzero if the bit at (x,y) is set. 
00104  * Coordinates start at (0,0)
00105  */
00106 static INLINE int bitmask_getbit(const bitmask *m,int x,int y) 
00107 { 
00108   return m->bits[x/BITW_LEN*m->h + y] & BITN(x & BITW_MASK); 
00109 }
00110 
00111 
00112 /* Sets the bit at (x,y) */
00113 static INLINE void bitmask_setbit(bitmask *m,int x,int y)
00114 { 
00115   m->bits[x/BITW_LEN*m->h + y] |= BITN(x & BITW_MASK); 
00116 }
00117 
00118 
00119 /* Clears the bit at (x,y) */
00120 static INLINE void bitmask_clearbit(bitmask *m,int x,int y)
00121 { 
00122   m->bits[x/BITW_LEN*m->h + y] &= ~BITN(x & BITW_MASK); 
00123 }
00124 
00125 
00126 /* Returns nonzero if the masks overlap with the given offset. */
00127 DECLSPEC int SDLCALL bitmask_overlap(const bitmask *a,const bitmask *b,int xoffset, int yoffset);
00128 
00129 /* Like bitmask_overlap(), but will also give a point of intersection.
00130  * x and y are given in the coordinates of mask a, and are untouched if the is 
00131  * no overlap.
00132  */
00133 DECLSPEC int SDLCALL bitmask_overlap_pos(const bitmask *a,const bitmask *b,int xoffset, int yoffset, int *x, int *y);
00134 
00135 /* Returns the number of overlapping 'pixels' */
00136 DECLSPEC int SDLCALL bitmask_overlap_area(const bitmask *a,const bitmask *b,int xoffset, int yoffset);
00137 
00138 /* Draws mask b onto mask a (bitwise OR) 
00139  * Can be used to compose large (game background?) mask from 
00140  * several submasks, which may speed up the testing. 
00141  */
00142 DECLSPEC void SDLCALL bitmask_draw(bitmask *a,bitmask *b,int xoffset, int yoffset);
00143 
00144 #include <SDL/close_code.h>
00145 
00146 #ifdef __cplusplus
00147 }
00148 #endif
00149 
00150 
00151 #endif

Generated on Sat Oct 11 13:19:25 2003 for Spritelib by doxygen 1.3.4