From 4d756daaf6cdcfd6d110ec2352b8637ee3b6976a Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sat, 27 Sep 2014 15:25:35 +0200 Subject: [PATCH 01/23] Simplified error handling in Lua API --- src/scenegraph/scenegraph.cpp | 95 ++++++----------------------- src/scripting/scriptengine.cpp | 108 +++++++++++++++++++++------------ 2 files changed, 86 insertions(+), 117 deletions(-) diff --git a/src/scenegraph/scenegraph.cpp b/src/scenegraph/scenegraph.cpp index 0142f19b83..12ffdf1388 100644 --- a/src/scenegraph/scenegraph.cpp +++ b/src/scenegraph/scenegraph.cpp @@ -71,53 +71,24 @@ namespace luascriptfunctions { */ int property_setValue(lua_State* L) { using ghoul::lua::luaTypeToString; - const std::string _loggerCat = "property_setValue"; - // TODO Check for argument number (ab) + int nArguments = lua_gettop(L); + if (nArguments != 2) + return luaL_error(L, "Expected %i arguments, got %i", 2, nArguments); + std::string uri = luaL_checkstring(L, -2); const int type = lua_type(L, -1); - // boost::any propertyValue; - // switch (type) { - // case LUA_TNONE: - // case LUA_TLIGHTUSERDATA: - // case LUA_TFUNCTION: - // case LUA_TUSERDATA: - // case LUA_TTHREAD: - // LERROR("Function parameter was of type '" << luaTypeToString(type) << "'"); - // return 0; - // case LUA_TNIL: - // propertyValue = 0; - // break; - // case LUA_TBOOLEAN: - // propertyValue = lua_toboolean(L, -1); - // break; - // case LUA_TNUMBER: - // propertyValue = lua_tonumber(L, -1); - // break; - // case LUA_TSTRING: - // propertyValue = std::string(lua_tostring(L, -1)); - // break; - //case LUA_TTABLE: { - // ghoul::Dictionary d; - // ghoul::lua::populateDictionary(L, d); - // propertyValue = d; - // break; - //} - // } openspace::properties::Property* prop = property(uri); - if (!prop) { - LERROR("Property with uri '" << uri << "' could not be found"); - return 0; - } + if (!prop) + return luaL_error(L, "Property with URL '%s' could not be found", uri); if (type != prop->typeLua()) - LERROR("Property '" << uri << "' does not accept input of type '" - << luaTypeToString(type) << "'. Requested type: '" - << luaTypeToString(prop->typeLua()) << "'"); + return luaL_error(L, "Property '%s' does not accept input of type '%s'. \ + Requested type: '%s'", uri, luaTypeToString(type), + luaTypeToString(prop->typeLua())); else prop->setLua(L); - //prop->set(propertyValue); return 0; } @@ -129,48 +100,17 @@ int property_setValue(lua_State* L) { * be passed to the setPropertyValue method. */ int property_getValue(lua_State* L) { - const std::string _loggerCat = "property_getValue"; + int nArguments = lua_gettop(L); + if (nArguments != 1) + return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments); - // TODO Check for argument number (ab) std::string uri = luaL_checkstring(L, -1); openspace::properties::Property* prop = property(uri); - if (!prop) { - LERROR("Property with uri '" << uri << "' could not be found"); - lua_pushnil(L); - } - else { + if (!prop) + return luaL_error(L, "Property with URL '%s' could not be found", uri); + else prop->getLua(L); - - //switch (type) { - // case LUA_TNONE: - // case LUA_TLIGHTUSERDATA: - // case LUA_TFUNCTION: - // case LUA_TUSERDATA: - // case LUA_TTHREAD: - // LERROR("Function parameter was of type '" << luaTypeToString(type) - // << "'"); - // return 0; - // case LUA_TNIL: - // propertyValue = 0; - // break; - // case LUA_TBOOLEAN: - // propertyValue = lua_toboolean(L, -1); - // break; - // case LUA_TNUMBER: - // propertyValue = lua_tonumber(L, -1); - // break; - // case LUA_TSTRING: - // propertyValue = std::string(lua_tostring(L, -1)); - // break; - // case LUA_TTABLE: { - // ghoul::Dictionary d; - // ghoul::lua::populateDictionary(L, d); - // propertyValue = d; - // break; - // } - //} - } return 1; } @@ -181,9 +121,10 @@ int property_getValue(lua_State* L) { * be passed to the setPropertyValue method. */ int loadScene(lua_State* L) { - const std::string _loggerCat = "loadScene"; + int nArguments = lua_gettop(L); + if (nArguments != 1) + return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments); - // TODO Check for argument number (ab) std::string sceneFile = luaL_checkstring(L, -1); OsEng.renderEngine().sceneGraph()->scheduleLoadSceneFile(sceneFile); diff --git a/src/scripting/scriptengine.cpp b/src/scripting/scriptengine.cpp index 5b7148ec3c..098b543cc6 100644 --- a/src/scripting/scriptengine.cpp +++ b/src/scripting/scriptengine.cpp @@ -34,32 +34,37 @@ namespace openspace { namespace luascriptfunctions { - void printInternal(ghoul::logging::LogManager::LogLevel level, lua_State* L) { + int printInternal(ghoul::logging::LogManager::LogLevel level, lua_State* L) { using ghoul::lua::luaTypeToString; const std::string _loggerCat = "print"; + int nArguments = lua_gettop(L); + if (nArguments != 1) + return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments); + const int type = lua_type(L, -1); switch (type) { - case LUA_TNONE: - case LUA_TLIGHTUSERDATA: - case LUA_TTABLE: - case LUA_TFUNCTION: - case LUA_TUSERDATA: - case LUA_TTHREAD: - LOG(level, "Function parameter was of type '" << - luaTypeToString(type) << "'"); - case LUA_TNIL: - break; - case LUA_TBOOLEAN: - LOG(level, lua_toboolean(L, -1)); - break; - case LUA_TNUMBER: - LOG(level, lua_tonumber(L, -1)); - break; - case LUA_TSTRING: - LOG(level, lua_tostring(L, -1)); - break; + case LUA_TNONE: + case LUA_TLIGHTUSERDATA: + case LUA_TTABLE: + case LUA_TFUNCTION: + case LUA_TUSERDATA: + case LUA_TTHREAD: + LOG(level, "Function parameter was of type '" << + luaTypeToString(type) << "'"); + case LUA_TNIL: + break; + case LUA_TBOOLEAN: + LOG(level, lua_toboolean(L, -1)); + break; + case LUA_TNUMBER: + LOG(level, lua_tonumber(L, -1)); + break; + case LUA_TSTRING: + LOG(level, lua_tostring(L, -1)); + break; } + return 0; } /** @@ -70,8 +75,7 @@ namespace luascriptfunctions { * types, the type is printed instead */ int printDebug(lua_State* L) { - printInternal(ghoul::logging::LogManager::LogLevel::Debug, L); - return 0; + return printInternal(ghoul::logging::LogManager::LogLevel::Debug, L); } /** @@ -82,8 +86,7 @@ namespace luascriptfunctions { * types, the type is printed instead */ int printInfo(lua_State* L) { - printInternal(ghoul::logging::LogManager::LogLevel::Info, L); - return 0; + return printInternal(ghoul::logging::LogManager::LogLevel::Info, L); } /** @@ -94,8 +97,7 @@ namespace luascriptfunctions { * types, the type is printed instead */ int printWarning(lua_State* L) { - printInternal(ghoul::logging::LogManager::LogLevel::Warning, L); - return 0; + return printInternal(ghoul::logging::LogManager::LogLevel::Warning, L); } /** @@ -106,8 +108,7 @@ namespace luascriptfunctions { * types, the type is printed instead */ int printError(lua_State* L) { - printInternal(ghoul::logging::LogManager::LogLevel::Error, L); - return 0; + return printInternal(ghoul::logging::LogManager::LogLevel::Error, L); } /** @@ -118,8 +119,7 @@ namespace luascriptfunctions { * types, the type is printed instead */ int printFatal(lua_State* L) { - printInternal(ghoul::logging::LogManager::LogLevel::Fatal, L); - return 0; + return printInternal(ghoul::logging::LogManager::LogLevel::Fatal, L); } /** @@ -129,13 +129,33 @@ namespace luascriptfunctions { * tokens and returns the absolute path. */ int absolutePath(lua_State* L) { - // TODO check number of arguments (ab) + int nArguments = lua_gettop(L); + if (nArguments != 1) + return luaL_error(L, "Expected %d arguments, got %d", 1, nArguments); + std::string path = luaL_checkstring(L, -1); path = absPath(path); lua_pushstring(L, path.c_str()); return 1; } + /** + * \ingroup LuaScripts + * setPathToken(string, string): + * Registers the path token provided by the first argument to the path in the second + * argument. If the path token already exists, it will be silently overridden. + */ + int setPathToken(lua_State* L) { + int nArguments = lua_gettop(L); + if (nArguments != 2) + return luaL_error(L, "Expected %i arguments, got %i", 2, nArguments); + + std::string pathToken = luaL_checkstring(L, -1); + std::string path = luaL_checkstring(L, -2); + FileSys.registerPathToken(pathToken, path, true); + return 0; + } + } // namespace luascriptfunctions namespace scripting { @@ -256,18 +276,20 @@ bool ScriptEngine::runScriptFile(const std::string& filename) { LERROR("Script with name '" << filename << "' did not exist"); return false; } - std::ifstream file(filename.c_str()); - if (file.bad()) { - LERROR("Error opening file '" << filename << "'"); + + int status = luaL_loadfile(_state, filename.c_str()); + if (status != LUA_OK) { + LERROR("Error loading script: '" << lua_tostring(_state, -1) << "'"); + return false; + } + + LDEBUG("Executing script '" << filename << "'"); + if (lua_pcall(_state, 0, LUA_MULTRET, 0)) { + LERROR("Error executing script: " << lua_tostring(_state, -1)); return false; } - // Read the contents of the script - std::string script((std::istreambuf_iterator(file)), - std::istreambuf_iterator()); - - const bool runSuccess = runScript(script); - return runSuccess; + return true; } bool ScriptEngine::hasLibrary(const std::string& name) @@ -391,6 +413,12 @@ void ScriptEngine::addBaseLibrary() { &luascriptfunctions::absolutePath, "absPath(string): Returns the absolute path to the passed path, resolving" " path tokens as well as resolving relative paths" + }, + { + "setPathToken", + &luascriptfunctions::setPathToken, + "setPathToken(string, string): Registers a new path token provided by the" + " first argument to the path provided in the second argument" } } }; From b343f4e552cdab5fae0ffa40d9c115a0189c5723 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sat, 27 Sep 2014 15:33:16 +0200 Subject: [PATCH 02/23] GCC compile fixes --- src/scenegraph/scenegraph.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/scenegraph/scenegraph.cpp b/src/scenegraph/scenegraph.cpp index 12ffdf1388..5bceaa96dd 100644 --- a/src/scenegraph/scenegraph.cpp +++ b/src/scenegraph/scenegraph.cpp @@ -81,12 +81,13 @@ int property_setValue(lua_State* L) { openspace::properties::Property* prop = property(uri); if (!prop) - return luaL_error(L, "Property with URL '%s' could not be found", uri); + return luaL_error(L, "Property with URL '%s' could not be found", uri.c_str()); if (type != prop->typeLua()) return luaL_error(L, "Property '%s' does not accept input of type '%s'. \ - Requested type: '%s'", uri, luaTypeToString(type), - luaTypeToString(prop->typeLua())); + Requested type: '%s'", uri.c_str(), + luaTypeToString(type).c_str(), + luaTypeToString(prop->typeLua()).c_str()); else prop->setLua(L); @@ -108,7 +109,7 @@ int property_getValue(lua_State* L) { openspace::properties::Property* prop = property(uri); if (!prop) - return luaL_error(L, "Property with URL '%s' could not be found", uri); + return luaL_error(L, "Property with URL '%s' could not be found", uri.c_str()); else prop->getLua(L); return 1; From 0570bffb687845de2230f8476e66e18d45bf237c Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sat, 27 Sep 2014 18:04:43 +0200 Subject: [PATCH 03/23] Cleanup of OpenSpaceEngine by factoring out ConfigurationManager class --- .../openspace/engine/configurationmanager.h | 43 +++++++ include/openspace/engine/openspaceengine.h | 9 +- include/openspace/util/constants.h | 8 +- src/engine/configurationmanager.cpp | 115 ++++++++++++++++++ src/engine/openspaceengine.cpp | 78 ++---------- 5 files changed, 180 insertions(+), 73 deletions(-) create mode 100644 include/openspace/engine/configurationmanager.h create mode 100644 src/engine/configurationmanager.cpp diff --git a/include/openspace/engine/configurationmanager.h b/include/openspace/engine/configurationmanager.h new file mode 100644 index 0000000000..6cbd98780a --- /dev/null +++ b/include/openspace/engine/configurationmanager.h @@ -0,0 +1,43 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * 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 __CONFIGURATIONMANAGER_H__ +#define __CONFIGURATIONMANAGER_H__ + +#include + +namespace openspace { + +class ConfigurationManager : public ghoul::Dictionary { +public: + bool loadFromFile(const std::string& filename); + +private: + bool registerPaths(); + bool registerBasePathFromConfigurationFile(const std::string& filename); +}; + +} // namespace openspace + +#endif // __CONFIGURATIONMANAGER_H__ diff --git a/include/openspace/engine/openspaceengine.h b/include/openspace/engine/openspaceengine.h index fea931f77d..00a85e34f4 100644 --- a/include/openspace/engine/openspaceengine.h +++ b/include/openspace/engine/openspaceengine.h @@ -33,7 +33,8 @@ #include #include -#include +#include +//#include #include #include @@ -74,11 +75,9 @@ public: static bool isInitialized(); bool initialize(); - static void registerPathsFromDictionary(const ghoul::Dictionary& dictionary); - static bool registerBasePathFromConfigurationFile(const std::string& filename); static bool findConfiguration(std::string& filename); - ghoul::Dictionary& configurationManager(); + ConfigurationManager& configurationManager(); ghoul::opencl::CLContext& clContext(); InteractionHandler& interactionHandler(); RenderEngine& renderEngine(); @@ -108,7 +107,7 @@ private: static OpenSpaceEngine* _engine; - ghoul::Dictionary* _configurationManager; + ConfigurationManager* _configurationManager; InteractionHandler* _interactionHandler; RenderEngine* _renderEngine; scripting::ScriptEngine* _scriptEngine; diff --git a/include/openspace/util/constants.h b/include/openspace/util/constants.h index ee5035cc66..8289ca1065 100644 --- a/include/openspace/util/constants.h +++ b/include/openspace/util/constants.h @@ -29,13 +29,17 @@ namespace openspace { namespace constants { -namespace openspaceengine { + +namespace configurationmanager { const std::string keyPaths = "Paths"; const std::string keyConfigSgct = "SGCTConfig"; const std::string keyConfigScene = "Scene"; const std::string keyStartupScript = "StartupScripts"; const std::string keyConfigTimekernel = "SpiceTimeKernel"; -} // namespace openspaceengine + namespace paths { + const std::string keyBasePath = "BASE_PATH"; + } // namespace paths +} // namespace configurationmanager namespace scenegraph { const std::string keyPathScene = "ScenePath"; diff --git a/src/engine/configurationmanager.cpp b/src/engine/configurationmanager.cpp new file mode 100644 index 0000000000..7ddda9ab00 --- /dev/null +++ b/src/engine/configurationmanager.cpp @@ -0,0 +1,115 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * 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 + +namespace { + const std::string _loggerCat = "ConfigurationManager"; +} + +namespace openspace { + +bool ConfigurationManager::loadFromFile(const std::string& filename) { + const bool basePathSuccess = registerBasePathFromConfigurationFile(filename); + if (!basePathSuccess) { + LERROR("Registering Base Path failed"); + return false; + } + + const bool loadingSuccess = ghoul::lua::loadDictionaryFromFile(filename, *this); + if (!loadingSuccess) { + LERROR("Loading dictionary from file failed"); + return false; + } + + const bool registerSuccess = registerPaths(); + if (!registerSuccess) { + LERROR("Registering paths failed"); + return false; + } + + return true; +} + +bool ConfigurationManager::registerPaths() { + ghoul::Dictionary dictionary; + const bool success = getValueSafe(constants::configurationmanager::keyPaths, dictionary); + if (!success) { + LERROR("Configuration does not contain the key '" << + constants::configurationmanager::keyPaths << "'"); + return false; + } + + std::vector&& pathKeys = dictionary.keys(); + for (const std::string& key : pathKeys) { + std::string p; + if (dictionary.getValue(key, p)) { + const std::string fullKey + = ghoul::filesystem::FileSystem::TokenOpeningBraces + key + + ghoul::filesystem::FileSystem::TokenClosingBraces; + LDEBUG("Registering path " << fullKey << ": " << p); + + std::string&& basePath = ghoul::filesystem::FileSystem::TokenOpeningBraces + + constants::configurationmanager::paths::keyBasePath + + ghoul::filesystem::FileSystem::TokenClosingBraces; + + bool override = (basePath == fullKey); + + if (override) + LINFO("Overriding base path with '" << p << "'"); + FileSys.registerPathToken(fullKey, p, override); + } + } + return true; +} + +bool ConfigurationManager::registerBasePathFromConfigurationFile(const std::string& filename) +{ + if (!FileSys.fileExists(filename)) + return false; + + const std::string absolutePath = FileSys.absolutePath(filename); + + std::string::size_type last + = absolutePath.find_last_of(ghoul::filesystem::FileSystem::PathSeparator); + if (last == std::string::npos) + return false; + + std::string basePath = absolutePath.substr(0, last); + + std::string&& basePathToken = ghoul::filesystem::FileSystem::TokenOpeningBraces + + constants::configurationmanager::paths::keyBasePath + + ghoul::filesystem::FileSystem::TokenClosingBraces; + + FileSys.registerPathToken(basePathToken, basePath); + + return true; +} + +} // namespace openspace diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 494b95039b..0ad4808e93 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -52,7 +52,6 @@ using namespace openspace::scripting; namespace { const std::string _loggerCat = "OpenSpaceEngine"; const std::string _configurationFile = "openspace.cfg"; - const std::string _basePathToken = "${BASE_PATH}"; const std::string _sgctDefaultConfigFile = "${SGCT}/single.xml"; const std::string _sgctConfigArgumentCommand = "-config"; @@ -69,7 +68,7 @@ namespace openspace { OpenSpaceEngine* OpenSpaceEngine::_engine = nullptr; OpenSpaceEngine::OpenSpaceEngine(std::string programName) - : _configurationManager(new ghoul::Dictionary) + : _configurationManager(new ConfigurationManager) , _interactionHandler(new InteractionHandler) , _renderEngine(new RenderEngine) , _scriptEngine(new ScriptEngine) @@ -116,45 +115,6 @@ bool OpenSpaceEngine::gatherCommandlineArguments() return true; } -void OpenSpaceEngine::registerPathsFromDictionary(const ghoul::Dictionary& dictionary) -{ - const std::vector& pathKeys = dictionary.keys(); - for (const std::string& key : pathKeys) { - std::string p; - if (dictionary.getValue(key, p)) { - const std::string fullKey - = ghoul::filesystem::FileSystem::TokenOpeningBraces + key - + ghoul::filesystem::FileSystem::TokenClosingBraces; - LDEBUG("Registering path " << fullKey << ": " << p); - - bool override = (_basePathToken == fullKey); - - if (override) - LINFO("Overriding base path with '" << p << "'"); - FileSys.registerPathToken(fullKey, p, override); - } - } -} - -bool OpenSpaceEngine::registerBasePathFromConfigurationFile(const std::string& filename) -{ - if (!FileSys.fileExists(filename)) - return false; - - const std::string absolutePath = FileSys.absolutePath(filename); - - std::string::size_type last - = absolutePath.find_last_of(ghoul::filesystem::FileSystem::PathSeparator); - if (last == std::string::npos) - return false; - - std::string basePath = absolutePath.substr(0, last); - - FileSys.registerPathToken(_basePathToken, basePath); - - return true; -} - bool OpenSpaceEngine::findConfiguration(std::string& filename) { std::string currentDirectory = FileSys.absolutePath(FileSys.currentDirectory()); @@ -232,33 +192,19 @@ bool OpenSpaceEngine::create(int argc, char** argv, } LINFO("Configuration Path: '" << FileSys.absolutePath(configurationFilePath) << "'"); - - // Registering base path - LDEBUG("Registering base path"); - if (!OpenSpaceEngine::registerBasePathFromConfigurationFile(configurationFilePath)) { - LFATAL("Could not register base path"); - return false; - } - - // Loading configuration from disk LDEBUG("Loading configuration from disk"); - ghoul::Dictionary& configuration = _engine->configurationManager(); - ghoul::lua::loadDictionaryFromFile(configurationFilePath, configuration); - ghoul::Dictionary pathsDictionary; - const bool success = configuration.getValueSafe(constants::openspaceengine::keyPaths, pathsDictionary); - if (success) - OpenSpaceEngine::registerPathsFromDictionary(pathsDictionary); - else { - LFATAL("Configuration file does not contain paths token '" << constants::openspaceengine::keyPaths << "'"); - return false; - } - + const bool configLoadSuccess = _engine->configurationManager().loadFromFile( + configurationFilePath); + if (!configLoadSuccess) { + LERROR("Loading of configuration file '" << configurationFilePath << "' failed"); + return false; + } // Determining SGCT configuration file LDEBUG("Determining SGCT configuration file"); std::string sgctConfigurationPath = _sgctDefaultConfigFile; - configuration.getValueSafe(constants::openspaceengine::keyConfigSgct, + _engine->configurationManager().getValueSafe(constants::configurationmanager::keyConfigSgct, sgctConfigurationPath); // Prepend the outgoing sgctArguments with the program name @@ -316,7 +262,7 @@ bool OpenSpaceEngine::initialize() SysCap.logCapabilities(); std::string timeKernel; - OsEng.configurationManager().getValueSafe(constants::openspaceengine::keyConfigTimekernel, timeKernel); + OsEng.configurationManager().getValueSafe(constants::configurationmanager::keyConfigTimekernel, timeKernel); // initialize OpenSpace helpers SpiceManager::initialize(); @@ -351,7 +297,7 @@ bool OpenSpaceEngine::initialize() std::string sceneDescriptionPath; bool success = OsEng.configurationManager().getValueSafe( - constants::openspaceengine::keyConfigScene, sceneDescriptionPath); + constants::configurationmanager::keyConfigScene, sceneDescriptionPath); if (success) sceneGraph->scheduleLoadSceneFile(sceneDescriptionPath); @@ -370,7 +316,7 @@ bool OpenSpaceEngine::initialize() // Run start up scripts ghoul::Dictionary scripts; success = _engine->configurationManager().getValueSafe( - constants::openspaceengine::keyStartupScript, scripts); + constants::configurationmanager::keyStartupScript, scripts); for (size_t i = 1; i <= scripts.size(); ++i) { std::stringstream stream; stream << i; @@ -395,7 +341,7 @@ bool OpenSpaceEngine::initialize() return true; } -ghoul::Dictionary& OpenSpaceEngine::configurationManager() +ConfigurationManager& OpenSpaceEngine::configurationManager() { // TODO custom assert (ticket #5) assert(_configurationManager); From 72aac7b240a98ec66f69cc8dbbc332335aa5b6f1 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sat, 27 Sep 2014 18:15:03 +0200 Subject: [PATCH 04/23] Refactoring OpenSpaceEngine pointers into unique_ptr Compile fix for GCC --- include/openspace/engine/openspaceengine.h | 10 +++++----- src/engine/openspaceengine.cpp | 5 ----- src/tests/main.cpp | 17 +++-------------- 3 files changed, 8 insertions(+), 24 deletions(-) diff --git a/include/openspace/engine/openspaceengine.h b/include/openspace/engine/openspaceengine.h index 00a85e34f4..050e990a35 100644 --- a/include/openspace/engine/openspaceengine.h +++ b/include/openspace/engine/openspaceengine.h @@ -107,11 +107,11 @@ private: static OpenSpaceEngine* _engine; - ConfigurationManager* _configurationManager; - InteractionHandler* _interactionHandler; - RenderEngine* _renderEngine; - scripting::ScriptEngine* _scriptEngine; - ghoul::cmdparser::CommandlineParser* _commandlineParser; + std::unique_ptr _configurationManager; + std::unique_ptr _interactionHandler; + std::unique_ptr _renderEngine; + std::unique_ptr _scriptEngine; + std::unique_ptr _commandlineParser; #ifdef OPENSPACE_VIDEO_EXPORT bool _doVideoExport; #endif diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 0ad4808e93..5a265d35e8 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -78,15 +78,10 @@ OpenSpaceEngine::OpenSpaceEngine(std::string programName) OpenSpaceEngine::~OpenSpaceEngine() { - delete _configurationManager; _configurationManager = nullptr; - delete _interactionHandler; _interactionHandler = nullptr; - delete _renderEngine; _renderEngine = nullptr; - delete _scriptEngine; _scriptEngine = nullptr; - delete _commandlineParser; _commandlineParser = nullptr; SpiceManager::deinitialize(); diff --git a/src/tests/main.cpp b/src/tests/main.cpp index b65a6237fd..9df4efbf5d 100644 --- a/src/tests/main.cpp +++ b/src/tests/main.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -64,20 +65,8 @@ int main(int argc, char** argv) { } LINFO("Configuration file found: " << FileSys.absolutePath(configurationFilePath)); - LDEBUG("Registering base path"); - if( ! openspace::OpenSpaceEngine::registerBasePathFromConfigurationFile(configurationFilePath)) { - LFATAL("Could not register base path"); - assert(false); - } - - ghoul::Dictionary configuration; - ghoul::lua::loadDictionaryFromFile(configurationFilePath, configuration); - if (configuration.hasKey(openspace::constants::openspaceengine::keyPaths)) { - ghoul::Dictionary pathsDictionary; - if (configuration.getValue(openspace::constants::openspaceengine::keyPaths, pathsDictionary)) { - openspace::OpenSpaceEngine::registerPathsFromDictionary(pathsDictionary); - } - } + openspace::ConfigurationManager manager; + manager.loadFromFile(configurationFilePath); openspace::FactoryManager::initialize(); From dd15c4e3d015bf1b47c7294eeb89700856634b97 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sat, 27 Sep 2014 18:41:03 +0200 Subject: [PATCH 05/23] Make the subcomponents not pointers in the first place --- include/openspace/engine/openspaceengine.h | 18 ++---- src/engine/openspaceengine.cpp | 64 ++++++++-------------- 2 files changed, 29 insertions(+), 53 deletions(-) diff --git a/include/openspace/engine/openspaceengine.h b/include/openspace/engine/openspaceengine.h index 050e990a35..50e3ee55a2 100644 --- a/include/openspace/engine/openspaceengine.h +++ b/include/openspace/engine/openspaceengine.h @@ -41,6 +41,7 @@ #include #include +#include // #define FLARE_ONLY #include @@ -53,13 +54,6 @@ // #define OPENSPACE_VIDEO_EXPORT -namespace ghoul { - namespace cmdparser { - class CommandlineParser; - class CommandlineCommand; - } -} - namespace openspace { namespace scripting { @@ -107,11 +101,11 @@ private: static OpenSpaceEngine* _engine; - std::unique_ptr _configurationManager; - std::unique_ptr _interactionHandler; - std::unique_ptr _renderEngine; - std::unique_ptr _scriptEngine; - std::unique_ptr _commandlineParser; + ConfigurationManager _configurationManager; + InteractionHandler _interactionHandler; + RenderEngine _renderEngine; + scripting::ScriptEngine _scriptEngine; + ghoul::cmdparser::CommandlineParser _commandlineParser; #ifdef OPENSPACE_VIDEO_EXPORT bool _doVideoExport; #endif diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 5a265d35e8..fbc7edac9c 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -68,22 +68,12 @@ namespace openspace { OpenSpaceEngine* OpenSpaceEngine::_engine = nullptr; OpenSpaceEngine::OpenSpaceEngine(std::string programName) - : _configurationManager(new ConfigurationManager) - , _interactionHandler(new InteractionHandler) - , _renderEngine(new RenderEngine) - , _scriptEngine(new ScriptEngine) - , _commandlineParser(new CommandlineParser(programName, true)) + : _commandlineParser(programName, true) { } OpenSpaceEngine::~OpenSpaceEngine() { - _configurationManager = nullptr; - _interactionHandler = nullptr; - _renderEngine = nullptr; - _scriptEngine = nullptr; - _commandlineParser = nullptr; - SpiceManager::deinitialize(); Spice::deinit(); Time::deinitialize(); @@ -105,7 +95,7 @@ bool OpenSpaceEngine::gatherCommandlineArguments() CommandlineCommand* configurationFileCommand = new SingleCommand( &commandlineArgumentPlaceholders.configurationName, "-config", "-c", "Provides the path to the OpenSpace configuration file"); - _commandlineParser->addCommand(configurationFileCommand); + _commandlineParser.addCommand(configurationFileCommand); return true; } @@ -169,8 +159,8 @@ bool OpenSpaceEngine::create(int argc, char** argv, // Parse commandline arguments std::vector remainingArguments; - _engine->_commandlineParser->setCommandLine(argc, argv, &sgctArguments); - const bool executeSuccess = _engine->_commandlineParser->execute(); + _engine->_commandlineParser.setCommandLine(argc, argv, &sgctArguments); + const bool executeSuccess = _engine->_commandlineParser.execute(); if (!executeSuccess) return false; @@ -282,12 +272,12 @@ bool OpenSpaceEngine::initialize() // Load scenegraph SceneGraph* sceneGraph = new SceneGraph; - _renderEngine->setSceneGraph(sceneGraph); + _renderEngine.setSceneGraph(sceneGraph); // initialize the RenderEngine, needs ${SCENEPATH} to be set - _renderEngine->initialize(); + _renderEngine.initialize(); sceneGraph->initialize(); std::string sceneDescriptionPath; @@ -296,7 +286,7 @@ bool OpenSpaceEngine::initialize() if (success) sceneGraph->scheduleLoadSceneFile(sceneDescriptionPath); - _renderEngine->setSceneGraph(sceneGraph); + _renderEngine.setSceneGraph(sceneGraph); #ifdef FLARE_ONLY _flare = new Flare(); @@ -306,7 +296,7 @@ bool OpenSpaceEngine::initialize() // Initialize OpenSpace input devices DeviceIdentifier::init(); DeviceIdentifier::ref().scanDevices(); - _engine->_interactionHandler->connectDevices(); + _engine->_interactionHandler.connectDevices(); // Run start up scripts ghoul::Dictionary scripts; @@ -338,9 +328,7 @@ bool OpenSpaceEngine::initialize() ConfigurationManager& OpenSpaceEngine::configurationManager() { - // TODO custom assert (ticket #5) - assert(_configurationManager); - return *_configurationManager; + return _configurationManager; } ghoul::opencl::CLContext& OpenSpaceEngine::clContext() @@ -350,23 +338,17 @@ ghoul::opencl::CLContext& OpenSpaceEngine::clContext() InteractionHandler& OpenSpaceEngine::interactionHandler() { - // TODO custom assert (ticket #5) - assert(_interactionHandler); - return *_interactionHandler; + return _interactionHandler; } RenderEngine& OpenSpaceEngine::renderEngine() { - // TODO custom assert (ticket #5) - assert(_renderEngine); - return *_renderEngine; + return _renderEngine; } ScriptEngine& OpenSpaceEngine::scriptEngine() { - // TODO custom assert (ticket #5) - assert(_scriptEngine); - return *_scriptEngine; + return _scriptEngine; } @@ -378,7 +360,7 @@ ShaderCreator& OpenSpaceEngine::shaderBuilder() bool OpenSpaceEngine::initializeGL() { - return _renderEngine->initializeGL(); + return _renderEngine.initializeGL(); } void OpenSpaceEngine::preSynchronization() @@ -390,8 +372,8 @@ void OpenSpaceEngine::preSynchronization() if (sgct::Engine::instance()->isMaster()) { const double dt = sgct::Engine::instance()->getDt(); - _interactionHandler->update(dt); - _interactionHandler->lockControls(); + _interactionHandler.update(dt); + _interactionHandler.lockControls(); Time::ref().advanceTime(dt); } @@ -402,7 +384,7 @@ void OpenSpaceEngine::preSynchronization() void OpenSpaceEngine::postSynchronizationPreDraw() { - _renderEngine->postSynchronizationPreDraw(); + _renderEngine.postSynchronizationPreDraw(); #ifdef FLARE_ONLY _flare->postSyncPreDraw(); #endif @@ -413,14 +395,14 @@ void OpenSpaceEngine::render() #ifdef FLARE_ONLY _flare->render(); #else - _renderEngine->render(); + _renderEngine.render(); #endif } void OpenSpaceEngine::postDraw() { if (sgct::Engine::instance()->isMaster()) { - _interactionHandler->unlockControls(); + _interactionHandler.unlockControls(); } #ifdef OPENSPACE_VIDEO_EXPORT float speed = 0.01; @@ -441,7 +423,7 @@ void OpenSpaceEngine::postDraw() void OpenSpaceEngine::keyboardCallback(int key, int action) { if (sgct::Engine::instance()->isMaster()) { - _interactionHandler->keyboardCallback(key, action); + _interactionHandler.keyboardCallback(key, action); } #ifdef OPENSPACE_VIDEO_EXPORT if(action == SGCT_PRESS && key == SGCT_KEY_PRINT_SCREEN) @@ -455,7 +437,7 @@ void OpenSpaceEngine::keyboardCallback(int key, int action) void OpenSpaceEngine::mouseButtonCallback(int key, int action) { if (sgct::Engine::instance()->isMaster()) { - _interactionHandler->mouseButtonCallback(key, action); + _interactionHandler.mouseButtonCallback(key, action); } #ifdef FLARE_ONLY _flare->mouse(key, action); @@ -464,12 +446,12 @@ void OpenSpaceEngine::mouseButtonCallback(int key, int action) void OpenSpaceEngine::mousePositionCallback(int x, int y) { - _interactionHandler->mousePositionCallback(x, y); + _interactionHandler.mousePositionCallback(x, y); } void OpenSpaceEngine::mouseScrollWheelCallback(int pos) { - _interactionHandler->mouseScrollWheelCallback(pos); + _interactionHandler.mouseScrollWheelCallback(pos); } void OpenSpaceEngine::encode() @@ -515,7 +497,7 @@ void OpenSpaceEngine::externalControlCallback(const char* receivedChars, { std::string script = std::string(receivedChars + 1); LINFO("Received Lua Script: '" << script << "'"); - _scriptEngine->runScript(script); + _scriptEngine.runScript(script); } } } From add7e06a641a13382b22e2ebfa7d5f20e810dffc Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sat, 27 Sep 2014 18:54:10 +0200 Subject: [PATCH 06/23] Cleaning up ConfigurationManager --- .../openspace/engine/configurationmanager.h | 4 - src/engine/configurationmanager.cpp | 78 +++++++------------ 2 files changed, 27 insertions(+), 55 deletions(-) diff --git a/include/openspace/engine/configurationmanager.h b/include/openspace/engine/configurationmanager.h index 6cbd98780a..15e29ed8bf 100644 --- a/include/openspace/engine/configurationmanager.h +++ b/include/openspace/engine/configurationmanager.h @@ -32,10 +32,6 @@ namespace openspace { class ConfigurationManager : public ghoul::Dictionary { public: bool loadFromFile(const std::string& filename); - -private: - bool registerPaths(); - bool registerBasePathFromConfigurationFile(const std::string& filename); }; } // namespace openspace diff --git a/src/engine/configurationmanager.cpp b/src/engine/configurationmanager.cpp index 7ddda9ab00..a21ea3619c 100644 --- a/src/engine/configurationmanager.cpp +++ b/src/engine/configurationmanager.cpp @@ -36,80 +36,56 @@ namespace { namespace openspace { bool ConfigurationManager::loadFromFile(const std::string& filename) { - const bool basePathSuccess = registerBasePathFromConfigurationFile(filename); - if (!basePathSuccess) { - LERROR("Registering Base Path failed"); - return false; + using ghoul::filesystem::FileSystem; + using constants::configurationmanager::keyPaths; + if (!FileSys.fileExists(filename)) { + LERROR("Could not find file '" << filename << "'"); + return false; } - + + // ${BASE_PATH} + std::string&& basePathToken = FileSystem::TokenOpeningBraces + + constants::configurationmanager::paths::keyBasePath + + FileSystem::TokenClosingBraces; + + // Retrieving the directory in which the configuration file lies + std::string absolutePath = FileSys.absolutePath(filename); + std::string basePath = ghoul::filesystem::File(absolutePath).directoryName(); + FileSys.registerPathToken(basePathToken, basePath); + + // Loading the configuration file into ourselves const bool loadingSuccess = ghoul::lua::loadDictionaryFromFile(filename, *this); if (!loadingSuccess) { LERROR("Loading dictionary from file failed"); return false; } - const bool registerSuccess = registerPaths(); - if (!registerSuccess) { - LERROR("Registering paths failed"); - return false; - } - - return true; -} - -bool ConfigurationManager::registerPaths() { + // Register all the paths ghoul::Dictionary dictionary; - const bool success = getValueSafe(constants::configurationmanager::keyPaths, dictionary); + const bool success = getValueSafe(keyPaths, dictionary); if (!success) { - LERROR("Configuration does not contain the key '" << - constants::configurationmanager::keyPaths << "'"); + LERROR("Configuration does not contain the key '" << keyPaths << "'"); return false; } - std::vector&& pathKeys = dictionary.keys(); - for (const std::string& key : pathKeys) { + std::vector pathKeys = dictionary.keys(); + for (std::string key : pathKeys) { std::string p; if (dictionary.getValue(key, p)) { - const std::string fullKey - = ghoul::filesystem::FileSystem::TokenOpeningBraces + key - + ghoul::filesystem::FileSystem::TokenClosingBraces; + std::string fullKey + = FileSystem::TokenOpeningBraces + key + + FileSystem::TokenClosingBraces; LDEBUG("Registering path " << fullKey << ": " << p); - std::string&& basePath = ghoul::filesystem::FileSystem::TokenOpeningBraces + - constants::configurationmanager::paths::keyBasePath - + ghoul::filesystem::FileSystem::TokenClosingBraces; - - bool override = (basePath == fullKey); + bool override = (basePathToken == fullKey); if (override) LINFO("Overriding base path with '" << p << "'"); - FileSys.registerPathToken(fullKey, p, override); + FileSys.registerPathToken(std::move(fullKey), std::move(p), override); } } return true; } -bool ConfigurationManager::registerBasePathFromConfigurationFile(const std::string& filename) -{ - if (!FileSys.fileExists(filename)) - return false; - - const std::string absolutePath = FileSys.absolutePath(filename); - - std::string::size_type last - = absolutePath.find_last_of(ghoul::filesystem::FileSystem::PathSeparator); - if (last == std::string::npos) - return false; - - std::string basePath = absolutePath.substr(0, last); - - std::string&& basePathToken = ghoul::filesystem::FileSystem::TokenOpeningBraces + - constants::configurationmanager::paths::keyBasePath - + ghoul::filesystem::FileSystem::TokenClosingBraces; - - FileSys.registerPathToken(basePathToken, basePath); - - return true; -} } // namespace openspace From cfcf0247be899a458d48f6dc5df937c6c1484ed4 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sat, 27 Sep 2014 19:13:36 +0200 Subject: [PATCH 07/23] More cleanup of ConfigurationManager --- .gitignore | 2 ++ include/openspace/util/constants.h | 3 --- openspace.cfg | 5 +++-- src/engine/configurationmanager.cpp | 8 ++++++-- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index ce9b9d5a70..ffa711ee63 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ bin/ build/ +cache/ +tmp/ ext/SGCT .DS_Store *.swp diff --git a/include/openspace/util/constants.h b/include/openspace/util/constants.h index 8289ca1065..b912a04105 100644 --- a/include/openspace/util/constants.h +++ b/include/openspace/util/constants.h @@ -36,9 +36,6 @@ namespace configurationmanager { const std::string keyConfigScene = "Scene"; const std::string keyStartupScript = "StartupScripts"; const std::string keyConfigTimekernel = "SpiceTimeKernel"; - namespace paths { - const std::string keyBasePath = "BASE_PATH"; - } // namespace paths } // namespace configurationmanager namespace scenegraph { diff --git a/openspace.cfg b/openspace.cfg index 3a580bc567..8757c0f75b 100644 --- a/openspace.cfg +++ b/openspace.cfg @@ -2,11 +2,12 @@ return { Paths = { SGCT = "${BASE_PATH}/config/sgct", SCRIPTS = "${BASE_PATH}/scripts", - KERNELS = "${BASE_PATH}/kernels", SHADERS = "${BASE_PATH}/shaders", OPENSPACE_DATA = "${BASE_PATH}/openspace-data", TESTDIR = "${BASE_PATH}/src/tests", - CONFIG = "${BASE_PATH}/config" + CONFIG = "${BASE_PATH}/config", + CACHE = "${BASE_PATH}/cache", + TEMPORARY = "${BASE_PATH}/tmp" }, SGCTConfig = "${SGCT}/single.xml", --SGCTConfig = "${SGCT}/two_nodes.xml", diff --git a/src/engine/configurationmanager.cpp b/src/engine/configurationmanager.cpp index a21ea3619c..8c438f3ea9 100644 --- a/src/engine/configurationmanager.cpp +++ b/src/engine/configurationmanager.cpp @@ -31,6 +31,8 @@ namespace { const std::string _loggerCat = "ConfigurationManager"; + + const std::string _keyBasePath = "BASE_PATH"; } namespace openspace { @@ -44,8 +46,7 @@ bool ConfigurationManager::loadFromFile(const std::string& filename) { } // ${BASE_PATH} - std::string&& basePathToken = FileSystem::TokenOpeningBraces + - constants::configurationmanager::paths::keyBasePath + std::string&& basePathToken = FileSystem::TokenOpeningBraces + _keyBasePath + FileSystem::TokenClosingBraces; // Retrieving the directory in which the configuration file lies @@ -84,6 +85,9 @@ bool ConfigurationManager::loadFromFile(const std::string& filename) { FileSys.registerPathToken(std::move(fullKey), std::move(p), override); } } + + + return true; } From f3fb8cd95edbe0c410daf0d7657e890d5c3d68dc Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sat, 27 Sep 2014 19:23:24 +0200 Subject: [PATCH 08/23] Apply getValueSafe/getValue change of Dictionary to the codebase --- ext/ghoul | 2 +- src/engine/configurationmanager.cpp | 2 +- src/engine/openspaceengine.cpp | 8 ++++---- src/properties/property.cpp | 4 ++-- src/rendering/planets/planetgeometry.cpp | 2 +- src/rendering/planets/renderableplanet.cpp | 4 ++-- src/rendering/planets/simplespheregeometry.cpp | 4 ++-- src/rendering/renderable.cpp | 4 ++-- src/rendering/renderablefieldlines.cpp | 16 ++++++++-------- src/rendering/renderablevolumegl.cpp | 16 ++++++++-------- src/scenegraph/scenegraph.cpp | 2 +- 11 files changed, 32 insertions(+), 32 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index 4b0e00c748..d873c668d4 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 4b0e00c748310dcd3f6af2b61acd7b8322596ac3 +Subproject commit d873c668d426a2992bcdd370a34408ab88b2c55b diff --git a/src/engine/configurationmanager.cpp b/src/engine/configurationmanager.cpp index 8c438f3ea9..32631d20e1 100644 --- a/src/engine/configurationmanager.cpp +++ b/src/engine/configurationmanager.cpp @@ -63,7 +63,7 @@ bool ConfigurationManager::loadFromFile(const std::string& filename) { // Register all the paths ghoul::Dictionary dictionary; - const bool success = getValueSafe(keyPaths, dictionary); + const bool success = getValue(keyPaths, dictionary); if (!success) { LERROR("Configuration does not contain the key '" << keyPaths << "'"); return false; diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index fbc7edac9c..93a88ceca7 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -189,7 +189,7 @@ bool OpenSpaceEngine::create(int argc, char** argv, // Determining SGCT configuration file LDEBUG("Determining SGCT configuration file"); std::string sgctConfigurationPath = _sgctDefaultConfigFile; - _engine->configurationManager().getValueSafe(constants::configurationmanager::keyConfigSgct, + _engine->configurationManager().getValue(constants::configurationmanager::keyConfigSgct, sgctConfigurationPath); // Prepend the outgoing sgctArguments with the program name @@ -247,7 +247,7 @@ bool OpenSpaceEngine::initialize() SysCap.logCapabilities(); std::string timeKernel; - OsEng.configurationManager().getValueSafe(constants::configurationmanager::keyConfigTimekernel, timeKernel); + OsEng.configurationManager().getValue(constants::configurationmanager::keyConfigTimekernel, timeKernel); // initialize OpenSpace helpers SpiceManager::initialize(); @@ -281,7 +281,7 @@ bool OpenSpaceEngine::initialize() sceneGraph->initialize(); std::string sceneDescriptionPath; - bool success = OsEng.configurationManager().getValueSafe( + bool success = OsEng.configurationManager().getValue( constants::configurationmanager::keyConfigScene, sceneDescriptionPath); if (success) sceneGraph->scheduleLoadSceneFile(sceneDescriptionPath); @@ -300,7 +300,7 @@ bool OpenSpaceEngine::initialize() // Run start up scripts ghoul::Dictionary scripts; - success = _engine->configurationManager().getValueSafe( + success = _engine->configurationManager().getValue( constants::configurationmanager::keyStartupScript, scripts); for (size_t i = 1; i <= scripts.size(); ++i) { std::stringstream stream; diff --git a/src/properties/property.cpp b/src/properties/property.cpp index 0b5004a281..81347f43bd 100644 --- a/src/properties/property.cpp +++ b/src/properties/property.cpp @@ -87,7 +87,7 @@ int Property::typeLua() const { const std::string& Property::guiName() const { std::string result; - _metaData.getValueSafe(_metaDataKeyGuiName, result); + _metaData.getValue(_metaDataKeyGuiName, result); return std::move(result); } @@ -97,7 +97,7 @@ void Property::setGroupIdentifier(std::string groupId) { std::string Property::groupIdentifier() const { std::string result; - _metaData.getValueSafe(_metaDataKeyGroup, result); + _metaData.getValue(_metaDataKeyGroup, result); return std::move(result); } diff --git a/src/rendering/planets/planetgeometry.cpp b/src/rendering/planets/planetgeometry.cpp index 547984a8fe..7802145493 100644 --- a/src/rendering/planets/planetgeometry.cpp +++ b/src/rendering/planets/planetgeometry.cpp @@ -37,7 +37,7 @@ namespace planetgeometry { PlanetGeometry* PlanetGeometry::createFromDictionary(const ghoul::Dictionary& dictionary) { std::string geometryType; - const bool success = dictionary.getValueSafe( + const bool success = dictionary.getValue( constants::planetgeometry::keyType, geometryType); if (!success) { LERROR("PlanetGeometry did not contain a correct value of the key '" diff --git a/src/rendering/planets/renderableplanet.cpp b/src/rendering/planets/renderableplanet.cpp index 8b6cc755e1..0b574c8ffd 100644 --- a/src/rendering/planets/renderableplanet.cpp +++ b/src/rendering/planets/renderableplanet.cpp @@ -59,7 +59,7 @@ RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary) assert(success); ghoul::Dictionary geometryDictionary; - success = dictionary.getValueSafe( + success = dictionary.getValue( constants::renderableplanet::keyGeometry, geometryDictionary); if (success) { geometryDictionary.setValue(constants::scenegraphnode::keyName, name); @@ -73,7 +73,7 @@ RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary) // TODO: textures need to be replaced by a good system similar to the geometry as soon // as the requirements are fixed (ab) std::string texturePath = ""; - success = dictionary.getValueSafe("Textures.Color", texturePath); + success = dictionary.getValue("Textures.Color", texturePath); if (success) _colorTexturePath = path + "/" + texturePath; diff --git a/src/rendering/planets/simplespheregeometry.cpp b/src/rendering/planets/simplespheregeometry.cpp index bd08f2368f..f34de92b95 100644 --- a/src/rendering/planets/simplespheregeometry.cpp +++ b/src/rendering/planets/simplespheregeometry.cpp @@ -57,7 +57,7 @@ SimpleSphereGeometry::SimpleSphereGeometry(const ghoul::Dictionary& dictionary) assert(success); glm::vec2 radius; - success = dictionary.getValueSafe(keyRadius, radius); + success = dictionary.getValue(keyRadius, radius); if (!success) { LERROR("SimpleSphereGeometry of '" << name << "' did not provide a key '" << keyRadius << "'"); @@ -66,7 +66,7 @@ SimpleSphereGeometry::SimpleSphereGeometry(const ghoul::Dictionary& dictionary) _radius = radius; double segments; - success = dictionary.getValueSafe(keySegments, segments); + success = dictionary.getValue(keySegments, segments); if (!success) { LERROR("SimpleSphereGeometry of '" << name << "' did not provide a key '" << keySegments << "'"); diff --git a/src/rendering/renderable.cpp b/src/rendering/renderable.cpp index c789148cb7..832a3a6f39 100644 --- a/src/rendering/renderable.cpp +++ b/src/rendering/renderable.cpp @@ -43,7 +43,7 @@ Renderable* Renderable::createFromDictionary(const ghoul::Dictionary& dictionary assert(success); std::string renderableType; - success = dictionary.getValueSafe(constants::renderable::keyType, renderableType); + success = dictionary.getValue(constants::renderable::keyType, renderableType); if (!success) { LERROR("Renderable '" << name << "' did not have key '" << constants::renderable::keyType << "'"); @@ -67,7 +67,7 @@ Renderable::Renderable(const ghoul::Dictionary& dictionary) setName("renderable"); // get path if available - const bool success = dictionary.getValueSafe(constants::scenegraph::keyPathModule, _relativePath); + const bool success = dictionary.getValue(constants::scenegraph::keyPathModule, _relativePath); if (success) _relativePath += ghoul::filesystem::FileSystem::PathSeparator; diff --git a/src/rendering/renderablefieldlines.cpp b/src/rendering/renderablefieldlines.cpp index 4c25ab73d5..2c950aa753 100644 --- a/src/rendering/renderablefieldlines.cpp +++ b/src/rendering/renderablefieldlines.cpp @@ -53,7 +53,7 @@ RenderableFieldlines::RenderableFieldlines(const ghoul::Dictionary& dictionary) assert(success); ghoul::Dictionary fieldlines; - success = dictionary.getValueSafe(keyFieldlines, fieldlines); + success = dictionary.getValue(keyFieldlines, fieldlines); if (!success) { LERROR("RenderableFieldlines '" << name << "' did not contain a '" << keyFieldlines << "' key"); @@ -61,7 +61,7 @@ RenderableFieldlines::RenderableFieldlines(const ghoul::Dictionary& dictionary) } for (const std::string& key : fieldlines.keys()) { ghoul::Dictionary fieldline; - success = fieldlines.getValueSafe(key, fieldline); + success = fieldlines.getValue(key, fieldline); if (!success) { LERROR("Key '" << key << "' in '" << keyFieldlines << @@ -71,13 +71,13 @@ RenderableFieldlines::RenderableFieldlines(const ghoul::Dictionary& dictionary) } std::string fileName; - fieldline.getValueSafe(keyFilename, fileName); + fieldline.getValue(keyFilename, fileName); fileName = findPath(fileName); if (fileName.empty()) LERROR("File not found!"); else { ghoul::Dictionary hintsDictionary; - fieldline.getValueSafe(keyHints, hintsDictionary); + fieldline.getValue(keyHints, hintsDictionary); _filenames.push_back(fileName); _hintsDictionaries.push_back(hintsDictionary); @@ -85,7 +85,7 @@ RenderableFieldlines::RenderableFieldlines(const ghoul::Dictionary& dictionary) } ghoul::Dictionary shaderDictionary; - success = dictionary.getValueSafe(keyShaders, shaderDictionary); + success = dictionary.getValue(keyShaders, shaderDictionary); if (!success) { LERROR("RenderableFieldlines '" << name << "' does not contain a '" << keyShaders << "' table"); @@ -93,7 +93,7 @@ RenderableFieldlines::RenderableFieldlines(const ghoul::Dictionary& dictionary) } std::string vshaderpath; - success = shaderDictionary.getValueSafe(keyVertexShader, vshaderpath); + success = shaderDictionary.getValue(keyVertexShader, vshaderpath); if (!success) { LERROR("RenderableFieldlines '" << name << "' does not have a '" << keyVertexShader << "'"); @@ -102,7 +102,7 @@ RenderableFieldlines::RenderableFieldlines(const ghoul::Dictionary& dictionary) vshaderpath = findPath(vshaderpath); std::string fshaderpath; - success = shaderDictionary.getValueSafe(keyFragmentShader, fshaderpath); + success = shaderDictionary.getValue(keyFragmentShader, fshaderpath); if (!success) { LERROR("RenderableFieldlines '" << name << "' does not have a '" << keyFragmentShader << "'"); @@ -117,7 +117,7 @@ RenderableFieldlines::RenderableFieldlines(const ghoul::Dictionary& dictionary) ShaderCreator sc = OsEng.shaderBuilder(); _fieldlinesProgram = sc.buildShader("FieldlinesProgram", vshaderpath, fshaderpath); - dictionary.getValueSafe("UpdateOnSave", _programUpdateOnSave); + dictionary.getValue("UpdateOnSave", _programUpdateOnSave); setBoundingSphere(PowerScaledScalar::CreatePSS(5)); // FIXME a non-magic number perhaps } diff --git a/src/rendering/renderablevolumegl.cpp b/src/rendering/renderablevolumegl.cpp index f602384b47..fd68ed3cbf 100644 --- a/src/rendering/renderablevolumegl.cpp +++ b/src/rendering/renderablevolumegl.cpp @@ -56,7 +56,7 @@ RenderableVolumeGL::RenderableVolumeGL(const ghoul::Dictionary& dictionary) assert(success); _filename = ""; - success = dictionary.getValueSafe(constants::renderablevolumegl::keyVolume, + success = dictionary.getValue(constants::renderablevolumegl::keyVolume, _filename); if (!success) { LERROR("Node '" << name << "' did not contain a valid '" << @@ -67,12 +67,12 @@ RenderableVolumeGL::RenderableVolumeGL(const ghoul::Dictionary& dictionary) LDEBUG("Volume Filename: " << _filename); - dictionary.getValueSafe(constants::renderablevolumegl::keyHints, _hintsDictionary); + dictionary.getValue(constants::renderablevolumegl::keyHints, _hintsDictionary); _transferFunction = nullptr; _transferFunctionFile = nullptr; _transferFunctionPath = ""; - success = dictionary.getValueSafe( + success = dictionary.getValue( constants::renderablevolumegl::keyTransferFunction, _transferFunctionPath); if (!success) { LERROR("Node '" << name << "' did not contain a valid '" << @@ -83,7 +83,7 @@ RenderableVolumeGL::RenderableVolumeGL(const ghoul::Dictionary& dictionary) _transferFunctionFile = new ghoul::filesystem::File(_transferFunctionPath, true); _samplerFilename = ""; - success = dictionary.getValueSafe(constants::renderablevolumegl::keySampler, + success = dictionary.getValue(constants::renderablevolumegl::keySampler, _samplerFilename); if (!success) { LERROR("Node '" << name << "' did not contain a valid '" << @@ -93,14 +93,14 @@ RenderableVolumeGL::RenderableVolumeGL(const ghoul::Dictionary& dictionary) _samplerFilename = findPath(_samplerFilename); glm::vec4 scalingVec4(_boxScaling, _w); - success = dictionary.getValueSafe(constants::renderablevolumegl::keyBoxScaling, + success = dictionary.getValue(constants::renderablevolumegl::keyBoxScaling, scalingVec4); if (success) { _boxScaling = scalingVec4.xyz; _w = scalingVec4.w; } else { - success = dictionary.getValueSafe(constants::renderablevolumegl::keyBoxScaling, + success = dictionary.getValue(constants::renderablevolumegl::keyBoxScaling, _boxScaling); if (!success) { LERROR("Node '" << name << "' did not contain a valid '" << @@ -109,8 +109,8 @@ RenderableVolumeGL::RenderableVolumeGL(const ghoul::Dictionary& dictionary) } } - dictionary.getValueSafe(constants::renderablevolumegl::keyVolumeName, _volumeName); - dictionary.getValueSafe(constants::renderablevolumegl::keyTransferFunctionName, + dictionary.getValue(constants::renderablevolumegl::keyVolumeName, _volumeName); + dictionary.getValue(constants::renderablevolumegl::keyTransferFunctionName, _transferFunctionName); setBoundingSphere(PowerScaledScalar::CreatePSS(glm::length(_boxScaling)*pow(10,_w))); diff --git a/src/scenegraph/scenegraph.cpp b/src/scenegraph/scenegraph.cpp index 5bceaa96dd..7c72226568 100644 --- a/src/scenegraph/scenegraph.cpp +++ b/src/scenegraph/scenegraph.cpp @@ -466,7 +466,7 @@ bool SceneGraph::loadSceneInternal(const std::string& sceneDescriptionFilePath) std::string&& sceneDescriptionDirectory = ghoul::filesystem::File(sceneDescriptionFilePath).directoryName(); std::string moduleDirectory("."); - dictionary.getValueSafe(constants::scenegraph::keyPathScene, moduleDirectory); + dictionary.getValue(constants::scenegraph::keyPathScene, moduleDirectory); // The scene path could either be an absolute or relative path to the description // paths directory From 3a2c4e92fc17314aeff08630a92a358b82edbd7b Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sat, 27 Sep 2014 19:42:25 +0200 Subject: [PATCH 09/23] Remove the paths from the configuration dictionary to make it unnecessary to keep them synchronized with the filesystem --- ext/ghoul | 2 +- src/engine/configurationmanager.cpp | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index d873c668d4..01bf202879 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit d873c668d426a2992bcdd370a34408ab88b2c55b +Subproject commit 01bf202879785ca6672109ab847dd81839a6f3b6 diff --git a/src/engine/configurationmanager.cpp b/src/engine/configurationmanager.cpp index 32631d20e1..8343383e28 100644 --- a/src/engine/configurationmanager.cpp +++ b/src/engine/configurationmanager.cpp @@ -86,7 +86,9 @@ bool ConfigurationManager::loadFromFile(const std::string& filename) { } } - + // Remove the Paths dictionary from the configuration manager as those paths might + // change later and we don't want to be forced to keep our local copy up to date + removeKey(keyPaths); return true; } From 1b3823d88ccc252e31783a3b65023411cd7abb1d Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sat, 27 Sep 2014 21:46:24 +0200 Subject: [PATCH 10/23] Remove old Spice wrapper --- include/openspace/scenegraph/spiceephemeris.h | 2 - include/openspace/util/spice.h | 42 ---- src/engine/openspaceengine.cpp | 4 - src/scenegraph/scenegraph.cpp | 1 - src/scenegraph/scenegraphnode.cpp | 1 - src/scenegraph/spiceephemeris.cpp | 25 +-- src/util/spice.cpp | 196 ------------------ 7 files changed, 11 insertions(+), 260 deletions(-) delete mode 100644 include/openspace/util/spice.h delete mode 100644 src/util/spice.cpp diff --git a/include/openspace/scenegraph/spiceephemeris.h b/include/openspace/scenegraph/spiceephemeris.h index 1d454cbc01..d52a990d87 100644 --- a/include/openspace/scenegraph/spiceephemeris.h +++ b/include/openspace/scenegraph/spiceephemeris.h @@ -42,8 +42,6 @@ public: private: std::string _targetName; std::string _originName; - int _target; - int _origin; psc _position; }; diff --git a/include/openspace/util/spice.h b/include/openspace/util/spice.h deleted file mode 100644 index 6a1ec6230c..0000000000 --- a/include/openspace/util/spice.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef SPICE_H -#define SPICE_H - -// std includes -#include - -namespace openspace -{ - -class Spice { -public: - virtual ~Spice(); - - static void init(); - static void deinit(); - static Spice& ref(); - static bool isInitialized(); - - void loadDefaultKernels(); - bool loadKernel(const std::string &path); - - void bod_NameToInt(const std::string &name, int *id, int *success); - bool getRadii(const std::string & name, double radii[3], int *n); - - bool spk_getPosition(const std::string &target, const std::string &origin, double state[3]); - void spk_getPosition(int target, int origin, double state[3]); - bool spk_getOrientation(const std::string &target, double state[3][3]); - -private: - static Spice* this_; - Spice(void); - Spice(const Spice& src); - Spice& operator=(const Spice& rhs); - - - -}; - - -} // namespace openspace - -#endif \ No newline at end of file diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 93a88ceca7..4009bd8979 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -75,7 +74,6 @@ OpenSpaceEngine::OpenSpaceEngine(std::string programName) OpenSpaceEngine::~OpenSpaceEngine() { SpiceManager::deinitialize(); - Spice::deinit(); Time::deinitialize(); DeviceIdentifier::deinit(); FileSystem::deinitialize(); @@ -252,8 +250,6 @@ bool OpenSpaceEngine::initialize() // initialize OpenSpace helpers SpiceManager::initialize(); Time::initialize(timeKernel); - Spice::init(); - Spice::ref().loadDefaultKernels(); // changeto: instantiate spicemanager, load kernels. SpiceManager::ref().loadKernel(absPath("${OPENSPACE_DATA}/spice/de430_1850-2150.bsp"), "SPK_EARTH"); SpiceManager::ref().loadKernel(absPath("${OPENSPACE_DATA}/spice/MAR063.bsp") , "SPK_MARS"); diff --git a/src/scenegraph/scenegraph.cpp b/src/scenegraph/scenegraph.cpp index 7c72226568..554afb5986 100644 --- a/src/scenegraph/scenegraph.cpp +++ b/src/scenegraph/scenegraph.cpp @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include diff --git a/src/scenegraph/scenegraphnode.cpp b/src/scenegraph/scenegraphnode.cpp index 6966db4035..074b9d6003 100644 --- a/src/scenegraph/scenegraphnode.cpp +++ b/src/scenegraph/scenegraphnode.cpp @@ -24,7 +24,6 @@ // open space includes #include -#include #include #include diff --git a/src/scenegraph/spiceephemeris.cpp b/src/scenegraph/spiceephemeris.cpp index 4a3100488b..bb2cf6b975 100644 --- a/src/scenegraph/spiceephemeris.cpp +++ b/src/scenegraph/spiceephemeris.cpp @@ -25,7 +25,6 @@ #include #include -#include #include #include @@ -40,8 +39,6 @@ using namespace constants::spiceephemeris; SpiceEphemeris::SpiceEphemeris(const ghoul::Dictionary& dictionary) : _targetName("") , _originName("") - , _target(0) - , _origin(0) , _position() { const bool hasBody = dictionary.hasKeyAndValue(keyBody); @@ -61,17 +58,17 @@ SpiceEphemeris::~SpiceEphemeris() {} bool SpiceEphemeris::initialize() { - if (!_targetName.empty() && !_originName.empty()) { - int bsuccess = 0; - int osuccess = 0; - Spice::ref().bod_NameToInt(_targetName, &_target, &bsuccess); - Spice::ref().bod_NameToInt(_originName, &_origin, &osuccess); - - if (bsuccess && osuccess) - return true; - } - - return false; + //if (!_targetName.empty() && !_originName.empty()) { + // int bsuccess = 0; + // int osuccess = 0; + // Spice::ref().bod_NameToInt(_targetName, &_target, &bsuccess); + // Spice::ref().bod_NameToInt(_originName, &_origin, &osuccess); + // + // if (bsuccess && osuccess) + // return true; + //} + // + return true; } const psc& SpiceEphemeris::position() const { diff --git a/src/util/spice.cpp b/src/util/spice.cpp deleted file mode 100644 index e7f8dc17fc..0000000000 --- a/src/util/spice.cpp +++ /dev/null @@ -1,196 +0,0 @@ - -// openspace stuff -#include -#include -#include -#include - -// spice -#include "SpiceUsr.h" - -// other -#include -#include -#include "ghoul/logging/logmanager.h" -#include "ghoul/logging/consolelog.h" -#include - -namespace openspace { - -#define lenout 81 -#define shrtms_len 81 - -Spice* Spice::this_ = nullptr; - -Spice::Spice() { - - // logger string - std::string _loggerCat = "Spice::Spice()"; - - // print spice toolkit version - ConstSpiceChar * versn; - versn = tkvrsn_c( "TOOLKIT" ); - LINFO("Spice Toolkit version: " << versn); - - // make the spice framework not exit on error - erract_c (const_cast("SET"), lenout, const_cast("RETURN")); - - // make spice print the errors to a log file - errdev_c (const_cast("SET"), lenout, const_cast("NULL") ); - -} - -Spice::~Spice() { - -} - -void Spice::init() { - assert( ! this_); - this_ = new Spice(); -} - -void Spice::deinit() { - assert(this_); - delete this_; - this_ = nullptr; -} - -Spice& Spice::ref() { - assert(this_); - return *this_; -} - -bool Spice::isInitialized() { - return this_ != nullptr; -} - -void Spice::loadDefaultKernels() { - assert(this_); - - // load - loadKernel(absPath("${OPENSPACE_DATA}/spice/de430_1850-2150.bsp")); - //Summary for: de430_1850-2150.bsp - //Bodies: MERCURY BARYCENTER (1) SATURN BARYCENTER (6) MERCURY (199) - // VENUS BARYCENTER (2) URANUS BARYCENTER (7) VENUS (299) - // EARTH BARYCENTER (3) NEPTUNE BARYCENTER (8) MOON (301) - // MARS BARYCENTER (4) PLUTO BARYCENTER (9) EARTH (399) - // JUPITER BARYCENTER (5) SUN (10) - // Start of Interval (ET) End of Interval (ET) - // ----------------------------- ----------------------------- - // 1849 DEC 26 00:00:00.000 2150 JAN 22 00:00:00.000 - - loadKernel(absPath("${OPENSPACE_DATA}/spice/pck00010.tpc")); -} - -bool Spice::loadKernel(const std::string &path) { - assert(this_); - - // ghoul logging - std::string _loggerCat = "Spice::loadKernel"; - - furnsh_c ( path.c_str() ); - int failed = failed_c(); - if(failed) { - char shrtms[shrtms_len]; - getmsg_c ( "SHORT", shrtms_len, shrtms ); - LERROR("Error when loading kernel with path: " << path); - LERROR("Spice reported: " << shrtms); - reset_c(); - } - return ( ! failed); -} - -void Spice::bod_NameToInt(const std::string & name, int *id, int *success) { - assert(this_); - bodn2c_c (name.c_str(), id, success); -} - -bool Spice::getRadii(const std::string & name, double radii[3], int *n) { - assert(this_); - - // ghoul logging - std::string _loggerCat = "Spice::getRadii"; - - bodvrd_c (name.c_str(), "RADII", 3, n, radii ); - int failed = failed_c(); - if(failed) { - char shrtms[shrtms_len]; - getmsg_c ( "SHORT", shrtms_len, shrtms ); - LERROR("Error when fetching radii"); - LERROR("Spice reported: " << shrtms); - reset_c(); - } - return ( ! failed); -} - -// has error checking -bool Spice::spk_getPosition(const std::string &target, const std::string &origin, double state[3]) { - assert(this_); - assert(Time::ref().isInitialized()); - - SpiceDouble et = Time::ref().currentTime(); - SpiceDouble lt; - spkpos_c(target.c_str(), et, "J2000", "LT+S", origin.c_str(), state, <); - int failed = failed_c(); - if(failed) { - reset_c(); - } - return ( ! failed); -} - -// no error checking -void Spice::spk_getPosition(int target, int origin, double state[3]) { - assert(this_); - assert(Time::ref().isInitialized()); - - SpiceDouble et = Time::ref().currentTime(); - SpiceDouble lt; - spkezp_c (target, et, "J2000", "NONE", origin, state, <); -} - -// has error checking -bool Spice::spk_getOrientation(const std::string &target, double state[3][3]) { - assert(this_); - assert(Time::ref().isInitialized()); - - // ghoul logging - std::string _loggerCat = "Spice::spk_getOrientation"; - - SpiceDouble et = Time::ref().currentTime(); - std::string newname = "IAU_"; - newname += target; - pxform_c ( "J2000", newname.c_str(), et, state ); - int failed = failed_c(); - if(failed) { - char shrtms[shrtms_len]; - getmsg_c ( "SHORT", shrtms_len, shrtms ); - LERROR("Error when fetching orientation"); - LERROR("Spice reported: " << shrtms); - reset_c(); - } - return ( ! failed); -} - -/* -The following example retrieves radii for Mars and computes - orientation of the Mars body-fixed frame: - - SpiceDouble et; - SpiceDouble mat[3][3]; - SpiceDouble radii[3]; - SpiceInt n; - - furnsh_c ( "naif0008.tls" ); - furnsh_c ( "pck00008.tpc" ); - - // retrieve Mars radii - bodvrd_c ( "MARS", "RADII", 3, &n, radii ); - - // convert UTC to ET - str2et_c ( "2005-DEC-28 12:00", &et ); - - // compute Mars orientation relative to the J2000 frame - pxform_c ( "J2000", "IAU_MARS", et, mat ); -*/ - -} // namespace openspace From e0d100c13a24f4c94ffd536551a5f7f02dcc1c2d Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sat, 27 Sep 2014 22:00:25 +0200 Subject: [PATCH 11/23] GCC compile fix --- src/tests/main.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tests/main.cpp b/src/tests/main.cpp index 9df4efbf5d..00dbeb4c3d 100644 --- a/src/tests/main.cpp +++ b/src/tests/main.cpp @@ -39,7 +39,6 @@ #include #include #include -#include #include #include From b667a4910c1b651acf74e009a200f062b07b349c Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 28 Sep 2014 00:06:53 +0200 Subject: [PATCH 12/23] Reworked how SPICE kernels are loaded - SpiceEphemeris can provide a list of kernels that are loaded when created - Time and Leapsecond kernels are provided in the openspace.cfg file --- ext/ghoul | 2 +- include/openspace/util/constants.h | 4 +- include/openspace/util/spicemanager.h | 2 +- include/openspace/util/time.h | 7 +-- openspace-data | 2 +- openspace.cfg | 5 +- src/engine/openspaceengine.cpp | 75 +++++++++++++++------------ src/scenegraph/spiceephemeris.cpp | 23 +++++--- src/util/spicemanager.cpp | 4 +- src/util/time.cpp | 11 +--- 10 files changed, 74 insertions(+), 61 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index 01bf202879..1df1dbf256 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 01bf202879785ca6672109ab847dd81839a6f3b6 +Subproject commit 1df1dbf2562930cb01b0d46d562ae1ed2e359552 diff --git a/include/openspace/util/constants.h b/include/openspace/util/constants.h index b912a04105..2004620508 100644 --- a/include/openspace/util/constants.h +++ b/include/openspace/util/constants.h @@ -35,7 +35,8 @@ namespace configurationmanager { const std::string keyConfigSgct = "SGCTConfig"; const std::string keyConfigScene = "Scene"; const std::string keyStartupScript = "StartupScripts"; - const std::string keyConfigTimekernel = "SpiceTimeKernel"; + const std::string keySpiceTimeKernel = "SpiceKernel.Time"; + const std::string keySpiceLeapsecondKernel = "SpiceKernel.LeapSecond"; } // namespace configurationmanager namespace scenegraph { @@ -100,6 +101,7 @@ namespace staticephemeris { namespace spiceephemeris { const std::string keyBody = "Body"; const std::string keyOrigin = "Observer"; + const std::string keyKernels = "Kernels"; } // namespace spiceephemeris } // namespace constants diff --git a/include/openspace/util/spicemanager.h b/include/openspace/util/spicemanager.h index 32ce34cafd..c72a371879 100644 --- a/include/openspace/util/spicemanager.h +++ b/include/openspace/util/spicemanager.h @@ -57,7 +57,7 @@ public: * \param kernelId unique integer ID for the loaded kernel * \return loaded kernels/metakernels unique integer id */ - int loadKernel(const std::string& fullPath, + int loadKernel(std::string fullPath, const std::string& shorthand); /** diff --git a/include/openspace/util/time.h b/include/openspace/util/time.h index 2db604e328..1735fa260e 100644 --- a/include/openspace/util/time.h +++ b/include/openspace/util/time.h @@ -52,14 +52,11 @@ namespace openspace { class Time { public: /** - * Initializes the Time singleton and loads an LSK spice kernel with the provided - * name. - * \param lskKernel The name of the kernel that should be loaded during the - * initialization. If the parameter is empty, no kernel will be loaded + * Initializes the Time singleton. * \return true if the initialization succeeded, false * otherwise */ - static bool initialize(const std::string& lskKernel = ""); + static bool initialize(); /** * Deinitializes the Time singleton. This method will not unload the kernel that was diff --git a/openspace-data b/openspace-data index 7ca4cc9594..f11e50b102 160000 --- a/openspace-data +++ b/openspace-data @@ -1 +1 @@ -Subproject commit 7ca4cc95942916fce110ee457d9604588f717e64 +Subproject commit f11e50b10255fed5f1ea6e8ddc02aa33156e8dc7 diff --git a/openspace.cfg b/openspace.cfg index 8757c0f75b..24fcdc1837 100644 --- a/openspace.cfg +++ b/openspace.cfg @@ -9,11 +9,14 @@ return { CACHE = "${BASE_PATH}/cache", TEMPORARY = "${BASE_PATH}/tmp" }, + SpiceKernel = { + Time = "${OPENSPACE_DATA}/spice/naif0010.tls", + LeapSecond = "${OPENSPACE_DATA}/spice/pck00010.tpc" + }, SGCTConfig = "${SGCT}/single.xml", --SGCTConfig = "${SGCT}/two_nodes.xml", --SGCTConfig = "${SGCT}/single_sbs_stereo.xml", Scene = "${OPENSPACE_DATA}/scene/default.scene", - SpiceTimeKernel = "${OPENSPACE_DATA}/spice/naif0010.tls", StartupScripts = { "${SCRIPTS}/default_startup.lua" } diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 4009bd8979..0b956dd070 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -100,27 +100,27 @@ bool OpenSpaceEngine::gatherCommandlineArguments() bool OpenSpaceEngine::findConfiguration(std::string& filename) { - std::string currentDirectory = FileSys.absolutePath(FileSys.currentDirectory()); - size_t occurrences = std::count(currentDirectory.begin(), currentDirectory.end(), - ghoul::filesystem::FileSystem::PathSeparator); + using ghoul::filesystem::Directory; - std::string cfgname = _configurationFile; + Directory directory = FileSys.currentDirectory(); + std::string configurationName = _configurationFile; - bool cfgFileFound = false; - for (size_t i = 0; i < occurrences; ++i) { - if (i > 0) - cfgname = "../" + cfgname; - if (FileSys.fileExists(cfgname)) { - cfgFileFound = true; - break; - } - } - if (!cfgFileFound) - return false; + while (true) { + std::string&& fullPath = FileSys.pathByAppendingComponent(directory, + configurationName); + bool exists = FileSys.fileExists(fullPath); + if (exists) { + filename = fullPath; + return true; + } - filename = cfgname; + Directory nextDirectory = directory.parentDirectory(true); - return true; + if (directory.path() == nextDirectory.path()) + // We have reached the root of the file system and did not find the file + return false; + directory = nextDirectory; + } } bool OpenSpaceEngine::create(int argc, char** argv, @@ -167,7 +167,8 @@ bool OpenSpaceEngine::create(int argc, char** argv, std::string configurationFilePath = commandlineArgumentPlaceholders.configurationName; if (configurationFilePath.empty()) { LDEBUG("Finding configuration"); - const bool findConfigurationSuccess = OpenSpaceEngine::findConfiguration(configurationFilePath); + const bool findConfigurationSuccess = + OpenSpaceEngine::findConfiguration(configurationFilePath); if (!findConfigurationSuccess) { LFATAL("Could not find OpenSpace configuration file!"); return false; @@ -186,10 +187,10 @@ bool OpenSpaceEngine::create(int argc, char** argv, // Determining SGCT configuration file LDEBUG("Determining SGCT configuration file"); - std::string sgctConfigurationPath = _sgctDefaultConfigFile; - _engine->configurationManager().getValue(constants::configurationmanager::keyConfigSgct, - sgctConfigurationPath); - + std::string sgctConfigurationPath = _sgctDefaultConfigFile; + _engine->configurationManager().getValue( + constants::configurationmanager::keyConfigSgct, sgctConfigurationPath); + // Prepend the outgoing sgctArguments with the program name // as well as the configuration file that sgct is supposed to use sgctArguments.insert(sgctArguments.begin(), argv[0]); @@ -244,21 +245,31 @@ bool OpenSpaceEngine::initialize() SysCap.detectCapabilities(); SysCap.logCapabilities(); - std::string timeKernel; - OsEng.configurationManager().getValue(constants::configurationmanager::keyConfigTimekernel, timeKernel); - // initialize OpenSpace helpers SpiceManager::initialize(); - Time::initialize(timeKernel); + Time::initialize(); - SpiceManager::ref().loadKernel(absPath("${OPENSPACE_DATA}/spice/de430_1850-2150.bsp"), "SPK_EARTH"); - SpiceManager::ref().loadKernel(absPath("${OPENSPACE_DATA}/spice/MAR063.bsp") , "SPK_MARS"); - SpiceManager::ref().loadKernel(absPath("${OPENSPACE_DATA}/spice/pck00010.tpc") , "PCK"); - SpiceManager::ref().loadKernel(absPath("${OPENSPACE_DATA}/spice/naif0010.tls") , "LSK"); + using constants::configurationmanager::keySpiceTimeKernel; + std::string timeKernel; + bool success = OsEng.configurationManager().getValue(keySpiceTimeKernel, timeKernel); + if (!success) { + LERROR("Configuration file does not contain a '" << keySpiceTimeKernel << "'"); + return false; + } + SpiceManager::ref().loadKernel(timeKernel, timeKernel); + + using constants::configurationmanager::keySpiceLeapsecondKernel; + std::string leapSecondKernel; + success = OsEng.configurationManager().getValue(keySpiceLeapsecondKernel, leapSecondKernel); + if (!success) { + LERROR("Configuration file does not contain a '" << keySpiceLeapsecondKernel << "'"); + return false; + } + SpiceManager::ref().loadKernel(leapSecondKernel, leapSecondKernel); + FactoryManager::initialize(); - scriptEngine().initialize(); // Register Lua script functions @@ -277,7 +288,7 @@ bool OpenSpaceEngine::initialize() sceneGraph->initialize(); std::string sceneDescriptionPath; - bool success = OsEng.configurationManager().getValue( + success = OsEng.configurationManager().getValue( constants::configurationmanager::keyConfigScene, sceneDescriptionPath); if (success) sceneGraph->scheduleLoadSceneFile(sceneDescriptionPath); diff --git a/src/scenegraph/spiceephemeris.cpp b/src/scenegraph/spiceephemeris.cpp index bb2cf6b975..02f23a06df 100644 --- a/src/scenegraph/spiceephemeris.cpp +++ b/src/scenegraph/spiceephemeris.cpp @@ -41,17 +41,24 @@ SpiceEphemeris::SpiceEphemeris(const ghoul::Dictionary& dictionary) , _originName("") , _position() { - const bool hasBody = dictionary.hasKeyAndValue(keyBody); - if (hasBody) - dictionary.getValue(keyBody, _targetName); - else + const bool hasBody = dictionary.getValue(keyBody, _targetName); + if (!hasBody) LERROR("SpiceEphemeris does not contain the key '" << keyBody << "'"); - const bool hasObserver = dictionary.hasKeyAndValue(keyOrigin); - if (hasObserver) - dictionary.getValue(keyOrigin, _originName); - else + const bool hasObserver = dictionary.getValue(keyOrigin, _originName); + if (!hasObserver) LERROR("SpiceEphemeris does not contain the key '" << keyOrigin << "'"); + + ghoul::Dictionary kernels; + dictionary.getValue(keyKernels, kernels); + for (size_t i = 1; i <= kernels.size(); ++i) { + std::string kernel; + bool success = kernels.getValue(std::to_string(i), kernel); + if (!success) + LERROR("'" << keyKernels << "' has to be an array-style table"); + + SpiceManager::ref().loadKernel(kernel, kernel); + } } SpiceEphemeris::~SpiceEphemeris() {} diff --git a/src/util/spicemanager.cpp b/src/util/spicemanager.cpp index e70c460a6b..9e4e52f89b 100644 --- a/src/util/spicemanager.cpp +++ b/src/util/spicemanager.cpp @@ -63,10 +63,12 @@ SpiceManager& SpiceManager::ref() { return *_manager; } -int SpiceManager::loadKernel(const std::string& fullPath, const std::string& shorthand){ +int SpiceManager::loadKernel(std::string fullPath, const std::string& shorthand){ unsigned int kernelId = ++_kernelCount; assert(kernelId > 0); + fullPath = absPath(fullPath); + std::string currentDirectory = FileSys.currentDirectory(); std::string::size_type last = fullPath.find_last_of(ghoul::filesystem::FileSystem::PathSeparator); if (last == std::string::npos) diff --git a/src/util/time.cpp b/src/util/time.cpp index 54d976e927..6520e3f4c5 100644 --- a/src/util/time.cpp +++ b/src/util/time.cpp @@ -150,17 +150,8 @@ Time::Time() { } -bool Time::initialize(const std::string& lskKernel) { +bool Time::initialize() { assert( _instance == nullptr); - - if (!lskKernel.empty()) { - const int success = SpiceManager::ref().loadKernel( - absPath(lskKernel), "TimeKernel"); - if (success == 0) { - LERROR("Error loading SPICE time kernel '" << lskKernel << "'"); - return false; - } - } _instance = new Time(); return true; } From e6ab0f51fc067d6d2beb1d5fc4fd19f2d77ce5eb Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 28 Sep 2014 02:28:14 +0200 Subject: [PATCH 13/23] Started cleanup of SpiceManager --- ext/ghoul | 2 +- include/openspace/util/spicemanager.h | 133 +++++++++++++++----------- src/engine/openspaceengine.cpp | 5 +- src/scenegraph/spiceephemeris.cpp | 2 +- src/util/spicemanager.cpp | 89 +++++++++-------- 5 files changed, 123 insertions(+), 108 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index 1df1dbf256..5a8a150468 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 1df1dbf2562930cb01b0d46d562ae1ed2e359552 +Subproject commit 5a8a150468b2e0c8b31f7e3238c1c5abbd667799 diff --git a/include/openspace/util/spicemanager.h b/include/openspace/util/spicemanager.h index c72a371879..dcbfb35162 100644 --- a/include/openspace/util/spicemanager.h +++ b/include/openspace/util/spicemanager.h @@ -1,28 +1,29 @@ /***************************************************************************************** -* * -* OpenSpace * -* * -* Copyright (c) 2014 * -* * -* 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 __SPICEWRAPPER_H__ -#define __SPICEWRAPPER_H__ + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * 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 __SPICEMANAGER_H__ +#define __SPICEMANAGER_H__ #include "SpiceUsr.h" @@ -32,45 +33,59 @@ #include #include -namespace openspace{ +namespace openspace { + class transformMatrix; + class SpiceManager{ public: -// Initialization ----------------------------------------------------------------------- // /** - * Static initializer that initializes the static member. + * Initializer that initializes the static member. */ static void initialize(); + + /** + * Deinitializes the SpiceManager and unloads all kernels which have been loaded using + * this manager. + */ static void deinitialize(); + + /** + * Returns the reference to the singleton SpiceManager object that must have been + * initialized by a call to the initialize method earlier. + * \return The SpiceManager singleton + */ static SpiceManager& ref(); /** - * Load one or more SPICE kernels into a program. If client provides - * the path to a binary kernel or meta-kernel upon which its loaded - * to the appropriate SPICE subsystem. if the file is a textkernel - * it will be loaded into kernel pool. - * In order to locate the spice kernels, the method temorarily changes the - * current working directory to the client-provided filePath. - * For further details, please refer to furnsh_c in SPICE Docummentation - * - * \param filePath path to single kernel or meta-kernel to load. - * \param kernelId unique integer ID for the loaded kernel - * \return loaded kernels/metakernels unique integer id + * Loads one or more SPICE kernels into a program. The provided path can either be a + * binary, text-kernel, or meta-kernel which gets loaded into the kernel pool. The + * loading is done by passing the filePath to the furnsh_c + * function. http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/furnsh_c.html + * \param filePath The path to the kernel that should be loaded + * \return The loaded kernel's unique identifier that can be used to unload the kernel */ - int loadKernel(std::string fullPath, - const std::string& shorthand); + int loadKernel(std::string filePath); /** - * Unload SPICE kernel. - * For further details, please refer to 'unload_c' in SPICE Docummentation - * - * \param either correspondign unique ID or shorthand with - * which the kernel was loaded and is to be unloaded. - * \return Whether the function succeeded or not + * Unloads a SPICE kernel identified by the kernelId which was returned + * by the loading call to loadKernel. The unloading is done by calling the + * unload_c function. + * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/unload_c.html + * \param kernelId The unique identifier that was returned from the call to + * loadKernel which loaded the kernel */ + void unloadKernel(int kernelId); - bool unloadKernel(const std::string& shorthand); - bool unloadKernel(int kernelId); + /** + * Unloads a SPICE kernel identified by the filePath which was used in + * the loading call to loadKernel. The unloading is done by calling the + * unload_c function. + * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/unload_c.html + * \param filePath The path of the kernel that should be unloaded, it has to refer to + * a file that was loaded in using the loadKernel method + */ + void unloadKernel(std::string filePath); // Acessing Kernel Data - Constants and Ids --------------------------------------------- // @@ -352,17 +367,19 @@ public: double& targetEpoch, glm::dvec3& vectorToSurfacePoint) const; private: + struct KernelInformation { + std::string path; + unsigned int id; + }; + SpiceManager() = default; ~SpiceManager(); SpiceManager(const SpiceManager& c) = delete; + + std::vector _loadedKernels; + static unsigned int _kernelCount; + static SpiceManager* _manager; - struct spiceKernel { - std::string path; - std::string name; - unsigned int id; - }; - std::vector _loadedKernels; - unsigned int _kernelCount = 0; }; /** @@ -457,5 +474,7 @@ public: } }; #undef COPY -} -#endif \ No newline at end of file + +} // namespace openspace + +#endif // __SPICEMANAGER_H__ diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 0b956dd070..36ecdafd4a 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -256,7 +256,7 @@ bool OpenSpaceEngine::initialize() LERROR("Configuration file does not contain a '" << keySpiceTimeKernel << "'"); return false; } - SpiceManager::ref().loadKernel(timeKernel, timeKernel); + SpiceManager::ref().loadKernel(std::move(timeKernel)); using constants::configurationmanager::keySpiceLeapsecondKernel; std::string leapSecondKernel; @@ -265,9 +265,8 @@ bool OpenSpaceEngine::initialize() LERROR("Configuration file does not contain a '" << keySpiceLeapsecondKernel << "'"); return false; } - SpiceManager::ref().loadKernel(leapSecondKernel, leapSecondKernel); + SpiceManager::ref().loadKernel(std::move(leapSecondKernel)); - FactoryManager::initialize(); scriptEngine().initialize(); diff --git a/src/scenegraph/spiceephemeris.cpp b/src/scenegraph/spiceephemeris.cpp index 02f23a06df..7eae196d37 100644 --- a/src/scenegraph/spiceephemeris.cpp +++ b/src/scenegraph/spiceephemeris.cpp @@ -57,7 +57,7 @@ SpiceEphemeris::SpiceEphemeris(const ghoul::Dictionary& dictionary) if (!success) LERROR("'" << keyKernels << "' has to be an array-style table"); - SpiceManager::ref().loadKernel(kernel, kernel); + SpiceManager::ref().loadKernel(kernel); } } diff --git a/src/util/spicemanager.cpp b/src/util/spicemanager.cpp index 9e4e52f89b..b9d2003c4b 100644 --- a/src/util/spicemanager.cpp +++ b/src/util/spicemanager.cpp @@ -22,25 +22,29 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ +#include + +#include #include #include #include #include -#ifdef WIN32 -#include -#endif +//#ifdef WIN32 +//#include +//#endif -#include "openspace/util/spicemanager.h" -#include "ghoul/filesystem/filesystem.h" -#include "ghoul/logging/logmanager.h" +#include +#include namespace { const std::string _loggerCat = "SpiceManager"; } -namespace openspace{ +namespace openspace { + SpiceManager* SpiceManager::_manager = nullptr; +unsigned int SpiceManager::_kernelCount = 0; SpiceManager::~SpiceManager(){ // cleanup... @@ -48,14 +52,22 @@ SpiceManager::~SpiceManager(){ void SpiceManager::initialize(){ assert(_manager == nullptr); - if (_manager == nullptr) _manager = new SpiceManager; - assert(_manager != nullptr); + _manager = new SpiceManager; + + // Set the SPICE library to not exit the program if an error occurs + erract_c("SET", 0, "REPORT"); + // But we do not want SPICE to print the errors, we will fetch them ourselves + errprt_c("SET", 0, "NONE"); } void SpiceManager::deinitialize(){ - assert(_manager != nullptr); delete _manager; _manager = nullptr; + _kernelCount = 0; + + // Set values back to default + erract_c("SET", 0, "DEFAULT"); + errprt_c("SET", 0, "DEFAULT"); } SpiceManager& SpiceManager::ref() { @@ -63,55 +75,40 @@ SpiceManager& SpiceManager::ref() { return *_manager; } -int SpiceManager::loadKernel(std::string fullPath, const std::string& shorthand){ +int SpiceManager::loadKernel(std::string filePath) { unsigned int kernelId = ++_kernelCount; assert(kernelId > 0); - fullPath = absPath(fullPath); - - std::string currentDirectory = FileSys.currentDirectory(); - std::string::size_type last = fullPath.find_last_of(ghoul::filesystem::FileSystem::PathSeparator); - if (last == std::string::npos) - return 0; - std::string kernelDir = fullPath.substr(0, last); - FileSys.setCurrentDirectory(kernelDir); - furnsh_c(fullPath.c_str()); - FileSys.setCurrentDirectory(currentDirectory); - - spiceKernel current = { fullPath, - shorthand, - kernelId }; - - _loadedKernels.push_back(current); + filePath = std::move(absPath(filePath)); + furnsh_c(filePath.c_str()); + KernelInformation&& info = { std::move(filePath), std::move(kernelId) }; + _loadedKernels.push_back(info); return kernelId; } -bool SpiceManager::unloadKernel(const std::string& shorthand){ - assert(shorthand != ""); +void SpiceManager::unloadKernel(int kernelId) { + auto it = std::find_if(_loadedKernels.begin(), _loadedKernels.end(), + [&kernelId](const KernelInformation& info) { return info.id == kernelId ; }); - std::vector::iterator it; - for (it = _loadedKernels.begin(); it != _loadedKernels.end(); it++){ - if (it->name == shorthand){ - unload_c((it->path).c_str()); - return true; - } + if (it != _loadedKernels.end()) { + unload_c(it->path.c_str()); + _loadedKernels.erase(it); } - return false; } -bool SpiceManager::unloadKernel(int kernelId){ - std::vector::iterator it; - for (it = _loadedKernels.begin(); it != _loadedKernels.end(); it++){ - if (it->id == kernelId){ - unload_c((it->path).c_str()); - return true; - } - } - return false; +void SpiceManager::unloadKernel(std::string filePath) { + filePath = absPath(filePath); + unload_c(filePath.c_str()); + + auto it = std::find_if(_loadedKernels.begin(), _loadedKernels.end(), + [&filePath](const KernelInformation& info) { return info.path == filePath; }); + + if (it != _loadedKernels.end()) + _loadedKernels.erase(it); } -bool SpiceManager::hasValue(int naifId, const std::string& kernelPoolValue) const{ +bool SpiceManager::hasValue(int naifId, const std::string& kernelPoolValue) const { return bodfnd_c(naifId, kernelPoolValue.c_str()); } From 83e7398fee7cf73732836d949b2f35b29bcd6fbd Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 28 Sep 2014 03:03:24 +0200 Subject: [PATCH 14/23] GCC fixes, fixed unit tests --- include/openspace/tests/test_spicemanager.inl | 19 +++---- include/openspace/util/spicemanager.h | 48 ++++++++++++----- src/util/spicemanager.cpp | 53 +++++++++++++++---- 3 files changed, 86 insertions(+), 34 deletions(-) diff --git a/include/openspace/tests/test_spicemanager.inl b/include/openspace/tests/test_spicemanager.inl index ab69468cbd..b73417e9c9 100644 --- a/include/openspace/tests/test_spicemanager.inl +++ b/include/openspace/tests/test_spicemanager.inl @@ -59,14 +59,14 @@ double abs_error = 0.00001; // In this testclass only a handset of the testfunctions require a single kernel. // The remaining methods rely on multiple kernels, loaded as a SPICE 'meta-kernel'. -#define KERNEL(param, name) int kernelID = -1; \ - kernelID = openspace::SpiceManager::ref().loadKernel(param, name); \ +#define KERNEL(param) int kernelID = -1; \ + kernelID = openspace::SpiceManager::ref().loadKernel(param); \ EXPECT_TRUE(kernelID != -1) << "loadKernel did not return proper id"; \ return kernelID; \ -int loadMetaKernel() { KERNEL(META , "METAKERNEL" ); } -int loadLSKKernel() { KERNEL(LSK , "LEAPSECONDS"); } -int loadPCKKernel() { KERNEL(PCK , "CASSINI_PCK"); } +int loadMetaKernel() { KERNEL(META); } +int loadLSKKernel() { KERNEL(LSK); } +int loadPCKKernel() { KERNEL(PCK); } std::string fileType(char type[]){ std::string str(type); @@ -108,8 +108,7 @@ TEST_F(SpiceManagerTest, unloadKernelString){ ASSERT_TRUE(found == SPICETRUE); //unload using string keyword - bool unloaded = openspace::SpiceManager::ref().unloadKernel("LEAPSECONDS"); - EXPECT_TRUE(unloaded); + openspace::SpiceManager::ref().unloadKernel(LSK); found = SPICEFALSE; kdata_c(0, "text", FILLEN, TYPLEN, SRCLEN, file, filtyp, source, &handle, &found); @@ -124,8 +123,7 @@ TEST_F(SpiceManagerTest, unloadKernelInteger){ ASSERT_TRUE(found == SPICETRUE); //unload using unique int ID - bool unloaded = openspace::SpiceManager::ref().unloadKernel(kernelID); - EXPECT_TRUE(unloaded) << "Kernel did not unload"; + openspace::SpiceManager::ref().unloadKernel(kernelID); found = SPICEFALSE; kdata_c(0, "text", FILLEN, TYPLEN, SRCLEN, file, filtyp, source, &handle, &found); @@ -145,8 +143,7 @@ TEST_F(SpiceManagerTest, unloadMetaKernel){ kdata_c(i, "all", FILLEN, TYPLEN, SRCLEN, file, filtyp, source, &handle, &found); EXPECT_EQ(fileType(filtyp), typeArr[i]) << "One or more kernels did not load properly"; } - bool unloaded = openspace::SpiceManager::ref().unloadKernel("METAKERNEL"); - EXPECT_TRUE(unloaded); + openspace::SpiceManager::ref().unloadKernel(META); for (int i = 0; i < nrMetaKernels; i++){ // the values should by now be unloaded diff --git a/include/openspace/util/spicemanager.h b/include/openspace/util/spicemanager.h index dcbfb35162..ba444f2568 100644 --- a/include/openspace/util/spicemanager.h +++ b/include/openspace/util/spicemanager.h @@ -37,7 +37,7 @@ namespace openspace { class transformMatrix; -class SpiceManager{ +class SpiceManager { public: /** * Initializer that initializes the static member. @@ -81,23 +81,48 @@ public: * Unloads a SPICE kernel identified by the filePath which was used in * the loading call to loadKernel. The unloading is done by calling the * unload_c function. - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/unload_c.html + * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/unload_c.html. * \param filePath The path of the kernel that should be unloaded, it has to refer to * a file that was loaded in using the loadKernel method */ void unloadKernel(std::string filePath); -// Acessing Kernel Data - Constants and Ids --------------------------------------------- // + /** + * Determines whether values exist for some item for any body, + * identified by it's naifId, in the kernel pool by passing it to the + * bodfnd_c function. + * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bodfnd_c.html + * For a description on NAIF IDs, see + * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html. + * \param naifId NAIF ID code of body + * \param item The item to find + * \return true if the function succeeded, false otherwise + */ + bool hasValue(int naifId, const std::string& item) const; /** - * Determine whether values exist for some item for any body in the kernel pool. - * For further details, please refer to 'bodfnd_c' in SPICE Docummentation - * - * \param naifId ID code of body. - * \param item Item to find ("RADII", "NUT_AMP_RA", etc.). - * \return Whether the function succeeded or not + * Determines whether values exist for some item for any + * code>body in the kernel pool by passing it to the bodfnd_c + * function. + * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bodfnd_c.html + * \param body The name of the body that should be sampled + * \param item The item to find + * \return true if the function succeeded, false otherwise */ - bool hasValue(int naifId, const std::string& kernelPoolValueName) const; + bool hasValue(const std::string& body, const std::string& item) const; + + /** + * Returns the NAIF ID for a specific body. For a description on NAIF IDs, see + * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html. The + * id will only be set if the retrieval was successful, otherwise it will + * remain unchanged. + * \param body The body name that should be retrieved + * \param id The ID of the body will be stored in this variable. The + * value will only be changed if the retrieval was successful + * \return true if the body was found, false + * otherwise + */ + bool getNaifIdForBody(const std::string& body, int& id) const; /** * Fetch from the kernel pool the double precision values of an @@ -373,11 +398,10 @@ private: }; SpiceManager() = default; - ~SpiceManager(); SpiceManager(const SpiceManager& c) = delete; std::vector _loadedKernels; - static unsigned int _kernelCount; + static unsigned int _lastAssignedKernel; static SpiceManager* _manager; }; diff --git a/src/util/spicemanager.cpp b/src/util/spicemanager.cpp index b9d2003c4b..a92b026885 100644 --- a/src/util/spicemanager.cpp +++ b/src/util/spicemanager.cpp @@ -44,13 +44,9 @@ namespace { namespace openspace { SpiceManager* SpiceManager::_manager = nullptr; -unsigned int SpiceManager::_kernelCount = 0; +unsigned int SpiceManager::_lastAssignedKernel = 0; -SpiceManager::~SpiceManager(){ - // cleanup... -} - -void SpiceManager::initialize(){ +void SpiceManager::initialize() { assert(_manager == nullptr); _manager = new SpiceManager; @@ -60,10 +56,13 @@ void SpiceManager::initialize(){ errprt_c("SET", 0, "NONE"); } -void SpiceManager::deinitialize(){ +void SpiceManager::deinitialize() { + for (const KernelInformation& i : _manager->_loadedKernels) + unload_c(i.path.c_str()); + delete _manager; _manager = nullptr; - _kernelCount = 0; + _lastAssignedKernel = 0; // Set values back to default erract_c("SET", 0, "DEFAULT"); @@ -76,11 +75,28 @@ SpiceManager& SpiceManager::ref() { } int SpiceManager::loadKernel(std::string filePath) { - unsigned int kernelId = ++_kernelCount; + unsigned int kernelId = ++_lastAssignedKernel; assert(kernelId > 0); filePath = std::move(absPath(filePath)); + ghoul::filesystem::Directory currentDirectory = FileSys.currentDirectory(); + std::string&& fileDirectory = ghoul::filesystem::File(filePath).directoryName(); + FileSys.setCurrentDirectory(fileDirectory); + furnsh_c(filePath.c_str()); + + FileSys.setCurrentDirectory(currentDirectory); + + int failed = failed_c(); + if (failed) { + char msg[1024]; + getmsg_c ( "LONG", 1024, msg ); + LERROR("Error loading kernel '" + filePath + "'"); + LERROR("Spice reported: " + std::string(msg)); + reset_c(); + return false; + } + KernelInformation&& info = { std::move(filePath), std::move(kernelId) }; _loadedKernels.push_back(info); @@ -108,8 +124,23 @@ void SpiceManager::unloadKernel(std::string filePath) { _loadedKernels.erase(it); } -bool SpiceManager::hasValue(int naifId, const std::string& kernelPoolValue) const { - return bodfnd_c(naifId, kernelPoolValue.c_str()); +bool SpiceManager::hasValue(int naifId, const std::string& item) const { + return (bodfnd_c(naifId, item.c_str()) == SPICETRUE); +} + +bool SpiceManager::hasValue(const std::string& body, const std::string& item) const { + int id; + bool success = getNaifIdForBody(body, id); + if (success) + return hasValue(id, item); + else + return false; +} + +bool SpiceManager::getNaifIdForBody(const std::string& body, int& id) const { + SpiceBoolean success; + bods2c_c(body.c_str(), &id, &success); + return (success == SPICETRUE); } // 1D From e97d5f17bca9a38aab369ac9b25ca33aa23e2dd1 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 28 Sep 2014 16:13:26 +0200 Subject: [PATCH 15/23] More SpiceManager cleanup --- include/openspace/tests/test_spicemanager.inl | 14 +- include/openspace/util/spicemanager.h | 231 +++++++++++++---- src/util/spicemanager.cpp | 244 +++++++++--------- src/util/time.cpp | 6 +- 4 files changed, 320 insertions(+), 175 deletions(-) diff --git a/include/openspace/tests/test_spicemanager.inl b/include/openspace/tests/test_spicemanager.inl index b73417e9c9..e12173c3f4 100644 --- a/include/openspace/tests/test_spicemanager.inl +++ b/include/openspace/tests/test_spicemanager.inl @@ -173,7 +173,7 @@ TEST_F(SpiceManagerTest, getValueFromID_1D){ std::string value1D = "MAG_NORTH_POLE_LAT"; double return1D; - bool found = openspace::SpiceManager::ref().getValueFromID(target, value1D, return1D); + bool found = openspace::SpiceManager::ref().getValue(target, value1D, return1D); ASSERT_TRUE(found) << "Could not retrieve value"; EXPECT_EQ(return1D, 78.565) << "Value not found / differs from expected return"; unload_c(PCK.c_str()); @@ -186,7 +186,7 @@ TEST_F(SpiceManagerTest, getValueFromID_3D){ std::string value3D = "RADII"; glm::dvec3 return3D; - openspace::SpiceManager::ref().getValueFromID(target, value3D, return3D); + openspace::SpiceManager::ref().getValue(target, value3D, return3D); EXPECT_EQ(return3D.x, 6378.14) << "Value not found / differs from expected return"; EXPECT_EQ(return3D.y, 6378.14) << "Value not found / differs from expected return"; @@ -200,16 +200,15 @@ TEST_F(SpiceManagerTest, getValueFromID_ND){ std::string target = "SATURN"; std::string valueND = "RING6_A"; - std::vector returnND; - unsigned int nr = 5; - bool found = openspace::SpiceManager::ref().getValueFromID(target, valueND, returnND, nr); + std::vector returnND(5); + bool found = openspace::SpiceManager::ref().getValue(target, valueND, returnND); ASSERT_TRUE(found) << "Could not retrieve value for specified kernel"; std::vector controlVec{ 189870.0, 256900.0, 9000.0, 9000.0, 0.000003 }; ASSERT_EQ(controlVec.size(), returnND.size()) << "Vectors differ in size"; - for (unsigned int i = 0; i < nr; ++i){ + for (unsigned int i = 0; i < returnND.size(); ++i){ EXPECT_EQ(controlVec[i], returnND[i]) << "Vector value not equal"; } unload_c(PCK.c_str()); @@ -223,7 +222,8 @@ TEST_F(SpiceManagerTest, stringToEphemerisTime){ char date[SRCLEN] = "Thu Mar 20 12:53:29 PST 1997"; str2et_c(date, &control_ephemerisTime); - ephemerisTime = openspace::SpiceManager::ref().convertStringToTdbSeconds(date); + bool success = openspace::SpiceManager::ref().getETfromDate(date, ephemerisTime); + EXPECT_EQ(success, true); EXPECT_EQ(ephemerisTime, control_ephemerisTime) << "Ephemeries times differ / not found"; unload_c(LSK.c_str()); diff --git a/include/openspace/util/spicemanager.h b/include/openspace/util/spicemanager.h index ba444f2568..dfe4f87e48 100644 --- a/include/openspace/util/spicemanager.h +++ b/include/openspace/util/spicemanager.h @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -122,62 +123,196 @@ public: * \return true if the body was found, false * otherwise */ - bool getNaifIdForBody(const std::string& body, int& id) const; - - /** - * Fetch from the kernel pool the double precision values of an - * item associated with a body. - * For further details, please refer to 'bodvrd_c' in SPICE Docummentation - * - * \param bodyName Body name. - * \param kernelPoolValueName Item for which values are desired. ("RADII", "NUT_PREC_ANGLES", etc. ) - * \return Whether the function succeeded or not - */ - bool getValueFromID(const std::string& bodyname, - const std::string& kernelPoolValueName, - double& value) const; - /* Overloaded method for 3dim vectors, see above specification.*/ - bool getValueFromID(const std::string& bodyname, - const std::string& kernelPoolValueName, - glm::dvec3& value) const; - /* Overloaded method for 4dim vectors, see above specification.*/ - bool getValueFromID(const std::string& bodyname, - const std::string& kernelPoolValueName, - glm::dvec4& value) const; - /* Overloaded method for Ndim vectors, see above specification.*/ - bool getValueFromID(const std::string& bodyname, - const std::string& kernelPoolValueName, - std::vector& values, unsigned int num) const; - -// Converting between UTC and Ephemeris Time (LSK) ------------------------------------- // - + bool getNaifId(const std::string& body, int& id) const; /** - * Convert a string representing an epoch to a double precision - * value representing the number of TDB seconds past the J2000 - * epoch corresponding to the input epoch. - * For further details, please refer to 'str2et_c' in SPICE Docummentation - * - * \param epochString, A string representing an epoch. - * \return Corresponding ephemeris time, equivalent value in seconds past J2000, TDB. + * Retrieves a single value for a certain body. This method + * succeeds iff body is the name of a valid body, value + * is a value associated with the body, and the value consists of only a single + * double value. If all conditions are true, the value is retrieved using + * the method bodvrd_c and stored in v + * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bodvrd_c.html. If one of + * the conditions is false an error is logged and the value v is + * unchanged. + * \param body The name of the body whose value should be retrieved + * \param value The value of that should be retrieved, this value is case-sensitive + * \param v The destination for the retrieved value + * \return true if the body named a valid body, + * value is a valid item for the body and the retrieved + * value is only a single value. false otherwise */ - double convertStringToTdbSeconds(const std::string& epochString) const; + bool getValue(const std::string& body, const std::string& value, double& v) const; /** - * Convert the number of TDB seconds past the J2000 epoch into a human readable - * string representation. Fur further details, please refer to 'timout_c' in SPICE - * Documentation - * - * \param seconds The number of seconds that have passed since the J2000 epoch - * \param format The output format of the string - * (see ftp://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/timout_c.html) - * \return The formatted date string + * Retrieves a single value for a certain body with a NAIF ID of + * id. This method succeeds iff id is the ID of a valid + * body, value is a value associated with the body, and the value + * consists of only a single double value. If all conditions are true, + * the value is retrieved using the method bodvrd_c and stored in + * v + * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bodvrd_c.html. If one of + * the conditions is false an error is logged and the value v is + * unchanged. For a description on NAIF IDs, see + * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html. + * \param id The NAIF ID of the body whose information should be retrieved + * \param value The value of that should be retrieved, this value is case-sensitive + * \param v The destination for the retrieved value + * \return true if the body named a valid body, + * value is a valid item for the body and the retrieved + * value is only a single value. false otherwise */ - std::string convertTdbSecondsToString(double seconds, const std::string& format) const; + bool getValue(int id, const std::string& value, double& v) const; - std::string ephemerisTimeToString(const double et) const; + /** + * Retrieves a value with three components for a certain + * body. This method succeeds iff body is the name of a + * valid body, value is a value associated with the body, and the value + * consists of three double values. If all conditions are true, the value + * is retrieved using the method bodvrd_c and stored in v + * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bodvrd_c.html. If one of + * the conditions is false an error is logged and the value v is + * unchanged. + * \param body The name of the body whose value should be retrieved + * \param value The value of that should be retrieved, this value is case-sensitive + * \param v The destination for the retrieved values + * \return true if the body named a valid body, + * value is a valid item for the body and the retrieved + * value is only a single value. false otherwise + */ + bool getValue(const std::string& body, const std::string& value, glm::dvec3& v) const; -// Computing Positions of Spacecraft and Natural Bodies(SPK) ---------------------------- // + /** + * Retrieves a value with three components for a certain body with a + * NAIF ID of id. This method succeeds id is the ID of a + * valid body, value is a value associated with the body, and the value + * consists of three double values. If all conditions are true, the value + * is retrieved using the method bodvrd_c and stored in v + * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bodvrd_c.html. If one of + * the conditions is false an error is logged and the value v is + * unchanged. For a description on NAIF IDs, see + * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html. + * \param id The NAIF ID of the body whose information should be retrieved + * \param value The value of that should be retrieved, this value is case-sensitive + * \param v The destination for the retrieved values + * \return true if the body named a valid body, + * value is a valid item for the body and the retrieved + * value is only a single value. false otherwise + */ + bool getValue(int id, const std::string& value, glm::dvec3& v) const; + + /** + * Retrieves a value with four components for a certain + * body. This method succeeds iff body is the name of a + * valid body, value is a value associated with the body, and the value + * consists of four double values. If all conditions are true, the value + * is retrieved using the method bodvrd_c and stored in v + * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bodvrd_c.html. If one of + * the conditions is false an error is logged and the value v is + * unchanged. + * \param body The name of the body whose value should be retrieved + * \param value The value of that should be retrieved, this value is case-sensitive + * \param v The destination for the retrieved values + * \return true if the body named a valid body, + * value is a valid item for the body and the retrieved + * value is only a single value. false otherwise + */ + bool getValue(const std::string& body, const std::string& value, glm::dvec4& v) const; + + /** + * Retrieves a value with four components for a certain body with a + * NAIF ID of id. This method succeeds id is the ID of a + * valid body, value is a value associated with the body, and the value + * consists of four double values. If all conditions are true, the value + * is retrieved using the method bodvrd_c and stored in v + * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bodvrd_c.html. If one of + * the conditions is false an error is logged and the value v is + * unchanged. For a description on NAIF IDs, see + * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html. + * \param id The NAIF ID of the body whose information should be retrieved + * \param value The value of that should be retrieved, this value is case-sensitive + * \param v The destination for the retrieved values + * \return true if the body named a valid body, + * value is a valid item for the body and the retrieved + * value is only a single value. false otherwise + */ + bool getValue(int id, const std::string& value, glm::dvec4& v) const; + + /** + * Retrieves a value with an arbitrary number of components for a certain + * body. This method succeeds body is a valid body, + * value is a value associated with the body, and the value consists of a + * number of double values. The requested number is equal to the + * size of the passed vector v which means that this vector + * has to be preallocated. If all conditions are true, the value is retrieved using + * the method bodvrd_c and stored in v + * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bodvrd_c.html. If one of + * the conditions is false an error is logged and the value v is + * unchanged. + * \param body The body whose information should be retrieved + * \param value The value of that should be retrieved, this value is case-sensitive + * \param v The destination for the retrieved values. The size of this vector + * determines how many values will be retrieved + * \return true if the body named a valid body, + * value is a valid item for the body and the retrieved + * value is only a single value. false otherwise + */ + bool getValue(const std::string& body, const std::string& value, + std::vector& v) const; + + /** + * Retrieves a value with an arbitrary number of components for a certain + * body with a NAIF ID of id. This method succeeds id is the + * ID of a valid body, value is a value associated with the body, and the + * value consists of a number of double values. The requested number is + * equal to the size of the passed vector v which means that + * this vector has to be preallocated. If all conditions are true, the value is + * retrieved using the method bodvrd_c and stored in v + * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bodvrd_c.html. If one of + * the conditions is false an error is logged and the value v is + * unchanged. For a description on NAIF IDs, see + * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html. + * \param id The NAIF ID of the body whose information should be retrieved + * \param value The value of that should be retrieved, this value is case-sensitive + * \param v The destination for the retrieved values. The size of this vector + * determines how many values will be retrieved + * \return true if the body named a valid body, + * value is a valid item for the body and the retrieved + * value is only a single value. false otherwise + */ + bool getValue(int id, const std::string& value, std::vector& v) const; + + /** + * Converts the epochString representing a date to a double precision + * value representing the ephemerisTime; that is the number of TDB + * seconds past the J2000 epoch. For further details, please refer to + * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/str2et_c.html. If an error + * occurs, an error is logged, the method returns false and the + * ephemerisTime remains unchanged. + * \param epochString A string representing an epoch + * \param ephemerisTime The destination for the converted time; the number of TDB + * seconds past the J2000 epoch, representing the passed epochString + * \return true if the epochString is a valid string and + * the conversion succeeded, false otherwise + */ + bool getETfromDate(const std::string& epochString, double& ephemerisTime) const; + + /** + * Converts the passed ephemerisTime into a human-readable + * date string with a specific format. For details on the + * formatting, refer to + * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/timout_c.html. In case of + * an error, date will not be modified, an error will be logged and the + * method returns false. + * \param ephemerisTime The ephemeris time, that is the number of TDB seconds past the + * J2000 epoch + * \param date The destination for the converted date. This will only be changed if + * the conversion succeeded + * \param format The format string describing the output format for the + * date + * \return true if the conversion succeeded, false otherwise + */ + bool getDateFromET(double ephemerisTime, std::string& date, + const std::string& format = "YYYY MON DDTHR:MN:SC.### ::RND"); /** * Return the position of a target body relative to an observing diff --git a/src/util/spicemanager.cpp b/src/util/spicemanager.cpp index a92b026885..20ad4d193c 100644 --- a/src/util/spicemanager.cpp +++ b/src/util/spicemanager.cpp @@ -30,6 +30,8 @@ #include #include +#include + //#ifdef WIN32 //#include //#endif @@ -130,145 +132,151 @@ bool SpiceManager::hasValue(int naifId, const std::string& item) const { bool SpiceManager::hasValue(const std::string& body, const std::string& item) const { int id; - bool success = getNaifIdForBody(body, id); + bool success = getNaifId(body, id); if (success) return hasValue(id, item); else return false; } -bool SpiceManager::getNaifIdForBody(const std::string& body, int& id) const { +bool SpiceManager::getNaifId(const std::string& body, int& id) const { SpiceBoolean success; bods2c_c(body.c_str(), &id, &success); return (success == SPICETRUE); } -// 1D -bool SpiceManager::getValueFromID(const std::string& bodyname, - const std::string& kernelPoolValue, - double& value) const{ - int n; - int code; - int found; - - bodn2c_c(bodyname.c_str(), &code, &found); - if (!found) return false; - bodvrd_c(bodyname.c_str(), kernelPoolValue.c_str(), 1, &n, &value); - - return true; -} -// 2D -/* -bool SpiceManager::getValueFromID(const std::string& bodyname, - const std::string& kernelPoolValueName, - glm::dvec2& value) const{ - int n; - double val[2]; - int code; - int found; - - bodn2c_c(bodyname.c_str(), &code, &found); - if (!found) return false; - bodvrd_c(bodyname.c_str(), kernelPoolValueName.c_str(), 2, &n, val); - - value[0] = val[0]; - value[1] = val[1]; - - return true; - -} -*/ -// 3D -bool SpiceManager::getValueFromID(const std::string& bodyname, - const std::string& kernelPoolValueName, - glm::dvec3& value) const{ - int n; - double val[3]; - int code; - int found; - - bodn2c_c(bodyname.c_str(), &code, &found); - if (!found) return false; - bodvrd_c(bodyname.c_str(), kernelPoolValueName.c_str(), 3, &n, val); - - memcpy(&value, val, sizeof(double)* 3); - - return true; -} -// 4D -/* -bool SpiceManager::getValueFromID(const std::string& bodyname, - const std::string& kernelPoolValueName, - glm::dvec4& value) const{ - int n; - double val[4]; - int code; - int found; - - bodn2c_c(bodyname.c_str(), &code, &found); - if (!found) return false; - bodvrd_c(bodyname.c_str(), kernelPoolValueName.c_str(), 4, &n, val); - - value[0] = val[0]; - value[1] = val[1]; - value[2] = val[2]; - value[3] = val[3]; - - return true; -} -*/ -// ND -bool SpiceManager::getValueFromID(const std::string& bodyname, - const std::string& kernelPoolValueName, - std::vector& values, - unsigned int num) const{ - int n; - double *val; - val = (double*)malloc(num*sizeof(double)); - int code; - int found; - - bodn2c_c(bodyname.c_str(), &code, &found); - if (!found) return false; - bodvrd_c(bodyname.c_str(), kernelPoolValueName.c_str(), num, &n, val); - - for (int i = 0; i < num; i++){ - values.push_back(val[i]); - } - - return true; -} - -double SpiceManager::convertStringToTdbSeconds(const std::string& epochString) const{ - double et; - str2et_c(epochString.c_str(), &et); - return et; -} - -std::string SpiceManager::ephemerisTimeToString(const double et) const{ - char utcstr[40]; - timout_c(et, "YYYY MON DD HR:MN:SC.### ::RND", 32, utcstr); - return std::string(utcstr); -} - -std::string SpiceManager::convertTdbSecondsToString(double seconds, - const std::string& format) const +bool SpiceManager::getValue(const std::string& body, const std::string& value, + double& v) const { - const int bufferSize = 128; - SpiceChar buffer[bufferSize]; - timout_c(seconds, format.c_str(), bufferSize - 1, buffer); + int n; + bodvrd_c(body.c_str(), value.c_str(), 1, &n, &v); int failed = failed_c(); if (failed) { char msg[1024]; getmsg_c("LONG", 1024, msg); - //LERROR("Error retrieving position of target '" + target + "'"); + LERROR("Error getting value '" << value << "' for body '" << body << "'"); LERROR("Spice reported: " + std::string(msg)); reset_c(); - return ""; + return false; } - return std::string(buffer); + return true; +} + +bool SpiceManager::getValue(int id, const std::string& value, double& v) const { + return getValue(std::to_string(id), value, v); +} + +bool SpiceManager::getValue(const std::string& body, const std::string& value, + glm::dvec3& v) const +{ + int n; + bodvrd_c(body.c_str(), value.c_str(), 3, &n, glm::value_ptr(v)); + + int failed = failed_c(); + if (failed) { + char msg[1024]; + getmsg_c("LONG", 1024, msg); + LERROR("Error getting value '" << value << "' for body '" << body << "'"); + LERROR("Spice reported: " + std::string(msg)); + reset_c(); + return false; + } + + return true; +} + +bool SpiceManager::getValue(int id, const std::string& value, glm::dvec3& v) const +{ + return getValue(std::to_string(id), value, v); +} + +bool SpiceManager::getValue(const std::string& body, const std::string& value, + glm::dvec4& v) const +{ + int n; + bodvrd_c(body.c_str(), value.c_str(), 4, &n, glm::value_ptr(v)); + + int failed = failed_c(); + if (failed) { + char msg[1024]; + getmsg_c("LONG", 1024, msg); + LERROR("Error getting value '" << value << "' for body '" << body << "'"); + LERROR("Spice reported: " + std::string(msg)); + reset_c(); + return false; + } + + return true; +} + +bool SpiceManager::getValue(int id, const std::string& value, glm::dvec4& v) const +{ + return getValue(std::to_string(id), value, v); +} + +bool SpiceManager::getValue(const std::string& body, const std::string& value, + std::vector& v) const +{ + assert(v.size() > 0); + int n; + bodvrd_c(body.c_str(), value.c_str(), static_cast(v.size()), &n, &v[0]); + + int failed = failed_c(); + if (failed) { + char msg[1024]; + getmsg_c("LONG", 1024, msg); + LERROR("Error getting value '" << value << "' for body '" << body << "'"); + LERROR("Spice reported: " + std::string(msg)); + reset_c(); + return false; + } + + return true; +} + +bool SpiceManager::getValue(int id, const std::string& value, + std::vector& v) const +{ + return getValue(std::to_string(id), value, v); +} + +bool SpiceManager::getETfromDate(const std::string& epochString, + double& ephemerisTime) const +{ + str2et_c(epochString.c_str(), &ephemerisTime); + int failed = failed_c(); + if (failed) { + char msg[1024]; + getmsg_c("LONG", 1024, msg); + LERROR("Error converting date '" + epochString+ "'"); + LERROR("Spice reported: " + std::string(msg)); + reset_c(); + return false; + } + return true; +} + +bool SpiceManager::getDateFromET(double ephemerisTime, std::string& date, + const std::string& format) +{ + static const int BufferSize = 256; + SpiceChar buffer[BufferSize]; + + timout_c(ephemerisTime, format.c_str(), BufferSize - 1, buffer); + int failed = failed_c(); + if (failed) { + char msg[1024]; + getmsg_c("LONG", 1024, msg); + LERROR("Error converting ephemeris time to date with format '" + format + "'"); + LERROR("Spice reported: " + std::string(msg)); + reset_c(); + return false; + } + + date = std::string(buffer); + return true; } bool SpiceManager::getTargetPosition(const std::string& target, diff --git a/src/util/time.cpp b/src/util/time.cpp index 6520e3f4c5..38443ac42a 100644 --- a/src/util/time.cpp +++ b/src/util/time.cpp @@ -193,11 +193,13 @@ double Time::deltaTime() const { } void Time::setTime(std::string time) { - _time = SpiceManager::ref().convertStringToTdbSeconds(std::move(time)); + SpiceManager::ref().getETfromDate(std::move(time), _time); } std::string Time::currentTimeUTC() const { - return SpiceManager::ref().convertTdbSecondsToString(_time, "YYYY-MM-DDTHR:MN:SC.#####"); + std::string date; + SpiceManager::ref().getDateFromET(_time, date); + return std::move(date); } scripting::ScriptEngine::LuaLibrary Time::luaLibrary() { scripting::ScriptEngine::LuaLibrary timeLibrary = { From cc3f9ef34b73ef6b5bfed68d1cfd4dd8bdda725f Mon Sep 17 00:00:00 2001 From: Jonas Strandstedt Date: Mon, 29 Sep 2014 13:03:58 +0200 Subject: [PATCH 16/23] Fixed ABuffer to update shader when Scengraph is updated --- include/openspace/abuffer/abuffer.h | 2 + shaders/ABuffer/abufferResolveFragment.glsl | 4 +- src/abuffer/abuffer.cpp | 12 +- src/engine/openspaceengine.cpp | 4 +- src/rendering/renderablevolumegl.cpp | 10 -- src/scenegraph/scenegraph.cpp | 169 +------------------- src/scenegraph/scenegraphnode.cpp | 3 +- 7 files changed, 19 insertions(+), 185 deletions(-) diff --git a/include/openspace/abuffer/abuffer.h b/include/openspace/abuffer/abuffer.h index f7c2f9e032..0323f77f76 100644 --- a/include/openspace/abuffer/abuffer.h +++ b/include/openspace/abuffer/abuffer.h @@ -52,6 +52,8 @@ public: void addTransferFunction(const std::string& tag,ghoul::opengl::Texture* transferFunction); int addSamplerfile(const std::string& filename); + void invalidateABuffer(); + protected: virtual std::string settings() = 0; diff --git a/shaders/ABuffer/abufferResolveFragment.glsl b/shaders/ABuffer/abufferResolveFragment.glsl index c076cad685..c4c441dc5b 100644 --- a/shaders/ABuffer/abufferResolveFragment.glsl +++ b/shaders/ABuffer/abufferResolveFragment.glsl @@ -252,7 +252,9 @@ vec4 calculate_final_color(uint frag_count) { #pragma openspace insert TRANSFERFUNC #endif - // if(frag_count == 1) { + // if(frag_count == 0) { + // final_color = vec4(0.5,0.5,0.5,1.0); + // } else if(frag_count == 1) { // final_color = vec4(1.0,0.0,0.0,1.0); // } else if(frag_count == 2) { // final_color = vec4(0.0,1.0,0.0,1.0); diff --git a/src/abuffer/abuffer.cpp b/src/abuffer/abuffer.cpp index 920a87b24d..925de91b82 100644 --- a/src/abuffer/abuffer.cpp +++ b/src/abuffer/abuffer.cpp @@ -45,7 +45,7 @@ std::string padGeneratedString(const std::string& content) { namespace openspace { -ABuffer::ABuffer(): _validShader(true) { +ABuffer::ABuffer() : _validShader(false), _resolveShader(nullptr) { int x1, xSize, y1, ySize; sgct::Engine::instance()->getActiveWindowPtr()->getCurrentViewportPixelCoords(x1, y1, xSize, ySize); _width = xSize; @@ -69,7 +69,6 @@ ABuffer::~ABuffer() { for(auto file: _shaderFiles) { delete file; } - } bool ABuffer::initializeABuffer() { @@ -93,10 +92,6 @@ bool ABuffer::initializeABuffer() { addFunc("${SHADERS}/PowerScaling/powerScaling_fs.hglsl"); addFunc("${SHADERS}/PowerScaling/powerScaling_vs.hglsl"); - _resolveShader = nullptr; - generateShaderSource(); - updateShader(); - // ============================ // GEOMETRY (quad) // ============================ @@ -127,7 +122,6 @@ void ABuffer::resolve() { _validShader = true; generateShaderSource(); updateShader(); - } if(_resolveShader) { @@ -375,5 +369,9 @@ std::string ABuffer::openspaceTransferFunction() { return tf; } +void ABuffer::invalidateABuffer() { + _validShader = false; +} + } // openspace \ No newline at end of file diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 36ecdafd4a..6dca374ecc 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -283,7 +283,7 @@ bool OpenSpaceEngine::initialize() // initialize the RenderEngine, needs ${SCENEPATH} to be set - _renderEngine.initialize(); + _renderEngine.initialize(); sceneGraph->initialize(); std::string sceneDescriptionPath; @@ -292,7 +292,7 @@ bool OpenSpaceEngine::initialize() if (success) sceneGraph->scheduleLoadSceneFile(sceneDescriptionPath); - _renderEngine.setSceneGraph(sceneGraph); + //_renderEngine.setSceneGraph(sceneGraph); #ifdef FLARE_ONLY _flare = new Flare(); diff --git a/src/rendering/renderablevolumegl.cpp b/src/rendering/renderablevolumegl.cpp index fd68ed3cbf..86d2f9c4b8 100644 --- a/src/rendering/renderablevolumegl.cpp +++ b/src/rendering/renderablevolumegl.cpp @@ -127,16 +127,6 @@ RenderableVolumeGL::~RenderableVolumeGL() { } bool RenderableVolumeGL::initialize() { - // assert(_filename != ""); - // ------ VOLUME READING ---------------- -// <<<<<<< HEAD -// ======= -// _volume = loadVolume(_filename, _hintsDictionary); -// _volume->uploadTexture(); -// _transferFunction = loadTransferFunction(_transferFunctionPath); -// _transferFunction->uploadTexture(); - -// >>>>>>> feature/fieldlines // TODO: fix volume an transferfunction names if(_filename != "") { _volume = loadVolume(_filename, _hintsDictionary); diff --git a/src/scenegraph/scenegraph.cpp b/src/scenegraph/scenegraph.cpp index 554afb5986..779c35486f 100644 --- a/src/scenegraph/scenegraph.cpp +++ b/src/scenegraph/scenegraph.cpp @@ -223,167 +223,6 @@ bool SceneGraph::initialize() double elapsed = std::chrono::duration_cast(clock_::now()-beginning).count(); LINFO("Time to load shaders: " << elapsed); - /* - - auto programCreator = [] ( const std::string& name, - const std::string& vpath, - const std::string& fpath) - { - const std::string vsPath = absPath(vpath); - const std::string fsPath = absPath(fpath); - const ShaderObject::ShaderType vsType = ShaderObject::ShaderType::ShaderTypeVertex; - const ShaderObject::ShaderType fsType = ShaderObject::ShaderType::ShaderTypeFragment; - - ProgramObject* po = new ProgramObject(name); - ShaderObject* vs = new ShaderObject(vsType, vsPath, name + "Vertex"); - ShaderObject* fs = new ShaderObject(fsType, fsPath, name + "Fragment"); - po->attachObject(vs); - po->attachObject(fs); - if ( po->compileShaderObjects() && po->linkProgramObject()) - return po; - - // unsuccessful compilation, cleanup and return nullptr - delete po; - po = nullptr; -//<<<<<<< HEAD - } - - ShaderObject* powerscale_vs - = new ShaderObject(ShaderObject::ShaderType::ShaderTypeVertex, - absPath("${SHADERS}/pscstandard_vs.glsl"), "PS Vertex"); - ShaderObject* powerscale_fs - = new ShaderObject(ShaderObject::ShaderType::ShaderTypeFragment, - absPath("${SHADERS}/pscstandard_fs.glsl"), "PS Fragment"); - - po = new ProgramObject; - po->attachObject(powerscale_vs); - po->attachObject(powerscale_fs); - - if (!po->compileShaderObjects()) - return false; - if (!po->linkProgramObject()) - return false; - - OsEng.ref().configurationManager().setValue("pscShader", po); - - ProgramObject* _gridProgram = new ProgramObject("GridProgram"); - ShaderObject* gridvs = new ShaderObject(ShaderObject::ShaderTypeVertex, - absPath("${SHADERS}/grid_vs.glsl")); - ShaderObject* gridfs = new ShaderObject(ShaderObject::ShaderTypeFragment, - absPath("${SHADERS}/grid_fs.glsl")); - _gridProgram->attachObject(gridvs); - _gridProgram->attachObject(gridfs); - _gridProgram->compileShaderObjects(); - _gridProgram->linkProgramObject(); - - - // STAR HALO RENDERING - ProgramObject* _starProgram = new ProgramObject("StarProgram"); - ShaderObject* starvs = new ShaderObject(ShaderObject::ShaderTypeVertex, - absPath("${SHADERS}/star_vs.glsl")); - ShaderObject* starge = new ShaderObject(ShaderObject::ShaderTypeGeometry, - absPath("${SHADERS}/star_ge.glsl")); - ShaderObject* starfs = new ShaderObject(ShaderObject::ShaderTypeFragment, - absPath("${SHADERS}/star_fs.glsl")); - _starProgram->attachObject(starvs); - _starProgram->attachObject(starge); - _starProgram->attachObject(starfs); - _starProgram->compileShaderObjects(); - _starProgram->linkProgramObject(); - - // STAR POINT RENDERING - ProgramObject* _pointProgram = new ProgramObject("PointProgram"); - ShaderObject* starvs_point = new ShaderObject(ShaderObject::ShaderTypeVertex, - absPath("${SHADERS}/star_vs_points.glsl")); - ShaderObject* starge_point = new ShaderObject(ShaderObject::ShaderTypeGeometry, - absPath("${SHADERS}/star_ge_points.glsl")); - ShaderObject* starfs_point = new ShaderObject(ShaderObject::ShaderTypeFragment, - absPath("${SHADERS}/star_fs_points.glsl")); - - _pointProgram->attachObject(starvs_point); - _pointProgram->attachObject(starge_point); - _pointProgram->attachObject(starfs_point); - _pointProgram->compileShaderObjects(); - _pointProgram->linkProgramObject(); - - ProgramObject* _fboProgram = new ProgramObject("RaycastProgram"); - ShaderObject* vertexShader = new ShaderObject(ShaderObject::ShaderTypeVertex, - absPath("${SHADERS}/exitpoints.vert")); - ShaderObject* fragmentShader = new ShaderObject(ShaderObject::ShaderTypeFragment, - absPath("${SHADERS}/exitpoints.frag")); - _fboProgram->attachObject(vertexShader); - _fboProgram->attachObject(fragmentShader); - _fboProgram->compileShaderObjects(); - _fboProgram->linkProgramObject(); - - ProgramObject* _twopassProgram = new ProgramObject("TwoPassProgram"); - vertexShader = new ShaderObject(ShaderObject::ShaderTypeVertex, - absPath("${SHADERS}/twopassraycaster.vert")); - fragmentShader = new ShaderObject(ShaderObject::ShaderTypeFragment, - absPath("${SHADERS}/twopassraycaster.frag")); - _twopassProgram->attachObject(vertexShader); - _twopassProgram->attachObject(fragmentShader); - _twopassProgram->compileShaderObjects(); - _twopassProgram->linkProgramObject(); - _twopassProgram->setUniform("texBack", 0); - _twopassProgram->setUniform("texFront", 1); - _twopassProgram->setUniform("texVolume", 2); - - ProgramObject* quad = new ProgramObject("Quad"); - ShaderObject* quadv = new ShaderObject(ShaderObject::ShaderTypeVertex, - absPath("${SHADERS}/quadVert.glsl")); - ShaderObject* quadf = new ShaderObject(ShaderObject::ShaderTypeFragment, - absPath("${SHADERS}/quadFrag.glsl")); - quad->attachObject(quadv); - quad->attachObject(quadf); - quad->compileShaderObjects(); - quad->linkProgramObject(); - quad->setUniform("quadTex", 0); - - OsEng.ref().configurationManager().setValue("RaycastProgram", _fboProgram); - OsEng.ref().configurationManager().setValue("TwoPassProgram", _twopassProgram); - OsEng.ref().configurationManager().setValue("Quad", quad); - OsEng.ref().configurationManager().setValue("PointProgram", _pointProgram); - OsEng.ref().configurationManager().setValue("StarProgram", _starProgram); - OsEng.ref().configurationManager().setValue("GridProgram", _gridProgram); - -======= - return po; - }; - // pscstandard - tmpProgram = programCreator("pscstandard", - "${SHADERS}/pscstandard_vs.glsl", - "${SHADERS}/pscstandard_fs.glsl"); - if( ! tmpProgram) return false; - OsEng.ref().configurationManager().setValue("pscShader", tmpProgram); - - // RaycastProgram - tmpProgram = programCreator("RaycastProgram", - "${SHADERS}/exitpoints.vert", - "${SHADERS}/exitpoints.frag"); - if( ! tmpProgram) return false; - OsEng.ref().configurationManager().setValue("RaycastProgram", tmpProgram); - - - // TwoPassProgram - tmpProgram = programCreator("TwoPassProgram", - "${SHADERS}/twopassraycaster.vert", - "${SHADERS}/twopassraycaster.frag"); - if( ! tmpProgram) return false; - tmpProgram->setUniform("texBack", 0); - tmpProgram->setUniform("texFront", 1); - tmpProgram->setUniform("texVolume", 2); - OsEng.ref().configurationManager().setValue("TwoPassProgram", tmpProgram); - - // Quad - tmpProgram = programCreator("Quad", - "${SHADERS}/quadVert.glsl", - "${SHADERS}/quadFrag.glsl"); - if( ! tmpProgram) return false; - tmpProgram->setUniform("quadTex", 0); - OsEng.ref().configurationManager().setValue("Quad", tmpProgram); - */ -//>>>>>>> develop return true; } @@ -402,6 +241,8 @@ void SceneGraph::update(const UpdateData& data) _sceneGraphToLoad = ""; if (!success) return; + + OsEng.renderEngine().abuffer()->invalidateABuffer(); } for (auto node : _nodes) @@ -534,8 +375,8 @@ bool SceneGraph::loadSceneInternal(const std::string& sceneDescriptionFilePath) // update the position of all nodes // TODO need to check this; unnecessary? (ab) - for (auto node : _nodes) - node->update({Time::ref().currentTime()}); + for (auto node : _nodes) + node->update({ Time::ref().currentTime() }); // Calculate the bounding sphere for the scenegraph _root->calculateBoundingSphere(); @@ -557,7 +398,7 @@ bool SceneGraph::loadSceneInternal(const std::string& sceneDescriptionFilePath) // TODO: Set scaling dependent on the position and distance // set position for camera const PowerScaledScalar bound = positionNode->calculateBoundingSphere(); - + // this part is full of magic! glm::vec2 boundf = bound.vec2(); glm::vec2 scaling{1.0f, -boundf[1]}; diff --git a/src/scenegraph/scenegraphnode.cpp b/src/scenegraph/scenegraphnode.cpp index 074b9d6003..841f102654 100644 --- a/src/scenegraph/scenegraphnode.cpp +++ b/src/scenegraph/scenegraphnode.cpp @@ -282,7 +282,8 @@ const std::vector& SceneGraphNode::children() const{ // bounding sphere PowerScaledScalar SceneGraphNode::calculateBoundingSphere(){ // set the bounding sphere to 0.0 - _boundingSphere = 1000.0; + _boundingSphere = 0.0; + //_boundingSphere = 1000.0; if (_children.size() > 0) { // node PowerScaledScalar maxChild; From e4a8e87098e6626687a5eef37a7e661bbebbf376 Mon Sep 17 00:00:00 2001 From: Jonas Strandstedt Date: Wed, 1 Oct 2014 15:30:39 +0200 Subject: [PATCH 17/23] Using new ghoul ProgramObject functionality - Fixed risk of memory leak in SceneGraph (deleting shaders) --- ext/ghoul | 2 +- include/openspace/engine/openspaceengine.h | 3 - include/openspace/scenegraph/scenegraph.h | 6 + include/openspace/util/shadercreator.h | 60 ------- shaders/ABuffer/abufferAddToBuffer.hglsl | 2 + src/abuffer/abuffer.cpp | 13 +- src/engine/openspaceengine.cpp | 18 -- src/rendering/renderablefieldlines.cpp | 3 +- src/scenegraph/scenegraph.cpp | 117 ++++++++----- src/util/shadercreator.cpp | 195 --------------------- 10 files changed, 89 insertions(+), 330 deletions(-) delete mode 100644 include/openspace/util/shadercreator.h delete mode 100644 src/util/shadercreator.cpp diff --git a/ext/ghoul b/ext/ghoul index 5a8a150468..44fec6ce6f 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 5a8a150468b2e0c8b31f7e3238c1c5abbd667799 +Subproject commit 44fec6ce6f9f214269c764f4a950dab8ccc127a4 diff --git a/include/openspace/engine/openspaceengine.h b/include/openspace/engine/openspaceengine.h index 50e3ee55a2..4973bb4606 100644 --- a/include/openspace/engine/openspaceengine.h +++ b/include/openspace/engine/openspaceengine.h @@ -45,7 +45,6 @@ // #define FLARE_ONLY #include -#include #define ABUFFER_SINGLE_LINKED 1 #define ABUFFER_FIXED 2 @@ -76,7 +75,6 @@ public: InteractionHandler& interactionHandler(); RenderEngine& renderEngine(); scripting::ScriptEngine& scriptEngine(); - ShaderCreator& shaderBuilder(); // SGCT callbacks bool initializeGL(); @@ -116,7 +114,6 @@ private: ghoul::opencl::CLContext _context; sgct::SharedVector _synchronizationBuffer; - ShaderCreator _shaderBuilder; }; #define OsEng (openspace::OpenSpaceEngine::ref()) diff --git a/include/openspace/scenegraph/scenegraph.h b/include/openspace/scenegraph/scenegraph.h index 07544bbd99..869f375e5c 100644 --- a/include/openspace/scenegraph/scenegraph.h +++ b/include/openspace/scenegraph/scenegraph.h @@ -28,6 +28,8 @@ // std includes #include #include +#include +#include #include #include @@ -118,6 +120,10 @@ private: std::map _allNodes; std::string _sceneGraphToLoad; + + std::mutex _programUpdateLock; + std::set _programsToUpdate; + std::vector _programs; }; } // namespace openspace diff --git a/include/openspace/util/shadercreator.h b/include/openspace/util/shadercreator.h deleted file mode 100644 index 61ddecf338..0000000000 --- a/include/openspace/util/shadercreator.h +++ /dev/null @@ -1,60 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014 * - * * - * 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 __SHADERCREATOR_H__ -#define __SHADERCREATOR_H__ - - -#include - -#include - -namespace openspace { -class ShaderCreator { - -public: - ShaderCreator(); - ~ShaderCreator(); - - void createSourceFile(bool b); - void sourceFileExtension(const std::string& extension); - void sourceFileHeader(const std::string& header); - - ghoul::opengl::ProgramObject* buildShader(const std::string& name, const std::string& vpath, const std::string& fpath, const std::string& gpath = ""); - -private: - - void _generateSource(const std::string& filename); - std::string _loadSource(const std::string& filename, unsigned int depth = 0); - std::string _generateFilename(const std::string& filename); - - bool _createSourceFile; - std::string _sourceFileExtension; - std::string _sourceFileHeader; - unsigned int _maxDepth; - -}; -} - -#endif \ No newline at end of file diff --git a/shaders/ABuffer/abufferAddToBuffer.hglsl b/shaders/ABuffer/abufferAddToBuffer.hglsl index 92248796c0..b819de22e7 100644 --- a/shaders/ABuffer/abufferAddToBuffer.hglsl +++ b/shaders/ABuffer/abufferAddToBuffer.hglsl @@ -22,6 +22,8 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ +#include <${SHADERS}/ABuffer/constants.hglsl> + #if ABUFFER_IMPLEMENTATION == ABUFFER_SINGLE_LINKED layout (binding = 0, r32ui) uniform uimage2D anchorPointerTexture; layout (binding = 1, rgba32ui) uniform uimageBuffer fragmentTexture; diff --git a/src/abuffer/abuffer.cpp b/src/abuffer/abuffer.cpp index 925de91b82..97d06b4a95 100644 --- a/src/abuffer/abuffer.cpp +++ b/src/abuffer/abuffer.cpp @@ -89,8 +89,9 @@ bool ABuffer::initializeABuffer() { addFunc("${SHADERS}/ABuffer/abufferSort.hglsl"); addFunc("${SHADERS}/ABuffer/abufferAddToBuffer.hglsl"); addFunc("${SHADERS}/ABuffer/abufferStruct.hglsl"); - addFunc("${SHADERS}/PowerScaling/powerScaling_fs.hglsl"); - addFunc("${SHADERS}/PowerScaling/powerScaling_vs.hglsl"); + addFunc("${SHADERS}/PowerScaling/powerScaling_fs.hglsl"); + addFunc("${SHADERS}/PowerScaling/powerScaling_vs.hglsl"); + addFunc("${SHADERS}/PowerScaling/powerScalingMath.hglsl"); // ============================ // GEOMETRY (quad) @@ -182,9 +183,11 @@ bool ABuffer::updateShader() { using ghoul::opengl::ShaderObject; using ghoul::opengl::ProgramObject; - ShaderCreator sc = OsEng.shaderBuilder(); - ghoul::opengl::ProgramObject* resolveShader = sc.buildShader("ABuffer resolve", absPath("${SHADERS}/ABuffer/abufferResolveVertex.glsl"), _fragmentShaderPath); - if( ! resolveShader) { + ProgramObject* resolveShader = ProgramObject::Build("ABuffer resolve", + "${SHADERS}/ABuffer/abufferResolveVertex.glsl", + _fragmentShaderPath); + + if( ! resolveShader) { LERROR("Resolve shader not updated"); return false; } diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 6dca374ecc..36e0d1c53a 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -221,17 +221,6 @@ bool OpenSpaceEngine::initialize() //int samples = sqrt(sgct::Engine::instance()->getActiveWindowPtr()->getNumberOfAASamples()); //LDEBUG("samples: " << samples); - int x1, xSize, y1, ySize; - sgct::Engine::instance()->getActiveWindowPtr()->getCurrentViewportPixelCoords(x1, y1, xSize, ySize); - std::string sourceHeader = ""; - sourceHeader += "#define SCREEN_WIDTH " + std::to_string(xSize) + "\n"; - sourceHeader += "#define SCREEN_HEIGHT " + std::to_string(ySize) + "\n"; - sourceHeader += "#define ABUFFER_SINGLE_LINKED " + std::to_string(ABUFFER_SINGLE_LINKED) + "\n"; - sourceHeader += "#define ABUFFER_FIXED " + std::to_string(ABUFFER_FIXED) + "\n"; - sourceHeader += "#define ABUFFER_DYNAMIC " + std::to_string(ABUFFER_DYNAMIC) + "\n"; - sourceHeader += "#define ABUFFER_IMPLEMENTATION " + std::to_string(ABUFFER_IMPLEMENTATION) + "\n"; - _shaderBuilder.createSourceFile(true); - _shaderBuilder.sourceFileHeader(sourceHeader); // Register the filepaths from static function enables easy testing // registerFilePaths(); @@ -357,13 +346,6 @@ ScriptEngine& OpenSpaceEngine::scriptEngine() return _scriptEngine; } - -ShaderCreator& OpenSpaceEngine::shaderBuilder() -{ - // TODO custom assert (ticket #5) - return _shaderBuilder; -} - bool OpenSpaceEngine::initializeGL() { return _renderEngine.initializeGL(); diff --git a/src/rendering/renderablefieldlines.cpp b/src/rendering/renderablefieldlines.cpp index 2c950aa753..7301266bf1 100644 --- a/src/rendering/renderablefieldlines.cpp +++ b/src/rendering/renderablefieldlines.cpp @@ -114,8 +114,7 @@ RenderableFieldlines::RenderableFieldlines(const ghoul::Dictionary& dictionary) _fragmentSourceFile = new ghoul::filesystem::File(fshaderpath, false); - ShaderCreator sc = OsEng.shaderBuilder(); - _fieldlinesProgram = sc.buildShader("FieldlinesProgram", vshaderpath, fshaderpath); + _fieldlinesProgram = ghoul::opengl::ProgramObject::Build("FieldlinesProgram", vshaderpath, fshaderpath); dictionary.getValue("UpdateOnSave", _programUpdateOnSave); diff --git a/src/scenegraph/scenegraph.cpp b/src/scenegraph/scenegraph.cpp index 779c35486f..bc2913ebc7 100644 --- a/src/scenegraph/scenegraph.cpp +++ b/src/scenegraph/scenegraph.cpp @@ -29,7 +29,6 @@ #include #include #include -#include #include #include @@ -47,6 +46,7 @@ #include #include +#include #include #include @@ -149,87 +149,105 @@ SceneGraph::~SceneGraph() bool SceneGraph::initialize() { LDEBUG("Initializing SceneGraph"); - - LDEBUG("Creating ProgramObjects"); + using ghoul::opengl::ShaderObject; using ghoul::opengl::ProgramObject; - ShaderCreator sc = OsEng.shaderBuilder(); ProgramObject* tmpProgram; - typedef std::chrono::high_resolution_clock clock_; - typedef std::chrono::duration > second_; + int x1, xSize, y1, ySize; + sgct::Engine::instance()-> + getActiveWindowPtr()-> + getCurrentViewportPixelCoords(x1, y1, xSize, ySize); - std::chrono::time_point beginning(clock_::now()); + // TODO: Make this file creation dynamic and better in every way + // TODO: If the screen size changes it is enough if this file is regenerated to + // recompile all necessary files + std::ofstream os(absPath("${SHADERS}/ABuffer/constants.hglsl")); + os << "#define SCREEN_WIDTH " << xSize << "\n" + << "#define SCREEN_HEIGHT " << ySize << "\n" + << "#define ABUFFER_SINGLE_LINKED 1\n" + << "#define ABUFFER_FIXED 2\n" + << "#define ABUFFER_DYNAMIC 3\n" + << "#define ABUFFER_IMPLEMENTATION 1\n"; + os.close(); - // pscstandard - tmpProgram = sc.buildShader("pscstandard", - "${SHADERS}/pscstandard_vs.glsl", - "${SHADERS}/pscstandard_fs.glsl"); + // TODO: Figure out why the callback is called twice + ghoul::opengl::ProgramObject::ProgramObjectCallback cb = [this](ghoul::opengl::ProgramObject* program) { + _programUpdateLock.lock(); + _programsToUpdate.insert(program); + _programUpdateLock.unlock(); + }; + + // Start Timing for building SceneGraph shaders + typedef std::chrono::high_resolution_clock clock_; + typedef std::chrono::duration > second_; + std::chrono::time_point beginning(clock_::now()); + + // pscstandard + tmpProgram = ProgramObject::Build("pscstandard", + "${SHADERS}/pscstandard_vs.glsl", + "${SHADERS}/pscstandard_fs.glsl", + cb); if( ! tmpProgram) return false; + _programs.push_back(tmpProgram); OsEng.ref().configurationManager().setValue("pscShader", tmpProgram); // RaycastProgram - tmpProgram = sc.buildShader("RaycastProgram", - "${SHADERS}/exitpoints.vert", - "${SHADERS}/exitpoints.frag"); - if( ! tmpProgram) return false; + tmpProgram = ProgramObject::Build("RaycastProgram", + "${SHADERS}/exitpoints.vert", + "${SHADERS}/exitpoints.frag", + cb); + if (!tmpProgram) return false; + _programs.push_back(tmpProgram); OsEng.ref().configurationManager().setValue("RaycastProgram", tmpProgram); - - // // TwoPassProgram - // tmpProgram = sc.buildShader("TwoPassProgram", - // "${SHADERS}/twopassraycaster.vert", - // "${SHADERS}/twopassraycaster.frag"); - // if( ! tmpProgram) return false; - // tmpProgram->setUniform("texBack", 0); - // tmpProgram->setUniform("texFront", 1); - // tmpProgram->setUniform("texVolume", 2); - // OsEng.ref().configurationManager().setValue("TwoPassProgram", tmpProgram); - - // Quad - tmpProgram = sc.buildShader("Quad", - "${SHADERS}/quadVert.glsl", - "${SHADERS}/quadFrag.glsl"); - if (!tmpProgram) return false; - tmpProgram->setUniform("quadTex", 0); - OsEng.ref().configurationManager().setValue("Quad", tmpProgram); - // Star program - tmpProgram = sc.buildShader("Star", + tmpProgram = ProgramObject::Build("Star", "${SHADERS}/star_vs.glsl", "${SHADERS}/star_fs.glsl", - "${SHADERS}/star_ge.glsl"); + "${SHADERS}/star_ge.glsl", + cb); if (!tmpProgram) return false; + _programs.push_back(tmpProgram); OsEng.ref().configurationManager().setValue("StarProgram", tmpProgram); // Point program - tmpProgram = sc.buildShader("Point", + tmpProgram = ProgramObject::Build("Point", "${SHADERS}/star_vs.glsl", "${SHADERS}/star_fs.glsl", - "${SHADERS}/star_ge.glsl"); + "${SHADERS}/star_ge.glsl", + cb); if (!tmpProgram) return false; + _programs.push_back(tmpProgram); OsEng.ref().configurationManager().setValue("PointProgram", tmpProgram); // Grid program - tmpProgram = sc.buildShader("Grid", + tmpProgram = ProgramObject::Build("Grid", "${SHADERS}/grid_vs.glsl", - "${SHADERS}/grid_fs.glsl"); + "${SHADERS}/grid_fs.glsl", + cb); if (!tmpProgram) return false; + _programs.push_back(tmpProgram); OsEng.ref().configurationManager().setValue("GridProgram", tmpProgram); - - + // Done building shaders double elapsed = std::chrono::duration_cast(clock_::now()-beginning).count(); LINFO("Time to load shaders: " << elapsed); - return true; } bool SceneGraph::deinitialize() { clearSceneGraph(); + + // clean up all programs + _programsToUpdate.clear(); + for (auto program : _programs) { + delete program; + } + _programs.clear(); return true; } @@ -257,6 +275,13 @@ void SceneGraph::evaluate(Camera* camera) void SceneGraph::render(const RenderData& data) { + _programUpdateLock.lock(); + for (auto program : _programsToUpdate) { + LDEBUG("Attempting to recompile " << program->name()); + program->rebuildFromFile(); + } + _programsToUpdate.erase(_programsToUpdate.begin(), _programsToUpdate.end()); + _programUpdateLock.unlock(); if (_root) _root->render(data); } @@ -474,7 +499,8 @@ SceneGraphNode* SceneGraph::sceneGraphNode(const std::string& name) const { } scripting::ScriptEngine::LuaLibrary SceneGraph::luaLibrary() { - scripting::ScriptEngine::LuaLibrary sceneGraphLibrary = { + //scripting::ScriptEngine::LuaLibrary sceneGraphLibrary = { + return { "", { { @@ -498,8 +524,7 @@ scripting::ScriptEngine::LuaLibrary SceneGraph::luaLibrary() { } } }; - - return std::move(sceneGraphLibrary); + //return std::move(sceneGraphLibrary); } } // namespace openspace diff --git a/src/util/shadercreator.cpp b/src/util/shadercreator.cpp deleted file mode 100644 index aaec11b539..0000000000 --- a/src/util/shadercreator.cpp +++ /dev/null @@ -1,195 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014 * - * * - * 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 - -#include -#include -#include -// #include -// #include - -using ghoul::opengl::ProgramObject; -using ghoul::opengl::ShaderObject; - -namespace { - const std::string _loggerCat = "ShaderCreator"; - const std::string defaultSourceFileExtension = "OpenSpaceGenerated.glsl"; - const std::string separator = "//=====================================================================\n"; - const ShaderObject::ShaderType vsType = ShaderObject::ShaderType::ShaderTypeVertex; - const ShaderObject::ShaderType fsType = ShaderObject::ShaderType::ShaderTypeFragment; - const ShaderObject::ShaderType gsType = ShaderObject::ShaderType::ShaderTypeGeometry; -} - -namespace openspace { -ShaderCreator::ShaderCreator(): - _createSourceFile(false), - _sourceFileExtension(defaultSourceFileExtension), - _sourceFileHeader(""), - _maxDepth(2) -{ - -} - -ShaderCreator::~ShaderCreator() { - -} - -void ShaderCreator::createSourceFile(bool b) { - _createSourceFile = b; -} - -void ShaderCreator::sourceFileExtension(const std::string& extension) { - if(extension != "") { - _sourceFileExtension = extension; - } -} - -void ShaderCreator::sourceFileHeader(const std::string& header) { - _sourceFileHeader = header; -} - -ghoul::opengl::ProgramObject* ShaderCreator::buildShader( - const std::string& name, const std::string& vpath, const std::string& fpath, const std::string& gpath) -{ - std::string vsPath = absPath(vpath); - std::string fsPath = absPath(fpath); - std::string gsPath = absPath(gpath); - - if( ! FileSys.fileExists(vsPath)) - return nullptr; - if( ! FileSys.fileExists(fsPath)) - return nullptr; - if (gsPath != "" && !FileSys.fileExists(gsPath)) - return nullptr; - - if(_createSourceFile) { - _generateSource(vsPath); - _generateSource(fsPath); - - vsPath = _generateFilename(vsPath); - fsPath = _generateFilename(fsPath); - } - - ProgramObject* po = new ProgramObject(name); - ShaderObject* vs = new ShaderObject(vsType, vsPath, name + " Vertex"); - ShaderObject* fs = new ShaderObject(fsType, fsPath, name + " Fragment"); - po->attachObject(vs); - po->attachObject(fs); - - if (gsPath != "") { - _generateSource(gsPath); - gsPath = _generateFilename(gsPath); - ShaderObject* gs = new ShaderObject(gsType, gsPath, name + " Geometry"); - po->attachObject(gs); - } - - if ( po->compileShaderObjects() && po->linkProgramObject()) - return po; - - // unsuccessful compilation, cleanup and return nullptr - delete po; - po = nullptr; - return po; -} - -void ShaderCreator::_generateSource(const std::string& filename) { - std::string generatedSource = ""; - if(_sourceFileHeader != "") - generatedSource += separator + "// HEADER\n" + separator + _sourceFileHeader + "\n"; - generatedSource += _loadSource(filename); - - std::ofstream of(_generateFilename(filename)); - of << generatedSource; - of.close(); -} - -std::string ShaderCreator::_loadSource(const std::string& filename, unsigned int depth) { - std::string contents = "", line; - std::ifstream f(filename); - - // Pre-allocate memory so the return string doesn't have to resize too often - // f.seekg( 0, std::ios::end ); - // unsigned int fsize = f.tellg(); - // f.seekg( 0); - // contents.reserve(fsize*3); - // line.reserve(fsize*3); - - contents += "\n"; - contents += separator; - contents += "// Filename: " + filename + "\n"; - // contents += "// Size: " + std::to_string(fsize) + "\n"; - contents += separator; - if(depth > _maxDepth) { - contents += "// TOO DEEP"; - return contents; - } - - if( ! FileSys.fileExists(filename)){ - contents += "// FILE NOT FOUND\n"; - return contents; - } - - std::regex e1(R"(^\s*#include \"(.+)\"\s*)"); - std::regex e2(R"(^\s*#include <(.+)>\s*)"); - while(std::getline(f, line)) { - std::smatch m; - if(std::regex_search(line, m, e1)) { - using namespace ghoul::filesystem; - std::string includeFilename = m[1]; - File f(filename); - includeFilename = f.directoryName() + FileSystem::PathSeparator + includeFilename; - //includeFilename = filename.substr(0, filename.find_last_of("/")+1) + includeFilename; - line = _loadSource(includeFilename, depth + 1); - } else if(std::regex_search(line, m, e2)) { - std::string includeFilename = m[1]; - line = _loadSource(absPath(includeFilename), depth + 1); - } - - contents += line + "\n"; - } - f.close(); - - return contents; -} - -std::string ShaderCreator::_generateFilename(const std::string& filename) { - // If way of confirming and creating a directory this could be a good solution - // to avoid cluttering in folders - // if(_cacheFolder != "") { - // size_t delimiter = filename.find_last_of("/"); - // std::string file = filename.substr(delimiter+1, filename.length() - delimiter); - // std::string path = filename.substr(0, filename.find_last_of("/")); - - // return path + "/" + _cacheFolder + "/" + file + "." + _sourceFileExtension; - // } - - return filename + "." + _sourceFileExtension; -} - -} \ No newline at end of file From 3cad506b5bbebb7cd9c10c72e11a9831b1d617bf Mon Sep 17 00:00:00 2001 From: Jonas Strandstedt Date: Fri, 3 Oct 2014 17:02:31 +0200 Subject: [PATCH 18/23] PowerScaling modifications - Started working on PowerScaling with some initial changes - Faking the stars by blending with the abuffer - Changed texture filtering for planets, looks better in my opinion --- config/sgct/single.xml | 2 + ext/ghoul | 2 +- include/openspace/abuffer/abuffer.h | 2 + include/openspace/rendering/renderengine.h | 2 + shaders/ABuffer/abufferAddToBuffer.hglsl | 2 +- shaders/ABuffer/abufferResolveFragment.glsl | 9 +++ shaders/PowerScaling/powerScalingMath.hglsl | 15 ++++ shaders/PowerScaling/powerScaling_fs.hglsl | 7 +- shaders/PowerScaling/powerScaling_vs.hglsl | 19 +++-- shaders/exitpoints.frag | 4 +- shaders/exitpoints.vert | 9 +-- shaders/grid_fs.glsl | 89 +++++---------------- shaders/grid_vs.glsl | 69 +++------------- shaders/pscstandard_fs.glsl | 9 ++- shaders/pscstandard_vs.glsl | 15 ++-- shaders/star_fs.glsl | 18 +++-- shaders/star_ge.glsl | 5 +- shaders/star_vs.glsl | 80 ++---------------- src/abuffer/abuffer.cpp | 8 +- src/abuffer/abufferSingleLinked.cpp | 2 - src/abuffer/abufferdynamic.cpp | 2 - src/abuffer/abufferfixed.cpp | 2 - src/interaction/interactionhandler.cpp | 11 +++ src/rendering/planets/renderableplanet.cpp | 11 +-- src/rendering/renderablesphericalgrid.cpp | 17 +--- src/rendering/renderengine.cpp | 28 +++++++ src/rendering/stars/renderablestars.cpp | 7 +- src/scenegraph/scenegraph.cpp | 30 +++---- 28 files changed, 183 insertions(+), 293 deletions(-) diff --git a/config/sgct/single.xml b/config/sgct/single.xml index 6db1d5faca..76ce8cb4d0 100644 --- a/config/sgct/single.xml +++ b/config/sgct/single.xml @@ -5,6 +5,8 @@ + + diff --git a/ext/ghoul b/ext/ghoul index 44fec6ce6f..7431cfdf88 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 44fec6ce6f9f214269c764f4a950dab8ccc127a4 +Subproject commit 7431cfdf88483dab8498306938b8a4e9c182d7cc diff --git a/include/openspace/abuffer/abuffer.h b/include/openspace/abuffer/abuffer.h index 0323f77f76..8ee0cf253d 100644 --- a/include/openspace/abuffer/abuffer.h +++ b/include/openspace/abuffer/abuffer.h @@ -44,6 +44,8 @@ namespace openspace { class ABuffer: public ABuffer_I { public: + static const int MAX_LAYERS = 32; + ABuffer(); virtual ~ABuffer(); virtual void resolve(); diff --git a/include/openspace/rendering/renderengine.h b/include/openspace/rendering/renderengine.h index 6ae5056338..908b9e117e 100644 --- a/include/openspace/rendering/renderengine.h +++ b/include/openspace/rendering/renderengine.h @@ -62,6 +62,8 @@ private: Camera* _mainCamera; SceneGraph* _sceneGraph; ABuffer* _abuffer; + + void generateGlslConfig(); }; } // namespace openspace diff --git a/shaders/ABuffer/abufferAddToBuffer.hglsl b/shaders/ABuffer/abufferAddToBuffer.hglsl index b819de22e7..f930813941 100644 --- a/shaders/ABuffer/abufferAddToBuffer.hglsl +++ b/shaders/ABuffer/abufferAddToBuffer.hglsl @@ -34,7 +34,7 @@ layout (binding = 0, offset = 0) uniform atomic_uint atomicCounterBuffer; layout (binding = 0, r32ui) uniform uimage2D anchorPointerTexture; layout (binding = 1, rgba32ui) uniform uimageBuffer fragmentTexture; - #define _MAX_LAYERS_ 16 + #define _MAX_LAYERS_ 64 #define _SCREEN_WIDTH_ 1280 #define _SCREEN_HEIGHT_ 720 #endif diff --git a/shaders/ABuffer/abufferResolveFragment.glsl b/shaders/ABuffer/abufferResolveFragment.glsl index c4c441dc5b..3c9abf186b 100644 --- a/shaders/ABuffer/abufferResolveFragment.glsl +++ b/shaders/ABuffer/abufferResolveFragment.glsl @@ -35,7 +35,11 @@ #define ZTYPE ZDEPTH // Maximum number of fragments +#ifdef MAX_LAYERS +#define MAX_FRAGMENTS MAX_LAYERS +#else #define MAX_FRAGMENTS 16 // The size of the local fragment list +#endif // #define VISUALIZE_TRANSFERFUNCTIONS // #define USE_JITTERING // // #define USE_COLORNORMALIZATION // @@ -269,6 +273,11 @@ vec4 calculate_final_color(uint frag_count) { // final_color = vec4(1.0,1.0,1.0,1.0); // } + // if(frag_count > 12) { + // final_color = vec4(1.0,0.0,1.0,1.0); + // } + + #ifdef USE_COLORNORMALIZATION final_color.rgb = final_color.rgb * final_color.a; final_color.a = 1.0; diff --git a/shaders/PowerScaling/powerScalingMath.hglsl b/shaders/PowerScaling/powerScalingMath.hglsl index 521331526b..d820328fcc 100644 --- a/shaders/PowerScaling/powerScalingMath.hglsl +++ b/shaders/PowerScaling/powerScalingMath.hglsl @@ -26,6 +26,7 @@ #define POWERSCALING_MATH_HGLSL const float k = 10.0; +const float FLT_MAX = 1e38; // Not max but large enough for the purpose vec4 psc_addition(vec4 v1, vec4 v2) { float ds = v2.w - v1.w; @@ -38,4 +39,18 @@ vec4 psc_addition(vec4 v1, vec4 v2) { } } +vec4 z_normalization(vec4 v_in) { + vec4 v_out = v_in; + if(v_out.z > 0.0) { + v_out.z = 1; + } else if(v_out.z < 0.0) { + v_out.z = 1; + } else { + float tmp = max(max(abs(v_out.x), abs(v_out.y)),0); + if(tmp == 0.0) + v_out.s = FLT_MAX; + } + return v_out; +} + #endif \ No newline at end of file diff --git a/shaders/PowerScaling/powerScaling_fs.hglsl b/shaders/PowerScaling/powerScaling_fs.hglsl index c227016f1d..9841ea5f28 100644 --- a/shaders/PowerScaling/powerScaling_fs.hglsl +++ b/shaders/PowerScaling/powerScaling_fs.hglsl @@ -28,10 +28,11 @@ // Observable universe is 10^27m, setting the far value to extremely high, aka 30!! ERMAHGERD! const float k = 10.0; + const float s_far = 27.0f; //= gl_DepthRange.far; // 40 const float s_farcutoff = 12.0f; const float s_nearcutoff = 7.00f; -const float s_near = 0.00f;// gl_DepthRange.near; // 0.1 +const float s_near = 1.00f;// gl_DepthRange.near; // 0.1 vec4 psc_normlization(vec4 invec) { @@ -56,7 +57,8 @@ float pscDepth(vec4 position) { } else { depth = position.w+log(abs(position.z)); } - + depth = (position.w+log(abs(position.z)))/pow(k, position.w); + // depth = (position.w+log(abs(position.z)))/pow(k, position.w); // DEBUG float depth_orig = depth; @@ -84,6 +86,7 @@ float pscDepth(vec4 position) { depth = (depth - s_near) / (s_far - s_near); } + // return 1.0; return depth; } diff --git a/shaders/PowerScaling/powerScaling_vs.hglsl b/shaders/PowerScaling/powerScaling_vs.hglsl index bf8a914dae..ce8d936289 100644 --- a/shaders/PowerScaling/powerScaling_vs.hglsl +++ b/shaders/PowerScaling/powerScaling_vs.hglsl @@ -46,20 +46,22 @@ vec4 psc_scaling(vec4 v1, vec2 v2) { } } -vec4 pscTransform(vec4 vertexPosition, mat4 modelTransform) { +vec4 pscTransform(inout vec4 vertexPosition, mat4 modelTransform) { vec3 local_vertex_pos = mat3(modelTransform) * vertexPosition.xyz; //vec4 lvp = ModelTransform * vertexPosition; // PSC addition; local vertex position and the object power scaled world position - vec4 position = psc_addition(vec4(local_vertex_pos,vertexPosition.w),objpos); + vertexPosition = psc_addition(vec4(local_vertex_pos,vertexPosition.w),objpos); //position = psc_addition(lvp,objpos); // PSC addition; rotated and viewscaled vertex and the cmaeras negative position - position = psc_addition(position,vec4(-campos.xyz,campos.w)); + vertexPosition = psc_addition(vertexPosition,vec4(-campos.xyz,campos.w)); // rotate the camera - local_vertex_pos = mat3(camrot) * position.xyz; - position = vec4(local_vertex_pos, position.w); + vertexPosition.xyz = mat3(camrot) * vertexPosition.xyz; + vec4 tmp = vertexPosition; + vertexPosition = psc_scaling(vertexPosition, scaling); + //position = vec4(local_vertex_pos, position.w); //position = camrot* position; // rescales the scene to fit inside the view frustum @@ -68,7 +70,12 @@ vec4 pscTransform(vec4 vertexPosition, mat4 modelTransform) { // project using the rescaled coordinates, //vec4 vs_position_rescaled = psc_scaling(position, scaling); - return psc_to_meter(position, scaling); + tmp = psc_to_meter(tmp, scaling); + + // tmp.z *= 2.0; + + // return vertexPosition; + return tmp; } #endif \ No newline at end of file diff --git a/shaders/exitpoints.frag b/shaders/exitpoints.frag index 71dac97245..afaf281515 100644 --- a/shaders/exitpoints.frag +++ b/shaders/exitpoints.frag @@ -27,7 +27,7 @@ uniform int volumeType; in vec3 vPosition; -in vec3 worldPosition; +in vec4 worldPosition; in float s; #include "ABuffer/abufferStruct.hglsl" @@ -36,7 +36,7 @@ in float s; void main() { vec4 fragColor = vec4(vPosition+0.5, 1.0); - vec4 position = vec4(worldPosition,s); + vec4 position = worldPosition; float depth = pscDepth(position); gl_FragDepth = depth; diff --git a/shaders/exitpoints.vert b/shaders/exitpoints.vert index a82bcd1a16..6f43c22681 100644 --- a/shaders/exitpoints.vert +++ b/shaders/exitpoints.vert @@ -30,7 +30,7 @@ uniform mat4 modelViewProjection; uniform mat4 modelTransform; out vec3 vPosition; -out vec3 worldPosition; +out vec4 worldPosition; out float s; #include "PowerScaling/powerScaling_vs.hglsl" @@ -41,16 +41,15 @@ void main() { //vs_stp = in_position.xyz; vPosition = vertPosition.xyz; + worldPosition = vertPosition; // this is wrong for the normal. The normal transform is the transposed inverse of the model transform //vs_normal = normalize(modelTransform * vec4(in_normal,0)); - vec4 position = pscTransform(vertPosition, modelTransform); - worldPosition = position.xyz; - s = position.w; + vec4 position = pscTransform(worldPosition, modelTransform); // project the position to view space - gl_Position = modelViewProjection * position; + gl_Position = z_normalization(modelViewProjection * position); // vPosition = vertPosition.xyz; // worldPosition = (modelTransform *vec4(vPosition, 1.0)).xyz; diff --git a/shaders/grid_fs.glsl b/shaders/grid_fs.glsl index 43a9309765..b4281b0ae8 100644 --- a/shaders/grid_fs.glsl +++ b/shaders/grid_fs.glsl @@ -7,12 +7,10 @@ The above copyright notice and this permission notice shall be included in all c 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. */ -#version 400 core +#version 430 core uniform mat4 ViewProjection; uniform mat4 ModelTransform; -uniform vec4 campos; -uniform vec4 objpos; uniform vec4 gridColor; in vec2 vs_st; @@ -20,80 +18,17 @@ in vec2 vs_st; in vec4 vs_normal; in vec4 vs_position; -out vec4 diffuse; -const float k = 10.0; - -vec4 psc_normlization(vec4 invec) { - - float xymax = max(invec.x,invec.y); - - if(invec.z > 0.0f || invec.z < 0.0f) { - return invec / abs(invec.z); - } else if (xymax != 0.0f) { - return invec / xymax; - } else { - return invec / -.0; - } -} +#include "ABuffer/abufferStruct.hglsl" +#include "ABuffer/abufferAddToBuffer.hglsl" +#include "PowerScaling/powerScaling_fs.hglsl" +// out vec4 diffuse; void main() { - - // Observable universe is 10^27m, setting the far value to extremely high, aka 30!! ERMAHGERD! - float s_far = 40.0; //= gl_DepthRange.far; // 40 - float s_farcutoff = 12.0; - float s_nearcutoff = 7.0; - float s_near = 0.0f;// gl_DepthRange.near; // 0.1 - float depth; - - // the value can be normalized to 1 - - vec4 p = vs_position; - if(vs_position.w <= 0.5) { - //depth = abs(vs_position.z * pow(10, vs_position.w)) / pow(k,s_far); - depth = (vs_position.w+log(abs(vs_position.z)))/pow(k, vs_position.w); - } else if(vs_position.w < 3.0) { - depth = vs_position.w+log(abs(vs_position.z))/pow(k, vs_position.w); - } else { - depth = vs_position.w+log(abs(vs_position.z)); - } - - - // DEBUG - float depth_orig = depth; - float x = 0.0f; - float cutoffs = 0.0; - float orig_z = vs_position.z; - - // calculate a normalized depth [0.0 1.0] - if((depth > s_near && depth <= s_nearcutoff) || (depth > s_farcutoff && depth < s_far)) { - - // completely linear interpolation [s_near .. depth .. s_far] - depth = (depth - s_near) / (s_far - s_near); - - } else if(depth > s_nearcutoff && depth < s_farcutoff) { - - // DEBUG - cutoffs = 1.0; - - // interpolate [10^s_nearcutoff .. 10^depth .. 10^s_farcutoff] - // calculate between 0..1 where the depth is - x = (pow(10,depth) - pow(10, s_nearcutoff)) / (pow(10,s_farcutoff) - pow(10, s_nearcutoff)); - - // remap the depth to the 0..1 depth buffer - depth = s_nearcutoff + x * (s_farcutoff - s_nearcutoff); - depth = (depth - s_near) / (s_far - s_near); - - } else { - // where am I? - // do I need to be discarded? - // discard; - } - // set the depth - gl_FragDepth = depth; + //gl_FragDepth = depth; //gl_FragDepth = 0.5; // color @@ -105,11 +40,23 @@ void main() //diffuse = vec4(depth*5,0.0, 0.0, 1.0); //diffuse = vec4(vs_position.w,0.0, 0.0, 1.0); + vec4 diffuse = vec4(1,0,0,1); if( floor(vs_st[0]) == -2){ diffuse = gridColor*2.f; }else{ diffuse = gridColor; } + diffuse = gridColor; + + + vec4 position = vs_position; + float depth = pscDepth(position); + // gl_FragDepth = depth; + + //ABufferStruct_t frag = createGeometryFragment(vec4(1,0,0,1), position, depth); + ABufferStruct_t frag = createGeometryFragment(diffuse, position, depth); + addToBuffer(frag); + discard; } \ No newline at end of file diff --git a/shaders/grid_vs.glsl b/shaders/grid_vs.glsl index c57f885f24..8844e98c82 100644 --- a/shaders/grid_vs.glsl +++ b/shaders/grid_vs.glsl @@ -19,14 +19,10 @@ 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. */ -#version 400 core +#version 430 core uniform mat4 ViewProjection; uniform mat4 ModelTransform; -uniform vec4 campos; -uniform mat4 camrot; -uniform vec2 scaling; -uniform vec4 objpos; uniform vec4 gridColor; layout(location = 0) in vec4 in_position; @@ -39,33 +35,7 @@ out vec3 vs_stp; out vec4 vs_normal; out vec4 vs_position; -const float k = 10.0; -const float dgr_to_rad = 0.0174532925; - -vec4 psc_addition(vec4 v1, vec4 v2) { - float ds = v2.w - v1.w; - if(ds >= 0) { - float p = pow(k,-ds); - return vec4(v1.x*p + v2.x, v1.y*p + v2.y, v1.z*p + v2.z, v2.w); - } else { - float p = pow(k,ds); - return vec4(v1.x + v2.x*p, v1.y + v2.y*p, v1.z + v2.z*p, v1.w); - } -} - -vec4 psc_to_meter(vec4 v1, vec2 v2) { - float factor = v2.x * pow(k,v2.y + v1.w); - return vec4(v1.xyz * factor, 1.0); -} - -vec4 psc_scaling(vec4 v1, vec2 v2) { - float ds = v2.y - v1.w; - if(ds >= 0) { - return vec4(v1.xyz * v2.x * pow(k,v1.w), v2.y); - } else { - return vec4(v1.xyz * v2.x * pow(k,v2.y), v1.w); - } -} +#include "PowerScaling/powerScaling_vs.hglsl" void main() { @@ -74,35 +44,14 @@ void main() //vs_stp = in_position.xyz; vs_normal = normalize(ModelTransform * vec4(in_normal,0)); - // fetch model and view translation - //vec4 vertex_translate = ModelTransform[3]; - // rotate and scale vertex with model transform and add the translation - vec3 local_vertex_pos = mat3(ModelTransform) * in_position.xyz; - //vec4 lvp = ModelTransform * in_position; + vec4 tmp = in_position; - // PSC addition; local vertex position and the object power scaled world position - vs_position = psc_addition(vec4(local_vertex_pos,in_position.w),objpos); - //vs_position = psc_addition(lvp,objpos); + // this is wrong for the normal. The normal transform is the transposed inverse of the model transform + vs_normal = normalize(ModelTransform * vec4(in_normal,0)); - // PSC addition; rotated and viewscaled vertex and the cmaeras negative position - vs_position = psc_addition(vs_position,vec4(-campos.xyz,campos.w)); - - // rotate the camera - local_vertex_pos = mat3(camrot) * vs_position.xyz; - vs_position = vec4(local_vertex_pos, vs_position.w); - //vs_position = camrot* vs_position; - - // rescales the scene to fit inside the view frustum - // is set from the main program, but these are decent values - // scaling = vec2(1.0, -8.0); - - // project using the rescaled coordinates, - //vec4 vs_position_rescaled = psc_scaling(vs_position, scaling); - vec4 vs_position_rescaled = psc_to_meter(vs_position, scaling); - //vs_position = vs_position_rescaled; - - - // project the position to view space - gl_Position = ViewProjection * vs_position_rescaled; + vec4 position = pscTransform(tmp, ModelTransform); + vs_position = tmp; + position = ViewProjection * position; + gl_Position = z_normalization(position); } \ No newline at end of file diff --git a/shaders/pscstandard_fs.glsl b/shaders/pscstandard_fs.glsl index 26a3d1987d..d9c7ef2354 100644 --- a/shaders/pscstandard_fs.glsl +++ b/shaders/pscstandard_fs.glsl @@ -29,8 +29,7 @@ uniform sampler2D texture1; in vec2 vs_st; in vec4 vs_normal; -in vec3 vs_position; -in float s; +in vec4 vs_position; #include "ABuffer/abufferStruct.hglsl" #include "ABuffer/abufferAddToBuffer.hglsl" @@ -38,10 +37,14 @@ in float s; void main() { - vec4 position = vec4(vs_position,s); + vec4 position = vs_position; float depth = pscDepth(position); vec4 diffuse = texture(texture1, vs_st); + // if(position.w > 9.0) { + // diffuse = vec4(1,0,0,1); + // } + ABufferStruct_t frag = createGeometryFragment(diffuse, position, depth); addToBuffer(frag); diff --git a/shaders/pscstandard_vs.glsl b/shaders/pscstandard_vs.glsl index d92ef70e32..0f2ca12ef2 100644 --- a/shaders/pscstandard_vs.glsl +++ b/shaders/pscstandard_vs.glsl @@ -33,9 +33,8 @@ layout(location = 1) in vec2 in_st; layout(location = 2) in vec3 in_normal; out vec2 vs_st; -out vec3 vs_stp; out vec4 vs_normal; -out vec3 vs_position; +out vec4 vs_position; out float s; #include "PowerScaling/powerScaling_vs.hglsl" @@ -45,14 +44,14 @@ void main() // set variables vs_st = in_st; //vs_stp = in_position.xyz; + vs_position = in_position; + vec4 tmp = in_position; // this is wrong for the normal. The normal transform is the transposed inverse of the model transform vs_normal = normalize(ModelTransform * vec4(in_normal,0)); - vec4 position = pscTransform(in_position, ModelTransform); - vs_position = position.xyz; - s = position.w; - - // project the position to view space - gl_Position = ViewProjection * position; + vec4 position = pscTransform(tmp, ModelTransform); + vs_position = tmp; + position = ViewProjection * position; + gl_Position = z_normalization(position); } \ No newline at end of file diff --git a/shaders/star_fs.glsl b/shaders/star_fs.glsl index a5da3344db..ac37322e84 100644 --- a/shaders/star_fs.glsl +++ b/shaders/star_fs.glsl @@ -8,7 +8,7 @@ in vec2 texCoord; layout(location = 2) in vec3 ge_brightness; -//out vec4 diffuse; +out vec4 diffuse; #include "ABuffer/abufferStruct.hglsl" @@ -48,20 +48,22 @@ void main(void) //glEnable(GL_BLEND); //glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE); vec4 color = bv2rgb(ge_brightness[0])/1.1; - //color.rgb = 1/ color.rgb; - color.a = 1-color.a; - vec4 diffuse = texture2D(texture1, texCoord)*color; + // color.rgb = 1/ color.rgb; + // color.a = 1-color.a; + diffuse = texture2D(texture1, texCoord)*color; - + //diffuse = vec4(1,1,0,1); ///diffuse = vec4(Color, 1.0); vec4 position = vs_position; float depth = pscDepth(position); + gl_FragDepth = depth; + gl_FragDepth = 10.0; //ABufferStruct_t frag = createGeometryFragment(vec4(1,0,0,1), position, depth); - ABufferStruct_t frag = createGeometryFragment(diffuse, position, depth); - addToBuffer(frag); + //ABufferStruct_t frag = createGeometryFragment(diffuse, position, depth); + //addToBuffer(frag); - discard; + //discard; } \ No newline at end of file diff --git a/shaders/star_ge.glsl b/shaders/star_ge.glsl index 75d9f9702a..361d9fb757 100644 --- a/shaders/star_ge.glsl +++ b/shaders/star_ge.glsl @@ -21,6 +21,7 @@ layout(location = 2) out vec3 ge_brightness[]; layout(triangle_strip, max_vertices = 4) out; out vec2 texCoord; +out vec4 vs_position; uniform mat4 projection; // we do this after distance computation. @@ -63,7 +64,9 @@ void main(){ for(int i = 0; i < 4; i++){ vec4 p1 = P; p1.xy += spriteSize *(corners[i] - vec2(0.5)); - gl_Position = projection * p1; // projection here + vs_position = p1; + gl_Position = projection * p1; + // gl_Position = z_normalization(projection * p1); // projection here texCoord = corners[i]; EmitVertex(); } diff --git a/shaders/star_vs.glsl b/shaders/star_vs.glsl index fd520faa15..0423f5548f 100644 --- a/shaders/star_vs.glsl +++ b/shaders/star_vs.glsl @@ -11,40 +11,10 @@ uniform sampler2D texture1; layout(location = 0) in vec4 in_position; layout(location = 2) in vec3 in_brightness; -out vec4 vs_position; out vec3 vs_brightness; out vec4 psc_position; out vec4 cam_position; -/* -const float k = 10.0; -const float dgr_to_rad = 0.0174532925; - -vec4 psc_addition(vec4 v1, vec4 v2) { - float ds = v2.w - v1.w; - if(ds >= 0) { - float p = pow(k,-ds); - return vec4(v1.x*p + v2.x, v1.y*p + v2.y, v1.z*p + v2.z, v2.w); - } else { - float p = pow(k,ds); - return vec4(v1.x + v2.x*p, v1.y + v2.y*p, v1.z + v2.z*p, v1.w); - } -} - -vec4 psc_to_meter(vec4 v1, vec2 v2) { - float factor = v2.x * pow(k,v2.y + v1.w); - return vec4(v1.xyz * factor, 1.0); -} - -vec4 psc_scaling(vec4 v1, vec2 v2) { - float ds = v2.y - v1.w; - if(ds >= 0) { - return vec4(v1.xyz * v2.x * pow(k,v1.w), v2.y); - } else { - return vec4(v1.xyz * v2.x * pow(k,v2.y), v1.w); - } -} -*/ #include "PowerScaling/powerScaling_vs.hglsl" @@ -52,51 +22,13 @@ void main(){ vs_brightness = in_brightness; psc_position = in_position; cam_position = campos; - /* - // rotate and scale vertex with model transform and add the translation - vec3 local_vertex_pos = mat3(ModelTransform) * in_position.xyz; - //vec4 lvp = ModelTransform * in_position; - - // PSC addition; local vertex position and the object power scaled world position - vs_position = psc_addition(vec4(local_vertex_pos,in_position.w),objpos); - //vs_position = psc_addition(lvp,objpos); - - // PSC addition; rotated and viewscaled vertex and the cmaeras negative position - vs_position = psc_addition(vs_position,vec4(-campos.xyz,campos.w)); - - // rotate the camera - local_vertex_pos = mat3(camrot) * vs_position.xyz; - vs_position = vec4(local_vertex_pos, vs_position.w); - //vs_position = camrot * vs_position; - - // project using the rescaled coordinates, - //vec4 vs_position_rescaled = psc_scaling(vs_position, scaling); - - //psc_position = vs_position; - - // individual scaling per point, needs fix. - //vec2 scaling = vec2(1.0, -in_position.w); - - vec4 vs_position_rescaled = psc_to_meter(vs_position, scaling); - //vs_position = vs_position_rescaled; - // project the position to view space - //gl_Position = ViewProjection * vs_position_rescaled; - gl_Position = view * model * vs_position_rescaled; - */ - /*psc_position = view * model * vs_position_rescaled; - gl_Position = psc_position; /// reduntant way but easier to go back. */ - - - - // this is wrong for the normal. The normal transform is the transposed inverse of the model transform - //vs_normal = normalize(modelTransform * vec4(in_normal,0)); - - vec4 position = pscTransform(in_position, ModelTransform); - - // project the position to view space - //gl_Position = ViewProjection * position; - gl_Position = view * model * position; + vec4 tmp = in_position; + vec4 position = pscTransform(tmp, ModelTransform); + // psc_position = tmp; + position = view * model * position; + // gl_Position = z_normalization(position); + gl_Position = position; } \ No newline at end of file diff --git a/src/abuffer/abuffer.cpp b/src/abuffer/abuffer.cpp index 97d06b4a95..74cd43521d 100644 --- a/src/abuffer/abuffer.cpp +++ b/src/abuffer/abuffer.cpp @@ -85,10 +85,12 @@ bool ABuffer::initializeABuffer() { ghoul::filesystem::File* f = new ghoul::filesystem::File(path, false); f->setCallback(shaderCallback); _shaderFiles.push_back(f); - }; - addFunc("${SHADERS}/ABuffer/abufferSort.hglsl"); + }; + addFunc("${SHADERS}/ABuffer/constants.hglsl"); + addFunc("${SHADERS}/ABuffer/abufferSort.hglsl"); addFunc("${SHADERS}/ABuffer/abufferAddToBuffer.hglsl"); - addFunc("${SHADERS}/ABuffer/abufferStruct.hglsl"); + addFunc("${SHADERS}/ABuffer/abufferStruct.hglsl"); + addFunc("${SHADERS}/PowerScaling/powerScaling_fs.hglsl"); addFunc("${SHADERS}/PowerScaling/powerScaling_fs.hglsl"); addFunc("${SHADERS}/PowerScaling/powerScaling_vs.hglsl"); addFunc("${SHADERS}/PowerScaling/powerScalingMath.hglsl"); diff --git a/src/abuffer/abufferSingleLinked.cpp b/src/abuffer/abufferSingleLinked.cpp index f1a09b3c2d..37d96745c1 100644 --- a/src/abuffer/abufferSingleLinked.cpp +++ b/src/abuffer/abufferSingleLinked.cpp @@ -32,8 +32,6 @@ #include #include -#define MAX_LAYERS 10 - namespace { std::string _loggerCat = "ABufferSingleLinked"; } diff --git a/src/abuffer/abufferdynamic.cpp b/src/abuffer/abufferdynamic.cpp index 8943905eda..3ec7051f8e 100644 --- a/src/abuffer/abufferdynamic.cpp +++ b/src/abuffer/abufferdynamic.cpp @@ -32,8 +32,6 @@ #include #include -#define MAX_LAYERS 10 - namespace { std::string _loggerCat = "ABufferDynamic"; } diff --git a/src/abuffer/abufferfixed.cpp b/src/abuffer/abufferfixed.cpp index 36c5a7aeae..4f1693a269 100644 --- a/src/abuffer/abufferfixed.cpp +++ b/src/abuffer/abufferfixed.cpp @@ -32,8 +32,6 @@ #include #include -#define MAX_LAYERS 32 - namespace { std::string _loggerCat = "ABufferFixed"; } diff --git a/src/interaction/interactionhandler.cpp b/src/interaction/interactionhandler.cpp index edeb51976d..a707c6c0e7 100644 --- a/src/interaction/interactionhandler.cpp +++ b/src/interaction/interactionhandler.cpp @@ -370,6 +370,17 @@ void InteractionHandler::keyboardCallback(int key, int action) { PowerScaledScalar dist(speed * 100.0 * dt, 6.0); distance(dist); } + + if (key == SGCT_KEY_KP_SUBTRACT) { + glm::vec2 s = OsEng.renderEngine().camera()->scaling(); + s[1] -= 0.5; + OsEng.renderEngine().camera()->setScaling(s); + } + if (key == SGCT_KEY_KP_ADD) { + glm::vec2 s = OsEng.renderEngine().camera()->scaling(); + s[1] += 0.5; + OsEng.renderEngine().camera()->setScaling(s); + } } /* if (key == '1') { diff --git a/src/rendering/planets/renderableplanet.cpp b/src/rendering/planets/renderableplanet.cpp index 0b574c8ffd..719565a768 100644 --- a/src/rendering/planets/renderableplanet.cpp +++ b/src/rendering/planets/renderableplanet.cpp @@ -123,12 +123,6 @@ void RenderablePlanet::render(const RenderData& data) // activate shader _programObject->activate(); - // fetch data - psc currentPosition = data.position; - psc campos = data.camera.position(); - glm::mat4 camrot = data.camera.viewRotationMatrix(); - // PowerScaledScalar scaling = camera->scaling(); - PowerScaledScalar scaling = glm::vec2(1, -6); // scale the planet to appropriate size since the planet is a unit sphere @@ -179,7 +173,10 @@ void RenderablePlanet::loadTexture() _texture = ghoul::opengl::loadTexture(absPath(_colorTexturePath)); if (_texture) { LDEBUG("Loaded texture from '" << absPath(_colorTexturePath) << "'"); - _texture->uploadTexture(); + _texture->uploadTexture(); + + // Textures of planets looks much smoother with AnisotropicMipMap rather than linear + _texture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); } } } diff --git a/src/rendering/renderablesphericalgrid.cpp b/src/rendering/renderablesphericalgrid.cpp index eaa4460274..2505edfbfd 100644 --- a/src/rendering/renderablesphericalgrid.cpp +++ b/src/rendering/renderablesphericalgrid.cpp @@ -185,22 +185,11 @@ void RenderableSphericalGrid::render(const RenderData& data){ assert(_gridProgram); _gridProgram->activate(); - // fetch data - psc currentPosition = data.position; - psc campos = data.camera.position(); - glm::mat4 camrot = data.camera.viewRotationMatrix(); - // PowerScaledScalar scaling = camera->scaling(); - PowerScaledScalar scaling = glm::vec2(1, -6); - - glm::mat4 transform = glm::mat4(1); - // setup the data to the shader + _gridProgram->setIgnoreUniformLocationError(true); _gridProgram->setUniform("ViewProjection", data.camera.viewProjectionMatrix()); - _gridProgram->setUniform("ModelTransform", transform); - _gridProgram->setUniform("campos", campos.vec4()); - _gridProgram->setUniform("objpos", currentPosition.vec4()); - _gridProgram->setUniform("camrot", camrot); - _gridProgram->setUniform("scaling", scaling.vec2()); + _gridProgram->setUniform("ModelTransform", glm::mat4(1)); + setPscUniforms(_gridProgram, &data.camera, data.position); _gridProgram->setUniform("gridColor", _gridColor); glLineWidth(1.0f); diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index c352f2dac9..e4a31036f7 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -37,6 +37,7 @@ #include #include +#include #include #include @@ -62,6 +63,8 @@ RenderEngine::~RenderEngine() bool RenderEngine::initialize() { + generateGlslConfig(); + // LDEBUG("RenderEngine::initialize()"); // init camera and set temporary position and scaling _mainCamera = new Camera(); @@ -161,6 +164,10 @@ bool RenderEngine::initializeGL() void RenderEngine::postSynchronizationPreDraw() { + sgct_core::SGCTNode * thisNode = sgct_core::ClusterManager::instance()->getThisNodePtr(); + for (unsigned int i = 0; i < thisNode->getNumberOfWindows(); i++) + if (sgct::Engine::instance()->getWindowPtr(i)->isWindowResized()) + generateGlslConfig(); // Move time forward. //_runtimeData->advanceTimeBy(1, DAY); @@ -463,4 +470,25 @@ ABuffer* RenderEngine::abuffer() const { return _abuffer; } +void RenderEngine::generateGlslConfig() { + LDEBUG("Generating GLSLS config, expect shader recompilation"); + int x1, xSize, y1, ySize; + sgct::Engine::instance()-> + getActiveWindowPtr()-> + getCurrentViewportPixelCoords(x1, y1, xSize, ySize); + + // TODO: Make this file creation dynamic and better in every way + // TODO: If the screen size changes it is enough if this file is regenerated to + // recompile all necessary files + std::ofstream os(absPath("${SHADERS}/ABuffer/constants.hglsl")); + os << "#define SCREEN_WIDTH " << xSize << "\n" + << "#define SCREEN_HEIGHT " << ySize << "\n" + << "#define MAX_LAYERS " << ABuffer::MAX_LAYERS << "\n" + << "#define ABUFFER_SINGLE_LINKED 1\n" + << "#define ABUFFER_FIXED 2\n" + << "#define ABUFFER_DYNAMIC 3\n" + << "#define ABUFFER_IMPLEMENTATION ABUFFER_SINGLE_LINKED\n"; + os.close(); +} + } // namespace openspace diff --git a/src/rendering/stars/renderablestars.cpp b/src/rendering/stars/renderablestars.cpp index 41e3eb230b..5e0d759044 100644 --- a/src/rendering/stars/renderablestars.cpp +++ b/src/rendering/stars/renderablestars.cpp @@ -322,9 +322,10 @@ void RenderableStars::render(const RenderData& data){ glm::vec3(0.0f, 1.0f, 0.0f)); #endif // disable depth test, enable additative blending - //glDisable(GL_DEPTH_TEST); - //glEnable(GL_BLEND); - //glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_BLEND); + glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE); + //glBlendFunc(GL_ONE, GL_ONE_MINUS_DST_COLOR); #ifdef GLSPRITES glm::mat4 modelMatrix = data.camera.modelMatrix(); diff --git a/src/scenegraph/scenegraph.cpp b/src/scenegraph/scenegraph.cpp index bc2913ebc7..3134041bd5 100644 --- a/src/scenegraph/scenegraph.cpp +++ b/src/scenegraph/scenegraph.cpp @@ -155,24 +155,6 @@ bool SceneGraph::initialize() ProgramObject* tmpProgram; - int x1, xSize, y1, ySize; - sgct::Engine::instance()-> - getActiveWindowPtr()-> - getCurrentViewportPixelCoords(x1, y1, xSize, ySize); - - // TODO: Make this file creation dynamic and better in every way - // TODO: If the screen size changes it is enough if this file is regenerated to - // recompile all necessary files - std::ofstream os(absPath("${SHADERS}/ABuffer/constants.hglsl")); - os << "#define SCREEN_WIDTH " << xSize << "\n" - << "#define SCREEN_HEIGHT " << ySize << "\n" - << "#define ABUFFER_SINGLE_LINKED 1\n" - << "#define ABUFFER_FIXED 2\n" - << "#define ABUFFER_DYNAMIC 3\n" - << "#define ABUFFER_IMPLEMENTATION 1\n"; - os.close(); - - // TODO: Figure out why the callback is called twice ghoul::opengl::ProgramObject::ProgramObjectCallback cb = [this](ghoul::opengl::ProgramObject* program) { _programUpdateLock.lock(); _programsToUpdate.insert(program); @@ -235,6 +217,7 @@ bool SceneGraph::initialize() double elapsed = std::chrono::duration_cast(clock_::now()-beginning).count(); LINFO("Time to load shaders: " << elapsed); + return true; } @@ -275,6 +258,8 @@ void SceneGraph::evaluate(Camera* camera) void SceneGraph::render(const RenderData& data) { + bool emptyProgramsToUpdate = _programsToUpdate.empty(); + _programUpdateLock.lock(); for (auto program : _programsToUpdate) { LDEBUG("Attempting to recompile " << program->name()); @@ -282,6 +267,15 @@ void SceneGraph::render(const RenderData& data) } _programsToUpdate.erase(_programsToUpdate.begin(), _programsToUpdate.end()); _programUpdateLock.unlock(); + + if (!emptyProgramsToUpdate) { + LDEBUG("Setting uniforms"); + // Ignore attribute locations + for (auto program : _programs) { + program->setIgnoreSubroutineUniformLocationError(true); + } + } + if (_root) _root->render(data); } From 795d02b9aa6020ec5df1576225e22f3deb9bc8f7 Mon Sep 17 00:00:00 2001 From: jonasstrandstedt Date: Fri, 3 Oct 2014 21:21:21 +0200 Subject: [PATCH 19/23] Fixed delete of unallocated memory --- src/main.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index ffad9cdfce..333b9d4d5f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -66,8 +66,6 @@ int main(int argc, char** argv) _sgctEngine = new sgct::Engine(newArgc, newArgv); // deallocate sgct c arguments - for (int i = 0; i < newArgc; ++i) - delete newArgv[i]; delete[] newArgv; // Bind functions From b7da50b3dddf27d93bfdf3c8dd502e14f555b4ca Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 5 Oct 2014 17:31:47 +0200 Subject: [PATCH 20/23] Added Lua method to print a screenshot --- include/openspace/rendering/renderengine.h | 12 ++++++++ src/engine/openspaceengine.cpp | 1 + src/rendering/renderengine.cpp | 35 +++++++++++++++++++++- 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/include/openspace/rendering/renderengine.h b/include/openspace/rendering/renderengine.h index 908b9e117e..8859f7a0c1 100644 --- a/include/openspace/rendering/renderengine.h +++ b/include/openspace/rendering/renderengine.h @@ -27,6 +27,8 @@ #include +#include + #include #include @@ -58,6 +60,16 @@ public: void serialize(std::vector& dataStream, size_t& offset); void deserialize(const std::vector& dataStream, size_t& offset); + /** + * Returns the Lua library that contains all Lua functions available to affect the + * rendering. The functions contained are + * - openspace::luascriptfunctions::printScreen + * \return The Lua library that contains all Lua functions available to affect the + * rendering + */ + static scripting::ScriptEngine::LuaLibrary luaLibrary(); + + private: Camera* _mainCamera; SceneGraph* _sceneGraph; diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 36e0d1c53a..72001b7977 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -262,6 +262,7 @@ bool OpenSpaceEngine::initialize() // Register Lua script functions LDEBUG("Registering Lua libraries"); + scriptEngine().addLibrary(RenderEngine::luaLibrary()); scriptEngine().addLibrary(SceneGraph::luaLibrary()); scriptEngine().addLibrary(Time::luaLibrary()); diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index e4a31036f7..5f851f141a 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -35,6 +35,7 @@ #include "sgct.h" #include +#include #include #include @@ -44,10 +45,28 @@ #include namespace { -const std::string _loggerCat = "RenderEngine"; + const std::string _loggerCat = "RenderEngine"; } + namespace openspace { +namespace luascriptfunctions { + +/** + * \ingroup LuaScripts + * printImage(): + * Save the rendering to an image file + */ +int printImage(lua_State* L) { + int nArguments = lua_gettop(L); + if (nArguments != 0) + return luaL_error(L, "Expected %i arguments, got %i", 0, nArguments); + sgct::Engine::instance()->takeScreenshot(); + return 0; +} + +} // namespace luascriptfunctions + RenderEngine::RenderEngine() : _mainCamera(nullptr) @@ -491,4 +510,18 @@ void RenderEngine::generateGlslConfig() { os.close(); } +scripting::ScriptEngine::LuaLibrary RenderEngine::luaLibrary() { + return { + "", + { + { + "printImage", + &luascriptfunctions::printImage, + "printImage(): Renders the current image to a file on disk" + } + } + }; + +} + } // namespace openspace From f7af8256dd19639e14fd85add71a3d1e401d8375 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 6 Oct 2014 01:33:56 +0200 Subject: [PATCH 21/23] Finished cleaning the SpiceManager --- ext/ghoul | 2 +- include/openspace/tests/test_spicemanager.inl | 169 ++---- include/openspace/util/spicemanager.h | 556 +++++++----------- src/rendering/planets/renderableplanet.cpp | 2 +- src/scenegraph/spiceephemeris.cpp | 2 +- src/util/spicemanager.cpp | 167 ++---- 6 files changed, 324 insertions(+), 574 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index 7431cfdf88..cec683e244 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 7431cfdf88483dab8498306938b8a4e9c182d7cc +Subproject commit cec683e244ab02a4454d07f7406a5c837a4a6f97 diff --git a/include/openspace/tests/test_spicemanager.inl b/include/openspace/tests/test_spicemanager.inl index e12173c3f4..ecf9187400 100644 --- a/include/openspace/tests/test_spicemanager.inl +++ b/include/openspace/tests/test_spicemanager.inl @@ -242,7 +242,7 @@ TEST_F(SpiceManagerTest, getTargetPosition){ glm::dvec3 targetPosition; double lightTime = 0.0; - bool found = openspace::SpiceManager::ref().getTargetPosition("EARTH", et, "J2000", "LT+S", "CASSINI", + bool found = openspace::SpiceManager::ref().getTargetPosition("EARTH", "CASSINI", "J2000", "LT+S", et, targetPosition, lightTime); ASSERT_TRUE(found); EXPECT_DOUBLE_EQ(pos[0], targetPosition[0]) << "Position not found or differs from expected return"; @@ -265,7 +265,7 @@ TEST_F(SpiceManagerTest, getTargetState){ glm::dvec3 targetPosition; glm::dvec3 targetVelocity; double lightTime = 0.0; - bool found = openspace::SpiceManager::ref().getTargetState("EARTH", et, "J2000", "LT+S", "CASSINI", + bool found = openspace::SpiceManager::ref().getTargetState("EARTH", "CASSINI", "J2000", "LT+S", et, targetPosition, targetVelocity, lightTime); ASSERT_TRUE(found); //x,y,z @@ -292,7 +292,7 @@ TEST_F(SpiceManagerTest, getStateTransformMatrix){ glm::dvec3 position(state[0], state[1], state[2]); glm::dvec3 velocity(state[3], state[4], state[5]); - openspace::transformMatrix stateMatrix(6); + openspace::SpiceManager::TransformMatrix stateMatrix; bool found = openspace::SpiceManager::ref().getStateTransformMatrix("J2000", "IAU_PHOEBE", et, @@ -301,12 +301,12 @@ TEST_F(SpiceManagerTest, getStateTransformMatrix){ //check for matrix consistency for (int i = 0; i < 6; i++){ for (int j = 0; j < 6; j++){ - EXPECT_DOUBLE_EQ(referenceMatrix[i][j], stateMatrix(i, j)) << "State-matrix not set or has wrong values"; + EXPECT_DOUBLE_EQ(referenceMatrix[i][j], stateMatrix[i * 6 + j]) << "State-matrix not set or has wrong values"; } } mxvg_c(referenceMatrix, state, 6, 6, state_t); - stateMatrix.transform(position, velocity); + openspace::SpiceManager::ref().applyTransformationMatrix(position, velocity, stateMatrix); for (int i = 0; i < 3; i++){ EXPECT_DOUBLE_EQ(position[i], state_t[i]) << "Position vector differs from its reference"; @@ -326,7 +326,7 @@ TEST_F(SpiceManagerTest, getPositionTransformMatrix){ str2et_c("2004 jun 11 19:32:00", &et); pxform_c("CASSINI_HGA", "J2000", et, referenceMatrix); - openspace::transformMatrix positionMatrix(3); + glm::dmat3 positionMatrix; glm::dvec3 position(state[0], state[1], state[2]); bool found = openspace::SpiceManager::ref().getPositionTransformMatrix("CASSINI_HGA", "J2000", @@ -336,13 +336,13 @@ TEST_F(SpiceManagerTest, getPositionTransformMatrix){ //check for matrix consistency for (int i = 0; i < 3; i++){ for (int j = 0; j < 3; j++){ - EXPECT_DOUBLE_EQ(referenceMatrix[i][j], positionMatrix(i, j)) << "Position-matrix not set or has wrong values"; + EXPECT_DOUBLE_EQ(referenceMatrix[i][j], positionMatrix[i][j]) << "Position-matrix not set or has wrong values"; } } //transform reference position into new frame mxvg_c(referenceMatrix, state, 3, 3, state_t); - positionMatrix.transform(position); + position = positionMatrix * position; //check transformed values match for (int i = 0; i < 3; i++){ EXPECT_DOUBLE_EQ(position[i], state_t[i]) << "Position vector differs from its reference"; @@ -356,32 +356,31 @@ TEST_F(SpiceManagerTest, getFieldOfView){ int n; int cassini_ID; double et; - double boresight[3]; + glm::dvec3 boresight; double bounds_ref[5][3]; char shape_ref[TYPLEN]; char name_ref[FILLEN]; + double boresightVec[3]; str2et_c("2004 jun 11 19:32:00", &et); SpiceBoolean found; bodn2c_c("CASSINI_ISS_NAC", &cassini_ID, &found); ASSERT_TRUE(found == SPICETRUE) << "Cannot locate ID for Cassini"; - getfov_c(cassini_ID, 5, TYPLEN, TYPLEN, shape_ref, name_ref, boresight, &n, bounds_ref); + getfov_c(cassini_ID, 5, TYPLEN, TYPLEN, shape_ref, name_ref, boresightVec, &n, bounds_ref); std::string shape, name; shape.resize(32); name.resize(32); std::vector bounds; - int nrReturned; found = openspace::SpiceManager::ref().getFieldOfView("CASSINI_ISS_NAC", shape, name, boresight, - bounds, - nrReturned); + bounds); ASSERT_TRUE(found == SPICETRUE); //check vectors have correct values - for (int i = 0; i < nrReturned; i++){ + for (int i = 0; i < bounds.size(); i++){ for (int j = 0; j < 3; j++){ EXPECT_DOUBLE_EQ(bounds_ref[i][j], bounds[i][j]) << "One or more Field of View Boundary vectors \ differ from expected output"; @@ -389,80 +388,6 @@ TEST_F(SpiceManagerTest, getFieldOfView){ } unload_c(META.c_str()); } -// Try converting rectangular coordinates to latitudal -TEST_F(SpiceManagerTest, rectangularToLatitudal){ - loadMetaKernel(); - - char frame[FILLEN], shape[FILLEN]; - double lat, lon; - double bounds[4][3], bsight[3], - obspos[3], point_ref[3]; - double dist, et, radius_ref, trgepc; - int n, naifId; - bool found; - SpiceBoolean foundSpice; - - // First, find an intersection point to convert to rectangular coordinates - str2et_c("2004 jun 11 19:32:00", &et); - bodn2c_c("CASSINI_ISS_NAC", &naifId, &foundSpice); - ASSERT_TRUE(foundSpice == SPICETRUE); - getfov_c(naifId, 4, FILLEN, FILLEN, shape, frame, bsight, &n, bounds); - srfxpt_c("Ellipsoid", "PHOEBE", et, "LT+S", "CASSINI", frame, bsight, - point_ref, &dist, &trgepc, obspos, &foundSpice); - ASSERT_TRUE(foundSpice == SPICETRUE); - - reclat_c(point_ref, &radius_ref, &lon, &lat); - glm::dvec3 point(point_ref[0], point_ref[1], point_ref[2]); - double radius, longitude, latitude; - found = openspace::SpiceManager::ref().rectangularToLatitudal(point, radius, longitude, latitude); - - ASSERT_TRUE(found); - ASSERT_NEAR(radius, radius_ref, abs_error) << "radius is not set / has incorrect values"; - ASSERT_NEAR(longitude, lon, abs_error) << "longitude is not set / has incorrect values"; - ASSERT_NEAR(latitude, lat, abs_error) << "latitude is not set / has incorrect values"; - unload_c(META.c_str()); -} -// Try converting latitudinal coordinates to rectangular -TEST_F(SpiceManagerTest, latitudinalToRectangular){ - loadMetaKernel(); - - char frame[FILLEN], shape[FILLEN]; - double lat, lon; - double bounds[4][3], bsight[3], - obspos[3], point_ref[3]; - double dist, et, radius_ref, trgepc; - int n, naifId; - SpiceBoolean foundSpice; - - // First, find an intersection point to convert to latitudinal coordinates // - str2et_c("2004 jun 11 19:32:00", &et); - bodn2c_c("CASSINI_ISS_NAC", &naifId, &foundSpice); - ASSERT_TRUE(foundSpice == SPICETRUE); - getfov_c(naifId, 4, FILLEN, FILLEN, shape, frame, bsight, &n, bounds); - foundSpice = SPICEFALSE; - srfxpt_c("Ellipsoid", "PHOEBE", et, "LT+S", "CASSINI", frame, bsight, - point_ref, &dist, &trgepc, obspos, &foundSpice); - ASSERT_TRUE(foundSpice == SPICETRUE); - - reclat_c(point_ref, &radius_ref, &lon, &lat); - - lat *= rpd_c(); - lon *= rpd_c(); - - double lat_ref = lat; - double lon_ref = lon; - - double rectangular_ref[3]; - latrec_c(radius_ref, lon, lat, rectangular_ref); - - glm::dvec3 coordinates; - bool found = openspace::SpiceManager::ref().latidudinalToRectangular(radius_ref, lon, lat, coordinates); - - ASSERT_TRUE(found); - ASSERT_NEAR(lon_ref, lon, abs_error) << "longitude is not set / has incorrect values"; - ASSERT_NEAR(lat_ref, lat, abs_error) << "latitude is not set / has incorrect values"; - unload_c(META.c_str()); -} // Try to convert planetocentric coordinates to rectangular TEST_F(SpiceManagerTest, planetocentricToRectangular){ loadPCKKernel(); @@ -506,9 +431,9 @@ TEST_F(SpiceManagerTest, getSubObserverPoint){ subpnt_c(method[i], "phoebe", et, "iau_phoebe", "lt+s", "earth", subObserverPoint_ref, &targetEt_ref, vectorToSurfacePoint_ref); - bool found = openspace::SpiceManager::ref().getSubObserverPoint(method[i], "phoebe", et, "iau_phoebe", - "lt+s", "earth", subObserverPoint, - targetEt, vectorToSurfacePoint); + bool found = openspace::SpiceManager::ref().getSubObserverPoint( + "phoebe", "earth", method[i], "iau_phoebe", "lt+s", et, subObserverPoint, + targetEt, vectorToSurfacePoint); ASSERT_TRUE(found); EXPECT_EQ(targetEt_ref, targetEt); for (int i = 0; i < 3; i++){ @@ -521,34 +446,34 @@ TEST_F(SpiceManagerTest, getSubObserverPoint){ unload_c(META.c_str()); } // Try getting sub-solar point -TEST_F(SpiceManagerTest, getSubSolarPoint){ - loadMetaKernel(); - - double et, targetEt_ref, targetEt; - double subSolarPoint_ref[3]; - double vectorToSurfacePoint_ref[3]; - static SpiceChar * method[2] = { "Intercept: ellipsoid", "Near point: ellipsoid" }; - - str2et_c("2004 jun 11 19:32:00", &et); - - glm::dvec3 subSolarPoint; - glm::dvec3 vectorToSurfacePoint; - - for (int i = 0; i < 2; i++){ - subslr_c(method[i], "phoebe", et, "iau_phoebe", - "lt+s", "earth", subSolarPoint_ref, &targetEt_ref, vectorToSurfacePoint_ref); - - bool found = openspace::SpiceManager::ref().getSubSolarPoint(method[i], "phoebe", et, "iau_phoebe", - "lt+s", "earth", subSolarPoint, - targetEt, vectorToSurfacePoint); - ASSERT_TRUE(found); - EXPECT_EQ(targetEt_ref, targetEt); - for (int i = 0; i < 3; i++){ - EXPECT_EQ(subSolarPoint_ref[i], subSolarPoint[i]) - << "Sub-solar vector differs from its reference"; - EXPECT_EQ(vectorToSurfacePoint_ref[i], vectorToSurfacePoint[i]) - << "Observer to surface point vector differs from its reference"; - } - } - unload_c(META.c_str()); -} +//TEST_F(SpiceManagerTest, getSubSolarPoint){ +// loadMetaKernel(); +// +// double et, targetEt_ref, targetEt; +// double subSolarPoint_ref[3]; +// double vectorToSurfacePoint_ref[3]; +// static SpiceChar * method[2] = { "Intercept: ellipsoid", "Near point: ellipsoid" }; +// +// str2et_c("2004 jun 11 19:32:00", &et); +// +// glm::dvec3 subSolarPoint; +// glm::dvec3 vectorToSurfacePoint; +// +// for (int i = 0; i < 2; i++){ +// subslr_c(method[i], "phoebe", et, "iau_phoebe", +// "lt+s", "earth", subSolarPoint_ref, &targetEt_ref, vectorToSurfacePoint_ref); +// +// bool found = openspace::SpiceManager::ref().getSubSolarPoint(method[i], "phoebe", et, "iau_phoebe", +// "lt+s", "earth", subSolarPoint, +// targetEt, vectorToSurfacePoint); +// ASSERT_TRUE(found); +// EXPECT_EQ(targetEt_ref, targetEt); +// for (int i = 0; i < 3; i++){ +// EXPECT_EQ(subSolarPoint_ref[i], subSolarPoint[i]) +// << "Sub-solar vector differs from its reference"; +// EXPECT_EQ(vectorToSurfacePoint_ref[i], vectorToSurfacePoint[i]) +// << "Observer to surface point vector differs from its reference"; +// } +// } +// unload_c(META.c_str()); +//} diff --git a/include/openspace/util/spicemanager.h b/include/openspace/util/spicemanager.h index dfe4f87e48..a9685f5813 100644 --- a/include/openspace/util/spicemanager.h +++ b/include/openspace/util/spicemanager.h @@ -36,10 +36,10 @@ namespace openspace { -class transformMatrix; - class SpiceManager { public: + typedef std::array TransformMatrix; + /** * Initializer that initializes the static member. */ @@ -133,8 +133,10 @@ public: * the method bodvrd_c and stored in v * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bodvrd_c.html. If one of * the conditions is false an error is logged and the value v is - * unchanged. - * \param body The name of the body whose value should be retrieved + * unchanged. For a description on NAIF IDs, see + * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html. + * \param body The name of the body whose value should be retrieved or the NAIF ID of + * this body * \param value The value of that should be retrieved, this value is case-sensitive * \param v The destination for the retrieved value * \return true if the body named a valid body, @@ -143,26 +145,6 @@ public: */ bool getValue(const std::string& body, const std::string& value, double& v) const; - /** - * Retrieves a single value for a certain body with a NAIF ID of - * id. This method succeeds iff id is the ID of a valid - * body, value is a value associated with the body, and the value - * consists of only a single double value. If all conditions are true, - * the value is retrieved using the method bodvrd_c and stored in - * v - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bodvrd_c.html. If one of - * the conditions is false an error is logged and the value v is - * unchanged. For a description on NAIF IDs, see - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html. - * \param id The NAIF ID of the body whose information should be retrieved - * \param value The value of that should be retrieved, this value is case-sensitive - * \param v The destination for the retrieved value - * \return true if the body named a valid body, - * value is a valid item for the body and the retrieved - * value is only a single value. false otherwise - */ - bool getValue(int id, const std::string& value, double& v) const; - /** * Retrieves a value with three components for a certain * body. This method succeeds iff body is the name of a @@ -171,8 +153,10 @@ public: * is retrieved using the method bodvrd_c and stored in v * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bodvrd_c.html. If one of * the conditions is false an error is logged and the value v is - * unchanged. - * \param body The name of the body whose value should be retrieved + * unchanged. For a description on NAIF IDs, see + * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html. + * \param body The name of the body whose value should be retrieved or the NAIF ID of + * the body * \param value The value of that should be retrieved, this value is case-sensitive * \param v The destination for the retrieved values * \return true if the body named a valid body, @@ -181,25 +165,6 @@ public: */ bool getValue(const std::string& body, const std::string& value, glm::dvec3& v) const; - /** - * Retrieves a value with three components for a certain body with a - * NAIF ID of id. This method succeeds id is the ID of a - * valid body, value is a value associated with the body, and the value - * consists of three double values. If all conditions are true, the value - * is retrieved using the method bodvrd_c and stored in v - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bodvrd_c.html. If one of - * the conditions is false an error is logged and the value v is - * unchanged. For a description on NAIF IDs, see - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html. - * \param id The NAIF ID of the body whose information should be retrieved - * \param value The value of that should be retrieved, this value is case-sensitive - * \param v The destination for the retrieved values - * \return true if the body named a valid body, - * value is a valid item for the body and the retrieved - * value is only a single value. false otherwise - */ - bool getValue(int id, const std::string& value, glm::dvec3& v) const; - /** * Retrieves a value with four components for a certain * body. This method succeeds iff body is the name of a @@ -208,8 +173,10 @@ public: * is retrieved using the method bodvrd_c and stored in v * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bodvrd_c.html. If one of * the conditions is false an error is logged and the value v is - * unchanged. - * \param body The name of the body whose value should be retrieved + * unchanged. For a description on NAIF IDs, see + * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html. + * \param body The name of the body whose value should be retrieved or the NAIF ID of + * the body * \param value The value of that should be retrieved, this value is case-sensitive * \param v The destination for the retrieved values * \return true if the body named a valid body, @@ -218,25 +185,6 @@ public: */ bool getValue(const std::string& body, const std::string& value, glm::dvec4& v) const; - /** - * Retrieves a value with four components for a certain body with a - * NAIF ID of id. This method succeeds id is the ID of a - * valid body, value is a value associated with the body, and the value - * consists of four double values. If all conditions are true, the value - * is retrieved using the method bodvrd_c and stored in v - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bodvrd_c.html. If one of - * the conditions is false an error is logged and the value v is - * unchanged. For a description on NAIF IDs, see - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html. - * \param id The NAIF ID of the body whose information should be retrieved - * \param value The value of that should be retrieved, this value is case-sensitive - * \param v The destination for the retrieved values - * \return true if the body named a valid body, - * value is a valid item for the body and the retrieved - * value is only a single value. false otherwise - */ - bool getValue(int id, const std::string& value, glm::dvec4& v) const; - /** * Retrieves a value with an arbitrary number of components for a certain * body. This method succeeds body is a valid body, @@ -247,8 +195,10 @@ public: * the method bodvrd_c and stored in v * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bodvrd_c.html. If one of * the conditions is false an error is logged and the value v is - * unchanged. - * \param body The body whose information should be retrieved + * unchanged. For a description on NAIF IDs, see + * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html. + * \param body The body whose information should be retrieved or the NAIF ID of that + * body * \param value The value of that should be retrieved, this value is case-sensitive * \param v The destination for the retrieved values. The size of this vector * determines how many values will be retrieved @@ -259,28 +209,6 @@ public: bool getValue(const std::string& body, const std::string& value, std::vector& v) const; - /** - * Retrieves a value with an arbitrary number of components for a certain - * body with a NAIF ID of id. This method succeeds id is the - * ID of a valid body, value is a value associated with the body, and the - * value consists of a number of double values. The requested number is - * equal to the size of the passed vector v which means that - * this vector has to be preallocated. If all conditions are true, the value is - * retrieved using the method bodvrd_c and stored in v - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bodvrd_c.html. If one of - * the conditions is false an error is logged and the value v is - * unchanged. For a description on NAIF IDs, see - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html. - * \param id The NAIF ID of the body whose information should be retrieved - * \param value The value of that should be retrieved, this value is case-sensitive - * \param v The destination for the retrieved values. The size of this vector - * determines how many values will be retrieved - * \return true if the body named a valid body, - * value is a valid item for the body and the retrieved - * value is only a single value. false otherwise - */ - bool getValue(int id, const std::string& value, std::vector& v) const; - /** * Converts the epochString representing a date to a double precision * value representing the ephemerisTime; that is the number of TDB @@ -315,193 +243,219 @@ public: const std::string& format = "YYYY MON DDTHR:MN:SC.### ::RND"); /** - * Return the position of a target body relative to an observing - * body, optionally corrected for light time (planetary aberration) - * and stellar aberration. - * For further details, please refer to 'spkpos_c' in SPICE Docummentation - * - * \param target Target body name. - * \param ephemeris Observer epoch. - * \param referenceFrame Reference frame of output position vector. - * \param aberrationCorrection Aberration correction flag. - * \param observer Observing body name. - * \param targetPosition Position of target. - * \param lightTime One way light time between observer and target. - * \return Whether the function succeeded or not + * Returns the position of a target body relative to an + * observer in a specific referenceFrame, optionally + * corrected for light time (planetary aberration) and stellar aberration + * (aberrationCorrection). For further details, refer to + * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/spkpos_c.html. For more + * information on NAIF IDs, refer to + * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html + * \param target The target body name or the target body's NAIF ID + * \param observer The observing body name or the observing body's NAIF ID + * \param referenceFrame The reference frame of the output position vector + * \param aberrationCorrection The aberration correction flag out of the list of + * values (NONE, LT, LT+S, CN, + * CN+S for the reception case or XLT, XLT+S, + * XCN, or XCN+S for the transmission case. + * \param ephemerisTime The time at which the position is to be queried + * \param position The output containing the position of the target; if the method + * fails, the target position is unchanged + * \param lightTime If the aberrationCorrection is different from + * NONE, this variable will contain the one-way light time between the + * observer and the target. If the method fails, the lightTime is unchanged + * \return true if the function was successful, false + * otherwise */ bool getTargetPosition(const std::string& target, - double ephemerisTime, + const std::string& observer, const std::string& referenceFrame, const std::string& aberrationCorrection, - const std::string& observer, - glm::dvec3& targetPosition, + double ephemerisTime, + glm::dvec3& position, double& lightTime) const; + + /** - * Return the state (position and velocity) of a target body - * relative to an observing body, optionally corrected for light - * time (planetary aberration) and stellar aberration. - * For further details, please refer to 'spkezr_c' in SPICE Docummentation - * - * \param target Target body name. - * \param ephemerisTime Observer epoch. - * \param referenceFrame Reference frame of output state vector. - * \param aberrationCorrection Aberration correction flag. - * \param observer Observing body name. - * \param targetPosition Position of target. - * \param targetVelocity Velocity of target. - * \param lightTime One way light time between observer and target. - * \return Whether the function succeeded or not + * Returns the state vector (position and velocity) of a + * target body relative to an observer in a specific + * referenceFrame, optionally corrected for light time (planetary + * aberration) and stellar aberration (aberrationCorrection). For further + * details, refer to + * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/spkezr_c.html. For more + * information on NAIF IDs, refer to + * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html + * \param target The target body name or the target body's NAIF ID + * \param observer The observing body name or the observing body's NAIF ID + * \param referenceFrame The reference frame of the output position vector + * \param aberrationCorrection The aberration correction flag out of the list of + * values (NONE, LT, LT+S, CN, + * CN+S for the reception case or XLT, XLT+S, + * XCN, or XCN+S for the transmission case. + * \param ephemerisTime The time at which the position is to be queried + * \param position The output containing the position of the target; if the method + * fails, the position is unchanged + * \param velocity The output containing the velocity of the target; if the method + * fails, the velocity is unchanged + * \param lightTime If the aberrationCorrection is different from + * NONE, this variable will contain the one-way light time between the + * observer and the target.If the method fails, the lightTime is unchanged + * \return true if the function was successful, false + * otherwise */ bool getTargetState(const std::string& target, - double ephemerisTime, + const std::string& observer, const std::string& referenceFrame, const std::string& aberrationCorrection, - const std::string& observer, - glm::dvec3& targetPosition, - glm::dvec3& targetVelocity, + double ephemerisTime, + glm::dvec3& position, + glm::dvec3& velocity, double& lightTime) const; -// Computing Transformations Between Frames (FK) -------------------------------------- // - /** - * Return the state transformation matrix from one frame to - * another at a specified epoch. - * For further details, please refer to 'sxform_c' in SPICE Docummentation - * - * \param fromFrame Name of the frame to transform from. - * \param toFrame Name of the frame to transform to. - * \param et Epoch of the rotation matrix. - * \param posTransMat A rotation matrix. - * \return Whether the function succeeded or not + * Returns the state transformation matrix used to convert from one frame to another + * at a specified ephemerisTime. For further details, please refer to + * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/sxform_c.html. + * \param sourceFrame The name of the source reference frame + * \param destinationFrame The name of the destination reference frame + * \param ephemerisTime The time at which the transformation matrix is to be queried + * \param transformationMatrix The output containing the TransformMatrix containing + * the transformation matrix that defines the transformation from the + * sourceFrame to the destinationFrame. If the method fails + * the transformationMatrix is unchanged + * \return true if the function was successful, false + * otherwise */ - bool getStateTransformMatrix(const std::string& fromFrame, - const std::string& toFrame, + bool getStateTransformMatrix(const std::string& sourceFrame, + const std::string& destinationFrame, double ephemerisTime, - transformMatrix& stateMatrix) const; + TransformMatrix& transformationMatrix) const; /** - * Return the matrix that transforms position vectors from one - * specified frame to another at a specified epoch. - * For further details, please refer to 'pxform_c' in SPICE Docummentation - * - * \param fromFrame Name of the frame to transform from. - * \param toFrame Name of the frame to transform to. - * \param et Epoch of the state transformation matrix. - * \param stateTransMat A state transformation matrix. - * \return Whether the function succeeded or not + * Returns the matrix that transforms position vectors from one reference frame to + * another at a specified ephemerisTime. For further details, please refer to + * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/pxform_c.html. + * \param sourceFrame The name of the source reference frame + * \param destinationFrame The name of the destination reference frame + * \param ephemerisTime The time at which the transformation matrix is to be queried + * \param transformationMatrix The output containing the transformation matrix that + * defines the transformation from the sourceFrame to the + * destinationFrame. If the method fails the + * transformationMatrix is unchanged + * \return true if the function was successful, false + * otherwise */ - bool getPositionTransformMatrix(const std::string& fromFrame, - const std::string& toFrame, - double ephemerisTime, - transformMatrix& positionMatrix) const; - - - void getPositionTransformMatrixGLM(const std::string& fromFrame, - const std::string& toFrame, + bool getPositionTransformMatrix(const std::string& sourceFrame, + const std::string& destinationFrame, double ephemerisTime, - glm::dmat3& positionMatrix) const; - -// Retrieving Instrument Parameters (IK) ------------------------------------------ // + glm::dmat3& transformationMatrix) const; /** - * This routine returns the field-of-view (FOV) parameters for a - * specified instrument. - * For further details, please refer to 'getfov_c' in SPICE Docummentation - * - * \param naifInstrumentId NAIF ID of an instrument. - * \param instrumentFovShape Instrument Field Of View shape. - * \param nameOfFrame Name of fram in which FOV vectors are defines. - * \param boresightVector Boresight vector. - * \param numberOfBoundaryVectors Number of boundary vectors returned. - * \param bounds Field Of View boundary vectors - * \param room Maximum number of vectors that can be returned. - * \return Whether the function succeeded or not + * Applies the transformationMatrix retrieved from + * getStateTransformMatrix to the position and velocity. The + * position and velocity parameters are used as input and + * output. + * \param position The position that should be transformed. The transformed position + * will be stored back in this parameter + * \param velocity The velocity that should be transformed. The transformed velocity + * will be stored back in this parameter + * \param transformationMatrix The 6x6 transformation matrix retrieved from + * getStateTransformMatrix that is used to transform the position and + * velocity vectors */ - bool getFieldOfView(const std::string& naifInstrumentId, + void applyTransformationMatrix(glm::dvec3& position, + glm::dvec3& velocity, + const TransformMatrix& transformationMatrix); + + /** + * This routine returns the field-of-view (FOV) parameters for a specified + * instrument. For further details, please refer to + * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/getfov_c.html. + * \param instrument The name of the instrument for which the FOV is to be retrieved + * \param fovShape The output containing the rough shape of the returned FOV. If the + * method fails, this value remains unchanged + * \param frameName The output containing the name of the frame in which the FOV + * bounds are computed. If the method fails, this value remains unchanged + * \param boresightVector The output containing the boresight, that is the vector for + * the center direction of the FOV. If the method fails, this value remains unchanged + * \param bounds The output containing the values defining the bounds of the FOV as + * explained by http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/getfov_c.html. + * If the method fails, this value remains unchanged + * \return true if the function was successful, false + * otherwise + */ + bool getFieldOfView(const std::string& instrument, std::string& fovShape, std::string& frameName, - double boresightVector[], - std::vector& bounds, - int& nrReturned) const; - -// Computing Planetocentric, Planetodetic, and Planetographic Coordinates ---------- // - - /** - * Convert from rectangular coordinates to latitudinal coordinates. - * For further details, please refer to 'reclat_c ' in SPICE Docummentation - * - * \param coordinates Rectangular coordinates of a point, 3-vectors - * \param radius Distance of the point from the origin. - * \param longitude Longitude of the point in radians. The range is [-pi, pi]. - * \param latitude Latitude of the point in radians. The range is [-pi/2, pi/2]. - * \return Whether the function succeeded or not - */ - bool rectangularToLatitudal(const glm::dvec3 coordinates, - double& radius, - double& longitude, - double& latitude) const; - /** - * Convert from latitudinal coordinates to rectangular coordinates. - * For further details, please refer to 'latrec_c ' in SPICE Docummentation - * - * \param radius Distance of a point from the origin. - * \param longitude Longitude of point in radians. - * \param longitude Latitude of point in radians. - * \param latitude Rectangular coordinates of the point. - * \return Whether the function succeeded or not - */ - bool latidudinalToRectangular(double radius, - double& longitude, - double& latitude, - glm::dvec3& coordinates) const; - - /** - * Convert planetocentric latitude and longitude of a surface - * point on a specified body to rectangular coordinates. - * For further details, please refer to 'srfrec_c ' in SPICE Docummentation - * - * \param naif_id NAIF integer code of an extended body. - * \param longitude Longitude of point in radians. - * \param latitude Latitude of point in radians. - * \param coordinates Rectangular coordinates of the point. - * \return Whether the function succeeded or not - */ - bool planetocentricToRectangular(const std::string& naifName, - double& longitude, - double& latitude, - glm::dvec3& coordinates) const; - -// Computing Sub - observer and Sub - solar Points --------------------------------- // + glm::dvec3& boresightVector, + std::vector& bounds) const; /** - * Compute the rectangular coordinates of the sub-observer point on - * a target body at a specified epoch, optionally corrected for - * light time and stellar aberration. - * For further details, please refer to 'subpnt_c ' in SPICE Docummentation - * - * \param computationMethod Computation method. - * \param target Name of target body. - * \param ephemeris Epoch in ephemeris seconds past J2000 TDB. - * \param bodyFixedFrame Body-fixed, body-centered target body frame. - * \param aberrationCorrection Aberration correction. - * \param observer Name of observing body. - * \param subObserverPoint Sub-observer point on the target body. - * \param targetEpoch Sub-observer point epoch. - * \param observerToSubObserverVec Vector from observer to sub-observer point. - * \return Whether the function succeeded or not + * Converts planeto-centric latitude and longitude of a + * surface point on a specified body to rectangular + * coordinates. For further details, refer to + * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/srfrec_c.html. + * \param body The body on which the longitude and latitude + * are defined. This body needs to have a defined radius for this function to work + * \param longitude The longitude of the point on the body in radians + * \param latitude The latitude of the point on the body in radians + * \param coordinates The output containing the rectangular coordinates of the point + * defined by longitude and latitude on the + * body. If the method fails, the coordinate are unchanged + * \return true if the function was successful, false + * otherwise */ - bool getSubObserverPoint(std::string computationMethod, - std::string target, - double ephemeris, + bool planetocentricToRectangular(const std::string& body, double longitude, + double latitude, glm::dvec3& coordinates) const; + + /** + * Compute the rectangular coordinates of the sub-observer point of an + * observer on a target body at a specified + * ephemerisTime, optionally corrected for light time and stellar + * aberration. For further details, refer to + * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/subpnt_c.html. + * Example: If the sub-observer point on Mars for MRO is requested, the + * target would be Mars and the observer would + * be MRO. + * \param target The name of the target body on which the sub-observer point lies + * \param observer The name of the ephemeris object whose sub-observer point should be + * retrieved + * \param computationMethod The computation method used for the sub-observer point. + * Must be one of Near point: ellipsoid or + * Intercept: ellipsoid and it determines the interpretation of the + * results; see http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/subpnt_c.html + * for detailed description on the computation methods + * \param bodyFixedFrame The body-fixed, body-centered frame belonging to the + * target + * \param aberrationCorrection The aberration correction flag out of the list of + * values (NONE, LT, LT+S, CN, + * CN+S for the reception case or XLT, XLT+S, + * XCN, or XCN+S for the transmission case. + * \param ephemerisTime The ephemeris time for which the sub-observer point should be + * retrieved + * \param subObserverPoint The output containing the observer's sub-observer point on + * the target body. If the method fails, the value remains unchanged + * \param targetEphemerisTime The output containing the target's ephemeris time + * accounting for the aberration, if an aberrationCorrection value + * different from NONE is chosen. If the method fails, the value remains + * unchanged + * \param vectorToSurfacePoint The output containing the vector from the observer to + * the, potentially aberration corrected, sub-observer point. If the method fails the + * value remains unchanged + * \return true if the function was successful, false + * otherwise + */ + bool getSubObserverPoint(std::string target, + std::string observer, + std::string computationMethod, std::string bodyFixedFrame, std::string aberrationCorrection, - std::string observer, + double ephemerisTime, glm::dvec3& subObserverPoint, - double& targetEpoch, + double& targetEphemerisTime, glm::dvec3& vectorToSurfacePoint) const; /** - * Compute the rectangular coordinates of the sub-observer point on + * Computes the rectangular coordinates of the sub-solar point on * a target body at a specified epoch, optionally corrected for * light time and stellar aberration. * For further details, please refer to 'subslr_c ' in SPICE Docummentation @@ -517,15 +471,16 @@ public: * \param observerToSubObserverVec Vector from observer to sub-observer point. * \return Whether the function succeeded or not */ - bool getSubSolarPoint(std::string computationMethod, - std::string target, - double ephemeris, - std::string bodyFixedFrame, - std::string aberrationCorrection, - std::string observer, - glm::dvec3& subSolarPoint, - double& targetEpoch, - glm::dvec3& vectorToSurfacePoint) const; + //bool getSubSolarPoint(std::string target, + // std::string computationMethod, + // + // double ephemeris, + // std::string bodyFixedFrame, + // std::string aberrationCorrection, + // + // glm::dvec3& subSolarPoint, + // double& targetEpoch, + // glm::dvec3& vectorToSurfacePoint) const; private: struct KernelInformation { std::string path; @@ -534,6 +489,8 @@ private: SpiceManager() = default; SpiceManager(const SpiceManager& c) = delete; + SpiceManager& operator=(const SpiceManager& r) = delete; + SpiceManager(SpiceManager&& r) = delete; std::vector _loadedKernels; static unsigned int _lastAssignedKernel; @@ -541,99 +498,6 @@ private: static SpiceManager* _manager; }; -/** -* SpiceManager helper class, a storage container used to -* transform state vectors from one reference frame to another. -* The client creates an instance of transformMatrix -* and after its been passed to either getStateTransformMatrix -* or getPositionTransformMatrix the instantiated object -* can transform position and velocity to any specified reference frame. -* -* Client-side example: -* openspace::transformMatrix stateMatrix(6); -* openspace::SpiceManager::ref().getStateTransformMatrix("J2000", -* "IAU_PHOEBE", -* et, -* stateMatrix); -* stateMatrix.transform(position, velocity); -* (or if transformMatrix is 3x3:) -* stateMatrix.transform(position); -*/ -#define COPY(to, from) memcpy(to, from, sizeof(double)* 3); -class transformMatrix{ -private: - int N; - double *data; - bool empty; - - friend class SpiceManager; -public: - double* ptr() { - empty = false; - return data; - } - /* default constructor */ - transformMatrix(); - /* default destructor */ -// ~transformMatrix(){ delete[] data; }; - /* allocation of memory */ - transformMatrix(int n) : N(n){ - data = new double[N*N]; - empty = true; - } - - void transform(glm::dvec3& position) { - assert(!empty); // transformation matrix is empty - - double *state; - double *state_t; - state = new double[N]; - state_t = new double[N]; - - COPY(state, &position); - mxvg_c(data, state, N, N, state_t); - - COPY(&position, state_t); - } - - /** As the spice function mxvg_c requires a 6dim vector - * the two 3dim state vectors are packed into 'state'. - * Transformed values are then copied back from state_t - * to each corresponding statevector. - * - * \param position, positional vector to be expressed in - * the new reference frame. - * \param velocity, (optional) velocity input is only - * transformed in conjunction with a 6x6 matrix, otherwise - * the method ignores its second argument. - */ - void transform(glm::dvec3& position, - glm::dvec3& velocity) { - assert(!empty); // transformation matrix is empty - - double *state; - double *state_t; - state = new double[N]; - state_t = new double[N]; - - COPY(state, &position); - if (N == 6) COPY(state + velocity.length(), &velocity); - - mxvg_c(data, state, N, N, state_t); - - COPY(&position, state_t); - if (N == 6) COPY(&velocity, state_t + velocity.length()); - } - /* overloaded operator() - * asserts matrix has been filled - */ - inline double operator()(int i, int j) const{ - assert(!empty); // transformation matrix is empty - return data[j + i*N]; - } -}; -#undef COPY - } // namespace openspace #endif // __SPICEMANAGER_H__ diff --git a/src/rendering/planets/renderableplanet.cpp b/src/rendering/planets/renderableplanet.cpp index 719565a768..87511edf45 100644 --- a/src/rendering/planets/renderableplanet.cpp +++ b/src/rendering/planets/renderableplanet.cpp @@ -161,7 +161,7 @@ void RenderablePlanet::render(const RenderData& data) void RenderablePlanet::update(const UpdateData& data) { // set spice-orientation in accordance to timestamp - openspace::SpiceManager::ref().getPositionTransformMatrixGLM("GALACTIC", "IAU_EARTH", data.time, _stateMatrix); + openspace::SpiceManager::ref().getPositionTransformMatrix("GALACTIC", "IAU_EARTH", data.time, _stateMatrix); } diff --git a/src/scenegraph/spiceephemeris.cpp b/src/scenegraph/spiceephemeris.cpp index 7eae196d37..3be9ac06a7 100644 --- a/src/scenegraph/spiceephemeris.cpp +++ b/src/scenegraph/spiceephemeris.cpp @@ -88,7 +88,7 @@ void SpiceEphemeris::update(const UpdateData& data) { glm::dvec3 position(0,0,0); double lightTime = 0.0; - SpiceManager::ref().getTargetPosition(_targetName, data.time, "GALACTIC", "LT+S", _originName, position, lightTime); + SpiceManager::ref().getTargetPosition(_targetName, _originName, "GALACTIC", "LT+S", data.time, position, lightTime); /* std::cout << _targetName << " ("; diff --git a/src/util/spicemanager.cpp b/src/util/spicemanager.cpp index 20ad4d193c..ead68bff68 100644 --- a/src/util/spicemanager.cpp +++ b/src/util/spicemanager.cpp @@ -80,7 +80,7 @@ int SpiceManager::loadKernel(std::string filePath) { unsigned int kernelId = ++_lastAssignedKernel; assert(kernelId > 0); - filePath = std::move(absPath(filePath)); + filePath = absPath(filePath); ghoul::filesystem::Directory currentDirectory = FileSys.currentDirectory(); std::string&& fileDirectory = ghoul::filesystem::File(filePath).directoryName(); FileSys.setCurrentDirectory(fileDirectory); @@ -164,10 +164,6 @@ bool SpiceManager::getValue(const std::string& body, const std::string& value, return true; } -bool SpiceManager::getValue(int id, const std::string& value, double& v) const { - return getValue(std::to_string(id), value, v); -} - bool SpiceManager::getValue(const std::string& body, const std::string& value, glm::dvec3& v) const { @@ -187,11 +183,6 @@ bool SpiceManager::getValue(const std::string& body, const std::string& value, return true; } -bool SpiceManager::getValue(int id, const std::string& value, glm::dvec3& v) const -{ - return getValue(std::to_string(id), value, v); -} - bool SpiceManager::getValue(const std::string& body, const std::string& value, glm::dvec4& v) const { @@ -211,11 +202,6 @@ bool SpiceManager::getValue(const std::string& body, const std::string& value, return true; } -bool SpiceManager::getValue(int id, const std::string& value, glm::dvec4& v) const -{ - return getValue(std::to_string(id), value, v); -} - bool SpiceManager::getValue(const std::string& body, const std::string& value, std::vector& v) const { @@ -236,12 +222,6 @@ bool SpiceManager::getValue(const std::string& body, const std::string& value, return true; } -bool SpiceManager::getValue(int id, const std::string& value, - std::vector& v) const -{ - return getValue(std::to_string(id), value, v); -} - bool SpiceManager::getETfromDate(const std::string& epochString, double& ephemerisTime) const { @@ -280,10 +260,10 @@ bool SpiceManager::getDateFromET(double ephemerisTime, std::string& date, } bool SpiceManager::getTargetPosition(const std::string& target, - double ephemerisTime, + const std::string& observer, const std::string& referenceFrame, const std::string& aberrationCorrection, - const std::string& observer, + double ephemerisTime, glm::dvec3& targetPosition, double& lightTime) const{ double pos[3] = { 0.0, 0.0, 0.0 }; @@ -307,10 +287,10 @@ bool SpiceManager::getTargetPosition(const std::string& target, return true; } bool SpiceManager::getTargetState(const std::string& target, - double ephemerisTime, + const std::string& observer, const std::string& referenceFrame, const std::string& aberrationCorrection, - const std::string& observer, + double ephemerisTime, glm::dvec3& targetPosition, glm::dvec3& targetVelocity, double& lightTime) const{ @@ -340,40 +320,31 @@ bool SpiceManager::getTargetState(const std::string& target, bool SpiceManager::getStateTransformMatrix(const std::string& fromFrame, const std::string& toFrame, double ephemerisTime, - transformMatrix& stateMatrix) const{ + TransformMatrix& stateMatrix) const{ sxform_c(fromFrame.c_str(), toFrame.c_str(), - ephemerisTime, (double(*)[6])stateMatrix.ptr()); + ephemerisTime, (double(*)[6])stateMatrix.data()); return true; } bool SpiceManager::getPositionTransformMatrix(const std::string& fromFrame, - const std::string& toFrame, - double ephemerisTime, - transformMatrix& positionMatrix) const{ - - pxform_c(fromFrame.c_str(), toFrame.c_str(), - ephemerisTime, (double(*)[3])positionMatrix.ptr()); - - return true; -} - -void SpiceManager::getPositionTransformMatrixGLM(const std::string& fromFrame, const std::string& toFrame, double ephemerisTime, glm::dmat3& positionMatrix) const{ pxform_c(fromFrame.c_str(), toFrame.c_str(), ephemerisTime, (double(*)[3])glm::value_ptr(positionMatrix)); + positionMatrix = glm::transpose(positionMatrix); + return true; } -bool SpiceManager::getFieldOfView(const std::string& naifInstrumentId, +bool SpiceManager::getFieldOfView(const std::string& instrument, std::string& fovShape, std::string& frameName, - double boresightVector[], - std::vector& bounds, - int& nrReturned) const{ + glm::dvec3& boresightVector, + std::vector& bounds) const{ int found; int naifId; int maxVectors = 12; + int nrReturned; double *boundsArr = new double[maxVectors * 3]; for (int i = 0; i < maxVectors; i++){ @@ -382,7 +353,7 @@ bool SpiceManager::getFieldOfView(const std::string& naifInstrumentId, } } - bodn2c_c(naifInstrumentId.c_str(), &naifId, &found); + bodn2c_c(instrument.c_str(), &naifId, &found); if (!found) return false; if (fovShape.size() != 0 && frameName.size() != 0){ @@ -392,7 +363,7 @@ bool SpiceManager::getFieldOfView(const std::string& naifInstrumentId, frameName.size(), const_cast(fovShape.c_str()), const_cast(frameName.c_str()), - boresightVector, + glm::value_ptr(boresightVector), &nrReturned, (double(*)[3])boundsArr); }else{ @@ -411,35 +382,15 @@ bool SpiceManager::getFieldOfView(const std::string& naifInstrumentId, return true; } -bool SpiceManager::rectangularToLatitudal(const glm::dvec3 coordinates, - double& radius, - double& longitude, - double& latitude) const{ - double point[3] = { coordinates.x, coordinates.y, coordinates.z }; - reclat_c(point, &radius, &longitude, &latitude); - //check if returns values - return (radius && longitude && latitude); -} - -bool SpiceManager::latidudinalToRectangular(double radius, - double& longitude, - double& latitude, - glm::dvec3& coordinates) const{ - double point[3] = { coordinates.x, coordinates.y, coordinates.z }; - latrec_c(radius, longitude, latitude, point); - //check if returns values - return (radius && longitude && latitude); -} - -bool SpiceManager::planetocentricToRectangular(const std::string& naifName, - double& longitude, - double& latitude, +bool SpiceManager::planetocentricToRectangular(const std::string& body, + double longitude, + double latitude, glm::dvec3& coordinates) const{ int naifId; int found; double rectangular[3]; - bodn2c_c(naifName.c_str(), &naifId, &found); + bodn2c_c(body.c_str(), &naifId, &found); if (!found) return false; srfrec_c(naifId, longitude*rpd_c(), latitude*rpd_c(), rectangular); @@ -448,51 +399,61 @@ bool SpiceManager::planetocentricToRectangular(const std::string& naifName, return true; } -bool SpiceManager::getSubObserverPoint(std::string computationMethod, - std::string target, - double ephemeris, +bool SpiceManager::getSubObserverPoint(std::string target, + std::string observer, + std::string computationMethod, std::string bodyFixedFrame, std::string aberrationCorrection, - std::string observer, + double ephemerisTime, glm::dvec3& subObserverPoint, - double& targetEpoch, + double& targetEphemerisTime, glm::dvec3& vectorToSurfacePoint) const{ - double subPoint[3], vecToSurf[3]; - subpnt_c(computationMethod.c_str(), target.c_str(), - ephemeris, + ephemerisTime, bodyFixedFrame.c_str(), aberrationCorrection.c_str(), - observer.c_str(), subPoint, &targetEpoch, vecToSurf); - - memcpy(&subObserverPoint , subPoint , sizeof(double) * 3); - memcpy(&vectorToSurfacePoint, vecToSurf, sizeof(double) * 3); - - return true; -} -bool SpiceManager::getSubSolarPoint(std::string computationMethod, - std::string target, - double ephemeris, - std::string bodyFixedFrame, - std::string aberrationCorrection, - std::string observer, - glm::dvec3& subSolarPoint, - double& targetEpoch, - glm::dvec3& vectorToSurfacePoint) const{ - double subPoint[3], vecToSurf[3]; - - subslr_c(computationMethod.c_str(), - target.c_str(), - ephemeris, - bodyFixedFrame.c_str(), - aberrationCorrection.c_str(), - observer.c_str(), subPoint, &targetEpoch, vecToSurf); - - memcpy(&subSolarPoint, subPoint, sizeof(double)* 3); - memcpy(&vectorToSurfacePoint, vecToSurf, sizeof(double)* 3); + observer.c_str(), glm::value_ptr(subObserverPoint), &targetEphemerisTime, + glm::value_ptr(vectorToSurfacePoint)); return true; } +void SpiceManager::applyTransformationMatrix(glm::dvec3& position, + glm::dvec3& velocity, + const TransformMatrix& transformationMatrix) +{ + double input[6]; + double output[6]; + memmove(input, glm::value_ptr(position), 3 * sizeof(glm::dvec3::value_type)); + memmove(input + 3, glm::value_ptr(velocity), 3 * sizeof(glm::dvec3::value_type)); + mxvg_c(transformationMatrix.data(), input, 6, 6, output); + memmove(glm::value_ptr(position), output, 3 * sizeof(glm::dvec3::value_type)); + memmove(glm::value_ptr(velocity), output + 3, 3 * sizeof(glm::dvec3::value_type)); +} + +//bool SpiceManager::getSubSolarPoint(std::string computationMethod, +// std::string target, +// double ephemeris, +// std::string bodyFixedFrame, +// std::string aberrationCorrection, +// std::string observer, +// glm::dvec3& subSolarPoint, +// double& targetEpoch, +// glm::dvec3& vectorToSurfacePoint) const{ +// double subPoint[3], vecToSurf[3]; +// +// subslr_c(computationMethod.c_str(), +// target.c_str(), +// ephemeris, +// bodyFixedFrame.c_str(), +// aberrationCorrection.c_str(), +// observer.c_str(), subPoint, &targetEpoch, vecToSurf); +// +// memcpy(&subSolarPoint, subPoint, sizeof(double)* 3); +// memcpy(&vectorToSurfacePoint, vecToSurf, sizeof(double)* 3); +// +// return true; +//} + } From 32c2c499fa2157a4a364786834a988effacc2d31 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 6 Oct 2014 01:43:33 +0200 Subject: [PATCH 22/23] Fix SpiceManager test --- include/openspace/tests/test_spicemanager.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/openspace/tests/test_spicemanager.inl b/include/openspace/tests/test_spicemanager.inl index ecf9187400..1ee9982d57 100644 --- a/include/openspace/tests/test_spicemanager.inl +++ b/include/openspace/tests/test_spicemanager.inl @@ -336,7 +336,7 @@ TEST_F(SpiceManagerTest, getPositionTransformMatrix){ //check for matrix consistency for (int i = 0; i < 3; i++){ for (int j = 0; j < 3; j++){ - EXPECT_DOUBLE_EQ(referenceMatrix[i][j], positionMatrix[i][j]) << "Position-matrix not set or has wrong values"; + EXPECT_DOUBLE_EQ(referenceMatrix[i][j], positionMatrix[j][i]) << "Position-matrix not set or has wrong values"; } } //transform reference position into new frame From 62e084467103d12843ba83ef35ee4a921ea77580 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 6 Oct 2014 13:44:21 +0200 Subject: [PATCH 23/23] Add ABuffer/constants.hglsl to the ignore list --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index ffa711ee63..cbb57e35f8 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,4 @@ install_manifest.txt # Doxygen stuff html/ latex/ +shaders/ABuffer/constants.hglsl