- Restructure Rotation classes to make the base class store the rotation to remove an additional virtual function

- Add Matrix verifiers
- Add documentation to StaticRotation and SpiceRotation
This commit is contained in:
Alexander Bock
2016-10-26 16:47:42 +02:00
parent b95c80bb40
commit db4524d2ac
12 changed files with 650 additions and 69 deletions
+1
View File
@@ -136,6 +136,7 @@ void BaseModule::internalInitialize() {
std::vector<Documentation> BaseModule::documentations() const {
return {
SpiceRotation::Documentation(),
StaticScale::Documentation(),
StaticTranslation::Documentation(),
SpiceTranslation::Documentation()
+74 -38
View File
@@ -24,6 +24,8 @@
#include <modules/base/rotation/spicerotation.h>
#include <openspace/documentation/verifier.h>
#include <openspace/util/spicemanager.h>
#include <openspace/util/time.h>
@@ -38,56 +40,90 @@ namespace {
namespace openspace {
SpiceRotation::SpiceRotation(const ghoul::Dictionary& dictionary)
: _sourceFrame("")
, _destinationFrame("")
, _rotationMatrix(1.0)
, _kernelsLoadedSuccessfully(true)
{
const bool hasSourceFrame = dictionary.getValue(KeySourceFrame, _sourceFrame);
if (!hasSourceFrame)
LERROR("SpiceRotation does not contain the key '" << KeySourceFrame << "'");
const bool hasDestinationFrame = dictionary.getValue(KeyDestinationFrame, _destinationFrame);
if (!hasDestinationFrame)
LERROR("SpiceRotation does not contain the key '" << KeyDestinationFrame << "'");
ghoul::Dictionary kernels;
dictionary.getValue(KeyKernels, kernels);
for (size_t i = 1; i <= kernels.size(); ++i) {
std::string kernel;
bool success = kernels.getValue(std::to_string(i), kernel);
if (!success)
LERROR("'" << KeyKernels << "' has to be an array-style table");
try {
SpiceManager::ref().loadKernel(kernel);
_kernelsLoadedSuccessfully = true;
Documentation SpiceRotation::Documentation() {
using namespace openspace::documentation;
return {
"Spice Rotation",
"base_transform_rotation_spice",
{
{
"Type",
new StringEqualVerifier("SpiceRotation"),
"",
Optional::No
},
{
KeySourceFrame,
new StringAnnotationVerifier("A valid SPICE NAIF name or integer"),
"The source frame that is used as the basis for the coordinate "
"transformation. This has to be a valid SPICE name.",
Optional::No
},
{
KeyDestinationFrame,
new StringAnnotationVerifier("A valid SPICE NAIF name or integer"),
"The destination frame that is used for the coordinate transformation. "
"This has to be a valid SPICE name.",
Optional::No
},
{
KeyKernels,
new OrVerifier(
new TableVerifier({
{ "*", new StringVerifier }
}),
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
}
}
catch (const SpiceManager::SpiceException& e) {
LERROR("Could not load SPICE kernel: " << e.what());
_kernelsLoadedSuccessfully = false;
};
}
SpiceRotation::SpiceRotation(const ghoul::Dictionary& dictionary)
: _sourceFrame("source", "Source", "")
, _destinationFrame("destination", "Destination", "")
{
documentation::testSpecificationAndThrow(
Documentation(),
dictionary,
"SpiceRotation"
);
_sourceFrame = dictionary.value<std::string>(KeySourceFrame);
_destinationFrame = dictionary.value<std::string>(KeyDestinationFrame);
if (dictionary.hasKeyAndValue<std::string>(KeyKernels)) {
SpiceManager::ref().loadKernel(dictionary.value<std::string>(KeyKernels));
}
else if (dictionary.hasKeyAndValue<ghoul::Dictionary>(KeyKernels)) {
ghoul::Dictionary kernels = dictionary.value<ghoul::Dictionary>(KeyKernels);
for (size_t i = 1; i <= kernels.size(); ++i) {
if (!kernels.hasKeyAndValue<std::string>(std::to_string(i))) {
throw ghoul::RuntimeError("Kernels has to be an array-style table");
}
std::string kernel = kernels.value<std::string>(std::to_string(i));
SpiceManager::ref().loadKernel(kernel);
}
}
}
const glm::dmat3& SpiceRotation::matrix() const {
return _rotationMatrix;
}
void SpiceRotation::update(const UpdateData& data) {
if (!_kernelsLoadedSuccessfully)
return;
try {
_rotationMatrix = SpiceManager::ref().positionTransformMatrix(
_matrix = SpiceManager::ref().positionTransformMatrix(
_sourceFrame,
_destinationFrame,
data.time);
data.time
);
}
catch (const ghoul::RuntimeError&) {
// In case of missing coverage
_rotationMatrix = glm::dmat3(1);
_matrix = glm::dmat3(1);
}
}
} // namespace openspace
} // namespace openspace
+7 -5
View File
@@ -26,20 +26,22 @@
#define __SPICEROTATION_H__
#include <openspace/scene/rotation.h>
#include <openspace/documentation/documentation.h>
#include <openspace/properties/stringproperty.h>
namespace openspace {
class SpiceRotation : public Rotation {
public:
SpiceRotation(const ghoul::Dictionary& dictionary);
virtual const glm::dmat3& matrix() const;
const glm::dmat3& matrix() const;
void update(const UpdateData& data) override;
static openspace::Documentation Documentation();
private:
std::string _sourceFrame;
std::string _destinationFrame;
glm::dmat3 _rotationMatrix;
bool _kernelsLoadedSuccessfully;
properties::StringProperty _sourceFrame;
properties::StringProperty _destinationFrame;
};
} // namespace openspace
+53 -16
View File
@@ -24,29 +24,66 @@
#include <modules/base/rotation/staticrotation.h>
#include <openspace/documentation/verifier.h>
namespace {
const std::string KeyEulerAngles = "EulerAngles";
const std::string KeyRotation = "Rotation";
}
namespace openspace {
Documentation StaticRotation::Documentation() {
using namespace openspace::documentation;
return {
"Static Rotation",
"base_transform_rotation_static",
{
{
"Type",
new StringEqualVerifier("StaticRotation"),
"",
Optional::No
},
{
KeyRotation,
new OrVerifier(
new DoubleVector3Verifier(),
new DoubleMatrix3Verifier()
),
"Stores the static rotation as either a vector containing Euler angles "
"or by specifiying the 3x3 rotation matrix directly",
Optional::No
}
},
Exhaustive::Yes
};
}
StaticRotation::StaticRotation()
: _rotationMatrix("rotation", "Rotation", glm::dmat3(1.0))
{}
StaticRotation::StaticRotation(const ghoul::Dictionary& dictionary)
: _rotationMatrix(1.0)
: StaticRotation()
{
const bool hasEulerAngles = dictionary.hasKeyAndValue<glm::dvec3>(KeyEulerAngles);
if (hasEulerAngles) {
glm::dvec3 tmp;
dictionary.getValue(KeyEulerAngles, tmp);
_rotationMatrix = glm::mat3_cast(glm::dquat(tmp));
documentation::testSpecificationAndThrow(
Documentation(),
dictionary,
"StaticRotation"
);
if (dictionary.hasKeyAndValue<glm::dvec3>(KeyRotation)) {
_rotationMatrix = glm::mat3_cast(
glm::dquat(dictionary.value<glm::dvec3>(KeyRotation))
);
}
else {
// Must be glm::dmat3 due to specification restriction
_rotationMatrix = dictionary.value<glm::dmat3>(KeyRotation);
}
_rotationMatrix.onChange([this]() { _matrix = _rotationMatrix; });
}
StaticRotation::~StaticRotation() {}
const glm::dmat3& StaticRotation::matrix() const {
return _rotationMatrix;
}
void StaticRotation::update(const UpdateData&) {}
} // namespace openspace
} // namespace openspace
+10 -7
View File
@@ -27,17 +27,20 @@
#include <openspace/scene/rotation.h>
#include <openspace/documentation/documentation.h>
#include <openspace/properties/matrixproperty.h>
namespace openspace {
class StaticRotation: public Rotation {
class StaticRotation : public Rotation {
public:
StaticRotation(const ghoul::Dictionary& dictionary
= ghoul::Dictionary());
virtual ~StaticRotation();
virtual const glm::dmat3& matrix() const;
virtual void update(const UpdateData& data) override;
StaticRotation();
StaticRotation(const ghoul::Dictionary& dictionary);
static openspace::Documentation Documentation();
private:
glm::dmat3 _rotationMatrix;
properties::DMat3Property _rotationMatrix;
};
} // namespace openspace