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
collide.cpp
Go to the documentation of this file.
1 #include "cmd/collide.h"
2 #include "vegastrike.h"
3 #include "unit_generic.h"
4 #include "beam.h"
5 #include "bolt.h"
6 #include "gfx/mesh.h"
7 #include "unit_collide.h"
8 #include "physics.h"
9 
12 #include "collide2/basecollider.h"
13 
14 #include "hashtable.h"
15 #include <string>
16 #include "vs_globals.h"
17 #include "configxml.h"
19 collideTrees::collideTrees( const std::string &hk, csOPCODECollider *cT,
20  csOPCODECollider *cS ) : hash_key( hk )
21  , colShield( cS )
22 {
23  for (unsigned int i = 0; i < collideTreesMaxTrees; ++i)
24  rapidColliders[i] = NULL;
25  rapidColliders[0] = cT;
26 
27  refcount = 1;
28  unitColliders.Put( hash_key, this );
29 }
30 float loge2 = log( 2.f );
31 
32 csOPCODECollider* collideTrees::colTree( Unit *un, const Vector &othervelocity )
33 {
34  const float const_factor = 1;
35  float magsqr = un->GetVelocity().MagnitudeSquared();
36  float newmagsqr = (un->GetVelocity()-othervelocity).MagnitudeSquared();
37  float speedsquared = const_factor*const_factor*(magsqr > newmagsqr ? newmagsqr : magsqr);
38  static unsigned int max_collide_trees = static_cast<unsigned int>(XMLSupport::parse_int( vs_config->getVariable( "physics", "max_collide_trees", "16384" ) ));
39  if (un->rSize()*un->rSize() > SIMULATION_ATOM*SIMULATION_ATOM*speedsquared || max_collide_trees == 1)
40  return rapidColliders[0];
41  if (rapidColliders[0] == NULL)
42  return NULL;
43  if (un->rSize() <= 0.) //Shouldn't happen bug I've seen this for asteroid fields...
44  return NULL;
45  //Force pow to 0 in order to avoid nan problems...
46  unsigned int pow = 0;
47  if (pow >= collideTreesMaxTrees || pow >= max_collide_trees)
48  pow = collideTreesMaxTrees-1;
49  int val = 1<<pow;
50  if (rapidColliders[pow] == NULL)
51  rapidColliders[pow] = un->getCollideTree( Vector( 1, 1, val ) );
52  return rapidColliders[pow];
53 }
54 
55 collideTrees* collideTrees::Get( const std::string &hash_key )
56 {
57  return unitColliders.Get( hash_key );
58 }
59 
61 {
62  refcount--;
63  if (refcount == 0) {
64  unitColliders.Delete( hash_key );
65  for (unsigned int i = 0; i < collideTreesMaxTrees; ++i)
66  if (rapidColliders[i])
67  delete rapidColliders[i];
68  if (colShield)
69  delete colShield;
70  delete this;
71  return;
72  }
73 }
74 
75 bool TableLocationChanged( const QVector &Mini, const QVector &minz )
76 {
77  return _Universe->activeStarSystem()->collidetable->c.hash_int( Mini.i )
83 }
84 
85 bool TableLocationChanged( const LineCollide &lc, const QVector &minx, const QVector &maxx )
86 {
87  return TableLocationChanged( lc.Mini, minx ) || TableLocationChanged( lc.Maxi, maxx );
88 }
89 
91 {
92  if (lc->type == LineCollide::UNIT)
93  ss->collidetable->c.Remove( lc, lc->object.u );
94  else
95  printf( "such collide types as %d not allowed", lc->type );
96 }
97 
99 {
100  if (lc->type == LineCollide::UNIT) {
101  return ss->collidetable->c.Eradicate( lc->object.u );
102  } else {
103  printf( "such collide types as %d not allowed", lc->type );
104  return false;
105  }
106 }
107 
109 {
110  if (tmp.type == LineCollide::UNIT)
111  ss->collidetable->c.Put( &tmp, tmp.object.u );
112  else
113  printf( "such collide types as %d not allowed", tmp.type );
114 }
115 
116 bool lcwithin( const LineCollide &lc, const LineCollide &tmp )
117 {
118  return lc.Mini.i< tmp.Maxi.i
119  && lc.Mini.j< tmp.Maxi.j
120  && lc.Mini.k< tmp.Maxi.k
121  && lc.Maxi.i >tmp.Mini.i
122  && lc.Maxi.j >tmp.Mini.j
123  && lc.Maxi.k >tmp.Mini.k;
124 }
125 
127 {
128  const unsigned int A = 9301;
129  const unsigned int C = 49297;
130  const unsigned int M = 233280;
131  static unsigned int seed = 3259235;
132  seed = (seed*A+C)%M;
133  return seed < (M/100);
134 }
135 
137 {
139 }
140 
141 static bool beamCheckCollision( QVector pos, float len, const Collidable &un )
142 {
143  return (un.GetPosition()-pos).MagnitudeSquared() <= len*len+2*len*un.radius+un.radius*un.radius;
144 }
145 
146 void Beam::CollideHuge( const LineCollide &lc, Unit *targetToCollideWith, Unit *firer, Unit *superunit )
147 {
148  QVector x0 = center;
149  QVector v = direction*curlength;
150  if (is_null( superunit->location[Unit::UNIT_ONLY] ) && curlength) {
151  if (targetToCollideWith)
152  this->Collide( targetToCollideWith, firer, superunit );
153  } else if (curlength) {
155 
156  CollideMap::iterator superloc = superunit->location[Unit::UNIT_ONLY];
157  CollideMap::iterator tmore = superloc;
158  if ( !cm->Iterable( superloc ) ) {
159  CollideArray::CollidableBackref *br = static_cast< CollideArray::CollidableBackref* > (superloc);
161  if ( tmploc == cm->end() )
162  tmploc--;
163  tmore = superloc = tmploc; //don't decrease tless
164  } else {
165  ++tmore;
166  }
167  double r0 = x0.i;
168  double r1 = x0.i+v.i;
169  double minlook = r0 < r1 ? r0 : r1;
170  double maxlook = r0 < r1 ? r1 : r0;
171  bool targcheck = false;
172  maxlook += ( maxlook-(*superunit->location[Unit::UNIT_ONLY])->getKey() )+2*curlength; //double damage, yo
173  minlook += ( minlook-(*superunit->location[Unit::UNIT_ONLY])->getKey() )-2*curlength*curlength;
174  //(a+2*b)^2-(a+b)^2 = 3b^2+2ab = 2b^2+(a+b)^2-a^2
175  if ( superloc != cm->begin()
176  && minlook < (*superunit->location[Unit::UNIT_ONLY])->getKey() ) {
177  //less traversal
178  CollideMap::iterator tless = superloc;
179  --tless;
180  while ( (*tless)->getKey() >= minlook ) {
181  CollideMap::iterator curcheck = tless;
182  bool breakit = false;
183  if ( tless != cm->begin() )
184  --tless;
185  else
186  breakit = true;
187  if ( (*curcheck)->radius > 0 ) {
188  if ( beamCheckCollision( center, curlength, (**curcheck) ) ) {
189  Unit *tmp = (**curcheck).ref.unit;
190  this->Collide( tmp, firer, superunit );
191  targcheck = (targcheck || tmp == targetToCollideWith);
192  }
193  }
194  if (breakit)
195  break;
196  }
197  }
198  if ( maxlook > (*superunit->location[Unit::UNIT_ONLY])->getKey() ) {
199  //greater traversal
200  while (tmore != cm->end() && (*tmore)->getKey() <= maxlook) {
201  if ( (*tmore)->radius > 0 ) {
202  Unit *un = (*tmore)->ref.unit;
203  if ( beamCheckCollision( center, curlength, **tmore++ ) ) {
204  this->Collide( un, firer, superunit );
205  targcheck = (targcheck || un == targetToCollideWith);
206  }
207  } else {++tmore; }}
208  }
209  if (targetToCollideWith && !targcheck)
210  this->Collide( targetToCollideWith, firer, superunit );
211  }
212 }
213