From b74b01d294946a8b8e5696a41974d40fee4e65ab Mon Sep 17 00:00:00 2001 From: Erik Broberg Date: Mon, 29 Aug 2016 16:16:11 -0400 Subject: [PATCH 1/2] Add new class ScriptScheduler together with example input file: data/scene/osirisrex/scheduled_scripts.lua --- data/scene/osirisrex.scene | 11 +- data/scene/osirisrex/scheduled_scripts.lua | 17 ++ include/openspace/engine/openspaceengine.h | 3 + include/openspace/scripting/scriptscheduler.h | 86 ++++++++ src/CMakeLists.txt | 2 + src/engine/openspaceengine.cpp | 19 +- src/scripting/scriptscheduler.cpp | 186 ++++++++++++++++++ 7 files changed, 322 insertions(+), 2 deletions(-) create mode 100644 data/scene/osirisrex/scheduled_scripts.lua create mode 100644 include/openspace/scripting/scriptscheduler.h create mode 100644 src/scripting/scriptscheduler.cpp diff --git a/data/scene/osirisrex.scene b/data/scene/osirisrex.scene index 65d1e13774..4f0016adf7 100644 --- a/data/scene/osirisrex.scene +++ b/data/scene/osirisrex.scene @@ -143,11 +143,18 @@ function preInitialization() dofile(openspace.absPath('${SCRIPTS}/bind_keys.lua')) dofile(openspace.absPath('${SCRIPTS}/bind_keys_osirisrex.lua')) + local startTime = "2019 APR 16 12:03:00.00"; -- openspace.time.setTime("2018-12-20T22:47:00.00") --openspace.time.setTime("2019-05-25T03:57:55.00") --openspace.time.setTime("2016 SEP 8 23:05:00.50") - openspace.time.setTime("2019 APR 16 12:03:00.00") + openspace.time.setTime(startTime) openspace.time.setDeltaTime(0) + + openspace.scriptScheduler.load("${OPENSPACE_DATA}/scene/osirisrex/scheduled_scripts.lua") + + -- Removing the line below will cause all scripts prior to to be executed during initialization + openspace.scriptScheduler.skipTo(startTime); + end function postInitialization() @@ -173,6 +180,8 @@ function postInitialization() openspace.printInfo("Done setting default values") openspace.loadMission("${OPENSPACE_DATA}/scene/osirisrex/osirisrex/osirisrex.mission") + + openspace.resetCameraDirection() end diff --git a/data/scene/osirisrex/scheduled_scripts.lua b/data/scene/osirisrex/scheduled_scripts.lua new file mode 100644 index 0000000000..5f58a00218 --- /dev/null +++ b/data/scene/osirisrex/scheduled_scripts.lua @@ -0,0 +1,17 @@ +return +{ + { + Time = "2016 SEP 08 23:10:13", + ReversibleLuaScript = { + Forward = "openspace.printInfo('forward test 1');", + Backward = "openspace.printInfo('backward test 1');", + } + }, + { + Time = "2016 SEP 09 00:08:13", + ReversibleLuaScript = { + Forward = "openspace.printInfo('forward test 2');", + Backward = "openspace.printInfo('backward test 2');", + } + }, +} \ No newline at end of file diff --git a/include/openspace/engine/openspaceengine.h b/include/openspace/engine/openspaceengine.h index 99b6507d78..3af650bcf7 100644 --- a/include/openspace/engine/openspaceengine.h +++ b/include/openspace/engine/openspaceengine.h @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -80,6 +81,7 @@ public: interaction::InteractionHandler& interactionHandler(); RenderEngine& renderEngine(); scripting::ScriptEngine& scriptEngine(); + scripting::ScriptScheduler& scriptScheduler(); NetworkEngine& networkEngine(); LuaConsole& console(); ModuleEngine& moduleEngine(); @@ -138,6 +140,7 @@ private: std::unique_ptr _interactionHandler; std::unique_ptr _renderEngine; std::unique_ptr _scriptEngine; + std::unique_ptr _scriptScheduler; std::unique_ptr _networkEngine; std::unique_ptr _commandlineParser; std::unique_ptr _console; diff --git a/include/openspace/scripting/scriptscheduler.h b/include/openspace/scripting/scriptscheduler.h new file mode 100644 index 0000000000..75c45e1e71 --- /dev/null +++ b/include/openspace/scripting/scriptscheduler.h @@ -0,0 +1,86 @@ +/***************************************************************************************** + * * + * 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. * + ****************************************************************************************/ + +#ifndef __SCRIPTSCHEDULER_H__ +#define __SCRIPTSCHEDULER_H__ + +#include + +#include + +#include +#include + +namespace openspace { + +namespace scripting { + + + +struct ReversibleLuaScript { + std::string forwardScript; + std::string backwardScript; +}; + +struct ScheduledScript { + ScheduledScript() : time(-DBL_MAX) { } + ScheduledScript(const ghoul::Dictionary& dict); + + double time; + ReversibleLuaScript script; +}; + + +/** + * Maintains an ordered list of \code ScheduledScripts. + */ +class ScriptScheduler { +public: + + void loadScripts(const std::string& filename); + void loadScripts(const ghoul::Dictionary& dict); + + void skipTo(double time); + void skipTo(const std::string& timeStr); + + std::queue scheduledScripts(double newTime); + std::queue scheduledScripts(const std::string& timeStr); + + const std::vector& allScripts() const { return _scheduledScripts; }; + + static LuaLibrary luaLibrary(); + +private: + + std::vector _scheduledScripts; + + size_t _currentIndex = 0; + double _lastTime; + +}; + +} // namespace scripting +} // namespace openspace + +#endif // __SCRIPTSCHEDULER_H__ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 718429a4e2..0edb26d5f7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -82,6 +82,7 @@ set(OPENSPACE_SOURCE ${OPENSPACE_BASE_DIR}/src/scene/scenegraphnode.cpp ${OPENSPACE_BASE_DIR}/src/scripting/lualibrary.cpp ${OPENSPACE_BASE_DIR}/src/scripting/scriptengine.cpp + ${OPENSPACE_BASE_DIR}/src/scripting/scriptscheduler.cpp ${OPENSPACE_BASE_DIR}/src/scripting/scriptengine_lua.inl ${OPENSPACE_BASE_DIR}/src/util/blockplaneintersectiongeometry.cpp ${OPENSPACE_BASE_DIR}/src/util/boxgeometry.cpp @@ -169,6 +170,7 @@ set(OPENSPACE_HEADER ${OPENSPACE_BASE_DIR}/include/openspace/scripting/lualibrary.h ${OPENSPACE_BASE_DIR}/include/openspace/scripting/script_helper.h ${OPENSPACE_BASE_DIR}/include/openspace/scripting/scriptengine.h + ${OPENSPACE_BASE_DIR}/include/openspace/scripting/scriptscheduler.h ${OPENSPACE_BASE_DIR}/include/openspace/util/blockplaneintersectiongeometry.h ${OPENSPACE_BASE_DIR}/include/openspace/util/boxgeometry.h ${OPENSPACE_BASE_DIR}/include/openspace/util/camera.h diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index c6c58c861e..e0751a3066 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -49,6 +50,7 @@ #include #include + #include #include #include @@ -64,6 +66,7 @@ #include #include +#include #ifdef OPENSPACE_MODULE_ONSCREENGUI_ENABLED #include @@ -123,6 +126,7 @@ OpenSpaceEngine::OpenSpaceEngine(std::string programName, , _interactionHandler(new interaction::InteractionHandler) , _renderEngine(new RenderEngine) , _scriptEngine(new scripting::ScriptEngine) + , _scriptScheduler(new scripting::ScriptScheduler) , _networkEngine(new NetworkEngine) , _commandlineParser(new ghoul::cmdparser::CommandlineParser( programName, ghoul::cmdparser::CommandlineParser::AllowUnknownCommands::Yes @@ -386,6 +390,7 @@ bool OpenSpaceEngine::initialize() { _scriptEngine->addLibrary(gui::GUI::luaLibrary()); _scriptEngine->addLibrary(network::ParallelConnection::luaLibrary()); _scriptEngine->addLibrary(ModuleEngine::luaLibrary()); + _scriptEngine->addLibrary(ScriptScheduler::luaLibrary()); #ifdef OPENSPACE_MODULE_ISWA_ENABLED _scriptEngine->addLibrary(IswaManager::luaLibrary()); @@ -748,6 +753,12 @@ void OpenSpaceEngine::preSynchronization() { Time::ref().advanceTime(dt); Time::ref().preSynchronization(); + auto scheduledScripts = _scriptScheduler->scheduledScripts(Time::ref().currentTime()); + while(scheduledScripts.size()){ + _scriptEngine->queueScript(scheduledScripts.front()); + scheduledScripts.pop(); + } + _scriptEngine->preSynchronization(); _renderEngine->preSynchronization(); @@ -771,7 +782,7 @@ void OpenSpaceEngine::postSynchronizationPreDraw() { } Time::ref().postSynchronizationPreDraw(); - + _scriptEngine->postSynchronizationPreDraw(); _renderEngine->postSynchronizationPreDraw(); @@ -782,6 +793,7 @@ void OpenSpaceEngine::postSynchronizationPreDraw() { _interactionHandler->postSynchronizationPreDraw(); // Update the synched variables in the camera class + _renderEngine->camera()->preSynchronization(); _renderEngine->camera()->postSynchronizationPreDraw(); @@ -1019,6 +1031,11 @@ ScriptEngine& OpenSpaceEngine::scriptEngine() { return *_scriptEngine; } +ScriptScheduler& OpenSpaceEngine::scriptScheduler(){ + ghoul_assert(_scriptScheduler, "ScriptScheduler must not be nullptr"); + return *_scriptScheduler; +} + LuaConsole& OpenSpaceEngine::console() { ghoul_assert(_console, "LuaConsole must not be nullptr"); return *_console; diff --git a/src/scripting/scriptscheduler.cpp b/src/scripting/scriptscheduler.cpp new file mode 100644 index 0000000000..ef73fb4a13 --- /dev/null +++ b/src/scripting/scriptscheduler.cpp @@ -0,0 +1,186 @@ +/***************************************************************************************** + * * + * 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 + +#include + +#include +#include // parse time +#include +#include + + +namespace openspace { +namespace scripting { + +namespace { + const std::string _loggerCat = "ScriptScheduler"; + + const std::string KEY_TIME = "Time"; + const std::string KEY_FORWARD_SCRIPT = "ReversibleLuaScript.Forward"; + const std::string KEY_BACKWARD_SCRIPT = "ReversibleLuaScript.Backward"; +} + + +ScheduledScript::ScheduledScript(const ghoul::Dictionary& dict) + : ScheduledScript() // default init first +{ + std::string timeStr; + if (dict.getValue(KEY_TIME, timeStr)) { + time = SpiceManager::ref().ephemerisTimeFromDate(timeStr); + + if (!dict.getValue(KEY_FORWARD_SCRIPT, script.forwardScript)) { + LERROR("Unable to read " << KEY_FORWARD_SCRIPT); + } + if (!dict.getValue(KEY_BACKWARD_SCRIPT, script.backwardScript)) { + LERROR("Unable to read " << KEY_BACKWARD_SCRIPT); + } + } + else { + LERROR("Unable to read " << KEY_TIME); + } +} + +void ScriptScheduler::loadScripts(const std::string& filepath) { + ghoul::Dictionary timedScriptsDict; + try { + ghoul::lua::loadDictionaryFromFile(absPath(filepath), timedScriptsDict); + } + catch (const ghoul::RuntimeError& e) { + LERROR(e.what()); + return; + } + loadScripts(timedScriptsDict); +} + +void ScriptScheduler::loadScripts(const ghoul::Dictionary& dict) { + for (size_t i = 0; i < dict.size(); ++i) { + std::string id = std::to_string(i + 1); + const ghoul::Dictionary& timedScriptDict = dict.value(id); + _scheduledScripts.push_back(ScheduledScript(timedScriptDict)); + } +} + +void ScriptScheduler::skipTo(double newTime) { + if (newTime > _lastTime) { + while (_currentIndex < _scheduledScripts.size() && _scheduledScripts[_currentIndex].time <= newTime) { + _currentIndex++; + } + } + else { + while (0 < _currentIndex && _scheduledScripts[_currentIndex - 1].time > newTime) { + _currentIndex--; + } + } +} + +void ScriptScheduler::skipTo(const std::string& timeStr) { + skipTo(SpiceManager::ref().ephemerisTimeFromDate(timeStr)); +} + + +std::queue ScriptScheduler::scheduledScripts(double newTime) { + std::queue triggeredScripts; + if (newTime > _lastTime) { + while(_currentIndex < _scheduledScripts.size() && _scheduledScripts[_currentIndex].time <= newTime){ + triggeredScripts.push(_scheduledScripts[_currentIndex].script.forwardScript); + _currentIndex++; + } + } + else { + while (0 < _currentIndex && _scheduledScripts[_currentIndex - 1].time > newTime) { + triggeredScripts.push(_scheduledScripts[_currentIndex - 1].script.backwardScript); + _currentIndex--; + } + } + + _lastTime = newTime; + return triggeredScripts; +} + +std::queue ScriptScheduler::scheduledScripts(const std::string& timeStr) { + return std::move(scheduledScripts(SpiceManager::ref().ephemerisTimeFromDate(timeStr))); +} + + +///////////////////////////////////////////////////////////////////// +// Lua library functions // +///////////////////////////////////////////////////////////////////// + +namespace luascriptfunctions { + int loadTimedScripts(lua_State* L) { + using ghoul::lua::luaTypeToString; + int nArguments = lua_gettop(L); + if (nArguments != 1) + return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments); + + std::string missionFileName = luaL_checkstring(L, -1); + if (missionFileName.empty()) { + return luaL_error(L, "filepath string is empty"); + } + + OsEng.scriptScheduler().loadScripts(missionFileName); + } + + int skipTo(lua_State* L) { + using ghoul::lua::luaTypeToString; + int nArguments = lua_gettop(L); + if (nArguments != 1) + return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments); + + std::string dateStr = luaL_checkstring(L, -1); + if (dateStr.empty()) { + return luaL_error(L, "date string is empty"); + } + + OsEng.scriptScheduler().skipTo(dateStr); + } +} // namespace luascriptfunction + + + +LuaLibrary ScriptScheduler::luaLibrary() { + return { + "scriptScheduler", + { + { + "load", + &luascriptfunctions::loadTimedScripts, + "string", + "Load timed scripts from file" + }, + { + "skipTo", + &luascriptfunctions::skipTo, + "string", + "skip to a time without executing scripts" + }, + } + }; +} + +} // namespace scripting + +} // namespace openspace From 99309b3cb33d61aa062a89f662fee754c8160b0c Mon Sep 17 00:00:00 2001 From: Erik Broberg Date: Mon, 29 Aug 2016 16:52:18 -0400 Subject: [PATCH 2/2] Use more explicit names for different osiris rex trails --- data/scene/osirisrex/osirisrex/osirisrex.mod | 70 +++++++++++--------- 1 file changed, 39 insertions(+), 31 deletions(-) diff --git a/data/scene/osirisrex/osirisrex/osirisrex.mod b/data/scene/osirisrex/osirisrex/osirisrex.mod index 0cfa8f34e2..f15b2b52cd 100644 --- a/data/scene/osirisrex/osirisrex/osirisrex.mod +++ b/data/scene/osirisrex/osirisrex/osirisrex.mod @@ -198,35 +198,10 @@ return { }, }, ]] + + -- Trail relative to Earth { - Name = "OsirisRexTrailLocal", - Parent = "BennuBarycenter", - Renderable = { - Type = "RenderableTrailNew", - -- Spice - Body = "OSIRIS-REX", - Frame = "GALACTIC", - Observer = BENNU_BODY, - -- Optional rendering properties - LineColor = { 0.9, 0.2, 0.9 }, - PointColor = { 0.9, 0.2, 0.9 }, - LineFade = 0.5, -- [0,1] - RenderPart = 0.06, - LineWidth = 2, - ShowTimeStamps = false, - RenderFullTrail = false, - -- Time interval - TimeRange = { - Start = "2016 SEP 8 23:05:00.50", - End = "2023 SEP 24 12:00:00", - }, - SampleDeltaTime = 3600, -- Seconds between each point - SubSamples = 3, - }, - GuiName = "OsirisRexTrailLocal" - }, - { - Name = "OsirisRexTrailGlobal", + Name = "OsirisRexTrailEarth", Parent = "LodEarth", Renderable = { Type = "RenderableTrailNew", @@ -250,10 +225,12 @@ return { SampleDeltaTime = 60, -- Seconds between each point SubSamples = 59, }, - GuiName = "OsirisRexTrailGlobal" + GuiName = "OsirisRexTrailEarth" }, + + -- Trail relative to solar system barycenter { - Name = "OsirisRexTrailSolar", + Name = "OsirisRexTrailSolarSystem", Parent = "SolarSystemBarycenter", Renderable = { Type = "RenderableTrailNew", @@ -277,6 +254,37 @@ return { SampleDeltaTime = 3600, -- Seconds between each point SubSamples = 0, }, - GuiName = "OsirisRexTrailSolar" + GuiName = "OsirisRexTrailSolarSystem" }, + + -- Trail relative to Bennu + { + Name = "OsirisRexTrailBennu", + Parent = "BennuBarycenter", + Renderable = { + Type = "RenderableTrailNew", + -- Spice + Body = "OSIRIS-REX", + Frame = "GALACTIC", + Observer = BENNU_BODY, + -- Optional rendering properties + LineColor = { 0.9, 0.2, 0.9 }, + PointColor = { 0.9, 0.2, 0.9 }, + LineFade = 0.5, -- [0,1] + RenderPart = 0.06, + LineWidth = 2, + ShowTimeStamps = false, + RenderFullTrail = false, + -- Time interval + TimeRange = { + Start = "2016 SEP 8 23:05:00.50", + End = "2023 SEP 24 12:00:00", + }, + SampleDeltaTime = 3600, -- Seconds between each point + SubSamples = 3, + }, + GuiName = "OsirisRexTrailBennu" + }, + + }