Files
OpenSpace/modules/base/translation/spicetranslation.cpp
Alexander Bock d4145ede0c Enable Translation classes to signal when settings have changed substantially
RenderableTrail listens to those changes and recomputes the trail if Translation settings have changed
Minor GUI improvements
Remove try/catch block from SpiceRotation
Update Ghoul reference
2016-11-26 14:45:09 +01:00

173 lines
6.7 KiB
C++

/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#include <modules/base/translation/spicetranslation.h>
#include <openspace/util/spicemanager.h>
#include <openspace/util/time.h>
#include <ghoul/filesystem/filesystem.h>
#include <openspace/documentation/verifier.h>
namespace {
const char* KeyBody = "Body";
const char* KeyObserver = "Observer";
const char* KeyFrame = "Frame";
const char* KeyKernels = "Kernels";
const char* DefaultReferenceFrame = "GALACTIC";
}
namespace openspace {
Documentation SpiceTranslation::Documentation() {
using namespace openspace::documentation;
return{
"Spice Translation",
"base_translation_spicetranslation",
{
{
"Type",
new StringEqualVerifier("SpiceTranslation"),
"",
Optional::No
},
{
KeyBody,
new StringAnnotationVerifier("A valid SPICE NAIF name or identifier"),
"This is the SPICE NAIF name for the body whose translation is to be "
"computed by the SpiceTranslation. It can either be a fully qualified "
"name (such as 'EARTH') or a NAIF integer id code (such as '399').",
Optional::No
},
{
KeyObserver,
new StringAnnotationVerifier("A valid SPICE NAIF name or identifier"),
"This is the SPICE NAIF name for the parent of the body whose "
"translation is to be computed by the SpiceTranslation. It can either be "
"a fully qualified name (such as 'SOLAR SYSTEM BARYCENTER') or a NAIF "
"integer id code (such as '0').",
Optional::No
},
{
KeyFrame,
new StringAnnotationVerifier(
"A valid SPICE NAIF name for a reference frame"
),
"This is the SPICE NAIF name for the reference frame in which the "
"position should be retrieved. The default value is GALACTIC",
Optional::Yes
},
{
KeyKernels,
new OrVerifier(
new StringListVerifier,
new StringVerifier
),
"A single kernel or list of kernels that this SpiceTranslation depends "
"on. All provided kernels will be loaded before any other operation is "
"performed.",
Optional::Yes
}
},
Exhaustive::Yes
};
}
SpiceTranslation::SpiceTranslation(const ghoul::Dictionary& dictionary)
: _target("target", "Target", "")
, _origin("origin", "Origin", "")
, _frame("frame", "Reference Frame", DefaultReferenceFrame)
, _kernelsLoadedSuccessfully(true)
{
documentation::testSpecificationAndThrow(
Documentation(),
dictionary,
"SpiceTranslation"
);
_target = dictionary.value<std::string>(KeyBody);
_origin = dictionary.value<std::string>(KeyObserver);
if (dictionary.hasKey(KeyFrame)) {
_frame = dictionary.value<std::string>(KeyFrame);
}
auto loadKernel = [](const std::string& kernel) {
if (!FileSys.fileExists(kernel)) {
throw SpiceManager::SpiceException("Kernel '" + kernel + "' does not exist");
}
try {
SpiceManager::ref().loadKernel(kernel);
}
catch (const SpiceManager::SpiceException& exception) {
LERRORC("SpiceEphemeris", exception.message);
}
};
if (dictionary.hasKey(KeyKernels)) {
// Due to the specification, we can be sure it is either a Dictionary or a string
if (dictionary.hasValue<std::string>(KeyKernels)) {
std::string kernel = dictionary.value<std::string>(KeyKernels);
loadKernel(kernel);
}
else {
ghoul::Dictionary kernels = dictionary.value<ghoul::Dictionary>(KeyKernels);
for (size_t i = 1; i <= kernels.size(); ++i) {
std::string kernel = kernels.value<std::string>(std::to_string(i));
loadKernel(kernel);
}
}
}
auto update = [this](){
notifyObservers();
};
_target.onChange(update);
addProperty(_target);
_origin.onChange(update);
addProperty(_origin);
_frame.onChange(update);
addProperty(_frame);
}
glm::dvec3 SpiceTranslation::position() const {
return _position;
}
void SpiceTranslation::update(const UpdateData& data) {
double lightTime = 0.0;
_position = SpiceManager::ref().targetPosition(
_target, _origin, _frame, {}, data.time, lightTime
) * glm::pow(10.0, 3.0);
}
} // namespace openspace