Vegastrike 0.5.1 rc1  1.0
Original sources for Vegastrike Evolved
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
hashtable_3d.h
Go to the documentation of this file.
1 #ifndef _HASHTABLE_3D_H_
2 #define _HASHTABLE_3D_H_
3 #include "gfx/vec.h"
4 #include <algorithm>
5 #include <vector>
6 #include <stdio.h>
7 #include <assert.h>
8 #include "linecollide.h"
9 //#define COLLIDETABLESIZE sizeof(CTSIZ)
10 //#define COLLIDETABLEACCURACY sizeof (CTACCURACY)
12 //#define HUGEOBJECT sizeof (CTHUGE)
13 
19 template < class T, int COLLIDETABLESIZE, int COLLIDETABLEACCURACY, int HUGEOBJECT >
21 {
23  std::vector< T >hugeobjects;
25  std::vector< T >table[COLLIDETABLESIZE][COLLIDETABLESIZE][COLLIDETABLESIZE];
27  static void hash_vec( double i, double j, double k, int &x, int &y, int &z )
28  {
29  x = hash_int( i );
30  y = hash_int( j );
31  z = hash_int( k );
32  }
34  static void hash_vec( const QVector &t, int &x, int &y, int &z )
35  {
36  hash_vec( t.i, t.j, t.k, x, y, z );
37  }
38 public:
40  int hash_int( const double aye )
41  {
42  return ( (int) ( ( (aye < 0) ? (aye
43  -COLLIDETABLEACCURACY) : aye )
45  }
47  void Clear()
48  {
49  hugeobjects.clear();
50  for (int i = 0; i <= COLLIDETABLESIZE-1; i++)
51  for (int j = 0; j <= COLLIDETABLESIZE-1; j++)
52  for (int k = 0; k <= COLLIDETABLESIZE-1; k++)
53  if ( table[i][j][k].size() )
54  table[i][j][k].clear();
55  }
57  int Get( const QVector &Exact, std::vector< T > *retval[] )
58  {
59  retval[1] = &table[hash_int( Exact.i )][hash_int( Exact.j )][hash_int( Exact.k )];
60  //retval+=hugeobjects;
61  //blah = blooh;
62  retval[0] = &hugeobjects;
63  return 2;
64  }
66  std::vector< T >& GetHuge()
67  {
68  return hugeobjects;
69  }
71  int Get( const LineCollide *target, std::vector< T > *retval[] )
72  {
73  unsigned int sizer = 1;
74  //int minx,miny,minz,maxx,maxy,maxz;
75  //hash_vec(Min,minx,miny,minz);
76  //hash_vec(Max,maxx,maxy,maxz);
77  double maxx = ( ceil( target->Maxi.i/COLLIDETABLEACCURACY ) )*COLLIDETABLEACCURACY;
78  double maxy = ( ceil( target->Maxi.j/COLLIDETABLEACCURACY ) )*COLLIDETABLEACCURACY;
79  double maxz = ( ceil( target->Maxi.k/COLLIDETABLEACCURACY ) )*COLLIDETABLEACCURACY;
80  int x, y, z;
81  if (target->Mini.i == maxx) maxx += COLLIDETABLEACCURACY/2;
82  if (target->Mini.j == maxy) maxy += COLLIDETABLEACCURACY/2;
83  if (target->Mini.k == maxz) maxz += COLLIDETABLEACCURACY/2;
84  retval[0] = &hugeobjects;
85  if (target->hhuge)
86  return sizer; //we can't get _everything
87  for (double i = target->Mini.i; i < maxx; i += COLLIDETABLEACCURACY) {
88  x = hash_int( i );
89  for (double j = target->Mini.j; j < maxy; j += COLLIDETABLEACCURACY) {
90  y = hash_int( j );
91  for (double k = target->Mini.k; k < maxz; k += COLLIDETABLEACCURACY) {
92  z = hash_int( k );
93  if ( !table[x][y][z].empty() ) {
94  retval[sizer] = &table[x][y][z];
95  sizer++;
96  if (sizer >= HUGEOBJECT+1)
97  return sizer;
98  }
99  }
100  }
101  }
102  assert( sizer <= HUGEOBJECT+1 ); //make sure we didn't overrun our array
103  return sizer;
104  }
106  void Put( LineCollide *target, const T objectToPut )
107  {
108  int x, y, z;
109  double maxx = ( ceil( target->Maxi.i/COLLIDETABLEACCURACY ) )*COLLIDETABLEACCURACY;
110  double maxy = ( ceil( target->Maxi.j/COLLIDETABLEACCURACY ) )*COLLIDETABLEACCURACY;
111  double maxz = ( ceil( target->Maxi.k/COLLIDETABLEACCURACY ) )*COLLIDETABLEACCURACY;
112  //for huge calculation...not sure it's necessary
113  double minx = ( floor( target->Mini.i/COLLIDETABLEACCURACY ) )*COLLIDETABLEACCURACY;
114  double miny = ( floor( target->Mini.j/COLLIDETABLEACCURACY ) )*COLLIDETABLEACCURACY;
115  double minz = ( floor( target->Mini.k/COLLIDETABLEACCURACY ) )*COLLIDETABLEACCURACY;
116  if (target->Mini.i == maxx)
117  maxx += COLLIDETABLEACCURACY/2;
118  if (target->Mini.j == maxy) maxy += COLLIDETABLEACCURACY/2;
119  if (target->Mini.k == maxz) maxz += COLLIDETABLEACCURACY/2;
120  if ( fabs( (maxx
121  -minx)
122  *(maxy
123  -miny)
124  *(maxz
125  -minz) ) > ( (double) COLLIDETABLEACCURACY )*( (double) COLLIDETABLEACCURACY )
126  *( (double) COLLIDETABLEACCURACY )
127  *( (double) HUGEOBJECT ) ) {
128  target->hhuge = true;
129  hugeobjects.push_back( objectToPut );
130  return;
131  } else {
132  target->hhuge = false;
133  }
134  for (double i = target->Mini.i; i < maxx; i += COLLIDETABLEACCURACY) {
135  x = hash_int( i );
136  for (double j = target->Mini.j; j < maxy; j += COLLIDETABLEACCURACY) {
137  y = hash_int( j );
138  for (double k = target->Mini.k; k < maxz; k += COLLIDETABLEACCURACY) {
139  z = hash_int( k );
140  table[x][y][z].push_back( objectToPut );
141  }
142  }
143  }
144  }
145  static bool removeFromVector( std::vector< T > &myvector, T &objectToKill )
146  {
147  bool ret = false;
148  typename std::vector< T >::iterator removal = myvector.begin();
149  while ( removal != myvector.end() ) {
150  removal = std::find( removal, myvector.end(), objectToKill );
151  if ( removal != myvector.end() ) {
152  ret = true;
153  int offset = removal-myvector.begin();
154  objectToKill = *removal;
155  myvector.erase( removal );
156  removal = myvector.begin()+offset;
157  }
158  }
159  return ret;
160  }
161  bool Eradicate( T objectToKill )
162  {
163  bool ret = removeFromVector( hugeobjects, objectToKill );
164  for (unsigned int i = 0; i <= COLLIDETABLESIZE-1; i++)
165  for (unsigned int j = 0; j <= COLLIDETABLESIZE-1; j++)
166  for (unsigned int k = 0; k <= COLLIDETABLESIZE-1; k++)
167  ret |= removeFromVector( table[i][j][k], objectToKill );
168  return ret;
169  }
171  bool Remove( const LineCollide *target, T &objectToKill )
172  {
173  //int minx,miny,minz,maxx,maxy,maxz;
174  //hash_vec(target->Mini,minx,miny,minz);
175  //hash_vec(target->Maxi,maxx,maxy,maxz);
176  bool ret = false;
177  int x, y, z;
178  double maxx = ( ceil( target->Maxi.i/COLLIDETABLEACCURACY ) )*COLLIDETABLEACCURACY;
179  double maxy = ( ceil( target->Maxi.j/COLLIDETABLEACCURACY ) )*COLLIDETABLEACCURACY;
180  double maxz = ( ceil( target->Maxi.k/COLLIDETABLEACCURACY ) )*COLLIDETABLEACCURACY;
181  if (target->Mini.i == maxx) maxx += COLLIDETABLEACCURACY/2;
182  if (target->Mini.j == maxy) maxy += COLLIDETABLEACCURACY/2;
183  if (target->Mini.k == maxz) maxz += COLLIDETABLEACCURACY/2;
184  if (!target->hhuge)
185  for (double i = target->Mini.i; i < maxx; i += COLLIDETABLEACCURACY) {
186  x = hash_int( i );
187  for (double j = target->Mini.j; j < maxy; j += COLLIDETABLEACCURACY) {
188  y = hash_int( j );
189  for (double k = target->Mini.k; k < maxz; k += COLLIDETABLEACCURACY) {
190  z = hash_int( k );
191  ret |= removeFromVector( table[x][y][z], objectToKill );
192  }
193  }
194  }
195  if (!ret && !target->hhuge)
196  fprintf( stderr, "Nonfatal Collide Error\n" );
197  if (!ret || target->hhuge)
198  ret |= removeFromVector( hugeobjects, objectToKill );
199  return ret;
200  }
201 };
202 
203 #endif
204