Added support for alternate surface textures for planets/moons/etc.

ver1_5_1
Chris Laurel 2003-06-09 03:57:43 +00:00
parent b8c245ed85
commit 6e4d02e324
8 changed files with 140 additions and 44 deletions

View File

@ -45,7 +45,8 @@ Body::Body(PlanetarySystem* _system) :
atmosphere(NULL),
rings(NULL),
satellites(NULL),
classification(Unknown)
classification(Unknown),
altSurfaces(NULL)
{
system = _system;
}
@ -418,6 +419,46 @@ void Body::setInfoURL(const string& _infoURL)
}
Surface* Body::getAlternateSurface(const string& name) const
{
if (altSurfaces == NULL)
return NULL;
AltSurfaceTable::iterator iter = altSurfaces->find(name);
if (iter == altSurfaces->end())
return NULL;
else
return iter->second;
}
void Body::addAlternateSurface(const string& name, Surface* surface)
{
if (altSurfaces == NULL)
altSurfaces = new AltSurfaceTable();
//altSurfaces->insert(AltSurfaceTable::value_type(name, surface));
(*altSurfaces)[name] = surface;
}
vector<string>* Body::getAlternateSurfaceNames() const
{
vector<string>* names = new vector<string>();
if (altSurfaces != NULL)
{
for (AltSurfaceTable::const_iterator iter = altSurfaces->begin();
iter != altSurfaces->end(); iter++)
{
names->insert(names->end(), iter->first);
}
}
return names;
}
/**** Implementation of PlanetarySystem ****/
PlanetarySystem::PlanetarySystem(Body* _primary) : primary(_primary)

View File

@ -12,6 +12,7 @@
#include <string>
#include <vector>
#include <map>
#include <celmath/quaternion.h>
#include <celengine/surface.h>
#include <celengine/atmosphere.h>
@ -163,6 +164,10 @@ class Body
bool extant(double) const;
void setLifespan(double, double);
Surface* getAlternateSurface(const std::string&) const;
void addAlternateSurface(const std::string&, Surface*);
std::vector<std::string>* getAlternateSurfaceNames() const;
private:
std::string name;
@ -191,6 +196,9 @@ class Body
int classification;
std::string infoURL;
typedef std::map<const std::string, Surface*> AltSurfaceTable;
AltSurfaceTable *altSurfaces;
};
#endif // _BODY_H_

View File

@ -336,6 +336,18 @@ void Observer::setTrackedObject(const Selection& sel)
}
const string& Observer::getDisplayedSurface() const
{
return displayedSurface;
}
void Observer::setDisplayedSurface(const string& surf)
{
displayedSurface = surf;
}
void Observer::reverseOrientation()
{
Quatf q = getOrientation();

View File

@ -25,7 +25,7 @@ class Observer
public:
Observer();
// The getPosition method returns the observer's position in light
// The getPosition method returns the observer's position in micro light
// years.
UniversalCoord getPosition() const;
@ -66,6 +66,9 @@ public:
Selection getTrackedObject() const;
void setTrackedObject(const Selection&);
const std::string& getDisplayedSurface() const;
void setDisplayedSurface(const std::string&);
void gotoSelection(const Selection&,
double gotoTime,
Vec3f up,
@ -170,6 +173,8 @@ public:
float fov;
bool reverseFlag;
std::string displayedSurface;
};
#endif // _CELENGINE_OBSERVER_H_

View File

@ -900,6 +900,9 @@ void Renderer::render(const Observer& observer,
// Set the modelview matrix
glMatrixMode(GL_MODELVIEW);
// Get the displayed surface texture set to use from the observer
displayedSurface = observer.getDisplayedSurface();
// Set up the camera
Point3f observerPos = (Point3f) observer.getPosition();
observerPos.x *= 1e-6f;
@ -1255,7 +1258,7 @@ void Renderer::render(const Observer& observer,
// The calls to renderSolarSystem/renderStars filled renderList
// with visible planetary bodies. Sort it by distance, then
// render each entry.
sort(renderList.begin(), renderList.end());
stable_sort(renderList.begin(), renderList.end());
int nEntries = renderList.size();
@ -3694,7 +3697,16 @@ void Renderer::renderPlanet(const Body& body,
{
RenderProperties rp;
rp.surface = const_cast<Surface *>(&body.getSurface());
if (displayedSurface.empty())
{
rp.surface = const_cast<Surface*>(&body.getSurface());
}
else
{
rp.surface = body.getAlternateSurface(displayedSurface);
if (rp.surface == NULL)
rp.surface = const_cast<Surface*>(&body.getSurface());
}
rp.atmosphere = body.getAtmosphere();
rp.rings = body.getRings();
rp.radius = body.getRadius();
@ -4330,7 +4342,6 @@ void Renderer::renderPlanetarySystem(const Star& sun,
now, showLabels);
}
}
}
}

View File

@ -326,6 +326,7 @@ class Renderer
float saturationMag;
Color ambientColor;
std::string displayedSurface;
StarVertexBuffer* starVertexBuffer;
std::vector<RenderListEntry> renderList;

View File

@ -484,6 +484,13 @@ bool LoadSolarSystemObjects(istream& in,
while (tokenizer.nextToken() != Tokenizer::TokenEnd)
{
string itemType("Body");
if (tokenizer.getTokenType() == Tokenizer::TokenName)
{
itemType = tokenizer.getNameValue();
tokenizer.nextToken();
}
if (tokenizer.getTokenType() != Tokenizer::TokenString)
{
cout << "Error parsing solar system file.\n";
@ -512,55 +519,67 @@ bool LoadSolarSystemObjects(istream& in,
}
Hash* objectData = objectDataValue->getHash();
DPRINTF(2, "Reading planet %s %s\n", parentName.c_str(), name.c_str());
DPRINTF(2, "%s %s %s\n", itemType.c_str(), parentName.c_str(), name.c_str());
Selection parent = universe.findPath(parentName, NULL, 0);
PlanetarySystem* parentSystem = NULL;
bool orbitsPlanet = false;
if (parent.star != NULL)
{
SolarSystem* solarSystem = universe.getSolarSystem(parent.star);
if (solarSystem == NULL)
{
// No solar system defined for this star yet, so we need
// to create it.
solarSystem = universe.createSolarSystem(parent.star);
}
parentSystem = solarSystem->getPlanets();
}
else if (parent.body != NULL)
{
// Parent is a planet or moon
parentSystem = parent.body->getSatellites();
if (parentSystem == NULL)
{
// If the planet doesn't already have any satellites, we
// have to create a new planetary system for it.
parentSystem = new PlanetarySystem(parent.body);
parent.body->setSatellites(parentSystem);
}
orbitsPlanet = true;
}
else
{
cout << "Parent body '" << parentName << "' of '" << name << "' not found.\n";
}
if (parentSystem != NULL)
if (itemType == "Body")
{
if (parentSystem->find(name))
bool orbitsPlanet = false;
if (parent.star != NULL)
{
DPRINTF(0, "Warning duplicate definition of %s %s!\n",
parentName.c_str(), name.c_str());
SolarSystem* solarSystem = universe.getSolarSystem(parent.star);
if (solarSystem == NULL)
{
// No solar system defined for this star yet, so we need
// to create it.
solarSystem = universe.createSolarSystem(parent.star);
}
parentSystem = solarSystem->getPlanets();
}
else if (parent.body != NULL)
{
// Parent is a planet or moon
parentSystem = parent.body->getSatellites();
if (parentSystem == NULL)
{
// If the planet doesn't already have any satellites, we
// have to create a new planetary system for it.
parentSystem = new PlanetarySystem(parent.body);
parent.body->setSatellites(parentSystem);
}
orbitsPlanet = true;
}
else
{
cout << "Parent body '" << parentName << "' of '" << name << "' not found.\n";
}
Body* body = CreatePlanet(parentSystem, objectData, directory, !orbitsPlanet);
if (body != NULL)
if (parentSystem != NULL)
{
body->setName(name);
parentSystem->addBody(body);
if (parentSystem->find(name))
{
DPRINTF(0, "Warning duplicate definition of %s %s!\n",
parentName.c_str(), name.c_str());
}
Body* body = CreatePlanet(parentSystem, objectData, directory, !orbitsPlanet);
if (body != NULL)
{
body->setName(name);
parentSystem->addBody(body);
}
}
}
else if (itemType == "AltSurface")
{
Surface* surface = CreateSurface(objectData, directory);
if (surface != NULL && parent.body != NULL)
parent.body->addAlternateSurface(name, surface);
else
DPRINTF(0, "Bad alternate surface\n");
}
}
// TODO: Return some notification if there's an error parsing the file

View File

@ -35,7 +35,6 @@ typedef std::map<uint32, SolarSystem*> SolarSystemCatalog;
class Universe;
bool ReadSolarSystems(std::istream&, const StarDatabase&, SolarSystemCatalog&);
bool LoadSolarSystemObjects(std::istream& in,
Universe& universe,
const std::string& dir = "");