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

solarsysxml.cpp File Reference

#include <cassert>
#include <libxml/parser.h>
#include <libxml/parserInternals.h>
#include <libxml/SAX.h>
#include <celutil/debug.h>
#include <celmath/mathlib.h>
#include "astro.h"
#include "customorbit.h"
#include "texmanager.h"
#include "meshmanager.h"
#include "solarsysxml.h"

Include dependency graph for solarsysxml.cpp:

Go to the source code of this file.

Enumerations

enum  ParserState {
  StartState, EndState, BodyState, SurfaceState,
  AtmosphereState, RingsState, BodyLeafState, SurfaceLeafState,
  AtmosphereLeafState, RingsLeafState, ErrorState
}

Functions

static bool createAtmosphere (ParserContext *ctx, const xmlChar **att)
static bool createBody (ParserContext *ctx, const xmlChar **att)
static ResourceHandle createBumpMap (ParserContext *ctx, const xmlChar **att)
static bool createCustomOrbit (ParserContext *ctx, const xmlChar **att)
static bool createEllipticalOrbit (ParserContext *ctx, const xmlChar **att)
static bool createGeometry (ParserContext *ctx, const xmlChar **att)
static bool createHaze (ParserContext *ctx, const xmlChar **att)
static bool createRings (ParserContext *ctx, const xmlChar **att)
static bool createRotation (ParserContext *ctx, const xmlChar **att)
static bool createSurface (ParserContext *ctx, const xmlChar **att)
static ResourceHandle createTexture (ParserContext *ctx, const xmlChar **att)
static int hexDigit (char c)
static void initSAXHandler (xmlSAXHandler &sax)
bool LoadSolarSystemObjectsXML (const string &source, Universe &universe)
static bool matchName (const xmlChar *s, const char *name)
ostream & operator<< (ostream &out, const Color &c)
static bool parseAngle (const xmlChar *s, float &f)
static bool parseAngle (const xmlChar *s, double &d)
static bool parseBoolean (const xmlChar *s, bool &b)
static bool parseColor (const xmlChar *s, Color &c)
static bool parseDistance (const xmlChar *s, float &f, char *defaultUnitName)
static bool parseDistance (const xmlChar *s, double &d, char *defaultUnitName)
static bool parseEpoch (const xmlChar *s, double &d)
static bool parseNumber (const xmlChar *s, float &f)
static bool parseNumber (const xmlChar *s, double &d)
static bool parseNumberUnits (const xmlChar *s, double &d, UnitDefinition *unitTable, int unitTableLength, char *defaultUnitName)
static bool parseSolarSystemXML (xmlSAXHandlerPtr sax, void *userData, const char *filename)
static bool parseTime (const xmlChar *s, float &f, char *defaultUnitName)
static bool parseTime (const xmlChar *s, double &d, char *defaultUnitName)
static void solarSysEndDocument (void *data)
static void solarSysEndElement (void *data, const xmlChar *name)
static void solarSysStartDocument (void *data)
static void solarSysStartElement (void *data, const xmlChar *name, const xmlChar **att)

Variables

UnitDefinition distanceUnits []
static xmlSAXHandler emptySAXHandler
static xmlSAXHandler saxHandler
UnitDefinition timeUnits []


Enumeration Type Documentation

enum ParserState
 

Enumeration values:
StartState 
EndState 
BodyState 
SurfaceState 
AtmosphereState 
RingsState 
BodyLeafState 
SurfaceLeafState 
AtmosphereLeafState 
RingsLeafState 
ErrorState 

Definition at line 85 of file solarsysxml.cpp.

00085                  {
00086     StartState,
00087     EndState,
00088     BodyState,
00089     SurfaceState,
00090     AtmosphereState,
00091     RingsState,
00092     BodyLeafState,
00093     SurfaceLeafState,
00094     AtmosphereLeafState,
00095     RingsLeafState,
00096     ErrorState,
00097 };


Function Documentation

static bool createAtmosphere ParserContext ctx,
const xmlChar **  att
[static]
 

Definition at line 558 of file solarsysxml.cpp.

References Atmosphere::cloudHeight, Atmosphere::cloudSpeed, Atmosphere::height, Atmosphere::lowerColor, matchName(), parseAngle(), parseColor(), parseDistance(), Atmosphere::skyColor, and Atmosphere::upperColor.

Referenced by solarSysStartElement().

00559 {
00560     Atmosphere* atmosphere = new Atmosphere();
00561 
00562     if (att != NULL)
00563     {
00564         for (int i = 0; att[i] != NULL; i += 2)
00565         {
00566             if (matchName(att[i], "height"))
00567                 parseDistance(att[i + 1], atmosphere->height, "km");
00568             else if (matchName(att[i], "lower-color"))
00569                 parseColor(att[i + 1], atmosphere->lowerColor);
00570             else if (matchName(att[i], "upper-color"))
00571                 parseColor(att[i + 1], atmosphere->upperColor);
00572             else if (matchName(att[i], "sky-color"))
00573                 parseColor(att[i + 1], atmosphere->skyColor);
00574             else if (matchName(att[i], "cloud-height"))
00575                 parseDistance(att[i + 1], atmosphere->cloudHeight, "km");
00576             else if (matchName(att[i], "cloud-speed"))
00577                 parseAngle(att[i + 1], atmosphere->cloudSpeed);
00578         }
00579     }
00580 
00581     assert(ctx->body != NULL);
00582     ctx->body->setAtmosphere(*atmosphere);
00583     delete atmosphere;
00584     
00585     return true;
00586 }

static bool createBody ParserContext ctx,
const xmlChar **  att
[static]
 

Definition at line 387 of file solarsysxml.cpp.

References PlanetarySystem::addBody(), Selection::body(), SolarSystem::getPlanets(), Body::getSatellites(), matchName(), Body::setName(), Body::setSatellites(), and Selection::star().

Referenced by solarSysStartElement().

00388 {
00389     const xmlChar* name = NULL;
00390     const xmlChar* parentName = NULL;
00391 
00392     // Get the name and parent attributes
00393     if (att != NULL)
00394     {
00395         for (int i = 0; att[i] != NULL; i += 2)
00396         {
00397             if (matchName(att[i], "name"))
00398                 name = att[i + 1];
00399             else if (matchName(att[i], "parent"))
00400                 parentName = att[i + 1];
00401         }
00402     }
00403 
00404     // Require that both are present
00405     if (name == NULL)
00406     {
00407         return false;
00408     }
00409     else if (parentName == NULL)
00410     {
00411         return false;
00412     }
00413 
00414     bool orbitsPlanet = false;
00415     Selection parent = ctx->universe->findPath(reinterpret_cast<const char*>(parentName), NULL, 0);
00416     PlanetarySystem* parentSystem = NULL;
00417     if (parent.star != NULL)
00418     {
00419         SolarSystem* solarSystem = ctx->universe->getSolarSystem(parent.star);
00420         if (solarSystem == NULL)
00421         {
00422             // No solar system defined for this star yet, so we need
00423             // to create it.
00424             solarSystem = ctx->universe->createSolarSystem(parent.star);
00425         }
00426         parentSystem = solarSystem->getPlanets();
00427     }
00428     else if (parent.body != NULL)
00429     {
00430         // Parent is a planet or moon
00431         parentSystem = parent.body->getSatellites();
00432         if (parentSystem == NULL)
00433         {
00434             // If the planet doesn't already have any satellites, we
00435             // have to create a new planetary system for it.
00436             parentSystem = new PlanetarySystem(parent.body);
00437             parent.body->setSatellites(parentSystem);
00438         }
00439         orbitsPlanet = true;
00440     }
00441     else
00442     {
00443         cout << "Parent body '" << parentName << "' of '" << name << "' not found.\n";
00444         return false;
00445     }
00446 
00447     if (parentSystem != NULL)
00448     {
00449         ctx->body = new Body(parentSystem);
00450         ctx->body->setName(reinterpret_cast<const char*>(name));
00451         parentSystem->addBody(ctx->body);
00452         return true;
00453     }
00454 
00455     return false;
00456 }

static ResourceHandle createBumpMap ParserContext ctx,
const xmlChar **  att
[static]
 

Definition at line 517 of file solarsysxml.cpp.

References ResourceManager< T >::getHandle(), GetTextureManager(), InvalidResource, matchName(), parseNumber(), and SurfaceState.

Referenced by solarSysStartElement().

00518 {
00519     const xmlChar* heightmap = NULL;
00520     float bumpHeight = 2.5f;
00521 
00522     // Get the type, image, and compress attributes
00523     if (att != NULL)
00524     {
00525         for (int i = 0; att[i] != NULL; i += 2)
00526         {
00527             if (matchName(att[i], "heightmap"))
00528                 heightmap = att[i + 1];
00529             else if (matchName(att[i], "bump-height"))
00530                 parseNumber(att[i + 1], bumpHeight);
00531         }
00532     }
00533 
00534     if (heightmap == NULL)
00535     {
00536         cout << "Bump map has no height map source.\n";
00537         return false;
00538     }
00539 
00540     ResourceHandle texHandle = GetTextureManager()->getHandle(TextureInfo(reinterpret_cast<const char*>(heightmap), bumpHeight));
00541     if (ctx->state == SurfaceState)
00542     {
00543         assert(ctx->body != NULL);
00544         if (texHandle != InvalidResource)
00545         {
00546             ctx->body->getSurface().bumpTexture = texHandle;
00547             ctx->body->getSurface().appearanceFlags |= Surface::ApplyBumpMap;
00548         }
00549         return true;
00550     }
00551     else
00552     {
00553         return false;
00554     }
00555 }

static bool createCustomOrbit ParserContext ctx,
const xmlChar **  att
[static]
 

Definition at line 779 of file solarsysxml.cpp.

References DPRINTF, GetCustomOrbit(), and matchName().

Referenced by solarSysStartElement().

00780 {
00781     const xmlChar* name = NULL;
00782 
00783     // Get the type, image, and compress attributes
00784     if (att != NULL)
00785     {
00786         for (int i = 0; att[i] != NULL; i += 2)
00787         {
00788             if (matchName(att[i], "name"))
00789                 name = att[i + 1];
00790         }
00791     }
00792 
00793     if (name == NULL)
00794         return false;
00795 
00796     Orbit* orbit = GetCustomOrbit(reinterpret_cast<const char*>(name));
00797     if (orbit == NULL)
00798     {
00799         DPRINTF(0, "Could not find custom orbit named '%s'\n",
00800                 reinterpret_cast<const char*>(name));
00801     }
00802     else
00803     {
00804         assert(ctx->body != NULL);
00805         ctx->body->setOrbit(orbit);
00806     }
00807 
00808     return true;
00809 }

static bool createEllipticalOrbit ParserContext ctx,
const xmlChar **  att
[static]
 

Definition at line 657 of file solarsysxml.cpp.

References degToRad(), matchName(), parseAngle(), parseDistance(), parseEpoch(), parseNumber(), and parseTime().

Referenced by solarSysStartElement().

00658 {
00659     // SemiMajorAxis and Period are absolutely required; everything
00660     // else has a reasonable default.
00661     double pericenterDistance = 0.0;
00662     double semiMajorAxis = 0.0;
00663     double period = 0.0;
00664     double eccentricity = 0.0;
00665     double inclination = 0.0;
00666     double ascendingNode = 0.0;
00667     double argOfPericenter = 0.0;
00668     double anomalyAtEpoch = 0.0;
00669     double epoch = astro::J2000;
00670     bool foundPeriod = false;
00671     bool foundSMA = false;
00672     bool foundPD = false;
00673 
00674     // On the first pass through the attribute list, extract the
00675     // period, epoch, ascending node, semi-major axis, eccentricity,
00676     // and inclination.
00677     if (att != NULL)
00678     {
00679         int i;
00680         for (i = 0; att[i] != NULL; i += 2)
00681         {
00682             if (matchName(att[i], "period"))
00683             {
00684                 foundPeriod = true;
00685                 parseTime(att[i + 1], period, "d");
00686             }
00687             else if (matchName(att[i], "semi-major-axis"))
00688             {
00689                 foundSMA = true;
00690                 parseDistance(att[i + 1], semiMajorAxis, "km");
00691                 cout << "SMA: " << semiMajorAxis << '\n';
00692             }
00693             else if (matchName(att[i], "pericenter-distance"))
00694             {
00695                 foundPD = true;
00696                 parseDistance(att[i + 1], pericenterDistance, "km");
00697             }
00698             else if (matchName(att[i], "epoch"))
00699                 parseEpoch(att[i + 1], epoch);
00700             else if (matchName(att[i], "eccentricity"))
00701                 parseNumber(att[i + 1], eccentricity);
00702             else if (matchName(att[i], "inclination"))
00703                 parseAngle(att[i + 1], inclination);
00704             else if (matchName(att[i], "ascending-node"))
00705                 parseAngle(att[i + 1], ascendingNode);
00706         }
00707 
00708         // On the next pass, get the argument or longitude of pericenter; it's
00709         // important that we get the longitude of pericenter after we know the
00710         // ascending node, because this value is required to convert to
00711         // argument of pericenter
00712         for (i = 0; att[i] != NULL; i += 2)
00713         {
00714             if (matchName(att[i], "arg-of-pericenter"))
00715             {
00716                 parseAngle(att[i + 1], argOfPericenter);
00717             }
00718             else if (matchName(att[i + 1], "long-of-pericenter"))
00719             {
00720                 double longOfPericenter;
00721                 parseAngle(att[i + 1], longOfPericenter);
00722                 argOfPericenter = longOfPericenter - ascendingNode;
00723             }
00724         }
00725 
00726         // On the third pass, get the anomaly or mean longitude; converting
00727         // from mean longitude to anomaly requires the arg of pericenter from the
00728         // second pass.
00729         for (i = 0; att[i] != NULL; i += 2)
00730         {
00731             if (matchName(att[i], "mean-anomaly"))
00732             {
00733                 parseAngle(att[i + 1], anomalyAtEpoch);
00734             }
00735             else if (matchName(att[i + 1], "mean-longitude"))
00736             {
00737                 double longAtEpoch;
00738                 parseAngle(att[i + 1], longAtEpoch);
00739                 anomalyAtEpoch = longAtEpoch - (argOfPericenter + ascendingNode);
00740             }
00741         }
00742     }
00743 
00744     if (!foundPeriod)
00745     {
00746         return false;
00747     }
00748     else if (!foundSMA && !foundPD)
00749     {
00750         return false;
00751     }
00752 
00753     // If we read the semi-major axis, use it to compute the pericenter
00754     // distance.
00755     if (foundSMA)
00756         pericenterDistance = semiMajorAxis * (1.0 - eccentricity);
00757 
00758     EllipticalOrbit* orbit = new EllipticalOrbit(pericenterDistance,
00759                                                  eccentricity,
00760                                                  degToRad(inclination),
00761                                                  degToRad(ascendingNode),
00762                                                  degToRad(argOfPericenter),
00763                                                  degToRad(anomalyAtEpoch),
00764                                                  period,
00765                                                  epoch);
00766     assert(ctx->body != NULL);
00767 
00768     // Custom orbits have precedence over elliptical orbits, so don't set
00769     // the orbit if the object already has one assigned.
00770     if (ctx->body->getOrbit() == NULL)
00771         ctx->body->setOrbit(orbit);
00772     else
00773         delete orbit;
00774 
00775     return true;
00776 }

static bool createGeometry ParserContext ctx,
const xmlChar **  att
[static]
 

Definition at line 867 of file solarsysxml.cpp.

References InvalidResource, matchName(), parseDistance(), and parseNumber().

Referenced by solarSysStartElement().

00868 {
00869     double radius = 1.0;
00870     double oblateness = 0.0;
00871     const xmlChar* meshName = NULL;
00872 
00873     // Get the radius and mesh attributes
00874     if (att != NULL)
00875     {
00876         for (int i = 0; att[i] != NULL; i += 2)
00877         {
00878             if (matchName(att[i], "radius"))
00879                 parseDistance(att[i + 1], radius, "km");
00880             else if (matchName(att[i], "mesh"))
00881                 meshName = att[i + 1];
00882             else if (matchName(att[i], "oblateness"))
00883                 parseNumber(att[i + 1], oblateness);
00884         }
00885     }
00886 
00887     assert(ctx->body != NULL);
00888 
00889     ResourceHandle meshHandle = InvalidResource;
00890     if (meshName != NULL)
00891         meshHandle = GetMeshManager()->getHandle(MeshInfo(reinterpret_cast<const char*>(meshName)));
00892     ctx->body->setMesh(meshHandle);
00893     ctx->body->setRadius((float) radius);
00894     ctx->body->setOblateness((float) oblateness);
00895 
00896     return false;
00897 }

static bool createHaze ParserContext ctx,
const xmlChar **  att
[static]
 

Definition at line 589 of file solarsysxml.cpp.

References Color::blue(), Color::green(), matchName(), parseColor(), parseNumber(), and Color::red().

Referenced by solarSysStartElement().

00590 {
00591     Color hazeColor;
00592     float hazeDensity = 0.0f;
00593 
00594     if (att != NULL)
00595     {
00596         for (int i = 0; att[i] != NULL; i += 2)
00597         {
00598             if (matchName(att[i], "density"))
00599                 parseNumber(att[i + 1], hazeDensity);
00600             else if (matchName(att[i], "color"))
00601                 parseColor(att[i + 1], hazeColor);
00602         }
00603     }
00604 
00605     assert(ctx->body != NULL);
00606     ctx->body->getSurface().hazeColor = Color(hazeColor.red(),
00607                                               hazeColor.green(),
00608                                               hazeColor.blue(),
00609                                               hazeDensity);
00610     
00611     return true;
00612 }

static bool createRings ParserContext ctx,
const xmlChar **  att
[static]
 

Definition at line 900 of file solarsysxml.cpp.

References matchName(), parseColor(), and parseDistance().

Referenced by solarSysStartElement().

00901 {
00902     double innerRadius = 0.0;
00903     double outerRadius = 0.0;
00904     Color color(1.0f, 1.0f, 1.0f);
00905 
00906     // Get the radius and color attributes
00907     if (att != NULL)
00908     {
00909         for (int i = 0; att[i] != NULL; i += 2)
00910         {
00911             if (matchName(att[i], "inner-radius"))
00912                 parseDistance(att[i + 1], innerRadius, "km");
00913             else if (matchName(att[i], "outer-radius"))
00914                 parseDistance(att[i + 1], outerRadius, "km");
00915             else if (matchName(att[i], "color"))
00916                 parseColor(att[i + 1], color);
00917         }
00918     }
00919 
00920     assert(ctx->body != NULL);
00921     ctx->body->setRings(RingSystem(innerRadius, outerRadius, color));
00922 
00923     return true;
00924 }

static bool createRotation ParserContext ctx,
const xmlChar **  att
[static]
 

Definition at line 812 of file solarsysxml.cpp.

References degToRad(), RotationElements::epoch, Orbit::getPeriod(), matchName(), RotationElements::obliquity, RotationElements::offset, parseAngle(), parseEpoch(), parseTime(), and RotationElements::period.

Referenced by solarSysStartElement().

00813 {
00814     double period = 0.0;
00815     double obliquity = 0.0;
00816     double axisLongitude = 0.0;
00817     double offset = 0.0;
00818     double epoch = astro::J2000;
00819 
00820     if (att != NULL)
00821     {
00822         for (int i = 0; att[i] != NULL; i += 2)
00823         {
00824             if (matchName(att[i], "period"))
00825             {
00826                 if (matchName(att[i + 1], "sync"))
00827                     period = 0.0;
00828                 else
00829                     parseTime(att[i + 1], period, "h");
00830             }
00831             else if (matchName(att[i], "obliquity"))
00832                 parseAngle(att[i + 1], obliquity);
00833             else if (matchName(att[i], "axis-longitude"))
00834                 parseAngle(att[i + 1], axisLongitude);
00835             else if (matchName(att[i], "offset"))
00836                 parseAngle(att[i + 1], offset);
00837             else if (matchName(att[i], "epoch"))
00838                 parseEpoch(att[i + 1], epoch);
00839         }
00840     }
00841 
00842     assert(ctx->body != NULL);
00843 
00844     RotationElements re;
00845     // A period of 0 means that the object is in synchronous rotation, so
00846     // we'll set its rotation period equal to its orbital period.  The catch
00847     // is that we require that the orbit was specified before the rotation
00848     // elements within the XML file.
00849     Orbit* orbit = ctx->body->getOrbit();
00850     if (orbit == NULL)
00851         return false;
00852 
00853     if (period == 0.0)
00854         re.period = (float) orbit->getPeriod();
00855     else
00856         re.period = (float) period / 24.0f;
00857     re.obliquity = (float) degToRad(obliquity);
00858     re.axisLongitude = (float) degToRad(axisLongitude);
00859     re.offset = (float) degToRad(offset);
00860     re.epoch = epoch;
00861     ctx->body->setRotationElements(re);
00862     
00863     return true;
00864 }

static bool createSurface ParserContext ctx,
const xmlChar **  att
[static]
 

Definition at line 615 of file solarsysxml.cpp.

References matchName(), parseBoolean(), parseColor(), and parseNumber().

Referenced by solarSysStartElement().

00616 {
00617     Color color(1.0f, 1.0f, 1.0f);
00618     Color specularColor(0.0f, 0.0f, 0.0f);
00619     float specularPower = 0.0f;
00620     float albedo = 0.5f;
00621     bool blendTexture = false;
00622     bool emissive = false;
00623 
00624     if (att != NULL)
00625     {
00626         for (int i = 0; att[i] != NULL; i += 2)
00627         {
00628             if (matchName(att[i], "color"))
00629                 parseColor(att[i + 1], color);
00630             if (matchName(att[i], "specular-color"))
00631                 parseColor(att[i + 1], specularColor);
00632             if (matchName(att[i], "specular-power"))
00633                 parseNumber(att[i + 1], specularPower);
00634             if (matchName(att[i], "blend-texture"))
00635                 parseBoolean(att[i + 1], blendTexture);
00636             if (matchName(att[i], "emissive"))
00637                 parseBoolean(att[i + 1], emissive);
00638             if (matchName(att[i], "albedo"))
00639                 parseNumber(att[i + 1], albedo);
00640         }
00641     }
00642 
00643     assert(ctx->body != NULL);
00644     ctx->body->setAlbedo(albedo);
00645     ctx->body->getSurface().color = color;
00646     ctx->body->getSurface().specularColor = specularColor;
00647     ctx->body->getSurface().specularPower = specularPower;
00648     if (blendTexture)
00649         ctx->body->getSurface().appearanceFlags |= Surface::BlendTexture;
00650     if (emissive)
00651         ctx->body->getSurface().appearanceFlags |= Surface::Emissive;
00652 
00653     return true;
00654 }

static ResourceHandle createTexture ParserContext ctx,
const xmlChar **  att
[static]
 

Definition at line 459 of file solarsysxml.cpp.

References AtmosphereState, Atmosphere::cloudTexture, ResourceManager< T >::getHandle(), GetTextureManager(), matchName(), parseBoolean(), RingsState, and SurfaceState.

Referenced by solarSysStartElement().

00460 {
00461     const xmlChar* type = reinterpret_cast<const xmlChar*>("base");
00462     const xmlChar* image = NULL;
00463     bool compress = false;
00464 
00465     // Get the type, image, and compress attributes
00466     if (att != NULL)
00467     {
00468         for (int i = 0; att[i] != NULL; i += 2)
00469         {
00470             if (matchName(att[i], "type"))
00471                 type = att[i + 1];
00472             else if (matchName(att[i], "image"))
00473                 image = att[i + 1];
00474             else if (matchName(att[i], "compress"))
00475                 parseBoolean(att[i + 1], compress);
00476         }
00477     }
00478 
00479     if (image == NULL)
00480     {
00481         cout << "Texture has no image source.\n";
00482         return false;
00483     }
00484 
00485     ResourceHandle texHandle = GetTextureManager()->getHandle(TextureInfo(reinterpret_cast<const char*>(image), compress));
00486     if (ctx->state == SurfaceState)
00487     {
00488         assert(ctx->body != NULL);
00489 
00490         if (matchName(type, "base"))
00491             ctx->body->getSurface().baseTexture = texHandle;
00492         else if (matchName(type, "night"))
00493             ctx->body->getSurface().nightTexture = texHandle;
00494     }
00495     else if (ctx->state == AtmosphereState)
00496     {
00497         assert(ctx->body != NULL);
00498         Atmosphere* atmosphere = ctx->body->getAtmosphere();
00499         assert(atmosphere != NULL);
00500 
00501         if (matchName(type, "base"))
00502             atmosphere->cloudTexture = texHandle;
00503     }
00504     else if (ctx->state == RingsState)
00505     {
00506         assert(ctx->body != NULL);
00507         assert(ctx->body->getRings() != NULL);
00508 
00509         if (matchName(type, "base"))
00510             ctx->body->getRings()->texture = texHandle;
00511     }
00512 
00513     return true;
00514 }

static int hexDigit char  c  )  [static]
 

Definition at line 311 of file solarsysxml.cpp.

Referenced by parseColor().

00312 {
00313     // Assumes an ASCII character set . . .
00314     if (c >= '0' && c <= '9')
00315         return c - '0';
00316     else if (c >= 'a' && c <= 'f')
00317         return 10 + (c - 'a');
00318     else if (c >= 'A' && c <= 'F')
00319         return 10 + (c - 'A');
00320     else
00321         return 0; // bad digit
00322 }

static void initSAXHandler xmlSAXHandler &  sax  )  [static]
 

Definition at line 1156 of file solarsysxml.cpp.

References emptySAXHandler, solarSysEndDocument(), solarSysEndElement(), solarSysStartDocument(), and solarSysStartElement().

Referenced by LoadSolarSystemObjectsXML().

01157 {
01158     sax = emptySAXHandler;
01159     sax.startDocument = solarSysStartDocument;
01160     sax.endDocument = solarSysEndDocument;
01161     sax.startElement = solarSysStartElement;
01162     sax.endElement = solarSysEndElement;
01163 }

bool LoadSolarSystemObjectsXML const string source,
Universe universe
 

Definition at line 1190 of file solarsysxml.cpp.

References initSAXHandler(), parseSolarSystemXML(), saxHandler, and ParserContext::universe.

Referenced by CelestiaCore::initSimulation().

01191 {
01192     initSAXHandler(saxHandler);
01193 
01194     ParserContext ctx;
01195     ctx.universe = &universe;
01196 
01197     if (!parseSolarSystemXML(&saxHandler, &ctx, source.c_str()))
01198     {
01199         cout << "Error parsing " << source << '\n';
01200         return false;
01201     }
01202 
01203     return true;
01204 }

static bool matchName const xmlChar *  s,
const char *  name
[static]
 

Definition at line 107 of file solarsysxml.cpp.

Referenced by createAtmosphere(), createBody(), createBumpMap(), createCustomOrbit(), createEllipticalOrbit(), createGeometry(), createHaze(), createRings(), createRotation(), createSurface(), createTexture(), parseBoolean(), parseEpoch(), solarSysEndElement(), and solarSysStartElement().

00108 {
00109     while ((char) *s == *name)
00110     {
00111         if (*s == '\0')
00112             return true;
00113         s++;
00114         name++;
00115     }
00116 
00117     return false;
00118 }

ostream& operator<< ostream &  out,
const Color c
 

Definition at line 325 of file solarsysxml.cpp.

00326 {
00327     cout << '[' << c.red() << ',' << c.green() << ',' << c.blue() << ']';
00328     return cout;
00329 }

static bool parseAngle const xmlChar *  s,
float &  f
[static]
 

Definition at line 258 of file solarsysxml.cpp.

References parseAngle().

00259 {
00260     double d;
00261     if (parseAngle(s, d))
00262     {
00263         f = (float) d;
00264         return true;
00265     }
00266     else
00267     {
00268         return false;
00269     }
00270 }

static bool parseAngle const xmlChar *  s,
double &  d
[static]
 

Definition at line 252 of file solarsysxml.cpp.

References parseNumber().

Referenced by createAtmosphere(), createEllipticalOrbit(), createRotation(), and parseAngle().

00253 {
00254     return parseNumber(s, d);
00255 }

static bool parseBoolean const xmlChar *  s,
bool &  b
[static]
 

Definition at line 121 of file solarsysxml.cpp.

References matchName().

Referenced by createSurface(), and createTexture().

00122 {
00123     if (matchName(s, "true") || matchName(s, "1") || matchName(s, "on"))
00124     {
00125         b = true;
00126         return true;
00127     }
00128     else if (matchName(s, "false") || matchName(s, "0") || matchName(s, "off"))
00129     {
00130         b = false;
00131         return true;
00132     }
00133     else
00134     {
00135         return false;
00136     }
00137 }

static bool parseColor const xmlChar *  s,
Color c
[static]
 

Definition at line 332 of file solarsysxml.cpp.

References hexDigit().

Referenced by createAtmosphere(), createHaze(), createRings(), and createSurface().

00333 {
00334     const char* colorName = reinterpret_cast<const char*>(s);
00335     char hexColor[7];
00336     float r = 0.0f;
00337     float g = 0.0f;
00338     float b = 0.0f;
00339 
00340     cout << "parsing color: " << colorName << '\n';
00341 
00342     if (sscanf(colorName, " #%6[0-9a-fA-F] ", hexColor))
00343     {
00344         if (strlen(hexColor) == 6)
00345         {
00346             c = Color((hexDigit(hexColor[0]) * 16 +
00347                        hexDigit(hexColor[1])) / 255.0f,
00348                       (hexDigit(hexColor[2]) * 16 +
00349                        hexDigit(hexColor[3])) / 255.0f,
00350                       (hexDigit(hexColor[4]) * 16 +
00351                        hexDigit(hexColor[5])) / 255.0f);
00352             cout << "1: " << c << '\n';
00353             return true;
00354         }
00355         else if (strlen(hexColor) == 3)
00356         {
00357             c = Color((hexDigit(hexColor[0]) * 17) / 255.0f,
00358                       (hexDigit(hexColor[1]) * 17) / 255.0f,
00359                       (hexDigit(hexColor[2]) * 17) / 255.0f);
00360             cout << "2: " << c << '\n';
00361             return true;
00362         }
00363         else
00364         {
00365             return false;
00366         }
00367     }
00368     else if (sscanf(colorName, " rgb( %f , %f , %f ) ", &r, &g, &b) == 3)
00369     {
00370         c = Color(r / 255.0f, g / 255.0f, b / 255.0f);
00371         cout << "3: " << c << '\n';
00372         return true;
00373     }
00374     else if (sscanf(colorName, " rgb( %f%% , %f%% , %f%% ) ", &r, &g, &b) == 3)
00375     {
00376         c = Color(r / 100.0f, g / 100.0f, b / 100.0f);
00377         cout << "4: " << c << '\n';
00378         return true;
00379     }
00380     else
00381     {
00382         return false;
00383     }
00384 }

static bool parseDistance const xmlChar *  s,
float &  f,
char *  defaultUnitName
[static]
 

Definition at line 237 of file solarsysxml.cpp.

References parseDistance().

00238 {
00239     double d;
00240     if (parseDistance(s, d, defaultUnitName))
00241     {
00242         f = (float) d;
00243         return true;
00244     }
00245     else
00246     {
00247         return false;
00248     }
00249 }

static bool parseDistance const xmlChar *  s,
double &  d,
char *  defaultUnitName
[static]
 

Definition at line 228 of file solarsysxml.cpp.

References distanceUnits, and parseNumberUnits().

Referenced by createAtmosphere(), createEllipticalOrbit(), createGeometry(), createRings(), and parseDistance().

00229 {
00230     return parseNumberUnits(s, d,
00231                             distanceUnits,
00232                             sizeof distanceUnits / sizeof distanceUnits[0],
00233                             defaultUnitName);
00234 }

static bool parseEpoch const xmlChar *  s,
double &  d
[static]
 

Definition at line 297 of file solarsysxml.cpp.

References matchName(), and parseNumber().

Referenced by createEllipticalOrbit(), and createRotation().

00298 {
00299     if (matchName(s, "J2000"))
00300     {
00301         d = astro::J2000;
00302         return true;
00303     }
00304     else
00305     {
00306         return parseNumber(s, d);
00307     }
00308 }

static bool parseNumber const xmlChar *  s,
float &  f
[static]
 

Definition at line 146 of file solarsysxml.cpp.

References parseNumber().

00147 {
00148     double d;
00149     if (parseNumber(s, d))
00150     {
00151         f = (float) d;
00152         return true;
00153     }
00154     else
00155     {
00156         return false;
00157     }
00158 }

static bool parseNumber const xmlChar *  s,
double &  d
[static]
 

Definition at line 140 of file solarsysxml.cpp.

Referenced by createBumpMap(), createEllipticalOrbit(), createGeometry(), createHaze(), createSurface(), parseAngle(), parseEpoch(), and parseNumber().

00141 {
00142     return sscanf((char*) s, "%lf", &d) == 1;
00143 }

static bool parseNumberUnits const xmlChar *  s,
double &  d,
UnitDefinition unitTable,
int  unitTableLength,
char *  defaultUnitName
[static]
 

Definition at line 161 of file solarsysxml.cpp.

References UnitDefinition::conversion, and UnitDefinition::name.

Referenced by parseDistance(), and parseTime().

00166 {
00167     char unitName[4];
00168     double value;
00169     int nMatched = sscanf(reinterpret_cast<const char*>(s),
00170                           "%lf%3s", &value, unitName);
00171     cout << "parseNumberUnits(" << reinterpret_cast<const char*>(s) << ")\n";
00172     if (nMatched == 1)
00173     {
00174         cout << "matched = 1: " << reinterpret_cast<const char*>(s) << '\n';
00175         d = value;
00176         return true;
00177     }
00178     else if (nMatched == 2)
00179     {
00180         cout << "matched = 2: " << reinterpret_cast<const char*>(s) << '\n';
00181         // Found a value and units; multiply the value by a conversion
00182         // factor to produce default units
00183         UnitDefinition* defaultUnit = NULL;
00184         UnitDefinition* unit = NULL;
00185         int i;
00186 
00187         // Get the default unit
00188         for (i = 0; i < unitTableLength; i++)
00189         {
00190             if (strcmp(defaultUnitName, unitTable[i].name) == 0)
00191             {
00192                 defaultUnit = &unitTable[i];
00193                 break;
00194             }
00195         }
00196         assert(defaultUnit != NULL);
00197 
00198         // Try and the match the unit name specified in the xml attribute
00199         for (i = 0; i < unitTableLength; i++)
00200         {
00201             if (strcmp(unitName, unitTable[i].name) == 0)
00202             {
00203                 unit = &unitTable[i];
00204                 break;
00205             }
00206         }
00207 
00208         if (unit != NULL)
00209         {
00210             // Match found; perform the conversion
00211             d = value * unit->conversion  / defaultUnit->conversion;
00212             cout << "converting: " << value << unit->name << " = " << d << defaultUnit->name << "\n";
00213             return true;
00214         }
00215         else
00216         {
00217             return false;
00218         }
00219     }
00220     else
00221     {
00222         // Error . . . we matched nothing.
00223         return false;
00224     }
00225 }

static bool parseSolarSystemXML xmlSAXHandlerPtr  sax,
void *  userData,
const char *  filename
[static]
 

Definition at line 1166 of file solarsysxml.cpp.

Referenced by LoadSolarSystemObjectsXML().

01169 {
01170     xmlParserCtxtPtr ctxt = xmlCreateFileParserCtxt(filename);
01171     if (ctxt == NULL)
01172         return false;
01173 
01174     ctxt->sax = sax;
01175     ctxt->userData = userData;
01176 
01177     xmlParseDocument(ctxt);
01178 
01179     int wellFormed = ctxt->wellFormed;
01180     if (sax != NULL)
01181         ctxt->sax = NULL;
01182     xmlFreeParserCtxt(ctxt);
01183 
01184     cout << "Well formed: " << wellFormed << '\n';
01185 
01186     return wellFormed != 0;
01187 }

static bool parseTime const xmlChar *  s,
float &  f,
char *  defaultUnitName
[static]
 

Definition at line 282 of file solarsysxml.cpp.

References parseTime().

00283 {
00284     double d;
00285     if (parseTime(s, d, defaultUnitName))
00286     {
00287         f = (float) d;
00288         return true;
00289     }
00290     else
00291     {
00292         return false;
00293     }
00294 }

static bool parseTime const xmlChar *  s,
double &  d,
char *  defaultUnitName
[static]
 

Definition at line 273 of file solarsysxml.cpp.

References parseNumberUnits(), and timeUnits.

Referenced by createEllipticalOrbit(), createRotation(), and parseTime().

00274 {
00275     return parseNumberUnits(s, d,
00276                             timeUnits,
00277                             sizeof timeUnits / sizeof timeUnits[0],
00278                             defaultUnitName);
00279 }

static void solarSysEndDocument void *  data  )  [static]
 

Definition at line 937 of file solarsysxml.cpp.

References ParserContext::body, EndState, and ParserContext::state.

Referenced by initSAXHandler().

00938 {
00939     ParserContext* ctx = reinterpret_cast<ParserContext*>(data);
00940     ctx->state = EndState;
00941     ctx->body = NULL;
00942 }

static void solarSysEndElement void *  data,
const xmlChar *  name
[static]
 

Definition at line 1068 of file solarsysxml.cpp.

References AtmosphereLeafState, AtmosphereState, ParserContext::body, BodyLeafState, BodyState, DPRINTF, ErrorState, Body::getName(), Body::getOrbit(), matchName(), RingsLeafState, RingsState, StartState, ParserContext::state, SurfaceLeafState, and SurfaceState.

Referenced by initSAXHandler().

01069 {
01070     ParserContext* ctx = reinterpret_cast<ParserContext*>(data);
01071     switch (ctx->state)
01072     {
01073     case ErrorState:
01074         return;
01075 
01076     case BodyState:
01077         if (matchName(name, "body"))
01078         {
01079             assert(ctx->body != NULL);
01080             if (ctx->body->getOrbit() == NULL)
01081             {
01082                 DPRINTF(0, "Object %s has no orbit!  Removing . . .\n",
01083                         ctx->body->getName().c_str());
01084                 
01085             }
01086             ctx->body = NULL;
01087             ctx->state = StartState;
01088         }
01089         else
01090         {
01091             ctx->state = ErrorState;
01092         }
01093         break;
01094 
01095     case SurfaceState:
01096         if (matchName(name, "surface"))
01097             ctx->state = BodyState;
01098         else
01099             ctx->state = ErrorState;
01100         break;
01101 
01102     case AtmosphereState:
01103         if (matchName(name, "atmosphere"))
01104             ctx->state = BodyState;
01105         else
01106             ctx->state = ErrorState;
01107         break;
01108 
01109     case RingsState:
01110         if (matchName(name, "rings"))
01111             ctx->state = BodyState;
01112         else
01113             ctx->state = ErrorState;
01114         break;
01115 
01116     case BodyLeafState:
01117         if (matchName(name, "geometry") ||
01118             matchName(name, "elliptical") ||
01119             matchName(name, "customorbit") ||
01120             matchName(name, "rotation"))
01121         {
01122             ctx->state = BodyState;
01123         }
01124         break;
01125 
01126     case SurfaceLeafState:
01127         if (matchName(name, "texture") ||
01128             matchName(name, "haze") ||
01129             matchName(name, "bumpmap"))
01130         {
01131             ctx->state = SurfaceState;
01132         }
01133         break;
01134 
01135     case AtmosphereLeafState:
01136         if (matchName(name, "texture"))
01137             ctx->state = AtmosphereState;
01138         break;
01139 
01140     case RingsLeafState:
01141         if (matchName(name, "texture"))
01142             ctx->state = RingsState;
01143         break;
01144 
01145     default:
01146         break;
01147     }
01148 
01149     if (ctx->state == ErrorState)
01150     {
01151         cout << "Error!  End of " << name << " element not expected.\n";
01152     }
01153 }

static void solarSysStartDocument void *  data  )  [static]
 

Definition at line 928 of file solarsysxml.cpp.

References ParserContext::body, StartState, and ParserContext::state.

Referenced by initSAXHandler().

00929 {
00930     ParserContext* ctx = reinterpret_cast<ParserContext*>(data);
00931     ctx->state = StartState;
00932     ctx->body = NULL;
00933 }

static void solarSysStartElement void *  data,
const xmlChar *  name,
const xmlChar **  att
[static]
 

Definition at line 946 of file solarsysxml.cpp.

References AtmosphereLeafState, AtmosphereState, BodyLeafState, BodyState, createAtmosphere(), createBody(), createBumpMap(), createCustomOrbit(), createEllipticalOrbit(), createGeometry(), createHaze(), createRings(), createRotation(), createSurface(), createTexture(), ErrorState, matchName(), RingsLeafState, RingsState, StartState, ParserContext::state, SurfaceLeafState, and SurfaceState.

Referenced by initSAXHandler().

00949 {
00950     ParserContext* ctx = reinterpret_cast<ParserContext*>(data);
00951 
00952     switch (ctx->state)
00953     {
00954     case ErrorState:
00955         return;
00956 
00957     case StartState:
00958         if (matchName(name, "body"))
00959         {
00960             createBody(ctx, att);
00961             ctx->state = BodyState;
00962         }
00963         else if (!matchName(name, "catalog"))
00964         {
00965             ctx->state = ErrorState;
00966         }
00967         break;
00968 
00969     case BodyState:
00970         if (matchName(name, "surface"))
00971         {
00972             createSurface(ctx, att);
00973             ctx->state = SurfaceState;
00974         }
00975         else if (matchName(name, "geometry"))
00976         {
00977             createGeometry(ctx, att);
00978             ctx->state = BodyLeafState;
00979         }
00980         else if (matchName(name, "elliptical"))
00981         {
00982             createEllipticalOrbit(ctx, att);
00983             ctx->state = BodyLeafState;
00984         }
00985         else if (matchName(name, "customorbit"))
00986         {
00987             createCustomOrbit(ctx, att);
00988             ctx->state = BodyLeafState;
00989         }
00990         else if (matchName(name, "rotation"))
00991         {
00992             createRotation(ctx, att);
00993             ctx->state = BodyLeafState;
00994         }
00995         else if (matchName(name, "atmosphere"))
00996         {
00997             createAtmosphere(ctx, att);
00998             ctx->state = AtmosphereState;
00999         }
01000         else if (matchName(name, "rings"))
01001         {
01002             createRings(ctx, att);
01003             ctx->state = RingsState;
01004         }
01005         else
01006         {
01007             ctx->state = ErrorState;
01008         }
01009         break;
01010 
01011     case SurfaceState:
01012         if (matchName(name, "texture"))
01013         {
01014             createTexture(ctx, att);
01015             ctx->state = SurfaceLeafState;
01016         }
01017         else if (matchName(name, "bumpmap"))
01018         {
01019             createBumpMap(ctx, att);
01020             ctx->state = SurfaceLeafState;
01021         }
01022         else if (matchName(name, "haze"))
01023         {
01024             createHaze(ctx, att);
01025             ctx->state = SurfaceLeafState;
01026         }
01027         else
01028         {
01029             ctx->state = ErrorState;
01030         }
01031         break;
01032 
01033     case RingsState:
01034         if (matchName(name, "texture"))
01035         {
01036             createTexture(ctx, att);
01037             ctx->state = RingsLeafState;
01038         }
01039         break;
01040 
01041     case AtmosphereState:
01042         if (matchName(name, "texture"))
01043         {
01044             createTexture(ctx, att);
01045             ctx->state = AtmosphereLeafState;
01046         }
01047         break;
01048 
01049     case BodyLeafState:
01050     case SurfaceLeafState:
01051     case AtmosphereLeafState:
01052     case RingsLeafState:
01053         ctx->state = ErrorState;
01054         break;
01055 
01056     default:
01057         break;
01058     }
01059 
01060     if (ctx->state == ErrorState)
01061     {
01062         cout << "Error!  " << name << " element not expected.\n";
01063     }
01064 }


Variable Documentation

UnitDefinition distanceUnits[]
 

Initial value:

{
    { "km", 1.0 },
    { "m",  0.001 },
    { "au", 149597870.7 },
    { "ly", 9466411842000.0 },
}

Definition at line 33 of file solarsysxml.cpp.

Referenced by parseDistance(), and ReadDestinationList().

xmlSAXHandler emptySAXHandler [static]
 

Definition at line 51 of file solarsysxml.cpp.

Referenced by initSAXHandler().

xmlSAXHandler saxHandler [static]
 

Definition at line 83 of file solarsysxml.cpp.

Referenced by LoadSolarSystemObjectsXML().

UnitDefinition timeUnits[]
 

Initial value:

{
    { "s", 1.0 },
    { "m", 60.0 },
    { "h", 3600.0 },
    { "d", 86400.0 },
    { "y", 86400.0 * 365.25 },
}

Definition at line 41 of file solarsysxml.cpp.

Referenced by parseTime().


Generated on Sat Jan 14 22:31:16 2006 for Celestia by  doxygen 1.4.1