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
unit_collide.h
Go to the documentation of this file.
1 #ifndef _CMD_COLLIDE_H_
2 #define _CMD_COLLIDE_H_
3 
4 #define SAFE_COLLIDE_DEBUG
5 #include "gfx/vec.h"
6 #include <algorithm>
7 #include <vector>
8 #include <stdio.h>
9 #include <assert.h>
10 #include "linecollide.h"
11 #include "collection.h"
12 #include "cmd/unit_generic.h"
13 #include <set>
14 #define COLLIDETABLESIZE sizeof (CTSIZ)
15 #define COLLIDETABLEACCURACY sizeof (CTACCURACY)
16 #define HUGEOBJECT sizeof (CTHUGE)
18 
19 class StarSystem;
25 template < class CTSIZ, class CTACCURACY, class CTHUGE >
27 {
29  UnitCollection hugeobjects;
30  UnitCollection ha;
31  UnitCollection hb;
32  UnitCollection *active_huge;
33  UnitCollection *accum_huge;
34  std::set< Unit* >act_huge;
35  std::set< Unit* >acc_huge;
38  StarSystem *activeStarSystem;
39  Unit *debugUnit;
40 
42 
43  static void hash_vec( double i, double j, double k, int &x, int &y, int &z )
44  {
45  x = hash_int( i );
46  y = hash_int( j );
47  z = hash_int( k );
48  }
50  static void hash_vec( const QVector &t, int &x, int &y, int &z )
51  {
52  hash_vec( t.i, t.j, t.k, x, y, z );
53  }
54 public: UnitHash3d( StarSystem *ss )
55  {
56  activeStarSystem = ss;
57  active_huge = &ha;
58  accum_huge = &hb;
59  }
61  {
62  if (active_huge == &ha) {
63  active_huge = &hb;
64  accum_huge = &ha;
65  } else {
66  active_huge = &ha;
67  accum_huge = &hb;
68  }
69  accum_huge->clear();
70  act_huge.swap( acc_huge );
71  acc_huge.clear();
72  }
73  void AddHugeToActive( Unit *un )
74  {
75  if ( acc_huge.find( un ) == acc_huge.end() ) {
76  acc_huge.insert( un );
77  accum_huge->prepend( un );
78  if ( act_huge.find( un ) == act_huge.end() ) {
79  act_huge.insert( un );
80  active_huge->prepend( un );
81  }
82  }
83  }
84 
86  static int hash_int( const double aye )
87  {
88  return ( (int) ( ( (aye < 0) ? (aye
89  -COLLIDETABLEACCURACY) : aye )
91  }
93  void Clear()
94  {
95  if ( !hugeobjects.empty() )
96  hugeobjects.clear();
97  if ( this->active_huge.size() )
98  ha.clear();
99  if ( this->accum_huge.size() )
100  hb.clear();
101  acc_huge.clear();
102  act_huge.clear();
103  for (int i = 0; i <= COLLIDETABLESIZE-1; i++)
104  for (int j = 0; j <= COLLIDETABLESIZE-1; j++)
105  for (int k = 0; k <= COLLIDETABLESIZE-1; k++)
106  if ( !table[i][j][k].empty() )
107  table[i][j][k].clear();
108  }
110  int Get( const QVector &Exact, UnitCollection *retval[], bool GetHuge )
111  {
112  retval[1] = &table[hash_int( Exact.i )][hash_int( Exact.j )][hash_int( Exact.k )];
113  retval[0] = active_huge;
114  if (GetHuge)
115  retval[0] = &hugeobjects;
116  return 2;
117  }
120  {
121  return hugeobjects;
122  }
124  int Get( const LineCollide *target, UnitCollection *retval[], bool GetHuge )
125  {
126  unsigned int sizer = 1;
127  double maxx = ( ceil( target->Maxi.i/COLLIDETABLEACCURACY ) )*COLLIDETABLEACCURACY;
128  double maxy = ( ceil( target->Maxi.j/COLLIDETABLEACCURACY ) )*COLLIDETABLEACCURACY;
129  double maxz = ( ceil( target->Maxi.k/COLLIDETABLEACCURACY ) )*COLLIDETABLEACCURACY;
130  int x, y, z;
131  if (target->Mini.i == maxx) maxx += COLLIDETABLEACCURACY/2;
132  if (target->Mini.j == maxy) maxy += COLLIDETABLEACCURACY/2;
133  if (target->Mini.k == maxz) maxz += COLLIDETABLEACCURACY/2;
134  retval[0] = &hugeobjects;
135  if (!GetHuge)
136  retval[0] = active_huge;
137  if (target->hhuge)
138  return sizer; //we can't get _everything
139  for (double i = target->Mini.i; i <= maxx; i += COLLIDETABLEACCURACY) {
140  x = hash_int( i );
141  for (double j = target->Mini.j; j <= maxy; j += COLLIDETABLEACCURACY) {
142  y = hash_int( j );
143  for (double k = target->Mini.k; k <= maxz; k += COLLIDETABLEACCURACY) {
144  z = hash_int( k );
145  if ( !table[x][y][z].empty() ) {
146  retval[sizer] = &table[x][y][z];
147  sizer++;
148  if (sizer >= HUGEOBJECT+1)
149  return sizer;
150  }
151  }
152  }
153  }
154  assert( sizer <= HUGEOBJECT+1 ); //make sure we didn't overrun our array
155  return sizer;
156  }
158  void Put( LineCollide *target, Unit *objectToPut )
159  {
160  int x, y, z;
161  double maxx = ( ceil( target->Maxi.i/COLLIDETABLEACCURACY ) )*COLLIDETABLEACCURACY;
162  double maxy = ( ceil( target->Maxi.j/COLLIDETABLEACCURACY ) )*COLLIDETABLEACCURACY;
163  double maxz = ( ceil( target->Maxi.k/COLLIDETABLEACCURACY ) )*COLLIDETABLEACCURACY;
164  //for huge calculation...not sure it's necessary
165  double minx = ( floor( target->Mini.i/COLLIDETABLEACCURACY ) )*COLLIDETABLEACCURACY;
166  double miny = ( floor( target->Mini.j/COLLIDETABLEACCURACY ) )*COLLIDETABLEACCURACY;
167  double minz = ( floor( target->Mini.k/COLLIDETABLEACCURACY ) )*COLLIDETABLEACCURACY;
168  if (target->Mini.i == maxx)
169  maxx += COLLIDETABLEACCURACY/2;
170  if (target->Mini.j == maxy) maxy += COLLIDETABLEACCURACY/2;
171  if (target->Mini.k == maxz) maxz += COLLIDETABLEACCURACY/2;
172  if ( fabs( (maxx
173  -minx)
174  *(maxy
175  -miny)
176  *(maxz
177  -minz) ) > ( (double) COLLIDETABLEACCURACY )*( (double) COLLIDETABLEACCURACY )
178  *( (double) COLLIDETABLEACCURACY )
179  *( (double) HUGEOBJECT ) ) {
180  target->hhuge = true;
181  hugeobjects.prepend( objectToPut );
182  return;
183  } else {
184  target->hhuge = false;
185  }
186  for (double i = target->Mini.i; i < maxx; i += COLLIDETABLEACCURACY) {
187  x = hash_int( i );
188  for (double j = target->Mini.j; j < maxy; j += COLLIDETABLEACCURACY) {
189  y = hash_int( j );
190  for (double k = target->Mini.k; k < maxz; k += COLLIDETABLEACCURACY) {
191  z = hash_int( k );
192  table[x][y][z].prepend( objectToPut );
193  }
194  }
195  }
196  }
197  static bool removeFromVector( UnitCollection &myvector, Unit *objectToKill )
198  {
199  bool ret = false;
200  un_iter removal = myvector.createIterator();
201  Unit *un;
202  while ( (un = *removal) ) {
203  if (un == objectToKill) {
204  ret = true;
205  removal.remove();
206  } else {
207  ++removal;
208  }
209  }
210  return ret;
211  }
212  bool Eradicate( Unit *objectToKill )
213  {
214  bool ret = removeFromVector( hugeobjects, objectToKill );
215  for (unsigned int i = 0; i <= COLLIDETABLESIZE-1; i++)
216  for (unsigned int j = 0; j <= COLLIDETABLESIZE-1; j++)
217  for (unsigned int k = 0; k <= COLLIDETABLESIZE-1; k++)
218  ret |= removeFromVector( table[i][j][k], objectToKill );
219  return ret;
220  }
222  bool Remove( const LineCollide *target, Unit *objectToKill )
223  {
224  bool ret = false;
225  int x, y, z;
226  double maxx = ( ceil( target->Maxi.i/COLLIDETABLEACCURACY ) )*COLLIDETABLEACCURACY;
227  double maxy = ( ceil( target->Maxi.j/COLLIDETABLEACCURACY ) )*COLLIDETABLEACCURACY;
228  double maxz = ( ceil( target->Maxi.k/COLLIDETABLEACCURACY ) )*COLLIDETABLEACCURACY;
229  if (target->Mini.i == maxx) maxx += COLLIDETABLEACCURACY/2;
230  if (target->Mini.j == maxy) maxy += COLLIDETABLEACCURACY/2;
231  if (target->Mini.k == maxz) maxz += COLLIDETABLEACCURACY/2;
232  if (!target->hhuge)
233  for (double i = target->Mini.i; i < maxx; i += COLLIDETABLEACCURACY) {
234  x = hash_int( i );
235  for (double j = target->Mini.j; j < maxy; j += COLLIDETABLEACCURACY) {
236  y = hash_int( j );
237  for (double k = target->Mini.k; k < maxz; k += COLLIDETABLEACCURACY) {
238  z = hash_int( k );
239  ret |= removeFromVector( table[x][y][z], objectToKill );
240  }
241  }
242  }
243  if (!ret && !target->hhuge)
244  fprintf( stderr, "Nonfatal Collide Error\n" );
245  if (!ret || target->hhuge)
246  ret |= removeFromVector( hugeobjects, objectToKill );
247  return ret;
248  }
249 };
250 
251 const int tablehuge = 27;
252 const int coltableacc = 128;
253 const int coltablesize = 20;
255 {
256  unsigned int blocupdate;
257 public: CollideTable( StarSystem *ss ) : blocupdate( 0 )
258  , c( ss ) {}
259  void Update()
260  {
261  ++blocupdate;
262  }
264 };
265 
267 bool TableLocationChanged( const QVector&, const QVector& );
268 bool TableLocationChanged( const LineCollide&, const QVector&, const QVector& );
269 void KillCollideTable( LineCollide *lc, StarSystem *ss );
271 
272 class csOPCODECollider;
273 const unsigned int collideTreesMaxTrees = 16;
275 {
276  std::string hash_key;
277 
279 
280  bool usingColTree() const
281  {
282  return rapidColliders[0] != NULL;
283  }
284 
285  csOPCODECollider * colTree( Unit *un, const Vector &othervelocity ); //gets the appropriately scaled unit collide tree
286 
287  // Not sure at the moment where we decide to collide to the shield ...since all we ever compare to is colTree in Collide()
288  // Yet, this is used somewhere.
290 
291  int refcount;
292  collideTrees( const std::string &hk, csOPCODECollider *cT, csOPCODECollider *cS );
293  void Inc()
294  {
295  refcount++;
296  }
297  void Dec();
298  static collideTrees * Get( const std::string &hash_key );
299 };
300 
301 #endif
302