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

simulation.cpp

Go to the documentation of this file.
00001 // simulation.cpp
00002 // 
00003 // Copyright (C) 2001, Chris Laurel <claurel@shatters.net>
00004 //
00005 // The core of Celestia--tracks an observer moving through a
00006 // stars and their solar systems.
00007 //
00008 // This program is free software; you can redistribute it and/or
00009 // modify it under the terms of the GNU General Public License
00010 // as published by the Free Software Foundation; either version 2
00011 // of the License, or (at your option) any later version.
00012 
00013 #include <algorithm>
00014 #include "simulation.h"
00015 
00016 using namespace std;
00017 
00018 
00019 Simulation::Simulation(Universe* _universe) :
00020     realTime(0.0),
00021     timeScale(1.0),
00022     syncTime(true),
00023     universe(_universe),
00024     closestSolarSystem(NULL),
00025     selection(),
00026     faintestVisible(5.0f)
00027 {
00028     activeObserver = new Observer();
00029     observers.insert(observers.end(), activeObserver);
00030 }
00031 
00032 
00033 Simulation::~Simulation()
00034 {
00035     for (vector<Observer*>::iterator iter = observers.begin();
00036          iter != observers.end(); iter++)
00037     {
00038         delete *iter;
00039     }
00040 }
00041 
00042 
00043 static const Star* getSun(Body* body)
00044 {
00045     PlanetarySystem* system = body->getSystem();
00046     if (system == NULL)
00047         return NULL;
00048     else
00049         return system->getStar();
00050 }
00051 
00052 
00053 void Simulation::render(Renderer& renderer)
00054 {
00055     renderer.render(*activeObserver,
00056                     *universe,
00057                     faintestVisible,
00058                     selection);
00059 }
00060 
00061 
00062 void Simulation::render(Renderer& renderer, Observer& observer)
00063 {
00064     renderer.render(observer,
00065                     *universe,
00066                     faintestVisible,
00067                     selection);
00068 }
00069 
00070 
00071 Universe* Simulation::getUniverse() const
00072 {
00073     return universe;
00074 }
00075 
00076 
00077 // Get the time (Julian date)
00078 double Simulation::getTime() const
00079 {
00080     return activeObserver->getTime();
00081 }
00082 
00083 // Set the time to the specified Julian date
00084 void Simulation::setTime(double jd)
00085 {
00086     if (syncTime)
00087     {
00088         for (vector<Observer*>::iterator iter = observers.begin();
00089              iter != observers.end(); iter++)
00090         {
00091             (*iter)->setTime(jd);
00092         }
00093     }
00094     else
00095     {
00096         activeObserver->setTime(jd);
00097     }
00098 }
00099 
00100 
00101 // Get the clock time elapsed since the object was created
00102 double Simulation::getRealTime() const
00103 {
00104     return realTime;
00105 }
00106 
00107 
00108 double Simulation::getArrivalTime() const
00109 {
00110     return activeObserver->getArrivalTime();
00111 }
00112 
00113 
00114 // Tick the simulation by dt seconds
00115 void Simulation::update(double dt)
00116 {
00117     realTime += dt;
00118 
00119     for (vector<Observer*>::iterator iter = observers.begin();
00120          iter != observers.end(); iter++)
00121     {
00122         (*iter)->update(dt, timeScale);
00123     }
00124 
00125     // Find the closest solar system
00126     closestSolarSystem = universe->getNearestSolarSystem(activeObserver->getPosition());
00127 }
00128 
00129 
00130 Selection Simulation::getSelection() const
00131 {
00132     return selection;
00133 }
00134 
00135 
00136 void Simulation::setSelection(const Selection& sel)
00137 {
00138     if (sel != selection)
00139     {
00140         universe->unmarkObject(selection, 0);
00141         selection = sel;
00142         universe->markObject(selection,
00143                              10.0f,
00144                              Color(1.0f, 0.0f, 0.0f, 0.9f),
00145                              Marker::Diamond,
00146                              0);
00147     }
00148 }
00149 
00150 
00151 Selection Simulation::getTrackedObject() const
00152 {
00153     return activeObserver->getTrackedObject();
00154 }
00155 
00156 
00157 void Simulation::setTrackedObject(const Selection& sel)
00158 {
00159     activeObserver->setTrackedObject(sel);
00160 }
00161 
00162 
00163 Selection Simulation::pickObject(Vec3f pickRay, float tolerance)
00164 {
00165     return universe->pick(activeObserver->getPosition(),
00166                           pickRay * activeObserver->getOrientation().toMatrix4(),
00167                           activeObserver->getTime(),
00168                           faintestVisible,
00169                           tolerance);
00170 }
00171 
00172 void Simulation::reverseObserverOrientation()
00173 {
00174     activeObserver->reverseOrientation();
00175 }
00176 
00177 
00178 Observer& Simulation::getObserver()
00179 {
00180     return *activeObserver;
00181 }
00182 
00183 
00184 Observer* Simulation::addObserver()
00185 {
00186     Observer* o = new Observer();
00187     observers.insert(observers.end(), o);
00188     return o;
00189 }
00190 
00191 
00192 void Simulation::removeObserver(Observer* o)
00193 {
00194     vector<Observer*>::iterator iter = find(observers.begin(), observers.end(), o);
00195     if (iter != observers.end())
00196         observers.erase(iter);
00197 }
00198 
00199 
00200 Observer* Simulation::getActiveObserver()
00201 {
00202     return activeObserver;
00203 }
00204 
00205 
00206 void Simulation::setActiveObserver(Observer* o)
00207 {
00208     vector<Observer*>::iterator iter= find(observers.begin(), observers.end(), o);
00209     if (iter != observers.end())
00210         activeObserver = o;
00211 }
00212 
00213 
00214 void Simulation::setObserverPosition(const UniversalCoord& pos)
00215 {
00216     activeObserver->setPosition(pos);
00217 }
00218 
00219 void Simulation::setObserverOrientation(const Quatf& orientation)
00220 {
00221     activeObserver->setOrientation(orientation);
00222 }
00223 
00224 
00225 Observer::ObserverMode Simulation::getObserverMode() const
00226 {
00227     return activeObserver->getMode();
00228 }
00229 
00230 void Simulation::setObserverMode(Observer::ObserverMode mode)
00231 {
00232     activeObserver->setMode(mode);
00233 }
00234 
00235 void Simulation::setFrame(astro::CoordinateSystem coordSys,
00236                           const Selection& sel)
00237 {
00238     activeObserver->setFrame(FrameOfReference(coordSys, sel));
00239 }
00240 
00241 void Simulation::setFrame(const FrameOfReference& _frame)
00242 {
00243     activeObserver->setFrame(_frame);
00244 }
00245 
00246 FrameOfReference Simulation::getFrame() const
00247 {
00248     return activeObserver->getFrame();
00249 }
00250 
00251 // Rotate the observer about its center.
00252 void Simulation::rotate(Quatf q)
00253 {
00254     activeObserver->rotate(q);
00255 }
00256 
00257 // Orbit around the selection (if there is one.)  This involves changing
00258 // both the observer's position and orientation.
00259 void Simulation::orbit(Quatf q)
00260 {
00261     activeObserver->orbit(selection, q);
00262 }
00263 
00264 
00265 // Exponential camera dolly--move toward or away from the selected object
00266 // at a rate dependent on the observer's distance from the object.
00267 void Simulation::changeOrbitDistance(float d)
00268 {
00269     activeObserver->changeOrbitDistance(selection, d);
00270 }
00271 
00272 
00273 void Simulation::setTargetSpeed(float s)
00274 {
00275     activeObserver->setTargetSpeed(s);
00276 }
00277 
00278 float Simulation::getTargetSpeed()
00279 {
00280     return activeObserver->getTargetSpeed();
00281 }
00282 
00283 void Simulation::gotoSelection(double gotoTime, 
00284                                Vec3f up,
00285                                astro::CoordinateSystem upFrame)
00286 {
00287     if (selection.getType() == Selection::Type_Location)
00288     {
00289         activeObserver->gotoSelectionGC(selection,
00290                                         gotoTime, 0.0, 0.5,
00291                                         up, upFrame);
00292     }
00293     else
00294     {
00295         activeObserver->gotoSelection(selection, gotoTime, up, upFrame);
00296     }
00297 }
00298 
00299 void Simulation::gotoSelection(double gotoTime,
00300                                double distance,
00301                                Vec3f up,
00302                                astro::CoordinateSystem upFrame)
00303 {
00304     activeObserver->gotoSelection(selection, gotoTime, distance, up, upFrame);
00305 }
00306 
00307 void Simulation::gotoSelectionLongLat(double gotoTime,
00308                                       double distance,
00309                                       float longitude,
00310                                       float latitude,
00311                                       Vec3f up)
00312 {
00313     activeObserver->gotoSelectionLongLat(selection, gotoTime, distance,
00314                                          longitude, latitude, up);
00315 }
00316 
00317 
00318 void Simulation::gotoLocation(const RigidTransform& transform,
00319                               double duration)
00320 {
00321     activeObserver->gotoLocation(transform, duration);
00322 }
00323 
00324 
00325 void Simulation::getSelectionLongLat(double& distance,
00326                                      double& longitude,
00327                                      double& latitude)
00328 {
00329     activeObserver->getSelectionLongLat(selection, distance, longitude, latitude);
00330 }
00331 
00332 
00333 void Simulation::gotoSurface(double duration)
00334 {
00335     activeObserver->gotoSurface(selection, duration);
00336 };
00337 
00338 
00339 void Simulation::cancelMotion()
00340 {
00341     activeObserver->cancelMotion();
00342 }
00343 
00344 void Simulation::centerSelection(double centerTime)
00345 {
00346     activeObserver->centerSelection(selection, centerTime);
00347 }
00348 
00349 void Simulation::centerSelectionCO(double centerTime)
00350 {
00351     activeObserver->centerSelectionCO(selection, centerTime);
00352 }
00353 
00354 void Simulation::follow()
00355 {
00356     activeObserver->follow(selection);
00357 }
00358 
00359 void Simulation::geosynchronousFollow()
00360 {
00361     activeObserver->geosynchronousFollow(selection);
00362 }
00363 
00364 void Simulation::phaseLock()
00365 {
00366     activeObserver->phaseLock(selection);
00367 }
00368 
00369 void Simulation::chase()
00370 {
00371     activeObserver->chase(selection);
00372 }
00373 
00374 
00375 // Choose a planet around a star given it's index in the planetary system.
00376 // The planetary system is either the system of the selected object, or the
00377 // nearest planetary system if no object is selected.  If index is less than
00378 // zero, pick the star.  This function should probably be in celestiacore.cpp.
00379 void Simulation::selectPlanet(int index)
00380 {
00381     if (index < 0)
00382     {
00383         if (selection.getType() == Selection::Type_Body)
00384         {
00385             PlanetarySystem* system = selection.body()->getSystem();
00386             if (system != NULL)
00387                 setSelection(system->getStar());
00388         }
00389     }
00390     else
00391     {
00392         const Star* star = NULL;
00393         if (selection.getType() == Selection::Type_Star)
00394             star = selection.star();
00395         else if (selection.getType() == Selection::Type_Body)
00396             star = getSun(selection.body());
00397 
00398         SolarSystem* solarSystem = NULL;
00399         if (star != NULL)
00400             solarSystem = universe->getSolarSystem(star);
00401         else
00402             solarSystem = closestSolarSystem;
00403 
00404         if (solarSystem != NULL &&
00405             index < solarSystem->getPlanets()->getSystemSize())
00406         {
00407             setSelection(Selection(solarSystem->getPlanets()->getBody(index)));
00408         }
00409     }
00410 }
00411 
00412 
00413 // Select an object by name, with the following priority:
00414 //   1. Try to look up the name in the star database
00415 //   2. Search the deep sky catalog for a matching name.
00416 //   3. Search the planets and moons in the planetary system of the currently selected
00417 //      star
00418 //   4. Search the planets and moons in any 'nearby' (< 0.1 ly) planetary systems
00419 Selection Simulation::findObject(string s, bool i18n)
00420 {
00421     Selection path[2];
00422     int nPathEntries = 0;
00423 
00424     if (!selection.empty())
00425         path[nPathEntries++] = selection;
00426 
00427     if (closestSolarSystem != NULL)
00428         path[nPathEntries++] = Selection(closestSolarSystem->getStar());
00429 
00430     return universe->find(s, path, nPathEntries, i18n);
00431 }
00432 
00433 
00434 // Find an object from a path, for example Sol/Earth/Moon or Upsilon And/b
00435 // Currently, 'absolute' paths starting with a / are not supported nor are
00436 // paths that contain galaxies.
00437 Selection Simulation::findObjectFromPath(string s, bool i18n)
00438 {
00439     Selection path[2];
00440     int nPathEntries = 0;
00441 
00442     if (!selection.empty())
00443         path[nPathEntries++] = selection;
00444 
00445     if (closestSolarSystem != NULL)
00446         path[nPathEntries++] = Selection(closestSolarSystem->getStar());
00447 
00448     return universe->findPath(s, path, nPathEntries, i18n);
00449 }
00450 
00451 
00452 vector<std::string> Simulation::getObjectCompletion(string s, bool withLocations)
00453 {
00454     Selection path[2];
00455     int nPathEntries = 0;
00456 
00457     if (!selection.empty()) {
00458         if (selection.getType() == Selection::Type_Location)
00459         {
00460             path[nPathEntries++] = Selection(selection.location()->getParentBody());
00461         }
00462         else
00463         {
00464             path[nPathEntries++] = selection;
00465         }
00466     }
00467 
00468     if (closestSolarSystem != NULL &&
00469         closestSolarSystem != universe->getSolarSystem(selection))
00470     {
00471         path[nPathEntries++] = Selection(closestSolarSystem->getStar());
00472     }
00473 
00474     return universe->getCompletionPath(s, path, nPathEntries, withLocations);
00475 }
00476 
00477 
00478 double Simulation::getTimeScale() const
00479 {
00480     return timeScale;
00481 }
00482 
00483 void Simulation::setTimeScale(double _timeScale)
00484 {
00485     timeScale = _timeScale;
00486 }
00487 
00488 bool Simulation::getSyncTime() const
00489 {
00490     return syncTime;
00491 }
00492 
00493 void Simulation::setSyncTime(bool sync)
00494 {
00495     syncTime = sync;
00496 }
00497 
00498 // Synchronize all observers to active observer time
00499 void Simulation::synchronizeTime()
00500 {
00501     for (vector<Observer*>::iterator iter = observers.begin();
00502          iter != observers.end(); iter++)
00503     {
00504         (*iter)->setTime(activeObserver->getTime());
00505     }
00506 }
00507 
00508 
00509 float Simulation::getFaintestVisible() const
00510 {
00511     return faintestVisible;
00512 }
00513 
00514 
00515 void Simulation::setFaintestVisible(float magnitude)
00516 {
00517     faintestVisible = magnitude;
00518 }
00519 
00520 
00521 SolarSystem* Simulation::getNearestSolarSystem() const
00522 {
00523     return closestSolarSystem;
00524 }

Generated on Sat Jan 14 22:30:28 2006 for Celestia by  doxygen 1.4.1