From a112ebcec796780736e7d466fdd2036be312d4bb Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 19 Feb 2018 16:28:18 -0500 Subject: [PATCH] Specify simplification of field of view renderables --- .../missions/newhorizons/fov.asset | 3 +- .../rendering/renderablefov.cpp | 89 ++++++++++++++----- .../rendering/renderablefov.h | 1 + 3 files changed, 70 insertions(+), 23 deletions(-) diff --git a/data/assets/scene/solarsystem/missions/newhorizons/fov.asset b/data/assets/scene/solarsystem/missions/newhorizons/fov.asset index a5614476f2..260742ac55 100644 --- a/data/assets/scene/solarsystem/missions/newhorizons/fov.asset +++ b/data/assets/scene/solarsystem/missions/newhorizons/fov.asset @@ -267,7 +267,8 @@ local AliceAirglow = { "Pluto", "Charon", -- "Jupiter", "Io", "Europa", "Ganymede", "Callisto" - } + }, + SimplifyBounds = true }, Transform = { Translation = { diff --git a/modules/spacecraftinstruments/rendering/renderablefov.cpp b/modules/spacecraftinstruments/rendering/renderablefov.cpp index c34551e2d6..eff9c2f308 100644 --- a/modules/spacecraftinstruments/rendering/renderablefov.cpp +++ b/modules/spacecraftinstruments/rendering/renderablefov.cpp @@ -33,6 +33,8 @@ #include #include +#include +#include #include #include @@ -40,18 +42,22 @@ #include namespace { - const char* KeyBody = "Body"; - const char* KeyFrame = "Frame"; + constexpr const char* KeyBody = "Body"; + constexpr const char* KeyFrame = "Frame"; // const char* KeyColor = "RGB"; - const char* KeyInstrument = "Instrument"; - const char* KeyInstrumentName = "Name"; - const char* KeyInstrumentAberration = "Aberration"; + constexpr const char* KeyInstrument = "Instrument"; + constexpr const char* KeyInstrumentName = "Name"; + constexpr const char* KeyInstrumentAberration = "Aberration"; - const char* KeyPotentialTargets = "PotentialTargets"; - const char* KeyFrameConversions = "FrameConversions"; + constexpr const char* KeyPotentialTargets = "PotentialTargets"; + constexpr const char* KeyFrameConversions = "FrameConversions"; + + constexpr const char* KeyBoundsSimplification = "SimplifyBounds"; const int InterpolationSteps = 5; + + const double Epsilon = 1e-4; static const openspace::properties::Property::PropertyInfo LineWidthInfo = { "LineWidth", @@ -130,7 +136,6 @@ namespace { "the case that there is no intersection and that the instrument is not currently " "active." }; - } // namespace namespace openspace { @@ -214,6 +219,15 @@ documentation::Documentation RenderableFov::Documentation() { new DoubleVerifier, Optional::Yes, StandoffDistanceInfo.description + }, + { + KeyBoundsSimplification, + new BoolVerifier, + Optional::Yes, + "If this value is set to 'true' the field-of-views bounds values will be " + "simplified on load. Bound vectors will be removed if they are the " + "strict linear interpolation between the two neighboring vectors. This " + "value is disabled on default." } } }; @@ -285,6 +299,10 @@ RenderableFov::RenderableFov(const ghoul::Dictionary& dictionary) )); } + if (dictionary.hasKey(KeyBoundsSimplification)) { + _simplifyBounds = dictionary.value(KeyBoundsSimplification); + } + addProperty(_lineWidth); addProperty(_drawSolid); addProperty(_standOffDistance); @@ -342,6 +360,33 @@ void RenderableFov::initializeGL() { "RenderableFov" ); } + + if (_simplifyBounds) { + const size_t sizeBefore = res.bounds.size(); + for (size_t i = 1; i < res.bounds.size() - 1; ++i) { + const glm::dvec3& prev = res.bounds[i - 1]; + const glm::dvec3& curr = res.bounds[i]; + const glm::dvec3& next = res.bounds[i + 1]; + + const double area = glm::length( + glm::cross((curr - prev), (next - prev)) + ); + + const bool isCollinear = area < Epsilon; + + if (isCollinear) { + res.bounds.erase(res.bounds.begin() + i); + + // Need to subtract one as we have shortened the array and the next + // item is now on the current position + --i; + } + } + const size_t sizeAfter = res.bounds.size(); + + LINFOC(_instrument.name, "Simplified from " << sizeBefore << " to " << sizeAfter); + } + _instrument.bounds = std::move(res.bounds); _instrument.boresight = std::move(res.boresightVector); @@ -1315,24 +1360,24 @@ void RenderableFov::update(const UpdateData& data) { } std::pair RenderableFov::determineTarget(double time) { + SpiceManager::UseException oldValue = SpiceManager::ref().exceptionHandling(); + defer { SpiceManager::ref().setExceptionHandling(oldValue); }; + // First, for all potential targets, check whether they are in the field of view for (const std::string& pt : _instrument.potentialTargets) { - try { - bool inFOV = SpiceManager::ref().isTargetInFieldOfView( - pt, - _instrument.spacecraft, - _instrument.name, - SpiceManager::FieldOfViewMethod::Ellipsoid, - _instrument.aberrationCorrection, - time - ); + bool inFOV = SpiceManager::ref().isTargetInFieldOfView( + pt, + _instrument.spacecraft, + _instrument.name, + SpiceManager::FieldOfViewMethod::Ellipsoid, + _instrument.aberrationCorrection, + time + ); - if (inFOV) { - _previousTarget = pt; - return { pt, true }; - } + if (inFOV) { + _previousTarget = pt; + return { pt, true }; } - catch (const openspace::SpiceManager::SpiceException&) {} } // If none of the targets is in field of view, either use the last target or if there diff --git a/modules/spacecraftinstruments/rendering/renderablefov.h b/modules/spacecraftinstruments/rendering/renderablefov.h index 909c2a0010..5fcbcf1e06 100644 --- a/modules/spacecraftinstruments/rendering/renderablefov.h +++ b/modules/spacecraftinstruments/rendering/renderablefov.h @@ -100,6 +100,7 @@ private: // instance variables bool _rebuild = false; + bool _simplifyBounds = false; //std::vector _fovBounds; //std::vector _fovPlane;