Split parser.* into hash.*, value.* and parser.*
parent
4598c3cf62
commit
4a38917e08
|
@ -51,6 +51,8 @@ set(CELENGINE_SOURCES
|
|||
globular.h
|
||||
glshader.cpp
|
||||
glshader.h
|
||||
hash.cpp
|
||||
hash.h
|
||||
#hdrfuncrender.cpp
|
||||
image.cpp
|
||||
image.h
|
||||
|
@ -152,6 +154,8 @@ set(CELENGINE_SOURCES
|
|||
univcoord.h
|
||||
universe.cpp
|
||||
universe.h
|
||||
value.cpp
|
||||
value.h
|
||||
vecgl.h
|
||||
vertexobject.cpp
|
||||
vertexobject.h
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "stardb.h"
|
||||
#include "asterism.h"
|
||||
#include "parser.h"
|
||||
#include "tokenizer.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "parseobject.h"
|
||||
#include "multitexture.h"
|
||||
#include "meshmanager.h"
|
||||
#include "tokenizer.h"
|
||||
#include <celutil/debug.h>
|
||||
|
||||
#include <celengine/galaxy.h>
|
||||
|
|
|
@ -0,0 +1,660 @@
|
|||
// hash.cpp
|
||||
//
|
||||
// Copyright (C) 2001-2019, the Celestia Development Team
|
||||
// Original version by Chris Laurel <claurel@gmail.com>
|
||||
//
|
||||
// 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 <utility>
|
||||
#include <celutil/color.h>
|
||||
#include <celutil/util.h>
|
||||
#include <celmath/mathlib.h>
|
||||
#include "astro.h"
|
||||
#include "hash.h"
|
||||
#include "value.h"
|
||||
|
||||
using namespace Eigen;
|
||||
using namespace std;
|
||||
using namespace celmath;
|
||||
|
||||
|
||||
AssociativeArray::~AssociativeArray()
|
||||
{
|
||||
for (const auto &iter : assoc)
|
||||
delete iter.second;
|
||||
}
|
||||
|
||||
|
||||
Value* AssociativeArray::getValue(const string& key) const
|
||||
{
|
||||
map<string, Value*>::const_iterator iter = assoc.find(key);
|
||||
if (iter == assoc.end())
|
||||
return nullptr;
|
||||
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
|
||||
void AssociativeArray::addValue(const string& key, Value& val)
|
||||
{
|
||||
assoc.insert(map<string, Value*>::value_type(key, &val));
|
||||
}
|
||||
|
||||
|
||||
bool AssociativeArray::getNumber(const string& key, double& val) const
|
||||
{
|
||||
Value* v = getValue(key);
|
||||
if (v == nullptr || v->getType() != Value::NumberType)
|
||||
return false;
|
||||
|
||||
val = v->getNumber();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool AssociativeArray::getNumber(const string& key, float& val) const
|
||||
{
|
||||
double dval;
|
||||
|
||||
if (!getNumber(key, dval))
|
||||
return false;
|
||||
|
||||
val = (float) dval;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool AssociativeArray::getNumber(const string& key, int& val) const
|
||||
{
|
||||
double ival;
|
||||
|
||||
if (!getNumber(key, ival))
|
||||
return false;
|
||||
|
||||
val = (int) ival;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool AssociativeArray::getNumber(const string& key, uint32_t& val) const
|
||||
{
|
||||
double ival;
|
||||
|
||||
if (!getNumber(key, ival))
|
||||
return false;
|
||||
|
||||
val = (uint32_t) ival;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool AssociativeArray::getString(const string& key, string& val) const
|
||||
{
|
||||
Value* v = getValue(key);
|
||||
if (v == nullptr || v->getType() != Value::StringType)
|
||||
return false;
|
||||
|
||||
val = v->getString();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool AssociativeArray::getPath(const string& key, fs::path& val) const
|
||||
{
|
||||
string v;
|
||||
if (getString(key, v))
|
||||
{
|
||||
val = PathExp(v);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool AssociativeArray::getBoolean(const string& key, bool& val) const
|
||||
{
|
||||
Value* v = getValue(key);
|
||||
if (v == nullptr || v->getType() != Value::BooleanType)
|
||||
return false;
|
||||
|
||||
val = v->getBoolean();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool AssociativeArray::getVector(const string& key, Vector3d& val) const
|
||||
{
|
||||
Value* v = getValue(key);
|
||||
if (v == nullptr || v->getType() != Value::ArrayType)
|
||||
return false;
|
||||
|
||||
ValueArray* arr = v->getArray();
|
||||
if (arr->size() != 3)
|
||||
return false;
|
||||
|
||||
Value* x = (*arr)[0];
|
||||
Value* y = (*arr)[1];
|
||||
Value* z = (*arr)[2];
|
||||
|
||||
if (x->getType() != Value::NumberType ||
|
||||
y->getType() != Value::NumberType ||
|
||||
z->getType() != Value::NumberType)
|
||||
return false;
|
||||
|
||||
val = Vector3d(x->getNumber(), y->getNumber(), z->getNumber());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool AssociativeArray::getVector(const string& key, Vector3f& val) const
|
||||
{
|
||||
Vector3d vecVal;
|
||||
|
||||
if (!getVector(key, vecVal))
|
||||
return false;
|
||||
|
||||
val = vecVal.cast<float>();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool AssociativeArray::getVector(const string& key, Vector4d& val) const
|
||||
{
|
||||
Value* v = getValue(key);
|
||||
if (v == nullptr || v->getType() != Value::ArrayType)
|
||||
return false;
|
||||
|
||||
ValueArray* arr = v->getArray();
|
||||
if (arr->size() != 4)
|
||||
return false;
|
||||
|
||||
Value* x = (*arr)[0];
|
||||
Value* y = (*arr)[1];
|
||||
Value* z = (*arr)[2];
|
||||
Value* w = (*arr)[3];
|
||||
|
||||
if (x->getType() != Value::NumberType ||
|
||||
y->getType() != Value::NumberType ||
|
||||
z->getType() != Value::NumberType ||
|
||||
w->getType() != Value::NumberType)
|
||||
return false;
|
||||
|
||||
val = Vector4d(x->getNumber(), y->getNumber(), z->getNumber(), w->getNumber());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool AssociativeArray::getVector(const string& key, Vector4f& val) const
|
||||
{
|
||||
Vector4d vecVal;
|
||||
|
||||
if (!getVector(key, vecVal))
|
||||
return false;
|
||||
|
||||
val = vecVal.cast<float>();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves a quaternion, scaled to an associated angle unit.
|
||||
*
|
||||
* The quaternion is specified in the catalog file in axis-angle format as follows:
|
||||
* \verbatim {PropertyName} [ angle axisX axisY axisZ ] \endverbatim
|
||||
*
|
||||
* @param[in] key Hash key for the rotation.
|
||||
* @param[out] val A quaternion representing the value if present, unaffected if not.
|
||||
* @return True if the key exists in the hash, false otherwise.
|
||||
*/
|
||||
bool AssociativeArray::getRotation(const string& key, Eigen::Quaternionf& val) const
|
||||
{
|
||||
Value* v = getValue(key);
|
||||
if (v == nullptr || v->getType() != Value::ArrayType)
|
||||
return false;
|
||||
|
||||
ValueArray* arr = v->getArray();
|
||||
if (arr->size() != 4)
|
||||
return false;
|
||||
|
||||
Value* w = (*arr)[0];
|
||||
Value* x = (*arr)[1];
|
||||
Value* y = (*arr)[2];
|
||||
Value* z = (*arr)[3];
|
||||
|
||||
if (w->getType() != Value::NumberType ||
|
||||
x->getType() != Value::NumberType ||
|
||||
y->getType() != Value::NumberType ||
|
||||
z->getType() != Value::NumberType)
|
||||
return false;
|
||||
|
||||
Vector3f axis((float) x->getNumber(),
|
||||
(float) y->getNumber(),
|
||||
(float) z->getNumber());
|
||||
|
||||
double ang = w->getNumber();
|
||||
double angScale = 1.0;
|
||||
getAngleScale(key, angScale);
|
||||
float angle = degToRad((float) (ang * angScale));
|
||||
|
||||
val = Quaternionf(AngleAxisf(angle, axis.normalized()));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool AssociativeArray::getColor(const string& key, Color& val) const
|
||||
{
|
||||
Vector4d vec4;
|
||||
if (getVector(key, vec4))
|
||||
{
|
||||
Vector4f vec4f = vec4.cast<float>();
|
||||
val = Color(vec4f);
|
||||
return true;
|
||||
}
|
||||
|
||||
Vector3d vec3;
|
||||
if (getVector(key, vec3))
|
||||
{
|
||||
Vector3f vec3f = vec3.cast<float>();
|
||||
val = Color(vec3f);
|
||||
return true;
|
||||
}
|
||||
|
||||
string rgba;
|
||||
if (getString(key, rgba))
|
||||
{
|
||||
int r, g, b, a;
|
||||
int ret = sscanf(rgba.c_str(), "#%2x%2x%2x%2x", &r, &g, &b, &a);
|
||||
switch (ret)
|
||||
{
|
||||
case 3:
|
||||
a = 0xFF;
|
||||
case 4:
|
||||
val = Color((char unsigned)r, (char unsigned)g, (unsigned char)b, (unsigned char)a);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves a numeric quantity scaled to an associated angle unit.
|
||||
* @param[in] key Hash key for the quantity.
|
||||
* @param[out] val The returned quantity if present, unaffected if not.
|
||||
* @param[in] outputScale Returned value is scaled to this value.
|
||||
* @param[in] defaultScale If no units are specified, use this scale. Defaults to outputScale.
|
||||
* @return True if the key exists in the hash, false otherwise.
|
||||
*/
|
||||
bool
|
||||
AssociativeArray::getAngle(const string& key, double& val, double outputScale, double defaultScale) const
|
||||
{
|
||||
if (!getNumber(key, val))
|
||||
return false;
|
||||
|
||||
double angleScale;
|
||||
if(getAngleScale(key, angleScale))
|
||||
{
|
||||
angleScale /= outputScale;
|
||||
}
|
||||
else
|
||||
{
|
||||
angleScale = (defaultScale == 0.0) ? 1.0 : defaultScale / outputScale;
|
||||
}
|
||||
|
||||
val *= angleScale;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/** @copydoc AssociativeArray::getAngle() */
|
||||
bool
|
||||
AssociativeArray::getAngle(const string& key, float& val, double outputScale, double defaultScale) const
|
||||
{
|
||||
double dval;
|
||||
|
||||
if (!getAngle(key, dval, outputScale, defaultScale))
|
||||
return false;
|
||||
|
||||
val = ((float) dval);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves a numeric quantity scaled to an associated length unit.
|
||||
* @param[in] key Hash key for the quantity.
|
||||
* @param[out] val The returned quantity if present, unaffected if not.
|
||||
* @param[in] outputScale Returned value is scaled to this value.
|
||||
* @param[in] defaultScale If no units are specified, use this scale. Defaults to outputScale.
|
||||
* @return True if the key exists in the hash, false otherwise.
|
||||
*/
|
||||
bool
|
||||
AssociativeArray::getLength(const string& key, double& val, double outputScale, double defaultScale) const
|
||||
{
|
||||
if(!getNumber(key, val))
|
||||
return false;
|
||||
|
||||
double lengthScale;
|
||||
if(getLengthScale(key, lengthScale))
|
||||
{
|
||||
lengthScale /= outputScale;
|
||||
}
|
||||
else
|
||||
{
|
||||
lengthScale = (defaultScale == 0.0) ? 1.0 : defaultScale / outputScale;
|
||||
}
|
||||
|
||||
val *= lengthScale;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/** @copydoc AssociativeArray::getLength() */
|
||||
bool AssociativeArray::getLength(const string& key, float& val, double outputScale, double defaultScale) const
|
||||
{
|
||||
double dval;
|
||||
|
||||
if (!getLength(key, dval, outputScale, defaultScale))
|
||||
return false;
|
||||
|
||||
val = ((float) dval);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves a numeric quantity scaled to an associated time unit.
|
||||
* @param[in] key Hash key for the quantity.
|
||||
* @param[out] val The returned quantity if present, unaffected if not.
|
||||
* @param[in] outputScale Returned value is scaled to this value.
|
||||
* @param[in] defaultScale If no units are specified, use this scale. Defaults to outputScale.
|
||||
* @return True if the key exists in the hash, false otherwise.
|
||||
*/
|
||||
bool AssociativeArray::getTime(const string& key, double& val, double outputScale, double defaultScale) const
|
||||
{
|
||||
if(!getNumber(key, val))
|
||||
return false;
|
||||
|
||||
double timeScale;
|
||||
if(getTimeScale(key, timeScale))
|
||||
{
|
||||
timeScale /= outputScale;
|
||||
}
|
||||
else
|
||||
{
|
||||
timeScale = (defaultScale == 0.0) ? 1.0 : defaultScale / outputScale;
|
||||
}
|
||||
|
||||
val *= timeScale;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/** @copydoc AssociativeArray::getTime() */
|
||||
bool AssociativeArray::getTime(const string& key, float& val, double outputScale, double defaultScale) const
|
||||
{
|
||||
double dval;
|
||||
|
||||
if(!getTime(key, dval, outputScale, defaultScale))
|
||||
return false;
|
||||
|
||||
val = ((float) dval);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves a numeric quantity scaled to an associated mass unit.
|
||||
* @param[in] key Hash key for the quantity.
|
||||
* @param[out] val The returned quantity if present, unaffected if not.
|
||||
* @param[in] outputScale Returned value is scaled to this value.
|
||||
* @param[in] defaultScale If no units are specified, use this scale. Defaults to outputScale.
|
||||
* @return True if the key exists in the hash, false otherwise.
|
||||
*/
|
||||
bool AssociativeArray::getMass(const string& key, double& val, double outputScale, double defaultScale) const
|
||||
{
|
||||
if(!getNumber(key, val))
|
||||
return false;
|
||||
|
||||
double massScale;
|
||||
if(getMassScale(key, massScale))
|
||||
{
|
||||
massScale /= outputScale;
|
||||
}
|
||||
else
|
||||
{
|
||||
massScale = (defaultScale == 0.0) ? 1.0 : defaultScale / outputScale;
|
||||
}
|
||||
|
||||
val *= massScale;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/** @copydoc AssociativeArray::getMass() */
|
||||
bool AssociativeArray::getMass(const string& key, float& val, double outputScale, double defaultScale) const
|
||||
{
|
||||
double dval;
|
||||
|
||||
if(!getMass(key, dval, outputScale, defaultScale))
|
||||
return false;
|
||||
|
||||
val = ((float) dval);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves a vector quantity scaled to an associated length unit.
|
||||
* @param[in] key Hash key for the quantity.
|
||||
* @param[out] val The returned vector if present, unaffected if not.
|
||||
* @param[in] outputScale Returned value is scaled to this value.
|
||||
* @param[in] defaultScale If no units are specified, use this scale. Defaults to outputScale.
|
||||
* @return True if the key exists in the hash, false otherwise.
|
||||
*/
|
||||
bool AssociativeArray::getLengthVector(const string& key, Eigen::Vector3d& val, double outputScale, double defaultScale) const
|
||||
{
|
||||
if(!getVector(key, val))
|
||||
return false;
|
||||
|
||||
double lengthScale;
|
||||
if(getLengthScale(key, lengthScale))
|
||||
{
|
||||
lengthScale /= outputScale;
|
||||
}
|
||||
else
|
||||
{
|
||||
lengthScale = (defaultScale == 0.0) ? 1.0 : defaultScale / outputScale;
|
||||
}
|
||||
|
||||
val *= lengthScale;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/** @copydoc AssociativeArray::getLengthVector() */
|
||||
bool AssociativeArray::getLengthVector(const string& key, Eigen::Vector3f& val, double outputScale, double defaultScale) const
|
||||
{
|
||||
Vector3d vecVal;
|
||||
|
||||
if(!getLengthVector(key, vecVal, outputScale, defaultScale))
|
||||
return false;
|
||||
|
||||
val = vecVal.cast<float>();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves a spherical tuple \verbatim [longitude, latitude, altitude] \endverbatim scaled to associated angle and length units.
|
||||
* @param[in] key Hash key for the quantity.
|
||||
* @param[out] val The returned tuple in units of degrees and kilometers if present, unaffected if not.
|
||||
* @return True if the key exists in the hash, false otherwise.
|
||||
*/
|
||||
bool AssociativeArray::getSphericalTuple(const string& key, Vector3d& val) const
|
||||
{
|
||||
if(!getVector(key, val))
|
||||
return false;
|
||||
|
||||
double angleScale;
|
||||
if(getAngleScale(key, angleScale))
|
||||
{
|
||||
val[0] *= angleScale;
|
||||
val[1] *= angleScale;
|
||||
}
|
||||
|
||||
double lengthScale = 1.0;
|
||||
getLengthScale(key, lengthScale);
|
||||
val[2] *= lengthScale;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/** @copydoc AssociativeArray::getSphericalTuple */
|
||||
bool AssociativeArray::getSphericalTuple(const string& key, Vector3f& val) const
|
||||
{
|
||||
Vector3d vecVal;
|
||||
|
||||
if(!getSphericalTuple(key, vecVal))
|
||||
return false;
|
||||
|
||||
val = vecVal.cast<float>();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the angle unit associated with a given property.
|
||||
* @param[in] key Hash key for the property.
|
||||
* @param[out] scale The returned angle unit scaled to degrees if present, unaffected if not.
|
||||
* @return True if an angle unit has been specified for the property, false otherwise.
|
||||
*/
|
||||
bool AssociativeArray::getAngleScale(const string& key, double& scale) const
|
||||
{
|
||||
string unitKey(key + "%Angle");
|
||||
string unit;
|
||||
|
||||
if (!getString(unitKey, unit))
|
||||
return false;
|
||||
|
||||
return astro::getAngleScale(unit, scale);
|
||||
}
|
||||
|
||||
|
||||
/** @copydoc AssociativeArray::getAngleScale() */
|
||||
bool AssociativeArray::getAngleScale(const string& key, float& scale) const
|
||||
{
|
||||
double dscale;
|
||||
if (!getAngleScale(key, dscale))
|
||||
return false;
|
||||
|
||||
scale = ((float) dscale);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the length unit associated with a given property.
|
||||
* @param[in] key Hash key for the property.
|
||||
* @param[out] scale The returned length unit scaled to kilometers if present, unaffected if not.
|
||||
* @return True if a length unit has been specified for the property, false otherwise.
|
||||
*/
|
||||
bool AssociativeArray::getLengthScale(const string& key, double& scale) const
|
||||
{
|
||||
string unitKey(key + "%Length");
|
||||
string unit;
|
||||
|
||||
if (!getString(unitKey, unit))
|
||||
return false;
|
||||
|
||||
return astro::getLengthScale(unit, scale);
|
||||
}
|
||||
|
||||
|
||||
/** @copydoc AssociativeArray::getLengthScale() */
|
||||
bool AssociativeArray::getLengthScale(const string& key, float& scale) const
|
||||
{
|
||||
double dscale;
|
||||
if (!getLengthScale(key, dscale))
|
||||
return false;
|
||||
|
||||
scale = ((float) dscale);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the time unit associated with a given property.
|
||||
* @param[in] key Hash key for the property.
|
||||
* @param[out] scale The returned time unit scaled to days if present, unaffected if not.
|
||||
* @return True if a time unit has been specified for the property, false otherwise.
|
||||
*/
|
||||
bool AssociativeArray::getTimeScale(const string& key, double& scale) const
|
||||
{
|
||||
string unitKey(key + "%Time");
|
||||
string unit;
|
||||
|
||||
if (!getString(unitKey, unit))
|
||||
return false;
|
||||
|
||||
return astro::getTimeScale(unit, scale);
|
||||
}
|
||||
|
||||
|
||||
/** @copydoc AssociativeArray::getTimeScale() */
|
||||
bool AssociativeArray::getTimeScale(const string& key, float& scale) const
|
||||
{
|
||||
double dscale;
|
||||
if (!getTimeScale(key, dscale))
|
||||
return false;
|
||||
|
||||
scale = ((float) dscale);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the mass unit associated with a given property.
|
||||
* @param[in] key Hash key for the property.
|
||||
* @param[out] scale The returned mass unit scaled to Earth mass if present, unaffected if not.
|
||||
* @return True if a mass unit has been specified for the property, false otherwise.
|
||||
*/
|
||||
bool AssociativeArray::getMassScale(const string& key, double& scale) const
|
||||
{
|
||||
string unitKey(key + "%Mass");
|
||||
string unit;
|
||||
|
||||
if (!getString(unitKey, unit))
|
||||
return false;
|
||||
|
||||
return astro::getMassScale(unit, scale);
|
||||
}
|
||||
|
||||
|
||||
/** @copydoc AssociativeArray::getMassScale() */
|
||||
bool AssociativeArray::getMassScale(const string& key, float& scale) const
|
||||
{
|
||||
double dscale;
|
||||
if (!getMassScale(key, dscale))
|
||||
return false;
|
||||
|
||||
scale = ((float) dscale);
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
// hash.h
|
||||
//
|
||||
// Copyright (C) 2001-2019, the Celestia Development Team
|
||||
// Original version by Chris Laurel <claurel@gmail.com>
|
||||
//
|
||||
// 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.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <celcompat/filesystem.h>
|
||||
#include <celmath/mathlib.h>
|
||||
#include <Eigen/Geometry>
|
||||
|
||||
|
||||
class Color;
|
||||
class Value;
|
||||
|
||||
using HashIterator = std::map<std::string, Value*>::const_iterator;
|
||||
|
||||
class AssociativeArray
|
||||
{
|
||||
public:
|
||||
AssociativeArray() = default;
|
||||
~AssociativeArray();
|
||||
AssociativeArray(AssociativeArray&&) = default;
|
||||
AssociativeArray(const AssociativeArray&) = delete;
|
||||
AssociativeArray& operator=(AssociativeArray&&) = default;
|
||||
AssociativeArray& operator=(AssociativeArray&) = delete;
|
||||
|
||||
Value* getValue(const std::string&) const;
|
||||
void addValue(const std::string&, Value&);
|
||||
|
||||
bool getNumber(const std::string&, double&) const;
|
||||
bool getNumber(const std::string&, float&) const;
|
||||
bool getNumber(const std::string&, int&) const;
|
||||
bool getNumber(const std::string&, uint32_t&) const;
|
||||
bool getString(const std::string&, std::string&) const;
|
||||
bool getPath(const std::string&, fs::path&) const;
|
||||
bool getBoolean(const std::string&, bool&) const;
|
||||
bool getVector(const std::string&, Eigen::Vector3d&) const;
|
||||
bool getVector(const std::string&, Eigen::Vector3f&) const;
|
||||
bool getVector(const std::string&, Eigen::Vector4d&) const;
|
||||
bool getVector(const std::string&, Eigen::Vector4f&) const;
|
||||
bool getRotation(const std::string&, Eigen::Quaternionf&) const;
|
||||
bool getColor(const std::string&, Color&) const;
|
||||
bool getAngle(const std::string&, double&, double = 1.0, double = 0.0) const;
|
||||
bool getAngle(const std::string&, float&, double = 1.0, double = 0.0) const;
|
||||
bool getLength(const std::string&, double&, double = 1.0, double = 0.0) const;
|
||||
bool getLength(const std::string&, float&, double = 1.0, double = 0.0) const;
|
||||
bool getTime(const std::string&, double&, double = 1.0, double = 0.0) const;
|
||||
bool getTime(const std::string&, float&, double = 1.0, double = 0.0) const;
|
||||
bool getMass(const std::string&, double&, double = 1.0, double = 0.0) const;
|
||||
bool getMass(const std::string&, float&, double = 1.0, double = 0.0) const;
|
||||
bool getLengthVector(const std::string&, Eigen::Vector3d&, double = 1.0, double = 0.0) const;
|
||||
bool getLengthVector(const std::string&, Eigen::Vector3f&, double = 1.0, double = 0.0) const;
|
||||
bool getSphericalTuple(const std::string&, Eigen::Vector3d&) const;
|
||||
bool getSphericalTuple(const std::string&, Eigen::Vector3f&) const;
|
||||
bool getAngleScale(const std::string&, double&) const;
|
||||
bool getAngleScale(const std::string&, float&) const;
|
||||
bool getLengthScale(const std::string&, double&) const;
|
||||
bool getLengthScale(const std::string&, float&) const;
|
||||
bool getTimeScale(const std::string&, double&) const;
|
||||
bool getTimeScale(const std::string&, float&) const;
|
||||
bool getMassScale(const std::string&, double&) const;
|
||||
bool getMassScale(const std::string&, float&) const;
|
||||
|
||||
HashIterator begin() const
|
||||
{
|
||||
return assoc.begin();
|
||||
}
|
||||
HashIterator end() const
|
||||
{
|
||||
return assoc.end();
|
||||
}
|
||||
|
||||
private:
|
||||
std::map<std::string, Value*> assoc;
|
||||
};
|
||||
|
||||
using Hash = AssociativeArray;
|
|
@ -21,6 +21,7 @@
|
|||
#include "texmanager.h"
|
||||
#include "meshmanager.h"
|
||||
#include "modelgeometry.h"
|
||||
#include "tokenizer.h"
|
||||
|
||||
#include <cel3ds/3dsread.h>
|
||||
#include <celmodel/modelfile.h>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// parser.cpp
|
||||
//
|
||||
// Copyright (C) 2001-2009, the Celestia Development Team
|
||||
// Copyright (C) 2001-2019, the Celestia Development Team
|
||||
// Original version by Chris Laurel <claurel@gmail.com>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
|
@ -8,114 +8,15 @@
|
|||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
|
||||
#include "parser.h"
|
||||
#include "astro.h"
|
||||
#include <celutil/util.h>
|
||||
#include "parser.h"
|
||||
#include "tokenizer.h"
|
||||
#include "value.h"
|
||||
|
||||
using namespace Eigen;
|
||||
using namespace celmath;
|
||||
|
||||
|
||||
/****** Value method implementations *******/
|
||||
|
||||
Value::Value(double d)
|
||||
{
|
||||
type = NumberType;
|
||||
data.d = d;
|
||||
}
|
||||
|
||||
Value::Value(const string& s)
|
||||
{
|
||||
type = StringType;
|
||||
data.s = new string(s);
|
||||
}
|
||||
|
||||
Value::Value(ValueArray* a)
|
||||
{
|
||||
type = ArrayType;
|
||||
data.a = a;
|
||||
}
|
||||
|
||||
Value::Value(Hash* h)
|
||||
{
|
||||
type = HashType;
|
||||
data.h = h;
|
||||
}
|
||||
|
||||
Value::Value(bool b)
|
||||
{
|
||||
type = BooleanType;
|
||||
data.d = b ? 1.0 : 0.0;
|
||||
}
|
||||
|
||||
Value::~Value()
|
||||
{
|
||||
if (type == StringType)
|
||||
{
|
||||
delete data.s;
|
||||
}
|
||||
else if (type == ArrayType)
|
||||
{
|
||||
if (data.a != nullptr)
|
||||
{
|
||||
for (unsigned int i = 0; i < data.a->size(); i++)
|
||||
delete (*data.a)[i];
|
||||
delete data.a;
|
||||
}
|
||||
}
|
||||
else if (type == HashType)
|
||||
{
|
||||
if (data.h != nullptr)
|
||||
{
|
||||
#if 0
|
||||
Hash::iterator iter = data.h->begin();
|
||||
while (iter != data.h->end())
|
||||
{
|
||||
delete iter->second;
|
||||
iter++;
|
||||
}
|
||||
#endif
|
||||
delete data.h;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Value::ValueType Value::getType() const
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
double Value::getNumber() const
|
||||
{
|
||||
// ASSERT(type == NumberType);
|
||||
return data.d;
|
||||
}
|
||||
|
||||
string Value::getString() const
|
||||
{
|
||||
// ASSERT(type == StringType);
|
||||
return *data.s;
|
||||
}
|
||||
|
||||
ValueArray* Value::getArray() const
|
||||
{
|
||||
// ASSERT(type == ArrayType);
|
||||
return data.a;
|
||||
}
|
||||
|
||||
Hash* Value::getHash() const
|
||||
{
|
||||
// ASSERT(type == HashType);
|
||||
return data.h;
|
||||
}
|
||||
|
||||
bool Value::getBoolean() const
|
||||
{
|
||||
// ASSERT(type == BooleanType);
|
||||
return (data.d != 0.0);
|
||||
}
|
||||
|
||||
|
||||
/****** Parser method implementation ******/
|
||||
|
||||
Parser::Parser(Tokenizer* _tokenizer) :
|
||||
|
@ -133,7 +34,7 @@ ValueArray* Parser::readArray()
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
auto* array = new ValueArray();
|
||||
ValueArray* array = new ValueArray();
|
||||
|
||||
Value* v = readValue();
|
||||
while (v != nullptr)
|
||||
|
@ -285,7 +186,7 @@ Value* Parser::readValue()
|
|||
case Tokenizer::TokenBeginArray:
|
||||
tokenizer->pushBack();
|
||||
{
|
||||
ValueArray* array = readArray();
|
||||
auto* array = readArray();
|
||||
if (array == nullptr)
|
||||
return nullptr;
|
||||
else
|
||||
|
@ -307,652 +208,3 @@ Value* Parser::readValue()
|
|||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
AssociativeArray::~AssociativeArray()
|
||||
{
|
||||
#if 0
|
||||
Hash::iterator iter = data.h->begin();
|
||||
while (iter != data.h->end())
|
||||
{
|
||||
delete iter->second;
|
||||
iter++;
|
||||
}
|
||||
#endif
|
||||
for (const auto &iter : assoc)
|
||||
delete iter.second;
|
||||
}
|
||||
|
||||
Value* AssociativeArray::getValue(const string& key) const
|
||||
{
|
||||
map<string, Value*>::const_iterator iter = assoc.find(key);
|
||||
if (iter == assoc.end())
|
||||
return nullptr;
|
||||
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
void AssociativeArray::addValue(const string& key, Value& val)
|
||||
{
|
||||
assoc.insert(map<string, Value*>::value_type(key, &val));
|
||||
}
|
||||
|
||||
bool AssociativeArray::getNumber(const string& key, double& val) const
|
||||
{
|
||||
Value* v = getValue(key);
|
||||
if (v == nullptr || v->getType() != Value::NumberType)
|
||||
return false;
|
||||
|
||||
val = v->getNumber();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AssociativeArray::getNumber(const string& key, float& val) const
|
||||
{
|
||||
double dval;
|
||||
|
||||
if (!getNumber(key, dval))
|
||||
return false;
|
||||
|
||||
val = (float) dval;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AssociativeArray::getNumber(const string& key, int& val) const
|
||||
{
|
||||
double ival;
|
||||
|
||||
if (!getNumber(key, ival))
|
||||
return false;
|
||||
|
||||
val = (int) ival;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AssociativeArray::getNumber(const string& key, uint32_t& val) const
|
||||
{
|
||||
double ival;
|
||||
|
||||
if (!getNumber(key, ival))
|
||||
return false;
|
||||
|
||||
val = (uint32_t) ival;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AssociativeArray::getString(const string& key, string& val) const
|
||||
{
|
||||
Value* v = getValue(key);
|
||||
if (v == nullptr || v->getType() != Value::StringType)
|
||||
return false;
|
||||
|
||||
val = v->getString();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AssociativeArray::getPath(const string& key, fs::path& val) const
|
||||
{
|
||||
string v;
|
||||
if (getString(key, v))
|
||||
{
|
||||
val = PathExp(v);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AssociativeArray::getBoolean(const string& key, bool& val) const
|
||||
{
|
||||
Value* v = getValue(key);
|
||||
if (v == nullptr || v->getType() != Value::BooleanType)
|
||||
return false;
|
||||
|
||||
val = v->getBoolean();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AssociativeArray::getVector(const string& key, Vector3d& val) const
|
||||
{
|
||||
Value* v = getValue(key);
|
||||
if (v == nullptr || v->getType() != Value::ArrayType)
|
||||
return false;
|
||||
|
||||
ValueArray* arr = v->getArray();
|
||||
if (arr->size() != 3)
|
||||
return false;
|
||||
|
||||
Value* x = (*arr)[0];
|
||||
Value* y = (*arr)[1];
|
||||
Value* z = (*arr)[2];
|
||||
|
||||
if (x->getType() != Value::NumberType ||
|
||||
y->getType() != Value::NumberType ||
|
||||
z->getType() != Value::NumberType)
|
||||
return false;
|
||||
|
||||
val = Vector3d(x->getNumber(), y->getNumber(), z->getNumber());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool AssociativeArray::getVector(const string& key, Vector3f& val) const
|
||||
{
|
||||
Vector3d vecVal;
|
||||
|
||||
if (!getVector(key, vecVal))
|
||||
return false;
|
||||
|
||||
val = vecVal.cast<float>();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool AssociativeArray::getVector(const string& key, Vector4d& val) const
|
||||
{
|
||||
Value* v = getValue(key);
|
||||
if (v == nullptr || v->getType() != Value::ArrayType)
|
||||
return false;
|
||||
|
||||
ValueArray* arr = v->getArray();
|
||||
if (arr->size() != 4)
|
||||
return false;
|
||||
|
||||
Value* x = (*arr)[0];
|
||||
Value* y = (*arr)[1];
|
||||
Value* z = (*arr)[2];
|
||||
Value* w = (*arr)[3];
|
||||
|
||||
if (x->getType() != Value::NumberType ||
|
||||
y->getType() != Value::NumberType ||
|
||||
z->getType() != Value::NumberType ||
|
||||
w->getType() != Value::NumberType)
|
||||
return false;
|
||||
|
||||
val = Vector4d(x->getNumber(), y->getNumber(), z->getNumber(), w->getNumber());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool AssociativeArray::getVector(const string& key, Vector4f& val) const
|
||||
{
|
||||
Vector4d vecVal;
|
||||
|
||||
if (!getVector(key, vecVal))
|
||||
return false;
|
||||
|
||||
val = vecVal.cast<float>();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves a quaternion, scaled to an associated angle unit.
|
||||
*
|
||||
* The quaternion is specified in the catalog file in axis-angle format as follows:
|
||||
* \verbatim {PropertyName} [ angle axisX axisY axisZ ] \endverbatim
|
||||
*
|
||||
* @param[in] key Hash key for the rotation.
|
||||
* @param[out] val A quaternion representing the value if present, unaffected if not.
|
||||
* @return True if the key exists in the hash, false otherwise.
|
||||
*/
|
||||
bool AssociativeArray::getRotation(const string& key, Eigen::Quaternionf& val) const
|
||||
{
|
||||
Value* v = getValue(key);
|
||||
if (v == nullptr || v->getType() != Value::ArrayType)
|
||||
return false;
|
||||
|
||||
ValueArray* arr = v->getArray();
|
||||
if (arr->size() != 4)
|
||||
return false;
|
||||
|
||||
Value* w = (*arr)[0];
|
||||
Value* x = (*arr)[1];
|
||||
Value* y = (*arr)[2];
|
||||
Value* z = (*arr)[3];
|
||||
|
||||
if (w->getType() != Value::NumberType ||
|
||||
x->getType() != Value::NumberType ||
|
||||
y->getType() != Value::NumberType ||
|
||||
z->getType() != Value::NumberType)
|
||||
return false;
|
||||
|
||||
Vector3f axis((float) x->getNumber(),
|
||||
(float) y->getNumber(),
|
||||
(float) z->getNumber());
|
||||
|
||||
double ang = w->getNumber();
|
||||
double angScale = 1.0;
|
||||
getAngleScale(key, angScale);
|
||||
float angle = degToRad((float) (ang * angScale));
|
||||
|
||||
val = Quaternionf(AngleAxisf(angle, axis.normalized()));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool AssociativeArray::getColor(const string& key, Color& val) const
|
||||
{
|
||||
Vector4d vec4;
|
||||
if (getVector(key, vec4))
|
||||
{
|
||||
Vector4f vec4f = vec4.cast<float>();
|
||||
val = Color(vec4f);
|
||||
return true;
|
||||
}
|
||||
|
||||
Vector3d vec3;
|
||||
if (getVector(key, vec3))
|
||||
{
|
||||
Vector3f vec3f = vec3.cast<float>();
|
||||
val = Color(vec3f);
|
||||
return true;
|
||||
}
|
||||
|
||||
string rgba;
|
||||
if (getString(key, rgba))
|
||||
{
|
||||
int r, g, b, a;
|
||||
int ret = sscanf(rgba.c_str(), "#%2x%2x%2x%2x", &r, &g, &b, &a);
|
||||
switch (ret)
|
||||
{
|
||||
case 3:
|
||||
a = 0xFF;
|
||||
case 4:
|
||||
val = Color((char unsigned)r, (char unsigned)g, (unsigned char)b, (unsigned char)a);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves a numeric quantity scaled to an associated angle unit.
|
||||
* @param[in] key Hash key for the quantity.
|
||||
* @param[out] val The returned quantity if present, unaffected if not.
|
||||
* @param[in] outputScale Returned value is scaled to this value.
|
||||
* @param[in] defaultScale If no units are specified, use this scale. Defaults to outputScale.
|
||||
* @return True if the key exists in the hash, false otherwise.
|
||||
*/
|
||||
bool
|
||||
AssociativeArray::getAngle(const string& key, double& val, double outputScale, double defaultScale) const
|
||||
{
|
||||
if (!getNumber(key, val))
|
||||
return false;
|
||||
|
||||
double angleScale;
|
||||
if(getAngleScale(key, angleScale))
|
||||
{
|
||||
angleScale /= outputScale;
|
||||
}
|
||||
else
|
||||
{
|
||||
angleScale = (defaultScale == 0.0) ? 1.0 : defaultScale / outputScale;
|
||||
}
|
||||
|
||||
val *= angleScale;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/** @copydoc AssociativeArray::getAngle() */
|
||||
bool
|
||||
AssociativeArray::getAngle(const string& key, float& val, double outputScale, double defaultScale) const
|
||||
{
|
||||
double dval;
|
||||
|
||||
if (!getAngle(key, dval, outputScale, defaultScale))
|
||||
return false;
|
||||
|
||||
val = ((float) dval);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves a numeric quantity scaled to an associated length unit.
|
||||
* @param[in] key Hash key for the quantity.
|
||||
* @param[out] val The returned quantity if present, unaffected if not.
|
||||
* @param[in] outputScale Returned value is scaled to this value.
|
||||
* @param[in] defaultScale If no units are specified, use this scale. Defaults to outputScale.
|
||||
* @return True if the key exists in the hash, false otherwise.
|
||||
*/
|
||||
bool
|
||||
AssociativeArray::getLength(const string& key, double& val, double outputScale, double defaultScale) const
|
||||
{
|
||||
if(!getNumber(key, val))
|
||||
return false;
|
||||
|
||||
double lengthScale;
|
||||
if(getLengthScale(key, lengthScale))
|
||||
{
|
||||
lengthScale /= outputScale;
|
||||
}
|
||||
else
|
||||
{
|
||||
lengthScale = (defaultScale == 0.0) ? 1.0 : defaultScale / outputScale;
|
||||
}
|
||||
|
||||
val *= lengthScale;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/** @copydoc AssociativeArray::getLength() */
|
||||
bool AssociativeArray::getLength(const string& key, float& val, double outputScale, double defaultScale) const
|
||||
{
|
||||
double dval;
|
||||
|
||||
if (!getLength(key, dval, outputScale, defaultScale))
|
||||
return false;
|
||||
|
||||
val = ((float) dval);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves a numeric quantity scaled to an associated time unit.
|
||||
* @param[in] key Hash key for the quantity.
|
||||
* @param[out] val The returned quantity if present, unaffected if not.
|
||||
* @param[in] outputScale Returned value is scaled to this value.
|
||||
* @param[in] defaultScale If no units are specified, use this scale. Defaults to outputScale.
|
||||
* @return True if the key exists in the hash, false otherwise.
|
||||
*/
|
||||
bool AssociativeArray::getTime(const string& key, double& val, double outputScale, double defaultScale) const
|
||||
{
|
||||
if(!getNumber(key, val))
|
||||
return false;
|
||||
|
||||
double timeScale;
|
||||
if(getTimeScale(key, timeScale))
|
||||
{
|
||||
timeScale /= outputScale;
|
||||
}
|
||||
else
|
||||
{
|
||||
timeScale = (defaultScale == 0.0) ? 1.0 : defaultScale / outputScale;
|
||||
}
|
||||
|
||||
val *= timeScale;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/** @copydoc AssociativeArray::getTime() */
|
||||
bool AssociativeArray::getTime(const string& key, float& val, double outputScale, double defaultScale) const
|
||||
{
|
||||
double dval;
|
||||
|
||||
if(!getTime(key, dval, outputScale, defaultScale))
|
||||
return false;
|
||||
|
||||
val = ((float) dval);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves a numeric quantity scaled to an associated mass unit.
|
||||
* @param[in] key Hash key for the quantity.
|
||||
* @param[out] val The returned quantity if present, unaffected if not.
|
||||
* @param[in] outputScale Returned value is scaled to this value.
|
||||
* @param[in] defaultScale If no units are specified, use this scale. Defaults to outputScale.
|
||||
* @return True if the key exists in the hash, false otherwise.
|
||||
*/
|
||||
bool AssociativeArray::getMass(const string& key, double& val, double outputScale, double defaultScale) const
|
||||
{
|
||||
if(!getNumber(key, val))
|
||||
return false;
|
||||
|
||||
double massScale;
|
||||
if(getMassScale(key, massScale))
|
||||
{
|
||||
massScale /= outputScale;
|
||||
}
|
||||
else
|
||||
{
|
||||
massScale = (defaultScale == 0.0) ? 1.0 : defaultScale / outputScale;
|
||||
}
|
||||
|
||||
val *= massScale;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** @copydoc AssociativeArray::getMass() */
|
||||
bool AssociativeArray::getMass(const string& key, float& val, double outputScale, double defaultScale) const
|
||||
{
|
||||
double dval;
|
||||
|
||||
if(!getMass(key, dval, outputScale, defaultScale))
|
||||
return false;
|
||||
|
||||
val = ((float) dval);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves a vector quantity scaled to an associated length unit.
|
||||
* @param[in] key Hash key for the quantity.
|
||||
* @param[out] val The returned vector if present, unaffected if not.
|
||||
* @param[in] outputScale Returned value is scaled to this value.
|
||||
* @param[in] defaultScale If no units are specified, use this scale. Defaults to outputScale.
|
||||
* @return True if the key exists in the hash, false otherwise.
|
||||
*/
|
||||
bool AssociativeArray::getLengthVector(const string& key, Eigen::Vector3d& val, double outputScale, double defaultScale) const
|
||||
{
|
||||
if(!getVector(key, val))
|
||||
return false;
|
||||
|
||||
double lengthScale;
|
||||
if(getLengthScale(key, lengthScale))
|
||||
{
|
||||
lengthScale /= outputScale;
|
||||
}
|
||||
else
|
||||
{
|
||||
lengthScale = (defaultScale == 0.0) ? 1.0 : defaultScale / outputScale;
|
||||
}
|
||||
|
||||
val *= lengthScale;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/** @copydoc AssociativeArray::getLengthVector() */
|
||||
bool AssociativeArray::getLengthVector(const string& key, Eigen::Vector3f& val, double outputScale, double defaultScale) const
|
||||
{
|
||||
Vector3d vecVal;
|
||||
|
||||
if(!getLengthVector(key, vecVal, outputScale, defaultScale))
|
||||
return false;
|
||||
|
||||
val = vecVal.cast<float>();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves a spherical tuple \verbatim [longitude, latitude, altitude] \endverbatim scaled to associated angle and length units.
|
||||
* @param[in] key Hash key for the quantity.
|
||||
* @param[out] val The returned tuple in units of degrees and kilometers if present, unaffected if not.
|
||||
* @return True if the key exists in the hash, false otherwise.
|
||||
*/
|
||||
bool AssociativeArray::getSphericalTuple(const string& key, Vector3d& val) const
|
||||
{
|
||||
if(!getVector(key, val))
|
||||
return false;
|
||||
|
||||
double angleScale;
|
||||
if(getAngleScale(key, angleScale))
|
||||
{
|
||||
val[0] *= angleScale;
|
||||
val[1] *= angleScale;
|
||||
}
|
||||
|
||||
double lengthScale = 1.0;
|
||||
getLengthScale(key, lengthScale);
|
||||
val[2] *= lengthScale;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/** @copydoc AssociativeArray::getSphericalTuple */
|
||||
bool AssociativeArray::getSphericalTuple(const string& key, Vector3f& val) const
|
||||
{
|
||||
Vector3d vecVal;
|
||||
|
||||
if(!getSphericalTuple(key, vecVal))
|
||||
return false;
|
||||
|
||||
val = vecVal.cast<float>();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the angle unit associated with a given property.
|
||||
* @param[in] key Hash key for the property.
|
||||
* @param[out] scale The returned angle unit scaled to degrees if present, unaffected if not.
|
||||
* @return True if an angle unit has been specified for the property, false otherwise.
|
||||
*/
|
||||
bool AssociativeArray::getAngleScale(const string& key, double& scale) const
|
||||
{
|
||||
string unitKey(key + "%Angle");
|
||||
string unit;
|
||||
|
||||
if (!getString(unitKey, unit))
|
||||
return false;
|
||||
|
||||
return astro::getAngleScale(unit, scale);
|
||||
}
|
||||
|
||||
|
||||
/** @copydoc AssociativeArray::getAngleScale() */
|
||||
bool AssociativeArray::getAngleScale(const string& key, float& scale) const
|
||||
{
|
||||
double dscale;
|
||||
if (!getAngleScale(key, dscale))
|
||||
return false;
|
||||
|
||||
scale = ((float) dscale);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the length unit associated with a given property.
|
||||
* @param[in] key Hash key for the property.
|
||||
* @param[out] scale The returned length unit scaled to kilometers if present, unaffected if not.
|
||||
* @return True if a length unit has been specified for the property, false otherwise.
|
||||
*/
|
||||
bool AssociativeArray::getLengthScale(const string& key, double& scale) const
|
||||
{
|
||||
string unitKey(key + "%Length");
|
||||
string unit;
|
||||
|
||||
if (!getString(unitKey, unit))
|
||||
return false;
|
||||
|
||||
return astro::getLengthScale(unit, scale);
|
||||
}
|
||||
|
||||
|
||||
/** @copydoc AssociativeArray::getLengthScale() */
|
||||
bool AssociativeArray::getLengthScale(const string& key, float& scale) const
|
||||
{
|
||||
double dscale;
|
||||
if (!getLengthScale(key, dscale))
|
||||
return false;
|
||||
|
||||
scale = ((float) dscale);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the time unit associated with a given property.
|
||||
* @param[in] key Hash key for the property.
|
||||
* @param[out] scale The returned time unit scaled to days if present, unaffected if not.
|
||||
* @return True if a time unit has been specified for the property, false otherwise.
|
||||
*/
|
||||
bool AssociativeArray::getTimeScale(const string& key, double& scale) const
|
||||
{
|
||||
string unitKey(key + "%Time");
|
||||
string unit;
|
||||
|
||||
if (!getString(unitKey, unit))
|
||||
return false;
|
||||
|
||||
return astro::getTimeScale(unit, scale);
|
||||
}
|
||||
|
||||
|
||||
/** @copydoc AssociativeArray::getTimeScale() */
|
||||
bool AssociativeArray::getTimeScale(const string& key, float& scale) const
|
||||
{
|
||||
double dscale;
|
||||
if (!getTimeScale(key, dscale))
|
||||
return false;
|
||||
|
||||
scale = ((float) dscale);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the mass unit associated with a given property.
|
||||
* @param[in] key Hash key for the property.
|
||||
* @param[out] scale The returned mass unit scaled to Earth mass if present, unaffected if not.
|
||||
* @return True if a mass unit has been specified for the property, false otherwise.
|
||||
*/
|
||||
bool AssociativeArray::getMassScale(const string& key, double& scale) const
|
||||
{
|
||||
string unitKey(key + "%Mass");
|
||||
string unit;
|
||||
|
||||
if (!getString(unitKey, unit))
|
||||
return false;
|
||||
|
||||
return astro::getMassScale(unit, scale);
|
||||
}
|
||||
|
||||
|
||||
/** @copydoc AssociativeArray::getMassScale() */
|
||||
bool AssociativeArray::getMassScale(const string& key, float& scale) const
|
||||
{
|
||||
double dscale;
|
||||
if (!getMassScale(key, dscale))
|
||||
return false;
|
||||
|
||||
scale = ((float) dscale);
|
||||
return true;
|
||||
}
|
||||
|
||||
HashIterator
|
||||
AssociativeArray::begin()
|
||||
{
|
||||
return assoc.begin();
|
||||
}
|
||||
|
||||
|
||||
HashIterator
|
||||
AssociativeArray::end()
|
||||
{
|
||||
return assoc.end();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// parser.h
|
||||
//
|
||||
// Copyright (C) 2001-2009, the Celestia Development Team
|
||||
// Copyright (C) 2001-2019, the Celestia Development Team
|
||||
// Original version by Chris Laurel <claurel@gmail.com>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
|
@ -8,127 +8,25 @@
|
|||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
|
||||
#ifndef _PARSER_H_
|
||||
#define _PARSER_H_
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <celmath/mathlib.h>
|
||||
#include <celutil/color.h>
|
||||
#include <celcompat/filesystem.h>
|
||||
#include <celengine/tokenizer.h>
|
||||
#include <Eigen/Core>
|
||||
#include <Eigen/Geometry>
|
||||
#include "hash.h"
|
||||
#include "value.h"
|
||||
|
||||
class Tokenizer;
|
||||
class Value;
|
||||
|
||||
typedef map<string, Value*>::const_iterator HashIterator;
|
||||
|
||||
class AssociativeArray
|
||||
{
|
||||
public:
|
||||
AssociativeArray() = default;
|
||||
~AssociativeArray();
|
||||
|
||||
Value* getValue(const std::string&) const;
|
||||
void addValue(const std::string&, Value&);
|
||||
|
||||
bool getNumber(const std::string&, double&) const;
|
||||
bool getNumber(const std::string&, float&) const;
|
||||
bool getNumber(const std::string&, int&) const;
|
||||
bool getNumber(const std::string&, uint32_t&) const;
|
||||
bool getString(const std::string&, std::string&) const;
|
||||
bool getPath(const std::string&, fs::path&) const;
|
||||
bool getBoolean(const std::string&, bool&) const;
|
||||
bool getVector(const std::string&, Eigen::Vector3d&) const;
|
||||
bool getVector(const std::string&, Eigen::Vector3f&) const;
|
||||
bool getVector(const std::string&, Eigen::Vector4d&) const;
|
||||
bool getVector(const std::string&, Eigen::Vector4f&) const;
|
||||
bool getRotation(const std::string&, Eigen::Quaternionf&) const;
|
||||
bool getColor(const std::string&, Color&) const;
|
||||
bool getAngle(const std::string&, double&, double = 1.0, double = 0.0) const;
|
||||
bool getAngle(const std::string&, float&, double = 1.0, double = 0.0) const;
|
||||
bool getLength(const std::string&, double&, double = 1.0, double = 0.0) const;
|
||||
bool getLength(const std::string&, float&, double = 1.0, double = 0.0) const;
|
||||
bool getTime(const std::string&, double&, double = 1.0, double = 0.0) const;
|
||||
bool getTime(const std::string&, float&, double = 1.0, double = 0.0) const;
|
||||
bool getMass(const std::string&, double&, double = 1.0, double = 0.0) const;
|
||||
bool getMass(const std::string&, float&, double = 1.0, double = 0.0) const;
|
||||
bool getLengthVector(const std::string&, Eigen::Vector3d&, double = 1.0, double = 0.0) const;
|
||||
bool getLengthVector(const std::string&, Eigen::Vector3f&, double = 1.0, double = 0.0) const;
|
||||
bool getSphericalTuple(const std::string&, Eigen::Vector3d&) const;
|
||||
bool getSphericalTuple(const std::string&, Eigen::Vector3f&) const;
|
||||
bool getAngleScale(const std::string&, double&) const;
|
||||
bool getAngleScale(const std::string&, float&) const;
|
||||
bool getLengthScale(const std::string&, double&) const;
|
||||
bool getLengthScale(const std::string&, float&) const;
|
||||
bool getTimeScale(const std::string&, double&) const;
|
||||
bool getTimeScale(const std::string&, float&) const;
|
||||
bool getMassScale(const string&, double&) const;
|
||||
bool getMassScale(const string&, float&) const;
|
||||
|
||||
HashIterator begin();
|
||||
HashIterator end();
|
||||
|
||||
private:
|
||||
map<string, Value*> assoc;
|
||||
};
|
||||
|
||||
typedef vector<Value*> Array;
|
||||
typedef vector<Value*> ValueArray;
|
||||
typedef AssociativeArray Hash;
|
||||
|
||||
class Value
|
||||
{
|
||||
public:
|
||||
enum ValueType {
|
||||
NumberType = 0,
|
||||
StringType = 1,
|
||||
ArrayType = 2,
|
||||
HashType = 3,
|
||||
BooleanType = 4
|
||||
};
|
||||
|
||||
Value(double);
|
||||
Value(const string&);
|
||||
Value(ValueArray*);
|
||||
Value(Hash*);
|
||||
Value(bool);
|
||||
~Value();
|
||||
|
||||
ValueType getType() const;
|
||||
|
||||
double getNumber() const;
|
||||
string getString() const;
|
||||
ValueArray* getArray() const;
|
||||
Hash* getHash() const;
|
||||
bool getBoolean() const;
|
||||
|
||||
private:
|
||||
ValueType type;
|
||||
|
||||
union {
|
||||
string* s;
|
||||
double d;
|
||||
ValueArray* a;
|
||||
Hash* h;
|
||||
} data;
|
||||
};
|
||||
|
||||
|
||||
class Parser
|
||||
{
|
||||
public:
|
||||
public:
|
||||
Parser(Tokenizer*);
|
||||
|
||||
Value* readValue();
|
||||
|
||||
private:
|
||||
private:
|
||||
Tokenizer* tokenizer;
|
||||
|
||||
bool readUnits(const std::string&, Hash*);
|
||||
ValueArray* readArray();
|
||||
Array* readArray();
|
||||
Hash* readHash();
|
||||
};
|
||||
|
||||
#endif // _PARSER_H_
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <celutil/debug.h>
|
||||
#include "astro.h"
|
||||
#include "parser.h"
|
||||
#include "tokenizer.h"
|
||||
#include "texmanager.h"
|
||||
#include "meshmanager.h"
|
||||
#include "universe.h"
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "parseobject.h"
|
||||
#include "multitexture.h"
|
||||
#include "meshmanager.h"
|
||||
#include "tokenizer.h"
|
||||
#include <celutil/debug.h>
|
||||
|
||||
using namespace Eigen;
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
// value.cpp
|
||||
//
|
||||
// Copyright (C) 2001-2019, the Celestia Development Team
|
||||
// Original version by Chris Laurel <claurel@gmail.com>
|
||||
//
|
||||
// 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 "value.h"
|
||||
|
||||
/****** Value method implementations *******/
|
||||
|
||||
Value::~Value()
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case StringType:
|
||||
delete data.s;
|
||||
break;
|
||||
case ArrayType:
|
||||
if (data.a != nullptr)
|
||||
{
|
||||
for (auto *p : *data.a)
|
||||
delete p;
|
||||
delete data.a;
|
||||
}
|
||||
break;
|
||||
case HashType:
|
||||
delete data.h;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
// value.h
|
||||
//
|
||||
// Copyright (C) 2001-2019, the Celestia Development Team
|
||||
// Original version by Chris Laurel <claurel@gmail.com>
|
||||
//
|
||||
// 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.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "hash.h"
|
||||
|
||||
class Value;
|
||||
using Array = std::vector<Value*>;
|
||||
using ValueArray = Array;
|
||||
|
||||
class Value
|
||||
{
|
||||
public:
|
||||
enum ValueType
|
||||
{
|
||||
NullType = 0,
|
||||
NumberType = 1,
|
||||
StringType = 2,
|
||||
ArrayType = 3,
|
||||
HashType = 4,
|
||||
BooleanType = 5
|
||||
};
|
||||
|
||||
Value() = default;
|
||||
~Value();
|
||||
Value(const Value&) = delete;
|
||||
Value(Value&&) = default;
|
||||
Value& operator=(const Value&) = delete;
|
||||
Value& operator=(Value&&) = default;
|
||||
|
||||
Value(double d) : type(NumberType)
|
||||
{
|
||||
data.d = d;
|
||||
}
|
||||
Value(const char *s) : type(StringType)
|
||||
{
|
||||
data.s = new std::string(s);
|
||||
}
|
||||
explicit Value(const std::string &s) : type(StringType)
|
||||
{
|
||||
data.s = new std::string(s);
|
||||
}
|
||||
Value(Array *a) : type(ArrayType)
|
||||
{
|
||||
data.a = a;
|
||||
}
|
||||
Value(Hash *h) : type(HashType)
|
||||
{
|
||||
data.h = h;
|
||||
}
|
||||
Value(bool b) : type(BooleanType)
|
||||
{
|
||||
data.d = b ? 1.0 : 0.0;
|
||||
}
|
||||
|
||||
ValueType getType() const
|
||||
{
|
||||
return type;
|
||||
}
|
||||
bool isNull() const
|
||||
{
|
||||
return type == NullType;
|
||||
}
|
||||
double getNumber() const
|
||||
{
|
||||
assert(type == NumberType);
|
||||
return data.d;
|
||||
}
|
||||
std::string getString() const
|
||||
{
|
||||
assert(type == StringType);
|
||||
return *data.s;
|
||||
}
|
||||
Array* getArray() const
|
||||
{
|
||||
assert(type == ArrayType);
|
||||
return data.a;
|
||||
}
|
||||
Hash* getHash() const
|
||||
{
|
||||
assert(type == HashType);
|
||||
return data.h;
|
||||
}
|
||||
bool getBoolean() const
|
||||
{
|
||||
assert(type == BooleanType);
|
||||
return (data.d != 0.0);
|
||||
}
|
||||
|
||||
private:
|
||||
union Data
|
||||
{
|
||||
std::string *s;
|
||||
double d;
|
||||
Array *a;
|
||||
Hash *h;
|
||||
};
|
||||
|
||||
ValueType type { NullType };
|
||||
Data data;
|
||||
};
|
|
@ -20,6 +20,7 @@
|
|||
#include <celcompat/filesystem.h>
|
||||
#include <celutil/filetype.h>
|
||||
#include "parser.h"
|
||||
#include "tokenizer.h"
|
||||
#include "virtualtex.h"
|
||||
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <celutil/debug.h>
|
||||
#include <celutil/util.h>
|
||||
#include <celengine/texmanager.h>
|
||||
#include <celengine/tokenizer.h>
|
||||
#include "configfile.h"
|
||||
|
||||
using namespace std;
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <celutil/util.h>
|
||||
#include <celengine/astro.h>
|
||||
#include <celengine/parser.h>
|
||||
#include <celengine/tokenizer.h>
|
||||
#include "destination.h"
|
||||
|
||||
using namespace std;
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <celengine/parser.h>
|
||||
#include <celengine/tokenizer.h>
|
||||
#include <celutil/debug.h>
|
||||
#include <celutil/util.h>
|
||||
#include "favorites.h"
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <celmath/mathlib.h>
|
||||
#include <celengine/astro.h>
|
||||
#include <celengine/render.h>
|
||||
#include <celengine/tokenizer.h>
|
||||
#ifdef USE_GLCONTEXT
|
||||
#include <celengine/glcontext.h>
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue