diff --git a/include/openspace/util/distanceconstants.h b/include/openspace/util/distanceconstants.h index 695e463324..4184263485 100644 --- a/include/openspace/util/distanceconstants.h +++ b/include/openspace/util/distanceconstants.h @@ -35,6 +35,12 @@ namespace openspace::distanceconstants { constexpr double LightHour = LightDay / 24; constexpr double AstronomicalUnit = 1.495978707E11; constexpr double Parsec = 3.0856776E16; + + constexpr double Inch = 0.0254; + constexpr double Foot = 0.3048; + constexpr double Yard = 0.9144; + constexpr double Chain = 20.1168; + constexpr double Mile = 1609.344; } // openspace::distanceconstants #endif // __OPENSPACE_CORE___DISTANCECONSTANTS___H__ diff --git a/include/openspace/util/distanceconversion.h b/include/openspace/util/distanceconversion.h index 79258ba131..9cc496e5ef 100644 --- a/include/openspace/util/distanceconversion.h +++ b/include/openspace/util/distanceconversion.h @@ -39,6 +39,8 @@ enum class DistanceUnit { Nanometer = 0, Micrometer, Millimeter, + Centimeter, + Decimeter, Meter, Kilometer, AU, @@ -66,6 +68,8 @@ enum class DistanceUnit { constexpr const char* DistanceUnitNanometer = "nanometer"; constexpr const char* DistanceUnitMicrometer = "micrometer"; constexpr const char* DistanceUnitMillimeter = "millimeter"; +constexpr const char* DistanceUnitCentimeter = "centimeter"; +constexpr const char* DistanceUnitDecimeter = "decimeter"; constexpr const char* DistanceUnitMeter = "meter"; constexpr const char* DistanceUnitKilometer = "km"; constexpr const char* DistanceUnitAU = "AU"; @@ -91,6 +95,8 @@ constexpr const char* DistanceUnitLeague = "league"; constexpr const char* DistanceUnitNanometers = "nanometers"; constexpr const char* DistanceUnitMicrometers = "micrometers"; constexpr const char* DistanceUnitMillimeters = "millimeters"; +constexpr const char* DistanceUnitCentimeters = "centimeters"; +constexpr const char* DistanceUnitDecimeters = "decimeters"; constexpr const char* DistanceUnitMeters = "meters"; constexpr const char* DistanceUnitKilometers = "km"; constexpr const char* DistanceUnitAUs = "AU"; @@ -114,18 +120,20 @@ constexpr const char* DistanceUnitLeagues = "leagues"; constexpr const std::array(DistanceUnit::League) + 1> DistanceUnits = { DistanceUnit::Nanometer, DistanceUnit::Micrometer, DistanceUnit::Millimeter, - DistanceUnit::Meter, DistanceUnit::Kilometer, DistanceUnit::AU, - DistanceUnit::Lighthour, DistanceUnit::Lightday, DistanceUnit::Lightmonth, - DistanceUnit::Lightyear, DistanceUnit::Parsec, DistanceUnit::Kiloparsec, - DistanceUnit::Megaparsec, DistanceUnit::Gigaparsec, DistanceUnit::Thou, - DistanceUnit::Inch, DistanceUnit::Foot, DistanceUnit::Yard, DistanceUnit::Chain, - DistanceUnit::Furlong, DistanceUnit::Mile, DistanceUnit::League + DistanceUnit::Centimeter, DistanceUnit::Decimeter, DistanceUnit::Meter, + DistanceUnit::Kilometer, DistanceUnit::AU, DistanceUnit::Lighthour, + DistanceUnit::Lightday, DistanceUnit::Lightmonth, DistanceUnit::Lightyear, + DistanceUnit::Parsec, DistanceUnit::Kiloparsec, DistanceUnit::Megaparsec, + DistanceUnit::Gigaparsec, DistanceUnit::Thou, DistanceUnit::Inch, + DistanceUnit::Foot, DistanceUnit::Yard, DistanceUnit::Chain, DistanceUnit::Furlong, + DistanceUnit::Mile, DistanceUnit::League }; constexpr const std::array(DistanceUnit::League) + 1> DistanceUnitNamesSingular = { DistanceUnitNanometer, DistanceUnitMicrometer, DistanceUnitMillimeter, - DistanceUnitMeter, DistanceUnitKilometer, DistanceUnitAU, DistanceUnitLighthour, + DistanceUnitCentimeter, DistanceUnitDecimeter, DistanceUnitMeter, + DistanceUnitKilometer, DistanceUnitAU, DistanceUnitLighthour, DistanceUnitLightday, DistanceUnitLightmonth, DistanceUnitLightyear, DistanceUnitParsec, DistanceUnitKiloparsec, DistanceUnitMegaparsec, DistanceUnitGigaparsec, DistanceUnitThou, DistanceUnitInch, DistanceUnitFoot, @@ -136,7 +144,8 @@ DistanceUnitNamesSingular = { constexpr const std::array(DistanceUnit::League) + 1> DistanceUnitNamesPlural = { DistanceUnitNanometers, DistanceUnitMicrometers, DistanceUnitMillimeters, - DistanceUnitMeters, DistanceUnitKilometers, DistanceUnitAUs, DistanceUnitLighthours, + DistanceUnitCentimeters, DistanceUnitDecimeters, DistanceUnitMeters, + DistanceUnitKilometers, DistanceUnitAUs, DistanceUnitLighthours, DistanceUnitLightdays, DistanceUnitLightmonths, DistanceUnitLightyears, DistanceUnitParsecs, DistanceUnitKiloparsecs, DistanceUnitMegaparsecs, DistanceUnitGigaparsecs, DistanceUnitThous, DistanceUnitInches, DistanceUnitFeet, @@ -168,6 +177,8 @@ constexpr const char* nameForDistanceUnit(DistanceUnit unit, bool pluralForm = f case DistanceUnit::Nanometer: case DistanceUnit::Micrometer: case DistanceUnit::Millimeter: + case DistanceUnit::Centimeter: + case DistanceUnit::Decimeter: case DistanceUnit::Meter: case DistanceUnit::Kilometer: case DistanceUnit::AU: @@ -232,7 +243,7 @@ constexpr DistanceUnit distanceUnitFromString(const char* unitName) { std::pair simplifyDistance(double meters, bool forceSingularForm = false); -constexpr double convertDistance(double meters, DistanceUnit requestedUnit) { +constexpr double convertMeters(double meters, DistanceUnit requestedUnit) { switch (requestedUnit) { case DistanceUnit::Nanometer: return meters / 1e-9; @@ -240,6 +251,10 @@ constexpr double convertDistance(double meters, DistanceUnit requestedUnit) { return meters / 1e-6; case DistanceUnit::Millimeter: return meters / 1e-3; + case DistanceUnit::Centimeter: + return meters / 1e-2; + case DistanceUnit::Decimeter: + return meters / 1e-1; case DistanceUnit::Meter: return meters; case DistanceUnit::Kilometer: @@ -262,7 +277,6 @@ constexpr double convertDistance(double meters, DistanceUnit requestedUnit) { return meters / (1e6 * distanceconstants::Parsec); case DistanceUnit::Gigaparsec: return meters / (1e9 * distanceconstants::Parsec); - // Such wow, such coefficients case DistanceUnit::Thou: return (meters * 1000.0 / 25.4) * 1000.0; // m -> mm -> inch -> thou case DistanceUnit::Inch: @@ -289,6 +303,69 @@ constexpr double convertDistance(double meters, DistanceUnit requestedUnit) { } } +constexpr double toMeter(DistanceUnit unit) { + switch (unit) { + case DistanceUnit::Nanometer: + return 1e-9; + case DistanceUnit::Micrometer: + return 1e-6; + case DistanceUnit::Millimeter: + return 1e-3; + case DistanceUnit::Centimeter: + return 1e-2; + case DistanceUnit::Decimeter: + return 1e-1; + case DistanceUnit::Meter: + return 1.0; + case DistanceUnit::Kilometer: + return 1000.0; + case DistanceUnit::AU: + return distanceconstants::AstronomicalUnit; + case DistanceUnit::Lighthour: + return distanceconstants::LightHour; + case DistanceUnit::Lightday: + return distanceconstants::LightDay; + case DistanceUnit::Lightmonth: + return distanceconstants::LightMonth; + case DistanceUnit::Lightyear: + return distanceconstants::LightYear; + case DistanceUnit::Parsec: + return distanceconstants::Parsec; + case DistanceUnit::Kiloparsec: + return 1e3 * distanceconstants::Parsec; + case DistanceUnit::Megaparsec: + return 1e6 * distanceconstants::Parsec; + case DistanceUnit::Gigaparsec: + return 1e9 * distanceconstants::Parsec; + case DistanceUnit::Thou: + return 1e-3 * distanceconstants::Inch; + case DistanceUnit::Inch: + return distanceconstants::Inch; + case DistanceUnit::Foot: + return distanceconstants::Foot; + case DistanceUnit::Yard: + return distanceconstants::Yard; + case DistanceUnit::Chain: + return distanceconstants::Chain; + case DistanceUnit::Furlong: + return 10.0 * distanceconstants::Chain; + case DistanceUnit::Mile: + return distanceconstants::Mile; + case DistanceUnit::League: + return 3.0 * distanceconstants::Mile; + default: + throw ghoul::MissingCaseException(); + } +} + +constexpr double convertUnit(DistanceUnit fromUnit, DistanceUnit toUnit) { + return convertMeters(toMeter(fromUnit), toUnit); +} + +constexpr double convertDistance(double distance, DistanceUnit fromUnit, DistanceUnit toUnit) { + return distance * convertUnit(fromUnit, toUnit); +} + float convertMasPerYearToMeterPerSecond(float masPerYear, float parallax); } // namespace openspace diff --git a/modules/base/dashboard/dashboarditemdistance.cpp b/modules/base/dashboard/dashboarditemdistance.cpp index bcca68c879..bfb364ad2d 100644 --- a/modules/base/dashboard/dashboarditemdistance.cpp +++ b/modules/base/dashboard/dashboarditemdistance.cpp @@ -368,7 +368,7 @@ void DashboardItemDistance::render(glm::vec2& penPosition) { } else { const DistanceUnit unit = static_cast(_requestedUnit.value()); - const double convertedD = convertDistance(d, unit); + const double convertedD = convertMeters(d, unit); dist = { convertedD, nameForDistanceUnit(unit, convertedD != 1.0) }; } @@ -399,7 +399,7 @@ glm::vec2 DashboardItemDistance::size() const { } else { DistanceUnit unit = static_cast(_requestedUnit.value()); - double convertedD = convertDistance(d, unit); + double convertedD = convertMeters(d, unit); dist = { convertedD, nameForDistanceUnit(unit, convertedD != 1.0) }; } diff --git a/modules/base/dashboard/dashboarditemvelocity.cpp b/modules/base/dashboard/dashboarditemvelocity.cpp index d71e4c585d..587e83f4f3 100644 --- a/modules/base/dashboard/dashboarditemvelocity.cpp +++ b/modules/base/dashboard/dashboarditemvelocity.cpp @@ -133,7 +133,7 @@ void DashboardItemVelocity::render(glm::vec2& penPosition) { } else { const DistanceUnit unit = static_cast(_requestedUnit.value()); - const double convertedD = convertDistance(speedPerSecond, unit); + const double convertedD = convertMeters(speedPerSecond, unit); dist = { convertedD, nameForDistanceUnit(unit, convertedD != 1.0) }; } @@ -159,7 +159,7 @@ glm::vec2 DashboardItemVelocity::size() const { } else { DistanceUnit unit = static_cast(_requestedUnit.value()); - double convertedD = convertDistance(d, unit); + double convertedD = convertMeters(d, unit); dist = { convertedD, nameForDistanceUnit(unit, convertedD != 1.0) }; } diff --git a/modules/base/rendering/renderablemodel.cpp b/modules/base/rendering/renderablemodel.cpp index 4d991aa8e9..47f0b45af6 100644 --- a/modules/base/rendering/renderablemodel.cpp +++ b/modules/base/rendering/renderablemodel.cpp @@ -148,6 +148,20 @@ namespace { // This specifies the model that is rendered by the Renderable. std::variant> geometryFile; + enum class ScaleUnit { + Nanometer [[codegen::key("nm")]], + Micrometer [[codegen::key("um")]], + Millimeter [[codegen::key("mm")]], + Centimeter [[codegen::key("cm")]], + Decimeter [[codegen::key("dm")]], + Meter [[codegen::key("m")]], + Kilometer [[codegen::key("km")]] + }; + + // The scale of the model. For example if the model is in centimeters + // then ModelScale=cm + std::optional modelScale; + // Set if invisible parts (parts with no textures or materials) of the model // should be forced to render or not. std::optional forceRenderInvisible; @@ -320,6 +334,38 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary) }*/ } + if (p.modelScale.has_value()) { + Parameters::ScaleUnit scaleUnit = *p.modelScale; + + switch (scaleUnit) { + case Parameters::ScaleUnit::Nanometer: + _modelScale = DistanceUnit::Nanometer; + break; + case Parameters::ScaleUnit::Micrometer: + _modelScale = DistanceUnit::Micrometer; + break; + case Parameters::ScaleUnit::Millimeter: + _modelScale = DistanceUnit::Millimeter; + break; + case Parameters::ScaleUnit::Centimeter: + _modelScale = DistanceUnit::Centimeter; + break; + case Parameters::ScaleUnit::Decimeter: + _modelScale = DistanceUnit::Decimeter; + break; + case Parameters::ScaleUnit::Meter: + _modelScale = DistanceUnit::Meter; + break; + case Parameters::ScaleUnit::Kilometer: + _modelScale = DistanceUnit::Kilometer; + break; + default: + throw ghoul::MissingCaseException(); + } + + _scaleVector = glm::dvec3(convertUnit(_modelScale, DistanceUnit::Meter)); + } + if (p.animationStartTime.has_value()) { if (!_geometry->hasAnimation()) { LWARNING("Animation start time given to model without animation"); @@ -546,9 +592,8 @@ void RenderableModel::render(const RenderData& data, RendererTasks&) { const glm::dmat4 modelTransform = glm::translate(glm::dmat4(1.0), data.modelTransform.translation) * // Translation glm::dmat4(data.modelTransform.rotation) * // Spice rotation - glm::scale( - glm::dmat4(_modelTransform.value()), glm::dvec3(data.modelTransform.scale) - ); + glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale)) * + glm::scale(glm::dmat4(_modelTransform.value()), _scaleVector); // Model scale unit const glm::dmat4 modelViewTransform = data.camera.combinedViewMatrix() * modelTransform; diff --git a/modules/base/rendering/renderablemodel.h b/modules/base/rendering/renderablemodel.h index 167158b4fd..e0c6449e7b 100644 --- a/modules/base/rendering/renderablemodel.h +++ b/modules/base/rendering/renderablemodel.h @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -79,6 +80,8 @@ private: }; std::unique_ptr _geometry; + DistanceUnit _modelScale; + glm::dvec3 _scaleVector = glm::dvec3(1.0, 1.0, 1.0); bool _forceRenderInvisible = false; bool _notifyInvisibleDropped = true; std::string _animationStart = "";