Add support for different temperature scales

pull/1256/head
Levin Li 2021-12-24 12:27:39 +08:00
parent ab409356c1
commit 968199915c
5 changed files with 95 additions and 15 deletions

View File

@ -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

View File

@ -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());

View File

@ -160,6 +160,7 @@ class CelestiaCore // : public Watchable<CelestiaCore>
TextEnterModeChanged = 0x0080,
GalaxyLightGainChanged = 0x0100,
MeasurementSystemChanged = 0x0200,
TemperatureScaleChanged = 0x0400,
};
enum
@ -184,6 +185,13 @@ class CelestiaCore // : public Watchable<CelestiaCore>
Imperial = 1,
};
enum TemperatureScale
{
Kelvin = 0,
Celsius = 1,
Fahrenheit = 2,
};
public:
CelestiaCore();
~CelestiaCore();
@ -381,6 +389,8 @@ class CelestiaCore // : public Watchable<CelestiaCore>
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<CelestiaCore>
EdgeInsets safeAreaInsets { 0, 0, 0, 0 };
MeasurementSystem measurement { Metric };
TemperatureScale temperatureScale { Kelvin };
Selection lastSelection;
std::string selectionNames;

View File

@ -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);

View File

@ -83,6 +83,7 @@ public:
std::string viewportEffect;
std::string warpMeshFile;
std::string measurementSystem;
std::string temperatureScale;
std::string x264EncoderOptions;
std::string ffvhEncoderOptions;