SolarSystem.cpp   SolarSystem.cpp 
skipping to change at line 40 skipping to change at line 40
#include "StelTextureMgr.hpp" #include "StelTextureMgr.hpp"
#include "StelObjectMgr.hpp" #include "StelObjectMgr.hpp"
#include "StelLocaleMgr.hpp" #include "StelLocaleMgr.hpp"
#include "StelSkyCultureMgr.hpp" #include "StelSkyCultureMgr.hpp"
#include "StelFileMgr.hpp" #include "StelFileMgr.hpp"
#include "StelModuleMgr.hpp" #include "StelModuleMgr.hpp"
#include "StelIniParser.hpp" #include "StelIniParser.hpp"
#include "Planet.hpp" #include "Planet.hpp"
#include "MinorPlanet.hpp" #include "MinorPlanet.hpp"
#include "Comet.hpp" #include "Comet.hpp"
#include "StelMainView.hpp"
#include "StelSkyDrawer.hpp" #include "StelSkyDrawer.hpp"
#include "StelUtils.hpp" #include "StelUtils.hpp"
#include "StelPainter.hpp" #include "StelPainter.hpp"
#include "TrailGroup.hpp" #include "TrailGroup.hpp"
#include "RefractionExtinction.hpp" #include "RefractionExtinction.hpp"
#include "AstroCalcDialog.hpp" #include "AstroCalcDialog.hpp"
#include <functional> #include <functional>
skipping to change at line 66 skipping to change at line 67
#include <QStringList> #include <QStringList>
#include <QMap> #include <QMap>
#include <QMultiMap> #include <QMultiMap>
#include <QMapIterator> #include <QMapIterator>
#include <QDebug> #include <QDebug>
#include <QDir> #include <QDir>
SolarSystem::SolarSystem() SolarSystem::SolarSystem()
: shadowPlanetCount(0) : shadowPlanetCount(0)
, flagMoonScale(false) , flagMoonScale(false)
, moonScale(1.) , moonScale(1.0)
, flagMinorBodyScale(false)
, minorBodyScale(1.0)
, labelsAmount(false) , labelsAmount(false)
, flagOrbits(false) , flagOrbits(false)
, flagLightTravelTime(true) , flagLightTravelTime(true)
, flagUseObjModels(false)
, flagShowObjSelfShadows(true)
, flagShow(false) , flagShow(false)
, flagPointer(false) , flagPointer(false)
, flagNativePlanetNames(false) , flagNativePlanetNames(false)
, flagTranslatedNames(false) , flagTranslatedNames(false)
, flagIsolatedTrails(true) , flagIsolatedTrails(true)
, flagIsolatedOrbits(true) , flagIsolatedOrbits(true)
, ephemerisMarkersDisplayed(true) , ephemerisMarkersDisplayed(true)
, ephemerisDatesDisplayed(false) , ephemerisDatesDisplayed(false)
, allTrails(NULL) , ephemerisMagnitudesDisplayed(false)
, ephemerisHorizontalCoordinates(false)
, allTrails(Q_NULLPTR)
, conf(StelApp::getInstance().getSettings()) , conf(StelApp::getInstance().getSettings())
{ {
planetNameFont.setPixelSize(StelApp::getInstance().getBaseFontSize() ); planetNameFont.setPixelSize(StelApp::getInstance().getBaseFontSize() );
setObjectName("SolarSystem"); setObjectName("SolarSystem");
gui = dynamic_cast<StelGui*>(StelApp::getInstance().getGui()); gui = dynamic_cast<StelGui*>(StelApp::getInstance().getGui());
} }
void SolarSystem::setFontSize(float newFontSize) void SolarSystem::setFontSize(float newFontSize)
{ {
planetNameFont.setPixelSize(newFontSize); planetNameFont.setPixelSize(newFontSize);
} }
SolarSystem::~SolarSystem() SolarSystem::~SolarSystem()
{ {
// release selected: // release selected:
selected.clear(); selected.clear();
foreach (Orbit* orb, orbits) foreach (Orbit* orb, orbits)
{ {
delete orb; delete orb;
orb = NULL; orb = Q_NULLPTR;
} }
sun.clear(); sun.clear();
moon.clear(); moon.clear();
earth.clear(); earth.clear();
Planet::hintCircleTex.clear(); Planet::hintCircleTex.clear();
Planet::texEarthShadow.clear(); Planet::texEarthShadow.clear();
texCircle.clear(); texCircle.clear();
texPointer.clear(); texPointer.clear();
delete allTrails; delete allTrails;
allTrails = NULL; allTrails = Q_NULLPTR;
// Get rid of circular reference between the shared pointers which p revent proper destruction of the Planet objects. // Get rid of circular reference between the shared pointers which p revent proper destruction of the Planet objects.
foreach (PlanetP p, systemPlanets) foreach (PlanetP p, systemPlanets)
{ {
p->satellites.clear(); p->satellites.clear();
} }
//delete comet textures created in loadPlanets //delete comet textures created in loadPlanets
Comet::comaTexture.clear(); Comet::comaTexture.clear();
Comet::tailTexture.clear(); Comet::tailTexture.clear();
skipping to change at line 150 skipping to change at line 157
Planet::init(); Planet::init();
loadPlanets(); // Load planets data loadPlanets(); // Load planets data
// Compute position and matrix of sun and all the satellites (ie pla nets) // Compute position and matrix of sun and all the satellites (ie pla nets)
// for the first initialization Q_ASSERT that center is sun center ( only impacts on light speed correction) // for the first initialization Q_ASSERT that center is sun center ( only impacts on light speed correction)
computePositions(StelApp::getInstance().getCore()->getJDE()); computePositions(StelApp::getInstance().getCore()->getJDE());
setSelected(""); // Fix a bug on macosX! Thanks Fumio! setSelected(""); // Fix a bug on macosX! Thanks Fumio!
setFlagMoonScale(conf->value("viewing/flag_moon_scaled", conf->value ("viewing/flag_init_moon_scaled", "false").toBool()).toBool()); // name ch ange setFlagMoonScale(conf->value("viewing/flag_moon_scaled", conf->value ("viewing/flag_init_moon_scaled", "false").toBool()).toBool()); // name ch ange
setMinorBodyScale(conf->value("viewing/minorbodies_scale", 10.0).toF
loat());
setFlagMinorBodyScale(conf->value("viewing/flag_minorbodies_scaled",
false).toBool());
setMoonScale(conf->value("viewing/moon_scale", 4.0).toFloat()); setMoonScale(conf->value("viewing/moon_scale", 4.0).toFloat());
setFlagPlanets(conf->value("astro/flag_planets").toBool()); setFlagPlanets(conf->value("astro/flag_planets").toBool());
setFlagHints(conf->value("astro/flag_planets_hints").toBool()); setFlagHints(conf->value("astro/flag_planets_hints").toBool());
setFlagLabels(conf->value("astro/flag_planets_labels", true).toBool( )); setFlagLabels(conf->value("astro/flag_planets_labels", true).toBool( ));
setLabelsAmount(conf->value("astro/labels_amount", 3.).toFloat()); setLabelsAmount(conf->value("astro/labels_amount", 3.).toFloat());
setFlagOrbits(conf->value("astro/flag_planets_orbits").toBool()); setFlagOrbits(conf->value("astro/flag_planets_orbits").toBool());
setFlagLightTravelTime(conf->value("astro/flag_light_travel_time", t rue).toBool()); setFlagLightTravelTime(conf->value("astro/flag_light_travel_time", t rue).toBool());
setFlagUseObjModels(conf->value("astro/flag_use_obj_models", false).
toBool());
setFlagShowObjSelfShadows(conf->value("astro/flag_show_obj_self_shad
ows", true).toBool());
setFlagPointer(conf->value("astro/flag_planets_pointers", true).toBo ol()); setFlagPointer(conf->value("astro/flag_planets_pointers", true).toBo ol());
// Set the algorithm from Astronomical Almanac for computation of ap parent magnitudes for // Set the algorithm from Astronomical Almanac for computation of ap parent magnitudes for
// planets in case observer on the Earth by default // planets in case observer on the Earth by default
setApparentMagnitudeAlgorithmOnEarth(conf->value("astro/apparent_mag nitude_algorithm", "Harris").toString()); setApparentMagnitudeAlgorithmOnEarth(conf->value("astro/apparent_mag nitude_algorithm", "ExplSup2013").toString());
setFlagNativePlanetNames(conf->value("viewing/flag_planets_native_na mes", true).toBool()); setFlagNativePlanetNames(conf->value("viewing/flag_planets_native_na mes", true).toBool());
// Is enabled the showing of isolated trails for selected objects on ly? // Is enabled the showing of isolated trails for selected objects on ly?
setFlagIsolatedTrails(conf->value("viewing/flag_isolated_trails", tr ue).toBool()); setFlagIsolatedTrails(conf->value("viewing/flag_isolated_trails", tr ue).toBool());
setFlagIsolatedOrbits(conf->value("viewing/flag_isolated_orbits", tr ue).toBool()); setFlagIsolatedOrbits(conf->value("viewing/flag_isolated_orbits", tr ue).toBool());
setFlagPermanentOrbits(conf->value("astro/flag_permanent_orbits", fa lse).toBool()); setFlagPermanentOrbits(conf->value("astro/flag_permanent_orbits", fa lse).toBool());
setOrbitColorStyle(conf->value("astro/planets_orbits_color_style", " one_color").toString()); setOrbitColorStyle(conf->value("astro/planets_orbits_color_style", " one_color").toString());
setFlagEphemerisMarkers(conf->value("astro/flag_ephemeris_markers", setFlagEphemerisMarkers(conf->value("astrocalc/flag_ephemeris_marker
true).toBool()); s", true).toBool());
setFlagEphemerisDates(conf->value("astro/flag_ephemeris_dates", fals setFlagEphemerisDates(conf->value("astrocalc/flag_ephemeris_dates",
e).toBool()); false).toBool());
setFlagEphemerisMagnitudes(conf->value("astrocalc/flag_ephemeris_mag
nitudes", false).toBool());
setFlagEphemerisHorizontalCoordinates(conf->value("astrocalc/flag_ep
hemeris_horizontal", false).toBool());
// Settings for calculation of position of Great Red Spot on Jupiter // Settings for calculation of position of Great Red Spot on Jupiter
setFlagCustomGrsSettings(conf->value("astro/flag_grs_custom", false) .toBool()); setFlagCustomGrsSettings(conf->value("astro/flag_grs_custom", false) .toBool());
setCustomGrsLongitude(conf->value("astro/grs_longitude", 216).toInt( )); setCustomGrsLongitude(conf->value("astro/grs_longitude", 216).toInt( ));
setCustomGrsDrift(conf->value("astro/grs_drift", 15.).toDouble()); setCustomGrsDrift(conf->value("astro/grs_drift", 15.).toDouble());
setCustomGrsJD(conf->value("astro/grs_jd", 2456901.5).toDouble()); setCustomGrsJD(conf->value("astro/grs_jd", 2456901.5).toDouble());
// Load colors from config file // Load colors from config file
QString defaultColor = conf->value("color/default_color").toString() ; QString defaultColor = conf->value("color/default_color").toString() ;
setLabelsColor(StelUtils::strToVec3f(conf->value("color/planet_names _color", defaultColor).toString())); setLabelsColor(StelUtils::strToVec3f(conf->value("color/planet_names _color", defaultColor).toString()));
skipping to change at line 218 skipping to change at line 231
connect(objectManager, SIGNAL(selectedObjectChanged(StelModule::Stel ModuleSelectAction)), connect(objectManager, SIGNAL(selectedObjectChanged(StelModule::Stel ModuleSelectAction)),
this, SLOT(selectedObjectChange(StelModule::StelModuleSelect Action))); this, SLOT(selectedObjectChange(StelModule::StelModuleSelect Action)));
texPointer = StelApp::getInstance().getTextureManager().createTextur e(StelFileMgr::getInstallationDir()+"/textures/pointeur4.png"); texPointer = StelApp::getInstance().getTextureManager().createTextur e(StelFileMgr::getInstallationDir()+"/textures/pointeur4.png");
texCircle = StelApp::getInstance().getTextureManager().createTexture (StelFileMgr::getInstallationDir()+"/textures/neb.png"); // Load circle texture texCircle = StelApp::getInstance().getTextureManager().createTexture (StelFileMgr::getInstallationDir()+"/textures/neb.png"); // Load circle texture
Planet::hintCircleTex = StelApp::getInstance().getTextureManager().c reateTexture(StelFileMgr::getInstallationDir()+"/textures/planet-indicator. png"); Planet::hintCircleTex = StelApp::getInstance().getTextureManager().c reateTexture(StelFileMgr::getInstallationDir()+"/textures/planet-indicator. png");
StelApp *app = &StelApp::getInstance(); StelApp *app = &StelApp::getInstance();
connect(app, SIGNAL(languageChanged()), this, SLOT(updateI18n())); connect(app, SIGNAL(languageChanged()), this, SLOT(updateI18n()));
connect(&app->getSkyCultureMgr(), SIGNAL(currentSkyCultureChanged(QS tring)), this, SLOT(updateSkyCulture(QString))); connect(&app->getSkyCultureMgr(), SIGNAL(currentSkyCultureChanged(QS tring)), this, SLOT(updateSkyCulture(QString)));
connect(&StelMainView::getInstance(), SIGNAL(reloadShadersRequested( )), this, SLOT(reloadShaders()));
QString displayGroup = N_("Display Options"); QString displayGroup = N_("Display Options");
addAction("actionShow_Planets", displayGroup, N_("Planets"), "planet sDisplayed", "P"); addAction("actionShow_Planets", displayGroup, N_("Planets"), "planet sDisplayed", "P");
addAction("actionShow_Planets_Labels", displayGroup, N_("Planet labe ls"), "labelsDisplayed", "Alt+P"); addAction("actionShow_Planets_Labels", displayGroup, N_("Planet labe ls"), "labelsDisplayed", "Alt+P");
addAction("actionShow_Planets_Orbits", displayGroup, N_("Planet orbi ts"), "flagOrbits", "O"); addAction("actionShow_Planets_Orbits", displayGroup, N_("Planet orbi ts"), "flagOrbits", "O");
addAction("actionShow_Planets_Trails", displayGroup, N_("Planet trai ls"), "trailsDisplayed", "Shift+T"); addAction("actionShow_Planets_Trails", displayGroup, N_("Planet trai ls"), "trailsDisplayed", "Shift+T");
//there is a small discrepancy in the GUI: "Show planet markers" act ually means show planet hints //there is a small discrepancy in the GUI: "Show planet markers" act ually means show planet hints
addAction("actionShow_Planets_Hints", displayGroup, N_("Planet marke rs"), "flagHints", "Ctrl+P"); addAction("actionShow_Planets_Hints", displayGroup, N_("Planet marke rs"), "flagHints", "Ctrl+P");
addAction("actionShow_Planets_Pointers", displayGroup, N_("Planet se lection marker"), "flagPointer", "Ctrl+Shift+P"); addAction("actionShow_Planets_Pointers", displayGroup, N_("Planet se lection marker"), "flagPointer", "Ctrl+Shift+P");
addAction("actionShow_Skyculture_NativePlanetNames", displayGroup, N _("Native planet names (from starlore)"), "flagNativePlanetNames", "Ctrl+Sh ift+N"); addAction("actionShow_Skyculture_NativePlanetNames", displayGroup, N _("Native planet names (from starlore)"), "flagNativePlanetNames", "Ctrl+Sh ift+N");
} }
void SolarSystem::deinit() void SolarSystem::deinit()
{ {
if(Planet::planetShaderProgram) Planet::deinitShader();
Planet::deinitShader(); Planet::deinitFBO();
} }
void SolarSystem::recreateTrails() void SolarSystem::recreateTrails()
{ {
// Create a trail group containing all the planets orbiting the sun (not including satellites) // Create a trail group containing all the planets orbiting the sun (not including satellites)
if (allTrails!=NULL) if (allTrails!=Q_NULLPTR)
delete allTrails; delete allTrails;
allTrails = new TrailGroup(365.f); allTrails = new TrailGroup(365.f);
PlanetP p = getSelected(); PlanetP p = getSelected();
if (p!=NULL && getFlagIsolatedTrails()) if (p!=Q_NULLPTR && getFlagIsolatedTrails())
{ {
allTrails->addObject((QSharedPointer<StelObject>)p, &trailCo lor); allTrails->addObject((QSharedPointer<StelObject>)p, &trailCo lor);
} }
else else
{ {
foreach (const PlanetP& p, getSun()->satellites) foreach (const PlanetP& p, getSun()->satellites)
{ {
allTrails->addObject((QSharedPointer<StelObject>)p, &trailColor); allTrails->addObject((QSharedPointer<StelObject>)p, &trailColor);
} }
} }
skipping to change at line 278 skipping to change at line 292
p->setNativeName(""); p->setNativeName("");
} }
updateI18n(); updateI18n();
return; return;
} }
// Open file // Open file
QFile planetNamesFile(namesFile); QFile planetNamesFile(namesFile);
if (!planetNamesFile.open(QIODevice::ReadOnly | QIODevice::Text)) if (!planetNamesFile.open(QIODevice::ReadOnly | QIODevice::Text))
{ {
qDebug() << "Cannot open file" << QDir::toNativeSeparators(n amesFile); qDebug() << " Cannot open file" << QDir::toNativeSeparators( namesFile);
return; return;
} }
// Now parse the file // Now parse the file
// lines to ignore which start with a # or are empty // lines to ignore which start with a # or are empty
QRegExp commentRx("^(\\s*#.*|\\s*)$"); QRegExp commentRx("^(\\s*#.*|\\s*)$");
// lines which look like records - we use the RE to extract the fiel ds // lines which look like records - we use the RE to extract the fiel ds
// which will be available in recRx.capturedTexts() // which will be available in recRx.capturedTexts()
QRegExp recRx("^\\s*(\\w+)\\s+\"(.+)\"\\s+_[(]\"(.+)\"[)]\\n"); QRegExp recRx("^\\s*(\\w+)\\s+\"(.+)\"\\s+_[(]\"(.+)\"[)]\\n");
skipping to change at line 331 skipping to change at line 345
foreach (const PlanetP& p, systemPlanets) foreach (const PlanetP& p, systemPlanets)
{ {
if (p->getPlanetType()==Planet::isPlanet || p->getPlanetType ()==Planet::isMoon || p->getPlanetType()==Planet::isStar) if (p->getPlanetType()==Planet::isPlanet || p->getPlanetType ()==Planet::isMoon || p->getPlanetType()==Planet::isStar)
p->setNativeName(planetNativeNamesMap[p->getEnglishN ame()]); p->setNativeName(planetNativeNamesMap[p->getEnglishN ame()]);
} }
updateI18n(); updateI18n();
} }
void SolarSystem::reloadShaders()
{
Planet::deinitShader();
Planet::initShader();
}
void SolarSystem::drawPointer(const StelCore* core) void SolarSystem::drawPointer(const StelCore* core)
{ {
const StelProjectorP prj = core->getProjection(StelCore::FrameJ2000) ; const StelProjectorP prj = core->getProjection(StelCore::FrameJ2000) ;
const QList<StelObjectP> newSelected = GETSTELMODULE(StelObjectMgr)- >getSelectedObject("Planet"); const QList<StelObjectP> newSelected = GETSTELMODULE(StelObjectMgr)- >getSelectedObject("Planet");
if (!newSelected.empty()) if (!newSelected.empty())
{ {
const StelObjectP obj = newSelected[0]; const StelObjectP obj = newSelected[0];
Vec3d pos=obj->getJ2000EquatorialPos(core); Vec3d pos=obj->getJ2000EquatorialPos(core);
skipping to change at line 381 skipping to change at line 401
void ellipticalOrbitPosFunc(double jd,double xyz[3], void* userDataPtr) void ellipticalOrbitPosFunc(double jd,double xyz[3], void* userDataPtr)
{ {
static_cast<EllipticalOrbit*>(userDataPtr)->positionAtTimevInVSOP87C oordinates(jd, xyz); static_cast<EllipticalOrbit*>(userDataPtr)->positionAtTimevInVSOP87C oordinates(jd, xyz);
} }
void cometOrbitPosFunc(double jd,double xyz[3], void* userDataPtr) void cometOrbitPosFunc(double jd,double xyz[3], void* userDataPtr)
{ {
static_cast<CometOrbit*>(userDataPtr)->positionAtTimevInVSOP87Coordi nates(jd, xyz); static_cast<CometOrbit*>(userDataPtr)->positionAtTimevInVSOP87Coordi nates(jd, xyz);
} }
// Init and load the solar system data // Init and load the solar system data (2 files)
void SolarSystem::loadPlanets() void SolarSystem::loadPlanets()
{ {
qDebug() << "Loading Solar System data ..."; minorBodies.clear();
QStringList solarSystemFiles = StelFileMgr::findFileInAllPaths("data qDebug() << "Loading Solar System data (1: planets and moons) ...";
/ssystem.ini"); QString solarSystemFile = StelFileMgr::findFile("data/ssystem_major.
ini");
if (solarSystemFile.isEmpty())
{
qWarning() << "ERROR while loading ssystem_major.ini (unable
to find data/ssystem_major.ini): " << endl;
return;
}
if (!loadPlanets(solarSystemFile))
{
qWarning() << "ERROR while loading ssystem_major.ini: " << e
ndl;
return;
}
qDebug() << "Loading Solar System data (2: minor bodies)...";
QStringList solarSystemFiles = StelFileMgr::findFileInAllPaths("data
/ssystem_minor.ini");
if (solarSystemFiles.isEmpty()) if (solarSystemFiles.isEmpty())
{ {
qWarning() << "ERROR while loading ssysyem.ini (unable to fi nd data/ssystem.ini): " << endl; qWarning() << "ERROR while loading ssystem_minor.ini (unable to find data/ssystem_minor.ini): " << endl;
return; return;
} }
foreach (const QString& solarSystemFile, solarSystemFiles) foreach (const QString& solarSystemFile, solarSystemFiles)
{ {
if (loadPlanets(solarSystemFile)) if (loadPlanets(solarSystemFile))
{
qDebug() << "File ssystem_minor.ini is loaded succes
sfully...";
break; break;
}
else else
{ {
sun.clear(); // sun.clear();
moon.clear(); // moon.clear();
earth.clear(); // earth.clear();
//qCritical() << "We should not be here!";
qDebug() << "Removing minor bodies";
foreach (PlanetP p, systemPlanets) foreach (PlanetP p, systemPlanets)
{ {
p->satellites.clear(); // We can only delete minor objects now!
p.clear(); if (p->pType >= Planet::isAsteroid)
{
p->satellites.clear();
p.clear();
}
} }
systemPlanets.clear(); systemPlanets.clear();
//Memory leak? What's the proper way of cleaning sha red pointers? //Memory leak? What's the proper way of cleaning sha red pointers?
// TODO: 0.16pre what about the orbits list?
//If the file is in the user data directory, rename it: //If the file is in the user data directory, rename it:
if (solarSystemFile.contains(StelFileMgr::getUserDir ())) if (solarSystemFile.contains(StelFileMgr::getUserDir ()))
{ {
QString newName = QString("%1/data/ssystem-% 2.ini").arg(StelFileMgr::getUserDir()).arg(QDateTime::currentDateTime().toS tring("yyyyMMddThhmmss")); QString newName = QString("%1/data/ssystem-% 2.ini").arg(StelFileMgr::getUserDir()).arg(QDateTime::currentDateTime().toS tring("yyyyMMddThhmmss"));
if (QFile::rename(solarSystemFile, newName)) if (QFile::rename(solarSystemFile, newName))
qWarning() << "Invalid Solar System file" << QDir::toNativeSeparators(solarSystemFile) << "has been renamed to" << QDir::toNativeSeparators(newName); qWarning() << "Invalid Solar System file" << QDir::toNativeSeparators(solarSystemFile) << "has been renamed to" << QDir::toNativeSeparators(newName);
else else
{ {
qWarning() << "Invalid Solar System file" << QDir::toNativeSeparators(solarSystemFile) << "cannot be removed!"; qWarning() << "Invalid Solar System file" << QDir::toNativeSeparators(solarSystemFile) << "cannot be removed!";
qWarning() << "Please either delete it, rename it or move it elsewhere."; qWarning() << "Please either delete it, rename it or move it elsewhere.";
skipping to change at line 434 skipping to change at line 480
shadowPlanetCount = 0; shadowPlanetCount = 0;
foreach (const PlanetP& planet, systemPlanets) foreach (const PlanetP& planet, systemPlanets)
if(planet->parent != sun || !planet->satellites.isEmpty()) if(planet->parent != sun || !planet->satellites.isEmpty())
shadowPlanetCount++; shadowPlanetCount++;
} }
bool SolarSystem::loadPlanets(const QString& filePath) bool SolarSystem::loadPlanets(const QString& filePath)
{ {
qDebug() << "Loading from :" << filePath;
int readOk = 0;
QSettings pd(filePath, StelIniFormat); QSettings pd(filePath, StelIniFormat);
if (pd.status() != QSettings::NoError) if (pd.status() != QSettings::NoError)
{ {
qWarning() << "ERROR while parsing" << QDir::toNativeSeparat ors(filePath); qWarning() << "ERROR while parsing" << QDir::toNativeSeparat ors(filePath);
return false; return false;
} }
// QSettings does not allow us to say that the sections of the file // QSettings does not allow us to say that the sections of the file
// will be listed in the same order as in the file like the old // will be listed in the same order as in the file like the old
// InitParser used to so we can no longer assume that. // InitParser used to so we can no longer assume that.
// //
// This means we must first decide what order to read the sections // This means we must first decide what order to read the sections
// of the file in (each section contains one planet) to avoid settin g // of the file in (each section contains one planet/moon/asteroid/co met/...) to avoid setting
// the parent Planet* to one which has not yet been created. // the parent Planet* to one which has not yet been created.
// //
// Stage 1: Make a map of body names back to the section names // Stage 1: Make a map of body names back to the section names
// which they come from. Also make a map of body name to parent body // which they come from. Also make a map of body name to parent body
// name. These two maps can be made in a single pass through the // name. These two maps can be made in a single pass through the
// sections of the file. // sections of the file.
// //
// Stage 2: Make an ordered list of section names such that each // Stage 2: Make an ordered list of section names such that each
// item is only ever dependent on items which appear earlier in the // item is only ever dependent on items which appear earlier in the
// list. // list.
// 2a: Make a QMultiMap relating the number of levels of dependency // 2a: Make a QMultiMap relating the number of levels of dependency
// to the body name, i.e. // to the body name, i.e.
// 0 -> Sun // 0 -> Sun
// 1 -> Mercury // 1 -> Mercury
// 1 -> Venus // 1 -> Venus
// 1 -> Earth // 1 -> Earth
// 2 -> Moon // 2 -> Moon
// etc. // etc.
// 2b: Populate an ordered list of section names by iterating over // 2b: Populate an ordered list of section names by iterating over
// the QMultiMap. This type of contains is always sorted on the // the QMultiMap. This type of container is always sorted on th
// key, so it's easy. e
// i.e. [sol, earth, moon] is fine, but not [sol, moon, earth] // key in ascending order, so it's easy.
// i.e. [sun, earth, moon] is fine, but not [sun, moon, earth]
// //
// Stage 3: iterate over the ordered sections decided in stage 2, // Stage 3: iterate over the ordered sections decided in stage 2,
// creating the planet objects from the QSettings data. // creating the planet objects from the QSettings data.
// Stage 1 (as described above). // Stage 1 (as described above).
QMap<QString, QString> secNameMap; QMap<QString, QString> secNameMap;
QMap<QString, QString> parentMap; QMap<QString, QString> parentMap;
QStringList sections = pd.childGroups(); QStringList sections = pd.childGroups();
// qDebug() << "Stage 1: load ini file with" << sections.size() << " entries: "<< sections;
for (int i=0; i<sections.size(); ++i) for (int i=0; i<sections.size(); ++i)
{ {
const QString secname = sections.at(i); const QString secname = sections.at(i);
const QString englishName = pd.value(secname+"/name").toStri ng(); const QString englishName = pd.value(secname+"/name").toStri ng();
const QString strParent = pd.value(secname+"/parent").toStri ng(); const QString strParent = pd.value(secname+"/parent", "Sun") .toString();
secNameMap[englishName] = secname; secNameMap[englishName] = secname;
if (strParent!="none" && !strParent.isEmpty() && !englishNam e.isEmpty()) if (strParent!="none" && !strParent.isEmpty() && !englishNam e.isEmpty())
{
parentMap[englishName] = strParent; parentMap[englishName] = strParent;
// qDebug() << "parentmap[" << englishName << "] = "
<< strParent;
}
} }
// Stage 2a (as described above). // Stage 2a (as described above).
QMultiMap<int, QString> depLevelMap; QMultiMap<int, QString> depLevelMap;
for (int i=0; i<sections.size(); ++i) for (int i=0; i<sections.size(); ++i)
{ {
const QString englishName = pd.value(sections.at(i)+"/name") .toString(); const QString englishName = pd.value(sections.at(i)+"/name") .toString();
// follow dependencies, incrementing level when we have one // follow dependencies, incrementing level when we have one
// till we run out. // till we run out.
QString p=englishName; QString p=englishName;
int level = 0; int level = 0;
while(parentMap.contains(p) && parentMap[p]!="none") while(parentMap.contains(p) && parentMap[p]!="none")
{ {
level++; level++;
p = parentMap[p]; p = parentMap[p];
} }
depLevelMap.insert(level, secNameMap[englishName]); depLevelMap.insert(level, secNameMap[englishName]);
// qDebug() << "2a: Level" << level << "secNameMap[" << engl ishName << "]="<< secNameMap[englishName];
} }
// Stage 2b (as described above). // Stage 2b (as described above).
// qDebug() << "Stage 2b:";
QStringList orderedSections; QStringList orderedSections;
QMapIterator<int, QString> levelMapIt(depLevelMap); QMapIterator<int, QString> levelMapIt(depLevelMap);
while(levelMapIt.hasNext()) while(levelMapIt.hasNext())
{ {
levelMapIt.next(); levelMapIt.next();
orderedSections << levelMapIt.value(); orderedSections << levelMapIt.value();
} }
// qDebug() << orderedSections;
// Stage 3 (as described above). // Stage 3 (as described above).
int readOk=0; //int readOk=0;
int totalPlanets=0; //int totalPlanets=0;
// qDebug() << "Adding " << orderedSections.size() << "objects...";
for (int i = 0;i<orderedSections.size();++i) for (int i = 0;i<orderedSections.size();++i)
{ {
totalPlanets++; // qDebug() << "Processing entry" << orderedSections.at(i);
//totalPlanets++;
const QString secname = orderedSections.at(i); const QString secname = orderedSections.at(i);
const QString englishName = pd.value(secname+"/name").toStri ng().simplified(); const QString englishName = pd.value(secname+"/name").toStri ng().simplified();
const QString strParent = pd.value(secname+"/parent").toStri ng(); const QString strParent = pd.value(secname+"/parent", "Sun") .toString(); // Obvious default, keep file entries simple.
PlanetP parent; PlanetP parent;
if (strParent!="none") if (strParent!="none")
{ {
// Look in the other planets the one named with strP arent // Look in the other planets the one named with strP arent
foreach (const PlanetP& p, systemPlanets) foreach (const PlanetP& p, systemPlanets)
{ {
if (p->getEnglishName()==strParent) if (p->getEnglishName()==strParent)
{ {
parent = p; parent = p;
break; break;
skipping to change at line 545 skipping to change at line 604
} }
if (parent.isNull()) if (parent.isNull())
{ {
qWarning() << "ERROR : can't find parent sol ar system body for " << englishName; qWarning() << "ERROR : can't find parent sol ar system body for " << englishName;
//abort(); //abort();
continue; continue;
} }
} }
const QString funcName = pd.value(secname+"/coord_func").toS tring(); const QString funcName = pd.value(secname+"/coord_func").toS tring();
posFuncType posfunc=NULL; // qDebug() << "englishName:" << englishName << ", parent:"
void* userDataPtr=NULL; << strParent << ", coord_func:" << funcName;
OsculatingFunctType *osculatingFunc = 0; posFuncType posfunc=Q_NULLPTR;
void* orbitPtr=Q_NULLPTR;
OsculatingFunctType *osculatingFunc = Q_NULLPTR;
bool closeOrbit = pd.value(secname+"/closeOrbit", true).toBo ol(); bool closeOrbit = pd.value(secname+"/closeOrbit", true).toBo ol();
if (funcName=="ell_orbit") if (funcName=="ell_orbit")
{ {
// GZ TODO: It seems ell_orbit is only used for plan et moons. Just assert eccentricity<1 and remove a few extra calculations?
// Read the orbital elements // Read the orbital elements
const double epoch = pd.value(secname+"/orbit_Epoch" ,J2000).toDouble(); const double epoch = pd.value(secname+"/orbit_Epoch" ,J2000).toDouble();
const double eccentricity = pd.value(secname+"/orbit _Eccentricity").toDouble(); const double eccentricity = pd.value(secname+"/orbit _Eccentricity").toDouble();
if (eccentricity >= 1.0) closeOrbit = false; if (eccentricity >= 1.0) closeOrbit = false;
double pericenterDistance = pd.value(secname+"/orbit _PericenterDistance",-1e100).toDouble(); double pericenterDistance = pd.value(secname+"/orbit _PericenterDistance",-1e100).toDouble();
double semi_major_axis; double semi_major_axis;
if (pericenterDistance <= 0.0) { if (pericenterDistance <= 0.0) {
semi_major_axis = pd.value(secname+"/orbit_S emiMajorAxis",-1e100).toDouble(); semi_major_axis = pd.value(secname+"/orbit_S emiMajorAxis",-1e100).toDouble();
if (semi_major_axis <= -1e100) { if (semi_major_axis <= -1e100) {
qDebug() << "ERROR: " << englishName qDebug() << "ERROR: " << englishName
<< ": you must provide orbit _PericenterDistance or orbit_SemiMajorAxis"; << ": you must provide orbi t_PericenterDistance or orbit_SemiMajorAxis";
//abort(); //abort();
continue; continue;
} else { } else {
semi_major_axis /= AU; semi_major_axis /= AU;
Q_ASSERT(eccentricity != 1.0); // pa rabolic orbits have no semi_major_axis Q_ASSERT(eccentricity != 1.0); // pa rabolic orbits have no semi_major_axis
pericenterDistance = semi_major_axis * (1.0-eccentricity); pericenterDistance = semi_major_axis * (1.0-eccentricity);
} }
} else { } else {
pericenterDistance /= AU; pericenterDistance /= AU;
semi_major_axis = (eccentricity == 1.0) semi_major_axis = (eccentricity == 1.0)
skipping to change at line 619 skipping to change at line 680
} else { } else {
mean_anomaly *= (M_PI/180.0); mean_anomaly *= (M_PI/180.0);
mean_longitude = mean_anomaly + long_of_peri center; mean_longitude = mean_anomaly + long_of_peri center;
} }
// when the parent is the sun use ecliptic rather th an sun equator: // when the parent is the sun use ecliptic rather th an sun equator:
const double parentRotObliquity = parent->getParent( ) const double parentRotObliquity = parent->getParent( )
? parent->getRotObliquity(2451545.0) ? parent->getRotObliquity(2451545.0)
: 0.0; : 0.0;
const double parent_rot_asc_node = parent->getParent () const double parent_rot_asc_node = parent->getParent ()
? parent->getRotAscendingnode() ? parent->getRotAscendingNode()
: 0.0; : 0.0;
double parent_rot_j2000_longitude = 0.0; double parent_rot_j2000_longitude = 0.0;
if (parent->getParent()) { if (parent->getParent()) {
const double c_obl = cos(parentRotObliquity) ; const double c_obl = cos(parentRotObliquity) ;
const double s_obl = sin(parentRotObliquity) ; const double s_obl = sin(parentRotObliquity) ;
const double c_nod = cos(parent_rot_asc_node ); const double c_nod = cos(parent_rot_asc_node );
const double s_nod = sin(parent_rot_asc_node ); const double s_nod = sin(parent_rot_asc_node );
const Vec3d OrbitAxis0( c_nod, s_nod, 0.0); const Vec3d OrbitAxis0( c_nod, s_nod, 0.0);
const Vec3d OrbitAxis1(-s_nod*c_obl, c_nod*c _obl,s_obl); const Vec3d OrbitAxis1(-s_nod*c_obl, c_nod*c _obl,s_obl);
const Vec3d OrbitPole( s_nod*s_obl,-c_nod*s _obl,c_obl); const Vec3d OrbitPole( s_nod*s_obl,-c_nod*s _obl,c_obl);
skipping to change at line 650 skipping to change at line 711
ascending _node, ascending _node,
arg_of_pe ricenter, arg_of_pe ricenter,
mean_anom aly, mean_anom aly,
period, period,
epoch, epoch,
parentRot Obliquity, parentRot Obliquity,
parent_ro t_asc_node, parent_ro t_asc_node,
parent_ro t_j2000_longitude); parent_ro t_j2000_longitude);
orbits.push_back(orb); orbits.push_back(orb);
userDataPtr = orb; orbitPtr = orb;
posfunc = &ellipticalOrbitPosFunc; posfunc = &ellipticalOrbitPosFunc;
} }
else if (funcName=="comet_orbit") else if (funcName=="comet_orbit")
{ {
// Read the orbital elements // Read the orbital elements
// orbit_PericenterDistance,orbit_SemiMajorAxis: giv en in AU // orbit_PericenterDistance,orbit_SemiMajorAxis: giv en in AU
// orbit_MeanMotion: given in degrees/day // orbit_MeanMotion: given in degrees/day
// orbit_Period: given in days // orbit_Period: given in days
// orbit_TimeAtPericenter,orbit_Epoch: JD // orbit_TimeAtPericenter,orbit_Epoch: JD
// orbit_MeanAnomaly,orbit_Inclination,orbit_ArgOfPe ricenter,orbit_AscendingNode: given in degrees // orbit_MeanAnomaly,orbit_Inclination,orbit_ArgOfPe ricenter,orbit_AscendingNode: given in degrees
const double eccentricity = pd.value(secname+"/orbit _Eccentricity",0.0).toDouble(); const double eccentricity = pd.value(secname+"/orbit _Eccentricity",0.0).toDouble();
if (eccentricity >= 1.0) closeOrbit = false; if (eccentricity >= 1.0) closeOrbit = false;
double pericenterDistance = pd.value(secname+"/orbit _PericenterDistance",-1e100).toDouble(); double pericenterDistance = pd.value(secname+"/orbit _PericenterDistance",-1e100).toDouble();
double semi_major_axis; double semi_major_axis;
if (pericenterDistance <= 0.0) { if (pericenterDistance <= 0.0) {
semi_major_axis = pd.value(secname+"/orbit_S emiMajorAxis",-1e100).toDouble(); semi_major_axis = pd.value(secname+"/orbit_S emiMajorAxis",-1e100).toDouble();
if (semi_major_axis <= -1e100) { if (semi_major_axis <= -1e100) {
qWarning() << "ERROR: " << englishNa me qWarning() << "ERROR: " << englishNa me
<< ": you must provide orbit _PericenterDistance or orbit_SemiMajorAxis"; << ": you must provide or bit_PericenterDistance or orbit_SemiMajorAxis";
//abort(); //abort();
continue; continue;
} else { } else {
Q_ASSERT(eccentricity != 1.0); // pa rabolic orbits have no semi_major_axis Q_ASSERT(eccentricity != 1.0); // pa rabolic orbits have no semi_major_axis
pericenterDistance = semi_major_axis * (1.0-eccentricity); pericenterDistance = semi_major_axis * (1.0-eccentricity);
} }
} else { } else {
semi_major_axis = (eccentricity == 1.0) semi_major_axis = (eccentricity == 1.0)
? 0.0 // par abolic orbits have no semi_major_axis ? 0.0 // par abolic orbits have no semi_major_axis
: pericenter Distance / (1.0-eccentricity); : pericenter Distance / (1.0-eccentricity);
} }
double meanMotion = pd.value(secname+"/orbit_MeanMot ion",-1e100).toDouble(); double meanMotion = pd.value(secname+"/orbit_MeanMot ion",-1e100).toDouble();
if (meanMotion <= -1e100) { if (meanMotion <= -1e100) {
const double period = pd.value(secname+"/orb it_Period",-1e100).toDouble(); const double period = pd.value(secname+"/orb it_Period",-1e100).toDouble();
if (period <= -1e100) { if (period <= -1e100) {
if (parent->getParent()) { if (parent->getParent()) {
qWarning() << "ERROR: " << e nglishName qWarning() << "ERROR: " << e nglishName
<< ": when the paren << ": when the pa
t body is not the sun, you must provide " rent body is not the sun, you must provide "
<< "either orbit_Mea << "either orbit_
nMotion or orbit_Period"; MeanMotion or orbit_Period";
} else { } else {
// in case of parent=sun: us e Gaussian gravitational constant // in case of parent=sun: us e Gaussian gravitational constant
// for calculating meanMotio n: // for calculating meanMotio n:
//meanMotion = (eccentricity >= 0.9999 && eccentricity <= 1.0) //meanMotion = (eccentricity >= 0.9999 && eccentricity <= 1.0)
// ? 0. 01720209895 * (1.5/pericenterDistance) * sqrt(0.5/pericenterDistance) // ? 0. 01720209895 * (1.5/pericenterDistance) * sqrt(0.5/pericenterDistance)
// : (s emi_major_axis > 0.0) // : (s emi_major_axis > 0.0)
// ? 0. 01720209895 / (semi_major_axis*sqrt(semi_major_axis)) // ? 0. 01720209895 / (semi_major_axis*sqrt(semi_major_axis))
// : 0. 01720209895 / (-semi_major_axis*sqrt(-semi_major_axis)); // : 0. 01720209895 / (-semi_major_axis*sqrt(-semi_major_axis));
meanMotion = (eccentricity = = 1.0) meanMotion = (eccentricity = = 1.0)
? 0. 01720209895 * (1.5/pericenterDistance) * std::sqrt(0.5/pericenterDistance) // GZ: This is Heafner's W / dt ? 0. 01720209895 * (1.5/pericenterDistance) * std::sqrt(0.5/pericenterDistance) // GZ: This is Heafner's W / dt
skipping to change at line 713 skipping to change at line 774
} }
} else { } else {
meanMotion *= (M_PI/180.0); meanMotion *= (M_PI/180.0);
} }
double time_at_pericenter = pd.value(secname+"/orbit _TimeAtPericenter",-1e100).toDouble(); double time_at_pericenter = pd.value(secname+"/orbit _TimeAtPericenter",-1e100).toDouble();
if (time_at_pericenter <= -1e100) { if (time_at_pericenter <= -1e100) {
const double epoch = pd.value(secname+"/orbi t_Epoch",-1e100).toDouble(); const double epoch = pd.value(secname+"/orbi t_Epoch",-1e100).toDouble();
double mean_anomaly = pd.value(secname+"/orb it_MeanAnomaly",-1e100).toDouble(); double mean_anomaly = pd.value(secname+"/orb it_MeanAnomaly",-1e100).toDouble();
if (epoch <= -1e100 || mean_anomaly <= -1e10 0) { if (epoch <= -1e100 || mean_anomaly <= -1e10 0) {
qWarning() << "ERROR: " << englishNa me qWarning() << "ERROR: " << englishNa me
<< ": when you do not provid << ": when you do not pro
e orbit_TimeAtPericenter, you must provide both " vide orbit_TimeAtPericenter, you must provide both "
<< "orbit_Epoch and orbit_Me << "orbit_Epoch and orbit
anAnomaly"; _MeanAnomaly";
//abort(); //abort();
continue; continue;
} else { } else {
mean_anomaly *= (M_PI/180.0); mean_anomaly *= (M_PI/180.0);
time_at_pericenter = epoch - mean_an omaly / meanMotion; time_at_pericenter = epoch - mean_an omaly / meanMotion;
} }
} }
const double orbitGoodDays=pd.value(secname+"/orbit_ good", 1000).toDouble(); const double orbitGoodDays=pd.value(secname+"/orbit_ good", 1000).toDouble();
const double inclination = pd.value(secname+"/orbit_ Inclination").toDouble()*(M_PI/180.0); const double inclination = pd.value(secname+"/orbit_ Inclination").toDouble()*(M_PI/180.0);
const double arg_of_pericenter = pd.value(secname+"/ orbit_ArgOfPericenter").toDouble()*(M_PI/180.0); const double arg_of_pericenter = pd.value(secname+"/ orbit_ArgOfPericenter").toDouble()*(M_PI/180.0);
const double ascending_node = pd.value(secname+"/orb it_AscendingNode").toDouble()*(M_PI/180.0); const double ascending_node = pd.value(secname+"/orb it_AscendingNode").toDouble()*(M_PI/180.0);
const double parentRotObliquity = parent->getParent( ) ? parent->getRotObliquity(2451545.0) : 0.0; const double parentRotObliquity = parent->getParent( ) ? parent->getRotObliquity(2451545.0) : 0.0;
const double parent_rot_asc_node = parent->getParent () ? parent->getRotAscendingnode() : 0.0; const double parent_rot_asc_node = parent->getParent () ? parent->getRotAscendingNode() : 0.0;
double parent_rot_j2000_longitude = 0.0; double parent_rot_j2000_longitude = 0.0;
if (parent->getParent()) { if (parent->getParent()) {
const double c_obl = cos(parentRotObliquity); const double c_obl = cos(parentRotObliquity);
const double s_obl = sin(parentRotObliquity); const double s_obl = sin(parentRotObliquity);
const double c_nod = cos(parent_rot_asc_node); const double c_nod = cos(parent_rot_asc_node);
const double s_nod = sin(parent_rot_asc_node); const double s_nod = sin(parent_rot_asc_node);
const Vec3d OrbitAxi s0( c_nod, s_nod, 0.0); const Vec3d OrbitAxi s0( c_nod, s_nod, 0.0);
const Vec3d OrbitAxi s1(-s_nod*c_obl, c_nod*c_obl,s_obl); const Vec3d OrbitAxi s1(-s_nod*c_obl, c_nod*c_obl,s_obl);
const Vec3d OrbitPol e( s_nod*s_obl,-c_nod*s_obl,c_obl); const Vec3d OrbitPol e( s_nod*s_obl,-c_nod*s_obl,c_obl);
const Vec3d J2000Pol e(StelCore::matJ2000ToVsop87.multiplyWithoutTranslation(Vec3d(0,0,1))); const Vec3d J2000Pol e(StelCore::matJ2000ToVsop87.multiplyWithoutTranslation(Vec3d(0,0,1)));
skipping to change at line 755 skipping to change at line 816
inclination, inclination,
ascending_node, ascending_node,
arg_of_pericenter, arg_of_pericenter,
time_at_pericenter, time_at_pericenter,
orbitGoodDays, orbitGoodDays,
meanMotion, meanMotion,
parentRotObliquity, parentRotObliquity,
parent_rot_asc_node , parent_rot_asc_node ,
parent_rot_j2000_lo ngitude); parent_rot_j2000_lo ngitude);
orbits.push_back(orb); orbits.push_back(orb);
userDataPtr = orb; orbitPtr = orb;
posfunc = &cometOrbitPosFunc; posfunc = &cometOrbitPosFunc;
} }
if (funcName=="sun_special") else if (funcName=="sun_special")
posfunc = &get_sun_helio_coordsv; posfunc = &get_sun_helio_coordsv;
if (funcName=="mercury_special") { else if (funcName=="mercury_special") {
posfunc = &get_mercury_helio_coordsv; posfunc = &get_mercury_helio_coordsv;
osculatingFunc = &get_mercury_helio_osculating_coord s; osculatingFunc = &get_mercury_helio_osculating_coord s;
} }
if (funcName=="venus_special") { else if (funcName=="venus_special") {
posfunc = &get_venus_helio_coordsv; posfunc = &get_venus_helio_coordsv;
osculatingFunc = &get_venus_helio_osculating_coords; osculatingFunc = &get_venus_helio_osculating_coords;
} }
if (funcName=="earth_special") { else if (funcName=="earth_special") {
posfunc = &get_earth_helio_coordsv; posfunc = &get_earth_helio_coordsv;
osculatingFunc = &get_earth_helio_osculating_coords; osculatingFunc = &get_earth_helio_osculating_coords;
} }
if (funcName=="lunar_special") else if (funcName=="lunar_special")
posfunc = &get_lunar_parent_coordsv; posfunc = &get_lunar_parent_coordsv;
if (funcName=="mars_special") { else if (funcName=="mars_special") {
posfunc = &get_mars_helio_coordsv; posfunc = &get_mars_helio_coordsv;
osculatingFunc = &get_mars_helio_osculating_coords; osculatingFunc = &get_mars_helio_osculating_coords;
} }
if (funcName=="phobos_special") else if (funcName=="phobos_special")
posfunc = posFuncType(get_phobos_parent_coordsv); posfunc = &get_phobos_parent_coordsv;
if (funcName=="deimos_special") else if (funcName=="deimos_special")
posfunc = &get_deimos_parent_coordsv; posfunc = &get_deimos_parent_coordsv;
if (funcName=="jupiter_special") { else if (funcName=="jupiter_special") {
posfunc = &get_jupiter_helio_coordsv; posfunc = &get_jupiter_helio_coordsv;
osculatingFunc = &get_jupiter_helio_osculating_coord s; osculatingFunc = &get_jupiter_helio_osculating_coord s;
} }
if (funcName=="europa_special") else if (funcName=="europa_special")
posfunc = &get_europa_parent_coordsv; posfunc = &get_europa_parent_coordsv;
if (funcName=="calisto_special") else if (funcName=="calisto_special")
posfunc = &get_callisto_parent_coordsv; posfunc = &get_callisto_parent_coordsv;
if (funcName=="io_special") else if (funcName=="io_special")
posfunc = &get_io_parent_coordsv; posfunc = &get_io_parent_coordsv;
if (funcName=="ganymede_special") else if (funcName=="ganymede_special")
posfunc = &get_ganymede_parent_coordsv; posfunc = &get_ganymede_parent_coordsv;
if (funcName=="saturn_special") { else if (funcName=="saturn_special") {
posfunc = &get_saturn_helio_coordsv; posfunc = &get_saturn_helio_coordsv;
osculatingFunc = &get_saturn_helio_osculating_coords ; osculatingFunc = &get_saturn_helio_osculating_coords ;
} }
if (funcName=="mimas_special") else if (funcName=="mimas_special")
posfunc = &get_mimas_parent_coordsv; posfunc = &get_mimas_parent_coordsv;
if (funcName=="enceladus_special") else if (funcName=="enceladus_special")
posfunc = &get_enceladus_parent_coordsv; posfunc = &get_enceladus_parent_coordsv;
if (funcName=="tethys_special") else if (funcName=="tethys_special")
posfunc = &get_tethys_parent_coordsv; posfunc = &get_tethys_parent_coordsv;
if (funcName=="dione_special") else if (funcName=="dione_special")
posfunc = &get_dione_parent_coordsv; posfunc = &get_dione_parent_coordsv;
if (funcName=="rhea_special") else if (funcName=="rhea_special")
posfunc = &get_rhea_parent_coordsv; posfunc = &get_rhea_parent_coordsv;
if (funcName=="titan_special") else if (funcName=="titan_special")
posfunc = &get_titan_parent_coordsv; posfunc = &get_titan_parent_coordsv;
if (funcName=="iapetus_special") else if (funcName=="iapetus_special")
posfunc = &get_iapetus_parent_coordsv; posfunc = &get_iapetus_parent_coordsv;
if (funcName=="hyperion_special") else if (funcName=="hyperion_special")
posfunc = &get_hyperion_parent_coordsv; posfunc = &get_hyperion_parent_coordsv;
if (funcName=="uranus_special") { else if (funcName=="uranus_special") {
posfunc = &get_uranus_helio_coordsv; posfunc = &get_uranus_helio_coordsv;
osculatingFunc = &get_uranus_helio_osculating_coords ; osculatingFunc = &get_uranus_helio_osculating_coords ;
} }
if (funcName=="miranda_special") else if (funcName=="miranda_special")
posfunc = &get_miranda_parent_coordsv; posfunc = &get_miranda_parent_coordsv;
if (funcName=="ariel_special") else if (funcName=="ariel_special")
posfunc = &get_ariel_parent_coordsv; posfunc = &get_ariel_parent_coordsv;
if (funcName=="umbriel_special") else if (funcName=="umbriel_special")
posfunc = &get_umbriel_parent_coordsv; posfunc = &get_umbriel_parent_coordsv;
if (funcName=="titania_special") else if (funcName=="titania_special")
posfunc = &get_titania_parent_coordsv; posfunc = &get_titania_parent_coordsv;
if (funcName=="oberon_special") else if (funcName=="oberon_special")
posfunc = &get_oberon_parent_coordsv; posfunc = &get_oberon_parent_coordsv;
if (funcName=="neptune_special") { else if (funcName=="neptune_special") {
posfunc = posFuncType(get_neptune_helio_coordsv); posfunc = &get_neptune_helio_coordsv;
osculatingFunc = &get_neptune_helio_osculating_coord s; osculatingFunc = &get_neptune_helio_osculating_coord s;
} }
if (funcName=="pluto_special") else if (funcName=="pluto_special")
posfunc = &get_pluto_helio_coordsv; posfunc = &get_pluto_helio_coordsv;
if (posfunc==NULL) if (posfunc==Q_NULLPTR)
{ {
qCritical() << "ERROR : can't find posfunc " << func Name << " for " << englishName; qCritical() << "ERROR in section " << secname << ": can't find posfunc " << funcName << " for " << englishName;
exit(-1); exit(-1);
} }
// Create the Solar System body and add it to the list // Create the Solar System body and add it to the list
QString type = pd.value(secname+"/type").toString(); QString type = pd.value(secname+"/type").toString();
//TODO: Refactor the subclass selection to reduce duplicate
code mess here,
// by at least using this base class pointer and using setXX
X functions instead of mega-constructors
// that have to pass most of it on to the Planet class
PlanetP p; PlanetP p;
// New class objects, named "plutino", "cubewano", "dwarf pl anet", "SDO", "OCO", has properties // New class objects, named "plutino", "cubewano", "dwarf pl anet", "SDO", "OCO", has properties
// similar to asteroids and we should calculate their positi ons like for asteroids. Dwarf planets // similar to asteroids and we should calculate their positi ons like for asteroids. Dwarf planets
// have one exception: Pluto - we should use special functio n for calculation of orbit of Pluto. // have one exception: Pluto - we should use special functio n for calculation of orbit of Pluto.
if ((type == "asteroid" || type == "dwarf planet" || type == "cubewano" || type == "plutino" || type == "scattered disc object" || type == "Oort cloud object") && !englishName.contains("Pluto")) if ((type == "asteroid" || type == "dwarf planet" || type == "cubewano" || type == "plutino" || type == "scattered disc object" || type == "Oort cloud object") && !englishName.contains("Pluto"))
{ {
minorBodies << englishName;
p = PlanetP(new MinorPlanet(englishName, p = PlanetP(new MinorPlanet(englishName,
pd.value(secname+"/light ing").toBool(),
pd.value(secname+"/radiu s").toDouble()/AU, pd.value(secname+"/radiu s").toDouble()/AU,
pd.value(secname+"/oblat eness", 0.0).toDouble(), pd.value(secname+"/oblat eness", 0.0).toDouble(),
StelUtils::strToVec3f(pd StelUtils::strToVec3f(pd
.value(secname+"/color").toString()), .value(secname+"/color", "1.0,1.0,1.0").toString()), // halo color
pd.value(secname+"/albed pd.value(secname+"/albed
o").toFloat(), o", 0.25f).toFloat(),
pd.value(secname+"/tex_m pd.value(secname+"/rough
ap").toString(), ness",0.9f).toFloat(),
pd.value(secname+"/tex_m
ap", "nomap.png").toString(),
pd.value(secname+"/model
").toString(),
posfunc, posfunc,
userDataPtr, orbitPtr,
osculatingFunc, osculatingFunc,
closeOrbit, closeOrbit,
pd.value(secname+"/hidde n", 0).toBool(), pd.value(secname+"/hidde n", false).toBool(),
type)); type));
QSharedPointer<MinorPlanet> mp = p.dynamicCast<Mino rPlanet>(); QSharedPointer<MinorPlanet> mp = p.dynamicCast<Mino rPlanet>();
//Number //Number
int minorPlanetNumber = pd.value(secname+"/minor_pla net_number", 0).toInt(); int minorPlanetNumber = pd.value(secname+"/minor_pla net_number", 0).toInt();
if (minorPlanetNumber) if (minorPlanetNumber)
{ {
mp->setMinorPlanetNumber(minorPlanetNumber); mp->setMinorPlanetNumber(minorPlanetNumber);
} }
skipping to change at line 929 skipping to change at line 997
{ {
mp->setAbsoluteMagnitudeAndSlope(mag nitude, 0.15); mp->setAbsoluteMagnitudeAndSlope(mag nitude, 0.15);
} }
} }
mp->setSemiMajorAxis(pd.value(secname+"/orbit_SemiMa jorAxis", 0).toDouble()); mp->setSemiMajorAxis(pd.value(secname+"/orbit_SemiMa jorAxis", 0).toDouble());
} }
else if (type == "comet") else if (type == "comet")
{ {
minorBodies << englishName;
p = PlanetP(new Comet(englishName, p = PlanetP(new Comet(englishName,
pd.value(secname+"/lighting").toBool( pd.value(secname+"/radius").to
), Double()/AU,
pd.value(secname+"/radius").toDouble( pd.value(secname+"/oblateness"
)/AU, , 0.0).toDouble(),
pd.value(secname+"/oblateness", 0.0). StelUtils::strToVec3f(pd.value
toDouble(), (secname+"/color", "1.0,1.0,1.0").toString()), // halo color
StelUtils::strToVec3f(pd.value(secnam pd.value(secname+"/albedo", 0.
e+"/color").toString()), 25f).toFloat(),
pd.value(secname+"/albedo").toFloat() pd.value(secname+"/roughness",
, 0.9f).toFloat(),
pd.value(secname+"/tex_map").toString pd.value(secname+"/outgas_inte
(), nsity",0.1f).toFloat(),
posfunc, pd.value(secname+"/outgas_fall
userDataPtr, off", 0.1f).toFloat(),
osculatingFunc, pd.value(secname+"/tex_map", "
closeOrbit, nomap.png").toString(),
pd.value(secname+"/hidden pd.value(secname+"/model").toS
", 0).toBool(), tring(),
type, posfunc,
pd.value(secname+"/dust_w orbitPtr,
idthfactor", 1.5f).toFloat(), osculatingFunc,
pd.value(secname+"/dust_l closeOrbit,
engthfactor", 0.4f).toFloat(), pd.value(secname+"/hidden", fa
pd.value(secname+"/dust_b lse).toBool(),
rightnessfactor", 1.5f).toFloat() type,
)); pd.value(secname+"/dust_widthf
actor", 1.5f).toFloat(),
pd.value(secname+"/dust_length
factor", 0.4f).toFloat(),
pd.value(secname+"/dust_bright
nessfactor", 1.5f).toFloat()
));
QSharedPointer<Comet> mp = p.dynamicCast<Comet>(); QSharedPointer<Comet> mp = p.dynamicCast<Comet>();
//g,k magnitude system //g,k magnitude system
double magnitude = pd.value(secname+"/absolute_magni tude", -99).toDouble(); double magnitude = pd.value(secname+"/absolute_magni tude", -99).toDouble();
double slope = pd.value(secname+"/slope_parameter", 4.0).toDouble(); double slope = pd.value(secname+"/slope_parameter", 4.0).toDouble();
if (magnitude > -99) if (magnitude > -99)
{ {
if (slope >= 0 && slope <= 20) if (slope >= 0 && slope <= 20)
{ {
skipping to change at line 976 skipping to change at line 1048
if (eccentricity<1 && pericenterDistance>0) if (eccentricity<1 && pericenterDistance>0)
{ {
mp->setSemiMajorAxis(pericenterDistance / (1 .0-eccentricity)); mp->setSemiMajorAxis(pericenterDistance / (1 .0-eccentricity));
} }
} }
else else
{ {
// Set possible default name of the normal map for a voiding yin-yang shaped moon // Set possible default name of the normal map for a voiding yin-yang shaped moon
// phase when normal map key not exists. Example: mo on_normals.png // phase when normal map key not exists. Example: mo on_normals.png
// Details: https://bugs.launchpad.net/stellarium/+b ug/1335609 // Details: https://bugs.launchpad.net/stellarium/+b ug/1335609
QString normalMapName = englishName.toLower().append QString normalMapName = "";
("_normals.png"); if (!pd.value(secname+"/hidden", false).toBool()) //
no normal maps for invisible objects!
normalMapName = englishName.toLower().append
("_normals.png");
p = PlanetP(new Planet(englishName, p = PlanetP(new Planet(englishName,
pd.value(secname+"/lighting") .toBool(),
pd.value(secname+"/radius").t oDouble()/AU, pd.value(secname+"/radius").t oDouble()/AU,
pd.value(secname+"/oblateness ", 0.0).toDouble(), pd.value(secname+"/oblateness ", 0.0).toDouble(),
StelUtils::strToVec3f(pd.valu StelUtils::strToVec3f(pd.valu
e(secname+"/color").toString()), e(secname+"/color", "1.0,1.0,1.0").toString()), // halo color
pd.value(secname+"/albedo").t pd.value(secname+"/albedo", 0
oFloat(), .25f).toFloat(),
pd.value(secname+"/tex_map"). pd.value(secname+"/roughness"
toString(), ,0.9f).toFloat(),
pd.value(secname+"/tex_map",
"nomap.png").toString(),
pd.value(secname+"/normals_ma p", normalMapName).toString(), pd.value(secname+"/normals_ma p", normalMapName).toString(),
pd.value(secname+"/model").to String(),
posfunc, posfunc,
userDataPtr, orbitPtr,
osculatingFunc, osculatingFunc,
closeOrbit, closeOrbit,
pd.value(secname+"/hidden", 0 ).toBool(), pd.value(secname+"/hidden", f alse).toBool(),
pd.value(secname+"/atmosphere ", false).toBool(), pd.value(secname+"/atmosphere ", false).toBool(),
pd.value(secname+"/halo", 0). toBool(), pd.value(secname+"/halo", tru e).toBool(), // GZ new default. Avoids clutter in ssystem.ini.
type)); type));
p->absoluteMagnitude = pd.value(secname+"/absolute_m agnitude", -99.).toDouble(); p->absoluteMagnitude = pd.value(secname+"/absolute_m agnitude", -99.).toDouble();
} }
if (!parent.isNull()) if (!parent.isNull())
{ {
parent->satellites.append(p); parent->satellites.append(p);
p->parent = parent; p->parent = parent;
} }
if (secname=="earth") earth = p; if (secname=="earth") earth = p;
skipping to change at line 1058 skipping to change at line 1133
readOk++; readOk++;
} }
if (systemPlanets.isEmpty()) if (systemPlanets.isEmpty())
{ {
qWarning() << "No Solar System objects loaded from" << QDir: :toNativeSeparators(filePath); qWarning() << "No Solar System objects loaded from" << QDir: :toNativeSeparators(filePath);
return false; return false;
} }
// special case: load earth shadow texture // special case: load earth shadow texture
Planet::texEarthShadow = StelApp::getInstance().getTextureManager(). if (!Planet::texEarthShadow)
createTexture(StelFileMgr::getInstallationDir()+"/textures/earth-shadow.png Planet::texEarthShadow = StelApp::getInstance().getTextureMa
"); nager().createTexture(StelFileMgr::getInstallationDir()+"/textures/earth-sh
adow.png");
// Also comets just have static textures. // Also comets just have static textures.
Comet::comaTexture = StelApp::getInstance().getTextureManager().crea if (!Comet::comaTexture)
teTextureThread(StelFileMgr::getInstallationDir()+"/textures/cometComa.png" Comet::comaTexture = StelApp::getInstance().getTextureManage
, StelTexture::StelTextureParams(true, GL_LINEAR, GL_CLAMP_TO_EDGE)); r().createTextureThread(StelFileMgr::getInstallationDir()+"/textures/cometC
oma.png", StelTexture::StelTextureParams(true, GL_LINEAR, GL_CLAMP_TO_EDGE)
);
//tail textures. We use paraboloid tail bodies, textured like a fish eye sphere, i.e. center=head. The texture should be something like a mottle d star to give some structure. //tail textures. We use paraboloid tail bodies, textured like a fish eye sphere, i.e. center=head. The texture should be something like a mottle d star to give some structure.
Comet::tailTexture = StelApp::getInstance().getTextureManager().crea if (!Comet::tailTexture)
teTextureThread(StelFileMgr::getInstallationDir()+"/textures/cometTail.png" Comet::tailTexture = StelApp::getInstance().getTextureManage
, StelTexture::StelTextureParams(true, GL_LINEAR, GL_CLAMP_TO_EDGE)); r().createTextureThread(StelFileMgr::getInstallationDir()+"/textures/cometT
ail.png", StelTexture::StelTextureParams(true, GL_LINEAR, GL_CLAMP_TO_EDGE)
);
if (readOk>0)
qDebug() << "Loaded" << readOk << "Solar System bodies";
return true; return true;
} }
// Compute the position for every elements of the solar system. // Compute the position for every elements of the solar system.
// The order is not important since the position is computed relatively to the mother body // The order is not important since the position is computed relatively to the mother body
void SolarSystem::computePositions(double dateJDE, const Vec3d& observerPos ) void SolarSystem::computePositions(double dateJDE, const Vec3d& observerPos )
{ {
if (flagLightTravelTime) if (flagLightTravelTime)
{ {
foreach (PlanetP p, systemPlanets) foreach (PlanetP p, systemPlanets)
{ {
p->computePositionWithoutOrbits(dateJDE); p->computePositionWithoutOrbits(dateJDE);
} }
// BEGIN HACK: 0.16.0pre for solar aberration/light time cor
rection: (This fixes eclipse bug LP:#1275092)
Vec3d earthPosJDE=getEarth()->getHeliocentricEclipticPos();
const double earthDist=earthPosJDE.length();
getEarth()->computePosition(dateJDE-earthDist * (AU / (SPEED
_OF_LIGHT * 86400)));
Vec3d earthPosJDEbefore=getEarth()->getHeliocentricEclipticP
os();
getSun()->setHeliocentricEclipticPos(earthPosJDE-earthPosJDE
before);
// We must reset Earth for the next step!
getEarth()->computePosition(dateJDE);
// END HACK FOR SOLAR LOGHT TIME/ABERRATION
foreach (PlanetP p, systemPlanets) foreach (PlanetP p, systemPlanets)
{ {
const double light_speed_correction = (p->getHelioce ntricEclipticPos()-observerPos).length() * (AU / (SPEED_OF_LIGHT * 86400)); const double light_speed_correction = (p->getHelioce ntricEclipticPos()-observerPos).length() * (AU / (SPEED_OF_LIGHT * 86400));
p->computePosition(dateJDE-light_speed_correction); p->computePosition(dateJDE-light_speed_correction);
} }
// BEGIN HACK PART 2
getSun()->setHeliocentricEclipticPos(earthPosJDE-earthPosJDE
before);
// END HACK PART 2
} }
else else
{ {
foreach (PlanetP p, systemPlanets) foreach (PlanetP p, systemPlanets)
{ {
p->computePosition(dateJDE); p->computePosition(dateJDE);
} }
} }
computeTransMatrices(dateJDE, observerPos); computeTransMatrices(dateJDE, observerPos);
} }
skipping to change at line 1168 skipping to change at line 1264
{ {
p->draw(core, maxMagLabel, planetNameFont); p->draw(core, maxMagLabel, planetNameFont);
} }
if (GETSTELMODULE(StelObjectMgr)->getFlagSelectedObjectPointer() && getFlagPointer()) if (GETSTELMODULE(StelObjectMgr)->getFlagSelectedObjectPointer() && getFlagPointer())
drawPointer(core); drawPointer(core);
// AstroCalcDialog // AstroCalcDialog
if (getFlagEphemerisMarkers()) if (getFlagEphemerisMarkers())
{ {
StelProjectorP prj = core->getProjection(StelCore::FrameJ200 StelProjectorP prj;
0); // , StelCore::RefractionOff); if (getFlagEphemerisHorizontalCoordinates())
prj = core->getProjection(StelCore::FrameAltAz);
else
prj = core->getProjection(StelCore::FrameJ2000); //
, StelCore::RefractionOff);
StelPainter sPainter(prj); StelPainter sPainter(prj);
float size, shift; float size, shift;
bool showDates = getFlagEphemerisDates();
bool showMagnitudes = getFlagEphemerisMagnitudes();
QString info = "";
for (int i =0; i< AstroCalcDialog::EphemerisListJ2000.count( ); i++) for (int i =0; i< AstroCalcDialog::EphemerisListCoords.count (); i++)
{ {
// draw EphemerisListJ2000[i]; // draw EphemerisListJ2000[i];
Vec3d win; Vec3d win;
// Check visibility of pointer // Check visibility of pointer
if (!(sPainter.getProjector()->projectCheck(AstroCal cDialog::EphemerisListJ2000[i], win))) if (!(sPainter.getProjector()->projectCheck(AstroCal cDialog::EphemerisListCoords[i], win)))
continue; continue;
if (i == AstroCalcDialog::DisplayedPositionIndex) if (i == AstroCalcDialog::DisplayedPositionIndex)
{ {
sPainter.setColor(1.0f, 0.7f, 0.0f, 1.0f); sPainter.setColor(1.0f, 0.7f, 0.0f, 1.0f);
size = 6.f; size = 6.f;
} }
else else
{ {
sPainter.setColor(1.0f, 1.0f, 0.0f, 1.0f); sPainter.setColor(1.0f, 1.0f, 0.0f, 1.0f);
size = 4.f; size = 4.f;
} }
sPainter.setBlending(true, GL_ONE, GL_ONE); sPainter.setBlending(true, GL_ONE, GL_ONE);
texCircle->bind(); texCircle->bind();
sPainter.drawSprite2dMode(AstroCalcDialog::Ephemeris ListJ2000[i], size); sPainter.drawSprite2dMode(AstroCalcDialog::Ephemeris ListCoords[i], size);
if (getFlagEphemerisDates()) if (showDates || showMagnitudes)
{ {
shift = 3.f + size/1.6f; shift = 3.f + size/1.6f;
sPainter.drawText(AstroCalcDialog::Ephemeris if (showDates && showMagnitudes)
ListJ2000[i], AstroCalcDialog::EphemerisListDates[i], 0, shift, shift, fals info = QString("%1 (%2)").arg(AstroC
e); alcDialog::EphemerisListDates[i], QString::number(AstroCalcDialog::Ephemeri
sListMagnitudes[i], 'f', 2));
if (showDates && !showMagnitudes)
info = AstroCalcDialog::EphemerisLis
tDates[i];
if (!showDates && showMagnitudes)
info = QString::number(AstroCalcDial
og::EphemerisListMagnitudes[i], 'f', 2);
sPainter.drawText(AstroCalcDialog::Ephemeris
ListCoords[i], info, 0, shift, shift, false);
} }
} }
} }
} }
PlanetP SolarSystem::searchByEnglishName(QString planetEnglishName) const PlanetP SolarSystem::searchByEnglishName(QString planetEnglishName) const
{ {
foreach (const PlanetP& p, systemPlanets) foreach (const PlanetP& p, systemPlanets)
{ {
if (p->getEnglishName() == planetEnglishName) if (p->getEnglishName() == planetEnglishName)
skipping to change at line 1344 skipping to change at line 1454
QList<StelObjectP> result; QList<StelObjectP> result;
if (!getFlagPlanets()) if (!getFlagPlanets())
return result; return result;
Vec3d v = core->j2000ToEquinoxEqu(vv, StelCore::RefractionOff); Vec3d v = core->j2000ToEquinoxEqu(vv, StelCore::RefractionOff);
v.normalize(); v.normalize();
double cosLimFov = std::cos(limitFov * M_PI/180.); double cosLimFov = std::cos(limitFov * M_PI/180.);
Vec3d equPos; Vec3d equPos;
double cosAngularSize; double cosAngularSize;
QString weAreHere = core->getCurrentPlanet()->getEnglishName();
foreach (const PlanetP& p, systemPlanets) foreach (const PlanetP& p, systemPlanets)
{ {
equPos = p->getEquinoxEquatorialPos(core); equPos = p->getEquinoxEquatorialPos(core);
equPos.normalize(); equPos.normalize();
cosAngularSize = std::cos(p->getSpheroidAngularSize(core) * M_PI/180.); cosAngularSize = std::cos(p->getSpheroidAngularSize(core) * M_PI/180.);
if (equPos*v>=std::min(cosLimFov, cosAngularSize)) if (equPos*v>=std::min(cosLimFov, cosAngularSize) && p->getE nglishName()!=weAreHere)
{ {
result.append(qSharedPointerCast<StelObject>(p)); result.append(qSharedPointerCast<StelObject>(p));
} }
} }
return result; return result;
} }
// Update i18 names from english names according to current sky culture tra nslator // Update i18 names from english names according to current sky culture tra nslator
void SolarSystem::updateI18n() void SolarSystem::updateI18n()
{ {
skipping to change at line 1469 skipping to change at line 1580
void SolarSystem::setFlagLightTravelTime(bool b) void SolarSystem::setFlagLightTravelTime(bool b)
{ {
if(b!=flagLightTravelTime) if(b!=flagLightTravelTime)
{ {
flagLightTravelTime = b; flagLightTravelTime = b;
emit flagLightTravelTimeChanged(b); emit flagLightTravelTimeChanged(b);
} }
} }
void SolarSystem::setFlagShowObjSelfShadows(bool b)
{
if(b!=flagShowObjSelfShadows)
{
flagShowObjSelfShadows = b;
if(!b)
Planet::deinitFBO();
emit flagShowObjSelfShadowsChanged(b);
}
}
void SolarSystem::setSelected(PlanetP obj) void SolarSystem::setSelected(PlanetP obj)
{ {
if (obj && obj->getType() == "Planet") if (obj && obj->getType() == "Planet")
selected = obj; selected = obj;
else else
selected.clear();; selected.clear();;
// Undraw other objects hints, orbit, trails etc.. // Undraw other objects hints, orbit, trails etc..
setFlagHints(getFlagHints()); setFlagHints(getFlagHints());
setFlagOrbits(getFlagOrbits()); setFlagOrbits(getFlagOrbits());
} }
skipping to change at line 1513 skipping to change at line 1635
// shadow location at earth + moon distance along earth vector from sun // shadow location at earth + moon distance along earth vector from sun
Vec3d en = e; Vec3d en = e;
en.normalize(); en.normalize();
Vec3d shadow = en * (e.length() + m.length()); Vec3d shadow = en * (e.length() + m.length());
// find shadow radii in AU // find shadow radii in AU
double r_penumbra = shadow.length()*702378.1/AU/e.length() - 696000/ AU; double r_penumbra = shadow.length()*702378.1/AU/e.length() - 696000/ AU;
// modify shadow location for scaled moon // modify shadow location for scaled moon
Vec3d mdist = shadow - mh; Vec3d mdist = shadow - mh;
if(mdist.length() > r_penumbra + 2000/AU) return 0; // not visible so don't bother drawing if(mdist.length() > r_penumbra + 2000/AU) return false; // not vis ible so don't bother drawing
return 1; return true;
} }
QStringList SolarSystem::listAllObjects(bool inEnglish) const QStringList SolarSystem::listAllObjects(bool inEnglish) const
{ {
QStringList result; QStringList result;
if (inEnglish) if (inEnglish)
{ {
foreach(const PlanetP& p, systemPlanets) foreach(const PlanetP& p, systemPlanets)
{ {
result << p->getEnglishName(); result << p->getEnglishName();
skipping to change at line 1593 skipping to change at line 1715
bool SolarSystem::getFlagPlanets(void) const bool SolarSystem::getFlagPlanets(void) const
{ {
return flagShow; return flagShow;
} }
void SolarSystem::setFlagEphemerisMarkers(bool b) void SolarSystem::setFlagEphemerisMarkers(bool b)
{ {
if (b!=ephemerisMarkersDisplayed) if (b!=ephemerisMarkersDisplayed)
{ {
ephemerisMarkersDisplayed=b; ephemerisMarkersDisplayed=b;
conf->setValue("astro/flag_ephemeris_markers", b); // Immedi ate saving of state conf->setValue("astrocalc/flag_ephemeris_markers", b); // Im mediate saving of state
emit ephemerisMarkersChanged(b); emit ephemerisMarkersChanged(b);
} }
} }
bool SolarSystem::getFlagEphemerisMarkers() const bool SolarSystem::getFlagEphemerisMarkers() const
{ {
return ephemerisMarkersDisplayed; return ephemerisMarkersDisplayed;
} }
void SolarSystem::setFlagEphemerisHorizontalCoordinates(bool b)
{
if (b!=ephemerisHorizontalCoordinates)
{
ephemerisHorizontalCoordinates=b;
conf->setValue("astrocalc/flag_ephemeris_horizontal", b); //
Immediate saving of state
emit ephemerisHorizontalCoordinatesChanged(b);
}
}
bool SolarSystem::getFlagEphemerisHorizontalCoordinates() const
{
return ephemerisHorizontalCoordinates;
}
void SolarSystem::setFlagEphemerisDates(bool b) void SolarSystem::setFlagEphemerisDates(bool b)
{ {
if (b!=ephemerisDatesDisplayed) if (b!=ephemerisDatesDisplayed)
{ {
ephemerisDatesDisplayed=b; ephemerisDatesDisplayed=b;
conf->setValue("astro/flag_ephemeris_dates", b); // Immediat e saving of state conf->setValue("astrocalc/flag_ephemeris_dates", b); // Imme diate saving of state
emit ephemerisDatesChanged(b); emit ephemerisDatesChanged(b);
} }
} }
bool SolarSystem::getFlagEphemerisDates() const bool SolarSystem::getFlagEphemerisDates() const
{ {
return ephemerisDatesDisplayed; return ephemerisDatesDisplayed;
} }
void SolarSystem::setFlagEphemerisMagnitudes(bool b)
{
if (b!=ephemerisMagnitudesDisplayed)
{
ephemerisMagnitudesDisplayed=b;
conf->setValue("astrocalc/flag_ephemeris_magnitudes", b); //
Immediate saving of state
emit ephemerisMagnitudesChanged(b);
}
}
bool SolarSystem::getFlagEphemerisMagnitudes() const
{
return ephemerisMagnitudesDisplayed;
}
void SolarSystem::setFlagNativePlanetNames(bool b) void SolarSystem::setFlagNativePlanetNames(bool b)
{ {
if (b!=flagNativePlanetNames) if (b!=flagNativePlanetNames)
{ {
flagNativePlanetNames=b; flagNativePlanetNames=b;
foreach (const PlanetP& p, systemPlanets) foreach (const PlanetP& p, systemPlanets)
{ {
if (p->getPlanetType()==Planet::isPlanet || p->getPl anetType()==Planet::isMoon || p->getPlanetType()==Planet::isStar) if (p->getPlanetType()==Planet::isPlanet || p->getPl anetType()==Planet::isMoon || p->getPlanetType()==Planet::isStar)
p->setFlagNativeName(flagNativePlanetNames); p->setFlagNativeName(flagNativePlanetNames);
} }
skipping to change at line 1900 skipping to change at line 2052
{ {
if(b!=flagMoonScale) if(b!=flagMoonScale)
{ {
if (!b) getMoon()->setSphereScale(1); if (!b) getMoon()->setSphereScale(1);
else getMoon()->setSphereScale(moonScale); else getMoon()->setSphereScale(moonScale);
flagMoonScale = b; flagMoonScale = b;
emit flagMoonScaleChanged(b); emit flagMoonScaleChanged(b);
} }
} }
// Set/Get Moon display scaling factor // Set/Get Moon display scaling factor. This goes directly to the Moon obje ct.
void SolarSystem::setMoonScale(double f) void SolarSystem::setMoonScale(double f)
{ {
if(moonScale != f) if(moonScale != f)
{ {
moonScale = f; moonScale = f;
if (flagMoonScale) if (flagMoonScale)
getMoon()->setSphereScale(moonScale); getMoon()->setSphereScale(moonScale);
emit moonScaleChanged(f); emit moonScaleChanged(f);
} }
} }
// Set/Get if minor body display is scaled. This flag will be queried by al
l Planet objects except for the Moon.
void SolarSystem::setFlagMinorBodyScale(bool b)
{
if(b!=flagMinorBodyScale)
{
flagMinorBodyScale = b;
double newScale = b ? minorBodyScale : 1.0;
//update the bodies with the new scale
foreach(PlanetP p, systemPlanets)
{
if(p == moon) continue;
if (p->getPlanetType()!=Planet::isPlanet
&& p->getPlanetType()!=Planet::isSta
r
)
p->setSphereScale(newScale);
}
emit flagMinorBodyScaleChanged(b);
}
}
// Set/Get minor body display scaling factor. This will be queried by all P
lanet objects except for the Moon.
void SolarSystem::setMinorBodyScale(double f)
{
if(minorBodyScale != f)
{
minorBodyScale = f;
if(flagMinorBodyScale) //update the bodies with the new scal
e
{
foreach(PlanetP p, systemPlanets)
{
if(p == moon) continue;
if (p->getPlanetType()!=Planet::isPlanet
&& p->getPlanetType()!=Plane
t::isStar
)
p->setSphereScale(minorBodyScale);
}
}
emit minorBodyScaleChanged(f);
}
}
// Set selected planets by englishName // Set selected planets by englishName
void SolarSystem::setSelected(const QString& englishName) void SolarSystem::setSelected(const QString& englishName)
{ {
setSelected(searchByEnglishName(englishName)); setSelected(searchByEnglishName(englishName));
} }
// Get the list of all the planet english names // Get the list of all the planet english names
QStringList SolarSystem::getAllPlanetEnglishNames() const QStringList SolarSystem::getAllPlanetEnglishNames() const
{ {
QStringList res; QStringList res;
skipping to change at line 1935 skipping to change at line 2129
} }
QStringList SolarSystem::getAllPlanetLocalizedNames() const QStringList SolarSystem::getAllPlanetLocalizedNames() const
{ {
QStringList res; QStringList res;
foreach (const PlanetP& p, systemPlanets) foreach (const PlanetP& p, systemPlanets)
res.append(p->nameI18); res.append(p->nameI18);
return res; return res;
} }
// GZ TODO: This could be modified to only delete&reload the minor objects. For now, we really load both parts again like in the 0.10?-0.15 series.
void SolarSystem::reloadPlanets() void SolarSystem::reloadPlanets()
{ {
// Save flag states // Save flag states
bool flagScaleMoon = getFlagMoonScale(); bool flagScaleMoon = getFlagMoonScale();
float moonScale = getMoonScale(); float moonScale = getMoonScale();
bool flagScaleMinorBodies=getFlagMinorBodyScale();
float minorScale= getMinorBodyScale();
bool flagPlanets = getFlagPlanets(); bool flagPlanets = getFlagPlanets();
bool flagHints = getFlagHints(); bool flagHints = getFlagHints();
bool flagLabels = getFlagLabels(); bool flagLabels = getFlagLabels();
bool flagOrbits = getFlagOrbits(); bool flagOrbits = getFlagOrbits();
bool flagNative = getFlagNativePlanetNames(); bool flagNative = getFlagNativePlanetNames();
bool flagTrans = getFlagTranslatedNames(); bool flagTrans = getFlagTranslatedNames();
bool hasSelection = false; bool hasSelection = false;
// Save observer location (fix for LP bug # 969211) // Save observer location (fix for LP bug # 969211)
// TODO: This can probably be done better with a better understandin g of StelObserver --BM // TODO: This can probably be done better with a better understandin g of StelObserver --BM
skipping to change at line 1964 skipping to change at line 2161
// Whether any planet are selected? Save the current selection... // Whether any planet are selected? Save the current selection...
const QList<StelObjectP> selectedObject = objMgr->getSelectedObject( "Planet"); const QList<StelObjectP> selectedObject = objMgr->getSelectedObject( "Planet");
if (!selectedObject.isEmpty()) if (!selectedObject.isEmpty())
{ {
// ... unselect current planet. // ... unselect current planet.
hasSelection = true; hasSelection = true;
objMgr->unSelect(); objMgr->unSelect();
} }
// Unload all Solar System objects // Unload all Solar System objects
selected.clear();//Release the selected one selected.clear();//Release the selected one
// GZ TODO in case this methods gets converted to only reload minor
bodies: Only delete Orbits which are not referenced by some Planet.
foreach (Orbit* orb, orbits) foreach (Orbit* orb, orbits)
{ {
delete orb; delete orb;
orb = NULL; orb = Q_NULLPTR;
} }
orbits.clear(); orbits.clear();
sun.clear(); sun.clear();
moon.clear(); moon.clear();
earth.clear(); earth.clear();
Planet::texEarthShadow.clear(); //Loaded in loadPlanets() Planet::texEarthShadow.clear(); //Loaded in loadPlanets()
delete allTrails; delete allTrails;
allTrails = NULL; allTrails = Q_NULLPTR;
foreach (PlanetP p, systemPlanets) foreach (PlanetP p, systemPlanets)
{ {
p->satellites.clear(); p->satellites.clear();
p.clear(); p.clear();
} }
systemPlanets.clear(); systemPlanets.clear();
// Memory leak? What's the proper way of cleaning shared pointers? // Memory leak? What's the proper way of cleaning shared pointers?
// Also delete Comet textures (loaded in loadPlanets() // Also delete Comet textures (loaded in loadPlanets()
Comet::tailTexture.clear(); Comet::tailTexture.clear();
Comet::comaTexture.clear(); Comet::comaTexture.clear();
// Re-load the ssystem.ini file // Re-load the ssystem_major.ini and ssystem_minor.ini file
loadPlanets(); loadPlanets();
computePositions(core->getJDE()); computePositions(core->getJDE());
setSelected(""); setSelected("");
recreateTrails(); recreateTrails();
// Restore observer location // Restore observer location
core->moveObserverTo(loc, 0., 0.); core->moveObserverTo(loc, 0., 0.);
// Restore flag states // Restore flag states
setFlagMoonScale(flagScaleMoon); setFlagMoonScale(flagScaleMoon);
setMoonScale(moonScale); setMoonScale(moonScale);
setFlagMinorBodyScale(flagScaleMinorBodies);
setMinorBodyScale(1.0); // force-reset first to really reach the obj
ects in the next call.
setMinorBodyScale(minorScale);
setFlagPlanets(flagPlanets); setFlagPlanets(flagPlanets);
setFlagHints(flagHints); setFlagHints(flagHints);
setFlagLabels(flagLabels); setFlagLabels(flagLabels);
setFlagOrbits(flagOrbits); setFlagOrbits(flagOrbits);
setFlagNativePlanetNames(flagNative); setFlagNativePlanetNames(flagNative);
setFlagTranslatedNames(flagTrans); setFlagTranslatedNames(flagTrans);
if (hasSelection) if (hasSelection)
{ {
// Restore selection... // Restore selection...
skipping to change at line 2025 skipping to change at line 2227
// Restore translations // Restore translations
updateI18n(); updateI18n();
emit solarSystemDataReloaded(); emit solarSystemDataReloaded();
} }
// Set the algorithm for computation of apparent magnitudes for planets in case observer on the Earth // Set the algorithm for computation of apparent magnitudes for planets in case observer on the Earth
void SolarSystem::setApparentMagnitudeAlgorithmOnEarth(QString algorithm) void SolarSystem::setApparentMagnitudeAlgorithmOnEarth(QString algorithm)
{ {
getEarth()->setApparentMagnitudeAlgorithm(algorithm); Planet::setApparentMagnitudeAlgorithm(algorithm);
} }
// Get the algorithm used for computation of apparent magnitudes for planet s in case observer on the Earth // Get the algorithm used for computation of apparent magnitudes for planet s in case observer on the Earth
QString SolarSystem::getApparentMagnitudeAlgorithmOnEarth() const QString SolarSystem::getApparentMagnitudeAlgorithmOnEarth() const
{ {
return getEarth()->getApparentMagnitudeAlgorithmString(); return Planet::getApparentMagnitudeAlgorithmString();
} }
void SolarSystem::setFlagPermanentOrbits(bool b) void SolarSystem::setFlagPermanentOrbits(bool b)
{ {
Planet::permanentDrawingOrbits=b; Planet::permanentDrawingOrbits=b;
} }
void SolarSystem::setFlagCustomGrsSettings(bool b) void SolarSystem::setFlagCustomGrsSettings(bool b)
{ {
Planet::flagCustomGrsSettings=b; Planet::flagCustomGrsSettings=b;
skipping to change at line 2192 skipping to change at line 2394
illumination = 1.0 - (AR + Ar) / AS; illumination = 1.0 - (AR + Ar) / AS;
} }
if(illumination < final_illumination) if(illumination < final_illumination)
final_illumination = illumination; final_illumination = illumination;
} }
return final_illumination; return final_illumination;
} }
bool SolarSystem::removePlanet(QString name)
{
PlanetP candidate = searchByEnglishName(name);
if (!candidate)
{
qWarning() << "Cannot remove planet " << name << ": Not foun
d.";
return false;
}
// TODO: In case we want major bodies or Pluto to be deleted, think
about proper handling of moons!
//candidate->satellites.clear();
if (candidate->pType < Planet::isAsteroid)
{
qWarning() << "REMOVING MAJOR OBJECT:" << name;
qWarning() << " This is likely not what you wan
t, but will be accepted.";
Q_ASSERT(0);
}
Orbit* orbPtr=(Orbit*) candidate->orbitPtr;
if (orbPtr)
orbits.removeOne(orbPtr);
systemPlanets.removeOne(candidate);
candidate.clear();
return true;
}
 End of changes. 129 change blocks. 
160 lines changed or deleted 403 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/