Merge commit 'd20bb6d63405e1a1a351b349dcd04af5e958437f' into feature/websocketnavigation

* commit 'd20bb6d63405e1a1a351b349dcd04af5e958437f':
  Set maximum iterations for geodetic surface projection
  Feature/time frame (#642)
This commit is contained in:
Matthew Territo
2018-07-12 15:42:40 -06:00
17 changed files with 614 additions and 21 deletions
@@ -2,11 +2,14 @@ local assetHelper = asset.require('util/asset_helper')
local sunTransforms = asset.require('scene/solarsystem/sun/transforms')
local kernels = asset.require('./kernels')
local PlutoBarycenter = {
Identifier = "PlutoBarycenter",
Parent = sunTransforms.SolarSystemBarycenter.Identifier,
TimeFrame = {
Type = "TimeFrameInterval",
Start = "2015-JAN-01",
End = "2015-AUG-01"
},
Transform = {
Translation = {
Type = "SpiceTranslation",
@@ -6,6 +6,11 @@ asset.require("spice/base")
-- Barycenter of the solar system, expressed in the Galactic frame
local SolarSystemBarycenter = {
Identifier = "SolarSystemBarycenter",
TimeFrame = { -- Using Spice kernels for 1850-2150
Type = "TimeFrameInterval",
Start = "1850-JAN-01",
End = "2150-JAN-01"
},
GUI = {
Name = "Solar System Barycenter",
Path = "/Solar System",
+5
View File
@@ -48,6 +48,8 @@ class Scale;
class Scene;
struct UpdateData;
struct SurfacePositionHandle;
class TimeFrame;
class Time;
namespace documentation { struct Documentation; }
@@ -120,6 +122,7 @@ public:
glm::dmat4 modelTransform() const;
glm::dmat4 inverseModelTransform() const;
double worldScale() const;
bool isTimeFrameActive(const Time& time) const;
SceneGraphNode* parent() const;
std::vector<SceneGraphNode*> children() const;
@@ -168,6 +171,8 @@ private:
std::unique_ptr<Scale> scale;
} _transform;
std::unique_ptr<TimeFrame> _timeFrame;
// Cached transform data
glm::dvec3 _worldPositionCached;
glm::dmat3 _worldRotationCached;
+58
View File
@@ -0,0 +1,58 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2018 *
* *
* 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. *
****************************************************************************************/
#ifndef __OPENSPACE_CORE___TIMEFRAME___H__
#define __OPENSPACE_CORE___TIMEFRAME___H__
#include <openspace/properties/propertyowner.h>
#include <ghoul/glm.h>
#include <memory>
namespace ghoul { class Dictionary; }
namespace openspace {
class Time;
namespace documentation { struct Documentation; }
class TimeFrame : public properties::PropertyOwner {
public:
static std::unique_ptr<TimeFrame> createFromDictionary(
const ghoul::Dictionary& dictionary);
TimeFrame();
virtual ~TimeFrame() = default;
virtual bool initialize();
virtual bool isActive(const Time& time) const = 0;
static documentation::Documentation Documentation();
};
} // namespace openspace
#endif // __OPENSPACE_CORE___TIMEFRAME___H__
+4
View File
@@ -56,6 +56,8 @@ set(HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/rotation/staticrotation.h
${CMAKE_CURRENT_SOURCE_DIR}/scale/luascale.h
${CMAKE_CURRENT_SOURCE_DIR}/scale/staticscale.h
${CMAKE_CURRENT_SOURCE_DIR}/timeframe/timeframeinterval.h
${CMAKE_CURRENT_SOURCE_DIR}/timeframe/timeframeunion.h
)
source_group("Header Files" FILES ${HEADER_FILES})
@@ -91,6 +93,8 @@ set(SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/rotation/staticrotation.cpp
${CMAKE_CURRENT_SOURCE_DIR}/scale/luascale.cpp
${CMAKE_CURRENT_SOURCE_DIR}/scale/staticscale.cpp
${CMAKE_CURRENT_SOURCE_DIR}/timeframe/timeframeinterval.cpp
${CMAKE_CURRENT_SOURCE_DIR}/timeframe/timeframeunion.cpp
)
source_group("Source Files" FILES ${SOURCE_FILES})
+11
View File
@@ -53,6 +53,8 @@
#include <modules/base/scale/staticscale.h>
#include <modules/base/translation/luatranslation.h>
#include <modules/base/translation/statictranslation.h>
#include <modules/base/timeframe/timeframeinterval.h>
#include <modules/base/timeframe/timeframeunion.h>
#include <openspace/documentation/documentation.h>
#include <openspace/rendering/renderable.h>
#include <openspace/rendering/screenspacerenderable.h>
@@ -134,6 +136,12 @@ void BaseModule::internalInitialize(const ghoul::Dictionary&) {
fScale->registerClass<LuaScale>("LuaScale");
fScale->registerClass<StaticScale>("StaticScale");
auto fTimeFrame = FactoryManager::ref().factory<TimeFrame>();
ghoul_assert(fTimeFrame, "Scale factory was not created");
fTimeFrame->registerClass<TimeFrameInterval>("TimeFrameInterval");
fTimeFrame->registerClass<TimeFrameUnion>("TimeFrameUnion");
auto fGeometry = FactoryManager::ref().factory<modelgeometry::ModelGeometry>();
ghoul_assert(fGeometry, "Model geometry factory was not created");
fGeometry->registerClass<modelgeometry::MultiModelGeometry>("MultiModelGeometry");
@@ -175,6 +183,9 @@ std::vector<documentation::Documentation> BaseModule::documentations() const {
LuaTranslation::Documentation(),
StaticTranslation::Documentation(),
TimeFrameInterval::Documentation(),
TimeFrameUnion::Documentation(),
modelgeometry::ModelGeometry::Documentation(),
};
}
@@ -0,0 +1,160 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2018 *
* *
* 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/timeframe/timeframeinterval.h>
#include <openspace/documentation/documentation.h>
#include <openspace/documentation/verifier.h>
#include <openspace/util/spicemanager.h>
#include <openspace/util/time.h>
namespace {
constexpr const openspace::properties::Property::PropertyInfo HasStartInfo = {
"HasStart",
"Has Start",
"If enabled, this TimeFrame will be inactive before the Start"
};
constexpr const openspace::properties::Property::PropertyInfo StartInfo = {
"Start",
"Start",
"Specifies the time when this TimeFrame becomes active"
};
constexpr const openspace::properties::Property::PropertyInfo HasEndInfo = {
"HasEnd",
"Has End",
"If enabled, this TimeFrame will be inactive after the End"
};
constexpr const openspace::properties::Property::PropertyInfo EndInfo = {
"End",
"End",
"Specifies the time when this TimeFrame becomes inactive"
};
} // namespace
namespace openspace {
documentation::Documentation TimeFrameInterval::Documentation() {
using namespace openspace::documentation;
return {
"Time Frame Interval",
"base_time_frame_interval",
{
{
HasStartInfo.identifier,
new BoolVerifier,
Optional::Yes,
HasStartInfo.description
},
{
StartInfo.identifier,
new OrVerifier{
new DoubleVerifier,
new StringVerifier,
},
Optional::Yes,
StartInfo.description
},
{
HasEndInfo.identifier,
new BoolVerifier,
Optional::Yes,
HasEndInfo.description
},
{
EndInfo.identifier,
new OrVerifier{
new DoubleVerifier,
new StringVerifier,
},
Optional::Yes,
EndInfo.description
},
}
};
}
bool TimeFrameInterval::isActive(const Time& time) const {
if (_hasStart && time.j2000Seconds() < _start ) {
return false;
}
if (_hasEnd && time.j2000Seconds() >= _end ) {
return false;
}
return true;
}
TimeFrameInterval::TimeFrameInterval()
: _hasStart(HasStartInfo, false)
, _start(StartInfo, 0, 0, 1E9)
, _hasEnd(HasEndInfo, false)
, _end(EndInfo, 0, 0, 1E9)
{
addProperty(_hasStart);
addProperty(_start);
addProperty(_hasEnd);
addProperty(_end);
}
TimeFrameInterval::TimeFrameInterval(const ghoul::Dictionary& dictionary)
: TimeFrame()
, _hasStart(HasStartInfo, false)
, _start(StartInfo, 0, 0, 1E9)
, _hasEnd(HasEndInfo, false)
, _end(EndInfo, 0, 0, 1E9)
{
addProperty(_hasStart);
addProperty(_start);
addProperty(_hasEnd);
addProperty(_end);
documentation::testSpecificationAndThrow(Documentation(),
dictionary,
"TimeFrameInterval");
if (dictionary.hasValue<std::string>(StartInfo.identifier)) {
_start = SpiceManager::ref().ephemerisTimeFromDate(
dictionary.value<std::string>(StartInfo.identifier)
);
_hasStart = true;
} else if (dictionary.hasValue<double>(StartInfo.identifier)) {
_start = dictionary.value<double>(StartInfo.identifier);
_hasStart = true;
}
if (dictionary.hasValue<std::string>(EndInfo.identifier)) {
_end = SpiceManager::ref().ephemerisTimeFromDate(
dictionary.value<std::string>(EndInfo.identifier)
);
_hasEnd = true;
}
else if (dictionary.hasValue<double>(EndInfo.identifier)) {
_end = dictionary.value<double>(EndInfo.identifier);
_hasEnd = true;
}
}
} // namespace openspace
@@ -0,0 +1,57 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2018 *
* *
* 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. *
****************************************************************************************/
#ifndef __OPENSPACE_MODULE_BASE___TIMEFRAMEINTERVAL___H__
#define __OPENSPACE_MODULE_BASE___TIMEFRAMEINTERVAL___H__
#include <openspace/scene/timeframe.h>
#include <openspace/properties/scalar/doubleproperty.h>
#include <openspace/properties/scalar/boolproperty.h>
namespace openspace {
class Time;
namespace documentation { struct Documentation; }
class TimeFrameInterval : public TimeFrame {
public:
TimeFrameInterval();
TimeFrameInterval(const ghoul::Dictionary& dictionary);
bool isActive(const Time&) const override;
static documentation::Documentation Documentation();
private:
properties::BoolProperty _hasStart;
properties::DoubleProperty _start;
properties::BoolProperty _hasEnd;
properties::DoubleProperty _end;
};
} // namespace openspace
#endif // __OPENSPACE_MODULE_BASE___TIMEFRAMEINTERVAL___H__
+101
View File
@@ -0,0 +1,101 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2018 *
* *
* 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/timeframe/timeframeunion.h>
#include <openspace/properties/property.h>
#include <openspace/documentation/documentation.h>
#include <openspace/documentation/verifier.h>
#include <openspace/util/spicemanager.h>
#include <openspace/util/time.h>
namespace {
constexpr const openspace::properties::Property::PropertyInfo TimeFramesInfo = {
"TimeFrames",
"Time Frames",
"A vector of time frames to combine into one."
"The time frame is active when any of the contained time frames are, "
"but not in gaps between contained time frames."
};
} // namespace
namespace openspace {
documentation::Documentation TimeFrameUnion::Documentation() {
using namespace openspace::documentation;
return {
"Time Frame Union",
"base_time_frame_union",
{
{
TimeFramesInfo.identifier,
new TableVerifier({
{
"*",
new ReferencingVerifier("core_time_frame"),
Optional::Yes
}
}),
Optional::No,
TimeFramesInfo.description
},
}
};
}
bool TimeFrameUnion::isActive(const Time& time) const {
for (const auto& tf : _timeFrames) {
if (tf->isActive(time)) {
return true;
}
}
return false;
}
TimeFrameUnion::TimeFrameUnion() {}
TimeFrameUnion::TimeFrameUnion(const ghoul::Dictionary& dictionary)
: TimeFrame()
{
documentation::testSpecificationAndThrow(Documentation(),
dictionary,
"TimeFrameUnion");
ghoul::Dictionary frames =
dictionary.value<ghoul::Dictionary>(TimeFramesInfo.identifier);
for (const std::string& k : frames.keys()) {
const ghoul::Dictionary& subDictionary = frames.value<ghoul::Dictionary>(k);
_timeFrames.push_back(TimeFrame::createFromDictionary(subDictionary));
TimeFrame& subFrame = *_timeFrames.back();
subFrame.setIdentifier(k);
subFrame.setGuiName(k);
subFrame.setDescription(k);
addPropertySubOwner(*_timeFrames.back());
}
}
} // namespace openspace
+50
View File
@@ -0,0 +1,50 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2018 *
* *
* 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. *
****************************************************************************************/
#ifndef __OPENSPACE_MODULE_BASE___TIMEFRAMEUNION___H__
#define __OPENSPACE_MODULE_BASE___TIMEFRAMEUNION___H__
#include <openspace/scene/timeframe.h>
namespace openspace {
class Time;
namespace documentation { struct Documentation; }
class TimeFrameUnion : public TimeFrame {
public:
TimeFrameUnion();
TimeFrameUnion(const ghoul::Dictionary& dictionary);
bool isActive(const Time&) const override;
static documentation::Documentation Documentation();
private:
std::vector<std::unique_ptr<TimeFrame>> _timeFrames;
};
} // namespace openspace
#endif // __OPENSPACE_MODULE_BASE___TIMEFRAMEUNION___H__
+9 -1
View File
@@ -31,6 +31,10 @@
#include <array>
#include <vector>
namespace {
constexpr const size_t MaxIterations = 8;
}
namespace openspace::globebrowsing {
Ellipsoid::Ellipsoid(glm::dvec3 radii) : _radii(radii) {
@@ -70,6 +74,8 @@ glm::dvec3 Ellipsoid::geodeticSurfaceProjection(const glm::dvec3& p) const {
double dSdA = 1.0;
double epsilon = 1e-10;
size_t nIterations = 0;
do {
alpha -= (s / dSdA);
@@ -80,8 +86,10 @@ glm::dvec3 Ellipsoid::geodeticSurfaceProjection(const glm::dvec3& p) const {
s = glm::dot(p2 / (_cached._radiiSquared * d2), glm::dvec3(1.0)) - 1.0;
dSdA = -2.0 * glm::dot(p2 / (_cached._radiiToTheFourth * d3), glm::dvec3(1.0));
++nIterations;
}
while (std::abs(s) > epsilon);
while (std::abs(s) > epsilon && nIterations < MaxIterations);
return p / d;
}
+2
View File
@@ -156,6 +156,7 @@ set(OPENSPACE_SOURCE
${OPENSPACE_BASE_DIR}/src/scene/scenelicensewriter.cpp
${OPENSPACE_BASE_DIR}/src/scene/scenegraphnode.cpp
${OPENSPACE_BASE_DIR}/src/scene/scenegraphnode_doc.inl
${OPENSPACE_BASE_DIR}/src/scene/timeframe.cpp
${OPENSPACE_BASE_DIR}/src/scripting/lualibrary.cpp
${OPENSPACE_BASE_DIR}/src/scripting/scriptengine.cpp
${OPENSPACE_BASE_DIR}/src/scripting/scriptengine_lua.inl
@@ -336,6 +337,7 @@ set(OPENSPACE_HEADER
${OPENSPACE_BASE_DIR}/include/openspace/scene/scenelicense.h
${OPENSPACE_BASE_DIR}/include/openspace/scene/scenelicensewriter.h
${OPENSPACE_BASE_DIR}/include/openspace/scene/scenegraphnode.h
${OPENSPACE_BASE_DIR}/include/openspace/scene/timeframe.h
${OPENSPACE_BASE_DIR}/include/openspace/scripting/lualibrary.h
${OPENSPACE_BASE_DIR}/include/openspace/scripting/scriptengine.h
${OPENSPACE_BASE_DIR}/include/openspace/scripting/scriptscheduler.h
+2
View File
@@ -43,6 +43,7 @@
#include <openspace/scene/scenegraphnode.h>
#include <openspace/scene/scale.h>
#include <openspace/scene/translation.h>
#include <openspace/scene/timeframe.h>
#include <openspace/scripting/scriptengine.h>
#include <openspace/scripting/scriptscheduler.h>
#include <openspace/scripting/systemcapabilitiesbinding.h>
@@ -62,6 +63,7 @@ void registerCoreClasses(documentation::DocumentationEngine& engine) {
engine.addDocumentation(ScreenSpaceRenderable::Documentation());
engine.addDocumentation(TimeRange::Documentation());
engine.addDocumentation(Translation::Documentation());
engine.addDocumentation(TimeFrame::Documentation());
}
void registerCoreClasses(scripting::ScriptEngine& engine) {
+5
View File
@@ -50,6 +50,7 @@
#include <openspace/scene/scene.h>
#include <openspace/scene/rotation.h>
#include <openspace/scene/scale.h>
#include <openspace/scene/timeframe.h>
#include <openspace/scene/sceneinitializer.h>
#include <openspace/scene/translation.h>
#include <openspace/scripting/scriptscheduler.h>
@@ -202,6 +203,10 @@ OpenSpaceEngine::OpenSpaceEngine(std::string programName,
std::make_unique<ghoul::TemplateFactory<Scale>>(),
"Scale"
);
FactoryManager::ref().addFactory(
std::make_unique<ghoul::TemplateFactory<TimeFrame>>(),
"TimeFrame"
);
FactoryManager::ref().addFactory(
std::make_unique<ghoul::TemplateFactory<Task>>(),
"Task"
+56 -18
View File
@@ -29,6 +29,7 @@
#include <modules/base/translation/statictranslation.h>
#include <openspace/rendering/renderable.h>
#include <openspace/scene/scene.h>
#include <openspace/scene/timeframe.h>
#include <openspace/util/updatestructures.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/opengl/ghoul_gl.h>
@@ -45,6 +46,8 @@ namespace {
constexpr const char* KeyTransformTranslation = "Transform.Translation";
constexpr const char* KeyTransformRotation = "Transform.Rotation";
constexpr const char* KeyTransformScale = "Transform.Scale";
constexpr const char* KeyTimeFrame = "TimeFrame";
} // namespace
namespace openspace {
@@ -119,6 +122,24 @@ std::unique_ptr<SceneGraphNode> SceneGraphNode::createFromDictionary(
LDEBUG(fmt::format("Successfully created scale for '{}'", result->identifier()));
}
if (dictionary.hasKey(KeyTimeFrame)) {
ghoul::Dictionary timeFrameDictionary;
dictionary.getValue(KeyTimeFrame, timeFrameDictionary);
result->_timeFrame = TimeFrame::createFromDictionary(timeFrameDictionary);
if (result->_timeFrame == nullptr) {
LERROR(fmt::format(
"Failed to create time frame for SceneGraphNode '{}'",
result->identifier()
));
return nullptr;
}
result->addPropertySubOwner(result->_timeFrame.get());
LDEBUG(fmt::format(
"Successfully created time frame for '{}'",
result->identifier()
));
}
// We initialize the renderable last as it probably has the most dependencies
if (dictionary.hasValue<ghoul::Dictionary>(KeyRenderable)) {
ghoul::Dictionary renderableDictionary;
@@ -240,6 +261,10 @@ void SceneGraphNode::update(const UpdateData& data) {
if (s != State::Initialized && _state != State::GLInitialized) {
return;
}
if (!isTimeFrameActive(data.time)) {
return;
}
if (_transform.translation) {
if (data.doPerformanceMeasurement) {
glFinish();
@@ -351,7 +376,9 @@ void SceneGraphNode::render(const RenderData& data, RendererTasks& tasks) {
{ _worldPositionCached, _worldRotationCached, _worldScaleCached }
};
//_performanceRecord.renderTime = 0;
if (!isTimeFrameActive(data.time)) {
return;
}
bool visible = _renderable &&
_renderable->isVisible() &&
@@ -359,26 +386,23 @@ void SceneGraphNode::render(const RenderData& data, RendererTasks& tasks) {
_renderable->isEnabled() &&
_renderable->matchesRenderBinMask(data.renderBinMask);
if (visible) {
if (data.doPerformanceMeasurement) {
glFinish();
auto start = std::chrono::high_resolution_clock::now();
_renderable->render(newData, tasks);
glFinish();
auto end = std::chrono::high_resolution_clock::now();
_performanceRecord.renderTime = (end - start).count();
}
else {
_renderable->render(newData, tasks);
}
if (!visible) {
return;
}
// evaluate all the children, tail-recursive function(?)
if (data.doPerformanceMeasurement) {
glFinish();
auto start = std::chrono::high_resolution_clock::now();
//for (SceneGraphNode* child : _children)
// child->render(newData);
_renderable->render(newData, tasks);
glFinish();
auto end = std::chrono::high_resolution_clock::now();
_performanceRecord.renderTime = (end - start).count();
}
else {
_renderable->render(newData, tasks);
}
}
void SceneGraphNode::setParent(SceneGraphNode& parent) {
@@ -589,6 +613,20 @@ glm::dvec3 SceneGraphNode::calculateWorldPosition() const {
}
}
bool SceneGraphNode::isTimeFrameActive(const Time& time) const {
for (const auto& dep : _dependencies) {
if (!dep->isTimeFrameActive(time)) {
return false;
}
}
if (_parent && !_parent->isTimeFrameActive(time)) {
return false;
}
return !_timeFrame || _timeFrame->isActive(time);
}
glm::dmat3 SceneGraphNode::calculateWorldRotation() const {
// recursive up the hierarchy if there are parents available
if (_parent) {
+6
View File
@@ -98,6 +98,12 @@ documentation::Documentation SceneGraphNode::Documentation() {
"node and all of its children. There are only three possible values "
"corresponding to a 'Translation', a 'Rotation', and a 'Scale'."
},
{
"TimeFrame",
new ReferencingVerifier("core_time_frame"),
Optional::Yes,
"Specifies the time frame for when this node should be active."
},
{
"GUI",
new TableVerifier({
+78
View File
@@ -0,0 +1,78 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2018 *
* *
* 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 <openspace/scene/timeframe.h>
#include <openspace/documentation/documentation.h>
#include <openspace/documentation/verifier.h>
#include <openspace/util/factorymanager.h>
#include <openspace/util/updatestructures.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/misc/dictionary.h>
#include <ghoul/misc/templatefactory.h>
namespace {
constexpr const char* KeyType = "Type";
} // namespace
namespace openspace {
documentation::Documentation TimeFrame::Documentation() {
using namespace openspace::documentation;
return {
"Time Frame",
"core_time_frame",
{
{
KeyType,
new StringAnnotationVerifier("Must name a valid TimeFrame type"),
Optional::No,
"The type of the time frame that is described in this element. "
"The available types of scaling depend on the configuration "
"of the application and can be written to disk on "
"application startup into the FactoryDocumentation."
}
}
};
}
std::unique_ptr<TimeFrame> TimeFrame::createFromDictionary(const ghoul::Dictionary& dictionary) {
documentation::testSpecificationAndThrow(Documentation(), dictionary, "TimeFrame");
const std::string timeFrameType = dictionary.value<std::string>(KeyType);
auto factory = FactoryManager::ref().factory<TimeFrame>();
std::unique_ptr<TimeFrame> result = factory->create(timeFrameType, dictionary);
result->setIdentifier("TimeFrame");
return result;
}
TimeFrame::TimeFrame() : properties::PropertyOwner({ "TimeFrame" }) {}
bool TimeFrame::initialize() {
return true;
}
} // namespace openspace