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
flybywire.cpp
Go to the documentation of this file.
1 #include "flybywire.h"
2 #include "vegastrike.h"
3 #include <math.h>
4 #include <stdio.h>
5 #include "cmd/unit_generic.h"
6 #include "lin_time.h"
7 #include "gfx/cockpit_generic.h"
8 #include "vs_globals.h"
9 #include "config_xml.h"
10 #define VELTHRESHOLD .1
11 #define ANGVELTHRESHOLD .01
12 
14 
16 
18 
19 //Careful with this macro!!! I can't wrap it in do{...}while(0) because it declares variables that are then
20 //used by code that follows. Be sure it's never instantiated like a single statement body of a conditional
21 //or loop, or the formatter might remove the braces and then you'll be in a heap of trouble looking for the
22 //bug... --chuck_starchaser.
23 #define MATCHLINVELSETUP() \
24  Unit *match = parent->VelocityReference(); Vector desired( desired_velocity ); Vector FrameOfRef( 0, \
25  0, \
26  0 ); \
27  if (match != NULL) {float dif1, dif2; match->GetVelocityDifficultyMult( dif1 ); dif1 *= \
28  match->graphicOptions.WarpFieldStrength; \
29  parent->GetVelocityDifficultyMult( dif2 ); \
30  if (match->graphicOptions.WarpFieldStrength > 1) {dif2 *= parent->graphicOptions.WarpFieldStrength; \
31  } \
32  FrameOfRef = \
33  parent->ToLocalCoordinates( match->GetWarpVelocity()*dif1 \
34  /dif2 ); } \
35  if (!LocalVelocity) {desired = parent->ToLocalCoordinates( \
36  desired ); } \
37  Vector velocity( \
38  parent->UpCoordinateLevel( parent->GetVelocity() ) )
39 
40 #define MATCHLINVELEXECUTE() \
41  do { \
42  parent->Thrust( (parent->GetMass() \
43  *(parent->ClampVelocity( desired, \
44  afterburn )+FrameOfRef-velocity)/SIMULATION_ATOM), \
45  afterburn ); \
46  } \
47  while (0)
48 
57 void MatchLinearVelocity::Execute()
58 {
59  if ( !suborders.empty() ) {
60  static int i = 0;
61  if (i++%1000 == 0)
62  VSFileSystem::vs_fprintf( stderr, "cannot execute suborders as Linear Velocity Matcher" ); //error printout just in case
63  }
65  if (willfinish) {
66  if ( (done = fabs( desired.i+FrameOfRef.i-velocity.i ) < VELTHRESHOLD && fabs( desired.j+FrameOfRef.j-velocity.j )
67  < VELTHRESHOLD && fabs( desired.k+FrameOfRef.k-velocity.k ) < VELTHRESHOLD) )
68  return;
69  }
71 }
72 
74 {
75 #ifdef ORDERDEBUG
76  VSFileSystem::vs_fprintf( stderr, "mlv%x", this );
77  fflush( stderr );
78 #endif
79 }
80 
82 {
83  bool temp = done;
85  done = temp;
86  Vector angvel( parent->UpCoordinateLevel( parent->GetAngularVelocity() ) );
87  if (willfinish)
88  if (fabs( desired_roll-angvel.k ) < ANGVELTHRESHOLD)
89  return;
90  //prevent matchangvel from resetting this (kinda a hack)
91  parent->ApplyLocalTorque( parent->GetMoment()*Vector( 0, 0, desired_roll-angvel.k )/SIMULATION_ATOM );
92  parent->ApplyLocalTorque( parent->GetMoment()*Vector( 0, 0, desired_roll-angvel.k )/SIMULATION_ATOM );
93 }
94 
96 {
97  bool temp = done;
99  done = temp;
100  Vector desired( desired_ang_velocity );
101 
103  if (!LocalAng)
104  desired = parent->ToLocalCoordinates( desired );
105  if (willfinish) {
106  if ( (done = fabs( desired.i-angvel.i ) < ANGVELTHRESHOLD && fabs( desired.j-angvel.j ) < ANGVELTHRESHOLD
107  && fabs( desired.k-angvel.k ) < ANGVELTHRESHOLD) )
108  return;
109  }
112 }
113 
115 {
116 #ifdef ORDERDEBUG
117  VSFileSystem::vs_fprintf( stderr, "mav%x", this );
118  fflush( stderr );
119 #endif
120 }
121 
123 {
125 
127  if (willfinish) {
128  if ( (done = done && fabs( desired.i-velocity.i ) < VELTHRESHOLD && fabs( desired.j-velocity.j ) < VELTHRESHOLD
129  && fabs( desired.k-velocity.k ) < VELTHRESHOLD) )
130  return;
131  }
133 }
134 
136 {
137 #ifdef ORDERDEBUG
138  VSFileSystem::vs_fprintf( stderr, "mv%x", this );
139  fflush( stderr );
140 #endif
141 }
142 
143 static bool getControlType()
144 {
145  static bool control = XMLSupport::parse_bool( vs_config->getVariable( "physics", "CarControl",
146 #ifdef CAR_SIM
147  "true"
148 #else
149  "false"
150 #endif
151  ) );
152  return control;
153 }
154 
155 FlyByWire::FlyByWire() : MatchVelocity( Vector( 0, 0, 0 ), Vector( 0, 0, 0 ), true, false, false )
156  , sheltonslide( false )
157  , controltype( !getControlType() )
158 {
159  DesiredShiftVelocity = Vector( 0, 0, 0 );
160  DirectThrust = Vector( 0, 0, 0 );
161  stolen_setspeed = false;
163 
164  static bool static_inertial_flight_model =
165  XMLSupport::parse_bool( vs_config->getVariable( "flight", "inertial::initial", "false" ) );
166  static bool static_inertial_flight_enable =
167  XMLSupport::parse_bool( vs_config->getVariable( "flight", "inertial::enable", "true" ) );
168  inertial_flight_model = static_inertial_flight_model;
169  inertial_flight_enable = static_inertial_flight_enable;
170 }
171 
172 void FlyByWire::Stop( float per )
173 {
174  SetDesiredVelocity( Vector( 0, 0, per*parent->GetComputerData().max_speed() ), true );
175 
177 }
178 
179 void FlyByWire::Right( float per )
180 {
182  ( -per
183  *(per
186  0,
187  1,
188  0 );
189 }
190 
191 void FlyByWire::Up( float per )
192 {
194  ( -per
195  *(per
198  1,
199  0,
200  0 );
201 }
202 
203 void FlyByWire::RollRight( float per )
204 {
206  ( -per
207  *(per
210  0,
211  0,
212  1 );
213 }
214 
215 void FlyByWire::Afterburn( float per )
216 {
218 
219  afterburn = (per > .1);
221  desired_velocity = Vector( 0, 0, cpu->set_speed+per*(cpu->max_ab_speed()-cpu->set_speed) );
222  else if (inertial_flight_model)
223  DirectThrust += Vector( 0, 0, parent->Limits().afterburn*per );
224  if ( parent == _Universe->AccessCockpit()->GetParent() ) {
225  //printf("afterburn is %d\n",afterburn); // DELETEME WTF all this force feedback code and its unused.
226  //COMMENTED BECAUSE OF SERVER -- NEED TO REINTEGRATE IT IN ANOTHER WAY
227  //forcefeedback->playAfterburner(afterburn);
228  }
229 }
230 
231 void FlyByWire::SheltonSlide( bool onoff )
232 {
233  sheltonslide = onoff;
234 }
235 
236 void FlyByWire::MatchSpeed( const Vector &vec )
237 {
239 
240  cpu->set_speed = (vec).Magnitude();
241  if ( cpu->set_speed > cpu->max_speed() )
242  cpu->set_speed = cpu->max_speed();
243 }
244 
245 void FlyByWire::Accel( float per )
246 {
248 
249  cpu->set_speed += per*cpu->max_speed()*SIMULATION_ATOM;
250  if ( cpu->set_speed > cpu->max_speed() )
251  cpu->set_speed = cpu->max_speed();
252  static float reverse_speed_limit = XMLSupport::parse_float( vs_config->getVariable( "physics", "reverse_speed_limit", "1.0" ) );
253  if (cpu->set_speed < -cpu->max_speed()*reverse_speed_limit)
254  cpu->set_speed = -cpu->max_speed()*reverse_speed_limit;
255  afterburn = false;
256 
257  desired_velocity = Vector( 0, 0, cpu->set_speed );
258 }
259 
260 #define FBWABS( m ) (m >= 0 ? m : -m)
261 
262 void FlyByWire::ThrustRight( float percent )
263 {
265 }
266 
267 void FlyByWire::ThrustUp( float percent )
268 {
270 }
271 
272 void FlyByWire::ThrustFront( float percent )
273 {
275 }
276 
277 void FlyByWire::DirectThrustRight( float percent )
278 {
279  DirectThrust.i = parent->Limits().lateral*percent;
280 }
281 
282 void FlyByWire::DirectThrustUp( float percent )
283 {
284  DirectThrust.j = parent->Limits().vertical*percent;
285 }
286 
287 void FlyByWire::DirectThrustFront( float percent )
288 {
289  if (percent > 0)
290  DirectThrust.k = parent->Limits().forward*percent;
291  else
292  DirectThrust.k = parent->Limits().retro*percent;
293 }
294 
296 {
297  bool desireThrust = false;
298  Vector des_vel_bak( desired_velocity );
299  if (!inertial_flight_model) {
300  //Must translate the thrust values to velocities, which is somewhat cumbersome.
301  Vector Limit(
303  ( (DirectThrust.k > 0) ? parent->Limits().forward : parent->Limits().retro )
304  );
305  if (Limit.i <= 1) Limit.i = 1;
306  if (Limit.j <= 1) Limit.j = 1;
307  if (Limit.k <= 1) Limit.k = 1;
308  Vector DesiredDrift(
309  DirectThrust.i/Limit.i,
310  DirectThrust.j/Limit.j,
311  DirectThrust.k/Limit.k
312  );
313  //Now, scale so that maximum shift velocity is max_speed
314  DesiredDrift *= parent->GetComputerData().max_speed();
315  //And apply
316  DesiredShiftVelocity += DesiredDrift;
317  }
319  if (!stolen_setspeed) {
320  stolen_setspeed = true;
322  }
325 
326  desireThrust = true;
327  if (!controltype) {
328  if (desired_velocity.k < 0) {
329  desired_velocity.k = 0;
331  }
332  }
333  } else if (stolen_setspeed) {
335  stolen_setspeed = false;
336  }
337  static double collidepanic = XMLSupport::parse_float( vs_config->getVariable( "physics", "collision_inertial_time", "1.25" ) );
340  || !controltype)
341  && (!desireThrust) )
342  || ( tempcp && Network == NULL && ( (getNewTime()-tempcp->TimeOfLastCollision) < collidepanic ) ) ) {
343  MatchAngularVelocity::Execute(); //only match turning
346  } else {
347  MatchVelocity::Execute();
348  }
349  DesiredShiftVelocity.Set( 0, 0, 0 );
350  DirectThrust.Set( 0, 0, 0 );
351  desired_velocity = des_vel_bak;
352 }
353 
355 {
356 #ifdef ORDERDEBUG
357  VSFileSystem::vs_fprintf( stderr, "fbw%x", this );
358  fflush( stderr );
359 #endif
360 }
361 
362 void FlyByWire::InertialFlight( bool onoff )
363 {
364  inertial_flight_model = onoff;
365  parent->inertialmode = onoff;
366 }
367 
369 {
370  return inertial_flight_model;
371 }
372 
374 {
375  return inertial_flight_enable;
376 }
377