diff --git a/celestia.cfg b/celestia.cfg index 17478b7d1..0b0e92de3 100644 --- a/celestia.cfg +++ b/celestia.cfg @@ -396,10 +396,13 @@ StarTextures #------------------------------------------------------------------------ # The following define the measurement system Celestia uses to display -# in HUD, available options are `metric` and `imperial`, by default, -# metric measurement system is used. +# in HUD, available options for MeasurementSystem are `metric` and +# `imperial`. By default, metric measurement system is used. Available +# options for TemperatureScale are `kelvin`, `celsius`, and `fahrenheit`. +# By default kelvin is used. #------------------------------------------------------------------------ # MeasurementSystem "imperial" +# TemperatureScale "celsius" #------------------------------------------------------------------------ # The following options are used to configure how scenes in Celestia diff --git a/src/celestia/celestiacore.cpp b/src/celestia/celestiacore.cpp index e400c7675..8579fce67 100644 --- a/src/celestia/celestiacore.cpp +++ b/src/celestia/celestiacore.cpp @@ -90,6 +90,47 @@ static const double OneFtInKm = 0.0003048; static const double OneLbInKg = 0.45359237; static const double OneLbPerFt3InKgPerM3 = OneLbInKg / pow(OneFtInKm * 1000.0, 3); +namespace +{ +float KelvinToCelsius(float kelvin) +{ + return kelvin - 273.15f; +} + +float KelvinToFahrenheit(float kelvin) +{ + return kelvin * 1.8f - 459.67f; +} + +FormattedNumber SigDigitNum(double v, int digits) +{ + return FormattedNumber(v, digits, + FormattedNumber::GroupThousands | + FormattedNumber::SignificantDigits); +} + +string KelvinToStr(float value, int digits, CelestiaCore::TemperatureScale temperatureScale) +{ + const char* unitTemplate = ""; + + switch (temperatureScale) + { + case CelestiaCore::Celsius: + value = KelvinToCelsius(value); + unitTemplate = "{} °C"; + break; + case CelestiaCore::Fahrenheit: + value = KelvinToFahrenheit(value); + unitTemplate = "{} °F"; + break; + case CelestiaCore::Kelvin: + default: + unitTemplate = "{} K"; + break; + } + return fmt::format(unitTemplate, SigDigitNum(value, digits)); +} +} static bool is_valid_directory(const fs::path& dir) { @@ -2478,13 +2519,6 @@ int CelestiaCore::getTextWidth(const std::string &s) const return titleFont->getWidth(s); } -static FormattedNumber SigDigitNum(double v, int digits) -{ - return FormattedNumber(v, digits, - FormattedNumber::GroupThousands | - FormattedNumber::SignificantDigits); -} - static string DistanceLyToStr(double distance, int digits, CelestiaCore::MeasurementSystem measurement) { @@ -2821,7 +2855,8 @@ static void displayStarInfo(Overlay& overlay, Star& star, const Universe& universe, double distance, - CelestiaCore::MeasurementSystem measurement) + CelestiaCore::MeasurementSystem measurement, + CelestiaCore::TemperatureScale temperatureScale) { overlay.printf(_("Distance: %s\n"), DistanceLyToStr(distance, 5, measurement)); @@ -2857,7 +2892,7 @@ static void displayStarInfo(Overlay& overlay, if (detail > 1) { - overlay.printf(_("Surface temp: %s K\n"), SigDigitNum(star.getTemperature(), 3)); + overlay.printf(_("Surface temp: %s\n"), KelvinToStr(star.getTemperature(), 3, temperatureScale)); float solarRadii = star.getRadius() / 6.96e5f; if (solarRadii > 0.01f) @@ -2922,7 +2957,8 @@ static void displayPlanetInfo(Overlay& overlay, double t, double distanceKm, const Vector3d& viewVec, - CelestiaCore::MeasurementSystem measurement) + CelestiaCore::MeasurementSystem measurement, + CelestiaCore::TemperatureScale temperatureScale) { double distance = distanceKm - body.getRadius(); overlay.printf(_("Distance: %s\n"), DistanceKmToStr(distance, 5, measurement)); @@ -2996,7 +3032,7 @@ static void displayPlanetInfo(Overlay& overlay, float planetTemp = body.getTemperature(t); if (planetTemp > 0) - overlay.printf(_("Temperature: %.0f K\n"), planetTemp); + overlay.printf(_("Temperature: %s\n"), KelvinToStr(planetTemp, 3, temperatureScale)); } } @@ -3331,7 +3367,8 @@ void CelestiaCore::renderOverlay() *(sel.star()), *(sim->getUniverse()), astro::kilometersToLightYears(v.norm()), - measurement); + measurement, + temperatureScale); } break; @@ -3397,7 +3434,8 @@ void CelestiaCore::renderOverlay() sim->getTime(), v.norm(), v, - measurement); + measurement, + temperatureScale); } break; @@ -3978,6 +4016,18 @@ bool CelestiaCore::initSimulation(const fs::path& configFileName, GetLogger()->warn("Unknown measurement system {}\n", config->measurementSystem); } + if (!config->temperatureScale.empty()) + { + if (compareIgnoringCase(config->temperatureScale, "kelvin") == 0) + temperatureScale = Kelvin; + else if (compareIgnoringCase(config->temperatureScale, "celsius") == 0) + temperatureScale = Celsius; + else if (compareIgnoringCase(config->temperatureScale, "fahrenheit") == 0) + temperatureScale = Fahrenheit; + else + GetLogger()->warn("Unknown temperature scale {}\n", config->temperatureScale); + } + sim = new Simulation(universe); if ((renderer->getRenderFlags() & Renderer::ShowAutoMag) == 0) { @@ -4814,6 +4864,20 @@ CelestiaCore::MeasurementSystem CelestiaCore::getMeasurementSystem() const return measurement; } +void CelestiaCore::setTemperatureScale(CelestiaCore::TemperatureScale newScale) +{ + if (temperatureScale != newScale) + { + temperatureScale = newScale; + notifyWatchers(TemperatureScaleChanged); + } +} + +CelestiaCore::TemperatureScale CelestiaCore::getTemperatureScale() const +{ + return temperatureScale; +} + void CelestiaCore::setLogFile(const fs::path &fn) { m_logfile = std::ofstream(fn.string()); diff --git a/src/celestia/celestiacore.h b/src/celestia/celestiacore.h index e1d9dee71..6127da84f 100644 --- a/src/celestia/celestiacore.h +++ b/src/celestia/celestiacore.h @@ -160,6 +160,7 @@ class CelestiaCore // : public Watchable TextEnterModeChanged = 0x0080, GalaxyLightGainChanged = 0x0100, MeasurementSystemChanged = 0x0200, + TemperatureScaleChanged = 0x0400, }; enum @@ -184,6 +185,13 @@ class CelestiaCore // : public Watchable Imperial = 1, }; + enum TemperatureScale + { + Kelvin = 0, + Celsius = 1, + Fahrenheit = 2, + }; + public: CelestiaCore(); ~CelestiaCore(); @@ -381,6 +389,8 @@ class CelestiaCore // : public Watchable void setMeasurementSystem(MeasurementSystem); MeasurementSystem getMeasurementSystem() const; + void setTemperatureScale(TemperatureScale); + TemperatureScale getTemperatureScale() const; protected: bool readStars(const CelestiaConfig&, ProgressNotifier*); @@ -524,6 +534,7 @@ class CelestiaCore // : public Watchable EdgeInsets safeAreaInsets { 0, 0, 0, 0 }; MeasurementSystem measurement { Metric }; + TemperatureScale temperatureScale { Kelvin }; Selection lastSelection; std::string selectionNames; diff --git a/src/celestia/configfile.cpp b/src/celestia/configfile.cpp index 166c833c1..50664eab4 100644 --- a/src/celestia/configfile.cpp +++ b/src/celestia/configfile.cpp @@ -99,6 +99,7 @@ CelestiaConfig* ReadCelestiaConfig(const fs::path& filename, CelestiaConfig *con configParams->getString("X264EncoderOptions", config->x264EncoderOptions); configParams->getString("FFVHEncoderOptions", config->ffvhEncoderOptions); configParams->getString("MeasurementSystem", config->measurementSystem); + configParams->getString("TemperatureScale", config->temperatureScale); float maxDist = 1.0; configParams->getNumber("SolarSystemMaxDistance", maxDist); diff --git a/src/celestia/configfile.h b/src/celestia/configfile.h index cbfbf4a15..43acc24dd 100644 --- a/src/celestia/configfile.h +++ b/src/celestia/configfile.h @@ -83,6 +83,7 @@ public: std::string viewportEffect; std::string warpMeshFile; std::string measurementSystem; + std::string temperatureScale; std::string x264EncoderOptions; std::string ffvhEncoderOptions;