Add model scale that can be set in asset file for each model

* Add cm and dm as units in DistanceUnits

* Scale the model according to the set unit
This commit is contained in:
Malin Ejdbo
2021-03-24 10:47:40 +01:00
parent aa5394e88c
commit 3a976ba0b0
6 changed files with 148 additions and 17 deletions

View File

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

View File

@@ -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, static_cast<int>(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<const char*, static_cast<int>(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<const char*, static_cast<int>(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<double, std::string> 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

View File

@@ -368,7 +368,7 @@ void DashboardItemDistance::render(glm::vec2& penPosition) {
}
else {
const DistanceUnit unit = static_cast<DistanceUnit>(_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<DistanceUnit>(_requestedUnit.value());
double convertedD = convertDistance(d, unit);
double convertedD = convertMeters(d, unit);
dist = { convertedD, nameForDistanceUnit(unit, convertedD != 1.0) };
}

View File

@@ -133,7 +133,7 @@ void DashboardItemVelocity::render(glm::vec2& penPosition) {
}
else {
const DistanceUnit unit = static_cast<DistanceUnit>(_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<DistanceUnit>(_requestedUnit.value());
double convertedD = convertDistance(d, unit);
double convertedD = convertMeters(d, unit);
dist = { convertedD, nameForDistanceUnit(unit, convertedD != 1.0) };
}

View File

@@ -148,6 +148,20 @@ namespace {
// This specifies the model that is rendered by the Renderable.
std::variant<std::string, std::vector<std::string>> 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<ScaleUnit> modelScale;
// Set if invisible parts (parts with no textures or materials) of the model
// should be forced to render or not.
std::optional<bool> 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;

View File

@@ -33,6 +33,7 @@
#include <openspace/properties/scalar/boolproperty.h>
#include <openspace/properties/scalar/floatproperty.h>
#include <openspace/properties/vector/vec3property.h>
#include <openspace/util/distanceconversion.h>
#include <ghoul/misc/managedmemoryuniqueptr.h>
#include <ghoul/io/model/modelreader.h>
#include <ghoul/opengl/uniformcache.h>
@@ -79,6 +80,8 @@ private:
};
std::unique_ptr<ghoul::modelgeometry::ModelGeometry> _geometry;
DistanceUnit _modelScale;
glm::dvec3 _scaleVector = glm::dvec3(1.0, 1.0, 1.0);
bool _forceRenderInvisible = false;
bool _notifyInvisibleDropped = true;
std::string _animationStart = "";