Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

Ship.cpp

Go to the documentation of this file.
00001 
00002 /*
00003     TSGL - Teddy Space Game Library
00004     Copyright (C) 2002 Timo Suoranta
00005     tksuoran@cc.helsinki.fi
00006 
00007     This library is free software; you can redistribute it and/or
00008     modify it under the terms of the GNU Lesser General Public
00009     License as published by the Free Software Foundation; either
00010     version 2.1 of the License, or (at your option) any later version.
00011 
00012     This library is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015     Lesser General Public License for more details.
00016 
00017     You should have received a copy of the GNU Lesser General Public
00018     License along with this library; if not, write to the Free Software
00019     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020 
00021     $Id: Ship.cpp,v 1.1 2002/01/08 20:47:05 tksuoran Exp $
00022 */
00023 
00024 
00025 #include "Teddy/SpaceGame/Root.h"
00026 #include "Teddy/SpaceGame/SimulatedInstance.h"
00027 #include "Teddy/SpaceGame/Ship.h"
00028 #include "Teddy/SpaceGame/ShipType.h"
00029 using namespace Teddy::Models;
00030 
00031 
00032 namespace Teddy     {
00033 namespace SpaceGame {
00034 
00035 
00036 void Ship::collide(){
00037     tick_translation = getViewAxis() * speed * -2;;
00038     translate( tick_translation );
00039     speed *= -0.5;
00040 }
00041 
00042 
00048 Ship::Ship( char *name, ShipType *ship_type, Root *root )
00049 :
00050 SimulatedInstance( name, ship_type->getMesh() )
00051 {
00052     this->ship_type = ship_type;
00053     this->root      = root;
00054 
00055     target              = NULL;
00056     target_offset       = Vector(0,0,0);
00057     pitch               = 0;
00058     roll                = 0;
00059     speed               = 0;
00060     accel               = 0;
00061     control_pitch_up    = false;
00062     control_pitch_down  = false;
00063     control_roll_left   = false;
00064     control_roll_right  = false;
00065     control_more_speed  = false;
00066     control_less_speed  = false;
00067     control_stop        = false;
00068     control_fire_weapon = false;
00069     active_pitch        = false;
00070     active_roll         = false;
00071     pitch_delta         = 0;
00072     roll_delta          = 0;
00073 }
00074 
00076 /*virtual*/ void Ship::tick(){
00077     applyControls( 10.0f );
00078     SimulatedInstance::tick();
00079 }
00080 
00081 //  -----  SIMPLE CONTROLS -----
00082 
00083 
00084 void Ship::stopSpeed(){
00085     if( speed > 0 ){
00086         controlMoreSpeed( false );
00087         controlLessSpeed( true  );
00088     }else if( speed < 0 ){
00089         controlMoreSpeed( true  );
00090         controlLessSpeed( false );
00091     }
00092 }
00093 
00094 
00095 void Ship::stopPitch(){
00096     if( pitch > 0 ){
00097         controlPitchDown( true  );
00098         controlPitchUp  ( false );
00099     }else if( pitch < 0 ){
00100         controlPitchDown( false );
00101         controlPitchUp  ( true  );
00102     }
00103 }
00104 
00105 
00106 void Ship::stopRoll(){
00107     if( roll > 0 ){
00108         controlRollLeft ( true  );
00109         controlRollRight( false );
00110     }else if( roll < 0 ){
00111         controlRollLeft ( false );
00112         controlRollRight( true  );
00113     }
00114 }
00115 
00116 
00117 //  -----  USED BY DEBUG HUD  -----
00118 
00119 
00120 float Ship::getTargetDistance() const {
00121     if( target != NULL ){
00122         Vector tpos   = target->getPosition();
00123         Vector cpos   = this->getPosition();
00124         Vector delta  = tpos - cpos;
00125 
00126         float target_distance = delta.magnitude();
00127         target_distance -= target->getClipRadius() * 2;
00128 //      target_distance -= this->getClipRadius() * 2;
00129         return target_distance;
00130     }else{
00131         return 0;
00132     }
00133 }
00134 
00135 float Ship::getBrakeDistance() const {
00136     return (speed * speed) / (2 * ship_type->getAcceleration() * 10);
00137 }
00138 
00139 
00140 //  ----- TRACKING CODE -----
00141 
00142 
00155 void Ship::trackTarget(){
00156     if( target == NULL ){
00157         return;
00158     }
00159     
00160     Vector tpos   = target->getPosition();
00161     Vector cpos   = this->getPosition();
00162     Vector tview  = target->getViewAxis ();
00163     Vector tup    = target->getUpAxis   ();
00164     Vector tright = target->getRightAxis();
00165     Vector cview  = getViewAxis ();
00166     Vector cup    = getUpAxis   ();
00167     Vector cright = getRightAxis();
00168     Vector offset = tright * target_offset.v[0] +
00169                     tup    * target_offset.v[1] +
00170                     tview  * target_offset.v[2];
00171     Vector delta  = tpos + offset - cpos;
00172     float  target_speed;
00173 
00174     SimulatedInstance *sim_target = dynamic_cast<SimulatedInstance*>( target );
00175     if( sim_target != NULL ){
00176         target_speed = (float)(sim_target->tick_translation.magnitude());
00177     }else{
00178         target_speed = 0;
00179     }
00180 
00181     float  target_distance  = getTargetDistance();
00182     float  brake_distance   = (speed * speed) / (20 * ship_type->getAcceleration() );
00183     float  b_pitch_distance = 10 * (pitch * pitch) / (2 * ship_type->getPitchConst  () );
00184     float  b_roll_distance  = 10 * (roll  * roll ) / (2 * ship_type->getRollConst   () );
00185 
00186     delta .normalize();
00187     float  v = cview  | delta;
00188     float  u = cup    | delta;
00189     float  r = cright | delta;
00190     float  v_epsilon = 0.01f;  // error tolerance
00191     float  u_epsilon = 0.01f;  // error tolerance
00192     float  r_epsilon = 0.02f;  // error tolerance
00193     pitch_distance   = (float)acos( u );
00194     roll_distance    = (float)acos( r );
00195 
00196     //  Arrived to target?
00197     if( target_distance < 1 ){
00198         stopSpeed();
00199         stopPitch();
00200         stopRoll ();
00201         return;
00202     }
00203 
00204     bool speed_control = false;
00205     if(
00206         (  brake_distance  <  target_distance  )
00207         
00208         &&
00209 
00210         (
00211 
00212           (
00213            (target_distance <  100                ) &&
00214            (fabs(speed)     <  fabs(target_speed) )    
00215           )
00216          
00217           ||
00218 
00219           (
00220            target_distance >= 100
00221           )
00222         )
00223     ){
00224         speed_control = true;
00225     }
00226 
00227     //  Target in front
00228     if( v > 0.5 ){
00229 
00230         //  Go faster?
00231         if( speed_control == true ){
00232             controlMoreSpeed( true ); 
00233             controlLessSpeed( false );
00234         }else{
00235             stopSpeed();
00236         }
00237     }
00238 
00239     //  Target behind
00240     if( v < 0.5 ){
00241 
00242         //  Go backwards
00243         if( speed_control == true ){
00244             controlMoreSpeed( false ); 
00245             controlLessSpeed( true );
00246         }else{
00247             stopSpeed();
00248         }
00249     }
00250 
00251     // Looking pretty straight at target?
00252     if( fabs(0.5-v) < v_epsilon ){
00253         stopPitch();
00254         stopRoll();
00255         return;
00256     }
00257 
00258     //  Target above
00259     if( u >= 0 ){ 
00260 
00261         //  Pitch up
00262         if( (b_pitch_distance < pitch_distance) && 
00263             (fabs(u)          > fabs(r)       ) &&
00264             (u > u_epsilon                    )    )
00265         {
00266             controlPitchUp  ( true  );
00267             controlPitchDown( false );
00268         }else{
00269             stopPitch();
00270         }
00271 
00272         //  Target on right (above)
00273         if( r > r_epsilon ){
00274             //  Roll right
00275             if( b_roll_distance < roll_distance ){
00276                 controlRollRight( true  ); 
00277                 controlRollLeft ( false );
00278             }else{
00279                 stopRoll();
00280             }
00281         }
00282 
00283         //  Target on left (above)
00284         if( r < -r_epsilon ){
00285             //  Roll left
00286             if( b_roll_distance < roll_distance ){
00287                 controlRollRight( false );
00288                 controlRollLeft ( true  ); 
00289             }else{
00290                 stopRoll();
00291             }
00292         }
00293     }
00294 
00295     //  Target below
00296     if( u < 0 ){ 
00297 
00298         //  Pitch down
00299         if( (b_pitch_distance < pitch_distance) && 
00300             (fabs(u)          > fabs(r)       ) &&
00301             (u                < -u_epsilon    )    )
00302         {
00303             controlPitchUp  ( false );
00304             controlPitchDown( true  );
00305         }else{
00306             stopPitch();
00307         }
00308 
00309         //  Target on right (below)
00310         if( r > r_epsilon ){
00311             //  Roll left
00312             if( b_roll_distance < roll_distance ){
00313                 controlRollRight( false );
00314                 controlRollLeft ( true  ); 
00315             }else{
00316                 stopRoll();
00317             }
00318         }
00319 
00320         //  Target on left (below)
00321         if( r < -r_epsilon ){
00322             //  Roll right
00323             if( b_roll_distance < roll_distance ){
00324                 controlRollRight( true  ); 
00325                 controlRollLeft ( false );
00326             }else{
00327                 stopRoll();
00328             }
00329         }
00330     }
00331 }
00332 
00333 
00334 //  ----- ACCESSORS -----
00335 
00336 
00337 ShipType *Ship::getShipType(){
00338     return this->ship_type;
00339 }
00340 
00341 void Ship::setTarget( ModelInstance *mi, Vector offset ){
00342     this->target        = mi;
00343     this->target_offset = offset;
00344 }
00345 
00346 
00348 void Ship::setTargetPosition(){
00349     Vector tpos   = target->getPosition();
00350 //  Vector cpos   = this->getPosition();
00351     Vector tview  = target->getViewAxis ();
00352     Vector tup    = target->getUpAxis   ();
00353     Vector tright = target->getRightAxis();
00354 //  Vector cview  = getViewAxis ();
00355 //  Vector cup    = getUpAxis   ();
00356 //  Vector cright = getRightAxis();
00357     Vector offset = tright * target_offset.v[0] +
00358                     tup    * target_offset.v[1] +
00359                     tview  * target_offset.v[2];
00360 //  Vector delta  = tpos + offset - cpos;
00361     setPosition( tpos + offset );
00362 }
00363 
00364 ModelInstance *Ship::getTarget(){
00365     return target;
00366 }
00367 
00368 float Ship::getPitch() const {
00369     return pitch;
00370 }
00371 
00372 float Ship::getRoll() const {
00373     return roll;
00374 }
00375 
00376 float Ship::getSpeed() const {
00377     return speed;
00378 }
00379 
00380 
00381 };  //  namespace SpaceTeddy
00382 };  //  namespace Teddy
00383