diff --git a/src/core/StelPainter.cpp b/src/core/StelPainter.cpp index b3da35365292fe..2081fb22cf16f4 100644 --- a/src/core/StelPainter.cpp +++ b/src/core/StelPainter.cpp @@ -1737,6 +1737,45 @@ void StelPainter::drawCircle(float x, float y, float r) enableClientStates(false); } +// rx: radius in x axis +// ry: radius in y axis +// angle rotation (counterclockwise), radians [0..2pi] +void StelPainter::drawEllipse(float x, float y, float rX, float rY, float angle) +{ + if (rX <= 1.0f || rY <= 1.0f) + return; + // Taken largely from Nebula::renderEllipticMarker() + // Take into account device pixel density and global scale ratio, as we are drawing 2D stuff. + const auto pixelRatio = getProjector()->getDevicePixelsPerPixel(); + const auto scale = pixelRatio * StelApp::getInstance().getGlobalScalingRatio(); + rX *= scale; + rY *= scale; + + //const float radiusY = 0.35 * size; + //const float radiusX = aspectRatio * radiusY; + const int numPoints = std::lround(std::clamp(qMax(rX, rY)/3, 32.f, 1024.f)); + std::vector vertexData; + vertexData.reserve(numPoints*2); + const float*const cossin = StelUtils::ComputeCosSinTheta(numPoints); + const auto cosa = std::cos(angle); + const auto sina = std::sin(angle); + for(int n = 0; n < numPoints; ++n) + { + const auto cosb = cossin[2*n], sinb = cossin[2*n+1]; + const auto pointX = rX*sinb; + const auto pointY = rY*cosb; + vertexData.push_back(x + pointX*cosa - pointY*sina); + vertexData.push_back(y + pointY*cosa + pointX*sina); + } + const auto vertCount = vertexData.size() / 2; + setLineSmooth(true); + setLineWidth(scale * std::clamp(qMax(rX, rY)/40, 1.f, 2.f)); + enableClientStates(true); + setVertexPointer(2, GL_FLOAT, vertexData.data()); + drawFromArray(StelPainter::LineLoop, vertCount, 0, false); + enableClientStates(false); +} + void StelPainter::drawSprite2dMode(float x, float y, float radius) { static float vertexData[] = {-10.,-10.,10.,-10., 10.,10., -10.,10.}; diff --git a/src/core/StelPainter.hpp b/src/core/StelPainter.hpp index 120a0a59e1583f..597db5887e8deb 100644 --- a/src/core/StelPainter.hpp +++ b/src/core/StelPainter.hpp @@ -135,6 +135,12 @@ class StelPainter : protected QOpenGLFunctions //! Draw a simple circle, 2d viewport coordinates in pixel void drawCircle(float x, float y, float r); + //! Draw a simple ellipse, 2d viewport coordinates in pixel + //! @param rx: radius in x axis + //! @param ry: radius in y axis + //! @param angle: rotation (counterclockwise), radians [0..2pi] + void drawEllipse(float x, float y, float rx, float ry, float angle); + //! Draw a square using the current texture at the given projected 2d position. //! This method is not thread safe. //! @param x x position in the viewport in pixel. diff --git a/src/core/modules/NomenclatureItem.cpp b/src/core/modules/NomenclatureItem.cpp index 7cec958f4c8e94..9223ba37c7e0d6 100644 --- a/src/core/modules/NomenclatureItem.cpp +++ b/src/core/modules/NomenclatureItem.cpp @@ -28,6 +28,7 @@ const QString NomenclatureItem::NOMENCLATURE_TYPE = QStringLiteral("NomenclatureItem"); Vec3f NomenclatureItem::color = Vec3f(0.1f,1.0f,0.1f); +bool NomenclatureItem::flagOutlineCraters = false; bool NomenclatureItem::hideLocalNomenclature = false; bool NomenclatureItem::showTerminatorZoneOnly = false; int NomenclatureItem::terminatorMinAltitude=-2; @@ -355,23 +356,23 @@ float NomenclatureItem::getAngularDiameterRatio(const StelCore *core) const void NomenclatureItem::draw(StelCore* core, StelPainter *painter) { + // show special points only? + if (getFlagShowSpecialNomenclatureOnly() && nTypegetCurrentPlanet()) + return; + // Called by NomenclatureMgr, so we don't need to check if labelsFader is true. // The painter has been set to enable blending. const Vec3d equPos = planet->getJ2000EquatorialPos(core); - Vec3d XYZ = getJ2000EquatorialPos(core); + const Vec3d XYZ = getJ2000EquatorialPos(core); // In case we are located at a labeled site, don't show this label or any labels within 150 km. Else we have bad flicker... if (XYZ.normSquared() < 150.*150.*AU_KM*AU_KM ) return; - if (getFlagHideLocalNomenclature()) - { - // Check the state when needed only! - if (planet==core->getCurrentPlanet()) - return; - } - - const double screenSize = 2.*getAngularRadius(core)*M_PI_180*static_cast(painter->getProjector()->getPixelPerRadAtCenter()); + const double screenRadius = getAngularRadius(core)*M_PI_180*static_cast(painter->getProjector()->getPixelPerRadAtCenter()); // We can use ratio of angular size to the FOV to checking visibility of features also! // double scale = getAngularSize(core)/painter->getProjector()->getFov(); @@ -380,29 +381,34 @@ void NomenclatureItem::draw(StelCore* core, StelPainter *painter) // check visibility of feature Vec3d srcPos; const float scale = getAngularDiameterRatio(core); - NomenclatureItem::NomenclatureItemType niType = getNomenclatureType(); - - if (getFlagShowSpecialNomenclatureOnly()) - { - // show special points only - if (niTypegetProjector()->projectCheck(XYZ, srcPos) && (equPos.normSquared() >= XYZ.normSquared()) - && (scale>0.04f && (scale<0.5f || niType>=NomenclatureItem::niSpecialPointPole ))) + && (scale>0.04f && (scale<0.5f || nType>=NomenclatureItem::niSpecialPointPole ))) { const float solarAltitude=getSolarAltitude(core); // Throw out real items if not along the terminator? - if ( (niType terminatorMaxAltitude || solarAltitude < terminatorMinAltitude) ) + if ( (nType terminatorMaxAltitude || solarAltitude < terminatorMinAltitude) ) return; - float brightness=(solarAltitude<0. ? 0.25f : 1.0f); - if (niType>=NomenclatureItem::niSpecialPointPole) - brightness = 0.5f; + const float brightness=(nType>=NomenclatureItem::niSpecialPointPole ? 0.5f : (solarAltitude<0. ? 0.25f : 1.0f)); painter->setColor(color*brightness, labelsFader.getInterstate()); painter->drawCircle(static_cast(srcPos[0]), static_cast(srcPos[1]), 2.f); - if (nType==niCrater || nType==niSatelliteFeature) // probably all satellite features are satellite craters - painter->drawCircle(static_cast(srcPos[0]), static_cast(srcPos[1]), screenSize/2.); + if (flagOutlineCraters && (nType==niCrater || nType==niSatelliteFeature)) // probably all satellite features are satellite craters + { + // Compute aspectRatio and angle from position of planet and own position, parallactic angle, ... + double ra, de, raPl, dePl; + StelUtils::rectToSphe(&ra, &de, XYZ); + StelUtils::rectToSphe(&raPl, &dePl, equPos); + const double distDegrees=StelLocation::distanceDegrees(raPl*M_180_PIf, dePl*M_180_PIf, ra*M_180_PIf, de*M_180_PIf); + const double plRadiusDeg=planet->getAngularRadius(core); + const double sinDistCenter=distDegrees/plRadiusDeg; // 0...1 + if (sinDistCenter>1.f) + qWarning() << "Distance greater 1"; + const double angleDistCenterRad=asin(sinDistCenter); // 0..pi/2 on the lunar/planet sphere + const double aspectRatio=cos(angleDistCenterRad); + const double angle=atan2(ra-raPl, de-dePl); + const double par = static_cast(getParallacticAngle(core)); + painter->drawEllipse(static_cast(srcPos[0]), static_cast(srcPos[1]), screenRadius, screenRadius*aspectRatio, angle-par ); + } painter->drawText(static_cast(srcPos[0]), static_cast(srcPos[1]), nameI18n, 0, 5.f, 5.f, false); } } diff --git a/src/core/modules/NomenclatureItem.hpp b/src/core/modules/NomenclatureItem.hpp index b48a75016d58ce..f8b416769dfa0f 100644 --- a/src/core/modules/NomenclatureItem.hpp +++ b/src/core/modules/NomenclatureItem.hpp @@ -212,6 +212,7 @@ class NomenclatureItem : public StelObject mutable Vec3d XYZ; // holds J2000 position in space (i.e. including planet position, offset from planetocenter) mutable double jde; // jde time of XYZ value static Vec3f color; + static bool flagOutlineCraters; // draw craters and satellite features as ellipses? static bool hideLocalNomenclature; static bool showTerminatorZoneOnly; static int terminatorMinAltitude; diff --git a/src/core/modules/NomenclatureMgr.cpp b/src/core/modules/NomenclatureMgr.cpp index 971fa1f95d4fae..bac71b7094e54b 100644 --- a/src/core/modules/NomenclatureMgr.cpp +++ b/src/core/modules/NomenclatureMgr.cpp @@ -71,6 +71,7 @@ void NomenclatureMgr::init() setFlagShowTerminatorZoneOnly(conf->value("astro/flag_planets_nomenclature_terminator_only", false).toBool()); setTerminatorMinAltitude(conf->value("astro/planet_nomenclature_solar_altitude_min", -5).toInt()); setTerminatorMaxAltitude(conf->value("astro/planet_nomenclature_solar_altitude_max", 40).toInt()); + setFlagOutlineCraters(conf->value("astro/flag_planets_nomenclature_outline_craters", false).toBool()); setFlagHideLocalNomenclature(conf->value("astro/flag_hide_local_nomenclature", true).toBool()); setFlagShowSpecialNomenclatureOnly(conf->value("astro/flag_special_nomenclature_only", false).toBool()); @@ -553,6 +554,17 @@ int NomenclatureMgr::getTerminatorMaxAltitude() const return NomenclatureItem::terminatorMaxAltitude; } +void NomenclatureMgr::setFlagOutlineCraters(bool b) +{ + NomenclatureItem::flagOutlineCraters = b; + emit flagOutlineCratersChanged(b); +} + +bool NomenclatureMgr::getFlagOutlineCraters() const +{ + return NomenclatureItem::flagOutlineCraters; +} + void NomenclatureMgr::setFlagHideLocalNomenclature(bool b) { NomenclatureItem::hideLocalNomenclature = b; diff --git a/src/core/modules/NomenclatureMgr.hpp b/src/core/modules/NomenclatureMgr.hpp index 6925bf38d82964..d90fa1348fc191 100644 --- a/src/core/modules/NomenclatureMgr.hpp +++ b/src/core/modules/NomenclatureMgr.hpp @@ -40,6 +40,7 @@ class NomenclatureMgr : public StelObjectModule Q_PROPERTY(bool flagShowTerminatorZoneOnly READ getFlagShowTerminatorZoneOnly WRITE setFlagShowTerminatorZoneOnly NOTIFY flagShowTerminatorZoneOnlyChanged) Q_PROPERTY(int terminatorMinAltitude READ getTerminatorMinAltitude WRITE setTerminatorMinAltitude NOTIFY terminatorMinAltitudeChanged) Q_PROPERTY(int terminatorMaxAltitude READ getTerminatorMaxAltitude WRITE setTerminatorMaxAltitude NOTIFY terminatorMaxAltitudeChanged) + Q_PROPERTY(bool flagOutlineCraters READ getFlagOutlineCraters WRITE setFlagOutlineCraters NOTIFY flagOutlineCratersChanged) Q_PROPERTY(bool flagHideLocalNomenclature READ getFlagHideLocalNomenclature WRITE setFlagHideLocalNomenclature NOTIFY localNomenclatureHidingChanged) Q_PROPERTY(bool specialNomenclatureOnlyDisplayed READ getFlagShowSpecialNomenclatureOnly WRITE setFlagShowSpecialNomenclatureOnly NOTIFY specialNomenclatureOnlyDisplayingChanged) Q_PROPERTY(Vec3f nomenclatureColor READ getColor WRITE setColor NOTIFY nomenclatureColorChanged) @@ -119,6 +120,11 @@ public slots: //! Get maximum solar altitude (degrees) to draw only nomenclature along the terminator. int getTerminatorMaxAltitude() const; + //! Set flag which determines if craters and satellite features (which are usually also craters) are outlined as ellipses. + void setFlagOutlineCraters(bool b); + //! Get the current value of the flag which determines if craters and satellite features (which are usually also craters) are outlined as ellipses. + bool getFlagOutlineCraters() const; + //! Set flag which determines if nomenclature labels are drawn or hidden on the celestial body of observer. void setFlagHideLocalNomenclature(bool b); //! Get the current value of the flag which determines if nomenclature labels are drawn or hidden on the celestial body of observer. @@ -139,6 +145,7 @@ public slots: void flagShowTerminatorZoneOnlyChanged(bool b); void terminatorMinAltitudeChanged(int deg); void terminatorMaxAltitudeChanged(int deg); + void flagOutlineCratersChanged(bool b); void localNomenclatureHidingChanged(bool b); void specialNomenclatureOnlyDisplayingChanged(bool b); void nomenclatureColorChanged(const Vec3f & color) const; diff --git a/src/gui/ConfigurationDialog.cpp b/src/gui/ConfigurationDialog.cpp index ca2f85549c8fc7..aea58c8a7c3b5a 100644 --- a/src/gui/ConfigurationDialog.cpp +++ b/src/gui/ConfigurationDialog.cpp @@ -904,6 +904,7 @@ void ConfigurationDialog::saveAllSettings() conf->setValue("astro/flag_show_obj_self_shadows", propMgr->getStelPropertyValue("SolarSystem.flagShowObjSelfShadows").toBool()); conf->setValue("astro/apparent_magnitude_algorithm", Planet::getApparentMagnitudeAlgorithmString()); conf->setValue("astro/flag_planets_nomenclature", propMgr->getStelPropertyValue("NomenclatureMgr.flagShowNomenclature").toBool()); + conf->setValue("astro/flag_planets_nomenclature_outline_craters",propMgr->getStelPropertyValue("NomenclatureMgr.flagOutlineCraters").toBool()); conf->setValue("astro/flag_hide_local_nomenclature", propMgr->getStelPropertyValue("NomenclatureMgr.flagHideLocalNomenclature").toBool()); conf->setValue("astro/flag_special_nomenclature_only", propMgr->getStelPropertyValue("NomenclatureMgr.specialNomenclatureOnlyDisplayed").toBool()); conf->setValue("astro/flag_planets_nomenclature_terminator_only",propMgr->getStelPropertyValue("NomenclatureMgr.flagShowTerminatorZoneOnly").toBool()); diff --git a/src/gui/ViewDialog.cpp b/src/gui/ViewDialog.cpp index fe53cc209c2f63..61242d5a44d94e 100644 --- a/src/gui/ViewDialog.cpp +++ b/src/gui/ViewDialog.cpp @@ -249,6 +249,7 @@ void ViewDialog::createDialogContent() connectDoubleProperty(ui->planetsLabelsHorizontalSlider, "SolarSystem.labelsAmount",0.0,10.0); connectCheckBox(ui->planetNomenclatureCheckBox, "actionShow_Planets_Nomenclature"); connectColorButton(ui->planetNomenclatureColor, "NomenclatureMgr.nomenclatureColor", "color/planet_nomenclature_color"); + connectBoolProperty(ui->outlineCratersCheckBox, "NomenclatureMgr.flagOutlineCraters"); connectColorButton(ui->planetLabelColor, "SolarSystem.labelsColor", "color/planet_names_color"); connectColorButton(ui->planetTrailsColor, "SolarSystem.trailsColor", "color/object_trails_color"); connectBoolProperty(ui->planetTrailsCheckBox, "SolarSystem.trailsDisplayed"); diff --git a/src/gui/viewDialog.ui b/src/gui/viewDialog.ui index 842daa1a97a282..d892b0ff9dd396 100644 --- a/src/gui/viewDialog.ui +++ b/src/gui/viewDialog.ui @@ -2021,11 +2021,22 @@ - - - Show special nomenclature points only - - + + + + + Outline craters + + + + + + + Show special nomenclature points only + + + + @@ -5690,12 +5701,12 @@ - + false - + false