diff --git a/.gitignore b/.gitignore index 512c197509..b6b3900ce1 100644 --- a/.gitignore +++ b/.gitignore @@ -154,3 +154,4 @@ data/scene/juno/juno/textures data/scene/juno/juno/spice data/scene/juno/juno/Juno.mtl data/scene/juno/juno/Juno.obj +KeyboardMapping.txt diff --git a/apps/OpenSpace/main.cpp b/apps/OpenSpace/main.cpp index d43be6508b..094f376248 100644 --- a/apps/OpenSpace/main.cpp +++ b/apps/OpenSpace/main.cpp @@ -130,6 +130,9 @@ int main(int argc, char** argv) { _sgctEngine->setExternalControlCallback(mainExternalControlCallback); _sgctEngine->setCharCallbackFunction(mainCharCallback); + // Disable the immediate exit of the application when the ESC key is pressed + _sgctEngine->setExitKey(SGCT_KEY_UNKNOWN); + sgct::MessageHandler::instance()->setNotifyLevel(sgct::MessageHandler::NOTIFY_ALL); // set encode and decode functions diff --git a/data/scene/atmosphereearth.scene b/data/scene/atmosphereearth.scene index 0b501b21f2..bc120bbd57 100644 --- a/data/scene/atmosphereearth.scene +++ b/data/scene/atmosphereearth.scene @@ -6,6 +6,9 @@ function preInitialization() critical objects. ]]-- + openspace.spice.loadKernel("${SPICE}/naif0011.tls") + openspace.spice.loadKernel("${SPICE}/pck00010.tpc") + openspace.time.setTime(openspace.time.currentWallTime()) dofile(openspace.absPath('${SCRIPTS}/bind_keys.lua')) end diff --git a/data/scene/dawn.scene b/data/scene/dawn.scene index b4298f5eb9..74ad519767 100644 --- a/data/scene/dawn.scene +++ b/data/scene/dawn.scene @@ -6,6 +6,9 @@ function preInitialization() critical objects. ]]-- + openspace.spice.loadKernel("${SPICE}/naif0011.tls") + openspace.spice.loadKernel("${SPICE}/pck00010.tpc") + openspace.time.setTime("2011 AUG 06 00:00:00") dofile(openspace.absPath('${SCRIPTS}/bind_keys.lua')) end diff --git a/data/scene/default-moon.scene b/data/scene/default-moon.scene index cd1fa6c10b..90748de3bf 100644 --- a/data/scene/default-moon.scene +++ b/data/scene/default-moon.scene @@ -19,6 +19,9 @@ function preInitialization() -- 6:20 -> 23:20 day before in UTC ]]-- + openspace.spice.loadKernel("${SPICE}/naif0011.tls") + openspace.spice.loadKernel("${SPICE}/pck00010.tpc") + openspace.time.setTime("2016-03-08T22:45:00") diff --git a/data/scene/default.scene b/data/scene/default.scene index 0490fe0750..9dc1e2802d 100644 --- a/data/scene/default.scene +++ b/data/scene/default.scene @@ -6,9 +6,12 @@ function preInitialization() critical objects. ]]-- - --openspace.time.setTime(openspace.time.currentWallTime()) - openspace.time.setTime('2015-03-15T11:00:00.00') + openspace.spice.loadKernel("${SPICE}/naif0011.tls") + openspace.spice.loadKernel("${SPICE}/pck00010.tpc") + + openspace.time.setTime(openspace.time.currentWallTime()) dofile(openspace.absPath('${SCRIPTS}/bind_keys.lua')) + end function postInitialization() @@ -66,7 +69,7 @@ return { "uranus", "neptune", "stars", - --"stars-denver", + -- "stars-denver", "milkyway", --"milkyway-eso", "constellationbounds", diff --git a/data/scene/fieldlines.scene b/data/scene/fieldlines.scene index eb0711c7fe..43068d7b75 100644 --- a/data/scene/fieldlines.scene +++ b/data/scene/fieldlines.scene @@ -6,6 +6,9 @@ function preInitialization() critical objects. ]]-- + openspace.spice.loadKernel("${SPICE}/naif0011.tls") + openspace.spice.loadKernel("${SPICE}/pck00010.tpc") + openspace.time.setTime("2015 JAN 01 12:00:00.000") dofile(openspace.absPath('${SCRIPTS}/bind_keys.lua')) end diff --git a/data/scene/globebrowsing.scene b/data/scene/globebrowsing.scene index 7bcb2ff1ff..6161b2f05f 100644 --- a/data/scene/globebrowsing.scene +++ b/data/scene/globebrowsing.scene @@ -6,10 +6,14 @@ function preInitialization() critical objects. ]]-- - openspace.time.setTime("2015 NOV 24 00:00:00") --openspace.time.setTime(openspace.time.currentWallTime()) + openspace.spice.loadKernel("${SPICE}/naif0011.tls") + openspace.spice.loadKernel("${SPICE}/pck00010.tpc") + + openspace.time.setTime("2015 NOV 24 00:00:00") + + openspace.time.setTime(openspace.time.currentWallTime()) dofile(openspace.absPath('${SCRIPTS}/bind_keys.lua')) - --openspace.bindKey("v", "openspace.setPropertyValue('DebugGlobe.saveOrThrowCamera', true)") end function postInitialization() diff --git a/data/scene/juno.scene b/data/scene/juno.scene index 54e58865da..346b872c2d 100755 --- a/data/scene/juno.scene +++ b/data/scene/juno.scene @@ -5,16 +5,10 @@ function preInitialization() which the scene should start and other settings that might determine initialization critical objects. ]]-- + openspace.spice.loadKernel("${SPICE}/naif0011.tls") + openspace.spice.loadKernel("${SPICE}/pck00010.tpc") - -- openspace.time.setTime("2007-02-28T11:40:00.000") - - -- openspace.time.setTime("2015-07-08T15:57:45.00") - -- openspace.time.setTime("2015-07-12T07:41:00.00") - -- openspace.time.setTime("2015-07-12T15:43:00.00") - -- 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-07-12T10:05:00.00") + openspace.time.setTime("2016-07-05T10:05:00.00") openspace.time.setDeltaTime(0) dofile(openspace.absPath('${SCRIPTS}/common.lua')) @@ -24,6 +18,8 @@ function preInitialization() 1, 5, 10, 20, 40, 90, 360, 720, 2880, 14400, 28800, 57600, 115200, 230400, 460800, 921600, 1843200, 3686400, 7372800, 14745600 }) + + openspace.bindKey("F6", "openspace.setPropertyValue('Interaction.coordinateSystem', 'Jupiter');"); end function postInitialization() diff --git a/data/scene/juno/juno/juno.mod b/data/scene/juno/juno/juno.mod index 50f5475b16..01006cfa80 100644 --- a/data/scene/juno/juno/juno.mod +++ b/data/scene/juno/juno/juno.mod @@ -26,12 +26,8 @@ return { 0.0, -1.0, 0.0 } }, - Shading = { - PerformShading = true, - Fadeable = false, - Ghosting = false, - }, }, + Ephemeris = { Type = "Spice", Body = "JUNO", @@ -136,8 +132,7 @@ return { Body = "JUNO", Frame = "GALACTIC", Observer = "JUPITER BARYCENTER", - -- Observer = "PLUTO BARYCENTER", - RGB = {0.70,0.50,0.20}, + RGB = { 0.70,0.50,0.20 }, TropicalOrbitPeriod = 394250.0, EarthOrbitRatio = 4.5, DayLength = 9.9259, @@ -145,9 +140,7 @@ return { Textures = { Type = "simple", Color = "textures/glare_blue.png", - -- need to add different texture }, }, - GuiName = "/Solar/JunoTrail" }, } diff --git a/data/scene/newhorizons.scene b/data/scene/newhorizons.scene index 6558ca2de6..d7ea180ab3 100644 --- a/data/scene/newhorizons.scene +++ b/data/scene/newhorizons.scene @@ -11,6 +11,9 @@ function preInitialization() critical objects. ]]-- + openspace.spice.loadKernel("${SPICE}/naif0011.tls") + openspace.spice.loadKernel("${SPICE}/pck00010.tpc") + -- openspace.time.setTime("2007-02-28T11:40:00.000") -- openspace.time.setTime("2015-07-08T15:57:45.00") diff --git a/data/scene/rosetta.scene b/data/scene/rosetta.scene index 45a5578e92..e36dcb3841 100644 --- a/data/scene/rosetta.scene +++ b/data/scene/rosetta.scene @@ -6,6 +6,9 @@ function preInitialization() critical objects. ]]-- + openspace.spice.loadKernel("${SPICE}/naif0011.tls") + openspace.spice.loadKernel("${SPICE}/pck00010.tpc") + openspace.time.setTime("2014-08-15T03:05:18.101") -- openspace.time.setTime("2014-11-17T03:05:18.101") -- openspace.time.setTime("2015-07-29T06:02:10.000") diff --git a/data/scene/volumetricmilkyway.scene b/data/scene/volumetricmilkyway.scene index dd795dee0d..9d6c9ba91d 100644 --- a/data/scene/volumetricmilkyway.scene +++ b/data/scene/volumetricmilkyway.scene @@ -6,6 +6,9 @@ function preInitialization() critical objects. ]]-- + openspace.spice.loadKernel("${SPICE}/naif0011.tls") + openspace.spice.loadKernel("${SPICE}/pck00010.tpc") + openspace.time.setTime(openspace.time.currentWallTime()) dofile(openspace.absPath('${SCRIPTS}/bind_keys.lua')) end diff --git a/ext/ghoul b/ext/ghoul index 18c2a46152..60e65350db 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 18c2a46152f0a05cd876f3d5b8c9138657deeb55 +Subproject commit 60e65350db67a5a364dfa5e201f1e888395f4f06 diff --git a/include/openspace/engine/configurationmanager.h b/include/openspace/engine/configurationmanager.h index da899ce3bb..23a5109043 100644 --- a/include/openspace/engine/configurationmanager.h +++ b/include/openspace/engine/configurationmanager.h @@ -61,6 +61,10 @@ public: static const std::string KeyPropertyDocumentationType; /// The key that stores the save location of the Property documentation static const std::string KeyPropertyDocumentationFile; + /// The key that stores the type of keyboard bindings that should be stored + static const std::string KeyKeyboardShortcutsType; + /// The key that stores the save location of the keyboard bindings file + static const std::string KeyKeyboardShortcutsFile; /// The key that stores the location of the scene file that is initially loaded static const std::string KeyConfigScene; /// The key that stores the subdirectory containing a list of all startup scripts to @@ -69,12 +73,6 @@ public: /// The key that stores the subdirectory containing a list of all settings scripts to /// be executed on application start and after the scene file is loaded static const std::string KeySettingsScript; - /// The key that stores the location of the SPICE time kernel to be loaded on - /// application start - static const std::string KeySpiceTimeKernel; - /// The key that stores the location of the SPICE leapsecond kernel to be loaded on - /// application start - static const std::string KeySpiceLeapsecondKernel; /// The key that stores the desired LogLevel for the whole application /// \sa ghoul::logging::LogManager static const std::string KeyLogLevel; @@ -88,6 +86,9 @@ public: /// The key that stores the verbosity (None, Minimal, Default, Full) of the system /// capabilities components static const std::string KeyCapabilitiesVerbosity; + /// The key that stores the time (in seconds) that the application will wait before + /// shutting down after the shutdown call is made + static const std::string KeyShutdownCountdown; /// The key that stores whether the master node should perform rendering just function /// as a pure manager static const std::string KeyDisableMasterRendering; diff --git a/include/openspace/engine/moduleengine.h b/include/openspace/engine/moduleengine.h index a15515c4d0..6075ebe125 100644 --- a/include/openspace/engine/moduleengine.h +++ b/include/openspace/engine/moduleengine.h @@ -79,7 +79,7 @@ public: * Returns the Lua library that contains all Lua functions available to affect the * modules. */ - static scripting::ScriptEngine::LuaLibrary luaLibrary(); + static scripting::LuaLibrary luaLibrary(); private: /// The list of all registered OpenSpaceModule%s diff --git a/include/openspace/engine/openspaceengine.h b/include/openspace/engine/openspaceengine.h index 2261ba879a..99b6507d78 100644 --- a/include/openspace/engine/openspaceengine.h +++ b/include/openspace/engine/openspaceengine.h @@ -28,6 +28,8 @@ #include #include +#include + #include #include @@ -55,7 +57,7 @@ class SettingsEngine; namespace interaction { class InteractionHandler; } namespace gui { class GUI; } -namespace scripting { class ScriptEngine; } +//namespace scripting { class ScriptEngine; } namespace network { class ParallelConnection; } namespace properties { class PropertyOwner; } @@ -110,15 +112,22 @@ public: void enableBarrier(); void disableBarrier(); + void toggleShutdownMode(); + void runPostInitializationScripts(const std::string& sceneDescription); + /** + * Returns the Lua library that contains all Lua functions available to affect the + * application. + */ + static scripting::LuaLibrary luaLibrary(); + private: OpenSpaceEngine(std::string programName, std::unique_ptr windowWrapper); ~OpenSpaceEngine(); void clearAllWindows(); bool gatherCommandlineArguments(); - bool loadSpiceKernels(); void loadFonts(); void runScripts(const ghoul::Dictionary& scripts); void runPreInitializationScripts(const std::string& sceneDescription); @@ -149,6 +158,14 @@ private: bool _isMaster; double _runTime; + // Whether the application is currently in shutdown mode (i.e. counting down the timer + // and closing it at '0' + bool _isInShutdownMode; + // The total amount of time the application will wait before actually shutting down + float _shutdownWait; + // The current state of the countdown; if it reaches '0', the application will close + float _shutdownCountdown; + static OpenSpaceEngine* _engine; }; diff --git a/include/openspace/engine/wrapper/sgctwindowwrapper.h b/include/openspace/engine/wrapper/sgctwindowwrapper.h index 62e9c728a3..5f3a59a9bf 100644 --- a/include/openspace/engine/wrapper/sgctwindowwrapper.h +++ b/include/openspace/engine/wrapper/sgctwindowwrapper.h @@ -36,6 +36,7 @@ namespace openspace { */ class SGCTWindowWrapper : public WindowWrapper { public: + void terminate() override; void setBarrier(bool enabled) override; void clearAllWindows(const glm::vec4& clearColor) override; bool windowHasResized() const override; diff --git a/include/openspace/engine/wrapper/windowwrapper.h b/include/openspace/engine/wrapper/windowwrapper.h index f9b778e5a5..cd91bc1732 100644 --- a/include/openspace/engine/wrapper/windowwrapper.h +++ b/include/openspace/engine/wrapper/windowwrapper.h @@ -42,6 +42,12 @@ namespace openspace { */ class WindowWrapper { public: + /** + * This method closes the application by calling the necessary terminate function of + * the window management system + */ + virtual void terminate(); + /** * This method enables or disables a framelock barrier. If the specific windowing * framework does not provide a framelock, this method defaults to a no-op. diff --git a/include/openspace/interaction/interactionhandler.h b/include/openspace/interaction/interactionhandler.h index ea9c39169c..d8fe42faa2 100644 --- a/include/openspace/interaction/interactionhandler.h +++ b/include/openspace/interaction/interactionhandler.h @@ -92,7 +92,7 @@ public: * \return The Lua library that contains all Lua functions available to affect the * interaction */ - static scripting::ScriptEngine::LuaLibrary luaLibrary(); + static scripting::LuaLibrary luaLibrary(); // Callback functions @@ -108,6 +108,7 @@ public: void distanceDelta(const PowerScaledScalar& distance, size_t iterations = 0); void lookAt(const glm::quat& rotation); void setRotation(const glm::quat& rotation); + private: // Remove copy and move constructors @@ -187,7 +188,7 @@ public: * \return The Lua library that contains all Lua functions available to affect the * interaction */ - static scripting::ScriptEngine::LuaLibrary luaLibrary(); + static scripting::LuaLibrary luaLibrary(); // Callback functions void keyboardCallback(Key key, KeyModifier modifier, KeyAction action); @@ -197,6 +198,7 @@ public: void saveCameraStateToFile(const std::string& filepath); void restoreCameraStateFromFile(const std::string& filepath); + void writeKeyboardDocumentation(const std::string& type, const std::string& file); private: void setInteractionMode(std::shared_ptr interactionMode); diff --git a/include/openspace/interaction/luaconsole.h b/include/openspace/interaction/luaconsole.h index d3e6aed595..9273a717a7 100644 --- a/include/openspace/interaction/luaconsole.h +++ b/include/openspace/interaction/luaconsole.h @@ -52,7 +52,7 @@ public: void setVisible(bool visible); void toggleVisibility(); - static scripting::ScriptEngine::LuaLibrary luaLibrary(); + static scripting::LuaLibrary luaLibrary(); private: diff --git a/include/openspace/network/parallelconnection.h b/include/openspace/network/parallelconnection.h index f377ab0457..979b57a8cc 100644 --- a/include/openspace/network/parallelconnection.h +++ b/include/openspace/network/parallelconnection.h @@ -108,7 +108,7 @@ namespace openspace{ * \return The Lua library that contains all Lua functions available to affect the * interaction */ - static scripting::ScriptEngine::LuaLibrary luaLibrary(); + static scripting::LuaLibrary luaLibrary(); protected: diff --git a/include/openspace/performance/performancemeasurement.h b/include/openspace/performance/performancemeasurement.h index f08dbb94b2..9bf1395d67 100644 --- a/include/openspace/performance/performancemeasurement.h +++ b/include/openspace/performance/performancemeasurement.h @@ -25,6 +25,9 @@ #ifndef __PERFORMANCEMEASUREMENT_H__ #define __PERFORMANCEMEASUREMENT_H__ +#include +#include + #include #include @@ -49,7 +52,12 @@ private: #define __LABEL(a) __MERGE(unique_name_, a) /// Declare a new variable for measuring the performance of the current block -#define PerfMeasure(name) auto __LABEL(__LINE__) = openspace::performance::PerformanceMeasurement((name), OsEng.renderEngine().performanceManager()) +#define PerfMeasure(name) \ + auto __LABEL(__LINE__) = \ + openspace::performance::PerformanceMeasurement(\ + (name), \ + OsEng.renderEngine().performanceManager() \ + ) } // namespace performance } // namespace openspace diff --git a/include/openspace/query/query.h b/include/openspace/query/query.h index ccb05b58ca..a48c55aed3 100644 --- a/include/openspace/query/query.h +++ b/include/openspace/query/query.h @@ -26,12 +26,14 @@ #define __QUERY_H__ #include +#include namespace openspace { namespace properties { class Property; } + class Renderable; class Scene; class SceneGraphNode; @@ -42,6 +44,7 @@ Scene* sceneGraph(); SceneGraphNode* sceneGraphNode(const std::string& name); Renderable* renderable(const std::string& name); properties::Property* property(const std::string& uri); +std::vector allProperties(); } // namespace diff --git a/include/openspace/rendering/renderengine.h b/include/openspace/rendering/renderengine.h index e94f7a320b..647f516c3e 100644 --- a/include/openspace/rendering/renderengine.h +++ b/include/openspace/rendering/renderengine.h @@ -89,7 +89,10 @@ public: bool initializeGL(); void postSynchronizationPreDraw(); void preSynchronization(); - void render(const glm::mat4& projectionMatrix, const glm::mat4& viewMatrix, bool showGui); + void render(const glm::mat4& projectionMatrix, const glm::mat4& viewMatrix); + + void renderScreenLog(); + void renderShutdownInformation(float timer, float fullTime); void postDraw(); void takeScreenshot(); @@ -162,7 +165,7 @@ public: * Returns the Lua library that contains all Lua functions available to affect the * rendering. */ - static scripting::ScriptEngine::LuaLibrary luaLibrary(); + static scripting::LuaLibrary luaLibrary(); // This is a temporary method to change the origin of the coordinate system ---abock void changeViewPoint(std::string origin); @@ -183,7 +186,6 @@ private: RendererImplementation rendererFromString(const std::string& method); void renderInformation(); - void renderScreenLog(); Camera* _mainCamera; Scene* _sceneGraph; diff --git a/include/openspace/scene/scene.h b/include/openspace/scene/scene.h index d871fac952..4844d3ac7b 100644 --- a/include/openspace/scene/scene.h +++ b/include/openspace/scene/scene.h @@ -100,7 +100,7 @@ public: */ SceneGraphNode* sceneGraphNode(const std::string& name) const; - std::vector allSceneGraphNodes(); + std::vector allSceneGraphNodes() const; SceneGraph& sceneGraph(); @@ -115,7 +115,7 @@ public: * \return The Lua library that contains all Lua functions available to change the * scene graph */ - static scripting::ScriptEngine::LuaLibrary luaLibrary(); + static scripting::LuaLibrary luaLibrary(); private: bool loadSceneInternal(const std::string& sceneDescriptionFilePath); diff --git a/include/openspace/scripting/lualibrary.h b/include/openspace/scripting/lualibrary.h new file mode 100644 index 0000000000..6787575a84 --- /dev/null +++ b/include/openspace/scripting/lualibrary.h @@ -0,0 +1,69 @@ +/***************************************************************************************** + * * + * 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 __LUALIBRARY_H__ +#define __LUALIBRARY_H__ + +#include + +namespace openspace { +namespace scripting { + +/** +* This structure represents a Lua library, itself consisting of a unique #name and +* an arbitrary number of #functions +*/ +struct LuaLibrary { + /** + * This structure represents a Lua function with its #name, #function pointer + * #argumentText describing the arguments this function takes, the #helpText + * describing the function, and whether it should be shared in a parallel + * connection (#parallelShared) + */ + struct Function { + /// The name of the function + std::string name; + /// The function pointer that is executed if the function is called + lua_CFunction function; + /// A text describing the arugments to this function + std::string argumentText; + /// A help text describing what the function does/ + std::string helpText; + /// If true, this function will be shared with other parallel + /// connections + bool parallelShared; + }; + /// The name of the library + std::string name; + /// The list of all functions for this library + std::vector functions; + + /// Comparison function that compares two LuaLibrary%s name + bool operator<(const LuaLibrary& rhs) const; +}; + +} // namespace scripting +} // namespace openspace + +#endif // __LUALIBRARY_H__ diff --git a/include/openspace/scripting/scriptengine.h b/include/openspace/scripting/scriptengine.h index 54242e7081..cb7797e181 100644 --- a/include/openspace/scripting/scriptengine.h +++ b/include/openspace/scripting/scriptengine.h @@ -25,6 +25,8 @@ #ifndef __SCRIPTENGINE_H__ #define __SCRIPTENGINE_H__ +#include + #include #include @@ -47,39 +49,6 @@ namespace scripting { */ class ScriptEngine { public: - /** - * This structure represents a Lua library, itself consisting of a unique #name and - * an arbitrary number of #functions - */ - struct LuaLibrary { - /** - * This structure represents a Lua function with its #name, #function pointer - * #argumentText describing the arguments this function takes, the #helpText - * describing the function, and whether it should be shared in a parallel - * connection (#parallelShared) - */ - struct Function { - /// The name of the function - std::string name; - /// The function pointer that is executed if the function is called - lua_CFunction function; - /// A text describing the arugments to this function - std::string argumentText; - /// A help text describing what the function does/ - std::string helpText; - /// If true, this function will be shared with other parallel - /// connections - bool parallelShared; - }; - /// The name of the library - std::string name; - /// The list of all functions for this library - std::vector functions; - - /// Comparison function that compares two LuaLibrary%s name - bool operator<(const LuaLibrary& rhs) const; - }; - /** * Initializes the internal Lua state and registers a common set of library functions * \throw LuaRuntimeException If the creation of the new Lua state fails diff --git a/include/openspace/util/keys.h b/include/openspace/util/keys.h index 10317f4180..9c41fea2df 100644 --- a/include/openspace/util/keys.h +++ b/include/openspace/util/keys.h @@ -359,7 +359,14 @@ static const std::map KeyMapping = { { "MENU", Key::Menu } }; - } // namespace openspace + +namespace std { + +std::string to_string(openspace::Key key); +std::string to_string(openspace::KeyModifier mod); +std::string to_string(openspace::KeyWithModifier key); + +} // namespace std #endif // __KEYS_H__ diff --git a/include/openspace/util/spicemanager.h b/include/openspace/util/spicemanager.h index 4e0eb64fcf..f0041b6679 100644 --- a/include/openspace/util/spicemanager.h +++ b/include/openspace/util/spicemanager.h @@ -25,6 +25,7 @@ #ifndef __SPICEMANAGER_H__ #define __SPICEMANAGER_H__ +#include #include #include @@ -47,7 +48,6 @@ namespace openspace { class SpiceManager : public ghoul::Singleton { friend class ghoul::Singleton; - public: using TransformMatrix = std::array; using KernelHandle = unsigned int; @@ -809,6 +809,8 @@ public: */ std::string frameFromBody(const std::string& body) const; + static scripting::LuaLibrary luaLibrary(); + private: /// Struct storing the information about all loaded kernels struct KernelInformation { diff --git a/include/openspace/util/time.h b/include/openspace/util/time.h index 345a5be062..8820bcbcc0 100644 --- a/include/openspace/util/time.h +++ b/include/openspace/util/time.h @@ -207,7 +207,7 @@ public: * \return The Lua library that contains all Lua functions available to change the * Time singleton */ - static scripting::ScriptEngine::LuaLibrary luaLibrary(); + static scripting::LuaLibrary luaLibrary(); private: static Time* _instance; ///< The singleton instance diff --git a/modules/iswa/util/iswamanager.cpp b/modules/iswa/util/iswamanager.cpp index 2b0728698b..bad0b41bf7 100644 --- a/modules/iswa/util/iswamanager.cpp +++ b/modules/iswa/util/iswamanager.cpp @@ -652,7 +652,7 @@ void IswaManager::setBaseUrl(std::string bUrl){ baseUrl = bUrl; } -scripting::ScriptEngine::LuaLibrary IswaManager::luaLibrary() { +scripting::LuaLibrary IswaManager::luaLibrary() { return { "iswa", { diff --git a/modules/iswa/util/iswamanager.h b/modules/iswa/util/iswamanager.h index bab50f2deb..9b81fa4646 100644 --- a/modules/iswa/util/iswamanager.h +++ b/modules/iswa/util/iswamanager.h @@ -99,7 +99,7 @@ public: std::map>& groups(); std::map>& cdfInformation(); - static scripting::ScriptEngine::LuaLibrary luaLibrary(); + static scripting::LuaLibrary luaLibrary(); ghoul::Event<>& iswaEvent(){ return _iswaEvent; diff --git a/modules/onscreengui/CMakeLists.txt b/modules/onscreengui/CMakeLists.txt index 2487474370..e0064f6c70 100644 --- a/modules/onscreengui/CMakeLists.txt +++ b/modules/onscreengui/CMakeLists.txt @@ -33,7 +33,7 @@ set(HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/guipropertycomponent.h ${CMAKE_CURRENT_SOURCE_DIR}/include/guitimecomponent.h ${CMAKE_CURRENT_SOURCE_DIR}/include/guiiswacomponent.h - ${CMAKE_CURRENT_SOURCE_DIR}/src/renderproperties.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/include/renderproperties.h ) source_group("Header Files" FILES ${HEADER_FILES}) diff --git a/modules/onscreengui/include/gui.h b/modules/onscreengui/include/gui.h index 7f36048b33..673e7dbb31 100644 --- a/modules/onscreengui/include/gui.h +++ b/modules/onscreengui/include/gui.h @@ -61,7 +61,7 @@ public: void render(); - static openspace::scripting::ScriptEngine::LuaLibrary luaLibrary(); + static openspace::scripting::LuaLibrary luaLibrary(); //protected: GuiHelpComponent _help; diff --git a/modules/onscreengui/src/gui.cpp b/modules/onscreengui/src/gui.cpp index 3e08132fca..2057c64a38 100644 --- a/modules/onscreengui/src/gui.cpp +++ b/modules/onscreengui/src/gui.cpp @@ -499,7 +499,7 @@ void GUI::render() { ImGui::End(); } -scripting::ScriptEngine::LuaLibrary GUI::luaLibrary() { +scripting::LuaLibrary GUI::luaLibrary() { return { "gui", { diff --git a/modules/onscreengui/src/renderproperties.cpp b/modules/onscreengui/src/renderproperties.cpp index 7ae57786cf..f027633784 100644 --- a/modules/onscreengui/src/renderproperties.cpp +++ b/modules/onscreengui/src/renderproperties.cpp @@ -46,7 +46,7 @@ void renderTooltip(Property* prop) { void executeScript(const std::string& id, const std::string& value) { std::string script = - "openspace.setPropertyValue('" + id + "', " + value + ");"; + "openspace.setPropertyValueSingle('" + id + "', " + value + ");"; OsEng.scriptEngine().queueScript(script); } diff --git a/openspace.cfg b/openspace.cfg index 00d7547c1a..6ce175337d 100644 --- a/openspace.cfg +++ b/openspace.cfg @@ -27,10 +27,6 @@ return { CACHE = "${BASE_PATH}/cache", FONTS = "${OPENSPACE_DATA}/fonts", }, - SpiceKernel = { - Time = "${SPICE}/naif0011.tls", - LeapSecond = "${SPICE}/pck00010.tpc", - }, Fonts = { Mono = "${FONTS}/Droid_Sans_Mono/DroidSansMono.ttf", Light = "${FONTS}/Roboto/Roboto-Regular.ttf" @@ -55,6 +51,7 @@ return { Type = "text", File = "${BASE_PATH}/ScriptLog.txt" }, + ShutdownCountdown = 3, DownloadRequestURL = "http://openspace.itn.liu.se/request.cgi", RenderingMethod = "Framebuffer" --RenderingMethod = "ABuffer" -- alternative: "Framebuffer" diff --git a/scripts/common.lua b/scripts/common.lua index 2083c2e5d3..222650ba52 100644 --- a/scripts/common.lua +++ b/scripts/common.lua @@ -11,6 +11,8 @@ helper.setCommonKeys = function() openspace.bindKey("F2", "openspace.setPerformanceMeasurement(true)") openspace.bindKey("F3", "openspace.setPerformanceMeasurement(false)") + openspace.bindKey("ESC", "openspace.toggleShutdown()") + openspace.bindKey("PRINT_SCREEN", "openspace.takeScreenshot()") openspace.bindKey("SPACE", "openspace.time.togglePause()") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f65d6e4b36..25b515e563 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -78,6 +78,7 @@ set(OPENSPACE_SOURCE ${OPENSPACE_BASE_DIR}/src/scene/scene_lua.inl ${OPENSPACE_BASE_DIR}/src/scene/scenegraph.cpp ${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/scriptengine_lua.inl ${OPENSPACE_BASE_DIR}/src/util/blockplaneintersectiongeometry.cpp @@ -160,6 +161,7 @@ set(OPENSPACE_HEADER ${OPENSPACE_BASE_DIR}/include/openspace/scene/scene.h ${OPENSPACE_BASE_DIR}/include/openspace/scene/scenegraph.h ${OPENSPACE_BASE_DIR}/include/openspace/scene/scenegraphnode.h + ${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/util/blockplaneintersectiongeometry.h diff --git a/src/engine/configurationmanager.cpp b/src/engine/configurationmanager.cpp index 55211d1074..e72939c75d 100644 --- a/src/engine/configurationmanager.cpp +++ b/src/engine/configurationmanager.cpp @@ -51,14 +51,15 @@ const string ConfigurationManager::KeyPropertyDocumentationType = "PropertyDocumentationFile.Type"; const string ConfigurationManager::KeyPropertyDocumentationFile = "PropertyDocumentationFile.File"; +const string ConfigurationManager::KeyKeyboardShortcutsType = "KeyboardShortcuts.Type"; +const string ConfigurationManager::KeyKeyboardShortcutsFile = "KeyboardShortcuts.File"; const string ConfigurationManager::KeyConfigScene = "Scene"; -const string ConfigurationManager::KeySpiceTimeKernel = "SpiceKernel.Time"; -const string ConfigurationManager::KeySpiceLeapsecondKernel = "SpiceKernel.LeapSecond"; const string ConfigurationManager::KeyLogLevel = "Logging.LogLevel"; const string ConfigurationManager::KeyLogImmediateFlush = "Logging.ImmediateFlush"; const string ConfigurationManager::KeyLogs = "Logging.Logs"; const string ConfigurationManager::KeyCapabilitiesVerbosity = "Logging.CapabilitiesVerbosity"; +const string ConfigurationManager::KeyShutdownCountdown = "ShutdownCountdown"; const string ConfigurationManager::KeyDisableMasterRendering = "DisableRenderingOnMaster"; const string ConfigurationManager::KeyDownloadRequestURL = "DownloadRequestURL"; diff --git a/src/engine/moduleengine.cpp b/src/engine/moduleengine.cpp index ed14d9a74e..76611a92cc 100644 --- a/src/engine/moduleengine.cpp +++ b/src/engine/moduleengine.cpp @@ -82,7 +82,7 @@ std::vector ModuleEngine::modules() const { return result; } -scripting::ScriptEngine::LuaLibrary ModuleEngine::luaLibrary() { +scripting::LuaLibrary ModuleEngine::luaLibrary() { return { "modules", { diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 5c57033ec0..0e821e6f06 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -84,6 +84,8 @@ #include #endif +#include "openspaceengine_lua.inl" + using namespace openspace::scripting; using namespace ghoul::filesystem; using namespace ghoul::logging; @@ -140,6 +142,9 @@ OpenSpaceEngine::OpenSpaceEngine(std::string programName, , _isMaster(false) , _runTime(0.0) , _syncBuffer(new SyncBuffer(4096)) + , _isInShutdownMode(false) + , _shutdownCountdown(0.f) + , _shutdownWait(0.f) { _interactionHandler->setPropertyOwner(_globalPropertyNamespace.get()); _globalPropertyNamespace->addPropertySubOwner(_interactionHandler.get()); @@ -369,13 +374,10 @@ bool OpenSpaceEngine::initialize() { _downloadManager = std::make_unique(requestURL, DownloadVersion); } - // Load SPICE time kernel - success = loadSpiceKernels(); - if (!success) - return false; - // Register Lua script functions LDEBUG("Registering Lua libraries"); + _scriptEngine->addLibrary(OpenSpaceEngine::luaLibrary()); + _scriptEngine->addLibrary(SpiceManager::luaLibrary()); _scriptEngine->addLibrary(RenderEngine::luaLibrary()); _scriptEngine->addLibrary(Scene::luaLibrary()); _scriptEngine->addLibrary(Time::luaLibrary()); @@ -410,6 +412,9 @@ bool OpenSpaceEngine::initialize() { ConfigurationManager::KeyDisableMasterRendering, disableMasterRendering); _renderEngine->setDisableRenderingOnMaster(disableMasterRendering); + configurationManager().getValue( + ConfigurationManager::KeyShutdownCountdown, _shutdownWait + ); // Load scenegraph Scene* sceneGraph = new Scene; @@ -525,30 +530,6 @@ bool OpenSpaceEngine::gatherCommandlineArguments() { return true; } -bool OpenSpaceEngine::loadSpiceKernels() { - // Load time kernel - std::string timeKernel; - bool success = configurationManager().getValue(ConfigurationManager::KeySpiceTimeKernel, timeKernel); - // Move this to configurationmanager::completenesscheck ---abock - if (!success) { - LERROR("Configuration file does not contain a '" << ConfigurationManager::KeySpiceTimeKernel << "'"); - return false; - } - SpiceManager::KernelHandle id = - SpiceManager::ref().loadKernel(timeKernel); - - // Load SPICE leap second kernel - std::string leapSecondKernel; - success = configurationManager().getValue(ConfigurationManager::KeySpiceLeapsecondKernel, leapSecondKernel); - if (!success) { - // Move this to configurationmanager::completenesscheck ---abock - LERROR("Configuration file does not have a '" << ConfigurationManager::KeySpiceLeapsecondKernel << "'"); - return false; - } - id = SpiceManager::ref().loadKernel(std::move(leapSecondKernel)); - return true; -} - void OpenSpaceEngine::runScripts(const ghoul::Dictionary& scripts) { for (size_t i = 1; i <= scripts.size(); ++i) { std::stringstream stream; @@ -768,6 +749,13 @@ void OpenSpaceEngine::preSynchronization() { } void OpenSpaceEngine::postSynchronizationPreDraw() { + if (_isInShutdownMode) { + if (_shutdownCountdown <= 0.f) { + _windowWrapper->terminate(); + } + _shutdownCountdown -= _windowWrapper->averageDeltaTime(); + } + Time::ref().postSynchronizationPreDraw(); _scriptEngine->postSynchronizationPreDraw(); @@ -816,24 +804,26 @@ void OpenSpaceEngine::postSynchronizationPreDraw() { } void OpenSpaceEngine::render(const glm::mat4& projectionMatrix, const glm::mat4& viewMatrix) { - bool showGui = _windowWrapper->hasGuiWindow() ? _windowWrapper->isGuiWindow() : true; - - _renderEngine->render(projectionMatrix, viewMatrix, showGui); - - if (_isMaster && _windowWrapper->isRegularRendering()) { - if (showGui) { - if (_console->isVisible()) - _console->render(); -#ifdef OPENSPACE_MODULE_ONSCREENGUI_ENABLED - if (_gui->isEnabled()) - _gui->endFrame(); - } -#endif - } + _renderEngine->render(projectionMatrix, viewMatrix); } void OpenSpaceEngine::postDraw() { _renderEngine->postDraw(); + + bool showGui = _windowWrapper->hasGuiWindow() ? _windowWrapper->isGuiWindow() : true; + if (showGui) { + _renderEngine->renderScreenLog(); + + if (_console->isVisible()) + _console->render(); +#ifdef OPENSPACE_MODULE_ONSCREENGUI_ENABLED + if (_gui->isEnabled()) + _gui->endFrame(); + } +#endif + + if (_isInShutdownMode) + _renderEngine->renderShutdownInformation(_shutdownCountdown, _shutdownWait); } void OpenSpaceEngine::keyboardCallback(Key key, KeyModifier mod, KeyAction action) { @@ -936,6 +926,35 @@ void OpenSpaceEngine::externalControlCallback(const char* receivedChars, int siz _networkEngine->handleMessage(std::string(receivedChars, size)); } +void OpenSpaceEngine::toggleShutdownMode() { + if (_isInShutdownMode) { + // If we are already in shutdown mode, we want to disable it instead + LINFO("Disabled shutdown mode"); + _isInShutdownMode = false; + } + else { + // Else, we hav eto enable it + LINFO("Shutting down OpenSpace"); + _shutdownCountdown = _shutdownWait; + _isInShutdownMode = true; + } +} + +scripting::LuaLibrary OpenSpaceEngine::luaLibrary() { + return { + "", + { + { + "toggleShutdown", + &luascriptfunctions::toggleShutdown, + "", + "Toggles the shutdown mode that will close the application after the count" + "down timer is reached" + } + } + }; +} + void OpenSpaceEngine::enableBarrier() { _windowWrapper->setBarrier(true); } diff --git a/src/engine/openspaceengine_lua.inl b/src/engine/openspaceengine_lua.inl new file mode 100644 index 0000000000..7d33f6af76 --- /dev/null +++ b/src/engine/openspaceengine_lua.inl @@ -0,0 +1,45 @@ +/***************************************************************************************** + * * + * 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. * + ****************************************************************************************/ + +namespace openspace { +namespace luascriptfunctions { + +/** + * \ingroup LuaScripts + * toggleShutdown(): + * Toggles the shutdown mode that will close the application after the countdown timer is + * reached + */ +int toggleShutdown(lua_State* L) { + int nArguments = lua_gettop(L); + if (nArguments != 0) + return luaL_error(L, "Expected %i arguments, got %i", 0, nArguments); + + OsEng.toggleShutdownMode(); + + return 1; +} + +} // namespace luascriptfunctions +} // namespace openspace diff --git a/src/engine/wrapper/sgctwindowwrapper.cpp b/src/engine/wrapper/sgctwindowwrapper.cpp index 1b0908db63..7abbdcda5c 100644 --- a/src/engine/wrapper/sgctwindowwrapper.cpp +++ b/src/engine/wrapper/sgctwindowwrapper.cpp @@ -36,6 +36,10 @@ namespace { namespace openspace { +void SGCTWindowWrapper::terminate() { + sgct::Engine::instance()->terminate(); +} + void SGCTWindowWrapper::setBarrier(bool enabled) { sgct::SGCTWindow::setBarrier(enabled); } diff --git a/src/engine/wrapper/windowwrapper.cpp b/src/engine/wrapper/windowwrapper.cpp index 0e45b73a0e..aa4c2ce284 100644 --- a/src/engine/wrapper/windowwrapper.cpp +++ b/src/engine/wrapper/windowwrapper.cpp @@ -31,6 +31,8 @@ namespace openspace { WindowWrapper::WindowWrapperException::WindowWrapperException(const std::string& msg) : ghoul::RuntimeError(msg, "WindowWrapper") {} + +void WindowWrapper::terminate() {} void WindowWrapper::setBarrier(bool) {} diff --git a/src/interaction/interactionhandler.cpp b/src/interaction/interactionhandler.cpp index a902ff1de3..c7fd50a34f 100644 --- a/src/interaction/interactionhandler.cpp +++ b/src/interaction/interactionhandler.cpp @@ -22,6 +22,8 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ +#include + #include #include #include @@ -29,6 +31,7 @@ #include #include +#include #include #include @@ -494,7 +497,7 @@ void InteractionHandler::bindKey(Key key, KeyModifier modifier, std::string lua) }); } -scripting::ScriptEngine::LuaLibrary InteractionHandler::luaLibrary() { +scripting::LuaLibrary InteractionHandler::luaLibrary() { return { "", { @@ -925,8 +928,26 @@ void InteractionHandler::bindKey(Key key, KeyModifier modifier, std::string lua) lua }); } + +void InteractionHandler::writeKeyboardDocumentation(const std::string& type, const std::string& file) +{ + if (type == "text") { + std::ofstream f(absPath(file)); + + for (const auto& p : _keyLua) { + f << std::to_string(p.first) << ": " << + p.second << std::endl; + } + } + else { + throw ghoul::RuntimeError( + "Unsupported keyboard documentation type '" + type + "'", + "InteractionHandler" + ); + } +} -scripting::ScriptEngine::LuaLibrary InteractionHandler::luaLibrary() { +scripting::LuaLibrary InteractionHandler::luaLibrary() { return{ "", { diff --git a/src/interaction/luaconsole.cpp b/src/interaction/luaconsole.cpp index 7fe960624b..b9adcbec21 100644 --- a/src/interaction/luaconsole.cpp +++ b/src/interaction/luaconsole.cpp @@ -398,7 +398,7 @@ void LuaConsole::toggleVisibility() { _isVisible = !_isVisible; } -scripting::ScriptEngine::LuaLibrary LuaConsole::luaLibrary() { +scripting::LuaLibrary LuaConsole::luaLibrary() { return { "console", { diff --git a/src/network/parallelconnection.cpp b/src/network/parallelconnection.cpp index 1b4a634350..416968cff7 100644 --- a/src/network/parallelconnection.cpp +++ b/src/network/parallelconnection.cpp @@ -1100,7 +1100,7 @@ int ParallelConnection::headerSize(){ return 2 * sizeof(uint8_t) + 2 + sizeof(uint32_t); } -scripting::ScriptEngine::LuaLibrary ParallelConnection::luaLibrary() { +scripting::LuaLibrary ParallelConnection::luaLibrary() { return { "parallel", { diff --git a/src/properties/propertyowner.cpp b/src/properties/propertyowner.cpp index 5f54329aae..24221357a5 100644 --- a/src/properties/propertyowner.cpp +++ b/src/properties/propertyowner.cpp @@ -104,8 +104,9 @@ Property* PropertyOwner::property(const std::string& id) const { } } } - else + else { return *it; + } } bool PropertyOwner::hasProperty(const std::string& id) const { diff --git a/src/query/query.cpp b/src/query/query.cpp index e80cfcc36b..7d87a9ccbf 100644 --- a/src/query/query.cpp +++ b/src/query/query.cpp @@ -96,4 +96,31 @@ properties::Property* property(const std::string& uri) { } } +std::vector allProperties() { + std::vector properties; + + auto p = OsEng.globalPropertyOwner().propertiesRecursive(); + + properties.insert( + properties.end(), + p.begin(), + p.end() + ); + + const Scene* graph = sceneGraph(); + std::vector nodes = graph->allSceneGraphNodes(); + + for (SceneGraphNode* n : nodes) { + auto p = n->propertiesRecursive(); + properties.insert( + properties.end(), + p.begin(), + p.end() + ); + } + + return properties; +} + + } // namespace diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 57bcfab967..cc8b7d4a7e 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -384,12 +384,10 @@ void RenderEngine::postSynchronizationPreDraw() { } -void RenderEngine::render(const glm::mat4& projectionMatrix, const glm::mat4& viewMatrix, bool showGui) { +void RenderEngine::render(const glm::mat4& projectionMatrix, const glm::mat4& viewMatrix){ _mainCamera->sgctInternal.setViewMatrix(viewMatrix); _mainCamera->sgctInternal.setProjectionMatrix(projectionMatrix); - - if (!(OsEng.isMaster() && _disableMasterRendering) && !OsEng.windowWrapper().isGuiWindow()) { _renderer->render(_globalBlackOutFactor, _performanceManager != nullptr); } @@ -399,9 +397,6 @@ void RenderEngine::render(const glm::mat4& projectionMatrix, const glm::mat4& vi if (_showInfo) { renderInformation(); } - if (_showLog && showGui) { - renderScreenLog(); - } } for (auto screenSpaceRenderable : _screenSpaceRenderables) { @@ -410,16 +405,44 @@ void RenderEngine::render(const glm::mat4& projectionMatrix, const glm::mat4& vi } } +void RenderEngine::renderShutdownInformation(float timer, float fullTime) { + timer = timer < 0.f ? 0.f : timer; + + auto size = ghoul::fontrendering::FontRenderer::defaultRenderer().boundingBox( + *_fontDate, + "Shutdown in: %.2fs/%.2fs", + timer, + fullTime + ); + + glm::vec2 penPosition = glm::vec2( + OsEng.windowWrapper().viewportPixelCoordinates().y - size.boundingBox.x, + OsEng.windowWrapper().viewportPixelCoordinates().w - size.boundingBox.y + ); + penPosition.y -= _fontDate->height(); + + RenderFontCr( + *_fontDate, + penPosition, + "Shutdown in: %.2fs/%.2fs", + timer, + fullTime + ); +} + void RenderEngine::postDraw() { - if (Time::ref().timeJumped()) + if (Time::ref().timeJumped()) { Time::ref().setTimeJumped(false); + } + if (_takeScreenshot) { OsEng.windowWrapper().takeScreenshot(); _takeScreenshot = false; } - if (_performanceManager) + if (_performanceManager) { _performanceManager->storeScenePerformanceMeasurements(scene()->allSceneGraphNodes()); + } } void RenderEngine::takeScreenshot() { @@ -655,7 +678,7 @@ void RenderEngine::setNAaSamples(int nAaSamples) { } } -scripting::ScriptEngine::LuaLibrary RenderEngine::luaLibrary() { +scripting::LuaLibrary RenderEngine::luaLibrary() { return { "", { @@ -1202,7 +1225,7 @@ void RenderEngine::renderInformation() { glm::vec2 penPosition = glm::vec2( 10.f, OsEng.windowWrapper().viewportPixelCoordinates().w - ); + ); penPosition.y -= _fontDate->height(); RenderFontCr(*_fontDate, @@ -1413,6 +1436,9 @@ void RenderEngine::renderInformation() { } void RenderEngine::renderScreenLog() { + if (!_showLog) + return; + _log->removeExpiredEntries(); const int max = 10; diff --git a/src/scene/scene.cpp b/src/scene/scene.cpp index bbd6c5ce23..a2f388d47b 100644 --- a/src/scene/scene.cpp +++ b/src/scene/scene.cpp @@ -87,14 +87,28 @@ bool Scene::deinitialize() { return true; } -//bool ONCE = false; - void Scene::update(const UpdateData& data) { if (!_sceneGraphToLoad.empty()) { OsEng.renderEngine().scene()->clearSceneGraph(); try { loadSceneInternal(_sceneGraphToLoad); _sceneGraphToLoad = ""; + + // After loading the scene, the keyboard bindings have been set + + std::string type; + std::string file; + bool hasType = OsEng.configurationManager().getValue( + ConfigurationManager::KeyKeyboardShortcutsType, type + ); + + bool hasFile = OsEng.configurationManager().getValue( + ConfigurationManager::KeyKeyboardShortcutsFile, file + ); + + if (hasType && hasFile) { + OsEng.interactionHandler().writeKeyboardDocumentation(type, file); + } } catch (const ghoul::RuntimeError& e) { LERROR(e.what()); @@ -380,7 +394,7 @@ SceneGraphNode* Scene::sceneGraphNode(const std::string& name) const { return _graph.sceneGraphNode(name); } -std::vector Scene::allSceneGraphNodes() { +std::vector Scene::allSceneGraphNodes() const { return _graph.nodes(); } @@ -415,7 +429,7 @@ void Scene::writePropertyDocumentation(const std::string& filename, const std::s LERROR("Undefined type '" << type << "' for Property documentation"); } -scripting::ScriptEngine::LuaLibrary Scene::luaLibrary() { +scripting::LuaLibrary Scene::luaLibrary() { return { "", { @@ -423,9 +437,25 @@ scripting::ScriptEngine::LuaLibrary Scene::luaLibrary() { "setPropertyValue", &luascriptfunctions::property_setValue, "string, *", + "Sets all properties identified by the URI (with potential wildcards) in " + "the first argument. The second argument can be any type, but it has to " + "match the type that the property (or properties) expect." + }, + { + "setPropertyValueRegex", + &luascriptfunctions::property_setValueRegex, + "Sets all properties that pass the regular expression in the first " + "argument. The second argument can be any type, but it has to match the " + "type of the properties that matched the regular expression. The regular " + "expression has to be of the ECMAScript grammar." + }, + { + "setPropertyValueSingle", + &luascriptfunctions::property_setValueSingle, + "string, *", "Sets a property identified by the URI in " "the first argument. The second argument can be any type, but it has to " - " agree with the type that the property expects", + "match the type that the property expects.", true }, { diff --git a/src/scene/scene_lua.inl b/src/scene/scene_lua.inl index c4472091ab..e1adcc30fb 100644 --- a/src/scene/scene_lua.inl +++ b/src/scene/scene_lua.inl @@ -22,18 +22,58 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ +#include + namespace openspace { +namespace { + +void applyRegularExpression(lua_State* L, std::regex regex, std::vector properties, int type) { + static const std::string _loggerCat = "property_setValue"; + + using ghoul::lua::errorLocation; + using ghoul::lua::luaTypeToString; + + for (properties::Property* prop : properties) { + // Check the regular expression for all properties + std::string id = prop->fullyQualifiedIdentifier(); + if (std::regex_match(id, regex)) { + // If the fully qualified id matches the regular expression, we queue the + // value change if the types agree + + if (type != prop->typeLua()) { + LERROR(errorLocation(L) << "Property '" << + prop->fullyQualifiedIdentifier() << + "' does not accept input of type '" << luaTypeToString(type) << + "'. Requested type: '" << luaTypeToString(prop->typeLua()) << "'"); + } + else { + prop->setLuaValue(L); + //ensure properties are synced over parallel connection + std::string value; + prop->getStringValue(value); + OsEng.parallelConnection().scriptMessage( + prop->fullyQualifiedIdentifier(), + value + ); + } + + } + } +} +} + + namespace luascriptfunctions { /** * \ingroup LuaScripts - * setPropertyValue(string, *): + * setPropertyValueSingle(string, *): * Sets the property identified by the URI in the first argument to the value passed to * the second argument. The type of the second argument is arbitrary, but it must agree * with the type the denoted Property expects */ -int property_setValue(lua_State* L) { +int property_setValueSingle(lua_State* L) { static const std::string _loggerCat = "property_setValue"; using ghoul::lua::errorLocation; using ghoul::lua::luaTypeToString; @@ -44,7 +84,7 @@ int property_setValue(lua_State* L) { std::string uri = luaL_checkstring(L, -2); const int type = lua_type(L, -1); - openspace::properties::Property* prop = property(uri); + properties::Property* prop = property(uri); if (!prop) { LERROR(errorLocation(L) << "Property with URI '" << uri << "' was not found"); return 0; @@ -57,7 +97,7 @@ int property_setValue(lua_State* L) { "'. Requested type: '" << luaTypeToString(prop->typeLua()) << "'"); return 0; } - else{ + else { prop->setLuaValue(L); //ensure properties are synced over parallel connection std::string value; @@ -68,6 +108,75 @@ int property_setValue(lua_State* L) { return 0; } +/** + * \ingroup LuaScripts + * setPropertyValueRegex(string, *): + * Sets all properties that pass the regular expression in the first argument. The second + * argument can be any type, but it has to match the type of the properties that matched + * the regular expression. The regular expression has to be of the ECMAScript grammar. +*/ +int property_setValueRegex(lua_State* L) { + static const std::string _loggerCat = "property_setValueRegex"; + using ghoul::lua::errorLocation; + using ghoul::lua::luaTypeToString; + + int nArguments = lua_gettop(L); + SCRIPT_CHECK_ARGUMENTS(L, 2, nArguments); + + std::string regex = luaL_checkstring(L, -2); + try { + applyRegularExpression( + L, + std::regex(regex, std::regex_constants::optimize), + allProperties(), + lua_type(L, -1) + ); + } + catch (const std::regex_error& e) { + LERROR("Malformed regular expression: '" << regex << "'"); + } + + return 0; +} + +/** +* \ingroup LuaScripts +* setPropertyValue(string, *): +* Sets all properties identified by the URI (with potential wildcards) in the first +* argument. The second argument can be any type, but it has to match the type that the +* property (or properties) expect. +*/ + +int property_setValue(lua_State* L) { + static const std::string _loggerCat = "property_setValueRegex"; + using ghoul::lua::errorLocation; + using ghoul::lua::luaTypeToString; + + int nArguments = lua_gettop(L); + SCRIPT_CHECK_ARGUMENTS(L, 2, nArguments); + + std::string regex = luaL_checkstring(L, -2); + + // Replace all wildcards * with the correct regex (.*) + size_t startPos = regex.find("*"); + while (startPos != std::string::npos) { + regex.replace(startPos, 1, "(.*)"); + startPos += 4; + + startPos = regex.find("*", startPos); + } + + + applyRegularExpression( + L, + std::regex(regex/*, std::regex_constants::optimize*/), + allProperties(), + lua_type(L, -1) + ); + + return 0; +} + /** * \ingroup LuaScripts * getPropertyValue(string): diff --git a/src/scene/scenegraph.cpp b/src/scene/scenegraph.cpp index 78bd484aa8..10eee43a66 100644 --- a/src/scene/scenegraph.cpp +++ b/src/scene/scenegraph.cpp @@ -168,9 +168,15 @@ bool SceneGraph::loadFromFile(const std::string& sceneDescription) { LERROR("Specified common folder '" << fullCommonFolder << "' did not exist"); else { if (!commonFolder.empty()) { - FileSys.registerPathToken(_commonModuleToken, commonFolder); + FileSys.registerPathToken( + _commonModuleToken, commonFolder, + ghoul::filesystem::FileSystem::Override::Yes + ); size_t nKeys = moduleDictionary.size(); - moduleDictionary.setValue(std::to_string(nKeys + 1), commonFolder); + moduleDictionary.setValue( + std::to_string(nKeys + 1), + commonFolder + ); } } } diff --git a/src/scripting/lualibrary.cpp b/src/scripting/lualibrary.cpp new file mode 100644 index 0000000000..4aff78390c --- /dev/null +++ b/src/scripting/lualibrary.cpp @@ -0,0 +1,35 @@ +/***************************************************************************************** + * * + * 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 + +namespace openspace { +namespace scripting { + +bool LuaLibrary::operator<(const LuaLibrary& rhs) const { + return name < rhs.name; +} + +} // namespace scripting +} // namespace openspace diff --git a/src/scripting/scriptengine.cpp b/src/scripting/scriptengine.cpp index 9ebfa1ca4b..a795067bf6 100644 --- a/src/scripting/scriptengine.cpp +++ b/src/scripting/scriptengine.cpp @@ -54,10 +54,6 @@ namespace { } -bool ScriptEngine::LuaLibrary::operator<(const LuaLibrary& rhs) const { - return name < rhs.name; -} - void ScriptEngine::initialize() { LDEBUG("Adding base library"); addBaseLibrary(); @@ -208,7 +204,7 @@ bool ScriptEngine::shouldScriptBeSent(const std::string& library, const std::str } } - std::vector::const_iterator funcit; + std::vector::const_iterator funcit; //library was found if (libit != _registeredLibraries.cend()){ for (funcit = libit->functions.cbegin(); diff --git a/src/util/keys.cpp b/src/util/keys.cpp index 71637f0a10..ecf3d2b65d 100644 --- a/src/util/keys.cpp +++ b/src/util/keys.cpp @@ -110,3 +110,39 @@ bool operator<(const KeyWithModifier& lhs, const KeyWithModifier& rhs) { } } // namespace openspace + +namespace std { + +std::string to_string(openspace::Key key) { + for (const auto& p : openspace::KeyMapping) { + if (p.second == key) + return p.first; + } + ghoul_assert(false, "Missing key in KeyMapping"); +} + +std::string to_string(openspace::KeyModifier mod) { + using namespace openspace; + + if (mod == KeyModifier::NoModifier) + return ""; + + std::string result; + for (const auto& p : KeyModifierMapping) { + if (hasKeyModifier(mod, p.second)) { + result += p.first + "+"; + } + } + // The last addition has added an additional '+' that we + // should remove + return result.substr(0, result.size() - 1); +} + +std::string to_string(openspace::KeyWithModifier key) { + if (key.modifier == openspace::KeyModifier::NoModifier) + return to_string(key.key); + else + return to_string(key.modifier) + "+" + to_string(key.key); +} + +} // namespace std diff --git a/src/util/spicemanager.cpp b/src/util/spicemanager.cpp index b76b21bf55..fbc87d1012 100644 --- a/src/util/spicemanager.cpp +++ b/src/util/spicemanager.cpp @@ -78,6 +78,8 @@ namespace { using fmt::format; using std::string; +#include "spicemanager_lua.inl" + namespace openspace { @@ -1109,6 +1111,28 @@ glm::dmat3 SpiceManager::getEstimatedTransformMatrix(const std::string& fromFram return result; } +scripting::LuaLibrary SpiceManager::luaLibrary() { + return { + "spice", + { + { + "loadKernel", + &luascriptfunctions::loadKernel, + "string", + "Loads the provided SPICE kernel by name. The name can contain path " + "tokens, which are automatically resolved" + }, + { + "unloadKernel", + &luascriptfunctions::unloadKernel, + "{string, number}", + "Unloads the provided SPICE kernel. The name can contain path tokens, " + "which are automatically resolved" + } + } + }; +} + } // namespace openspace diff --git a/src/util/spicemanager_lua.inl b/src/util/spicemanager_lua.inl new file mode 100644 index 0000000000..b37d6965d7 --- /dev/null +++ b/src/util/spicemanager_lua.inl @@ -0,0 +1,91 @@ +/***************************************************************************************** + * * + * 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 + +namespace openspace { +namespace luascriptfunctions { + +/** + * \ingroup LuaScripts + * loadKernel(string): + * Loads the provided SPICE kernel by name. The name can contain path tokens, which are + * automatically resolved. + */ + +int loadKernel(lua_State* L) { + const std::string _loggerCat = "loadKernel"; + + int nArguments = lua_gettop(L); + SCRIPT_CHECK_ARGUMENTS(L, 1, nArguments); + + bool isString = (lua_isstring(L, -1) == 1); + if (!isString) { + LERROR(ghoul::lua::errorLocation(L) << "Expected argument of type 'string'"); + return 0; + } + + std::string argument = lua_tostring(L, -1); + unsigned int result = SpiceManager::ref().loadKernel(argument); + + lua_pushnumber(L, result); + return 1; +} + +/** + * unloadKernel({string, number}): + * Unloads the provided SPICE kernel. The name can contain path tokens, which are + * automatically resolved. + */ +int unloadKernel(lua_State* L) { + const std::string _loggerCat = "loadKernel"; + + int nArguments = lua_gettop(L); + SCRIPT_CHECK_ARGUMENTS(L, 1, nArguments); + + bool isString = (lua_isstring(L, -1) == 1); + bool isNumber = (lua_isnumber(L, -1) == 1); + + if (!isString && !isNumber) { + LERROR( + ghoul::lua::errorLocation(L) << + "Expected argument of type 'string' or 'number'" + ); + return 0; + } + + if (isString) { + std::string argument = lua_tostring(L, -1); + SpiceManager::ref().unloadKernel(argument); + return 0; + } + + if (isNumber) { + unsigned int argument = static_cast(lua_tonumber(L, -1)); + SpiceManager::ref().unloadKernel(argument); + } +} + +} // luascriptfunctions +} // namespace openspace diff --git a/src/util/time.cpp b/src/util/time.cpp index a541638b6c..2695202e2e 100644 --- a/src/util/time.cpp +++ b/src/util/time.cpp @@ -240,8 +240,8 @@ bool Time::paused() const { return _timePaused; } -scripting::ScriptEngine::LuaLibrary Time::luaLibrary() { - scripting::ScriptEngine::LuaLibrary timeLibrary = { +scripting::LuaLibrary Time::luaLibrary() { + return { "time", { { @@ -307,7 +307,6 @@ scripting::ScriptEngine::LuaLibrary Time::luaLibrary() { } } }; - return timeLibrary; } } // namespace openspace diff --git a/support/cmake/support_macros.cmake b/support/cmake/support_macros.cmake index 44bbbc0df7..86b559d197 100644 --- a/support/cmake/support_macros.cmake +++ b/support/cmake/support_macros.cmake @@ -363,7 +363,10 @@ function (handle_internal_modules) message(STATUS "Included modules:") foreach (module ${sortedModules}) - message(STATUS "\t${module}") + create_option_name(${module} optionName) + if (${optionName}) + message(STATUS "\t${module}") + endif () endforeach () # Add subdirectories in the correct order