Add proper motion of stars (#3561)

This commit is contained in:
Alexander Bock
2025-03-20 09:55:19 +01:00
committed by GitHub
parent 6b35545f69
commit 28d0a778d5
4 changed files with 124 additions and 24 deletions

View File

@@ -300,6 +300,26 @@ namespace {
openspace::properties::Property::Visibility::AdvancedUser
};
constexpr openspace::properties::Property::PropertyInfo UseProperMotionInfo = {
"UseProperMotion",
"Enable proper motion of stars",
"If this setting is enabled and the loaded data file contains velocity "
"information for the stars, that information is used to move the stars' position "
"with progressing to show their proper motion through space."
};
constexpr openspace::properties::Property::PropertyInfo ProperMotionEpochInfo = {
"ProperMotionEpoch",
"Proper motion epoch",
"This value defines the epoch for the positions provided in the data file in "
"J2000 seconds. This value is only needed if the `ProperMotion` is enabled as "
"well, in which case it determines the epoch at which the position of the star "
"starts. This means that if the time in the application is at the epoch, the "
"stars will be exactly at their determined position without any velocity-based "
"offset. If this value is not specified, 2000-01-01 12:00:00 will be used as the "
"epoch instead."
};
constexpr openspace::properties::Property::PropertyInfo EnableFadeInInfo = {
"EnableFadeIn",
"Enable Fade-in effect",
@@ -398,6 +418,12 @@ namespace {
// [[codegen::verbatim(FadeInDistancesInfo.description)]]
std::optional<glm::dvec2> fadeInDistances;
// [[codegen::verbatim(UseProperMotionInfo.description)]]
std::optional<bool> useProperMotion;
// [[codegen::verbatim(ProperMotionEpochInfo.description)]]
std::optional<double> properMotionEpoch;
// [[codegen::verbatim(EnableFadeInInfo.description)]]
std::optional<bool> enableFadeIn;
};
@@ -472,6 +498,8 @@ RenderableStars::RenderableStars(const ghoul::Dictionary& dictionary)
glm::vec2(0.f),
glm::vec2(100.f)
)
, _useProperMotion(UseProperMotionInfo, true)
, _properMotionEpoch(ProperMotionEpochInfo, 0.0)
, _enableFadeInDistance(EnableFadeInInfo, false)
{
const Parameters p = codegen::bake<Parameters>(dictionary);
@@ -582,6 +610,15 @@ RenderableStars::RenderableStars(const ghoul::Dictionary& dictionary)
addProperty(_filterOutOfRange);
_useProperMotion.onChange([this]() { _dataIsDirty = true; });
_useProperMotion = p.useProperMotion.value_or(_useProperMotion);
addProperty(_useProperMotion);
_properMotionEpoch = p.properMotionEpoch.value_or(_properMotionEpoch);
addProperty(_properMotionEpoch);
auto markTextureAsDirty = [this]() {_pointSpreadFunctionTextureIsDirty = true; };
if (p.core.has_value()) {
@@ -763,6 +800,14 @@ void RenderableStars::render(const RenderData& data, RendererTasks&) {
glm::dmat4(data.camera.projectionMatrix()) * data.camera.combinedViewMatrix();
_program->setUniform(_uniformCache.cameraViewProjectionMatrix, viewProjectionMatrix);
_program->setUniform(_uniformCache.useProperMotion, _useProperMotion);
if (_useProperMotion) {
const double epoch = _properMotionEpoch;
const double curr = static_cast<double>(data.time.j2000Seconds());
const double diffTime = curr - epoch;
_program->setUniform(_uniformCache.diffTime, static_cast<float>(diffTime));
}
_program->setUniform(_uniformCache.colorOption, _colorOption);
_program->setUniform(_uniformCache.magnitudeExponent, _magnitudeExponent);
@@ -893,15 +938,37 @@ void RenderableStars::update(const UpdateData&) {
switch (colorOption) {
case ColorOption::Color:
case ColorOption::FixedColor:
glVertexAttribPointer(
bvLumAbsMagAttrib,
3,
GL_FLOAT,
GL_FALSE,
stride,
reinterpret_cast<void*>(offsetof(ColorVBOLayout, value))
);
if (_useProperMotion) {
glVertexAttribPointer(
bvLumAbsMagAttrib,
3,
GL_FLOAT,
GL_FALSE,
stride,
reinterpret_cast<void*>(offsetof(VelocityVBOLayout, value))
);
const GLint velocity = _program->attributeLocation("in_velocity");
glEnableVertexAttribArray(velocity);
glVertexAttribPointer(
velocity,
3,
GL_FLOAT,
GL_TRUE,
stride,
reinterpret_cast<void*>(offsetof(VelocityVBOLayout, vx))
);
}
else {
glVertexAttribPointer(
bvLumAbsMagAttrib,
3,
GL_FLOAT,
GL_FALSE,
stride,
reinterpret_cast<void*>(offsetof(ColorVBOLayout, value))
);
}
break;
case ColorOption::Velocity:
{
@@ -1070,18 +1137,38 @@ std::vector<float> RenderableStars::createDataSlice(ColorOption option) {
case ColorOption::Color:
case ColorOption::FixedColor:
{
union {
ColorVBOLayout value;
std::array<float, sizeof(ColorVBOLayout) / sizeof(float)> data;
} layout;
if (_useProperMotion) {
union {
VelocityVBOLayout value;
std::array<float, sizeof(VelocityVBOLayout) / sizeof(float)> data;
} layout;
layout.value.position = { pos.x, pos.y, pos.z };
layout.value.value = e.data[bvIdx];
layout.value.luminance = e.data[lumIdx];
layout.value.absoluteMagnitude = e.data[absMagIdx];
layout.value.position = { pos.x, pos.y, pos.z };
layout.value.value = e.data[bvIdx];
layout.value.luminance = e.data[lumIdx];
layout.value.absoluteMagnitude = e.data[absMagIdx];
result.insert(result.end(), layout.data.begin(), layout.data.end());
break;
layout.value.vx = e.data[vxIdx];
layout.value.vy = e.data[vyIdx];
layout.value.vz = e.data[vzIdx];
result.insert(result.end(), layout.data.begin(), layout.data.end());
break;
}
else {
union {
ColorVBOLayout value;
std::array<float, sizeof(ColorVBOLayout) / sizeof(float)> data;
} layout;
layout.value.position = { pos.x, pos.y, pos.z };
layout.value.value = e.data[bvIdx];
layout.value.luminance = e.data[lumIdx];
layout.value.absoluteMagnitude = e.data[absMagIdx];
result.insert(result.end(), layout.data.begin(), layout.data.end());
break;
}
}
case ColorOption::Velocity:
{

View File

@@ -126,15 +126,17 @@ private:
properties::FloatProperty _magnitudeExponent;
properties::Vec2Property _fadeInDistances;
properties::BoolProperty _useProperMotion;
properties::DoubleProperty _properMotionEpoch;
properties::BoolProperty _enableFadeInDistance;
std::unique_ptr<ghoul::opengl::ProgramObject> _program;
UniformCache(
modelMatrix, cameraViewProjectionMatrix, cameraUp, eyePosition, colorOption,
magnitudeExponent, sizeComposition, lumCent, radiusCent, colorTexture, opacity,
otherDataTexture, otherDataRange, filterOutOfRange, fixedColor, glareTexture,
glareMultiplier, glareGamma, glareScale, hasCore, coreTexture, coreMultiplier,
coreGamma, coreScale
useProperMotion, diffTime, magnitudeExponent, sizeComposition, lumCent,
radiusCent, colorTexture, opacity, otherDataTexture, otherDataRange,
filterOutOfRange, fixedColor, glareTexture, glareMultiplier, glareGamma,
glareScale, hasCore, coreTexture, coreMultiplier, coreGamma, coreScale
) _uniformCache;
bool _speckFileIsDirty = true;

View File

@@ -105,7 +105,7 @@ double scaleForDistanceModulus(float absMag) {
void main() {
vec3 pos = gl_in[0].gl_Position.xyz;
vs_position = pos; // in object space
dvec4 dpos = modelMatrix * dvec4(pos, 1.0);
dvec4 dpos = modelMatrix * dvec4(pos, 1.0);
ge_bv = vs_bvLumAbsMag[0].x;
ge_velocity = vs_velocity[0];

View File

@@ -33,11 +33,22 @@ out vec3 vs_bvLumAbsMag;
out vec3 vs_velocity;
out float vs_speed;
uniform int useProperMotion;
uniform float diffTime;
void main() {
vs_bvLumAbsMag = in_bvLumAbsMag;
vs_velocity = in_velocity;
vs_speed = in_speed;
gl_Position = vec4(in_position, 1.0);
if (useProperMotion == 1) {
// 1000 to get from km/s to m/s
dvec3 offsetInParsec = dvec3(in_velocity) * double(diffTime) * 1000.0;
vec3 pos = in_position + vec3(offsetInParsec);
gl_Position = vec4(pos, 1.0);
}
else {
gl_Position = vec4(in_position, 1.0);
}
}