mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-02-26 14:58:51 -06:00
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)
This commit is contained in:
@@ -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<float>(distanceconstants::AstronomicalUnit);
|
||||
const float AU = static_cast<float>(distanceconstants::AstronomicalUnit);
|
||||
const float SolarRadius = static_cast<float>(distanceconstants::SolarRadius);
|
||||
const float JupiterRadius = static_cast<float>(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<float>(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<glm::dmat3>(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<glm::dmat3>(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"
|
||||
"},"
|
||||
|
||||
@@ -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<glm::vec2>(OffsetInfo.identifier);
|
||||
}
|
||||
_offset.onChange([&]() { _planeIsDirty = true; });
|
||||
addProperty(_offset);
|
||||
|
||||
_size = static_cast<float>(dictionary.value<double>(SizeInfo.identifier));
|
||||
_size = static_cast<float>(
|
||||
_size + (_offset.value().y * distanceconstants::AstronomicalUnit)
|
||||
);
|
||||
setBoundingSphere(_size);
|
||||
_size.onChange([&]() { _planeIsDirty = true; });
|
||||
addProperty(_size);
|
||||
|
||||
setBoundingSphere(_size + _offset.value().y * _size);
|
||||
|
||||
_texturePath = absPath(dictionary.value<std::string>(TextureInfo.identifier));
|
||||
_textureFile = std::make_unique<File>(_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;
|
||||
|
||||
@@ -66,8 +66,8 @@ private:
|
||||
properties::Vec2Property _offset;
|
||||
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _shader = nullptr;
|
||||
UniformCache(modelViewProjection, textureOffset, opacity,
|
||||
texture, eccentricity, semiMajorAxis) _uniformCache;
|
||||
UniformCache(modelViewProjection, offset, opacity, texture,
|
||||
eccentricity, semiMajorAxis) _uniformCache;
|
||||
std::unique_ptr<ghoul::opengl::Texture> _texture = nullptr;
|
||||
std::unique_ptr<ghoul::filesystem::File> _textureFile;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user