vegastrike  0.5.1.r1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
physics.cpp
Go to the documentation of this file.
1 /*
2  * Vega Strike
3  * Copyright (C) 2001-2002 Daniel Horn
4  *
5  * http://vegastrike.sourceforge.net/
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */
21 #include "macosx_math.h"
22 #include "lin_time.h"
23 #include "physics.h"
24 #include "gfx/quaternion.h"
25 PhysicsSystem::PhysicsSystem( float M, float I, QVector *pos, Vector *p, Vector *q, Vector *r ) :
26  mass( M )
27  , MomentOfInertia( I )
28  , NetForce( 0, 0, 0 )
29  , NetTorque( 0, 0, 0 )
30  , AngularVelocity( 0, 0, 0 )
31  , Velocity( 0, 0, 0 )
32  , pos( pos )
33  , p( p )
34  , q( q )
35  , r( r )
36 {
37  NumActiveForces = 0;
38  NumActiveTorques = 0;
39 }
40 
41 void PhysicsSystem::ResistiveLiquidTorque( float ResistiveForceCoef )
42 {
43  NetTorque += ResistiveForceCoef*AngularVelocity;
44 }
45 void PhysicsSystem::ResistiveLiquidForce( float ResistiveForceCoef )
46 {
47  NetForce += ResistiveForceCoef*Velocity;
48 }
49 void PhysicsSystem::ResistiveThrust( float strength )
50 {
51  Vector V1 = Velocity;
52  float mag = V1.Magnitude();
53  float t = mag/fabs( strength );
54  ApplyForce( (strength/mag)*V1, t );
55 }
56 void PhysicsSystem::ResistiveTorqueThrust( float strength, const Vector &Position )
57 {
58  Vector V1 = AngularVelocity;
59  float mag = V1.Magnitude();
60  float t = mag/fabs( strength );
61  ApplyBalancedLocalTorque( (strength/mag)*V1, Position, t );
62 }
63 
64 void PhysicsSystem::ResistiveTorque( float ResistiveForceCoef )
65 {
66  if ( (AngularVelocity.i || AngularVelocity.j || AngularVelocity.k) && ResistiveForceCoef ) {
67  Vector temp = AngularVelocity;
68  NetTorque += (ResistiveForceCoef*AngularVelocity*AngularVelocity)*temp.Normalize();
69  }
70 }
71 void PhysicsSystem::ResistiveForce( float ResistiveForceCoef )
72 {
73  if ( (Velocity.i || Velocity.j || Velocity.k) && ResistiveForceCoef ) {
74  Vector temp = Velocity;
75  NetForce += (ResistiveForceCoef*Velocity*Velocity)*temp.Normalize();
76  }
77 }
78 
80 {
82  NetForce = Vector( 0, 0, 0 );
83  NetTorque = Vector( 0, 0, 0 );
84 }
85 
86 void PhysicsSystem::Rotate( const Vector &axis )
87 {
88  float theta = axis.Magnitude();
89  if (theta == 0.0f)
90  return;
91  float ootheta = 1/theta;
92  float s = cos( theta*.5 );
93  Quaternion rot = Quaternion( s, axis*(sin( theta*.5 )*ootheta) );
94  Quaternion rotprime = rot.Conjugate();
95  Quaternion pquat = rot*Quaternion( 0, *p )*rotprime;
96  Quaternion qquat = rot*Quaternion( 0, *q )*rotprime;
97  Quaternion rquat = rot*Quaternion( 0, *r )*rotprime;
98  *p = pquat.v;
99  *q = qquat.v;
100  *r = rquat.v;
101 }
102 
103 void PhysicsSystem::JettisonReactionMass( const Vector &Direction, float speed, float mass )
104 {
105  NetForce += Direction*( speed*mass/GetElapsedTime() );
106 }
107 
108 void PhysicsSystem::JettisonMass( const Vector &Direction, float speed, float jmass )
109 {
110  mass -= jmass; //fuel is sent out
111  JettisonReactionMass( Direction, speed, jmass );
112 }
113 
114 void PhysicsSystem::ApplyForce( const Vector &Vforce, float time )
115 {
116  if (NumActiveForces < forcemax) {
117  ActiveForces[NumActiveForces].F = Vforce;
118  ActiveForces[NumActiveForces].t = time;
119  ++NumActiveForces;
120  }
121 }
122 
123 void PhysicsSystem::ApplyTorque( const Vector &Vforce, const Vector &Location, float time )
124 {
125  ApplyForce( Vforce, time );
126  if (NumActiveTorques < forcemax) {
127  ActiveTorques[NumActiveTorques].F = (Location.Cast()-*pos).Cast().Cross( Vforce );
128  ActiveTorques[NumActiveTorques].t = time;
129  ++NumActiveTorques;
130  }
131 }
132 
133 void PhysicsSystem::ApplyLocalTorque( const Vector &Vforce, const Vector &Location, float time )
134 {
135  ApplyForce( Vforce, time );
136  if (NumActiveTorques < forcemax) {
137  ActiveTorques[NumActiveTorques].F = Location.Cross( Vforce );
138  ActiveTorques[NumActiveTorques].t = time;
139  ++NumActiveTorques;
140  }
141 }
142 
143 void PhysicsSystem::ApplyBalancedLocalTorque( const Vector &Vforce, const Vector &Location, float time )
144 {
145  if (NumActiveTorques < forcemax) {
146  ActiveTorques[NumActiveTorques].F = Location.Cross( Vforce );
147  ActiveTorques[NumActiveTorques].t = time;
148  ++NumActiveTorques;
149  }
150 }
152 {
153  Vector temptorque = Time*NetTorque;
154  Vector tempforce = Time*NetForce;
155  int i;
156  for (i = 0; i < NumActiveTorques; ++i) {
157  if (Time >= ActiveTorques[i].t) {
158  temptorque += ActiveTorques[i].t*ActiveTorques[i].F;
159  ActiveTorques[i].F = ActiveTorques[NumActiveTorques-1].F;
160  ActiveTorques[i].t = ActiveTorques[NumActiveTorques-1].t;
161  --NumActiveTorques;
162  --i; //so the loop goes through the active force that was just switched places with
163  } else {
164  temptorque += Time*ActiveTorques[i].F;
165  ActiveTorques[i].t -= Time;
166  }
167  }
168  for (i = 0; i < NumActiveForces; ++i) {
169  if (Time >= ActiveForces[i].t) {
170  tempforce += ActiveForces[i].t*ActiveForces[i].F;
171  ActiveForces[i].F = ActiveForces[NumActiveForces-1].F;
172  ActiveForces[i].t = ActiveForces[NumActiveForces-1].t;
173  NumActiveForces--;
174  i--; //so the loop goes through the active force that was just switched places with
175  } else {
176  tempforce += Time*ActiveForces[i].F;
177  ActiveForces[i].t -= Time;
178  }
179  }
180  temptorque = temptorque*(0.5/MomentOfInertia);
181  Rotate( AngularVelocity+0.5*temptorque );
182  AngularVelocity += temptorque;
183  tempforce = tempforce*(0.5/mass); //acceleration
184  //now the fuck with it... add relitivity to the picture here
185  if (fabs( Velocity.i )+fabs( Velocity.j )+fabs( Velocity.k ) > co10) {
186  float magvel = Velocity.Magnitude();
187  float y = (1-magvel*magvel*oocc);
188  tempforce = tempforce*powf( y, 1.5 );
189  }
190  *pos += (Velocity+.5*tempforce).Cast();
191  Velocity += tempforce;
192 }
193