simulation.cpp
上传用户:center1979
上传日期:2022-07-26
资源大小:50633k
文件大小:13k
源码类别:

OpenGL

开发平台:

Visual C++

  1. // simulation.cpp
  2. //
  3. // Copyright (C) 2001, Chris Laurel <claurel@shatters.net>
  4. //
  5. // The core of Celestia--tracks an observer moving through a
  6. // stars and their solar systems.
  7. //
  8. // This program is free software; you can redistribute it and/or
  9. // modify it under the terms of the GNU General Public License
  10. // as published by the Free Software Foundation; either version 2
  11. // of the License, or (at your option) any later version.
  12. #include <algorithm>
  13. #include "simulation.h"
  14. using namespace std;
  15. Simulation::Simulation(Universe* _universe) :
  16.     realTime(0.0),
  17.     timeScale(1.0),
  18.     storedTimeScale(1.0),
  19.     syncTime(true),
  20.     universe(_universe),
  21.     closestSolarSystem(NULL),
  22.     selection(),
  23.     faintestVisible(5.0f),
  24.     pauseState(false)
  25. {
  26.     activeObserver = new Observer();
  27.     observers.insert(observers.end(), activeObserver);
  28. }
  29. Simulation::~Simulation()
  30. {
  31.     for (vector<Observer*>::iterator iter = observers.begin();
  32.          iter != observers.end(); iter++)
  33.     {
  34.         delete *iter;
  35.     }
  36. }
  37. static const Star* getSun(Body* body)
  38. {
  39.     PlanetarySystem* system = body->getSystem();
  40.     if (system == NULL)
  41.         return NULL;
  42.     else
  43.         return system->getStar();
  44. }
  45. void Simulation::render(Renderer& renderer)
  46. {
  47.     renderer.render(*activeObserver,
  48.                     *universe,
  49.                     faintestVisible,
  50.                     selection);
  51. }
  52. void Simulation::draw(Renderer& renderer)
  53. {
  54.     renderer.draw(*activeObserver,
  55.                   *universe,
  56.                   faintestVisible,
  57.                   selection);
  58. }
  59. void Simulation::render(Renderer& renderer, Observer& observer)
  60. {
  61.     renderer.render(observer,
  62.                     *universe,
  63.                     faintestVisible,
  64.                     selection);
  65. }
  66. Universe* Simulation::getUniverse() const
  67. {
  68.     return universe;
  69. }
  70. // Get the time (Julian date)
  71. double Simulation::getTime() const
  72. {
  73.     return activeObserver->getTime();
  74. }
  75. // Set the time to the specified Julian date
  76. void Simulation::setTime(double jd)
  77. {
  78.     if (syncTime)
  79.     {
  80.         for (vector<Observer*>::iterator iter = observers.begin();
  81.              iter != observers.end(); iter++)
  82.         {
  83.             (*iter)->setTime(jd);
  84.         }
  85.     }
  86.     else
  87.     {
  88.         activeObserver->setTime(jd);
  89.     }
  90. }
  91. // Get the clock time elapsed since the object was created
  92. double Simulation::getRealTime() const
  93. {
  94.     return realTime;
  95. }
  96. double Simulation::getArrivalTime() const
  97. {
  98.     return activeObserver->getArrivalTime();
  99. }
  100. // Tick the simulation by dt seconds
  101. void Simulation::update(double dt)
  102. {
  103.     realTime += dt;
  104.     for (vector<Observer*>::iterator iter = observers.begin();
  105.          iter != observers.end(); iter++)
  106.     {
  107.         (*iter)->update(dt, timeScale);
  108.     }
  109.     // Find the closest solar system
  110.     closestSolarSystem = universe->getNearestSolarSystem(activeObserver->getPosition());
  111. }
  112. Selection Simulation::getSelection() const
  113. {
  114.     return selection;
  115. }
  116. void Simulation::setSelection(const Selection& sel)
  117. {
  118.     selection = sel;
  119. }
  120. Selection Simulation::getTrackedObject() const
  121. {
  122.     return activeObserver->getTrackedObject();
  123. }
  124. void Simulation::setTrackedObject(const Selection& sel)
  125. {
  126.     activeObserver->setTrackedObject(sel);
  127. }
  128. Selection Simulation::pickObject(Vec3f pickRay, int renderFlags, float tolerance)
  129. {
  130.     return universe->pick(activeObserver->getPosition(),
  131.                           pickRay * activeObserver->getOrientationf().toMatrix4(),
  132.                           activeObserver->getTime(),
  133.                           renderFlags,
  134.                           faintestVisible,
  135.                           tolerance);
  136. }
  137. void Simulation::reverseObserverOrientation()
  138. {
  139.     activeObserver->reverseOrientation();
  140. }
  141. Observer& Simulation::getObserver()
  142. {
  143.     return *activeObserver;
  144. }
  145. Observer* Simulation::addObserver()
  146. {
  147.     Observer* o = new Observer();
  148.     observers.insert(observers.end(), o);
  149.     return o;
  150. }
  151. void Simulation::removeObserver(Observer* o)
  152. {
  153.     vector<Observer*>::iterator iter = find(observers.begin(), observers.end(), o);
  154.     if (iter != observers.end())
  155.         observers.erase(iter);
  156. }
  157. Observer* Simulation::getActiveObserver()
  158. {
  159.     return activeObserver;
  160. }
  161. void Simulation::setActiveObserver(Observer* o)
  162. {
  163.     vector<Observer*>::iterator iter= find(observers.begin(), observers.end(), o);
  164.     if (iter != observers.end())
  165.         activeObserver = o;
  166. }
  167. void Simulation::setObserverPosition(const UniversalCoord& pos)
  168. {
  169.     activeObserver->setPosition(pos);
  170. }
  171. void Simulation::setObserverOrientation(const Quatf& orientation)
  172. {
  173.     activeObserver->setOrientation(orientation);
  174. }
  175. Observer::ObserverMode Simulation::getObserverMode() const
  176. {
  177.     return activeObserver->getMode();
  178. }
  179. void Simulation::setObserverMode(Observer::ObserverMode mode)
  180. {
  181.     activeObserver->setMode(mode);
  182. }
  183. void Simulation::setFrame(ObserverFrame::CoordinateSystem coordSys,
  184.                           const Selection& refObject,
  185.                           const Selection& targetObject)
  186. {
  187.     activeObserver->setFrame(coordSys, refObject, targetObject);
  188. }
  189. void Simulation::setFrame(ObserverFrame::CoordinateSystem coordSys,
  190.                           const Selection& refObject)
  191. {
  192.     activeObserver->setFrame(coordSys, refObject);
  193. }
  194. const ObserverFrame* Simulation::getFrame() const
  195. {
  196.     return activeObserver->getFrame();
  197. }
  198. // Rotate the observer about its center.
  199. void Simulation::rotate(Quatf q)
  200. {
  201.     activeObserver->rotate(q);
  202. }
  203. // Orbit around the selection (if there is one.)  This involves changing
  204. // both the observer's position and orientation.
  205. void Simulation::orbit(Quatf q)
  206. {
  207.     activeObserver->orbit(selection, q);
  208. }
  209. // Exponential camera dolly--move toward or away from the selected object
  210. // at a rate dependent on the observer's distance from the object.
  211. void Simulation::changeOrbitDistance(float d)
  212. {
  213.     activeObserver->changeOrbitDistance(selection, d);
  214. }
  215. void Simulation::setTargetSpeed(float s)
  216. {
  217.     activeObserver->setTargetSpeed(s);
  218. }
  219. float Simulation::getTargetSpeed()
  220. {
  221.     return activeObserver->getTargetSpeed();
  222. }
  223. void Simulation::gotoSelection(double gotoTime,
  224.                                Vec3f up,
  225.                                ObserverFrame::CoordinateSystem upFrame)
  226. {
  227.     if (selection.getType() == Selection::Type_Location)
  228.     {
  229.         activeObserver->gotoSelectionGC(selection,
  230.                                         gotoTime, 0.0, 0.5,
  231.                                         up, upFrame);
  232.     }
  233.     else
  234.     {
  235.         activeObserver->gotoSelection(selection, gotoTime, up, upFrame);
  236.     }
  237. }
  238. void Simulation::gotoSelection(double gotoTime,
  239.                                double distance,
  240.                                Vec3f up,
  241.                                ObserverFrame::CoordinateSystem upCoordSys)
  242. {
  243.     activeObserver->gotoSelection(selection, gotoTime, distance, up, upCoordSys);
  244. }
  245. void Simulation::gotoSelectionLongLat(double gotoTime,
  246.                                       double distance,
  247.                                       float longitude,
  248.                                       float latitude,
  249.                                       Vec3f up)
  250. {
  251.     activeObserver->gotoSelectionLongLat(selection, gotoTime, distance,
  252.                                          longitude, latitude, up);
  253. }
  254. void Simulation::gotoLocation(const UniversalCoord& position,
  255.                               const Quatd& orientation,
  256.                               double duration)
  257. {
  258.     activeObserver->gotoLocation(position, orientation, duration);
  259. }
  260. void Simulation::getSelectionLongLat(double& distance,
  261.                                      double& longitude,
  262.                                      double& latitude)
  263. {
  264.     activeObserver->getSelectionLongLat(selection, distance, longitude, latitude);
  265. }
  266. void Simulation::gotoSurface(double duration)
  267. {
  268.     activeObserver->gotoSurface(selection, duration);
  269. };
  270. void Simulation::cancelMotion()
  271. {
  272.     activeObserver->cancelMotion();
  273. }
  274. void Simulation::centerSelection(double centerTime)
  275. {
  276.     activeObserver->centerSelection(selection, centerTime);
  277. }
  278. void Simulation::centerSelectionCO(double centerTime)
  279. {
  280.     activeObserver->centerSelectionCO(selection, centerTime);
  281. }
  282. void Simulation::follow()
  283. {
  284.     activeObserver->follow(selection);
  285. }
  286. void Simulation::geosynchronousFollow()
  287. {
  288.     activeObserver->geosynchronousFollow(selection);
  289. }
  290. void Simulation::phaseLock()
  291. {
  292.     activeObserver->phaseLock(selection);
  293. }
  294. void Simulation::chase()
  295. {
  296.     activeObserver->chase(selection);
  297. }
  298. // Choose a planet around a star given it's index in the planetary system.
  299. // The planetary system is either the system of the selected object, or the
  300. // nearest planetary system if no object is selected.  If index is less than
  301. // zero, pick the star.  This function should probably be in celestiacore.cpp.
  302. void Simulation::selectPlanet(int index)
  303. {
  304.     if (index < 0)
  305.     {
  306.         if (selection.getType() == Selection::Type_Body)
  307.         {
  308.             PlanetarySystem* system = selection.body()->getSystem();
  309.             if (system != NULL)
  310.                 setSelection(system->getStar());
  311.         }
  312.     }
  313.     else
  314.     {
  315.         const Star* star = NULL;
  316.         if (selection.getType() == Selection::Type_Star)
  317.             star = selection.star();
  318.         else if (selection.getType() == Selection::Type_Body)
  319.             star = getSun(selection.body());
  320.         SolarSystem* solarSystem = NULL;
  321.         if (star != NULL)
  322.             solarSystem = universe->getSolarSystem(star);
  323.         else
  324.             solarSystem = closestSolarSystem;
  325.         if (solarSystem != NULL &&
  326.             index < solarSystem->getPlanets()->getSystemSize())
  327.         {
  328.             setSelection(Selection(solarSystem->getPlanets()->getBody(index)));
  329.         }
  330.     }
  331. }
  332. // Select an object by name, with the following priority:
  333. //   1. Try to look up the name in the star database
  334. //   2. Search the deep sky catalog for a matching name.
  335. //   3. Search the planets and moons in the planetary system of the currently selected
  336. //      star
  337. //   4. Search the planets and moons in any 'nearby' (< 0.1 ly) planetary systems
  338. Selection Simulation::findObject(string s, bool i18n)
  339. {
  340.     Selection path[2];
  341.     int nPathEntries = 0;
  342.     if (!selection.empty())
  343.         path[nPathEntries++] = selection;
  344.     if (closestSolarSystem != NULL)
  345.         path[nPathEntries++] = Selection(closestSolarSystem->getStar());
  346.     return universe->find(s, path, nPathEntries, i18n);
  347. }
  348. // Find an object from a path, for example Sol/Earth/Moon or Upsilon And/b
  349. // Currently, 'absolute' paths starting with a / are not supported nor are
  350. // paths that contain galaxies.
  351. Selection Simulation::findObjectFromPath(string s, bool i18n)
  352. {
  353.     Selection path[2];
  354.     int nPathEntries = 0;
  355.     if (!selection.empty())
  356.         path[nPathEntries++] = selection;
  357.     if (closestSolarSystem != NULL)
  358.         path[nPathEntries++] = Selection(closestSolarSystem->getStar());
  359.     return universe->findPath(s, path, nPathEntries, i18n);
  360. }
  361. vector<std::string> Simulation::getObjectCompletion(string s, bool withLocations)
  362. {
  363.     Selection path[2];
  364.     int nPathEntries = 0;
  365.     if (!selection.empty()) {
  366.         if (selection.getType() == Selection::Type_Location)
  367.         {
  368.             path[nPathEntries++] = Selection(selection.location()->getParentBody());
  369.         }
  370.         else
  371.         {
  372.             path[nPathEntries++] = selection;
  373.         }
  374.     }
  375.     if (closestSolarSystem != NULL &&
  376.         closestSolarSystem != universe->getSolarSystem(selection))
  377.     {
  378.         path[nPathEntries++] = Selection(closestSolarSystem->getStar());
  379.     }
  380.     return universe->getCompletionPath(s, path, nPathEntries, withLocations);
  381. }
  382. double Simulation::getTimeScale() const
  383. {
  384.     return pauseState?storedTimeScale:timeScale;
  385. }
  386. void Simulation::setTimeScale(double _timeScale)
  387. {
  388.     if (pauseState == true)
  389.     {
  390.         storedTimeScale = _timeScale;
  391.     }
  392.     else
  393.     {
  394.         timeScale = _timeScale;
  395.     }
  396. }
  397. bool Simulation::getSyncTime() const
  398. {
  399.     return syncTime;
  400. }
  401. void Simulation::setSyncTime(bool sync)
  402. {
  403.     syncTime = sync;
  404. }
  405. bool Simulation::getPauseState() const
  406. {
  407.     return pauseState;
  408. }
  409. void Simulation::setPauseState(bool state)
  410. {
  411.     if (pauseState == state) return;
  412.     pauseState = state;
  413.     if (pauseState == true)
  414.     {
  415.         storedTimeScale = timeScale;
  416.         timeScale = 0.0;
  417.     }
  418.     else
  419.     {
  420.         timeScale = storedTimeScale;
  421.     }
  422. }
  423. // Synchronize all observers to active observer time
  424. void Simulation::synchronizeTime()
  425. {
  426.     for (vector<Observer*>::iterator iter = observers.begin();
  427.          iter != observers.end(); iter++)
  428.     {
  429.         (*iter)->setTime(activeObserver->getTime());
  430.     }
  431. }
  432. float Simulation::getFaintestVisible() const
  433. {
  434.     return faintestVisible;
  435. }
  436. void Simulation::setFaintestVisible(float magnitude)
  437. {
  438.     faintestVisible = magnitude;
  439. }
  440. SolarSystem* Simulation::getNearestSolarSystem() const
  441. {
  442.     return closestSolarSystem;
  443. }