From 92085847f2137d57bd47f828f22a04185fc2546e Mon Sep 17 00:00:00 2001 From: Emma Broman Date: Fri, 11 Dec 2020 14:13:36 +0100 Subject: [PATCH] Try to make RenderableOrbitDisc more intuitive * The size now matches the semi-major axis * Avoid re-setting size value in constructor * Avoid inconsistent units for offsets and size (previously AU and meter) --- modules/exoplanets/exoplanetsmodule_lua.inl | 27 +++++++++++-------- .../rendering/renderableorbitdisc.cpp | 26 +++++++++--------- .../rendering/renderableorbitdisc.h | 4 +-- modules/exoplanets/shaders/orbitdisc_fs.glsl | 27 ++++++++++--------- 4 files changed, 46 insertions(+), 38 deletions(-) diff --git a/modules/exoplanets/exoplanetsmodule_lua.inl b/modules/exoplanets/exoplanetsmodule_lua.inl index f82db2f959..c6673e021a 100644 --- a/modules/exoplanets/exoplanetsmodule_lua.inl +++ b/modules/exoplanets/exoplanetsmodule_lua.inl @@ -58,7 +58,7 @@ constexpr const char* DiscTextureFile = constexpr const char* HabitableZoneTextureFile = "${SYNC}/http/exoplanets_textures/1/hz_disc_texture.png"; -const float AstronomicalUnit = static_cast(distanceconstants::AstronomicalUnit); +const float AU = static_cast(distanceconstants::AstronomicalUnit); const float SolarRadius = static_cast(distanceconstants::SolarRadius); const float JupiterRadius = static_cast(distanceconstants::JupiterRadius); @@ -280,7 +280,7 @@ void createExoplanetSystem(const std::string& starName) { std::string enabled; if (std::isnan(planet.r)) { if (std::isnan(planet.rStar)) { - planetRadius = planet.a * 0.001f * AstronomicalUnit; + planetRadius = planet.a * 0.001f * AU; } else { planetRadius = planet.rStar * 0.1f * SolarRadius; @@ -293,7 +293,7 @@ void createExoplanetSystem(const std::string& starName) { } const float periodInSeconds = static_cast(planet.per * SecondsPerDay); - const float semiMajorAxisInMeter = planet.a * AstronomicalUnit; + const float semiMajorAxisInMeter = planet.a * AU; const float semiMajorAxisInKm = semiMajorAxisInMeter * 0.001f; const std::string planetIdentifier = createIdentifier(planetName); @@ -373,6 +373,9 @@ void createExoplanetSystem(const std::string& starName) { ); const glm::dmat3 rotationMat3 = static_cast(rotation); + const float lowerOffset = planet.aLower / planet.a; + const float upperOffset = planet.aUpper / planet.a; + const std::string discNode = "{" "Identifier = '" + planetIdentifier + "_Disc'," "Parent = '" + starIdentifier + "'," @@ -383,8 +386,8 @@ void createExoplanetSystem(const std::string& starName) { "Size = " + std::to_string(semiMajorAxisInMeter) + "," "Eccentricity = " + std::to_string(planet.ecc) + "," "Offset = { " + - std::to_string(planet.aLower) + ", " + - std::to_string(planet.aUpper) + + std::to_string(lowerOffset) + ", " + + std::to_string(upperOffset) + "}," //min / max extend "Opacity = 0.3" "}," @@ -425,9 +428,11 @@ void createExoplanetSystem(const std::string& starName) { const glm::dmat4 rotation = computeOrbitPlaneRotationMatrix(meanInclination); const glm::dmat3 rotationMat3 = static_cast(rotation); - glm::vec2 limits = zone.value(); - float half = 0.5f * (limits[1] - limits[0]); - float center = limits[0] + half; + glm::vec2 limitsInMeter = zone.value() * AU; + float half = 0.5f * (limitsInMeter[1] - limitsInMeter[0]); + float center = limitsInMeter[0] + half; + float relativeOffset = half / center; + const std::string zoneDiscNode = "{" "Identifier = '" + starIdentifier + "_HZ_Disc'," "Parent = '" + starIdentifier + "'," @@ -439,11 +444,11 @@ void createExoplanetSystem(const std::string& starName) { "Rotation = " + ghoul::to_string(rotationMat3) + "" "}," "Texture = openspace.absPath('" + HabitableZoneTextureFile + "')," - "Size = " + std::to_string(center * AstronomicalUnit) + "," + "Size = " + std::to_string(center) + "," "Eccentricity = 0," "Offset = { " + - std::to_string(half) + ", " + - std::to_string(half) + + std::to_string(relativeOffset) + ", " + + std::to_string(relativeOffset) + "}," //min / max extend "Opacity = 0.05" "}," diff --git a/modules/exoplanets/rendering/renderableorbitdisc.cpp b/modules/exoplanets/rendering/renderableorbitdisc.cpp index 319b78b3b0..4e74e8526c 100644 --- a/modules/exoplanets/rendering/renderableorbitdisc.cpp +++ b/modules/exoplanets/rendering/renderableorbitdisc.cpp @@ -50,7 +50,7 @@ namespace { static const openspace::properties::Property::PropertyInfo SizeInfo = { "Size", "Size", - "This value specifies the semi-major axis of the orbit in meter." + "This value specifies the semi-major axis of the orbit, in meter." }; static const openspace::properties::Property::PropertyInfo EccentricityInfo = { @@ -63,8 +63,10 @@ namespace { static const openspace::properties::Property::PropertyInfo OffsetInfo = { "Offset", "Offset", - "This value is used to limit the width of the rings. Each of the two values is " - "the lower and the upper uncertainties of the semi-major axis. " + "This property determines the width of the disc. The values specify the lower " + "and upper deviation from the semi major axis, respectively. The values are " + "relative to the size of the semi-major axis. That is, 0 means no deviation " + "from the semi-major axis and 1 is a whole semi-major axis's worth of deviation." }; } // namespace @@ -114,7 +116,7 @@ RenderableOrbitDisc::RenderableOrbitDisc(const ghoul::Dictionary& dictionary) , _texturePath(TextureInfo) , _size(SizeInfo, 1.f, 0.f, 3.0e12f) , _eccentricity(EccentricityInfo, 0.f, 0.f, 1.f) - , _offset(OffsetInfo, glm::vec2(0.f, 1.f), glm::vec2(0.f), glm::vec2(1.f)) + , _offset(OffsetInfo, glm::vec2(0.f), glm::vec2(0.f), glm::vec2(1.f)) { using ghoul::filesystem::File; @@ -127,16 +129,15 @@ RenderableOrbitDisc::RenderableOrbitDisc(const ghoul::Dictionary& dictionary) if (dictionary.hasKey(OffsetInfo.identifier)) { _offset = dictionary.value(OffsetInfo.identifier); } + _offset.onChange([&]() { _planeIsDirty = true; }); addProperty(_offset); _size = static_cast(dictionary.value(SizeInfo.identifier)); - _size = static_cast( - _size + (_offset.value().y * distanceconstants::AstronomicalUnit) - ); - setBoundingSphere(_size); _size.onChange([&]() { _planeIsDirty = true; }); addProperty(_size); + setBoundingSphere(_size + _offset.value().y * _size); + _texturePath = absPath(dictionary.value(TextureInfo.identifier)); _textureFile = std::make_unique(_texturePath); @@ -168,7 +169,7 @@ void RenderableOrbitDisc::initializeGL() { _uniformCache.modelViewProjection = _shader->uniformLocation( "modelViewProjectionTransform" ); - _uniformCache.textureOffset = _shader->uniformLocation("textureOffset"); + _uniformCache.offset = _shader->uniformLocation("offset"); _uniformCache.opacity = _shader->uniformLocation("opacity"); _uniformCache.texture = _shader->uniformLocation("discTexture"); _uniformCache.eccentricity = _shader->uniformLocation("eccentricity"); @@ -209,7 +210,7 @@ void RenderableOrbitDisc::render(const RenderData& data, RendererTasks&) { _uniformCache.modelViewProjection, data.camera.projectionMatrix() * glm::mat4(modelViewTransform) ); - _shader->setUniform(_uniformCache.textureOffset, _offset); + _shader->setUniform(_uniformCache.offset, _offset); _shader->setUniform(_uniformCache.opacity, _opacity); _shader->setUniform(_uniformCache.eccentricity, _eccentricity); _shader->setUniform(_uniformCache.semiMajorAxis, _size); @@ -241,7 +242,7 @@ void RenderableOrbitDisc::update(const UpdateData&) { _uniformCache.modelViewProjection = _shader->uniformLocation( "modelViewProjectionTransform" ); - _uniformCache.textureOffset = _shader->uniformLocation("textureOffset"); + _uniformCache.offset = _shader->uniformLocation("offset"); _uniformCache.opacity = _shader->uniformLocation("opacity"); _uniformCache.texture = _shader->uniformLocation("discTexture"); _uniformCache.eccentricity = _shader->uniformLocation("eccentricity"); @@ -283,7 +284,8 @@ void RenderableOrbitDisc::loadTexture() { } void RenderableOrbitDisc::createPlane() { - const GLfloat size = _size * (1.f + _eccentricity); + const GLfloat outerDistance = (_size + _offset.value().y * _size); + const GLfloat size = outerDistance * (1.f + _eccentricity); struct VertexData { GLfloat x; diff --git a/modules/exoplanets/rendering/renderableorbitdisc.h b/modules/exoplanets/rendering/renderableorbitdisc.h index b7d55b6268..b0f1735d4d 100644 --- a/modules/exoplanets/rendering/renderableorbitdisc.h +++ b/modules/exoplanets/rendering/renderableorbitdisc.h @@ -66,8 +66,8 @@ private: properties::Vec2Property _offset; std::unique_ptr _shader = nullptr; - UniformCache(modelViewProjection, textureOffset, opacity, - texture, eccentricity, semiMajorAxis) _uniformCache; + UniformCache(modelViewProjection, offset, opacity, texture, + eccentricity, semiMajorAxis) _uniformCache; std::unique_ptr _texture = nullptr; std::unique_ptr _textureFile; diff --git a/modules/exoplanets/shaders/orbitdisc_fs.glsl b/modules/exoplanets/shaders/orbitdisc_fs.glsl index bf8cb01c5c..8032095f44 100644 --- a/modules/exoplanets/shaders/orbitdisc_fs.glsl +++ b/modules/exoplanets/shaders/orbitdisc_fs.glsl @@ -29,12 +29,11 @@ in vec2 vs_st; in vec4 vs_position; uniform sampler1D discTexture; -uniform vec2 textureOffset; +uniform vec2 offset; // relative to semi major axis uniform float opacity; uniform float eccentricity; uniform float semiMajorAxis; -const float AstronomicalUnit = 149597870700.0; // m const float Epsilon = 0.0000001; // Compute semi minor axis from major axis, a, and eccentricity, e @@ -56,16 +55,15 @@ Fragment getFragment() { // Moving the origin to the center vec2 st = (vs_st - vec2(0.5)) * 2.0; - float offsetLower = textureOffset.x; - float offsetUpper = textureOffset.y; - float offsetIntervalSize = offsetLower + offsetUpper; + float offsetLower = offset.x * semiMajorAxis; + float offsetUpper = offset.y * semiMajorAxis; - float AUpper = semiMajorAxis; + float AUpper = semiMajorAxis + offsetUpper; float BUpper = semiMinorAxis(AUpper, eccentricity); float CUpper = sqrt(AUpper*AUpper - BUpper*BUpper); float outerApoapsisDistance = AUpper * (1 + eccentricity); - float ALower = AUpper - AstronomicalUnit * offsetIntervalSize; + float ALower = semiMajorAxis - offsetLower; float BLower = semiMinorAxis(ALower, eccentricity); float CLower = sqrt(ALower*ALower - BLower*BLower); float innerApoapsisDistance = ALower * (1 + eccentricity); @@ -106,16 +104,19 @@ Fragment getFragment() { float discWidth = distance(outerPoint, innerPoint); float distanceFromOuterEdge = distance(outerPoint, st); - float textureCoord = distanceFromOuterEdge / discWidth; + float relativeDistance = distanceFromOuterEdge / discWidth; - // Scale texture coordinate to handle asymmetric offset intervals - float textureMid = offsetUpper / offsetIntervalSize; + // Compute texture coordinate based on the distance to outer edge + float textureCoord = 0.0; - if(textureCoord > textureMid) { - textureCoord = 0.5 + 0.5 * (textureCoord - textureMid) / (1.0 - textureMid); + // The midpoint (textureCoord = 0.5) depends on the ratio between the offsets + // (Note that the texture goes from outer to inner edge of disc) + float midPoint = offsetUpper / (offsetUpper + offsetLower); + if(relativeDistance > midPoint) { + textureCoord = 0.5 + 0.5 * (relativeDistance - midPoint) / (1.0 - midPoint); } else { - textureCoord = 0.5 * textureCoord / textureMid; + textureCoord = 0.5 * (relativeDistance / midPoint); } vec4 diffuse = texture(discTexture, textureCoord);