Merge branch 'master' into thesis/2025/black-hole

This commit is contained in:
Wilhelm Björkström
2025-03-12 09:22:11 +01:00
49 changed files with 467 additions and 225 deletions

View File

@@ -63,7 +63,8 @@ documentation::Documentation ConstantRotation::Documentation() {
}
ConstantRotation::ConstantRotation(const ghoul::Dictionary& dictionary)
: _rotationAxis(
: Rotation(dictionary)
, _rotationAxis(
RotationInfo,
glm::dvec3(0.0, 0.0, 1.0),
glm::dvec3(-1.0),

View File

@@ -37,6 +37,8 @@
#include <variant>
namespace {
constexpr std::string_view _loggerCat = "FixedRotation";
constexpr openspace::properties::Property::PropertyInfo EnableInfo = {
"Enable",
"Enabled",
@@ -243,7 +245,8 @@ documentation::Documentation FixedRotation::Documentation() {
}
FixedRotation::FixedRotation(const ghoul::Dictionary& dictionary)
: _enabled(EnableInfo, true)
: Rotation(dictionary)
, _enabled(EnableInfo, true)
, _xAxis{
properties::OptionProperty(
XAxisTypeInfo,
@@ -543,8 +546,7 @@ glm::dmat3 FixedRotation::matrix(const UpdateData&) const {
glm::dot(y, z) > 1.f - Epsilon ||
glm::dot(x, z) > 1.f - Epsilon) [[unlikely]]
{
LWARNINGC(
"FixedRotation",
LWARNING(
std::format(
"Near-collinear vectors detected: "
"x ({}, {}, {}) y ({}, {}, {}) z ({}, {}, {})",
@@ -564,7 +566,7 @@ glm::dmat3 FixedRotation::matrix(const UpdateData&) const {
glm::vec3 FixedRotation::xAxis() const {
switch (_xAxis.type) {
case Axis::Type::Unspecified:
LWARNINGC("FixedRotation", "Unspecified axis type for X axis");
LWARNING("Unspecified axis type for X axis");
return glm::vec3(1.f, 0.f, 0.f);
case Axis::Type::Object:
if (_xAxis.node && _attachedNode) {
@@ -579,17 +581,19 @@ glm::vec3 FixedRotation::xAxis() const {
}
else {
if (_xAxis.node) {
LWARNINGC("FixedRotation", "Missing attachment node");
LWARNING("Missing attachment node");
return glm::vec3(1.f, 0.f, 0.f);
}
else {
LWARNINGC("FixedRotation", "Missing node for X axis");
LWARNING(std::format(
"Missing node '{}' for X axis", _xAxis.object.value()
));
return glm::vec3(1.f, 0.f, 0.f);
}
}
case Axis::Type::Vector:
if (_xAxis.vector.value() == glm::vec3(0.f)) {
LWARNINGC("FixedRotation", "Zero vector detected for X Axis");
LWARNING("Zero vector detected for X Axis");
return glm::vec3(1.f, 0.f, 0.f);
}
else {
@@ -597,7 +601,7 @@ glm::vec3 FixedRotation::xAxis() const {
}
case Axis::Type::OrthogonalVector:
if (_xAxis.vector.value() == glm::vec3(0.f)) {
LWARNINGC("FixedRotation", "Zero vector detected for X Axis");
LWARNING("Zero vector detected for X Axis");
return glm::vec3(1.f, 0.f, 0.f);
}
else {
@@ -622,7 +626,7 @@ glm::vec3 FixedRotation::xAxis() const {
glm::vec3 FixedRotation::yAxis() const {
switch (_yAxis.type) {
case Axis::Type::Unspecified:
LWARNINGC("FixedRotation", "Unspecified axis type for Y axis");
LWARNING("Unspecified axis type for Y axis");
return glm::vec3(0.f, 1.f, 0.f);
case Axis::Type::Object:
if (_yAxis.node && _attachedNode) {
@@ -635,17 +639,19 @@ glm::vec3 FixedRotation::yAxis() const {
}
else {
if (_yAxis.node) {
LWARNINGC("FixedRotation", "Missing attachment node");
LWARNING("Missing attachment node");
return glm::vec3(0.f, 1.f, 0.f);
}
else {
LWARNINGC("FixedRotation", "Missing node for Y axis");
LWARNING(std::format(
"Missing node '{}' for Y axis", _yAxis.object.value()
));
return glm::vec3(0.f, 1.f, 0.f);
}
}
case Axis::Type::Vector:
if (_yAxis.vector.value() == glm::vec3(0.f)) {
LWARNINGC("FixedRotation", "Zero vector detected for Y Axis");
LWARNING("Zero vector detected for Y Axis");
return glm::vec3(0.f, 1.f, 0.f);
}
else {
@@ -653,7 +659,7 @@ glm::vec3 FixedRotation::yAxis() const {
}
case Axis::Type::OrthogonalVector:
if (_yAxis.vector.value() == glm::vec3(0.f)) {
LWARNINGC("FixedRotation", "Zero vector detected for Y Axis");
LWARNING("Zero vector detected for Y Axis");
return glm::vec3(0.f, 1.f, 0.f);
}
else {
@@ -678,7 +684,7 @@ glm::vec3 FixedRotation::yAxis() const {
glm::vec3 FixedRotation::zAxis() const {
switch (_zAxis.type) {
case Axis::Type::Unspecified:
LWARNINGC("FixedRotation", "Unspecified axis type for Z axis");
LWARNING("Unspecified axis type for Z axis");
return glm::vec3(0.f, 0.f, 1.f);
case Axis::Type::Object:
if (_zAxis.node && _attachedNode) {
@@ -689,17 +695,19 @@ glm::vec3 FixedRotation::zAxis() const {
}
else {
if (_zAxis.node) {
LWARNINGC("FixedRotation", "Missing attachment node");
LWARNING("Missing attachment node");
return glm::vec3(0.f, 0.f, 1.f);
}
else {
LWARNINGC("FixedRotation", "Missing node for Z axis");
LWARNING(std::format(
"Missing node '{}' for Z axis", _zAxis.object.value()
));
return glm::vec3(0.f, 0.f, 1.f);
}
}
case Axis::Type::Vector:
if (_zAxis.vector.value() == glm::vec3(0.f)) {
LWARNINGC("FixedRotation", "Zero vector detected for Z Axis");
LWARNING("Zero vector detected for Z Axis");
return glm::vec3(0.f, 0.f, 1.f);
}
else {
@@ -707,7 +715,7 @@ glm::vec3 FixedRotation::zAxis() const {
}
case Axis::Type::OrthogonalVector:
if (_zAxis.vector.value() == glm::vec3(0.f)) {
LWARNINGC("FixedRotation", "Zero vector detected for Z Axis");
LWARNING("Zero vector detected for Z Axis");
return glm::vec3(0.f, 0.f, 1.f);
}
else {

View File

@@ -65,7 +65,8 @@ documentation::Documentation LuaRotation::Documentation() {
}
LuaRotation::LuaRotation(const ghoul::Dictionary& dictionary)
: _luaScriptFile(ScriptInfo)
: Rotation(dictionary)
, _luaScriptFile(ScriptInfo)
{
const Parameters p = codegen::bake<Parameters>(dictionary);

View File

@@ -48,7 +48,9 @@ documentation::Documentation MultiRotation::Documentation() {
return codegen::doc<Parameters>("base_transform_rotation_multi");
}
MultiRotation::MultiRotation(const ghoul::Dictionary& dictionary) {
MultiRotation::MultiRotation(const ghoul::Dictionary& dictionary)
: Rotation(dictionary)
{
const Parameters p = codegen::bake<Parameters>(dictionary);
int i = 0;

View File

@@ -84,24 +84,22 @@ documentation::Documentation StaticRotation::Documentation() {
return codegen::doc<Parameters>("base_transform_rotation_static");
}
StaticRotation::StaticRotation()
: _eulerRotation(
StaticRotation::StaticRotation(const ghoul::Dictionary& dictionary)
: Rotation(dictionary)
, _eulerRotation(
RotationInfo,
glm::vec3(0.f),
glm::vec3(-glm::pi<float>()),
glm::vec3(glm::pi<float>())
)
{
addProperty(_eulerRotation);
const Parameters p = codegen::bake<Parameters>(dictionary);
_eulerRotation.onChange([this]() {
_matrixIsDirty = true;
requireUpdate();
});
_type = "StaticRotation";
}
StaticRotation::StaticRotation(const ghoul::Dictionary& dictionary) : StaticRotation() {
const Parameters p = codegen::bake<Parameters>(dictionary);
addProperty(_eulerRotation);
if (std::holds_alternative<glm::dvec3>(p.rotation)) {
_eulerRotation = std::get<glm::dvec3>(p.rotation);
@@ -116,7 +114,6 @@ StaticRotation::StaticRotation(const ghoul::Dictionary& dictionary) : StaticRota
_eulerRotation = rotationMatrixToEulerAngles(std::get<glm::dmat3>(p.rotation));
}
_matrixIsDirty = true;
_type = "StaticRotation";
}
glm::dmat3 StaticRotation::matrix(const UpdateData&) const {

View File

@@ -35,7 +35,6 @@ namespace documentation { struct Documentation; }
class StaticRotation : public Rotation {
public:
StaticRotation();
explicit StaticRotation(const ghoul::Dictionary& dictionary);
glm::dmat3 matrix(const UpdateData& data) const override;

View File

@@ -58,7 +58,8 @@ documentation::Documentation TimelineRotation::Documentation() {
}
TimelineRotation::TimelineRotation(const ghoul::Dictionary& dictionary)
: _shouldInterpolate(ShouldInterpolateInfo, true)
: Rotation(dictionary)
, _shouldInterpolate(ShouldInterpolateInfo, true)
{
const Parameters p = codegen::bake<Parameters>(dictionary);

View File

@@ -64,7 +64,8 @@ documentation::Documentation LuaScale::Documentation() {
}
LuaScale::LuaScale(const ghoul::Dictionary& dictionary)
: _luaScriptFile(ScriptInfo)
: Scale(dictionary)
, _luaScriptFile(ScriptInfo)
{
const Parameters p = codegen::bake<Parameters>(dictionary);

View File

@@ -47,7 +47,9 @@ documentation::Documentation MultiScale::Documentation() {
return codegen::doc<Parameters>("base_transform_scale_multi");
}
MultiScale::MultiScale(const ghoul::Dictionary& dictionary) {
MultiScale::MultiScale(const ghoul::Dictionary& dictionary)
: Scale(dictionary)
{
const Parameters p = codegen::bake<Parameters>(dictionary);
int i = 0;

View File

@@ -60,7 +60,8 @@ documentation::Documentation NonUniformStaticScale::Documentation() {
}
NonUniformStaticScale::NonUniformStaticScale(const ghoul::Dictionary& dictionary)
: _scaleValue(ScaleInfo, glm::dvec3(1.0), glm::dvec3(0.1), glm::dvec3(100.0))
: Scale(dictionary)
, _scaleValue(ScaleInfo, glm::dvec3(1.0), glm::dvec3(0.1), glm::dvec3(100.0))
{
const Parameters p = codegen::bake<Parameters>(dictionary);

View File

@@ -55,20 +55,14 @@ documentation::Documentation StaticScale::Documentation() {
}
StaticScale::StaticScale(const ghoul::Dictionary& dictionary)
: StaticScale()
: Scale(dictionary)
, _scaleValue(ScaleInfo, 1.0, 0.1, 100.0)
{
const Parameters p = codegen::bake<Parameters>(dictionary);
_scaleValue = p.scale;
_type = "StaticScale";
}
StaticScale::StaticScale()
: _scaleValue(ScaleInfo, 1.0, 0.1, 100.0)
{
addProperty(_scaleValue);
_scaleValue.onChange([this]() { requireUpdate(); });
_type = "StaticScale";
addProperty(_scaleValue);
}
glm::dvec3 StaticScale::scaleValue(const UpdateData&) const {

View File

@@ -35,7 +35,6 @@ namespace documentation { struct Documentation; }
class StaticScale : public Scale {
public:
StaticScale();
explicit StaticScale(const ghoul::Dictionary& dictionary);
glm::dvec3 scaleValue(const UpdateData& data) const override;

View File

@@ -87,7 +87,8 @@ documentation::Documentation TimeDependentScale::Documentation() {
}
TimeDependentScale::TimeDependentScale(const ghoul::Dictionary& dictionary)
: _referenceDate(ReferenceDateInfo, "")
: Scale(dictionary)
, _referenceDate(ReferenceDateInfo, "")
, _speed(SpeedInfo, 1.0, 0.0, 1e12)
, _clampToPositive(ClampToPositiveInfo, true)
{

View File

@@ -63,7 +63,8 @@ documentation::Documentation TimelineScale::Documentation() {
}
TimelineScale::TimelineScale(const ghoul::Dictionary& dictionary)
: _shouldInterpolate(ShouldInterpolateInfo, true)
: Scale(dictionary)
, _shouldInterpolate(ShouldInterpolateInfo, true)
{
const Parameters p = codegen::bake<Parameters>(dictionary);

View File

@@ -75,16 +75,6 @@ documentation::Documentation TimeFrameInterval::Documentation() {
return codegen::doc<Parameters>("base_time_frame_interval");
}
bool TimeFrameInterval::isActive(const Time& time) const {
if (_hasStart && time.j2000Seconds() < _start) {
return false;
}
if (_hasEnd && time.j2000Seconds() >= _end) {
return false;
}
return true;
}
TimeFrameInterval::TimeFrameInterval(const ghoul::Dictionary& dictionary)
: _hasStart(HasStartInfo, false)
, _start(StartInfo, 0, 0, 1E9)
@@ -122,4 +112,16 @@ TimeFrameInterval::TimeFrameInterval(const ghoul::Dictionary& dictionary)
addProperty(_end);
}
void TimeFrameInterval::update(const Time& time) {
if (_hasStart && time.j2000Seconds() < _start) {
_isInTimeFrame = false;
}
else if (_hasEnd && time.j2000Seconds() >= _end) {
_isInTimeFrame = false;
}
else {
_isInTimeFrame = true;
}
}
} // namespace openspace

View File

@@ -40,7 +40,7 @@ class TimeFrameInterval : public TimeFrame {
public:
explicit TimeFrameInterval(const ghoul::Dictionary& dictionary);
bool isActive(const Time&) const override;
void update(const Time& time) override;
static documentation::Documentation Documentation();

View File

@@ -60,15 +60,6 @@ documentation::Documentation TimeFrameUnion::Documentation() {
return codegen::doc<Parameters>("base_timeframe_union");
}
bool TimeFrameUnion::isActive(const Time& time) const {
for (const ghoul::mm_unique_ptr<TimeFrame>& tf : _timeFrames) {
if (tf->isActive(time)) {
return true;
}
}
return false;
}
TimeFrameUnion::TimeFrameUnion(const ghoul::Dictionary& dictionary) {
const Parameters p = codegen::bake<Parameters>(dictionary);
@@ -83,4 +74,16 @@ TimeFrameUnion::TimeFrameUnion(const ghoul::Dictionary& dictionary) {
}
}
void TimeFrameUnion::update(const Time& time) {
for (const ghoul::mm_unique_ptr<TimeFrame>& tf : _timeFrames) {
tf->update(time);
}
_isInTimeFrame = std::any_of(
_timeFrames.begin(),
_timeFrames.end(),
std::mem_fn(&TimeFrame::isActive)
);
}
} // namespace openspace

View File

@@ -37,7 +37,7 @@ class TimeFrameUnion : public TimeFrame {
public:
explicit TimeFrameUnion(const ghoul::Dictionary& dictionary);
bool isActive(const Time&) const override;
void update(const Time&) override;
static documentation::Documentation Documentation();

View File

@@ -65,7 +65,8 @@ documentation::Documentation LuaTranslation::Documentation() {
}
LuaTranslation::LuaTranslation(const ghoul::Dictionary& dictionary)
: _luaScriptFile(ScriptInfo)
: Translation(dictionary)
, _luaScriptFile(ScriptInfo)
{
const Parameters p = codegen::bake<Parameters>(dictionary);

View File

@@ -47,7 +47,9 @@ documentation::Documentation MultiTranslation::Documentation() {
return codegen::doc<Parameters>("base_transform_translation_multi");
}
MultiTranslation::MultiTranslation(const ghoul::Dictionary& dictionary) {
MultiTranslation::MultiTranslation(const ghoul::Dictionary& dictionary)
: Translation(dictionary)
{
const Parameters p = codegen::bake<Parameters>(dictionary);
int i = 0;

View File

@@ -49,27 +49,21 @@ documentation::Documentation StaticTranslation::Documentation() {
return codegen::doc<Parameters>("base_transform_translation_static");
}
StaticTranslation::StaticTranslation()
: _position(PositionInfo, glm::dvec3(0.0), glm::dvec3(-1e35), glm::dvec3(1e35))
StaticTranslation::StaticTranslation(const ghoul::Dictionary& dictionary)
: Translation(dictionary)
, _position(PositionInfo, glm::dvec3(0.0), glm::dvec3(-1e35), glm::dvec3(1e35))
{
// @TODO (2021-06-24, emmbr) The exponential sliders do not handle ranges with
// negative values very well. When they do, this line can be uncommented
//_position.setExponent(20.f);
addProperty(_position);
const Parameters p = codegen::bake<Parameters>(dictionary);
_position = p.position;
_position.onChange([this]() {
requireUpdate();
notifyObservers();
});
_type = "StaticTranslation";
}
StaticTranslation::StaticTranslation(const ghoul::Dictionary& dictionary)
: StaticTranslation()
{
const Parameters p = codegen::bake<Parameters>(dictionary);
_position = p.position;
_type = "StaticTranslation";
// @TODO (2021-06-24, emmbr) The exponential sliders do not handle ranges with
// negative values very well. When they do, this line can be uncommented
//_position.setExponent(20.f);
addProperty(_position);
}
glm::dvec3 StaticTranslation::position(const UpdateData&) const {

View File

@@ -37,7 +37,6 @@ namespace documentation { struct Documentation; }
class StaticTranslation : public Translation {
public:
StaticTranslation();
explicit StaticTranslation(const ghoul::Dictionary& dictionary);
glm::dvec3 position(const UpdateData& data) const override;

View File

@@ -58,7 +58,8 @@ documentation::Documentation TimelineTranslation::Documentation() {
}
TimelineTranslation::TimelineTranslation(const ghoul::Dictionary& dictionary)
: _shouldInterpolate(ShouldInterpolateInfo, true)
: Translation(dictionary)
, _shouldInterpolate(ShouldInterpolateInfo, true)
{
const Parameters p = codegen::bake<Parameters>(dictionary);

View File

@@ -117,7 +117,8 @@ documentation::Documentation GlobeRotation::Documentation() {
}
GlobeRotation::GlobeRotation(const ghoul::Dictionary& dictionary)
: _globe(GlobeInfo)
: Rotation(dictionary)
, _globe(GlobeInfo)
, _latitude(LatitudeInfo, 0.0, -90.0, 90.0)
, _longitude(LongitudeInfo, 0.0, -180.0, 180.0)
, _angle(AngleInfo, 0.0, 0.0, 360.0)

View File

@@ -126,7 +126,8 @@ documentation::Documentation GlobeTranslation::Documentation() {
}
GlobeTranslation::GlobeTranslation(const ghoul::Dictionary& dictionary)
: _globe(GlobeInfo)
: Translation(dictionary)
, _globe(GlobeInfo)
, _latitude(LatitudeInfo, 0.0, -90.0, 90.0)
, _longitude(LongitudeInfo, 0.0, -180.0, 180.0)
, _altitude(AltitudeInfo, 0.0, -1e12, 1e12)

View File

@@ -49,7 +49,7 @@ namespace {
renderSceneGraphNode(*c, time);
}
bool timeRangeActive = node.isTimeFrameActive(time);
bool timeRangeActive = node.isTimeFrameActive();
ImGui::Checkbox("Time Range Active", &timeRangeActive);
const Renderable* renderable = node.renderable();

View File

@@ -636,20 +636,20 @@ void RenderableOrbitalKepler::updateBuffers() {
_vertexBufferData.resize(nVerticesTotal);
size_t vertexBufIdx = 0;
KeplerTranslation keplerTranslator;
for (int orbitIdx = 0; orbitIdx < numOrbits; ++orbitIdx) {
const kepler::Parameters& orbit = parameters[orbitIdx];
keplerTranslator.setKeplerElements(
orbit.eccentricity,
orbit.semiMajorAxis,
orbit.inclination,
orbit.ascendingNode,
orbit.argumentOfPeriapsis,
orbit.meanAnomaly,
orbit.period,
orbit.epoch
);
ghoul::Dictionary d;
d.setValue("Type", std::string("KeplerTranslation"));
d.setValue("Eccentricity", orbit.eccentricity);
d.setValue("SemiMajorAxis", orbit.semiMajorAxis);
d.setValue("Inclination", orbit.inclination);
d.setValue("AscendingNode", orbit.ascendingNode);
d.setValue("ArgumentOfPeriapsis", orbit.argumentOfPeriapsis);
d.setValue("MeanAnomaly", orbit.meanAnomaly);
d.setValue("Period", orbit.period);
d.setValue("Epoch", orbit.epoch);
KeplerTranslation keplerTranslator = KeplerTranslation(d);
for (GLint j = 0 ; j < (_segmentSize[orbitIdx]); j++) {
const double timeOffset = orbit.period *

View File

@@ -48,13 +48,6 @@ namespace {
openspace::properties::Property::Visibility::Developer
};
constexpr openspace::properties::Property::PropertyInfo TimeFrameInfo = {
"TimeFrame",
"Time Frame",
"The time frame in which the spice kernels are valid.",
openspace::properties::Property::Visibility::AdvancedUser
};
constexpr openspace::properties::Property::PropertyInfo FixedDateInfo = {
"FixedDate",
"Fixed Date",
@@ -81,10 +74,6 @@ namespace {
// specified, a reference frame of 'GALACTIC' is used instead
std::optional<std::string> destinationFrame;
// [[codegen::verbatim(TimeFrameInfo.description)]]
std::optional<ghoul::Dictionary> timeFrame
[[codegen::reference("core_time_frame")]];
// [[codegen::verbatim(FixedDateInfo.description)]]
std::optional<std::string> fixedDate
[[codegen::annotation("A time to lock the rotation to")]];
@@ -102,7 +91,8 @@ documentation::Documentation SpiceRotation::Documentation() {
}
SpiceRotation::SpiceRotation(const ghoul::Dictionary& dictionary)
: _sourceFrame(SourceInfo)
: Rotation(dictionary)
, _sourceFrame(SourceInfo)
, _destinationFrame(DestinationInfo)
, _fixedDate(FixedDateInfo)
, _timeOffset(TimeOffsetInfo)
@@ -126,11 +116,6 @@ SpiceRotation::SpiceRotation(const ghoul::Dictionary& dictionary)
_timeOffset = p.timeOffset.value_or(_timeOffset);
addProperty(_timeOffset);
if (p.timeFrame.has_value()) {
_timeFrame = TimeFrame::createFromDictionary(*p.timeFrame);
addPropertySubOwner(_timeFrame.get());
}
addProperty(_sourceFrame);
addProperty(_destinationFrame);
@@ -139,9 +124,6 @@ SpiceRotation::SpiceRotation(const ghoul::Dictionary& dictionary)
}
glm::dmat3 SpiceRotation::matrix(const UpdateData& data) const {
if (_timeFrame && !_timeFrame->isActive(data.time)) {
return glm::dmat3(1.0);
}
return SpiceManager::ref().positionTransformMatrix(
_sourceFrame,
_destinationFrame,

View File

@@ -29,7 +29,6 @@
#include <openspace/properties/stringproperty.h>
#include <openspace/properties/scalar/floatproperty.h>
#include <openspace/scene/timeframe.h>
#include <optional>
namespace openspace {
@@ -40,7 +39,6 @@ class SpiceRotation : public Rotation {
public:
explicit SpiceRotation(const ghoul::Dictionary& dictionary);
const glm::dmat3& matrix() const;
glm::dmat3 matrix(const UpdateData& data) const override;
static documentation::Documentation Documentation();
@@ -51,7 +49,6 @@ private:
properties::StringProperty _fixedDate;
properties::FloatProperty _timeOffset;
ghoul::mm_unique_ptr<TimeFrame> _timeFrame;
std::optional<double> _fixedEphemerisTime;
};

View File

@@ -50,6 +50,43 @@ namespace {
std::optional<int> element [[codegen::greater(0)]];
};
#include "gptranslation_codegen.cpp"
ghoul::Dictionary gpDictionaryToKepler(const ghoul::Dictionary& dictionary) {
using namespace openspace;
const Parameters p = codegen::bake<Parameters>(dictionary);
if (!std::filesystem::is_regular_file(p.file)) {
throw ghoul::RuntimeError("The provided TLE file must exist");
}
int element = p.element.value_or(1);
std::vector<kepler::Parameters> parameters = kepler::readFile(
p.file,
codegen::map<kepler::Format>(p.format)
);
if (element > static_cast<int>(parameters.size())) {
throw ghoul::RuntimeError(std::format(
"Requested element {} but only {} are available", element, parameters.size()
));
}
const kepler::Parameters& param = parameters[element - 1];
// We copy the old dictionary to make sure we keep values intact that we don't
// want to touch here (for example the 'Type')
ghoul::Dictionary res = dictionary;
res.setValue("Eccentricity", param.eccentricity);
res.setValue("SemiMajorAxis", param.semiMajorAxis);
res.setValue("Inclination", param.inclination);
res.setValue("AscendingNode", param.ascendingNode);
res.setValue("ArgumentOfPeriapsis", param.argumentOfPeriapsis);
res.setValue("MeanAnomaly", param.meanAnomaly);
res.setValue("Period", param.period);
res.setValue("Epoch", param.epoch);
return res;
}
} // namespace
namespace openspace {
@@ -58,36 +95,8 @@ documentation::Documentation GPTranslation::Documentation() {
return codegen::doc<Parameters>("space_translation_gp");
}
GPTranslation::GPTranslation(const ghoul::Dictionary& dictionary) {
const Parameters p = codegen::bake<Parameters>(dictionary);
if (!std::filesystem::is_regular_file(p.file)) {
throw ghoul::RuntimeError("The provided TLE file must exist");
}
int element = p.element.value_or(1);
std::vector<kepler::Parameters> parameters = kepler::readFile(
p.file,
codegen::map<kepler::Format>(p.format)
);
if (element > static_cast<int>(parameters.size())) {
throw ghoul::RuntimeError(std::format(
"Requested element {} but only {} are available", element, parameters.size()
));
}
const kepler::Parameters& param = parameters[element - 1];
setKeplerElements(
param.eccentricity,
param.semiMajorAxis,
param.inclination,
param.ascendingNode,
param.argumentOfPeriapsis,
param.meanAnomaly,
param.period,
param.epoch
);
}
GPTranslation::GPTranslation(const ghoul::Dictionary& dictionary)
: KeplerTranslation(gpDictionaryToKepler(dictionary))
{}
} // namespace openspace

View File

@@ -66,19 +66,9 @@ documentation::Documentation HorizonsTranslation::Documentation() {
return codegen::doc<Parameters>("base_transform_translation_horizons");
}
HorizonsTranslation::HorizonsTranslation()
: _horizonsFiles(HorizonsTextFileInfo)
{
_horizonsFiles.onChange([this](){
requireUpdate();
notifyObservers();
loadData();
});
addProperty(_horizonsFiles);
}
HorizonsTranslation::HorizonsTranslation(const ghoul::Dictionary& dictionary)
: HorizonsTranslation()
: Translation(dictionary)
, _horizonsFiles(HorizonsTextFileInfo)
{
const Parameters p = codegen::bake<Parameters>(dictionary);
@@ -99,6 +89,13 @@ HorizonsTranslation::HorizonsTranslation(const ghoul::Dictionary& dictionary)
);
_horizonsFiles = f;
}
_horizonsFiles.onChange([this](){
requireUpdate();
notifyObservers();
loadData();
});
addProperty(_horizonsFiles);
}
glm::dvec3 HorizonsTranslation::position(const UpdateData& data) const {

View File

@@ -69,7 +69,6 @@ namespace documentation { struct Documentation; }
*/
class HorizonsTranslation : public Translation {
public:
HorizonsTranslation();
explicit HorizonsTranslation(const ghoul::Dictionary& dictionary);
glm::dvec3 position(const UpdateData& data) const override;

View File

@@ -101,8 +101,8 @@ namespace {
constexpr openspace::properties::Property::PropertyInfo EpochInfo = {
"Epoch",
"Epoch",
"This value determines the epoch for which the initial location is defined in "
"the form of YYYY MM DD HH:mm:ss.",
"Specifies the epoch in which the first position of the Kepler arguments are "
"provided. The epoch is specified in numbers of seconds past the J2000 epoch.",
openspace::properties::Property::Visibility::AdvancedUser
};
@@ -132,8 +132,10 @@ namespace {
// [[codegen::verbatim(MeanAnomalyAtEpochInfo.description)]]
double meanAnomaly [[codegen::inrange(-360.0, 360.0)]];
// [[codegen::verbatim(EpochInfo.description)]]
std::string epoch;
// This value determines the epoch for which the initial location is defined in.
// This is specified either in the form of a date (YYYY MM DD HH:mm:ss) or in the
// number of seconds past the J2000 epoch.
std::variant<std::string, double> epoch;
// [[codegen::verbatim(PeriodInfo.description)]]
double period [[codegen::greater(0.0)]];
@@ -152,8 +154,9 @@ documentation::Documentation KeplerTranslation::Documentation() {
return codegen::doc<Parameters>("space_transform_kepler");
}
KeplerTranslation::KeplerTranslation()
: _eccentricity(EccentricityInfo, 0.0, 0.0, 1.0)
KeplerTranslation::KeplerTranslation(const ghoul::Dictionary& dictionary)
: Translation(dictionary)
, _eccentricity(EccentricityInfo, 0.0, 0.0, 1.0)
, _semiMajorAxis(SemiMajorAxisInfo, 0.0, 0.0, 1e6)
, _inclination(InclinationInfo, 0.0, 0.0, 360.0)
, _ascendingNode(AscendingNodeInfo, 0.0, 0.0, 360.0)
@@ -162,6 +165,8 @@ KeplerTranslation::KeplerTranslation()
, _epoch(EpochInfo, 0.0, 0.0, 1e9)
, _period(PeriodInfo, 0.0, 0.0, 1e6)
{
const Parameters p = codegen::bake<Parameters>(dictionary);
auto update = [this]() {
_orbitPlaneDirty = true;
requireUpdate();
@@ -188,12 +193,11 @@ KeplerTranslation::KeplerTranslation()
addProperty(_meanAnomalyAtEpoch);
addProperty(_epoch);
addProperty(_period);
}
KeplerTranslation::KeplerTranslation(const ghoul::Dictionary& dictionary)
: KeplerTranslation()
{
const Parameters p = codegen::bake<Parameters>(dictionary);
const double epoch =
std::holds_alternative<double>(p.epoch) ?
std::get<double>(p.epoch) :
SpiceManager::ref().ephemerisTimeFromDate(std::get<std::string>(p.epoch));
setKeplerElements(
p.eccentricity,
@@ -201,11 +205,11 @@ KeplerTranslation::KeplerTranslation(const ghoul::Dictionary& dictionary)
p.inclination < 0.0 ? p.inclination + 360.0 : p.inclination,
p.ascendingNode < 0.0 ? p.ascendingNode + 360.0 : p.ascendingNode,
p.argumentOfPeriapsis < 0.0 ?
p.argumentOfPeriapsis + 360.0 :
p.argumentOfPeriapsis,
p.argumentOfPeriapsis + 360.0 :
p.argumentOfPeriapsis,
p.meanAnomaly < 0.0 ? p.meanAnomaly + 360.0 : p.meanAnomaly,
p.period,
p.epoch
epoch
);
}

View File

@@ -121,11 +121,6 @@ public:
double ascendingNode, double argumentOfPeriapsis, double meanAnomalyAtEpoch,
double orbitalPeriod, double epoch);
/**
* Default construct that initializes all the properties and member variables.
*/
KeplerTranslation();
/**
* Recombutes the rotation matrix used in the update method.
*/

View File

@@ -111,7 +111,8 @@ documentation::Documentation SpiceTranslation::Documentation() {
}
SpiceTranslation::SpiceTranslation(const ghoul::Dictionary& dictionary)
: _target(TargetInfo)
: Translation(dictionary)
, _target(TargetInfo)
, _observer(ObserverInfo)
, _frame(FrameInfo, "GALACTIC")
, _fixedDate(FixedDateInfo)