Added support for alternate surface textures for planets/moons/etc.
parent
b8c245ed85
commit
6e4d02e324
|
@ -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)
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -326,6 +326,7 @@ class Renderer
|
|||
float saturationMag;
|
||||
|
||||
Color ambientColor;
|
||||
std::string displayedSurface;
|
||||
|
||||
StarVertexBuffer* starVertexBuffer;
|
||||
std::vector<RenderListEntry> renderList;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 = "");
|
||||
|
|
Loading…
Reference in New Issue