From 542b9e11e60be44ffbf96e6f93e008cff002f8fb Mon Sep 17 00:00:00 2001 From: Kalle Bladin Date: Wed, 17 Aug 2016 00:19:25 -0400 Subject: [PATCH] Update SceneGraphNode to have a full transformation defined in terms of translation, scale and rotation. --- data/scene/osirisrex.scene | 2 +- data/scene/osirisrex/bennu/bennu.mod | 22 ++- data/scene/osirisrex/osirisrex/osirisrex.mod | 170 +++++++++++------ include/openspace/scene/scenegraphnode.h | 27 ++- include/openspace/util/updatestructures.h | 1 + modules/base/CMakeLists.txt | 6 + modules/base/basemodule.cpp | 26 ++- modules/base/ephemeris/staticephemeris.cpp | 8 +- modules/base/rendering/renderablemodel.cpp | 3 +- src/CMakeLists.txt | 4 + src/scene/scenegraphnode.cpp | 184 +++++++++++-------- 11 files changed, 296 insertions(+), 157 deletions(-) diff --git a/data/scene/osirisrex.scene b/data/scene/osirisrex.scene index 3caa345680..0df2d2b1ad 100644 --- a/data/scene/osirisrex.scene +++ b/data/scene/osirisrex.scene @@ -147,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("2016-09-08T00:00:00.00") + openspace.time.setTime("2018-12-20T22:47:00.00") openspace.time.setDeltaTime(0) end diff --git a/data/scene/osirisrex/bennu/bennu.mod b/data/scene/osirisrex/bennu/bennu.mod index be5b79ff2a..064a220167 100644 --- a/data/scene/osirisrex/bennu/bennu.mod +++ b/data/scene/osirisrex/bennu/bennu.mod @@ -75,12 +75,22 @@ return { }, }, - Ephemeris = { - Type = "Spice", - Body = BENNU_BODY, - -- Reference = "ECLIPJ2000", - Reference = "GALACTIC", - Observer = "SUN", + Transform = { + Translation = { + Type = "SpiceEphemeris", + Body = BENNU_BODY, + Reference = "GALACTIC", + Observer = "SUN", + }, + Rotation = { + Type = "SpiceRotation", + SourceFrame = "IAU_BENNU", + DestinationFrame = "GALACTIC", + }, + Scale = { + Type = "StaticScale", + Scale = 1, + }, }, GuiName = "/Solar/Bennu" diff --git a/data/scene/osirisrex/osirisrex/osirisrex.mod b/data/scene/osirisrex/osirisrex/osirisrex.mod index d3979c3bf6..8450ee546e 100644 --- a/data/scene/osirisrex/osirisrex/osirisrex.mod +++ b/data/scene/osirisrex/osirisrex/osirisrex.mod @@ -6,7 +6,7 @@ return { ------------------------ { Name = "OsirisRex", - Parent = "Bennu2", + Parent = "SolarSystemBarycenter", Renderable = { Type = "RenderableModel", Body = "OSIRIS-REX", @@ -25,18 +25,23 @@ return { Ghosting = false, }, }, - Ephemeris = { - Type = "Spice", - Body = "OSIRIS-REX", - -- Reference = "ECLIPJ2000", - Reference = "GALACTIC", - Observer = BENNU_BODY, + Transform = { + Translation = { + Type = "SpiceEphemeris", + Body = "OSIRIS-REX", + Reference = "GALACTIC", + Observer = "SUN", + }, + Rotation = { + Type = "SpiceRotation", + SourceFrame = "ORX_SPACECRAFT", + DestinationFrame = "GALACTIC", + }, + Scale = { + Type = "StaticScale", + Scale = 1, + }, }, - Rotation = { - Source = "ORX_SPACECRAFT", - Destination = "GALACTIC" - }, - GuiName = "/Solar/OsirisRex" }, @@ -61,55 +66,67 @@ return { Ghosting = false, }, }, - Ephemeris = { - Type = "Static", + + Transform = { + Translation = { + Type = "StaticEphemeris", + Position = {1, 0, 0}, + }, + Rotation = { + Type = "SpiceRotation", + SourceFrame = "ORX_OCAMS_POLYCAM", + DestinationFrame = "ORX_SPACECRAFT", + }, + Scale = { + Type = "StaticScale", + Scale = 1, + }, }, - Rotation = { - Source = "ORX_OCAMS_POLYCAM", - Destination = "ORX_SPACECRAFT" + GuiName = "/Solar/ORX_OCAMS_POLYCAM" + }, + + { + Name = "ORX_REXIS", + Parent = "OsirisRex", + Renderable = { + Type = "RenderableModel", + Body = "OSIRIS-REX", + Geometry = { + Type = "MultiModelGeometry", + GeometryFile = "models/Osiris.obj", + Magnification = 0, + }, + Textures = { + Type = "simple", + Color = "textures/osirisTex.png", + }, + Shading = { + PerformShading = true, + Fadeable = false, + Ghosting = false, + }, }, Transform = { - Translation = {1,0,0}, -- Translation relative to parent - --Rotation = {0,0,0}, -- Euler angles relative to parent (not implemented) - --Scale = {1,1,1}, -- Scale relative to parent (not implemented) + Translation = { + Type = "StaticEphemeris", + Position = {-1, 0, 0}, + }, + Rotation = { + Type = "SpiceRotation", + SourceFrame = "ORX_REXIS", + DestinationFrame = "ORX_SPACECRAFT", + }, + Scale = { + Type = "StaticScale", + Scale = 1, + }, }, - GuiName = "/Solar/ORX_OCAMS_POLYCAM" + GuiName = "/Solar/ORX_REXIS" }, - - --[[ { - Name = "ORX_OCAMS_POLYCAM FOV", - Parent = "ORX_OCAMS_POLYCAM", - Renderable = { - Type = "RenderableFov", - Body = "OSIRIS-REX", - Frame = "GALACTIC", - RGB = { 0.8, 0.7, 0.7 }, - Textures = { - Type = "simple", - Color = "textures/glare_blue.png", - -- need to add different texture - }, - Instrument = { - Name = "ORX_OCAMS_POLYCAM", - Method = "ELLIPSOID", - Aberration = "NONE", - }, - PotentialTargets = { - "Bennu2", - } - }, - GuiName = "/Solar/ORX_OCAMS_POLYCAM" - }, -]] - - - - - { - Name = "POLYCAM", + Name = "POLYCAM FOV", Parent = "ORX_OCAMS_POLYCAM", Renderable = { Type = "RenderableFov", @@ -130,10 +147,35 @@ return { BENNU_BODY -- Bennu } }, - GuiName = "/Solar/POLYCAM" + GuiName = "/Solar/POLYCAM FOV" + }, + + { + Name = "REXIS FOV", + Parent = "ORX_REXIS", + Renderable = { + Type = "RenderableFov", + Body = "OSIRIS-REX", + Frame = "ORX_REXIS", + RGB = { 0.8, 0.7, 0.7 }, + Textures = { + Type = "simple", + Color = "textures/glare_blue.png", + -- need to add different texture + }, + Instrument = { + Name = "ORX_REXIS", + Method = "ELLIPSOID", + Aberration = "NONE", + }, + PotentialTargets = { + BENNU_BODY -- Bennu + } + }, + GuiName = "/Solar/REXIS FOV" }, - -- Latest image taken by POLYCAM --[[ + -- Latest image taken by POLYCAM { Name = "ImagePlaneOsirisRex", Parent = "OsirisRex", @@ -151,6 +193,24 @@ return { Position = {0, 0, 0, 1} }, }, + -- POLYCAM FoV square + { + Name = "FovImagePlane", + Parent = "OsirisRex", + Renderable = { + Type = "RenderablePlaneProjection", + Frame = "IAU_BENNU", + DefaultTarget = BENNU_BODY, + Spacecraft = "OSIRIS-REX", + Instrument = "ORX_OCAMS_POLYCAM", + Moving = true, + Texture = "textures/squarefov.png", + }, + Ephemeris = { + Type = "Static", + Position = {0, 0, 0, 1} + }, + }, ]] { diff --git a/include/openspace/scene/scenegraphnode.h b/include/openspace/scene/scenegraphnode.h index b6c2339a69..3fbdee1216 100644 --- a/include/openspace/scene/scenegraphnode.h +++ b/include/openspace/scene/scenegraphnode.h @@ -28,6 +28,8 @@ // open space includes #include #include +#include +#include #include #include @@ -76,10 +78,12 @@ public: //bool abandonChild(SceneGraphNode* child); glm::dvec3 position() const; - glm::dvec3 worldPosition() const; - const glm::dmat3& rotationMatrix() const; + double scale() const; + + glm::dvec3 worldPosition() const; const glm::dmat3& worldRotationMatrix() const; + double worldScale() const; SceneGraphNode* parent() const; const std::vector& children() const; @@ -96,6 +100,7 @@ public: Renderable* renderable(); // @TODO Remove once the scalegraph is in effect ---abock + void setEphemeris(Ephemeris* eph) { delete _ephemeris; _ephemeris = eph; @@ -106,14 +111,19 @@ private: glm::dvec3 calculateWorldPosition() const; glm::dmat3 calculateWorldRotation() const; + double calculateWorldScale() const; + + // Transformation defined by ephemeris, rotation and scale + Ephemeris* _ephemeris; + Rotation* _rotation; + Scale* _scale; + + glm::dvec3 _worldPositionCached; + glm::dmat3 _worldRotationCached; + double _worldScaleCached; std::vector _children; SceneGraphNode* _parent; - Ephemeris* _ephemeris; - - std::string _rotationSourceFrame; - std::string _rotationDestinationFrame; - glm::dmat3 _rotationMatrix; PerformanceRecord _performanceRecord; @@ -123,9 +133,6 @@ private: bool _boundingSphereVisible; PowerScaledScalar _boundingSphere; - glm::dvec3 _translation; // Relative translation added on the ephemeris position - glm::dvec3 _worldPositionCached; - glm::dmat3 _worldRotationCached; }; } // namespace openspace diff --git a/include/openspace/util/updatestructures.h b/include/openspace/util/updatestructures.h index c4f1df7560..7dd777d765 100644 --- a/include/openspace/util/updatestructures.h +++ b/include/openspace/util/updatestructures.h @@ -52,6 +52,7 @@ struct RenderData { bool doPerformanceMeasurement; glm::dvec3 positionVec3; glm::dmat3 rotation; + double scale; }; struct RaycasterTask { diff --git a/modules/base/CMakeLists.txt b/modules/base/CMakeLists.txt index c373608f32..3e62431a91 100644 --- a/modules/base/CMakeLists.txt +++ b/modules/base/CMakeLists.txt @@ -43,6 +43,9 @@ set(HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/rendering/screenspaceimage.h ${CMAKE_CURRENT_SOURCE_DIR}/ephemeris/spiceephemeris.h ${CMAKE_CURRENT_SOURCE_DIR}/ephemeris/staticephemeris.h + ${CMAKE_CURRENT_SOURCE_DIR}/rotation/spicerotation.h + ${CMAKE_CURRENT_SOURCE_DIR}/rotation/staticrotation.h + ${CMAKE_CURRENT_SOURCE_DIR}/scale/staticscale.h ) source_group("Header Files" FILES ${HEADER_FILES}) @@ -65,6 +68,9 @@ set(SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/rendering/screenspaceimage.cpp ${CMAKE_CURRENT_SOURCE_DIR}/ephemeris/spiceephemeris.cpp ${CMAKE_CURRENT_SOURCE_DIR}/ephemeris/staticephemeris.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/rotation/spicerotation.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/rotation/staticrotation.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/scale/staticscale.cpp ) source_group("Source Files" FILES ${SOURCE_FILES}) diff --git a/modules/base/basemodule.cpp b/modules/base/basemodule.cpp index b33c35fabd..7247f244d2 100644 --- a/modules/base/basemodule.cpp +++ b/modules/base/basemodule.cpp @@ -50,6 +50,11 @@ #include #include +#include +#include + +#include + #include namespace openspace { @@ -61,7 +66,10 @@ BaseModule::BaseModule() void BaseModule::internalInitialize() { FactoryManager::ref().addFactory(std::make_unique>()); FactoryManager::ref().addFactory(std::make_unique>()); - FactoryManager::ref().addFactory(std::make_unique>()); + FactoryManager::ref().addFactory(std::make_unique>()); + + FactoryManager::ref().addFactory(std::make_unique>()); + FactoryManager::ref().addFactory(std::make_unique>()); auto fScreenSpaceRenderable = FactoryManager::ref().factory(); ghoul_assert(fScreenSpaceRenderable, "ScreenSpaceRenderable factory was not created"); @@ -85,8 +93,20 @@ void BaseModule::internalInitialize() { auto fEphemeris = FactoryManager::ref().factory(); ghoul_assert(fEphemeris, "Ephemeris factory was not created"); - fEphemeris->registerClass("Static"); - fEphemeris->registerClass("Spice"); + + fEphemeris->registerClass("StaticEphemeris"); + fEphemeris->registerClass("SpiceEphemeris"); + + auto fRotation = FactoryManager::ref().factory(); + ghoul_assert(fRotation, "Rotation factory was not created"); + + fRotation->registerClass("StaticRotation"); + fRotation->registerClass("SpiceRotation"); + + auto fScale = FactoryManager::ref().factory(); + ghoul_assert(fScale, "Scale factory was not created"); + + fScale->registerClass ("StaticScale"); auto fPlanetGeometry = FactoryManager::ref().factory(); ghoul_assert(fPlanetGeometry, "Planet geometry factory was not created"); diff --git a/modules/base/ephemeris/staticephemeris.cpp b/modules/base/ephemeris/staticephemeris.cpp index e8ea2d8674..e95e324546 100644 --- a/modules/base/ephemeris/staticephemeris.cpp +++ b/modules/base/ephemeris/staticephemeris.cpp @@ -31,13 +31,11 @@ namespace { namespace openspace { StaticEphemeris::StaticEphemeris(const ghoul::Dictionary& dictionary) - : _position(0.f, 0.f, 0.f) + : _position(0.0, 0.0, 0.0) { - const bool hasPosition = dictionary.hasKeyAndValue(KeyPosition); + const bool hasPosition = dictionary.hasKeyAndValue(KeyPosition); if (hasPosition) { - glm::dvec4 tmp; - dictionary.getValue(KeyPosition, tmp); - _position = tmp.xyz() * glm::pow(10.0, tmp.w); + dictionary.getValue(KeyPosition, _position); } } diff --git a/modules/base/rendering/renderablemodel.cpp b/modules/base/rendering/renderablemodel.cpp index 8863ebebf8..d0bfe8d734 100644 --- a/modules/base/rendering/renderablemodel.cpp +++ b/modules/base/rendering/renderablemodel.cpp @@ -211,11 +211,10 @@ void RenderableModel::render(const RenderData& data) { glm::dmat4 modelTransform = glm::translate(glm::dmat4(1.0), data.positionVec3) * // Translation glm::dmat4(data.rotation) * // Spice rotation + glm::dmat4(glm::scale(glm::dmat4(1.0), glm::dvec3(data.scale))); debugModelRotation; // debug model rotation controlled from GUI glm::dmat4 modelViewTransform = data.camera.combinedViewMatrix() * modelTransform; - - glm::vec3 directionToSun = glm::normalize(_sunPos - data.positionVec3); glm::vec3 directionToSunViewSpace = glm::mat3(data.camera.combinedViewMatrix()) * directionToSun; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d3b53a703f..718429a4e2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -74,6 +74,8 @@ set(OPENSPACE_SOURCE ${OPENSPACE_BASE_DIR}/src/rendering/screenspacerenderable.cpp ${OPENSPACE_BASE_DIR}/src/rendering/transferfunction.cpp ${OPENSPACE_BASE_DIR}/src/scene/ephemeris.cpp + ${OPENSPACE_BASE_DIR}/src/scene/rotation.cpp + ${OPENSPACE_BASE_DIR}/src/scene/scale.cpp ${OPENSPACE_BASE_DIR}/src/scene/scene.cpp ${OPENSPACE_BASE_DIR}/src/scene/scene_lua.inl ${OPENSPACE_BASE_DIR}/src/scene/scenegraph.cpp @@ -159,6 +161,8 @@ set(OPENSPACE_HEADER ${OPENSPACE_BASE_DIR}/include/openspace/rendering/volumeraycaster.h ${OPENSPACE_BASE_DIR}/include/openspace/rendering/transferfunction.h ${OPENSPACE_BASE_DIR}/include/openspace/scene/ephemeris.h + ${OPENSPACE_BASE_DIR}/include/openspace/scene/rotation.h + ${OPENSPACE_BASE_DIR}/include/openspace/scene/scale.h ${OPENSPACE_BASE_DIR}/include/openspace/scene/scene.h ${OPENSPACE_BASE_DIR}/include/openspace/scene/scenegraph.h ${OPENSPACE_BASE_DIR}/include/openspace/scene/scenegraphnode.h diff --git a/src/scene/scenegraphnode.cpp b/src/scene/scenegraphnode.cpp index d144eb4a9e..a26bfbf4c9 100644 --- a/src/scene/scenegraphnode.cpp +++ b/src/scene/scenegraphnode.cpp @@ -37,6 +37,9 @@ #include #include +#include +#include + #include #include @@ -46,10 +49,10 @@ namespace { const std::string _loggerCat = "SceneGraphNode"; const std::string KeyRenderable = "Renderable"; - const std::string KeyEphemeris = "Ephemeris"; - const std::string keyRotation = "Rotation"; - const std::string keyTranslation = "Transform.Translation"; + const std::string keyTransformTranslation = "Transform.Translation"; + const std::string keyTransformRotation = "Transform.Rotation"; + const std::string keyTransformScale = "Transform.Scale"; } namespace openspace { @@ -90,49 +93,46 @@ SceneGraphNode* SceneGraphNode::createFromDictionary(const ghoul::Dictionary& di LDEBUG("Successfully created renderable for '" << result->name() << "'"); } - if (dictionary.hasKey(KeyEphemeris)) { - ghoul::Dictionary ephemerisDictionary; - dictionary.getValue(KeyEphemeris, ephemerisDictionary); - delete result->_ephemeris; - result->_ephemeris = Ephemeris::createFromDictionary(ephemerisDictionary); + if (dictionary.hasKey(keyTransformTranslation)) { + ghoul::Dictionary translationDictionary; + dictionary.getValue(keyTransformTranslation, translationDictionary); + result->_ephemeris = + (Ephemeris::createFromDictionary(translationDictionary)); if (result->_ephemeris == nullptr) { LERROR("Failed to create ephemeris for SceneGraphNode '" - << result->name() << "'"); + << result->name() << "'"); delete result; return nullptr; } - //result->addPropertySubOwner(result->_ephemeris); LDEBUG("Successfully created ephemeris for '" << result->name() << "'"); } - if (dictionary.hasKey(keyRotation)) { - bool rotationSuccess = true; - + if (dictionary.hasKey(keyTransformRotation)) { ghoul::Dictionary rotationDictionary; - rotationSuccess &= dictionary.getValue("Rotation.Source", result->_rotationSourceFrame); - rotationSuccess &= dictionary.getValue("Rotation.Destination", result->_rotationDestinationFrame); - - if (!rotationSuccess) { + dictionary.getValue(keyTransformRotation, rotationDictionary); + result->_rotation = + (Rotation::createFromDictionary(rotationDictionary)); + if (result->_rotation == nullptr) { LERROR("Failed to create rotation for SceneGraphNode '" << result->name() << "'"); delete result; return nullptr; } - else - LDEBUG("Successfully created rotation for SceneGraphNode '" << result->name() << "'"); + LDEBUG("Successfully created rotation for '" << result->name() << "'"); } - else { - LERROR("Rotation specification not found for SceneGraphNode '" - << result->name() << "'. Using static rotation instead"); - result->_rotationSourceFrame = "GALACTIC"; - result->_rotationDestinationFrame = "GALACTIC"; - } - - if (dictionary.hasKey(keyTranslation)) { - dictionary.getValue(keyTranslation, result->_translation); - } - else { - result->_translation = glm::dvec3(0, 0, 0); + + if (dictionary.hasKey(keyTransformScale)) { + ghoul::Dictionary scaleDictionary; + dictionary.getValue(keyTransformScale, scaleDictionary); + result->_scale = + (Scale::createFromDictionary(scaleDictionary)); + if (result->_scale == nullptr) { + LERROR("Failed to create scale for SceneGraphNode '" + << result->name() << "'"); + delete result; + return nullptr; + } + LDEBUG("Successfully created scale for '" << result->name() << "'"); } //std::string parentName; @@ -157,9 +157,9 @@ SceneGraphNode* SceneGraphNode::createFromDictionary(const ghoul::Dictionary& di SceneGraphNode::SceneGraphNode() : _parent(nullptr) - , _ephemeris(new StaticEphemeris) - , _rotationMatrix(glm::dmat3(1.0)) - , _translation(glm::dvec3(0.0)) + , _ephemeris(new StaticEphemeris()) + , _rotation(new StaticRotation()) + , _scale(new StaticScale()) , _performanceRecord({0, 0, 0}) , _renderable(nullptr) , _renderableVisible(false) @@ -177,6 +177,10 @@ bool SceneGraphNode::initialize() { if (_ephemeris) _ephemeris->initialize(); + if (_rotation) + _rotation->initialize(); + if (_scale) + _scale->initialize(); return true; } @@ -190,8 +194,8 @@ bool SceneGraphNode::deinitialize() { _renderable = nullptr; } - delete _ephemeris; - _ephemeris = nullptr; + //delete _ephemeris; + //_ephemeris = nullptr; // for (SceneGraphNode* child : _children) { // child->deinitialize(); @@ -225,6 +229,36 @@ void SceneGraphNode::update(const UpdateData& data) { _ephemeris->update(newUpdateData); } + if (_rotation) { + if (data.doPerformanceMeasurement) { + glFinish(); + auto start = std::chrono::high_resolution_clock::now(); + + _rotation->update(newUpdateData); + + glFinish(); + auto end = std::chrono::high_resolution_clock::now(); + _performanceRecord.updateTimeEphemeris = (end - start).count(); + } + else + _rotation->update(newUpdateData); + } + + if (_scale) { + if (data.doPerformanceMeasurement) { + glFinish(); + auto start = std::chrono::high_resolution_clock::now(); + + _scale->update(newUpdateData); + + glFinish(); + auto end = std::chrono::high_resolution_clock::now(); + _performanceRecord.updateTimeEphemeris = (end - start).count(); + } + else + _scale->update(newUpdateData); + } + if (_renderable && _renderable->isReady()) { if (data.doPerformanceMeasurement) { glFinish(); @@ -240,35 +274,12 @@ void SceneGraphNode::update(const UpdateData& data) { _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); - } - _worldRotationCached = calculateWorldRotation(); + _worldScaleCached = calculateWorldScale(); + // Assumes _worldRotationCached and _worldScaleCached have been calculated for parent _worldPositionCached = calculateWorldPosition(); + newUpdateData.position = worldPosition(); } @@ -320,7 +331,8 @@ void SceneGraphNode::render(const RenderData& data, RendererTasks& tasks) { thisPositionPSC, data.doPerformanceMeasurement, _worldPositionCached, - _worldRotationCached}; + _worldRotationCached, + _worldScaleCached}; _performanceRecord.renderTime = 0; if (_renderableVisible && _renderable->isVisible() && _renderable->isReady() && _renderable->isEnabled()) { @@ -388,8 +400,17 @@ void SceneGraphNode::addChild(SceneGraphNode* child) { glm::dvec3 SceneGraphNode::position() const { - glm::dvec3 translationRotated = _parent->rotationMatrix() * _translation; - return _ephemeris->position() + translationRotated; + return _ephemeris->position(); +} + +const glm::dmat3& SceneGraphNode::rotationMatrix() const +{ + return _rotation->matrix(); +} + +double SceneGraphNode::scale() const +{ + return _scale->scaleValue(); } glm::dvec3 SceneGraphNode::worldPosition() const @@ -397,34 +418,47 @@ glm::dvec3 SceneGraphNode::worldPosition() const return _worldPositionCached; } -const glm::dmat3& SceneGraphNode::rotationMatrix() const -{ - return _rotationMatrix; -} - const glm::dmat3& SceneGraphNode::worldRotationMatrix() const { return _worldRotationCached; } +double SceneGraphNode::worldScale() const +{ + return _worldScaleCached; +} + glm::dvec3 SceneGraphNode::calculateWorldPosition() const { // recursive up the hierarchy if there are parents available if (_parent) { - glm::dvec3 translationRotated = _parent->rotationMatrix() * _translation; - return _ephemeris->position() + translationRotated + _parent->calculateWorldPosition(); + return + _parent->calculateWorldPosition() + + _parent->worldRotationMatrix() * + _parent->worldScale() * + position(); } else { - return _ephemeris->position(); + return position(); } } glm::dmat3 SceneGraphNode::calculateWorldRotation() const { // recursive up the hierarchy if there are parents available if (_parent) { - return _parent->calculateWorldRotation() * _rotationMatrix; + return rotationMatrix() * _parent->calculateWorldRotation(); } else { - return _rotationMatrix; + return rotationMatrix(); + } +} + +double SceneGraphNode::calculateWorldScale() const { + // recursive up the hierarchy if there are parents available + if (_parent) { + return _parent->calculateWorldScale() * scale(); + } + else { + return scale(); } }