simulation.cpp
上传用户:center1979
上传日期:2022-07-26
资源大小:50633k
文件大小:13k
- // simulation.cpp
- //
- // Copyright (C) 2001, Chris Laurel <claurel@shatters.net>
- //
- // The core of Celestia--tracks an observer moving through a
- // stars and their solar systems.
- //
- // This program is free software; you can redistribute it and/or
- // modify it under the terms of the GNU General Public License
- // as published by the Free Software Foundation; either version 2
- // of the License, or (at your option) any later version.
- #include <algorithm>
- #include "simulation.h"
- using namespace std;
- Simulation::Simulation(Universe* _universe) :
- realTime(0.0),
- timeScale(1.0),
- storedTimeScale(1.0),
- syncTime(true),
- universe(_universe),
- closestSolarSystem(NULL),
- selection(),
- faintestVisible(5.0f),
- pauseState(false)
- {
- activeObserver = new Observer();
- observers.insert(observers.end(), activeObserver);
- }
- Simulation::~Simulation()
- {
- for (vector<Observer*>::iterator iter = observers.begin();
- iter != observers.end(); iter++)
- {
- delete *iter;
- }
- }
- static const Star* getSun(Body* body)
- {
- PlanetarySystem* system = body->getSystem();
- if (system == NULL)
- return NULL;
- else
- return system->getStar();
- }
- void Simulation::render(Renderer& renderer)
- {
- renderer.render(*activeObserver,
- *universe,
- faintestVisible,
- selection);
- }
- void Simulation::draw(Renderer& renderer)
- {
- renderer.draw(*activeObserver,
- *universe,
- faintestVisible,
- selection);
- }
- void Simulation::render(Renderer& renderer, Observer& observer)
- {
- renderer.render(observer,
- *universe,
- faintestVisible,
- selection);
- }
- Universe* Simulation::getUniverse() const
- {
- return universe;
- }
- // Get the time (Julian date)
- double Simulation::getTime() const
- {
- return activeObserver->getTime();
- }
- // Set the time to the specified Julian date
- void Simulation::setTime(double jd)
- {
- if (syncTime)
- {
- for (vector<Observer*>::iterator iter = observers.begin();
- iter != observers.end(); iter++)
- {
- (*iter)->setTime(jd);
- }
- }
- else
- {
- activeObserver->setTime(jd);
- }
- }
- // Get the clock time elapsed since the object was created
- double Simulation::getRealTime() const
- {
- return realTime;
- }
- double Simulation::getArrivalTime() const
- {
- return activeObserver->getArrivalTime();
- }
- // Tick the simulation by dt seconds
- void Simulation::update(double dt)
- {
- realTime += dt;
- for (vector<Observer*>::iterator iter = observers.begin();
- iter != observers.end(); iter++)
- {
- (*iter)->update(dt, timeScale);
- }
- // Find the closest solar system
- closestSolarSystem = universe->getNearestSolarSystem(activeObserver->getPosition());
- }
- Selection Simulation::getSelection() const
- {
- return selection;
- }
- void Simulation::setSelection(const Selection& sel)
- {
- selection = sel;
- }
- Selection Simulation::getTrackedObject() const
- {
- return activeObserver->getTrackedObject();
- }
- void Simulation::setTrackedObject(const Selection& sel)
- {
- activeObserver->setTrackedObject(sel);
- }
- Selection Simulation::pickObject(Vec3f pickRay, int renderFlags, float tolerance)
- {
- return universe->pick(activeObserver->getPosition(),
- pickRay * activeObserver->getOrientationf().toMatrix4(),
- activeObserver->getTime(),
- renderFlags,
- faintestVisible,
- tolerance);
- }
- void Simulation::reverseObserverOrientation()
- {
- activeObserver->reverseOrientation();
- }
- Observer& Simulation::getObserver()
- {
- return *activeObserver;
- }
- Observer* Simulation::addObserver()
- {
- Observer* o = new Observer();
- observers.insert(observers.end(), o);
- return o;
- }
- void Simulation::removeObserver(Observer* o)
- {
- vector<Observer*>::iterator iter = find(observers.begin(), observers.end(), o);
- if (iter != observers.end())
- observers.erase(iter);
- }
- Observer* Simulation::getActiveObserver()
- {
- return activeObserver;
- }
- void Simulation::setActiveObserver(Observer* o)
- {
- vector<Observer*>::iterator iter= find(observers.begin(), observers.end(), o);
- if (iter != observers.end())
- activeObserver = o;
- }
- void Simulation::setObserverPosition(const UniversalCoord& pos)
- {
- activeObserver->setPosition(pos);
- }
- void Simulation::setObserverOrientation(const Quatf& orientation)
- {
- activeObserver->setOrientation(orientation);
- }
- Observer::ObserverMode Simulation::getObserverMode() const
- {
- return activeObserver->getMode();
- }
- void Simulation::setObserverMode(Observer::ObserverMode mode)
- {
- activeObserver->setMode(mode);
- }
- void Simulation::setFrame(ObserverFrame::CoordinateSystem coordSys,
- const Selection& refObject,
- const Selection& targetObject)
- {
- activeObserver->setFrame(coordSys, refObject, targetObject);
- }
- void Simulation::setFrame(ObserverFrame::CoordinateSystem coordSys,
- const Selection& refObject)
- {
- activeObserver->setFrame(coordSys, refObject);
- }
- const ObserverFrame* Simulation::getFrame() const
- {
- return activeObserver->getFrame();
- }
- // Rotate the observer about its center.
- void Simulation::rotate(Quatf q)
- {
- activeObserver->rotate(q);
- }
- // Orbit around the selection (if there is one.) This involves changing
- // both the observer's position and orientation.
- void Simulation::orbit(Quatf q)
- {
- activeObserver->orbit(selection, q);
- }
- // Exponential camera dolly--move toward or away from the selected object
- // at a rate dependent on the observer's distance from the object.
- void Simulation::changeOrbitDistance(float d)
- {
- activeObserver->changeOrbitDistance(selection, d);
- }
- void Simulation::setTargetSpeed(float s)
- {
- activeObserver->setTargetSpeed(s);
- }
- float Simulation::getTargetSpeed()
- {
- return activeObserver->getTargetSpeed();
- }
- void Simulation::gotoSelection(double gotoTime,
- Vec3f up,
- ObserverFrame::CoordinateSystem upFrame)
- {
- if (selection.getType() == Selection::Type_Location)
- {
- activeObserver->gotoSelectionGC(selection,
- gotoTime, 0.0, 0.5,
- up, upFrame);
- }
- else
- {
- activeObserver->gotoSelection(selection, gotoTime, up, upFrame);
- }
- }
- void Simulation::gotoSelection(double gotoTime,
- double distance,
- Vec3f up,
- ObserverFrame::CoordinateSystem upCoordSys)
- {
- activeObserver->gotoSelection(selection, gotoTime, distance, up, upCoordSys);
- }
- void Simulation::gotoSelectionLongLat(double gotoTime,
- double distance,
- float longitude,
- float latitude,
- Vec3f up)
- {
- activeObserver->gotoSelectionLongLat(selection, gotoTime, distance,
- longitude, latitude, up);
- }
- void Simulation::gotoLocation(const UniversalCoord& position,
- const Quatd& orientation,
- double duration)
- {
- activeObserver->gotoLocation(position, orientation, duration);
- }
- void Simulation::getSelectionLongLat(double& distance,
- double& longitude,
- double& latitude)
- {
- activeObserver->getSelectionLongLat(selection, distance, longitude, latitude);
- }
- void Simulation::gotoSurface(double duration)
- {
- activeObserver->gotoSurface(selection, duration);
- };
- void Simulation::cancelMotion()
- {
- activeObserver->cancelMotion();
- }
- void Simulation::centerSelection(double centerTime)
- {
- activeObserver->centerSelection(selection, centerTime);
- }
- void Simulation::centerSelectionCO(double centerTime)
- {
- activeObserver->centerSelectionCO(selection, centerTime);
- }
- void Simulation::follow()
- {
- activeObserver->follow(selection);
- }
- void Simulation::geosynchronousFollow()
- {
- activeObserver->geosynchronousFollow(selection);
- }
- void Simulation::phaseLock()
- {
- activeObserver->phaseLock(selection);
- }
- void Simulation::chase()
- {
- activeObserver->chase(selection);
- }
- // Choose a planet around a star given it's index in the planetary system.
- // The planetary system is either the system of the selected object, or the
- // nearest planetary system if no object is selected. If index is less than
- // zero, pick the star. This function should probably be in celestiacore.cpp.
- void Simulation::selectPlanet(int index)
- {
- if (index < 0)
- {
- if (selection.getType() == Selection::Type_Body)
- {
- PlanetarySystem* system = selection.body()->getSystem();
- if (system != NULL)
- setSelection(system->getStar());
- }
- }
- else
- {
- const Star* star = NULL;
- if (selection.getType() == Selection::Type_Star)
- star = selection.star();
- else if (selection.getType() == Selection::Type_Body)
- star = getSun(selection.body());
- SolarSystem* solarSystem = NULL;
- if (star != NULL)
- solarSystem = universe->getSolarSystem(star);
- else
- solarSystem = closestSolarSystem;
- if (solarSystem != NULL &&
- index < solarSystem->getPlanets()->getSystemSize())
- {
- setSelection(Selection(solarSystem->getPlanets()->getBody(index)));
- }
- }
- }
- // Select an object by name, with the following priority:
- // 1. Try to look up the name in the star database
- // 2. Search the deep sky catalog for a matching name.
- // 3. Search the planets and moons in the planetary system of the currently selected
- // star
- // 4. Search the planets and moons in any 'nearby' (< 0.1 ly) planetary systems
- Selection Simulation::findObject(string s, bool i18n)
- {
- Selection path[2];
- int nPathEntries = 0;
- if (!selection.empty())
- path[nPathEntries++] = selection;
- if (closestSolarSystem != NULL)
- path[nPathEntries++] = Selection(closestSolarSystem->getStar());
- return universe->find(s, path, nPathEntries, i18n);
- }
- // Find an object from a path, for example Sol/Earth/Moon or Upsilon And/b
- // Currently, 'absolute' paths starting with a / are not supported nor are
- // paths that contain galaxies.
- Selection Simulation::findObjectFromPath(string s, bool i18n)
- {
- Selection path[2];
- int nPathEntries = 0;
- if (!selection.empty())
- path[nPathEntries++] = selection;
- if (closestSolarSystem != NULL)
- path[nPathEntries++] = Selection(closestSolarSystem->getStar());
- return universe->findPath(s, path, nPathEntries, i18n);
- }
- vector<std::string> Simulation::getObjectCompletion(string s, bool withLocations)
- {
- Selection path[2];
- int nPathEntries = 0;
- if (!selection.empty()) {
- if (selection.getType() == Selection::Type_Location)
- {
- path[nPathEntries++] = Selection(selection.location()->getParentBody());
- }
- else
- {
- path[nPathEntries++] = selection;
- }
- }
- if (closestSolarSystem != NULL &&
- closestSolarSystem != universe->getSolarSystem(selection))
- {
- path[nPathEntries++] = Selection(closestSolarSystem->getStar());
- }
- return universe->getCompletionPath(s, path, nPathEntries, withLocations);
- }
- double Simulation::getTimeScale() const
- {
- return pauseState?storedTimeScale:timeScale;
- }
- void Simulation::setTimeScale(double _timeScale)
- {
- if (pauseState == true)
- {
- storedTimeScale = _timeScale;
- }
- else
- {
- timeScale = _timeScale;
- }
- }
- bool Simulation::getSyncTime() const
- {
- return syncTime;
- }
- void Simulation::setSyncTime(bool sync)
- {
- syncTime = sync;
- }
- bool Simulation::getPauseState() const
- {
- return pauseState;
- }
- void Simulation::setPauseState(bool state)
- {
- if (pauseState == state) return;
- pauseState = state;
- if (pauseState == true)
- {
- storedTimeScale = timeScale;
- timeScale = 0.0;
- }
- else
- {
- timeScale = storedTimeScale;
- }
- }
- // Synchronize all observers to active observer time
- void Simulation::synchronizeTime()
- {
- for (vector<Observer*>::iterator iter = observers.begin();
- iter != observers.end(); iter++)
- {
- (*iter)->setTime(activeObserver->getTime());
- }
- }
- float Simulation::getFaintestVisible() const
- {
- return faintestVisible;
- }
- void Simulation::setFaintestVisible(float magnitude)
- {
- faintestVisible = magnitude;
- }
- SolarSystem* Simulation::getNearestSolarSystem() const
- {
- return closestSolarSystem;
- }