From bd867ec402ba919457f296d9ed9dd585a7b9898d Mon Sep 17 00:00:00 2001 From: Kalle Bladin Date: Fri, 12 Aug 2016 12:28:56 -0400 Subject: [PATCH] Update SceneGraphNode to contain rotation information and remove rotation definition from renderable model. --- data/scene/osirisrex.scene | 15 +++- data/scene/osirisrex/osirisrex/osirisrex.mod | 11 ++- include/openspace/scene/ephemeris.h | 1 - include/openspace/scene/scenegraphnode.h | 9 ++- include/openspace/util/updatestructures.h | 2 +- modules/base/ephemeris/spiceephemeris.cpp | 17 +--- modules/base/ephemeris/spiceephemeris.h | 2 - modules/base/ephemeris/staticephemeris.cpp | 4 - modules/base/ephemeris/staticephemeris.h | 1 - modules/base/rendering/renderablemodel.cpp | 27 +++---- modules/base/rendering/renderablemodel.h | 6 +- src/scene/scenegraphnode.cpp | 84 ++++++++++++++++++-- 12 files changed, 122 insertions(+), 57 deletions(-) diff --git a/data/scene/osirisrex.scene b/data/scene/osirisrex.scene index 1fd97ca2e5..3caa345680 100644 --- a/data/scene/osirisrex.scene +++ b/data/scene/osirisrex.scene @@ -34,7 +34,18 @@ function preInitialization() openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/background/lsk/naif0011.tls") openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/background/pck/bennu_SPH250m.tpc") openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/background/pck/bennu_v10.tpc") - + + -- Low res SPK + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/background/spk/orx_160917_231024_pgaa3_day15m60_v1.bsp") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/background/spk/orx_160914_231024_pgaa3_day12m60_v1.bsp") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/background/spk/orx_160908_231024_pgaa3_day06m60_v1.bsp") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/background/spk/spk_orx_160908_231024_pgaa2_day06m60_v3.bsp") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/background/spk/orx_160908_231024_pgaa2_day06m60.bsp") + + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/background/spk/OREX_20160908_M60_complete.bsp") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/background/spk/OREX_20160904_M45_complete.bsp") + + -- SPK openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/background/spk/de421.bsp") openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/background/spk/sb-101955-76.bsp") @@ -136,7 +147,7 @@ function preInitialization() -- openspace.time.setTime("2015-07-12T22:19:20.00") -- openspace.time.setTime("2015-07-13T20:59:00.00") -- openspace.time.setTime("2015-07-14T02:41:55.00") - openspace.time.setTime("2019-01-13T19:18:00.00") + openspace.time.setTime("2016-09-08T00:00:00.00") openspace.time.setDeltaTime(0) end diff --git a/data/scene/osirisrex/osirisrex/osirisrex.mod b/data/scene/osirisrex/osirisrex/osirisrex.mod index 825ba84575..57988b5c16 100644 --- a/data/scene/osirisrex/osirisrex/osirisrex.mod +++ b/data/scene/osirisrex/osirisrex/osirisrex.mod @@ -19,17 +19,12 @@ return { Type = "simple", Color = "textures/osirisTex.png", }, - Rotation = { - Source = "ORX_SPACECRAFT", - Destination = "GALACTIC" - }, Shading = { PerformShading = true, Fadeable = false, Ghosting = false, }, }, - Ephemeris = { Type = "Spice", Body = "OSIRIS-REX", @@ -37,6 +32,10 @@ return { Reference = "GALACTIC", Observer = BENNU_BODY, }, + Rotation = { + Source = "ORX_SPACECRAFT", + Destination = "GALACTIC" + }, GuiName = "/Solar/OsirisRex" }, @@ -60,7 +59,7 @@ return { DrawLine = true, StartTime = "2016 SEP 8 12:00:00", - EndTime = "2022 OCT 17 12:00:00" + EndTime = "2023 SEP 24 12:00:00" }, GuiName = "/Solar/OsirisRexTrail" }, diff --git a/include/openspace/scene/ephemeris.h b/include/openspace/scene/ephemeris.h index 839b070f71..026e024b24 100644 --- a/include/openspace/scene/ephemeris.h +++ b/include/openspace/scene/ephemeris.h @@ -39,7 +39,6 @@ public: virtual ~Ephemeris(); virtual bool initialize(); virtual const glm::dvec3& position() const = 0; - virtual const glm::dmat3& worldRotationMatrix() const = 0; virtual void update(const UpdateData& data); protected: diff --git a/include/openspace/scene/scenegraphnode.h b/include/openspace/scene/scenegraphnode.h index f087f62a3b..9a938af6df 100644 --- a/include/openspace/scene/scenegraphnode.h +++ b/include/openspace/scene/scenegraphnode.h @@ -50,8 +50,7 @@ public: long long updateTimeEphemeris; // time in ns }; - static std::string RootNodeName; - + static const std::string RootNodeName; static const std::string KeyName; static const std::string KeyParentName; static const std::string KeyDependencies; @@ -105,11 +104,16 @@ private: bool sphereInsideFrustum(const psc& s_pos, const PowerScaledScalar& s_rad, const Camera* camera); glm::dvec3 calculateWorldPosition() const; + glm::dmat3 calculateWorldRotation() const; std::vector _children; SceneGraphNode* _parent; Ephemeris* _ephemeris; + std::string _rotationSourceFrame; + std::string _rotationDestinationFrame; + glm::dmat3 _rotationMatrix; + PerformanceRecord _performanceRecord; Renderable* _renderable; @@ -120,6 +124,7 @@ private: //psc _worldPositionCached; glm::dvec3 _worldPositionCached; + glm::dmat3 _worldRotationCached; }; } // namespace openspace diff --git a/include/openspace/util/updatestructures.h b/include/openspace/util/updatestructures.h index 4842f71277..c4f1df7560 100644 --- a/include/openspace/util/updatestructures.h +++ b/include/openspace/util/updatestructures.h @@ -51,7 +51,7 @@ struct RenderData { psc position; bool doPerformanceMeasurement; glm::dvec3 positionVec3; - + glm::dmat3 rotation; }; struct RaycasterTask { diff --git a/modules/base/ephemeris/spiceephemeris.cpp b/modules/base/ephemeris/spiceephemeris.cpp index a6ed521a55..36c81ac26a 100644 --- a/modules/base/ephemeris/spiceephemeris.cpp +++ b/modules/base/ephemeris/spiceephemeris.cpp @@ -77,25 +77,14 @@ const glm::dvec3& SpiceEphemeris::position() const { return _position; } -const glm::dmat3& SpiceEphemeris::worldRotationMatrix() const { - return _worldRotationMatrix; -} - void SpiceEphemeris::update(const UpdateData& data) { if (!_kernelsLoadedSuccessfully) return; double lightTime = 0.0; - glm::dvec3 position = SpiceManager::ref().targetPosition(_targetName, _originName, "GALACTIC", {}, data.time, lightTime); - std::string frame = SpiceManager::ref().frameFromBody(_targetName); - if (SpiceManager::ref().hasFrameId(frame)) - { - _worldRotationMatrix = SpiceManager::ref().positionTransformMatrix(frame, "GALACTIC", data.time); - } - else - { - _worldRotationMatrix = glm::dmat3(1.0); - } + glm::dvec3 position = SpiceManager::ref().targetPosition( + _targetName, _originName, "GALACTIC", {}, data.time, lightTime); + //double interval = openspace::ImageSequencer::ref().getIntervalLength(); //if (_ghosting == "TRUE" && interval > 60){ // double _time = openspace::ImageSequencer::ref().getNextCaptureTime(); diff --git a/modules/base/ephemeris/spiceephemeris.h b/modules/base/ephemeris/spiceephemeris.h index 7370759b13..973c388072 100644 --- a/modules/base/ephemeris/spiceephemeris.h +++ b/modules/base/ephemeris/spiceephemeris.h @@ -35,14 +35,12 @@ class SpiceEphemeris : public Ephemeris { public: SpiceEphemeris(const ghoul::Dictionary& dictionary); virtual const glm::dvec3& position() const; - virtual const glm::dmat3& worldRotationMatrix() const; void update(const UpdateData& data) override; private: std::string _targetName; std::string _originName; glm::dvec3 _position; - glm::dmat3 _worldRotationMatrix; bool _kernelsLoadedSuccessfully; //std::string _ghosting; std::string _name; diff --git a/modules/base/ephemeris/staticephemeris.cpp b/modules/base/ephemeris/staticephemeris.cpp index 9505ebce35..e8ea2d8674 100644 --- a/modules/base/ephemeris/staticephemeris.cpp +++ b/modules/base/ephemeris/staticephemeris.cpp @@ -47,10 +47,6 @@ const glm::dvec3& StaticEphemeris::position() const { return _position; } -const glm::dmat3& StaticEphemeris::worldRotationMatrix() const { - return glm::dmat3(1.0); -} - void StaticEphemeris::update(const UpdateData&) {} } // namespace openspace \ No newline at end of file diff --git a/modules/base/ephemeris/staticephemeris.h b/modules/base/ephemeris/staticephemeris.h index c30094467b..491a872b7a 100644 --- a/modules/base/ephemeris/staticephemeris.h +++ b/modules/base/ephemeris/staticephemeris.h @@ -35,7 +35,6 @@ public: = ghoul::Dictionary()); virtual ~StaticEphemeris(); virtual const glm::dvec3& position() const; - virtual const glm::dmat3& worldRotationMatrix() const; virtual void update(const UpdateData& data) override; private: glm::dvec3 _position; diff --git a/modules/base/rendering/renderablemodel.cpp b/modules/base/rendering/renderablemodel.cpp index 4becb16e01..57218e92ea 100644 --- a/modules/base/rendering/renderablemodel.cpp +++ b/modules/base/rendering/renderablemodel.cpp @@ -46,8 +46,6 @@ namespace { const std::string _loggerCat = "RenderableModel"; - const std::string keySource = "Rotation.Source"; - const std::string keyDestination = "Rotation.Destination"; const std::string keyGeometry = "Geometry"; const std::string keyBody = "Body"; const std::string keyStart = "StartTime"; @@ -61,12 +59,12 @@ namespace { namespace openspace { - RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary) +RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary) : Renderable(dictionary) , _colorTexturePath("colorTexture", "Color Texture") , _performFade("performFading", "Perform Fading", false) - , _debugModelRotation("modelrotation", "Model Rotation", glm::vec3(0.f), glm::vec3(0.f), glm::vec3(360.f)) , _fading("fading", "Fade", 0) + , _debugModelRotation("modelrotation", "Model Rotation", glm::vec3(0.f), glm::vec3(0.f), glm::vec3(360.f)) , _programObject(nullptr) , _texture(nullptr) , _geometry(nullptr) @@ -92,20 +90,21 @@ namespace openspace { _colorTexturePath = absPath(texturePath); addPropertySubOwner(_geometry); + addProperty(_colorTexturePath); _colorTexturePath.onChange(std::bind(&RenderableModel::loadTexture, this)); addProperty(_debugModelRotation); - dictionary.getValue(keySource, _source); - dictionary.getValue(keyDestination, _destination); + //dictionary.getValue(keySource, _source); + //dictionary.getValue(keyDestination, _destination); if (dictionary.hasKeyAndValue(keyModelTransform)) dictionary.getValue(keyModelTransform, _modelTransform); else _modelTransform = glm::dmat3(1.f); dictionary.getValue(keyBody, _target); - openspace::SpiceManager::ref().addFrame(_target, _source); + //openspace::SpiceManager::ref().addFrame(_target, _source); //setBoundingSphere(pss(1.f, 9.f)); addProperty(_performShading); @@ -149,8 +148,8 @@ bool RenderableModel::initialize() { completeSuccess &= (_texture != nullptr); completeSuccess &= _geometry->initialize(this); - completeSuccess &= !_source.empty(); - completeSuccess &= !_destination.empty(); + //completeSuccess &= !_source.empty(); + //completeSuccess &= !_destination.empty(); return completeSuccess; } @@ -200,8 +199,6 @@ void RenderableModel::render(const RenderData& data) { } - - // Calculate variables to be used as uniform variables in shader glm::dvec3 bodyPosition = data.positionVec3; @@ -216,7 +213,7 @@ void RenderableModel::render(const RenderData& data) { // Model transform and view transform needs to be in double precision glm::dmat4 modelTransform = glm::translate(glm::dmat4(1.0), bodyPosition) * // Translation - glm::dmat4(_stateMatrix) * // Spice rotation + glm::dmat4(data.rotation) * // Spice rotation debugModelRotation; // debug model rotation controlled from GUI glm::dmat4 modelViewTransform = data.camera.combinedViewMatrix() * modelTransform; glm::vec3 directionToSun = glm::normalize(_sunPosition.vec3() - glm::vec3(bodyPosition)); @@ -265,9 +262,9 @@ void RenderableModel::update(const UpdateData& data) { //} // set spice-orientation in accordance to timestamp - if (!_source.empty()) { - _stateMatrix = SpiceManager::ref().positionTransformMatrix(_source, _destination, _time) * _modelTransform; - } + //if (!_source.empty()) { + // _stateMatrix = SpiceManager::ref().positionTransformMatrix(_source, _destination, _time) * _modelTransform; + //} double lt; glm::dvec3 p = diff --git a/modules/base/rendering/renderablemodel.h b/modules/base/rendering/renderablemodel.h index bf658aca9d..f93a4afae4 100644 --- a/modules/base/rendering/renderablemodel.h +++ b/modules/base/rendering/renderablemodel.h @@ -67,10 +67,10 @@ private: glm::dmat3 _modelTransform; float _alpha; - glm::dmat3 _stateMatrix; + //glm::dmat3 _stateMatrix; - std::string _source; - std::string _destination; + //std::string _source; + //std::string _destination; std::string _target; //bool _isGhost; diff --git a/src/scene/scenegraphnode.cpp b/src/scene/scenegraphnode.cpp index 9750fd0847..bc3e0cebf9 100644 --- a/src/scene/scenegraphnode.cpp +++ b/src/scene/scenegraphnode.cpp @@ -25,6 +25,8 @@ // open space includes #include #include +#include +#include // ghoul includes #include @@ -45,11 +47,13 @@ namespace { const std::string _loggerCat = "SceneGraphNode"; const std::string KeyRenderable = "Renderable"; const std::string KeyEphemeris = "Ephemeris"; + const std::string keyRotation = "Rotation"; } namespace openspace { - -std::string SceneGraphNode::RootNodeName = "Root"; + +// Constants used outside of this file +const std::string SceneGraphNode::RootNodeName = "Root"; const std::string SceneGraphNode::KeyName = "Name"; const std::string SceneGraphNode::KeyParentName = "Parent"; const std::string SceneGraphNode::KeyDependencies = "Dependencies"; @@ -81,7 +85,7 @@ SceneGraphNode* SceneGraphNode::createFromDictionary(const ghoul::Dictionary& di return nullptr; } result->addPropertySubOwner(result->_renderable); - LDEBUG("Successfully create renderable for '" << result->name() << "'"); + LDEBUG("Successfully created renderable for '" << result->name() << "'"); } if (dictionary.hasKey(KeyEphemeris)) { @@ -96,7 +100,30 @@ SceneGraphNode* SceneGraphNode::createFromDictionary(const ghoul::Dictionary& di return nullptr; } //result->addPropertySubOwner(result->_ephemeris); - LDEBUG("Successfully create ephemeris for '" << result->name() << "'"); + LDEBUG("Successfully created ephemeris for '" << result->name() << "'"); + } + + if (dictionary.hasKey(keyRotation)) { + bool rotationSuccess = true; + + ghoul::Dictionary rotationDictionary; + rotationSuccess &= dictionary.getValue("Rotation.Source", result->_rotationSourceFrame); + rotationSuccess &= dictionary.getValue("Rotation.Destination", result->_rotationDestinationFrame); + + if (!rotationSuccess) { + LERROR("Failed to create rotation for SceneGraphNode '" + << result->name() << "'"); + delete result; + return nullptr; + } + else + LDEBUG("Successfully created rotation for SceneGraphNode '" << result->name() << "'"); + } + else { + LERROR("Rotation specification not found for SceneGraphNode '" + << result->name() << "'. Using static rotation instead"); + result->_rotationSourceFrame = "GALACTIC"; + result->_rotationDestinationFrame = "GALACTIC"; } //std::string parentName; @@ -122,6 +149,7 @@ SceneGraphNode* SceneGraphNode::createFromDictionary(const ghoul::Dictionary& di SceneGraphNode::SceneGraphNode() : _parent(nullptr) , _ephemeris(new StaticEphemeris) + , _rotationMatrix(glm::dmat3(1.0)) , _performanceRecord({0, 0, 0}) , _renderable(nullptr) , _renderableVisible(false) @@ -201,8 +229,37 @@ void SceneGraphNode::update(const UpdateData& data) { else _renderable->update(newUpdateData); } + + // TODO : Need to be checking for real if the frame is fixed since fixed frames + // do not have CK coverage. + bool sourceFrameIsFixed = _rotationSourceFrame == "GALACTIC"; + bool destinationFrameIsFixed = _rotationDestinationFrame == "GALACTIC"; + + bool sourceHasCoverage = + !_rotationSourceFrame.empty() && + SpiceManager::ref().hasFrameId(_rotationSourceFrame) && + (SpiceManager::ref().hasCkCoverage(_rotationSourceFrame, data.time) || + sourceFrameIsFixed); + bool destinationHasCoverage = + !_rotationDestinationFrame.empty() && + SpiceManager::ref().hasFrameId(_rotationDestinationFrame) && + (SpiceManager::ref().hasCkCoverage(_rotationDestinationFrame, data.time) || + destinationFrameIsFixed); + + if (sourceHasCoverage && destinationHasCoverage) { + _rotationMatrix = SpiceManager::ref().positionTransformMatrix( + _rotationSourceFrame, + _rotationDestinationFrame, + data.time); + } + else { + _rotationMatrix = glm::dmat3(1.0); + } + _worldPositionCached = calculateWorldPosition(); newUpdateData.position = worldPosition(); + + _worldRotationCached = calculateWorldRotation(); } void SceneGraphNode::evaluate(const Camera* camera, const psc& parentPosition) { @@ -248,7 +305,12 @@ void SceneGraphNode::evaluate(const Camera* camera, const psc& parentPosition) { void SceneGraphNode::render(const RenderData& data, RendererTasks& tasks) { const psc thisPositionPSC = psc::CreatePowerScaledCoordinate(_worldPositionCached.x, _worldPositionCached.y, _worldPositionCached.z); - RenderData newData = {data.camera, thisPositionPSC, data.doPerformanceMeasurement, _worldPositionCached}; + RenderData newData = { + data.camera, + thisPositionPSC, + data.doPerformanceMeasurement, + _worldPositionCached, + _worldRotationCached}; _performanceRecord.renderTime = 0; if (_renderableVisible && _renderable->isVisible() && _renderable->isReady() && _renderable->isEnabled()) { @@ -326,7 +388,7 @@ glm::dvec3 SceneGraphNode::worldPosition() const const glm::dmat3& SceneGraphNode::worldRotationMatrix() const { - return _ephemeris->worldRotationMatrix(); + return _worldRotationCached; } glm::dvec3 SceneGraphNode::calculateWorldPosition() const { @@ -339,6 +401,16 @@ glm::dvec3 SceneGraphNode::calculateWorldPosition() const { } } +glm::dmat3 SceneGraphNode::calculateWorldRotation() const { + // recursive up the hierarchy if there are parents available + if (_parent) { + return _parent->calculateWorldRotation() * _rotationMatrix; + } + else { + return _rotationMatrix; + } +} + SceneGraphNode* SceneGraphNode::parent() const { return _parent;