00001 #ifndef __OBSTACLE_GRID_H__
00002 #define __OBSTACLE_GRID_H__
00003 #include "obstacle.h"
00004 #include "hashtable.h"
00005
00007
00011 class VectorHash {
00013 static float frem (float a, float b) {
00014 float ne=fmod(a,b);
00015 if (ne<0) {
00016 return b+ne;
00017 } else {
00018 return ne;
00019 }
00020 }
00021 public:
00023 unsigned int hashval;
00025 static const float shortWidth() {return 65536-129;}
00026
00028 inline operator unsigned int () const {
00029 return hashval;
00030 }
00031 VectorHash () {
00032 hashval=0;
00033 }
00034 void operator= (const VectorHash &oth) {
00035 hashval=oth.hashval;
00036 }
00037 VectorHash (const VectorHash &oth) : hashval(oth.hashval) {}
00038 VectorHash (const Vector &coord) {
00039 Vector crd (coord.Scale(ScaleAmt));
00040 hashval =((unsigned int)((frem(floor(crd.i),shortWidth()))+(shortWidth()*floor(crd.j))));
00041 }
00043 bool operator== (const VectorHash &oth)const {
00044 return hashval==oth.hashval;
00045 }
00047 bool operator< (const VectorHash &oth)const {
00048 return hashval<oth.hashval;
00049 }
00051 static const float ScaleAmt;
00052 };
00053
00055
00057
00061 #include <stdio.h>
00062 class ObstacleGrid {
00063 public:
00064 typedef Hashtable <class VectorHash, Obstacle *, 65535> ObstMap;
00065 typedef std::multimap <Obstacle::ModelRef, Obstacle> MeshSortedObstMap;
00066 private:
00068 ObstMap collObst;
00070
00072 MeshSortedObstMap drawObst;
00073 public:
00075 ObstMap::iterator getByColl (const Vector& coord) {
00076 VectorHash hash (coord);
00077 return collObst.find (hash);
00078 }
00080 MeshSortedObstMap::iterator getByDraw (const Obstacle::ModelRef& model) {
00081 return drawObst.find (model);
00082 }
00084 class MyFuncBase {
00085 protected:
00086 ObstacleGrid *parent;
00087 Obstacle *obst;
00088 public:
00090 MyFuncBase (ObstacleGrid *myparent, Obstacle *obstacle)
00091 : parent (myparent), obst (obstacle) {
00092 }
00093 };
00095 class PutFunc : public MyFuncBase {
00096 public:
00097 PutFunc(ObstacleGrid * myparent, Obstacle * obstacle) : MyFuncBase(myparent,obstacle){}
00099 inline void operator() (Vector pos){
00100 ObstMap::iterator iter=parent->collObst.insert (ObstMap::value_type(VectorHash (pos), obst));
00101 printf ("Adding %X (%f,%f)\n",&(*iter),pos.i,pos.j);
00102 }
00103 };
00105 class EraseFunc : public MyFuncBase {
00106 public:
00107 EraseFunc(ObstacleGrid * myparent, Obstacle * obstacle) : MyFuncBase(myparent,obstacle){}
00109 inline void operator() (Vector pos){
00110 ObstMap::iterator iter=parent->getByColl(pos);
00111 while (iter!=iter.end()) {
00112 if (&(*iter->second)==obst) {
00113 printf ("Erasing %X (%f,%f)\n",obst,pos.i,pos.j);
00114 parent->collObst.erase(iter);
00115 break;
00116 }
00117 ++iter;
00118 }
00119 }
00120 };
00121 friend class MyFuncBase;
00122 friend class PutFunc;
00123 friend class EraseFunc;
00125 MeshSortedObstMap::iterator put (const Obstacle &o) {
00126 MeshSortedObstMap::value_type v(o.model,o);
00127 MeshSortedObstMap::iterator i = drawObst.insert (v);
00128 Obstacle * obst = &(*i).second;
00129 const Vector fudgeFactor (0,0,0);
00130 Vector firstcoord (obst->getPosition()+obst->getMin()-fudgeFactor);
00131 Vector lastcoord (obst->getPosition()+obst->getMax()+fudgeFactor);
00132 printf("ADD %X (%f,%f),(%f,%f)\n",obst,firstcoord.i,firstcoord.j,lastcoord.i,lastcoord.j);
00133 forEach2dVector (firstcoord, lastcoord, PutFunc(this, obst),Vector(1/VectorHash::ScaleAmt,1/VectorHash::ScaleAmt,1/VectorHash::ScaleAmt));
00134 return i;
00135 }
00137 void erase (Obstacle &obst) {
00138 {
00139 const Vector fudgeFactor (.05/VectorHash::ScaleAmt,.05/VectorHash::ScaleAmt,.05/VectorHash::ScaleAmt);
00140 Vector firstcoord (obst.getPosition()+obst.getMin()-fudgeFactor);
00141 Vector lastcoord (obst.getPosition()+obst.getMax()+fudgeFactor);
00142 printf("ERASE %X (%f,%f),(%f,%f)\n",&obst,firstcoord.i,firstcoord.j,lastcoord.i,lastcoord.j);
00143 forEach2dVector (firstcoord, lastcoord, EraseFunc(this, &obst),Vector(1/VectorHash::ScaleAmt,1/VectorHash::ScaleAmt,1/VectorHash::ScaleAmt));
00144 }{
00145 for (MeshSortedObstMap::iterator miter=drawObst.find(obst.model);miter!=drawObst.end()&&(*miter).first==obst.model;++miter) {
00146 if (&(*miter).second==(&obst)) {
00147 drawObst.erase(miter);
00148 break;
00149 }
00150 }
00151 }
00152
00153 }
00155
00157 ObstMap::vector_type &getCollObstacleList (const Vector &coord) {
00158 return collObst.GetAll(VectorHash (coord));
00159 }
00161
00163 std::vector <Obstacle> getDrawObstacleList (Collidable::ModelRef ref) {
00164 using std::vector;
00165 MeshSortedObstMap::iterator iter=getByDraw (ref);
00166 Collidable::ModelRef hash ((*iter).first);
00167 vector <Obstacle> obstvec;
00168 while (iter!=endByDraw()&&(*iter).first==hash) {
00169 obstvec.push_back ((*iter).second);
00170 iter++;
00171 }
00172 return obstvec;
00173 }
00174
00175 void collideWithSpectres () {
00176
00177
00178 }
00179
00181
00182 ObstMap::iterator::it_type endByColl (ObstMap::iterator tablenum) {
00183 return tablenum.end();
00184 }
00185
00187 const MeshSortedObstMap::iterator endByDraw () {return drawObst.end();}
00188 };
00189
00190 const float VectorHash::ScaleAmt=(float)(2.);
00191
00192 #endif