Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

Situation.cpp

Go to the documentation of this file.
00001 /*
00002  * Situation.cpp
00003  *
00004  * Part of Fly! Legacy project
00005  *
00006  * Copyright 2003 Chris Wallace
00007  *
00008  * Fly! Legacy is free software; you can redistribute it and/or modify
00009  *   it under the terms of the GNU General Public License as published by
00010  *   the Free Software Foundation; either version 2 of the License, or
00011  *   (at your option) any later version.
00012  *
00013  * Fly! Legacy is distributed in the hope that it will be useful,
00014  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  *   GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  *   along with Fly! Legacy; if not, write to the Free Software
00020  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  *
00022  */
00023 
00034 #include <time.h>
00035 
00036 #include "../Include/Globals.h"
00037 #include "../Include/Situation.h"
00038 #include "../Include/Ui.h"
00039 #include "../Include/Utility.h"
00040 #include "../Include/Subsystems.h"
00041 #include "../Include/Gauges.h"
00042 
00043 using namespace std;
00044 
00045 
00046 //
00047 // CSlewManager manages the user vehicle position when it is in slew mode
00048 //
00049 
00050 CSlewManager::CSlewManager (void)
00051 {
00052   enabled = false;
00053   nRate = eRate = aRate = 0;
00054 }
00055 
00056 
00057 void CSlewManager::Enable (void) 
00058 {
00059   enabled = true;
00060 }
00061 
00062 
00063 void CSlewManager::Disable (void) 
00064 {
00065   ZeroRate ();
00066   enabled = false;
00067 }
00068 
00069 
00070 bool CSlewManager::IsEnabled (void) 
00071 {
00072   return enabled;
00073 }
00074 
00075 
00076 float CSlewManager::GetNorthRate (void) 
00077 {
00078   return nRate;
00079 }
00080 
00081 float CSlewManager::GetEastRate (void) 
00082 {
00083   return eRate;
00084 }
00085 
00086 float CSlewManager::GetAltRate (void) 
00087 {
00088   return aRate;
00089 }
00090 
00091 void CSlewManager::SetNorthRate (float rate) 
00092 {
00093   nRate = rate;
00094 }
00095 
00096 void CSlewManager::SetEastRate (float rate) 
00097 {
00098   eRate = rate;
00099 }
00100 
00101 void CSlewManager::SetAltRate (float rate) 
00102 {
00103   aRate = rate;
00104 }
00105 
00106 void CSlewManager::ZeroRate (void)
00107 {
00108   nRate = eRate = aRate = 0;
00109 }
00110 
00111 void CSlewManager::Update (float dT)
00112 {
00113   if (enabled) {
00114     CVehicleObject *user = globals->sit->GetUserVehicle ();
00115     if (user) {
00116       // Update user vehicle position
00117       SPosition pos = user->GetPosition ();
00118 
00119       // Range checking against latitude and altitude extremes is done in
00120       //   CUserVehicle::SetPosition
00121       pos.alt += (aRate * dT);
00122       pos.lat += (nRate * dT);
00123       pos.lon += (eRate * dT);
00124       user->SetPosition (pos);
00125 
00126       /*
00127       // DEBUG
00128       char debug[80];
00129       sprintf (debug, "Slew : aRate=%f nRate=%f eRate=%f\n", aRate, nRate, eRate);
00130       DrawNoticeToUser (debug, 1);
00131       */
00132     }
00133   }
00134 };
00135 
00136 
00137 //
00138 // CSituation
00139 //
00140 
00141 CSituation::CSituation (const char *sitFilename)
00142 {
00143   // Perform base initialization
00144   user = NULL;
00145   cmgr = NULL;
00146   kmgr = NULL;
00147   rootModels = new ssgRoot;
00148   rootUserVehicle = new ssgRoot;
00149 
00150   // Get panel sound effect source
00151   sfx_source_panel = globals->audiomgr->CreateSource ();
00152   CGauge::sfx_source = sfx_source_panel;
00153 
00154   // Open SIT file from pod filesystem
00155   SStream s;
00156   strcpy (s.filename, "Saved Simulations\\");
00157   strcat (s.filename, sitFilename);
00158   strcpy (s.mode, "r");
00159   if (OpenStream (&s)) {
00160     // Successfully opened stream
00161     ReadFrom (this, &s);
00162   } else {
00163     gtfo ("CSituation : Cannot open SIT file %s", s.filename);
00164   }
00165   CloseStream (&s);
00166 }
00167 
00168 CSituation::~CSituation (void)
00169 {
00170   vector<CWorldObjectBase*>::iterator i;
00171   for (i=wobjList.begin(); i!=wobjList.end(); i++) {
00172     CWorldObjectBase *pObj = *i;
00173     delete pObj;
00174   }
00175 
00176   // Clean up SSG roots
00177   rootModels->removeAllKids();
00178   delete rootModels;
00179   rootUserVehicle->removeAllKids();
00180   delete rootUserVehicle;
00181 }
00182 
00183 int CSituation::Read (SStream *stream, Tag tag)
00184 {
00185   int rc = TAG_IGNORED;
00186 
00187   switch (tag) {
00188   case 'wobj':
00189     {
00190       // Determine the type of world object
00191       char s[80];
00192       ReadString (s, 80, stream);
00193       Tag type = StringToTag (s);
00194       switch (type) {
00195       case TYPE_FLY_WORLDOBJECT:
00196         {
00197           // Instantiate new CWorldObject
00198           CWorldObject *wobj = new CWorldObject ();
00199           ReadFrom (wobj, stream);
00200           wobjList.push_back (wobj);
00201         }
00202         break;
00203 
00204       case TYPE_FLY_MODELOBJECT:
00205         {
00206           // Instantiate new CModelObject
00207           CModelObject *mobj = new CModelObject ();
00208           ReadFrom (mobj, stream);
00209           wobjList.push_back (mobj);
00210 
00211           // Add top-level SSG entity to model root
00212           ssgEntity *e = mobj->GetSSGEntity();
00213           if (e != NULL) {
00214             rootModels->addKid (e);
00215           }
00216         }
00217         break;
00218 
00219       case TYPE_FLY_SIMULATEDOBJECT:
00220         {
00221           // Instantiate new CSimulatedObject
00222           CSimulatedObject *sobj = new CSimulatedObject ();
00223           ReadFrom (sobj, stream);
00224           wobjList.push_back (sobj);
00225 
00226           // Add top-level SSG entity to model root
00227           ssgEntity *e = sobj->GetSSGEntity();
00228           if (e != NULL) {
00229             rootModels->addKid (e);
00230           }
00231         }
00232         break;
00233 
00234       case TYPE_FLY_VEHICLE:
00235         {
00236           // Instantiate new CVehicleObject
00237           CVehicleObject *vehi = new CVehicleObject ();
00238           ReadFrom (vehi, stream);
00239           wobjList.push_back (vehi);
00240           if (vehi->isUserVehicle()) {
00241             user = vehi;
00242             userType = TYPE_FLY_VEHICLE;
00243 
00244             ssgEntity *e = vehi->GetSSGEntity();
00245             if (e != NULL) {
00246               rootModels->addKid (e);
00247             }
00248           } else {
00249             ssgEntity *e = vehi->GetSSGEntity();
00250             if (e != NULL) {
00251               rootUserVehicle->addKid (e);
00252             }
00253           }
00254         }
00255         break;
00256 
00257       case TYPE_FLY_GROUNDVEHICLE:
00258         {
00259           // Instantiate new CGroundVehicleObject
00260           CGroundVehicleObject *gveh = new CGroundVehicleObject ();
00261           ReadFrom (gveh, stream);
00262           wobjList.push_back (gveh);
00263           if (gveh->isUserVehicle()) {
00264             user = gveh;
00265             userType = TYPE_FLY_GROUNDVEHICLE;
00266 
00267             ssgEntity *e = gveh->GetSSGEntity();
00268             if (e != NULL) {
00269               rootModels->addKid (e);
00270             }
00271           } else {
00272             ssgEntity *e = gveh->GetSSGEntity();
00273             if (e != NULL) {
00274               rootUserVehicle->addKid (e);
00275             }
00276           }
00277         }
00278         break;
00279 
00280       case TYPE_FLY_AIRPLANE:
00281         {
00282           // Instantiate new CAirplaneObject
00283           CAirplaneObject *plan = new CAirplaneObject ();
00284           ReadFrom (plan, stream);
00285           wobjList.push_back (plan);
00286           if (plan->isUserVehicle()) {
00287             user = plan;
00288             userType = TYPE_FLY_AIRPLANE;
00289 
00290             ssgEntity *e = plan->GetSSGEntity();
00291             if (e != NULL) {
00292               rootUserVehicle->addKid (e);
00293             }
00294           } else {
00295             ssgEntity *e = plan->GetSSGEntity();
00296             if (e != NULL) {
00297               rootModels->addKid (e);
00298             }
00299           }
00300         }
00301         break;
00302 
00303       case TYPE_FLY_HELICOPTER:
00304         {
00305           // Instantiate new CHelicopterObject
00306           CHelicopterObject *heli = new CHelicopterObject ();
00307           ReadFrom (heli, stream);
00308           wobjList.push_back (heli);
00309           if (heli->isUserVehicle()) {
00310             user = heli;
00311             userType = TYPE_FLY_HELICOPTER;
00312 
00313             ssgEntity *e = heli->GetSSGEntity();
00314             if (e != NULL) {
00315               rootUserVehicle->addKid (e);
00316             }
00317           } else {
00318             ssgEntity *e = heli->GetSSGEntity();
00319             if (e != NULL) {
00320               rootModels->addKid (e);
00321             }
00322           }
00323         }
00324         break;
00325       }
00326       rc = TAG_READ;
00327     }
00328     break;
00329 
00330   default:
00331     char s[16];
00332     TagToString (s, tag);
00333     globals->logWarning->Write ("CSituation::Read : Unknown tag <%s>", s);
00334   }
00335 
00336   return rc;
00337 }
00338 
00339 void CSituation::ReadFinished (void)
00340 {
00341   // Validate that user vehicle pointer has been set
00342   if (user == NULL) {
00343     gtfo ("CSituation : NULL user vehicle");
00344   }
00345 
00346   // Validate pointer to camera manager
00347   cmgr = user->GetCameraManager();
00348   if (cmgr == NULL) {
00349     gtfo ("CSituation : NULL camera manager for user vehicle");
00350   }
00351 
00352   // Validate pointer to cockpit manager
00353   kmgr = user->GetCockpitManager();
00354   if (kmgr == NULL) {
00355     gtfo ("CSituation : NULL cockpit manager for user vehicle");
00356   }
00357 }
00358 
00359 CCamera* CSituation::GetCurrentCamera (void)
00360 {
00361   return cmgr->GetActiveCamera ();
00362 }
00363 
00364 CPanel* CSituation::GetCurrentPanel (void)
00365 {
00366   return kmgr->GetCurrentPanel ();
00367 }
00368 
00369 CVehicleObject* CSituation::GetUserVehicle (void)
00370 {
00371   return user;
00372 }
00373 
00374 EFlyObjectType CSituation::GetUserVehicleType (void)
00375 {
00376   return userType;
00377 }
00378 
00379 void CSituation::PrintUserVehicle (FILE *f)
00380 {
00381   rootUserVehicle->print (f);
00382 }
00383 
00384 //
00385 // The Prepare method is called after loading of the situation, but
00386 //   prior to the first Timeslice call.  It allows any initial real-time
00387 //   preparation to be done, inter-system communication setup, etc.
00388 //
00389 void CSituation::Prepare (void)
00390 {
00392 
00393   // Prepare terrain manager
00394   globals->terrainmgr->Prepare ();
00395 }
00396 
00397 
00398 //
00399 // This method is called on every simulation cycle, in order to update
00400 //   the simulation world and all entities within it.  This method
00401 //   calls the Draw method when it is deemed necessary to redraw the
00402 //   sim world onscreen.
00403 //
00404 void CSituation::Timeslice (float dT)
00405 {
00406   // Update the slew manager
00407   globals->slewmgr->Update (dT);
00408 
00409   // Update sky parameters
00410   globals->skymgr->Update (dT);
00411 
00412   // Update user vehicle subsystems
00413   CVehicleObject *vehi = globals->sit->GetUserVehicle ();
00414   EFlyObjectType userType = globals->sit->GetUserVehicleType ();
00415   switch (userType) {
00416   case TYPE_FLY_AIRPLANE:
00417     {
00418       CAirplaneObject *planObj = (CAirplaneObject *)vehi;
00419       CAirplane *plan = planObj->pAirplane;
00420       if (plan) {
00421         // Airplane object is valid
00422         plan->Timeslice (dT);
00423       }
00424     }
00425     break;
00426   default:
00427     // User vehicle not yet supported; do nothing
00428     ;
00429   }
00430 
00431 //  SDateTime dt = timemgr->GetLocalDateTime ();
00432 //  char debug[80];
00433 //  sprintf (debug, "%02d/%02d/%04d  %02d:%02d:%02d  %f",
00434 //    dt.date.day, dt.date.month, dt.date.year,
00435 //    dt.time.hour, dt.time.minute, dt.time.second, mjd);
00436 //  DrawNoticeToUser (debug, 1);
00437   
00438   // Check for an OpenGL error
00439   GLenum e = glGetError ();
00440   if (e != GL_NO_ERROR) {
00441     gtfo ("CSituation::Update : GL Error 0x%04X", e);
00442   }
00443 }
00444 
00445 void CSituation::Draw (float dT)
00446 {
00447   // All drawing of the scene (except for PUI user interface widgets) is
00448   //   controlled from this method.  For now, all SSG context manipulation
00449   //   is done here, although it might be better to move it into the
00450   //   individual sub-object Draw methods someday.
00451 
00452   // Get camera attributes from the camera manager attached to the user vehicle
00453   SPosition userPos = user->GetPosition();
00454 
00455   char debug[80];
00456 //  sprintf (debug, "slew nRate=%f eRate=%f aRate=%f", nRate, eRate, aRate);
00457   sprintf (debug, "pos : lat=%f lon=%f alt=%f", userPos.lat, userPos.lon, userPos.alt);
00458   DrawNoticeToUser (debug, 1);
00459 
00460   SVector userOrient = user->GetOrientation();
00461   SPosition eyePos;
00462   SVector eyeOrient;
00463   cmgr->UpdateCamera (&userPos, &userOrient, &eyePos, &eyeOrient, dT);
00464 
00465   // Set field of view
00467   float aspect = 4.0f / 3.0f;
00468   float fovX = 50.0f;
00469   float fovY = fovX / aspect;
00470   ssgSetFOV (fovX, fovY) ;
00471 
00472   //
00473   // Draw the opaque background sky elements (sky dome, sun, moon, etc.)
00474   //
00475   globals->skymgr->SetCamera (eyePos, eyeOrient);
00476   globals->skymgr->PreDraw ();
00477 
00478   // Draw the terrain (ground textures, airports, scenery models, etc.)
00479   globals->terrainmgr->SetPosition (userPos);
00481   globals->terrainmgr->SetCamera (eyePos, userPos, eyeOrient);
00482   globals->terrainmgr->Draw ();
00483 
00484   // Draw non-user vehicle models
00485   ssgCullAndDraw (rootModels);
00486 
00488 
00490 
00491   // If the current camera is of type CCameraCockpit, draw the panel
00492   CCamera *cam = cmgr->GetActiveCamera ();
00493   if (cam->GetCameraType() == CAMERA_COCKPIT) {
00494     // Ensure current panel is selected in CCockpitManager
00495     CCameraCockpit* camCock = (CCameraCockpit*) cam;
00496     Tag tag = camCock->GetCockpitPanel ();
00497     if (tag != user->GetPanel ()) {
00498       user->SetPanel (tag);
00499     }
00500 
00501     // Draw the panel
00502     user->DrawPanel ();
00503   } else {
00504     if (!cam->IsInteriorCamera ()) {
00505       ssgCullAndDraw (rootUserVehicle);
00506     }
00507   }
00508 
00509   //
00510   // Draw the translucent sky elements (clouds etc.)
00511   //
00512   // sky->PostDraw ();
00513 
00514   // Check for an OpenGL error
00515   GLenum e = glGetError ();
00516   if (e != GL_NO_ERROR) {
00517     gtfo ("CSituation::Draw : GL Error 0x%08x", e);
00518   }
00519 }
00520 
SourceForge.net Logo Documentation generated by doxygen