00001 /* 00002 Serial Collision detection classes. 00003 00004 Orion Sky Lawlor, olawlor@acm.org, 2003/3/19 00005 */ 00006 #ifndef __UIUC_CHARM_COLLIDE_SERIAL_H 00007 #define __UIUC_CHARM_COLLIDE_SERIAL_H 00008 00009 #include "collide_util.h" 00010 #include "collide_buffers.h" 00011 #include "collide_cfg.h" 00012 00013 #if !COLLIDE_STATS 00014 # define STATS(x) /* empty */ 00015 #else 00016 # define STATS(x) stats::x; 00017 //Collision statistics (for measurement-based optimization) 00018 class stats {public: 00019 static int objects;//Total number of objects 00020 static int gridCells;//Total number of grid cells 00021 static int gridAdds;//Number of additions to grid cells 00022 static int gridSizes[3];//Total sizes of grid cells in each dimension 00023 static int recursiveCalls;//Number of recursive calls 00024 static int simpleCalls;//Number of simple calls 00025 static int simpleFallbackCalls;//Number of unsplittable CollideOctants 00026 static int splits[3];//Number of divisions along each axis 00027 static int splitFailures[3];//Number of failed divisions along each axis 00028 static int pivots;//Number of pivot operations (CollideOctant::splitAt) 00029 static int rejHomo;//Call rejected for being from one object 00030 static int rejID;//Pair rejected for being out-of-order 00031 static int rejBbox;//Pair rejected for BBox mismatch 00032 static int rejTerritory[3];//Pair rejected for being out of territory 00033 static int rejCollide;//Pair rejected by slow intersection algorithm 00034 static int Collisions;//Number of actual intersections 00035 static void print(void); 00036 }; 00037 #endif 00038 00039 class CollideObjConsumer { 00040 public: 00041 virtual void add(const CollideObjRec *obj)=0; 00042 }; 00043 00044 //A set of objects, organized by the location of the small 00045 // corner of their bbox. 00046 // Objects with their smallest bbox corner here are called "home" polys. 00047 class CollideOctant : public growableBufferT<const CollideObjRec *>, public CollideObjConsumer 00048 { 00049 typedef growableBufferT<const CollideObjRec *> parent; 00050 int nHome;//Number of non-boundary elements 00051 bbox3d box;//We need every object that touches this region 00052 bbox3d territory;//We are responsible for intersections here 00053 00054 //Figure out what index to divide our polys at 00055 int splitAt(int alongAxis); 00056 00057 public: 00058 CollideOctant(int size,bbox3d myTerritory) 00059 : parent(size),territory(myTerritory) 00060 {nHome=0;box.empty();} 00061 virtual ~CollideOctant(); 00062 00063 void setBbox(const bbox3d &b) {box=b;} 00064 const bbox3d &getBbox(void) const {return box;} 00065 const bbox3d &getTerritory(void) const {return territory;} 00066 bool x_inTerritory(real v) const {return territory.axis(0).containsHalf(v);} 00067 bool y_inTerritory(real v) const {return territory.axis(1).containsHalf(v);} 00068 bool z_inTerritory(real v) const {return territory.axis(2).containsHalf(v);} 00069 00070 //Get total count 00071 int getTotal(void) const {return length();} 00072 //Get home count 00073 int getHome(void) const {return nHome;} 00074 //Mark 0..h as at home 00075 void markHome(int h) {nHome=h;} 00076 00077 //Grow to contain this added object (adjusts length if needed) 00078 void growTo(const CollideObjRec *b) { 00079 box.add(b->getBbox()); 00080 push_fast(b); 00081 } 00082 //If needed, add this boundary poly (length must be preallocated) 00083 void addIfBoundary(const CollideObjRec *b) { 00084 if (box.intersects(b->getBbox())) push_fast(b); 00085 } 00086 00087 // Divide this CollideOctant along the given axis. 00088 // This CollideOctant shrinks, the new one grows. 00089 // Respects non-home polys. 00090 CollideOctant *divide(int alongAxis); 00091 00092 void check(void) const;//Ensure our constraints hold 00093 void print(const char *desc=NULL) const; 00094 virtual void add(const CollideObjRec *); 00095 00096 void findCollisions(int splitAxis,CollisionList &dest); 00097 void findCollisions(CollisionList &dest) 00098 {findCollisions(0,dest);} 00099 }; 00100 00101 #endif //def(thisHeader)