mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-02-21 20:39:08 -06:00
Planets shape creation & fixed texture longitude
Instead of spheres, the planets are now created as triaxial ellipsoids according to the corresponding radii values in the SPICE kernels (if such values are available). Apart from being more scientifically accurate, the planets are shaped as the intersection functions in SPICE expects. The textures will now also be aligned in longitude as in reality (w.r.t. UTC) when using a texture map ranging from -180 in the left end to +180 on the right, with 0 longitude in the middle (such as Greenwich in Earth texture)
This commit is contained in:
@@ -66,6 +66,7 @@ private:
|
||||
ghoul::opengl::Texture* _texture;
|
||||
planetgeometry::PlanetGeometry* _geometry;
|
||||
properties::BoolProperty _performShading;
|
||||
properties::IntProperty _rotation;
|
||||
|
||||
glm::dmat3 _stateMatrix;
|
||||
|
||||
|
||||
@@ -74,6 +74,7 @@ private:
|
||||
properties::StringProperty _colorTexturePath;
|
||||
properties::StringProperty _projectionTexturePath;
|
||||
properties::TriggerProperty _imageTrigger;
|
||||
properties::IntProperty _rotation;
|
||||
|
||||
ghoul::opengl::ProgramObject* _programObject;
|
||||
ghoul::opengl::ProgramObject* _fboProgramObject;
|
||||
|
||||
@@ -50,8 +50,10 @@ public:
|
||||
private:
|
||||
void createSphere();
|
||||
|
||||
properties::Vec2Property _radius;
|
||||
glm::vec2 _modRadius;
|
||||
properties::Vec4Property _realRadius;
|
||||
properties::IntProperty _segments;
|
||||
std::string _name;
|
||||
|
||||
PowerScaledSphere* _sphere;
|
||||
};
|
||||
|
||||
@@ -49,9 +49,10 @@ public:
|
||||
private:
|
||||
void createSphere();
|
||||
|
||||
properties::Vec2Property _radius;
|
||||
glm::vec2 _modRadius;
|
||||
properties::Vec4Property _realRadius;
|
||||
properties::IntProperty _segments;
|
||||
|
||||
std::string _name;
|
||||
|
||||
properties::IntProperty _vaoID;
|
||||
properties::IntProperty _vBufferID;
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <ghoul/opengl/ghoul_gl.h>
|
||||
#include <openspace/util/powerscaledcoordinate.h>
|
||||
#include <openspace/util/powerscaledscalar.h>
|
||||
#include <openspace/properties/vectorproperty.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
@@ -37,6 +38,9 @@ public:
|
||||
// initializers
|
||||
PowerScaledSphere(const PowerScaledScalar& radius,
|
||||
int segments = 8);
|
||||
PowerScaledSphere(properties::Vec4Property &radius,
|
||||
int segments, std::string planetName);
|
||||
|
||||
~PowerScaledSphere();
|
||||
PowerScaledSphere(const PowerScaledSphere& cpy);
|
||||
|
||||
|
||||
@@ -648,6 +648,19 @@ public:
|
||||
*/
|
||||
static bool checkForError(std::string errorMessage);
|
||||
|
||||
/**
|
||||
* This method uses the SPICE kernels to get the radii of bodies defined as a
|
||||
* triaxial ellipsoid. The benefit of this is to be able to create more accurate
|
||||
* planet shapes, which is desirable when projecting images with SPICE intersection
|
||||
* methods
|
||||
* \param planetName - the name of the body, should be recognizable by SPICE
|
||||
* \param a - equatorial radius 1
|
||||
* \param b - equatorial radius 2
|
||||
* \param c - polar radius
|
||||
* \return <code>true</code> if SPICE reports no errors
|
||||
*/
|
||||
bool getPlanetEllipsoid(std::string planetName, float &a, float &b, float &c);
|
||||
|
||||
private:
|
||||
struct KernelInformation {
|
||||
std::string path; /// The path from which the kernel was loaded
|
||||
|
||||
@@ -28,7 +28,7 @@ uniform sampler2D texture1;
|
||||
uniform mat4 ProjectorMatrix;
|
||||
uniform mat4 ModelTransform;
|
||||
uniform vec2 _scaling;
|
||||
uniform vec2 radius;
|
||||
uniform vec4 radius;
|
||||
flat in uint vs_segments;
|
||||
|
||||
in vec4 vs_position;
|
||||
@@ -38,7 +38,7 @@ out vec4 color;
|
||||
|
||||
#define M_PI 3.14159265358979323846
|
||||
|
||||
vec4 uvToModel( float u, float v, vec2 radius, float segments){
|
||||
vec4 uvToModel( float u, float v, vec4 radius, float segments){
|
||||
const float fj = u * segments;
|
||||
const float fi = v * segments;
|
||||
|
||||
@@ -46,10 +46,10 @@ vec4 uvToModel( float u, float v, vec2 radius, float segments){
|
||||
const float phi = fj * float(M_PI) * 2.0f / segments;
|
||||
|
||||
const float x = radius[0] * sin(phi) * sin(theta); //
|
||||
const float y = radius[0] * cos(theta); // up
|
||||
const float z = radius[0] * cos(phi) * sin(theta); //
|
||||
const float y = radius[1] * cos(theta); // up
|
||||
const float z = radius[2] * cos(phi) * sin(theta); //
|
||||
|
||||
return vec4(x, y, z, radius[1]);
|
||||
return vec4(x, y, z, radius[3]);
|
||||
}
|
||||
|
||||
#include "PowerScaling/powerScaling_vs.hglsl"
|
||||
|
||||
@@ -60,6 +60,7 @@ RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary)
|
||||
, _texture(nullptr)
|
||||
, _geometry(nullptr)
|
||||
, _performShading("performShading", "Perform Shading", true)
|
||||
, _rotation("rotation", "Rotation", 0, 0, 360)
|
||||
{
|
||||
std::string name;
|
||||
bool success = dictionary.getValue(constants::scenegraphnode::keyName, name);
|
||||
@@ -104,6 +105,8 @@ RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary)
|
||||
}
|
||||
|
||||
addProperty(_performShading);
|
||||
// Mainly for debugging purposes @AA
|
||||
addProperty(_rotation);
|
||||
}
|
||||
|
||||
RenderablePlanet::~RenderablePlanet() {
|
||||
@@ -150,17 +153,15 @@ void RenderablePlanet::render(const RenderData& data)
|
||||
|
||||
//earth needs to be rotated for that to work.
|
||||
glm::mat4 rot = glm::rotate(transform, 90.f, glm::vec3(1, 0, 0));
|
||||
|
||||
glm::mat4 roty = glm::rotate(transform, 90.f, glm::vec3(0, -1, 0));
|
||||
glm::mat4 rotProp = glm::rotate(transform, static_cast<float>(_rotation), glm::vec3(0, 1, 0));
|
||||
|
||||
for (int i = 0; i < 3; i++){
|
||||
for (int j = 0; j < 3; j++){
|
||||
transform[i][j] = static_cast<float>(_stateMatrix[i][j]);
|
||||
}
|
||||
}
|
||||
transform = transform* rot;
|
||||
if (_frame == "IAU_JUPITER"){ //x = 0.935126
|
||||
transform *= glm::scale(glm::mat4(1), glm::vec3(1, 0.93513, 1));
|
||||
}
|
||||
|
||||
transform = transform * rot * roty * rotProp;
|
||||
|
||||
//glm::mat4 modelview = data.camera.viewMatrix()*data.camera.modelMatrix();
|
||||
//glm::vec3 camSpaceEye = (-(modelview*data.position.vec4())).xyz;
|
||||
|
||||
@@ -84,6 +84,7 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary&
|
||||
, _texture(nullptr)
|
||||
, _textureProj(nullptr)
|
||||
, _geometry(nullptr)
|
||||
, _rotation("rotation", "Rotation", 0, 0, 360)
|
||||
{
|
||||
std::string name;
|
||||
bool success = dictionary.getValue(constants::scenegraphnode::keyName, name);
|
||||
@@ -149,7 +150,7 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary&
|
||||
_projectionTexturePath = path + "/" + texturePath;
|
||||
}
|
||||
addPropertySubOwner(_geometry);
|
||||
|
||||
addProperty(_rotation);
|
||||
addProperty(_imageTrigger);
|
||||
_imageTrigger.onChange(std::bind(&RenderablePlanetProjection::loadTexture, this));
|
||||
|
||||
@@ -287,8 +288,8 @@ void RenderablePlanetProjection::imageProjectGPU(){
|
||||
|
||||
if (_geometry->hasProperty("radius")){
|
||||
boost::any r = _geometry->property("radius")->get();
|
||||
if (glm::vec2* radius = boost::any_cast<glm::vec2>(&r)){
|
||||
_fboProgramObject->setUniform("radius", radius[0]);
|
||||
if (glm::vec4* radius = boost::any_cast<glm::vec4>(&r)){
|
||||
_fboProgramObject->setUniform("radius", radius);
|
||||
}
|
||||
}else{
|
||||
LERROR("Geometry object needs to provide radius");
|
||||
@@ -345,15 +346,16 @@ void RenderablePlanetProjection::attitudeParameters(double time){
|
||||
_transform = glm::mat4(1);
|
||||
//90 deg rotation w.r.t spice req.
|
||||
glm::mat4 rot = glm::rotate(_transform, 90.f, glm::vec3(1, 0, 0));
|
||||
glm::mat4 roty = glm::rotate(_transform, 90.f, glm::vec3(0, -1, 0));
|
||||
glm::mat4 rotProp = glm::rotate(_transform, static_cast<float>(_rotation), glm::vec3(0, 1, 0));
|
||||
|
||||
for (int i = 0; i < 3; i++){
|
||||
for (int j = 0; j < 3; j++){
|
||||
_transform[i][j] = _stateMatrix[i][j];
|
||||
_transform[i][j] = static_cast<float>(_stateMatrix[i][j]);
|
||||
}
|
||||
}
|
||||
_transform = _transform* rot;
|
||||
if (_target == "IAU_JUPITER"){ // tmp solution scale of jupiterX = 0.935126
|
||||
_transform *= glm::scale(glm::mat4(1), glm::vec3(1, 0.935126, 1));
|
||||
}
|
||||
_transform = _transform * rot * roty * rotProp;
|
||||
|
||||
std::string shape, instrument;
|
||||
std::vector<glm::dvec3> bounds;
|
||||
glm::dvec3 bs;
|
||||
|
||||
@@ -43,8 +43,8 @@ namespace planetgeometry {
|
||||
|
||||
SimpleSphereGeometry::SimpleSphereGeometry(const ghoul::Dictionary& dictionary)
|
||||
: PlanetGeometry()
|
||||
, _radius("radius", "Radius", glm::vec2(1.f, 0.f), glm::vec2(-10.f, -20.f),
|
||||
glm::vec2(10.f, 20.f))
|
||||
, _realRadius("radius", "Radius", glm::vec4(1.f, 1.f, 1.f, 0.f), glm::vec4(-10.f, -10.f, -10.f, -20.f),
|
||||
glm::vec4(10.f, 10.f, 10.f, 20.f))
|
||||
, _segments("segments", "Segments", 20, 1, 50)
|
||||
, _sphere(nullptr)
|
||||
{
|
||||
@@ -53,30 +53,37 @@ SimpleSphereGeometry::SimpleSphereGeometry(const ghoul::Dictionary& dictionary)
|
||||
using constants::simplespheregeometry::keySegments;
|
||||
|
||||
// The name is passed down from the SceneGraphNode
|
||||
std::string name;
|
||||
bool success = dictionary.getValue(keyName, name);
|
||||
bool success = dictionary.getValue(keyName, _name);
|
||||
assert(success);
|
||||
|
||||
glm::vec2 radius;
|
||||
success = dictionary.getValue(keyRadius, radius);
|
||||
|
||||
glm::vec4 radius;
|
||||
success = dictionary.getValue(keyRadius, _modRadius);
|
||||
if (!success) {
|
||||
LERROR("SimpleSphereGeometry of '" << name << "' did not provide a key '"
|
||||
LERROR("SimpleSphereGeometry of '" << _name << "' did not provide a key '"
|
||||
<< keyRadius << "'");
|
||||
}
|
||||
else
|
||||
_radius = radius;
|
||||
else {
|
||||
radius[0] = _modRadius[0];
|
||||
radius[1] = _modRadius[0];
|
||||
radius[2] = _modRadius[0];
|
||||
radius[3] = _modRadius[1];
|
||||
_realRadius = radius; // In case the kernels does not supply a real
|
||||
}
|
||||
|
||||
double segments;
|
||||
success = dictionary.getValue(keySegments, segments);
|
||||
if (!success) {
|
||||
LERROR("SimpleSphereGeometry of '" << name << "' did not provide a key '"
|
||||
LERROR("SimpleSphereGeometry of '" << _name << "' did not provide a key '"
|
||||
<< keySegments << "'");
|
||||
}
|
||||
else
|
||||
_segments = static_cast<int>(segments);
|
||||
|
||||
addProperty(_radius);
|
||||
_radius.onChange(std::bind(&SimpleSphereGeometry::createSphere, this));
|
||||
// The shader need the radii values but they are not changeable runtime
|
||||
// TODO: Possibly add a scaling property @AA
|
||||
addProperty(_realRadius);
|
||||
// Changing the radius/scaling should affect the shader but not the geometry? @AA
|
||||
//_radius.onChange(std::bind(&SimpleSphereGeometry::createSphere, this));
|
||||
addProperty(_segments);
|
||||
_segments.onChange(std::bind(&SimpleSphereGeometry::createSphere, this));
|
||||
}
|
||||
@@ -107,13 +114,13 @@ void SimpleSphereGeometry::render()
|
||||
void SimpleSphereGeometry::createSphere(){
|
||||
//create the power scaled scalar
|
||||
|
||||
PowerScaledScalar planetSize(_radius);
|
||||
PowerScaledScalar planetSize(_modRadius);
|
||||
_parent->setBoundingSphere(planetSize);
|
||||
|
||||
if(_sphere)
|
||||
delete _sphere;
|
||||
|
||||
_sphere = new PowerScaledSphere(planetSize, _segments);
|
||||
//_sphere = new PowerScaledSphere(planetSize, _segments);
|
||||
_sphere = new PowerScaledSphere(_realRadius, _segments, _name);
|
||||
_sphere->initialize();
|
||||
}
|
||||
|
||||
|
||||
@@ -42,8 +42,8 @@ namespace planetgeometryprojection {
|
||||
|
||||
SimpleSphereGeometryProjection::SimpleSphereGeometryProjection(const ghoul::Dictionary& dictionary)
|
||||
: PlanetGeometryProjection()
|
||||
, _radius("radius", "Radius", glm::vec2(1.f, 0.f), glm::vec2(-10.f, -20.f),
|
||||
glm::vec2(10.f, 20.f))
|
||||
, _realRadius("radius", "Radius", glm::vec4(1.f, 1.f, 1.f, 0.f), glm::vec4(-10.f, -10.f, -10.f, -20.f),
|
||||
glm::vec4(10.f, 10.f, 10.f, 20.f))
|
||||
, _segments("segments", "Segments", 20, 1, 1000)
|
||||
, _vaoID("vaoID", "Vao", 1, 1, 1)
|
||||
, _vBufferID("vboID", "Vbo", 1, 1, 1)
|
||||
@@ -55,30 +55,37 @@ SimpleSphereGeometryProjection::SimpleSphereGeometryProjection(const ghoul::Dict
|
||||
using constants::simplespheregeometryprojection::keySegments;
|
||||
|
||||
// The name is passed down from the SceneGraphNode
|
||||
std::string name;
|
||||
bool success = dictionary.getValue(keyName, name);
|
||||
bool success = dictionary.getValue(keyName, _name);
|
||||
assert(success);
|
||||
|
||||
glm::vec2 radius;
|
||||
success = dictionary.getValue(keyRadius, radius);
|
||||
// removing "Projection"-suffix from name for SPICE compability, TODO: better solution @AA
|
||||
if(_name.find("Projection"))
|
||||
_name = _name.substr(0, _name.size() - 10);
|
||||
|
||||
glm::vec4 radius;
|
||||
success = dictionary.getValue(keyRadius, _modRadius);
|
||||
if (!success) {
|
||||
LERROR("SimpleSphereGeometry of '" << name << "' did not provide a key '"
|
||||
LERROR("SimpleSphereGeometry of '" << _name << "' did not provide a key '"
|
||||
<< keyRadius << "'");
|
||||
}
|
||||
else
|
||||
_radius = radius;
|
||||
|
||||
else {
|
||||
radius[0] = _modRadius[0];
|
||||
radius[1] = _modRadius[0];
|
||||
radius[2] = _modRadius[0];
|
||||
radius[3] = _modRadius[1];
|
||||
_realRadius = radius;
|
||||
}
|
||||
double segments;
|
||||
success = dictionary.getValue(keySegments, segments);
|
||||
if (!success) {
|
||||
LERROR("SimpleSphereGeometry of '" << name << "' did not provide a key '"
|
||||
LERROR("SimpleSphereGeometry of '" << _name << "' did not provide a key '"
|
||||
<< keySegments << "'");
|
||||
}
|
||||
else
|
||||
_segments = static_cast<int>(segments);
|
||||
|
||||
addProperty(_radius);
|
||||
_radius.onChange(std::bind(&SimpleSphereGeometryProjection::createSphere, this));
|
||||
addProperty(_realRadius);
|
||||
//_realRadius.onChange(std::bind(&SimpleSphereGeometryProjection::createSphere, this));
|
||||
addProperty(_segments);
|
||||
_segments.onChange(std::bind(&SimpleSphereGeometryProjection::createSphere, this));
|
||||
}
|
||||
@@ -117,12 +124,12 @@ void SimpleSphereGeometryProjection::createSphere()
|
||||
{
|
||||
//create the power scaled scalar
|
||||
|
||||
PowerScaledScalar planetSize(_radius);
|
||||
PowerScaledScalar planetSize(_modRadius);
|
||||
_parent->setBoundingSphere(planetSize);
|
||||
|
||||
delete _planet;
|
||||
_planet = new PowerScaledSphere(planetSize, _segments);
|
||||
_planet->initialize();
|
||||
_planet = new PowerScaledSphere(_realRadius, _segments, _name);
|
||||
_planet->initialize();
|
||||
}
|
||||
|
||||
} // namespace planetgeometry
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
// open space includes
|
||||
#include <openspace/util/powerscaledsphere.h>
|
||||
|
||||
#include <openspace/util/spicemanager.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
#define _USE_MATH_DEFINES
|
||||
@@ -125,6 +125,103 @@ PowerScaledSphere::PowerScaledSphere(const PowerScaledScalar& radius, int segmen
|
||||
}
|
||||
}
|
||||
|
||||
// Alternative Constructor for using accurate triaxial ellipsoid
|
||||
PowerScaledSphere::PowerScaledSphere(properties::Vec4Property &radius, int segments, std::string planetName)
|
||||
: _vaoID(0)
|
||||
, _vBufferID(0)
|
||||
, _iBufferID(0)
|
||||
, _isize(6 * segments * segments)
|
||||
, _vsize((segments + 1) * (segments + 1))
|
||||
, _varray(new Vertex[_vsize])
|
||||
, _iarray(new int[_isize])
|
||||
{
|
||||
static_assert(sizeof(Vertex) == 64,
|
||||
"The size of the Vertex needs to be 64 for performance");
|
||||
|
||||
float a, b, c, powerscale;
|
||||
bool accutareRadius = SpiceManager::ref().getPlanetEllipsoid(planetName, a, b, c);
|
||||
|
||||
if (accutareRadius) {
|
||||
PowerScaledCoordinate powerScaledRadii = psc::CreatePowerScaledCoordinate(a, b, c);
|
||||
powerScaledRadii[3] += 3; // SPICE returns radii in km
|
||||
|
||||
std::swap(powerScaledRadii[1], powerScaledRadii[2]); // c is equivalent to y in our coordinate system
|
||||
radius.set(powerScaledRadii.vec4());
|
||||
a = powerScaledRadii[0];
|
||||
b = powerScaledRadii[1];
|
||||
c = powerScaledRadii[2];
|
||||
powerscale = powerScaledRadii[3];
|
||||
}
|
||||
else {
|
||||
boost::any r = radius.get();
|
||||
glm::vec4 modRadius = boost::any_cast<glm::vec4>(r);
|
||||
a = modRadius[0];
|
||||
b = modRadius[1];
|
||||
c = modRadius[2];
|
||||
powerscale = modRadius[3];
|
||||
}
|
||||
|
||||
int nr = 0;
|
||||
const float fsegments = static_cast<float>(segments);
|
||||
|
||||
for (int i = 0; i <= segments; i++) {
|
||||
// define an extra vertex around the y-axis due to texture mapping
|
||||
for (int j = 0; j <= segments; j++) {
|
||||
const float fi = static_cast<float>(i);
|
||||
const float fj = static_cast<float>(j);
|
||||
// inclination angle (north to south)
|
||||
const float theta = fi * float(M_PI) / fsegments; // 0 -> PI
|
||||
// azimuth angle (east to west)
|
||||
const float phi = fj * float(M_PI) * 2.0f / fsegments; // 0 -> 2*PI
|
||||
|
||||
const float x = a * sin(phi) * sin(theta); //
|
||||
const float y = b * cos(theta); // up
|
||||
const float z = c * cos(phi) * sin(theta); //
|
||||
|
||||
_varray[nr].location[0] = x;
|
||||
_varray[nr].location[1] = y;
|
||||
_varray[nr].location[2] = z;
|
||||
_varray[nr].location[3] = powerscale;
|
||||
|
||||
glm::vec3 normal = glm::vec3(x, y, z);
|
||||
if (!(x == 0.f && y == 0.f && z == 0.f))
|
||||
normal = glm::normalize(normal);
|
||||
|
||||
_varray[nr].normal[0] = normal[0];
|
||||
_varray[nr].normal[1] = normal[1];
|
||||
_varray[nr].normal[2] = normal[2];
|
||||
|
||||
const float t1 = fj / fsegments;
|
||||
const float t2 = fi / fsegments;
|
||||
|
||||
_varray[nr].tex[0] = t1;
|
||||
_varray[nr].tex[1] = t2;
|
||||
++nr;
|
||||
}
|
||||
}
|
||||
|
||||
nr = 0;
|
||||
// define indices for all triangles
|
||||
for (int i = 1; i <= segments; ++i) {
|
||||
for (int j = 0; j < segments; ++j) {
|
||||
const int t = segments + 1;
|
||||
_iarray[nr] = t * (i - 1) + j + 0; //1
|
||||
++nr;
|
||||
_iarray[nr] = t * (i + 0) + j + 0; //2
|
||||
++nr;
|
||||
_iarray[nr] = t * (i + 0) + j + 1; //3
|
||||
++nr;
|
||||
|
||||
_iarray[nr] = t * (i - 1) + j + 0; //4
|
||||
++nr;
|
||||
_iarray[nr] = t * (i + 0) + j + 1; //5
|
||||
++nr;
|
||||
_iarray[nr] = t * (i - 1) + j + 1; //6
|
||||
++nr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PowerScaledSphere::PowerScaledSphere(const PowerScaledSphere& cpy)
|
||||
: _vaoID(cpy._vaoID)
|
||||
, _vBufferID(cpy._vBufferID)
|
||||
|
||||
@@ -766,6 +766,30 @@ bool SpiceManager::checkForError(std::string errorMessage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SpiceManager::getPlanetEllipsoid(std::string planetName, float &a, float &b, float &c) {
|
||||
|
||||
SpiceDouble radii[3];
|
||||
SpiceInt n;
|
||||
int id;
|
||||
|
||||
getNaifId(planetName, id);
|
||||
if (bodfnd_c(id, "RADII")) {
|
||||
bodvrd_c(planetName.c_str(), "RADII", 3, &n, radii);
|
||||
a = radii[0];
|
||||
b = radii[1];
|
||||
c = radii[2];
|
||||
}
|
||||
else {
|
||||
LWARNING("Could not find SPICE data for the shape of " + planetName + ", using modfile value");
|
||||
a = 1.f;
|
||||
b = 1.f;
|
||||
c = 1.f;
|
||||
}
|
||||
|
||||
bool hasError = checkForError("Error retrieving planet radii of " + planetName);
|
||||
return !hasError;
|
||||
}
|
||||
|
||||
//bool SpiceManager::getSubSolarPoint(std::string computationMethod,
|
||||
// std::string target,
|
||||
// double ephemeris,
|
||||
|
||||
Reference in New Issue
Block a user