From 44d046e770aad7194fba672444dfd4a29fe2b5d3 Mon Sep 17 00:00:00 2001 From: Oskar Carlbaum Date: Mon, 18 Sep 2017 03:15:19 +0200 Subject: [PATCH 01/39] Setup main files for fieldlinesSequence module --- modules/fieldlinessequence/CMakeLists.txt | 45 +++++++++++++++ .../fieldlinessequencemodule.cpp | 47 ++++++++++++++++ .../fieldlinessequencemodule.h | 42 ++++++++++++++ modules/fieldlinessequence/include.cmake | 3 + .../renderablefieldlinessequence.cpp | 56 +++++++++++++++++++ .../rendering/renderablefieldlinessequence.h | 50 +++++++++++++++++ 6 files changed, 243 insertions(+) create mode 100644 modules/fieldlinessequence/CMakeLists.txt create mode 100644 modules/fieldlinessequence/fieldlinessequencemodule.cpp create mode 100644 modules/fieldlinessequence/fieldlinessequencemodule.h create mode 100644 modules/fieldlinessequence/include.cmake create mode 100644 modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp create mode 100644 modules/fieldlinessequence/rendering/renderablefieldlinessequence.h diff --git a/modules/fieldlinessequence/CMakeLists.txt b/modules/fieldlinessequence/CMakeLists.txt new file mode 100644 index 0000000000..e8c46e4b8c --- /dev/null +++ b/modules/fieldlinessequence/CMakeLists.txt @@ -0,0 +1,45 @@ +########################################################################################## +# # +# OpenSpace # +# # +# Copyright (c) 2014-2017 # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy of this # +# software and associated documentation files (the "Software"), to deal in the Software # +# without restriction, including without limitation the rights to use, copy, modify, # +# merge, publish, distribute, sublicense, and/or sell copies of the Software, and to # +# permit persons to whom the Software is furnished to do so, subject to the following # +# conditions: # +# # +# The above copyright notice and this permission notice shall be included in all copies # +# or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, # +# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A # +# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF # +# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE # +# OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # +########################################################################################## + +include(${OPENSPACE_CMAKE_EXT_DIR}/module_definition.cmake) + +set(HEADER_FILES + ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablefieldlinessequence.h +) +source_group("Header Files" FILES ${HEADER_FILES}) + +set(SOURCE_FILES + ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablefieldlinessequence.cpp +) +source_group("Source Files" FILES ${SOURCE_FILES}) + +set(SHADER_FILES +) +source_group("Shader Files" FILES ${SHADER_FILES}) + +create_new_module( + "FieldlinesSequence" + fieldlinessequence_module + ${HEADER_FILES} ${SOURCE_FILES} ${SHADER_FILES} +) diff --git a/modules/fieldlinessequence/fieldlinessequencemodule.cpp b/modules/fieldlinessequence/fieldlinessequencemodule.cpp new file mode 100644 index 0000000000..040625f1f9 --- /dev/null +++ b/modules/fieldlinessequence/fieldlinessequencemodule.cpp @@ -0,0 +1,47 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2017 * + * * + * 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 + +namespace openspace { + +FieldlinesSequenceModule::FieldlinesSequenceModule() + : OpenSpaceModule("FieldlinesSequence") {} + +void FieldlinesSequenceModule::internalInitialize() { + auto fRenderable = FactoryManager::ref().factory(); + ghoul_assert(fRenderable, "No renderable factory existed"); + + fRenderable->registerClass("RenderableFieldlinesSequence"); +} + +} // namespace openspace diff --git a/modules/fieldlinessequence/fieldlinessequencemodule.h b/modules/fieldlinessequence/fieldlinessequencemodule.h new file mode 100644 index 0000000000..e8290795e2 --- /dev/null +++ b/modules/fieldlinessequence/fieldlinessequencemodule.h @@ -0,0 +1,42 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2017 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#ifndef __OPENSPACE_MODULE_FIELDLINESSEQUENCE___FIELDLINESSEQUENCEMODULE___H__ +#define __OPENSPACE_MODULE_FIELDLINESSEQUENCE___FIELDLINESSEQUENCEMODULE___H__ + +#include + +namespace openspace { + +class FieldlinesSequenceModule : public OpenSpaceModule { +public: + FieldlinesSequenceModule(); + +protected: + void internalInitialize() override; +}; + +} // namespace openspace + +#endif // __OPENSPACE_MODULE_FIELDLINESSEQUENCE___FIELDLINESSEQUENCEMODULE___H__ diff --git a/modules/fieldlinessequence/include.cmake b/modules/fieldlinessequence/include.cmake new file mode 100644 index 0000000000..67a0fe8d77 --- /dev/null +++ b/modules/fieldlinessequence/include.cmake @@ -0,0 +1,3 @@ +set (OPENSPACE_DEPENDENCIES + space +) diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp new file mode 100644 index 0000000000..62301fe154 --- /dev/null +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp @@ -0,0 +1,56 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2017 * + * * + * 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 + +namespace openspace { + +RenderableFieldlinesSequence::RenderableFieldlinesSequence(const ghoul::Dictionary& dictionary) + : Renderable(dictionary) { + + std::string name; + dictionary.getValue(SceneGraphNode::KeyName, name); + + _loggerCat += " [" + name + "]"; +} + +void RenderableFieldlinesSequence::initialize() { +} + +void RenderableFieldlinesSequence::deinitialize() { +} + +bool RenderableFieldlinesSequence::isReady() const { + return true; +} + +void RenderableFieldlinesSequence::render(const RenderData& data, RendererTasks&) { +} + +void RenderableFieldlinesSequence::update(const UpdateData& data) { +} + +} // namespace openspace diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h new file mode 100644 index 0000000000..adc4f49b2e --- /dev/null +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h @@ -0,0 +1,50 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2017 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#ifndef __OPENSPACE_MODULE_FIELDLINESSEQUENCE___RENDERABLEFIELDLINESSEQUENCE___H__ +#define __OPENSPACE_MODULE_FIELDLINESSEQUENCE___RENDERABLEFIELDLINESSEQUENCE___H__ + +#include + +namespace openspace { + +class RenderableFieldlinesSequence : public Renderable { +public: + RenderableFieldlinesSequence(const ghoul::Dictionary& dictionary); + // ~RenderableFieldlinesSequence(); + + void initialize() override; + void deinitialize() override; + + bool isReady() const override; + + void render(const RenderData& data, RendererTasks& rendererTask) override; + void update(const UpdateData& data) override; +private: + std::string _loggerCat = "RenderableFieldlinesSequence"; +}; + +} // namespace openspace + +#endif // __OPENSPACE_MODULE_FIELDLINESSEQUENCE___RENDERABLEFIELDLINESSEQUENCE___H__ From d6eaab8c268830be789c148169e011781f25eec6 Mon Sep 17 00:00:00 2001 From: Oskar Carlbaum Date: Mon, 18 Sep 2017 03:41:26 +0200 Subject: [PATCH 02/39] Add FieldlinesState class files --- modules/fieldlinessequence/CMakeLists.txt | 2 + .../rendering/renderablefieldlinessequence.h | 4 ++ .../util/fieldlinesstate.cpp | 31 +++++++++++++++ .../fieldlinessequence/util/fieldlinesstate.h | 38 +++++++++++++++++++ 4 files changed, 75 insertions(+) create mode 100644 modules/fieldlinessequence/util/fieldlinesstate.cpp create mode 100644 modules/fieldlinessequence/util/fieldlinesstate.h diff --git a/modules/fieldlinessequence/CMakeLists.txt b/modules/fieldlinessequence/CMakeLists.txt index e8c46e4b8c..32a65b9163 100644 --- a/modules/fieldlinessequence/CMakeLists.txt +++ b/modules/fieldlinessequence/CMakeLists.txt @@ -26,11 +26,13 @@ include(${OPENSPACE_CMAKE_EXT_DIR}/module_definition.cmake) set(HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablefieldlinessequence.h + ${CMAKE_CURRENT_SOURCE_DIR}/util/fieldlinesstate.h ) source_group("Header Files" FILES ${HEADER_FILES}) set(SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablefieldlinessequence.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/util/fieldlinesstate.cpp ) source_group("Source Files" FILES ${SOURCE_FILES}) diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h index adc4f49b2e..0b111f6c37 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h @@ -27,6 +27,8 @@ #include +#include + namespace openspace { class RenderableFieldlinesSequence : public Renderable { @@ -43,6 +45,8 @@ public: void update(const UpdateData& data) override; private: std::string _loggerCat = "RenderableFieldlinesSequence"; + + std::vector _states; }; } // namespace openspace diff --git a/modules/fieldlinessequence/util/fieldlinesstate.cpp b/modules/fieldlinessequence/util/fieldlinesstate.cpp new file mode 100644 index 0000000000..ca33976f63 --- /dev/null +++ b/modules/fieldlinessequence/util/fieldlinesstate.cpp @@ -0,0 +1,31 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2017 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include + +namespace openspace { + +FieldlinesState::FieldlinesState() {} + +} // namespace openspace diff --git a/modules/fieldlinessequence/util/fieldlinesstate.h b/modules/fieldlinessequence/util/fieldlinesstate.h new file mode 100644 index 0000000000..584c06608d --- /dev/null +++ b/modules/fieldlinessequence/util/fieldlinesstate.h @@ -0,0 +1,38 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2017 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#ifndef __OPENSPACE_MODULE_FIELDLINESSEQUENCE___FIELDLINESSTATE___H__ +#define __OPENSPACE_MODULE_FIELDLINESSEQUENCE___FIELDLINESSTATE___H__ + +namespace openspace { + +class FieldlinesState { +public: + FieldlinesState(); +private: +}; + +} // namespace openspace + +#endif // __OPENSPACE_MODULE_FIELDLINESSEQUENCE___FIELDLINESSTATE___H__ From 1519fa794fef6461c346d6a5a3d9bddd3f311781 Mon Sep 17 00:00:00 2001 From: Oskar Carlbaum Date: Mon, 18 Sep 2017 21:11:46 +0200 Subject: [PATCH 03/39] Add functionality for reading inputFileType from modfile dictionary --- .../renderablefieldlinessequence.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp index 62301fe154..3ae677fb4e 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp @@ -26,6 +26,17 @@ #include +namespace { + // ----- KEYS POSSIBLE IN MODFILE. EXPECTED DATA TYPE OF VALUE IN [BRACKETS] ----- // + // ---------------------------- MANDATORY MODFILE KEYS ---------------------------- // + const char* KEY_INPUT_FILE_TYPE = "InputFileType"; // [STRING] + + // ------------- POSSIBLE STRING VALUES FOR CORRESPONDING MODFILE KEY ------------- // + const char* VALUE_INPUT_FILE_TYPE_CDF = "cdf"; + const char* VALUE_INPUT_FILE_TYPE_JSON = "json"; + const char* VALUE_INPUT_FILE_TYPE_OSFLS = "osfls"; +} // namespace + namespace openspace { RenderableFieldlinesSequence::RenderableFieldlinesSequence(const ghoul::Dictionary& dictionary) @@ -35,6 +46,14 @@ RenderableFieldlinesSequence::RenderableFieldlinesSequence(const ghoul::Dictiona dictionary.getValue(SceneGraphNode::KeyName, name); _loggerCat += " [" + name + "]"; + + // ------------------- EXTRACT MANDATORY VALUES FROM DICTIONARY ------------------- // + std::string inputFileType; + if(!dictionary.getValue(KEY_INPUT_FILE_TYPE, inputFileType)) { + LERRORC("FieldlinesSequence", + "The field " + std::string(KEY_INPUT_FILE_TYPE) + " is missing!"); + return; + } } void RenderableFieldlinesSequence::initialize() { From 499156d22187f4f7c8bf4b601e07edb989bce4b0 Mon Sep 17 00:00:00 2001 From: Oskar Carlbaum Date: Mon, 18 Sep 2017 22:42:52 +0200 Subject: [PATCH 04/39] Add functionality which read sourceFolder from Modfile and extracts all valid files from that directory --- .../renderablefieldlinessequence.cpp | 38 +++++++++++++++++-- .../rendering/renderablefieldlinessequence.h | 2 + 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp index 3ae677fb4e..512326a7c3 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp @@ -26,10 +26,15 @@ #include +#include + +using std::string; + namespace { // ----- KEYS POSSIBLE IN MODFILE. EXPECTED DATA TYPE OF VALUE IN [BRACKETS] ----- // // ---------------------------- MANDATORY MODFILE KEYS ---------------------------- // const char* KEY_INPUT_FILE_TYPE = "InputFileType"; // [STRING] + const char* KEY_SOURCE_FOLDER = "SourceFolder"; // [STRING] // ------------- POSSIBLE STRING VALUES FOR CORRESPONDING MODFILE KEY ------------- // const char* VALUE_INPUT_FILE_TYPE_CDF = "cdf"; @@ -42,16 +47,43 @@ namespace openspace { RenderableFieldlinesSequence::RenderableFieldlinesSequence(const ghoul::Dictionary& dictionary) : Renderable(dictionary) { - std::string name; + string name; dictionary.getValue(SceneGraphNode::KeyName, name); _loggerCat += " [" + name + "]"; // ------------------- EXTRACT MANDATORY VALUES FROM DICTIONARY ------------------- // - std::string inputFileType; + string inputFileType; if(!dictionary.getValue(KEY_INPUT_FILE_TYPE, inputFileType)) { LERRORC("FieldlinesSequence", - "The field " + std::string(KEY_INPUT_FILE_TYPE) + " is missing!"); + "The field " + string(KEY_INPUT_FILE_TYPE) + " is missing!"); + return; + } + + string sourceFolderPath; + if(!dictionary.getValue(KEY_SOURCE_FOLDER, sourceFolderPath)) { + LERRORC("FieldlinesSequence", + "The field " + string(KEY_SOURCE_FOLDER) + " is missing!"); + return; + } + + // Ensure that the source folder exists and then extract + // the files with the same extension as + ghoul::filesystem::Directory sourceFolder(sourceFolderPath); + if (FileSys.directoryExists(sourceFolder)) { + // Extract all file paths from the provided folder (Non-recursively! Sorted!) + _sourceFiles = sourceFolder.readFiles(ghoul::Boolean::No, ghoul::Boolean::Yes); + + // Remove all files that don't have as extension + _sourceFiles.erase(std::remove_if(_sourceFiles.begin(), _sourceFiles.end(), + [inputFileType] (string str) { + const size_t EXT_LENGTH = inputFileType.length(); + string sub = str.substr(str.length() - EXT_LENGTH, EXT_LENGTH); + std::transform(sub.begin(), sub.end(), sub.begin(), ::tolower); + return sub != inputFileType; + }), _sourceFiles.end()); + } else { + LERRORC("FieldlinesSequence", sourceFolderPath + " is not a valid directory!"); return; } } diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h index 0b111f6c37..1a4a6f8875 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h @@ -47,6 +47,8 @@ private: std::string _loggerCat = "RenderableFieldlinesSequence"; std::vector _states; + std::vector _sourceFiles; + }; } // namespace openspace From 2e4108093b70c62b54f6017982e6c4830865f57d Mon Sep 17 00:00:00 2001 From: Oskar Carlbaum Date: Tue, 19 Sep 2017 03:46:25 +0200 Subject: [PATCH 05/39] Add member variables and function to read osfls files to FieldlinesState --- .../util/fieldlinesstate.cpp | 80 +++++++++++++++++++ .../fieldlinessequence/util/fieldlinesstate.h | 33 ++++++++ 2 files changed, 113 insertions(+) diff --git a/modules/fieldlinessequence/util/fieldlinesstate.cpp b/modules/fieldlinessequence/util/fieldlinesstate.cpp index ca33976f63..6336736d58 100644 --- a/modules/fieldlinessequence/util/fieldlinesstate.cpp +++ b/modules/fieldlinessequence/util/fieldlinesstate.cpp @@ -24,8 +24,88 @@ #include +#include + +#include + namespace openspace { FieldlinesState::FieldlinesState() {} +FieldlinesState::FieldlinesState(const std::string& PATH_TO_OSFLS_FILE, bool& loadSucessful) { + loadSucessful = loadStateFromOsfls(PATH_TO_OSFLS_FILE); +} + +bool FieldlinesState::loadStateFromOsfls(const std::string& PATH_TO_OSFLS_FILE) { + std::ifstream ifs(PATH_TO_OSFLS_FILE, std::ifstream::binary); + if (!ifs.is_open()) { + LERRORC("FieldlinesState", "Couldn't open file: " + PATH_TO_OSFLS_FILE); + return false; + } + + int binFileVersion; + ifs.read( reinterpret_cast(&binFileVersion), sizeof(int)); + + switch (binFileVersion) { + case 0 : { + // No need to put everything in this scope now, as only version 0 exists! + } + break; + default : + LERRORC("FieldlinesState","VERSION OF BINARY FILE WAS NOT RECOGNISED!"); + return false; + } + + // Define tmp variables to store meta data in + size_t numLines; + size_t numPoints; + size_t numExtras; + size_t byteSizeAllNames; + + // Read single value variables + ifs.read( reinterpret_cast(&_triggerTime), sizeof(double)); + ifs.read( reinterpret_cast(&_model), sizeof(int)); + ifs.read( reinterpret_cast(&_isMorphable), sizeof(bool)); + ifs.read( reinterpret_cast(&numLines), sizeof(size_t)); + ifs.read( reinterpret_cast(&numPoints), sizeof(size_t)); + ifs.read( reinterpret_cast(&numExtras), sizeof(size_t)); + ifs.read( reinterpret_cast(&byteSizeAllNames), sizeof(size_t)); + + // RESERVE/RESIZE vectors + // TODO: Do this without initializing values? Resize is slower than just using reserve, due to initialization of all values + _lineStart.resize(numLines); + _lineCount.resize(numLines); + _vertexPositions.resize(numPoints); + _extraVariables.resize(numExtras); + _extraVariableNames.reserve(numExtras); + + // Read vertex position data + ifs.read( reinterpret_cast(_lineStart.data()), sizeof(GLint)*numLines); + ifs.read( reinterpret_cast(_lineCount.data()), sizeof(GLsizei)*numLines); + ifs.read( reinterpret_cast(_vertexPositions.data()), sizeof(glm::vec3)*numPoints); + + // Read all extra variables + for (std::vector& vec : _extraVariables) { + vec.resize(numPoints); + ifs.read( reinterpret_cast(vec.data()), sizeof(float) * numPoints); + } + + // Read all extra variables' names. Stored as multiple c-strings + std::string allNamesInOne; + char* s = new char[byteSizeAllNames]; + ifs.read(s, byteSizeAllNames); + allNamesInOne.assign(s, byteSizeAllNames); + delete[] s; + + size_t offset = 0; + for (size_t i = 0; i < numExtras; ++i) { + auto endOfVarName = allNamesInOne.find('\0', offset); + endOfVarName -= offset; + std::string varName = allNamesInOne.substr(offset, endOfVarName); + offset += varName.size() + 1; + _extraVariableNames.push_back(varName); + } + + return true; +} } // namespace openspace diff --git a/modules/fieldlinessequence/util/fieldlinesstate.h b/modules/fieldlinessequence/util/fieldlinesstate.h index 584c06608d..e2145df1cf 100644 --- a/modules/fieldlinessequence/util/fieldlinesstate.h +++ b/modules/fieldlinessequence/util/fieldlinesstate.h @@ -25,12 +25,45 @@ #ifndef __OPENSPACE_MODULE_FIELDLINESSEQUENCE___FIELDLINESSTATE___H__ #define __OPENSPACE_MODULE_FIELDLINESSEQUENCE___FIELDLINESSTATE___H__ +#include +#include + +#include +#include + namespace openspace { class FieldlinesState { public: + enum Model : int { + batsrus = 0, + enlil = 1, + pfss = 2 + }; + FieldlinesState(); + FieldlinesState(const std::string& PATH_TO_OSFLS_FILE, bool& loadSucessful); + + bool loadStateFromOsfls(const std::string& PATH_TO_OSFLS_FILE); + + // Getters + double triggerTime() { return _triggerTime; } + Model model() { return _model; } + const std::vector& vertexPositions() { return _vertexPositions; } + const std::vector& lineStart() { return _lineStart; } + const std::vector& lineCount() { return _lineCount; } + private: + bool _isMorphable = false; + double _triggerTime = -1.0; + Model _model; + + std::vector _vertexPositions; + std::vector _lineStart; + std::vector _lineCount; + std::vector> _extraVariables; + std::vector _extraVariableNames; + // TODO: Maybe introduce a vector containing seed point indices }; } // namespace openspace From 4f51dafae3b6aeca2f8b492f36b26a8bc9514976 Mon Sep 17 00:00:00 2001 From: Oskar Carlbaum Date: Wed, 20 Sep 2017 06:58:57 +0200 Subject: [PATCH 06/39] Place _loggercat in empty namespace of .cpp instead of storing it as a member variable --- .../renderablefieldlinessequence.cpp | 28 +++++++++---------- .../rendering/renderablefieldlinessequence.h | 1 - 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp index 512326a7c3..172bdc8033 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp @@ -31,6 +31,8 @@ using std::string; namespace { + std::string _loggerCat = "RenderableFieldlinesSequence"; + // ----- KEYS POSSIBLE IN MODFILE. EXPECTED DATA TYPE OF VALUE IN [BRACKETS] ----- // // ---------------------------- MANDATORY MODFILE KEYS ---------------------------- // const char* KEY_INPUT_FILE_TYPE = "InputFileType"; // [STRING] @@ -49,41 +51,39 @@ RenderableFieldlinesSequence::RenderableFieldlinesSequence(const ghoul::Dictiona string name; dictionary.getValue(SceneGraphNode::KeyName, name); - - _loggerCat += " [" + name + "]"; + name += ": "; // ------------------- EXTRACT MANDATORY VALUES FROM DICTIONARY ------------------- // - string inputFileType; - if(!dictionary.getValue(KEY_INPUT_FILE_TYPE, inputFileType)) { - LERRORC("FieldlinesSequence", - "The field " + string(KEY_INPUT_FILE_TYPE) + " is missing!"); + string inputFileTypeValue; + if(!dictionary.getValue(KEY_INPUT_FILE_TYPE, inputFileTypeValue)) { + LERROR(name << "The field " << string(KEY_INPUT_FILE_TYPE) << " is missing!"); return; } string sourceFolderPath; if(!dictionary.getValue(KEY_SOURCE_FOLDER, sourceFolderPath)) { - LERRORC("FieldlinesSequence", - "The field " + string(KEY_SOURCE_FOLDER) + " is missing!"); + LERROR(name << "The field " << string(KEY_SOURCE_FOLDER) << " is missing!"); return; } // Ensure that the source folder exists and then extract - // the files with the same extension as + // the files with the same extension as ghoul::filesystem::Directory sourceFolder(sourceFolderPath); if (FileSys.directoryExists(sourceFolder)) { // Extract all file paths from the provided folder (Non-recursively! Sorted!) _sourceFiles = sourceFolder.readFiles(ghoul::Boolean::No, ghoul::Boolean::Yes); - // Remove all files that don't have as extension + // Remove all files that don't have as extension _sourceFiles.erase(std::remove_if(_sourceFiles.begin(), _sourceFiles.end(), - [inputFileType] (string str) { - const size_t EXT_LENGTH = inputFileType.length(); + [inputFileTypeValue] (string str) { + const size_t EXT_LENGTH = inputFileTypeValue.length(); string sub = str.substr(str.length() - EXT_LENGTH, EXT_LENGTH); std::transform(sub.begin(), sub.end(), sub.begin(), ::tolower); - return sub != inputFileType; + return sub != inputFileTypeValue; }), _sourceFiles.end()); } else { - LERRORC("FieldlinesSequence", sourceFolderPath + " is not a valid directory!"); + LERROR(name << "FieldlinesSequence" << sourceFolderPath + << " is not a valid directory!"); return; } } diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h index 1a4a6f8875..413320cda4 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h @@ -44,7 +44,6 @@ public: void render(const RenderData& data, RendererTasks& rendererTask) override; void update(const UpdateData& data) override; private: - std::string _loggerCat = "RenderableFieldlinesSequence"; std::vector _states; std::vector _sourceFiles; From 94d0cc3ddd3b65cf692f10e015cd7ee105eea78b Mon Sep 17 00:00:00 2001 From: Oskar Carlbaum Date: Wed, 20 Sep 2017 17:52:10 +0200 Subject: [PATCH 07/39] Handle inputs from modfile Dictionary in separate function --- .../renderablefieldlinessequence.cpp | 105 ++++++++++++++---- .../rendering/renderablefieldlinessequence.h | 12 +- 2 files changed, 97 insertions(+), 20 deletions(-) diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp index 172bdc8033..9dc65fecab 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp @@ -38,6 +38,9 @@ namespace { const char* KEY_INPUT_FILE_TYPE = "InputFileType"; // [STRING] const char* KEY_SOURCE_FOLDER = "SourceFolder"; // [STRING] + // ---------------------------- OPTIONAL MODFILE KEYS ---------------------------- // + const char* KEY_OSLFS_LOAD_AT_RUNTIME = "LoadAtRuntime"; // [BOOLEAN] If value False => Load in initializing step and store in RAM + // ------------- POSSIBLE STRING VALUES FOR CORRESPONDING MODFILE KEY ------------- // const char* VALUE_INPUT_FILE_TYPE_CDF = "cdf"; const char* VALUE_INPUT_FILE_TYPE_JSON = "json"; @@ -49,6 +52,44 @@ namespace openspace { RenderableFieldlinesSequence::RenderableFieldlinesSequence(const ghoul::Dictionary& dictionary) : Renderable(dictionary) { + if(!extractInfoFromDictionary(dictionary)) { + _sourceFileType = INVALID; + } + +} + +void RenderableFieldlinesSequence::initialize() { + switch (_sourceFileType) { + case CDF: + LERROR("CDF NOT YET IMPLEMENTED!"); + break; + case JSON: + LERROR("JSON NOT YET IMPLEMENTED!"); + break; + case OSFLS: + LERROR("OSFLS NOT YET IMPLEMENTED!"); + break; + default: + break; + } +} + +void RenderableFieldlinesSequence::deinitialize() { +} + +bool RenderableFieldlinesSequence::isReady() const { + return true; +} + +void RenderableFieldlinesSequence::render(const RenderData& data, RendererTasks&) { +} + +void RenderableFieldlinesSequence::update(const UpdateData& data) { +} + +bool RenderableFieldlinesSequence::extractInfoFromDictionary( + const ghoul::Dictionary& dictionary) { + string name; dictionary.getValue(SceneGraphNode::KeyName, name); name += ": "; @@ -57,13 +98,29 @@ RenderableFieldlinesSequence::RenderableFieldlinesSequence(const ghoul::Dictiona string inputFileTypeValue; if(!dictionary.getValue(KEY_INPUT_FILE_TYPE, inputFileTypeValue)) { LERROR(name << "The field " << string(KEY_INPUT_FILE_TYPE) << " is missing!"); - return; + return false; + } else { + std::transform(inputFileTypeValue.begin(), inputFileTypeValue.end(), + inputFileTypeValue.begin(), ::tolower); + // Verify that the input type is correct + if (inputFileTypeValue == VALUE_INPUT_FILE_TYPE_CDF) { + _sourceFileType = CDF; + } else if (inputFileTypeValue == VALUE_INPUT_FILE_TYPE_JSON) { + _sourceFileType = JSON; + } else if (inputFileTypeValue == VALUE_INPUT_FILE_TYPE_OSFLS) { + _sourceFileType = OSFLS; + } else { + LERROR(name << inputFileTypeValue << " is not a recognised " + << KEY_INPUT_FILE_TYPE); + _sourceFileType = INVALID; + return false; + } } string sourceFolderPath; if(!dictionary.getValue(KEY_SOURCE_FOLDER, sourceFolderPath)) { LERROR(name << "The field " << string(KEY_SOURCE_FOLDER) << " is missing!"); - return; + return false; } // Ensure that the source folder exists and then extract @@ -81,27 +138,37 @@ RenderableFieldlinesSequence::RenderableFieldlinesSequence(const ghoul::Dictiona std::transform(sub.begin(), sub.end(), sub.begin(), ::tolower); return sub != inputFileTypeValue; }), _sourceFiles.end()); + // Ensure that there are available and valid source files left + if (_sourceFiles.empty()) { + LERROR(name << sourceFolderPath << " contains no ." << inputFileTypeValue + << " files!"); + return false; + } } else { LERROR(name << "FieldlinesSequence" << sourceFolderPath << " is not a valid directory!"); - return; + return false; + } + + switch (_sourceFileType) { + case CDF: + LERROR(name << "CDF NOT YET IMPLEMENTED!"); + break; + case JSON: + LERROR(name << "JSON NOT YET IMPLEMENTED!"); + break; + case OSFLS: { + bool shouldLoadInRealtime = false; + if (dictionary.getValue(KEY_OSLFS_LOAD_AT_RUNTIME, shouldLoadInRealtime)) { + _isLoadingStatesAtRuntime = shouldLoadInRealtime; + } else { + LWARNING(name << KEY_OSLFS_LOAD_AT_RUNTIME << + " isn't specified! Fieldline states will be stored in RAM"); + } + } break; + default: + break; } } -void RenderableFieldlinesSequence::initialize() { -} - -void RenderableFieldlinesSequence::deinitialize() { -} - -bool RenderableFieldlinesSequence::isReady() const { - return true; -} - -void RenderableFieldlinesSequence::render(const RenderData& data, RendererTasks&) { -} - -void RenderableFieldlinesSequence::update(const UpdateData& data) { -} - } // namespace openspace diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h index 413320cda4..8cc0328d00 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h @@ -44,10 +44,20 @@ public: void render(const RenderData& data, RendererTasks& rendererTask) override; void update(const UpdateData& data) override; private: + enum SourceFileType : int { + CDF = 0, + JSON, + OSFLS, + INVALID + }; + + bool _isLoadingStatesAtRuntime = false; // False => loading osfls at runtime + SourceFileType _sourceFileType; std::vector _states; - std::vector _sourceFiles; + std::vector _sourceFiles; // Stored in RAM if files are loaded at runtime, else emptied after initialization + bool extractInfoFromDictionary(const ghoul::Dictionary& dictionary); }; } // namespace openspace From 8ff9cb403eea09389a2e411be6bbca74926ed559 Mon Sep 17 00:00:00 2001 From: Oskar Carlbaum Date: Wed, 20 Sep 2017 18:02:01 +0200 Subject: [PATCH 08/39] Load OSFLS states into RAM and keep track of trigger times --- .../renderablefieldlinessequence.cpp | 29 ++++++++++++++++++- .../rendering/renderablefieldlinessequence.h | 4 +++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp index 9dc65fecab..0c250825ad 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp @@ -67,11 +67,25 @@ void RenderableFieldlinesSequence::initialize() { LERROR("JSON NOT YET IMPLEMENTED!"); break; case OSFLS: - LERROR("OSFLS NOT YET IMPLEMENTED!"); + if (_isLoadingStatesAtRuntime) { + LERROR("OSFLS LOAD AT RUNTIME NOT YET IMPLEMENTED!"); + } else { + for (string filePath : _sourceFiles) { + FieldlinesState newState; + bool loadedSuccessfully = newState.loadStateFromOsfls(filePath); + if (loadedSuccessfully) { + _states.push_back(newState); + _startTimes.push_back(newState.triggerTime()); + _nStates++; + } + } + } break; default: break; } + + computeSequenceEndTime(); } void RenderableFieldlinesSequence::deinitialize() { @@ -171,4 +185,17 @@ bool RenderableFieldlinesSequence::extractInfoFromDictionary( } } +// Calculate expected end time. +void RenderableFieldlinesSequence::computeSequenceEndTime() { + if (_nStates > 1) { + const double LAST_TRIGGER_TIME = _startTimes[_nStates - 1]; + const double SEQUENCE_DURATION = LAST_TRIGGER_TIME - _startTimes[0]; + const double AVERAGE_STATE_DURATION = SEQUENCE_DURATION / (static_cast(_nStates) - 1.0); + _sequenceEndTime = LAST_TRIGGER_TIME + AVERAGE_STATE_DURATION; + } else { + // If there's just one state it should never disappear! + _sequenceEndTime = DBL_MAX; + } +} + } // namespace openspace diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h index 8cc0328d00..8e3ebdddaf 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h @@ -52,11 +52,15 @@ private: }; bool _isLoadingStatesAtRuntime = false; // False => loading osfls at runtime + size_t _nStates = 0; + double _sequenceEndTime; SourceFileType _sourceFileType; + std::vector _startTimes; std::vector _states; std::vector _sourceFiles; // Stored in RAM if files are loaded at runtime, else emptied after initialization + void computeSequenceEndTime(); bool extractInfoFromDictionary(const ghoul::Dictionary& dictionary); }; From 5882c16bcc3e80f7348c21feae4ead693dc4f769 Mon Sep 17 00:00:00 2001 From: Oskar Carlbaum Date: Wed, 20 Sep 2017 18:08:21 +0200 Subject: [PATCH 09/39] Add functionality for checking which state should be shown, depending on time --- .../renderablefieldlinessequence.cpp | 45 +++++++++++++++++++ .../rendering/renderablefieldlinessequence.h | 4 ++ 2 files changed, 49 insertions(+) diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp index 0c250825ad..7abe27eff5 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp @@ -99,6 +99,51 @@ void RenderableFieldlinesSequence::render(const RenderData& data, RendererTasks& } void RenderableFieldlinesSequence::update(const UpdateData& data) { + // This node shouldn't do anything if its been disabled from the gui! + if (_enabled) { + const double CURRENT_TIME = data.time.j2000Seconds(); + // Check if current time in OpenSpace is within sequence interval + if (isWithinSequenceInterval(CURRENT_TIME)) { + const int NEXT_IDX = _activeStateIndex + 1; + if (_activeStateIndex < 0 // true => Previous frame was not within the sequence interval + || CURRENT_TIME < _startTimes[_activeStateIndex] // true => OpenSpace has stepped back to a time represented by another state + || (NEXT_IDX < _nStates && CURRENT_TIME >= _startTimes[NEXT_IDX])) { // true => OpenSpace has stepped forward to a time represented by another state + + updateActiveStateIndex(CURRENT_TIME); + _needsUpdate = true; + } // else {we're still in same state as previous frame (no changes needed)} + } else { + // Not in interval => set everything to false + _activeStateIndex = -1; + _needsUpdate = false; + } + + if (_needsUpdate) { + // Update States + // ... + // ... + // Everything is set and ready for rendering! + _needsUpdate = false; + } + } +} + +inline bool RenderableFieldlinesSequence::isWithinSequenceInterval(const double CURRENT_TIME) { + return (CURRENT_TIME >= _startTimes[0]) && (CURRENT_TIME < _sequenceEndTime); +} + +// Assumes we already know that CURRENT_TIME is within the sequence interval +void RenderableFieldlinesSequence::updateActiveStateIndex(const double CURRENT_TIME) { + auto iter = std::upper_bound(_startTimes.begin(), _startTimes.end(), CURRENT_TIME); + if (iter != _startTimes.end()) { + if ( iter != _startTimes.begin()) { + _activeStateIndex = std::distance(_startTimes.begin(), iter) - 1; + } else { + _activeStateIndex = 0; + } + } else { + _activeStateIndex = _nStates - 1; + } } bool RenderableFieldlinesSequence::extractInfoFromDictionary( diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h index 8e3ebdddaf..56b39b4d5b 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h @@ -51,6 +51,8 @@ private: INVALID }; + int _activeStateIndex = -1; + bool _needsUpdate = false; // If still in same state as previous frame == false bool _isLoadingStatesAtRuntime = false; // False => loading osfls at runtime size_t _nStates = 0; double _sequenceEndTime; @@ -62,6 +64,8 @@ private: void computeSequenceEndTime(); bool extractInfoFromDictionary(const ghoul::Dictionary& dictionary); + inline bool isWithinSequenceInterval(const double CURRENT_TIME); + inline void updateActiveStateIndex(const double CURRENT_TIME); }; } // namespace openspace From 42d49ecc5561c821ed7c238d21b568489243fa9e Mon Sep 17 00:00:00 2001 From: Oskar Carlbaum Date: Wed, 20 Sep 2017 18:44:21 +0200 Subject: [PATCH 10/39] Setup OpenGL variables and shaders and draw field lines --- modules/fieldlinessequence/CMakeLists.txt | 2 + .../renderablefieldlinessequence.cpp | 80 ++++++++++++++++++- .../rendering/renderablefieldlinessequence.h | 9 +++ .../shaders/fieldlinessequence_fs.glsl | 43 ++++++++++ .../shaders/fieldlinessequence_vs.glsl | 42 ++++++++++ 5 files changed, 173 insertions(+), 3 deletions(-) create mode 100644 modules/fieldlinessequence/shaders/fieldlinessequence_fs.glsl create mode 100644 modules/fieldlinessequence/shaders/fieldlinessequence_vs.glsl diff --git a/modules/fieldlinessequence/CMakeLists.txt b/modules/fieldlinessequence/CMakeLists.txt index 32a65b9163..33a0b287ec 100644 --- a/modules/fieldlinessequence/CMakeLists.txt +++ b/modules/fieldlinessequence/CMakeLists.txt @@ -37,6 +37,8 @@ set(SOURCE_FILES source_group("Source Files" FILES ${SOURCE_FILES}) set(SHADER_FILES + ${CMAKE_CURRENT_SOURCE_DIR}/shaders/fieldlinessequence_vs.glsl + ${CMAKE_CURRENT_SOURCE_DIR}/shaders/fieldlinessequence_fs.glsl ) source_group("Shader Files" FILES ${SHADER_FILES}) diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp index 7abe27eff5..eb5831e681 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp @@ -24,9 +24,14 @@ #include +#include +#include #include +#include + #include +#include using std::string; @@ -86,9 +91,36 @@ void RenderableFieldlinesSequence::initialize() { } computeSequenceEndTime(); + + // Setup shader program + _shaderProgram = OsEng.renderEngine().buildRenderProgram( + "FieldlinesSequence", + "${MODULE_FIELDLINESSEQUENCE}/shaders/fieldlinessequence_vs.glsl", + "${MODULE_FIELDLINESSEQUENCE}/shaders/fieldlinessequence_fs.glsl" + ); + + if (!_shaderProgram) { + LERROR("Shader program failed initialization!"); + _sourceFileType = INVALID; + } + + //------------------ Initialize OpenGL VBOs and VAOs-------------------------------// + glGenVertexArrays(1, &_vertexArrayObject); + glGenBuffers(1, &_vertexPositionBuffer); } void RenderableFieldlinesSequence::deinitialize() { + glDeleteVertexArrays(1, &_vertexArrayObject); + _vertexArrayObject = 0; + + glDeleteBuffers(1, &_vertexPositionBuffer); + _vertexPositionBuffer = 0; + + RenderEngine& renderEngine = OsEng.renderEngine(); + if (_shaderProgram) { + renderEngine.removeRenderProgram(_shaderProgram); + _shaderProgram = nullptr; + } } bool RenderableFieldlinesSequence::isReady() const { @@ -96,9 +128,38 @@ bool RenderableFieldlinesSequence::isReady() const { } void RenderableFieldlinesSequence::render(const RenderData& data, RendererTasks&) { + if (_activeStateIndex != -1) { + _shaderProgram->activate(); + + const glm::dmat4 ROTATION_TRANSFORM = glm::dmat4(data.modelTransform.rotation); + // const glm::mat4 SCALE_TRANSFORM = glm::mat4(1.0); // TODO remove if no use + const glm::dmat4 MODEL_TRANSFORM = + glm::translate(glm::dmat4(1.0), data.modelTransform.translation) * + ROTATION_TRANSFORM * + glm::dmat4(glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale))); + const glm::dmat4 MODEL_VIEW_TRANSFORM = data.camera.combinedViewMatrix() * MODEL_TRANSFORM; + + _shaderProgram->setUniform("modelViewProjection", + data.camera.sgctInternal.projectionMatrix() * glm::mat4(MODEL_VIEW_TRANSFORM)); + + glBindVertexArray(_vertexArrayObject); + glMultiDrawArrays( + GL_LINE_STRIP, //_drawingOutputType, + _states[_activeStateIndex].lineStart().data(), + _states[_activeStateIndex].lineCount().data(), + static_cast(_states[_activeStateIndex].lineStart().size()) + ); + + glBindVertexArray(0); + _shaderProgram->deactivate(); + } } void RenderableFieldlinesSequence::update(const UpdateData& data) { + if (_shaderProgram->isDirty()) { + _shaderProgram->rebuildFromFile(); + } + // This node shouldn't do anything if its been disabled from the gui! if (_enabled) { const double CURRENT_TIME = data.time.j2000Seconds(); @@ -119,9 +180,22 @@ void RenderableFieldlinesSequence::update(const UpdateData& data) { } if (_needsUpdate) { - // Update States - // ... - // ... + glBindVertexArray(_vertexArrayObject); + glBindBuffer(GL_ARRAY_BUFFER, _vertexPositionBuffer); + + const std::vector& VERTEX_POS_VEC = + _states[_activeStateIndex].vertexPositions(); + + glBufferData(GL_ARRAY_BUFFER, VERTEX_POS_VEC.size() * sizeof(glm::vec3), + &VERTEX_POS_VEC.front(), GL_STATIC_DRAW); + + glEnableVertexAttribArray(_vertAttrVertexPos); + glVertexAttribPointer(_vertAttrVertexPos, 3, GL_FLOAT, GL_FALSE, 0, 0); + + // UNBIND + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); + // Everything is set and ready for rendering! _needsUpdate = false; } diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h index 56b39b4d5b..9f5c44d45a 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h @@ -58,10 +58,19 @@ private: double _sequenceEndTime; SourceFileType _sourceFileType; + std::unique_ptr _shaderProgram; + std::vector _startTimes; std::vector _states; std::vector _sourceFiles; // Stored in RAM if files are loaded at runtime, else emptied after initialization + GLuint _vertexArrayObject = 0; + GLuint _vertexPositionBuffer = 0; + + // THESE MUST CORRESPOND TO THE SHADER PROGRAM + // TODO: THIS CAN BE DETERMINED BY ASKING THE SHADER PROGRAM TOO + GLuint _vertAttrVertexPos = 0; + void computeSequenceEndTime(); bool extractInfoFromDictionary(const ghoul::Dictionary& dictionary); inline bool isWithinSequenceInterval(const double CURRENT_TIME); diff --git a/modules/fieldlinessequence/shaders/fieldlinessequence_fs.glsl b/modules/fieldlinessequence/shaders/fieldlinessequence_fs.glsl new file mode 100644 index 0000000000..8e8f3ec6d3 --- /dev/null +++ b/modules/fieldlinessequence/shaders/fieldlinessequence_fs.glsl @@ -0,0 +1,43 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2017 * + * * + * 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. * + ****************************************************************************************/ + +in vec4 vs_color; +in float vs_depth; + +#include "fragment.glsl" +#include "PowerScaling/powerScaling_fs.hglsl" + +Fragment getFragment() { + if (vs_color.a == 0) { + discard; + } + + vec4 fragColor = vs_color; + + Fragment frag; + frag.depth = vs_depth; + frag.color = fragColor; + + return frag; +} diff --git a/modules/fieldlinessequence/shaders/fieldlinessequence_vs.glsl b/modules/fieldlinessequence/shaders/fieldlinessequence_vs.glsl new file mode 100644 index 0000000000..cc6f48bc93 --- /dev/null +++ b/modules/fieldlinessequence/shaders/fieldlinessequence_vs.glsl @@ -0,0 +1,42 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2017 * + * * + * 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. * + ****************************************************************************************/ + +#version __CONTEXT__ + +uniform mat4 modelViewProjection; + +layout(location = 0) in vec3 in_position; // in meters + +out vec4 vs_color; +out float vs_depth; + +#include "PowerScaling/powerScaling_vs.hglsl" + +void main() { + vs_color = vec4(0.75, 0.5, 0.0, 0.75); + vec4 position_in_meters = vec4(in_position, 1); + vec4 positionClipSpace = modelViewProjection * position_in_meters; + gl_Position = z_normalization(positionClipSpace); + vs_depth = gl_Position.w; +} From eea7c7306a818c712fe98ba0a146b0a0c46ce67c Mon Sep 17 00:00:00 2001 From: Oskar Carlbaum Date: Thu, 21 Sep 2017 01:21:05 +0200 Subject: [PATCH 11/39] Add functionality to illustrate magnetic flow --- .../renderablefieldlinessequence.cpp | 69 ++++++++++++++++--- .../rendering/renderablefieldlinessequence.h | 15 ++++ .../shaders/fieldlinessequence_vs.glsl | 28 +++++++- 3 files changed, 101 insertions(+), 11 deletions(-) diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp index eb5831e681..fa6dfe77ef 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp @@ -50,12 +50,44 @@ namespace { const char* VALUE_INPUT_FILE_TYPE_CDF = "cdf"; const char* VALUE_INPUT_FILE_TYPE_JSON = "json"; const char* VALUE_INPUT_FILE_TYPE_OSFLS = "osfls"; + + static const openspace::properties::Property::PropertyInfo LineColorInfo = { + "lineColor", "Line Color", "Color of lines." + }; + static const openspace::properties::Property::PropertyInfo EnableFlowInfo = { + "Enable", "ON/OFF", + "Toggles the rendering of moving particles along the lines. Can e.g. illustrate magnetic flow." + }; + static const openspace::properties::Property::PropertyInfo ReverseFlowInfo = { + "reversed", "Reversed Flow", "Toggle to make the flow move in the opposite direction." + }; + static const openspace::properties::Property::PropertyInfo ParticleSizeInfo = { + "particleSize", "Particle Size", "Size of the particles." + }; + static const openspace::properties::Property::PropertyInfo ParticleSpacingInfo = { + "particleSpacing", "Particle Spacing", "Spacing inbetween particles." + }; + static const openspace::properties::Property::PropertyInfo FlowSpeedInfo = { + "speed", "Speed", "Speed of the flow." + }; + static const openspace::properties::Property::PropertyInfo FlowColorInfo = { + "color", "Color", "Color of particles." + }; } // namespace namespace openspace { RenderableFieldlinesSequence::RenderableFieldlinesSequence(const ghoul::Dictionary& dictionary) - : Renderable(dictionary) { + : Renderable(dictionary), + _lineColor(LineColorInfo, glm::vec4(0.75f, 0.5f, 0.0f, 0.5f), glm::vec4(0.f), glm::vec4(1.f)), + _flowGroup({ "Flow" }), + _flowEnabled(EnableFlowInfo, true), + _flowReversed(ReverseFlowInfo, false), + _flowParticleSize(ParticleSizeInfo, 5, 0, 500), + _flowParticleSpacing(ParticleSpacingInfo, 60, 0, 500), + _flowSpeed(FlowSpeedInfo, 20, 0, 1000), + _flowColor(FlowColorInfo, glm::vec4(0.8f, 0.7f, 0.0f, 0.6f), + glm::vec4(0.f), glm::vec4(1.f)) { if(!extractInfoFromDictionary(dictionary)) { _sourceFileType = INVALID; @@ -92,6 +124,16 @@ void RenderableFieldlinesSequence::initialize() { computeSequenceEndTime(); + // HANDLE PROPERTIES + addProperty(_lineColor); + addPropertySubOwner(_flowGroup); + _flowGroup.addProperty(_flowEnabled); + _flowGroup.addProperty(_flowReversed); + _flowGroup.addProperty(_flowColor); + _flowGroup.addProperty(_flowParticleSize); + _flowGroup.addProperty(_flowParticleSpacing); + _flowGroup.addProperty(_flowSpeed); + // Setup shader program _shaderProgram = OsEng.renderEngine().buildRenderProgram( "FieldlinesSequence", @@ -124,23 +166,32 @@ void RenderableFieldlinesSequence::deinitialize() { } bool RenderableFieldlinesSequence::isReady() const { - return true; + return _sourceFileType != INVALID; } void RenderableFieldlinesSequence::render(const RenderData& data, RendererTasks&) { if (_activeStateIndex != -1) { _shaderProgram->activate(); - const glm::dmat4 ROTATION_TRANSFORM = glm::dmat4(data.modelTransform.rotation); + const glm::dmat4 ROT_MAT = glm::dmat4(data.modelTransform.rotation); // const glm::mat4 SCALE_TRANSFORM = glm::mat4(1.0); // TODO remove if no use - const glm::dmat4 MODEL_TRANSFORM = + const glm::dmat4 MODEL_MAT = glm::translate(glm::dmat4(1.0), data.modelTransform.translation) * - ROTATION_TRANSFORM * - glm::dmat4(glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale))); - const glm::dmat4 MODEL_VIEW_TRANSFORM = data.camera.combinedViewMatrix() * MODEL_TRANSFORM; + ROT_MAT * + glm::dmat4(glm::scale(glm::dmat4(1), glm::dvec3(data.modelTransform.scale))); + const glm::dmat4 MODEL_VIEW_MAT = data.camera.combinedViewMatrix() * MODEL_MAT; _shaderProgram->setUniform("modelViewProjection", - data.camera.sgctInternal.projectionMatrix() * glm::mat4(MODEL_VIEW_TRANSFORM)); + data.camera.sgctInternal.projectionMatrix() * glm::mat4(MODEL_VIEW_MAT)); + + _shaderProgram->setUniform("lineColor", _lineColor); + // Flow/Particles + _shaderProgram->setUniform("usingParticles", _flowEnabled); + _shaderProgram->setUniform("flowColor", _flowColor); + _shaderProgram->setUniform("particleSize", _flowParticleSize); + _shaderProgram->setUniform("particleSpeed", _flowSpeed); + _shaderProgram->setUniform("particleSpacing", _flowParticleSpacing); + _shaderProgram->setUniform("time", OsEng.runTime() * (_flowReversed ? -1 : 1)); glBindVertexArray(_vertexArrayObject); glMultiDrawArrays( @@ -216,7 +267,7 @@ void RenderableFieldlinesSequence::updateActiveStateIndex(const double CURRENT_T _activeStateIndex = 0; } } else { - _activeStateIndex = _nStates - 1; + _activeStateIndex = static_cast(_nStates) - 1; } } diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h index 9f5c44d45a..aeb54134e7 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h @@ -27,6 +27,9 @@ #include +#include +#include + #include namespace openspace { @@ -71,6 +74,18 @@ private: // TODO: THIS CAN BE DETERMINED BY ASKING THE SHADER PROGRAM TOO GLuint _vertAttrVertexPos = 0; + // ----------------------------- Properties ----------------------------- + properties::Vec4Property _lineColor; // Uniform Field Line Color + + properties::PropertyOwner _flowGroup; + properties::BoolProperty _flowEnabled; // Toggle flow [ON/OFF] + properties::BoolProperty _flowReversed; // Toggle flow direction [FORWARDS/BACKWARDS] + properties::IntProperty _flowParticleSize; // Size of simulated flow particles + properties::IntProperty _flowParticleSpacing; // Size of simulated flow particles + properties::IntProperty _flowSpeed; // Speed of simulated flow + properties::Vec4Property _flowColor; // Simulated particles' color + + void computeSequenceEndTime(); bool extractInfoFromDictionary(const ghoul::Dictionary& dictionary); inline bool isWithinSequenceInterval(const double CURRENT_TIME); diff --git a/modules/fieldlinessequence/shaders/fieldlinessequence_vs.glsl b/modules/fieldlinessequence/shaders/fieldlinessequence_vs.glsl index cc6f48bc93..906953c7b7 100644 --- a/modules/fieldlinessequence/shaders/fieldlinessequence_vs.glsl +++ b/modules/fieldlinessequence/shaders/fieldlinessequence_vs.glsl @@ -24,7 +24,14 @@ #version __CONTEXT__ -uniform mat4 modelViewProjection; +uniform mat4 modelViewProjection; +uniform bool usingParticles; +uniform double time; +uniform int particleSize; +uniform int particleSpeed; +uniform int particleSpacing; +uniform vec4 flowColor; +uniform vec4 lineColor; layout(location = 0) in vec3 in_position; // in meters @@ -33,8 +40,25 @@ out float vs_depth; #include "PowerScaling/powerScaling_vs.hglsl" +bool isPartOfParticle(const double TIME, const int VERTEX_ID, const int PARTICLE_SIZE, + const int PARTICLE_SPEED, const int PARTICLE_SPACING) { + const int MODULUS_RESULT = int(double(PARTICLE_SPEED) * TIME + VERTEX_ID) % PARTICLE_SPACING; + return MODULUS_RESULT > 0 && MODULUS_RESULT <= PARTICLE_SIZE; +} + void main() { - vs_color = vec4(0.75, 0.5, 0.0, 0.75); + + const bool IS_PARTICLE = usingParticles && isPartOfParticle(time, gl_VertexID, + particleSize, + particleSpeed, + particleSpacing); + + if (IS_PARTICLE) { + vs_color = flowColor; + } else { + vs_color = lineColor; + } + vec4 position_in_meters = vec4(in_position, 1); vec4 positionClipSpace = modelViewProjection * position_in_meters; gl_Position = z_normalization(positionClipSpace); From ec8c3c5ea70f771cbb9b4ca47433992d588ae3ae Mon Sep 17 00:00:00 2001 From: Oskar Carlbaum Date: Thu, 21 Sep 2017 03:36:05 +0200 Subject: [PATCH 12/39] Add functionality for reading and displaying OSFLS files during runtime --- .../renderablefieldlinessequence.cpp | 108 +++++++++++++++--- .../rendering/renderablefieldlinessequence.h | 26 +++-- 2 files changed, 112 insertions(+), 22 deletions(-) diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp index fa6dfe77ef..bbf6fec31f 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp @@ -105,8 +105,19 @@ void RenderableFieldlinesSequence::initialize() { break; case OSFLS: if (_isLoadingStatesAtRuntime) { - LERROR("OSFLS LOAD AT RUNTIME NOT YET IMPLEMENTED!"); + extractTriggerTimesFromFileNames(); + FieldlinesState newState; + bool loadedSuccessfully = newState.loadStateFromOsfls(_sourceFiles[0]); + if (loadedSuccessfully) { + _states.push_back(newState); + _nStates = _startTimes.size(); + _activeStateIndex = 0; + } else { + LERROR("The provided .osfls files seem to be corrupt!"); + _sourceFileType = INVALID; + } } else { + // Load states into RAM! for (string filePath : _sourceFiles) { FieldlinesState newState; bool loadedSuccessfully = newState.loadStateFromOsfls(filePath); @@ -122,6 +133,11 @@ void RenderableFieldlinesSequence::initialize() { break; } + // No need to store source paths in memory if their states are already in RAM! + if (!_isLoadingStatesAtRuntime) { + _sourceFiles.clear(); + } + computeSequenceEndTime(); // HANDLE PROPERTIES @@ -163,6 +179,11 @@ void RenderableFieldlinesSequence::deinitialize() { renderEngine.removeRenderProgram(_shaderProgram); _shaderProgram = nullptr; } + + // Stall main thread until thread that's loading states is done! + while (/*!_newStateIsReady &&*/ _isLoadingStateFromDisk) { + LWARNING("TRYING TO DESTROY CLASS WHEN A THREAD USING IT IS STILL ACTIVE"); + } } bool RenderableFieldlinesSequence::isReady() const { @@ -170,7 +191,7 @@ bool RenderableFieldlinesSequence::isReady() const { } void RenderableFieldlinesSequence::render(const RenderData& data, RendererTasks&) { - if (_activeStateIndex != -1) { + if (_activeTriggerTimeIndex != -1) { _shaderProgram->activate(); const glm::dmat4 ROT_MAT = glm::dmat4(data.modelTransform.rotation); @@ -216,21 +237,44 @@ void RenderableFieldlinesSequence::update(const UpdateData& data) { const double CURRENT_TIME = data.time.j2000Seconds(); // Check if current time in OpenSpace is within sequence interval if (isWithinSequenceInterval(CURRENT_TIME)) { - const int NEXT_IDX = _activeStateIndex + 1; - if (_activeStateIndex < 0 // true => Previous frame was not within the sequence interval - || CURRENT_TIME < _startTimes[_activeStateIndex] // true => OpenSpace has stepped back to a time represented by another state + const int NEXT_IDX = _activeTriggerTimeIndex + 1; + if (_activeTriggerTimeIndex < 0 // true => Previous frame was not within the sequence interval + || CURRENT_TIME < _startTimes[_activeTriggerTimeIndex] // true => OpenSpace has stepped back to a time represented by another state || (NEXT_IDX < _nStates && CURRENT_TIME >= _startTimes[NEXT_IDX])) { // true => OpenSpace has stepped forward to a time represented by another state - updateActiveStateIndex(CURRENT_TIME); - _needsUpdate = true; + updateActiveTriggerTimeIndex(CURRENT_TIME); + + if (_isLoadingStatesAtRuntime) { + _mustLoadNewStateFromDisk = true; + } else { + _needsUpdate = true; + _activeStateIndex = _activeTriggerTimeIndex; + } } // else {we're still in same state as previous frame (no changes needed)} } else { // Not in interval => set everything to false - _activeStateIndex = -1; - _needsUpdate = false; + _activeTriggerTimeIndex = -1; + _mustLoadNewStateFromDisk = false; + _needsUpdate = false; } - if (_needsUpdate) { + if (_mustLoadNewStateFromDisk) { + if (!_isLoadingStateFromDisk && !_newStateIsReady) { + _isLoadingStateFromDisk = true; + _mustLoadNewStateFromDisk = false; + const std::string FILEPATH = _sourceFiles[_activeTriggerTimeIndex]; + std::thread readBinaryThread([this, FILEPATH] { + this->readNewState(FILEPATH); + }); + readBinaryThread.detach(); + } + } + + if (_needsUpdate || _newStateIsReady) { + if (_isLoadingStatesAtRuntime) { + _states[0] = std::move(_newState); + } + glBindVertexArray(_vertexArrayObject); glBindBuffer(GL_ARRAY_BUFFER, _vertexPositionBuffer); @@ -249,6 +293,7 @@ void RenderableFieldlinesSequence::update(const UpdateData& data) { // Everything is set and ready for rendering! _needsUpdate = false; + _newStateIsReady = false; } } } @@ -258,19 +303,30 @@ inline bool RenderableFieldlinesSequence::isWithinSequenceInterval(const double } // Assumes we already know that CURRENT_TIME is within the sequence interval -void RenderableFieldlinesSequence::updateActiveStateIndex(const double CURRENT_TIME) { +void RenderableFieldlinesSequence::updateActiveTriggerTimeIndex(const double CURRENT_TIME) { auto iter = std::upper_bound(_startTimes.begin(), _startTimes.end(), CURRENT_TIME); if (iter != _startTimes.end()) { if ( iter != _startTimes.begin()) { - _activeStateIndex = std::distance(_startTimes.begin(), iter) - 1; + _activeTriggerTimeIndex = std::distance(_startTimes.begin(), iter) - 1; } else { - _activeStateIndex = 0; + _activeTriggerTimeIndex = 0; } } else { - _activeStateIndex = static_cast(_nStates) - 1; + _activeTriggerTimeIndex = static_cast(_nStates) - 1; } } +// Reading state from disk. Thread safe! +void RenderableFieldlinesSequence::readNewState(const std::string& FILEPATH) { + FieldlinesState newState; + + bool isSuccessful = newState.loadStateFromOsfls(FILEPATH); + _newState = std::move(newState); + + _newStateIsReady = true; + _isLoadingStateFromDisk = false; +} + bool RenderableFieldlinesSequence::extractInfoFromDictionary( const ghoul::Dictionary& dictionary) { @@ -347,7 +403,7 @@ bool RenderableFieldlinesSequence::extractInfoFromDictionary( _isLoadingStatesAtRuntime = shouldLoadInRealtime; } else { LWARNING(name << KEY_OSLFS_LOAD_AT_RUNTIME << - " isn't specified! Fieldline states will be stored in RAM"); + " isn't specified! OSFLS files will be loaded during runtime!"); } } break; default: @@ -368,4 +424,26 @@ void RenderableFieldlinesSequence::computeSequenceEndTime() { } } +// Extract J2000 time from file names +// Requires files to be named as such: 'YYYY-MM-DDTHH-MM-SS-XXX.osfls' +void RenderableFieldlinesSequence::extractTriggerTimesFromFileNames() { + const size_t FILENAME_SIZE = 23; // number of characters in filename (excluding '.osfls') + const size_t EXT_SIZE = 6; // size(".osfls") + + for (const std::string& FILEPATH : _sourceFiles) { + const size_t STR_LENGTH = FILEPATH.size(); + // Extract the filename from the path (without extension) + std::string timeString = FILEPATH.substr(STR_LENGTH - FILENAME_SIZE - EXT_SIZE, + FILENAME_SIZE - 1); + // Ensure the separators are correct + timeString.replace( 4, 1, "-"); + timeString.replace( 7, 1, "-"); + timeString.replace(13, 1, ":"); + timeString.replace(16, 1, ":"); + timeString.replace(19, 1, "."); + const double TRIGGER_TIME = Time::convertTime(timeString); + _startTimes.push_back(TRIGGER_TIME); + } +} + } // namespace openspace diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h index aeb54134e7..455c4f1f9a 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h @@ -32,6 +32,8 @@ #include +#include + namespace openspace { class RenderableFieldlinesSequence : public Renderable { @@ -54,12 +56,19 @@ private: INVALID }; - int _activeStateIndex = -1; - bool _needsUpdate = false; // If still in same state as previous frame == false - bool _isLoadingStatesAtRuntime = false; // False => loading osfls at runtime - size_t _nStates = 0; - double _sequenceEndTime; - SourceFileType _sourceFileType; + int _activeStateIndex = -1; + int _activeTriggerTimeIndex = -1; + bool _isLoadingStatesAtRuntime = true; // False => loading osfls at runtime + bool _mustLoadNewStateFromDisk = false; // If still in same state as previous frame == false + bool _needsUpdate = false; // If still in same state as previous frame == false + FieldlinesState _newState; + size_t _nStates = 0; + double _sequenceEndTime; + SourceFileType _sourceFileType; + + std::atomic _isLoadingStateFromDisk{false}; + std::atomic _newStateIsReady{false}; + std::unique_ptr _shaderProgram; @@ -88,8 +97,11 @@ private: void computeSequenceEndTime(); bool extractInfoFromDictionary(const ghoul::Dictionary& dictionary); + void extractTriggerTimesFromFileNames(); + void readNewState(const std::string& FILEPATH); + inline bool isWithinSequenceInterval(const double CURRENT_TIME); - inline void updateActiveStateIndex(const double CURRENT_TIME); + inline void updateActiveTriggerTimeIndex(const double CURRENT_TIME); }; } // namespace openspace From f442dd4f7c5f24fcf19b1d9793b999f9fee4de09 Mon Sep 17 00:00:00 2001 From: Oskar Carlbaum Date: Fri, 22 Sep 2017 04:30:44 +0200 Subject: [PATCH 13/39] Add functionality for coloring lines by different quantities --- .../renderablefieldlinessequence.cpp | 233 +++++++++++++++--- .../rendering/renderablefieldlinessequence.h | 55 +++-- .../shaders/fieldlinessequence_vs.glsl | 46 +++- .../util/fieldlinesstate.cpp | 13 + .../fieldlinessequence/util/fieldlinesstate.h | 30 ++- 5 files changed, 303 insertions(+), 74 deletions(-) diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp index bbf6fec31f..8a79820554 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp @@ -29,9 +29,9 @@ #include #include - #include #include +#include using std::string; @@ -44,6 +44,8 @@ namespace { const char* KEY_SOURCE_FOLDER = "SourceFolder"; // [STRING] // ---------------------------- OPTIONAL MODFILE KEYS ---------------------------- // + const char* KEY_COLOR_TABLE_PATHS = "ColorTablePaths"; // [STRING ARRAY] Values should be paths to .txt files + const char* KEY_COLOR_TABLE_RANGES = "ColorTableRanges";// [VEC2 ARRAY] Values should be paths to .txt files const char* KEY_OSLFS_LOAD_AT_RUNTIME = "LoadAtRuntime"; // [BOOLEAN] If value False => Load in initializing step and store in RAM // ------------- POSSIBLE STRING VALUES FOR CORRESPONDING MODFILE KEY ------------- // @@ -51,8 +53,26 @@ namespace { const char* VALUE_INPUT_FILE_TYPE_JSON = "json"; const char* VALUE_INPUT_FILE_TYPE_OSFLS = "osfls"; - static const openspace::properties::Property::PropertyInfo LineColorInfo = { - "lineColor", "Line Color", "Color of lines." + static const openspace::properties::Property::PropertyInfo ColorMethodInfo = { + "colorMethod", "Color Method", "Color lines uniformly or using color tables based on extra variables like e.g. temperature or particle density." + }; + static const openspace::properties::Property::PropertyInfo ColorQuantityInfo = { + "colorQuantity", "Quantity to Color By", "Quantity/variable used to color lines if the \"By Quantity\" color method is selected." + }; + static const openspace::properties::Property::PropertyInfo ColorQuantityMinInfo = { + "colorQuantityMin", "ColorTable Min Value", "Value to map to the lowest end of the color table." + }; + static const openspace::properties::Property::PropertyInfo ColorQuantityMaxInfo = { + "colorQuantityMax", "ColorTable Max Value", "Value to map to the highest end of the color table." + }; + static const openspace::properties::Property::PropertyInfo ColorTablePathInfo = { + "colorTablePath", "Path to Color Table", "Color Table/Transfer Function to use for \"By Quantity\" coloring." + }; + static const openspace::properties::Property::PropertyInfo ColorUniformInfo = { + "uniform", "Uniform Line Color", "The uniform color of lines shown when \"Color Method\" is set to \"Uniform\"." + }; + static const openspace::properties::Property::PropertyInfo FlowColorInfo = { + "color", "Color", "Color of particles." }; static const openspace::properties::Property::PropertyInfo EnableFlowInfo = { "Enable", "ON/OFF", @@ -70,29 +90,37 @@ namespace { static const openspace::properties::Property::PropertyInfo FlowSpeedInfo = { "speed", "Speed", "Speed of the flow." }; - static const openspace::properties::Property::PropertyInfo FlowColorInfo = { - "color", "Color", "Color of particles." - }; + + enum ColorMethod { UNIFORM = 0, BY_QUANTITY }; } // namespace namespace openspace { RenderableFieldlinesSequence::RenderableFieldlinesSequence(const ghoul::Dictionary& dictionary) : Renderable(dictionary), - _lineColor(LineColorInfo, glm::vec4(0.75f, 0.5f, 0.0f, 0.5f), glm::vec4(0.f), glm::vec4(1.f)), - _flowGroup({ "Flow" }), + _colorGroup({ "Color" }), + _colorMethod(ColorMethodInfo, properties::OptionProperty::DisplayType::Radio), + _colorQuantity(ColorQuantityInfo, properties::OptionProperty::DisplayType::Dropdown), + _colorQuantityMin(ColorQuantityMinInfo), + _colorQuantityMax(ColorQuantityMaxInfo), + _colorTablePath(ColorTablePathInfo), + _colorUniform(ColorUniformInfo, glm::vec4(0.75f, 0.5f, 0.0f, 0.5f), + glm::vec4(0.f), glm::vec4(1.f)), + _flowColor(FlowColorInfo, glm::vec4(0.8f, 0.7f, 0.0f, 0.6f), + glm::vec4(0.f), glm::vec4(1.f)), _flowEnabled(EnableFlowInfo, true), - _flowReversed(ReverseFlowInfo, false), + _flowGroup({ "Flow" }), _flowParticleSize(ParticleSizeInfo, 5, 0, 500), _flowParticleSpacing(ParticleSpacingInfo, 60, 0, 500), - _flowSpeed(FlowSpeedInfo, 20, 0, 1000), - _flowColor(FlowColorInfo, glm::vec4(0.8f, 0.7f, 0.0f, 0.6f), - glm::vec4(0.f), glm::vec4(1.f)) { + _flowReversed(ReverseFlowInfo, false), + _flowSpeed(FlowSpeedInfo, 20, 0, 1000) { + + // Set the default color table, just in case user defined paths are corrupt! + _transferFunction = std::make_shared(absPath(_colorTablePaths[0])); if(!extractInfoFromDictionary(dictionary)) { _sourceFileType = INVALID; } - } void RenderableFieldlinesSequence::initialize() { @@ -133,16 +161,27 @@ void RenderableFieldlinesSequence::initialize() { break; } - // No need to store source paths in memory if their states are already in RAM! + // At this point there's at least one state loaded into memory! + // No need to store source paths in memory if they are already in RAM! if (!_isLoadingStatesAtRuntime) { _sourceFiles.clear(); } computeSequenceEndTime(); - // HANDLE PROPERTIES - addProperty(_lineColor); + // --------------------- HANDLE PROPERTIES --------------------- // + // Add Property Groups + addPropertySubOwner(_colorGroup); addPropertySubOwner(_flowGroup); + + // Add Properties to the groups + _colorGroup.addProperty(_colorMethod); + _colorGroup.addProperty(_colorQuantity); + _colorGroup.addProperty(_colorQuantityMin); + _colorGroup.addProperty(_colorQuantityMax); + _colorGroup.addProperty(_colorTablePath); + _colorGroup.addProperty(_colorUniform); + _flowGroup.addProperty(_flowEnabled); _flowGroup.addProperty(_flowReversed); _flowGroup.addProperty(_flowColor); @@ -150,6 +189,52 @@ void RenderableFieldlinesSequence::initialize() { _flowGroup.addProperty(_flowParticleSpacing); _flowGroup.addProperty(_flowSpeed); + // Add Options to OptionProperties + _colorMethod.addOption(ColorMethod::UNIFORM, "Uniform"); + _colorMethod.addOption(ColorMethod::BY_QUANTITY, "By Quantity"); + + // Add option for each extra quantity. We assume that there are just as many names to + // extra variables as there are extra variables. We also assume that all states in the + // given sequence have the same extra variables! + const size_t N_EXTRA_QUANTITIES = _states[0].nExtraVariables(); + auto EXTRA_VARIABLE_NAMES_VEC = _states[0].extraVariableNames(); + for (size_t i = 0; i < N_EXTRA_QUANTITIES; ++i) { + _colorQuantity.addOption(i, EXTRA_VARIABLE_NAMES_VEC[i]); + } + // Each quantity should have its own color table and color table range, no more, no less + _colorTablePaths.resize(N_EXTRA_QUANTITIES, _colorTablePaths.back()); + _colorTableRanges.resize(N_EXTRA_QUANTITIES, _colorTableRanges.back()); + + // Add Property Callback Functions + _colorQuantity.onChange([this] { + LDEBUG("CHANGED COLORING QUANTITY"); + _shouldUpdateColorBuffer = true; + _colorQuantityMin = std::to_string(_colorTableRanges[_colorQuantity].x); + _colorQuantityMax = std::to_string(_colorTableRanges[_colorQuantity].y); + _activeColorTable = &_colorTablePaths[_colorQuantity]; + _colorTablePath = *_activeColorTable; + }); + + _colorTablePath.onChange([this] { + // TOGGLE ACTIVE SHADER PROGRAM + _transferFunction->setPath(_colorTablePath); + *_activeColorTable = _colorTablePath; + }); + + _colorQuantityMin.onChange([this] { + LDEBUG("CHANGED MIN VALUE"); + // TODO CHECK IF VALID NUMBER! + // _updateTransferFunctionMin = true; + _colorTableRanges[_colorQuantity].x = std::stof(_colorQuantityMin); + }); + + _colorQuantityMax.onChange([this] { + LDEBUG("CHANGED MAX VALUE"); + // TODO CHECK IF VALID NUMBER! + // _updateTransferFunctionMin = true; + _colorTableRanges[_colorQuantity].y = std::stof(_colorQuantityMax); + }); + // Setup shader program _shaderProgram = OsEng.renderEngine().buildRenderProgram( "FieldlinesSequence", @@ -165,6 +250,7 @@ void RenderableFieldlinesSequence::initialize() { //------------------ Initialize OpenGL VBOs and VAOs-------------------------------// glGenVertexArrays(1, &_vertexArrayObject); glGenBuffers(1, &_vertexPositionBuffer); + glGenBuffers(1, &_vertexColorBuffer); } void RenderableFieldlinesSequence::deinitialize() { @@ -194,6 +280,7 @@ void RenderableFieldlinesSequence::render(const RenderData& data, RendererTasks& if (_activeTriggerTimeIndex != -1) { _shaderProgram->activate(); + // Calculate Model View MatrixProjection const glm::dmat4 ROT_MAT = glm::dmat4(data.modelTransform.rotation); // const glm::mat4 SCALE_TRANSFORM = glm::mat4(1.0); // TODO remove if no use const glm::dmat4 MODEL_MAT = @@ -205,7 +292,19 @@ void RenderableFieldlinesSequence::render(const RenderData& data, RendererTasks& _shaderProgram->setUniform("modelViewProjection", data.camera.sgctInternal.projectionMatrix() * glm::mat4(MODEL_VIEW_MAT)); - _shaderProgram->setUniform("lineColor", _lineColor); + + _shaderProgram->setUniform("colorMethod", _colorMethod); + _shaderProgram->setUniform("lineColor", _colorUniform); + + if (_colorMethod == ColorMethod::BY_QUANTITY) { + ghoul::opengl::TextureUnit textureUnit; + textureUnit.activate(); + _transferFunction->bind(); // Calls update internally + _shaderProgram->setUniform("colorTable", textureUnit); + _shaderProgram->setUniform("colorTableRange", + _colorTableRanges[_colorQuantity]); + } + // Flow/Particles _shaderProgram->setUniform("usingParticles", _flowEnabled); _shaderProgram->setUniform("flowColor", _flowColor); @@ -238,8 +337,8 @@ void RenderableFieldlinesSequence::update(const UpdateData& data) { // Check if current time in OpenSpace is within sequence interval if (isWithinSequenceInterval(CURRENT_TIME)) { const int NEXT_IDX = _activeTriggerTimeIndex + 1; - if (_activeTriggerTimeIndex < 0 // true => Previous frame was not within the sequence interval - || CURRENT_TIME < _startTimes[_activeTriggerTimeIndex] // true => OpenSpace has stepped back to a time represented by another state + if (_activeTriggerTimeIndex < 0 // true => Previous frame was not within the sequence interval + || CURRENT_TIME < _startTimes[_activeTriggerTimeIndex] // true => OpenSpace has stepped back to a time represented by another state || (NEXT_IDX < _nStates && CURRENT_TIME >= _startTimes[NEXT_IDX])) { // true => OpenSpace has stepped forward to a time represented by another state updateActiveTriggerTimeIndex(CURRENT_TIME); @@ -275,30 +374,27 @@ void RenderableFieldlinesSequence::update(const UpdateData& data) { _states[0] = std::move(_newState); } - glBindVertexArray(_vertexArrayObject); - glBindBuffer(GL_ARRAY_BUFFER, _vertexPositionBuffer); + updateVertexPositionBuffer(); - const std::vector& VERTEX_POS_VEC = - _states[_activeStateIndex].vertexPositions(); - - glBufferData(GL_ARRAY_BUFFER, VERTEX_POS_VEC.size() * sizeof(glm::vec3), - &VERTEX_POS_VEC.front(), GL_STATIC_DRAW); - - glEnableVertexAttribArray(_vertAttrVertexPos); - glVertexAttribPointer(_vertAttrVertexPos, 3, GL_FLOAT, GL_FALSE, 0, 0); - - // UNBIND - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindVertexArray(0); + if (_states[_activeStateIndex].nExtraVariables() > 0) { + _shouldUpdateColorBuffer = true; + } else { + _colorMethod = ColorMethod::UNIFORM; + } // Everything is set and ready for rendering! - _needsUpdate = false; + _needsUpdate = false; _newStateIsReady = false; } + + if (_shouldUpdateColorBuffer) { + updateVertexColorBuffer(); + _shouldUpdateColorBuffer = false; + } } } -inline bool RenderableFieldlinesSequence::isWithinSequenceInterval(const double CURRENT_TIME) { +inline bool RenderableFieldlinesSequence::isWithinSequenceInterval(const double CURRENT_TIME) const { return (CURRENT_TIME >= _startTimes[0]) && (CURRENT_TIME < _sequenceEndTime); } @@ -327,6 +423,47 @@ void RenderableFieldlinesSequence::readNewState(const std::string& FILEPATH) { _isLoadingStateFromDisk = false; } +// Unbind buffers and arrays +inline void unbindGL() { + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); +} + +void RenderableFieldlinesSequence::updateVertexPositionBuffer() { + glBindVertexArray(_vertexArrayObject); + glBindBuffer(GL_ARRAY_BUFFER, _vertexPositionBuffer); + + const std::vector& VERTEX_POS_VEC = + _states[_activeStateIndex].vertexPositions(); + + glBufferData(GL_ARRAY_BUFFER, VERTEX_POS_VEC.size() * sizeof(glm::vec3), + &VERTEX_POS_VEC.front(), GL_STATIC_DRAW); + + glEnableVertexAttribArray(_VA_POSITION); + glVertexAttribPointer(_VA_POSITION, 3, GL_FLOAT, GL_FALSE, 0, 0); + + unbindGL(); +} + +void RenderableFieldlinesSequence::updateVertexColorBuffer() { + glBindVertexArray(_vertexArrayObject); + glBindBuffer(GL_ARRAY_BUFFER, _vertexColorBuffer); + + bool isSuccessful; + const std::vector& QUANTITY_VEC = + _states[_activeStateIndex].extraVariable(_colorQuantity, isSuccessful); + + if (isSuccessful) { + glBufferData(GL_ARRAY_BUFFER, QUANTITY_VEC.size() * sizeof(float), + &QUANTITY_VEC.front(), GL_STATIC_DRAW); + + glEnableVertexAttribArray(_VA_COLOR); + glVertexAttribPointer(_VA_COLOR, 1, GL_FLOAT, GL_FALSE, 0, 0); + + unbindGL(); + } +} + bool RenderableFieldlinesSequence::extractInfoFromDictionary( const ghoul::Dictionary& dictionary) { @@ -390,6 +527,32 @@ bool RenderableFieldlinesSequence::extractInfoFromDictionary( return false; } + // Extract optional info from modfile + ghoul::Dictionary colorTablesPathsDictionary; + if (dictionary.getValue(KEY_COLOR_TABLE_PATHS, colorTablesPathsDictionary)) { + const size_t N_PROVIDED_PATHS = colorTablesPathsDictionary.size(); + if (N_PROVIDED_PATHS > 0) { + // Clear the default! It is already specified in the transferFunction + _colorTablePaths.clear(); + for (size_t i = 1; i <= N_PROVIDED_PATHS; ++i) { + _colorTablePaths.push_back( + colorTablesPathsDictionary.value( std::to_string(i) ) ); + } + } + } + + ghoul::Dictionary colorTablesRangesDictionary; + if (dictionary.getValue(KEY_COLOR_TABLE_RANGES, colorTablesRangesDictionary)) { + const size_t N_PROVIDED_RANGES = colorTablesRangesDictionary.size(); + for (size_t i = 1; i <= N_PROVIDED_RANGES; ++i) { + _colorTableRanges.push_back( + colorTablesRangesDictionary.value( std::to_string(i) ) ); + } + } else { + _colorTableRanges.push_back(glm::vec2(0, 1)); + } + + // Extract info specific to each inputType switch (_sourceFileType) { case CDF: LERROR(name << "CDF NOT YET IMPLEMENTED!"); diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h index 455c4f1f9a..06aff5c4e2 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h @@ -27,8 +27,12 @@ #include +#include #include +#include #include +#include + #include @@ -59,8 +63,9 @@ private: int _activeStateIndex = -1; int _activeTriggerTimeIndex = -1; bool _isLoadingStatesAtRuntime = true; // False => loading osfls at runtime - bool _mustLoadNewStateFromDisk = false; // If still in same state as previous frame == false + bool _mustLoadNewStateFromDisk = false; bool _needsUpdate = false; // If still in same state as previous frame == false + bool _shouldUpdateColorBuffer = false; FieldlinesState _newState; size_t _nStates = 0; double _sequenceEndTime; @@ -69,39 +74,53 @@ private: std::atomic _isLoadingStateFromDisk{false}; std::atomic _newStateIsReady{false}; - + std::shared_ptr _transferFunction; // Transfer funtion (tf) std::unique_ptr _shaderProgram; + std::string* _activeColorTable; + std::vector _colorTablePaths {"${OPENSPACE_DATA}/colortables/kroyw.txt"}; // Default in case user doesn't specify otherwise + std::vector _sourceFiles; // Stored in RAM if files are loaded at runtime, else emptied after initialization std::vector _startTimes; std::vector _states; - std::vector _sourceFiles; // Stored in RAM if files are loaded at runtime, else emptied after initialization + std::vector _colorTableRanges; // Values represents min & max values represented in the color table GLuint _vertexArrayObject = 0; GLuint _vertexPositionBuffer = 0; + GLuint _vertexColorBuffer = 0; // THESE MUST CORRESPOND TO THE SHADER PROGRAM // TODO: THIS CAN BE DETERMINED BY ASKING THE SHADER PROGRAM TOO - GLuint _vertAttrVertexPos = 0; + const GLuint _VA_POSITION = 0; + const GLuint _VA_COLOR = 1; // ----------------------------- Properties ----------------------------- - properties::Vec4Property _lineColor; // Uniform Field Line Color + properties::PropertyOwner _colorGroup; // Group to hold the color properties + properties::OptionProperty _colorMethod; // Uniform/transfer function/topology? + properties::OptionProperty _colorQuantity; // Index of the extra variable to color lines by + properties::StringProperty _colorQuantityMin; // Color table/transfer function min + properties::StringProperty _colorQuantityMax; // Color table/transfer function max + properties::StringProperty _colorTablePath; // Color table/transfer function for "By Quantity" coloring + properties::Vec4Property _colorUniform; // Uniform Field Line Color - properties::PropertyOwner _flowGroup; - properties::BoolProperty _flowEnabled; // Toggle flow [ON/OFF] - properties::BoolProperty _flowReversed; // Toggle flow direction [FORWARDS/BACKWARDS] - properties::IntProperty _flowParticleSize; // Size of simulated flow particles - properties::IntProperty _flowParticleSpacing; // Size of simulated flow particles - properties::IntProperty _flowSpeed; // Speed of simulated flow - properties::Vec4Property _flowColor; // Simulated particles' color + properties::Vec4Property _flowColor; // Simulated particles' color + properties::BoolProperty _flowEnabled; // Toggle flow [ON/OFF] + properties::PropertyOwner _flowGroup; // Gropu to hold the flow/particle properties + properties::IntProperty _flowParticleSize; // Size of simulated flow particles + properties::IntProperty _flowParticleSpacing; // Size of simulated flow particles + properties::BoolProperty _flowReversed; // Toggle flow direction [FORWARDS/BACKWARDS] + properties::IntProperty _flowSpeed; // Speed of simulated flow - void computeSequenceEndTime(); - bool extractInfoFromDictionary(const ghoul::Dictionary& dictionary); - void extractTriggerTimesFromFileNames(); - void readNewState(const std::string& FILEPATH); + void computeSequenceEndTime(); + bool extractInfoFromDictionary(const ghoul::Dictionary& dictionary); + void extractTriggerTimesFromFileNames(); + void readNewState(const std::string& FILEPATH); - inline bool isWithinSequenceInterval(const double CURRENT_TIME); - inline void updateActiveTriggerTimeIndex(const double CURRENT_TIME); + inline bool isWithinSequenceInterval(const double CURRENT_TIME) const; + + void updateActiveTriggerTimeIndex(const double CURRENT_TIME); + void updateVertexPositionBuffer(); + void updateVertexColorBuffer(); }; } // namespace openspace diff --git a/modules/fieldlinessequence/shaders/fieldlinessequence_vs.glsl b/modules/fieldlinessequence/shaders/fieldlinessequence_vs.glsl index 906953c7b7..de0bd246a6 100644 --- a/modules/fieldlinessequence/shaders/fieldlinessequence_vs.glsl +++ b/modules/fieldlinessequence/shaders/fieldlinessequence_vs.glsl @@ -24,21 +24,42 @@ #version __CONTEXT__ -uniform mat4 modelViewProjection; -uniform bool usingParticles; -uniform double time; -uniform int particleSize; -uniform int particleSpeed; -uniform int particleSpacing; -uniform vec4 flowColor; -uniform vec4 lineColor; +#include "PowerScaling/powerScaling_vs.hglsl" -layout(location = 0) in vec3 in_position; // in meters +// General Uniforms that's always needed +uniform vec4 lineColor; +uniform mat4 modelViewProjection; + +// Uniforms needed to color by quantity +uniform int colorMethod; +uniform sampler1D colorTable; +uniform vec2 colorTableRange; + +// Uniforms needed for Particle Flow +uniform vec4 flowColor; +uniform int particleSize; +uniform int particleSpeed; +uniform int particleSpacing; +uniform double time; +uniform bool usingParticles; + +layout(location = 0) in vec3 in_position; // Should be provided in meters +layout(location = 1) in float in_color_scalar; // The extra value used to color lines. Location must correspond to _VA_COLOR in renderablefieldlinessequence.h + +// These should correspond to the enum 'ColorMethod' in renderablefieldlinesequence.cpp +const int UNIFORM_COLOR = 0; +const int COLOR_BY_QUANTITY = 1; out vec4 vs_color; out float vs_depth; -#include "PowerScaling/powerScaling_vs.hglsl" + +vec4 getTransferFunctionColor() { + // Remap the color scalar to a [0,1] range + const float LOOK_UP_VAL = (in_color_scalar - colorTableRange.x) / + (colorTableRange.y - colorTableRange.x); + return texture(colorTable, LOOK_UP_VAL); +} bool isPartOfParticle(const double TIME, const int VERTEX_ID, const int PARTICLE_SIZE, const int PARTICLE_SPEED, const int PARTICLE_SPACING) { @@ -59,6 +80,11 @@ void main() { vs_color = lineColor; } + if (colorMethod == COLOR_BY_QUANTITY) { + const vec4 QUANTITY_COLOR = getTransferFunctionColor(); + vs_color = vec4(QUANTITY_COLOR.xyz, vs_color.a * QUANTITY_COLOR.a); + } + vec4 position_in_meters = vec4(in_position, 1); vec4 positionClipSpace = modelViewProjection * position_in_meters; gl_Position = z_normalization(positionClipSpace); diff --git a/modules/fieldlinessequence/util/fieldlinesstate.cpp b/modules/fieldlinessequence/util/fieldlinesstate.cpp index 6336736d58..89aa58ba06 100644 --- a/modules/fieldlinessequence/util/fieldlinesstate.cpp +++ b/modules/fieldlinessequence/util/fieldlinesstate.cpp @@ -108,4 +108,17 @@ bool FieldlinesState::loadStateFromOsfls(const std::string& PATH_TO_OSFLS_FILE) return true; } +// Returns one of the extra variable vectors, _extraVariables[INDEX]. +// If INDEX is out of scope an empty vector is returned and the referenced bool will be false. +const vector& FieldlinesState::extraVariable(const size_t INDEX, + bool& isSuccessful) const { + if (INDEX < _extraVariables.size()) { + isSuccessful = true; + return _extraVariables[INDEX]; + } + isSuccessful = false; + // return empty vector which goes out of scope hence unusable! + return std::vector(); +} + } // namespace openspace diff --git a/modules/fieldlinessequence/util/fieldlinesstate.h b/modules/fieldlinessequence/util/fieldlinesstate.h index e2145df1cf..b4088ccefd 100644 --- a/modules/fieldlinessequence/util/fieldlinesstate.h +++ b/modules/fieldlinessequence/util/fieldlinesstate.h @@ -31,6 +31,8 @@ #include #include +using std::vector; + namespace openspace { class FieldlinesState { @@ -46,23 +48,29 @@ public: bool loadStateFromOsfls(const std::string& PATH_TO_OSFLS_FILE); - // Getters - double triggerTime() { return _triggerTime; } - Model model() { return _model; } - const std::vector& vertexPositions() { return _vertexPositions; } - const std::vector& lineStart() { return _lineStart; } - const std::vector& lineCount() { return _lineCount; } + // ------------------------------GETTERS-----------------------------------------// + const vector>& extraVariables() const { return _extraVariables; } + const vector& extraVariableNames() const { return _extraVariableNames; } + const vector& lineCount() const { return _lineCount; } + const vector& lineStart() const { return _lineStart; } + size_t nExtraVariables() const { return _extraVariables.size(); } + Model model() const { return _model; } + double triggerTime() const { return _triggerTime; } + const vector& vertexPositions() const { return _vertexPositions; } + + // Special getter. Returns extraVariables[INDEX]. + const vector& extraVariable(const size_t INDEX, bool& isSuccesful) const; private: bool _isMorphable = false; double _triggerTime = -1.0; Model _model; - std::vector _vertexPositions; - std::vector _lineStart; - std::vector _lineCount; - std::vector> _extraVariables; - std::vector _extraVariableNames; + vector _vertexPositions; + vector _lineStart; + vector _lineCount; + vector> _extraVariables; + vector _extraVariableNames; // TODO: Maybe introduce a vector containing seed point indices }; From f521939370666d9e14f1d2d67b42321c50bd81fd Mon Sep 17 00:00:00 2001 From: Oskar Carlbaum Date: Fri, 22 Sep 2017 04:53:24 +0200 Subject: [PATCH 14/39] Always refer to the extra quantities used for coloring lines as quantities, never variables. --- .../renderablefieldlinessequence.cpp | 20 +++++++++---------- .../rendering/renderablefieldlinessequence.h | 2 +- .../util/fieldlinesstate.cpp | 20 +++++++++---------- .../fieldlinessequence/util/fieldlinesstate.h | 14 ++++++------- 4 files changed, 28 insertions(+), 28 deletions(-) diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp index 8a79820554..a7e5135302 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp @@ -54,10 +54,10 @@ namespace { const char* VALUE_INPUT_FILE_TYPE_OSFLS = "osfls"; static const openspace::properties::Property::PropertyInfo ColorMethodInfo = { - "colorMethod", "Color Method", "Color lines uniformly or using color tables based on extra variables like e.g. temperature or particle density." + "colorMethod", "Color Method", "Color lines uniformly or using color tables based on extra quantities like e.g. temperature or particle density." }; static const openspace::properties::Property::PropertyInfo ColorQuantityInfo = { - "colorQuantity", "Quantity to Color By", "Quantity/variable used to color lines if the \"By Quantity\" color method is selected." + "colorQuantity", "Quantity to Color By", "Quantity used to color lines if the \"By Quantity\" color method is selected." }; static const openspace::properties::Property::PropertyInfo ColorQuantityMinInfo = { "colorQuantityMin", "ColorTable Min Value", "Value to map to the lowest end of the color table." @@ -194,10 +194,10 @@ void RenderableFieldlinesSequence::initialize() { _colorMethod.addOption(ColorMethod::BY_QUANTITY, "By Quantity"); // Add option for each extra quantity. We assume that there are just as many names to - // extra variables as there are extra variables. We also assume that all states in the - // given sequence have the same extra variables! - const size_t N_EXTRA_QUANTITIES = _states[0].nExtraVariables(); - auto EXTRA_VARIABLE_NAMES_VEC = _states[0].extraVariableNames(); + // extra quantities as there are extra quantities. We also assume that all states in + // the given sequence have the same extra quantities! + const size_t N_EXTRA_QUANTITIES = _states[0].nExtraQuantities(); + auto EXTRA_VARIABLE_NAMES_VEC = _states[0].extraQuantityNames(); for (size_t i = 0; i < N_EXTRA_QUANTITIES; ++i) { _colorQuantity.addOption(i, EXTRA_VARIABLE_NAMES_VEC[i]); } @@ -337,8 +337,8 @@ void RenderableFieldlinesSequence::update(const UpdateData& data) { // Check if current time in OpenSpace is within sequence interval if (isWithinSequenceInterval(CURRENT_TIME)) { const int NEXT_IDX = _activeTriggerTimeIndex + 1; - if (_activeTriggerTimeIndex < 0 // true => Previous frame was not within the sequence interval - || CURRENT_TIME < _startTimes[_activeTriggerTimeIndex] // true => OpenSpace has stepped back to a time represented by another state + if (_activeTriggerTimeIndex < 0 // true => Previous frame was not within the sequence interval + || CURRENT_TIME < _startTimes[_activeTriggerTimeIndex] // true => OpenSpace has stepped back to a time represented by another state || (NEXT_IDX < _nStates && CURRENT_TIME >= _startTimes[NEXT_IDX])) { // true => OpenSpace has stepped forward to a time represented by another state updateActiveTriggerTimeIndex(CURRENT_TIME); @@ -376,7 +376,7 @@ void RenderableFieldlinesSequence::update(const UpdateData& data) { updateVertexPositionBuffer(); - if (_states[_activeStateIndex].nExtraVariables() > 0) { + if (_states[_activeStateIndex].nExtraQuantities() > 0) { _shouldUpdateColorBuffer = true; } else { _colorMethod = ColorMethod::UNIFORM; @@ -451,7 +451,7 @@ void RenderableFieldlinesSequence::updateVertexColorBuffer() { bool isSuccessful; const std::vector& QUANTITY_VEC = - _states[_activeStateIndex].extraVariable(_colorQuantity, isSuccessful); + _states[_activeStateIndex].extraQuantity(_colorQuantity, isSuccessful); if (isSuccessful) { glBufferData(GL_ARRAY_BUFFER, QUANTITY_VEC.size() * sizeof(float), diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h index 06aff5c4e2..a18a207bba 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h @@ -96,7 +96,7 @@ private: // ----------------------------- Properties ----------------------------- properties::PropertyOwner _colorGroup; // Group to hold the color properties properties::OptionProperty _colorMethod; // Uniform/transfer function/topology? - properties::OptionProperty _colorQuantity; // Index of the extra variable to color lines by + properties::OptionProperty _colorQuantity; // Index of the extra quantity to color lines by properties::StringProperty _colorQuantityMin; // Color table/transfer function min properties::StringProperty _colorQuantityMax; // Color table/transfer function max properties::StringProperty _colorTablePath; // Color table/transfer function for "By Quantity" coloring diff --git a/modules/fieldlinessequence/util/fieldlinesstate.cpp b/modules/fieldlinessequence/util/fieldlinesstate.cpp index 89aa58ba06..73ee392d5b 100644 --- a/modules/fieldlinessequence/util/fieldlinesstate.cpp +++ b/modules/fieldlinessequence/util/fieldlinesstate.cpp @@ -75,21 +75,21 @@ bool FieldlinesState::loadStateFromOsfls(const std::string& PATH_TO_OSFLS_FILE) _lineStart.resize(numLines); _lineCount.resize(numLines); _vertexPositions.resize(numPoints); - _extraVariables.resize(numExtras); - _extraVariableNames.reserve(numExtras); + _extraQuantities.resize(numExtras); + _extraQuantityNames.reserve(numExtras); // Read vertex position data ifs.read( reinterpret_cast(_lineStart.data()), sizeof(GLint)*numLines); ifs.read( reinterpret_cast(_lineCount.data()), sizeof(GLsizei)*numLines); ifs.read( reinterpret_cast(_vertexPositions.data()), sizeof(glm::vec3)*numPoints); - // Read all extra variables - for (std::vector& vec : _extraVariables) { + // Read all extra quantities + for (std::vector& vec : _extraQuantities) { vec.resize(numPoints); ifs.read( reinterpret_cast(vec.data()), sizeof(float) * numPoints); } - // Read all extra variables' names. Stored as multiple c-strings + // Read all extra quantities' names. Stored as multiple c-strings std::string allNamesInOne; char* s = new char[byteSizeAllNames]; ifs.read(s, byteSizeAllNames); @@ -102,19 +102,19 @@ bool FieldlinesState::loadStateFromOsfls(const std::string& PATH_TO_OSFLS_FILE) endOfVarName -= offset; std::string varName = allNamesInOne.substr(offset, endOfVarName); offset += varName.size() + 1; - _extraVariableNames.push_back(varName); + _extraQuantityNames.push_back(varName); } return true; } -// Returns one of the extra variable vectors, _extraVariables[INDEX]. +// Returns one of the extra quantity vectors, _extraQuantities[INDEX]. // If INDEX is out of scope an empty vector is returned and the referenced bool will be false. -const vector& FieldlinesState::extraVariable(const size_t INDEX, +const vector& FieldlinesState::extraQuantity(const size_t INDEX, bool& isSuccessful) const { - if (INDEX < _extraVariables.size()) { + if (INDEX < _extraQuantities.size()) { isSuccessful = true; - return _extraVariables[INDEX]; + return _extraQuantities[INDEX]; } isSuccessful = false; // return empty vector which goes out of scope hence unusable! diff --git a/modules/fieldlinessequence/util/fieldlinesstate.h b/modules/fieldlinessequence/util/fieldlinesstate.h index b4088ccefd..4819897d0f 100644 --- a/modules/fieldlinessequence/util/fieldlinesstate.h +++ b/modules/fieldlinessequence/util/fieldlinesstate.h @@ -49,17 +49,17 @@ public: bool loadStateFromOsfls(const std::string& PATH_TO_OSFLS_FILE); // ------------------------------GETTERS-----------------------------------------// - const vector>& extraVariables() const { return _extraVariables; } - const vector& extraVariableNames() const { return _extraVariableNames; } + const vector>& extraQuantities() const { return _extraQuantities; } + const vector& extraQuantityNames() const { return _extraQuantityNames; } const vector& lineCount() const { return _lineCount; } const vector& lineStart() const { return _lineStart; } - size_t nExtraVariables() const { return _extraVariables.size(); } + size_t nExtraQuantities() const { return _extraQuantities.size(); } Model model() const { return _model; } double triggerTime() const { return _triggerTime; } const vector& vertexPositions() const { return _vertexPositions; } - // Special getter. Returns extraVariables[INDEX]. - const vector& extraVariable(const size_t INDEX, bool& isSuccesful) const; + // Special getter. Returns extraQuantities[INDEX]. + const vector& extraQuantity(const size_t INDEX, bool& isSuccesful) const; private: bool _isMorphable = false; @@ -69,8 +69,8 @@ private: vector _vertexPositions; vector _lineStart; vector _lineCount; - vector> _extraVariables; - vector _extraVariableNames; + vector> _extraQuantities; + vector _extraQuantityNames; // TODO: Maybe introduce a vector containing seed point indices }; From 3c9d48315c02e2c59da09e85fcadb6ab0dba7c65 Mon Sep 17 00:00:00 2001 From: Oskar Carlbaum Date: Fri, 22 Sep 2017 06:27:44 +0200 Subject: [PATCH 15/39] Add trigger properties. One for focus the camera on parent and one for time jump to start of sequence! --- .../renderablefieldlinessequence.cpp | 37 ++++++++++++++++++- .../rendering/renderablefieldlinessequence.h | 33 ++++++++++------- 2 files changed, 55 insertions(+), 15 deletions(-) diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp index a7e5135302..25c98b57cb 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp @@ -25,8 +25,11 @@ #include #include +#include #include +#include #include +#include #include #include @@ -90,6 +93,12 @@ namespace { static const openspace::properties::Property::PropertyInfo FlowSpeedInfo = { "speed", "Speed", "Speed of the flow." }; + static const openspace::properties::Property::PropertyInfo OriginButtonInfo = { + "focusCameraOnParent", "Focus Camera", "Focus camera on parent." + }; + static const openspace::properties::Property::PropertyInfo TimeJumpButtonInfo = { + "timeJumpToStart", "Jump to Start Time", "Performs a time jump to the start of the sequence." + }; enum ColorMethod { UNIFORM = 0, BY_QUANTITY }; } // namespace @@ -113,7 +122,9 @@ RenderableFieldlinesSequence::RenderableFieldlinesSequence(const ghoul::Dictiona _flowParticleSize(ParticleSizeInfo, 5, 0, 500), _flowParticleSpacing(ParticleSpacingInfo, 60, 0, 500), _flowReversed(ReverseFlowInfo, false), - _flowSpeed(FlowSpeedInfo, 20, 0, 1000) { + _flowSpeed(FlowSpeedInfo, 20, 0, 1000), + _focusOnOriginBtn(OriginButtonInfo), + _jumpToStartBtn(TimeJumpButtonInfo) { // Set the default color table, just in case user defined paths are corrupt! _transferFunction = std::make_shared(absPath(_colorTablePaths[0])); @@ -174,6 +185,10 @@ void RenderableFieldlinesSequence::initialize() { addPropertySubOwner(_colorGroup); addPropertySubOwner(_flowGroup); + // Add non-grouped properties + addProperty(_focusOnOriginBtn); + addProperty(_jumpToStartBtn); + // Add Properties to the groups _colorGroup.addProperty(_colorMethod); _colorGroup.addProperty(_colorQuantity); @@ -235,6 +250,25 @@ void RenderableFieldlinesSequence::initialize() { _colorTableRanges[_colorQuantity].y = std::stof(_colorQuantityMax); }); + _focusOnOriginBtn.onChange([this] { + LDEBUG("SET FOCUS NODE TO PARENT"); + // TODO CHECK IF VALID NUMBER! + // _updateTransferFunctionMin = true; + //OsEng.navigationHandler().setFocusNode(); + SceneGraphNode* node = OsEng.renderEngine().scene()->sceneGraphNode(_name); + if (!node) { + LWARNING("Could not find a node in scenegraph called '" << _name << "'"); + return; + } + OsEng.navigationHandler().setFocusNode(node->parent()); + OsEng.navigationHandler().resetCameraDirection(); + }); + + _jumpToStartBtn.onChange([this] { + LDEBUG("Jump in time to start of sequence!"); + OsEng.timeManager().time().setTime(_startTimes[0]); + }); + // Setup shader program _shaderProgram = OsEng.renderEngine().buildRenderProgram( "FieldlinesSequence", @@ -469,6 +503,7 @@ bool RenderableFieldlinesSequence::extractInfoFromDictionary( string name; dictionary.getValue(SceneGraphNode::KeyName, name); + _name = name; name += ": "; // ------------------- EXTRACT MANDATORY VALUES FROM DICTIONARY ------------------- // diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h index a18a207bba..773022754c 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -60,6 +61,8 @@ private: INVALID }; + std::string _name; + int _activeStateIndex = -1; int _activeTriggerTimeIndex = -1; bool _isLoadingStatesAtRuntime = true; // False => loading osfls at runtime @@ -94,22 +97,24 @@ private: const GLuint _VA_COLOR = 1; // ----------------------------- Properties ----------------------------- - properties::PropertyOwner _colorGroup; // Group to hold the color properties - properties::OptionProperty _colorMethod; // Uniform/transfer function/topology? - properties::OptionProperty _colorQuantity; // Index of the extra quantity to color lines by - properties::StringProperty _colorQuantityMin; // Color table/transfer function min - properties::StringProperty _colorQuantityMax; // Color table/transfer function max - properties::StringProperty _colorTablePath; // Color table/transfer function for "By Quantity" coloring - properties::Vec4Property _colorUniform; // Uniform Field Line Color + properties::PropertyOwner _colorGroup; // Group to hold the color properties + properties::OptionProperty _colorMethod; // Uniform/transfer function/topology? + properties::OptionProperty _colorQuantity; // Index of the extra quantity to color lines by + properties::StringProperty _colorQuantityMin; // Color table/transfer function min + properties::StringProperty _colorQuantityMax; // Color table/transfer function max + properties::StringProperty _colorTablePath; // Color table/transfer function for "By Quantity" coloring + properties::Vec4Property _colorUniform; // Uniform Field Line Color - properties::Vec4Property _flowColor; // Simulated particles' color - properties::BoolProperty _flowEnabled; // Toggle flow [ON/OFF] - properties::PropertyOwner _flowGroup; // Gropu to hold the flow/particle properties - properties::IntProperty _flowParticleSize; // Size of simulated flow particles - properties::IntProperty _flowParticleSpacing; // Size of simulated flow particles - properties::BoolProperty _flowReversed; // Toggle flow direction [FORWARDS/BACKWARDS] - properties::IntProperty _flowSpeed; // Speed of simulated flow + properties::Vec4Property _flowColor; // Simulated particles' color + properties::BoolProperty _flowEnabled; // Toggle flow [ON/OFF] + properties::PropertyOwner _flowGroup; // Gropu to hold the flow/particle properties + properties::IntProperty _flowParticleSize; // Size of simulated flow particles + properties::IntProperty _flowParticleSpacing; // Size of simulated flow particles + properties::BoolProperty _flowReversed; // Toggle flow direction [FORWARDS/BACKWARDS] + properties::IntProperty _flowSpeed; // Speed of simulated flow + properties::TriggerProperty _focusOnOriginBtn; // Button which sets camera focus to parent node of the renderable + properties::TriggerProperty _jumpToStartBtn; // Button which executes a time jump to start of sequence void computeSequenceEndTime(); bool extractInfoFromDictionary(const ghoul::Dictionary& dictionary); From dc597f59c4730396782cb4b1c1358670bfc6050c Mon Sep 17 00:00:00 2001 From: Oskar Carlbaum Date: Wed, 4 Oct 2017 03:34:23 +0200 Subject: [PATCH 16/39] REFACTOR: split renderablefieldlinessequence.cpp into two files and give propertiy variables a 'p' as prefix --- modules/fieldlinessequence/CMakeLists.txt | 2 + .../renderablefieldlinessequence.cpp | 427 +--------------- .../rendering/renderablefieldlinessequence.h | 58 ++- .../renderablefieldlinessequencesetup.cpp | 460 ++++++++++++++++++ modules/fieldlinessequence/util/commons.h | 49 ++ .../util/fieldlinesstate.cpp | 39 +- .../fieldlinessequence/util/fieldlinesstate.h | 26 +- 7 files changed, 597 insertions(+), 464 deletions(-) create mode 100644 modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp create mode 100644 modules/fieldlinessequence/util/commons.h diff --git a/modules/fieldlinessequence/CMakeLists.txt b/modules/fieldlinessequence/CMakeLists.txt index 33a0b287ec..1fb4a1da1e 100644 --- a/modules/fieldlinessequence/CMakeLists.txt +++ b/modules/fieldlinessequence/CMakeLists.txt @@ -27,11 +27,13 @@ include(${OPENSPACE_CMAKE_EXT_DIR}/module_definition.cmake) set(HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablefieldlinessequence.h ${CMAKE_CURRENT_SOURCE_DIR}/util/fieldlinesstate.h + ${CMAKE_CURRENT_SOURCE_DIR}/util/commons.h ) source_group("Header Files" FILES ${HEADER_FILES}) set(SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablefieldlinessequence.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablefieldlinessequencesetup.cpp ${CMAKE_CURRENT_SOURCE_DIR}/util/fieldlinesstate.cpp ) source_group("Source Files" FILES ${SOURCE_FILES}) diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp index 25c98b57cb..0e23cb81ed 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp @@ -25,268 +25,19 @@ #include #include -#include #include -#include -#include -#include #include -#include #include #include -using std::string; namespace { std::string _loggerCat = "RenderableFieldlinesSequence"; - - // ----- KEYS POSSIBLE IN MODFILE. EXPECTED DATA TYPE OF VALUE IN [BRACKETS] ----- // - // ---------------------------- MANDATORY MODFILE KEYS ---------------------------- // - const char* KEY_INPUT_FILE_TYPE = "InputFileType"; // [STRING] - const char* KEY_SOURCE_FOLDER = "SourceFolder"; // [STRING] - - // ---------------------------- OPTIONAL MODFILE KEYS ---------------------------- // - const char* KEY_COLOR_TABLE_PATHS = "ColorTablePaths"; // [STRING ARRAY] Values should be paths to .txt files - const char* KEY_COLOR_TABLE_RANGES = "ColorTableRanges";// [VEC2 ARRAY] Values should be paths to .txt files - const char* KEY_OSLFS_LOAD_AT_RUNTIME = "LoadAtRuntime"; // [BOOLEAN] If value False => Load in initializing step and store in RAM - - // ------------- POSSIBLE STRING VALUES FOR CORRESPONDING MODFILE KEY ------------- // - const char* VALUE_INPUT_FILE_TYPE_CDF = "cdf"; - const char* VALUE_INPUT_FILE_TYPE_JSON = "json"; - const char* VALUE_INPUT_FILE_TYPE_OSFLS = "osfls"; - - static const openspace::properties::Property::PropertyInfo ColorMethodInfo = { - "colorMethod", "Color Method", "Color lines uniformly or using color tables based on extra quantities like e.g. temperature or particle density." - }; - static const openspace::properties::Property::PropertyInfo ColorQuantityInfo = { - "colorQuantity", "Quantity to Color By", "Quantity used to color lines if the \"By Quantity\" color method is selected." - }; - static const openspace::properties::Property::PropertyInfo ColorQuantityMinInfo = { - "colorQuantityMin", "ColorTable Min Value", "Value to map to the lowest end of the color table." - }; - static const openspace::properties::Property::PropertyInfo ColorQuantityMaxInfo = { - "colorQuantityMax", "ColorTable Max Value", "Value to map to the highest end of the color table." - }; - static const openspace::properties::Property::PropertyInfo ColorTablePathInfo = { - "colorTablePath", "Path to Color Table", "Color Table/Transfer Function to use for \"By Quantity\" coloring." - }; - static const openspace::properties::Property::PropertyInfo ColorUniformInfo = { - "uniform", "Uniform Line Color", "The uniform color of lines shown when \"Color Method\" is set to \"Uniform\"." - }; - static const openspace::properties::Property::PropertyInfo FlowColorInfo = { - "color", "Color", "Color of particles." - }; - static const openspace::properties::Property::PropertyInfo EnableFlowInfo = { - "Enable", "ON/OFF", - "Toggles the rendering of moving particles along the lines. Can e.g. illustrate magnetic flow." - }; - static const openspace::properties::Property::PropertyInfo ReverseFlowInfo = { - "reversed", "Reversed Flow", "Toggle to make the flow move in the opposite direction." - }; - static const openspace::properties::Property::PropertyInfo ParticleSizeInfo = { - "particleSize", "Particle Size", "Size of the particles." - }; - static const openspace::properties::Property::PropertyInfo ParticleSpacingInfo = { - "particleSpacing", "Particle Spacing", "Spacing inbetween particles." - }; - static const openspace::properties::Property::PropertyInfo FlowSpeedInfo = { - "speed", "Speed", "Speed of the flow." - }; - static const openspace::properties::Property::PropertyInfo OriginButtonInfo = { - "focusCameraOnParent", "Focus Camera", "Focus camera on parent." - }; - static const openspace::properties::Property::PropertyInfo TimeJumpButtonInfo = { - "timeJumpToStart", "Jump to Start Time", "Performs a time jump to the start of the sequence." - }; - - enum ColorMethod { UNIFORM = 0, BY_QUANTITY }; } // namespace namespace openspace { -RenderableFieldlinesSequence::RenderableFieldlinesSequence(const ghoul::Dictionary& dictionary) - : Renderable(dictionary), - _colorGroup({ "Color" }), - _colorMethod(ColorMethodInfo, properties::OptionProperty::DisplayType::Radio), - _colorQuantity(ColorQuantityInfo, properties::OptionProperty::DisplayType::Dropdown), - _colorQuantityMin(ColorQuantityMinInfo), - _colorQuantityMax(ColorQuantityMaxInfo), - _colorTablePath(ColorTablePathInfo), - _colorUniform(ColorUniformInfo, glm::vec4(0.75f, 0.5f, 0.0f, 0.5f), - glm::vec4(0.f), glm::vec4(1.f)), - _flowColor(FlowColorInfo, glm::vec4(0.8f, 0.7f, 0.0f, 0.6f), - glm::vec4(0.f), glm::vec4(1.f)), - _flowEnabled(EnableFlowInfo, true), - _flowGroup({ "Flow" }), - _flowParticleSize(ParticleSizeInfo, 5, 0, 500), - _flowParticleSpacing(ParticleSpacingInfo, 60, 0, 500), - _flowReversed(ReverseFlowInfo, false), - _flowSpeed(FlowSpeedInfo, 20, 0, 1000), - _focusOnOriginBtn(OriginButtonInfo), - _jumpToStartBtn(TimeJumpButtonInfo) { - - // Set the default color table, just in case user defined paths are corrupt! - _transferFunction = std::make_shared(absPath(_colorTablePaths[0])); - - if(!extractInfoFromDictionary(dictionary)) { - _sourceFileType = INVALID; - } -} - -void RenderableFieldlinesSequence::initialize() { - switch (_sourceFileType) { - case CDF: - LERROR("CDF NOT YET IMPLEMENTED!"); - break; - case JSON: - LERROR("JSON NOT YET IMPLEMENTED!"); - break; - case OSFLS: - if (_isLoadingStatesAtRuntime) { - extractTriggerTimesFromFileNames(); - FieldlinesState newState; - bool loadedSuccessfully = newState.loadStateFromOsfls(_sourceFiles[0]); - if (loadedSuccessfully) { - _states.push_back(newState); - _nStates = _startTimes.size(); - _activeStateIndex = 0; - } else { - LERROR("The provided .osfls files seem to be corrupt!"); - _sourceFileType = INVALID; - } - } else { - // Load states into RAM! - for (string filePath : _sourceFiles) { - FieldlinesState newState; - bool loadedSuccessfully = newState.loadStateFromOsfls(filePath); - if (loadedSuccessfully) { - _states.push_back(newState); - _startTimes.push_back(newState.triggerTime()); - _nStates++; - } - } - } - break; - default: - break; - } - - // At this point there's at least one state loaded into memory! - // No need to store source paths in memory if they are already in RAM! - if (!_isLoadingStatesAtRuntime) { - _sourceFiles.clear(); - } - - computeSequenceEndTime(); - - // --------------------- HANDLE PROPERTIES --------------------- // - // Add Property Groups - addPropertySubOwner(_colorGroup); - addPropertySubOwner(_flowGroup); - - // Add non-grouped properties - addProperty(_focusOnOriginBtn); - addProperty(_jumpToStartBtn); - - // Add Properties to the groups - _colorGroup.addProperty(_colorMethod); - _colorGroup.addProperty(_colorQuantity); - _colorGroup.addProperty(_colorQuantityMin); - _colorGroup.addProperty(_colorQuantityMax); - _colorGroup.addProperty(_colorTablePath); - _colorGroup.addProperty(_colorUniform); - - _flowGroup.addProperty(_flowEnabled); - _flowGroup.addProperty(_flowReversed); - _flowGroup.addProperty(_flowColor); - _flowGroup.addProperty(_flowParticleSize); - _flowGroup.addProperty(_flowParticleSpacing); - _flowGroup.addProperty(_flowSpeed); - - // Add Options to OptionProperties - _colorMethod.addOption(ColorMethod::UNIFORM, "Uniform"); - _colorMethod.addOption(ColorMethod::BY_QUANTITY, "By Quantity"); - - // Add option for each extra quantity. We assume that there are just as many names to - // extra quantities as there are extra quantities. We also assume that all states in - // the given sequence have the same extra quantities! - const size_t N_EXTRA_QUANTITIES = _states[0].nExtraQuantities(); - auto EXTRA_VARIABLE_NAMES_VEC = _states[0].extraQuantityNames(); - for (size_t i = 0; i < N_EXTRA_QUANTITIES; ++i) { - _colorQuantity.addOption(i, EXTRA_VARIABLE_NAMES_VEC[i]); - } - // Each quantity should have its own color table and color table range, no more, no less - _colorTablePaths.resize(N_EXTRA_QUANTITIES, _colorTablePaths.back()); - _colorTableRanges.resize(N_EXTRA_QUANTITIES, _colorTableRanges.back()); - - // Add Property Callback Functions - _colorQuantity.onChange([this] { - LDEBUG("CHANGED COLORING QUANTITY"); - _shouldUpdateColorBuffer = true; - _colorQuantityMin = std::to_string(_colorTableRanges[_colorQuantity].x); - _colorQuantityMax = std::to_string(_colorTableRanges[_colorQuantity].y); - _activeColorTable = &_colorTablePaths[_colorQuantity]; - _colorTablePath = *_activeColorTable; - }); - - _colorTablePath.onChange([this] { - // TOGGLE ACTIVE SHADER PROGRAM - _transferFunction->setPath(_colorTablePath); - *_activeColorTable = _colorTablePath; - }); - - _colorQuantityMin.onChange([this] { - LDEBUG("CHANGED MIN VALUE"); - // TODO CHECK IF VALID NUMBER! - // _updateTransferFunctionMin = true; - _colorTableRanges[_colorQuantity].x = std::stof(_colorQuantityMin); - }); - - _colorQuantityMax.onChange([this] { - LDEBUG("CHANGED MAX VALUE"); - // TODO CHECK IF VALID NUMBER! - // _updateTransferFunctionMin = true; - _colorTableRanges[_colorQuantity].y = std::stof(_colorQuantityMax); - }); - - _focusOnOriginBtn.onChange([this] { - LDEBUG("SET FOCUS NODE TO PARENT"); - // TODO CHECK IF VALID NUMBER! - // _updateTransferFunctionMin = true; - //OsEng.navigationHandler().setFocusNode(); - SceneGraphNode* node = OsEng.renderEngine().scene()->sceneGraphNode(_name); - if (!node) { - LWARNING("Could not find a node in scenegraph called '" << _name << "'"); - return; - } - OsEng.navigationHandler().setFocusNode(node->parent()); - OsEng.navigationHandler().resetCameraDirection(); - }); - - _jumpToStartBtn.onChange([this] { - LDEBUG("Jump in time to start of sequence!"); - OsEng.timeManager().time().setTime(_startTimes[0]); - }); - - // Setup shader program - _shaderProgram = OsEng.renderEngine().buildRenderProgram( - "FieldlinesSequence", - "${MODULE_FIELDLINESSEQUENCE}/shaders/fieldlinessequence_vs.glsl", - "${MODULE_FIELDLINESSEQUENCE}/shaders/fieldlinessequence_fs.glsl" - ); - - if (!_shaderProgram) { - LERROR("Shader program failed initialization!"); - _sourceFileType = INVALID; - } - - //------------------ Initialize OpenGL VBOs and VAOs-------------------------------// - glGenVertexArrays(1, &_vertexArrayObject); - glGenBuffers(1, &_vertexPositionBuffer); - glGenBuffers(1, &_vertexColorBuffer); -} - void RenderableFieldlinesSequence::deinitialize() { glDeleteVertexArrays(1, &_vertexArrayObject); _vertexArrayObject = 0; @@ -294,6 +45,9 @@ void RenderableFieldlinesSequence::deinitialize() { glDeleteBuffers(1, &_vertexPositionBuffer); _vertexPositionBuffer = 0; + glDeleteBuffers(1, &_vertexColorBuffer); + _vertexColorBuffer = 0; + RenderEngine& renderEngine = OsEng.renderEngine(); if (_shaderProgram) { renderEngine.removeRenderProgram(_shaderProgram); @@ -326,26 +80,25 @@ void RenderableFieldlinesSequence::render(const RenderData& data, RendererTasks& _shaderProgram->setUniform("modelViewProjection", data.camera.sgctInternal.projectionMatrix() * glm::mat4(MODEL_VIEW_MAT)); + _shaderProgram->setUniform("colorMethod", _pColorMethod); + _shaderProgram->setUniform("lineColor", _pColorUniform); - _shaderProgram->setUniform("colorMethod", _colorMethod); - _shaderProgram->setUniform("lineColor", _colorUniform); - - if (_colorMethod == ColorMethod::BY_QUANTITY) { + if (_pColorMethod == ColorMethod::BY_QUANTITY) { ghoul::opengl::TextureUnit textureUnit; textureUnit.activate(); _transferFunction->bind(); // Calls update internally _shaderProgram->setUniform("colorTable", textureUnit); _shaderProgram->setUniform("colorTableRange", - _colorTableRanges[_colorQuantity]); + _colorTableRanges[_pColorQuantity]); } // Flow/Particles - _shaderProgram->setUniform("usingParticles", _flowEnabled); - _shaderProgram->setUniform("flowColor", _flowColor); - _shaderProgram->setUniform("particleSize", _flowParticleSize); - _shaderProgram->setUniform("particleSpeed", _flowSpeed); - _shaderProgram->setUniform("particleSpacing", _flowParticleSpacing); - _shaderProgram->setUniform("time", OsEng.runTime() * (_flowReversed ? -1 : 1)); + _shaderProgram->setUniform("flowColor", _pFlowColor); + _shaderProgram->setUniform("usingParticles", _pFlowEnabled); + _shaderProgram->setUniform("particleSize", _pFlowParticleSize); + _shaderProgram->setUniform("particleSpacing", _pFlowParticleSpacing); + _shaderProgram->setUniform("particleSpeed", _pFlowSpeed); + _shaderProgram->setUniform("time", OsEng.runTime() * (_pFlowReversed ? -1 : 1)); glBindVertexArray(_vertexArrayObject); glMultiDrawArrays( @@ -377,7 +130,7 @@ void RenderableFieldlinesSequence::update(const UpdateData& data) { updateActiveTriggerTimeIndex(CURRENT_TIME); - if (_isLoadingStatesAtRuntime) { + if (_loadingStatesDynamically) { _mustLoadNewStateFromDisk = true; } else { _needsUpdate = true; @@ -404,7 +157,7 @@ void RenderableFieldlinesSequence::update(const UpdateData& data) { } if (_needsUpdate || _newStateIsReady) { - if (_isLoadingStatesAtRuntime) { + if (_loadingStatesDynamically) { _states[0] = std::move(_newState); } @@ -413,7 +166,7 @@ void RenderableFieldlinesSequence::update(const UpdateData& data) { if (_states[_activeStateIndex].nExtraQuantities() > 0) { _shouldUpdateColorBuffer = true; } else { - _colorMethod = ColorMethod::UNIFORM; + _pColorMethod = ColorMethod::UNIFORM; } // Everything is set and ready for rendering! @@ -437,7 +190,8 @@ void RenderableFieldlinesSequence::updateActiveTriggerTimeIndex(const double CUR auto iter = std::upper_bound(_startTimes.begin(), _startTimes.end(), CURRENT_TIME); if (iter != _startTimes.end()) { if ( iter != _startTimes.begin()) { - _activeTriggerTimeIndex = std::distance(_startTimes.begin(), iter) - 1; + _activeTriggerTimeIndex = + static_cast(std::distance(_startTimes.begin(), iter)) - 1; } else { _activeTriggerTimeIndex = 0; } @@ -485,7 +239,7 @@ void RenderableFieldlinesSequence::updateVertexColorBuffer() { bool isSuccessful; const std::vector& QUANTITY_VEC = - _states[_activeStateIndex].extraQuantity(_colorQuantity, isSuccessful); + _states[_activeStateIndex].extraQuantity(_pColorQuantity, isSuccessful); if (isSuccessful) { glBufferData(GL_ARRAY_BUFFER, QUANTITY_VEC.size() * sizeof(float), @@ -498,150 +252,7 @@ void RenderableFieldlinesSequence::updateVertexColorBuffer() { } } -bool RenderableFieldlinesSequence::extractInfoFromDictionary( - const ghoul::Dictionary& dictionary) { - string name; - dictionary.getValue(SceneGraphNode::KeyName, name); - _name = name; - name += ": "; - // ------------------- EXTRACT MANDATORY VALUES FROM DICTIONARY ------------------- // - string inputFileTypeValue; - if(!dictionary.getValue(KEY_INPUT_FILE_TYPE, inputFileTypeValue)) { - LERROR(name << "The field " << string(KEY_INPUT_FILE_TYPE) << " is missing!"); - return false; - } else { - std::transform(inputFileTypeValue.begin(), inputFileTypeValue.end(), - inputFileTypeValue.begin(), ::tolower); - // Verify that the input type is correct - if (inputFileTypeValue == VALUE_INPUT_FILE_TYPE_CDF) { - _sourceFileType = CDF; - } else if (inputFileTypeValue == VALUE_INPUT_FILE_TYPE_JSON) { - _sourceFileType = JSON; - } else if (inputFileTypeValue == VALUE_INPUT_FILE_TYPE_OSFLS) { - _sourceFileType = OSFLS; - } else { - LERROR(name << inputFileTypeValue << " is not a recognised " - << KEY_INPUT_FILE_TYPE); - _sourceFileType = INVALID; - return false; - } - } - - string sourceFolderPath; - if(!dictionary.getValue(KEY_SOURCE_FOLDER, sourceFolderPath)) { - LERROR(name << "The field " << string(KEY_SOURCE_FOLDER) << " is missing!"); - return false; - } - - // Ensure that the source folder exists and then extract - // the files with the same extension as - ghoul::filesystem::Directory sourceFolder(sourceFolderPath); - if (FileSys.directoryExists(sourceFolder)) { - // Extract all file paths from the provided folder (Non-recursively! Sorted!) - _sourceFiles = sourceFolder.readFiles(ghoul::Boolean::No, ghoul::Boolean::Yes); - - // Remove all files that don't have as extension - _sourceFiles.erase(std::remove_if(_sourceFiles.begin(), _sourceFiles.end(), - [inputFileTypeValue] (string str) { - const size_t EXT_LENGTH = inputFileTypeValue.length(); - string sub = str.substr(str.length() - EXT_LENGTH, EXT_LENGTH); - std::transform(sub.begin(), sub.end(), sub.begin(), ::tolower); - return sub != inputFileTypeValue; - }), _sourceFiles.end()); - // Ensure that there are available and valid source files left - if (_sourceFiles.empty()) { - LERROR(name << sourceFolderPath << " contains no ." << inputFileTypeValue - << " files!"); - return false; - } - } else { - LERROR(name << "FieldlinesSequence" << sourceFolderPath - << " is not a valid directory!"); - return false; - } - - // Extract optional info from modfile - ghoul::Dictionary colorTablesPathsDictionary; - if (dictionary.getValue(KEY_COLOR_TABLE_PATHS, colorTablesPathsDictionary)) { - const size_t N_PROVIDED_PATHS = colorTablesPathsDictionary.size(); - if (N_PROVIDED_PATHS > 0) { - // Clear the default! It is already specified in the transferFunction - _colorTablePaths.clear(); - for (size_t i = 1; i <= N_PROVIDED_PATHS; ++i) { - _colorTablePaths.push_back( - colorTablesPathsDictionary.value( std::to_string(i) ) ); - } - } - } - - ghoul::Dictionary colorTablesRangesDictionary; - if (dictionary.getValue(KEY_COLOR_TABLE_RANGES, colorTablesRangesDictionary)) { - const size_t N_PROVIDED_RANGES = colorTablesRangesDictionary.size(); - for (size_t i = 1; i <= N_PROVIDED_RANGES; ++i) { - _colorTableRanges.push_back( - colorTablesRangesDictionary.value( std::to_string(i) ) ); - } - } else { - _colorTableRanges.push_back(glm::vec2(0, 1)); - } - - // Extract info specific to each inputType - switch (_sourceFileType) { - case CDF: - LERROR(name << "CDF NOT YET IMPLEMENTED!"); - break; - case JSON: - LERROR(name << "JSON NOT YET IMPLEMENTED!"); - break; - case OSFLS: { - bool shouldLoadInRealtime = false; - if (dictionary.getValue(KEY_OSLFS_LOAD_AT_RUNTIME, shouldLoadInRealtime)) { - _isLoadingStatesAtRuntime = shouldLoadInRealtime; - } else { - LWARNING(name << KEY_OSLFS_LOAD_AT_RUNTIME << - " isn't specified! OSFLS files will be loaded during runtime!"); - } - } break; - default: - break; - } -} - -// Calculate expected end time. -void RenderableFieldlinesSequence::computeSequenceEndTime() { - if (_nStates > 1) { - const double LAST_TRIGGER_TIME = _startTimes[_nStates - 1]; - const double SEQUENCE_DURATION = LAST_TRIGGER_TIME - _startTimes[0]; - const double AVERAGE_STATE_DURATION = SEQUENCE_DURATION / (static_cast(_nStates) - 1.0); - _sequenceEndTime = LAST_TRIGGER_TIME + AVERAGE_STATE_DURATION; - } else { - // If there's just one state it should never disappear! - _sequenceEndTime = DBL_MAX; - } -} - -// Extract J2000 time from file names -// Requires files to be named as such: 'YYYY-MM-DDTHH-MM-SS-XXX.osfls' -void RenderableFieldlinesSequence::extractTriggerTimesFromFileNames() { - const size_t FILENAME_SIZE = 23; // number of characters in filename (excluding '.osfls') - const size_t EXT_SIZE = 6; // size(".osfls") - - for (const std::string& FILEPATH : _sourceFiles) { - const size_t STR_LENGTH = FILEPATH.size(); - // Extract the filename from the path (without extension) - std::string timeString = FILEPATH.substr(STR_LENGTH - FILENAME_SIZE - EXT_SIZE, - FILENAME_SIZE - 1); - // Ensure the separators are correct - timeString.replace( 4, 1, "-"); - timeString.replace( 7, 1, "-"); - timeString.replace(13, 1, ":"); - timeString.replace(16, 1, ":"); - timeString.replace(19, 1, "."); - const double TRIGGER_TIME = Time::convertTime(timeString); - _startTimes.push_back(TRIGGER_TIME); - } -} } // namespace openspace diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h index 773022754c..e138591c90 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h @@ -34,13 +34,14 @@ #include #include - #include #include namespace openspace { +class ghoul::Dictionary; + class RenderableFieldlinesSequence : public Renderable { public: RenderableFieldlinesSequence(const ghoul::Dictionary& dictionary); @@ -54,6 +55,11 @@ public: void render(const RenderData& data, RendererTasks& rendererTask) override; void update(const UpdateData& data) override; private: + enum ColorMethod : int { + UNIFORM = 0, + BY_QUANTITY + }; + enum SourceFileType : int { CDF = 0, JSON, @@ -63,12 +69,12 @@ private: std::string _name; - int _activeStateIndex = -1; - int _activeTriggerTimeIndex = -1; - bool _isLoadingStatesAtRuntime = true; // False => loading osfls at runtime - bool _mustLoadNewStateFromDisk = false; - bool _needsUpdate = false; // If still in same state as previous frame == false - bool _shouldUpdateColorBuffer = false; + int _activeStateIndex = -1; + int _activeTriggerTimeIndex = -1; + bool _loadingStatesDynamically = false; // False => loading osfls files into RAM in initializing step + bool _mustLoadNewStateFromDisk = false; + bool _needsUpdate = false; // If still in same state as previous frame == false + bool _shouldUpdateColorBuffer = false; FieldlinesState _newState; size_t _nStates = 0; double _sequenceEndTime; @@ -77,10 +83,10 @@ private: std::atomic _isLoadingStateFromDisk{false}; std::atomic _newStateIsReady{false}; + std::unique_ptr _dictionary; std::shared_ptr _transferFunction; // Transfer funtion (tf) std::unique_ptr _shaderProgram; - std::string* _activeColorTable; std::vector _colorTablePaths {"${OPENSPACE_DATA}/colortables/kroyw.txt"}; // Default in case user doesn't specify otherwise std::vector _sourceFiles; // Stored in RAM if files are loaded at runtime, else emptied after initialization std::vector _startTimes; @@ -97,24 +103,24 @@ private: const GLuint _VA_COLOR = 1; // ----------------------------- Properties ----------------------------- - properties::PropertyOwner _colorGroup; // Group to hold the color properties - properties::OptionProperty _colorMethod; // Uniform/transfer function/topology? - properties::OptionProperty _colorQuantity; // Index of the extra quantity to color lines by - properties::StringProperty _colorQuantityMin; // Color table/transfer function min - properties::StringProperty _colorQuantityMax; // Color table/transfer function max - properties::StringProperty _colorTablePath; // Color table/transfer function for "By Quantity" coloring - properties::Vec4Property _colorUniform; // Uniform Field Line Color + properties::PropertyOwner _pColorGroup; // Group to hold the color properties + properties::OptionProperty _pColorMethod; // Uniform/transfer function/topology? + properties::OptionProperty _pColorQuantity; // Index of the extra quantity to color lines by + properties::StringProperty _pColorQuantityMin; // Color table/transfer function min + properties::StringProperty _pColorQuantityMax; // Color table/transfer function max + properties::StringProperty _pColorTablePath; // Color table/transfer function for "By Quantity" coloring + properties::Vec4Property _pColorUniform; // Uniform Field Line Color - properties::Vec4Property _flowColor; // Simulated particles' color - properties::BoolProperty _flowEnabled; // Toggle flow [ON/OFF] - properties::PropertyOwner _flowGroup; // Gropu to hold the flow/particle properties - properties::IntProperty _flowParticleSize; // Size of simulated flow particles - properties::IntProperty _flowParticleSpacing; // Size of simulated flow particles - properties::BoolProperty _flowReversed; // Toggle flow direction [FORWARDS/BACKWARDS] - properties::IntProperty _flowSpeed; // Speed of simulated flow + properties::Vec4Property _pFlowColor; // Simulated particles' color + properties::BoolProperty _pFlowEnabled; // Toggle flow [ON/OFF] + properties::PropertyOwner _pFlowGroup; // Group to hold the flow/particle properties + properties::IntProperty _pFlowParticleSize; // Size of simulated flow particles + properties::IntProperty _pFlowParticleSpacing; // Size of simulated flow particles + properties::BoolProperty _pFlowReversed; // Toggle flow direction [FORWARDS/BACKWARDS] + properties::IntProperty _pFlowSpeed; // Speed of simulated flow - properties::TriggerProperty _focusOnOriginBtn; // Button which sets camera focus to parent node of the renderable - properties::TriggerProperty _jumpToStartBtn; // Button which executes a time jump to start of sequence + properties::TriggerProperty _pFocusOnOriginBtn; // Button which sets camera focus to parent node of the renderable + properties::TriggerProperty _pJumpToStartBtn; // Button which executes a time jump to start of sequence void computeSequenceEndTime(); bool extractInfoFromDictionary(const ghoul::Dictionary& dictionary); @@ -126,6 +132,10 @@ private: void updateActiveTriggerTimeIndex(const double CURRENT_TIME); void updateVertexPositionBuffer(); void updateVertexColorBuffer(); + void updateVertexMaskingBuffer(); + + void definePropertyCallbackFunctions(); + void setupProperties(); }; } // namespace openspace diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp b/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp new file mode 100644 index 0000000000..d2811e5ef4 --- /dev/null +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp @@ -0,0 +1,460 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2017 * + * * + * 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 + +namespace { + std::string _loggerCat = "RenderableFieldlinesSequence"; + + // ----- KEYS POSSIBLE IN MODFILE. EXPECTED DATA TYPE OF VALUE IN [BRACKETS] ----- // + // ---------------------------- MANDATORY MODFILE KEYS ---------------------------- // + const char* KEY_INPUT_FILE_TYPE = "InputFileType"; // [STRING] + const char* KEY_SOURCE_FOLDER = "SourceFolder"; // [STRING] + + // ---------------------------- OPTIONAL MODFILE KEYS ---------------------------- // + const char* KEY_COLOR_TABLE_PATHS = "ColorTablePaths"; // [STRING ARRAY] Values should be paths to .txt files + const char* KEY_COLOR_TABLE_RANGES = "ColorTableRanges";// [VEC2 ARRAY] Values should be entered as {X, Y}, where X & Y are numbers + const char* KEY_OSLFS_LOAD_AT_RUNTIME = "LoadAtRuntime"; // [BOOLEAN] If value False => Load in initializing step and store in RAM + + // ------------- POSSIBLE STRING VALUES FOR CORRESPONDING MODFILE KEY ------------- // + const char* VALUE_INPUT_FILE_TYPE_CDF = "cdf"; + const char* VALUE_INPUT_FILE_TYPE_JSON = "json"; + const char* VALUE_INPUT_FILE_TYPE_OSFLS = "osfls"; + + // --------------------------------- Property Info -------------------------------- // + static const openspace::properties::Property::PropertyInfo ColorMethodInfo = { + "colorMethod", "Color Method", "Color lines uniformly or using color tables based on extra quantities like e.g. temperature or particle density." + }; + static const openspace::properties::Property::PropertyInfo ColorQuantityInfo = { + "colorQuantity", "Quantity to Color By", "Quantity used to color lines if the \"By Quantity\" color method is selected." + }; + static const openspace::properties::Property::PropertyInfo ColorQuantityMinInfo = { + "colorQuantityMin", "ColorTable Min Value", "Value to map to the lowest end of the color table." + }; + static const openspace::properties::Property::PropertyInfo ColorQuantityMaxInfo = { + "colorQuantityMax", "ColorTable Max Value", "Value to map to the highest end of the color table." + }; + static const openspace::properties::Property::PropertyInfo ColorTablePathInfo = { + "colorTablePath", "Path to Color Table", "Color Table/Transfer Function to use for \"By Quantity\" coloring." + }; + static const openspace::properties::Property::PropertyInfo ColorUniformInfo = { + "uniform", "Uniform Line Color", "The uniform color of lines shown when \"Color Method\" is set to \"Uniform\"." + }; + static const openspace::properties::Property::PropertyInfo FlowColorInfo = { + "color", "Color", "Color of particles." + }; + static const openspace::properties::Property::PropertyInfo FlowEnabledInfo = { + "flowEnabled", "Flow Direction", + "Toggles the rendering of moving particles along the lines. Can e.g. illustrate magnetic flow." + }; + static const openspace::properties::Property::PropertyInfo FlowReversedInfo = { + "reversed", "Reversed Flow", "Toggle to make the flow move in the opposite direction." + }; + static const openspace::properties::Property::PropertyInfo FlowParticleSizeInfo = { + "particleSize", "Particle Size", "Size of the particles." + }; + static const openspace::properties::Property::PropertyInfo FlowParticleSpacingInfo = { + "particleSpacing", "Particle Spacing", "Spacing inbetween particles." + }; + static const openspace::properties::Property::PropertyInfo FlowSpeedInfo = { + "speed", "Speed", "Speed of the flow." + }; + static const openspace::properties::Property::PropertyInfo OriginButtonInfo = { + "focusCameraOnParent", "Focus Camera", "Focus camera on parent." + }; + static const openspace::properties::Property::PropertyInfo TimeJumpButtonInfo = { + "timeJumpToStart", "Jump to Start Of Sequence", "Performs a time jump to the start of the sequence." + }; + + float stringToFloat(const std::string INPUT, const float BACKUP_VALUE = 0.f) { + float tmp; + try { + tmp = std::stof(INPUT); + } catch (const std::invalid_argument& ia) { + LWARNING("Invalid argument: " << ia.what() << ". '" << INPUT << + "' is NOT a valid number!"); + return BACKUP_VALUE; + } + return tmp; + } +} // namespace + +namespace openspace { + +RenderableFieldlinesSequence::RenderableFieldlinesSequence(const ghoul::Dictionary& dictionary) + : Renderable(dictionary), + _pColorGroup({ "Color" }), + _pColorMethod(ColorMethodInfo, properties::OptionProperty::DisplayType::Radio), + _pColorQuantity(ColorQuantityInfo, properties::OptionProperty::DisplayType::Dropdown), + _pColorQuantityMin(ColorQuantityMinInfo), + _pColorQuantityMax(ColorQuantityMaxInfo), + _pColorTablePath(ColorTablePathInfo), + _pColorUniform(ColorUniformInfo, glm::vec4(0.75f, 0.5f, 0.0f, 0.5f), + glm::vec4(0.f), glm::vec4(1.f)), + _pFlowColor(FlowColorInfo, glm::vec4(0.8f, 0.7f, 0.0f, 0.6f), + glm::vec4(0.f), glm::vec4(1.f)), + _pFlowEnabled(FlowEnabledInfo, true), + _pFlowGroup({ "Flow" }), + _pFlowParticleSize(FlowParticleSizeInfo, 5, 0, 500), + _pFlowParticleSpacing(FlowParticleSpacingInfo, 60, 0, 500), + _pFlowReversed(FlowReversedInfo, false), + _pFlowSpeed(FlowSpeedInfo, 20, 0, 1000), + _pFocusOnOriginBtn(OriginButtonInfo), + _pJumpToStartBtn(TimeJumpButtonInfo) { + + _dictionary = std::make_unique(dictionary); + // Set the default color table, just in case user defined paths are corrupt! + _transferFunction = std::make_shared(absPath(_colorTablePaths[0])); +} + +void RenderableFieldlinesSequence::initialize() { + LINFO("RenderableFieldlinesSequence::initialize()"); + + if (!extractInfoFromDictionary(*_dictionary)) { + _sourceFileType = SourceFileType::INVALID; + } + + // dictionary is no longer necessary as everything is extracted + _dictionary.reset(); + + switch (_sourceFileType) { + case CDF: + LERROR("CDF NOT YET IMPLEMENTED!"); return; + break; + case JSON: + LERROR("JSON NOT YET IMPLEMENTED!"); return; + break; + case OSFLS: + if (_loadingStatesDynamically) { + extractTriggerTimesFromFileNames(); + FieldlinesState newState; + bool loadedSuccessfully = newState.loadStateFromOsfls(_sourceFiles[0]); + if (loadedSuccessfully) { + _states.push_back(newState); + _nStates = _startTimes.size(); + _activeStateIndex = 0; + } else { + LERROR("The provided .osfls files seem to be corrupt!"); + _sourceFileType = SourceFileType::INVALID; + } + } else { + // Load states into RAM! + for (std::string filePath : _sourceFiles) { + FieldlinesState newState; + bool loadedSuccessfully = newState.loadStateFromOsfls(filePath); + if (loadedSuccessfully) { + _states.push_back(newState); + _startTimes.push_back(newState.triggerTime()); + _nStates++; + } + } + } + break; + default: + return; + } + + // At this point there's at least one state loaded into memory! + // No need to store source paths in memory if they are already in RAM! + if (!_loadingStatesDynamically) { + _sourceFiles.clear(); + } + + computeSequenceEndTime(); + + setupProperties(); + + // Setup shader program + _shaderProgram = OsEng.renderEngine().buildRenderProgram( + "FieldlinesSequence", + "${MODULE_FIELDLINESSEQUENCE}/shaders/fieldlinessequence_vs.glsl", + "${MODULE_FIELDLINESSEQUENCE}/shaders/fieldlinessequence_fs.glsl" + ); + + if (!_shaderProgram) { + LERROR("Shader program failed initialization!"); + _sourceFileType = SourceFileType::INVALID; + } + + //------------------ Initialize OpenGL VBOs and VAOs-------------------------------// + glGenVertexArrays(1, &_vertexArrayObject); + glGenBuffers(1, &_vertexPositionBuffer); + glGenBuffers(1, &_vertexColorBuffer); +} + +bool RenderableFieldlinesSequence::extractInfoFromDictionary( + const ghoul::Dictionary& dictionary) { + + std::string name; + dictionary.getValue(SceneGraphNode::KeyName, name); + _name = name; + name += ": "; + + // ------------------- EXTRACT MANDATORY VALUES FROM DICTIONARY ------------------- // + std::string inputFileTypeString; + if (!dictionary.getValue(KEY_INPUT_FILE_TYPE, inputFileTypeString)) { + LERROR(name << "The field " << std::string(KEY_INPUT_FILE_TYPE) << " is missing!"); + return false; + } else { + std::transform(inputFileTypeString.begin(), inputFileTypeString.end(), + inputFileTypeString.begin(), ::tolower); + // Verify that the input type is correct + if (inputFileTypeString == VALUE_INPUT_FILE_TYPE_CDF) { + _sourceFileType = CDF; + } else if (inputFileTypeString == VALUE_INPUT_FILE_TYPE_JSON) { + _sourceFileType = JSON; + } else if (inputFileTypeString == VALUE_INPUT_FILE_TYPE_OSFLS) { + _sourceFileType = OSFLS; + } else { + LERROR(name << inputFileTypeString << " is not a recognised " + << KEY_INPUT_FILE_TYPE); + _sourceFileType = INVALID; + return false; + } + } + + std::string sourceFolderPath; + if (!dictionary.getValue(KEY_SOURCE_FOLDER, sourceFolderPath)) { + LERROR(name << "The field " << std::string(KEY_SOURCE_FOLDER) << " is missing!"); + return false; + } + + // Ensure that the source folder exists and then extract + // the files with the same extension as + ghoul::filesystem::Directory sourceFolder(sourceFolderPath); + if (FileSys.directoryExists(sourceFolder)) { + // Extract all file paths from the provided folder (Non-recursively! Sorted!) + _sourceFiles = sourceFolder.readFiles(ghoul::Boolean::No, ghoul::Boolean::Yes); + + // Remove all files that don't have as extension + _sourceFiles.erase(std::remove_if(_sourceFiles.begin(), _sourceFiles.end(), + [inputFileTypeString](std::string str) { + const size_t EXT_LENGTH = inputFileTypeString.length(); + std::string sub = str.substr(str.length() - EXT_LENGTH, EXT_LENGTH); + std::transform(sub.begin(), sub.end(), sub.begin(), ::tolower); + return sub != inputFileTypeString; + }), _sourceFiles.end()); + // Ensure that there are available and valid source files left + if (_sourceFiles.empty()) { + LERROR(name << sourceFolderPath << " contains no ." << inputFileTypeString + << " files!"); + return false; + } + } else { + LERROR(name << "FieldlinesSequence" << sourceFolderPath + << " is not a valid directory!"); + return false; + } + + // ------------------- EXTRACT OPTIONAL VALUES FROM DICTIONARY ------------------- // + ghoul::Dictionary colorTablesPathsDictionary; + if (dictionary.getValue(KEY_COLOR_TABLE_PATHS, colorTablesPathsDictionary)) { + const size_t N_PROVIDED_PATHS = colorTablesPathsDictionary.size(); + if (N_PROVIDED_PATHS > 0) { + // Clear the default! It is already specified in the transferFunction + _colorTablePaths.clear(); + for (size_t i = 1; i <= N_PROVIDED_PATHS; ++i) { + _colorTablePaths.push_back( + colorTablesPathsDictionary.value(std::to_string(i))); + } + } + } + + ghoul::Dictionary colorTablesRangesDictionary; + if (dictionary.getValue(KEY_COLOR_TABLE_RANGES, colorTablesRangesDictionary)) { + const size_t N_PROVIDED_RANGES = colorTablesRangesDictionary.size(); + for (size_t i = 1; i <= N_PROVIDED_RANGES; ++i) { + _colorTableRanges.push_back( + colorTablesRangesDictionary.value(std::to_string(i))); + } + } else { + _colorTableRanges.push_back(glm::vec2(0, 1)); + } + + // Extract info specific to each inputType + switch (_sourceFileType) { + case CDF: + LERROR(name << "CDF NOT YET IMPLEMENTED!"); + break; + case JSON: + LERROR(name << "JSON NOT YET IMPLEMENTED!"); + break; + case OSFLS: { + bool shouldLoadInRealtime = false; + if (dictionary.getValue(KEY_OSLFS_LOAD_AT_RUNTIME, shouldLoadInRealtime)) { + _loadingStatesDynamically = shouldLoadInRealtime; + } else { + LWARNING(name << KEY_OSLFS_LOAD_AT_RUNTIME << + " isn't specified! States from OSFLS files will be stored in RAM!"); + } + } break; + default: + break; + } + + return true; +} + +void RenderableFieldlinesSequence::setupProperties() { + // -------------- Add non-grouped properties (enablers and buttons) -------------- // + addProperty(_pFlowEnabled); + addProperty(_pFocusOnOriginBtn); + addProperty(_pJumpToStartBtn); + + // ----------------------------- Add Property Groups ----------------------------- // + addPropertySubOwner(_pColorGroup); + addPropertySubOwner(_pFlowGroup); + + // ------------------------- Add Properties to the groups ------------------------- // + _pColorGroup.addProperty(_pColorMethod); + _pColorGroup.addProperty(_pColorQuantity); + _pColorGroup.addProperty(_pColorQuantityMin); + _pColorGroup.addProperty(_pColorQuantityMax); + _pColorGroup.addProperty(_pColorTablePath); + _pColorGroup.addProperty(_pColorUniform); + + _pFlowGroup.addProperty(_pFlowReversed); + _pFlowGroup.addProperty(_pFlowColor); + _pFlowGroup.addProperty(_pFlowParticleSize); + _pFlowGroup.addProperty(_pFlowParticleSpacing); + _pFlowGroup.addProperty(_pFlowSpeed); + + // ----------------------- Add Options to OptionProperties ----------------------- // + _pColorMethod.addOption(ColorMethod::UNIFORM, "Uniform"); + _pColorMethod.addOption(ColorMethod::BY_QUANTITY, "By Quantity"); + + /* Add option for each extra quantity. We assume that there are just as many names to + extra quantities as there are extra quantities. We also assume that all states in + the given sequence have the same extra quantities! */ + const size_t N_EXTRA_QUANTITIES = _states[0].nExtraQuantities(); + auto EXTRA_VARIABLE_NAMES_VEC = _states[0].extraQuantityNames(); + for (int i = 0; i < N_EXTRA_QUANTITIES; ++i) { + _pColorQuantity.addOption(i, EXTRA_VARIABLE_NAMES_VEC[i]); + } + // Each quantity should have its own color table and color table range, no more, no less + _colorTablePaths.resize(N_EXTRA_QUANTITIES, _colorTablePaths.back()); + _colorTableRanges.resize(N_EXTRA_QUANTITIES, _colorTableRanges.back()); + + definePropertyCallbackFunctions(); + + // Set defaults + _pColorQuantity = 0; + _pColorQuantityMin = std::to_string(_colorTableRanges[_pColorQuantity].x); + _pColorQuantityMax = std::to_string(_colorTableRanges[_pColorQuantity].y); + _pColorTablePath = _colorTablePaths[_pColorQuantity]; + +} + +void RenderableFieldlinesSequence::definePropertyCallbackFunctions() { + // Add Property Callback Functions + _pColorQuantity.onChange([this] { + LDEBUG("CHANGED COLORING QUANTITY"); + _shouldUpdateColorBuffer = true; + _pColorQuantityMin = std::to_string(_colorTableRanges[_pColorQuantity].x); + _pColorQuantityMax = std::to_string(_colorTableRanges[_pColorQuantity].y); + _pColorTablePath = _colorTablePaths[_pColorQuantity]; + }); + + _pColorTablePath.onChange([this] { + _transferFunction->setPath(_pColorTablePath); + _colorTablePaths[_pColorQuantity] = _pColorTablePath; + }); + + _pColorQuantityMin.onChange([this] { + LDEBUG("CHANGED MIN VALUE"); + float f = stringToFloat(_pColorQuantityMin, _colorTableRanges[_pColorQuantity].x); + _pColorQuantityMin = std::to_string(f); + _colorTableRanges[_pColorQuantity].x = f; + }); + + _pColorQuantityMax.onChange([this] { + LDEBUG("CHANGED MAX VALUE"); + float f = stringToFloat(_pColorQuantityMax, _colorTableRanges[_pColorQuantity].y); + _pColorQuantityMax = std::to_string(f); + _colorTableRanges[_pColorQuantity].y = f; + }); + + _pFocusOnOriginBtn.onChange([this] { + LDEBUG("SET FOCUS NODE TO PARENT"); + SceneGraphNode* node = OsEng.renderEngine().scene()->sceneGraphNode(_name); + if (!node) { + LWARNING("Could not find a node in scenegraph called '" << _name << "'"); + return; + } + OsEng.navigationHandler().setFocusNode(node->parent()); + OsEng.navigationHandler().resetCameraDirection(); + }); + + _pJumpToStartBtn.onChange([this] { + LDEBUG("Jump in time to start of sequence!"); + OsEng.timeManager().time().setTime(_startTimes[0]); + }); +} + +// Calculate expected end time. +void RenderableFieldlinesSequence::computeSequenceEndTime() { + if (_nStates > 1) { + const double LAST_TRIGGER_TIME = _startTimes[_nStates - 1]; + const double SEQUENCE_DURATION = LAST_TRIGGER_TIME - _startTimes[0]; + const double AVERAGE_STATE_DURATION = SEQUENCE_DURATION / + (static_cast(_nStates) - 1.0); + _sequenceEndTime = LAST_TRIGGER_TIME + AVERAGE_STATE_DURATION; + } else { + // If there's just one state it should never disappear! + _sequenceEndTime = DBL_MAX; + } +} + +// Extract J2000 time from file names +// Requires files to be named as such: 'YYYY-MM-DDTHH-MM-SS-XXX.osfls' +void RenderableFieldlinesSequence::extractTriggerTimesFromFileNames() { + const size_t FILENAME_SIZE = 23; // number of characters in filename (excluding '.osfls') + const size_t EXT_SIZE = 6; // size(".osfls") + + for (const std::string& FILEPATH : _sourceFiles) { + const size_t STR_LENGTH = FILEPATH.size(); + // Extract the filename from the path (without extension) + std::string timeString = FILEPATH.substr(STR_LENGTH - FILENAME_SIZE - EXT_SIZE, + FILENAME_SIZE - 1); + // Ensure the separators are correct + timeString.replace(4, 1, "-"); + timeString.replace(7, 1, "-"); + timeString.replace(13, 1, ":"); + timeString.replace(16, 1, ":"); + timeString.replace(19, 1, "."); + const double TRIGGER_TIME = Time::convertTime(timeString); + _startTimes.push_back(TRIGGER_TIME); + } +} + +} // namespace openspace diff --git a/modules/fieldlinessequence/util/commons.h b/modules/fieldlinessequence/util/commons.h new file mode 100644 index 0000000000..f019070095 --- /dev/null +++ b/modules/fieldlinessequence/util/commons.h @@ -0,0 +1,49 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2017 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#ifndef __OPENSPACE_MODULE_FIELDLINESSEQUENCE___COMMONS___H__ +#define __OPENSPACE_MODULE_FIELDLINESSEQUENCE___COMMONS___H__ + +#include + +namespace openspace { +namespace fls { // (F)ield(L)ines(S)equence + +enum Model : int { + BATSRUS = 0, + ENLIL, + PFSS, + INVALID +}; + + + +const float A_U_TO_METER = 149597870700.f; // Astronomical Units +const float R_E_TO_METER = 6371000.f; // Earth radius +const float R_S_TO_METER = 695700000.f; // Sun radius + +} // namespace fls +} // namespace openspace + +#endif // __OPENSPACE_MODULE_FIELDLINESSEQUENCE___COMMONS___H__ diff --git a/modules/fieldlinessequence/util/fieldlinesstate.cpp b/modules/fieldlinessequence/util/fieldlinesstate.cpp index 73ee392d5b..bde5dc452b 100644 --- a/modules/fieldlinessequence/util/fieldlinesstate.cpp +++ b/modules/fieldlinessequence/util/fieldlinesstate.cpp @@ -28,6 +28,11 @@ #include +namespace { + std::string _loggerCat = "FieldlinesState"; + const int CURRENT_VERSION = 0; +} + namespace openspace { FieldlinesState::FieldlinesState() {} @@ -56,37 +61,37 @@ bool FieldlinesState::loadStateFromOsfls(const std::string& PATH_TO_OSFLS_FILE) } // Define tmp variables to store meta data in - size_t numLines; - size_t numPoints; - size_t numExtras; + size_t nLines; + size_t nPoints; + size_t nExtras; size_t byteSizeAllNames; // Read single value variables ifs.read( reinterpret_cast(&_triggerTime), sizeof(double)); ifs.read( reinterpret_cast(&_model), sizeof(int)); ifs.read( reinterpret_cast(&_isMorphable), sizeof(bool)); - ifs.read( reinterpret_cast(&numLines), sizeof(size_t)); - ifs.read( reinterpret_cast(&numPoints), sizeof(size_t)); - ifs.read( reinterpret_cast(&numExtras), sizeof(size_t)); + ifs.read( reinterpret_cast(&nLines), sizeof(size_t)); + ifs.read( reinterpret_cast(&nPoints), sizeof(size_t)); + ifs.read( reinterpret_cast(&nExtras), sizeof(size_t)); ifs.read( reinterpret_cast(&byteSizeAllNames), sizeof(size_t)); // RESERVE/RESIZE vectors // TODO: Do this without initializing values? Resize is slower than just using reserve, due to initialization of all values - _lineStart.resize(numLines); - _lineCount.resize(numLines); - _vertexPositions.resize(numPoints); - _extraQuantities.resize(numExtras); - _extraQuantityNames.reserve(numExtras); + _lineStart.resize(nLines); + _lineCount.resize(nLines); + _vertexPositions.resize(nPoints); + _extraQuantities.resize(nExtras); + _extraQuantityNames.reserve(nExtras); // Read vertex position data - ifs.read( reinterpret_cast(_lineStart.data()), sizeof(GLint)*numLines); - ifs.read( reinterpret_cast(_lineCount.data()), sizeof(GLsizei)*numLines); - ifs.read( reinterpret_cast(_vertexPositions.data()), sizeof(glm::vec3)*numPoints); + ifs.read( reinterpret_cast(_lineStart.data()), sizeof(GLint)*nLines); + ifs.read( reinterpret_cast(_lineCount.data()), sizeof(GLsizei)*nLines); + ifs.read( reinterpret_cast(_vertexPositions.data()), sizeof(glm::vec3)*nPoints); // Read all extra quantities for (std::vector& vec : _extraQuantities) { - vec.resize(numPoints); - ifs.read( reinterpret_cast(vec.data()), sizeof(float) * numPoints); + vec.resize(nPoints); + ifs.read( reinterpret_cast(vec.data()), sizeof(float) * nPoints); } // Read all extra quantities' names. Stored as multiple c-strings @@ -97,7 +102,7 @@ bool FieldlinesState::loadStateFromOsfls(const std::string& PATH_TO_OSFLS_FILE) delete[] s; size_t offset = 0; - for (size_t i = 0; i < numExtras; ++i) { + for (size_t i = 0; i < nExtras; ++i) { auto endOfVarName = allNamesInOne.find('\0', offset); endOfVarName -= offset; std::string varName = allNamesInOne.substr(offset, endOfVarName); diff --git a/modules/fieldlinessequence/util/fieldlinesstate.h b/modules/fieldlinessequence/util/fieldlinesstate.h index 4819897d0f..2e6a4a29df 100644 --- a/modules/fieldlinessequence/util/fieldlinesstate.h +++ b/modules/fieldlinessequence/util/fieldlinesstate.h @@ -25,6 +25,8 @@ #ifndef __OPENSPACE_MODULE_FIELDLINESSEQUENCE___FIELDLINESSTATE___H__ #define __OPENSPACE_MODULE_FIELDLINESSEQUENCE___FIELDLINESSTATE___H__ +#include + #include #include @@ -37,12 +39,6 @@ namespace openspace { class FieldlinesState { public: - enum Model : int { - batsrus = 0, - enlil = 1, - pfss = 2 - }; - FieldlinesState(); FieldlinesState(const std::string& PATH_TO_OSFLS_FILE, bool& loadSucessful); @@ -54,7 +50,7 @@ public: const vector& lineCount() const { return _lineCount; } const vector& lineStart() const { return _lineStart; } size_t nExtraQuantities() const { return _extraQuantities.size(); } - Model model() const { return _model; } + fls::Model model() const { return _model; } double triggerTime() const { return _triggerTime; } const vector& vertexPositions() const { return _vertexPositions; } @@ -62,15 +58,15 @@ public: const vector& extraQuantity(const size_t INDEX, bool& isSuccesful) const; private: - bool _isMorphable = false; - double _triggerTime = -1.0; - Model _model; + bool _isMorphable = false; + double _triggerTime = -1.0; + fls::Model _model; - vector _vertexPositions; - vector _lineStart; - vector _lineCount; - vector> _extraQuantities; - vector _extraQuantityNames; + vector _vertexPositions; + vector _lineStart; + vector _lineCount; + vector> _extraQuantities; + vector _extraQuantityNames; // TODO: Maybe introduce a vector containing seed point indices }; From adcd62deddf86549cdeeb3bfffc0e00c3c740788 Mon Sep 17 00:00:00 2001 From: Oskar Carlbaum Date: Wed, 4 Oct 2017 03:43:32 +0200 Subject: [PATCH 17/39] Add DomainLimiting, Masking and AdditiveBlending options --- .../renderablefieldlinessequence.cpp | 67 +++++++++- .../rendering/renderablefieldlinessequence.h | 24 +++- .../renderablefieldlinessequencesetup.cpp | 122 ++++++++++++++++++ .../shaders/fieldlinessequence_fs.glsl | 6 + .../shaders/fieldlinessequence_vs.glsl | 62 +++++++-- 5 files changed, 266 insertions(+), 15 deletions(-) diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp index 0e23cb81ed..2c8fc0b729 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp @@ -48,6 +48,9 @@ void RenderableFieldlinesSequence::deinitialize() { glDeleteBuffers(1, &_vertexColorBuffer); _vertexColorBuffer = 0; + glDeleteBuffers(1, &_vertexMaskingBuffer); + _vertexMaskingBuffer = 0; + RenderEngine& renderEngine = OsEng.renderEngine(); if (_shaderProgram) { renderEngine.removeRenderProgram(_shaderProgram); @@ -82,6 +85,8 @@ void RenderableFieldlinesSequence::render(const RenderData& data, RendererTasks& _shaderProgram->setUniform("colorMethod", _pColorMethod); _shaderProgram->setUniform("lineColor", _pColorUniform); + _shaderProgram->setUniform("usingDomain", _pDomainEnabled); + _shaderProgram->setUniform("usingMasking", _pMaskingEnabled); if (_pColorMethod == ColorMethod::BY_QUANTITY) { ghoul::opengl::TextureUnit textureUnit; @@ -92,6 +97,15 @@ void RenderableFieldlinesSequence::render(const RenderData& data, RendererTasks& _colorTableRanges[_pColorQuantity]); } + if (_pMaskingEnabled) { + _shaderProgram->setUniform("maskingRange", _maskingRanges[_pMaskingQuantity]); + } + + _shaderProgram->setUniform("domainLimR", _pDomainR.value() * _scalingFactor); + _shaderProgram->setUniform("domainLimX", _pDomainX.value() * _scalingFactor); + _shaderProgram->setUniform("domainLimY", _pDomainY.value() * _scalingFactor); + _shaderProgram->setUniform("domainLimZ", _pDomainZ.value() * _scalingFactor); + // Flow/Particles _shaderProgram->setUniform("flowColor", _pFlowColor); _shaderProgram->setUniform("usingParticles", _pFlowEnabled); @@ -100,6 +114,26 @@ void RenderableFieldlinesSequence::render(const RenderData& data, RendererTasks& _shaderProgram->setUniform("particleSpeed", _pFlowSpeed); _shaderProgram->setUniform("time", OsEng.runTime() * (_pFlowReversed ? -1 : 1)); + bool additiveBlending = false; + if (_pColorABlendEnabled) { + const auto RENDERER = OsEng.renderEngine().rendererImplementation(); + bool usingFBufferRenderer = RENDERER == + RenderEngine::RendererImplementation::Framebuffer; + + bool usingABufferRenderer = RENDERER == + RenderEngine::RendererImplementation::ABuffer; + + if (usingABufferRenderer) { + _shaderProgram->setUniform("usingAdditiveBlending", _pColorABlendEnabled); + } + + additiveBlending = usingFBufferRenderer; + if (additiveBlending) { + glDepthMask(false); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + } + } + glBindVertexArray(_vertexArrayObject); glMultiDrawArrays( GL_LINE_STRIP, //_drawingOutputType, @@ -110,6 +144,11 @@ void RenderableFieldlinesSequence::render(const RenderData& data, RendererTasks& glBindVertexArray(0); _shaderProgram->deactivate(); + + if (additiveBlending) { + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDepthMask(true); + } } } @@ -164,7 +203,8 @@ void RenderableFieldlinesSequence::update(const UpdateData& data) { updateVertexPositionBuffer(); if (_states[_activeStateIndex].nExtraQuantities() > 0) { - _shouldUpdateColorBuffer = true; + _shouldUpdateColorBuffer = true; + _shouldUpdateMaskingBuffer = true; } else { _pColorMethod = ColorMethod::UNIFORM; } @@ -178,6 +218,11 @@ void RenderableFieldlinesSequence::update(const UpdateData& data) { updateVertexColorBuffer(); _shouldUpdateColorBuffer = false; } + + if (_shouldUpdateMaskingBuffer) { + updateVertexMaskingBuffer(); + _shouldUpdateMaskingBuffer = false; + } } } @@ -252,6 +297,26 @@ void RenderableFieldlinesSequence::updateVertexColorBuffer() { } } +void RenderableFieldlinesSequence::updateVertexMaskingBuffer() { + glBindVertexArray(_vertexArrayObject); + glBindBuffer(GL_ARRAY_BUFFER, _vertexMaskingBuffer); + + bool isSuccessful; + const std::vector& QUANTITY_VEC = + _states[_activeStateIndex].extraQuantity(_pMaskingQuantity, isSuccessful); + + if (isSuccessful) { + glBufferData(GL_ARRAY_BUFFER, QUANTITY_VEC.size() * sizeof(float), + &QUANTITY_VEC.front(), GL_STATIC_DRAW); + + glEnableVertexAttribArray(_VA_MASKING); + glVertexAttribPointer(_VA_MASKING, 1, GL_FLOAT, GL_FALSE, 0, 0); + + unbindGL(); + } +} + + diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h index e138591c90..6302b43abf 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -75,8 +76,10 @@ private: bool _mustLoadNewStateFromDisk = false; bool _needsUpdate = false; // If still in same state as previous frame == false bool _shouldUpdateColorBuffer = false; + bool _shouldUpdateMaskingBuffer = false; FieldlinesState _newState; - size_t _nStates = 0; + size_t _nStates = 0; + float _scalingFactor = 1.f; double _sequenceEndTime; SourceFileType _sourceFileType; @@ -92,15 +95,18 @@ private: std::vector _startTimes; std::vector _states; std::vector _colorTableRanges; // Values represents min & max values represented in the color table + std::vector _maskingRanges; // Values represents min & max values for valid masking range GLuint _vertexArrayObject = 0; GLuint _vertexPositionBuffer = 0; GLuint _vertexColorBuffer = 0; + GLuint _vertexMaskingBuffer = 0; // THESE MUST CORRESPOND TO THE SHADER PROGRAM // TODO: THIS CAN BE DETERMINED BY ASKING THE SHADER PROGRAM TOO const GLuint _VA_POSITION = 0; const GLuint _VA_COLOR = 1; + const GLuint _VA_MASKING = 2; // ----------------------------- Properties ----------------------------- properties::PropertyOwner _pColorGroup; // Group to hold the color properties @@ -110,6 +116,14 @@ private: properties::StringProperty _pColorQuantityMax; // Color table/transfer function max properties::StringProperty _pColorTablePath; // Color table/transfer function for "By Quantity" coloring properties::Vec4Property _pColorUniform; // Uniform Field Line Color + properties::BoolProperty _pColorABlendEnabled; // Whether or not to use additive blending + + properties::BoolProperty _pDomainEnabled; // Whether or not to use Domain + properties::PropertyOwner _pDomainGroup; // Group to hold the Domain properties + properties::Vec2Property _pDomainX; // Domain Limits along x-axis + properties::Vec2Property _pDomainY; // Domain Limits along y-axis + properties::Vec2Property _pDomainZ; // Domain Limits along z-axis + properties::Vec2Property _pDomainR; // Domain Limits radially properties::Vec4Property _pFlowColor; // Simulated particles' color properties::BoolProperty _pFlowEnabled; // Toggle flow [ON/OFF] @@ -119,6 +133,12 @@ private: properties::BoolProperty _pFlowReversed; // Toggle flow direction [FORWARDS/BACKWARDS] properties::IntProperty _pFlowSpeed; // Speed of simulated flow + properties::BoolProperty _pMaskingEnabled; // Whether or not to use masking + properties::PropertyOwner _pMaskingGroup; // Group to hold the masking properties + properties::StringProperty _pMaskingMin; // Lower limit for allowed values + properties::StringProperty _pMaskingMax; // Upper limit for allowed values + properties::OptionProperty _pMaskingQuantity; // Index of the extra quantity to use for masking + properties::TriggerProperty _pFocusOnOriginBtn; // Button which sets camera focus to parent node of the renderable properties::TriggerProperty _pJumpToStartBtn; // Button which executes a time jump to start of sequence @@ -136,6 +156,8 @@ private: void definePropertyCallbackFunctions(); void setupProperties(); + + void setModelDependentConstants(); }; } // namespace openspace diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp b/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp index d2811e5ef4..ff1c7f14ad 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp @@ -44,6 +44,7 @@ namespace { // ---------------------------- OPTIONAL MODFILE KEYS ---------------------------- // const char* KEY_COLOR_TABLE_PATHS = "ColorTablePaths"; // [STRING ARRAY] Values should be paths to .txt files const char* KEY_COLOR_TABLE_RANGES = "ColorTableRanges";// [VEC2 ARRAY] Values should be entered as {X, Y}, where X & Y are numbers + const char* KEY_MASKING_RANGES = "MaskingRanges"; // [VEC2 ARRAY] Values should be entered as {X, Y}, where X & Y are numbers const char* KEY_OSLFS_LOAD_AT_RUNTIME = "LoadAtRuntime"; // [BOOLEAN] If value False => Load in initializing step and store in RAM // ------------- POSSIBLE STRING VALUES FOR CORRESPONDING MODFILE KEY ------------- // @@ -70,6 +71,24 @@ namespace { static const openspace::properties::Property::PropertyInfo ColorUniformInfo = { "uniform", "Uniform Line Color", "The uniform color of lines shown when \"Color Method\" is set to \"Uniform\"." }; + static const openspace::properties::Property::PropertyInfo ColorUseABlendingInfo = { + "aBlendingEnabled", "Additive Blending", "Activate/deactivate additive blending." + }; + static const openspace::properties::Property::PropertyInfo DomainEnabledInfo = { + "domainEnabled", "Domain Limits", "Enable/Disable domain limits" + }; + static const openspace::properties::Property::PropertyInfo DomainXInfo = { + "limitsX", "X-limits", "Valid range along the X-axis. [Min, Max]" + }; + static const openspace::properties::Property::PropertyInfo DomainYInfo = { + "limitsY", "Y-limits", "Valid range along the Y-axis. [Min, Max]" + }; + static const openspace::properties::Property::PropertyInfo DomainZInfo = { + "limitsZ", "Z-limits", "Valid range along the Z-axis. [Min, Max]" + }; + static const openspace::properties::Property::PropertyInfo DomainRInfo = { + "limitsR", "Radial limits", "Valid radial range. [Min, Max]" + }; static const openspace::properties::Property::PropertyInfo FlowColorInfo = { "color", "Color", "Color of particles." }; @@ -89,6 +108,19 @@ namespace { static const openspace::properties::Property::PropertyInfo FlowSpeedInfo = { "speed", "Speed", "Speed of the flow." }; + static const openspace::properties::Property::PropertyInfo MaskingEnabledInfo = { + "maskingEnabled", "Masking", + "Enable/disable masking. Use masking to show lines where a given quantity is within a given range, e.g. if you only want to see where the temperature is between 10 and 20 degrees. Also used for masking out line topologies like solar wind & closed lines." + }; + static const openspace::properties::Property::PropertyInfo MaskingMinInfo = { + "maskingMinLimit", "Lower Limit", "Lower limit of the valid masking range" + }; + static const openspace::properties::Property::PropertyInfo MaskingMaxInfo = { + "maskingMaxLimit", "Upper Limit", "Upper limit of the valid masking range" + }; + static const openspace::properties::Property::PropertyInfo MaskingQuantityInfo = { + "maskingQuantity", "Quantity used for Masking", "Quantity used for masking." + }; static const openspace::properties::Property::PropertyInfo OriginButtonInfo = { "focusCameraOnParent", "Focus Camera", "Focus camera on parent." }; @@ -121,6 +153,13 @@ RenderableFieldlinesSequence::RenderableFieldlinesSequence(const ghoul::Dictiona _pColorTablePath(ColorTablePathInfo), _pColorUniform(ColorUniformInfo, glm::vec4(0.75f, 0.5f, 0.0f, 0.5f), glm::vec4(0.f), glm::vec4(1.f)), + _pColorABlendEnabled(ColorUseABlendingInfo, true), + _pDomainEnabled(DomainEnabledInfo, true), + _pDomainGroup({ "Domain" }), + _pDomainX(DomainXInfo), + _pDomainY(DomainYInfo), + _pDomainZ(DomainZInfo), + _pDomainR(DomainRInfo), _pFlowColor(FlowColorInfo, glm::vec4(0.8f, 0.7f, 0.0f, 0.6f), glm::vec4(0.f), glm::vec4(1.f)), _pFlowEnabled(FlowEnabledInfo, true), @@ -129,6 +168,11 @@ RenderableFieldlinesSequence::RenderableFieldlinesSequence(const ghoul::Dictiona _pFlowParticleSpacing(FlowParticleSpacingInfo, 60, 0, 500), _pFlowReversed(FlowReversedInfo, false), _pFlowSpeed(FlowSpeedInfo, 20, 0, 1000), + _pMaskingEnabled(MaskingEnabledInfo, false), + _pMaskingGroup({ "Masking" }), + _pMaskingMin(MaskingMinInfo), + _pMaskingMax(MaskingMaxInfo), + _pMaskingQuantity(MaskingQuantityInfo, properties::OptionProperty::DisplayType::Dropdown), _pFocusOnOriginBtn(OriginButtonInfo), _pJumpToStartBtn(TimeJumpButtonInfo) { @@ -191,6 +235,7 @@ void RenderableFieldlinesSequence::initialize() { } computeSequenceEndTime(); + setModelDependentConstants(); setupProperties(); @@ -210,6 +255,10 @@ void RenderableFieldlinesSequence::initialize() { glGenVertexArrays(1, &_vertexArrayObject); glGenBuffers(1, &_vertexPositionBuffer); glGenBuffers(1, &_vertexColorBuffer); + glGenBuffers(1, &_vertexMaskingBuffer); + + // Needed for additive blending + setRenderBin(Renderable::RenderBin::Overlay); } bool RenderableFieldlinesSequence::extractInfoFromDictionary( @@ -327,13 +376,18 @@ bool RenderableFieldlinesSequence::extractInfoFromDictionary( void RenderableFieldlinesSequence::setupProperties() { // -------------- Add non-grouped properties (enablers and buttons) -------------- // + addProperty(_pColorABlendEnabled); + addProperty(_pDomainEnabled); addProperty(_pFlowEnabled); + addProperty(_pMaskingEnabled); addProperty(_pFocusOnOriginBtn); addProperty(_pJumpToStartBtn); // ----------------------------- Add Property Groups ----------------------------- // addPropertySubOwner(_pColorGroup); + addPropertySubOwner(_pDomainGroup); addPropertySubOwner(_pFlowGroup); + addPropertySubOwner(_pMaskingGroup); // ------------------------- Add Properties to the groups ------------------------- // _pColorGroup.addProperty(_pColorMethod); @@ -343,12 +397,21 @@ void RenderableFieldlinesSequence::setupProperties() { _pColorGroup.addProperty(_pColorTablePath); _pColorGroup.addProperty(_pColorUniform); + _pDomainGroup.addProperty(_pDomainX); + _pDomainGroup.addProperty(_pDomainY); + _pDomainGroup.addProperty(_pDomainZ); + _pDomainGroup.addProperty(_pDomainR); + _pFlowGroup.addProperty(_pFlowReversed); _pFlowGroup.addProperty(_pFlowColor); _pFlowGroup.addProperty(_pFlowParticleSize); _pFlowGroup.addProperty(_pFlowParticleSpacing); _pFlowGroup.addProperty(_pFlowSpeed); + _pMaskingGroup.addProperty(_pMaskingMin); + _pMaskingGroup.addProperty(_pMaskingMax); + _pMaskingGroup.addProperty(_pMaskingQuantity); + // ----------------------- Add Options to OptionProperties ----------------------- // _pColorMethod.addOption(ColorMethod::UNIFORM, "Uniform"); _pColorMethod.addOption(ColorMethod::BY_QUANTITY, "By Quantity"); @@ -360,10 +423,12 @@ void RenderableFieldlinesSequence::setupProperties() { auto EXTRA_VARIABLE_NAMES_VEC = _states[0].extraQuantityNames(); for (int i = 0; i < N_EXTRA_QUANTITIES; ++i) { _pColorQuantity.addOption(i, EXTRA_VARIABLE_NAMES_VEC[i]); + _pMaskingQuantity.addOption(i, EXTRA_VARIABLE_NAMES_VEC[i]); } // Each quantity should have its own color table and color table range, no more, no less _colorTablePaths.resize(N_EXTRA_QUANTITIES, _colorTablePaths.back()); _colorTableRanges.resize(N_EXTRA_QUANTITIES, _colorTableRanges.back()); + _maskingRanges.resize(N_EXTRA_QUANTITIES, _maskingRanges.back()); definePropertyCallbackFunctions(); @@ -373,6 +438,10 @@ void RenderableFieldlinesSequence::setupProperties() { _pColorQuantityMax = std::to_string(_colorTableRanges[_pColorQuantity].y); _pColorTablePath = _colorTablePaths[_pColorQuantity]; + _pMaskingQuantity = 0; + _pMaskingMin = std::to_string(_maskingRanges[_pMaskingQuantity].x); + _pMaskingMax = std::to_string(_maskingRanges[_pMaskingQuantity].y); + } void RenderableFieldlinesSequence::definePropertyCallbackFunctions() { @@ -404,6 +473,27 @@ void RenderableFieldlinesSequence::definePropertyCallbackFunctions() { _colorTableRanges[_pColorQuantity].y = f; }); + _pMaskingQuantity.onChange([this] { + LDEBUG("CHANGED MASKING QUANTITY"); + _shouldUpdateMaskingBuffer = true; + _pMaskingMin = std::to_string(_maskingRanges[_pMaskingQuantity].x); + _pMaskingMax = std::to_string(_maskingRanges[_pMaskingQuantity].y); + }); + + _pMaskingMin.onChange([this] { + LDEBUG("CHANGED LOWER MASKING LIMIT"); + float f = stringToFloat(_pMaskingMin, _maskingRanges[_pMaskingQuantity].x); + _pMaskingMin = std::to_string(f); + _maskingRanges[_pMaskingQuantity].x = f; + }); + + _pMaskingMax.onChange([this] { + LDEBUG("CHANGED UPPER MASKING LIMIT"); + float f = stringToFloat(_pMaskingMax, _maskingRanges[_pMaskingQuantity].y); + _pMaskingMax = std::to_string(f); + _maskingRanges[_pMaskingQuantity].y = f; + }); + _pFocusOnOriginBtn.onChange([this] { LDEBUG("SET FOCUS NODE TO PARENT"); SceneGraphNode* node = OsEng.renderEngine().scene()->sceneGraphNode(_name); @@ -435,6 +525,38 @@ void RenderableFieldlinesSequence::computeSequenceEndTime() { } } +void RenderableFieldlinesSequence::setModelDependentConstants() { + const fls::Model simulationModel = _states[0].model(); + float limit = 100.f; // Just used as a default value. + switch (simulationModel) { + case fls::Model::BATSRUS: + _scalingFactor = fls::R_E_TO_METER; + limit = 300; // Should include a long magnetotail + break; + case fls::Model::ENLIL: + _pFlowReversed = true; + _scalingFactor = fls::A_U_TO_METER; + limit = 50; // Should include Plutos furthest distance from the Sun + break; + case fls::Model::PFSS: + _scalingFactor = fls::R_S_TO_METER; + limit = 100; // Just a default value far away from the solar surface + break; + default: + break; + } + _pDomainX.setMinValue(glm::vec2(-limit)); _pDomainX.setMaxValue(glm::vec2(limit)); + _pDomainY.setMinValue(glm::vec2(-limit)); _pDomainY.setMaxValue(glm::vec2(limit)); + _pDomainZ.setMinValue(glm::vec2(-limit)); _pDomainZ.setMaxValue(glm::vec2(limit)); + // Radial should range from 0 out to a corner of the cartesian box: sqrt(3) = 1.732..., 1.75 is a nice and round number + _pDomainR.setMinValue(glm::vec2(0)); _pDomainR.setMaxValue(glm::vec2(limit*1.75f)); + + _pDomainX = glm::vec2(-limit, limit); + _pDomainY = glm::vec2(-limit, limit); + _pDomainZ = glm::vec2(-limit, limit); + _pDomainR = glm::vec2(0, limit*1.5f); +} + // Extract J2000 time from file names // Requires files to be named as such: 'YYYY-MM-DDTHH-MM-SS-XXX.osfls' void RenderableFieldlinesSequence::extractTriggerTimesFromFileNames() { diff --git a/modules/fieldlinessequence/shaders/fieldlinessequence_fs.glsl b/modules/fieldlinessequence/shaders/fieldlinessequence_fs.glsl index 8e8f3ec6d3..47f3c6ac2d 100644 --- a/modules/fieldlinessequence/shaders/fieldlinessequence_fs.glsl +++ b/modules/fieldlinessequence/shaders/fieldlinessequence_fs.glsl @@ -25,6 +25,8 @@ in vec4 vs_color; in float vs_depth; +uniform bool usingAdditiveBlending; + #include "fragment.glsl" #include "PowerScaling/powerScaling_fs.hglsl" @@ -39,5 +41,9 @@ Fragment getFragment() { frag.depth = vs_depth; frag.color = fragColor; + if (usingAdditiveBlending) { + frag.blend = BLEND_MODE_ADDITIVE; + } + return frag; } diff --git a/modules/fieldlinessequence/shaders/fieldlinessequence_vs.glsl b/modules/fieldlinessequence/shaders/fieldlinessequence_vs.glsl index de0bd246a6..8491716b29 100644 --- a/modules/fieldlinessequence/shaders/fieldlinessequence_vs.glsl +++ b/modules/fieldlinessequence/shaders/fieldlinessequence_vs.glsl @@ -43,8 +43,21 @@ uniform int particleSpacing; uniform double time; uniform bool usingParticles; -layout(location = 0) in vec3 in_position; // Should be provided in meters -layout(location = 1) in float in_color_scalar; // The extra value used to color lines. Location must correspond to _VA_COLOR in renderablefieldlinessequence.h +// Masking Uniforms +uniform bool usingMasking; +uniform vec2 maskingRange; + +// Domain Uniforms +uniform bool usingDomain; +uniform vec2 domainLimX; +uniform vec2 domainLimY; +uniform vec2 domainLimZ; +uniform vec2 domainLimR; + +// Inputs +layout(location = 0) in vec3 in_position; // Should be provided in meters +layout(location = 1) in float in_color_scalar; // The extra value used to color lines. Location must correspond to _VA_COLOR in renderablefieldlinessequence.h +layout(location = 2) in float in_masking_scalar; // The extra value used to mask out parts of lines. Location must correspond to _VA_MASKING in renderablefieldlinessequence.h // These should correspond to the enum 'ColorMethod' in renderablefieldlinesequence.cpp const int UNIFORM_COLOR = 0; @@ -69,20 +82,43 @@ bool isPartOfParticle(const double TIME, const int VERTEX_ID, const int PARTICLE void main() { - const bool IS_PARTICLE = usingParticles && isPartOfParticle(time, gl_VertexID, - particleSize, - particleSpeed, - particleSpacing); + bool hasColor = true; - if (IS_PARTICLE) { - vs_color = flowColor; - } else { - vs_color = lineColor; + if (usingMasking && (in_masking_scalar < maskingRange.x || + in_masking_scalar > maskingRange.y )) { + hasColor = false; } - if (colorMethod == COLOR_BY_QUANTITY) { - const vec4 QUANTITY_COLOR = getTransferFunctionColor(); - vs_color = vec4(QUANTITY_COLOR.xyz, vs_color.a * QUANTITY_COLOR.a); + if (usingDomain && hasColor) { + const float RADIUS = length(in_position); + + if (in_position.x < domainLimX.x || in_position.x > domainLimX.y || + in_position.y < domainLimY.x || in_position.y > domainLimY.y || + in_position.z < domainLimZ.x || in_position.z > domainLimZ.y || + RADIUS < domainLimR.x || RADIUS > domainLimR.y) { + + hasColor = false; + } + } + + if (hasColor) { + const bool IS_PARTICLE = usingParticles && isPartOfParticle(time, gl_VertexID, + particleSize, + particleSpeed, + particleSpacing); + + if (IS_PARTICLE) { + vs_color = flowColor; + } else { + vs_color = lineColor; + } + + if (colorMethod == COLOR_BY_QUANTITY) { + const vec4 QUANTITY_COLOR = getTransferFunctionColor(); + vs_color = vec4(QUANTITY_COLOR.xyz, vs_color.a * QUANTITY_COLOR.a); + } + } else { + vs_color = vec4(0); } vec4 position_in_meters = vec4(in_position, 1); From bfe0cfd770f2cb5cb59a70438a996ca11853e2c2 Mon Sep 17 00:00:00 2001 From: Oskar Carlbaum Date: Wed, 4 Oct 2017 14:19:51 +0200 Subject: [PATCH 18/39] Implement functionality for saving field line states to a JSON format --- .../util/fieldlinesstate.cpp | 77 +++++++++++++++++++ .../fieldlinessequence/util/fieldlinesstate.h | 2 + 2 files changed, 79 insertions(+) diff --git a/modules/fieldlinessequence/util/fieldlinesstate.cpp b/modules/fieldlinessequence/util/fieldlinesstate.cpp index bde5dc452b..519167a6e6 100644 --- a/modules/fieldlinessequence/util/fieldlinesstate.cpp +++ b/modules/fieldlinessequence/util/fieldlinesstate.cpp @@ -24,6 +24,9 @@ #include +#include +#include + #include #include @@ -31,6 +34,8 @@ namespace { std::string _loggerCat = "FieldlinesState"; const int CURRENT_VERSION = 0; + + using json = nlohmann::json; } namespace openspace { @@ -113,6 +118,78 @@ bool FieldlinesState::loadStateFromOsfls(const std::string& PATH_TO_OSFLS_FILE) return true; } +// TODO: This should probably be rewritten, but this is the way the files were structured by CCMC +// Structure of File! NO TRAILING COMMAS ALLOWED! +// Additional info can be stored within each line as the code only extracts the keys it needs (time, trace & data) +// The key/name of each line ("0" & "1" in the example below) is arbitrary +// { +// "0":{ +// "time": "YYYY-MM-DDTHH:MM:SS.XXX", +// "trace": { +// "columns": ["x","y","z","s","temperature","rho","j_para"], +// "data": [[8.694,127.853,115.304,0.0,0.047,9.249,-5e-10],...,[8.698,127.253,114.768,0.800,0.0,9.244,-5e-10]] +// }, +// }, +// "1":{ +// "time": "YYYY-MM-DDTHH:MM:SS.XXX +// "trace": { +// "columns": ["x","y","z","s","temperature","rho","j_para"], +// "data": [[8.694,127.853,115.304,0.0,0.047,9.249,-5e-10],...,[8.698,127.253,114.768,0.800,0.0,9.244,-5e-10]] +// }, +// } +// } +void FieldlinesState::saveStateToJson(const std::string& ABS_FILEPATH) { + // Create the file + const std::string EXT = ".json"; + std::ofstream ofs(ABS_FILEPATH + EXT, std::ofstream::trunc); + if (!ofs.is_open()) { + LERROR("Failed to save state to json file at location: " << ABS_FILEPATH << EXT); + return; + } + LINFO("Saving fieldline state to: " << ABS_FILEPATH << EXT ); + + json jColumns = {"x", "y", "z"}; + for (std::string s : _extraQuantityNames) { + jColumns.push_back(s); + } + + json jFile; + + const std::string TIME_STRING = Time(_triggerTime).ISO8601(); + + const size_t N_LINES = _lineStart.size(); + const size_t N_POINTS = _vertexPositions.size(); + const size_t N_EXTRAS = _extraQuantities.size(); + + size_t pointIndex = 0; + for (size_t lineIndex = 0; lineIndex < N_LINES; lineIndex++) { + json jData = json::array(); + for (size_t i = 0; i < _lineCount[lineIndex]; i++, pointIndex++) { + const glm::vec3 POS = _vertexPositions[pointIndex]; + json jDataElement = {POS.x, POS.y, POS.z}; + + for (size_t extraIndex = 0; extraIndex < N_EXTRAS; extraIndex++) { + jDataElement.push_back(_extraQuantities[extraIndex][pointIndex]); + } + jData.push_back(jDataElement); + } + + jFile[std::to_string(lineIndex)] = { + {"time", TIME_STRING}, + {"trace", { + {"columns", jColumns}, + {"data", jData} + }} + }; + } + + //------------------------------ WRITE EVERYTHING TO FILE ------------------------------ + const int INDENTATION_SPACES = 2; + ofs << std::setw(INDENTATION_SPACES) << jFile << std::endl; + + LINFO("Saved fieldline state to: " << ABS_FILEPATH << EXT ); +} + // Returns one of the extra quantity vectors, _extraQuantities[INDEX]. // If INDEX is out of scope an empty vector is returned and the referenced bool will be false. const vector& FieldlinesState::extraQuantity(const size_t INDEX, diff --git a/modules/fieldlinessequence/util/fieldlinesstate.h b/modules/fieldlinessequence/util/fieldlinesstate.h index 2e6a4a29df..aa14fd71cb 100644 --- a/modules/fieldlinessequence/util/fieldlinesstate.h +++ b/modules/fieldlinessequence/util/fieldlinesstate.h @@ -44,6 +44,8 @@ public: bool loadStateFromOsfls(const std::string& PATH_TO_OSFLS_FILE); + void saveStateToJson(const std::string& PATH_TO_JSON_FILE); + // ------------------------------GETTERS-----------------------------------------// const vector>& extraQuantities() const { return _extraQuantities; } const vector& extraQuantityNames() const { return _extraQuantityNames; } From 84a511a1fc9cd7f27a92c6ce947b9a12db124865 Mon Sep 17 00:00:00 2001 From: Oskar Carlbaum Date: Wed, 4 Oct 2017 14:35:02 +0200 Subject: [PATCH 19/39] Add functionality for reading field line states from JSON files --- .../util/fieldlinesstate.cpp | 75 +++++++++++++++++++ .../fieldlinessequence/util/fieldlinesstate.h | 2 + 2 files changed, 77 insertions(+) diff --git a/modules/fieldlinessequence/util/fieldlinesstate.cpp b/modules/fieldlinessequence/util/fieldlinesstate.cpp index 519167a6e6..d5801bfb84 100644 --- a/modules/fieldlinessequence/util/fieldlinesstate.cpp +++ b/modules/fieldlinessequence/util/fieldlinesstate.cpp @@ -118,6 +118,81 @@ bool FieldlinesState::loadStateFromOsfls(const std::string& PATH_TO_OSFLS_FILE) return true; } +bool FieldlinesState::loadStateFromJson(const std::string& PATH_TO_JSON_FILE, + const fls::Model MODEL, + const float COORD_TO_METERS = 1.f) { + + // --------------------- ENSURE FILE IS VALID, THEN PARSE IT --------------------- // + std::ifstream ifs(PATH_TO_JSON_FILE); + + if (!ifs.is_open()) { + LERROR("FAILED TO OPEN FILE: " << PATH_TO_JSON_FILE); + return false; + } + + json jFile; + ifs >> jFile; + // -------------------------------------------------------------------------------- // + + _model = MODEL; + + const std::string S_DATA = "data"; + const std::string S_TRACE = "trace"; + + // ----- EXTRACT THE EXTRA QUANTITY NAMES & TRIGGER TIME (same for all lines) ----- // + { + const json J_TMP = *jFile.begin(); // First field line in the file + _triggerTime = Time::convertTime(J_TMP["time"]); + + const std::string S_COLUMNS = "columns"; + auto variableNameVec = J_TMP[S_TRACE][S_COLUMNS]; + const size_t N_VARIABLES = variableNameVec.size(); + const size_t N_POS_COMPONENTS = 3; // x,y,z + + if (N_VARIABLES < N_POS_COMPONENTS) { + LERROR(PATH_TO_JSON_FILE + ": Each field '" + S_COLUMNS + + "' must contain the variables: 'x', 'y' and 'z' (order is important)."); + return false; + } + + for (size_t i = N_POS_COMPONENTS ; i < N_VARIABLES ; i++) { + _extraQuantityNames.push_back(variableNameVec[i]); + } + } + + const size_t N_EXTRAS = _extraQuantityNames.size(); + _extraQuantities.resize(N_EXTRAS); + + size_t lineStartIdx = 0; + // Loop through all fieldlines + for (json::iterator fieldlineIt = jFile.begin(); fieldlineIt != jFile.end(); ++fieldlineIt) { + // The 'data' field in the 'trace' variable contains all vertex positions and the + // extra quantities. Each element is an array related to one vertex point. + const std::vector> J_DATA = (*fieldlineIt)[S_TRACE][S_DATA]; + const size_t N_POINTS = J_DATA.size(); + + for (size_t j = 0; j < N_POINTS; ++j) { + const std::vector& VARIABLES = J_DATA[j]; + + // Expects the x, y and z variables to be stored first! + const size_t X_IDX = 0, Y_IDX = 1, Z_IDX = 2; + _vertexPositions.push_back(COORD_TO_METERS * glm::vec3(VARIABLES[X_IDX], + VARIABLES[Y_IDX], + VARIABLES[Z_IDX])); + + // Add the extra quantites. Stored in the same array as the x,y,z variables. + // Hence index of the first extra quantity = 3 + for (size_t xtraIdx = 3, k = 0 ; k < N_EXTRAS; ++k, ++xtraIdx) { + _extraQuantities[k].push_back(VARIABLES[xtraIdx]); + } + } + _lineCount.push_back(static_cast(N_POINTS)); + _lineStart.push_back(static_cast(lineStartIdx)); + lineStartIdx += N_POINTS; + } + return true; +} + // TODO: This should probably be rewritten, but this is the way the files were structured by CCMC // Structure of File! NO TRAILING COMMAS ALLOWED! // Additional info can be stored within each line as the code only extracts the keys it needs (time, trace & data) diff --git a/modules/fieldlinessequence/util/fieldlinesstate.h b/modules/fieldlinessequence/util/fieldlinesstate.h index aa14fd71cb..2417907a71 100644 --- a/modules/fieldlinessequence/util/fieldlinesstate.h +++ b/modules/fieldlinessequence/util/fieldlinesstate.h @@ -44,6 +44,8 @@ public: bool loadStateFromOsfls(const std::string& PATH_TO_OSFLS_FILE); + bool loadStateFromJson(const std::string& PATH_TO_JSON_FILE, + const fls::Model MODEL, const float COORD_TO_METERS); void saveStateToJson(const std::string& PATH_TO_JSON_FILE); // ------------------------------GETTERS-----------------------------------------// From d9268593cec0366c9be487cee87eddea3f93f4c1 Mon Sep 17 00:00:00 2001 From: Oskar Carlbaum Date: Wed, 4 Oct 2017 14:56:47 +0200 Subject: [PATCH 20/39] Add functionality for saving states to the OSFLS format --- .../util/fieldlinesstate.cpp | 62 +++++++++++++++++++ .../fieldlinessequence/util/fieldlinesstate.h | 1 + 2 files changed, 63 insertions(+) diff --git a/modules/fieldlinessequence/util/fieldlinesstate.cpp b/modules/fieldlinessequence/util/fieldlinesstate.cpp index d5801bfb84..264513ce0c 100644 --- a/modules/fieldlinessequence/util/fieldlinesstate.cpp +++ b/modules/fieldlinessequence/util/fieldlinesstate.cpp @@ -193,6 +193,68 @@ bool FieldlinesState::loadStateFromJson(const std::string& PATH_TO_JSON_FILE, return true; } +/** + * @param ABS_FILEPATH must be the path to the file (incl. filename but excl. extension!) + * Directory must exist! File is created (or overwritten if already existing). + * File is structured like this: (for version 0) + * 0. int - version number of binary state file! (in case something needs to be altered in the future, then increase CURRENT_VERSION) + * 1. double - _triggerTime + * 2. int - _model + * 3. bool - _isMorphable + * 4. size_t - Number of lines in the state == _lineStart.size() == _lineCount.size() + * 5. size_t - Total number of vertex points == _vertexPositions.size() == _extraQuantities[i].size() + * 6. size_t - Number of extra quantites == _extraQuantities.size() == _extraQuantityNames.size() + * 7. site_t - Number of total bytes that ALL _extraQuantityNames consists of (Each such name is stored as a c_str which means it ends with the null char '\0' ) + * 7. std::vector - _lineStart + * 8. std::vector - _lineCount + * 9. std::vector - _vertexPositions + * 10. std::vector - _extraQuantities + * 11. array of c_str - Strings naming the extra quantities (elements of _extraQuantityNames). Each string ends with null char '\0' + */ +void FieldlinesState::saveStateToOsfls(const std::string& ABS_FILEPATH) { + // Create the file + const std::string EXT = ".osfls"; + std::ofstream ofs(ABS_FILEPATH + EXT, std::ofstream::binary | std::ofstream::trunc); + if (!ofs.is_open()) { + LERROR("Failed to save state to binary file: " << ABS_FILEPATH << EXT); + return; + } + + std::string allExtraQuantityNamesInOne = ""; + for (std::string str : _extraQuantityNames) { + allExtraQuantityNamesInOne += str + '\0'; // Add the null char '\0' for easier reading + } + + const size_t N_LINES = _lineStart.size(); + const size_t N_POINTS = _vertexPositions.size(); + const size_t N_EXTRAS = _extraQuantities.size(); + const size_t N_STRING_BYTES = allExtraQuantityNamesInOne.size(); + + //------------------------------ WRITE EVERYTHING TO FILE ------------------------------ + // WHICH VERSION OF BINARY FIELDLINES STATE FILE - IN CASE STRUCTURE CHANGES IN THE FUTURE + ofs.write( (char*)(&CURRENT_VERSION), sizeof( int ) ); + + //-------------------- WRITE META DATA FOR STATE -------------------------------- + ofs.write( reinterpret_cast(&_triggerTime), sizeof( _triggerTime ) ); + ofs.write( reinterpret_cast(&_model), sizeof( int ) ); + ofs.write( reinterpret_cast(&_isMorphable), sizeof( bool ) ); + + ofs.write( reinterpret_cast(&N_LINES), sizeof( size_t ) ); + ofs.write( reinterpret_cast(&N_POINTS), sizeof( size_t ) ); + ofs.write( reinterpret_cast(&N_EXTRAS), sizeof( size_t ) ); + ofs.write( reinterpret_cast(&N_STRING_BYTES), sizeof( size_t ) ); + + //---------------------- WRITE ALL ARRAYS OF DATA -------------------------------- + ofs.write( reinterpret_cast(_lineStart.data()), sizeof(GLint) * N_LINES); + ofs.write( reinterpret_cast(_lineCount.data()), sizeof(GLsizei) * N_LINES); + ofs.write( reinterpret_cast(_vertexPositions.data()), sizeof(glm::vec3) * N_POINTS); + // Write the data for each vector in _extraQuantities + for (std::vector& vec : _extraQuantities) { + ofs.write( reinterpret_cast(vec.data()), sizeof(float) * N_POINTS); + } + ofs.write( allExtraQuantityNamesInOne.c_str(), N_STRING_BYTES); +} + // TODO: This should probably be rewritten, but this is the way the files were structured by CCMC // Structure of File! NO TRAILING COMMAS ALLOWED! // Additional info can be stored within each line as the code only extracts the keys it needs (time, trace & data) diff --git a/modules/fieldlinessequence/util/fieldlinesstate.h b/modules/fieldlinessequence/util/fieldlinesstate.h index 2417907a71..a4f2a9b50e 100644 --- a/modules/fieldlinessequence/util/fieldlinesstate.h +++ b/modules/fieldlinessequence/util/fieldlinesstate.h @@ -43,6 +43,7 @@ public: FieldlinesState(const std::string& PATH_TO_OSFLS_FILE, bool& loadSucessful); bool loadStateFromOsfls(const std::string& PATH_TO_OSFLS_FILE); + void saveStateToOsfls(const std::string& PATH_TO_OSFLS_FILE); bool loadStateFromJson(const std::string& PATH_TO_JSON_FILE, const fls::Model MODEL, const float COORD_TO_METERS); From b1d1a7cf026ed3c53e86bc1353d2accc4eeb76b2 Mon Sep 17 00:00:00 2001 From: Oskar Carlbaum Date: Thu, 5 Oct 2017 01:35:14 +0200 Subject: [PATCH 21/39] Refactor: restructure & clean up --- .../renderablefieldlinessequence.cpp | 22 +-- .../rendering/renderablefieldlinessequence.h | 103 +++++++------ .../renderablefieldlinessequencesetup.cpp | 138 +++++++++++------- 3 files changed, 145 insertions(+), 118 deletions(-) diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp index 2c8fc0b729..2fb669f39f 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp @@ -34,6 +34,10 @@ namespace { std::string _loggerCat = "RenderableFieldlinesSequence"; + + const GLuint _VA_POSITION = 0; // MUST CORRESPOND TO THE SHADER PROGRAM + const GLuint _VA_COLOR = 1; // MUST CORRESPOND TO THE SHADER PROGRAM + const GLuint _VA_MASKING = 2; // MUST CORRESPOND TO THE SHADER PROGRAM } // namespace namespace openspace { @@ -58,13 +62,13 @@ void RenderableFieldlinesSequence::deinitialize() { } // Stall main thread until thread that's loading states is done! - while (/*!_newStateIsReady &&*/ _isLoadingStateFromDisk) { + while (_isLoadingStateFromDisk) { LWARNING("TRYING TO DESTROY CLASS WHEN A THREAD USING IT IS STILL ACTIVE"); } } bool RenderableFieldlinesSequence::isReady() const { - return _sourceFileType != INVALID; + return _isReady; } void RenderableFieldlinesSequence::render(const RenderData& data, RendererTasks&) { @@ -197,7 +201,7 @@ void RenderableFieldlinesSequence::update(const UpdateData& data) { if (_needsUpdate || _newStateIsReady) { if (_loadingStatesDynamically) { - _states[0] = std::move(_newState); + _states[0] = std::move(*_newState); } updateVertexPositionBuffer(); @@ -245,14 +249,12 @@ void RenderableFieldlinesSequence::updateActiveTriggerTimeIndex(const double CUR } } -// Reading state from disk. Thread safe! +// Reading state from disk. Must be thread safe! void RenderableFieldlinesSequence::readNewState(const std::string& FILEPATH) { - FieldlinesState newState; - - bool isSuccessful = newState.loadStateFromOsfls(FILEPATH); - _newState = std::move(newState); - - _newStateIsReady = true; + _newState = std::make_unique(); + if (_newState->loadStateFromOsfls(FILEPATH)) { + _newStateIsReady = true; + } _isLoadingStateFromDisk = false; } diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h index 6302b43abf..dcf7363c90 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h @@ -39,14 +39,15 @@ #include -namespace openspace { +namespace { + enum class SourceFileType; +} -class ghoul::Dictionary; +namespace openspace { class RenderableFieldlinesSequence : public Renderable { public: RenderableFieldlinesSequence(const ghoul::Dictionary& dictionary); - // ~RenderableFieldlinesSequence(); void initialize() override; void deinitialize() override; @@ -56,59 +57,51 @@ public: void render(const RenderData& data, RendererTasks& rendererTask) override; void update(const UpdateData& data) override; private: - enum ColorMethod : int { + // ------------------------------------- ENUMS -------------------------------------// + enum ColorMethod : int { // Used to determine if lines should be colored UNIFORMLY or by an extraQuantity UNIFORM = 0, BY_QUANTITY }; - enum SourceFileType : int { - CDF = 0, - JSON, - OSFLS, - INVALID - }; + // ------------------------------------ STRINGS ------------------------------------// + std::string _name; // Name of the Node! - std::string _name; + // ------------------------------------- FLAGS -------------------------------------// + std::atomic _isLoadingStateFromDisk { false}; // Used for 'runtime-states'. True when loading a new state from disk on another thread. + bool _isReady = false; // If initialization proved successful + bool _loadingStatesDynamically = false; // False => states are stored in RAM (using 'in-RAM-states'), True => states are loaded from disk during runtime (using 'runtime-states') + bool _mustLoadNewStateFromDisk = false; // Used for 'runtime-states': True if new 'runtime-state' must be loaded from disk. False => the previous frame's state should still be shown + bool _needsUpdate = false; // Used for 'in-RAM-states' : True if new 'in-RAM-state' must be loaded. False => the previous frame's state should still be shown + std::atomic _newStateIsReady { false}; // Used for 'runtime-states'. True when finished loading a new state from disk on another thread. + bool _shouldUpdateColorBuffer = false; // True when new state is loaded or user change which quantity to color the lines by + bool _shouldUpdateMaskingBuffer = false; // True when new state is loaded or user change which quantity used for masking out line segments - int _activeStateIndex = -1; - int _activeTriggerTimeIndex = -1; - bool _loadingStatesDynamically = false; // False => loading osfls files into RAM in initializing step - bool _mustLoadNewStateFromDisk = false; - bool _needsUpdate = false; // If still in same state as previous frame == false - bool _shouldUpdateColorBuffer = false; - bool _shouldUpdateMaskingBuffer = false; - FieldlinesState _newState; - size_t _nStates = 0; - float _scalingFactor = 1.f; - double _sequenceEndTime; - SourceFileType _sourceFileType; + // --------------------------------- NUMERICALS ----------------------------------- // + int _activeStateIndex = -1; // Active index of _states. If(==-1)=>no state available for current time. Always the same as _activeTriggerTimeIndex if(_loadingStatesDynamically==true), else always = 0 + int _activeTriggerTimeIndex = -1; // Active index of _startTimes + size_t _nStates = 0; // Number of states in the sequence + float _scalingFactor = 1.f; // In setup it is used to scale JSON coordinates. During runtime it is used to scale domain limits. + double _sequenceEndTime; // Estimated end of sequence. + GLuint _vertexArrayObject = 0; // OpenGL Vertex Array Object + GLuint _vertexColorBuffer = 0; // OpenGL Vertex Buffer Object containing the extraQuantity values used for coloring the lines + GLuint _vertexMaskingBuffer = 0; // OpenGL Vertex Buffer Object containing the extraQuantity values used for masking out segments of the lines + GLuint _vertexPositionBuffer = 0; // OpenGL Vertex Buffer Object containing the vertex positions - std::atomic _isLoadingStateFromDisk{false}; - std::atomic _newStateIsReady{false}; - - std::unique_ptr _dictionary; - std::shared_ptr _transferFunction; // Transfer funtion (tf) + // ----------------------------------- POINTERS ------------------------------------// + std::unique_ptr _dictionary; // The Lua-Modfile-Dictionary used during initialization + std::unique_ptr _newState; // Used for 'runtime-states' when switching out current state to a new state std::unique_ptr _shaderProgram; + std::shared_ptr _transferFunction; // Transfer function used to color lines when _pColorMethod is set to BY_QUANTITY - std::vector _colorTablePaths {"${OPENSPACE_DATA}/colortables/kroyw.txt"}; // Default in case user doesn't specify otherwise - std::vector _sourceFiles; // Stored in RAM if files are loaded at runtime, else emptied after initialization - std::vector _startTimes; - std::vector _states; - std::vector _colorTableRanges; // Values represents min & max values represented in the color table - std::vector _maskingRanges; // Values represents min & max values for valid masking range + // ------------------------------------ VECTORS ----------------------------------- // + std::vector _colorTablePaths; // Paths to color tables. One for each 'extraQuantity' + std::vector _colorTableRanges; // Values represents min & max values represented in the color table + std::vector _maskingRanges; // Values represents min & max limits for valid masking range + std::vector _sourceFiles; // Stores the provided source file paths if using 'runtime-states', else emptied after initialization + std::vector _startTimes; // Contains the _triggerTimes for all FieldlineStates in the sequence + std::vector _states; // Stores the FieldlineStates - GLuint _vertexArrayObject = 0; - GLuint _vertexPositionBuffer = 0; - GLuint _vertexColorBuffer = 0; - GLuint _vertexMaskingBuffer = 0; - - // THESE MUST CORRESPOND TO THE SHADER PROGRAM - // TODO: THIS CAN BE DETERMINED BY ASKING THE SHADER PROGRAM TOO - const GLuint _VA_POSITION = 0; - const GLuint _VA_COLOR = 1; - const GLuint _VA_MASKING = 2; - - // ----------------------------- Properties ----------------------------- + // ---------------------------------- Properties ---------------------------------- // properties::PropertyOwner _pColorGroup; // Group to hold the color properties properties::OptionProperty _pColorMethod; // Uniform/transfer function/topology? properties::OptionProperty _pColorQuantity; // Index of the extra quantity to color lines by @@ -142,22 +135,24 @@ private: properties::TriggerProperty _pFocusOnOriginBtn; // Button which sets camera focus to parent node of the renderable properties::TriggerProperty _pJumpToStartBtn; // Button which executes a time jump to start of sequence + // --------------------- FUNCTIONS USED DURING INITIALIZATION --------------------- // void computeSequenceEndTime(); - bool extractInfoFromDictionary(const ghoul::Dictionary& dictionary); + void definePropertyCallbackFunctions(); + bool extractJsonInfoFromDictionary(fls::Model& model); + bool extractMandatoryInfoFromDictionary(SourceFileType& sourceFileType); + void extractOptionalInfoFromDictionary(std::string& outputFolderPath); + void extractOsflsInfoFromDictionary(); void extractTriggerTimesFromFileNames(); - void readNewState(const std::string& FILEPATH); + void setModelDependentConstants(); + void setupProperties(); + // ------------------------- FUNCTIONS USED DURING RUNTIME ------------------------ // inline bool isWithinSequenceInterval(const double CURRENT_TIME) const; - + void readNewState(const std::string& FILEPATH); void updateActiveTriggerTimeIndex(const double CURRENT_TIME); void updateVertexPositionBuffer(); void updateVertexColorBuffer(); void updateVertexMaskingBuffer(); - - void definePropertyCallbackFunctions(); - void setupProperties(); - - void setModelDependentConstants(); }; } // namespace openspace diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp b/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp index ff1c7f14ad..5f960324b0 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp @@ -128,6 +128,13 @@ namespace { "timeJumpToStart", "Jump to Start Of Sequence", "Performs a time jump to the start of the sequence." }; + enum class SourceFileType : int { + CDF = 0, + JSON, + OSFLS, + INVALID + }; + float stringToFloat(const std::string INPUT, const float BACKUP_VALUE = 0.f) { float tmp; try { @@ -143,8 +150,8 @@ namespace { namespace openspace { -RenderableFieldlinesSequence::RenderableFieldlinesSequence(const ghoul::Dictionary& dictionary) - : Renderable(dictionary), +RenderableFieldlinesSequence::RenderableFieldlinesSequence(const ghoul::Dictionary& DICTIONARY) + : Renderable(DICTIONARY), _pColorGroup({ "Color" }), _pColorMethod(ColorMethodInfo, properties::OptionProperty::DisplayType::Radio), _pColorQuantity(ColorQuantityInfo, properties::OptionProperty::DisplayType::Dropdown), @@ -176,29 +183,37 @@ RenderableFieldlinesSequence::RenderableFieldlinesSequence(const ghoul::Dictiona _pFocusOnOriginBtn(OriginButtonInfo), _pJumpToStartBtn(TimeJumpButtonInfo) { - _dictionary = std::make_unique(dictionary); - // Set the default color table, just in case user defined paths are corrupt! - _transferFunction = std::make_shared(absPath(_colorTablePaths[0])); + _dictionary = std::make_unique(DICTIONARY); } void RenderableFieldlinesSequence::initialize() { LINFO("RenderableFieldlinesSequence::initialize()"); - if (!extractInfoFromDictionary(*_dictionary)) { - _sourceFileType = SourceFileType::INVALID; + // EXTRACT MANDATORY INFORMATION FROM DICTIONARY + SourceFileType sourceFileType = SourceFileType::INVALID; + if (!extractMandatoryInfoFromDictionary(sourceFileType)) { + return; } - // dictionary is no longer necessary as everything is extracted - _dictionary.reset(); + // Set the default color table, just in case the (optional) user defined paths are corrupt! + _colorTablePaths.push_back("${OPENSPACE_DATA}/colortables/kroyw.txt"); + _transferFunction = std::make_shared(absPath(_colorTablePaths[0])); - switch (_sourceFileType) { - case CDF: + // EXTRACT OPTIONAL INFORMATION FROM DICTIONARY + std::string outputFolderPath; + extractOptionalInfoFromDictionary(outputFolderPath); + const bool SHOULD_SAVE_STATES = !outputFolderPath.empty(); + + // EXTRACT SOURCE FILE TYPE SPECIFIC INFOMRATION FROM DICTIONARY & GET STATES FROM SOURCE + switch (sourceFileType) { + case SourceFileType::CDF: LERROR("CDF NOT YET IMPLEMENTED!"); return; break; - case JSON: + case SourceFileType::JSON: LERROR("JSON NOT YET IMPLEMENTED!"); return; break; - case OSFLS: + case SourceFileType::OSFLS: + extractOsflsInfoFromDictionary(); if (_loadingStatesDynamically) { extractTriggerTimesFromFileNames(); FieldlinesState newState; @@ -209,7 +224,7 @@ void RenderableFieldlinesSequence::initialize() { _activeStateIndex = 0; } else { LERROR("The provided .osfls files seem to be corrupt!"); - _sourceFileType = SourceFileType::INVALID; + sourceFileType = SourceFileType::INVALID; } } else { // Load states into RAM! @@ -228,6 +243,9 @@ void RenderableFieldlinesSequence::initialize() { return; } + // dictionary is no longer needed as everything is extracted + _dictionary.reset(); + // At this point there's at least one state loaded into memory! // No need to store source paths in memory if they are already in RAM! if (!_loadingStatesDynamically) { @@ -248,7 +266,7 @@ void RenderableFieldlinesSequence::initialize() { if (!_shaderProgram) { LERROR("Shader program failed initialization!"); - _sourceFileType = SourceFileType::INVALID; + sourceFileType = SourceFileType::INVALID; } //------------------ Initialize OpenGL VBOs and VAOs-------------------------------// @@ -259,42 +277,44 @@ void RenderableFieldlinesSequence::initialize() { // Needed for additive blending setRenderBin(Renderable::RenderBin::Overlay); + + _isReady = true; } -bool RenderableFieldlinesSequence::extractInfoFromDictionary( - const ghoul::Dictionary& dictionary) { +/* + * Returns false if it fails to extract mandatory information! + */ +bool RenderableFieldlinesSequence::extractMandatoryInfoFromDictionary( + SourceFileType& sourceFileType) { - std::string name; - dictionary.getValue(SceneGraphNode::KeyName, name); - _name = name; - name += ": "; + _dictionary->getValue(SceneGraphNode::KeyName, _name); // ------------------- EXTRACT MANDATORY VALUES FROM DICTIONARY ------------------- // std::string inputFileTypeString; - if (!dictionary.getValue(KEY_INPUT_FILE_TYPE, inputFileTypeString)) { - LERROR(name << "The field " << std::string(KEY_INPUT_FILE_TYPE) << " is missing!"); + if (!_dictionary->getValue(KEY_INPUT_FILE_TYPE, inputFileTypeString)) { + LERROR(_name << ": The field " << std::string(KEY_INPUT_FILE_TYPE) << " is missing!"); return false; } else { std::transform(inputFileTypeString.begin(), inputFileTypeString.end(), inputFileTypeString.begin(), ::tolower); // Verify that the input type is correct if (inputFileTypeString == VALUE_INPUT_FILE_TYPE_CDF) { - _sourceFileType = CDF; + sourceFileType = SourceFileType::CDF; } else if (inputFileTypeString == VALUE_INPUT_FILE_TYPE_JSON) { - _sourceFileType = JSON; + sourceFileType = SourceFileType::JSON; } else if (inputFileTypeString == VALUE_INPUT_FILE_TYPE_OSFLS) { - _sourceFileType = OSFLS; + sourceFileType = SourceFileType::OSFLS; } else { - LERROR(name << inputFileTypeString << " is not a recognised " + LERROR(_name << ": " << inputFileTypeString << " is not a recognised " << KEY_INPUT_FILE_TYPE); - _sourceFileType = INVALID; + sourceFileType = SourceFileType::INVALID; return false; } } std::string sourceFolderPath; - if (!dictionary.getValue(KEY_SOURCE_FOLDER, sourceFolderPath)) { - LERROR(name << "The field " << std::string(KEY_SOURCE_FOLDER) << " is missing!"); + if (!_dictionary->getValue(KEY_SOURCE_FOLDER, sourceFolderPath)) { + LERROR(_name << ": The field " << std::string(KEY_SOURCE_FOLDER) << " is missing!"); return false; } @@ -315,19 +335,25 @@ bool RenderableFieldlinesSequence::extractInfoFromDictionary( }), _sourceFiles.end()); // Ensure that there are available and valid source files left if (_sourceFiles.empty()) { - LERROR(name << sourceFolderPath << " contains no ." << inputFileTypeString + LERROR(_name << ": " << sourceFolderPath << " contains no ." << inputFileTypeString << " files!"); return false; } } else { - LERROR(name << "FieldlinesSequence" << sourceFolderPath + LERROR(_name << ": FieldlinesSequence" << sourceFolderPath << " is not a valid directory!"); return false; } + return true; +} + +void RenderableFieldlinesSequence::extractOptionalInfoFromDictionary( + std::string& outputFolderPath) { + // ------------------- EXTRACT OPTIONAL VALUES FROM DICTIONARY ------------------- // ghoul::Dictionary colorTablesPathsDictionary; - if (dictionary.getValue(KEY_COLOR_TABLE_PATHS, colorTablesPathsDictionary)) { + if (_dictionary->getValue(KEY_COLOR_TABLE_PATHS, colorTablesPathsDictionary)) { const size_t N_PROVIDED_PATHS = colorTablesPathsDictionary.size(); if (N_PROVIDED_PATHS > 0) { // Clear the default! It is already specified in the transferFunction @@ -340,7 +366,7 @@ bool RenderableFieldlinesSequence::extractInfoFromDictionary( } ghoul::Dictionary colorTablesRangesDictionary; - if (dictionary.getValue(KEY_COLOR_TABLE_RANGES, colorTablesRangesDictionary)) { + if (_dictionary->getValue(KEY_COLOR_TABLE_RANGES, colorTablesRangesDictionary)) { const size_t N_PROVIDED_RANGES = colorTablesRangesDictionary.size(); for (size_t i = 1; i <= N_PROVIDED_RANGES; ++i) { _colorTableRanges.push_back( @@ -350,30 +376,35 @@ bool RenderableFieldlinesSequence::extractInfoFromDictionary( _colorTableRanges.push_back(glm::vec2(0, 1)); } - // Extract info specific to each inputType - switch (_sourceFileType) { - case CDF: - LERROR(name << "CDF NOT YET IMPLEMENTED!"); - break; - case JSON: - LERROR(name << "JSON NOT YET IMPLEMENTED!"); - break; - case OSFLS: { - bool shouldLoadInRealtime = false; - if (dictionary.getValue(KEY_OSLFS_LOAD_AT_RUNTIME, shouldLoadInRealtime)) { - _loadingStatesDynamically = shouldLoadInRealtime; - } else { - LWARNING(name << KEY_OSLFS_LOAD_AT_RUNTIME << - " isn't specified! States from OSFLS files will be stored in RAM!"); - } - } break; - default: - break; + ghoul::Dictionary maskingRangesDictionary; + if (_dictionary->getValue(KEY_MASKING_RANGES, maskingRangesDictionary)) { + const size_t N_PROVIDED_RANGES = maskingRangesDictionary.size(); + for (size_t i = 1; i <= N_PROVIDED_RANGES; ++i) { + _maskingRanges.push_back( + maskingRangesDictionary.value(std::to_string(i))); + } + } else { + _maskingRanges.push_back(glm::vec2(-100000, 100000)); // Just some default values! } +} +/* + * Returns false if it fails to extract mandatory information! + */ +bool RenderableFieldlinesSequence::extractJsonInfoFromDictionary(fls::Model& model) { return true; } +void RenderableFieldlinesSequence::extractOsflsInfoFromDictionary() { + bool shouldLoadInRealtime = false; + if (_dictionary->getValue(KEY_OSLFS_LOAD_AT_RUNTIME, shouldLoadInRealtime)) { + _loadingStatesDynamically = shouldLoadInRealtime; + } else { + LWARNING(_name << ": " << KEY_OSLFS_LOAD_AT_RUNTIME << + " isn't specified! States will be stored in RAM!"); + } +} + void RenderableFieldlinesSequence::setupProperties() { // -------------- Add non-grouped properties (enablers and buttons) -------------- // addProperty(_pColorABlendEnabled); @@ -441,7 +472,6 @@ void RenderableFieldlinesSequence::setupProperties() { _pMaskingQuantity = 0; _pMaskingMin = std::to_string(_maskingRanges[_pMaskingQuantity].x); _pMaskingMax = std::to_string(_maskingRanges[_pMaskingQuantity].y); - } void RenderableFieldlinesSequence::definePropertyCallbackFunctions() { From 0bb118b4cc6847fe4e8a6031363873936613969d Mon Sep 17 00:00:00 2001 From: Oskar Carlbaum Date: Thu, 5 Oct 2017 01:40:02 +0200 Subject: [PATCH 22/39] Save state to JSON when input is .osfls and an output folder is specified in the lua-modfile --- .../renderablefieldlinessequencesetup.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp b/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp index 5f960324b0..31ace78104 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp @@ -45,6 +45,7 @@ namespace { const char* KEY_COLOR_TABLE_PATHS = "ColorTablePaths"; // [STRING ARRAY] Values should be paths to .txt files const char* KEY_COLOR_TABLE_RANGES = "ColorTableRanges";// [VEC2 ARRAY] Values should be entered as {X, Y}, where X & Y are numbers const char* KEY_MASKING_RANGES = "MaskingRanges"; // [VEC2 ARRAY] Values should be entered as {X, Y}, where X & Y are numbers + const char* KEY_OUTPUT_FOLDER = "OutputFolder"; // [STRING] Value should be path to folder where states are saved (JSON/CDF input => osfls output & oslfs input => JSON output) const char* KEY_OSLFS_LOAD_AT_RUNTIME = "LoadAtRuntime"; // [BOOLEAN] If value False => Load in initializing step and store in RAM // ------------- POSSIBLE STRING VALUES FOR CORRESPONDING MODFILE KEY ------------- // @@ -235,6 +236,11 @@ void RenderableFieldlinesSequence::initialize() { _states.push_back(newState); _startTimes.push_back(newState.triggerTime()); _nStates++; + + if (SHOULD_SAVE_STATES) { + ghoul::filesystem::File tmpFile(filePath); + newState.saveStateToJson(outputFolderPath + tmpFile.baseName()); + } } } } @@ -352,6 +358,16 @@ void RenderableFieldlinesSequence::extractOptionalInfoFromDictionary( std::string& outputFolderPath) { // ------------------- EXTRACT OPTIONAL VALUES FROM DICTIONARY ------------------- // + if (_dictionary->getValue(KEY_OUTPUT_FOLDER, outputFolderPath)) { + ghoul::filesystem::Directory outputFolder(outputFolderPath); + if (FileSys.directoryExists(outputFolder)) { + outputFolderPath = absPath(outputFolderPath); + } else { + LERROR(_name << ": The specified output path: '" << outputFolderPath << "', does not exist!"); + outputFolderPath = ""; + } + } + ghoul::Dictionary colorTablesPathsDictionary; if (_dictionary->getValue(KEY_COLOR_TABLE_PATHS, colorTablesPathsDictionary)) { const size_t N_PROVIDED_PATHS = colorTablesPathsDictionary.size(); From c4c576eaa2526d8b99fdbb71f4de5f3573874d31 Mon Sep 17 00:00:00 2001 From: Oskar Carlbaum Date: Thu, 5 Oct 2017 01:43:42 +0200 Subject: [PATCH 23/39] Load states from JSON into RAM and save to osfls if output folder is specified --- .../renderablefieldlinessequencesetup.cpp | 52 ++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp b/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp index 31ace78104..641dc90cb2 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp @@ -46,6 +46,8 @@ namespace { const char* KEY_COLOR_TABLE_RANGES = "ColorTableRanges";// [VEC2 ARRAY] Values should be entered as {X, Y}, where X & Y are numbers const char* KEY_MASKING_RANGES = "MaskingRanges"; // [VEC2 ARRAY] Values should be entered as {X, Y}, where X & Y are numbers const char* KEY_OUTPUT_FOLDER = "OutputFolder"; // [STRING] Value should be path to folder where states are saved (JSON/CDF input => osfls output & oslfs input => JSON output) + const char* KEY_JSON_SIMULATION_MODEL = "SimulationModel"; // [STRING] + const char* KEY_JSON_SCALING_FACTOR = "ScaleToMeters"; // [STRING] const char* KEY_OSLFS_LOAD_AT_RUNTIME = "LoadAtRuntime"; // [BOOLEAN] If value False => Load in initializing step and store in RAM // ------------- POSSIBLE STRING VALUES FOR CORRESPONDING MODFILE KEY ------------- // @@ -147,6 +149,17 @@ namespace { } return tmp; } + + openspace::fls::Model stringToModel(const std::string S) { + if (S == "batsrus") { + return openspace::fls::Model::BATSRUS; + } else if (S == "enlil") { + return openspace::fls::Model::ENLIL; + } else if (S == "pfss") { + return openspace::fls::Model::PFSS; + } + return openspace::fls::Model::INVALID; + } } // namespace namespace openspace { @@ -211,7 +224,28 @@ void RenderableFieldlinesSequence::initialize() { LERROR("CDF NOT YET IMPLEMENTED!"); return; break; case SourceFileType::JSON: - LERROR("JSON NOT YET IMPLEMENTED!"); return; + fls::Model model; + if (!extractJsonInfoFromDictionary(model)) { + return; + } + // Load states into RAM! + for (std::string filePath : _sourceFiles) { + FieldlinesState newState; + bool loadedSuccessfully = newState.loadStateFromJson(filePath, model, + _scalingFactor); + if (loadedSuccessfully) { + _states.push_back(newState); + _startTimes.push_back(newState.triggerTime()); + _nStates++; + if (SHOULD_SAVE_STATES) { + std::string pathSafeTimeString = Time(_startTimes.back()).ISO8601(); + pathSafeTimeString.replace(13, 1, "-"); + pathSafeTimeString.replace(16, 1, "-"); + pathSafeTimeString.replace(19, 1, "-"); + newState.saveStateToOsfls(outputFolderPath + pathSafeTimeString); + } + } + } break; case SourceFileType::OSFLS: extractOsflsInfoFromDictionary(); @@ -408,6 +442,22 @@ void RenderableFieldlinesSequence::extractOptionalInfoFromDictionary( * Returns false if it fails to extract mandatory information! */ bool RenderableFieldlinesSequence::extractJsonInfoFromDictionary(fls::Model& model) { + std::string modelStr; + if (_dictionary->getValue(KEY_JSON_SIMULATION_MODEL, modelStr)) { + std::transform(modelStr.begin(), modelStr.end(), modelStr.begin(), ::tolower); + model = stringToModel(modelStr); + } else { + LERROR(_name << ": Must specify '" << KEY_JSON_SIMULATION_MODEL << "'"); + return false; + } + + float scaleFactor; + if (_dictionary->getValue(KEY_JSON_SCALING_FACTOR, scaleFactor)) { + _scalingFactor = scaleFactor; + } else { + LWARNING(_name << ": Does not provide scalingFactor! " << + "Assumes coordinates are already expressed in meters!"); + } return true; } From caa98a4a629d23f51a4187cfd43c43e7f963ebb0 Mon Sep 17 00:00:00 2001 From: Oskar Carlbaum Date: Mon, 9 Oct 2017 19:45:04 +0200 Subject: [PATCH 24/39] Move stringToModel function to utils/commons.cpp --- modules/fieldlinessequence/CMakeLists.txt | 1 + .../renderablefieldlinessequencesetup.cpp | 13 +----- modules/fieldlinessequence/util/commons.cpp | 42 +++++++++++++++++++ modules/fieldlinessequence/util/commons.h | 2 +- 4 files changed, 45 insertions(+), 13 deletions(-) create mode 100644 modules/fieldlinessequence/util/commons.cpp diff --git a/modules/fieldlinessequence/CMakeLists.txt b/modules/fieldlinessequence/CMakeLists.txt index 1fb4a1da1e..195e9d93d7 100644 --- a/modules/fieldlinessequence/CMakeLists.txt +++ b/modules/fieldlinessequence/CMakeLists.txt @@ -35,6 +35,7 @@ set(SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablefieldlinessequence.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablefieldlinessequencesetup.cpp ${CMAKE_CURRENT_SOURCE_DIR}/util/fieldlinesstate.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/util/commons.cpp ) source_group("Source Files" FILES ${SOURCE_FILES}) diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp b/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp index 641dc90cb2..b126c689fa 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp @@ -149,17 +149,6 @@ namespace { } return tmp; } - - openspace::fls::Model stringToModel(const std::string S) { - if (S == "batsrus") { - return openspace::fls::Model::BATSRUS; - } else if (S == "enlil") { - return openspace::fls::Model::ENLIL; - } else if (S == "pfss") { - return openspace::fls::Model::PFSS; - } - return openspace::fls::Model::INVALID; - } } // namespace namespace openspace { @@ -445,7 +434,7 @@ bool RenderableFieldlinesSequence::extractJsonInfoFromDictionary(fls::Model& mod std::string modelStr; if (_dictionary->getValue(KEY_JSON_SIMULATION_MODEL, modelStr)) { std::transform(modelStr.begin(), modelStr.end(), modelStr.begin(), ::tolower); - model = stringToModel(modelStr); + model = fls::stringToModel(modelStr); } else { LERROR(_name << ": Must specify '" << KEY_JSON_SIMULATION_MODEL << "'"); return false; diff --git a/modules/fieldlinessequence/util/commons.cpp b/modules/fieldlinessequence/util/commons.cpp new file mode 100644 index 0000000000..76bedb6dc9 --- /dev/null +++ b/modules/fieldlinessequence/util/commons.cpp @@ -0,0 +1,42 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2017 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include + +namespace openspace { +namespace fls { + +Model stringToModel(const std::string S) { + if (S == "batsrus") { + return Model::BATSRUS; + } else if (S == "enlil") { + return Model::ENLIL; + } else if (S == "pfss") { + return Model::PFSS; + } + return Model::INVALID; +} + +} // namespace fls +} // namespace openspace \ No newline at end of file diff --git a/modules/fieldlinessequence/util/commons.h b/modules/fieldlinessequence/util/commons.h index f019070095..488f358451 100644 --- a/modules/fieldlinessequence/util/commons.h +++ b/modules/fieldlinessequence/util/commons.h @@ -37,7 +37,7 @@ enum Model : int { INVALID }; - +Model stringToModel(const std::string S); const float A_U_TO_METER = 149597870700.f; // Astronomical Units const float R_E_TO_METER = 6371000.f; // Earth radius From fad306d510e7d1a950b204f395f7395e573467a6 Mon Sep 17 00:00:00 2001 From: Oskar Carlbaum Date: Mon, 9 Oct 2017 20:26:02 +0200 Subject: [PATCH 25/39] Cleanup! Neater structure in initialize. --- .../rendering/renderablefieldlinessequence.h | 4 + .../renderablefieldlinessequencesetup.cpp | 113 ++++++++++-------- .../util/fieldlinesstate.cpp | 14 ++- 3 files changed, 80 insertions(+), 51 deletions(-) diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h index dcf7363c90..7fef4cb1cc 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h @@ -136,6 +136,7 @@ private: properties::TriggerProperty _pJumpToStartBtn; // Button which executes a time jump to start of sequence // --------------------- FUNCTIONS USED DURING INITIALIZATION --------------------- // + void addStateToSequence(FieldlinesState& STATE); void computeSequenceEndTime(); void definePropertyCallbackFunctions(); bool extractJsonInfoFromDictionary(fls::Model& model); @@ -143,8 +144,11 @@ private: void extractOptionalInfoFromDictionary(std::string& outputFolderPath); void extractOsflsInfoFromDictionary(); void extractTriggerTimesFromFileNames(); + bool loadJsonStatesIntoRAM(const std::string& OUTPUT_FOLDER); + void loadOsflsStatesIntoRAM(const std::string& OUTPUT_FOLDER); void setModelDependentConstants(); void setupProperties(); + bool prepareForOsflsStreaming(); // ------------------------- FUNCTIONS USED DURING RUNTIME ------------------------ // inline bool isWithinSequenceInterval(const double CURRENT_TIME) const; diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp b/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp index b126c689fa..8343f6cddd 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp @@ -205,7 +205,6 @@ void RenderableFieldlinesSequence::initialize() { // EXTRACT OPTIONAL INFORMATION FROM DICTIONARY std::string outputFolderPath; extractOptionalInfoFromDictionary(outputFolderPath); - const bool SHOULD_SAVE_STATES = !outputFolderPath.empty(); // EXTRACT SOURCE FILE TYPE SPECIFIC INFOMRATION FROM DICTIONARY & GET STATES FROM SOURCE switch (sourceFileType) { @@ -213,59 +212,18 @@ void RenderableFieldlinesSequence::initialize() { LERROR("CDF NOT YET IMPLEMENTED!"); return; break; case SourceFileType::JSON: - fls::Model model; - if (!extractJsonInfoFromDictionary(model)) { + if (!loadJsonStatesIntoRAM(outputFolderPath)) { return; } - // Load states into RAM! - for (std::string filePath : _sourceFiles) { - FieldlinesState newState; - bool loadedSuccessfully = newState.loadStateFromJson(filePath, model, - _scalingFactor); - if (loadedSuccessfully) { - _states.push_back(newState); - _startTimes.push_back(newState.triggerTime()); - _nStates++; - if (SHOULD_SAVE_STATES) { - std::string pathSafeTimeString = Time(_startTimes.back()).ISO8601(); - pathSafeTimeString.replace(13, 1, "-"); - pathSafeTimeString.replace(16, 1, "-"); - pathSafeTimeString.replace(19, 1, "-"); - newState.saveStateToOsfls(outputFolderPath + pathSafeTimeString); - } - } - } break; case SourceFileType::OSFLS: extractOsflsInfoFromDictionary(); if (_loadingStatesDynamically) { - extractTriggerTimesFromFileNames(); - FieldlinesState newState; - bool loadedSuccessfully = newState.loadStateFromOsfls(_sourceFiles[0]); - if (loadedSuccessfully) { - _states.push_back(newState); - _nStates = _startTimes.size(); - _activeStateIndex = 0; - } else { - LERROR("The provided .osfls files seem to be corrupt!"); - sourceFileType = SourceFileType::INVALID; + if (!prepareForOsflsStreaming()) { + return; } } else { - // Load states into RAM! - for (std::string filePath : _sourceFiles) { - FieldlinesState newState; - bool loadedSuccessfully = newState.loadStateFromOsfls(filePath); - if (loadedSuccessfully) { - _states.push_back(newState); - _startTimes.push_back(newState.triggerTime()); - _nStates++; - - if (SHOULD_SAVE_STATES) { - ghoul::filesystem::File tmpFile(filePath); - newState.saveStateToJson(outputFolderPath + tmpFile.baseName()); - } - } - } + loadOsflsStatesIntoRAM(outputFolderPath); } break; default: @@ -275,12 +233,17 @@ void RenderableFieldlinesSequence::initialize() { // dictionary is no longer needed as everything is extracted _dictionary.reset(); - // At this point there's at least one state loaded into memory! // No need to store source paths in memory if they are already in RAM! if (!_loadingStatesDynamically) { _sourceFiles.clear(); } + // At this point there should be at least one state loaded into memory! + if (_states.size() == 0) { + LERROR("Wasn't able to extract any valid states from provided source files!"); + return; + } + computeSequenceEndTime(); setModelDependentConstants(); @@ -450,6 +413,56 @@ bool RenderableFieldlinesSequence::extractJsonInfoFromDictionary(fls::Model& mod return true; } +bool RenderableFieldlinesSequence::loadJsonStatesIntoRAM(const std::string& OUTPUT_FOLDER) { + fls::Model model; + if (!extractJsonInfoFromDictionary(model)) { + return false; + } + // Load states into RAM! + for (std::string filePath : _sourceFiles) { + FieldlinesState newState; + bool loadedSuccessfully = newState.loadStateFromJson(filePath, model, + _scalingFactor); + if (loadedSuccessfully) { + addStateToSequence(newState); + if (!OUTPUT_FOLDER.empty()) { + newState.saveStateToOsfls(OUTPUT_FOLDER); + } + } + } + return true; +} + +bool RenderableFieldlinesSequence::prepareForOsflsStreaming() { + extractTriggerTimesFromFileNames(); + FieldlinesState newState; + if (!newState.loadStateFromOsfls(_sourceFiles[0])) { + LERROR("The provided .osfls files seem to be corrupt!"); + return false; + } + _states.push_back(newState); + _nStates = _startTimes.size(); + _activeStateIndex = 0; + return true; + +} + +void RenderableFieldlinesSequence::loadOsflsStatesIntoRAM(const std::string& OUTPUT_FOLDER) { + // Load states from .osfls files into RAM! + for (const std::string FILEPATH : _sourceFiles) { + FieldlinesState newState; + if (newState.loadStateFromOsfls(FILEPATH)) { + addStateToSequence(newState); + if (!OUTPUT_FOLDER.empty()) { + ghoul::filesystem::File tmpFile(FILEPATH); + newState.saveStateToJson(OUTPUT_FOLDER + tmpFile.baseName()); + } + } else { + LWARNING("Failed to load state from: " << FILEPATH); + } + } +} + void RenderableFieldlinesSequence::extractOsflsInfoFromDictionary() { bool shouldLoadInRealtime = false; if (_dictionary->getValue(KEY_OSLFS_LOAD_AT_RUNTIME, shouldLoadInRealtime)) { @@ -664,4 +677,10 @@ void RenderableFieldlinesSequence::extractTriggerTimesFromFileNames() { } } +void RenderableFieldlinesSequence::addStateToSequence(FieldlinesState& state) { + _states.push_back(state); + _startTimes.push_back(state.triggerTime()); + _nStates++; +} + } // namespace openspace diff --git a/modules/fieldlinessequence/util/fieldlinesstate.cpp b/modules/fieldlinessequence/util/fieldlinesstate.cpp index 264513ce0c..ed7928d763 100644 --- a/modules/fieldlinessequence/util/fieldlinesstate.cpp +++ b/modules/fieldlinessequence/util/fieldlinesstate.cpp @@ -212,14 +212,20 @@ bool FieldlinesState::loadStateFromJson(const std::string& PATH_TO_JSON_FILE, * 11. array of c_str - Strings naming the extra quantities (elements of _extraQuantityNames). Each string ends with null char '\0' */ void FieldlinesState::saveStateToOsfls(const std::string& ABS_FILEPATH) { - // Create the file - const std::string EXT = ".osfls"; - std::ofstream ofs(ABS_FILEPATH + EXT, std::ofstream::binary | std::ofstream::trunc); + // ------------------------------- Create the file ------------------------------- // + std::string pathSafeTimeString = Time(_triggerTime).ISO8601(); + pathSafeTimeString.replace(13, 1, "-"); + pathSafeTimeString.replace(16, 1, "-"); + pathSafeTimeString.replace(19, 1, "-"); + const std::string FILENAME = pathSafeTimeString + ".osfls"; + + std::ofstream ofs(ABS_FILEPATH + FILENAME, std::ofstream::binary | std::ofstream::trunc); if (!ofs.is_open()) { - LERROR("Failed to save state to binary file: " << ABS_FILEPATH << EXT); + LERROR("Failed to save state to binary file: " << ABS_FILEPATH << FILENAME); return; } + // --------- Add each string of _extraQuantityNames into one long string --------- // std::string allExtraQuantityNamesInOne = ""; for (std::string str : _extraQuantityNames) { allExtraQuantityNamesInOne += str + '\0'; // Add the null char '\0' for easier reading From 3f756016e746c6089d5e0cd49da735078307f051 Mon Sep 17 00:00:00 2001 From: Oskar Carlbaum Date: Mon, 9 Oct 2017 21:20:26 +0200 Subject: [PATCH 26/39] Ensure no extraQuantity-dependent properties are added when there are no extraQuantities --- .../renderablefieldlinessequence.cpp | 2 - .../renderablefieldlinessequencesetup.cpp | 161 +++++++++--------- 2 files changed, 83 insertions(+), 80 deletions(-) diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp index 2fb669f39f..c4a1cb89cf 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp @@ -209,8 +209,6 @@ void RenderableFieldlinesSequence::update(const UpdateData& data) { if (_states[_activeStateIndex].nExtraQuantities() > 0) { _shouldUpdateColorBuffer = true; _shouldUpdateMaskingBuffer = true; - } else { - _pColorMethod = ColorMethod::UNIFORM; } // Everything is set and ready for rendering! diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp b/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp index 8343f6cddd..53e92a433b 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp @@ -474,11 +474,13 @@ void RenderableFieldlinesSequence::extractOsflsInfoFromDictionary() { } void RenderableFieldlinesSequence::setupProperties() { + bool hasExtras = _states[0].nExtraQuantities() > 0; + // -------------- Add non-grouped properties (enablers and buttons) -------------- // addProperty(_pColorABlendEnabled); addProperty(_pDomainEnabled); addProperty(_pFlowEnabled); - addProperty(_pMaskingEnabled); + if (hasExtras) { addProperty(_pMaskingEnabled); } addProperty(_pFocusOnOriginBtn); addProperty(_pJumpToStartBtn); @@ -486,111 +488,114 @@ void RenderableFieldlinesSequence::setupProperties() { addPropertySubOwner(_pColorGroup); addPropertySubOwner(_pDomainGroup); addPropertySubOwner(_pFlowGroup); - addPropertySubOwner(_pMaskingGroup); + if (hasExtras) { addPropertySubOwner(_pMaskingGroup); } // ------------------------- Add Properties to the groups ------------------------- // - _pColorGroup.addProperty(_pColorMethod); - _pColorGroup.addProperty(_pColorQuantity); - _pColorGroup.addProperty(_pColorQuantityMin); - _pColorGroup.addProperty(_pColorQuantityMax); - _pColorGroup.addProperty(_pColorTablePath); _pColorGroup.addProperty(_pColorUniform); - _pDomainGroup.addProperty(_pDomainX); _pDomainGroup.addProperty(_pDomainY); _pDomainGroup.addProperty(_pDomainZ); _pDomainGroup.addProperty(_pDomainR); - _pFlowGroup.addProperty(_pFlowReversed); _pFlowGroup.addProperty(_pFlowColor); _pFlowGroup.addProperty(_pFlowParticleSize); _pFlowGroup.addProperty(_pFlowParticleSpacing); _pFlowGroup.addProperty(_pFlowSpeed); + if (hasExtras) { + _pColorGroup.addProperty(_pColorMethod); + _pColorGroup.addProperty(_pColorQuantity); + _pColorGroup.addProperty(_pColorQuantityMin); + _pColorGroup.addProperty(_pColorQuantityMax); + _pColorGroup.addProperty(_pColorTablePath); + _pMaskingGroup.addProperty(_pMaskingMin); + _pMaskingGroup.addProperty(_pMaskingMax); + _pMaskingGroup.addProperty(_pMaskingQuantity); - _pMaskingGroup.addProperty(_pMaskingMin); - _pMaskingGroup.addProperty(_pMaskingMax); - _pMaskingGroup.addProperty(_pMaskingQuantity); - - // ----------------------- Add Options to OptionProperties ----------------------- // - _pColorMethod.addOption(ColorMethod::UNIFORM, "Uniform"); - _pColorMethod.addOption(ColorMethod::BY_QUANTITY, "By Quantity"); - - /* Add option for each extra quantity. We assume that there are just as many names to - extra quantities as there are extra quantities. We also assume that all states in - the given sequence have the same extra quantities! */ - const size_t N_EXTRA_QUANTITIES = _states[0].nExtraQuantities(); - auto EXTRA_VARIABLE_NAMES_VEC = _states[0].extraQuantityNames(); - for (int i = 0; i < N_EXTRA_QUANTITIES; ++i) { - _pColorQuantity.addOption(i, EXTRA_VARIABLE_NAMES_VEC[i]); - _pMaskingQuantity.addOption(i, EXTRA_VARIABLE_NAMES_VEC[i]); + // --------------------- Add Options to OptionProperties --------------------- // + _pColorMethod.addOption(ColorMethod::UNIFORM, "Uniform"); + _pColorMethod.addOption(ColorMethod::BY_QUANTITY, "By Quantity"); + // Add option for each extra quantity. Assumes there are just as many names to + // extra quantities as there are extra quantities. Also assume that all states in + // the given sequence have the same extra quantities! */ + const size_t N_EXTRA_QUANTITIES = _states[0].nExtraQuantities(); + const std::vector& XTRA_NAMES_VEC = _states[0].extraQuantityNames(); + for (int i = 0; i < N_EXTRA_QUANTITIES; ++i) { + _pColorQuantity.addOption(i, XTRA_NAMES_VEC[i]); + _pMaskingQuantity.addOption(i, XTRA_NAMES_VEC[i]); + } + // Each quantity should have its own color table and color table range, no more, no less + _colorTablePaths.resize(N_EXTRA_QUANTITIES, _colorTablePaths.back()); + _colorTableRanges.resize(N_EXTRA_QUANTITIES, _colorTableRanges.back()); + _maskingRanges.resize(N_EXTRA_QUANTITIES, _maskingRanges.back()); } - // Each quantity should have its own color table and color table range, no more, no less - _colorTablePaths.resize(N_EXTRA_QUANTITIES, _colorTablePaths.back()); - _colorTableRanges.resize(N_EXTRA_QUANTITIES, _colorTableRanges.back()); - _maskingRanges.resize(N_EXTRA_QUANTITIES, _maskingRanges.back()); definePropertyCallbackFunctions(); - // Set defaults - _pColorQuantity = 0; - _pColorQuantityMin = std::to_string(_colorTableRanges[_pColorQuantity].x); - _pColorQuantityMax = std::to_string(_colorTableRanges[_pColorQuantity].y); - _pColorTablePath = _colorTablePaths[_pColorQuantity]; + if (hasExtras) { + // Set defaults + _pColorQuantity = 0; + _pColorQuantityMin = std::to_string(_colorTableRanges[0].x); + _pColorQuantityMax = std::to_string(_colorTableRanges[0].y); + _pColorTablePath = _colorTablePaths[0]; - _pMaskingQuantity = 0; - _pMaskingMin = std::to_string(_maskingRanges[_pMaskingQuantity].x); - _pMaskingMax = std::to_string(_maskingRanges[_pMaskingQuantity].y); + _pMaskingQuantity = 0; + _pMaskingMin = std::to_string(_maskingRanges[0].x); + _pMaskingMax = std::to_string(_maskingRanges[0].y); + } } void RenderableFieldlinesSequence::definePropertyCallbackFunctions() { // Add Property Callback Functions - _pColorQuantity.onChange([this] { - LDEBUG("CHANGED COLORING QUANTITY"); - _shouldUpdateColorBuffer = true; - _pColorQuantityMin = std::to_string(_colorTableRanges[_pColorQuantity].x); - _pColorQuantityMax = std::to_string(_colorTableRanges[_pColorQuantity].y); - _pColorTablePath = _colorTablePaths[_pColorQuantity]; - }); + bool hasExtras = _states[0].nExtraQuantities() > 0; + if (hasExtras) { + _pColorQuantity.onChange([this] { + LDEBUG("CHANGED COLORING QUANTITY"); + _shouldUpdateColorBuffer = true; + _pColorQuantityMin = std::to_string(_colorTableRanges[_pColorQuantity].x); + _pColorQuantityMax = std::to_string(_colorTableRanges[_pColorQuantity].y); + _pColorTablePath = _colorTablePaths[_pColorQuantity]; + }); - _pColorTablePath.onChange([this] { - _transferFunction->setPath(_pColorTablePath); - _colorTablePaths[_pColorQuantity] = _pColorTablePath; - }); + _pColorTablePath.onChange([this] { + _transferFunction->setPath(_pColorTablePath); + _colorTablePaths[_pColorQuantity] = _pColorTablePath; + }); - _pColorQuantityMin.onChange([this] { - LDEBUG("CHANGED MIN VALUE"); - float f = stringToFloat(_pColorQuantityMin, _colorTableRanges[_pColorQuantity].x); - _pColorQuantityMin = std::to_string(f); - _colorTableRanges[_pColorQuantity].x = f; - }); + _pColorQuantityMin.onChange([this] { + LDEBUG("CHANGED MIN VALUE"); + float f = stringToFloat(_pColorQuantityMin, _colorTableRanges[_pColorQuantity].x); + _pColorQuantityMin = std::to_string(f); + _colorTableRanges[_pColorQuantity].x = f; + }); - _pColorQuantityMax.onChange([this] { - LDEBUG("CHANGED MAX VALUE"); - float f = stringToFloat(_pColorQuantityMax, _colorTableRanges[_pColorQuantity].y); - _pColorQuantityMax = std::to_string(f); - _colorTableRanges[_pColorQuantity].y = f; - }); + _pColorQuantityMax.onChange([this] { + LDEBUG("CHANGED MAX VALUE"); + float f = stringToFloat(_pColorQuantityMax, _colorTableRanges[_pColorQuantity].y); + _pColorQuantityMax = std::to_string(f); + _colorTableRanges[_pColorQuantity].y = f; + }); - _pMaskingQuantity.onChange([this] { - LDEBUG("CHANGED MASKING QUANTITY"); - _shouldUpdateMaskingBuffer = true; - _pMaskingMin = std::to_string(_maskingRanges[_pMaskingQuantity].x); - _pMaskingMax = std::to_string(_maskingRanges[_pMaskingQuantity].y); - }); + _pMaskingQuantity.onChange([this] { + LDEBUG("CHANGED MASKING QUANTITY"); + _shouldUpdateMaskingBuffer = true; + _pMaskingMin = std::to_string(_maskingRanges[_pMaskingQuantity].x); + _pMaskingMax = std::to_string(_maskingRanges[_pMaskingQuantity].y); + }); - _pMaskingMin.onChange([this] { - LDEBUG("CHANGED LOWER MASKING LIMIT"); - float f = stringToFloat(_pMaskingMin, _maskingRanges[_pMaskingQuantity].x); - _pMaskingMin = std::to_string(f); - _maskingRanges[_pMaskingQuantity].x = f; - }); + _pMaskingMin.onChange([this] { + LDEBUG("CHANGED LOWER MASKING LIMIT"); + float f = stringToFloat(_pMaskingMin, _maskingRanges[_pMaskingQuantity].x); + _pMaskingMin = std::to_string(f); + _maskingRanges[_pMaskingQuantity].x = f; + }); - _pMaskingMax.onChange([this] { - LDEBUG("CHANGED UPPER MASKING LIMIT"); - float f = stringToFloat(_pMaskingMax, _maskingRanges[_pMaskingQuantity].y); - _pMaskingMax = std::to_string(f); - _maskingRanges[_pMaskingQuantity].y = f; - }); + _pMaskingMax.onChange([this] { + LDEBUG("CHANGED UPPER MASKING LIMIT"); + float f = stringToFloat(_pMaskingMax, _maskingRanges[_pMaskingQuantity].y); + _pMaskingMax = std::to_string(f); + _maskingRanges[_pMaskingQuantity].y = f; + }); + } _pFocusOnOriginBtn.onChange([this] { LDEBUG("SET FOCUS NODE TO PARENT"); From bf830731206cafa36d37b70ba49ac75cd520935b Mon Sep 17 00:00:00 2001 From: Oskar Carlbaum Date: Mon, 9 Oct 2017 21:30:57 +0200 Subject: [PATCH 27/39] Add general helper functions for Kameleon --- modules/kameleon/CMakeLists.txt | 2 + modules/kameleon/include/kameleonhelper.h | 42 ++++++ modules/kameleon/src/kameleonhelper.cpp | 152 ++++++++++++++++++++++ 3 files changed, 196 insertions(+) create mode 100644 modules/kameleon/include/kameleonhelper.h create mode 100644 modules/kameleon/src/kameleonhelper.cpp diff --git a/modules/kameleon/CMakeLists.txt b/modules/kameleon/CMakeLists.txt index be287a3f30..cbd27c5872 100644 --- a/modules/kameleon/CMakeLists.txt +++ b/modules/kameleon/CMakeLists.txt @@ -26,11 +26,13 @@ include(${OPENSPACE_CMAKE_EXT_DIR}/module_definition.cmake) set(HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/kameleonwrapper.h + ${CMAKE_CURRENT_SOURCE_DIR}/include/kameleonhelper.h ) source_group("Header Files" FILES ${HEADER_FILES}) set(SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/kameleonwrapper.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/kameleonhelper.cpp ) source_group("Source Files" FILES ${SOURCE_FILES}) diff --git a/modules/kameleon/include/kameleonhelper.h b/modules/kameleon/include/kameleonhelper.h new file mode 100644 index 0000000000..6d89c87c2f --- /dev/null +++ b/modules/kameleon/include/kameleonhelper.h @@ -0,0 +1,42 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2017 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#ifndef __OPENSPACE_MODULE_KAMELEON___KAMELEONHELPER___H__ +#define __OPENSPACE_MODULE_KAMELEON___KAMELEONHELPER___H__ + +#include +#include + +namespace ccmc { + class Kameleon; +} // namespace ccmc + +namespace openspace::kameleonHelper { + + std::unique_ptr createKameleonObject(const std::string& CDF_FILE_PATH); + double getTime(ccmc::Kameleon* kameleon); + +} //namespace openspace::kameleonHelper + +#endif // __OPENSPACE_MODULE_KAMELEON___KAMELEONHELPER___H__ diff --git a/modules/kameleon/src/kameleonhelper.cpp b/modules/kameleon/src/kameleonhelper.cpp new file mode 100644 index 0000000000..8ee44abd60 --- /dev/null +++ b/modules/kameleon/src/kameleonhelper.cpp @@ -0,0 +1,152 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2017 * + * * + * 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 { + std::string _loggerCat = "KameleonHelper"; +} + +namespace openspace::kameleonHelper { + +/** + * Opens a ccmc::Kameleon object from the provided path to a .cdf file. + * Path should be absolute. + * + * Returns 'nullptr' if the file fails to open! + */ +std::unique_ptr createKameleonObject(const std::string& CDF_FILE_PATH) { + + // ---------------------------- CREATE KAMELEON OBJECT ---------------------------- // + std::unique_ptr kameleon = std::make_unique(); + LDEBUG("\tOpening the cdf file: " << CDF_FILE_PATH); + long kamStatus = kameleon->open(CDF_FILE_PATH); + + if (kamStatus != ccmc::FileReader::OK) { + LERROR("Failed to create a Kameleon Object from file: " << CDF_FILE_PATH); + return nullptr; + } + LDEBUG("\tSuccessfully opened : " << CDF_FILE_PATH); + return kameleon; +} + +/** + * Extract the time for the simulation. Time is returned as a J2000 double. + * + * *NOTE!* The function has only been tested for some BATSRUS and ENLIL and may need to + * be updated to work with other models! + */ +double getTime(ccmc::Kameleon* kameleon) { + // Inspiration from 'void KameleonInterpolator::setEphemTime()' which doesn't seem to + // exist in the version of Kameleon that is included in OpenSpace. Alterations + // done to fit here. + // As a new version of Kameleon is included in OpenSpace this function may prove to be + // redundant! + + std::string seqStartStr; + double seqStartDbl; + if (kameleon->doesAttributeExist("start_time")){ + seqStartStr = + kameleon->getGlobalAttribute("start_time").getAttributeString(); + } else if (kameleon->doesAttributeExist("tim_rundate_cal")) { + seqStartStr = + kameleon->getGlobalAttribute("tim_rundate_cal").getAttributeString(); + const size_t N_CHARS = seqStartStr.length(); + if (N_CHARS < 19) { + // Fall through to add the required characters + switch (N_CHARS) { + case 10 : // YYYY-MM-DD => YYYY-MM-DDTHH + seqStartStr += "T00"; + case 13 : // YYYY-MM-DDTHH => YYYY-MM-DDTHH: + seqStartStr += ":"; + case 14 : // YYYY-MM-DDTHH: => YYYY-MM-DDTHH:MM + seqStartStr += "00"; + case 16 : // YYYY-MM-DDTHH:MM => YYYY-MM-DDTHH:MM: + seqStartStr += ":"; + case 17 : // YYYY-MM-DDTHH:MM: => YYYY-MM-DDTHH:MM:SS + seqStartStr += "00"; + // case 19 : // YYYY-MM-DDTHH:MM:SS => YYYY-MM-DDTHH:MM:SS.000 + // seqStartStr += ".000"; + // case 23 : // YYYY-MM-DDTHH:MM:SS. => YYYY-MM-DDTHH:MM:SS.000Z + // seqStartStr += "Z"; + default : + break; + } + } + // else if (seqStartStr.length() < 19 && kameleon->doesAttributeExist("tim_crstart_cal")) { + // seqStartStr = + // kameleon->getGlobalAttribute("tim_crstart_cal").getAttributeString(); + // } + } else if (kameleon->doesAttributeExist("tim_obsdate_cal")) { + seqStartStr = + kameleon->getGlobalAttribute("tim_obsdate_cal").getAttributeString(); + } else if (kameleon->doesAttributeExist("tim_crstart_cal")) { + seqStartStr = + kameleon->getGlobalAttribute("tim_crstart_cal").getAttributeString(); + } else { + LWARNING("No starting time attribute could be found in the .cdf file.\n\t" << + "Starting time is set to 01.JAN.2000 12:00."); + seqStartDbl = 0.0; + } + + if (seqStartStr.length() == 19){ + seqStartStr += ".000Z"; + } + + if (seqStartStr.length() == 24){ + seqStartDbl = + Time::convertTime( + seqStartStr.substr(0, seqStartStr.length() - 2)); + } else { + LWARNING("No starting time attribute could be found in the .cdf file.\n\t" << + "Starting time is set to 01.JAN.2000 12:00."); + seqStartDbl = 0.0; + } + + double stateStartOffset; + + if (kameleon->doesAttributeExist("elapsed_time_in_seconds")) { + stateStartOffset = static_cast( + kameleon->getGlobalAttribute( + "elapsed_time_in_seconds").getAttributeFloat()); + } else if (kameleon->doesAttributeExist("time_physical_time")) { + stateStartOffset = static_cast( + kameleon->getGlobalAttribute( + "time_physical_time").getAttributeFloat()); + } else { + stateStartOffset = 0.0; + LWARNING("No time offset attribute could be found in the .cdf file.\n\t" << + "The current state starts the same time as the sequence!"); + } + + return seqStartDbl + stateStartOffset; +} + +} // namespace openspace::kameleonHelper { From 4fc88c595f3b68cfbc70bb58e232197050576cb6 Mon Sep 17 00:00:00 2001 From: Oskar Carlbaum Date: Mon, 9 Oct 2017 21:56:47 +0200 Subject: [PATCH 28/39] Load CDFs and trace field lines using kameleon and store the info in FieldlinesState. --- .../rendering/renderablefieldlinessequence.h | 9 ++ .../renderablefieldlinessequencesetup.cpp | 150 +++++++++++++++++- .../util/fieldlinesstate.cpp | 104 ++++++++++++ .../fieldlinessequence/util/fieldlinesstate.h | 16 ++ 4 files changed, 275 insertions(+), 4 deletions(-) diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h index 7fef4cb1cc..b61b5667f7 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h @@ -149,6 +149,15 @@ private: void setModelDependentConstants(); void setupProperties(); bool prepareForOsflsStreaming(); +#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED + // --- Initialization functions which require the kameleon module to be loaded! --- // + bool extractCdfInfoFromDictionary(std::string& seedFilePath, + std::string& tracingVar, + std::vector& extraVars); + bool extractSeedPointsFromFile(const std::string& path, + std::vector& outVec); + bool getStatesFromCdfFiles(const std::string& OUTPUT_FOLDER); +#endif // OPENSPACE_MODULE_KAMELEON_ENABLED // ------------------------- FUNCTIONS USED DURING RUNTIME ------------------------ // inline bool isWithinSequenceInterval(const double CURRENT_TIME) const; diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp b/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp index 53e92a433b..c4e1d78b8c 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp @@ -24,6 +24,11 @@ #include +#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED + #include + #include +#endif // OPENSPACE_MODULE_KAMELEON_ENABLED + #include #include #include @@ -33,6 +38,9 @@ #include #include +#include +#include + namespace { std::string _loggerCat = "RenderableFieldlinesSequence"; @@ -41,14 +49,21 @@ namespace { const char* KEY_INPUT_FILE_TYPE = "InputFileType"; // [STRING] const char* KEY_SOURCE_FOLDER = "SourceFolder"; // [STRING] + // ---------------------- MANDATORY INPUT TYPE SPECIFIC KEYS ---------------------- // + const char* KEY_CDF_SEED_POINT_FILE = "SeedPointFile"; // [STRING] Path to a .txt file containing seed points + const char* KEY_JSON_SIMULATION_MODEL = "SimulationModel"; // [STRING] Currently supports: "batsrus", "enlil" & "pfss" + + // ----------------------- OPTIONAL INPUT TYPE SPECIFIC KEYS ---------------------- // + const char* KEY_CDF_EXTRA_VARIABLES = "ExtraVariables"; // [STRING ARRAY] + const char* KEY_CDF_TRACING_VARIABLE = "TracingVariable"; // [STRING] + const char* KEY_JSON_SCALING_FACTOR = "ScaleToMeters"; // [STRING] + const char* KEY_OSLFS_LOAD_AT_RUNTIME = "LoadAtRuntime"; // [BOOLEAN] If value False => Load in initializing step and store in RAM + // ---------------------------- OPTIONAL MODFILE KEYS ---------------------------- // const char* KEY_COLOR_TABLE_PATHS = "ColorTablePaths"; // [STRING ARRAY] Values should be paths to .txt files const char* KEY_COLOR_TABLE_RANGES = "ColorTableRanges";// [VEC2 ARRAY] Values should be entered as {X, Y}, where X & Y are numbers const char* KEY_MASKING_RANGES = "MaskingRanges"; // [VEC2 ARRAY] Values should be entered as {X, Y}, where X & Y are numbers const char* KEY_OUTPUT_FOLDER = "OutputFolder"; // [STRING] Value should be path to folder where states are saved (JSON/CDF input => osfls output & oslfs input => JSON output) - const char* KEY_JSON_SIMULATION_MODEL = "SimulationModel"; // [STRING] - const char* KEY_JSON_SCALING_FACTOR = "ScaleToMeters"; // [STRING] - const char* KEY_OSLFS_LOAD_AT_RUNTIME = "LoadAtRuntime"; // [BOOLEAN] If value False => Load in initializing step and store in RAM // ------------- POSSIBLE STRING VALUES FOR CORRESPONDING MODFILE KEY ------------- // const char* VALUE_INPUT_FILE_TYPE_CDF = "cdf"; @@ -209,7 +224,11 @@ void RenderableFieldlinesSequence::initialize() { // EXTRACT SOURCE FILE TYPE SPECIFIC INFOMRATION FROM DICTIONARY & GET STATES FROM SOURCE switch (sourceFileType) { case SourceFileType::CDF: - LERROR("CDF NOT YET IMPLEMENTED!"); return; +#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED + if (!getStatesFromCdfFiles(outputFolderPath)) { + return; + } +#endif // OPENSPACE_MODULE_KAMELEON_ENABLED break; case SourceFileType::JSON: if (!loadJsonStatesIntoRAM(outputFolderPath)) { @@ -292,6 +311,10 @@ bool RenderableFieldlinesSequence::extractMandatoryInfoFromDictionary( // Verify that the input type is correct if (inputFileTypeString == VALUE_INPUT_FILE_TYPE_CDF) { sourceFileType = SourceFileType::CDF; +#ifndef OPENSPACE_MODULE_KAMELEON_ENABLED + LERROR(_name << ": CDF file inputs requires the 'Kameleon' module to be enabled!"); + return false; +#endif // OPENSPACE_MODULE_KAMELEON_ENABLED } else if (inputFileTypeString == VALUE_INPUT_FILE_TYPE_JSON) { sourceFileType = SourceFileType::JSON; } else if (inputFileTypeString == VALUE_INPUT_FILE_TYPE_OSFLS) { @@ -688,4 +711,123 @@ void RenderableFieldlinesSequence::addStateToSequence(FieldlinesState& state) { _nStates++; } +#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED +bool RenderableFieldlinesSequence::getStatesFromCdfFiles(const std::string& OUTPUT_FOLDER) { + + std::string seedFilePath; + std::string tracingVar; + std::vector extraVars; + if (!extractCdfInfoFromDictionary(seedFilePath, tracingVar, extraVars)) { + return false; + } + + std::vector seedPoints; + if (!extractSeedPointsFromFile(seedFilePath, seedPoints)) { + return false; + } + + // Load states into RAM! + for (std::string filePath : _sourceFiles) { + // Create Kameleon object and open CDF file! + std::unique_ptr kameleon = + kameleonHelper::createKameleonObject(filePath); + + FieldlinesState newState; + newState.setTriggerTime(kameleonHelper::getTime(kameleon.get())); + + if (newState.addLinesFromKameleon(kameleon.get(), seedPoints, tracingVar)) { + switch (newState.model()) { + case fls::BATSRUS: + newState.scalePositions(fls::R_E_TO_METER); + break; + case fls::ENLIL : + newState.convertLatLonToCartesian(fls::A_U_TO_METER); + break; + default: + break; + } + + addStateToSequence(newState); + if (!OUTPUT_FOLDER.empty()) { + newState.saveStateToOsfls(OUTPUT_FOLDER); + } + } + } + return true; +} +#endif // OPENSPACE_MODULE_KAMELEON_ENABLED + +#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED +/* + * Returns false if it fails to extract mandatory information! + */ +bool RenderableFieldlinesSequence::extractCdfInfoFromDictionary( + std::string& seedFilePath, + std::string& tracingVar, + std::vector& extraVars) { + + if (_dictionary->getValue(KEY_CDF_SEED_POINT_FILE, seedFilePath)) { + ghoul::filesystem::File seedPointFile(seedFilePath); + if (FileSys.fileExists(seedPointFile)) { + seedFilePath = absPath(seedFilePath); + } else { + LERROR(_name << ": The specified seed point file: '" << seedFilePath + << "', does not exist!"); + return false; + } + } else { + LERROR(_name << ": Must specify '" << KEY_CDF_SEED_POINT_FILE << "'"); + return false; + } + + if (!_dictionary->getValue(KEY_CDF_TRACING_VARIABLE, tracingVar)) { + tracingVar = "b"; // Magnetic field variable as default + LWARNING(_name << ": No '" << KEY_CDF_TRACING_VARIABLE << "', using default: " + << tracingVar); + } + + ghoul::Dictionary extraQuantityNamesDictionary; + if (_dictionary->getValue(KEY_CDF_EXTRA_VARIABLES, extraQuantityNamesDictionary)) { + const size_t N_PROVIDED_EXTRAS = extraQuantityNamesDictionary.size(); + for (size_t i = 1; i <= N_PROVIDED_EXTRAS; ++i) { + extraVars.push_back( + extraQuantityNamesDictionary.value(std::to_string(i))); + } + } + + return true; +} +#endif // OPENSPACE_MODULE_KAMELEON_ENABLED + +#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED +bool RenderableFieldlinesSequence::extractSeedPointsFromFile( + const std::string& path, + std::vector& outVec) { + + std::ifstream seedFile(FileSys.relativePath(path)); + if (!seedFile.good()) { + LERROR("Could not open seed points file '" << path << "'"); + return false; + } + + LDEBUG("Reading seed points from file '" << path << "'"); + std::string line; + while (std::getline(seedFile, line)) { + glm::vec3 point; + std::stringstream ss(line); + ss >> point.x; + ss >> point.y; + ss >> point.z; + outVec.push_back(std::move(point)); + } + + if (outVec.size() == 0) { + LERROR("Found no seed points in: " << path); + return false; + } + + return true; +} +#endif // OPENSPACE_MODULE_KAMELEON_ENABLED + } // namespace openspace diff --git a/modules/fieldlinessequence/util/fieldlinesstate.cpp b/modules/fieldlinessequence/util/fieldlinesstate.cpp index ed7928d763..6dd298b0e7 100644 --- a/modules/fieldlinessequence/util/fieldlinesstate.cpp +++ b/modules/fieldlinessequence/util/fieldlinesstate.cpp @@ -25,16 +25,27 @@ #include #include + #include #include #include +#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED + #include + #include + #include +#endif // OPENSPACE_MODULE_KAMELEON_ENABLED + namespace { std::string _loggerCat = "FieldlinesState"; const int CURRENT_VERSION = 0; + const std::string T_AS_P_OVER_RHO = "T = p/rho"; + const std::string J_PARALLEL_B = "Current: mag(J||B)"; + const float TO_KELVIN = 72429735.6984f; // <-- [nPa]/[amu/cm^3] * TO_KELVIN => Temperature in Kelvin + using json = nlohmann::json; } @@ -45,6 +56,99 @@ FieldlinesState::FieldlinesState(const std::string& PATH_TO_OSFLS_FILE, bool& lo loadSucessful = loadStateFromOsfls(PATH_TO_OSFLS_FILE); } +#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED +/** + * Traces and adds line vertices to state. (Also sets the simulation model variable: _model!) + * Vertices may need to be scaled to meters & converted from spherical into cartesian coordinates. + * Note that extraQuantities will NOT be set! + */ +bool FieldlinesState::addLinesFromKameleon(ccmc::Kameleon* kameleon, + const std::vector& SEED_POINTS, + const std::string TRACING_VAR) { + + _model = fls::stringToModel(kameleon->getModelName()); + + float innerBoundaryLimit; + + switch (_model) { + case fls::Model::BATSRUS : + innerBoundaryLimit = 2.5f; // TODO specify in Lua? + break; + case fls::Model::ENLIL : + innerBoundaryLimit = 0.11f; // TODO specify in Lua? + break; + default: + LERROR("OpenSpace's fieldlines sequence currently only supports CDFs from" << + "the BATSRUS and ENLIL models!" ); + return false; + } + + // --------------------------- LOAD TRACING VARIABLE ---------------------------- // + if (!kameleon->loadVariable(TRACING_VAR)) { + LERROR("FAILED TO LOAD TRACING VARIABLE: " << TRACING_VAR); + return false; + } + + LINFO("TRACING FIELD LINES!"); + // - LOOP THROUGH THE SEED POINTS, TRACE LINES AND CONVERT TO THE DESIRED FORMAT - // + size_t lineStart = 0; + for (glm::vec3 seed : SEED_POINTS) { + //--------------------------------------------------------------------------// + // We have to create a new tracer (or actually a new interpolator) for each // + // new line, otherwise some issues occur // + //--------------------------------------------------------------------------// + std::unique_ptr interpolator = + std::make_unique(kameleon->model); + ccmc::Tracer tracer(kameleon, interpolator.get()); + tracer.setInnerBoundary(innerBoundaryLimit); // TODO specify in Lua? + ccmc::Fieldline ccmcFieldline = tracer.bidirectionalTrace(TRACING_VAR, + seed.x, + seed.y, + seed.z); + const std::vector& POSITIONS = ccmcFieldline.getPositions(); + + _lineStart.push_back(lineStart); + const size_t N_LINE_POINTS = POSITIONS.size(); + _lineCount.push_back(static_cast(N_LINE_POINTS)); + lineStart += static_cast(N_LINE_POINTS); + + for (const ccmc::Point3f& p : POSITIONS) { + _vertexPositions.emplace_back( + glm::vec3(p.component1, p.component2, p.component3)); + } + } + + return _vertexPositions.size() > 0; +} +#endif // OPENSPACE_MODULE_KAMELEON_ENABLED + +#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED +/** +* Converts all glm::vec3 in _vertexPositions from spherical (radius, latitude, longitude) +* coordinates into cartesian coordinates. The longitude and latitude coordinates are +* expected to be in degrees. SCALE is an optional scaling factor. +*/ +void FieldlinesState::convertLatLonToCartesian(const float SCALE /* = 1.f */) { + for (glm::vec3& p : _vertexPositions) { + + const float R = p.x * SCALE; + const float LAT = glm::radians(p.y); + const float LON = glm::radians(p.z); + const float R_COS_LAT = R * cos(LAT); + + p = glm::vec3(R_COS_LAT * cos(LON), R_COS_LAT* sin(LON), R * sin(LAT)); + } +} +#endif // OPENSPACE_MODULE_KAMELEON_ENABLED + +#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED +void FieldlinesState::scalePositions(const float SCALE) { + for (glm::vec3& p : _vertexPositions) { + p *= SCALE; + } +} +#endif // OPENSPACE_MODULE_KAMELEON_ENABLED + bool FieldlinesState::loadStateFromOsfls(const std::string& PATH_TO_OSFLS_FILE) { std::ifstream ifs(PATH_TO_OSFLS_FILE, std::ifstream::binary); if (!ifs.is_open()) { diff --git a/modules/fieldlinessequence/util/fieldlinesstate.h b/modules/fieldlinessequence/util/fieldlinesstate.h index a4f2a9b50e..076a025462 100644 --- a/modules/fieldlinessequence/util/fieldlinesstate.h +++ b/modules/fieldlinessequence/util/fieldlinesstate.h @@ -35,6 +35,12 @@ using std::vector; +#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED +namespace ccmc { + class Kameleon; +} +#endif // OPENSPACE_MODULE_KAMELEON_ENABLED + namespace openspace { class FieldlinesState { @@ -42,6 +48,14 @@ public: FieldlinesState(); FieldlinesState(const std::string& PATH_TO_OSFLS_FILE, bool& loadSucessful); +#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED + bool addLinesFromKameleon(ccmc::Kameleon* kameleon, + const vector& SEED_POINTS, + const std::string TRACING_VAR); + void convertLatLonToCartesian(const float SCALE = 1.f); + void scalePositions(const float SCALE); +#endif // OPENSPACE_MODULE_KAMELEON_ENABLED + bool loadStateFromOsfls(const std::string& PATH_TO_OSFLS_FILE); void saveStateToOsfls(const std::string& PATH_TO_OSFLS_FILE); @@ -62,6 +76,8 @@ public: // Special getter. Returns extraQuantities[INDEX]. const vector& extraQuantity(const size_t INDEX, bool& isSuccesful) const; + void setTriggerTime(const double T) { _triggerTime = T; } + private: bool _isMorphable = false; double _triggerTime = -1.0; From 173a32b0203e0125f2d5e727212994782a9a4bcc Mon Sep 17 00:00:00 2001 From: Oskar Carlbaum Date: Mon, 9 Oct 2017 22:16:57 +0200 Subject: [PATCH 29/39] Add extraQuanities to FieldlinesState from cdf source --- .../rendering/renderablefieldlinessequence.h | 2 + .../renderablefieldlinessequencesetup.cpp | 39 +++++ .../util/fieldlinesstate.cpp | 149 ++++++++++++++++++ .../fieldlinessequence/util/fieldlinesstate.h | 8 + 4 files changed, 198 insertions(+) diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h index b61b5667f7..a9f3b8d233 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h @@ -156,6 +156,8 @@ private: std::vector& extraVars); bool extractSeedPointsFromFile(const std::string& path, std::vector& outVec); + void extractMagnitudeVarsFromStrings(std::vector& extraVars, + std::vector& extraMagVars); bool getStatesFromCdfFiles(const std::string& OUTPUT_FOLDER); #endif // OPENSPACE_MODULE_KAMELEON_ENABLED diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp b/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp index c4e1d78b8c..0abd7901db 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp @@ -726,6 +726,9 @@ bool RenderableFieldlinesSequence::getStatesFromCdfFiles(const std::string& OUTP return false; } + std::vector extraMagVars; + extractMagnitudeVarsFromStrings(extraVars, extraMagVars); + // Load states into RAM! for (std::string filePath : _sourceFiles) { // Create Kameleon object and open CDF file! @@ -736,6 +739,10 @@ bool RenderableFieldlinesSequence::getStatesFromCdfFiles(const std::string& OUTP newState.setTriggerTime(kameleonHelper::getTime(kameleon.get())); if (newState.addLinesFromKameleon(kameleon.get(), seedPoints, tracingVar)) { + // The line points are in their RAW format (unscaled & maybe spherical) + // Before we scale to meters (and maybe cartesian) we must extract + // the extraQuantites, as the iterpolator needs the unaltered positions + newState.addExtraQuantities(kameleon.get(), extraVars, extraMagVars); switch (newState.model()) { case fls::BATSRUS: newState.scalePositions(fls::R_E_TO_METER); @@ -830,4 +837,36 @@ bool RenderableFieldlinesSequence::extractSeedPointsFromFile( } #endif // OPENSPACE_MODULE_KAMELEON_ENABLED +#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED +void RenderableFieldlinesSequence::extractMagnitudeVarsFromStrings( + std::vector& extraVars, + std::vector& extraMagVars) { + + + for (int i = 0; i < extraVars.size(); i++) { + const std::string STR = extraVars[i]; + // Check if string is in the format specified for magnitude variables + if (STR.substr(0, 2) == "|(" && STR.substr(STR.size() - 2, 2) == ")|") { + std::istringstream ss(STR.substr(2, STR.size() - 4)); + std::string magVar; + size_t counter = 0; + while(std::getline(ss, magVar, ',')) { + magVar.erase(std::remove_if(magVar.begin(), magVar.end(), ::isspace), + magVar.end()); + extraMagVars.push_back(magVar); + counter++; + if (counter == 3) { + break; + } + } + if (counter != 3 && counter > 0) { + extraMagVars.erase(extraMagVars.end() - counter, extraMagVars.end()); + } + extraVars.erase(extraVars.begin() + i); + i--; + } + } +} +#endif // OPENSPACE_MODULE_KAMELEON_ENABLED + } // namespace openspace diff --git a/modules/fieldlinessequence/util/fieldlinesstate.cpp b/modules/fieldlinessequence/util/fieldlinesstate.cpp index 6dd298b0e7..9ffa156c3b 100644 --- a/modules/fieldlinessequence/util/fieldlinesstate.cpp +++ b/modules/fieldlinessequence/util/fieldlinesstate.cpp @@ -122,6 +122,155 @@ bool FieldlinesState::addLinesFromKameleon(ccmc::Kameleon* kameleon, } #endif // OPENSPACE_MODULE_KAMELEON_ENABLED +#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED +void FieldlinesState::loadExtrasIntoKameleon(ccmc::Kameleon* kameleon, + std::vector& xtraScalarVars, + std::vector& xtraMagVars) { + // Load the existing SCALAR variables into kameleon. + // Remove non-existing variables from vector + for (int i = 0; i < xtraScalarVars.size(); i++) { + std::string& str = xtraScalarVars[i]; + bool isSuccesful = kameleon->doesVariableExist(str) && kameleon->loadVariable(str); + if (!isSuccesful && + (_model == fls::Model::BATSRUS && (str == T_AS_P_OVER_RHO || str == "T" ))) { + LDEBUG("BATSRUS doesn't contain variable T for temperature. Trying to " + << "calculate it using the ideal gas law: T = pressure/density"); + const std::string P = "p", R = "rho"; + isSuccesful = kameleon->doesVariableExist(P) && kameleon->loadVariable(P) + && kameleon->doesVariableExist(R) && kameleon->loadVariable(R); + str = T_AS_P_OVER_RHO; + } + if (!isSuccesful) { + LWARNING("FAILED TO LOAD EXTRA VARIABLE: '" << str << "'. Ignoring it!"); + xtraScalarVars.erase(xtraScalarVars.begin() + i); + --i; + } else { + _extraQuantityNames.push_back(str); + } + } + + // Load the existing magnitude variables (should be provided in multiple of 3) + // into kameleon. Remove non-existing variables from vector + if (xtraMagVars.size() % 3 == 0) { + for (int i = 0; i < static_cast(xtraMagVars.size()); i += 3) { + std::string s1 = xtraMagVars[i]; + std::string s2 = xtraMagVars[i+1]; + std::string s3 = xtraMagVars[i+2]; + bool isSuccesful = kameleon->doesVariableExist(s1) && + kameleon->doesVariableExist(s2) && + kameleon->doesVariableExist(s3) && + kameleon->loadVariable(s1) && + kameleon->loadVariable(s2) && + kameleon->loadVariable(s3); + std::string name = "Magnitude of (" + s1 + ", "+ s2 + ", "+ s3 + ")"; + if (isSuccesful && _model == fls::Model::BATSRUS && s1 == "jx" && s2 == "jy" + && s3 == "jz") { + // CCMC isn't really interested in the magnitude of current, but by the + // magnitude of the part of the current's vector that is parallel to the + // magnetic field => ensure that the magnetic variables are loaded + isSuccesful = kameleon->doesVariableExist("bx") && + kameleon->doesVariableExist("by") && + kameleon->doesVariableExist("bz") && + kameleon->loadVariable("bx") && + kameleon->loadVariable("by") && + kameleon->loadVariable("bz"); + name = J_PARALLEL_B; + } + if (!isSuccesful) { + LWARNING("FAILED TO LOAD AT LEAST ONE OF THE MAGNITUDE VARIABLES: " + << s1 << ", " << s2 << " & " << s3 + << ". Removing ability to store corresponding magnitude!"); + xtraMagVars.erase(xtraMagVars.begin() + i, xtraMagVars.begin() + i + 3); + i -= 3; + } else { + _extraQuantityNames.push_back(name); + } + } + } else { + // WRONG NUMBER OF MAGNITUDE VARIABLES.. REMOVE ALL! + xtraMagVars.clear(); + LWARNING("Wrong number of variables provided for storing magnitudes. " + << "Expects multiple of 3 but " << xtraMagVars.size() + << " are provided"); + } +} +#endif // OPENSPACE_MODULE_KAMELEON_ENABLED + +#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED +/** + * Loops through _vertexPositions and extracts corresponding 'extraQuantities' att each + * position from the kameleon object using a ccmc::interpolator. + * Note that the positions MUST be unaltered (NOT scaled NOR converted to different + * coordinate system)! + * + * @param kameleon raw pointer to an already opened Kameleon object + * @param xtraScalarVars vector of strings. Strings should be names of a scalar quantities + * to load into _extraQuantites; such as: "T" for temperature or "rho" for density. + * @param xtraMagVars vector of strings. Size must be multiple of 3. Strings should be + * names of the components needed to calculate magnitude. E.g. {"ux", "uy", "uz"} will + * calculate: sqrt(ux*ux + uy*uy + uz*uz). Magnitude will be stored in _extraQuantities + */ +void FieldlinesState::addExtraQuantities(ccmc::Kameleon* kameleon, + std::vector& xtraScalarVars, + std::vector& xtraMagVars) { + + loadExtrasIntoKameleon(kameleon, xtraScalarVars, xtraMagVars); + + const size_t N_XTRA_SCALARS = xtraScalarVars.size(); + const size_t N_XTRA_MAGNITUDES = xtraMagVars.size() / 3; + + _extraQuantities.resize(N_XTRA_SCALARS + N_XTRA_MAGNITUDES); + + std::unique_ptr interpolator = + std::make_unique(kameleon->model); + + // ------ Extract all the extraQuantities from kameleon and store in state! ------ // + for (const glm::vec3& P : _vertexPositions) { + // Load the scalars! + for (size_t i = 0; i < N_XTRA_SCALARS; i++) { + float val; + if (xtraScalarVars[i] == T_AS_P_OVER_RHO) { + val = interpolator->interpolate("p", P.x, P.y, P.z); + val *= TO_KELVIN; + val /= interpolator->interpolate("rho", P.x, P.y, P.z); + } else { + val = interpolator->interpolate(xtraScalarVars[i], P.x, P.y, P.z); + + // When measuring density in ENLIL CCMC multiply by the radius^2 + if (xtraScalarVars[i] == "rho" && _model == fls::Model::ENLIL) { + val *= std::pow(P.x * fls::A_U_TO_METER, 2.0f); + } + } + _extraQuantities[i].push_back(val); + } + // Calculate and store the magnitudes! + for (size_t i = 0; i < N_XTRA_MAGNITUDES; ++i) { + const size_t IDX = i*3; + + const float X = interpolator->interpolate(xtraMagVars[IDX] , P.x, P.y, P.z); + const float Y = interpolator->interpolate(xtraMagVars[IDX+1], P.x, P.y, P.z); + const float Z = interpolator->interpolate(xtraMagVars[IDX+2], P.x, P.y, P.z); + float val; + // When looking at the current's magnitude in Batsrus, CCMC staff are + // only interested in the magnitude parallel to the magnetic field + if (_extraQuantityNames[N_XTRA_SCALARS + i] == J_PARALLEL_B) { + const glm::vec3 NORM_MAGNETIC = glm::normalize(glm::vec3( + interpolator->interpolate("bx", P.x, P.y, P.z), + interpolator->interpolate("by", P.x, P.y, P.z), + interpolator->interpolate("bz", P.x, P.y, P.z))); + // Magnitude of the part of the current vector that's parallel to + // the magnetic field vector! + val = glm::dot(glm::vec3(X,Y,Z), NORM_MAGNETIC); + + } else { + val = std::sqrt(X*X + Y*Y + Z*Z); + } + _extraQuantities[i + N_XTRA_SCALARS].push_back(val); + } + } +} +#endif // OPENSPACE_MODULE_KAMELEON_ENABLED + #ifdef OPENSPACE_MODULE_KAMELEON_ENABLED /** * Converts all glm::vec3 in _vertexPositions from spherical (radius, latitude, longitude) diff --git a/modules/fieldlinessequence/util/fieldlinesstate.h b/modules/fieldlinessequence/util/fieldlinesstate.h index 076a025462..55bdde6f7e 100644 --- a/modules/fieldlinessequence/util/fieldlinesstate.h +++ b/modules/fieldlinessequence/util/fieldlinesstate.h @@ -52,6 +52,8 @@ public: bool addLinesFromKameleon(ccmc::Kameleon* kameleon, const vector& SEED_POINTS, const std::string TRACING_VAR); + void addExtraQuantities(ccmc::Kameleon* kameleon, vector& xtraScalarVars, + vector& xtraMagVars); void convertLatLonToCartesian(const float SCALE = 1.f); void scalePositions(const float SCALE); #endif // OPENSPACE_MODULE_KAMELEON_ENABLED @@ -88,6 +90,12 @@ private: vector _lineCount; vector> _extraQuantities; vector _extraQuantityNames; + +#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED + void loadExtrasIntoKameleon(ccmc::Kameleon* kameleon, + vector& xtraScalarVars, + vector& xtraMagVars); +#endif // OPENSPACE_MODULE_KAMELEON_ENABLED // TODO: Maybe introduce a vector containing seed point indices }; From bb43dace322e3440b91d2479db7a4d21c1ae9ff1 Mon Sep 17 00:00:00 2001 From: Oskar Carlbaum Date: Mon, 9 Oct 2017 22:44:33 +0200 Subject: [PATCH 30/39] Cleanup minor things --- .../renderablefieldlinessequencesetup.cpp | 12 +++-- .../shaders/fieldlinessequence_fs.glsl | 5 +- .../shaders/fieldlinessequence_vs.glsl | 4 +- .../util/fieldlinesstate.cpp | 9 +--- .../fieldlinessequence/util/fieldlinesstate.h | 50 +++++++++---------- 5 files changed, 35 insertions(+), 45 deletions(-) diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp b/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp index 0abd7901db..f87df3726a 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp @@ -46,8 +46,8 @@ namespace { // ----- KEYS POSSIBLE IN MODFILE. EXPECTED DATA TYPE OF VALUE IN [BRACKETS] ----- // // ---------------------------- MANDATORY MODFILE KEYS ---------------------------- // - const char* KEY_INPUT_FILE_TYPE = "InputFileType"; // [STRING] - const char* KEY_SOURCE_FOLDER = "SourceFolder"; // [STRING] + const char* KEY_INPUT_FILE_TYPE = "InputFileType"; // [STRING] "cdf", "json" or "osfls" + const char* KEY_SOURCE_FOLDER = "SourceFolder"; // [STRING] should be path to folder containing the input files // ---------------------- MANDATORY INPUT TYPE SPECIFIC KEYS ---------------------- // const char* KEY_CDF_SEED_POINT_FILE = "SeedPointFile"; // [STRING] Path to a .txt file containing seed points @@ -213,7 +213,7 @@ void RenderableFieldlinesSequence::initialize() { return; } - // Set the default color table, just in case the (optional) user defined paths are corrupt! + // Set a default color table, just in case the (optional) user defined paths are corrupt/not provided! _colorTablePaths.push_back("${OPENSPACE_DATA}/colortables/kroyw.txt"); _transferFunction = std::make_shared(absPath(_colorTablePaths[0])); @@ -292,7 +292,9 @@ void RenderableFieldlinesSequence::initialize() { _isReady = true; } -/* +/** + * Extracts the general information (from the lua modfile) that is mandatory for the class + * to function; such as the file type and the location of the source files. * Returns false if it fails to extract mandatory information! */ bool RenderableFieldlinesSequence::extractMandatoryInfoFromDictionary( @@ -413,7 +415,7 @@ void RenderableFieldlinesSequence::extractOptionalInfoFromDictionary( } } -/* +/** * Returns false if it fails to extract mandatory information! */ bool RenderableFieldlinesSequence::extractJsonInfoFromDictionary(fls::Model& model) { diff --git a/modules/fieldlinessequence/shaders/fieldlinessequence_fs.glsl b/modules/fieldlinessequence/shaders/fieldlinessequence_fs.glsl index 47f3c6ac2d..cfdef530df 100644 --- a/modules/fieldlinessequence/shaders/fieldlinessequence_fs.glsl +++ b/modules/fieldlinessequence/shaders/fieldlinessequence_fs.glsl @@ -22,14 +22,13 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ +#include "fragment.glsl" + in vec4 vs_color; in float vs_depth; uniform bool usingAdditiveBlending; -#include "fragment.glsl" -#include "PowerScaling/powerScaling_fs.hglsl" - Fragment getFragment() { if (vs_color.a == 0) { discard; diff --git a/modules/fieldlinessequence/shaders/fieldlinessequence_vs.glsl b/modules/fieldlinessequence/shaders/fieldlinessequence_vs.glsl index 8491716b29..a1313ae00d 100644 --- a/modules/fieldlinessequence/shaders/fieldlinessequence_vs.glsl +++ b/modules/fieldlinessequence/shaders/fieldlinessequence_vs.glsl @@ -24,8 +24,6 @@ #version __CONTEXT__ -#include "PowerScaling/powerScaling_vs.hglsl" - // General Uniforms that's always needed uniform vec4 lineColor; uniform mat4 modelViewProjection; @@ -123,6 +121,6 @@ void main() { vec4 position_in_meters = vec4(in_position, 1); vec4 positionClipSpace = modelViewProjection * position_in_meters; - gl_Position = z_normalization(positionClipSpace); + gl_Position = vec4(positionClipSpace.xy, 0, positionClipSpace.w); vs_depth = gl_Position.w; } diff --git a/modules/fieldlinessequence/util/fieldlinesstate.cpp b/modules/fieldlinessequence/util/fieldlinesstate.cpp index 9ffa156c3b..3bbeb7eabf 100644 --- a/modules/fieldlinessequence/util/fieldlinesstate.cpp +++ b/modules/fieldlinessequence/util/fieldlinesstate.cpp @@ -51,11 +51,6 @@ namespace { namespace openspace { -FieldlinesState::FieldlinesState() {} -FieldlinesState::FieldlinesState(const std::string& PATH_TO_OSFLS_FILE, bool& loadSucessful) { - loadSucessful = loadStateFromOsfls(PATH_TO_OSFLS_FILE); -} - #ifdef OPENSPACE_MODULE_KAMELEON_ENABLED /** * Traces and adds line vertices to state. (Also sets the simulation model variable: _model!) @@ -588,8 +583,8 @@ void FieldlinesState::saveStateToJson(const std::string& ABS_FILEPATH) { // Returns one of the extra quantity vectors, _extraQuantities[INDEX]. // If INDEX is out of scope an empty vector is returned and the referenced bool will be false. -const vector& FieldlinesState::extraQuantity(const size_t INDEX, - bool& isSuccessful) const { +const std::vector& FieldlinesState::extraQuantity(const size_t INDEX, + bool& isSuccessful) const { if (INDEX < _extraQuantities.size()) { isSuccessful = true; return _extraQuantities[INDEX]; diff --git a/modules/fieldlinessequence/util/fieldlinesstate.h b/modules/fieldlinessequence/util/fieldlinesstate.h index 55bdde6f7e..67172d1880 100644 --- a/modules/fieldlinessequence/util/fieldlinesstate.h +++ b/modules/fieldlinessequence/util/fieldlinesstate.h @@ -33,8 +33,6 @@ #include #include -using std::vector; - #ifdef OPENSPACE_MODULE_KAMELEON_ENABLED namespace ccmc { class Kameleon; @@ -45,15 +43,14 @@ namespace openspace { class FieldlinesState { public: - FieldlinesState(); - FieldlinesState(const std::string& PATH_TO_OSFLS_FILE, bool& loadSucessful); #ifdef OPENSPACE_MODULE_KAMELEON_ENABLED bool addLinesFromKameleon(ccmc::Kameleon* kameleon, - const vector& SEED_POINTS, + const std::vector& SEED_POINTS, const std::string TRACING_VAR); - void addExtraQuantities(ccmc::Kameleon* kameleon, vector& xtraScalarVars, - vector& xtraMagVars); + void addExtraQuantities(ccmc::Kameleon* kameleon, + std::vector& xtraScalarVars, + std::vector& xtraMagVars); void convertLatLonToCartesian(const float SCALE = 1.f); void scalePositions(const float SCALE); #endif // OPENSPACE_MODULE_KAMELEON_ENABLED @@ -66,37 +63,36 @@ public: void saveStateToJson(const std::string& PATH_TO_JSON_FILE); // ------------------------------GETTERS-----------------------------------------// - const vector>& extraQuantities() const { return _extraQuantities; } - const vector& extraQuantityNames() const { return _extraQuantityNames; } - const vector& lineCount() const { return _lineCount; } - const vector& lineStart() const { return _lineStart; } - size_t nExtraQuantities() const { return _extraQuantities.size(); } - fls::Model model() const { return _model; } - double triggerTime() const { return _triggerTime; } - const vector& vertexPositions() const { return _vertexPositions; } + const std::vector>& extraQuantities() const { return _extraQuantities; } + const std::vector& extraQuantityNames() const { return _extraQuantityNames; } + const std::vector& lineCount() const { return _lineCount; } + const std::vector& lineStart() const { return _lineStart; } + size_t nExtraQuantities() const { return _extraQuantities.size(); } + fls::Model model() const { return _model; } + double triggerTime() const { return _triggerTime; } + const std::vector& vertexPositions() const { return _vertexPositions; } // Special getter. Returns extraQuantities[INDEX]. - const vector& extraQuantity(const size_t INDEX, bool& isSuccesful) const; + const std::vector& extraQuantity(const size_t INDEX, bool& isSuccesful) const; void setTriggerTime(const double T) { _triggerTime = T; } private: - bool _isMorphable = false; - double _triggerTime = -1.0; - fls::Model _model; + bool _isMorphable = false; + double _triggerTime = -1.0; + fls::Model _model; - vector _vertexPositions; - vector _lineStart; - vector _lineCount; - vector> _extraQuantities; - vector _extraQuantityNames; + std::vector> _extraQuantities; + std::vector _extraQuantityNames; + std::vector _lineCount; + std::vector _lineStart; + std::vector _vertexPositions; #ifdef OPENSPACE_MODULE_KAMELEON_ENABLED void loadExtrasIntoKameleon(ccmc::Kameleon* kameleon, - vector& xtraScalarVars, - vector& xtraMagVars); + std::vector& xtraScalarVars, + std::vector& xtraMagVars); #endif // OPENSPACE_MODULE_KAMELEON_ENABLED - // TODO: Maybe introduce a vector containing seed point indices }; } // namespace openspace From 1a00d8a34f55fedfbc06e2d801d13f57d2349e57 Mon Sep 17 00:00:00 2001 From: Oskar Carlbaum Date: Mon, 9 Oct 2017 23:58:32 +0200 Subject: [PATCH 31/39] Add default colortable to data folder --- data/scene/fieldlinessequence/colortables/kroyw.txt | 9 +++++++++ .../rendering/renderablefieldlinessequencesetup.cpp | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 data/scene/fieldlinessequence/colortables/kroyw.txt diff --git a/data/scene/fieldlinessequence/colortables/kroyw.txt b/data/scene/fieldlinessequence/colortables/kroyw.txt new file mode 100644 index 0000000000..0852f05fc6 --- /dev/null +++ b/data/scene/fieldlinessequence/colortables/kroyw.txt @@ -0,0 +1,9 @@ +width 5 +lower 0.0 +upper 1.0 +mappingkey 0.0 0 0 0 255 +mappingkey 0.25 255 0 0 255 +mappingkey 0.5 255 140 0 255 +mappingkey 0.75 255 255 0 255 +mappingkey 1.0 255 255 255 255 + diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp b/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp index f87df3726a..2fdea78a0d 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp @@ -214,7 +214,7 @@ void RenderableFieldlinesSequence::initialize() { } // Set a default color table, just in case the (optional) user defined paths are corrupt/not provided! - _colorTablePaths.push_back("${OPENSPACE_DATA}/colortables/kroyw.txt"); + _colorTablePaths.push_back("${OPENSPACE_DATA}/scene/fieldlinessequence/colortables/kroyw.txt"); _transferFunction = std::make_shared(absPath(_colorTablePaths[0])); // EXTRACT OPTIONAL INFORMATION FROM DICTIONARY From ecc760ac12707deca05c1baf662287832b7a1ad6 Mon Sep 17 00:00:00 2001 From: Oskar Carlbaum Date: Wed, 18 Oct 2017 23:29:09 +0200 Subject: [PATCH 32/39] Change ALL_CAPS constants to camelCase --- .../renderablefieldlinessequence.cpp | 94 +++--- .../rendering/renderablefieldlinessequence.h | 16 +- .../renderablefieldlinessequencesetup.cpp | 236 +++++++-------- .../shaders/fieldlinessequence_vs.glsl | 32 +- modules/fieldlinessequence/util/commons.cpp | 16 +- modules/fieldlinessequence/util/commons.h | 16 +- .../util/fieldlinesstate.cpp | 277 +++++++++--------- .../fieldlinessequence/util/fieldlinesstate.h | 20 +- modules/kameleon/include/kameleonhelper.h | 2 +- modules/kameleon/src/kameleonhelper.cpp | 10 +- 10 files changed, 356 insertions(+), 363 deletions(-) diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp index c4a1cb89cf..ad467f4110 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp @@ -31,13 +31,12 @@ #include #include - namespace { std::string _loggerCat = "RenderableFieldlinesSequence"; - const GLuint _VA_POSITION = 0; // MUST CORRESPOND TO THE SHADER PROGRAM - const GLuint _VA_COLOR = 1; // MUST CORRESPOND TO THE SHADER PROGRAM - const GLuint _VA_MASKING = 2; // MUST CORRESPOND TO THE SHADER PROGRAM + const GLuint VaPosition = 0; // MUST CORRESPOND TO THE SHADER PROGRAM + const GLuint VaColor = 1; // MUST CORRESPOND TO THE SHADER PROGRAM + const GLuint VaMasking = 2; // MUST CORRESPOND TO THE SHADER PROGRAM } // namespace namespace openspace { @@ -76,23 +75,22 @@ void RenderableFieldlinesSequence::render(const RenderData& data, RendererTasks& _shaderProgram->activate(); // Calculate Model View MatrixProjection - const glm::dmat4 ROT_MAT = glm::dmat4(data.modelTransform.rotation); - // const glm::mat4 SCALE_TRANSFORM = glm::mat4(1.0); // TODO remove if no use - const glm::dmat4 MODEL_MAT = + const glm::dmat4 rotMat = glm::dmat4(data.modelTransform.rotation); + const glm::dmat4 modelMat = glm::translate(glm::dmat4(1.0), data.modelTransform.translation) * - ROT_MAT * + rotMat * glm::dmat4(glm::scale(glm::dmat4(1), glm::dvec3(data.modelTransform.scale))); - const glm::dmat4 MODEL_VIEW_MAT = data.camera.combinedViewMatrix() * MODEL_MAT; + const glm::dmat4 modelViewMat = data.camera.combinedViewMatrix() * modelMat; _shaderProgram->setUniform("modelViewProjection", - data.camera.sgctInternal.projectionMatrix() * glm::mat4(MODEL_VIEW_MAT)); + data.camera.sgctInternal.projectionMatrix() * glm::mat4(modelViewMat)); _shaderProgram->setUniform("colorMethod", _pColorMethod); _shaderProgram->setUniform("lineColor", _pColorUniform); _shaderProgram->setUniform("usingDomain", _pDomainEnabled); _shaderProgram->setUniform("usingMasking", _pMaskingEnabled); - if (_pColorMethod == ColorMethod::BY_QUANTITY) { + if (_pColorMethod == ColorMethod::ByQuantity) { ghoul::opengl::TextureUnit textureUnit; textureUnit.activate(); _transferFunction->bind(); // Calls update internally @@ -120,11 +118,11 @@ void RenderableFieldlinesSequence::render(const RenderData& data, RendererTasks& bool additiveBlending = false; if (_pColorABlendEnabled) { - const auto RENDERER = OsEng.renderEngine().rendererImplementation(); - bool usingFBufferRenderer = RENDERER == + const auto renderer = OsEng.renderEngine().rendererImplementation(); + bool usingFBufferRenderer = renderer == RenderEngine::RendererImplementation::Framebuffer; - bool usingABufferRenderer = RENDERER == + bool usingABufferRenderer = renderer == RenderEngine::RendererImplementation::ABuffer; if (usingABufferRenderer) { @@ -163,15 +161,15 @@ void RenderableFieldlinesSequence::update(const UpdateData& data) { // This node shouldn't do anything if its been disabled from the gui! if (_enabled) { - const double CURRENT_TIME = data.time.j2000Seconds(); + const double currentTime = data.time.j2000Seconds(); // Check if current time in OpenSpace is within sequence interval - if (isWithinSequenceInterval(CURRENT_TIME)) { - const int NEXT_IDX = _activeTriggerTimeIndex + 1; - if (_activeTriggerTimeIndex < 0 // true => Previous frame was not within the sequence interval - || CURRENT_TIME < _startTimes[_activeTriggerTimeIndex] // true => OpenSpace has stepped back to a time represented by another state - || (NEXT_IDX < _nStates && CURRENT_TIME >= _startTimes[NEXT_IDX])) { // true => OpenSpace has stepped forward to a time represented by another state + if (isWithinSequenceInterval(currentTime)) { + const int nextIdx = _activeTriggerTimeIndex + 1; + if (_activeTriggerTimeIndex < 0 // true => Previous frame was not within the sequence interval + || currentTime < _startTimes[_activeTriggerTimeIndex] // true => OpenSpace has stepped back to a time represented by another state + || (nextIdx < _nStates && currentTime >= _startTimes[nextIdx])) { // true => OpenSpace has stepped forward to a time represented by another state - updateActiveTriggerTimeIndex(CURRENT_TIME); + updateActiveTriggerTimeIndex(currentTime); if (_loadingStatesDynamically) { _mustLoadNewStateFromDisk = true; @@ -191,9 +189,9 @@ void RenderableFieldlinesSequence::update(const UpdateData& data) { if (!_isLoadingStateFromDisk && !_newStateIsReady) { _isLoadingStateFromDisk = true; _mustLoadNewStateFromDisk = false; - const std::string FILEPATH = _sourceFiles[_activeTriggerTimeIndex]; - std::thread readBinaryThread([this, FILEPATH] { - this->readNewState(FILEPATH); + const std::string filePath = _sourceFiles[_activeTriggerTimeIndex]; + std::thread readBinaryThread([this, filePath] { + this->readNewState(filePath); }); readBinaryThread.detach(); } @@ -228,13 +226,13 @@ void RenderableFieldlinesSequence::update(const UpdateData& data) { } } -inline bool RenderableFieldlinesSequence::isWithinSequenceInterval(const double CURRENT_TIME) const { - return (CURRENT_TIME >= _startTimes[0]) && (CURRENT_TIME < _sequenceEndTime); +inline bool RenderableFieldlinesSequence::isWithinSequenceInterval(const double currentTime) const { + return (currentTime >= _startTimes[0]) && (currentTime < _sequenceEndTime); } -// Assumes we already know that CURRENT_TIME is within the sequence interval -void RenderableFieldlinesSequence::updateActiveTriggerTimeIndex(const double CURRENT_TIME) { - auto iter = std::upper_bound(_startTimes.begin(), _startTimes.end(), CURRENT_TIME); +// Assumes we already know that currentTime is within the sequence interval +void RenderableFieldlinesSequence::updateActiveTriggerTimeIndex(const double currentTime) { + auto iter = std::upper_bound(_startTimes.begin(), _startTimes.end(), currentTime); if (iter != _startTimes.end()) { if ( iter != _startTimes.begin()) { _activeTriggerTimeIndex = @@ -248,9 +246,9 @@ void RenderableFieldlinesSequence::updateActiveTriggerTimeIndex(const double CUR } // Reading state from disk. Must be thread safe! -void RenderableFieldlinesSequence::readNewState(const std::string& FILEPATH) { +void RenderableFieldlinesSequence::readNewState(const std::string& filePath) { _newState = std::make_unique(); - if (_newState->loadStateFromOsfls(FILEPATH)) { + if (_newState->loadStateFromOsfls(filePath)) { _newStateIsReady = true; } _isLoadingStateFromDisk = false; @@ -266,14 +264,14 @@ void RenderableFieldlinesSequence::updateVertexPositionBuffer() { glBindVertexArray(_vertexArrayObject); glBindBuffer(GL_ARRAY_BUFFER, _vertexPositionBuffer); - const std::vector& VERTEX_POS_VEC = + const std::vector& vertexPosVec = _states[_activeStateIndex].vertexPositions(); - glBufferData(GL_ARRAY_BUFFER, VERTEX_POS_VEC.size() * sizeof(glm::vec3), - &VERTEX_POS_VEC.front(), GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, vertexPosVec.size() * sizeof(glm::vec3), + &vertexPosVec.front(), GL_STATIC_DRAW); - glEnableVertexAttribArray(_VA_POSITION); - glVertexAttribPointer(_VA_POSITION, 3, GL_FLOAT, GL_FALSE, 0, 0); + glEnableVertexAttribArray(VaPosition); + glVertexAttribPointer(VaPosition, 3, GL_FLOAT, GL_FALSE, 0, 0); unbindGL(); } @@ -283,15 +281,15 @@ void RenderableFieldlinesSequence::updateVertexColorBuffer() { glBindBuffer(GL_ARRAY_BUFFER, _vertexColorBuffer); bool isSuccessful; - const std::vector& QUANTITY_VEC = + const std::vector& quantityVec = _states[_activeStateIndex].extraQuantity(_pColorQuantity, isSuccessful); if (isSuccessful) { - glBufferData(GL_ARRAY_BUFFER, QUANTITY_VEC.size() * sizeof(float), - &QUANTITY_VEC.front(), GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, quantityVec.size() * sizeof(float), + &quantityVec.front(), GL_STATIC_DRAW); - glEnableVertexAttribArray(_VA_COLOR); - glVertexAttribPointer(_VA_COLOR, 1, GL_FLOAT, GL_FALSE, 0, 0); + glEnableVertexAttribArray(VaColor); + glVertexAttribPointer(VaColor, 1, GL_FLOAT, GL_FALSE, 0, 0); unbindGL(); } @@ -302,22 +300,18 @@ void RenderableFieldlinesSequence::updateVertexMaskingBuffer() { glBindBuffer(GL_ARRAY_BUFFER, _vertexMaskingBuffer); bool isSuccessful; - const std::vector& QUANTITY_VEC = + const std::vector& quantityVec = _states[_activeStateIndex].extraQuantity(_pMaskingQuantity, isSuccessful); if (isSuccessful) { - glBufferData(GL_ARRAY_BUFFER, QUANTITY_VEC.size() * sizeof(float), - &QUANTITY_VEC.front(), GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, quantityVec.size() * sizeof(float), + &quantityVec.front(), GL_STATIC_DRAW); - glEnableVertexAttribArray(_VA_MASKING); - glVertexAttribPointer(_VA_MASKING, 1, GL_FLOAT, GL_FALSE, 0, 0); + glEnableVertexAttribArray(VaMasking); + glVertexAttribPointer(VaMasking, 1, GL_FLOAT, GL_FALSE, 0, 0); unbindGL(); } } - - - - } // namespace openspace diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h index a9f3b8d233..ef4b4870bf 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h @@ -59,8 +59,8 @@ public: private: // ------------------------------------- ENUMS -------------------------------------// enum ColorMethod : int { // Used to determine if lines should be colored UNIFORMLY or by an extraQuantity - UNIFORM = 0, - BY_QUANTITY + Uniform = 0, + ByQuantity }; // ------------------------------------ STRINGS ------------------------------------// @@ -144,8 +144,8 @@ private: void extractOptionalInfoFromDictionary(std::string& outputFolderPath); void extractOsflsInfoFromDictionary(); void extractTriggerTimesFromFileNames(); - bool loadJsonStatesIntoRAM(const std::string& OUTPUT_FOLDER); - void loadOsflsStatesIntoRAM(const std::string& OUTPUT_FOLDER); + bool loadJsonStatesIntoRAM(const std::string& outputFolder); + void loadOsflsStatesIntoRAM(const std::string& outputFolder); void setModelDependentConstants(); void setupProperties(); bool prepareForOsflsStreaming(); @@ -158,13 +158,13 @@ private: std::vector& outVec); void extractMagnitudeVarsFromStrings(std::vector& extraVars, std::vector& extraMagVars); - bool getStatesFromCdfFiles(const std::string& OUTPUT_FOLDER); + bool getStatesFromCdfFiles(const std::string& outputFolder); #endif // OPENSPACE_MODULE_KAMELEON_ENABLED // ------------------------- FUNCTIONS USED DURING RUNTIME ------------------------ // - inline bool isWithinSequenceInterval(const double CURRENT_TIME) const; - void readNewState(const std::string& FILEPATH); - void updateActiveTriggerTimeIndex(const double CURRENT_TIME); + inline bool isWithinSequenceInterval(const double currentTime) const; + void readNewState(const std::string& filePath); + void updateActiveTriggerTimeIndex(const double currentTime); void updateVertexPositionBuffer(); void updateVertexColorBuffer(); void updateVertexMaskingBuffer(); diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp b/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp index 2fdea78a0d..112d4090e0 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp @@ -46,29 +46,29 @@ namespace { // ----- KEYS POSSIBLE IN MODFILE. EXPECTED DATA TYPE OF VALUE IN [BRACKETS] ----- // // ---------------------------- MANDATORY MODFILE KEYS ---------------------------- // - const char* KEY_INPUT_FILE_TYPE = "InputFileType"; // [STRING] "cdf", "json" or "osfls" - const char* KEY_SOURCE_FOLDER = "SourceFolder"; // [STRING] should be path to folder containing the input files + const char* KeyInputFileType = "InputFileType"; // [STRING] "cdf", "json" or "osfls" + const char* KeySourceFolder = "SourceFolder"; // [STRING] should be path to folder containing the input files // ---------------------- MANDATORY INPUT TYPE SPECIFIC KEYS ---------------------- // - const char* KEY_CDF_SEED_POINT_FILE = "SeedPointFile"; // [STRING] Path to a .txt file containing seed points - const char* KEY_JSON_SIMULATION_MODEL = "SimulationModel"; // [STRING] Currently supports: "batsrus", "enlil" & "pfss" + const char* KeyCdfSeedPointFile = "SeedPointFile"; // [STRING] Path to a .txt file containing seed points + const char* KeyJsonSimulationModel = "SimulationModel"; // [STRING] Currently supports: "batsrus", "enlil" & "pfss" // ----------------------- OPTIONAL INPUT TYPE SPECIFIC KEYS ---------------------- // - const char* KEY_CDF_EXTRA_VARIABLES = "ExtraVariables"; // [STRING ARRAY] - const char* KEY_CDF_TRACING_VARIABLE = "TracingVariable"; // [STRING] - const char* KEY_JSON_SCALING_FACTOR = "ScaleToMeters"; // [STRING] - const char* KEY_OSLFS_LOAD_AT_RUNTIME = "LoadAtRuntime"; // [BOOLEAN] If value False => Load in initializing step and store in RAM + const char* KeyCdfExtraVariables = "ExtraVariables"; // [STRING ARRAY] + const char* KeyCdfTracingVariable = "TracingVariable"; // [STRING] + const char* KeyJsonScalingFactor = "ScaleToMeters"; // [STRING] + const char* KeyOslfsLoadAtRuntime = "LoadAtRuntime"; // [BOOLEAN] If value False => Load in initializing step and store in RAM // ---------------------------- OPTIONAL MODFILE KEYS ---------------------------- // - const char* KEY_COLOR_TABLE_PATHS = "ColorTablePaths"; // [STRING ARRAY] Values should be paths to .txt files - const char* KEY_COLOR_TABLE_RANGES = "ColorTableRanges";// [VEC2 ARRAY] Values should be entered as {X, Y}, where X & Y are numbers - const char* KEY_MASKING_RANGES = "MaskingRanges"; // [VEC2 ARRAY] Values should be entered as {X, Y}, where X & Y are numbers - const char* KEY_OUTPUT_FOLDER = "OutputFolder"; // [STRING] Value should be path to folder where states are saved (JSON/CDF input => osfls output & oslfs input => JSON output) + const char* KeyColorTablePaths = "ColorTablePaths"; // [STRING ARRAY] Values should be paths to .txt files + const char* KeyColorTableRanges = "ColorTableRanges";// [VEC2 ARRAY] Values should be entered as {X, Y}, where X & Y are numbers + const char* KeyMaskingRanges = "MaskingRanges"; // [VEC2 ARRAY] Values should be entered as {X, Y}, where X & Y are numbers + const char* KeyOutputFolder = "OutputFolder"; // [STRING] Value should be path to folder where states are saved (JSON/CDF input => osfls output & oslfs input => JSON output) // ------------- POSSIBLE STRING VALUES FOR CORRESPONDING MODFILE KEY ------------- // - const char* VALUE_INPUT_FILE_TYPE_CDF = "cdf"; - const char* VALUE_INPUT_FILE_TYPE_JSON = "json"; - const char* VALUE_INPUT_FILE_TYPE_OSFLS = "osfls"; + const char* ValueInputFileTypeCdf = "cdf"; + const char* ValueInputFileTypeJson = "json"; + const char* ValueInputFileTypeOsfls = "osfls"; // --------------------------------- Property Info -------------------------------- // static const openspace::properties::Property::PropertyInfo ColorMethodInfo = { @@ -147,20 +147,20 @@ namespace { }; enum class SourceFileType : int { - CDF = 0, - JSON, - OSFLS, - INVALID + Cdf = 0, + Json, + Osfls, + Invalid }; - float stringToFloat(const std::string INPUT, const float BACKUP_VALUE = 0.f) { + float stringToFloat(const std::string input, const float backupValue = 0.f) { float tmp; try { - tmp = std::stof(INPUT); + tmp = std::stof(input); } catch (const std::invalid_argument& ia) { - LWARNING("Invalid argument: " << ia.what() << ". '" << INPUT << + LWARNING("Invalid argument: " << ia.what() << ". '" << input << "' is NOT a valid number!"); - return BACKUP_VALUE; + return backupValue; } return tmp; } @@ -168,8 +168,8 @@ namespace { namespace openspace { -RenderableFieldlinesSequence::RenderableFieldlinesSequence(const ghoul::Dictionary& DICTIONARY) - : Renderable(DICTIONARY), +RenderableFieldlinesSequence::RenderableFieldlinesSequence(const ghoul::Dictionary& dictionary) + : Renderable(dictionary), _pColorGroup({ "Color" }), _pColorMethod(ColorMethodInfo, properties::OptionProperty::DisplayType::Radio), _pColorQuantity(ColorQuantityInfo, properties::OptionProperty::DisplayType::Dropdown), @@ -201,14 +201,14 @@ RenderableFieldlinesSequence::RenderableFieldlinesSequence(const ghoul::Dictiona _pFocusOnOriginBtn(OriginButtonInfo), _pJumpToStartBtn(TimeJumpButtonInfo) { - _dictionary = std::make_unique(DICTIONARY); + _dictionary = std::make_unique(dictionary); } void RenderableFieldlinesSequence::initialize() { LINFO("RenderableFieldlinesSequence::initialize()"); // EXTRACT MANDATORY INFORMATION FROM DICTIONARY - SourceFileType sourceFileType = SourceFileType::INVALID; + SourceFileType sourceFileType = SourceFileType::Invalid; if (!extractMandatoryInfoFromDictionary(sourceFileType)) { return; } @@ -223,19 +223,19 @@ void RenderableFieldlinesSequence::initialize() { // EXTRACT SOURCE FILE TYPE SPECIFIC INFOMRATION FROM DICTIONARY & GET STATES FROM SOURCE switch (sourceFileType) { - case SourceFileType::CDF: + case SourceFileType::Cdf: #ifdef OPENSPACE_MODULE_KAMELEON_ENABLED if (!getStatesFromCdfFiles(outputFolderPath)) { return; } #endif // OPENSPACE_MODULE_KAMELEON_ENABLED break; - case SourceFileType::JSON: + case SourceFileType::Json: if (!loadJsonStatesIntoRAM(outputFolderPath)) { return; } break; - case SourceFileType::OSFLS: + case SourceFileType::Osfls: extractOsflsInfoFromDictionary(); if (_loadingStatesDynamically) { if (!prepareForOsflsStreaming()) { @@ -277,7 +277,7 @@ void RenderableFieldlinesSequence::initialize() { if (!_shaderProgram) { LERROR("Shader program failed initialization!"); - sourceFileType = SourceFileType::INVALID; + sourceFileType = SourceFileType::Invalid; } //------------------ Initialize OpenGL VBOs and VAOs-------------------------------// @@ -304,34 +304,34 @@ bool RenderableFieldlinesSequence::extractMandatoryInfoFromDictionary( // ------------------- EXTRACT MANDATORY VALUES FROM DICTIONARY ------------------- // std::string inputFileTypeString; - if (!_dictionary->getValue(KEY_INPUT_FILE_TYPE, inputFileTypeString)) { - LERROR(_name << ": The field " << std::string(KEY_INPUT_FILE_TYPE) << " is missing!"); + if (!_dictionary->getValue(KeyInputFileType, inputFileTypeString)) { + LERROR(_name << ": The field " << std::string(KeyInputFileType) << " is missing!"); return false; } else { std::transform(inputFileTypeString.begin(), inputFileTypeString.end(), inputFileTypeString.begin(), ::tolower); // Verify that the input type is correct - if (inputFileTypeString == VALUE_INPUT_FILE_TYPE_CDF) { - sourceFileType = SourceFileType::CDF; + if (inputFileTypeString == ValueInputFileTypeCdf) { + sourceFileType = SourceFileType::Cdf; #ifndef OPENSPACE_MODULE_KAMELEON_ENABLED LERROR(_name << ": CDF file inputs requires the 'Kameleon' module to be enabled!"); return false; #endif // OPENSPACE_MODULE_KAMELEON_ENABLED - } else if (inputFileTypeString == VALUE_INPUT_FILE_TYPE_JSON) { - sourceFileType = SourceFileType::JSON; - } else if (inputFileTypeString == VALUE_INPUT_FILE_TYPE_OSFLS) { - sourceFileType = SourceFileType::OSFLS; + } else if (inputFileTypeString == ValueInputFileTypeJson) { + sourceFileType = SourceFileType::Json; + } else if (inputFileTypeString == ValueInputFileTypeOsfls) { + sourceFileType = SourceFileType::Osfls; } else { LERROR(_name << ": " << inputFileTypeString << " is not a recognised " - << KEY_INPUT_FILE_TYPE); - sourceFileType = SourceFileType::INVALID; + << KeyInputFileType); + sourceFileType = SourceFileType::Invalid; return false; } } std::string sourceFolderPath; - if (!_dictionary->getValue(KEY_SOURCE_FOLDER, sourceFolderPath)) { - LERROR(_name << ": The field " << std::string(KEY_SOURCE_FOLDER) << " is missing!"); + if (!_dictionary->getValue(KeySourceFolder, sourceFolderPath)) { + LERROR(_name << ": The field " << std::string(KeySourceFolder) << " is missing!"); return false; } @@ -345,8 +345,8 @@ bool RenderableFieldlinesSequence::extractMandatoryInfoFromDictionary( // Remove all files that don't have as extension _sourceFiles.erase(std::remove_if(_sourceFiles.begin(), _sourceFiles.end(), [inputFileTypeString](std::string str) { - const size_t EXT_LENGTH = inputFileTypeString.length(); - std::string sub = str.substr(str.length() - EXT_LENGTH, EXT_LENGTH); + const size_t extLength = inputFileTypeString.length(); + std::string sub = str.substr(str.length() - extLength, extLength); std::transform(sub.begin(), sub.end(), sub.begin(), ::tolower); return sub != inputFileTypeString; }), _sourceFiles.end()); @@ -369,7 +369,7 @@ void RenderableFieldlinesSequence::extractOptionalInfoFromDictionary( std::string& outputFolderPath) { // ------------------- EXTRACT OPTIONAL VALUES FROM DICTIONARY ------------------- // - if (_dictionary->getValue(KEY_OUTPUT_FOLDER, outputFolderPath)) { + if (_dictionary->getValue(KeyOutputFolder, outputFolderPath)) { ghoul::filesystem::Directory outputFolder(outputFolderPath); if (FileSys.directoryExists(outputFolder)) { outputFolderPath = absPath(outputFolderPath); @@ -380,12 +380,12 @@ void RenderableFieldlinesSequence::extractOptionalInfoFromDictionary( } ghoul::Dictionary colorTablesPathsDictionary; - if (_dictionary->getValue(KEY_COLOR_TABLE_PATHS, colorTablesPathsDictionary)) { - const size_t N_PROVIDED_PATHS = colorTablesPathsDictionary.size(); - if (N_PROVIDED_PATHS > 0) { + if (_dictionary->getValue(KeyColorTablePaths, colorTablesPathsDictionary)) { + const size_t nProvidedPaths = colorTablesPathsDictionary.size(); + if (nProvidedPaths > 0) { // Clear the default! It is already specified in the transferFunction _colorTablePaths.clear(); - for (size_t i = 1; i <= N_PROVIDED_PATHS; ++i) { + for (size_t i = 1; i <= nProvidedPaths; ++i) { _colorTablePaths.push_back( colorTablesPathsDictionary.value(std::to_string(i))); } @@ -393,9 +393,9 @@ void RenderableFieldlinesSequence::extractOptionalInfoFromDictionary( } ghoul::Dictionary colorTablesRangesDictionary; - if (_dictionary->getValue(KEY_COLOR_TABLE_RANGES, colorTablesRangesDictionary)) { - const size_t N_PROVIDED_RANGES = colorTablesRangesDictionary.size(); - for (size_t i = 1; i <= N_PROVIDED_RANGES; ++i) { + if (_dictionary->getValue(KeyColorTableRanges, colorTablesRangesDictionary)) { + const size_t nProvidedRanges = colorTablesRangesDictionary.size(); + for (size_t i = 1; i <= nProvidedRanges; ++i) { _colorTableRanges.push_back( colorTablesRangesDictionary.value(std::to_string(i))); } @@ -404,9 +404,9 @@ void RenderableFieldlinesSequence::extractOptionalInfoFromDictionary( } ghoul::Dictionary maskingRangesDictionary; - if (_dictionary->getValue(KEY_MASKING_RANGES, maskingRangesDictionary)) { - const size_t N_PROVIDED_RANGES = maskingRangesDictionary.size(); - for (size_t i = 1; i <= N_PROVIDED_RANGES; ++i) { + if (_dictionary->getValue(KeyMaskingRanges, maskingRangesDictionary)) { + const size_t nProvidedRanges = maskingRangesDictionary.size(); + for (size_t i = 1; i <= nProvidedRanges; ++i) { _maskingRanges.push_back( maskingRangesDictionary.value(std::to_string(i))); } @@ -420,16 +420,16 @@ void RenderableFieldlinesSequence::extractOptionalInfoFromDictionary( */ bool RenderableFieldlinesSequence::extractJsonInfoFromDictionary(fls::Model& model) { std::string modelStr; - if (_dictionary->getValue(KEY_JSON_SIMULATION_MODEL, modelStr)) { + if (_dictionary->getValue(KeyJsonSimulationModel, modelStr)) { std::transform(modelStr.begin(), modelStr.end(), modelStr.begin(), ::tolower); model = fls::stringToModel(modelStr); } else { - LERROR(_name << ": Must specify '" << KEY_JSON_SIMULATION_MODEL << "'"); + LERROR(_name << ": Must specify '" << KeyJsonSimulationModel << "'"); return false; } float scaleFactor; - if (_dictionary->getValue(KEY_JSON_SCALING_FACTOR, scaleFactor)) { + if (_dictionary->getValue(KeyJsonScalingFactor, scaleFactor)) { _scalingFactor = scaleFactor; } else { LWARNING(_name << ": Does not provide scalingFactor! " << @@ -438,7 +438,7 @@ bool RenderableFieldlinesSequence::extractJsonInfoFromDictionary(fls::Model& mod return true; } -bool RenderableFieldlinesSequence::loadJsonStatesIntoRAM(const std::string& OUTPUT_FOLDER) { +bool RenderableFieldlinesSequence::loadJsonStatesIntoRAM(const std::string& outputFolder) { fls::Model model; if (!extractJsonInfoFromDictionary(model)) { return false; @@ -450,8 +450,8 @@ bool RenderableFieldlinesSequence::loadJsonStatesIntoRAM(const std::string& OUTP _scalingFactor); if (loadedSuccessfully) { addStateToSequence(newState); - if (!OUTPUT_FOLDER.empty()) { - newState.saveStateToOsfls(OUTPUT_FOLDER); + if (!outputFolder.empty()) { + newState.saveStateToOsfls(outputFolder); } } } @@ -472,28 +472,28 @@ bool RenderableFieldlinesSequence::prepareForOsflsStreaming() { } -void RenderableFieldlinesSequence::loadOsflsStatesIntoRAM(const std::string& OUTPUT_FOLDER) { +void RenderableFieldlinesSequence::loadOsflsStatesIntoRAM(const std::string& outputFolder) { // Load states from .osfls files into RAM! - for (const std::string FILEPATH : _sourceFiles) { + for (const std::string filePath : _sourceFiles) { FieldlinesState newState; - if (newState.loadStateFromOsfls(FILEPATH)) { + if (newState.loadStateFromOsfls(filePath)) { addStateToSequence(newState); - if (!OUTPUT_FOLDER.empty()) { - ghoul::filesystem::File tmpFile(FILEPATH); - newState.saveStateToJson(OUTPUT_FOLDER + tmpFile.baseName()); + if (!outputFolder.empty()) { + ghoul::filesystem::File tmpFile(filePath); + newState.saveStateToJson(outputFolder + tmpFile.baseName()); } } else { - LWARNING("Failed to load state from: " << FILEPATH); + LWARNING("Failed to load state from: " << filePath); } } } void RenderableFieldlinesSequence::extractOsflsInfoFromDictionary() { bool shouldLoadInRealtime = false; - if (_dictionary->getValue(KEY_OSLFS_LOAD_AT_RUNTIME, shouldLoadInRealtime)) { + if (_dictionary->getValue(KeyOslfsLoadAtRuntime, shouldLoadInRealtime)) { _loadingStatesDynamically = shouldLoadInRealtime; } else { - LWARNING(_name << ": " << KEY_OSLFS_LOAD_AT_RUNTIME << + LWARNING(_name << ": " << KeyOslfsLoadAtRuntime << " isn't specified! States will be stored in RAM!"); } } @@ -537,21 +537,21 @@ void RenderableFieldlinesSequence::setupProperties() { _pMaskingGroup.addProperty(_pMaskingQuantity); // --------------------- Add Options to OptionProperties --------------------- // - _pColorMethod.addOption(ColorMethod::UNIFORM, "Uniform"); - _pColorMethod.addOption(ColorMethod::BY_QUANTITY, "By Quantity"); + _pColorMethod.addOption(ColorMethod::Uniform, "Uniform"); + _pColorMethod.addOption(ColorMethod::ByQuantity, "By Quantity"); // Add option for each extra quantity. Assumes there are just as many names to // extra quantities as there are extra quantities. Also assume that all states in // the given sequence have the same extra quantities! */ - const size_t N_EXTRA_QUANTITIES = _states[0].nExtraQuantities(); - const std::vector& XTRA_NAMES_VEC = _states[0].extraQuantityNames(); - for (int i = 0; i < N_EXTRA_QUANTITIES; ++i) { - _pColorQuantity.addOption(i, XTRA_NAMES_VEC[i]); - _pMaskingQuantity.addOption(i, XTRA_NAMES_VEC[i]); + const size_t nExtraQuantities = _states[0].nExtraQuantities(); + const std::vector& extraNamesVec = _states[0].extraQuantityNames(); + for (int i = 0; i < nExtraQuantities; ++i) { + _pColorQuantity.addOption(i, extraNamesVec[i]); + _pMaskingQuantity.addOption(i, extraNamesVec[i]); } // Each quantity should have its own color table and color table range, no more, no less - _colorTablePaths.resize(N_EXTRA_QUANTITIES, _colorTablePaths.back()); - _colorTableRanges.resize(N_EXTRA_QUANTITIES, _colorTableRanges.back()); - _maskingRanges.resize(N_EXTRA_QUANTITIES, _maskingRanges.back()); + _colorTablePaths.resize(nExtraQuantities, _colorTablePaths.back()); + _colorTableRanges.resize(nExtraQuantities, _colorTableRanges.back()); + _maskingRanges.resize(nExtraQuantities, _maskingRanges.back()); } definePropertyCallbackFunctions(); @@ -642,11 +642,11 @@ void RenderableFieldlinesSequence::definePropertyCallbackFunctions() { // Calculate expected end time. void RenderableFieldlinesSequence::computeSequenceEndTime() { if (_nStates > 1) { - const double LAST_TRIGGER_TIME = _startTimes[_nStates - 1]; - const double SEQUENCE_DURATION = LAST_TRIGGER_TIME - _startTimes[0]; - const double AVERAGE_STATE_DURATION = SEQUENCE_DURATION / - (static_cast(_nStates) - 1.0); - _sequenceEndTime = LAST_TRIGGER_TIME + AVERAGE_STATE_DURATION; + const double lastTriggerTime = _startTimes[_nStates - 1]; + const double sequenceDuration = lastTriggerTime - _startTimes[0]; + const double averageStateDuration = sequenceDuration / + (static_cast(_nStates) - 1.0); + _sequenceEndTime = lastTriggerTime + averageStateDuration; } else { // If there's just one state it should never disappear! _sequenceEndTime = DBL_MAX; @@ -657,17 +657,17 @@ void RenderableFieldlinesSequence::setModelDependentConstants() { const fls::Model simulationModel = _states[0].model(); float limit = 100.f; // Just used as a default value. switch (simulationModel) { - case fls::Model::BATSRUS: - _scalingFactor = fls::R_E_TO_METER; + case fls::Model::Batsrus: + _scalingFactor = fls::ReToMeter; limit = 300; // Should include a long magnetotail break; - case fls::Model::ENLIL: + case fls::Model::Enlil: _pFlowReversed = true; - _scalingFactor = fls::A_U_TO_METER; + _scalingFactor = fls::AuToMeter; limit = 50; // Should include Plutos furthest distance from the Sun break; - case fls::Model::PFSS: - _scalingFactor = fls::R_S_TO_METER; + case fls::Model::Pfss: + _scalingFactor = fls::RsToMeter; limit = 100; // Just a default value far away from the solar surface break; default: @@ -682,28 +682,28 @@ void RenderableFieldlinesSequence::setModelDependentConstants() { _pDomainX = glm::vec2(-limit, limit); _pDomainY = glm::vec2(-limit, limit); _pDomainZ = glm::vec2(-limit, limit); - _pDomainR = glm::vec2(0, limit*1.5f); + _pDomainR = glm::vec2(0, limit * 1.5f); } // Extract J2000 time from file names // Requires files to be named as such: 'YYYY-MM-DDTHH-MM-SS-XXX.osfls' void RenderableFieldlinesSequence::extractTriggerTimesFromFileNames() { - const size_t FILENAME_SIZE = 23; // number of characters in filename (excluding '.osfls') - const size_t EXT_SIZE = 6; // size(".osfls") + const size_t filenameSize = 23; // number of characters in filename (excluding '.osfls') + const size_t extSize = 6; // size(".osfls") - for (const std::string& FILEPATH : _sourceFiles) { - const size_t STR_LENGTH = FILEPATH.size(); + for (const std::string& filePath : _sourceFiles) { + const size_t strLength = filePath.size(); // Extract the filename from the path (without extension) - std::string timeString = FILEPATH.substr(STR_LENGTH - FILENAME_SIZE - EXT_SIZE, - FILENAME_SIZE - 1); + std::string timeString = filePath.substr(strLength - filenameSize - extSize, + filenameSize - 1); // Ensure the separators are correct timeString.replace(4, 1, "-"); timeString.replace(7, 1, "-"); timeString.replace(13, 1, ":"); timeString.replace(16, 1, ":"); timeString.replace(19, 1, "."); - const double TRIGGER_TIME = Time::convertTime(timeString); - _startTimes.push_back(TRIGGER_TIME); + const double triggerTime = Time::convertTime(timeString); + _startTimes.push_back(triggerTime); } } @@ -714,7 +714,7 @@ void RenderableFieldlinesSequence::addStateToSequence(FieldlinesState& state) { } #ifdef OPENSPACE_MODULE_KAMELEON_ENABLED -bool RenderableFieldlinesSequence::getStatesFromCdfFiles(const std::string& OUTPUT_FOLDER) { +bool RenderableFieldlinesSequence::getStatesFromCdfFiles(const std::string& outputFolder) { std::string seedFilePath; std::string tracingVar; @@ -746,19 +746,19 @@ bool RenderableFieldlinesSequence::getStatesFromCdfFiles(const std::string& OUTP // the extraQuantites, as the iterpolator needs the unaltered positions newState.addExtraQuantities(kameleon.get(), extraVars, extraMagVars); switch (newState.model()) { - case fls::BATSRUS: - newState.scalePositions(fls::R_E_TO_METER); + case fls::Batsrus: + newState.scalePositions(fls::ReToMeter); break; - case fls::ENLIL : - newState.convertLatLonToCartesian(fls::A_U_TO_METER); + case fls::Enlil : + newState.convertLatLonToCartesian(fls::AuToMeter); break; default: break; } addStateToSequence(newState); - if (!OUTPUT_FOLDER.empty()) { - newState.saveStateToOsfls(OUTPUT_FOLDER); + if (!outputFolder.empty()) { + newState.saveStateToOsfls(outputFolder); } } } @@ -775,7 +775,7 @@ bool RenderableFieldlinesSequence::extractCdfInfoFromDictionary( std::string& tracingVar, std::vector& extraVars) { - if (_dictionary->getValue(KEY_CDF_SEED_POINT_FILE, seedFilePath)) { + if (_dictionary->getValue(KeyCdfSeedPointFile, seedFilePath)) { ghoul::filesystem::File seedPointFile(seedFilePath); if (FileSys.fileExists(seedPointFile)) { seedFilePath = absPath(seedFilePath); @@ -785,20 +785,20 @@ bool RenderableFieldlinesSequence::extractCdfInfoFromDictionary( return false; } } else { - LERROR(_name << ": Must specify '" << KEY_CDF_SEED_POINT_FILE << "'"); + LERROR(_name << ": Must specify '" << KeyCdfSeedPointFile << "'"); return false; } - if (!_dictionary->getValue(KEY_CDF_TRACING_VARIABLE, tracingVar)) { + if (!_dictionary->getValue(KeyCdfTracingVariable, tracingVar)) { tracingVar = "b"; // Magnetic field variable as default - LWARNING(_name << ": No '" << KEY_CDF_TRACING_VARIABLE << "', using default: " + LWARNING(_name << ": No '" << KeyCdfTracingVariable << "', using default: " << tracingVar); } ghoul::Dictionary extraQuantityNamesDictionary; - if (_dictionary->getValue(KEY_CDF_EXTRA_VARIABLES, extraQuantityNamesDictionary)) { - const size_t N_PROVIDED_EXTRAS = extraQuantityNamesDictionary.size(); - for (size_t i = 1; i <= N_PROVIDED_EXTRAS; ++i) { + if (_dictionary->getValue(KeyCdfExtraVariables, extraQuantityNamesDictionary)) { + const size_t nProvidedExtras = extraQuantityNamesDictionary.size(); + for (size_t i = 1; i <= nProvidedExtras; ++i) { extraVars.push_back( extraQuantityNamesDictionary.value(std::to_string(i))); } @@ -846,10 +846,10 @@ void RenderableFieldlinesSequence::extractMagnitudeVarsFromStrings( for (int i = 0; i < extraVars.size(); i++) { - const std::string STR = extraVars[i]; + const std::string str = extraVars[i]; // Check if string is in the format specified for magnitude variables - if (STR.substr(0, 2) == "|(" && STR.substr(STR.size() - 2, 2) == ")|") { - std::istringstream ss(STR.substr(2, STR.size() - 4)); + if (str.substr(0, 2) == "|(" && str.substr(str.size() - 2, 2) == ")|") { + std::istringstream ss(str.substr(2, str.size() - 4)); std::string magVar; size_t counter = 0; while(std::getline(ss, magVar, ',')) { diff --git a/modules/fieldlinessequence/shaders/fieldlinessequence_vs.glsl b/modules/fieldlinessequence/shaders/fieldlinessequence_vs.glsl index a1313ae00d..1dca94c11e 100644 --- a/modules/fieldlinessequence/shaders/fieldlinessequence_vs.glsl +++ b/modules/fieldlinessequence/shaders/fieldlinessequence_vs.glsl @@ -58,8 +58,8 @@ layout(location = 1) in float in_color_scalar; // The extra value used to colo layout(location = 2) in float in_masking_scalar; // The extra value used to mask out parts of lines. Location must correspond to _VA_MASKING in renderablefieldlinessequence.h // These should correspond to the enum 'ColorMethod' in renderablefieldlinesequence.cpp -const int UNIFORM_COLOR = 0; -const int COLOR_BY_QUANTITY = 1; +const int uniformColor = 0; +const int colorByQuantity = 1; out vec4 vs_color; out float vs_depth; @@ -67,15 +67,15 @@ out float vs_depth; vec4 getTransferFunctionColor() { // Remap the color scalar to a [0,1] range - const float LOOK_UP_VAL = (in_color_scalar - colorTableRange.x) / - (colorTableRange.y - colorTableRange.x); - return texture(colorTable, LOOK_UP_VAL); + const float lookUpVal = (in_color_scalar - colorTableRange.x) / + (colorTableRange.y - colorTableRange.x); + return texture(colorTable, lookUpVal); } -bool isPartOfParticle(const double TIME, const int VERTEX_ID, const int PARTICLE_SIZE, - const int PARTICLE_SPEED, const int PARTICLE_SPACING) { - const int MODULUS_RESULT = int(double(PARTICLE_SPEED) * TIME + VERTEX_ID) % PARTICLE_SPACING; - return MODULUS_RESULT > 0 && MODULUS_RESULT <= PARTICLE_SIZE; +bool isPartOfParticle(const double time, const int vertexId, const int particleSize, + const int particleSpeed, const int particleSpacing) { + const int modulusResult = int(double(particleSpeed) * time + vertexId) % particleSpacing; + return modulusResult > 0 && modulusResult <= particleSize; } void main() { @@ -88,32 +88,32 @@ void main() { } if (usingDomain && hasColor) { - const float RADIUS = length(in_position); + const float radius = length(in_position); if (in_position.x < domainLimX.x || in_position.x > domainLimX.y || in_position.y < domainLimY.x || in_position.y > domainLimY.y || in_position.z < domainLimZ.x || in_position.z > domainLimZ.y || - RADIUS < domainLimR.x || RADIUS > domainLimR.y) { + radius < domainLimR.x || radius > domainLimR.y) { hasColor = false; } } if (hasColor) { - const bool IS_PARTICLE = usingParticles && isPartOfParticle(time, gl_VertexID, + const bool isParticle = usingParticles && isPartOfParticle(time, gl_VertexID, particleSize, particleSpeed, particleSpacing); - if (IS_PARTICLE) { + if (isParticle) { vs_color = flowColor; } else { vs_color = lineColor; } - if (colorMethod == COLOR_BY_QUANTITY) { - const vec4 QUANTITY_COLOR = getTransferFunctionColor(); - vs_color = vec4(QUANTITY_COLOR.xyz, vs_color.a * QUANTITY_COLOR.a); + if (colorMethod == colorByQuantity) { + const vec4 quantityColor = getTransferFunctionColor(); + vs_color = vec4(quantityColor.xyz, vs_color.a * quantityColor.a); } } else { vs_color = vec4(0); diff --git a/modules/fieldlinessequence/util/commons.cpp b/modules/fieldlinessequence/util/commons.cpp index 76bedb6dc9..df3f76978f 100644 --- a/modules/fieldlinessequence/util/commons.cpp +++ b/modules/fieldlinessequence/util/commons.cpp @@ -27,15 +27,15 @@ namespace openspace { namespace fls { -Model stringToModel(const std::string S) { - if (S == "batsrus") { - return Model::BATSRUS; - } else if (S == "enlil") { - return Model::ENLIL; - } else if (S == "pfss") { - return Model::PFSS; +Model stringToModel(const std::string s) { + if (s == "batsrus") { + return Model::Batsrus; + } else if (s == "enlil") { + return Model::Enlil; + } else if (s == "pfss") { + return Model::Pfss; } - return Model::INVALID; + return Model::Invalid; } } // namespace fls diff --git a/modules/fieldlinessequence/util/commons.h b/modules/fieldlinessequence/util/commons.h index 488f358451..d730f8082c 100644 --- a/modules/fieldlinessequence/util/commons.h +++ b/modules/fieldlinessequence/util/commons.h @@ -31,17 +31,17 @@ namespace openspace { namespace fls { // (F)ield(L)ines(S)equence enum Model : int { - BATSRUS = 0, - ENLIL, - PFSS, - INVALID + Batsrus = 0, + Enlil, + Pfss, + Invalid }; -Model stringToModel(const std::string S); +Model stringToModel(const std::string s); -const float A_U_TO_METER = 149597870700.f; // Astronomical Units -const float R_E_TO_METER = 6371000.f; // Earth radius -const float R_S_TO_METER = 695700000.f; // Sun radius +const float AuToMeter = 149597870700.f; // Astronomical Units +const float ReToMeter = 6371000.f; // Earth radius +const float RsToMeter = 695700000.f; // Sun radius } // namespace fls } // namespace openspace diff --git a/modules/fieldlinessequence/util/fieldlinesstate.cpp b/modules/fieldlinessequence/util/fieldlinesstate.cpp index 3bbeb7eabf..f40f28a7bf 100644 --- a/modules/fieldlinessequence/util/fieldlinesstate.cpp +++ b/modules/fieldlinessequence/util/fieldlinesstate.cpp @@ -40,11 +40,11 @@ namespace { std::string _loggerCat = "FieldlinesState"; - const int CURRENT_VERSION = 0; + const int CurrentVersion = 0; - const std::string T_AS_P_OVER_RHO = "T = p/rho"; - const std::string J_PARALLEL_B = "Current: mag(J||B)"; - const float TO_KELVIN = 72429735.6984f; // <-- [nPa]/[amu/cm^3] * TO_KELVIN => Temperature in Kelvin + const std::string TAsPOverRho = "T = p/rho"; + const std::string JParallelB = "Current: mag(J||B)"; + const float ToKelvin = 72429735.6984f; // <-- [nPa]/[amu/cm^3] * ToKelvin => Temperature in Kelvin using json = nlohmann::json; } @@ -58,18 +58,18 @@ namespace openspace { * Note that extraQuantities will NOT be set! */ bool FieldlinesState::addLinesFromKameleon(ccmc::Kameleon* kameleon, - const std::vector& SEED_POINTS, - const std::string TRACING_VAR) { + const std::vector& seedPoints, + const std::string tracingVar) { _model = fls::stringToModel(kameleon->getModelName()); float innerBoundaryLimit; switch (_model) { - case fls::Model::BATSRUS : + case fls::Model::Batsrus : innerBoundaryLimit = 2.5f; // TODO specify in Lua? break; - case fls::Model::ENLIL : + case fls::Model::Enlil : innerBoundaryLimit = 0.11f; // TODO specify in Lua? break; default: @@ -79,15 +79,15 @@ bool FieldlinesState::addLinesFromKameleon(ccmc::Kameleon* kameleon, } // --------------------------- LOAD TRACING VARIABLE ---------------------------- // - if (!kameleon->loadVariable(TRACING_VAR)) { - LERROR("FAILED TO LOAD TRACING VARIABLE: " << TRACING_VAR); + if (!kameleon->loadVariable(tracingVar)) { + LERROR("FAILED TO LOAD TRACING VARIABLE: " << tracingVar); return false; } LINFO("TRACING FIELD LINES!"); // - LOOP THROUGH THE SEED POINTS, TRACE LINES AND CONVERT TO THE DESIRED FORMAT - // size_t lineStart = 0; - for (glm::vec3 seed : SEED_POINTS) { + for (glm::vec3 seed : seedPoints) { //--------------------------------------------------------------------------// // We have to create a new tracer (or actually a new interpolator) for each // // new line, otherwise some issues occur // @@ -96,18 +96,18 @@ bool FieldlinesState::addLinesFromKameleon(ccmc::Kameleon* kameleon, std::make_unique(kameleon->model); ccmc::Tracer tracer(kameleon, interpolator.get()); tracer.setInnerBoundary(innerBoundaryLimit); // TODO specify in Lua? - ccmc::Fieldline ccmcFieldline = tracer.bidirectionalTrace(TRACING_VAR, + ccmc::Fieldline ccmcFieldline = tracer.bidirectionalTrace(tracingVar, seed.x, seed.y, seed.z); - const std::vector& POSITIONS = ccmcFieldline.getPositions(); + const std::vector& positions = ccmcFieldline.getPositions(); _lineStart.push_back(lineStart); - const size_t N_LINE_POINTS = POSITIONS.size(); - _lineCount.push_back(static_cast(N_LINE_POINTS)); - lineStart += static_cast(N_LINE_POINTS); + const size_t nLinePoints = positions.size(); + _lineCount.push_back(static_cast(nLinePoints)); + lineStart += static_cast(nLinePoints); - for (const ccmc::Point3f& p : POSITIONS) { + for (const ccmc::Point3f& p : positions) { _vertexPositions.emplace_back( glm::vec3(p.component1, p.component2, p.component3)); } @@ -127,13 +127,13 @@ void FieldlinesState::loadExtrasIntoKameleon(ccmc::Kameleon* kameleon, std::string& str = xtraScalarVars[i]; bool isSuccesful = kameleon->doesVariableExist(str) && kameleon->loadVariable(str); if (!isSuccesful && - (_model == fls::Model::BATSRUS && (str == T_AS_P_OVER_RHO || str == "T" ))) { + (_model == fls::Model::Batsrus && (str == TAsPOverRho || str == "T" ))) { LDEBUG("BATSRUS doesn't contain variable T for temperature. Trying to " << "calculate it using the ideal gas law: T = pressure/density"); - const std::string P = "p", R = "rho"; - isSuccesful = kameleon->doesVariableExist(P) && kameleon->loadVariable(P) - && kameleon->doesVariableExist(R) && kameleon->loadVariable(R); - str = T_AS_P_OVER_RHO; + const std::string p = "p", r = "rho"; + isSuccesful = kameleon->doesVariableExist(p) && kameleon->loadVariable(p) + && kameleon->doesVariableExist(r) && kameleon->loadVariable(r); + str = TAsPOverRho; } if (!isSuccesful) { LWARNING("FAILED TO LOAD EXTRA VARIABLE: '" << str << "'. Ignoring it!"); @@ -158,7 +158,7 @@ void FieldlinesState::loadExtrasIntoKameleon(ccmc::Kameleon* kameleon, kameleon->loadVariable(s2) && kameleon->loadVariable(s3); std::string name = "Magnitude of (" + s1 + ", "+ s2 + ", "+ s3 + ")"; - if (isSuccesful && _model == fls::Model::BATSRUS && s1 == "jx" && s2 == "jy" + if (isSuccesful && _model == fls::Model::Batsrus && s1 == "jx" && s2 == "jy" && s3 == "jz") { // CCMC isn't really interested in the magnitude of current, but by the // magnitude of the part of the current's vector that is parallel to the @@ -169,7 +169,7 @@ void FieldlinesState::loadExtrasIntoKameleon(ccmc::Kameleon* kameleon, kameleon->loadVariable("bx") && kameleon->loadVariable("by") && kameleon->loadVariable("bz"); - name = J_PARALLEL_B; + name = JParallelB; } if (!isSuccesful) { LWARNING("FAILED TO LOAD AT LEAST ONE OF THE MAGNITUDE VARIABLES: " @@ -211,56 +211,56 @@ void FieldlinesState::addExtraQuantities(ccmc::Kameleon* kameleon, loadExtrasIntoKameleon(kameleon, xtraScalarVars, xtraMagVars); - const size_t N_XTRA_SCALARS = xtraScalarVars.size(); - const size_t N_XTRA_MAGNITUDES = xtraMagVars.size() / 3; + const size_t nXtraScalars = xtraScalarVars.size(); + const size_t nXtraMagnitudes = xtraMagVars.size() / 3; - _extraQuantities.resize(N_XTRA_SCALARS + N_XTRA_MAGNITUDES); + _extraQuantities.resize(nXtraScalars + nXtraMagnitudes); std::unique_ptr interpolator = std::make_unique(kameleon->model); // ------ Extract all the extraQuantities from kameleon and store in state! ------ // - for (const glm::vec3& P : _vertexPositions) { + for (const glm::vec3& p : _vertexPositions) { // Load the scalars! - for (size_t i = 0; i < N_XTRA_SCALARS; i++) { + for (size_t i = 0; i < nXtraScalars; i++) { float val; - if (xtraScalarVars[i] == T_AS_P_OVER_RHO) { - val = interpolator->interpolate("p", P.x, P.y, P.z); - val *= TO_KELVIN; - val /= interpolator->interpolate("rho", P.x, P.y, P.z); + if (xtraScalarVars[i] == TAsPOverRho) { + val = interpolator->interpolate("p", p.x, p.y, p.z); + val *= ToKelvin; + val /= interpolator->interpolate("rho", p.x, p.y, p.z); } else { - val = interpolator->interpolate(xtraScalarVars[i], P.x, P.y, P.z); + val = interpolator->interpolate(xtraScalarVars[i], p.x, p.y, p.z); // When measuring density in ENLIL CCMC multiply by the radius^2 - if (xtraScalarVars[i] == "rho" && _model == fls::Model::ENLIL) { - val *= std::pow(P.x * fls::A_U_TO_METER, 2.0f); + if (xtraScalarVars[i] == "rho" && _model == fls::Model::Enlil) { + val *= std::pow(p.x * fls::AuToMeter, 2.0f); } } _extraQuantities[i].push_back(val); } // Calculate and store the magnitudes! - for (size_t i = 0; i < N_XTRA_MAGNITUDES; ++i) { - const size_t IDX = i*3; + for (size_t i = 0; i < nXtraMagnitudes; ++i) { + const size_t idx = i*3; - const float X = interpolator->interpolate(xtraMagVars[IDX] , P.x, P.y, P.z); - const float Y = interpolator->interpolate(xtraMagVars[IDX+1], P.x, P.y, P.z); - const float Z = interpolator->interpolate(xtraMagVars[IDX+2], P.x, P.y, P.z); + const float x = interpolator->interpolate(xtraMagVars[idx] , p.x, p.y, p.z); + const float y = interpolator->interpolate(xtraMagVars[idx+1], p.x, p.y, p.z); + const float z = interpolator->interpolate(xtraMagVars[idx+2], p.x, p.y, p.z); float val; // When looking at the current's magnitude in Batsrus, CCMC staff are // only interested in the magnitude parallel to the magnetic field - if (_extraQuantityNames[N_XTRA_SCALARS + i] == J_PARALLEL_B) { - const glm::vec3 NORM_MAGNETIC = glm::normalize(glm::vec3( - interpolator->interpolate("bx", P.x, P.y, P.z), - interpolator->interpolate("by", P.x, P.y, P.z), - interpolator->interpolate("bz", P.x, P.y, P.z))); + if (_extraQuantityNames[nXtraScalars + i] == JParallelB) { + const glm::vec3 normMagnetic = glm::normalize(glm::vec3( + interpolator->interpolate("bx", p.x, p.y, p.z), + interpolator->interpolate("by", p.x, p.y, p.z), + interpolator->interpolate("bz", p.x, p.y, p.z))); // Magnitude of the part of the current vector that's parallel to // the magnetic field vector! - val = glm::dot(glm::vec3(X,Y,Z), NORM_MAGNETIC); + val = glm::dot(glm::vec3(x,y,z), normMagnetic); } else { - val = std::sqrt(X*X + Y*Y + Z*Z); + val = std::sqrt(x*x + y*y + z*z); } - _extraQuantities[i + N_XTRA_SCALARS].push_back(val); + _extraQuantities[i + nXtraScalars].push_back(val); } } } @@ -270,33 +270,33 @@ void FieldlinesState::addExtraQuantities(ccmc::Kameleon* kameleon, /** * Converts all glm::vec3 in _vertexPositions from spherical (radius, latitude, longitude) * coordinates into cartesian coordinates. The longitude and latitude coordinates are -* expected to be in degrees. SCALE is an optional scaling factor. +* expected to be in degrees. scale is an optional scaling factor. */ -void FieldlinesState::convertLatLonToCartesian(const float SCALE /* = 1.f */) { +void FieldlinesState::convertLatLonToCartesian(const float scale /* = 1.f */) { for (glm::vec3& p : _vertexPositions) { - const float R = p.x * SCALE; - const float LAT = glm::radians(p.y); - const float LON = glm::radians(p.z); - const float R_COS_LAT = R * cos(LAT); + const float r = p.x * scale; + const float lat = glm::radians(p.y); + const float lon = glm::radians(p.z); + const float rCosLat = r * cos(lat); - p = glm::vec3(R_COS_LAT * cos(LON), R_COS_LAT* sin(LON), R * sin(LAT)); + p = glm::vec3(rCosLat * cos(lon), rCosLat* sin(lon), r * sin(lat)); } } #endif // OPENSPACE_MODULE_KAMELEON_ENABLED #ifdef OPENSPACE_MODULE_KAMELEON_ENABLED -void FieldlinesState::scalePositions(const float SCALE) { +void FieldlinesState::scalePositions(const float scale) { for (glm::vec3& p : _vertexPositions) { - p *= SCALE; + p *= scale; } } #endif // OPENSPACE_MODULE_KAMELEON_ENABLED -bool FieldlinesState::loadStateFromOsfls(const std::string& PATH_TO_OSFLS_FILE) { - std::ifstream ifs(PATH_TO_OSFLS_FILE, std::ifstream::binary); +bool FieldlinesState::loadStateFromOsfls(const std::string& pathToOsflsFile) { + std::ifstream ifs(pathToOsflsFile, std::ifstream::binary); if (!ifs.is_open()) { - LERRORC("FieldlinesState", "Couldn't open file: " + PATH_TO_OSFLS_FILE); + LERRORC("FieldlinesState", "Couldn't open file: " + pathToOsflsFile); return false; } @@ -366,15 +366,15 @@ bool FieldlinesState::loadStateFromOsfls(const std::string& PATH_TO_OSFLS_FILE) return true; } -bool FieldlinesState::loadStateFromJson(const std::string& PATH_TO_JSON_FILE, - const fls::Model MODEL, - const float COORD_TO_METERS = 1.f) { +bool FieldlinesState::loadStateFromJson(const std::string& pathToJsonFile, + const fls::Model Model, + const float coordToMeters = 1.f) { // --------------------- ENSURE FILE IS VALID, THEN PARSE IT --------------------- // - std::ifstream ifs(PATH_TO_JSON_FILE); + std::ifstream ifs(pathToJsonFile); if (!ifs.is_open()) { - LERROR("FAILED TO OPEN FILE: " << PATH_TO_JSON_FILE); + LERROR("FAILED TO OPEN FILE: " << pathToJsonFile); return false; } @@ -382,70 +382,70 @@ bool FieldlinesState::loadStateFromJson(const std::string& PATH_TO_JSON_FILE, ifs >> jFile; // -------------------------------------------------------------------------------- // - _model = MODEL; + _model = Model; - const std::string S_DATA = "data"; - const std::string S_TRACE = "trace"; + const std::string sData = "data"; + const std::string sTrace = "trace"; // ----- EXTRACT THE EXTRA QUANTITY NAMES & TRIGGER TIME (same for all lines) ----- // { - const json J_TMP = *jFile.begin(); // First field line in the file - _triggerTime = Time::convertTime(J_TMP["time"]); + const json jTmp = *jFile.begin(); // First field line in the file + _triggerTime = Time::convertTime(jTmp["time"]); - const std::string S_COLUMNS = "columns"; - auto variableNameVec = J_TMP[S_TRACE][S_COLUMNS]; - const size_t N_VARIABLES = variableNameVec.size(); - const size_t N_POS_COMPONENTS = 3; // x,y,z + const std::string sColumns = "columns"; + auto variableNameVec = jTmp[sTrace][sColumns]; + const size_t nVariables = variableNameVec.size(); + const size_t nPosComponents = 3; // x,y,z - if (N_VARIABLES < N_POS_COMPONENTS) { - LERROR(PATH_TO_JSON_FILE + ": Each field '" + S_COLUMNS + + if (nVariables < nPosComponents) { + LERROR(pathToJsonFile + ": Each field '" + sColumns + "' must contain the variables: 'x', 'y' and 'z' (order is important)."); return false; } - for (size_t i = N_POS_COMPONENTS ; i < N_VARIABLES ; i++) { + for (size_t i = nPosComponents ; i < nVariables ; i++) { _extraQuantityNames.push_back(variableNameVec[i]); } } - const size_t N_EXTRAS = _extraQuantityNames.size(); - _extraQuantities.resize(N_EXTRAS); + const size_t nExtras = _extraQuantityNames.size(); + _extraQuantities.resize(nExtras); size_t lineStartIdx = 0; // Loop through all fieldlines - for (json::iterator fieldlineIt = jFile.begin(); fieldlineIt != jFile.end(); ++fieldlineIt) { + for (json::iterator lineIter = jFile.begin(); lineIter != jFile.end(); ++lineIter) { // The 'data' field in the 'trace' variable contains all vertex positions and the // extra quantities. Each element is an array related to one vertex point. - const std::vector> J_DATA = (*fieldlineIt)[S_TRACE][S_DATA]; - const size_t N_POINTS = J_DATA.size(); + const std::vector> jData = (*lineIter)[sTrace][sData]; + const size_t nPoints = jData.size(); - for (size_t j = 0; j < N_POINTS; ++j) { - const std::vector& VARIABLES = J_DATA[j]; + for (size_t j = 0; j < nPoints; ++j) { + const std::vector& variables = jData[j]; // Expects the x, y and z variables to be stored first! - const size_t X_IDX = 0, Y_IDX = 1, Z_IDX = 2; - _vertexPositions.push_back(COORD_TO_METERS * glm::vec3(VARIABLES[X_IDX], - VARIABLES[Y_IDX], - VARIABLES[Z_IDX])); + const size_t xIdx = 0, yIdx = 1, zIdx = 2; + _vertexPositions.push_back(coordToMeters * glm::vec3(variables[xIdx], + variables[yIdx], + variables[zIdx])); // Add the extra quantites. Stored in the same array as the x,y,z variables. // Hence index of the first extra quantity = 3 - for (size_t xtraIdx = 3, k = 0 ; k < N_EXTRAS; ++k, ++xtraIdx) { - _extraQuantities[k].push_back(VARIABLES[xtraIdx]); + for (size_t xtraIdx = 3, k = 0 ; k < nExtras; ++k, ++xtraIdx) { + _extraQuantities[k].push_back(variables[xtraIdx]); } } - _lineCount.push_back(static_cast(N_POINTS)); + _lineCount.push_back(static_cast(nPoints)); _lineStart.push_back(static_cast(lineStartIdx)); - lineStartIdx += N_POINTS; + lineStartIdx += nPoints; } return true; } /** - * @param ABS_FILEPATH must be the path to the file (incl. filename but excl. extension!) + * @param absPath must be the path to the file (incl. filename but excl. extension!) * Directory must exist! File is created (or overwritten if already existing). * File is structured like this: (for version 0) - * 0. int - version number of binary state file! (in case something needs to be altered in the future, then increase CURRENT_VERSION) + * 0. int - version number of binary state file! (in case something needs to be altered in the future, then increase CurrentVersion) * 1. double - _triggerTime * 2. int - _model * 3. bool - _isMorphable @@ -459,17 +459,17 @@ bool FieldlinesState::loadStateFromJson(const std::string& PATH_TO_JSON_FILE, * 10. std::vector - _extraQuantities * 11. array of c_str - Strings naming the extra quantities (elements of _extraQuantityNames). Each string ends with null char '\0' */ -void FieldlinesState::saveStateToOsfls(const std::string& ABS_FILEPATH) { +void FieldlinesState::saveStateToOsfls(const std::string& absPath) { // ------------------------------- Create the file ------------------------------- // std::string pathSafeTimeString = Time(_triggerTime).ISO8601(); pathSafeTimeString.replace(13, 1, "-"); pathSafeTimeString.replace(16, 1, "-"); pathSafeTimeString.replace(19, 1, "-"); - const std::string FILENAME = pathSafeTimeString + ".osfls"; + const std::string fileName = pathSafeTimeString + ".osfls"; - std::ofstream ofs(ABS_FILEPATH + FILENAME, std::ofstream::binary | std::ofstream::trunc); + std::ofstream ofs(absPath + fileName, std::ofstream::binary | std::ofstream::trunc); if (!ofs.is_open()) { - LERROR("Failed to save state to binary file: " << ABS_FILEPATH << FILENAME); + LERROR("Failed to save state to binary file: " << absPath << fileName); return; } @@ -479,34 +479,34 @@ void FieldlinesState::saveStateToOsfls(const std::string& ABS_FILEPATH) { allExtraQuantityNamesInOne += str + '\0'; // Add the null char '\0' for easier reading } - const size_t N_LINES = _lineStart.size(); - const size_t N_POINTS = _vertexPositions.size(); - const size_t N_EXTRAS = _extraQuantities.size(); - const size_t N_STRING_BYTES = allExtraQuantityNamesInOne.size(); + const size_t nLines = _lineStart.size(); + const size_t nPoints = _vertexPositions.size(); + const size_t nExtras = _extraQuantities.size(); + const size_t nStringBytes = allExtraQuantityNamesInOne.size(); //------------------------------ WRITE EVERYTHING TO FILE ------------------------------ // WHICH VERSION OF BINARY FIELDLINES STATE FILE - IN CASE STRUCTURE CHANGES IN THE FUTURE - ofs.write( (char*)(&CURRENT_VERSION), sizeof( int ) ); + ofs.write( (char*)(&CurrentVersion), sizeof( int ) ); //-------------------- WRITE META DATA FOR STATE -------------------------------- - ofs.write( reinterpret_cast(&_triggerTime), sizeof( _triggerTime ) ); - ofs.write( reinterpret_cast(&_model), sizeof( int ) ); - ofs.write( reinterpret_cast(&_isMorphable), sizeof( bool ) ); + ofs.write( reinterpret_cast(&_triggerTime), sizeof( _triggerTime ) ); + ofs.write( reinterpret_cast(&_model), sizeof( int ) ); + ofs.write( reinterpret_cast(&_isMorphable), sizeof( bool ) ); - ofs.write( reinterpret_cast(&N_LINES), sizeof( size_t ) ); - ofs.write( reinterpret_cast(&N_POINTS), sizeof( size_t ) ); - ofs.write( reinterpret_cast(&N_EXTRAS), sizeof( size_t ) ); - ofs.write( reinterpret_cast(&N_STRING_BYTES), sizeof( size_t ) ); + ofs.write( reinterpret_cast(&nLines), sizeof( size_t ) ); + ofs.write( reinterpret_cast(&nPoints), sizeof( size_t ) ); + ofs.write( reinterpret_cast(&nExtras), sizeof( size_t ) ); + ofs.write( reinterpret_cast(&nStringBytes), sizeof( size_t ) ); //---------------------- WRITE ALL ARRAYS OF DATA -------------------------------- - ofs.write( reinterpret_cast(_lineStart.data()), sizeof(GLint) * N_LINES); - ofs.write( reinterpret_cast(_lineCount.data()), sizeof(GLsizei) * N_LINES); - ofs.write( reinterpret_cast(_vertexPositions.data()), sizeof(glm::vec3) * N_POINTS); + ofs.write( reinterpret_cast(_lineStart.data()), sizeof(GLint) * nLines); + ofs.write( reinterpret_cast(_lineCount.data()), sizeof(GLsizei) * nLines); + ofs.write( reinterpret_cast(_vertexPositions.data()), sizeof(glm::vec3) * nPoints); // Write the data for each vector in _extraQuantities for (std::vector& vec : _extraQuantities) { - ofs.write( reinterpret_cast(vec.data()), sizeof(float) * N_POINTS); + ofs.write( reinterpret_cast(vec.data()), sizeof(float) * nPoints); } - ofs.write( allExtraQuantityNamesInOne.c_str(), N_STRING_BYTES); + ofs.write( allExtraQuantityNamesInOne.c_str(), nStringBytes); } // TODO: This should probably be rewritten, but this is the way the files were structured by CCMC @@ -529,15 +529,15 @@ void FieldlinesState::saveStateToOsfls(const std::string& ABS_FILEPATH) { // }, // } // } -void FieldlinesState::saveStateToJson(const std::string& ABS_FILEPATH) { +void FieldlinesState::saveStateToJson(const std::string& absPath) { // Create the file - const std::string EXT = ".json"; - std::ofstream ofs(ABS_FILEPATH + EXT, std::ofstream::trunc); + const std::string ext = ".json"; + std::ofstream ofs(absPath + ext, std::ofstream::trunc); if (!ofs.is_open()) { - LERROR("Failed to save state to json file at location: " << ABS_FILEPATH << EXT); + LERROR("Failed to save state to json file at location: " << absPath << ext); return; } - LINFO("Saving fieldline state to: " << ABS_FILEPATH << EXT ); + LINFO("Saving fieldline state to: " << absPath << ext ); json jColumns = {"x", "y", "z"}; for (std::string s : _extraQuantityNames) { @@ -546,27 +546,26 @@ void FieldlinesState::saveStateToJson(const std::string& ABS_FILEPATH) { json jFile; - const std::string TIME_STRING = Time(_triggerTime).ISO8601(); - - const size_t N_LINES = _lineStart.size(); - const size_t N_POINTS = _vertexPositions.size(); - const size_t N_EXTRAS = _extraQuantities.size(); + const std::string timeStr = Time(_triggerTime).ISO8601(); + const size_t nLines = _lineStart.size(); + const size_t nPoints = _vertexPositions.size(); + const size_t nExtras = _extraQuantities.size(); size_t pointIndex = 0; - for (size_t lineIndex = 0; lineIndex < N_LINES; lineIndex++) { + for (size_t lineIndex = 0; lineIndex < nLines; lineIndex++) { json jData = json::array(); for (size_t i = 0; i < _lineCount[lineIndex]; i++, pointIndex++) { - const glm::vec3 POS = _vertexPositions[pointIndex]; - json jDataElement = {POS.x, POS.y, POS.z}; + const glm::vec3 pos = _vertexPositions[pointIndex]; + json jDataElement = {pos.x, pos.y, pos.z}; - for (size_t extraIndex = 0; extraIndex < N_EXTRAS; extraIndex++) { + for (size_t extraIndex = 0; extraIndex < nExtras; extraIndex++) { jDataElement.push_back(_extraQuantities[extraIndex][pointIndex]); } jData.push_back(jDataElement); } jFile[std::to_string(lineIndex)] = { - {"time", TIME_STRING}, + {"time", timeStr}, {"trace", { {"columns", jColumns}, {"data", jData} @@ -575,19 +574,19 @@ void FieldlinesState::saveStateToJson(const std::string& ABS_FILEPATH) { } //------------------------------ WRITE EVERYTHING TO FILE ------------------------------ - const int INDENTATION_SPACES = 2; - ofs << std::setw(INDENTATION_SPACES) << jFile << std::endl; + const int indentationSpaces = 2; + ofs << std::setw(indentationSpaces) << jFile << std::endl; - LINFO("Saved fieldline state to: " << ABS_FILEPATH << EXT ); + LINFO("Saved fieldline state to: " << absPath << ext ); } -// Returns one of the extra quantity vectors, _extraQuantities[INDEX]. -// If INDEX is out of scope an empty vector is returned and the referenced bool will be false. -const std::vector& FieldlinesState::extraQuantity(const size_t INDEX, +// Returns one of the extra quantity vectors, _extraQuantities[index]. +// If index is out of scope an empty vector is returned and the referenced bool will be false. +const std::vector& FieldlinesState::extraQuantity(const size_t index, bool& isSuccessful) const { - if (INDEX < _extraQuantities.size()) { + if (index < _extraQuantities.size()) { isSuccessful = true; - return _extraQuantities[INDEX]; + return _extraQuantities[index]; } isSuccessful = false; // return empty vector which goes out of scope hence unusable! diff --git a/modules/fieldlinessequence/util/fieldlinesstate.h b/modules/fieldlinessequence/util/fieldlinesstate.h index 67172d1880..71184395c4 100644 --- a/modules/fieldlinessequence/util/fieldlinesstate.h +++ b/modules/fieldlinessequence/util/fieldlinesstate.h @@ -46,23 +46,23 @@ public: #ifdef OPENSPACE_MODULE_KAMELEON_ENABLED bool addLinesFromKameleon(ccmc::Kameleon* kameleon, - const std::vector& SEED_POINTS, - const std::string TRACING_VAR); + const std::vector& seedPoints, + const std::string tracingVar); void addExtraQuantities(ccmc::Kameleon* kameleon, std::vector& xtraScalarVars, std::vector& xtraMagVars); - void convertLatLonToCartesian(const float SCALE = 1.f); - void scalePositions(const float SCALE); + void convertLatLonToCartesian(const float scale = 1.f); + void scalePositions(const float scale); #endif // OPENSPACE_MODULE_KAMELEON_ENABLED - bool loadStateFromOsfls(const std::string& PATH_TO_OSFLS_FILE); - void saveStateToOsfls(const std::string& PATH_TO_OSFLS_FILE); + bool loadStateFromOsfls(const std::string& pathToOsflsFile); + void saveStateToOsfls(const std::string& pathToOsflsFile); - bool loadStateFromJson(const std::string& PATH_TO_JSON_FILE, - const fls::Model MODEL, const float COORD_TO_METERS); - void saveStateToJson(const std::string& PATH_TO_JSON_FILE); + bool loadStateFromJson(const std::string& pathToJsonFile, + const fls::Model model, const float coordToMeters); + void saveStateToJson(const std::string& pathToJsonFile); - // ------------------------------GETTERS-----------------------------------------// + // ----------------------------------- GETTERS ----------------------------------- // const std::vector>& extraQuantities() const { return _extraQuantities; } const std::vector& extraQuantityNames() const { return _extraQuantityNames; } const std::vector& lineCount() const { return _lineCount; } diff --git a/modules/kameleon/include/kameleonhelper.h b/modules/kameleon/include/kameleonhelper.h index 6d89c87c2f..180ae19e37 100644 --- a/modules/kameleon/include/kameleonhelper.h +++ b/modules/kameleon/include/kameleonhelper.h @@ -34,7 +34,7 @@ namespace ccmc { namespace openspace::kameleonHelper { - std::unique_ptr createKameleonObject(const std::string& CDF_FILE_PATH); + std::unique_ptr createKameleonObject(const std::string& cdfFilePath); double getTime(ccmc::Kameleon* kameleon); } //namespace openspace::kameleonHelper diff --git a/modules/kameleon/src/kameleonhelper.cpp b/modules/kameleon/src/kameleonhelper.cpp index 8ee44abd60..ad3c6444aa 100644 --- a/modules/kameleon/src/kameleonhelper.cpp +++ b/modules/kameleon/src/kameleonhelper.cpp @@ -42,18 +42,18 @@ namespace openspace::kameleonHelper { * * Returns 'nullptr' if the file fails to open! */ -std::unique_ptr createKameleonObject(const std::string& CDF_FILE_PATH) { +std::unique_ptr createKameleonObject(const std::string& cdfFilePath) { // ---------------------------- CREATE KAMELEON OBJECT ---------------------------- // std::unique_ptr kameleon = std::make_unique(); - LDEBUG("\tOpening the cdf file: " << CDF_FILE_PATH); - long kamStatus = kameleon->open(CDF_FILE_PATH); + LDEBUG("\tOpening the cdf file: " << cdfFilePath); + long kamStatus = kameleon->open(cdfFilePath); if (kamStatus != ccmc::FileReader::OK) { - LERROR("Failed to create a Kameleon Object from file: " << CDF_FILE_PATH); + LERROR("Failed to create a Kameleon Object from file: " << cdfFilePath); return nullptr; } - LDEBUG("\tSuccessfully opened : " << CDF_FILE_PATH); + LDEBUG("\tSuccessfully opened : " << cdfFilePath); return kameleon; } From 69fd2ed8a44f6b09362678b9aef5fc4980d0262d Mon Sep 17 00:00:00 2001 From: Oskar Carlbaum Date: Wed, 18 Oct 2017 23:48:39 +0200 Subject: [PATCH 33/39] Remove unnecessary debug messages and return false in update() if renderable is disabled --- .../renderablefieldlinessequence.cpp | 110 +++++++++--------- .../renderablefieldlinessequencesetup.cpp | 8 -- 2 files changed, 56 insertions(+), 62 deletions(-) diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp index ad467f4110..ac0ec033a7 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp @@ -155,74 +155,76 @@ void RenderableFieldlinesSequence::render(const RenderData& data, RendererTasks& } void RenderableFieldlinesSequence::update(const UpdateData& data) { + // This node shouldn't do anything if its been disabled from the gui! + if (!_enabled) { + return; + } + if (_shaderProgram->isDirty()) { _shaderProgram->rebuildFromFile(); } - // This node shouldn't do anything if its been disabled from the gui! - if (_enabled) { - const double currentTime = data.time.j2000Seconds(); - // Check if current time in OpenSpace is within sequence interval - if (isWithinSequenceInterval(currentTime)) { - const int nextIdx = _activeTriggerTimeIndex + 1; - if (_activeTriggerTimeIndex < 0 // true => Previous frame was not within the sequence interval - || currentTime < _startTimes[_activeTriggerTimeIndex] // true => OpenSpace has stepped back to a time represented by another state - || (nextIdx < _nStates && currentTime >= _startTimes[nextIdx])) { // true => OpenSpace has stepped forward to a time represented by another state + const double currentTime = data.time.j2000Seconds(); + // Check if current time in OpenSpace is within sequence interval + if (isWithinSequenceInterval(currentTime)) { + const int nextIdx = _activeTriggerTimeIndex + 1; + if (_activeTriggerTimeIndex < 0 // true => Previous frame was not within the sequence interval + || currentTime < _startTimes[_activeTriggerTimeIndex] // true => OpenSpace has stepped back to a time represented by another state + || (nextIdx < _nStates && currentTime >= _startTimes[nextIdx])) { // true => OpenSpace has stepped forward to a time represented by another state - updateActiveTriggerTimeIndex(currentTime); + updateActiveTriggerTimeIndex(currentTime); - if (_loadingStatesDynamically) { - _mustLoadNewStateFromDisk = true; - } else { - _needsUpdate = true; - _activeStateIndex = _activeTriggerTimeIndex; - } - } // else {we're still in same state as previous frame (no changes needed)} - } else { - // Not in interval => set everything to false - _activeTriggerTimeIndex = -1; - _mustLoadNewStateFromDisk = false; - _needsUpdate = false; - } - - if (_mustLoadNewStateFromDisk) { - if (!_isLoadingStateFromDisk && !_newStateIsReady) { - _isLoadingStateFromDisk = true; - _mustLoadNewStateFromDisk = false; - const std::string filePath = _sourceFiles[_activeTriggerTimeIndex]; - std::thread readBinaryThread([this, filePath] { - this->readNewState(filePath); - }); - readBinaryThread.detach(); - } - } - - if (_needsUpdate || _newStateIsReady) { if (_loadingStatesDynamically) { - _states[0] = std::move(*_newState); + _mustLoadNewStateFromDisk = true; + } else { + _needsUpdate = true; + _activeStateIndex = _activeTriggerTimeIndex; } + } // else {we're still in same state as previous frame (no changes needed)} + } else { + // Not in interval => set everything to false + _activeTriggerTimeIndex = -1; + _mustLoadNewStateFromDisk = false; + _needsUpdate = false; + } - updateVertexPositionBuffer(); + if (_mustLoadNewStateFromDisk) { + if (!_isLoadingStateFromDisk && !_newStateIsReady) { + _isLoadingStateFromDisk = true; + _mustLoadNewStateFromDisk = false; + const std::string filePath = _sourceFiles[_activeTriggerTimeIndex]; + std::thread readBinaryThread([this, filePath] { + this->readNewState(filePath); + }); + readBinaryThread.detach(); + } + } - if (_states[_activeStateIndex].nExtraQuantities() > 0) { - _shouldUpdateColorBuffer = true; - _shouldUpdateMaskingBuffer = true; - } - - // Everything is set and ready for rendering! - _needsUpdate = false; - _newStateIsReady = false; + if (_needsUpdate || _newStateIsReady) { + if (_loadingStatesDynamically) { + _states[0] = std::move(*_newState); } - if (_shouldUpdateColorBuffer) { - updateVertexColorBuffer(); - _shouldUpdateColorBuffer = false; + updateVertexPositionBuffer(); + + if (_states[_activeStateIndex].nExtraQuantities() > 0) { + _shouldUpdateColorBuffer = true; + _shouldUpdateMaskingBuffer = true; } - if (_shouldUpdateMaskingBuffer) { - updateVertexMaskingBuffer(); - _shouldUpdateMaskingBuffer = false; - } + // Everything is set and ready for rendering! + _needsUpdate = false; + _newStateIsReady = false; + } + + if (_shouldUpdateColorBuffer) { + updateVertexColorBuffer(); + _shouldUpdateColorBuffer = false; + } + + if (_shouldUpdateMaskingBuffer) { + updateVertexMaskingBuffer(); + _shouldUpdateMaskingBuffer = false; } } diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp b/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp index 112d4090e0..c529394613 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp @@ -574,7 +574,6 @@ void RenderableFieldlinesSequence::definePropertyCallbackFunctions() { bool hasExtras = _states[0].nExtraQuantities() > 0; if (hasExtras) { _pColorQuantity.onChange([this] { - LDEBUG("CHANGED COLORING QUANTITY"); _shouldUpdateColorBuffer = true; _pColorQuantityMin = std::to_string(_colorTableRanges[_pColorQuantity].x); _pColorQuantityMax = std::to_string(_colorTableRanges[_pColorQuantity].y); @@ -587,35 +586,30 @@ void RenderableFieldlinesSequence::definePropertyCallbackFunctions() { }); _pColorQuantityMin.onChange([this] { - LDEBUG("CHANGED MIN VALUE"); float f = stringToFloat(_pColorQuantityMin, _colorTableRanges[_pColorQuantity].x); _pColorQuantityMin = std::to_string(f); _colorTableRanges[_pColorQuantity].x = f; }); _pColorQuantityMax.onChange([this] { - LDEBUG("CHANGED MAX VALUE"); float f = stringToFloat(_pColorQuantityMax, _colorTableRanges[_pColorQuantity].y); _pColorQuantityMax = std::to_string(f); _colorTableRanges[_pColorQuantity].y = f; }); _pMaskingQuantity.onChange([this] { - LDEBUG("CHANGED MASKING QUANTITY"); _shouldUpdateMaskingBuffer = true; _pMaskingMin = std::to_string(_maskingRanges[_pMaskingQuantity].x); _pMaskingMax = std::to_string(_maskingRanges[_pMaskingQuantity].y); }); _pMaskingMin.onChange([this] { - LDEBUG("CHANGED LOWER MASKING LIMIT"); float f = stringToFloat(_pMaskingMin, _maskingRanges[_pMaskingQuantity].x); _pMaskingMin = std::to_string(f); _maskingRanges[_pMaskingQuantity].x = f; }); _pMaskingMax.onChange([this] { - LDEBUG("CHANGED UPPER MASKING LIMIT"); float f = stringToFloat(_pMaskingMax, _maskingRanges[_pMaskingQuantity].y); _pMaskingMax = std::to_string(f); _maskingRanges[_pMaskingQuantity].y = f; @@ -623,7 +617,6 @@ void RenderableFieldlinesSequence::definePropertyCallbackFunctions() { } _pFocusOnOriginBtn.onChange([this] { - LDEBUG("SET FOCUS NODE TO PARENT"); SceneGraphNode* node = OsEng.renderEngine().scene()->sceneGraphNode(_name); if (!node) { LWARNING("Could not find a node in scenegraph called '" << _name << "'"); @@ -634,7 +627,6 @@ void RenderableFieldlinesSequence::definePropertyCallbackFunctions() { }); _pJumpToStartBtn.onChange([this] { - LDEBUG("Jump in time to start of sequence!"); OsEng.timeManager().time().setTime(_startTimes[0]); }); } From afd91fc4af28ef9d3cba45cb55b0db0a5ee7ccf3 Mon Sep 17 00:00:00 2001 From: Oskar Carlbaum Date: Sun, 22 Oct 2017 14:55:59 +0200 Subject: [PATCH 34/39] Move all kameleon dependency to separate files named 'kameleonfieldlinehelper' --- modules/fieldlinessequence/CMakeLists.txt | 2 + .../rendering/renderablefieldlinessequence.h | 53 ++- .../renderablefieldlinessequencesetup.cpp | 45 +-- .../util/fieldlinesstate.cpp | 249 +------------ .../fieldlinessequence/util/fieldlinesstate.h | 38 +- .../util/kameleonfieldlinehelper.cpp | 342 ++++++++++++++++++ .../util/kameleonfieldlinehelper.h | 48 +++ 7 files changed, 454 insertions(+), 323 deletions(-) create mode 100644 modules/fieldlinessequence/util/kameleonfieldlinehelper.cpp create mode 100644 modules/fieldlinessequence/util/kameleonfieldlinehelper.h diff --git a/modules/fieldlinessequence/CMakeLists.txt b/modules/fieldlinessequence/CMakeLists.txt index 195e9d93d7..c9b49768f0 100644 --- a/modules/fieldlinessequence/CMakeLists.txt +++ b/modules/fieldlinessequence/CMakeLists.txt @@ -28,6 +28,7 @@ set(HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablefieldlinessequence.h ${CMAKE_CURRENT_SOURCE_DIR}/util/fieldlinesstate.h ${CMAKE_CURRENT_SOURCE_DIR}/util/commons.h + ${CMAKE_CURRENT_SOURCE_DIR}/util/kameleonfieldlinehelper.h ) source_group("Header Files" FILES ${HEADER_FILES}) @@ -36,6 +37,7 @@ set(SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablefieldlinessequencesetup.cpp ${CMAKE_CURRENT_SOURCE_DIR}/util/fieldlinesstate.cpp ${CMAKE_CURRENT_SOURCE_DIR}/util/commons.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/util/kameleonfieldlinehelper.cpp ) source_group("Source Files" FILES ${SOURCE_FILES}) diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h index ef4b4870bf..54f666b660 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h @@ -136,38 +136,33 @@ private: properties::TriggerProperty _pJumpToStartBtn; // Button which executes a time jump to start of sequence // --------------------- FUNCTIONS USED DURING INITIALIZATION --------------------- // - void addStateToSequence(FieldlinesState& STATE); - void computeSequenceEndTime(); - void definePropertyCallbackFunctions(); - bool extractJsonInfoFromDictionary(fls::Model& model); - bool extractMandatoryInfoFromDictionary(SourceFileType& sourceFileType); - void extractOptionalInfoFromDictionary(std::string& outputFolderPath); - void extractOsflsInfoFromDictionary(); - void extractTriggerTimesFromFileNames(); - bool loadJsonStatesIntoRAM(const std::string& outputFolder); - void loadOsflsStatesIntoRAM(const std::string& outputFolder); - void setModelDependentConstants(); - void setupProperties(); - bool prepareForOsflsStreaming(); -#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED - // --- Initialization functions which require the kameleon module to be loaded! --- // - bool extractCdfInfoFromDictionary(std::string& seedFilePath, - std::string& tracingVar, - std::vector& extraVars); - bool extractSeedPointsFromFile(const std::string& path, - std::vector& outVec); - void extractMagnitudeVarsFromStrings(std::vector& extraVars, - std::vector& extraMagVars); - bool getStatesFromCdfFiles(const std::string& outputFolder); -#endif // OPENSPACE_MODULE_KAMELEON_ENABLED + void addStateToSequence(FieldlinesState& STATE); + void computeSequenceEndTime(); + void definePropertyCallbackFunctions(); + bool extractCdfInfoFromDictionary(std::string& seedFilePath, std::string& tracingVar, + std::vector& extraVars); + bool extractJsonInfoFromDictionary(fls::Model& model); + void extractMagnitudeVarsFromStrings(std::vector& extraVars, + std::vector& extraMagVars); + bool extractMandatoryInfoFromDictionary(SourceFileType& sourceFileType); + void extractOptionalInfoFromDictionary(std::string& outputFolderPath); + void extractOsflsInfoFromDictionary(); + bool extractSeedPointsFromFile(const std::string& path, std::vector& outVec); + void extractTriggerTimesFromFileNames(); + bool loadJsonStatesIntoRAM(const std::string& outputFolder); + void loadOsflsStatesIntoRAM(const std::string& outputFolder); + bool getStatesFromCdfFiles(const std::string& outputFolder); + void setModelDependentConstants(); + void setupProperties(); + bool prepareForOsflsStreaming(); // ------------------------- FUNCTIONS USED DURING RUNTIME ------------------------ // inline bool isWithinSequenceInterval(const double currentTime) const; - void readNewState(const std::string& filePath); - void updateActiveTriggerTimeIndex(const double currentTime); - void updateVertexPositionBuffer(); - void updateVertexColorBuffer(); - void updateVertexMaskingBuffer(); + void readNewState(const std::string& filePath); + void updateActiveTriggerTimeIndex(const double currentTime); + void updateVertexPositionBuffer(); + void updateVertexColorBuffer(); + void updateVertexMaskingBuffer(); }; } // namespace openspace diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp b/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp index c529394613..538186e5e0 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequencesetup.cpp @@ -24,10 +24,7 @@ #include -#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED - #include - #include -#endif // OPENSPACE_MODULE_KAMELEON_ENABLED +#include #include #include @@ -224,11 +221,9 @@ void RenderableFieldlinesSequence::initialize() { // EXTRACT SOURCE FILE TYPE SPECIFIC INFOMRATION FROM DICTIONARY & GET STATES FROM SOURCE switch (sourceFileType) { case SourceFileType::Cdf: -#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED if (!getStatesFromCdfFiles(outputFolderPath)) { return; } -#endif // OPENSPACE_MODULE_KAMELEON_ENABLED break; case SourceFileType::Json: if (!loadJsonStatesIntoRAM(outputFolderPath)) { @@ -313,10 +308,6 @@ bool RenderableFieldlinesSequence::extractMandatoryInfoFromDictionary( // Verify that the input type is correct if (inputFileTypeString == ValueInputFileTypeCdf) { sourceFileType = SourceFileType::Cdf; -#ifndef OPENSPACE_MODULE_KAMELEON_ENABLED - LERROR(_name << ": CDF file inputs requires the 'Kameleon' module to be enabled!"); - return false; -#endif // OPENSPACE_MODULE_KAMELEON_ENABLED } else if (inputFileTypeString == ValueInputFileTypeJson) { sourceFileType = SourceFileType::Json; } else if (inputFileTypeString == ValueInputFileTypeOsfls) { @@ -705,7 +696,6 @@ void RenderableFieldlinesSequence::addStateToSequence(FieldlinesState& state) { _nStates++; } -#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED bool RenderableFieldlinesSequence::getStatesFromCdfFiles(const std::string& outputFolder) { std::string seedFilePath; @@ -724,30 +714,13 @@ bool RenderableFieldlinesSequence::getStatesFromCdfFiles(const std::string& outp extractMagnitudeVarsFromStrings(extraVars, extraMagVars); // Load states into RAM! - for (std::string filePath : _sourceFiles) { - // Create Kameleon object and open CDF file! - std::unique_ptr kameleon = - kameleonHelper::createKameleonObject(filePath); + for (std::string cdfPath : _sourceFiles) { FieldlinesState newState; - newState.setTriggerTime(kameleonHelper::getTime(kameleon.get())); - - if (newState.addLinesFromKameleon(kameleon.get(), seedPoints, tracingVar)) { - // The line points are in their RAW format (unscaled & maybe spherical) - // Before we scale to meters (and maybe cartesian) we must extract - // the extraQuantites, as the iterpolator needs the unaltered positions - newState.addExtraQuantities(kameleon.get(), extraVars, extraMagVars); - switch (newState.model()) { - case fls::Batsrus: - newState.scalePositions(fls::ReToMeter); - break; - case fls::Enlil : - newState.convertLatLonToCartesian(fls::AuToMeter); - break; - default: - break; - } + bool isSuccessful = fls::convertCdfToFieldlinesState(newState, cdfPath, + seedPoints, tracingVar, extraVars, extraMagVars); + if (isSuccessful) { addStateToSequence(newState); if (!outputFolder.empty()) { newState.saveStateToOsfls(outputFolder); @@ -756,9 +729,7 @@ bool RenderableFieldlinesSequence::getStatesFromCdfFiles(const std::string& outp } return true; } -#endif // OPENSPACE_MODULE_KAMELEON_ENABLED -#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED /* * Returns false if it fails to extract mandatory information! */ @@ -798,9 +769,7 @@ bool RenderableFieldlinesSequence::extractCdfInfoFromDictionary( return true; } -#endif // OPENSPACE_MODULE_KAMELEON_ENABLED -#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED bool RenderableFieldlinesSequence::extractSeedPointsFromFile( const std::string& path, std::vector& outVec) { @@ -829,14 +798,11 @@ bool RenderableFieldlinesSequence::extractSeedPointsFromFile( return true; } -#endif // OPENSPACE_MODULE_KAMELEON_ENABLED -#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED void RenderableFieldlinesSequence::extractMagnitudeVarsFromStrings( std::vector& extraVars, std::vector& extraMagVars) { - for (int i = 0; i < extraVars.size(); i++) { const std::string str = extraVars[i]; // Check if string is in the format specified for magnitude variables @@ -861,6 +827,5 @@ void RenderableFieldlinesSequence::extractMagnitudeVarsFromStrings( } } } -#endif // OPENSPACE_MODULE_KAMELEON_ENABLED } // namespace openspace diff --git a/modules/fieldlinessequence/util/fieldlinesstate.cpp b/modules/fieldlinessequence/util/fieldlinesstate.cpp index f40f28a7bf..3d61f1c384 100644 --- a/modules/fieldlinessequence/util/fieldlinesstate.cpp +++ b/modules/fieldlinessequence/util/fieldlinesstate.cpp @@ -32,241 +32,14 @@ #include -#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED - #include - #include - #include -#endif // OPENSPACE_MODULE_KAMELEON_ENABLED - namespace { std::string _loggerCat = "FieldlinesState"; const int CurrentVersion = 0; - - const std::string TAsPOverRho = "T = p/rho"; - const std::string JParallelB = "Current: mag(J||B)"; - const float ToKelvin = 72429735.6984f; // <-- [nPa]/[amu/cm^3] * ToKelvin => Temperature in Kelvin - using json = nlohmann::json; } namespace openspace { -#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED -/** - * Traces and adds line vertices to state. (Also sets the simulation model variable: _model!) - * Vertices may need to be scaled to meters & converted from spherical into cartesian coordinates. - * Note that extraQuantities will NOT be set! - */ -bool FieldlinesState::addLinesFromKameleon(ccmc::Kameleon* kameleon, - const std::vector& seedPoints, - const std::string tracingVar) { - - _model = fls::stringToModel(kameleon->getModelName()); - - float innerBoundaryLimit; - - switch (_model) { - case fls::Model::Batsrus : - innerBoundaryLimit = 2.5f; // TODO specify in Lua? - break; - case fls::Model::Enlil : - innerBoundaryLimit = 0.11f; // TODO specify in Lua? - break; - default: - LERROR("OpenSpace's fieldlines sequence currently only supports CDFs from" << - "the BATSRUS and ENLIL models!" ); - return false; - } - - // --------------------------- LOAD TRACING VARIABLE ---------------------------- // - if (!kameleon->loadVariable(tracingVar)) { - LERROR("FAILED TO LOAD TRACING VARIABLE: " << tracingVar); - return false; - } - - LINFO("TRACING FIELD LINES!"); - // - LOOP THROUGH THE SEED POINTS, TRACE LINES AND CONVERT TO THE DESIRED FORMAT - // - size_t lineStart = 0; - for (glm::vec3 seed : seedPoints) { - //--------------------------------------------------------------------------// - // We have to create a new tracer (or actually a new interpolator) for each // - // new line, otherwise some issues occur // - //--------------------------------------------------------------------------// - std::unique_ptr interpolator = - std::make_unique(kameleon->model); - ccmc::Tracer tracer(kameleon, interpolator.get()); - tracer.setInnerBoundary(innerBoundaryLimit); // TODO specify in Lua? - ccmc::Fieldline ccmcFieldline = tracer.bidirectionalTrace(tracingVar, - seed.x, - seed.y, - seed.z); - const std::vector& positions = ccmcFieldline.getPositions(); - - _lineStart.push_back(lineStart); - const size_t nLinePoints = positions.size(); - _lineCount.push_back(static_cast(nLinePoints)); - lineStart += static_cast(nLinePoints); - - for (const ccmc::Point3f& p : positions) { - _vertexPositions.emplace_back( - glm::vec3(p.component1, p.component2, p.component3)); - } - } - - return _vertexPositions.size() > 0; -} -#endif // OPENSPACE_MODULE_KAMELEON_ENABLED - -#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED -void FieldlinesState::loadExtrasIntoKameleon(ccmc::Kameleon* kameleon, - std::vector& xtraScalarVars, - std::vector& xtraMagVars) { - // Load the existing SCALAR variables into kameleon. - // Remove non-existing variables from vector - for (int i = 0; i < xtraScalarVars.size(); i++) { - std::string& str = xtraScalarVars[i]; - bool isSuccesful = kameleon->doesVariableExist(str) && kameleon->loadVariable(str); - if (!isSuccesful && - (_model == fls::Model::Batsrus && (str == TAsPOverRho || str == "T" ))) { - LDEBUG("BATSRUS doesn't contain variable T for temperature. Trying to " - << "calculate it using the ideal gas law: T = pressure/density"); - const std::string p = "p", r = "rho"; - isSuccesful = kameleon->doesVariableExist(p) && kameleon->loadVariable(p) - && kameleon->doesVariableExist(r) && kameleon->loadVariable(r); - str = TAsPOverRho; - } - if (!isSuccesful) { - LWARNING("FAILED TO LOAD EXTRA VARIABLE: '" << str << "'. Ignoring it!"); - xtraScalarVars.erase(xtraScalarVars.begin() + i); - --i; - } else { - _extraQuantityNames.push_back(str); - } - } - - // Load the existing magnitude variables (should be provided in multiple of 3) - // into kameleon. Remove non-existing variables from vector - if (xtraMagVars.size() % 3 == 0) { - for (int i = 0; i < static_cast(xtraMagVars.size()); i += 3) { - std::string s1 = xtraMagVars[i]; - std::string s2 = xtraMagVars[i+1]; - std::string s3 = xtraMagVars[i+2]; - bool isSuccesful = kameleon->doesVariableExist(s1) && - kameleon->doesVariableExist(s2) && - kameleon->doesVariableExist(s3) && - kameleon->loadVariable(s1) && - kameleon->loadVariable(s2) && - kameleon->loadVariable(s3); - std::string name = "Magnitude of (" + s1 + ", "+ s2 + ", "+ s3 + ")"; - if (isSuccesful && _model == fls::Model::Batsrus && s1 == "jx" && s2 == "jy" - && s3 == "jz") { - // CCMC isn't really interested in the magnitude of current, but by the - // magnitude of the part of the current's vector that is parallel to the - // magnetic field => ensure that the magnetic variables are loaded - isSuccesful = kameleon->doesVariableExist("bx") && - kameleon->doesVariableExist("by") && - kameleon->doesVariableExist("bz") && - kameleon->loadVariable("bx") && - kameleon->loadVariable("by") && - kameleon->loadVariable("bz"); - name = JParallelB; - } - if (!isSuccesful) { - LWARNING("FAILED TO LOAD AT LEAST ONE OF THE MAGNITUDE VARIABLES: " - << s1 << ", " << s2 << " & " << s3 - << ". Removing ability to store corresponding magnitude!"); - xtraMagVars.erase(xtraMagVars.begin() + i, xtraMagVars.begin() + i + 3); - i -= 3; - } else { - _extraQuantityNames.push_back(name); - } - } - } else { - // WRONG NUMBER OF MAGNITUDE VARIABLES.. REMOVE ALL! - xtraMagVars.clear(); - LWARNING("Wrong number of variables provided for storing magnitudes. " - << "Expects multiple of 3 but " << xtraMagVars.size() - << " are provided"); - } -} -#endif // OPENSPACE_MODULE_KAMELEON_ENABLED - -#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED -/** - * Loops through _vertexPositions and extracts corresponding 'extraQuantities' att each - * position from the kameleon object using a ccmc::interpolator. - * Note that the positions MUST be unaltered (NOT scaled NOR converted to different - * coordinate system)! - * - * @param kameleon raw pointer to an already opened Kameleon object - * @param xtraScalarVars vector of strings. Strings should be names of a scalar quantities - * to load into _extraQuantites; such as: "T" for temperature or "rho" for density. - * @param xtraMagVars vector of strings. Size must be multiple of 3. Strings should be - * names of the components needed to calculate magnitude. E.g. {"ux", "uy", "uz"} will - * calculate: sqrt(ux*ux + uy*uy + uz*uz). Magnitude will be stored in _extraQuantities - */ -void FieldlinesState::addExtraQuantities(ccmc::Kameleon* kameleon, - std::vector& xtraScalarVars, - std::vector& xtraMagVars) { - - loadExtrasIntoKameleon(kameleon, xtraScalarVars, xtraMagVars); - - const size_t nXtraScalars = xtraScalarVars.size(); - const size_t nXtraMagnitudes = xtraMagVars.size() / 3; - - _extraQuantities.resize(nXtraScalars + nXtraMagnitudes); - - std::unique_ptr interpolator = - std::make_unique(kameleon->model); - - // ------ Extract all the extraQuantities from kameleon and store in state! ------ // - for (const glm::vec3& p : _vertexPositions) { - // Load the scalars! - for (size_t i = 0; i < nXtraScalars; i++) { - float val; - if (xtraScalarVars[i] == TAsPOverRho) { - val = interpolator->interpolate("p", p.x, p.y, p.z); - val *= ToKelvin; - val /= interpolator->interpolate("rho", p.x, p.y, p.z); - } else { - val = interpolator->interpolate(xtraScalarVars[i], p.x, p.y, p.z); - - // When measuring density in ENLIL CCMC multiply by the radius^2 - if (xtraScalarVars[i] == "rho" && _model == fls::Model::Enlil) { - val *= std::pow(p.x * fls::AuToMeter, 2.0f); - } - } - _extraQuantities[i].push_back(val); - } - // Calculate and store the magnitudes! - for (size_t i = 0; i < nXtraMagnitudes; ++i) { - const size_t idx = i*3; - - const float x = interpolator->interpolate(xtraMagVars[idx] , p.x, p.y, p.z); - const float y = interpolator->interpolate(xtraMagVars[idx+1], p.x, p.y, p.z); - const float z = interpolator->interpolate(xtraMagVars[idx+2], p.x, p.y, p.z); - float val; - // When looking at the current's magnitude in Batsrus, CCMC staff are - // only interested in the magnitude parallel to the magnetic field - if (_extraQuantityNames[nXtraScalars + i] == JParallelB) { - const glm::vec3 normMagnetic = glm::normalize(glm::vec3( - interpolator->interpolate("bx", p.x, p.y, p.z), - interpolator->interpolate("by", p.x, p.y, p.z), - interpolator->interpolate("bz", p.x, p.y, p.z))); - // Magnitude of the part of the current vector that's parallel to - // the magnetic field vector! - val = glm::dot(glm::vec3(x,y,z), normMagnetic); - - } else { - val = std::sqrt(x*x + y*y + z*z); - } - _extraQuantities[i + nXtraScalars].push_back(val); - } - } -} -#endif // OPENSPACE_MODULE_KAMELEON_ENABLED - -#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED /** * Converts all glm::vec3 in _vertexPositions from spherical (radius, latitude, longitude) * coordinates into cartesian coordinates. The longitude and latitude coordinates are @@ -283,15 +56,12 @@ void FieldlinesState::convertLatLonToCartesian(const float scale /* = 1.f */) { p = glm::vec3(rCosLat * cos(lon), rCosLat* sin(lon), r * sin(lat)); } } -#endif // OPENSPACE_MODULE_KAMELEON_ENABLED -#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED void FieldlinesState::scalePositions(const float scale) { for (glm::vec3& p : _vertexPositions) { p *= scale; } } -#endif // OPENSPACE_MODULE_KAMELEON_ENABLED bool FieldlinesState::loadStateFromOsfls(const std::string& pathToOsflsFile) { std::ifstream ifs(pathToOsflsFile, std::ifstream::binary); @@ -588,9 +358,28 @@ const std::vector& FieldlinesState::extraQuantity(const size_t index, isSuccessful = true; return _extraQuantities[index]; } + LERROR("Provided Index was out of scope!"); isSuccessful = false; // return empty vector which goes out of scope hence unusable! return std::vector(); } +/** Moves the points in @param line over to _vertexPositions and updates _lineStart & _lineCount accordingly. + */ +void FieldlinesState::addLine(std::vector& line) { + const size_t nNewPoints = line.size(); + const size_t nOldPoints = _vertexPositions.size(); + _lineStart.push_back(static_cast(nOldPoints)); + _lineCount.push_back(static_cast(nNewPoints)); + _vertexPositions.reserve(nOldPoints + nNewPoints); + _vertexPositions.insert(_vertexPositions.end(), std::make_move_iterator(line.begin()), + std::make_move_iterator(line.end())); + line.clear(); +} + +void FieldlinesState::setExtraQuantityNames(std::vector& names) { + _extraQuantityNames = std::move(names); + names.clear(); + _extraQuantities.resize(_extraQuantityNames.size()); +} } // namespace openspace diff --git a/modules/fieldlinessequence/util/fieldlinesstate.h b/modules/fieldlinessequence/util/fieldlinesstate.h index 71184395c4..35b1fb9db3 100644 --- a/modules/fieldlinessequence/util/fieldlinesstate.h +++ b/modules/fieldlinessequence/util/fieldlinesstate.h @@ -43,39 +43,35 @@ namespace openspace { class FieldlinesState { public: + void convertLatLonToCartesian(const float scale = 1.f); + void scalePositions(const float scale); -#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED - bool addLinesFromKameleon(ccmc::Kameleon* kameleon, - const std::vector& seedPoints, - const std::string tracingVar); - void addExtraQuantities(ccmc::Kameleon* kameleon, - std::vector& xtraScalarVars, - std::vector& xtraMagVars); - void convertLatLonToCartesian(const float scale = 1.f); - void scalePositions(const float scale); -#endif // OPENSPACE_MODULE_KAMELEON_ENABLED + bool loadStateFromOsfls(const std::string& pathToOsflsFile); + void saveStateToOsfls(const std::string& pathToOsflsFile); - bool loadStateFromOsfls(const std::string& pathToOsflsFile); - void saveStateToOsfls(const std::string& pathToOsflsFile); - - bool loadStateFromJson(const std::string& pathToJsonFile, - const fls::Model model, const float coordToMeters); - void saveStateToJson(const std::string& pathToJsonFile); + bool loadStateFromJson(const std::string& pathToJsonFile, + const fls::Model model, const float coordToMeters); + void saveStateToJson(const std::string& pathToJsonFile); // ----------------------------------- GETTERS ----------------------------------- // const std::vector>& extraQuantities() const { return _extraQuantities; } const std::vector& extraQuantityNames() const { return _extraQuantityNames; } const std::vector& lineCount() const { return _lineCount; } const std::vector& lineStart() const { return _lineStart; } - size_t nExtraQuantities() const { return _extraQuantities.size(); } fls::Model model() const { return _model; } + size_t nExtraQuantities() const { return _extraQuantities.size(); } double triggerTime() const { return _triggerTime; } const std::vector& vertexPositions() const { return _vertexPositions; } // Special getter. Returns extraQuantities[INDEX]. const std::vector& extraQuantity(const size_t INDEX, bool& isSuccesful) const; - void setTriggerTime(const double T) { _triggerTime = T; } + void setModel(const fls::Model m) { _model = m; } + void setTriggerTime(const double t) { _triggerTime = t; } + void setExtraQuantityNames(std::vector& names); + + void addLine(std::vector& line); + void appendToExtra(size_t idx, float val) { _extraQuantities[idx].push_back(val); } private: bool _isMorphable = false; @@ -87,12 +83,6 @@ private: std::vector _lineCount; std::vector _lineStart; std::vector _vertexPositions; - -#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED - void loadExtrasIntoKameleon(ccmc::Kameleon* kameleon, - std::vector& xtraScalarVars, - std::vector& xtraMagVars); -#endif // OPENSPACE_MODULE_KAMELEON_ENABLED }; } // namespace openspace diff --git a/modules/fieldlinessequence/util/kameleonfieldlinehelper.cpp b/modules/fieldlinessequence/util/kameleonfieldlinehelper.cpp new file mode 100644 index 0000000000..283207ec1c --- /dev/null +++ b/modules/fieldlinessequence/util/kameleonfieldlinehelper.cpp @@ -0,0 +1,342 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2017 * + * * + * 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 + +#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED + #include + #include + #include +#endif // OPENSPACE_MODULE_KAMELEON_ENABLED + +#include + +#include + +namespace { + std::string _loggerCat = "FieldlinesSequence[ Kameleon ]"; + + const std::string TAsPOverRho = "T = p/rho"; + const std::string JParallelB = "Current: mag(J||B)"; + const float ToKelvin = 72429735.6984f; // <-- [nPa]/[amu/cm^3] * ToKelvin => Temperature in Kelvin +} + +namespace openspace { +namespace fls { + +// -------------------- DECLARE FUNCTIONS USED (ONLY) IN THIS FILE -------------------- // +#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED + bool addLinesToState(ccmc::Kameleon* kameleon, const std::vector& seeds, + const std::string tracingVar, FieldlinesState& state); + void addExtraQuantities(ccmc::Kameleon* kameleon, + std::vector& extraScalarVars, + std::vector& extraMagVars, + FieldlinesState& state); + void prepareStateAndKameleonForExtras(ccmc::Kameleon* kameleon, + std::vector& extraScalarVars, + std::vector& extraMagVars, + FieldlinesState& state); +#endif // OPENSPACE_MODULE_KAMELEON_ENABLED +// ----------------------------------------------------------------------------------- // + +/** Traces field lines from the provided cdf file using kameleon and stores the data in the provided FieldlinesState. + * Returns `false` if it fails to create a valid state. Requires the kameleon module to be activated! + * @param state, FieldlineState which should hold the extracted data + * @param cdfPath, std::string of the absolute path to a .cdf file + * @param seedPoints, vector of seed points from which to trace field lines + * @param tracingVar, which quantity to trace lines from. Typically "b" for magnetic field lines and "u" for velocity flow lines + * @param extraVars, extra scalar quantities to be stored in the FieldlinesState; e.g. "T" for temperature, "rho" for density or "P" for pressure + * @param extraMagVars, variables which should be used for extracting magnitudes, must be a multiple of 3; e.g. "ux", "uy" & "uz" to get the magnitude of the velocity vector at each line vertex + */ +bool convertCdfToFieldlinesState(FieldlinesState& state, const std::string cdfPath, + const std::vector& seedPoints, + const std::string tracingVar, + std::vector& extraVars, + std::vector& extraMagVars) { + +#ifndef OPENSPACE_MODULE_KAMELEON_ENABLED + + LERROR("CDF inputs provided but Kameleon module is deactivated!"); + return false; + +#else // OPENSPACE_MODULE_KAMELEON_ENABLED + + // Create Kameleon object and open CDF file! + std::unique_ptr kameleon = + kameleonHelper::createKameleonObject(cdfPath); + + state.setModel(fls::stringToModel(kameleon->getModelName())); + state.setTriggerTime(kameleonHelper::getTime(kameleon.get())); + + if (addLinesToState(kameleon.get(), seedPoints, tracingVar, state)) { + // The line points are in their RAW format (unscaled & maybe spherical) + // Before we scale to meters (and maybe cartesian) we must extract + // the extraQuantites, as the iterpolator needs the unaltered positions + addExtraQuantities(kameleon.get(), extraVars, extraMagVars, state); + switch (state.model()) { + case fls::Batsrus: + state.scalePositions(fls::ReToMeter); + break; + case fls::Enlil : + state.convertLatLonToCartesian(fls::AuToMeter); + break; + default: + break; + } + + return true; + } + + return false; +#endif // OPENSPACE_MODULE_KAMELEON_ENABLED +} + +#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED +/** + * Traces and adds line vertices to state. + * Vertices are not scaled to meters nor converted from spherical into cartesian coordinates. + * Note that extraQuantities will NOT be set! + */ +bool addLinesToState(ccmc::Kameleon* kameleon, const std::vector& seedPoints, + const std::string tracingVar, FieldlinesState& state) { + + float innerBoundaryLimit; + + switch (state.model()) { + case fls::Model::Batsrus : + innerBoundaryLimit = 2.5f; // TODO specify in Lua? + break; + case fls::Model::Enlil : + innerBoundaryLimit = 0.11f; // TODO specify in Lua? + break; + default: + LERROR("OpenSpace's fieldlines sequence currently only supports CDFs from the" + << " BATSRUS and ENLIL models!"); + return false; + } + + // ---------------------------- LOAD TRACING VARIABLE ---------------------------- // + if (!kameleon->loadVariable(tracingVar)) { + LERROR("FAILED TO LOAD TRACING VARIABLE: " + tracingVar); + return false; + } + + bool isSuccesful = false; + LINFO("TRACING FIELD LINES!"); + // LOOP THROUGH THE SEED POINTS, TRACE LINES, CONVERT POINTS TO glm::vec3 AND STORE // + for (glm::vec3 seed : seedPoints) { + //--------------------------------------------------------------------------// + // We have to create a new tracer (or actually a new interpolator) for each // + // new line, otherwise some issues occur // + //--------------------------------------------------------------------------// + std::unique_ptr interpolator = + std::make_unique(kameleon->model); + ccmc::Tracer tracer(kameleon, interpolator.get()); + tracer.setInnerBoundary(innerBoundaryLimit); // TODO specify in Lua? + ccmc::Fieldline ccmcFieldline = tracer.bidirectionalTrace(tracingVar, seed.x, + seed.y, + seed.z); + const std::vector& positions = ccmcFieldline.getPositions(); + + const size_t nLinePoints = positions.size(); + + std::vector vertices; + vertices.reserve(nLinePoints); + for (const ccmc::Point3f& p : positions) { + vertices.emplace_back(p.component1, p.component2, p.component3); + } + state.addLine(vertices); + isSuccesful = (nLinePoints > 0) ? true : isSuccesful; + } + + return isSuccesful; +} +#endif // OPENSPACE_MODULE_KAMELEON_ENABLED + +/** + * Loops through state's _vertexPositions and extracts corresponding 'extraQuantities' + * from the kameleon object using a ccmc::interpolator. + * Note that the positions MUST be unaltered (NOT scaled NOR converted to different + * coordinate system)! + * + * @param kameleon raw pointer to an already opened Kameleon object + * @param extraScalarVars vector of strings. Strings should be names of a scalar quantities + * to load into _extraQuantites; such as: "T" for temperature or "rho" for density. + * @param extraMagVars vector of strings. Size must be multiple of 3. Strings should be + * names of the components needed to calculate magnitude. E.g. {"ux", "uy", "uz"} will + * calculate: sqrt(ux*ux + uy*uy + uz*uz). Magnitude will be stored in _extraQuantities + * @param state, The FieldlinesState which the extra quantities should be added to. + */ +#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED +void addExtraQuantities(ccmc::Kameleon* kameleon, + std::vector& extraScalarVars, + std::vector& extraMagVars, FieldlinesState& state) { + + prepareStateAndKameleonForExtras(kameleon, extraScalarVars, extraMagVars, state); + + const size_t nXtraScalars = extraScalarVars.size(); + const size_t nXtraMagnitudes = extraMagVars.size() / 3; + + std::unique_ptr interpolator = + std::make_unique(kameleon->model); + + // ------ Extract all the extraQuantities from kameleon and store in state! ------ // + for (const glm::vec3 p : state.vertexPositions()) { + // Load the scalars! + for (size_t i = 0; i < nXtraScalars; i++) { + float val; + if (extraScalarVars[i] == TAsPOverRho) { + val = interpolator->interpolate("p", p.x, p.y, p.z); + val *= ToKelvin; + val /= interpolator->interpolate("rho", p.x, p.y, p.z); + } else { + val = interpolator->interpolate(extraScalarVars[i], p.x, p.y, p.z); + + // When measuring density in ENLIL CCMC multiply by the radius^2 + if (extraScalarVars[i] == "rho" && state.model() == fls::Model::Enlil) { + val *= std::pow(p.x * fls::AuToMeter, 2.0f); + } + } + state.appendToExtra(i, val); + } + // Calculate and store the magnitudes! + for (size_t i = 0; i < nXtraMagnitudes; ++i) { + const size_t idx = i*3; + + const float x = interpolator->interpolate(extraMagVars[idx] , p.x, p.y, p.z); + const float y = interpolator->interpolate(extraMagVars[idx+1], p.x, p.y, p.z); + const float z = interpolator->interpolate(extraMagVars[idx+2], p.x, p.y, p.z); + float val; + // When looking at the current's magnitude in Batsrus, CCMC staff are + // only interested in the magnitude parallel to the magnetic field + if (state.extraQuantityNames()[nXtraScalars + i] == JParallelB) { + const glm::vec3 normMagnetic = glm::normalize(glm::vec3( + interpolator->interpolate("bx", p.x, p.y, p.z), + interpolator->interpolate("by", p.x, p.y, p.z), + interpolator->interpolate("bz", p.x, p.y, p.z))); + // Magnitude of the part of the current vector that's parallel to + // the magnetic field vector! + val = glm::dot(glm::vec3(x,y,z), normMagnetic); + + } else { + val = std::sqrt(x*x + y*y + z*z); + } + state.appendToExtra(i + nXtraScalars, val); + } + } +} +#endif // OPENSPACE_MODULE_KAMELEON_ENABLED + +/** Validate the provided extra quantity variables -> load the data from the validated + * quantities into the kameleon object & add the quantity names into the state's + * _extraQuantityNames vector. + * + * @param kameleon, raw pointer to an already opened kameleon object + * @param extraScalarVars, names of scalar quantities to add to state; e.g "rho" for density + * @param extraMagVars, names of the variables used for calculating magnitudes. Must be multiple of 3. + */ +#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED +void prepareStateAndKameleonForExtras(ccmc::Kameleon* kameleon, + std::vector& extraScalarVars, + std::vector& extraMagVars, + FieldlinesState& state) { + std::vector extraQuantityNames; + fls::Model model = fls::stringToModel(kameleon->getModelName()); + + // Load the existing SCALAR variables into kameleon. + // Remove non-existing variables from vector + for (int i = 0; i < extraScalarVars.size(); i++) { + std::string& str = extraScalarVars[i]; + bool isSuccesful = kameleon->doesVariableExist(str) && kameleon->loadVariable(str); + if (!isSuccesful && + (model == fls::Model::Batsrus && (str == TAsPOverRho || str == "T" ))) { + LDEBUG("BATSRUS doesn't contain variable T for temperature. Trying to " + << "calculate it using the ideal gas law: T = pressure/density"); + const std::string p = "p", r = "rho"; + isSuccesful = kameleon->doesVariableExist(p) && kameleon->loadVariable(p) + && kameleon->doesVariableExist(r) && kameleon->loadVariable(r); + str = TAsPOverRho; + } + if (!isSuccesful) { + LWARNING("FAILED TO LOAD EXTRA VARIABLE: '" << str << "'. Ignoring it!"); + extraScalarVars.erase(extraScalarVars.begin() + i); + --i; + } else { + extraQuantityNames.push_back(str); + } + } + + // Load the existing magnitude variables (should be provided in multiple of 3) + // into kameleon. Remove non-existing variables from vector + if (extraMagVars.size() % 3 == 0) { + for (int i = 0; i < static_cast(extraMagVars.size()); i += 3) { + std::string s1 = extraMagVars[i]; + std::string s2 = extraMagVars[i+1]; + std::string s3 = extraMagVars[i+2]; + bool isSuccesful = kameleon->doesVariableExist(s1) && + kameleon->doesVariableExist(s2) && + kameleon->doesVariableExist(s3) && + kameleon->loadVariable(s1) && + kameleon->loadVariable(s2) && + kameleon->loadVariable(s3); + std::string name = "Magnitude of (" + s1 + ", "+ s2 + ", "+ s3 + ")"; + if (isSuccesful && model == fls::Model::Batsrus && s1 == "jx" && s2 == "jy" + && s3 == "jz") { + // CCMC isn't really interested in the magnitude of current, but by the + // magnitude of the part of the current's vector that is parallel to the + // magnetic field => ensure that the magnetic variables are loaded + isSuccesful = kameleon->doesVariableExist("bx") && + kameleon->doesVariableExist("by") && + kameleon->doesVariableExist("bz") && + kameleon->loadVariable("bx") && + kameleon->loadVariable("by") && + kameleon->loadVariable("bz"); + name = JParallelB; + } + if (!isSuccesful) { + LWARNING("FAILED TO LOAD AT LEAST ONE OF THE MAGNITUDE VARIABLES: " + << s1 << ", " << s2 << " & " << s3 + << ". Removing ability to store corresponding magnitude!"); + extraMagVars.erase(extraMagVars.begin() + i, extraMagVars.begin() + i + 3); + i -= 3; + } else { + extraQuantityNames.push_back(name); + } + } + } else { + // WRONG NUMBER OF MAGNITUDE VARIABLES.. REMOVE ALL! + extraMagVars.clear(); + LWARNING("Wrong number of variables provided for storing magnitudes. " + << "Expects multiple of 3 but " << extraMagVars.size() + << " are provided"); + } + state.setExtraQuantityNames(extraQuantityNames); +} +#endif // OPENSPACE_MODULE_KAMELEON_ENABLED + +} // namespace fls +} // namespace openspace diff --git a/modules/fieldlinessequence/util/kameleonfieldlinehelper.h b/modules/fieldlinessequence/util/kameleonfieldlinehelper.h new file mode 100644 index 0000000000..f6f898a5ed --- /dev/null +++ b/modules/fieldlinessequence/util/kameleonfieldlinehelper.h @@ -0,0 +1,48 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2017 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#ifndef __OPENSPACE_MODULE_FIELDLINESSEQUENCE___KAMELEONFIELDLINEHELPER___H__ +#define __OPENSPACE_MODULE_FIELDLINESSEQUENCE___KAMELEONFIELDLINEHELPER___H__ + +#include + +#include +#include + +namespace openspace { + +class FieldlinesState; + +namespace fls { + +bool convertCdfToFieldlinesState(FieldlinesState& state, const std::string cdfPath, + const std::vector& seedPoints, + const std::string tracingVar, + std::vector& extraVars, + std::vector& extraMagVars); + +} // namespace fls +} // namespace openspace + +#endif // __OPENSPACE_MODULE_FIELDLINESSEQUENCE___KAMELEONFIELDLINEHELPER___H__ \ No newline at end of file From d1735af1ed9de7c6e34029f766126d4d23d5d682 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Thu, 9 Nov 2017 11:41:27 -0500 Subject: [PATCH 35/39] Fix compile error in iswa module --- modules/iswa/rendering/iswakameleongroup.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/iswa/rendering/iswakameleongroup.cpp b/modules/iswa/rendering/iswakameleongroup.cpp index b60c826ea6..5d6e0eeff6 100644 --- a/modules/iswa/rendering/iswakameleongroup.cpp +++ b/modules/iswa/rendering/iswakameleongroup.cpp @@ -78,7 +78,7 @@ std::vector IswaKameleonGroup::fieldlineValue(){ } void IswaKameleonGroup::setFieldlineInfo(std::string fieldlineIndexFile, - std::string kameleonPath + std::string kameleonPath) { if (fieldlineIndexFile != _fieldlineIndexFile) { _fieldlineIndexFile = fieldlineIndexFile; From 51a71d5ce234c19d38e637a92d0aab3d8b465c69 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Thu, 9 Nov 2017 14:58:43 -0500 Subject: [PATCH 36/39] Compile fix to adjust to runTime method not existing anymore --- .../rendering/renderablefieldlinessequence.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp index ac0ec033a7..c75b589abf 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -114,7 +115,10 @@ void RenderableFieldlinesSequence::render(const RenderData& data, RendererTasks& _shaderProgram->setUniform("particleSize", _pFlowParticleSize); _shaderProgram->setUniform("particleSpacing", _pFlowParticleSpacing); _shaderProgram->setUniform("particleSpeed", _pFlowSpeed); - _shaderProgram->setUniform("time", OsEng.runTime() * (_pFlowReversed ? -1 : 1)); + _shaderProgram->setUniform( + "time", + OsEng.windowWrapper().applicationTime() * (_pFlowReversed ? -1 : 1) + ); bool additiveBlending = false; if (_pColorABlendEnabled) { From aa20c677ddc9c6a969a98d4d18e6976a0e6bb9f5 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Thu, 9 Nov 2017 18:12:13 -0500 Subject: [PATCH 37/39] Move onscreen rendering into SGCT's render2D function (closes #181) Same fix makes GUI windows work again (closes #412) --- apps/OpenSpace/main.cpp | 15 ++++++++++++ include/openspace/engine/openspaceengine.h | 3 +++ modules/imgui/imguimodule.cpp | 14 ++++------- modules/space/spacemodule.cpp | 2 ++ src/engine/openspaceengine.cpp | 27 ++++++++++++++-------- 5 files changed, 43 insertions(+), 18 deletions(-) diff --git a/apps/OpenSpace/main.cpp b/apps/OpenSpace/main.cpp index d5dc91c1b4..61d991897a 100644 --- a/apps/OpenSpace/main.cpp +++ b/apps/OpenSpace/main.cpp @@ -359,6 +359,20 @@ void mainRenderFunc() { LTRACE("main::mainRenderFunc(end)"); } +void mainDraw2DFunc() { + LTRACE("main::mainDraw2DFunc(begin)"); + + OsEng.drawOverlays(); + + // SGCT gets angry if we change this in our function + glEnable(GL_BLEND); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + + + LTRACE("main::mainDraw2DFunc(end)"); +} + void mainPostDrawFunc() { LTRACE("main::mainPostDrawFunc(begin)"); @@ -525,6 +539,7 @@ int main_main(int argc, char** argv) { SgctEngine->setPreSyncFunction(mainPreSyncFunc); SgctEngine->setPostSyncPreDrawFunction(mainPostSyncPreDrawFunc); SgctEngine->setDrawFunction(mainRenderFunc); + SgctEngine->setDraw2DFunction(mainDraw2DFunc); SgctEngine->setPostDrawFunction(mainPostDrawFunc); SgctEngine->setKeyboardCallbackFunction(mainKeyboardCallback); SgctEngine->setMouseButtonCallbackFunction(mainMouseButtonCallback); diff --git a/include/openspace/engine/openspaceengine.h b/include/openspace/engine/openspaceengine.h index 8aa395f08e..2630137c80 100644 --- a/include/openspace/engine/openspaceengine.h +++ b/include/openspace/engine/openspaceengine.h @@ -87,6 +87,7 @@ public: void postSynchronizationPreDraw(); void render(const glm::mat4& sceneMatrix, const glm::mat4& viewMatrix, const glm::mat4& projectionMatrix); + void drawOverlays(); void postDraw(); void keyboardCallback(Key key, KeyModifier mod, KeyAction action); void charCallback(unsigned int codepoint, KeyModifier mod); @@ -133,6 +134,7 @@ public: PreSync, // Callback for the end of the pre-sync function PostSyncPreDraw, // Callback for the end of the post-sync-pre-draw function Render, // Callback for the end of the render function + Draw2D, // Callback for the two-dimensional rendering functions PostDraw // Callback for the end of the post-draw function }; @@ -218,6 +220,7 @@ private: std::vector> preSync; std::vector> postSyncPreDraw; std::vector> render; + std::vector> draw2D; std::vector> postDraw; std::vector> keyboard; diff --git a/modules/imgui/imguimodule.cpp b/modules/imgui/imguimodule.cpp index 4e2eca5508..6dc0529b71 100644 --- a/modules/imgui/imguimodule.cpp +++ b/modules/imgui/imguimodule.cpp @@ -148,16 +148,12 @@ ImGUIModule::ImGUIModule() : OpenSpaceModule(Name) { ); OsEng.registerModuleCallback( - // This is done in the PostDraw phase so that it will render it on top of - // everything else in the case of fisheyes. With this being in the Render callback - // the GUI would be rendered on top of each of the cube faces - OpenSpaceEngine::CallbackOption::PostDraw, - [&](){ + OpenSpaceEngine::CallbackOption::Draw2D, + [&]() { WindowWrapper& wrapper = OsEng.windowWrapper(); bool showGui = wrapper.hasGuiWindow() ? wrapper.isGuiWindow() : true; - if (wrapper.isMaster() && showGui ) { + if (wrapper.isMaster() && showGui) { glm::vec2 mousePosition = wrapper.mousePosition(); - //glm::ivec2 drawBufferResolution = _windowWrapper->currentDrawBufferResolution(); glm::ivec2 windowSize = wrapper.currentWindowSize(); uint32_t mouseButtons = wrapper.mouseButtons(2); @@ -166,8 +162,8 @@ ImGUIModule::ImGUIModule() : OpenSpaceModule(Name) { mouseButtons = touchInput.action; mousePosition = touchInput.pos; } - // We don't do any collection of immediate mode user interface, so it is - // fine to open and close a frame immediately + // We don't do any collection of immediate mode user interface, so it + // is fine to open and close a frame immediately gui.startFrame( static_cast(dt), glm::vec2(windowSize), diff --git a/modules/space/spacemodule.cpp b/modules/space/spacemodule.cpp index 305ebbd1bc..242037940d 100644 --- a/modules/space/spacemodule.cpp +++ b/modules/space/spacemodule.cpp @@ -88,6 +88,8 @@ std::vector SpaceModule::documentations() const { RenderableStars::Documentation(), SpiceRotation::Documentation(), SpiceTranslation::Documentation(), + KeplerTranslation::Documentation(), + TLETranslation::Documentation(), planetgeometry::PlanetGeometry::Documentation(), planetgeometry::SimpleSphereGeometry::Documentation() }; diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index b9019d278d..406f8c7750 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -1214,18 +1214,11 @@ void OpenSpaceEngine::render(const glm::mat4& sceneMatrix, func(); } - if (isGuiWindow && _shutdown.inShutdown) { - _renderEngine->renderShutdownInformation(_shutdown.timer, _shutdown.waitTime); - } - LTRACE("OpenSpaceEngine::render(end)"); } -void OpenSpaceEngine::postDraw() { - LTRACE("OpenSpaceEngine::postDraw(begin)"); - - _renderEngine->postDraw(); - +void OpenSpaceEngine::drawOverlays() { + LTRACE("OpenSpaceEngine::drawOverlays(begin)"); const bool isGuiWindow = _windowWrapper->hasGuiWindow() ? _windowWrapper->isGuiWindow() : true; @@ -1241,6 +1234,18 @@ void OpenSpaceEngine::postDraw() { _console->render(); } + for (const auto& func : _moduleCallbacks.draw2D) { + func(); + } + + LTRACE("OpenSpaceEngine::drawOverlays(end)"); +} + +void OpenSpaceEngine::postDraw() { + LTRACE("OpenSpaceEngine::postDraw(begin)"); + + _renderEngine->postDraw(); + for (const auto& func : _moduleCallbacks.postDraw) { func(); } @@ -1250,6 +1255,7 @@ void OpenSpaceEngine::postDraw() { _isFirstRenderingFirstFrame = false; } + LTRACE("OpenSpaceEngine::postDraw(end)"); } @@ -1430,6 +1436,9 @@ void OpenSpaceEngine::registerModuleCallback(OpenSpaceEngine::CallbackOption opt case CallbackOption::Render: _moduleCallbacks.render.push_back(std::move(function)); break; + case CallbackOption::Draw2D: + _moduleCallbacks.draw2D.push_back(std::move(function)); + break; case CallbackOption::PostDraw: _moduleCallbacks.postDraw.push_back(std::move(function)); break; From 7b12a241eda98e63f993415653449e78e7a7ffb5 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Thu, 9 Nov 2017 19:10:32 -0500 Subject: [PATCH 38/39] Remove BOMs Fix coding style and script --- modules/fieldlinessequence/util/commons.cpp | 2 +- modules/fieldlinessequence/util/kameleonfieldlinehelper.h | 2 +- modules/globebrowsing/rendering/layer/layer.cpp | 2 +- src/engine/configurationmanager_doc.inl | 2 +- support/coding/check_style_guide.py | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/fieldlinessequence/util/commons.cpp b/modules/fieldlinessequence/util/commons.cpp index df3f76978f..cf006a4abc 100644 --- a/modules/fieldlinessequence/util/commons.cpp +++ b/modules/fieldlinessequence/util/commons.cpp @@ -39,4 +39,4 @@ Model stringToModel(const std::string s) { } } // namespace fls -} // namespace openspace \ No newline at end of file +} // namespace openspace diff --git a/modules/fieldlinessequence/util/kameleonfieldlinehelper.h b/modules/fieldlinessequence/util/kameleonfieldlinehelper.h index f6f898a5ed..e496dcd258 100644 --- a/modules/fieldlinessequence/util/kameleonfieldlinehelper.h +++ b/modules/fieldlinessequence/util/kameleonfieldlinehelper.h @@ -45,4 +45,4 @@ bool convertCdfToFieldlinesState(FieldlinesState& state, const std::string cdfPa } // namespace fls } // namespace openspace -#endif // __OPENSPACE_MODULE_FIELDLINESSEQUENCE___KAMELEONFIELDLINEHELPER___H__ \ No newline at end of file +#endif // __OPENSPACE_MODULE_FIELDLINESSEQUENCE___KAMELEONFIELDLINEHELPER___H__ diff --git a/modules/globebrowsing/rendering/layer/layer.cpp b/modules/globebrowsing/rendering/layer/layer.cpp index 1034cd385c..7a970cf579 100644 --- a/modules/globebrowsing/rendering/layer/layer.cpp +++ b/modules/globebrowsing/rendering/layer/layer.cpp @@ -1,4 +1,4 @@ -/***************************************************************************************** +/***************************************************************************************** * * * OpenSpace * * * diff --git a/src/engine/configurationmanager_doc.inl b/src/engine/configurationmanager_doc.inl index 5d13ee7742..561bd447e7 100644 --- a/src/engine/configurationmanager_doc.inl +++ b/src/engine/configurationmanager_doc.inl @@ -1,4 +1,4 @@ -/***************************************************************************************** +/***************************************************************************************** * * * OpenSpace * * * diff --git a/support/coding/check_style_guide.py b/support/coding/check_style_guide.py index a2c6d9705e..048bf311c4 100644 --- a/support/coding/check_style_guide.py +++ b/support/coding/check_style_guide.py @@ -310,7 +310,7 @@ def check_line_length(lines): previousSymbols = {} def check_header_file(file, component): - with open(file, 'r+') as f: + with open(file, 'r+', encoding="utf8") as f: lines = f.readlines() correctness = check_correctness(lines) From afa1d6d33edf4eaa62bd629721d5a6d5135e3739 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Thu, 9 Nov 2017 23:47:51 -0500 Subject: [PATCH 39/39] Add strict test for whitespace at end of line More work on coding style --- apps/OpenSpace/main.cpp | 4 +- apps/TimelineView/main.cpp | 2 +- apps/TimelineView/timelinewidget.h | 2 +- ext/ghoul | 2 +- .../openspace/documentation/documentation.h | 8 +- .../documentation/documentationengine.h | 2 +- .../documentation/documentationgenerator.h | 8 +- include/openspace/documentation/verifier.h | 14 +- include/openspace/documentation/verifier.inl | 2 +- include/openspace/engine/moduleengine.h | 2 +- include/openspace/engine/syncengine.h | 4 +- .../openspace/engine/wrapper/windowwrapper.h | 7 +- .../openspace/interaction/keybindingmanager.h | 2 +- include/openspace/interaction/mousestate.h | 2 +- .../openspace/interaction/navigationhandler.h | 6 +- .../openspace/interaction/orbitalnavigator.h | 6 +- include/openspace/mission/mission.h | 2 +- include/openspace/mission/missionmanager.h | 8 +- include/openspace/network/messagestructures.h | 2 +- .../properties/numericalproperty.inl | 2 +- include/openspace/properties/optionproperty.h | 4 +- include/openspace/properties/property.h | 8 +- include/openspace/properties/propertyowner.h | 4 +- .../properties/scalar/boolproperty.h | 4 +- .../properties/scalar/charproperty.h | 4 +- .../properties/scalar/doubleproperty.h | 4 +- .../properties/scalar/floatproperty.h | 4 +- .../openspace/properties/scalar/intproperty.h | 4 +- .../properties/scalar/longdoubleproperty.h | 4 +- .../properties/scalar/longlongproperty.h | 4 +- .../properties/scalar/longproperty.h | 4 +- .../properties/scalar/shortproperty.h | 4 +- .../properties/scalar/signedcharproperty.h | 4 +- .../properties/scalar/ucharproperty.h | 4 +- .../properties/scalar/uintproperty.h | 4 +- .../properties/scalar/ulonglongproperty.h | 4 +- .../properties/scalar/ulongproperty.h | 4 +- .../properties/scalar/ushortproperty.h | 4 +- .../properties/scalar/wcharproperty.h | 4 +- .../openspace/properties/triggerproperty.h | 2 +- include/openspace/rendering/abufferrenderer.h | 2 +- include/openspace/rendering/renderable.h | 2 +- .../rendering/screenspacerenderable.h | 4 +- include/openspace/rendering/volume.h | 12 +- include/openspace/rendering/volumeraycaster.h | 10 +- include/openspace/scripting/scriptscheduler.h | 8 +- include/openspace/util/concurrentjobmanager.h | 2 +- include/openspace/util/gpudata.h | 8 +- include/openspace/util/histogram.h | 4 +- include/openspace/util/openspacemodule.h | 2 +- include/openspace/util/spicemanager.h | 8 +- include/openspace/util/syncdata.h | 12 +- include/openspace/util/threadpool.h | 2 +- include/openspace/util/time.h | 8 +- include/openspace/util/timerange.h | 2 +- modules/base/rendering/multimodelgeometry.cpp | 2 +- modules/base/rendering/renderablemodel.cpp | 2 +- modules/base/rendering/renderablemodel.h | 2 +- modules/base/rendering/renderableplane.cpp | 4 +- modules/base/rendering/renderabletrail.h | 10 +- .../base/rendering/renderabletrailorbit.cpp | 10 +- modules/base/rendering/renderabletrailorbit.h | 2 +- .../base/rendering/screenspaceframebuffer.cpp | 2 +- modules/base/rendering/wavefrontgeometry.cpp | 2 +- modules/base/translation/luatranslation.cpp | 4 +- modules/debugging/debuggingmodule.cpp | 2 +- modules/debugging/rendering/debugrenderer.cpp | 6 +- modules/debugging/rendering/debugrenderer.h | 10 +- .../rendering/renderablepoints.cpp | 12 +- .../rendering/renderablepoints.h | 4 +- .../rendering/renderablefieldlines.cpp | 4 +- modules/galaxy/rendering/renderablegalaxy.cpp | 2 +- .../galaxy/tasks/milkywayconversiontask.cpp | 2 +- modules/globebrowsing/chunk/chunk.cpp | 8 +- modules/globebrowsing/chunk/chunk.h | 2 +- .../projectedareaevaluator.cpp | 14 +- modules/globebrowsing/chunk/chunknode.cpp | 4 +- .../chunk/culling/horizonculler.cpp | 2 +- modules/globebrowsing/geometry/angle.h | 4 +- modules/globebrowsing/geometry/angle.inl | 2 +- modules/globebrowsing/geometry/ellipsoid.cpp | 2 +- .../globebrowsing/geometry/geodeticpatch.cpp | 34 +- .../globebrowsing/geometry/geodeticpatch.h | 2 +- .../globebrowsing/globes/chunkedlodglobe.cpp | 2 +- .../globebrowsing/globes/chunkedlodglobe.h | 2 +- modules/globebrowsing/globes/pointglobe.cpp | 4 +- .../globebrowsing/globes/renderableglobe.cpp | 8 +- .../globebrowsing/globes/renderableglobe.h | 4 +- modules/globebrowsing/meshes/basicgrid.h | 2 +- modules/globebrowsing/meshes/grid.h | 2 +- modules/globebrowsing/other/distanceswitch.h | 4 +- modules/globebrowsing/other/lruthreadpool.h | 2 +- modules/globebrowsing/other/pixelbuffer.h | 2 +- .../globebrowsing/rendering/chunkrenderer.cpp | 2 +- .../rendering/gpu/gpuchunktile.h | 8 +- .../rendering/gpu/gpuchunktilepile.h | 8 +- .../rendering/gpu/gpuheightlayer.h | 6 +- .../globebrowsing/rendering/gpu/gpulayer.h | 6 +- .../rendering/gpu/gpulayergroup.cpp | 2 +- .../rendering/gpu/gpulayergroup.h | 6 +- .../rendering/gpu/gpulayermanager.cpp | 2 +- .../rendering/gpu/gpulayermanager.h | 6 +- .../rendering/gpu/gpulayerrendersettings.h | 6 +- .../rendering/gpu/gputiledepthtransform.h | 8 +- .../rendering/gpu/gputileuvtransform.h | 8 +- .../globebrowsing/rendering/layer/layer.cpp | 4 +- modules/globebrowsing/tile/pixelregion.cpp | 18 +- modules/globebrowsing/tile/pixelregion.h | 2 +- .../gdalrawtiledatareader.cpp | 4 +- .../rawtiledatareader/gdalrawtiledatareader.h | 4 +- .../rawtiledatareader/rawtiledatareader.cpp | 34 +- .../tile/rawtiledatareader/tiledatatype.cpp | 14 +- modules/globebrowsing/tile/tileindex.cpp | 2 +- modules/globebrowsing/tile/tileloadjob.h | 2 +- .../tile/tileprovider/defaulttileprovider.cpp | 4 +- .../tile/tileprovider/defaulttileprovider.h | 8 +- .../tileprovider/temporaltileprovider.cpp | 8 +- .../tile/tileprovider/temporaltileprovider.h | 46 +- .../tile/tileprovider/texttileprovider.h | 14 +- .../tile/tileprovider/tileprovider.cpp | 6 +- .../tile/tileprovider/tileprovider.h | 38 +- modules/imgui/src/gui.cpp | 12 +- modules/imgui/src/guipropertycomponent.cpp | 2 +- modules/imgui/src/guispacetimecomponent.cpp | 4 +- modules/iswa/rendering/datacygnet.cpp | 12 +- modules/iswa/rendering/datacygnet.h | 4 +- modules/iswa/rendering/dataplane.cpp | 6 +- modules/iswa/rendering/dataplane.h | 2 +- modules/iswa/rendering/datasphere.cpp | 4 +- modules/iswa/rendering/datasphere.h | 4 +- modules/iswa/rendering/iswabasegroup.cpp | 12 +- modules/iswa/rendering/iswacygnet.h | 4 +- modules/iswa/rendering/iswadatagroup.cpp | 6 +- modules/iswa/rendering/kameleonplane.cpp | 10 +- modules/iswa/rendering/kameleonplane.h | 12 +- modules/iswa/rendering/texturecygnet.cpp | 11 +- modules/iswa/rendering/texturecygnet.h | 2 +- modules/iswa/rendering/textureplane.h | 2 +- modules/iswa/util/dataprocessor.cpp | 16 +- modules/iswa/util/dataprocessor.h | 2 +- modules/iswa/util/dataprocessorjson.cpp | 9 +- modules/iswa/util/dataprocessorkameleon.cpp | 8 +- modules/iswa/util/dataprocessortext.cpp | 14 +- modules/iswa/util/iswamanager.cpp | 26 +- modules/iswa/util/iswamanager.h | 2 +- modules/iswa/util/iswamanager_lua.inl | 8 +- .../rendering/renderablekameleonvolume.cpp | 27 +- .../tasks/kameleondocumentationtask.cpp | 30 +- modules/space/rendering/renderableplanet.cpp | 14 +- modules/space/rendering/renderableplanet.h | 2 +- modules/space/rendering/renderablestars.cpp | 2 +- .../space/translation/keplertranslation.cpp | 2 +- modules/space/translation/tletranslation.h | 2 +- .../rendering/renderablecrawlingline.cpp | 4 +- .../rendering/renderablefov.cpp | 20 +- .../rendering/renderablefov.h | 2 +- .../rendering/renderablemodelprojection.h | 2 +- .../rendering/renderableplaneprojection.cpp | 6 +- .../rendering/renderableplanetprojection.cpp | 10 +- .../util/hongkangparser.cpp | 22 +- .../util/hongkangparser.h | 2 +- .../util/imagesequencer.cpp | 149 ++-- .../util/imagesequencer.h | 54 +- .../util/instrumenttimesparser.cpp | 2 +- .../util/labelparser.cpp | 13 +- .../spacecraftinstruments/util/labelparser.h | 6 +- .../util/projectioncomponent.cpp | 2 +- .../util/projectioncomponent.h | 2 +- modules/touch/include/touchinteraction.h | 16 +- modules/touch/src/touchinteraction.cpp | 711 ++++++++++++------ modules/touch/src/touchmarker.cpp | 38 +- modules/touch/src/tuioear.cpp | 8 +- modules/touch/touchmodule.cpp | 38 +- .../rendering/renderabletoyvolume.cpp | 62 +- .../rendering/toyvolumeraycaster.cpp | 12 +- .../toyvolume/rendering/toyvolumeraycaster.h | 2 +- modules/volume/rawvolumewriter.h | 4 +- modules/volume/rawvolumewriter.inl | 2 +- .../volume/rendering/basicvolumeraycaster.h | 4 +- modules/volume/rendering/volumeclipplanes.cpp | 2 +- modules/volume/volumeutils.cpp | 2 +- src/documentation/documentation.cpp | 2 +- src/documentation/documentationgenerator.cpp | 2 +- src/documentation/verifier.cpp | 2 +- src/engine/downloadmanager.cpp | 2 +- src/engine/openspaceengine.cpp | 4 +- src/engine/syncengine.cpp | 2 +- src/engine/wrapper/sgctwindowwrapper.cpp | 2 +- src/interaction/navigationhandler.cpp | 2 +- src/interaction/orbitalnavigator.cpp | 8 +- src/mission/mission.cpp | 4 +- src/network/networkengine.cpp | 4 +- src/network/parallelconnection.cpp | 2 +- src/properties/matrix/dmat2property.cpp | 2 +- src/properties/matrix/dmat2x3property.cpp | 2 +- src/properties/matrix/dmat2x4property.cpp | 2 +- src/properties/matrix/dmat3property.cpp | 4 +- src/properties/matrix/dmat3x2property.cpp | 2 +- src/properties/matrix/dmat3x4property.cpp | 4 +- src/properties/matrix/dmat4property.cpp | 6 +- src/properties/matrix/dmat4x2property.cpp | 2 +- src/properties/matrix/dmat4x3property.cpp | 4 +- src/properties/matrix/mat3x4property.cpp | 4 +- src/properties/matrix/mat4property.cpp | 6 +- src/properties/matrix/mat4x2property.cpp | 2 +- src/properties/matrix/mat4x3property.cpp | 4 +- src/properties/property.cpp | 2 +- src/rendering/abufferrenderer.cpp | 10 +- src/rendering/framebufferrenderer.cpp | 2 +- src/rendering/renderengine.cpp | 6 +- src/rendering/screenspacerenderable.cpp | 4 +- src/scene/rotation.cpp | 2 +- src/scene/scene_doc.inl | 2 +- src/scene/scene_lua.inl | 2 +- src/scripting/scriptengine_lua.inl | 8 +- src/scripting/scriptscheduler.cpp | 4 +- src/util/openspacemodule.cpp | 2 +- src/util/progressbar.cpp | 2 +- src/util/spicemanager.cpp | 12 +- src/util/time.cpp | 2 +- src/util/timerange.cpp | 4 +- src/util/transformationmanager.cpp | 2 +- support/coding/check_style_guide.py | 28 +- 223 files changed, 1402 insertions(+), 961 deletions(-) diff --git a/apps/OpenSpace/main.cpp b/apps/OpenSpace/main.cpp index 61d991897a..986a1908fc 100644 --- a/apps/OpenSpace/main.cpp +++ b/apps/OpenSpace/main.cpp @@ -268,7 +268,7 @@ void mainInitFunc() { const sgct::SGCTWindow::StereoMode sm = windowPtr->getStereoMode(); const bool hasStereo = - (sm != sgct::SGCTWindow::No_Stereo) && + (sm != sgct::SGCTWindow::No_Stereo) && (sm < sgct::SGCTWindow::Side_By_Side_Stereo); if (hasStereo) { @@ -624,7 +624,7 @@ int main_main(int argc, char** argv) { cleanup(); // Exit program - exit(EXIT_SUCCESS); + exit(EXIT_SUCCESS); } } // namespace diff --git a/apps/TimelineView/main.cpp b/apps/TimelineView/main.cpp index 420f02fcd7..6add883ca7 100644 --- a/apps/TimelineView/main.cpp +++ b/apps/TimelineView/main.cpp @@ -112,7 +112,7 @@ QCombobox { } QComboBox:editable { - background: lightgrey; + background: lightgrey; } QComboBox QAbstractItemView { diff --git a/apps/TimelineView/timelinewidget.h b/apps/TimelineView/timelinewidget.h index 3ad24c33b5..ca0618f065 100644 --- a/apps/TimelineView/timelinewidget.h +++ b/apps/TimelineView/timelinewidget.h @@ -48,7 +48,7 @@ public: std::string nextTarget() const; protected: - void paintEvent(QPaintEvent* event); + void paintEvent(QPaintEvent* event); void drawContent(QPainter& painter, QRectF rect); void drawLegend(QPainter& painter, QRectF rect); void drawImages(QPainter& painter, QRectF timelineRect, std::vector images, double minimumTime, double maximumTime); diff --git a/ext/ghoul b/ext/ghoul index a6244a16f9..4dce717aac 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit a6244a16f98687c9196c4ba8ced11a3d68a88b46 +Subproject commit 4dce717aac293edd8662d03cc336da355c797343 diff --git a/include/openspace/documentation/documentation.h b/include/openspace/documentation/documentation.h index c82ba9ac90..82cfcde267 100644 --- a/include/openspace/documentation/documentation.h +++ b/include/openspace/documentation/documentation.h @@ -47,7 +47,7 @@ using Optional = ghoul::Boolean; struct TestResult { /** * An Offense is a violation against a specific verifier. The Offense::offender is the - * key that caused the offense (in the case of nested tables, it will be fully + * key that caused the offense (in the case of nested tables, it will be fully * qualified identifier) and the Offense::Reason is the reason that caused the * offense. */ @@ -142,8 +142,8 @@ struct DocumentationEntry { /** * The constructor for a DocumentationEntry describing a \p key in a Documentation. - * The value for the key (or each value in the case of the - * DocumentationEntry::Wildcard) is tested using the \p verifier, that specifies the + * The value for the key (or each value in the case of the + * DocumentationEntry::Wildcard) is tested using the \p verifier, that specifies the * conditions that the \p key%'s value has to fulfill. The textual documentation * \p doc shall describe the usage of the key-value pair and will be printed for human * consumption for example in the DocumentationEngine. Each DocumentationEntry can @@ -211,7 +211,7 @@ Documentation doc = { { // A list of DocumentationEntry%s; also specified using initializer lists { "key1", new IntVerifier, "Documentation key1", Optional::Yes }, { "key2", new FloatVerifier, "Documentation key2" }, - { "key3", new StringVerifier } + { "key3", new StringVerifier } } }; \endverbatim diff --git a/include/openspace/documentation/documentationengine.h b/include/openspace/documentation/documentationengine.h index 9e73e9f8c5..5d313a5ee8 100644 --- a/include/openspace/documentation/documentationengine.h +++ b/include/openspace/documentation/documentationengine.h @@ -62,7 +62,7 @@ public: DocumentationEngine(); /** - * Adds the \p documentation to the list of Documentation%s that are written to a + * Adds the \p documentation to the list of Documentation%s that are written to a * documentation file with the writeDocumentation method. * \param documentation The Documentation object that is to be stored for later use * \throws DuplicateDocumentationException If the \p documentation has a non-empty diff --git a/include/openspace/documentation/documentationgenerator.h b/include/openspace/documentation/documentationgenerator.h index ff51c29aba..430823c3f1 100644 --- a/include/openspace/documentation/documentationgenerator.h +++ b/include/openspace/documentation/documentationgenerator.h @@ -33,10 +33,10 @@ namespace openspace { /* * This abstract class is used for instances when another class has the ability to * generate a Handlebar generated documentation file that contains valuable information - * for the user. Instances of this are the DocumentationEngine results, the list of + * for the user. Instances of this are the DocumentationEngine results, the list of * Property%s generated by the Scene, or the FactoryEngine results. The documentation is * generated through the writeDocumentation method. - * + * * The concrete subclass needs to overload the generateJson class that will return the * Json that is parsed by Handlebar to generate the webpage. * @@ -57,7 +57,7 @@ public: * writeDocumentation method. * \param name The name of the written documentation * \param jsonName The variable name of the value generated by the generateJson - * \param handlebarTemplates A list of Handlebar templates that is added to the + * \param handlebarTemplates A list of Handlebar templates that is added to the * documentation file * \param javascriptFilename The path to a Javascript source file that is added to the * documentation and that can contain additional functionality @@ -76,7 +76,7 @@ public: /** * Create the documentation into the provided filename. Any existing file will be * silently overwritten. This method will call the generateJson method that can be - * used by concrete subclasses to provide the actual data that is provided in the + * used by concrete subclasses to provide the actual data that is provided in the * documentation. * \param filename The filename in which the documentation is written */ diff --git a/include/openspace/documentation/verifier.h b/include/openspace/documentation/verifier.h index 7c231d02e9..123f3ec1f3 100644 --- a/include/openspace/documentation/verifier.h +++ b/include/openspace/documentation/verifier.h @@ -61,7 +61,7 @@ struct Verifier { * \post If the return values' TestResult::success is \c true, its * TestResult::offenders is empty */ - virtual TestResult operator()(const ghoul::Dictionary& dictionary, + virtual TestResult operator()(const ghoul::Dictionary& dictionary, const std::string& key) const = 0; /** @@ -116,7 +116,7 @@ struct TemplateVerifier : public Verifier { }; /** - * A Verifier that checks whether a given key inside a ghoul::Dictionary is of type + * A Verifier that checks whether a given key inside a ghoul::Dictionary is of type * \c bool. No implicit conversion is considered in this testing. */ struct BoolVerifier : public TemplateVerifier { @@ -258,7 +258,7 @@ struct Vector4Verifier : public TemplateVerifier>, public VectorVe }; /** -* A Verifier that checks whether all values contained in a Table are of +* A Verifier that checks whether all values contained in a Table are of * type glm::tvec2 */ template @@ -627,7 +627,7 @@ struct InListVerifier : public T { * Tests whether the \p key exists in the \p dictionary, whether it has the correct * type by invoking the template parameter \c T, and then tests if the \p key's value * is part of the list passed to the constructor. - * \param dictionary The ghoul::Dictionary that contains the \p key + * \param dictionary The ghoul::Dictionary that contains the \p key * \param key The key that is contained in the \p dictionary and whose value is tested * \return A TestResult containing the results of the specification testing. If the * \p key%'s value has the wrong type, it will be added to the TestResult's offense @@ -688,7 +688,7 @@ struct NotInListVerifier : public T { * This Verifier checks whether the incoming value is of the correct type, using the * Verifier passed as a template parameter \c T and then checks whether it is greater or * equal to a lower limit and less or equal to a higher limit. To the missing comparison -* operators, \c T cannot be a subclass of (or the same as) BoolVerifier, StringVerifier, +* operators, \c T cannot be a subclass of (or the same as) BoolVerifier, StringVerifier, * TableVerifier, or VectorVerifier. Both the lower and the higher limit are inclusive). */ template @@ -890,7 +890,7 @@ struct ReferencingVerifier : public TableVerifier { std::string documentation() const override; - /// The identifier that references another Documentation registered with the + /// The identifier that references another Documentation registered with the /// DocumentationEngine std::string identifier; }; @@ -900,7 +900,7 @@ struct ReferencingVerifier : public TableVerifier { //---------------------------------------------------------------------------------------- /** - * This Verifier takes two Verifiers and performs a boolean \c and operation on their + * This Verifier takes two Verifiers and performs a boolean \c and operation on their * results. In essence, a value only passes this Verifier if it passes both Verifier%s * that are passed in the constructor. Opposed to the C++ && * operator, the AndVerifier does not perform any short-circut evaluation. diff --git a/include/openspace/documentation/verifier.inl b/include/openspace/documentation/verifier.inl index 9ace596fb3..012591802c 100644 --- a/include/openspace/documentation/verifier.inl +++ b/include/openspace/documentation/verifier.inl @@ -122,7 +122,7 @@ OperatorVerifier::OperatorVerifier(typename T::Type val) template TestResult OperatorVerifier::operator()(const ghoul::Dictionary& dict, - const std::string& key) const + const std::string& key) const { TestResult res = T::operator()(dict, key); if (res.success) { diff --git a/include/openspace/engine/moduleengine.h b/include/openspace/engine/moduleengine.h index 22b15f142f..2b750e31ab 100644 --- a/include/openspace/engine/moduleengine.h +++ b/include/openspace/engine/moduleengine.h @@ -68,7 +68,7 @@ public: * Registers the passed \p module with this ModuleEngine. The OpenSpaceModule::create * method will be called on the \p module in the process. * \param module The OpenSpaceModule that is to be registered - * \throw ghoul::RuntimeError If the name of the \p module was already registered + * \throw ghoul::RuntimeError If the name of the \p module was already registered * previously * \pre \p module must not be nullptr */ diff --git a/include/openspace/engine/syncengine.h b/include/openspace/engine/syncengine.h index a23dc78c22..847a80a5f6 100644 --- a/include/openspace/engine/syncengine.h +++ b/include/openspace/engine/syncengine.h @@ -51,7 +51,7 @@ public: SyncEngine(unsigned int syncBufferSize); /** - * Encodes all added Syncables in the injected SyncBuffer. + * Encodes all added Syncables in the injected SyncBuffer. * This method is only called on the SGCT master node */ void encodeSyncables(); @@ -95,7 +95,7 @@ public: void removeSyncables(const std::vector& syncables); private: - /** + /** * Vector of Syncables. The vectors ensures consistent encode/decode order */ std::vector _syncables; diff --git a/include/openspace/engine/wrapper/windowwrapper.h b/include/openspace/engine/wrapper/windowwrapper.h index 2498addbfd..ea290776d3 100644 --- a/include/openspace/engine/wrapper/windowwrapper.h +++ b/include/openspace/engine/wrapper/windowwrapper.h @@ -125,7 +125,7 @@ public: * is 1 if mouse button i is pressed down; * false otherwise. On default, this method returns that none of the * buttons is pressed. - * \param maxNumber The maximum number of mouse buttons that should be queried + * \param maxNumber The maximum number of mouse buttons that should be queried * \return A bitmask showing the status of all mouse buttons (up to \p maxNumber) */ virtual uint32_t mouseButtons(int maxNumber = 8) const; @@ -201,8 +201,9 @@ public: virtual bool isUsingSwapGroups() const; /** - * Returns true if the current rendering window is master of the swap its group. - */ + * Returns true if the current rendering window is master of the swap its + * group. + */ virtual bool isSwapGroupMaster() const; /** diff --git a/include/openspace/interaction/keybindingmanager.h b/include/openspace/interaction/keybindingmanager.h index 8682fecc6a..7426610a99 100644 --- a/include/openspace/interaction/keybindingmanager.h +++ b/include/openspace/interaction/keybindingmanager.h @@ -61,7 +61,7 @@ public: static scripting::LuaLibrary luaLibrary(); - // Callback functions + // Callback functions void keyboardCallback(Key key, KeyModifier modifier, KeyAction action); private: diff --git a/include/openspace/interaction/mousestate.h b/include/openspace/interaction/mousestate.h index 7db9a94d53..5d39ef7bad 100644 --- a/include/openspace/interaction/mousestate.h +++ b/include/openspace/interaction/mousestate.h @@ -46,7 +46,7 @@ public: /** * \param sensitivity * \param velocityScaleFactor can be set to 60 to remove the inertia of the - * interaction. Lower value will make it harder to move the camera. + * interaction. Lower value will make it harder to move the camera. */ MouseStates(double sensitivity, double velocityScaleFactor); void updateMouseStatesFromInput(const InputState& inputState, double deltaTime); diff --git a/include/openspace/interaction/navigationhandler.h b/include/openspace/interaction/navigationhandler.h index 6e8d4fad76..d09966ce4e 100644 --- a/include/openspace/interaction/navigationhandler.h +++ b/include/openspace/interaction/navigationhandler.h @@ -57,7 +57,7 @@ public: void setCamera(Camera* camera); void resetCameraDirection(); - void setCameraStateFromDictionary(const ghoul::Dictionary& cameraDict); + void setCameraStateFromDictionary(const ghoul::Dictionary& cameraDict); void updateCamera(double deltaTime); @@ -69,9 +69,9 @@ public: Camera* camera() const; const InputState& inputState() const; const OrbitalNavigator& orbitalNavigator() const; - KeyframeNavigator& keyframeNavigator() const; + KeyframeNavigator& keyframeNavigator() const; - // Callback functions + // Callback functions void keyboardCallback(Key key, KeyModifier modifier, KeyAction action); void mouseButtonCallback(MouseButton button, MouseAction action); void mousePositionCallback(double x, double y); diff --git a/include/openspace/interaction/orbitalnavigator.h b/include/openspace/interaction/orbitalnavigator.h index 8a99f752e6..3887023cde 100644 --- a/include/openspace/interaction/orbitalnavigator.h +++ b/include/openspace/interaction/orbitalnavigator.h @@ -55,7 +55,7 @@ public: void setFocusNode(SceneGraphNode* focusNode); void startInterpolateCameraDirection(const Camera& camera); - bool followingNodeRotation() const; + bool followingNodeRotation() const; SceneGraphNode* focusNode() const; bool hasRotationalFriction() const; @@ -99,7 +99,7 @@ private: * camera points towards the focus node in the direction opposite to the direction * out from the surface of the object. The local rotation defines the differential * from the global to the current total rotation so that - * cameraRotation = globalRotation * localRotation. + * cameraRotation = globalRotation * localRotation. */ CameraRotationDecomposition decomposeCameraRotation(const glm::dvec3& cameraPosition, const glm::dquat& cameraRotation, const glm::dvec3& cameraLookUp, @@ -139,7 +139,7 @@ private: /* * Adds rotation to the camera position so that it follows the rotation of the focus - * node defined by the differential focusNodeRotationDiff. + * node defined by the differential focusNodeRotationDiff. * \returns a position updated with the rotation defined by focusNodeRotationDiff */ glm::dvec3 followFocusNodeRotation(const glm::dvec3& cameraPosition, diff --git a/include/openspace/mission/mission.h b/include/openspace/mission/mission.h index a7036bfb44..7dfb165522 100644 --- a/include/openspace/mission/mission.h +++ b/include/openspace/mission/mission.h @@ -41,7 +41,7 @@ namespace documentation { struct Documentation; } * Used to represent a named period of time within a mission. Allows nested phases, i.e. * phases within phases. Designed for WORM usage (Write Once, Read Multiple), and, * therefore, has only accessors. - * + * * Each MissionPhase is characterized by its MissionPhase::name, a TimeRange, an * optional MissionPhase::description, and optional subphases. */ diff --git a/include/openspace/mission/missionmanager.h b/include/openspace/mission/missionmanager.h index 2d31f89ba4..06dae81df3 100644 --- a/include/openspace/mission/missionmanager.h +++ b/include/openspace/mission/missionmanager.h @@ -38,7 +38,7 @@ namespace openspace { namespace scripting { struct LuaLibrary; } /** -* Singleton class keeping track of space missions. +* Singleton class keeping track of space missions. */ class MissionManager : public ghoul::Singleton { public: @@ -50,7 +50,7 @@ public: /** * Reads a mission from file and maps the mission name to the Mission object. If - * this is the first mission to be loaded, the mission will also be set as the + * this is the first mission to be loaded, the mission will also be set as the * current active mission. * \pre \p filename must not be empty * \pre \p filename must not contain tokens @@ -79,8 +79,8 @@ public: bool hasCurrentMission() const; /** - * Returns the latest mission specified to `setCurrentMission()`. If no mission has - * been specified, the first mission loaded will be returned. If no mission has been + * Returns the latest mission specified to `setCurrentMission()`. If no mission has + * been specified, the first mission loaded will be returned. If no mission has been * loaded, a warning will be printed and a dummy mission will be returned. */ const Mission& currentMission(); diff --git a/include/openspace/network/messagestructures.h b/include/openspace/network/messagestructures.h index eb3c9eea09..6d7c3d5d6a 100644 --- a/include/openspace/network/messagestructures.h +++ b/include/openspace/network/messagestructures.h @@ -94,7 +94,7 @@ struct CameraKeyframe { // Focus node int nodeNameLength; size = sizeof(int); - memcpy(&nodeNameLength, buffer.data() + offset, size); + memcpy(&nodeNameLength, buffer.data() + offset, size); offset += size; size = nodeNameLength; _focusNode = std::string(buffer.data() + offset, buffer.data() + offset + size); diff --git a/include/openspace/properties/numericalproperty.inl b/include/openspace/properties/numericalproperty.inl index 39a4ea2cf9..3a64404e31 100644 --- a/include/openspace/properties/numericalproperty.inl +++ b/include/openspace/properties/numericalproperty.inl @@ -231,7 +231,7 @@ const std::string NumericalProperty::SteppingValueKey = "SteppingValue"; // Delegating constructors are necessary; automatic template deduction cannot // deduce template argument for 'U' if 'default' methods are used as default values in -// a single constructor +// a single constructor template NumericalProperty::NumericalProperty(Property::PropertyInfo info) diff --git a/include/openspace/properties/optionproperty.h b/include/openspace/properties/optionproperty.h index b465c33039..cb87fc2532 100644 --- a/include/openspace/properties/optionproperty.h +++ b/include/openspace/properties/optionproperty.h @@ -32,7 +32,7 @@ namespace openspace::properties { /** - * The OptionProperty is a property that provides a number of predefined (using the + * The OptionProperty is a property that provides a number of predefined (using the * addOption method) options consisting of a description and a * value. The available options can be queried using the options method. * Only values representing valid options can be used to set this property, or an error @@ -119,7 +119,7 @@ public: /** * Get the description of the option that matches value - * \param value The value of the option + * \param value The value of the option */ std::string getDescriptionByValue(int value); diff --git a/include/openspace/properties/property.h b/include/openspace/properties/property.h index 83301f87d1..da89a1c809 100644 --- a/include/openspace/properties/property.h +++ b/include/openspace/properties/property.h @@ -88,7 +88,7 @@ public: Visibility visibility = Visibility::All; }; - /// An OnChangeHandle is returned by the onChange method to uniquely identify an + /// An OnChangeHandle is returned by the onChange method to uniquely identify an /// onChange callback using OnChangeHandle = uint32_t; @@ -102,7 +102,7 @@ public: * to be accessed by the GUI elements using the guiName key. The default * visibility settings is Visibility::All, whereas the default read-only state is * false. - * \param info The PropertyInfo structure that contains all the required static + * \param info The PropertyInfo structure that contains all the required static * information for initializing this Property. * \pre \p info.identifier must not be empty * \pre \p info.guiName must not be empty @@ -399,7 +399,7 @@ protected: * generateAdditionalDescription()}, which #generateMetaDataDescription * and this method being the override points to customize the behavior. * \return The information specific to each subclass of Property - */ + */ virtual std::string generateAdditionalDescription() const; /** @@ -409,7 +409,7 @@ protected: void notifyListener(); /// The PropetyOwner this Property belongs to, or nullptr - PropertyOwner* _owner; + PropertyOwner* _owner; /// The identifier for this Property std::string _identifier; diff --git a/include/openspace/properties/propertyowner.h b/include/openspace/properties/propertyowner.h index c0f8bc8914..1720a2e90a 100644 --- a/include/openspace/properties/propertyowner.h +++ b/include/openspace/properties/propertyowner.h @@ -39,7 +39,7 @@ class Property; * sub-owners must be unique to this PropertyOwner. A Property cannot have the same name * as a PropertyOwner owned by this PropertyOwner. * Propertys can be added using the Property::addProperty methods and be removed by the - * Property::removeProperty method. The same holds true for sub-owners + * Property::removeProperty method. The same holds true for sub-owners * (Property::addPropertySubOwner, Property::removePropertySubOwner). These methods will * inform the passed object about the new ownership automatically. * Stored properties can be accessed using the Property::properties method or the @@ -231,7 +231,7 @@ public: void addTag(std::string tag); /** - * Removes a tag from this PropertyOwner. No error is reported if the tag does not + * Removes a tag from this PropertyOwner. No error is reported if the tag does not * exist * @param tag The tag is that is to be removed from this PropertyOwner */ diff --git a/include/openspace/properties/scalar/boolproperty.h b/include/openspace/properties/scalar/boolproperty.h index ee74bbfcf8..d38576b698 100644 --- a/include/openspace/properties/scalar/boolproperty.h +++ b/include/openspace/properties/scalar/boolproperty.h @@ -28,9 +28,9 @@ /** * \file boolproperty.h * - * \addtogroup openspace + * \addtogroup openspace * @{ - * \addtogroup properties + * \addtogroup properties * @{ * \class BoolProperty diff --git a/include/openspace/properties/scalar/charproperty.h b/include/openspace/properties/scalar/charproperty.h index 3151c53ebe..f1178e42a1 100644 --- a/include/openspace/properties/scalar/charproperty.h +++ b/include/openspace/properties/scalar/charproperty.h @@ -28,9 +28,9 @@ /** * \file charproperty.h * - * \addtogroup openspace + * \addtogroup openspace * @{ - * \addtogroup properties + * \addtogroup properties * @{ * \class CharProperty diff --git a/include/openspace/properties/scalar/doubleproperty.h b/include/openspace/properties/scalar/doubleproperty.h index 0ef4ed259c..4ac78f8602 100644 --- a/include/openspace/properties/scalar/doubleproperty.h +++ b/include/openspace/properties/scalar/doubleproperty.h @@ -28,9 +28,9 @@ /** * \file doubleproperty.h * - * \addtogroup openspace + * \addtogroup openspace * @{ - * \addtogroup properties + * \addtogroup properties * @{ * \class DoubleProperty diff --git a/include/openspace/properties/scalar/floatproperty.h b/include/openspace/properties/scalar/floatproperty.h index bf7957d4f0..838521aa3f 100644 --- a/include/openspace/properties/scalar/floatproperty.h +++ b/include/openspace/properties/scalar/floatproperty.h @@ -28,9 +28,9 @@ /** * \file floatproperty.h * - * \addtogroup openspace + * \addtogroup openspace * @{ - * \addtogroup properties + * \addtogroup properties * @{ * \class FloatProperty diff --git a/include/openspace/properties/scalar/intproperty.h b/include/openspace/properties/scalar/intproperty.h index b0fbdd9acb..43214ce1c8 100644 --- a/include/openspace/properties/scalar/intproperty.h +++ b/include/openspace/properties/scalar/intproperty.h @@ -28,9 +28,9 @@ /** * \file intproperty.h * - * \addtogroup openspace + * \addtogroup openspace * @{ - * \addtogroup properties + * \addtogroup properties * @{ * \class IntProperty diff --git a/include/openspace/properties/scalar/longdoubleproperty.h b/include/openspace/properties/scalar/longdoubleproperty.h index f02ac8f44f..72455378ee 100644 --- a/include/openspace/properties/scalar/longdoubleproperty.h +++ b/include/openspace/properties/scalar/longdoubleproperty.h @@ -28,9 +28,9 @@ /** * \file longdoubleproperty.h * - * \addtogroup openspace + * \addtogroup openspace * @{ - * \addtogroup properties + * \addtogroup properties * @{ * \class LongDoubleProperty diff --git a/include/openspace/properties/scalar/longlongproperty.h b/include/openspace/properties/scalar/longlongproperty.h index d8f86f3351..645c0cd54d 100644 --- a/include/openspace/properties/scalar/longlongproperty.h +++ b/include/openspace/properties/scalar/longlongproperty.h @@ -28,9 +28,9 @@ /** * \file longlongproperty.h * - * \addtogroup openspace + * \addtogroup openspace * @{ - * \addtogroup properties + * \addtogroup properties * @{ * \class LongLongProperty diff --git a/include/openspace/properties/scalar/longproperty.h b/include/openspace/properties/scalar/longproperty.h index 85576f258c..0adfbf881c 100644 --- a/include/openspace/properties/scalar/longproperty.h +++ b/include/openspace/properties/scalar/longproperty.h @@ -28,9 +28,9 @@ /** * \file longproperty.h * - * \addtogroup openspace + * \addtogroup openspace * @{ - * \addtogroup properties + * \addtogroup properties * @{ * \class LongProperty diff --git a/include/openspace/properties/scalar/shortproperty.h b/include/openspace/properties/scalar/shortproperty.h index 90cb81af0c..93cae8a937 100644 --- a/include/openspace/properties/scalar/shortproperty.h +++ b/include/openspace/properties/scalar/shortproperty.h @@ -28,9 +28,9 @@ /** * \file shortproperty.h * - * \addtogroup openspace + * \addtogroup openspace * @{ - * \addtogroup properties + * \addtogroup properties * @{ * \class ShortProperty diff --git a/include/openspace/properties/scalar/signedcharproperty.h b/include/openspace/properties/scalar/signedcharproperty.h index fae4a5e2ed..3b45631b6d 100644 --- a/include/openspace/properties/scalar/signedcharproperty.h +++ b/include/openspace/properties/scalar/signedcharproperty.h @@ -28,9 +28,9 @@ /** * \file signedcharproperty.h * - * \addtogroup openspace + * \addtogroup openspace * @{ - * \addtogroup properties + * \addtogroup properties * @{ * \class SignedCharProperty diff --git a/include/openspace/properties/scalar/ucharproperty.h b/include/openspace/properties/scalar/ucharproperty.h index 04f799179a..55f3cc5da3 100644 --- a/include/openspace/properties/scalar/ucharproperty.h +++ b/include/openspace/properties/scalar/ucharproperty.h @@ -28,9 +28,9 @@ /** * \file ucharproperty.h * - * \addtogroup openspace + * \addtogroup openspace * @{ - * \addtogroup properties + * \addtogroup properties * @{ * \class UCharProperty diff --git a/include/openspace/properties/scalar/uintproperty.h b/include/openspace/properties/scalar/uintproperty.h index bb3b346a40..43b3debcbc 100644 --- a/include/openspace/properties/scalar/uintproperty.h +++ b/include/openspace/properties/scalar/uintproperty.h @@ -28,9 +28,9 @@ /** * \file uintproperty.h * - * \addtogroup openspace + * \addtogroup openspace * @{ - * \addtogroup properties + * \addtogroup properties * @{ * \class UIntProperty diff --git a/include/openspace/properties/scalar/ulonglongproperty.h b/include/openspace/properties/scalar/ulonglongproperty.h index b0b36b5eb3..e571fcf1f9 100644 --- a/include/openspace/properties/scalar/ulonglongproperty.h +++ b/include/openspace/properties/scalar/ulonglongproperty.h @@ -28,9 +28,9 @@ /** * \file ulonglongproperty.h * - * \addtogroup openspace + * \addtogroup openspace * @{ - * \addtogroup properties + * \addtogroup properties * @{ * \class ULongLongProperty diff --git a/include/openspace/properties/scalar/ulongproperty.h b/include/openspace/properties/scalar/ulongproperty.h index 8372f62938..e27839dc75 100644 --- a/include/openspace/properties/scalar/ulongproperty.h +++ b/include/openspace/properties/scalar/ulongproperty.h @@ -28,9 +28,9 @@ /** * \file ulongproperty.h * - * \addtogroup openspace + * \addtogroup openspace * @{ - * \addtogroup properties + * \addtogroup properties * @{ * \class ULongProperty diff --git a/include/openspace/properties/scalar/ushortproperty.h b/include/openspace/properties/scalar/ushortproperty.h index 10fac45e29..15a0acb3c8 100644 --- a/include/openspace/properties/scalar/ushortproperty.h +++ b/include/openspace/properties/scalar/ushortproperty.h @@ -28,9 +28,9 @@ /** * \file ushortproperty.h * - * \addtogroup openspace + * \addtogroup openspace * @{ - * \addtogroup properties + * \addtogroup properties * @{ * \class UShortProperty diff --git a/include/openspace/properties/scalar/wcharproperty.h b/include/openspace/properties/scalar/wcharproperty.h index d9b2ca546a..73683b857d 100644 --- a/include/openspace/properties/scalar/wcharproperty.h +++ b/include/openspace/properties/scalar/wcharproperty.h @@ -28,9 +28,9 @@ /** * \file wcharproperty.h * - * \addtogroup openspace + * \addtogroup openspace * @{ - * \addtogroup properties + * \addtogroup properties * @{ * \class WCharProperty diff --git a/include/openspace/properties/triggerproperty.h b/include/openspace/properties/triggerproperty.h index 3ddb7619c4..089f579536 100644 --- a/include/openspace/properties/triggerproperty.h +++ b/include/openspace/properties/triggerproperty.h @@ -54,7 +54,7 @@ public: /** * Accepts only the LUA_TNIL type and will notify all the listeners * that the event has been triggered. - * \param state The unused Lua state + * \param state The unused Lua state * \return Returns always true */ bool setLuaValue(lua_State* state) override; diff --git a/include/openspace/rendering/abufferrenderer.h b/include/openspace/rendering/abufferrenderer.h index 5a1a7becdf..ce9c356e47 100644 --- a/include/openspace/rendering/abufferrenderer.h +++ b/include/openspace/rendering/abufferrenderer.h @@ -109,7 +109,7 @@ private: * The _volumes map keeps track of which volumes that can * be rendered using the current resolve program, along with their raycast data * (id, namespace, etc) - */ + */ std::map _raycastData; std::map> _boundsPrograms; std::vector _helperPaths; diff --git a/include/openspace/rendering/renderable.h b/include/openspace/rendering/renderable.h index 57b89d29e2..bef7b25d43 100644 --- a/include/openspace/rendering/renderable.h +++ b/include/openspace/rendering/renderable.h @@ -42,7 +42,7 @@ struct UpdateData; struct RendererTasks; struct SurfacePositionHandle; -namespace documentation { struct Documentation; } +namespace documentation { struct Documentation; } // Forward declare to minimize dependencies diff --git a/include/openspace/rendering/screenspacerenderable.h b/include/openspace/rendering/screenspacerenderable.h index 7db38d281e..1c912c0c83 100644 --- a/include/openspace/rendering/screenspacerenderable.h +++ b/include/openspace/rendering/screenspacerenderable.h @@ -44,7 +44,7 @@ namespace documentation { struct Documentation; } /** * The base class for screen space images and screen space framebuffers. - * This base class handles general functionality specific to planes that are rendered in + * This base class handles general functionality specific to planes that are rendered in * front of the camera. It implements protected methods and properties for converting * the planes from Spherical to Euclidean coordinates and back. It also specifies the * interface that its children need to implement. @@ -79,7 +79,7 @@ protected: * Converts Spherical coordinates to Euclidean. * \param spherical The coordinates theta and phi * \param radius The radius position value of the plane - * \return The x and y position value of the plane + * \return The x and y position value of the plane */ glm::vec2 toEuclidean(const glm::vec2& spherical, float radius); diff --git a/include/openspace/rendering/volume.h b/include/openspace/rendering/volume.h index 8d954ab531..a9fda2e452 100644 --- a/include/openspace/rendering/volume.h +++ b/include/openspace/rendering/volume.h @@ -40,7 +40,7 @@ public: /** * Constructor */ - Volume() {}; + Volume() {}; /** * Destructor @@ -76,7 +76,7 @@ public: * * The shader preprocessor will have acceess to * A #{namespace} variable (unique per helper file) - * + * * Should define the function: * vec4 getVertex() */ @@ -84,14 +84,14 @@ public: /* * Return a path to a file with the functions, uniforms and fragment shader in variables - * required to generate the fragment color and depth. + * required to generate the fragment color and depth. * * Should define the function: * Fragment getFragment() - * + * * The shader preprocessor will have acceess to * A #{namespace} variable (unique per helper file) - */ + */ //virtual std::string getBoundsFsPath() = 0; /** @@ -116,7 +116,7 @@ public: * This file will be included once per shader program generated, * regardless of how many volumes say they require the file. * Ideal to avoid redefinitions of helper functions. - * + * * The shader preprocessor will have access to the #{namespace} variable (unique per helper file) * which should be a prefix to all symbols defined by the helper */ diff --git a/include/openspace/rendering/volumeraycaster.h b/include/openspace/rendering/volumeraycaster.h index 14db9e5eab..b01517a22b 100644 --- a/include/openspace/rendering/volumeraycaster.h +++ b/include/openspace/rendering/volumeraycaster.h @@ -84,14 +84,14 @@ public: /* * Return a path to a file with the functions, uniforms and fragment shader in variables - * required to generate the fragment color and depth. + * required to generate the fragment color and depth. * * Should define the function: * Fragment getFragment() - * + * * The shader preprocessor will have acceess to * A #{namespace} variable (unique per helper file) - */ + */ virtual std::string getBoundsFsPath() const = 0 ; /** @@ -116,7 +116,7 @@ public: * This file will be included once per shader program generated, * regardless of how many volumes say they require the file. * Ideal to avoid redefinitions of helper functions. - * + * * The shader preprocessor will have access to the #{namespace} variable (unique per helper file) * which should be a prefix to all symbols defined by the helper */ @@ -125,4 +125,4 @@ public: } // namespace openspace -#endif // __OPENSPACE_CORE___VOLUMERAYCASTER___H__ +#endif // __OPENSPACE_CORE___VOLUMERAYCASTER___H__ diff --git a/include/openspace/scripting/scriptscheduler.h b/include/openspace/scripting/scriptscheduler.h index 6641e47f3f..67e66948cc 100644 --- a/include/openspace/scripting/scriptscheduler.h +++ b/include/openspace/scripting/scriptscheduler.h @@ -37,7 +37,7 @@ namespace openspace::documentation { struct Documentation; } namespace openspace::scripting { /** - * Maintains an ordered list of ScheduledScripts and provides a simple + * Maintains an ordered list of ScheduledScripts and provides a simple * interface for retrieveing scheduled scripts */ class ScriptScheduler { @@ -72,8 +72,8 @@ public: void clearSchedule(); /** - * Progresses the script schedulers time and returns all scripts that has been - * scheduled to run between \param newTime and the time provided in the last invocation + * Progresses the script schedulers time and returns all scripts that has been + * scheduled to run between \param newTime and the time provided in the last invocation * of this method. * * \param newTime A j2000 time value specifying the new time stamp that @@ -96,7 +96,7 @@ public: > progressTo(double newTime); /** - * Returns the the j2000 time value that the script scheduler is currently at + * Returns the the j2000 time value that the script scheduler is currently at */ double currentTime() const; diff --git a/include/openspace/util/concurrentjobmanager.h b/include/openspace/util/concurrentjobmanager.h index a0c446a2e6..72f66312c1 100644 --- a/include/openspace/util/concurrentjobmanager.h +++ b/include/openspace/util/concurrentjobmanager.h @@ -43,7 +43,7 @@ struct Job { virtual std::shared_ptr

product() = 0; }; -/* +/* * Templated Concurrent Job Manager * This class is used execute specific jobs on one (1) parallell thread */ diff --git a/include/openspace/util/gpudata.h b/include/openspace/util/gpudata.h index bf030e3c7d..b5189cbd65 100644 --- a/include/openspace/util/gpudata.h +++ b/include/openspace/util/gpudata.h @@ -41,7 +41,7 @@ class UniformLocation { public: /** - * Updates the uniform location of the uniform variable named + * Updates the uniform location of the uniform variable named * in the provided shader program. */ void bind(ghoul::opengl::ProgramObject* program, const std::string& name); @@ -53,7 +53,7 @@ protected: /** * Manages a GPU representation of the templated data type T. - * This class provides a simple interface setting the value of + * This class provides a simple interface setting the value of * the binded GLSL variable. */ template @@ -71,13 +71,13 @@ public: /** * Manages a Texture on the GPU. - * This class provides a simple interface binding texture to the + * This class provides a simple interface binding texture to the * named uniform. */ class GPUTexture : public UniformLocation{ public: /** - * Sets and assignes a texture unit within the provided shader + * Sets and assignes a texture unit within the provided shader * program. * OBS! Users must ensure bind has been called before using this method. */ diff --git a/include/openspace/util/histogram.h b/include/openspace/util/histogram.h index 408cc2222c..8029951bf6 100644 --- a/include/openspace/util/histogram.h +++ b/include/openspace/util/histogram.h @@ -49,10 +49,10 @@ public: * Enter value into the histogram. The add method takes the given * value, works out which bin this corresponds to, and increments * this bin by 'repeat'. - * + * * @param value The Value to insert into the histogram * @param repeat How many times you want to insert it - * + * * @return Returns true if succesful insertion, otherwise return false */ bool add(float value, float repeat = 1.0f); diff --git a/include/openspace/util/openspacemodule.h b/include/openspace/util/openspacemodule.h index 791c6cfef3..97eaf3c9d0 100644 --- a/include/openspace/util/openspacemodule.h +++ b/include/openspace/util/openspacemodule.h @@ -45,7 +45,7 @@ namespace documentation { struct Documentation; } class OpenSpaceModule : public properties::PropertyOwner { public: /** - * Constructs the OpenSpaceModule with a specific \p name. The uniqueness of the + * Constructs the OpenSpaceModule with a specific \p name. The uniqueness of the * \p name will be checked at a later stage. * \param name The name of this OpenSpace module * \pre \p name must not be empty diff --git a/include/openspace/util/spicemanager.h b/include/openspace/util/spicemanager.h index e40d0509a9..aa38bd9c25 100644 --- a/include/openspace/util/spicemanager.h +++ b/include/openspace/util/spicemanager.h @@ -630,7 +630,7 @@ public: }; /** - * Returns the state vector (position and velocity) of a \p target body relative to an + * Returns the state vector (position and velocity) of a \p target body relative to an * \p observer in a specific \p referenceFrame, optionally corrected for aberration * (\p aberrationCorrection). * \param target The target body name or the target body's NAIF ID @@ -660,7 +660,7 @@ public: const std::string& observer, const std::string& referenceFrame, AberrationCorrection aberrationCorrection, double ephemerisTime) const; - /** + /** * Returns the state transformation matrix used to convert from the \p sourceFrame to * the \p destinationFrame at a specific \p ephemerisTime. * \param sourceFrame The name of the source reference frame @@ -824,7 +824,7 @@ public: bool addFrame(std::string body, std::string frame); /** - * This function returns the frame of a body if defined, otherwise it returns + * This function returns the frame of a body if defined, otherwise it returns * IAU_ + body (most frames are known by the International Astronomical Union) * \param body - the name of the body * \return the frame of the body @@ -833,7 +833,7 @@ public: std::string frameFromBody(const std::string& body) const; /** - * Sets the SpiceManager's exception handling. If UseException::No is passed to this + * Sets the SpiceManager's exception handling. If UseException::No is passed to this * function, all subsequent calls will not throw an error, but fail silently instead. * If set to UseException::Yes, a SpiceException is thrown whenever an error occurs. * \param useException The new exeception handling method that the SpiceManager should diff --git a/include/openspace/util/syncdata.h b/include/openspace/util/syncdata.h index ec22cea74a..6b688ac068 100644 --- a/include/openspace/util/syncdata.h +++ b/include/openspace/util/syncdata.h @@ -53,13 +53,13 @@ protected: }; /** - * A double buffered implementation of the Syncable interface. - * Users are encouraged to used this class as a default way to synchronize different + * A double buffered implementation of the Syncable interface. + * Users are encouraged to used this class as a default way to synchronize different * C++ data types using the SyncEngine * - * This class aims to handle the synchronization parts and yet act like a regular - * instance of T. Implicit casts are supported, however, when accessing member functions or - * or variables, user may have to do explicit casts. + * This class aims to handle the synchronization parts and yet act like a regular + * instance of T. Implicit casts are supported, however, when accessing member functions + * or variables, user may have to do explicit casts. * * ((T&) t).method(); * @@ -71,7 +71,7 @@ public: SyncData() {}; SyncData(const T& val) : data(val) {}; SyncData(const SyncData& o) : data(o.data) { - // Should not have to be copied! + // Should not have to be copied! }; /** diff --git a/include/openspace/util/threadpool.h b/include/openspace/util/threadpool.h index f83b622b2f..556d0cba1f 100644 --- a/include/openspace/util/threadpool.h +++ b/include/openspace/util/threadpool.h @@ -40,7 +40,7 @@ namespace openspace { class ThreadPool; class Worker { -public: +public: Worker(ThreadPool& pool); void operator()(); private: diff --git a/include/openspace/util/time.h b/include/openspace/util/time.h index 06a4a629b2..a3f23059e5 100644 --- a/include/openspace/util/time.h +++ b/include/openspace/util/time.h @@ -36,7 +36,7 @@ namespace openspace { /** * This singleton class represents the current simulation time in OpenSpace. It * internally stores the time and provides methods to set the time directly - * (setTime(double), setTime(std::string)) using a double value using the + * (setTime(double), setTime(std::string)) using a double value using the * number of seconds passed since the J2000 epoch or a string that denotes * a valid date string in accordance to the Spice library * (http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/str2et_c.html). The time can @@ -47,12 +47,12 @@ namespace openspace { * the number of seconds that pass for each real-time second. This value is set with * setDeltaTime(double), retrieved with deltaTime() and solely used in the * advanceTime(double), which takes a tickTime parameter. The value of the - * parameter is dependent on the usage of the class and must be equal to the real-world + * parameter is dependent on the usage of the class and must be equal to the real-world * time that has passed since the last call to the method. For example, if the * advanceTime(double) method is called each frame, the tickTime has to be * equal to the frame time. * - * The synchronization of the simulation time requires + * The synchronization of the simulation time requires */ class Time { public: @@ -144,7 +144,7 @@ public: double deltaTime() const; /** - * Sets the pause function, i.e. setting the deltaTime to 0 (pause = + * Sets the pause function, i.e. setting the deltaTime to 0 (pause = * true) and restoring it when the function is called with a parameter of * false. * \param pause If true, the simulation time stops; diff --git a/include/openspace/util/timerange.h b/include/openspace/util/timerange.h index 4b2e567249..90a532a64c 100644 --- a/include/openspace/util/timerange.h +++ b/include/openspace/util/timerange.h @@ -38,7 +38,7 @@ struct TimeRange { TimeRange(); /** - * Initializes a TimeRange with both start and end time. Initializing empty timeranges + * Initializes a TimeRange with both start and end time. Initializing empty timeranges * is OK. */ TimeRange(double startTime, double endTime); diff --git a/modules/base/rendering/multimodelgeometry.cpp b/modules/base/rendering/multimodelgeometry.cpp index 94638e5cd5..bb18d0663d 100644 --- a/modules/base/rendering/multimodelgeometry.cpp +++ b/modules/base/rendering/multimodelgeometry.cpp @@ -52,7 +52,7 @@ bool MultiModelGeometry::loadModel(const std::string& filename) { _vertices.push_back(vv); } - _indices.resize(indices.size()); + _indices.resize(indices.size()); std::copy(indices.begin(), indices.end(), _indices.begin()); return true; diff --git a/modules/base/rendering/renderablemodel.cpp b/modules/base/rendering/renderablemodel.cpp index faf34d5477..ae1e1732b0 100644 --- a/modules/base/rendering/renderablemodel.cpp +++ b/modules/base/rendering/renderablemodel.cpp @@ -165,7 +165,7 @@ void RenderableModel::initialize() { loadTexture(); - _geometry->initialize(this); + _geometry->initialize(this); } void RenderableModel::deinitialize() { diff --git a/modules/base/rendering/renderablemodel.h b/modules/base/rendering/renderablemodel.h index 86b8d1c35f..c0d6a80dae 100644 --- a/modules/base/rendering/renderablemodel.h +++ b/modules/base/rendering/renderablemodel.h @@ -35,7 +35,7 @@ #include namespace ghoul::opengl { - class ProgramObject; + class ProgramObject; class Texture; } // namespace ghoul::opengl diff --git a/modules/base/rendering/renderableplane.cpp b/modules/base/rendering/renderableplane.cpp index d867404864..8e4c90795f 100644 --- a/modules/base/rendering/renderableplane.cpp +++ b/modules/base/rendering/renderableplane.cpp @@ -210,7 +210,7 @@ void RenderablePlane::deinitialize() { void RenderablePlane::render(const RenderData& data, RendererTasks&) { _shader->activate(); //if (_projectionListener){ - // //get parent node-texture and set with correct dimensions + // //get parent node-texture and set with correct dimensions // SceneGraphNode* textureNode = OsEng.renderEngine().scene()->sceneGraphNode( // _nodeName // )->parent(); @@ -342,7 +342,7 @@ void RenderablePlane::createPlane() { glEnableVertexAttribArray(1); glVertexAttribPointer( - 1, + 1, 2, GL_FLOAT, GL_FALSE, diff --git a/modules/base/rendering/renderabletrail.h b/modules/base/rendering/renderabletrail.h index 8dd51a5c78..ed45eab5be 100644 --- a/modules/base/rendering/renderabletrail.h +++ b/modules/base/rendering/renderabletrail.h @@ -60,7 +60,7 @@ class Translation; * * Trails can be rendered either as lines, as points, or a combination of both with * varying colors, line thicknesses, or fading settings. If trails are rendered as points, - * the RenderInformation's \c stride parameter determines the number of points between + * the RenderInformation's \c stride parameter determines the number of points between * larger points. A potential use case for this is showing the passage of time along a * trail by using a point separation of one hour and a subsampling of 4, you would get a * point every 15 minutes with every hourly point being bigger. @@ -109,7 +109,7 @@ protected: std::unique_ptr _translation; /// The RenderInformation contains information filled in by the concrete subclasses to - /// be used by this class. + /// be used by this class. struct RenderInformation { enum class VertexSorting { NewestFirst = 0, ///< Newer vertices have a lower index than older ones @@ -117,13 +117,13 @@ protected: NoSorting ///< No ordering in the vertices; no fading applied }; /// The first element in the vertex buffer to be rendered - GLint first = 0; + GLint first = 0; /// The number of values to be rendered GLsizei count = 0; /// The stride between 'major' points in the array int stride = 1; /// Sorting of the vertices; required for correct fading - VertexSorting sorting = VertexSorting::NoSorting; + VertexSorting sorting = VertexSorting::NoSorting; /// Local model matrix transformation, used for rendering in camera space glm::dmat4 _localTransform = glm::dmat4(1.0); @@ -156,7 +156,7 @@ private: /// The option determining which rendering method to use properties::OptionProperty _renderingModes; - /// Program object used to render the data stored in RenderInformation + /// Program object used to render the data stored in RenderInformation std::unique_ptr _programObject; }; diff --git a/modules/base/rendering/renderabletrailorbit.cpp b/modules/base/rendering/renderabletrailorbit.cpp index 3818d7f965..8688c032d8 100644 --- a/modules/base/rendering/renderabletrailorbit.cpp +++ b/modules/base/rendering/renderabletrailorbit.cpp @@ -39,11 +39,11 @@ // --------------------------------------------------------------------------------- // | FF | | | | | | | | | | | | | | | | // --------------------------------------------------------------------------------- -// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 +// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // <------ newer in time oldest // // In the begining the floating value starts at 0; this means that array element 0 is -// updated and uploaded to the GPU at every frame. The FF+1 element is the newest fixed +// updated and uploaded to the GPU at every frame. The FF+1 element is the newest fixed // location and FF-1 element is the oldest fixed location (including wrapping around the // array) with the times of _lastPointTime and _firstPointTime. // @@ -53,7 +53,7 @@ // --------------------------------------------------------------------------------- // | | | | | | | | | | | | | | | | FF | // --------------------------------------------------------------------------------- -// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 +// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // <------ newer in time oldest // // Thus making the floating point traverse backwards through the array and element 0 being @@ -257,7 +257,7 @@ void RenderableTrailOrbit::update(const UpdateData& data) { // Only update the changed ones // Since we are using a ring buffer, the number of updated needed might be // bigger than our current points, which means we have to split the upload - // into two calls. + // into two calls. if (report.nUpdated > 0) { // deltaT is positive, so the pointer is moving backwards and update has // to happen towards the front @@ -277,7 +277,7 @@ void RenderableTrailOrbit::update(const UpdateData& data) { // The current index is too close to the wrap around part, so we need // to split the upload into two parts: // 1. from the current index to the end of the array - // 2. the rest starting from the beginning of the array + // 2. the rest starting from the beginning of the array int first = s - i; int second = n - first; upload(i, first); // 1 diff --git a/modules/base/rendering/renderabletrailorbit.h b/modules/base/rendering/renderabletrailorbit.h index 1c74839b23..2e6b7be12b 100644 --- a/modules/base/rendering/renderabletrailorbit.h +++ b/modules/base/rendering/renderabletrailorbit.h @@ -68,7 +68,7 @@ private: static const int All = 0; ///< The entire array was touched in the update /// If \c true at least one point was touched - bool needsUpdate; + bool needsUpdate; /// Returns the number of fixed points that were touched in the update method /// If this value is negative, the newest values were replaced, if positive the /// oldest diff --git a/modules/base/rendering/screenspaceframebuffer.cpp b/modules/base/rendering/screenspaceframebuffer.cpp index 25d11833ee..de508f4fe9 100644 --- a/modules/base/rendering/screenspaceframebuffer.cpp +++ b/modules/base/rendering/screenspaceframebuffer.cpp @@ -54,7 +54,7 @@ documentation::Documentation ScreenSpaceFramebuffer::Documentation() { }; } -ScreenSpaceFramebuffer::ScreenSpaceFramebuffer(const ghoul::Dictionary& dictionary) +ScreenSpaceFramebuffer::ScreenSpaceFramebuffer(const ghoul::Dictionary& dictionary) : ScreenSpaceRenderable(dictionary) , _size(SizeInfo, glm::vec4(0), glm::vec4(0), glm::vec4(16384)) , _framebuffer(nullptr) diff --git a/modules/base/rendering/wavefrontgeometry.cpp b/modules/base/rendering/wavefrontgeometry.cpp index bbf4f25ba8..853c1e1d00 100644 --- a/modules/base/rendering/wavefrontgeometry.cpp +++ b/modules/base/rendering/wavefrontgeometry.cpp @@ -35,7 +35,7 @@ namespace openspace { namespace modelgeometry { WavefrontGeometry::WavefrontGeometry(const ghoul::Dictionary& dictionary) - : ModelGeometry(dictionary) + : ModelGeometry(dictionary) { loadObj(_file); } diff --git a/modules/base/translation/luatranslation.cpp b/modules/base/translation/luatranslation.cpp index 139fa48cf8..7dd8353d9e 100644 --- a/modules/base/translation/luatranslation.cpp +++ b/modules/base/translation/luatranslation.cpp @@ -78,8 +78,8 @@ LuaTranslation::LuaTranslation() _luaScriptFile.onChange([&](){ _fileHandle = std::make_unique(_luaScriptFile); - _fileHandle->setCallback([&](const ghoul::filesystem::File&){ - notifyObservers(); + _fileHandle->setCallback([&](const ghoul::filesystem::File&) { + notifyObservers(); }); }); } diff --git a/modules/debugging/debuggingmodule.cpp b/modules/debugging/debuggingmodule.cpp index 4b009b91d4..ff873e22e0 100644 --- a/modules/debugging/debuggingmodule.cpp +++ b/modules/debugging/debuggingmodule.cpp @@ -43,7 +43,7 @@ void DebuggingModule::internalInitialize() { fRenderable->registerClass("RenderableDebugPlane"); } -std::vector DebuggingModule::documentations() const { +std::vector DebuggingModule::documentations() const { return { RenderableDebugPlane::Documentation() }; diff --git a/modules/debugging/rendering/debugrenderer.cpp b/modules/debugging/rendering/debugrenderer.cpp index c6f348857a..bfabe1cd25 100644 --- a/modules/debugging/rendering/debugrenderer.cpp +++ b/modules/debugging/rendering/debugrenderer.cpp @@ -44,15 +44,15 @@ DebugRenderer* DebugRenderer::_reference = nullptr; DebugRenderer::DebugRenderer() { _programObject = OsEng.renderEngine().buildRenderProgram( - "BasicDebugShader", + "BasicDebugShader", "${MODULE_DEBUGGING}/rendering/debugshader_vs.glsl", "${MODULE_DEBUGGING}/rendering/debugshader_fs.glsl" ); } DebugRenderer::DebugRenderer(std::unique_ptr programObject) - : _programObject(std::move(programObject)) -{ + : _programObject(std::move(programObject)) +{ // nothing to do } diff --git a/modules/debugging/rendering/debugrenderer.h b/modules/debugging/rendering/debugrenderer.h index 1d86ecf8c0..da6b87af56 100644 --- a/modules/debugging/rendering/debugrenderer.h +++ b/modules/debugging/rendering/debugrenderer.h @@ -40,7 +40,7 @@ namespace openspace { /** - * A helper class for quick rendering of vertices IN clipping space. + * A helper class for quick rendering of vertices IN clipping space. * The class is practically stateless. It only stores a ghoul::opengl::ProgramObject * which can be reused despite the fact that rendering calls are invoked from different * callers. Therefore a static reference is provided for convenience which is accessed @@ -77,7 +77,7 @@ public: /** * Takes a vector of exactly 8 vertices, i.e. corner points in a box. * The box corners should be ordered from smaller to larger, - * first by x, the, y and finally z. + * first by x, the, y and finally z. * * 6-------7 * |\ |\ @@ -93,7 +93,7 @@ public: /** * Takes a vector of exactly 8 vertices, i.e. corner points in a box. * The box corners should be ordered from smaller to larger, - * first by x, the, y and finally z. + * first by x, the, y and finally z. * * 6-------7 * |\ |\ @@ -124,7 +124,7 @@ public: /** * Input arguments: - * 1. const RenderData& data: defines position and camera that we will see the + * 1. const RenderData& data: defines position and camera that we will see the * other cameras view frustum from * 2. const Camera& otherCamera: The camera who's view frustum is to be rendered * 3. RGBA rgba Color to draw the view frustum with @@ -143,7 +143,7 @@ public: #ifdef OPENSPACE_MODULE_GLOBEBROWSING_ENABLED /** - * Takes a AABB3 in screen space and returns vertices representing the corner points + * Takes a AABB3 in screen space and returns vertices representing the corner points * of the AABB. The ordering of the corner points is compatible with the box * rendering methods in this class. */ diff --git a/modules/digitaluniverse/rendering/renderablepoints.cpp b/modules/digitaluniverse/rendering/renderablepoints.cpp index d5147a7c0a..707c2a0b70 100644 --- a/modules/digitaluniverse/rendering/renderablepoints.cpp +++ b/modules/digitaluniverse/rendering/renderablepoints.cpp @@ -62,7 +62,7 @@ namespace { static const openspace::properties::Property::PropertyInfo SpriteTextureInfo = { "Texture", "Point Sprite Texture", - "The path to the texture that should be used as the point sprite." + "The path to the texture that should be used as the point sprite." }; static const openspace::properties::Property::PropertyInfo TransparencyInfo = { @@ -112,7 +112,7 @@ namespace openspace { "The path to the SPECK file that contains information about the astronomical " "object being rendered." }, - { + { keyColor, new Vector3Verifier, Optional::No, @@ -184,7 +184,7 @@ namespace openspace { } else if (unit == KilometerUnit) { _unit = Kilometer; - } + } else if (unit == ParsecUnit) { _unit = Parsec; } @@ -298,7 +298,7 @@ namespace openspace { using IgnoreError = ghoul::opengl::ProgramObject::IgnoreError; _program->setIgnoreUniformLocationError(IgnoreError::Yes); - _program->setUniform("modelViewProjectionTransform", glm::dmat4(data.camera.projectionMatrix()) * + _program->setUniform("modelViewProjectionTransform", glm::dmat4(data.camera.projectionMatrix()) * data.camera.combinedViewMatrix() * modelMatrix); _program->setUniform("color", _pointColor); @@ -334,7 +334,7 @@ namespace openspace { glDepthMask(true); } - void RenderablePoints::update(const UpdateData&) { + void RenderablePoints::update(const UpdateData&) { if (_dataIsDirty) { LDEBUG("Regenerating data"); @@ -653,7 +653,7 @@ namespace openspace { // Converting untis if (_unit == Kilometer) { p *= 1E3; - } + } else if (_unit == Parsec) { p *= PARSEC; } diff --git a/modules/digitaluniverse/rendering/renderablepoints.h b/modules/digitaluniverse/rendering/renderablepoints.h index 51cb4b819e..afcdaed93f 100644 --- a/modules/digitaluniverse/rendering/renderablepoints.h +++ b/modules/digitaluniverse/rendering/renderablepoints.h @@ -35,8 +35,8 @@ #include -namespace ghoul::filesystem { - class File; +namespace ghoul::filesystem { + class File; } namespace ghoul::opengl { diff --git a/modules/fieldlines/rendering/renderablefieldlines.cpp b/modules/fieldlines/rendering/renderablefieldlines.cpp index 7253e7ff86..863a89d530 100644 --- a/modules/fieldlines/rendering/renderablefieldlines.cpp +++ b/modules/fieldlines/rendering/renderablefieldlines.cpp @@ -104,7 +104,7 @@ namespace { namespace openspace { -RenderableFieldlines::RenderableFieldlines(const ghoul::Dictionary& dictionary) +RenderableFieldlines::RenderableFieldlines(const ghoul::Dictionary& dictionary) : Renderable(dictionary) , _stepSize(StepSizeInfo, defaultFieldlineStepSize, 0.f, 10.f) , _classification(Classification, true) @@ -427,7 +427,7 @@ RenderableFieldlines::generateFieldlinesVolumeKameleon() if (model != vectorFieldKameleonModelBATSRUS) { //modelType = KameleonWrapper::Model::BATSRUS; //else { - LERROR(keyVectorField << "." << keyVectorFieldVolumeModel << " model '" << + LERROR(keyVectorField << "." << keyVectorFieldVolumeModel << " model '" << model << "' not supported"); return {}; } diff --git a/modules/galaxy/rendering/renderablegalaxy.cpp b/modules/galaxy/rendering/renderablegalaxy.cpp index 2c62310399..be5aaa79a3 100644 --- a/modules/galaxy/rendering/renderablegalaxy.cpp +++ b/modules/galaxy/rendering/renderablegalaxy.cpp @@ -272,7 +272,7 @@ void RenderableGalaxy::initialize() { GLint colorAttrib = _pointsProgram->attributeLocation("inColor"); glBindBuffer(GL_ARRAY_BUFFER, _positionVbo); - glEnableVertexAttribArray(positionAttrib); + glEnableVertexAttribArray(positionAttrib); glVertexAttribPointer(positionAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0); glBindBuffer(GL_ARRAY_BUFFER, _colorVbo); diff --git a/modules/galaxy/tasks/milkywayconversiontask.cpp b/modules/galaxy/tasks/milkywayconversiontask.cpp index 4002251bb9..6b623b1b92 100644 --- a/modules/galaxy/tasks/milkywayconversiontask.cpp +++ b/modules/galaxy/tasks/milkywayconversiontask.cpp @@ -39,7 +39,7 @@ namespace { const char* KeyInNSlices = "InNSlices"; const char* KeyOutFilename = "OutFilename"; const char* KeyOutDimensions = "OutDimensions"; -} // namespace +} // namespace namespace openspace { diff --git a/modules/globebrowsing/chunk/chunk.cpp b/modules/globebrowsing/chunk/chunk.cpp index 6e10fde6f6..19c0799545 100644 --- a/modules/globebrowsing/chunk/chunk.cpp +++ b/modules/globebrowsing/chunk/chunk.cpp @@ -40,7 +40,7 @@ Chunk::Chunk(const RenderableGlobe& owner, const TileIndex& tileIndex, bool init : _owner(owner) , _tileIndex(tileIndex) , _isVisible(initVisible) - , _surfacePatch(tileIndex) + , _surfacePatch(tileIndex) {} const GeodeticPatch& Chunk::surfacePatch() const { @@ -171,8 +171,8 @@ std::vector Chunk::getBoundingPolyhedronCorners() const { double maxCenterRadius = patchCenterRadius + boundingHeight.max; Geodetic2 halfSize = patch.halfSize(); - // As the patch is curved, the maximum height offsets at the corners must be long - // enough to cover large enough to cover a boundingHeight.max at the center of the + // As the patch is curved, the maximum height offsets at the corners must be long + // enough to cover large enough to cover a boundingHeight.max at the center of the // patch. // Approximating scaleToCoverCenter by assuming the latitude and longitude angles // of "halfSize" are equal to the angles they create from the center of the @@ -189,7 +189,7 @@ std::vector Chunk::getBoundingPolyhedronCorners() const { bool chunkIsNorthOfEquator = patch.isNorthern(); - // The minimum height offset, however, we can simply + // The minimum height offset, however, we can simply double minCornerHeight = boundingHeight.min; std::vector corners(8); diff --git a/modules/globebrowsing/chunk/chunk.h b/modules/globebrowsing/chunk/chunk.h index c3c676adab..fc3af610e5 100644 --- a/modules/globebrowsing/chunk/chunk.h +++ b/modules/globebrowsing/chunk/chunk.h @@ -66,7 +66,7 @@ public: * return Status::WANT_MERGE, if it is larger it will return Status::WANT_SPLIT, * otherwise Status::DO_NOTHING. * - * \returns The Status of the chunk. + * \returns The Status of the chunk. */ Status update(const RenderData& data); diff --git a/modules/globebrowsing/chunk/chunklevelevaluator/projectedareaevaluator.cpp b/modules/globebrowsing/chunk/chunklevelevaluator/projectedareaevaluator.cpp index c31e1d5818..5760f519c0 100644 --- a/modules/globebrowsing/chunk/chunklevelevaluator/projectedareaevaluator.cpp +++ b/modules/globebrowsing/chunk/chunklevelevaluator/projectedareaevaluator.cpp @@ -46,12 +46,12 @@ int ProjectedArea::getDesiredLevel(const Chunk& chunk, const RenderData& data) c glm::dvec3(inverseModelTransform * cameraPositionModelSpace); glm::dvec3 cameraToEllipsoidCenter = -cameraPosition; - Geodetic2 cameraGeodeticPos = ellipsoid.cartesianToGeodetic2(cameraPosition); + Geodetic2 cameraGeodeticPos = ellipsoid.cartesianToGeodetic2(cameraPosition); // Approach: // The projected area of the chunk will be calculated based on a small area that // is close to the camera, and the scaled up to represent the full area. - // The advantage of doing this is that it will better handle the cases where the + // The advantage of doing this is that it will better handle the cases where the // full patch is very curved (e.g. stretches from latitude 0 to 90 deg). const Geodetic2 center = chunk.surfacePatch().center(); @@ -61,11 +61,11 @@ int ProjectedArea::getDesiredLevel(const Chunk& chunk, const RenderData& data) c // | // V // - // oo + // oo // [ ]< // *geodetic space* - // - // closestCorner + // + // closestCorner // +-----------------+ <-- north east corner // | | // | center | @@ -81,7 +81,7 @@ int ProjectedArea::getDesiredLevel(const Chunk& chunk, const RenderData& data) c // | // V // - // oo + // oo // [ ]< // *geodetic space* // @@ -103,7 +103,7 @@ int ProjectedArea::getDesiredLevel(const Chunk& chunk, const RenderData& data) c C = glm::normalize(C); // Camera *cartesian space* - // | +--------+---+ + // | +--------+---+ // V __--'' __--'' / // C-------A--------- + // oo / / / diff --git a/modules/globebrowsing/chunk/chunknode.cpp b/modules/globebrowsing/chunk/chunknode.cpp index bbe9392605..1ef8c7694b 100644 --- a/modules/globebrowsing/chunk/chunknode.cpp +++ b/modules/globebrowsing/chunk/chunknode.cpp @@ -109,7 +109,7 @@ void ChunkNode::reverseBreadthFirst(const std::function& // Loop through nodes in breadths first order Q.push(this); while (Q.size() > 0) { - const ChunkNode* node = Q.front(); + const ChunkNode* node = Q.front(); Q.pop(); // Add node to future stack @@ -126,7 +126,7 @@ void ChunkNode::reverseBreadthFirst(const std::function& } } - // Loop through all nodes in stack, this will be reversed breadth first + // Loop through all nodes in stack, this will be reversed breadth first while (S.size() > 0) { f(*S.top()); S.pop(); diff --git a/modules/globebrowsing/chunk/culling/horizonculler.cpp b/modules/globebrowsing/chunk/culling/horizonculler.cpp index 84edb71c90..4919490c4f 100644 --- a/modules/globebrowsing/chunk/culling/horizonculler.cpp +++ b/modules/globebrowsing/chunk/culling/horizonculler.cpp @@ -79,7 +79,7 @@ bool HorizonCuller::isCullable(const Chunk& chunk, const RenderData& data) { maxHeight, minimumGlobeRadius); } -bool HorizonCuller::isCullable(const glm::dvec3& cameraPosition, +bool HorizonCuller::isCullable(const glm::dvec3& cameraPosition, const glm::dvec3& globePosition, const glm::dvec3& objectPosition, double objectBoundingSphereRadius, diff --git a/modules/globebrowsing/geometry/angle.h b/modules/globebrowsing/geometry/angle.h index 9ad16bfa41..68cb1f4cd7 100644 --- a/modules/globebrowsing/geometry/angle.h +++ b/modules/globebrowsing/geometry/angle.h @@ -96,8 +96,8 @@ public: Angle& normalizeAround(const Angle& center); /** - * Clamps the angle to the interval [min, max]. - * Default arguments are [0, 2pi]. + * Clamps the angle to the interval [min, max]. + * Default arguments are [0, 2pi]. */ Angle& clamp(const Angle& min = ZERO, const Angle& max = FULL); diff --git a/modules/globebrowsing/geometry/angle.inl b/modules/globebrowsing/geometry/angle.inl index 0ef33336cb..d6b763885d 100644 --- a/modules/globebrowsing/geometry/angle.inl +++ b/modules/globebrowsing/geometry/angle.inl @@ -30,7 +30,7 @@ template const T Angle::PI = T(3.14159265358979323846264338327950); template -const T Angle::EPSILON = 1e-10; // Should depend on the typedef /eb +const T Angle::EPSILON = 1e-10; // Should depend on the typedef /eb ////////////////////////////////////////////////////////////////////////////////////////// // STATIC CONSTANTS // diff --git a/modules/globebrowsing/geometry/ellipsoid.cpp b/modules/globebrowsing/geometry/ellipsoid.cpp index 2482b459ed..d679960709 100644 --- a/modules/globebrowsing/geometry/ellipsoid.cpp +++ b/modules/globebrowsing/geometry/ellipsoid.cpp @@ -91,7 +91,7 @@ glm::dvec3 Ellipsoid::geodeticSurfaceNormal(Geodetic2 geodetic2) const { //geodetic2.lon = geodetic2.lon > M_PI ? geodetic2.lon - M_PI * 2 : geodetic2.lon; return glm::dvec3( cosLat * cos(geodetic2.lon), - cosLat * sin(geodetic2.lon), + cosLat * sin(geodetic2.lon), sin(geodetic2.lat)); } diff --git a/modules/globebrowsing/geometry/geodeticpatch.cpp b/modules/globebrowsing/geometry/geodeticpatch.cpp index 3171225df4..3258e96a43 100644 --- a/modules/globebrowsing/geometry/geodeticpatch.cpp +++ b/modules/globebrowsing/geometry/geodeticpatch.cpp @@ -139,7 +139,7 @@ Geodetic2 GeodeticPatch::clamp(const Geodetic2& p) const { // Normalize w.r.t. the center in order for the clamping to done correctly // - // Example: + // Example: // centerLat = 0 deg, halfSize.lat = 10 deg, pointLat = 330 deg // --> Just clamping pointLat would be clamp(330, -10, 10) = 10 // WRONG! // Instead, if we first normalize 330 deg around 0, we get -30 deg @@ -163,11 +163,11 @@ Geodetic2 GeodeticPatch::closestCorner(const Geodetic2& p) const { Ang latDiff = Ang::fromRadians(centerToPoint.lat).normalizeAround(Ang::ZERO); Ang lonDiff = Ang::fromRadians(centerToPoint.lon).normalizeAround(Ang::ZERO); - // If latDiff > 0 - // --> point p is north of the patch center + // If latDiff > 0 + // --> point p is north of the patch center // --> the closest corner to the point must be a northern one // --> set the corner's latitude coordinate to center.lat + halfSize.lat - // else + // else // --> set corner's latidude coordinate to center.lat - halfSize.lat double cornerLat = _center.lat + _halfSize.lat * (latDiff > Ang::ZERO ? 1 : -1); @@ -179,31 +179,31 @@ Geodetic2 GeodeticPatch::closestCorner(const Geodetic2& p) const { Geodetic2 GeodeticPatch::closestPoint(const Geodetic2& p) const { // This method finds the closest point on the patch, to the provided - // point p. As we are deali ng with latitude-longitude patches, distance in this + // point p. As we are deali ng with latitude-longitude patches, distance in this // context refers to great-circle distance. // (https://en.wikipedia.org/wiki/Great-circle_distance) // - // This uses a simple clamping approach to find the closest point on the - // patch. A naive castesian clamp is not sufficient for this purpose, + // This uses a simple clamping approach to find the closest point on the + // patch. A naive castesian clamp is not sufficient for this purpose, // as illustrated with an example below. // Example: (degrees are used for latidude, longitude) // patchCenter = (0,0), patchHalfSize = (45,45), point = (5, 170) // Note, the point and the patch are on opposite sides of the sphere // - // cartesian clamp: + // cartesian clamp: // --> clampedPointLat = clamp(5, -45, 45) = 5 // --> clampedPointLon = clamp(170, -45, 45) = 45 // --> result: (5, 45) - // --> closest point is actually (45, 45) + // --> closest point is actually (45, 45) // --> The error is significant - // - // This method simply adds an extra clamp on the latitude in these cases. In the + // + // This method simply adds an extra clamp on the latitude in these cases. In the // above example, that would be the following: // --> clampedPointLat = clamp(180 - 5, -45, 45) = 45 - // + // // Just doing this actually makes points returned from this methods being the - // true closest point, great-circle distance-wise. + // true closest point, great-circle distance-wise. using Ang = Angle; @@ -213,17 +213,17 @@ Geodetic2 GeodeticPatch::closestPoint(const Geodetic2& p) const { Ang pointLat = Ang::fromRadians(p.lat); Ang pointLon = Ang::fromRadians(p.lon); - // Normalize point with respect to center. This is done because the point + // Normalize point with respect to center. This is done because the point // will later be clamped. See LatLonPatch::clamp(const LatLon&) for explanation pointLat.normalizeAround(centerLat); pointLon.normalizeAround(centerLon); - // Calculate the longitud difference between center and point. We normalize around - // zero because we want the "shortest distance" difference, i.e the difference + // Calculate the longitud difference between center and point. We normalize around + // zero because we want the "shortest distance" difference, i.e the difference // should be in the interval [-180 deg, 180 deg] Ang centerToPointLon = (centerLon - pointLon).normalizeAround(Ang::ZERO); - // Calculate the longitudinal distance to the closest patch edge + // Calculate the longitudinal distance to the closest patch edge Ang longitudeDistanceToClosestPatchEdge = centerToPointLon.abs() - Ang::fromRadians(_halfSize.lon); // If the longitude distance to the closest patch edge is larger than 90 deg diff --git a/modules/globebrowsing/geometry/geodeticpatch.h b/modules/globebrowsing/geometry/geodeticpatch.h index fda307db1f..a67a84dc71 100644 --- a/modules/globebrowsing/geometry/geodeticpatch.h +++ b/modules/globebrowsing/geometry/geodeticpatch.h @@ -48,7 +48,7 @@ public: GeodeticPatch(const TileIndex& tileIndex); void setCenter(const Geodetic2&); - void setHalfSize(const Geodetic2&); + void setHalfSize(const Geodetic2&); /** * Returns the latitude boundary which is closest to the equator diff --git a/modules/globebrowsing/globes/chunkedlodglobe.cpp b/modules/globebrowsing/globes/chunkedlodglobe.cpp index 31dea61166..d21fd18e7d 100644 --- a/modules/globebrowsing/globes/chunkedlodglobe.cpp +++ b/modules/globebrowsing/globes/chunkedlodglobe.cpp @@ -80,7 +80,7 @@ ChunkedLodGlobe::ChunkedLodGlobe(const RenderableGlobe& owner, size_t segmentsPe AABB3(glm::vec3(-1, -1, 0), glm::vec3(1, 1, 1e35))) ); - _chunkEvaluatorByAvailableTiles = + _chunkEvaluatorByAvailableTiles = std::make_unique(); _chunkEvaluatorByProjectedArea = std::make_unique(); diff --git a/modules/globebrowsing/globes/chunkedlodglobe.h b/modules/globebrowsing/globes/chunkedlodglobe.h index 3ccad36387..872659ae9c 100644 --- a/modules/globebrowsing/globes/chunkedlodglobe.h +++ b/modules/globebrowsing/globes/chunkedlodglobe.h @@ -83,7 +83,7 @@ public: * lower than the current level of the Chunkss * TileIndex. If the desired level is higher than that of the * Chunk, it wants to split. If it is lower, it wants to merge with - * its siblings. + * its siblings. */ int getDesiredLevel(const Chunk& chunk, const RenderData& renderData) const; diff --git a/modules/globebrowsing/globes/pointglobe.cpp b/modules/globebrowsing/globes/pointglobe.cpp index 581f0345de..1101a7d103 100644 --- a/modules/globebrowsing/globes/pointglobe.cpp +++ b/modules/globebrowsing/globes/pointglobe.cpp @@ -37,7 +37,7 @@ namespace { static const openspace::properties::Property::PropertyInfo IntensityClampInfo = { "IntensityClamp", "Intensity clamp", - "" + "" }; static const openspace::properties::Property::PropertyInfo LightIntensityInfo = { @@ -138,7 +138,7 @@ void PointGlobe::render(const RenderData& data, RendererTasks&) { // Model transform and view transform needs to be in double precision glm::dmat4 modelTransform = glm::translate(glm::dmat4(1.0), bodyPosition) * // Translation - glm::inverse(rotationTransform) * + glm::inverse(rotationTransform) * scaleTransform; // Scale glm::dmat4 modelViewTransform = data.camera.combinedViewMatrix() * modelTransform; //glm::vec3 directionToSun = glm::normalize(glm::vec3(0) - glm::vec3(bodyPosition)); diff --git a/modules/globebrowsing/globes/renderableglobe.cpp b/modules/globebrowsing/globes/renderableglobe.cpp index ecdfb53687..5b50ab4297 100644 --- a/modules/globebrowsing/globes/renderableglobe.cpp +++ b/modules/globebrowsing/globes/renderableglobe.cpp @@ -157,11 +157,11 @@ namespace openspace::globebrowsing { RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary) : Renderable(dictionary) , _debugProperties({ - BoolProperty(SaveOrThrowInfo, false), + BoolProperty(SaveOrThrowInfo, false), BoolProperty(ShowChunkEdgeInfo, false), BoolProperty(ShowChunkBoundsInfo, false), BoolProperty(ShowChunkAABBInfo, false), - BoolProperty(HeightResolutionInfo, false), + BoolProperty(HeightResolutionInfo, false), BoolProperty(HeightIntensityInfo, false), BoolProperty(FrustumCullingInfo, true), BoolProperty(HorizonCullingInfo, true), @@ -368,7 +368,7 @@ const std::shared_ptr RenderableGlobe::savedCamera() const { } SurfacePositionHandle RenderableGlobe::calculateSurfacePositionHandle( - const glm::dvec3& targetModelSpace) + const glm::dvec3& targetModelSpace) { glm::dvec3 centerToEllipsoidSurface = _ellipsoid.geodeticSurfaceProjection(targetModelSpace); @@ -396,7 +396,7 @@ SurfacePositionHandle RenderableGlobe::calculateSurfacePositionHandle( }; } -void RenderableGlobe::setSaveCamera(std::shared_ptr camera) { +void RenderableGlobe::setSaveCamera(std::shared_ptr camera) { _savedCamera = camera; } diff --git a/modules/globebrowsing/globes/renderableglobe.h b/modules/globebrowsing/globes/renderableglobe.h index ffbda5040d..2dc6f001ab 100644 --- a/modules/globebrowsing/globes/renderableglobe.h +++ b/modules/globebrowsing/globes/renderableglobe.h @@ -45,7 +45,7 @@ class LayerManager; * algorithm for rendering. * The renderable uses a DistanceSwitch to determine if the renderable - * should be rendered. + * should be rendered. */ class RenderableGlobe : public Renderable { public: @@ -107,7 +107,7 @@ public: void setSaveCamera(std::shared_ptr camera); virtual SurfacePositionHandle calculateSurfacePositionHandle( - const glm::dvec3& targetModelSpace) override; + const glm::dvec3& targetModelSpace) override; private: // Globes. These are renderables inserted in a distance switch so that the heavier diff --git a/modules/globebrowsing/meshes/basicgrid.h b/modules/globebrowsing/meshes/basicgrid.h index efcceff7c1..4edc91bcb5 100644 --- a/modules/globebrowsing/meshes/basicgrid.h +++ b/modules/globebrowsing/meshes/basicgrid.h @@ -45,7 +45,7 @@ public: * \param useNormals determines whether or not to upload any vertex normal data * to the GPU. */ - BasicGrid(unsigned int xSegments, unsigned int ySegments, + BasicGrid(unsigned int xSegments, unsigned int ySegments, TriangleSoup::Positions usePositions, TriangleSoup::TextureCoordinates useTextureCoordinates, TriangleSoup::Normals useNormals); diff --git a/modules/globebrowsing/meshes/grid.h b/modules/globebrowsing/meshes/grid.h index 8c4372e1c6..4465eda9ad 100644 --- a/modules/globebrowsing/meshes/grid.h +++ b/modules/globebrowsing/meshes/grid.h @@ -62,7 +62,7 @@ public: protected: /** - * Should return the indices of vertices for a grid with size xSegments * + * Should return the indices of vertices for a grid with size xSegments * ySegments. Where the number of vertices in each direction is the number * of segments + 1. */ diff --git a/modules/globebrowsing/other/distanceswitch.h b/modules/globebrowsing/other/distanceswitch.h index 45d9a6bd3c..2a3d63271b 100644 --- a/modules/globebrowsing/other/distanceswitch.h +++ b/modules/globebrowsing/other/distanceswitch.h @@ -38,7 +38,7 @@ namespace openspace { namespace openspace::globebrowsing { /** - * Selects a specific Renderable to be used for rendering, based on distance to the + * Selects a specific Renderable to be used for rendering, based on distance to the * camera */ class DistanceSwitch { @@ -49,7 +49,7 @@ public: bool deinitialize(); /** - * Picks the first Renderable with the associated maxDistance greater than the + * Picks the first Renderable with the associated maxDistance greater than the * current distance to the camera */ void render(const RenderData& data, RendererTasks& rendererTask); diff --git a/modules/globebrowsing/other/lruthreadpool.h b/modules/globebrowsing/other/lruthreadpool.h index 99ea554d47..359c74349c 100644 --- a/modules/globebrowsing/other/lruthreadpool.h +++ b/modules/globebrowsing/other/lruthreadpool.h @@ -43,7 +43,7 @@ template class LRUThreadPool; template class LRUThreadPoolWorker { -public: +public: LRUThreadPoolWorker(LRUThreadPool& pool); void operator()(); private: diff --git a/modules/globebrowsing/other/pixelbuffer.h b/modules/globebrowsing/other/pixelbuffer.h index 7cde0ab2ff..4765fbf2eb 100644 --- a/modules/globebrowsing/other/pixelbuffer.h +++ b/modules/globebrowsing/other/pixelbuffer.h @@ -116,7 +116,7 @@ public: void unbind(); /** - * \returns true of the buffer is mapped, otherwise false + * \returns true of the buffer is mapped, otherwise false */ bool isMapped() const; diff --git a/modules/globebrowsing/rendering/chunkrenderer.cpp b/modules/globebrowsing/rendering/chunkrenderer.cpp index 06dce09b32..a35c59ef99 100644 --- a/modules/globebrowsing/rendering/chunkrenderer.cpp +++ b/modules/globebrowsing/rendering/chunkrenderer.cpp @@ -143,7 +143,7 @@ void ChunkRenderer::setCommonUniforms(ghoul::opengl::ProgramObject& programObjec } if (chunk.owner().generalProperties().useAccurateNormals && - !_layerManager->layerGroup(layergroupid::HeightLayers).activeLayers().empty()) + !_layerManager->layerGroup(layergroupid::HeightLayers).activeLayers().empty()) { glm::dvec3 corner00 = chunk.owner().ellipsoid().cartesianSurfacePosition( chunk.surfacePatch().getCorner(Quad::SOUTH_WEST)); diff --git a/modules/globebrowsing/rendering/gpu/gpuchunktile.h b/modules/globebrowsing/rendering/gpu/gpuchunktile.h index e94536ecd7..7d5c1d3c3b 100644 --- a/modules/globebrowsing/rendering/gpu/gpuchunktile.h +++ b/modules/globebrowsing/rendering/gpu/gpuchunktile.h @@ -45,15 +45,15 @@ public: /** * Sets the value of ChunkTile to its corresponding - * GPU struct. OBS! Users must ensure bind has been + * GPU struct. OBS! Users must ensure bind has been * called before setting using this method. */ void setValue(ghoul::opengl::ProgramObject* programObject, const ChunkTile& chunkTile); - /** - * Binds GLSL variables with identifiers starting with - * nameBase within the provided shader program with this object. + /** + * Binds GLSL variables with identifiers starting with + * nameBase within the provided shader program with this object. * After this method has been called, users may invoke setValue. */ void bind(ghoul::opengl::ProgramObject* programObject, const std::string& nameBase); diff --git a/modules/globebrowsing/rendering/gpu/gpuchunktilepile.h b/modules/globebrowsing/rendering/gpu/gpuchunktilepile.h index be896aa15a..a7e1bf15a2 100644 --- a/modules/globebrowsing/rendering/gpu/gpuchunktilepile.h +++ b/modules/globebrowsing/rendering/gpu/gpuchunktilepile.h @@ -45,18 +45,18 @@ public: /** * Sets the value of ChunkTilePile to its corresponding - * GPU struct. OBS! Users must ensure bind has been + * GPU struct. OBS! Users must ensure bind has been * called before setting using this method. */ void setValue(ghoul::opengl::ProgramObject* programObject, const ChunkTilePile& chunkTilePile); - /** - * Binds this object with GLSL variables with identifiers starting + /** + * Binds this object with GLSL variables with identifiers starting * with nameBase within the provided shader program. * After this method has been called, users may invoke setValue. */ - void bind(ghoul::opengl::ProgramObject* programObject, const std::string& nameBase, + void bind(ghoul::opengl::ProgramObject* programObject, const std::string& nameBase, int pileSize); /** * Deactivates any TextureUnits assigned by this object. diff --git a/modules/globebrowsing/rendering/gpu/gpuheightlayer.h b/modules/globebrowsing/rendering/gpu/gpuheightlayer.h index c0b25b308f..48d61db381 100644 --- a/modules/globebrowsing/rendering/gpu/gpuheightlayer.h +++ b/modules/globebrowsing/rendering/gpu/gpuheightlayer.h @@ -49,14 +49,14 @@ public: /** * Sets the value of Layer to its corresponding - * GPU struct. OBS! Users must ensure bind has been + * GPU struct. OBS! Users must ensure bind has been * called before setting using this method. */ virtual void setValue(ghoul::opengl::ProgramObject* programObject, const Layer& layer, const TileIndex& tileIndex, int pileSize) override; - /** - * Binds this object with GLSL variables with identifiers starting + /** + * Binds this object with GLSL variables with identifiers starting * with nameBase within the provided shader program. * After this method has been called, users may invoke setValue. */ diff --git a/modules/globebrowsing/rendering/gpu/gpulayer.h b/modules/globebrowsing/rendering/gpu/gpulayer.h index 6e4f737a9e..7603544dde 100644 --- a/modules/globebrowsing/rendering/gpu/gpulayer.h +++ b/modules/globebrowsing/rendering/gpu/gpulayer.h @@ -48,14 +48,14 @@ public: /** * Sets the value of Layer to its corresponding - * GPU struct. OBS! Users must ensure bind has been + * GPU struct. OBS! Users must ensure bind has been * called before setting using this method. */ virtual void setValue(ghoul::opengl::ProgramObject* programObject, const Layer& layer, const TileIndex& tileIndex, int pileSize); - /** - * Binds this object with GLSL variables with identifiers starting + /** + * Binds this object with GLSL variables with identifiers starting * with nameBase within the provided shader program. * After this method has been called, users may invoke setValue. */ diff --git a/modules/globebrowsing/rendering/gpu/gpulayergroup.cpp b/modules/globebrowsing/rendering/gpu/gpulayergroup.cpp index f73e2ab2ec..dc55b69019 100644 --- a/modules/globebrowsing/rendering/gpu/gpulayergroup.cpp +++ b/modules/globebrowsing/rendering/gpu/gpulayergroup.cpp @@ -58,7 +58,7 @@ void GPULayerGroup::bind(ghoul::opengl::ProgramObject* programObject, for (size_t i = 0; i < _gpuActiveLayers.size(); ++i) { // should maybe a proper GPULayer factory _gpuActiveLayers[i] = (category == layergroupid::GroupID::HeightLayers) ? - std::make_unique() : + std::make_unique() : std::make_unique(); std::string nameExtension = "[" + std::to_string(i) + "]."; _gpuActiveLayers[i]->bind( diff --git a/modules/globebrowsing/rendering/gpu/gpulayergroup.h b/modules/globebrowsing/rendering/gpu/gpulayergroup.h index d94c9daa32..ff186929be 100644 --- a/modules/globebrowsing/rendering/gpu/gpulayergroup.h +++ b/modules/globebrowsing/rendering/gpu/gpulayergroup.h @@ -55,14 +55,14 @@ public: /** * Sets the value of LayerGroup to its corresponding - * GPU struct. OBS! Users must ensure bind has been + * GPU struct. OBS! Users must ensure bind has been * called before setting using this method. */ virtual void setValue(ghoul::opengl::ProgramObject* programObject, const LayerGroup& layerGroup, const TileIndex& tileIndex); - /** - * Binds this object with GLSL variables with identifiers starting + /** + * Binds this object with GLSL variables with identifiers starting * with nameBase within the provided shader program. * After this method has been called, users may invoke setValue. */ diff --git a/modules/globebrowsing/rendering/gpu/gpulayermanager.cpp b/modules/globebrowsing/rendering/gpu/gpulayermanager.cpp index 475b744462..f3d0ea2e51 100644 --- a/modules/globebrowsing/rendering/gpu/gpulayermanager.cpp +++ b/modules/globebrowsing/rendering/gpu/gpulayermanager.cpp @@ -29,7 +29,7 @@ namespace openspace::globebrowsing { void GPULayerManager::setValue(ghoul::opengl::ProgramObject* programObject, - const LayerManager& layerManager, + const LayerManager& layerManager, const TileIndex& tileIndex) { auto layerGroups = layerManager.layerGroups(); diff --git a/modules/globebrowsing/rendering/gpu/gpulayermanager.h b/modules/globebrowsing/rendering/gpu/gpulayermanager.h index 8c6f237da7..bc196cc742 100644 --- a/modules/globebrowsing/rendering/gpu/gpulayermanager.h +++ b/modules/globebrowsing/rendering/gpu/gpulayermanager.h @@ -45,14 +45,14 @@ public: /** * Sets the value of LayerGroup to its corresponding - * GPU struct. OBS! Users must ensure bind has been + * GPU struct. OBS! Users must ensure bind has been * called before setting using this method. */ virtual void setValue(ghoul::opengl::ProgramObject* programObject, const LayerManager& layerManager, const TileIndex& tileIndex); - /** - * Binds this object with GLSL variables with identifiers starting + /** + * Binds this object with GLSL variables with identifiers starting * with nameBase within the provided shader program. * After this method has been called, users may invoke setValue. */ diff --git a/modules/globebrowsing/rendering/gpu/gpulayerrendersettings.h b/modules/globebrowsing/rendering/gpu/gpulayerrendersettings.h index 6b2c1c4f04..ddaafcaa18 100644 --- a/modules/globebrowsing/rendering/gpu/gpulayerrendersettings.h +++ b/modules/globebrowsing/rendering/gpu/gpulayerrendersettings.h @@ -42,14 +42,14 @@ class GPULayerRenderSettings{ public: /** * Sets the value of LayerRenderSettings to its corresponding - * GPU struct. OBS! Users must ensure bind has been + * GPU struct. OBS! Users must ensure bind has been * called before setting using this method. */ void setValue(ghoul::opengl::ProgramObject* programObject, const LayerRenderSettings& layerSettings); - /** - * Binds this object with GLSL variables with identifiers starting + /** + * Binds this object with GLSL variables with identifiers starting * with nameBase within the provided shader program. * After this method has been called, users may invoke setValue. */ diff --git a/modules/globebrowsing/rendering/gpu/gputiledepthtransform.h b/modules/globebrowsing/rendering/gpu/gputiledepthtransform.h index 79065249c1..9de5a3d776 100644 --- a/modules/globebrowsing/rendering/gpu/gputiledepthtransform.h +++ b/modules/globebrowsing/rendering/gpu/gputiledepthtransform.h @@ -42,15 +42,15 @@ class GPUTileDepthTransform { public: /** * Sets the value of TileDepthTransform to its corresponding - * GPU struct. OBS! Users must ensure bind has been + * GPU struct. OBS! Users must ensure bind has been * called before setting using this method. */ void setValue(ghoul::opengl::ProgramObject* programObject, const TileDepthTransform& depthTransform); - /** - * Binds GLSL variables with identifiers starting with - * nameBase within the provided shader program with this object. + /** + * Binds GLSL variables with identifiers starting with + * nameBase within the provided shader program with this object. * After this method has been called, users may invoke setValue. */ void bind(ghoul::opengl::ProgramObject* programObject, diff --git a/modules/globebrowsing/rendering/gpu/gputileuvtransform.h b/modules/globebrowsing/rendering/gpu/gputileuvtransform.h index fb52dcaa33..9245742aff 100644 --- a/modules/globebrowsing/rendering/gpu/gputileuvtransform.h +++ b/modules/globebrowsing/rendering/gpu/gputileuvtransform.h @@ -42,15 +42,15 @@ class GPUTileUvTransform { public: /** * Sets the value of TileUvTransform to its corresponding - * GPU struct. OBS! Users must ensure bind has been + * GPU struct. OBS! Users must ensure bind has been * called before setting using this method. */ void setValue(ghoul::opengl::ProgramObject* programObject, const TileUvTransform& uvTransform); - /** - * Binds GLSL variables with identifiers starting with - * nameBase within the provided shader program with this object. + /** + * Binds GLSL variables with identifiers starting with + * nameBase within the provided shader program with this object. * After this method has been called, users may invoke setValue. */ void bind(ghoul::opengl::ProgramObject* programObject, diff --git a/modules/globebrowsing/rendering/layer/layer.cpp b/modules/globebrowsing/rendering/layer/layer.cpp index 7a970cf579..23a27a63f7 100644 --- a/modules/globebrowsing/rendering/layer/layer.cpp +++ b/modules/globebrowsing/rendering/layer/layer.cpp @@ -223,7 +223,7 @@ ChunkTilePile Layer::getChunkTilePile(const TileIndex& tileIndex, int pileSize) if (_tileProvider) { return _tileProvider->getChunkTilePile(tileIndex, pileSize); } - else { + else { ChunkTilePile chunkTilePile; chunkTilePile.resize(pileSize); for (int i = 0; i < pileSize; ++i) { @@ -350,7 +350,7 @@ void Layer::initializeBasedOnType(layergroupid::TypeID typeId, ghoul::Dictionary if (tileProviderInitDict.hasKeyAndValue(keyName)) { std::string name; tileProviderInitDict.getValue(keyName, name); - LDEBUG("Initializing tile provider for layer: '" + name + "'"); + LDEBUG("Initializing tile provider for layer: '" + name + "'"); } _tileProvider = std::shared_ptr( tileprovider::TileProvider::createFromDictionary(typeId, tileProviderInitDict) diff --git a/modules/globebrowsing/tile/pixelregion.cpp b/modules/globebrowsing/tile/pixelregion.cpp index df6d7a83a1..fabd02f3a7 100644 --- a/modules/globebrowsing/tile/pixelregion.cpp +++ b/modules/globebrowsing/tile/pixelregion.cpp @@ -31,7 +31,7 @@ namespace openspace::globebrowsing { PixelRegion::PixelRegion(const PixelCoordinate& pixelStart, const PixelRange& numberOfPixels) : start(pixelStart) - , numPixels(numberOfPixels) + , numPixels(numberOfPixels) {} PixelRegion::PixelRegion(const PixelRegion& o) @@ -91,20 +91,20 @@ void PixelRegion::align(Side side, int pos) { } } -void PixelRegion::alignLeft(int x) { - start.x = x; +void PixelRegion::alignLeft(int x) { + start.x = x; } -void PixelRegion::alignTop(int y) { - start.y = y; +void PixelRegion::alignTop(int y) { + start.y = y; } -void PixelRegion::alignRight(int x) { - start.x = x - numPixels.x; +void PixelRegion::alignRight(int x) { + start.x = x - numPixels.x; } -void PixelRegion::alignBottom(int y) { - start.y = y - numPixels.y; +void PixelRegion::alignBottom(int y) { + start.y = y - numPixels.y; } void PixelRegion::scale(const glm::dvec2& s) { diff --git a/modules/globebrowsing/tile/pixelregion.h b/modules/globebrowsing/tile/pixelregion.h index c597365443..018d67b294 100644 --- a/modules/globebrowsing/tile/pixelregion.h +++ b/modules/globebrowsing/tile/pixelregion.h @@ -58,7 +58,7 @@ struct PixelRegion { void setBottom(int y); /** - * Aligns one the sides of the pixel regino to the specified position. This does + * Aligns one the sides of the pixel regino to the specified position. This does * not change the number of pixels within the region. * * Example: Side = left and pos = 16: diff --git a/modules/globebrowsing/tile/rawtiledatareader/gdalrawtiledatareader.cpp b/modules/globebrowsing/tile/rawtiledatareader/gdalrawtiledatareader.cpp index a53f36092e..66fd37cc96 100644 --- a/modules/globebrowsing/tile/rawtiledatareader/gdalrawtiledatareader.cpp +++ b/modules/globebrowsing/tile/rawtiledatareader/gdalrawtiledatareader.cpp @@ -167,8 +167,8 @@ RawTile::ReadError GdalRawTileDataReader::rasterRead( char* dataDest = dataDestination; // GDAL reads pixels top to bottom, but we want our pixels bottom to top. - // Therefore, we increment the destination pointer to the last line on in the - // buffer, and the we specify in the rasterIO call that we want negative line + // Therefore, we increment the destination pointer to the last line on in the + // buffer, and the we specify in the rasterIO call that we want negative line // spacing. Doing this compensates the flipped Y axis dataDest += (io.write.totalNumBytes - io.write.bytesPerLine); diff --git a/modules/globebrowsing/tile/rawtiledatareader/gdalrawtiledatareader.h b/modules/globebrowsing/tile/rawtiledatareader/gdalrawtiledatareader.h index a4211de38d..78a2cfea5d 100644 --- a/modules/globebrowsing/tile/rawtiledatareader/gdalrawtiledatareader.h +++ b/modules/globebrowsing/tile/rawtiledatareader/gdalrawtiledatareader.h @@ -55,7 +55,7 @@ class GdalRawTileDataReader : public RawTileDataReader { public: /** - * Opens a GDALDataset in readonly mode and calculates meta data required for + * Opens a GDALDataset in readonly mode and calculates meta data required for * reading tile using a TileIndex. * * \param filePath, a path to a specific file GDAL can read @@ -103,7 +103,7 @@ private: /** * Use as a helper function when determining the maximum tile level. This function * returns the negated number of overviews requred to downscale the highest overview - * dataset so that it fits within minimumPixelSize pixels in the x-dimension. + * dataset so that it fits within minimumPixelSize pixels in the x-dimension. */ int calculateTileLevelDifference(int minimumPixelSize) const; diff --git a/modules/globebrowsing/tile/rawtiledatareader/rawtiledatareader.cpp b/modules/globebrowsing/tile/rawtiledatareader/rawtiledatareader.cpp index bf29c170c0..e40233e187 100644 --- a/modules/globebrowsing/tile/rawtiledatareader/rawtiledatareader.cpp +++ b/modules/globebrowsing/tile/rawtiledatareader/rawtiledatareader.cpp @@ -373,15 +373,15 @@ RawTile::ReadError RawTileDataReader::repeatedRasterRead( { RawTile::ReadError worstError = RawTile::ReadError::None; - // NOTE: - // Ascii graphics illustrates the implementation details of this method, for one - // specific case. Even though the illustrated case is specific, readers can + // NOTE: + // Ascii graphics illustrates the implementation details of this method, for one + // specific case. Even though the illustrated case is specific, readers can // hopefully find it useful to get the general idea. // Make a copy of the full IO desription as we will have to modify it IODescription io = fullIO; - // Example: + // Example: // We have an io description that defines a WRITE and a READ region. // In this case the READ region extends outside of the defined io.read.fullRegion, // meaning we will have to perform wrapping @@ -389,12 +389,12 @@ RawTile::ReadError RawTileDataReader::repeatedRasterRead( // io.write.region io.read.region // | | // V V - // +-------+ +-------+ - // | | | |--------+ + // +-------+ +-------+ + // | | | |--------+ // | | | | | // | | | | | // +-------+ +-------+ | - // | | <-- io.read.fullRegion + // | | <-- io.read.fullRegion // | | // +--------------+ @@ -402,27 +402,27 @@ RawTile::ReadError RawTileDataReader::repeatedRasterRead( // Loop through each side: left, top, right, bottom for (int i = 0; i < 4; ++i) { - // Example: + // Example: // We are currently considering the left side of the pixel region PixelRegion::Side side = static_cast(i); IODescription cutoff = io.cut(side, io.read.fullRegion.edge(side)); - // Example: + // Example: // We cut off the left part that was outside the io.read.fullRegion, and we - // now have an additional io description for the cut off region. - // Note that the cut-method used above takes care of the corresponding + // now have an additional io description for the cut off region. + // Note that the cut-method used above takes care of the corresponding // WRITE region for us. // cutoff.write.region cutoff.read.region // | io.write.region | io.read.region // | | | | // V V V V - // +-+-----+ +-+-----+ + // +-+-----+ +-+-----+ // | | | | | |--------+ // | | | | | | | // | | | | | | | // +-+-----+ +-+-----+ | - // | | <-- io.read.fullRegion + // | | <-- io.read.fullRegion // | | // +--------------+ @@ -435,7 +435,7 @@ RawTile::ReadError RawTileDataReader::repeatedRasterRead( // Example: // The cut off region is wrapped to the opposite side of the region, - // i.e. "repeated". Note that we don't want WRITE region to change, + // i.e. "repeated". Note that we don't want WRITE region to change, // we're only wrapping the READ region. // cutoff.write.region io.read.region cutoff.read.region @@ -443,15 +443,15 @@ RawTile::ReadError RawTileDataReader::repeatedRasterRead( // | | V V // V V +-----+ +-+ // +-+-----+ | |------| | - // | | | | | | | + // | | | | | | | // | | | | | | | // | | | +-----+ +-+ - // +-+-----+ | | <-- io.read.fullRegion + // +-+-----+ | | <-- io.read.fullRegion // | | // +--------------+ // Example: - // The cutoff region has been repeated along one of its sides, but + // The cutoff region has been repeated along one of its sides, but // as we can see in this example, it still has a top part outside the // defined gdal region. This is handled through recursion. RawTile::ReadError err = repeatedRasterRead( diff --git a/modules/globebrowsing/tile/rawtiledatareader/tiledatatype.cpp b/modules/globebrowsing/tile/rawtiledatareader/tiledatatype.cpp index 9c3da72259..ff2811e1ab 100644 --- a/modules/globebrowsing/tile/rawtiledatareader/tiledatatype.cpp +++ b/modules/globebrowsing/tile/rawtiledatareader/tiledatatype.cpp @@ -138,7 +138,7 @@ TextureFormat getTextureFormat(int rasterCount, GDALDataType gdalType) { // No representation of 64 bit float? //case GDT_Float64: // format.glFormat = GL_RED; - // break; + // break; default: LERROR("GDAL data type unknown to OpenGL: " << gdalType); } @@ -192,7 +192,7 @@ TextureFormat getTextureFormat(int rasterCount, GDALDataType gdalType) { case GDT_Float32: format.glFormat = GL_RGB32F; break; - // No representation of 64 bit float? + // No representation of 64 bit float? //case GDT_Float64: // format.glFormat = GL_RED; // break; @@ -224,7 +224,7 @@ TextureFormat getTextureFormat(int rasterCount, GDALDataType gdalType) { // No representation of 64 bit float? //case GDT_Float64: // format.glFormat = GL_RED; - // break; + // break; default: LERROR("GDAL data type unknown to OpenGL: " << gdalType); } @@ -264,7 +264,7 @@ TextureFormat getTextureFormatOptimized(int rasterCount, GDALDataType gdalType) // No representation of 64 bit float? //case GDT_Float64: // format.glFormat = GL_RED; - // break; + // break; default: LERROR("GDAL data type unknown to OpenGL: " << gdalType); } @@ -306,7 +306,7 @@ TextureFormat getTextureFormatOptimized(int rasterCount, GDALDataType gdalType) case GDT_UInt16: format.glFormat = GL_RGB16UI; break; - case GDT_Int16: + case GDT_Int16: format.glFormat = GL_RGB16_SNORM; break; case GDT_UInt32: @@ -318,7 +318,7 @@ TextureFormat getTextureFormatOptimized(int rasterCount, GDALDataType gdalType) case GDT_Float32: format.glFormat = GL_RGB32F; break; - // No representation of 64 bit float? + // No representation of 64 bit float? //case GDT_Float64: // format.glFormat = GL_RED; // break; @@ -350,7 +350,7 @@ TextureFormat getTextureFormatOptimized(int rasterCount, GDALDataType gdalType) // No representation of 64 bit float? //case GDT_Float64: // format.glFormat = GL_RED; - // break; + // break; default: LERROR("GDAL data type unknown to OpenGL: " << gdalType); } diff --git a/modules/globebrowsing/tile/tileindex.cpp b/modules/globebrowsing/tile/tileindex.cpp index b3e8e856ec..992e2dce67 100644 --- a/modules/globebrowsing/tile/tileindex.cpp +++ b/modules/globebrowsing/tile/tileindex.cpp @@ -112,7 +112,7 @@ int TileIndex::manhattan(const TileIndex& other) const { } // Creates a hash which can be used as key in hash maps. -// +// // +-------+------------+-------+------------+ // | USAGE | BIT RANGE | #BITS | MAX VALUE | // +-------+------------+-------+------------+ diff --git a/modules/globebrowsing/tile/tileloadjob.h b/modules/globebrowsing/tile/tileloadjob.h index 515ca97472..21c60a56b2 100644 --- a/modules/globebrowsing/tile/tileloadjob.h +++ b/modules/globebrowsing/tile/tileloadjob.h @@ -46,7 +46,7 @@ struct TileLoadJob : public Job { /** * No data is allocated unless specified so by the TileTextureInitData of * rawTileDataReader but it is assumed that pboDataPtr is a mapped pointer to a pixel - * buffer object. + * buffer object. */ TileLoadJob(std::shared_ptr rawTileDataReader, const TileIndex& tileIndex, char* pboDataPtr); diff --git a/modules/globebrowsing/tile/tileprovider/defaulttileprovider.cpp b/modules/globebrowsing/tile/tileprovider/defaulttileprovider.cpp index fb1222f649..3b72e93b68 100644 --- a/modules/globebrowsing/tile/tileprovider/defaulttileprovider.cpp +++ b/modules/globebrowsing/tile/tileprovider/defaulttileprovider.cpp @@ -70,7 +70,7 @@ namespace { namespace openspace::globebrowsing::tileprovider { -DefaultTileProvider::DefaultTileProvider(const ghoul::Dictionary& dictionary) +DefaultTileProvider::DefaultTileProvider(const ghoul::Dictionary& dictionary) : TileProvider(dictionary) , _filePath(FilePathInfo, "") , _tilePixelSize(TilePixelSizeInfo, 32, 32, 2048) @@ -97,7 +97,7 @@ DefaultTileProvider::DefaultTileProvider(const ghoul::Dictionary& dictionary) int tilePixelSize = 0; if (dictionary.getValue(KeyTilePixelSize, pixelSize)) { LDEBUG("Default pixel size overridden: " << pixelSize); - tilePixelSize = static_cast(pixelSize); + tilePixelSize = static_cast(pixelSize); } _padTiles = true; diff --git a/modules/globebrowsing/tile/tileprovider/defaulttileprovider.h b/modules/globebrowsing/tile/tileprovider/defaulttileprovider.h index 83447d8e8e..9e7a8540a6 100644 --- a/modules/globebrowsing/tile/tileprovider/defaulttileprovider.h +++ b/modules/globebrowsing/tile/tileprovider/defaulttileprovider.h @@ -41,7 +41,7 @@ namespace openspace::globebrowsing { namespace openspace::globebrowsing::tileprovider { /** -* Provides tiles loaded by AsyncTileDataProvider and +* Provides tiles loaded by AsyncTileDataProvider and * caches them in memory using LRU caching */ class DefaultTileProvider : public TileProvider { @@ -52,8 +52,8 @@ public: virtual ~DefaultTileProvider() override; /** - * \returns a Tile with status OK iff it exists in in-memory - * cache. If not, it may enqueue some IO operations on a + * \returns a Tile with status OK iff it exists in in-memory + * cache. If not, it may enqueue some IO operations on a * separate thread. */ virtual Tile getTile(const TileIndex& tileIndex) override; @@ -68,7 +68,7 @@ public: private: /** * Collects all asynchronously downloaded RawTile - * and uses createTile to create Tiles, + * and uses createTile to create Tiles, * which are put in the LRU cache - potentially pushing out outdated * Tiles. */ diff --git a/modules/globebrowsing/tile/tileprovider/temporaltileprovider.cpp b/modules/globebrowsing/tile/tileprovider/temporaltileprovider.cpp index a482fdaa17..858d625e98 100644 --- a/modules/globebrowsing/tile/tileprovider/temporaltileprovider.cpp +++ b/modules/globebrowsing/tile/tileprovider/temporaltileprovider.cpp @@ -61,7 +61,7 @@ const char* TemporalTileProvider::TemporalXMLTags::TIME_RESOLUTION = "OpenSpaceTimeResolution"; const char* TemporalTileProvider::TemporalXMLTags::TIME_FORMAT = "OpenSpaceTimeIdFormat"; -TemporalTileProvider::TemporalTileProvider(const ghoul::Dictionary& dictionary) +TemporalTileProvider::TemporalTileProvider(const ghoul::Dictionary& dictionary) : _initDict(dictionary) , _filePath(FilePathInfo) , _successfulInitialization(false) @@ -99,7 +99,7 @@ TemporalTileProvider::TemporalTileProvider(const ghoul::Dictionary& dictionary) else { LERROR("Unable to read file " + _filePath.value()); _successfulInitialization = false; - } + } } bool TemporalTileProvider::readFilePath() { @@ -210,7 +210,7 @@ std::string TemporalTileProvider::getXMLValue(CPLXMLNode* root, const std::strin TileDepthTransform TemporalTileProvider::depthTransform() { if (_successfulInitialization) { ensureUpdated(); - return _currentTileProvider->depthTransform(); + return _currentTileProvider->depthTransform(); } else { return { 1.0f, 0.0f}; @@ -402,7 +402,7 @@ TimeFormat* TimeIdProviderFactory::getProvider(const std::string& format) { init(); } ghoul_assert( - _timeIdProviderMap.find(format) != _timeIdProviderMap.end(), + _timeIdProviderMap.find(format) != _timeIdProviderMap.end(), "Unsupported Time format: " + format ); return _timeIdProviderMap[format].get(); diff --git a/modules/globebrowsing/tile/tileprovider/temporaltileprovider.h b/modules/globebrowsing/tile/tileprovider/temporaltileprovider.h index f14289e3bb..e8c37f8d9b 100644 --- a/modules/globebrowsing/tile/tileprovider/temporaltileprovider.h +++ b/modules/globebrowsing/tile/tileprovider/temporaltileprovider.h @@ -50,7 +50,7 @@ namespace openspace::globebrowsing::tileprovider { * Interface for stringifying OpenSpace Time instances. * * Once OpenSpace has a proper Time format class, this should be handled by that instead - * of here. + * of here. */ struct TimeFormat { virtual ~TimeFormat() = default; @@ -110,7 +110,7 @@ struct YYYY_MM_DDThh_mm_ssZ : public TimeFormat { /** * Static factory class for providing different TimeFormats. * A time format stringifier is retrieved by a name of the format. - * See implementation of init() to see what time + * See implementation of init() to see what time * id formats are supported. */ struct TimeIdProviderFactory { @@ -122,7 +122,7 @@ struct TimeIdProviderFactory { * See implementation of init() for supported time formats. * * \param format - name of TimeFormat, eg "YYYY-MM-DDThh:mm:ssZ". - * \returns a concrete TimeFormat used to stringify instances of Time + * \returns a concrete TimeFormat used to stringify instances of Time */ static TimeFormat* getProvider(const std::string& format); @@ -136,7 +136,7 @@ struct TimeIdProviderFactory { }; /** - * Used to quantize time to descrete values. + * Used to quantize time to descrete values. */ struct TimeQuantizer { TimeQuantizer() {} @@ -144,13 +144,13 @@ struct TimeQuantizer { TimeQuantizer(const Time& start, const Time& end, const std::string& resolutionStr); /** - * Takes a time resulition string and parses it into a double + * Takes a time resulition string and parses it into a double * value representing the time resolution as seconds. * * Example: parseTimeResolutionStr("1d"); - * + * * \param resoltutionStr with the format {number}{unit} - * where supported units are: + * where supported units are: * (s)econds, (m)inutes, (h)ours, (d)ays, (y)ears * * \returns the time resolution in seconds @@ -186,12 +186,12 @@ private: * Provide Tiles from web map services that have temporal resolution. * * TemporalTileProviders are instantiated using a ghoul::Dictionary, - * and must define a filepath to a Openspace Temporal dataset description file. + * and must define a filepath to a Openspace Temporal dataset description file. * This is an xml-file that defines the same meta data as the GDAL wms description - * (http://www.gdal.org/frmt_wms.html), but augmented with some - * extra tags describing the temporal properties of the dataset. See + * (http://www.gdal.org/frmt_wms.html), but augmented with some + * extra tags describing the temporal properties of the dataset. See * TemporalTileProvider::TemporalXMLTags - * + * */ class TemporalTileProvider : public TileProvider { public: @@ -218,7 +218,7 @@ public: private: /** - * A placeholder string that must be provided in the WMS template url. This + * A placeholder string that must be provided in the WMS template url. This * placeholder will be replaced by quantized date-time strings during run time * in order to access the datasets for different instances of time. */ @@ -243,8 +243,8 @@ private: static const char* TIME_END; /** - * Tag should contain the time resolution of the dataset. - * The resolution is defined by a number along with a unit specifying how + * Tag should contain the time resolution of the dataset. + * The resolution is defined by a number along with a unit specifying how * often the dataset is updated temporally. Supported units are: * (s)econds, (m)inutes, (h)ours, (d)ays, (y)ears. * @@ -255,7 +255,7 @@ private: /** * Tag should contain a string specifying the date-time format expected by the - * WMS. + * WMS. */ static const char* TIME_FORMAT; }; @@ -275,12 +275,12 @@ private: std::string getGdalDatasetXML(TimeKey key); /** - * Instantiates a new TileProvder for the temporal dataset at the time - * specified. - * + * Instantiates a new TileProvder for the temporal dataset at the time + * specified. + * * This method replaced the URL_TIME_PLACEHOLDER in the template URL * with the provided timekey, the opens a new GDAL dataset with that URL. - * + * * \param timekey time specifying dataset's temporality * \returns newly instantiated TileProvider */ @@ -288,14 +288,14 @@ private: /** * Takes as input a Openspace Temporal dataset description, extracts the temporal - * metadata provided by reading the TemporalXMLTags, removes the - * read tags from the description, and returns a GDAL template GDAL dataset - * description. The template GDAL dataset description has the a + * metadata provided by reading the TemporalXMLTags, removes the + * read tags from the description, and returns a GDAL template GDAL dataset + * description. The template GDAL dataset description has the a * URL_TIME_PLACEHOLDER still in it, which needs to be replaced before * GDAL can open it as a GDALDataset. * * \param xml Openspace Temporal dataset description - * \returns a GDAL template data description. + * \returns a GDAL template data description. */ std::string consumeTemporalMetaData(const std::string &xml); diff --git a/modules/globebrowsing/tile/tileprovider/texttileprovider.h b/modules/globebrowsing/tile/tileprovider/texttileprovider.h index 5382762f98..c7ee2661e5 100644 --- a/modules/globebrowsing/tile/tileprovider/texttileprovider.h +++ b/modules/globebrowsing/tile/tileprovider/texttileprovider.h @@ -40,9 +40,9 @@ namespace ghoul::fontrendering { namespace openspace::globebrowsing::tileprovider { /** - * Enables a simple way of providing tiles with any type of rendered text. - * Internally it handles setting up a FBO for rendering the text, and defines a new - * interface, consisting of only a single method for subclasses to implement: + * Enables a simple way of providing tiles with any type of rendered text. + * Internally it handles setting up a FBO for rendering the text, and defines a new + * interface, consisting of only a single method for subclasses to implement: * renderText(const FontRenderer&, const TileIndex&) const; */ class TextTileProvider : public TileProvider { @@ -62,7 +62,7 @@ public: virtual int maxLevel() override; /** - * Allow overriding of hash function. + * Allow overriding of hash function. * Default is TileIndex::hashKey() * * \param tileIndex tileIndex to hash @@ -71,9 +71,9 @@ public: virtual TileIndex::TileHashKey toHash(const TileIndex& tileIndex) const; /** - * Uses the fontRenderer to render some text onto the tile texture provided in - * backgroundTile(const TileIndex& tileIndex). - * + * Uses the fontRenderer to render some text onto the tile texture provided in + * backgroundTile(const TileIndex& tileIndex). + * * \param fontRenderer used for rendering text onto texture * \param tileIndex associated with the tile to be rendered onto */ diff --git a/modules/globebrowsing/tile/tileprovider/tileprovider.cpp b/modules/globebrowsing/tile/tileprovider/tileprovider.cpp index f67bf3022e..98e54247a5 100644 --- a/modules/globebrowsing/tile/tileprovider/tileprovider.cpp +++ b/modules/globebrowsing/tile/tileprovider/tileprovider.cpp @@ -84,7 +84,7 @@ ChunkTile TileProvider::getChunkTile(TileIndex tileIndex, int parents, int maxPa } maxParents -= parents; - // Step 2. Traverse 0 or more parents up the chunkTree to make sure we're inside + // Step 2. Traverse 0 or more parents up the chunkTree to make sure we're inside // the range of defined data. int maximumLevel = maxLevel(); while (tileIndex.level > maximumLevel){ @@ -95,8 +95,8 @@ ChunkTile TileProvider::getChunkTile(TileIndex tileIndex, int parents, int maxPa return ChunkTile{ Tile::TileUnavailable, uvTransform, TileDepthTransform() }; } - // Step 3. Traverse 0 or more parents up the chunkTree until we find a chunk that - // has a loaded tile ready to use. + // Step 3. Traverse 0 or more parents up the chunkTree until we find a chunk that + // has a loaded tile ready to use. while (tileIndex.level > 1) { Tile tile = getTile(tileIndex); if (tile.status() != Tile::Status::OK) { diff --git a/modules/globebrowsing/tile/tileprovider/tileprovider.h b/modules/globebrowsing/tile/tileprovider/tileprovider.h index 59cb47a10c..1b6550d20c 100644 --- a/modules/globebrowsing/tile/tileprovider/tileprovider.h +++ b/modules/globebrowsing/tile/tileprovider/tileprovider.h @@ -39,14 +39,14 @@ namespace openspace::globebrowsing::tileprovider { /** - * Interface for providing Tiles given a - * TileIndex. + * Interface for providing Tiles given a + * TileIndex. */ class TileProvider : public properties::PropertyOwner { public: /** - * Factory method for instantiating different implementations of - * TileProviders. The provided dictionary must + * Factory method for instantiating different implementations of + * TileProviders. The provided dictionary must * define a key specifying what implementation of TileProvider * to be instantiated. */ @@ -54,15 +54,15 @@ public: layergroupid::TypeID layerTypeID, const ghoul::Dictionary& dictionary); - /** - * Default constructor. + /** + * Default constructor. */ TileProvider(); /** - * Implementations of the TileProvider interface must implement - * a constructor taking a dictionary as input. The provided - * dictionary must define a key specifying what implementation + * Implementations of the TileProvider interface must implement + * a constructor taking a dictionary as input. The provided + * dictionary must define a key specifying what implementation * of TileProvider to be instantiated. */ TileProvider(const ghoul::Dictionary& dictionary); @@ -80,16 +80,16 @@ public: * Method for querying tiles, given a specified TileIndex. * * This method is expected to be invoked multiple times per frame, - * and should therefore return quickly, e.g. not perform heavy I/O + * and should therefore return quickly, e.g. not perform heavy I/O * operations. However, invoking this method may spawn separate threads - * to perform such operations. Therefore, programmers shoud - * note that there is no guarantee that the Tile + * to perform such operations. Therefore, programmers shoud + * note that there is no guarantee that the Tile * status and texture will be consistent over different invocations * of this method. - * - * \param tileIndex specifying a region of a map for which + * + * \param tileIndex specifying a region of a map for which * we want tile data. - * + * * \returns The tile corresponding to the TileIndex by the time * the method was invoked. */ @@ -113,7 +113,7 @@ public: /** * Get the associated depth transform for this TileProvider. - * This is necessary for TileProviders serving height map + * This is necessary for TileProviders serving height map * data, in order to correcly map pixel values to meters. */ virtual TileDepthTransform depthTransform() = 0; @@ -125,8 +125,8 @@ public: virtual void update() = 0; /** - * Provides a uniform way of all TileProviders to reload or - * restore all of its internal state. This is mainly useful + * Provides a uniform way of all TileProviders to reload or + * restore all of its internal state. This is mainly useful * for debugging purposes. */ virtual void reset() = 0; @@ -145,7 +145,7 @@ public: /** * \returns a unique identifier for the TileProvider<\code>. All * TileProviders<\code> have an ID starting at 0 from the first created. - * The maximum number of unique identifiers is UINT_MAX + * The maximum number of unique identifiers is UINT_MAX */ unsigned int uniqueIdentifier() const; diff --git a/modules/imgui/src/gui.cpp b/modules/imgui/src/gui.cpp index 30f8941616..e3bd6d3db6 100644 --- a/modules/imgui/src/gui.cpp +++ b/modules/imgui/src/gui.cpp @@ -233,7 +233,7 @@ void addScreenSpaceRenderableOnline(std::string texturePath) { OsEng.scriptEngine().queueScript(script, openspace::scripting::ScriptEngine::RemoteScripting::Yes); } -} // namespace +} // namespace namespace openspace::gui { @@ -243,7 +243,7 @@ void CaptionText(const char* text) { ImGui::PopFont(); } -GUI::GUI() +GUI::GUI() : GuiComponent("Main") , _globalProperty("Global") , _property( @@ -388,7 +388,7 @@ void GUI::initialize() { _featuredProperties.setHasRegularProperties(true); _virtualProperty.initialize(); _filePath.initialize(); -#ifdef GLOBEBROWSING_USE_GDAL +#ifdef GLOBEBROWSING_USE_GDAL _globeBrowsing.initialize(); #endif // GLOBEBROWSING_USE_GDAL _performance.initialize(); @@ -396,7 +396,7 @@ void GUI::initialize() { _parallel.initialize(); _mission.initialize(); #ifdef OPENSPACE_MODULE_ISWA_ENABLED - _iswa.initialize(); + _iswa.initialize(); #endif // OPENSPACE_MODULE_ISWA_ENABLED } @@ -493,7 +493,7 @@ void GUI::initializeGL() { _globalProperty.initializeGL(); _featuredProperties.initializeGL(); _performance.initializeGL(); - _help.initializeGL(); + _help.initializeGL(); #ifdef GLOBEBROWSING_USE_GDAL _globeBrowsing.initializeGL(); #endif // GLOBEBROWSING_USE_GDAL @@ -644,7 +644,7 @@ bool GUI::keyCallback(Key key, KeyModifier modifier, KeyAction action) { const bool consumeEvent = io.WantCaptureKeyboard; if (consumeEvent) { if (action == KeyAction::Press) { - io.KeysDown[keyIndex] = true; + io.KeysDown[keyIndex] = true; } io.KeyShift = hasShift; io.KeyCtrl = hasCtrl; diff --git a/modules/imgui/src/guipropertycomponent.cpp b/modules/imgui/src/guipropertycomponent.cpp index 05e4dd7145..14f9fbe798 100644 --- a/modules/imgui/src/guipropertycomponent.cpp +++ b/modules/imgui/src/guipropertycomponent.cpp @@ -317,7 +317,7 @@ void GuiPropertyComponent::render() { if (header()) { renderPropertyOwner(pOwner); - } + } }; if (!_currentUseTreeLayout || noGuiGroups) { diff --git a/modules/imgui/src/guispacetimecomponent.cpp b/modules/imgui/src/guispacetimecomponent.cpp index 31266675d8..7ccb55bba3 100644 --- a/modules/imgui/src/guispacetimecomponent.cpp +++ b/modules/imgui/src/guispacetimecomponent.cpp @@ -100,8 +100,8 @@ void GuiSpaceTimeComponent::render() { nodeNames += n->name() + '\0'; } - auto iCurrentFocus = std::find(nodes.begin(), nodes.end(), currentFocus); - if (!nodes.empty()) { + auto iCurrentFocus = std::find(nodes.begin(), nodes.end(), currentFocus); + if (!nodes.empty()) { // Only check if we found the current focus node if we have any nodes at all // only then it would be a real error ghoul_assert(iCurrentFocus != nodes.end(), "Focus node not found"); diff --git a/modules/iswa/rendering/datacygnet.cpp b/modules/iswa/rendering/datacygnet.cpp index 4cd2dff370..dfa24757a1 100644 --- a/modules/iswa/rendering/datacygnet.cpp +++ b/modules/iswa/rendering/datacygnet.cpp @@ -124,10 +124,10 @@ bool DataCygnet::updateTexture(){ if (!_textures[option]) { auto texture = std::make_unique( - values, + values, _textureDimensions, ghoul::opengl::Texture::Format::Red, - GL_RED, + GL_RED, GL_FLOAT, ghoul::opengl::Texture::FilterMode::Linear, ghoul::opengl::Texture::WrappingMode::ClampToEdge @@ -308,7 +308,7 @@ void DataCygnet::setPropertyCallbacks(){ _backgroundValues.setValue(_dataProcessor->filterValues()); }); - _dataOptions.onChange([this](){ + _dataOptions.onChange([this](){ if(_dataOptions.value().size() > MAX_TEXTURES) LWARNING("Too many options chosen, max is " + std::to_string(MAX_TEXTURES)); updateTexture(); @@ -327,7 +327,7 @@ void DataCygnet::subscribeToGroup(){ std::vector values; bool success = dict.getValue >("dataOptions", values); if(success){ - _dataOptions.setValue(values); + _dataOptions.setValue(values); } }); @@ -336,7 +336,7 @@ void DataCygnet::subscribeToGroup(){ glm::vec2 values; bool success = dict.getValue("normValues", values); if(success){ - _normValues.setValue(values); + _normValues.setValue(values); } }); @@ -345,7 +345,7 @@ void DataCygnet::subscribeToGroup(){ glm::vec2 values; bool success = dict.getValue("backgroundValues", values); if(success){ - _backgroundValues.setValue(values); + _backgroundValues.setValue(values); } }); diff --git a/modules/iswa/rendering/datacygnet.h b/modules/iswa/rendering/datacygnet.h index 89f5375607..f75726c802 100644 --- a/modules/iswa/rendering/datacygnet.h +++ b/modules/iswa/rendering/datacygnet.h @@ -51,7 +51,7 @@ protected: /** * loads the transferfunctions specified in tfPath into * _transferFunctions list. - * + * * @param tfPath Path to transfer function file */ void readTransferFunctions(std::string tfPath); @@ -99,7 +99,7 @@ protected: properties::BoolProperty _useHistogram; properties::BoolProperty _autoFilter; - std::shared_ptr _dataProcessor; + std::shared_ptr _dataProcessor; std::string _dataBuffer; glm::size3_t _textureDimensions; diff --git a/modules/iswa/rendering/dataplane.cpp b/modules/iswa/rendering/dataplane.cpp index 550bf44cf3..bc03293756 100644 --- a/modules/iswa/rendering/dataplane.cpp +++ b/modules/iswa/rendering/dataplane.cpp @@ -35,7 +35,7 @@ namespace openspace { DataPlane::DataPlane(const ghoul::Dictionary& dictionary) :DataCygnet(dictionary) -{ +{ _programName = "DataPlaneProgram"; _vsPath = "${MODULE_ISWA}/shaders/dataplane_vs.glsl"; _fsPath = "${MODULE_ISWA}/shaders/dataplane_fs.glsl"; @@ -54,13 +54,13 @@ void DataPlane::initialize() { //If autofiler is on, background values property should be hidden _autoFilter.onChange([this]() { - // If autofiler is selected, use _dataProcessor to set backgroundValues + // If autofiler is selected, use _dataProcessor to set backgroundValues // and unregister backgroundvalues property. if (_autoFilter.value()) { _backgroundValues.setValue(_dataProcessor->filterValues()); _backgroundValues.setVisibility(properties::Property::Visibility::Hidden); //_backgroundValues.setVisible(false); - // else if autofilter is turned off, register backgroundValues + // else if autofilter is turned off, register backgroundValues } else { _backgroundValues.setVisibility(properties::Property::Visibility::All); //_backgroundValues.setVisible(true); diff --git a/modules/iswa/rendering/dataplane.h b/modules/iswa/rendering/dataplane.h index 960d0db7b4..250bbc1748 100644 --- a/modules/iswa/rendering/dataplane.h +++ b/modules/iswa/rendering/dataplane.h @@ -30,7 +30,7 @@ namespace openspace { /** - * DataPlane is a concrete IswaCygnet with data files as its input source. + * DataPlane is a concrete IswaCygnet with data files as its input source. * The class handles creation, destruction and rendering of a plane geometry. * It also specifies what uniforms to use and what GUI properties it needs. */ diff --git a/modules/iswa/rendering/datasphere.cpp b/modules/iswa/rendering/datasphere.cpp index 527e191674..ddf7d98326 100644 --- a/modules/iswa/rendering/datasphere.cpp +++ b/modules/iswa/rendering/datasphere.cpp @@ -67,13 +67,13 @@ void DataSphere::initialize() { _dataProcessor = std::make_shared(); //If autofiler is on, background values property should be hidden _autoFilter.onChange([this]() { - // If autofiler is selected, use _dataProcessor to set backgroundValues + // If autofiler is selected, use _dataProcessor to set backgroundValues // and unregister backgroundvalues property. if (_autoFilter.value()) { _backgroundValues.setValue(_dataProcessor->filterValues()); _backgroundValues.setVisibility(properties::Property::Visibility::Hidden); //_backgroundValues.setVisible(false); - // else if autofilter is turned off, register backgroundValues + // else if autofilter is turned off, register backgroundValues } else { _backgroundValues.setVisibility(properties::Property::Visibility::All); //_backgroundValues.setVisible(true); diff --git a/modules/iswa/rendering/datasphere.h b/modules/iswa/rendering/datasphere.h index dff23ca92e..f635350b48 100644 --- a/modules/iswa/rendering/datasphere.h +++ b/modules/iswa/rendering/datasphere.h @@ -32,7 +32,7 @@ namespace openspace { class PowerScaledSphere; /** - * DataSphere is a concrete IswaCygnet with data files as its input source. + * DataSphere is a concrete IswaCygnet with data files as its input source. * The class handles creation, destruction and rendering of a sphere geometry. * It also specifies what uniforms to use and what GUI properties it needs. */ @@ -57,6 +57,6 @@ protected: float _radius; }; -} // namespace openspace +} // namespace openspace #endif // __OPENSPACE_MODULE_ISWA___DATASPHERE___H__ diff --git a/modules/iswa/rendering/iswabasegroup.cpp b/modules/iswa/rendering/iswabasegroup.cpp index 2201a57f77..efe81edf7e 100644 --- a/modules/iswa/rendering/iswabasegroup.cpp +++ b/modules/iswa/rendering/iswabasegroup.cpp @@ -63,7 +63,7 @@ namespace openspace { IswaBaseGroup::IswaBaseGroup(std::string name, std::string type) : properties::PropertyOwner({ std::move(name) }) - , _enabled(EnabledInfo, true) + , _enabled(EnabledInfo, true) , _alpha(AlphaInfo, 0.9f, 0.f, 1.f) , _delete(DeleteInfo) , _registered(false) @@ -100,8 +100,8 @@ std::shared_ptr IswaBaseGroup::dataProcessor(){ return _dataProcessor; } -std::shared_ptr > IswaBaseGroup::groupEvent(){ - return _groupEvent; +std::shared_ptr > IswaBaseGroup::groupEvent() { + return _groupEvent; }; @@ -119,12 +119,12 @@ void IswaBaseGroup::registerProperties(){ _delete.onChange([this]{ clearGroup(); - }); + }); - _registered = true; + _registered = true; } -void IswaBaseGroup::unregisterProperties(){ +void IswaBaseGroup::unregisterProperties() { _registered = false; } diff --git a/modules/iswa/rendering/iswacygnet.h b/modules/iswa/rendering/iswacygnet.h index b9ecf2c7bb..b7fa75dc35 100644 --- a/modules/iswa/rendering/iswacygnet.h +++ b/modules/iswa/rendering/iswacygnet.h @@ -88,7 +88,7 @@ protected: void initializeTime(); void initializeGroup(); /** - * Creates the shader program. Concrete IswaCygnets must set + * Creates the shader program. Concrete IswaCygnets must set * _vsPath, _fsPath and _programName before this function in called. * @return true if successful creation */ @@ -113,7 +113,7 @@ protected: */ virtual bool updateTextureResource() = 0; /** - * should send a http request to get the resource it needs to create + * should send a http request to get the resource it needs to create * a texture. For Texture cygnets, this should be an image. For DataCygnets, * this should be the data file. * @return true if update was successfull diff --git a/modules/iswa/rendering/iswadatagroup.cpp b/modules/iswa/rendering/iswadatagroup.cpp index 8ff483a794..ed39c58bce 100644 --- a/modules/iswa/rendering/iswadatagroup.cpp +++ b/modules/iswa/rendering/iswadatagroup.cpp @@ -85,7 +85,7 @@ namespace { namespace openspace{ IswaDataGroup::IswaDataGroup(std::string name, std::string type) - : IswaBaseGroup(name, type) + : IswaBaseGroup(name, type) , _useLog(UseLogInfo, false) , _useHistogram(UseHistogramInfo, false) , _autoFilter(AutoFilterInfo, true) @@ -133,13 +133,13 @@ void IswaDataGroup::registerProperties(){ //If autofiler is on, background values property should be hidden _autoFilter.onChange([this](){ LDEBUG("Group " + name() + " published autoFilterChanged"); - // If autofiler is selected, use _dataProcessor to set backgroundValues + // If autofiler is selected, use _dataProcessor to set backgroundValues // and unregister backgroundvalues property. if(_autoFilter.value()){ _backgroundValues.setValue(_dataProcessor->filterValues()); _backgroundValues.setVisibility(properties::Property::Visibility::Hidden); //_backgroundValues.setVisible(false); - // else if autofilter is turned off, register backgroundValues + // else if autofilter is turned off, register backgroundValues } else { _backgroundValues.setVisibility(properties::Property::Visibility::All); //_backgroundValues.setVisible(true); diff --git a/modules/iswa/rendering/kameleonplane.cpp b/modules/iswa/rendering/kameleonplane.cpp index a6807f59f5..12f0ecf14c 100644 --- a/modules/iswa/rendering/kameleonplane.cpp +++ b/modules/iswa/rendering/kameleonplane.cpp @@ -57,7 +57,7 @@ namespace openspace { KameleonPlane::KameleonPlane(const ghoul::Dictionary& dictionary) : DataCygnet(dictionary) - , _fieldlines(FieldLineSeedsInfo) + , _fieldlines(FieldLineSeedsInfo) , _resolution(ResolutionInfo, 100.f, 10.f, 200.f) , _slice(SliceInfo, 0.f, 0.f, 1.f) { @@ -124,13 +124,13 @@ void KameleonPlane::initialize() { //If autofiler is on, background values property should be hidden _autoFilter.onChange([this](){ - // If autofiler is selected, use _dataProcessor to set backgroundValues + // If autofiler is selected, use _dataProcessor to set backgroundValues // and unregister backgroundvalues property. if (_autoFilter) { _backgroundValues.setValue(_dataProcessor->filterValues()); _backgroundValues.setVisibility(properties::Property::Visibility::Hidden); //_backgroundValues.setVisible(false); - // else if autofilter is turned off, register backgroundValues + // else if autofilter is turned off, register backgroundValues } else { _backgroundValues.setVisibility(properties::Property::Visibility::All); //_backgroundValues.setVisible(true); @@ -160,7 +160,7 @@ void KameleonPlane::initialize() { updateTextureResource(); }); - _fieldlines.onChange([this](){ + _fieldlines.onChange([this](){ updateFieldlineSeeds(); }); @@ -354,7 +354,7 @@ void KameleonPlane::subscribeToGroup() { void KameleonPlane::setDimensions() { // the cdf files has an offset of 0.5 in normali resolution. - // with lower resolution the offset increases. + // with lower resolution the offset increases. _data->offset = _origOffset - 0.5f*(100.0f/_resolution.value()); _dimensions = glm::size3_t(_data->scale*((float)_resolution.value()/100.f)); _dimensions[_cut] = 1; diff --git a/modules/iswa/rendering/kameleonplane.h b/modules/iswa/rendering/kameleonplane.h index 544cdb4a6c..8fc3f3874c 100644 --- a/modules/iswa/rendering/kameleonplane.h +++ b/modules/iswa/rendering/kameleonplane.h @@ -31,7 +31,7 @@ namespace openspace { /** - * KameleonPlane is a concrete IswaCygnet with volume data files from + * KameleonPlane is a concrete IswaCygnet with volume data files from * disk as input source. An object of this class will provide a cutplane * through a volume of space weather data. It will also give the option * to create fieldlines around and intersecting the planes. Interaction @@ -53,23 +53,23 @@ private: */ bool createGeometry() override; bool destroyGeometry() override; - bool updateTextureResource() override; + bool updateTextureResource() override; void renderGeometry() const override; void setUniforms() override; std::vector textureData() override; void setDimensions(); /** - * Given a path to the json index of seedpoints file, this + * Given a path to the json index of seedpoints file, this * method reads, parses and adds them as checkbox options * in the _fieldlines SelectionProperty - * + * * @param indexFile Path to json index file */ void readFieldlinePaths(std::string indexFile); /** - * Updates the _fieldlineState map to match the _fieldlines + * Updates the _fieldlineState map to match the _fieldlines * SelectionProperty and creates or removes fieldlines in the scene. */ void updateFieldlineSeeds(); @@ -92,7 +92,7 @@ private: glm::vec3 _origOffset; /** - * _fieldlineState maps the checkbox value of each fieldline seedpoint file to a tuple + * _fieldlineState maps the checkbox value of each fieldline seedpoint file to a tuple * containing information that is needed to either add or remove a fieldline from the scenegraph. * this is the name, path to seedpoints file and a boolean to determine if it is active or inactive. */ diff --git a/modules/iswa/rendering/texturecygnet.cpp b/modules/iswa/rendering/texturecygnet.cpp index 1dc59af620..ea235dd086 100644 --- a/modules/iswa/rendering/texturecygnet.cpp +++ b/modules/iswa/rendering/texturecygnet.cpp @@ -34,17 +34,18 @@ namespace openspace { TextureCygnet::TextureCygnet(const ghoul::Dictionary& dictionary) : IswaCygnet(dictionary) -{ +{ registerProperties(); } TextureCygnet::~TextureCygnet() {} bool TextureCygnet::updateTexture() { - std::unique_ptr texture = ghoul::io::TextureReader::ref().loadTexture( - (void*) _imageFile.buffer, - _imageFile.size, - _imageFile.format); + auto texture = ghoul::io::TextureReader::ref().loadTexture( + (void*) _imageFile.buffer, + _imageFile.size, + _imageFile.format + ); if (texture) { LDEBUG("Loaded texture from image iswa cygnet with id: '" << _data->id << "'"); diff --git a/modules/iswa/rendering/texturecygnet.h b/modules/iswa/rendering/texturecygnet.h index 151cbdb96a..a53b052cd2 100644 --- a/modules/iswa/rendering/texturecygnet.h +++ b/modules/iswa/rendering/texturecygnet.h @@ -32,7 +32,7 @@ namespace openspace { /** * This class exist to abstract away the loading of images * from iSWA and updating of the textures for child geometries. - * The class specifies the minimum interface that child classes + * The class specifies the minimum interface that child classes * needs to implement. */ class TextureCygnet : public IswaCygnet { diff --git a/modules/iswa/rendering/textureplane.h b/modules/iswa/rendering/textureplane.h index 5ebae5c00b..768c20732b 100644 --- a/modules/iswa/rendering/textureplane.h +++ b/modules/iswa/rendering/textureplane.h @@ -31,7 +31,7 @@ namespace openspace { /** * TexturePlane is a "concrete" IswaCygnet with texture as its input source. - * It handles the creation, destruction and rendering of a plane geometry. + * It handles the creation, destruction and rendering of a plane geometry. * It also specifies which shaders to use and the uniforms that it needs. */ class TexturePlane : public TextureCygnet{ diff --git a/modules/iswa/util/dataprocessor.cpp b/modules/iswa/util/dataprocessor.cpp index 1c224c1d7a..98663d863b 100644 --- a/modules/iswa/util/dataprocessor.cpp +++ b/modules/iswa/util/dataprocessor.cpp @@ -97,7 +97,7 @@ float DataProcessor::processDataPoint(float value, int option) { } float DataProcessor::normalizeWithStandardScore(float value, float mean, float sd, - glm::vec2 normalizationValues) + glm::vec2 normalizationValues) { float zScoreMin = normalizationValues.x; //10.0f;//_normValues.x; float zScoreMax = normalizationValues.y; //10.0f;//_normValues.y; @@ -105,25 +105,25 @@ float DataProcessor::normalizeWithStandardScore(float value, float mean, float s // Clamp intresting values standardScore = glm::clamp(standardScore, -zScoreMin, zScoreMax); //return and normalize - return ( standardScore + zScoreMin )/(zScoreMin + zScoreMax ); + return ( standardScore + zScoreMin )/(zScoreMin + zScoreMax ); } float DataProcessor::unnormalizeWithStandardScore(float standardScore, float mean, float sd, glm::vec2 normalizationValues) { float zScoreMin = normalizationValues.x; - float zScoreMax = normalizationValues.y; + float zScoreMax = normalizationValues.y; float value = standardScore*(zScoreMax+zScoreMin)-zScoreMin; - value = value*sd+mean; + value = value*sd+mean; - // std::cout << value << std::endl; + // std::cout << value << std::endl; return value; // float standardScore = ( value - mean ) / sd; // // Clamp intresting values // standardScore = glm::clamp(standardScore, -zScoreMin, zScoreMax); // //return and normalize - // return ( standardScore + zScoreMin )/(zScoreMin + zScoreMax ); + // return ( standardScore + zScoreMin )/(zScoreMin + zScoreMax ); } void DataProcessor::initializeVectors(int numOptions){ @@ -179,7 +179,7 @@ void DataProcessor::calculateFilterValues(std::vector selectedOptions) { _filterValues += glm::vec2(filterMid, filterWidth); } - _filterValues /= numSelected; + _filterValues /= numSelected; } } @@ -230,7 +230,7 @@ void DataProcessor::add(std::vector>& optionValues, //unnormalize histMin, histMax // min = std::min(min, histMin) std::shared_ptr newHist = std::make_shared( - std::min(min, normalizeWithStandardScore(unNormHistMin, mean, _standardDeviation[i], _histNormValues)), + std::min(min, normalizeWithStandardScore(unNormHistMin, mean, _standardDeviation[i], _histNormValues)), std::min(max, normalizeWithStandardScore(unNormHistMax, mean, _standardDeviation[i], _histNormValues)), numBins ); diff --git a/modules/iswa/util/dataprocessor.h b/modules/iswa/util/dataprocessor.h index 923bae21b0..8c3dec76ac 100644 --- a/modules/iswa/util/dataprocessor.h +++ b/modules/iswa/util/dataprocessor.h @@ -66,7 +66,7 @@ protected: glm::vec2 _normValues; glm::vec2 _filterValues; - std::vector _min; + std::vector _min; std::vector _max; std::vector _sum; std::vector _standardDeviation; diff --git a/modules/iswa/util/dataprocessorjson.cpp b/modules/iswa/util/dataprocessorjson.cpp index 8b21e67eda..880b721af8 100644 --- a/modules/iswa/util/dataprocessorjson.cpp +++ b/modules/iswa/util/dataprocessorjson.cpp @@ -100,10 +100,13 @@ void DataProcessorJson::addDataValues(std::string data, properties::SelectionPro } } -std::vector DataProcessorJson::processData(std::string data, properties::SelectionProperty& dataOptions, glm::size3_t& dimensions){ - if(!data.empty()){ +std::vector DataProcessorJson::processData(std::string data, + properties::SelectionProperty& dataOptions, + glm::size3_t& dimensions) +{ + if (!data.empty()) { json j = json::parse(data); - json variables = j["variables"]; + json variables = j["variables"]; std::vector selectedOptions = dataOptions.value(); // int numSelected = selectedOptions.size(); diff --git a/modules/iswa/util/dataprocessorkameleon.cpp b/modules/iswa/util/dataprocessorkameleon.cpp index 6615b33af0..7864999e13 100644 --- a/modules/iswa/util/dataprocessorkameleon.cpp +++ b/modules/iswa/util/dataprocessorkameleon.cpp @@ -52,10 +52,10 @@ std::vector DataProcessorKameleon::readMetadata(std::string path, g std::vector opts = _kw->getVariables(); opts.erase( std::remove_if( - opts.begin(), - opts.end(), + opts.begin(), + opts.end(), [this](std::string opt){ return (opt.size() > 3 || _coordinateVariables.find(opt) != _coordinateVariables.end());} - ), + ), opts.end() ); return opts; @@ -100,7 +100,7 @@ void DataProcessorKameleon::addDataValues(std::string path, properties::Selectio } std::vector DataProcessorKameleon::processData(std::string path, properties::SelectionProperty& dataOptions, glm::size3_t& dimensions, float slice){ _slice = slice; - // _dimensions = dimensions; + // _dimensions = dimensions; return processData(path, dataOptions, dimensions); } diff --git a/modules/iswa/util/dataprocessortext.cpp b/modules/iswa/util/dataprocessortext.cpp index 4e461b77df..11f8f85bfc 100644 --- a/modules/iswa/util/dataprocessortext.cpp +++ b/modules/iswa/util/dataprocessortext.cpp @@ -86,7 +86,7 @@ std::vector DataProcessorText::readMetadata(std::string data, glm:: } void DataProcessorText::addDataValues(std::string data, properties::SelectionProperty& dataOptions){ - int numOptions = dataOptions.options().size(); + int numOptions = dataOptions.options().size(); initializeVectors(numOptions); if(!data.empty()){ @@ -185,13 +185,13 @@ std::vector DataProcessorText::processData(std::string data, properties: // ); // for(int option : selectedOptions){ - // value = values[option]; + // value = values[option]; // //value = values[option+3]; //+3 because options x, y and z in the file // dataOptions[option][numValues] = processDataPoint(value, option); // } // ----------- OLD METHODS ------------------------ -// first = 0; +// first = 0; last = 0; option = -3; lineSize = line.size(); @@ -202,8 +202,12 @@ std::vector DataProcessorText::processData(std::string data, properties: last = line.find_first_of(" \t", first); last = (last > 0)? last : lineSize; - if (option >= 0 && std::find(selectedOptions.begin(), selectedOptions.end(), option) != selectedOptions.end()){ - // boost::spirit::qi::parse(&line[first], &line[last], boost::spirit::qi::float_, value); + auto it = std::find( + selectedOptions.begin(), + selectedOptions.end(), + option + ); + if (option >= 0 && it != selectedOptions.end()) { value = std::stof(line.substr(first, last)); dataOptions[option][numValues] = processDataPoint(value, option); } diff --git a/modules/iswa/util/iswamanager.cpp b/modules/iswa/util/iswamanager.cpp index 7c0f472585..60f58d2f5b 100644 --- a/modules/iswa/util/iswamanager.cpp +++ b/modules/iswa/util/iswamanager.cpp @@ -140,7 +140,7 @@ void IswaManager::addIswaCygnet(int id, std::string type, std::string group) { } // This callback determines what geometry should be used and creates the right cygbet - auto metadataCallback = + auto metadataCallback = [this, metaFuture](const DownloadManager::MemoryFile& file) { //Create a string from downloaded file std::string res; @@ -201,7 +201,7 @@ std::future IswaManager::fetchImageCygnet(int id, d std::to_string(id) + ": " + err ); } - ) ); + ) ); } std::future IswaManager::fetchDataCygnet(int id, double timestamp) { @@ -219,7 +219,7 @@ std::future IswaManager::fetchDataCygnet(int id, do std::to_string(id) + ": " + err ); } - ) ); + ) ); } std::string IswaManager::iswaUrl(int id, double timestamp, std::string type) { @@ -228,15 +228,15 @@ std::string IswaManager::iswaUrl(int id, double timestamp, std::string type) { url = _baseUrl + type+"/" + std::to_string(-id) + "/"; } else { url = "http://iswa3.ccmc.gsfc.nasa.gov/IswaSystemWebApp/iSWACygnetStreamer?window=-1&cygnetId="+ std::to_string(id) +"×tamp="; - } + } - //std::string t = Time::ref().currentTimeUTC(); + //std::string t = Time::ref().currentTimeUTC(); std::string t = SpiceManager::ref().dateFromEphemerisTime(timestamp); std::stringstream ss(t); std::string token; std::getline(ss, token, ' '); - url += token + "-"; + url += token + "-"; std::getline(ss, token, ' '); url += _month[token] + "-"; std::getline(ss, token, 'T'); @@ -347,7 +347,7 @@ std::string IswaManager::jsonPlaneToLuaTable(std::shared_ptr dat std::string table = "{" "Name = '" + data->name +"' , " "Parent = '" + parent + "', " - "Renderable = {" + "Renderable = {" "Type = '" + _type[data->type] + _geom[data->geom] + "', " "Id = " + std::to_string(data->id) + ", " "Frame = '" + frame + "' , " @@ -396,8 +396,8 @@ std::string IswaManager::parseKWToLuaTable(CdfInfo info, std::string cut) { std::string table = "{" "Name = '" +info.name+ "'," - "Parent = '" + parent + "', " - "Renderable = {" + "Parent = '" + parent + "', " + "Renderable = {" "Type = 'KameleonPlane', " "Id = 0 ," "Frame = '" + frame + "' , " @@ -405,7 +405,7 @@ std::string IswaManager::parseKWToLuaTable(CdfInfo info, std::string cut) { "GridMax = " + std::to_string(max) + ", " "SpatialScale = " + std::to_string(spatialScale) + ", " "UpdateTime = 0, " - "kwPath = '" + info.path + "' ," + "kwPath = '" + info.path + "' ," "axisCut = '"+cut+"'," "CoordinateType = '" + coordinateType + "', " "Group = '"+ info.group + "'," @@ -413,7 +413,7 @@ std::string IswaManager::parseKWToLuaTable(CdfInfo info, std::string cut) { "fieldlineSeedsIndexFile = '"+info.fieldlineSeedsIndexFile+"'" "}" "}" - ; + ; return table; } } @@ -452,7 +452,7 @@ std::string IswaManager::jsonSphereToLuaTable(std::shared_ptr da std::string table = "{" "Name = '" + data->name +"' , " "Parent = '" + parent + "', " - "Renderable = {" + "Renderable = {" "Type = '" + _type[data->type] + _geom[data->geom] + "', " "Id = " + std::to_string(data->id) + ", " "Frame = '" + frame + "' , " @@ -648,7 +648,7 @@ void IswaManager::fillCygnetInfo(std::string jsonString) { }; _cygnetInformation[jCygnet["cygnetID"]] = std::make_shared(info); } - } + } } } diff --git a/modules/iswa/util/iswamanager.h b/modules/iswa/util/iswamanager.h index f12876031f..814582e1ab 100644 --- a/modules/iswa/util/iswamanager.h +++ b/modules/iswa/util/iswamanager.h @@ -64,7 +64,7 @@ namespace openspace { class IswaBaseGroup; -class IswaCygnet; +class IswaCygnet; struct CdfInfo { std::string name; diff --git a/modules/iswa/util/iswamanager_lua.inl b/modules/iswa/util/iswamanager_lua.inl index 53a4e7b304..4484d0bd7f 100644 --- a/modules/iswa/util/iswamanager_lua.inl +++ b/modules/iswa/util/iswamanager_lua.inl @@ -71,7 +71,7 @@ int iswa_addScreenSpaceCygnet(lua_State* L) { float id; d.getValue("CygnetId", id); - auto cygnetInformation = IswaManager::ref().cygnetInformation(); + auto cygnetInformation = IswaManager::ref().cygnetInformation(); if (cygnetInformation.find((int)id) == cygnetInformation.end()) { LWARNING("Could not find Cygnet with id = " + std::to_string(id)); return 0; @@ -131,7 +131,7 @@ int iswa_removeScrenSpaceCygnet(lua_State* L) { int id = static_cast(lua_tonumber(L, 1)); - auto cygnetInformation = IswaManager::ref().cygnetInformation(); + auto cygnetInformation = IswaManager::ref().cygnetInformation(); if (cygnetInformation.find(id) == cygnetInformation.end()) { LWARNING("Could not find Cygnet with id = " + std::to_string(id)); return 0; @@ -152,7 +152,7 @@ int iswa_removeGroup(lua_State* L) { std::string name = luaL_checkstring(L, -1); // IswaManager::ref().unregisterGroup(id); - auto groups = IswaManager::ref().groups(); + auto groups = IswaManager::ref().groups(); if (groups.find(name) != groups.end()) { groups[name]->clearGroup(); } @@ -171,7 +171,7 @@ int iswa_addKameleonPlanes(lua_State* L) { std::string group = luaL_checkstring(L, 1); int pos = static_cast(lua_tonumber(L, 2)); IswaManager::ref().addKameleonCdf(group, pos); - // auto cdfInfo = + // auto cdfInfo = return 0; } diff --git a/modules/kameleonvolume/rendering/renderablekameleonvolume.cpp b/modules/kameleonvolume/rendering/renderablekameleonvolume.cpp index d7dc43ab0d..b317796e1e 100644 --- a/modules/kameleonvolume/rendering/renderablekameleonvolume.cpp +++ b/modules/kameleonvolume/rendering/renderablekameleonvolume.cpp @@ -172,7 +172,9 @@ RenderableKameleonVolume::RenderableKameleonVolume(const ghoul::Dictionary& dict std::string transferFunctionPath; if (dictionary.getValue(KeyTransferFunction, transferFunctionPath)) { _transferFunctionPath = transferFunctionPath; - _transferFunction = std::make_shared(absPath(transferFunctionPath)); + _transferFunction = std::make_shared( + absPath(transferFunctionPath) + ); } std::string sourcePath; @@ -234,8 +236,14 @@ RenderableKameleonVolume::RenderableKameleonVolume(const ghoul::Dictionary& dict _cache = cache; } - _gridType.addOption(static_cast(volume::VolumeGridType::Cartesian), "Cartesian grid"); - _gridType.addOption(static_cast(volume::VolumeGridType::Spherical), "Spherical grid"); + _gridType.addOption( + static_cast(volume::VolumeGridType::Cartesian), + "Cartesian grid" + ); + _gridType.addOption( + static_cast(volume::VolumeGridType::Spherical), + "Spherical grid" + ); _gridType.setValue(static_cast(volume::VolumeGridType::Cartesian)); std::string gridType; @@ -256,7 +264,11 @@ void RenderableKameleonVolume::initialize() { _volumeTexture->uploadTexture(); _transferFunction->update(); - _raycaster = std::make_unique(_volumeTexture, _transferFunction, _clipPlanes); + _raycaster = std::make_unique( + _volumeTexture, + _transferFunction, + _clipPlanes + ); _raycaster->setStepSize(_stepSize); _gridType.onChange([this] { @@ -409,7 +421,12 @@ void RenderableKameleonVolume::loadCdf(const std::string& path) { } ghoul::Dictionary dict = reader.readMetaData(); - _rawVolume = reader.readFloatVolume(_dimensions, _variable, _lowerDomainBound, _upperDomainBound); + _rawVolume = reader.readFloatVolume( + _dimensions, + _variable, + _lowerDomainBound, + _upperDomainBound + ); updateTextureFromVolume(); } diff --git a/modules/kameleonvolume/tasks/kameleondocumentationtask.cpp b/modules/kameleonvolume/tasks/kameleondocumentationtask.cpp index c61581477b..80714452d0 100644 --- a/modules/kameleonvolume/tasks/kameleondocumentationtask.cpp +++ b/modules/kameleonvolume/tasks/kameleondocumentationtask.cpp @@ -38,7 +38,8 @@ namespace { const char* KeyInput = "Input"; const char* KeyOutput = "Output"; - const char* MainTemplateFilename = "${OPENSPACE_DATA}/web/kameleondocumentation/main.hbs"; + const char* MainTemplateFilename = + "${OPENSPACE_DATA}/web/kameleondocumentation/main.hbs"; const char* HandlebarsFilename = "${OPENSPACE_DATA}/web/common/handlebars-v4.0.5.js"; const char* JsFilename = "${OPENSPACE_DATA}/web/kameleondocumentation/script.js"; const char* BootstrapFilename = "${OPENSPACE_DATA}/web/common/bootstrap.min.css"; @@ -48,7 +49,8 @@ namespace { namespace openspace { namespace kameleonvolume { -KameleonDocumentationTask::KameleonDocumentationTask(const ghoul::Dictionary& dictionary) { +KameleonDocumentationTask::KameleonDocumentationTask(const ghoul::Dictionary& dictionary) +{ openspace::documentation::testSpecificationAndThrow( documentation(), dictionary, @@ -90,8 +92,16 @@ void KameleonDocumentationTask::perform(const Task::ProgressCallback & progressC std::string jsContent; std::back_insert_iterator jsInserter(jsContent); - std::copy(std::istreambuf_iterator{handlebarsInput}, std::istreambuf_iterator(), jsInserter); - std::copy(std::istreambuf_iterator{jsInput}, std::istreambuf_iterator(), jsInserter); + std::copy( + std::istreambuf_iterator{handlebarsInput}, + std::istreambuf_iterator(), + jsInserter + ); + std::copy( + std::istreambuf_iterator{jsInput}, + std::istreambuf_iterator(), + jsInserter + ); std::ifstream bootstrapInput(absPath(BootstrapFilename)); std::ifstream cssInput(absPath(CssFilename)); @@ -99,8 +109,16 @@ void KameleonDocumentationTask::perform(const Task::ProgressCallback & progressC std::string cssContent; std::back_insert_iterator cssInserter(cssContent); - std::copy(std::istreambuf_iterator{bootstrapInput}, std::istreambuf_iterator(), cssInserter); - std::copy(std::istreambuf_iterator{cssInput}, std::istreambuf_iterator(), cssInserter); + std::copy( + std::istreambuf_iterator{bootstrapInput}, + std::istreambuf_iterator(), + cssInserter + ); + std::copy( + std::istreambuf_iterator{cssInput}, + std::istreambuf_iterator(), + cssInserter + ); std::ifstream mainTemplateInput(absPath(MainTemplateFilename)); std::string mainTemplateContent{ std::istreambuf_iterator{mainTemplateInput}, diff --git a/modules/space/rendering/renderableplanet.cpp b/modules/space/rendering/renderableplanet.cpp index cad826fb14..d6c2853d11 100644 --- a/modules/space/rendering/renderableplanet.cpp +++ b/modules/space/rendering/renderableplanet.cpp @@ -279,9 +279,11 @@ RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary) sourceName, sourceRadius)); } else { - LWARNING("No Radius value expecified for Shadow Source Name " - << sourceName << " from " << name - << " planet.\nDisabling shadows for this planet."); + LWARNING( + "No Radius value expecified for Shadow Source Name " + << sourceName << " from " << name + << " planet.\nDisabling shadows for this planet." + ); disableShadows = true; break; } @@ -342,14 +344,14 @@ void RenderablePlanet::initialize() { "shadowNightProgram", "${MODULE_SPACE}/shaders/shadow_nighttexture_vs.glsl", "${MODULE_SPACE}/shaders/shadow_nighttexture_fs.glsl"); - } + } else if (_programObject == nullptr && _shadowEnabled) { // shadow program _programObject = renderEngine.buildRenderProgram( "shadowProgram", "${MODULE_SPACE}/shaders/shadow_vs.glsl", "${MODULE_SPACE}/shaders/shadow_fs.glsl"); - } + } else if (_programObject == nullptr && _hasNightTexture) { // Night texture program _programObject = renderEngine.buildRenderProgram( @@ -433,7 +435,7 @@ void RenderablePlanet::render(const RenderData& data, RendererTasks&) { _programObject->setUniform("transparency", _alpha); _programObject->setUniform( - "modelViewProjectionTransform", + "modelViewProjectionTransform", data.camera.projectionMatrix() * glm::mat4(modelViewTransform) ); _programObject->setUniform("ModelTransform", glm::mat4(modelTransform)); diff --git a/modules/space/rendering/renderableplanet.h b/modules/space/rendering/renderableplanet.h index 8ead4e4fe8..1dc59d2fc4 100644 --- a/modules/space/rendering/renderableplanet.h +++ b/modules/space/rendering/renderableplanet.h @@ -88,7 +88,7 @@ private: std::unique_ptr _programObject; std::unique_ptr _texture; - std::unique_ptr _nightTexture; + std::unique_ptr _nightTexture; std::unique_ptr _heightMapTexture; properties::FloatProperty _heightExaggeration; diff --git a/modules/space/rendering/renderablestars.cpp b/modules/space/rendering/renderablestars.cpp index 8912cd6129..df3489f73e 100644 --- a/modules/space/rendering/renderablestars.cpp +++ b/modules/space/rendering/renderablestars.cpp @@ -321,7 +321,7 @@ void RenderableStars::render(const RenderData& data, RendererTasks&) { // @Check overwriting the scaling from the camera; error as parsec->meter conversion // is done twice? ---abock - glm::vec2 scaling = glm::vec2(1, -19); + glm::vec2 scaling = glm::vec2(1, -19); glm::mat4 modelMatrix = glm::mat4(1.0); glm::mat4 viewMatrix = data.camera.viewMatrix(); diff --git a/modules/space/translation/keplertranslation.cpp b/modules/space/translation/keplertranslation.cpp index b2aa8bb9d3..309f597d06 100644 --- a/modules/space/translation/keplertranslation.cpp +++ b/modules/space/translation/keplertranslation.cpp @@ -220,7 +220,7 @@ KeplerTranslation::KeplerTranslation() addProperty(_period); } -KeplerTranslation::KeplerTranslation(const ghoul::Dictionary& dictionary) +KeplerTranslation::KeplerTranslation(const ghoul::Dictionary& dictionary) : KeplerTranslation() { documentation::testSpecificationAndThrow( diff --git a/modules/space/translation/tletranslation.h b/modules/space/translation/tletranslation.h index bdcc737cf8..fae1fab8fc 100644 --- a/modules/space/translation/tletranslation.h +++ b/modules/space/translation/tletranslation.h @@ -63,7 +63,7 @@ private: /** * Reads the provided TLE file and calles the KeplerTranslation::setKeplerElments * method with the correct values. If \p filename is a valid TLE file but contains - * disallowed values (see KeplerTranslation::setKeplerElements), a + * disallowed values (see KeplerTranslation::setKeplerElements), a * KeplerTranslation::RangeError is thrown. * \param filename The path to the file that contains the TLE file. * \param lineNum The line number in the file where the set of 3 TLE lines starts diff --git a/modules/spacecraftinstruments/rendering/renderablecrawlingline.cpp b/modules/spacecraftinstruments/rendering/renderablecrawlingline.cpp index 51d4014f91..45aa195974 100644 --- a/modules/spacecraftinstruments/rendering/renderablecrawlingline.cpp +++ b/modules/spacecraftinstruments/rendering/renderablecrawlingline.cpp @@ -196,7 +196,7 @@ void RenderableCrawlingLine::render(const RenderData& data, RendererTasks&) { data.camera.projectionMatrix() * glm::mat4(data.camera.combinedViewMatrix() * modelTransform - ) + ) ; //glm::dmat4 modelViewTransform = data.camera.combinedViewMatrix() * modelTransform; @@ -283,7 +283,7 @@ void RenderableCrawlingLine::update(const UpdateData& data) { glBindBuffer(GL_ARRAY_BUFFER, _vbo); glBufferSubData( - GL_ARRAY_BUFFER, + GL_ARRAY_BUFFER, 0, 2 * sizeof(VBOData), vboData diff --git a/modules/spacecraftinstruments/rendering/renderablefov.cpp b/modules/spacecraftinstruments/rendering/renderablefov.cpp index 2612b023fb..233b09549e 100644 --- a/modules/spacecraftinstruments/rendering/renderablefov.cpp +++ b/modules/spacecraftinstruments/rendering/renderablefov.cpp @@ -428,7 +428,7 @@ bool RenderableFov::isReady() const { // Orthogonal projection next to planets surface glm::dvec3 RenderableFov::orthogonalProjection(const glm::dvec3& vecFov, double time, - const std::string& target) const + const std::string& target) const { glm::dvec3 vecToTarget = SpiceManager::ref().targetPosition( target, @@ -714,13 +714,13 @@ void RenderableFov::computeIntercepts(const UpdateData& data, const std::string& const double t2 = 0.5 + bisect(half, jBound, intercepts); // - // The target is sticking out somewhere between i and j, so we + // The target is sticking out somewhere between i and j, so we // have three regions here: // The first (0,t1) and second (t2,1) are not intersecting // The third between (t1,t2) is intersecting // - // i p1 p2 j - // ***** + // i p1 p2 j + // ***** // x-------* *-------x // 0 t1 t2 1 @@ -806,7 +806,7 @@ void RenderableFov::computeIntercepts(const UpdateData& data, const std::string& // SpiceManager::ref().surfaceIntercept( // target, // _instrument.spacecraft, - // _instrument.name, + // _instrument.name, // bodyfixed, // _instrument.aberrationCorrection, // data.time, @@ -825,7 +825,7 @@ void RenderableFov::computeIntercepts(const UpdateData& data, const std::string& // bool intercepted = res.interceptFound; // if (intercepted) { - // // find the two outer most points of intersection + // // find the two outer most points of intersection // glm::dvec3 root1 = bisection(half, current, data.time, target); // glm::dvec3 root2 = bisection(half, next, data.time, target); @@ -1022,7 +1022,7 @@ void RenderableFov::computeIntercepts(const UpdateData& data, const std::string& if (interceptTag[i] == false) { // If point is non-interceptive, project it. insertPoint( _fovPlane, - glm::vec4(orthogonalProjection(current, data.time, target), 0.0), + glm::vec4(orthogonalProjection(current, data.time, target), 0.0), tmp ); _rebuild = true; @@ -1064,7 +1064,7 @@ void RenderableFov::computeIntercepts(const UpdateData& data, const std::string& bool intercepted = res.interceptFound; if (intercepted) { - // find the two outer most points of intersection + // find the two outer most points of intersection glm::dvec3 root1 = bisection(half, current, data.time, target); glm::dvec3 root2 = bisection(half, next, data.time, target); @@ -1122,7 +1122,7 @@ void RenderableFov::computeIntercepts(const UpdateData& data, const std::string& for (int j = 1; j <= InterpolationSteps; ++j) { float t = (static_cast(j) / InterpolationSteps); interpolated = interpolate(mid, next, t); - glm::dvec3 ivec = + glm::dvec3 ivec = (j > 1) ? checkForIntercept(interpolated, data.time, target) : orthogonalProjection(interpolated, data.time, target); @@ -1353,7 +1353,7 @@ void RenderableFov::updateGPU() { // ); //} //else { - // // new points - memory change + // // new points - memory change // glBindVertexArray(_orthogonalPlane.vao); // glBindBuffer(GL_ARRAY_BUFFER, _orthogonalPlane.vbo); // glBufferData( diff --git a/modules/spacecraftinstruments/rendering/renderablefov.h b/modules/spacecraftinstruments/rendering/renderablefov.h index 02bf625b42..b9c4fbae7e 100644 --- a/modules/spacecraftinstruments/rendering/renderablefov.h +++ b/modules/spacecraftinstruments/rendering/renderablefov.h @@ -116,7 +116,7 @@ private: float _interpolationTime; struct RenderInformation { - // Differentiating different vertex types + // Differentiating different vertex types using VertexColorType = int32_t; // This needs to be synced with the fov_vs.glsl shader static const VertexColorType VertexColorTypeDefaultStart = 0; diff --git a/modules/spacecraftinstruments/rendering/renderablemodelprojection.h b/modules/spacecraftinstruments/rendering/renderablemodelprojection.h index feb97b823b..e487c35b97 100644 --- a/modules/spacecraftinstruments/rendering/renderablemodelprojection.h +++ b/modules/spacecraftinstruments/rendering/renderablemodelprojection.h @@ -43,7 +43,7 @@ namespace ghoul::opengl { namespace openspace { -namespace documentation { struct Documentation; } +namespace documentation { struct Documentation; } struct RenderData; struct UpdateData; diff --git a/modules/spacecraftinstruments/rendering/renderableplaneprojection.cpp b/modules/spacecraftinstruments/rendering/renderableplaneprojection.cpp index 5f85e63803..4e75eab50a 100644 --- a/modules/spacecraftinstruments/rendering/renderableplaneprojection.cpp +++ b/modules/spacecraftinstruments/rendering/renderableplaneprojection.cpp @@ -221,8 +221,8 @@ void RenderablePlaneProjection::updatePlane(const Image& img, double currentTime glm::dvec3 boresight; std::string target = _defaultTarget; - // Turned on if the plane should be attached to the closest target, - // rather than the target specified in img + // Turned on if the plane should be attached to the closest target, + // rather than the target specified in img //if (!_moving) { // target = findClosestTarget(currentTime); //} @@ -290,7 +290,7 @@ void RenderablePlaneProjection::updatePlane(const Image& img, double currentTime ); if (thisNode && newParent) { thisNode->setParent(*newParent); - } + } } const GLfloat vertex_data[] = { diff --git a/modules/spacecraftinstruments/rendering/renderableplanetprojection.cpp b/modules/spacecraftinstruments/rendering/renderableplanetprojection.cpp index f0b1b6219c..9f1bc301e2 100644 --- a/modules/spacecraftinstruments/rendering/renderableplanetprojection.cpp +++ b/modules/spacecraftinstruments/rendering/renderableplanetprojection.cpp @@ -184,7 +184,7 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& std::string texturePath = ""; success = dict.getValue(ColorTextureInfo.identifier, texturePath); if (success) { - _colorTexturePath = absPath(texturePath); + _colorTexturePath = absPath(texturePath); } std::string heightMapPath = ""; @@ -241,7 +241,7 @@ void RenderablePlanetProjection::initialize() { _geometry->initialize(this); //completeSuccess &= auxiliaryRendertarget(); - // SCREEN-QUAD + // SCREEN-QUAD const GLfloat size = 1.f; const GLfloat w = 1.f; const GLfloat vertex_data[] = { @@ -308,7 +308,7 @@ void RenderablePlanetProjection::imageProjectGPU( _fboProgramObject->setUniform("_scaling" , _camScaling); _fboProgramObject->setUniform("boresight" , _boresight); - if (_geometry->hasProperty("Radius")){ + if (_geometry->hasProperty("Radius")) { ghoul::any r = _geometry->property("Radius")->get(); if (glm::vec3* radius = ghoul::any_cast(&r)){ _fboProgramObject->setUniform("_radius", radius); @@ -339,7 +339,7 @@ void RenderablePlanetProjection::attitudeParameters(double time) { ); _transform = glm::mat4(1); - //90 deg rotation w.r.t spice req. + //90 deg rotation w.r.t spice req. glm::mat4 rot = glm::rotate( _transform, static_cast(M_PI_2), @@ -376,7 +376,7 @@ void RenderablePlanetProjection::attitudeParameters(double time) { ); psc position = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); - //change to KM and add psc camera scaling. + //change to KM and add psc camera scaling. position[3] += (3 + _camScaling[1]); //position[3] += 3; glm::vec3 cpos = position.vec3(); diff --git a/modules/spacecraftinstruments/util/hongkangparser.cpp b/modules/spacecraftinstruments/util/hongkangparser.cpp index f2297f734b..a38a2e03f4 100644 --- a/modules/spacecraftinstruments/util/hongkangparser.cpp +++ b/modules/spacecraftinstruments/util/hongkangparser.cpp @@ -41,7 +41,7 @@ namespace { namespace openspace { -HongKangParser::HongKangParser(std::string name, std::string fileName, +HongKangParser::HongKangParser(std::string name, std::string fileName, std::string spacecraft, ghoul::Dictionary translationDictionary, std::vector potentialTargets) @@ -84,7 +84,7 @@ HongKangParser::HongKangParser(std::string name, std::string fileName, } void HongKangParser::findPlaybookSpecifiedTarget(std::string line, std::string& target) { - //remembto add this lua later... + //remembto add this lua later... std::transform( line.begin(), line.end(), @@ -100,14 +100,14 @@ void HongKangParser::findPlaybookSpecifiedTarget(std::string line, std::string& break; } else { - // not found - we set void until we have more info. + // not found - we set void until we have more info. target = "VOID"; } } } bool HongKangParser::create() { - //check input for errors. + //check input for errors. bool hasObserver = SpiceManager::ref().hasNaifId(_spacecraft); if (!hasObserver) { throw ghoul::RuntimeError( @@ -160,7 +160,7 @@ bool HongKangParser::create() { while (!file.eof()) { std::getline(file, line); - std::string event = line.substr(0, line.find_first_of(" ")); + std::string event = line.substr(0, line.find_first_of(" ")); auto it = _fileTranslation.find(event); bool foundEvent = (it != _fileTranslation.end()); @@ -169,7 +169,7 @@ bool HongKangParser::create() { double time = getETfromMet(met); if (foundEvent){ - //store the time, this is used for getNextCaptureTime() + //store the time, this is used for getNextCaptureTime() _captureProgression.push_back(time); if (it->second->getDecoderType() == "CAMERA") { @@ -215,10 +215,10 @@ bool HongKangParser::create() { // store actual image in map. All targets get _only_ their // corresp. subset. _subsetMap[image.target]._subset.push_back(image); - // compute and store the range for each subset + // compute and store the range for each subset _subsetMap[image.target]._range.include(time); } - if (it->second->getDecoderType() == "SCANNER") { // SCANNER START + if (it->second->getDecoderType() == "SCANNER") { // SCANNER START scan_start = time; InstrumentDecoder* scanner = static_cast( @@ -292,8 +292,8 @@ bool HongKangParser::create() { return true; } -bool HongKangParser::augmentWithSpice(Image& image, std::string spacecraft, - std::vector, +bool HongKangParser::augmentWithSpice(Image& image, std::string spacecraft, + std::vector, std::vector potentialTargets) { image.target = "VOID"; @@ -338,8 +338,6 @@ double HongKangParser::getETfromMet(double met) { const double referenceET = SpiceManager::ref().ephemerisTimeFromDate("2015-07-14T11:50:00.00"); - //_metRef += 3; // MET reference time is off by 3 sec? - const double diff = std::abs(met - _metRef); if (met > _metRef) { return referenceET + diff; diff --git a/modules/spacecraftinstruments/util/hongkangparser.h b/modules/spacecraftinstruments/util/hongkangparser.h index 8f774ae84b..3e348bc14d 100644 --- a/modules/spacecraftinstruments/util/hongkangparser.h +++ b/modules/spacecraftinstruments/util/hongkangparser.h @@ -43,7 +43,7 @@ private: double getETfromMet(std::string timestr); double getETfromMet(double met); - bool augmentWithSpice(Image& image, std::string spacecraft, + bool augmentWithSpice(Image& image, std::string spacecraft, std::vector payload, std::vector potentialTargets); std::string _defaultCaptureImage; diff --git a/modules/spacecraftinstruments/util/imagesequencer.cpp b/modules/spacecraftinstruments/util/imagesequencer.cpp index 3dc284197c..9561a17c66 100644 --- a/modules/spacecraftinstruments/util/imagesequencer.cpp +++ b/modules/spacecraftinstruments/util/imagesequencer.cpp @@ -159,7 +159,7 @@ std::pair> ImageSequencer::getIncidentTargetLis // move the iterator to the first element of the range std::advance(it, -(range + 1)); - // now extract incident range + // now extract incident range for (int i = 0; i < 2 * range + 1; i++){ incidentTargets.first = it->first; incidentTargets.second.push_back(it->second); @@ -220,7 +220,7 @@ std::map ImageSequencer::getActiveInstruments() { for (const auto& key : _fileTranslation) { // for each spice-instrument for (const auto& instrumentID : key.second->getTranslation()) { - // check if the spice-instrument is active + // check if the spice-instrument is active if (instrumentActive(instrumentID)) { // go over switching map for (const auto& instrument : _switchingMap) { @@ -240,11 +240,11 @@ std::map ImageSequencer::getActiveInstruments() { bool ImageSequencer::instrumentActive(std::string instrumentID) { for (const auto& i : _instrumentTimes) { //check if this instrument is in range - if (i.second.includes(_currentTime)) { + if (i.second.includes(_currentTime)) { //if so, then get the corresponding spiceID - std::vector spiceIDs = _fileTranslation[i.first]->getTranslation(); + std::vector ids = _fileTranslation[i.first]->getTranslation(); //check which specific subinstrument is firing - for (const auto& s : spiceIDs) { + for (const auto& s : ids) { if (s == instrumentID) { return true; } @@ -259,11 +259,13 @@ float ImageSequencer::instrumentActiveTime(const std::string& instrumentID) cons //check if this instrument is in range if (i.second.includes(_currentTime)){ //if so, then get the corresponding spiceID - std::vector spiceIDs = _fileTranslation.at(i.first)->getTranslation(); + std::vector ids = _fileTranslation.at(i.first)->getTranslation(); //check which specific subinstrument is firing - for (auto s : spiceIDs){ + for (auto s : ids){ if (s == instrumentID) { - return static_cast((_currentTime - i.second.start) / (i.second.end - i.second.start)); + return static_cast( + (_currentTime - i.second.start) / (i.second.end - i.second.start) + ); } } } @@ -271,14 +273,16 @@ float ImageSequencer::instrumentActiveTime(const std::string& instrumentID) cons return -1.f; } -bool ImageSequencer::getImagePaths(std::vector& captures, +bool ImageSequencer::getImagePaths(std::vector& captures, std::string projectee, std::string instrumentRequest){ - // check if this instance is either in range or - // a valid candidate to recieve data - if (!instrumentActive(instrumentRequest) && !OsEng.timeManager().time().timeJumped()) return false; - + // check if this instance is either in range or + // a valid candidate to recieve data + if (!instrumentActive(instrumentRequest) && !OsEng.timeManager().time().timeJumped()) + { + return false; + } //if (!Time::ref().timeJumped() && projectee == getCurrentTarget().second) if (_subsetMap[projectee]._range.includes(_currentTime) || @@ -286,14 +290,14 @@ bool ImageSequencer::getImagePaths(std::vector& captures, auto compareTime = [](const Image &a, const Image &b)->bool{ return a.timeRange.start < b.timeRange.start; - }; + }; // for readability we store the iterators - auto begin = _subsetMap[projectee]._subset.begin(); + auto begin = _subsetMap[projectee]._subset.begin(); auto end = _subsetMap[projectee]._subset.end(); // create temporary storage std::vector captureTimes; - // what to look for + // what to look for Image findPrevious, findCurrent; findPrevious.timeRange.start = _previousTime; findCurrent.timeRange.start = _currentTime; @@ -302,18 +306,21 @@ bool ImageSequencer::getImagePaths(std::vector& captures, auto curr = std::lower_bound(begin, end, findCurrent , compareTime); auto prev = std::lower_bound(begin, end, findPrevious, compareTime); - if (curr != begin && curr != end && prev != begin && prev != end && prev < curr){ - if (curr->timeRange.start >= prev->timeRange.start){ - std::copy_if(prev, curr, back_inserter(captureTimes), + if (curr != begin && curr != end && prev != begin && prev != end && prev < curr) + { + if (curr->timeRange.start >= prev->timeRange.start) { + std::copy_if(prev, curr, back_inserter(captureTimes), [instrumentRequest](const Image& i) { - bool correctInstrument = i.activeInstruments[0] == instrumentRequest; - return correctInstrument; - }); + return i.activeInstruments[0] == instrumentRequest; + } + ); //std::reverse(captureTimes.begin(), captureTimes.end()); captures = captureTimes; - if (!captures.empty()) - _latestImages[captures.back().activeInstruments.front()] = captures.back(); + if (!captures.empty()) { + _latestImages[captures.back().activeInstruments.front()] = + captures.back(); + } std::vector toDelete; for (auto it = captures.begin(); it != captures.end(); ++it) { @@ -321,13 +328,17 @@ bool ImageSequencer::getImagePaths(std::vector& captures, double beforeDist = std::numeric_limits::max(); if (it != captures.begin()) { auto before = std::prev(it); - beforeDist = std::abs(before->timeRange.start - it->timeRange.start); + beforeDist = std::abs( + before->timeRange.start - it->timeRange.start + ); } double nextDist = std::numeric_limits::max(); if (it != captures.end() - 1) { auto next = std::next(it); - nextDist = std::abs(next->timeRange.start - it->timeRange.start); + nextDist = std::abs( + next->timeRange.start - it->timeRange.start + ); } if (beforeDist < 1.0 || nextDist < 1.0) { @@ -371,7 +382,9 @@ void ImageSequencer::sortData() { std::sort( _instrumentTimes.begin(), _instrumentTimes.end(), - [](const std::pair& a, const std::pair& b) { + [](const std::pair& a, + const std::pair& b) + { return a.second.start < b.second.start; } ); @@ -380,12 +393,15 @@ void ImageSequencer::sortData() { void ImageSequencer::runSequenceParser(SequenceParser* parser){ bool parserComplete = parser->create(); if (parserComplete){ - // get new data - std::map>& translations = parser->getTranslation(); // in1 - std::map imageData = parser->getSubsetMap(); // in2 - std::vector> instrumentTimes = parser->getInstrumentTimes(); //in3 - std::vector> targetTimes = parser->getTargetTimes(); //in4 - std::vector captureProgression = parser->getCaptureProgression(); //in5 + // get new data + std::map>& translations = + parser->getTranslation(); + std::map imageData = parser->getSubsetMap(); + std::vector> instrumentTimes = + parser->getInstrumentTimes(); + std::vector> targetTimes = + parser->getTargetTimes(); + std::vector captureProgression = parser->getCaptureProgression(); // check for sanity if (imageData.empty() || instrumentTimes.empty() || captureProgression.empty()) { @@ -404,18 +420,20 @@ void ImageSequencer::runSequenceParser(SequenceParser* parser){ _subsetMap.insert(it); } else { std::string key = it.first; - std::vector &source = it.second._subset; // prediction + std::vector &source = it.second._subset; // prediction std::vector &destination = _subsetMap[key]._subset; // imagery // simple search function - double min = 10; + double min = 10; auto findMin = [&](std::vector &vector)->double{ - for (int i = 1; i < static_cast(vector.size()); i++){ - double e = std::abs(vector[i].timeRange.start - vector[i - 1].timeRange.start); - if (e < min){ + for (int i = 1; i < static_cast(vector.size()); ++i) { + double e = std::abs( + vector[i].timeRange.start - vector[i - 1].timeRange.start + ); + if (e < min) { min = e; } - } + } return min; }; @@ -426,42 +444,63 @@ void ImageSequencer::runSequenceParser(SequenceParser* parser){ // set epsilon as 1% smaller than min epsilon -= min * 0.01; - // IFF images have same time as mission planned capture, erase that event from - // 'predicted event file' (mission-playbook) - for (size_t i = 0; i < source.size(); i++) { - for (size_t j = 0; j < destination.size(); j++) { - double diff = std::abs(source[i].timeRange.start - destination[j].timeRange.start); - if (diff < epsilon){ + // IFF images have same time as mission planned capture, erase that event + // from 'predicted event file' (mission-playbook) + for (size_t i = 0; i < source.size(); ++i) { + for (size_t j = 0; j < destination.size(); ++j) { + double diff = std::abs( + source[i].timeRange.start - destination[j].timeRange.start + ); + if (diff < epsilon) { source.erase(source.begin() + i); } } } - // pad image data with predictions (ie - where no actual images, add placeholder) - _subsetMap[key]._subset.insert(_subsetMap[key]._subset.end(), source.begin(), source.end()); + // pad image data with predictions (ie - where no actual images, + // add placeholder) + _subsetMap[key]._subset.insert( + _subsetMap[key]._subset.end(), + source.begin(), + source.end() + ); } } - _instrumentTimes.insert(_instrumentTimes.end(), instrumentTimes.begin(), instrumentTimes.end()); - _targetTimes.insert(_targetTimes.end(), targetTimes.begin(), targetTimes.end()); - _captureProgression.insert(_captureProgression.end(), captureProgression.begin(), captureProgression.end()); + _instrumentTimes.insert( + _instrumentTimes.end(), + instrumentTimes.begin(), + instrumentTimes.end() + ); + _targetTimes.insert( + _targetTimes.end(), + targetTimes.begin(), + targetTimes.end() + ); + _captureProgression.insert( + _captureProgression.end(), + captureProgression.begin(), + captureProgression.end() + ); // sorting of data _not_ optional sortData(); - // extract payload from _fileTranslation - for (auto& t : _fileTranslation){ + // extract payload from _fileTranslation + for (auto& t : _fileTranslation) { if (t.second->getDecoderType() == "CAMERA" || - t.second->getDecoderType() == "SCANNER"){ + t.second->getDecoderType() == "SCANNER") + { std::vector spiceIDs = t.second->getTranslation(); - for (auto id : spiceIDs){ + for (auto id : spiceIDs) { _switchingMap[id] = false; } } } _hasData = true; } - else + else { LERROR("One or more sequence loads failed; please check mod files"); + } } } // namespace openspace diff --git a/modules/spacecraftinstruments/util/imagesequencer.h b/modules/spacecraftinstruments/util/imagesequencer.h index 77920691d2..dfcb6f149e 100644 --- a/modules/spacecraftinstruments/util/imagesequencer.h +++ b/modules/spacecraftinstruments/util/imagesequencer.h @@ -39,13 +39,13 @@ class SequenceParser; /** * The ImageSequencer singleton main function is to manage the timekeeping and -* distribution of large image data-sets across all openspace renderable instances, -* both for past and future unmanned-spacecraft missions. To load the instance with -* data the client must provide a parser inherited from the abstract base class +* distribution of large image data-sets across all openspace renderable instances, +* both for past and future unmanned-spacecraft missions. To load the instance with +* data the client must provide a parser inherited from the abstract base class * SequenceParser. Hence, there is no restriction imposed on data input, whether its -* data in the form of existing images or in the form of a planned observation schedule. -* Notably, in order for the sequencer to function the client must provide or write a -* parser that fills the ImageSequencers private members. +* data in the form of existing images or in the form of a planned observation schedule. +* Notably, in order for the sequencer to function the client must provide or write a +* parser that fills the ImageSequencers private members * \see SequenceParser * \see ImageSequencer::runSequenceParser(SequenceParser* parser) * std::map @@ -78,17 +78,17 @@ public: /** * Updates sequencer with current time. This is used internally for keeping - * track of both current simulation time and the time of the previously rendered frame. - */ + * track of both current simulation time and the time of the previously rendered frame. + */ void updateSequencer(const Time& time); /** - * Runs parser and recieves the datastructures filled by it. + * Runs parser and recieves the datastructures filled by it. * \see SequenceParser */ void runSequenceParser(SequenceParser* parser); /** - * Retrieves the next upcoming target in time. + * Retrieves the next upcoming target in time. */ std::pair getNextTarget(); @@ -103,32 +103,32 @@ public: std::pair> getIncidentTargetList(int range = 2); /** - * Retrieves the next upcoming time of image capture. + * Retrieves the next upcoming time of image capture. */ double getNextCaptureTime(); /** - * Retrieves the time interval length between the current time and an upcoming capture. + * Retrieves the time interval length between the current time and an upcoming capture. */ double getIntervalLength(); /* * Returns a map with key instrument names whose value indicate whether - * an instrument is active or not. + * an instrument is active or not. */ std::map getActiveInstruments(); /* * Retrieves the relevant data from a specific subset based on the what instance * makes the request. If an instance is not registered in the class then the singleton - * returns false and no projections will occur. + * returns false and no projections will occur. */ bool getImagePaths(std::vector& captures, std::string projectee, std::string instrumentRequest); /* - * returns true if instrumentID is within a capture range. + * returns true if instrumentID is within a capture range. */ bool instrumentActive(std::string instrumentID); @@ -143,9 +143,9 @@ private: void sortData(); /* - * _fileTranslation handles any types of ambiguities between the data and - * spice/openspace -calls. This map is composed of a key that is a string in - * the data to be translated and a Decoder that holds the corresponding + * _fileTranslation handles any types of ambiguities between the data and + * spice/openspace -calls. This map is composed of a key that is a string in + * the data to be translated and a Decoder that holds the corresponding * translation provided through a modfile. * \see Decoder * \see (projection mod files) @@ -153,8 +153,8 @@ private: std::map> _fileTranslation; /* - * This is the main container of image data. The key is the target name, - * the value is a subset of images. + * This is the main container of image data. The key is the target name, + * the value is a subset of images. * \see SequenceParser */ std::map _subsetMap; @@ -163,24 +163,24 @@ private: * In order for the simulation to know when to turn on/off any instrument within * all instruments in the spacecraft payload, the key is the data-file given * instrument name. - */ + */ std::map _switchingMap; /* - * This datastructure holds the specific times when the spacecraft switches from - * observing one inertial body to the next. This happens a lot in such missions - * and the coupling of target with specific time is usually therefore not 1:1. + * This datastructure holds the specific times when the spacecraft switches from + * observing one inertial body to the next. This happens a lot in such missions + * and the coupling of target with specific time is usually therefore not 1:1. */ std::vector> _targetTimes; /* * Holds the time ranges of each instruments on and off periods. An instrument - * rendering class may ask the ImageSequencer whether or not it + * rendering class may ask the ImageSequencer whether or not it */ std::vector> _instrumentTimes; /* - * Each consecutive images capture time, for easier traversal. + * Each consecutive images capture time, for easier traversal. */ std::vector _captureProgression; @@ -196,7 +196,7 @@ private: std::string _defaultCaptureImage; std::map _latestImages; - // if no data, no run + // if no data, no run bool _hasData; }; diff --git a/modules/spacecraftinstruments/util/instrumenttimesparser.cpp b/modules/spacecraftinstruments/util/instrumenttimesparser.cpp index 703626887f..4490b915e7 100644 --- a/modules/spacecraftinstruments/util/instrumenttimesparser.cpp +++ b/modules/spacecraftinstruments/util/instrumenttimesparser.cpp @@ -114,7 +114,7 @@ bool InstrumentTimesParser::create() { continue; } - // Read file into string + // Read file into string std::ifstream inFile(filepath); std::string line; std::smatch matches; diff --git a/modules/spacecraftinstruments/util/labelparser.cpp b/modules/spacecraftinstruments/util/labelparser.cpp index f5bdcd1446..1a9750ce61 100644 --- a/modules/spacecraftinstruments/util/labelparser.cpp +++ b/modules/spacecraftinstruments/util/labelparser.cpp @@ -170,7 +170,7 @@ bool LabelParser::create() { if (position != std::string::npos){ ghoul::filesystem::File currentFile(path); std::string extension = currentFile.fileExtension(); - if (extension == "lbl" || extension == "LBL"){ // discovered header file + if (extension == "lbl" || extension == "LBL") { // discovered header file std::ifstream file(currentFile.path()); if (!file.good()){ @@ -224,13 +224,8 @@ bool LabelParser::create() { } if (read == "DETECTOR_TYPE"){ _detectorType = decode(line); - count++; + count++; } - // if (_badDecoding){ - // LERROR("Please examine file: '" << currentFile.path() << "'"); - // return false; - // } - if (read == "START_TIME"){ std::string start = line.substr(line.find("=") + 1); @@ -266,7 +261,9 @@ bool LabelParser::create() { ), stop.end() ); - stopTime = SpiceManager::ref().ephemerisTimeFromDate(stop); + stopTime = SpiceManager::ref().ephemerisTimeFromDate( + stop + ); count++; } else{ diff --git a/modules/spacecraftinstruments/util/labelparser.h b/modules/spacecraftinstruments/util/labelparser.h index 5728e23d87..9ed0723caa 100644 --- a/modules/spacecraftinstruments/util/labelparser.h +++ b/modules/spacecraftinstruments/util/labelparser.h @@ -52,9 +52,9 @@ private: std::string decode(std::string line); std::string encode(std::string line); - bool augmentWithSpice(Image& image, - std::string spacecraft, - std::vector payload, + bool augmentWithSpice(Image& image, + std::string spacecraft, + std::vector payload, std::vector potentialTargets); std::string _name; diff --git a/modules/spacecraftinstruments/util/projectioncomponent.cpp b/modules/spacecraftinstruments/util/projectioncomponent.cpp index fbed52475f..3f894ff910 100644 --- a/modules/spacecraftinstruments/util/projectioncomponent.cpp +++ b/modules/spacecraftinstruments/util/projectioncomponent.cpp @@ -465,7 +465,7 @@ void ProjectionComponent::imageProjectBegin() { // Generate the new textures generateProjectionLayerTexture(_textureSize); - if (_shadowing.isEnabled) { + if (_shadowing.isEnabled) { generateDepthTexture(_textureSize); } diff --git a/modules/spacecraftinstruments/util/projectioncomponent.h b/modules/spacecraftinstruments/util/projectioncomponent.h index d7332a887a..cc1a2d614f 100644 --- a/modules/spacecraftinstruments/util/projectioncomponent.h +++ b/modules/spacecraftinstruments/util/projectioncomponent.h @@ -74,7 +74,7 @@ public: glm::mat4 computeProjectorMatrix( const glm::vec3 loc, glm::dvec3 aim, const glm::vec3 up, const glm::dmat3& instrumentMatrix, - float fieldOfViewY, + float fieldOfViewY, float aspectRatio, float nearPlane, float farPlane, diff --git a/modules/touch/include/touchinteraction.h b/modules/touch/include/touchinteraction.h index 25f832102e..6d3fee3a82 100644 --- a/modules/touch/include/touchinteraction.h +++ b/modules/touch/include/touchinteraction.h @@ -72,7 +72,7 @@ public: std::vector selectedPoints; std::vector screenPoints; int nDOF; - glm::dvec2(*castToNDC)(glm::dvec3, Camera&, SceneGraphNode*); + glm::dvec2(*castToNDC)(const glm::dvec3&, Camera&, SceneGraphNode*); double(*distToMinimize)(double* par, int x, void* fdata, LMstat* lmstat); Camera* camera; SceneGraphNode* node; @@ -86,12 +86,12 @@ public: * 3 Continues if GUI isn't on * 4 If the node in focus is large enough and all contact points have selected it, * calls directControl() function for direct-manipulation - * 5 Updates std::vector _selected (only if LMA successfully + * 5 Updates std::vector _selected (only if LMA successfully * converged, avoids interaction to snap on LMA fails) - * 6 If directControl() wasn't called this frame, interpret the incoming + * 6 If directControl() wasn't called this frame, interpret the incoming * list and decide what type of interaction this frame should do * 7 Compute the new total velocities after interaction - * 8 Evaluate if directControl should be called next frame- true if all contact points + * 8 Evaluate if directControl should be called next frame- true if all contact points * select the same node and said node is larger than _nodeRadiusThreshold */ void updateStateFromInput(const std::vector& list, @@ -100,10 +100,10 @@ public: // Calculates the new camera state with velocities and time since last frame void step(double dt); - // Used to save LMA data for one frame if the user chose to + // Used to save LMA data for one frame if the user chose to void unitTest(); - // Called each frame we have no new input, used to reset data + // Called each frame we have no new input, used to reset data void resetAfterInput(); // Sets _tap to true, called if tap occured current frame (called from touchmodule) @@ -125,7 +125,7 @@ private: bool guiMode(const std::vector& list); /* Function that calculates the new camera state such that it minimizes the L2 error - * in screenspace + * in screenspace * between contact points and surface coordinates projected to clip space using LMA */ void directControl(const std::vector& list); @@ -136,7 +136,7 @@ private: */ void findSelectedNode(const std::vector& list); - /* Returns an int (ROT = 0, PINCH, PAN, ROLL, PICK) for what interaction to be used, + /* Returns an int (ROT = 0, PINCH, PAN, ROLL, PICK) for what interaction to be used, * depending on what input was gotten */ int interpretInteraction(const std::vector& list, diff --git a/modules/touch/src/touchinteraction.cpp b/modules/touch/src/touchinteraction.cpp index 53f0f36496..8a66aac409 100644 --- a/modules/touch/src/touchinteraction.cpp +++ b/modules/touch/src/touchinteraction.cpp @@ -67,6 +67,121 @@ namespace { const char* _loggerCat = "TouchInteraction"; + + static const openspace::properties::Property::PropertyInfo OriginInfo = { + "Origin", + "Origin", + "" // @TODO Missing documentation + }; + + static const openspace::properties::Property::PropertyInfo UnitTestInfo = { + "UnitTest", + "Take a unit test saving the LM data into file", + "" // @TODO Missing documentation + }; + + static const openspace::properties::Property::PropertyInfo EventsInfo = { + "TouchEvents", + "True if we have a touch event", + "", + openspace::properties::Property::Visibility::Hidden + }; + + static const openspace::properties::Property::PropertyInfo SetDefaultInfo = { + "SetDefault", + "Reset all properties to default", + "" // @TODO Missing documentation + }; + + static const openspace::properties::Property::PropertyInfo MaxTapTimeInfo = { + "MaxTapTime", + "Max tap delay (in ms) for double tap", + "" // @TODO Missing documentation + }; + + static const openspace::properties::Property::PropertyInfo DecelatesPerSecondInfo = { + "DeceleratesPerSecond", + "Number of times velocity is decelerated per second", + "" // @TODO Missing documentation + }; + + static const openspace::properties::Property::PropertyInfo TouchScreenSizeInfo = { + "TouchScreenSize", + "Touch Screen size in inches", + "" // @TODO Missing documentation + }; + + static const openspace::properties::Property::PropertyInfo TapZoomFactorInfo = { + "TapZoomFactor", + "Scaling distance travelled on tap", + "" // @TODO Missing documentation + }; + + static const openspace::properties::Property::PropertyInfo DirectManipulationInfo = { + "DirectManipulationRadius", + "Radius a planet has to have to activate direct-manipulation", + "" // @TODO Missing documentation + }; + + static const openspace::properties::Property::PropertyInfo RollThresholdInfo = { + "RollThreshold", + "Threshold for min angle for roll interpret", + "" // @TODO Missing documentation + }; + + static const openspace::properties::Property::PropertyInfo OrbitSpinningThreshold = { + "OrbitThreshold", + "Threshold to activate orbit spinning in direct-manipulation", + "" // @TODO Missing documentation + }; + + static const openspace::properties::Property::PropertyInfo SpinningSensitivityInfo = { + "SpinningSensitivity", + "Sensitivity of spinning in direct-manipulation", + "" // @TODO Missing documentation + }; + + static const openspace::properties::Property::PropertyInfo InputSensitivityInfo = { + "InputSensitivity", + "Threshold for interpreting input as still", + "" + }; + + static const openspace::properties::Property::PropertyInfo StationaryCentroidInfo = { + "CentroidStationary", + "Threshold for stationary centroid", + "" // @TODO Missing documentation + }; + + static const openspace::properties::Property::PropertyInfo PanDeltaDistanceInfo = { + "PanDeltaDistance", + "Delta distance between fingers allowed for interpreting pan interaction", + "" // @TODO Missing documentation + }; + + static const openspace::properties::Property::PropertyInfo SlerpTimeInfo = { + "SlerpTime", + "Time to slerp in seconds to new orientation with new node picking", + "" // @TODO Missing documentation + }; + + static const openspace::properties::Property::PropertyInfo GuiButtonSizeInfo = { + "GuiButtonSize", + "GUI button size in pixels", + "" // @TODO Missing documentation + }; + + static const openspace::properties::Property::PropertyInfo FrictionInfo = { + "Friction", + "Friction for different interactions (orbit, zoom, roll, pan)", + "" // @TODO Missing documentation + }; + + static const openspace::properties::Property::PropertyInfo PickingRadiusInfo = { + "PickingRadiusMinimum", + "Minimum radius for picking in NDC coordinates", + "" // @TODO Missing documentation + }; } // namespace using namespace TUIO; @@ -75,113 +190,42 @@ namespace openspace { TouchInteraction::TouchInteraction() : properties::PropertyOwner({ "TouchInteraction" }) - , _origin({ "Origin", "Origin", "" }) // @TODO Missing documentation - , _unitTest( - { "Click to take a unit test", "Take a unit test saving the LM data into file", "" }, // @TODO Missing documentation - false - ) - , _touchActive( - { "TouchEvents", "True if we have a touch event", "", properties::Property::Visibility::Hidden }, // @TODO Missing documentation - false - ) - , _reset( - { "Default Values", "Reset all properties to default", "" }, // @TODO Missing documentation - false - ) - , _maxTapTime( - { "Max Tap Time", "Max tap delay (in ms) for double tap", "" }, // @TODO Missing documentation - 300, - 10, - 1000 - ) - , _deceleratesPerSecond( - { "Decelerates per second", "Number of times velocity is decelerated per second", "" }, // @TODO Missing documentation - 240, - 60, - 300 - ) - , _touchScreenSize( - { "TouchScreenSize", "Touch Screen size in inches", "" }, // @TODO Missing documentation - 55.0f, - 5.5f, - 150.0f - ) - , _tapZoomFactor( - { "Tap zoom factor", "Scaling distance travelled on tap", "" }, // @TODO Missing documentation - 0.2f, - 0.f, - 0.5f - ) - , _nodeRadiusThreshold( - { "Activate direct-manipulation", "Radius a planet has to have to activate direct-manipulation", "" }, // @TODO Missing documentation - 0.2f, - 0.0f, - 1.0f - ) - , _rollAngleThreshold( - { "Interpret roll", "Threshold for min angle for roll interpret", "" }, // @TODO Missing documentation - 0.025f, - 0.f, - 0.05f - ) - , _orbitSpeedThreshold( - { "Activate orbit spinning", "Threshold to activate orbit spinning in direct-manipulation", "" }, // @TODO Missing documentation - 0.005f, - 0.f, - 0.01f - ) - , _spinSensitivity( - { "Sensitivity of spinning", "Sensitivity of spinning in direct-manipulation", "" }, // @TODO Missing documentation - 1.f, - 0.f, - 2.f - ) - , _inputStillThreshold( - { "Input still", "Threshold for interpreting input as still", "" }, // @TODO Missing documentation - 0.0005f, - 0.f, - 0.001f - ) - , _centroidStillThreshold( - { "Centroid stationary", "Threshold for stationary centroid", "" }, // @TODO Missing documentation - 0.0018f, - 0.f, - 0.01f - ) // used to void wrongly interpreted roll interactions - , _interpretPan( - { "Pan delta distance", "Delta distance between fingers allowed for interpreting pan interaction", "" }, // @TODO Missing documentation - 0.015f, - 0.f, - 0.1f - ) - , _slerpTime( - { "Time to slerp", "Time to slerp in seconds to new orientation with new node picking", "" }, // @TODO Missing documentation - 3.f, - 0.f, - 5.f - ) + , _origin(OriginInfo) + , _unitTest(UnitTestInfo, false) + , _touchActive(EventsInfo, false) + , _reset(SetDefaultInfo, false) + , _maxTapTime(MaxTapTimeInfo, 300, 10, 1000) + , _deceleratesPerSecond(DecelatesPerSecondInfo, 240, 60, 300) + , _touchScreenSize(TouchScreenSizeInfo, 55.0f, 5.5f, 150.0f) + , _tapZoomFactor(TapZoomFactorInfo, 0.2f, 0.f, 0.5f) + , _nodeRadiusThreshold(DirectManipulationInfo, 0.2f, 0.0f, 1.0f) + , _rollAngleThreshold(RollThresholdInfo, 0.025f, 0.f, 0.05f) + , _orbitSpeedThreshold(OrbitSpinningThreshold, 0.005f, 0.f, 0.01f) + , _spinSensitivity(SpinningSensitivityInfo, 1.f, 0.f, 2.f) + , _inputStillThreshold(InputSensitivityInfo, 0.0005f, 0.f, 0.001f) + // used to void wrongly interpreted roll interactions + , _centroidStillThreshold(StationaryCentroidInfo, 0.0018f, 0.f, 0.01f) + , _interpretPan(PanDeltaDistanceInfo, 0.015f, 0.f, 0.1f) + , _slerpTime(SlerpTimeInfo, 3.f, 0.f, 5.f) , _guiButton( - { "GUI Button", "GUI button size in pixels", "" }, // @TODO Missing documentation + GuiButtonSizeInfo, glm::ivec2(32, 64), glm::ivec2(8, 16), glm::ivec2(128, 256) ) , _friction( - { "Friction", "Friction for different interactions (orbit, zoom, roll, pan)", "" }, // @TODO Missing documentation + FrictionInfo, glm::vec4(0.01f, 0.025f, 0.02f, 0.02f), glm::vec4(0.f), glm::vec4(0.2f) ) - , _pickingRadiusMinimum( - { "Picking Radius", "Minimum radius for picking in NDC coordinates", "" }, - 0.1f, - 0.f, - 1.f - ) + , _pickingRadiusMinimum(PickingRadiusInfo, 0.1f, 0.f, 1.f) , _vel{ glm::dvec2(0.0), 0.0, 0.0, glm::dvec2(0.0) } , _sensitivity{ glm::dvec2(0.08, 0.045), 4.0, 2.75, glm::dvec2(0.08, 0.045) } , _centroid(glm::dvec3(0.0)) - , _projectionScaleFactor(1.000004) // calculated with two vectors with known diff in length, then projDiffLength/diffLength. + // calculated with two vectors with known diff in length, then + // projDiffLength/diffLength. + , _projectionScaleFactor(1.000004) , _currentRadius(1.0) , _slerpdT(1000) , _numOfTests(0) @@ -214,7 +258,9 @@ TouchInteraction::TouchInteraction() _origin.onChange([this]() { SceneGraphNode* node = sceneGraphNode(_origin.value()); if (!node) { - LWARNING("Could not find a node in scenegraph called '" << _origin.value() << "'"); + LWARNING( + "Could not find a node in scenegraph called '" << _origin.value() << "'" + ); return; } setFocusNode(node); @@ -227,7 +273,9 @@ TouchInteraction::TouchInteraction() } // Called each frame if there is any input -void TouchInteraction::updateStateFromInput(const std::vector& list, std::vector& lastProcessed) { +void TouchInteraction::updateStateFromInput(const std::vector& list, + std::vector& lastProcessed) +{ if (_tap) { // check for doubletap if (_time.getSessionTime().getTotalMilliseconds() < _maxTapTime) { _doubleTap = true; @@ -247,8 +295,9 @@ void TouchInteraction::updateStateFromInput(const std::vector& list, computeVelocities(list, lastProcessed); } - // evaluates if current frame is in directTouchMode (will if so be used next frame) - _directTouchMode = (_currentRadius > _nodeRadiusThreshold && _selected.size() == list.size()); + // evaluates if current frame is in directTouchMode (will be used next frame) + _directTouchMode = + (_currentRadius > _nodeRadiusThreshold && _selected.size() == list.size()); } } @@ -256,18 +305,27 @@ void TouchInteraction::updateStateFromInput(const std::vector& list, bool TouchInteraction::guiMode(const std::vector& list) { WindowWrapper& wrapper = OsEng.windowWrapper(); glm::ivec2 res = wrapper.currentWindowSize(); - glm::dvec2 pos = glm::vec2(list.at(0).getScreenX(res.x), list.at(0).getScreenY(res.y)); // mouse pixel position + glm::dvec2 pos = glm::vec2( + list.at(0).getScreenX(res.x), + list.at(0).getScreenY(res.y) + ); ImGUIModule& module = *(OsEng.moduleEngine().module()); _guiON = module.gui.isEnabled(); - if (_tap && list.size() == 1 && std::abs(pos.x) < _guiButton.value().x && std::abs(pos.y) < _guiButton.value().y) { // pressed invisible button + if (_tap && list.size() == 1 && + std::abs(pos.x) < _guiButton.value().x && std::abs(pos.y) < _guiButton.value().y) + { + // pressed invisible button _guiON = !_guiON; module.gui.setEnabled(_guiON); std::string mode = (_guiON) ? "" : "de"; - LINFO("GUI mode is " << mode << "activated. Inside box by: (" << - static_cast(100 * (pos.x / _guiButton.value().x)) << "%, " << static_cast(100 * (pos.y / _guiButton.value().y)) << "%)\n"); + LINFO( + "GUI mode is " << mode << "activated. Inside box by: (" << + static_cast(100 * (pos.x / _guiButton.value().x)) << "%, " << + static_cast(100 * (pos.y / _guiButton.value().y)) << "%)\n" + ); } else if (_guiON) { module.touchInput = { _guiON, pos, 1 }; // emulate touch input as a mouse @@ -283,12 +341,16 @@ void TouchInteraction::directControl(const std::vector& list) { _vel.roll = 0.0; _vel.pan = glm::dvec2(0.0, 0.0); - // Returns the screen point s(xi,par) dependant the transform M(par) and object point xi + // Returns the screen point s(xi,par) dependent the transform M(par) and object + // point xi auto distToMinimize = [](double* par, int x, void* fdata, LMstat* lmstat) { FunctionData* ptr = reinterpret_cast(fdata); - // Apply transform to camera and find the new screen point of the updated camera state - double q[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; // { vec2 globalRot, zoom, roll, vec2 localRot } + // Apply transform to camera and find the new screen point of the updated camera + // state + + // { vec2 globalRot, zoom, roll, vec2 localRot } + double q[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; for (int i = 0; i < ptr->nDOF; ++i) { q[i] = par[i]; } @@ -303,11 +365,13 @@ void TouchInteraction::directControl(const std::vector& list) { dvec3 lookUp = ptr->camera->lookUpVectorWorldSpace(); dvec3 camDirection = ptr->camera->viewDirectionWorldSpace(); - // Make a representation of the rotation quaternion with local and global rotations + // Make a representation of the rotation quaternion with local and global + // rotations dmat4 lookAtMat = lookAt( dvec3(0, 0, 0), directionToCenter, - normalize(camDirection + lookUp)); // To avoid problem with lookup in up direction + // To avoid problem with lookup in up direction + normalize(camDirection + lookUp)); dquat globalCamRot = normalize(quat_cast(inverse(lookAtMat))); dquat localCamRot = inverse(globalCamRot) * ptr->camera->rotationQuaternion(); @@ -324,13 +388,16 @@ void TouchInteraction::directControl(const std::vector& list) { dvec3 eulerAngles(q[1], q[0], 0); dquat rotationDiffCamSpace = dquat(eulerAngles); - dquat rotationDiffWorldSpace = globalCamRot * rotationDiffCamSpace * inverse(globalCamRot); - dvec3 rotationDiffVec3 = centerToCamera * rotationDiffWorldSpace - centerToCamera; + dquat rotationDiffWorldSpace = + globalCamRot * rotationDiffCamSpace * inverse(globalCamRot); + dvec3 rotationDiffVec3 = + centerToCamera * rotationDiffWorldSpace - centerToCamera; camPos += rotationDiffVec3; dvec3 centerToCamera = camPos - centerPos; directionToCenter = normalize(-centerToCamera); - dvec3 lookUpWhenFacingCenter = globalCamRot * dvec3(ptr->camera->lookUpVectorCameraSpace()); + dvec3 lookUpWhenFacingCenter = + globalCamRot * dvec3(ptr->camera->lookUpVectorCameraSpace()); dmat4 lookAtMat = lookAt( dvec3(0, 0, 0), directionToCenter, @@ -345,8 +412,13 @@ void TouchInteraction::directControl(const std::vector& list) { cam.setPositionVec3(camPos); cam.setRotation(globalCamRot * localCamRot); - // we now have a new position and orientation of camera, project surfacePoint to the new screen to get distance to minimize - glm::dvec2 newScreenPoint = ptr->castToNDC(ptr->selectedPoints.at(x), cam, ptr->node); + // we now have a new position and orientation of camera, project surfacePoint to + // the new screen to get distance to minimize + glm::dvec2 newScreenPoint = ptr->castToNDC( + ptr->selectedPoints.at(x), + cam, + ptr->node + ); lmstat->pos.push_back(newScreenPoint); return glm::length(ptr->screenPoints.at(x) - newScreenPoint); }; @@ -354,7 +426,8 @@ void TouchInteraction::directControl(const std::vector& list) { auto gradient = [](double* g, double* par, int x, void* fdata, LMstat* lmstat) { FunctionData* ptr = reinterpret_cast(fdata); double h, lastG, f1, f0 = ptr->distToMinimize(par, x, fdata, lmstat); - double scale = log10(ptr->node->boundingSphere()); // scale value to find minimum step size h, dependant on planet size + // scale value to find minimum step size h, dependant on planet size + double scale = log10(ptr->node->boundingSphere()); std::vector dPar(ptr->nDOF, 0.0); dPar.assign(par, par + ptr->nDOF); @@ -366,7 +439,7 @@ void TouchInteraction::directControl(const std::vector& list) { f1 = ptr->distToMinimize(dPar.data(), x, fdata, lmstat); dPar.at(i) = par[i]; // Iterative process to find the minimum step h that gives a good gradient - for (int j = 0; j < 100; ++j) { + for (int j = 0; j < 100; ++j) { if ((f1 - f0) != 0 && lastG == 0) { // found minimum step size h // scale up to get a good initial guess value h *= scale * scale * scale; @@ -374,7 +447,8 @@ void TouchInteraction::directControl(const std::vector& list) { // clamp min step size to a fraction of the incoming parameter if (i == 2) { double epsilon = 1e-3; - h = std::max(std::max(std::abs(dPar.at(i)), epsilon) * 0.001, h); // make sure incoming parameter is larger than 0 + // make sure incoming parameter is larger than 0 + h = std::max(std::max(std::abs(dPar.at(i)), epsilon) * 0.001, h); } else if (ptr->nDOF == 2) { h = std::max(std::abs(dPar.at(i)) * 0.001, h); @@ -399,30 +473,36 @@ void TouchInteraction::directControl(const std::vector& list) { } g[i] = (f1 - f0) / h; } - if (ptr->nDOF == 2) { // normalize on 1 finger case to allow for horizontal/vertical movement + if (ptr->nDOF == 2) { + // normalize on 1 finger case to allow for horizontal/vertical movement for (int i = 0; i < 2; ++i) { g[i] = g[i]/std::abs(g[i]); } } else if (ptr->nDOF == 6) { - for (int i = 0; i < ptr->nDOF; ++i) { // lock to only pan and zoom on 3 finger case, no roll/orbit + for (int i = 0; i < ptr->nDOF; ++i) { + // lock to only pan and zoom on 3 finger case, no roll/orbit g[i] = (i == 2) ? g[i] : g[i] / std::abs(g[i]); } } }; - // project back a 3D point in model view to clip space [-1,1] coordinates on the view plane - auto castToNDC = [](glm::dvec3 vec, Camera& camera, SceneGraphNode* node) { - glm::dvec3 posInCamSpace = glm::inverse(camera.rotationQuaternion()) - * ((node->rotationMatrix() * vec) + (node->worldPosition() - camera.positionVec3()) ); + // project back a 3D point in model view to clip space [-1,1] coordinates on the view + // plane + auto castToNDC = [](const glm::dvec3& vec, Camera& camera, SceneGraphNode* node) { + glm::dvec3 posInCamSpace = glm::inverse(camera.rotationQuaternion()) * + (node->rotationMatrix() * vec + + (node->worldPosition() - camera.positionVec3())); glm::dvec4 clipspace = camera.projectionMatrix() * glm::dvec4(posInCamSpace, 1.0); return (glm::dvec2(clipspace) / clipspace.w); }; - int nFingers = std::min(static_cast(list.size()), 3); // only send in first three fingers (to make it easier for LMA to converge on 3+ finger case with only zoom/pan) + // only send in first three fingers (to make it easier for LMA to converge on 3+ + // finger case with only zoom/pan) + int nFingers = std::min(static_cast(list.size()), 3); int nDOF = std::min(nFingers * 2, 6); - std::vector par(nDOF, 0.0); + std::vector par(nDOF, 0.0); par.at(0) = _lastVel.orbit.x; // use _lastVel for orbit par.at(1) = _lastVel.orbit.y; @@ -433,16 +513,43 @@ void TouchInteraction::directControl(const std::vector& list) { const SelectedBody& sb = _selected.at(i); selectedPoints.push_back(sb.coordinates); - std::vector::const_iterator c = std::find_if(list.begin(), list.end(), [&sb](const TuioCursor& c) { return c.getSessionID() == sb.id; }); - screenPoints.push_back(glm::dvec2(2 * (c->getX() - 0.5), -2 * (c->getY() - 0.5))); // normalized -1 to 1 coordinates on screen + std::vector::const_iterator c = std::find_if( + list.begin(), + list.end(), + [&sb](const TuioCursor& c) { return c.getSessionID() == sb.id; } + ); + // normalized -1 to 1 coordinates on screen + screenPoints.push_back( + glm::dvec2(2 * (c->getX() - 0.5), -2 * (c->getY() - 0.5)) + ); } - FunctionData fData = { selectedPoints, screenPoints, nDOF, castToNDC, distToMinimize, _camera, _selected.at(0).node, _lmstat, _currentRadius }; + FunctionData fData = { + selectedPoints, + screenPoints, + nDOF, + castToNDC, + distToMinimize, + _camera, + _selected.at(0).node, + _lmstat, + _currentRadius + }; void* dataPtr = reinterpret_cast(&fData); // finds best transform values for the new camera state and stores them in par - _lmSuccess = levmarq(nDOF, par.data(), nFingers, NULL, distToMinimize, gradient, dataPtr, &_lmstat); + _lmSuccess = levmarq( + nDOF, + par.data(), + nFingers, + nullptr, + distToMinimize, + gradient, + dataPtr, + &_lmstat + ); - if (_lmSuccess && !_unitTest) { // if good values were found set new camera state + if (_lmSuccess && !_unitTest) { + // if good values were found set new camera state _vel.orbit = glm::dvec2(par.at(0), par.at(1)); if (nDOF > 2) { _vel.zoom = par.at(2); @@ -461,18 +568,27 @@ void TouchInteraction::directControl(const std::vector& list) { _vel.roll = 0.0; _vel.pan = glm::dvec2(0.0, 0.0); } - else { // prevents touch to infinitely be active (due to windows bridge case where event doesnt get consumed sometimes when LMA fails to converge) - OsEng.moduleEngine().module()->touchInput = { 1, glm::dvec2(0.0, 0.0), 1 }; + else { + // prevents touch to infinitely be active (due to windows bridge case where event + // doesnt get consumed sometimes when LMA fails to converge) + OsEng.moduleEngine().module()->touchInput = { + 1, + glm::dvec2(0.0, 0.0), 1 + }; resetAfterInput(); } } -// Traces the touch input into the scene and finds the surface coordinates of touched planets (if occuring) +// Traces the touch input into the scene and finds the surface coordinates of touched +// planets (if occuring) void TouchInteraction::findSelectedNode(const std::vector& list) { //trim list to only contain visible nodes that make sense - std::string selectables[30] = { "Sun", "Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto", - "Moon", "Titan", "Rhea", "Mimas", "Iapetus", "Enceladus", "Dione", "Io", "Ganymede", "Europa", - "Callisto", "NewHorizons", "Styx", "Nix", "Kerberos", "Hydra", "Charon", "Tethys", "OsirisRex", "Bennu" }; + std::string selectables[30] = { + "Sun", "Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", + "Neptune", "Pluto", "Moon", "Titan", "Rhea", "Mimas", "Iapetus", "Enceladus", + "Dione", "Io", "Ganymede", "Europa", "Callisto", "NewHorizons", "Styx", "Nix", + "Kerberos", "Hydra", "Charon", "Tethys", "OsirisRex", "Bennu" + }; std::vector selectableNodes; for (SceneGraphNode* node : OsEng.renderEngine().scene()->allSceneGraphNodes()) for (std::string name : selectables) @@ -494,8 +610,10 @@ void TouchInteraction::findSelectedNode(const std::vector& list) { for (const TuioCursor& c : list) { double xCo = 2 * (c.getX() - 0.5); double yCo = -2 * (c.getY() - 0.5); // normalized -1 to 1 coordinates on screen - glm::dvec3 cursorInWorldSpace = camToWorldSpace * - glm::dvec3(glm::inverse(_camera->projectionMatrix()) * glm::dvec4(xCo, yCo, -1.0, 1.0)); // vec3(projectionmatrix * clipspace), divide with w? + // vec3(projectionmatrix * clipspace), divide with w? + glm::dvec3 cursorInWorldSpace = camToWorldSpace * + glm::dvec3(glm::inverse(_camera->projectionMatrix()) * + glm::dvec4(xCo, yCo, -1.0, 1.0)); glm::dvec3 raytrace = glm::normalize(cursorInWorldSpace); int id = c.getSessionID(); @@ -503,22 +621,34 @@ void TouchInteraction::findSelectedNode(const std::vector& list) { for (SceneGraphNode* node : selectableNodes) { double boundingSphere = node->boundingSphere(); glm::dvec3 camToSelectable = node->worldPosition() - camPos; - double dist = length(glm::cross(cursorInWorldSpace, camToSelectable)) / glm::length(cursorInWorldSpace) - boundingSphere; + double dist = length(glm::cross(cursorInWorldSpace, camToSelectable)) / + glm::length(cursorInWorldSpace) - boundingSphere; if (dist <= 0.0) { - // finds intersection closest point between boundingsphere and line in world coordinates, assumes line direction is normalized + // finds intersection closest point between boundingsphere and line in + // world coordinates, assumes line direction is normalized double d = glm::dot(raytrace, camToSelectable); - double root = boundingSphere * boundingSphere - glm::dot(camToSelectable, camToSelectable) + d * d; + double root = boundingSphere * boundingSphere - + glm::dot(camToSelectable, camToSelectable) + d * d; if (root > 0) { // two intersection points (take the closest one) d -= sqrt(root); } glm::dvec3 intersectionPoint = camPos + d * raytrace; - glm::dvec3 pointInModelView = glm::inverse(node->rotationMatrix()) * (intersectionPoint - node->worldPosition()); + glm::dvec3 pointInModelView = glm::inverse(node->rotationMatrix()) * + (intersectionPoint - node->worldPosition()); // Add id, node and surface coordinates to the selected list - std::vector::iterator oldNode = std::find_if(newSelected.begin(), newSelected.end(), [id](SelectedBody s) { return s.id == id; }); + std::vector::iterator oldNode = std::find_if( + newSelected.begin(), + newSelected.end(), + [id](SelectedBody s) { return s.id == id; } + ); if (oldNode != newSelected.end()) { - double oldNodeDist = glm::length(oldNode->node->worldPosition() - camPos); - if (glm::length(camToSelectable) < oldNodeDist) { // new node is closer, remove added node and add the new one instead + double oldNodeDist = glm::length( + oldNode->node->worldPosition() - camPos + ); + if (glm::length(camToSelectable) < oldNodeDist) { + // new node is closer, remove added node and add the new one + // instead newSelected.pop_back(); newSelected.push_back({ id, node, pointInModelView }); } @@ -529,7 +659,9 @@ void TouchInteraction::findSelectedNode(const std::vector& list) { } // Compute locations in view space to perform the picking - glm::dvec4 clip = glm::dmat4(_camera->projectionMatrix()) * _camera->combinedViewMatrix() * glm::vec4(node->worldPosition(), 1.0); + glm::dvec4 clip = glm::dmat4(_camera->projectionMatrix()) * + _camera->combinedViewMatrix() * + glm::vec4(node->worldPosition(), 1.0); glm::dvec2 ndc = clip / clip.w; // If the object is not in the screen, we dont want to consider it at all @@ -537,17 +669,17 @@ void TouchInteraction::findSelectedNode(const std::vector& list) { glm::dvec2 cursor = { xCo, yCo }; double ndcDist = glm::length(ndc - cursor); - // We either want to select the object if it's bounding sphere as been touched - // (checked by the first part of this loop above) or if the touch point is - // within a minimum distance of the center + // We either want to select the object if it's bounding sphere as been + // touched (checked by the first part of this loop above) or if the touch + // point is within a minimum distance of the center if (dist <= 0.0 || (ndcDist <= _pickingRadiusMinimum)) { - // If the user touched the planet directly, this is definitely the one they are - // interested in => minimum distance + // If the user touched the planet directly, this is definitely the one + // they are interested in => minimum distance if (dist <= 0.0) { LINFOC(node->name(), "Picking candidate based on direct touch"); pickingInfo.push_back({ - node, + node, -std::numeric_limits::max(), -std::numeric_limits::max() }); @@ -589,29 +721,48 @@ void TouchInteraction::findSelectedNode(const std::vector& list) { } // Interprets the input gesture to a specific interaction -int TouchInteraction::interpretInteraction(const std::vector& list, const std::vector& lastProcessed) { +int TouchInteraction::interpretInteraction(const std::vector& list, + const std::vector& lastProcessed) +{ glm::dvec3 lastCentroid = _centroid; - _centroid.x = std::accumulate(list.begin(), list.end(), 0.0, [](double x, const TuioCursor& c) { return x + c.getX(); }) / list.size(); - _centroid.y = std::accumulate(list.begin(), list.end(), 0.0, [](double y, const TuioCursor& c) { return y + c.getY(); }) / list.size(); + _centroid.x = std::accumulate( + list.begin(), + list.end(), + 0.0, + [](double x, const TuioCursor& c) { return x + c.getX(); } + ) / list.size(); + _centroid.y = std::accumulate( + list.begin(), + list.end(), + 0.0, + [](double y, const TuioCursor& c) { return y + c.getY(); } + ) / list.size(); // see if the distance between fingers changed - used in pan interpretation double dist = 0; double lastDist = 0; TuioCursor cursor = list.at(0); for (const TuioCursor& c : list) { - dist += glm::length(glm::dvec2(c.getX(), c.getY()) - glm::dvec2(cursor.getX(), cursor.getY())); + dist += glm::length( + glm::dvec2(c.getX(), c.getY()) - glm::dvec2(cursor.getX(), cursor.getY()) + ); cursor = c; } TuioPoint point = lastProcessed.at(0).second; for (const Point& p : lastProcessed) { - lastDist += glm::length(glm::dvec2(p.second.getX(), p.second.getY()) - glm::dvec2(point.getX(), point.getY())); + lastDist += glm::length(glm::dvec2(p.second.getX(), p.second.getY()) - + glm::dvec2(point.getX(), point.getY())); point = p.second; } // find the slowest moving finger - used in roll interpretation double minDiff = 1000; int id = 0; for (const TuioCursor& c : list) { - TuioPoint point = std::find_if(lastProcessed.begin(), lastProcessed.end(), [&c](const Point& p) { return p.first == c.getSessionID(); })->second; + TuioPoint point = std::find_if( + lastProcessed.begin(), + lastProcessed.end(), + [&c](const Point& p) { return p.first == c.getSessionID(); } + )->second; double diff = c.getX() - point.getX() + c.getY() - point.getY(); if (!c.isMoving()) { diff = minDiff = 0.0; @@ -623,22 +774,36 @@ int TouchInteraction::interpretInteraction(const std::vector& list, } } // find if all fingers angles are high - used in roll interpretation - double rollOn = std::accumulate(list.begin(), list.end(), 0.0, [&](double diff, const TuioCursor& c) { - TuioPoint point = std::find_if(lastProcessed.begin(), lastProcessed.end(), [&c](const Point& p) { return p.first == c.getSessionID(); })->second; - double res = 0.0; - float lastAngle = point.getAngle(_centroid.x, _centroid.y); - float currentAngle = c.getAngle(_centroid.x, _centroid.y); - if (lastAngle > currentAngle + 1.5 * M_PI) - res = currentAngle + (2 * M_PI - lastAngle); - else if (currentAngle > lastAngle + 1.5 * M_PI) - res = (2 * M_PI - currentAngle) + lastAngle; - else - res = currentAngle - lastAngle; - if (std::abs(res) < _rollAngleThreshold) - return 1000.0; - else - return (diff + res); - }); + double rollOn = std::accumulate( + list.begin(), + list.end(), + 0.0, + [&](double diff, const TuioCursor& c) { + TuioPoint point = std::find_if( + lastProcessed.begin(), + lastProcessed.end(), + [&c](const Point& p) { return p.first == c.getSessionID(); } + )->second; + double res = 0.0; + float lastAngle = point.getAngle(_centroid.x, _centroid.y); + float currentAngle = c.getAngle(_centroid.x, _centroid.y); + if (lastAngle > currentAngle + 1.5 * M_PI) { + res = currentAngle + (2 * M_PI - lastAngle); + } + else if (currentAngle > lastAngle + 1.5 * M_PI) { + res = (2 * M_PI - currentAngle) + lastAngle; + } + else { + res = currentAngle - lastAngle; + } + if (std::abs(res) < _rollAngleThreshold) { + return 1000.0; + } + else { + return (diff + res); + } + } + ); if (_doubleTap) { return PICK; @@ -647,12 +812,19 @@ int TouchInteraction::interpretInteraction(const std::vector& list, return ROT; } else { + float avgDistance = std::abs(dist - lastDist) / list.at(0).getMotionSpeed(); // if average distance between 3 fingers are constant we have panning - if (std::abs(dist - lastDist) / list.at(0).getMotionSpeed() < _interpretPan && list.size() == 3) { + if (avgDistance < _interpretPan && list.size() == 3) { return PAN; } - // we have roll if one finger is still, or the total roll angles around the centroid is over _rollAngleThreshold (_centroidStillThreshold is used to void misinterpretations) - else if (std::abs(minDiff) < _inputStillThreshold || (std::abs(rollOn) < 100.0 && glm::distance(_centroid, lastCentroid) / list.size() < _centroidStillThreshold)) { + // we have roll if one finger is still, or the total roll angles around the + // centroid is over _rollAngleThreshold (_centroidStillThreshold is used to void + // misinterpretations) + else if (std::abs(minDiff) < _inputStillThreshold || + (std::abs(rollOn) < 100.0 && + glm::distance(_centroid, lastCentroid) / list.size() + < _centroidStillThreshold)) + { return ROLL; } else { @@ -661,81 +833,128 @@ int TouchInteraction::interpretInteraction(const std::vector& list, } } -// Calculate how much interpreted interaction should change the camera state (based on _vel) -void TouchInteraction::computeVelocities(const std::vector& list, const std::vector& lastProcessed) { +// Calculate how much interpreted interaction (_vel) should change the camera state +void TouchInteraction::computeVelocities(const std::vector& list, + const std::vector& lastProcessed) +{ TuioCursor cursor = list.at(0); int action = interpretInteraction(list, lastProcessed); switch (action) { case ROT: { // add rotation velocity - _vel.orbit += glm::dvec2(cursor.getXSpeed() * _sensitivity.orbit.x, cursor.getYSpeed() * _sensitivity.orbit.y); + _vel.orbit += glm::dvec2(cursor.getXSpeed() * + _sensitivity.orbit.x, cursor.getYSpeed() * + _sensitivity.orbit.y); break; } - case PINCH: { // add zooming velocity - dependant on distance difference between contact points this/last frame - double distance = std::accumulate(list.begin(), list.end(), 0.0, [&](double d, const TuioCursor& c) { - return d + c.getDistance(_centroid.x, _centroid.y); - }) / list.size(); - double lastDistance = std::accumulate(lastProcessed.begin(), lastProcessed.end(), 0.0f, [&](float d, const Point& p) { - return d + p.second.getDistance(_centroid.x, _centroid.y); - }) / lastProcessed.size(); + case PINCH: { + // add zooming velocity - dependant on distance difference between contact + // points this/last frame + double distance = std::accumulate( + list.begin(), + list.end(), + 0.0, + [&](double d, const TuioCursor& c) { + return d + c.getDistance(_centroid.x, _centroid.y); + } + ) / list.size(); + double lastDistance = std::accumulate( + lastProcessed.begin(), + lastProcessed.end(), + 0.0f, + [&](float d, const Point& p) { + return d + p.second.getDistance(_centroid.x, _centroid.y); + } + ) / lastProcessed.size(); - double zoomFactor = (distance - lastDistance) * (glm::distance(_camera->positionVec3(), _camera->focusPositionVec3()) - _focusNode->boundingSphere()); - _vel.zoom += zoomFactor * _sensitivity.zoom * std::max(_touchScreenSize.value() * 0.1, 1.0); + double zoomFactor = (distance - lastDistance) * + (glm::distance(_camera->positionVec3(), _camera->focusPositionVec3()) - + _focusNode->boundingSphere()); + _vel.zoom += zoomFactor * _sensitivity.zoom * + std::max(_touchScreenSize.value() * 0.1, 1.0); break; } - case ROLL: { // add global roll rotation velocity - double rollFactor = std::accumulate(list.begin(), list.end(), 0.0, [&](double diff, const TuioCursor& c) { - TuioPoint point = std::find_if(lastProcessed.begin(), lastProcessed.end(), [&c](const Point& p) { return p.first == c.getSessionID(); })->second; - double res = diff; - double lastAngle = point.getAngle(_centroid.x, _centroid.y); - double currentAngle = c.getAngle(_centroid.x, _centroid.y); - // if's used to set angles 359 + 1 = 0 and 0 - 1 = 359 - if (lastAngle > currentAngle + 1.5 * M_PI) - res += currentAngle + (2 * M_PI - lastAngle); - else if (currentAngle > lastAngle + 1.5 * M_PI) - res += (2 * M_PI - currentAngle) + lastAngle; - else - res += currentAngle - lastAngle; - return res; - }) / list.size(); + case ROLL: { + // add global roll rotation velocity + double rollFactor = std::accumulate( + list.begin(), + list.end(), + 0.0, + [&](double diff, const TuioCursor& c) { + TuioPoint point = std::find_if( + lastProcessed.begin(), + lastProcessed.end(), + [&c](const Point& p) { return p.first == c.getSessionID(); } + )->second; + double res = diff; + double lastAngle = point.getAngle(_centroid.x, _centroid.y); + double currentAngle = c.getAngle(_centroid.x, _centroid.y); + // if's used to set angles 359 + 1 = 0 and 0 - 1 = 359 + if (lastAngle > currentAngle + 1.5 * M_PI) { + res += currentAngle + (2 * M_PI - lastAngle); + } + else if (currentAngle > lastAngle + 1.5 * M_PI) { + res += (2 * M_PI - currentAngle) + lastAngle; + } + else { + res += currentAngle - lastAngle; + } + return res; + } + ) / list.size(); _vel.roll += -rollFactor * _sensitivity.roll; break; } - case PAN: { // add local rotation velocity - _vel.pan += glm::dvec2(cursor.getXSpeed() * _sensitivity.pan.x, cursor.getYSpeed() * _sensitivity.pan.y); + case PAN: { + // add local rotation velocity + _vel.pan += glm::dvec2(cursor.getXSpeed() * + _sensitivity.pan.x, cursor.getYSpeed() * _sensitivity.pan.y); break; } - case PICK: { // pick something in the scene as focus node + case PICK: { + // pick something in the scene as focus node if (_pickingSelected) { setFocusNode(_pickingSelected); - OsEng.navigationHandler().setFocusNode(_focusNode); // cant do setFocusNode() since TouchInteraction is not subclass of InteractionMode + // cant do setFocusNode() since TouchInteraction is not subclass of + // InteractionMode + OsEng.navigationHandler().setFocusNode(_focusNode); // rotate camera to look at new focus, using slerp quat - glm::dvec3 camToFocus = _focusNode->worldPosition() - _camera->positionVec3(); - glm::dvec3 camForward = glm::normalize(_camera->viewDirectionWorldSpace()); - double angle = glm::angle(camForward, camToFocus); - glm::dvec3 axis = glm::normalize(glm::cross(camForward, camToFocus)); - _toSlerp.x = axis.x * sin(angle / 2.0); + glm::dvec3 camToFocus = _focusNode->worldPosition() - + _camera->positionVec3(); + glm::dvec3 forward = glm::normalize(_camera->viewDirectionWorldSpace()); + double angle = glm::angle(forward, camToFocus); + glm::dvec3 axis = glm::normalize(glm::cross(forward, camToFocus)); + _toSlerp.x = axis.x * sin(angle / 2.0); _toSlerp.y = axis.y * sin(angle / 2.0); _toSlerp.z = axis.z * sin(angle / 2.0); _toSlerp.w = cos(angle / 2.0); _slerpdT = 0.0; } - else { // zooms in to current if PICK interpret happened but only space was selected - double dist = glm::distance(_camera->positionVec3(), _camera->focusPositionVec3()) - _focusNode->boundingSphere(); - _vel.zoom = (_sensitivity.zoom * std::max(_touchScreenSize.value() * 0.1, 1.0)) * _tapZoomFactor * dist; + else { + // zooms in to current if PICK interpret happened but only space was + // selected + double dist = glm::distance( + _camera->positionVec3(), _camera->focusPositionVec3() + ) - _focusNode->boundingSphere(); + _vel.zoom = _sensitivity.zoom * + std::max(_touchScreenSize.value() * 0.1, 1.0) * + _tapZoomFactor * dist; } break; } } } -// Main update call, calculates the new orientation and position for the camera depending on _vel and dt. Called every frame +// Main update call, calculates the new orientation and position for the camera depending +// on _vel and dt. Called every frame void TouchInteraction::step(double dt) { using namespace glm; - setFocusNode(OsEng.navigationHandler().focusNode()); // since functions cant be called directly (TouchInteraction not a subclass of InteractionMode) + // since functions cant be called directly (TouchInteraction not a subclass of + // InteractionMode) + setFocusNode(OsEng.navigationHandler().focusNode()); if (_focusNode && _camera) { // Create variables from current state dvec3 camPos = _camera->positionVec3(); @@ -746,25 +965,31 @@ void TouchInteraction::step(double dt) { dvec3 lookUp = _camera->lookUpVectorWorldSpace(); dvec3 camDirection = _camera->viewDirectionWorldSpace(); - // Make a representation of the rotation quaternion with local and global rotations + // Make a representation of the rotation quaternion with local and global + // rotations + // To avoid problem with lookup in up direction dmat4 lookAtMat = lookAt( dvec3(0, 0, 0), directionToCenter, - normalize(camDirection + lookUp)); // To avoid problem with lookup in up direction + normalize(camDirection + lookUp) + ); dquat globalCamRot = normalize(quat_cast(inverse(lookAtMat))); dquat localCamRot = inverse(globalCamRot) * _camera->rotationQuaternion(); double boundingSphere = _focusNode->boundingSphere(); dvec3 centerToBoundingSphere; double distance = std::max(length(centerToCamera) - boundingSphere, 0.0); - _currentRadius = boundingSphere / std::max(distance * _projectionScaleFactor, 1.0); + _currentRadius = boundingSphere / + std::max(distance * _projectionScaleFactor, 1.0); - { // Roll - dquat camRollRot = angleAxis(_vel.roll*dt, dvec3(0.0, 0.0, 1.0)); + { + // Roll + dquat camRollRot = angleAxis(_vel.roll * dt, dvec3(0.0, 0.0, 1.0)); localCamRot = localCamRot * camRollRot; } - { // Panning (local rotation) - dvec3 eulerAngles(_vel.pan.y*dt, _vel.pan.x*dt, 0); + { + // Panning (local rotation) + dvec3 eulerAngles(_vel.pan.y * dt, _vel.pan.x * dt, 0); dquat rotationDiff = dquat(eulerAngles); localCamRot = localCamRot * rotationDiff; @@ -774,17 +999,21 @@ void TouchInteraction::step(double dt) { localCamRot = slerp(localCamRot, _toSlerp, _slerpdT / _slerpTime); } } - { // Orbit (global rotation) + { + // Orbit (global rotation) dvec3 eulerAngles(_vel.orbit.y*dt, _vel.orbit.x*dt, 0); dquat rotationDiffCamSpace = dquat(eulerAngles); - dquat rotationDiffWorldSpace = globalCamRot * rotationDiffCamSpace * inverse(globalCamRot); - dvec3 rotationDiffVec3 = centerToCamera * rotationDiffWorldSpace - centerToCamera; + dquat rotationDiffWorldSpace = globalCamRot * rotationDiffCamSpace * + inverse(globalCamRot); + dvec3 rotationDiffVec3 = centerToCamera * rotationDiffWorldSpace - + centerToCamera; camPos += rotationDiffVec3; dvec3 centerToCamera = camPos - centerPos; directionToCenter = normalize(-centerToCamera); - dvec3 lookUpWhenFacingCenter = globalCamRot * dvec3(_camera->lookUpVectorCameraSpace()); + dvec3 lookUpWhenFacingCenter = globalCamRot * + dvec3(_camera->lookUpVectorCameraSpace()); dmat4 lookAtMat = lookAt( dvec3(0, 0, 0), directionToCenter, @@ -796,7 +1025,10 @@ void TouchInteraction::step(double dt) { dvec3 centerToCamera = camPos - centerPos; double distToSurface = length(centerToCamera - centerToBoundingSphere); - if (length(_vel.zoom*dt) < distToSurface && length(centerToCamera + directionToCenter*_vel.zoom*dt) > length(centerToBoundingSphere)) { + if (length(_vel.zoom * dt) < distToSurface && + length(centerToCamera + directionToCenter*_vel.zoom * dt) > + length(centerToBoundingSphere)) + { camPos += directionToCenter * _vel.zoom * dt; } else { @@ -856,21 +1088,25 @@ void TouchInteraction::unitTest() { } } -/* Decelerate velocities, called a set number of times per second to dereference it from frame time -* Example: -* Assume: frequency = 0.01, dt = 0.05 (200 fps), _timeSlack = 0.0001 -* times = floor((0.05 + 0.0001) / 0.01) = 5 -* _timeSlack = 0.0501 % 0.01 = 0.01 -*/ +// Decelerate velocities, called a set number of times per second to dereference it from +// frame time +// Example: +// Assume: frequency = 0.01, dt = 0.05 (200 fps), _timeSlack = 0.0001 +// times = floor((0.05 + 0.0001) / 0.01) = 5 +// _timeSlack = 0.0501 % 0.01 = 0.01 + void TouchInteraction::decelerate(double dt) { double frequency = 1.0 / _deceleratesPerSecond; - // Number of times velocities should decelerate, depending on chosen frequency and time slack over from last frame + // Number of times velocities should decelerate, depending on chosen frequency and + // time slack over from last frame int times = (dt + _timeSlack) / frequency; // Save the new time slack for the next frame _timeSlack = fmod((dt + _timeSlack), frequency); // Decelerate zoom velocity quicker if we're close enough to use direct-manipulation - if (!_directTouchMode && _currentRadius > _nodeRadiusThreshold && _vel.zoom > _focusNode->boundingSphere()) { + if (!_directTouchMode && _currentRadius > _nodeRadiusThreshold && + _vel.zoom > _focusNode->boundingSphere()) + { _vel.zoom *= std::pow(1 - 2 * _friction.value().y, times); } _vel.orbit *= std::pow(1 - _friction.value().x, times); @@ -883,7 +1119,8 @@ void TouchInteraction::decelerate(double dt) { void TouchInteraction::resetAfterInput() { if (_directTouchMode && _selected.size() > 0 && _lmSuccess) { double spinDelta = _spinSensitivity / OsEng.windowWrapper().averageDeltaTime(); - if (glm::length(_lastVel.orbit) > _orbitSpeedThreshold) { // allow node to start "spinning" after direct-manipulation finger is let go off + if (glm::length(_lastVel.orbit) > _orbitSpeedThreshold) { + // allow node to start "spinning" after direct-manipulation finger is let go _vel.orbit = _lastVel.orbit * spinDelta; } } diff --git a/modules/touch/src/touchmarker.cpp b/modules/touch/src/touchmarker.cpp index d4cfe8afa4..d71404b413 100644 --- a/modules/touch/src/touchmarker.cpp +++ b/modules/touch/src/touchmarker.cpp @@ -34,18 +34,46 @@ namespace { const std::string _loggerCat = "TouchMarker"; const int MAX_FINGERS = 20; + + static const openspace::properties::Property::PropertyInfo VisibilityInfo = { + "Visibility", + "Toggle visibility of markers", + "" // @TODO Missing documentation + }; + + static const openspace::properties::Property::PropertyInfo RadiusInfo = { + "Size", + "Marker radius", + "" // @TODO Missing documentation + }; + + static const openspace::properties::Property::PropertyInfo TransparencyInfo = { + "Transparency", + "Marker transparency", + "" // @TODO Missing documentation + }; + + static const openspace::properties::Property::PropertyInfo ThicknessInfo = { + "Thickness", + "Marker thickness", + "" // @TODO Missing documentation + }; + + static const openspace::properties::Property::PropertyInfo ColorInfo = { + "MarkerColor", "Marker color", "" // @TODO Missing documentation + }; } // namespace namespace openspace { TouchMarker::TouchMarker() : properties::PropertyOwner({ "TouchMarker" }) - , _visible({ "TouchMarkers visible", "Toggle visibility of markers", "" }, true) // @TODO Missing documentation - , _radiusSize({ "Marker size", "Marker radius", "" }, 30.f, 0.f, 100.f) // @TODO Missing documentation - , _transparency({ "Transparency of marker", "Marker transparency", "" }, 0.8f, 0.f, 1.f) // @TODO Missing documentation - , _thickness({ "Thickness of marker", "Marker thickness", "" }, 2.f, 0.f, 4.f) // @TODO Missing documentation + , _visible(VisibilityInfo, true) + , _radiusSize(RadiusInfo, 30.f, 0.f, 100.f) + , _transparency(TransparencyInfo, 0.8f, 0.f, 1.f) + , _thickness(ThicknessInfo, 2.f, 0.f, 4.f ) , _color( - { "MarkerColor", "Marker color", "" }, // @TODO Missing documentation + ColorInfo, glm::vec3(204.f / 255.f, 51.f / 255.f, 51.f / 255.f), glm::vec3(0.f), glm::vec3(1.f) diff --git a/modules/touch/src/tuioear.cpp b/modules/touch/src/tuioear.cpp index a9e2e128ae..6841926a20 100644 --- a/modules/touch/src/tuioear.cpp +++ b/modules/touch/src/tuioear.cpp @@ -44,7 +44,8 @@ void TuioEar::removeTuioObject(TuioObject*) { } void TuioEar::addTuioCursor(TuioCursor* tcur) { _mx.lock(); _tap = false; - // find same id in _list if it exists in _removeList (new input with same ID as a previously stored) + // find same id in _list if it exists in _removeList (new input with same ID as a + // previously stored) int i = tcur->getSessionID(); std::vector::iterator foundID = std::find_if( _removeList.begin(), @@ -93,7 +94,10 @@ void TuioEar::removeTuioCursor(TuioCursor* tcur) { } dist /= tcur->getPath().size(); - double heldTime = tcur->getPath().back().getTuioTime().getTotalMilliseconds() - tcur->getPath().front().getTuioTime().getTotalMilliseconds(); + double heldTime = + tcur->getPath().back().getTuioTime().getTotalMilliseconds() - + tcur->getPath().front().getTuioTime().getTotalMilliseconds(); + if (heldTime < 180 && dist < 0.0004 && _list.size() == 1 && _removeList.size() == 1) { _tapCo = TuioCursor(*tcur); _tap = true; diff --git a/modules/touch/touchmodule.cpp b/modules/touch/touchmodule.cpp index 8da5114914..eb7505c81f 100644 --- a/modules/touch/touchmodule.cpp +++ b/modules/touch/touchmodule.cpp @@ -46,7 +46,8 @@ bool TouchModule::hasNewInput() { // Get new input from listener listOfContactPoints = ear.getInput(); ear.clearInput(); - touch.touchActive(!listOfContactPoints.empty()); // Set touch property to active (to void mouse input, mainly for mtdev bridges) + // Set touch property to active (to void mouse input, mainly for mtdev bridges) + touch.touchActive(!listOfContactPoints.empty()); // Erase old input id's that no longer exists lastProcessed.erase( @@ -73,14 +74,25 @@ bool TouchModule::hasNewInput() { } // Return true if we got new input - if (listOfContactPoints.size() == lastProcessed.size() && !listOfContactPoints.empty()) { + if (listOfContactPoints.size() == lastProcessed.size() && + !listOfContactPoints.empty()) + { bool newInput = true; - // go through list and check if the last registrered time is newer than the one in lastProcessed (last frame) - std::for_each(lastProcessed.begin(), lastProcessed.end(), [this, &newInput](Point& p) { - std::vector::iterator cursor = std::find_if(listOfContactPoints.begin(), listOfContactPoints.end(), - [&p](const TuioCursor& c) { return c.getSessionID() == p.first; }); + // go through list and check if the last registrered time is newer than the one in + // lastProcessed (last frame) + std::for_each( + lastProcessed.begin(), + lastProcessed.end(), + [this, &newInput](Point& p) { + std::vector::iterator cursor = std::find_if( + listOfContactPoints.begin(), + listOfContactPoints.end(), + [&p](const TuioCursor& c) { return c.getSessionID() == p.first; } + ); double now = cursor->getPath().back().getTuioTime().getTotalMilliseconds(); - if (!cursor->isMoving()) { // if current cursor isn't moving, we want to interpret that as new input for interaction purposes + if (!cursor->isMoving()) { + // if current cursor isn't moving, we want to interpret that as new input + // for interaction purposes newInput = true; } else if (p.second.getTuioTime().getTotalMilliseconds() == now) { @@ -134,16 +146,20 @@ TouchModule::TouchModule() for (const TuioCursor& c : listOfContactPoints) { lastProcessed.emplace_back(c.getSessionID(), c.getPath().back()); } - touch.unitTest(); // used to save data from solver, only calculated for one frame when user chooses in GUI - touch.step(OsEng.windowWrapper().deltaTime()); // calculate the new camera state for this frame + // used to save data from solver, only calculated for one frame when user chooses + // in GUI + touch.unitTest(); + // calculate the new camera state for this frame + touch.step(OsEng.windowWrapper().deltaTime()); } ); OsEng.registerModuleCallback( OpenSpaceEngine::CallbackOption::Render, [&]() { - markers.render(listOfContactPoints); // render markers, customizable through the GUI - } + // render markers, customizable through the GUI + markers.render(listOfContactPoints); + } ); } diff --git a/modules/toyvolume/rendering/renderabletoyvolume.cpp b/modules/toyvolume/rendering/renderabletoyvolume.cpp index b196bf5932..070cf4be64 100644 --- a/modules/toyvolume/rendering/renderabletoyvolume.cpp +++ b/modules/toyvolume/rendering/renderabletoyvolume.cpp @@ -33,16 +33,54 @@ #include #include +namespace { + static const openspace::properties::Property::PropertyInfo ScalingInfo = { + "Scaling", + "Scaling", + "" // @TODO Missing documentation + }; + + static const openspace::properties::Property::PropertyInfo ScalingExponentInfo = { + "ScalingExponent", + "Scaling Exponent", + "" // @TODO Missing documentation + }; + + static const openspace::properties::Property::PropertyInfo StepSizeInfo = { + "StepSize", + "Step Size", + "" // @TODO Missing documentation + }; + + static const openspace::properties::Property::PropertyInfo TranslationInfo = { + "Translation", + "Translation", + "" // @TODO Missing documentation + }; + + static const openspace::properties::Property::PropertyInfo RotationInfo = { + "Rotation", + "Euler rotation", + "" // @TODO Missing documentation + }; + + static const openspace::properties::Property::PropertyInfo ColorInfo = { + "Color", + "Color", + "" // @TODO Missing documentation + }; +} // namespace + namespace openspace { RenderableToyVolume::RenderableToyVolume(const ghoul::Dictionary& dictionary) : Renderable(dictionary) - , _scaling({ "Scaling", "Scaling", "" }, glm::vec3(1.f, 1.f, 1.f), glm::vec3(0.f), glm::vec3(10.f)) // @TODO Missing documentation - , _scalingExponent({ "ScalingExponent", "Scaling Exponent", "" }, 1, -10, 20) - , _stepSize({ "StepSize", "Step Size", "" }, 0.02f, 0.01f, 1.f) // @TODO Missing documentation - , _translation({ "Translation", "Translation", "" }, glm::vec3(0.f, 0.f, 0.f), glm::vec3(0.f), glm::vec3(10.f)) // @TODO Missing documentation - , _rotation({ "Rotation", "Euler rotation", "" }, glm::vec3(0.f, 0.f, 0.f), glm::vec3(0), glm::vec3(6.28f)) // @TODO Missing documentation - , _color({ "Color", "Color", "" }, glm::vec4(1.f, 0.f, 0.f, 0.1f), glm::vec4(0.f), glm::vec4(1.f)) // @TODO Missing documentation + , _scaling(ScalingInfo, glm::vec3(1.f, 1.f, 1.f), glm::vec3(0.f), glm::vec3(10.f)) + , _scalingExponent(ScalingExponentInfo, 1, -10, 20) + , _stepSize(StepSizeInfo, 0.02f, 0.01f, 1.f ) + , _translation(TranslationInfo, glm::vec3(0.f), glm::vec3(0.f), glm::vec3(10.f)) + , _rotation(RotationInfo, glm::vec3(0.f, 0.f, 0.f), glm::vec3(0), glm::vec3(6.28f)) + , _color(ColorInfo, glm::vec4(1.f, 0.f, 0.f, 0.1f), glm::vec4(0.f), glm::vec4(1.f)) { float stepSize, scalingExponent; glm::vec3 scaling, translation, rotation; @@ -108,12 +146,20 @@ bool RenderableToyVolume::isReady() const { void RenderableToyVolume::update(const UpdateData& data) { if (_raycaster) { - glm::mat4 transform = glm::translate(glm::mat4(1.0), static_cast(_translation) * std::pow(10.0f, static_cast(_scalingExponent))); + glm::mat4 transform = glm::translate( + glm::mat4(1.0), + static_cast(_translation) * + std::pow(10.0f, static_cast(_scalingExponent)) + ); glm::vec3 eulerRotation = static_cast(_rotation); transform = glm::rotate(transform, eulerRotation.x, glm::vec3(1, 0, 0)); transform = glm::rotate(transform, eulerRotation.y, glm::vec3(0, 1, 0)); transform = glm::rotate(transform, eulerRotation.z, glm::vec3(0, 0, 1)); - transform = glm::scale(transform, static_cast(_scaling) * std::pow(10.0f, static_cast(_scalingExponent))); + transform = glm::scale( + transform, + static_cast(_scaling) * + std::pow(10.0f, static_cast(_scalingExponent)) + ); _raycaster->setColor(_color); _raycaster->setStepSize(_stepSize); diff --git a/modules/toyvolume/rendering/toyvolumeraycaster.cpp b/modules/toyvolume/rendering/toyvolumeraycaster.cpp index 9031ca6943..04406014e3 100644 --- a/modules/toyvolume/rendering/toyvolumeraycaster.cpp +++ b/modules/toyvolume/rendering/toyvolumeraycaster.cpp @@ -54,7 +54,9 @@ void ToyVolumeRaycaster::initialize() { void ToyVolumeRaycaster::deinitialize() { } -void ToyVolumeRaycaster::renderEntryPoints(const RenderData& data, ghoul::opengl::ProgramObject& program) { +void ToyVolumeRaycaster::renderEntryPoints(const RenderData& data, + ghoul::opengl::ProgramObject& program) +{ program.setUniform("modelTransform", _modelTransform); program.setUniform("viewProjection", data.camera.viewProjectionMatrix()); Renderable::setPscUniforms(program, data.camera, data.position); @@ -67,7 +69,9 @@ void ToyVolumeRaycaster::renderEntryPoints(const RenderData& data, ghoul::opengl _boundingBox.render(); } -void ToyVolumeRaycaster::renderExitPoints(const RenderData& data, ghoul::opengl::ProgramObject& program) { +void ToyVolumeRaycaster::renderExitPoints(const RenderData& data, + ghoul::opengl::ProgramObject& program) +{ // Uniforms program.setUniform("modelTransform", _modelTransform); program.setUniform("viewProjection", data.camera.viewProjectionMatrix()); @@ -84,7 +88,9 @@ void ToyVolumeRaycaster::renderExitPoints(const RenderData& data, ghoul::opengl: glCullFace(GL_BACK); } -void ToyVolumeRaycaster::preRaycast(const RaycastData& data, ghoul::opengl::ProgramObject& program) { +void ToyVolumeRaycaster::preRaycast(const RaycastData& data, + ghoul::opengl::ProgramObject& program) +{ std::string colorUniformName = "color" + std::to_string(data.id); std::string timeUniformName = "time" + std::to_string(data.id); std::string stepSizeUniformName = "maxStepSize" + std::to_string(data.id); diff --git a/modules/toyvolume/rendering/toyvolumeraycaster.h b/modules/toyvolume/rendering/toyvolumeraycaster.h index a433952c96..ac5eaa3569 100644 --- a/modules/toyvolume/rendering/toyvolumeraycaster.h +++ b/modules/toyvolume/rendering/toyvolumeraycaster.h @@ -75,4 +75,4 @@ private: } // openspace -#endif // __OPENSPACE_MODULE_TOYVOLUME___TOYVOLUMERAYCASTER___H__ +#endif // __OPENSPACE_MODULE_TOYVOLUME___TOYVOLUMERAYCASTER___H__ diff --git a/modules/volume/rawvolumewriter.h b/modules/volume/rawvolumewriter.h index 5fc5ff4d3a..20baf35b68 100644 --- a/modules/volume/rawvolumewriter.h +++ b/modules/volume/rawvolumewriter.h @@ -36,7 +36,7 @@ template class RawVolumeWriter { public: RawVolumeWriter(std::string path, size_t bufferSize = 1024); - void setPath(const std::string& path); + void setPath(const std::string& path); glm::uvec3 dimensions() const; void setDimensions(const glm::uvec3& dimensions); void write(const std::function& fn, @@ -53,7 +53,7 @@ private: }; } // namespace volume -} // namespace openspace +} // namespace openspace #include "rawvolumewriter.inl" diff --git a/modules/volume/rawvolumewriter.inl b/modules/volume/rawvolumewriter.inl index 3f999295df..0e443e39ad 100644 --- a/modules/volume/rawvolumewriter.inl +++ b/modules/volume/rawvolumewriter.inl @@ -85,7 +85,7 @@ void RawVolumeWriter::write(const std::function +template void RawVolumeWriter::write(const RawVolume& volume) { setDimensions(volume.dimensions()); diff --git a/modules/volume/rendering/basicvolumeraycaster.h b/modules/volume/rendering/basicvolumeraycaster.h index 9182ffc8b8..4ff6580d49 100644 --- a/modules/volume/rendering/basicvolumeraycaster.h +++ b/modules/volume/rendering/basicvolumeraycaster.h @@ -56,7 +56,7 @@ class BasicVolumeRaycaster : public VolumeRaycaster { public: BasicVolumeRaycaster( std::shared_ptr texture, - std::shared_ptr transferFunction, + std::shared_ptr transferFunction, std::shared_ptr clipPlanes); virtual ~BasicVolumeRaycaster(); void initialize(); @@ -111,4 +111,4 @@ private: } // namespace openspace -#endif // __OPENSPACE_MODULE_VOLUME___BASICVOLUMERAYCASTER___H__ +#endif // __OPENSPACE_MODULE_VOLUME___BASICVOLUMERAYCASTER___H__ diff --git a/modules/volume/rendering/volumeclipplanes.cpp b/modules/volume/rendering/volumeclipplanes.cpp index 83219e4e87..b34fcc4c1b 100644 --- a/modules/volume/rendering/volumeclipplanes.cpp +++ b/modules/volume/rendering/volumeclipplanes.cpp @@ -33,7 +33,7 @@ namespace volume { VolumeClipPlanes::VolumeClipPlanes(const ghoul::Dictionary& dictionary) : properties::PropertyOwner({ "" }) // @TODO Missing name // @TODO Missing documentation - , _nClipPlanes({ "nClipPlanes", "Number of clip planes", "" }, 0, 0, 10) + , _nClipPlanes({ "nClipPlanes", "Number of clip planes", "" }, 0, 0, 10) { std::vector keys = dictionary.keys(); for (const std::string& key : keys) { diff --git a/modules/volume/volumeutils.cpp b/modules/volume/volumeutils.cpp index 287726e027..f6431ca69f 100644 --- a/modules/volume/volumeutils.cpp +++ b/modules/volume/volumeutils.cpp @@ -30,7 +30,7 @@ size_t coordsToIndex(const glm::uvec3& coords, const glm::uvec3& dims) { size_t w = dims.x; size_t h = dims.y; // size_t d = dims.z; -// +// // size_t x = coords.x; // size_t y = coords.y; // size_t z = coords.z; diff --git a/src/documentation/documentation.cpp b/src/documentation/documentation.cpp index 8d8b7afff4..941b50d5b5 100644 --- a/src/documentation/documentation.cpp +++ b/src/documentation/documentation.cpp @@ -65,7 +65,7 @@ struct WarningCompare { // so we have to include one ourselves namespace std { std::string to_string(std::string value) { - return value; + return value; } std::string to_string(openspace::documentation::TestResult::Offense::Reason reason) { diff --git a/src/documentation/documentationgenerator.cpp b/src/documentation/documentationgenerator.cpp index 7526fddf37..ba0fca7354 100644 --- a/src/documentation/documentationgenerator.cpp +++ b/src/documentation/documentationgenerator.cpp @@ -136,7 +136,7 @@ void DocumentationGenerator::writeDocumentation(const std::string& filename) { << "\t" << "" << '\n' << "\t" << "" << '\n' << "\t\t" << "" << _name << "" << '\n' << "\t" << "" << '\n' diff --git a/src/documentation/verifier.cpp b/src/documentation/verifier.cpp index 8d4b302e87..43c69580e4 100644 --- a/src/documentation/verifier.cpp +++ b/src/documentation/verifier.cpp @@ -300,7 +300,7 @@ AndVerifier::AndVerifier(Verifier* l, Verifier* r) } TestResult AndVerifier::operator()(const ghoul::Dictionary& dict, - const std::string& key) const + const std::string& key) const { TestResult resLhs = lhs->operator()(dict, key); TestResult resRhs = rhs->operator()(dict, key); diff --git a/src/engine/downloadmanager.cpp b/src/engine/downloadmanager.cpp index 21e67c259c..019878987d 100644 --- a/src/engine/downloadmanager.cpp +++ b/src/engine/downloadmanager.cpp @@ -426,7 +426,7 @@ void DownloadManager::getFileExtension(const std::string& url, if (CURLE_OK == res) { char* ct; // ask for the content-type - res = curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &ct); + res = curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &ct); if ((res == CURLE_OK) && ct && finishedCallback) { finishedCallback(std::string(ct)); } diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 406f8c7750..876ae47594 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -832,7 +832,7 @@ void OpenSpaceEngine::configureLogging() { ConfigurationManager::KeyLogging + '.' + ConfigurationManager::PartLogLevel; const std::string KeyLogImmediateFlush = ConfigurationManager::KeyLogging + '.' + ConfigurationManager::PartImmediateFlush; - const std::string KeyLogs = + const std::string KeyLogs = ConfigurationManager::KeyLogging + '.' + ConfigurationManager::PartLogs; if (configurationManager().hasKeyAndValue(KeyLogLevel)) { @@ -1009,7 +1009,7 @@ void OpenSpaceEngine::initializeGL() { // The ordering of the KeyCheckOpenGLState and KeyLogEachOpenGLCall are important as // the callback mask in glbinding is stateful for each context, and since - // KeyLogEachOpenGLCall is more specific, we want it to be able to overwrite the + // KeyLogEachOpenGLCall is more specific, we want it to be able to overwrite the // state from KeyCheckOpenGLState if (_configurationManager->hasKey(ConfigurationManager::KeyCheckOpenGLState)) { const bool val = _configurationManager->value( diff --git a/src/engine/syncengine.cpp b/src/engine/syncengine.cpp index 684669b5f9..1337e5ef2d 100644 --- a/src/engine/syncengine.cpp +++ b/src/engine/syncengine.cpp @@ -32,7 +32,7 @@ namespace openspace { -SyncEngine::SyncEngine(unsigned int syncBufferSize) +SyncEngine::SyncEngine(unsigned int syncBufferSize) : _syncBuffer(syncBufferSize) { ghoul_assert(syncBufferSize > 0, "syncBufferSize must be bigger than 0"); diff --git a/src/engine/wrapper/sgctwindowwrapper.cpp b/src/engine/wrapper/sgctwindowwrapper.cpp index 4940e12b33..6754293148 100644 --- a/src/engine/wrapper/sgctwindowwrapper.cpp +++ b/src/engine/wrapper/sgctwindowwrapper.cpp @@ -171,7 +171,7 @@ glm::vec2 SGCTWindowWrapper::dpiScaling() const { int SGCTWindowWrapper::currentNumberOfAaSamples() const { return sgct::Engine::instance()->getCurrentWindowPtr()->getNumberOfAASamples(); -} +} bool SGCTWindowWrapper::isRegularRendering() const { sgct::SGCTWindow* w = sgct::Engine::instance()->getCurrentWindowPtr(); diff --git a/src/interaction/navigationhandler.cpp b/src/interaction/navigationhandler.cpp index 4746f84296..08c4373dac 100644 --- a/src/interaction/navigationhandler.cpp +++ b/src/interaction/navigationhandler.cpp @@ -149,7 +149,7 @@ void NavigationHandler::updateCamera(double deltaTime) { } else { _orbitalNavigator->updateMouseStatesFromInput(*_inputState, deltaTime); - _orbitalNavigator->updateCameraStateFromMouseStates(*_camera, deltaTime); + _orbitalNavigator->updateCameraStateFromMouseStates(*_camera, deltaTime); } _camera->setFocusPositionVec3(focusNode()->worldPosition()); } diff --git a/src/interaction/orbitalnavigator.cpp b/src/interaction/orbitalnavigator.cpp index a7f67fe980..0478eceb6f 100644 --- a/src/interaction/orbitalnavigator.cpp +++ b/src/interaction/orbitalnavigator.cpp @@ -88,7 +88,7 @@ namespace { namespace openspace::interaction { -OrbitalNavigator::Friction::Friction() +OrbitalNavigator::Friction::Friction() : properties::PropertyOwner({ "Friction" }) , roll(RollFrictionInfo, true) , rotational(RotationalFrictionInfo, true) @@ -108,7 +108,7 @@ OrbitalNavigator::OrbitalNavigator() , _sensitivity(SensitivityInfo, 20.0f, 1.0f, 50.f) , _mouseStates(_sensitivity * pow(10.0, -4), 1 / (_friction.friction + 0.0000001)) { - auto smoothStep = + auto smoothStep = [](double t) { double res = 3.0 * t*t - 2.0 * t*t*t; return glm::clamp(res, 0.0, 1.0); @@ -261,7 +261,7 @@ void OrbitalNavigator::updateCameraStateFromMouseStates(Camera& camera, double d ); // Update the camera state - camera.setPositionVec3(camPos); + camera.setPositionVec3(camPos); camera.setRotation(camRot.globalRotation * camRot.localRotation); } } @@ -504,7 +504,7 @@ glm::dvec3 OrbitalNavigator::translateVertically( glm::dquat OrbitalNavigator::rotateHorizontally( double deltaTime, const glm::dquat& globalCameraRotation, - const glm::dvec3& /*cameraPosition*/, + const glm::dvec3& /*cameraPosition*/, const SurfacePositionHandle& positionHandle) const { glm::dmat4 modelTransform = _focusNode->modelTransform(); diff --git a/src/mission/mission.cpp b/src/mission/mission.cpp index 88297f165a..1445f9a3e7 100644 --- a/src/mission/mission.cpp +++ b/src/mission/mission.cpp @@ -125,8 +125,8 @@ MissionPhase::MissionPhase(const ghoul::Dictionary& dict) { _timeRange.include(overallTimeRange); } else { - // Its OK to not specify an overall time range, the time range for the - // subphases will simply be used. + // Its OK to not specify an overall time range, the time range for the + // subphases will simply be used. _timeRange.include(timeRangeSubPhases); } } diff --git a/src/network/networkengine.cpp b/src/network/networkengine.cpp index 0a0be411f2..edea7cc398 100644 --- a/src/network/networkengine.cpp +++ b/src/network/networkengine.cpp @@ -49,7 +49,7 @@ namespace { namespace openspace { -NetworkEngine::NetworkEngine() +NetworkEngine::NetworkEngine() // -1 is okay as we assign one identifier in this ctor : _lastAssignedIdentifier(MessageIdentifier(-1)) , _shouldPublishStatusMessage(true) @@ -217,7 +217,7 @@ void NetworkEngine::sendInitialInformation() { std::vector payload = m.body; payload.insert(payload.begin(), identifier.data.begin(), identifier.data.end()); OsEng.windowWrapper().sendMessageToExternalControl(payload); - LINFO("Sent initial message: (s=" << m.body.size() << ")" << + LINFO("Sent initial message: (s=" << m.body.size() << ")" << "[i=" << identifier.value << "]" ); diff --git a/src/network/parallelconnection.cpp b/src/network/parallelconnection.cpp index 2860fdf55e..550c3abfef 100644 --- a/src/network/parallelconnection.cpp +++ b/src/network/parallelconnection.cpp @@ -628,7 +628,7 @@ double ParallelConnection::timeTolerance() const { void ParallelConnection::dataMessageReceived(const std::vector& messageContent) { // The type of data message received - uint32_t type = *(reinterpret_cast(messageContent.data())); + uint32_t type = *(reinterpret_cast(messageContent.data())); std::vector buffer( messageContent.begin() + sizeof(uint32_t), messageContent.end() diff --git a/src/properties/matrix/dmat2property.cpp b/src/properties/matrix/dmat2property.cpp index 9dd7bf0e53..009afe1de4 100644 --- a/src/properties/matrix/dmat2property.cpp +++ b/src/properties/matrix/dmat2property.cpp @@ -126,7 +126,7 @@ REGISTER_NUMERICALPROPERTY_SOURCE(DMat2Property, glm::dmat2x2, glm::dmat2x2(0), numeric_limits::max() ), glm::dmat2x2( - 0.01, 0.01, + 0.01, 0.01, 0.01, 0.01 ), DEFAULT_FROM_LUA_LAMBDA(glm::dmat2x2), diff --git a/src/properties/matrix/dmat2x3property.cpp b/src/properties/matrix/dmat2x3property.cpp index 1cfecabde0..8178e25617 100644 --- a/src/properties/matrix/dmat2x3property.cpp +++ b/src/properties/matrix/dmat2x3property.cpp @@ -130,7 +130,7 @@ REGISTER_NUMERICALPROPERTY_SOURCE(DMat2x3Property, glm::dmat2x3, glm::dmat2x3(0) numeric_limits::max() ), glm::dmat2x3( - 0.01, 0.01, 0.01, + 0.01, 0.01, 0.01, 0.01, 0.01, 0.01 ), DEFAULT_FROM_LUA_LAMBDA(glm::dmat2x3), diff --git a/src/properties/matrix/dmat2x4property.cpp b/src/properties/matrix/dmat2x4property.cpp index 6277315574..9706a1929c 100644 --- a/src/properties/matrix/dmat2x4property.cpp +++ b/src/properties/matrix/dmat2x4property.cpp @@ -134,7 +134,7 @@ REGISTER_NUMERICALPROPERTY_SOURCE(DMat2x4Property, glm::dmat2x4, glm::dmat2x4(0) numeric_limits::max() ), glm::dmat2x4( - 0.01, 0.01, 0.01, 0.01, + 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01 ), DEFAULT_FROM_LUA_LAMBDA(glm::dmat2x4), diff --git a/src/properties/matrix/dmat3property.cpp b/src/properties/matrix/dmat3property.cpp index e00d73ea6d..acdb6af091 100644 --- a/src/properties/matrix/dmat3property.cpp +++ b/src/properties/matrix/dmat3property.cpp @@ -136,8 +136,8 @@ REGISTER_NUMERICALPROPERTY_SOURCE(DMat3Property, glm::dmat3x3, glm::dmat3x3(0), numeric_limits::max() ), glm::dmat3x3( - 0.01, 0.01, 0.01, - 0.01, 0.01, 0.01, + 0.01, 0.01, 0.01, + 0.01, 0.01, 0.01, 0.01, 0.01, 0.01 ), DEFAULT_FROM_LUA_LAMBDA(glm::dmat3x3), diff --git a/src/properties/matrix/dmat3x2property.cpp b/src/properties/matrix/dmat3x2property.cpp index 29bcf67716..8ee35db37f 100644 --- a/src/properties/matrix/dmat3x2property.cpp +++ b/src/properties/matrix/dmat3x2property.cpp @@ -130,7 +130,7 @@ REGISTER_NUMERICALPROPERTY_SOURCE(DMat3x2Property, glm::dmat3x2, glm::dmat3x2(0) numeric_limits::max() ), glm::dmat3x2( - 0.01, 0.01, 0.01, + 0.01, 0.01, 0.01, 0.01, 0.01, 0.01 ), DEFAULT_FROM_LUA_LAMBDA(glm::dmat3x2), diff --git a/src/properties/matrix/dmat3x4property.cpp b/src/properties/matrix/dmat3x4property.cpp index 1fc0b7b2d2..d0523030e5 100644 --- a/src/properties/matrix/dmat3x4property.cpp +++ b/src/properties/matrix/dmat3x4property.cpp @@ -142,8 +142,8 @@ REGISTER_NUMERICALPROPERTY_SOURCE(DMat3x4Property, glm::dmat3x4, glm::dmat3x4(0) numeric_limits::max() ), glm::dmat3x4( - 0.01, 0.01, 0.01, 0.01, - 0.01, 0.01, 0.01, 0.01, + 0.01, 0.01, 0.01, 0.01, + 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01 ), DEFAULT_FROM_LUA_LAMBDA(glm::dmat3x4), diff --git a/src/properties/matrix/dmat4property.cpp b/src/properties/matrix/dmat4property.cpp index 2a0c829c13..283549e309 100644 --- a/src/properties/matrix/dmat4property.cpp +++ b/src/properties/matrix/dmat4property.cpp @@ -150,9 +150,9 @@ REGISTER_NUMERICALPROPERTY_SOURCE(DMat4Property, glm::dmat4x4, glm::dmat4x4(0), numeric_limits::max() ), glm::dmat4x4( - 0.01, 0.01, 0.01, 0.01, - 0.01, 0.01, 0.01, 0.01, - 0.01, 0.01, 0.01, 0.01, + 0.01, 0.01, 0.01, 0.01, + 0.01, 0.01, 0.01, 0.01, + 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01 ), DEFAULT_FROM_LUA_LAMBDA(glm::dmat4x4), diff --git a/src/properties/matrix/dmat4x2property.cpp b/src/properties/matrix/dmat4x2property.cpp index 2301a25424..3a38fd9cf6 100644 --- a/src/properties/matrix/dmat4x2property.cpp +++ b/src/properties/matrix/dmat4x2property.cpp @@ -134,7 +134,7 @@ REGISTER_NUMERICALPROPERTY_SOURCE(DMat4x2Property, glm::dmat4x2, glm::dmat4x2(0) numeric_limits::max() ), glm::dmat4x2( - 0.01, 0.01, 0.01, 0.01, + 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01 ), DEFAULT_FROM_LUA_LAMBDA(glm::dmat4x2), diff --git a/src/properties/matrix/dmat4x3property.cpp b/src/properties/matrix/dmat4x3property.cpp index 5d88da9057..7edc09ecdb 100644 --- a/src/properties/matrix/dmat4x3property.cpp +++ b/src/properties/matrix/dmat4x3property.cpp @@ -142,8 +142,8 @@ REGISTER_NUMERICALPROPERTY_SOURCE(DMat4x3Property, glm::dmat4x3, glm::dmat4x3(0) numeric_limits::max() ), glm::dmat4x3( - 0.01, 0.01, 0.01, 0.01, - 0.01, 0.01, 0.01, 0.01, + 0.01, 0.01, 0.01, 0.01, + 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01 ), DEFAULT_FROM_LUA_LAMBDA(glm::dmat4x3), diff --git a/src/properties/matrix/mat3x4property.cpp b/src/properties/matrix/mat3x4property.cpp index d74e4eef22..3412134a3c 100644 --- a/src/properties/matrix/mat3x4property.cpp +++ b/src/properties/matrix/mat3x4property.cpp @@ -142,8 +142,8 @@ REGISTER_NUMERICALPROPERTY_SOURCE(Mat3x4Property, glm::mat3x4, glm::mat3x4(0), numeric_limits::max() ), glm::mat3x4( - 0.01f, 0.01f, 0.01f, 0.01f, - 0.01f, 0.01f, 0.01f, 0.01f, + 0.01f, 0.01f, 0.01f, 0.01f, + 0.01f, 0.01f, 0.01f, 0.01f, 0.01f, 0.01f, 0.01f, 0.01f ), DEFAULT_FROM_LUA_LAMBDA(glm::mat3x4), diff --git a/src/properties/matrix/mat4property.cpp b/src/properties/matrix/mat4property.cpp index 2fc8200cc8..e0afddd0ea 100644 --- a/src/properties/matrix/mat4property.cpp +++ b/src/properties/matrix/mat4property.cpp @@ -150,9 +150,9 @@ REGISTER_NUMERICALPROPERTY_SOURCE(Mat4Property, glm::mat4x4, glm::mat4x4(0), numeric_limits::max() ), glm::mat4x4( - 0.01f, 0.01f, 0.01f, 0.01f, - 0.01f, 0.01f, 0.01f, 0.01f, - 0.01f, 0.01f, 0.01f, 0.01f, + 0.01f, 0.01f, 0.01f, 0.01f, + 0.01f, 0.01f, 0.01f, 0.01f, + 0.01f, 0.01f, 0.01f, 0.01f, 0.01f, 0.01f, 0.01f, 0.01f ), DEFAULT_FROM_LUA_LAMBDA(glm::mat4x4), diff --git a/src/properties/matrix/mat4x2property.cpp b/src/properties/matrix/mat4x2property.cpp index b3d8aaf043..7bc809a0ef 100644 --- a/src/properties/matrix/mat4x2property.cpp +++ b/src/properties/matrix/mat4x2property.cpp @@ -134,7 +134,7 @@ REGISTER_NUMERICALPROPERTY_SOURCE(Mat4x2Property, glm::mat4x2, glm::mat4x2(0), numeric_limits::max() ), glm::mat4x2( - 0.01f, 0.01f, 0.01f, 0.01f, + 0.01f, 0.01f, 0.01f, 0.01f, 0.01f, 0.01f, 0.01f, 0.01f ), DEFAULT_FROM_LUA_LAMBDA(glm::mat4x2), diff --git a/src/properties/matrix/mat4x3property.cpp b/src/properties/matrix/mat4x3property.cpp index 5ca0e28437..22dcac9bd4 100644 --- a/src/properties/matrix/mat4x3property.cpp +++ b/src/properties/matrix/mat4x3property.cpp @@ -142,8 +142,8 @@ REGISTER_NUMERICALPROPERTY_SOURCE(Mat4x3Property, glm::mat4x3, glm::mat4x3(0), numeric_limits::max() ), glm::mat4x3( - 0.01f, 0.01f, 0.01f, 0.01f, - 0.01f, 0.01f, 0.01f, 0.01f, + 0.01f, 0.01f, 0.01f, 0.01f, + 0.01f, 0.01f, 0.01f, 0.01f, 0.01f, 0.01f, 0.01f, 0.01f ), DEFAULT_FROM_LUA_LAMBDA(glm::mat4x3), diff --git a/src/properties/property.cpp b/src/properties/property.cpp index 2f6e41a51b..1454467423 100644 --- a/src/properties/property.cpp +++ b/src/properties/property.cpp @@ -223,7 +223,7 @@ std::string Property::generateBaseDescription() const { std::string(TypeKey) + " = \"" + className() + "\", " + IdentifierKey + " = \"" + fullyQualifiedIdentifier() + "\", " + NameKey + " = \"" + guiName() + "\", " + - generateMetaDataDescription() + ", " + + generateMetaDataDescription() + ", " + generateAdditionalDescription(); } diff --git a/src/rendering/abufferrenderer.cpp b/src/rendering/abufferrenderer.cpp index 82f2393c4d..ee7bc8a4fb 100644 --- a/src/rendering/abufferrenderer.cpp +++ b/src/rendering/abufferrenderer.cpp @@ -74,10 +74,10 @@ void ABufferRenderer::initialize() { const GLfloat vertex_data[] = { // x y s t -size, -size, 0.0f, 1.0f, - size, size, 0.0f, 1.0f, - -size, size, 0.0f, 1.0f, - -size, -size, 0.0f, 1.0f, - size, -size, 0.0f, 1.0f, + size, size, 0.0f, 1.0f, + -size, size, 0.0f, 1.0f, + -size, -size, 0.0f, 1.0f, + size, -size, 0.0f, 1.0f, size, size, 0.0f, 1.0f, }; @@ -237,7 +237,7 @@ void ABufferRenderer::update() { void ABufferRenderer::render(float blackoutFactor, bool doPerformanceMeasurements) { PerfMeasure("ABufferRenderer::render"); - if (!_scene || !_camera) { + if (!_scene || !_camera) { return; } diff --git a/src/rendering/framebufferrenderer.cpp b/src/rendering/framebufferrenderer.cpp index 97c2616bc1..211f970b48 100644 --- a/src/rendering/framebufferrenderer.cpp +++ b/src/rendering/framebufferrenderer.cpp @@ -405,7 +405,7 @@ void FramebufferRenderer::render(float blackoutFactor, bool doPerformanceMeasure glBindFramebuffer(GL_FRAMEBUFFER, _exitFramebuffer); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - ghoul::opengl::ProgramObject* exitProgram = _exitPrograms[raycaster].get(); + ghoul::opengl::ProgramObject* exitProgram = _exitPrograms[raycaster].get(); if (exitProgram) { exitProgram->activate(); raycaster->renderExitPoints(raycasterTask.renderData, *exitProgram); diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 73a7a6365b..b7660d1f8e 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -22,7 +22,7 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#include +#include #ifdef OPENSPACE_MODULE_SPACECRAFTINSTRUMENTS_ENABLED #include @@ -80,7 +80,7 @@ namespace { const char* _loggerCat = "RenderEngine"; - const char* KeyRenderingMethod = "RenderingMethod"; + const char* KeyRenderingMethod = "RenderingMethod"; const std::chrono::seconds ScreenLogTimeToLive(15); const char* DefaultRenderingMethod = "ABuffer"; const char* RenderFsPath = "${SHADERS}/render.frag"; @@ -375,7 +375,7 @@ void RenderEngine::initialize() { void RenderEngine::initializeGL() { LTRACE("RenderEngine::initializeGL(begin)"); - // TODO: Fix the power scaled coordinates in such a way that these + // TODO: Fix the power scaled coordinates in such a way that these // values can be set to more realistic values // set the close clip plane and the far clip plane to extreme values while in diff --git a/src/rendering/screenspacerenderable.cpp b/src/rendering/screenspacerenderable.cpp index 1fcd91818e..f62ab66629 100644 --- a/src/rendering/screenspacerenderable.cpp +++ b/src/rendering/screenspacerenderable.cpp @@ -294,7 +294,7 @@ ScreenSpaceRenderable::ScreenSpaceRenderable(const ghoul::Dictionary& dictionary } _delete.onChange([this](){ - std::string script = + std::string script = "openspace.unregisterScreenSpaceRenderable('" + name() + "');"; OsEng.scriptEngine().queueScript( script, @@ -454,7 +454,7 @@ glm::mat4 ScreenSpaceRenderable::scaleMatrix() { _scale * scalingRatioY * textureRatio, 1.f ) - ); + ); } glm::mat4 ScreenSpaceRenderable::rotationMatrix() { diff --git a/src/scene/rotation.cpp b/src/scene/rotation.cpp index f25f5b2189..f1209576f6 100644 --- a/src/scene/rotation.cpp +++ b/src/scene/rotation.cpp @@ -66,7 +66,7 @@ std::unique_ptr Rotation::createFromDictionary(const ghoul::Dictionary return result; } -Rotation::Rotation() +Rotation::Rotation() : properties::PropertyOwner({ "Rotation" }) {} diff --git a/src/scene/scene_doc.inl b/src/scene/scene_doc.inl index 7e12ff7475..dfc66f0537 100644 --- a/src/scene/scene_doc.inl +++ b/src/scene/scene_doc.inl @@ -78,7 +78,7 @@ documentation::Documentation Scene::Documentation() { { "Modules", new TableVerifier({ - { + { "*", new StringVerifier, Optional::No, diff --git a/src/scene/scene_lua.inl b/src/scene/scene_lua.inl index 6912630ec2..4d1110ed85 100644 --- a/src/scene/scene_lua.inl +++ b/src/scene/scene_lua.inl @@ -180,7 +180,7 @@ int property_setValueSingle(lua_State* L) { for (properties::Property* prop : allProperties()) { std::string propFullId = prop->fullyQualifiedIdentifier(); //Look for a match in the uri with the group name (first term) removed - int propMatchLength = + int propMatchLength = static_cast(propFullId.length()) - static_cast(pathRemainderToMatch.length()); diff --git a/src/scripting/scriptengine_lua.inl b/src/scripting/scriptengine_lua.inl index 887bfac211..883f6774a2 100644 --- a/src/scripting/scriptengine_lua.inl +++ b/src/scripting/scriptengine_lua.inl @@ -201,7 +201,7 @@ int absolutePath(lua_State* L) { path = FileSys.convertPathSeparator(path, '/'); lua_pushstring(L, path.c_str()); return 1; -} +} /** * \ingroup LuaScripts @@ -262,7 +262,7 @@ int directoryExists(lua_State* L) { /** * \ingroup LuaScripts * walkDirectory(string, bool, bool): - * Walks a directory and returns the contents of the directory as absolute paths. The + * Walks a directory and returns the contents of the directory as absolute paths. The * first argument is the path of the directory that should be walked, the second argument * determines if the walk is recursive and will continue in contained directories. The * default value for this parameter is "false". The third argument determines whether the @@ -303,8 +303,8 @@ int walkDirectoryFolder(lua_State* L) { /** * \ingroup LuaScripts * directoryForPath(string): - * This function extracts the directory part of the passed path. For example, if the - * parameter is 'C:\\OpenSpace\\foobar\\foo.txt', this function returns + * This function extracts the directory part of the passed path. For example, if the + * parameter is 'C:\\OpenSpace\\foobar\\foo.txt', this function returns * 'C:\\OpenSpace\\foobar'." */ int directoryForPath(lua_State* L) { diff --git a/src/scripting/scriptscheduler.cpp b/src/scripting/scriptscheduler.cpp index f78b82d032..6b3caa26d6 100644 --- a/src/scripting/scriptscheduler.cpp +++ b/src/scripting/scriptscheduler.cpp @@ -244,13 +244,13 @@ ScriptScheduler::progressTo(double newTime) } double ScriptScheduler::currentTime() const { - return _currentTime; + return _currentTime; } std::vector ScriptScheduler::allScripts() const { std::vector result; for (size_t i = 0; i < _timings.size(); ++i) { - ScheduledScript script; + ScheduledScript script; script.time = _timings[i]; script.forwardScript = _forwardScripts[i]; script.backwardScript = _backwardScripts[i]; diff --git a/src/util/openspacemodule.cpp b/src/util/openspacemodule.cpp index 4d91e4a52d..2a5b036666 100644 --- a/src/util/openspacemodule.cpp +++ b/src/util/openspacemodule.cpp @@ -40,7 +40,7 @@ namespace { namespace openspace { -OpenSpaceModule::OpenSpaceModule(std::string name) +OpenSpaceModule::OpenSpaceModule(std::string name) : properties::PropertyOwner({ std::move(name) }) {} diff --git a/src/util/progressbar.cpp b/src/util/progressbar.cpp index 3d9b78d76b..14ec9f879c 100644 --- a/src/util/progressbar.cpp +++ b/src/util/progressbar.cpp @@ -32,7 +32,7 @@ ProgressBar::ProgressBar(int end, int width, std::ostream& stream) : _width(width) , _previous(-1) , _end(end) - , _stream(stream) + , _stream(stream) { print(0); } diff --git a/src/util/spicemanager.cpp b/src/util/spicemanager.cpp index 3978bc4090..ae27937026 100644 --- a/src/util/spicemanager.cpp +++ b/src/util/spicemanager.cpp @@ -175,7 +175,7 @@ SpiceManager::TerminatorType SpiceManager::terminatorTypeFromString( const strin return Mapping.at(type); } -SpiceManager::SpiceManager() +SpiceManager::SpiceManager() : _useExceptions(UseException::Yes) { // Set the SPICE library to not exit the program if an error occurs @@ -447,7 +447,7 @@ void SpiceManager::getValue(const std::string& body, const std::string& value, } void SpiceManager::getValue(const std::string& body, const std::string& value, - std::vector& v) const + std::vector& v) const { ghoul_assert(!v.empty(), "Array for values has to be preallocaed"); @@ -864,10 +864,10 @@ SpiceManager::TerminatorEllipseResult SpiceManager::terminatorEllipse( res.terminatorPoints.resize(numberOfTerminatorPoints); edterm_c(toString(terminatorType), - lightSource.c_str(), - target.c_str(), - ephemerisTime, - frame.c_str(), + lightSource.c_str(), + target.c_str(), + ephemerisTime, + frame.c_str(), aberrationCorrection, observer.c_str(), numberOfTerminatorPoints, diff --git a/src/util/time.cpp b/src/util/time.cpp index 422f1a038e..5bbbeb5ffd 100644 --- a/src/util/time.cpp +++ b/src/util/time.cpp @@ -97,7 +97,7 @@ double Time::deltaTime() const { } void Time::setPause(bool pause) { - _timePaused = pause; + _timePaused = pause; } bool Time::togglePause() { diff --git a/src/util/timerange.cpp b/src/util/timerange.cpp index c50db091f2..f5fb0c0eee 100644 --- a/src/util/timerange.cpp +++ b/src/util/timerange.cpp @@ -82,7 +82,7 @@ bool TimeRange::initializeFromDictionary(const ghoul::Dictionary& dict, TimeRang success &= dict.getValue(KeyStart, startTimeStr); success &= dict.getValue(KeyEnd, endTimeStr); if (success) { - // Parse to date. + // Parse to date. // @TODO converting string to time stamp should not rely on Spice timeRange.start = SpiceManager::ref().ephemerisTimeFromDate(startTimeStr); timeRange.end = SpiceManager::ref().ephemerisTimeFromDate(endTimeStr); @@ -118,7 +118,7 @@ double TimeRange::duration() const { } bool TimeRange::isDefined() const { - return start <= end; + return start <= end; } bool TimeRange::isEmpty() const { diff --git a/src/util/transformationmanager.cpp b/src/util/transformationmanager.cpp index 71cb0b04e3..45223c770a 100644 --- a/src/util/transformationmanager.cpp +++ b/src/util/transformationmanager.cpp @@ -75,7 +75,7 @@ glm::dmat3 TransformationManager::kameleonTransformationMatrix( ); #else return glm::dmat3(0.0); -#endif +#endif } glm::dmat3 TransformationManager::frameTransformationMatrix( diff --git a/support/coding/check_style_guide.py b/support/coding/check_style_guide.py index 048bf311c4..95a3d7e13c 100644 --- a/support/coding/check_style_guide.py +++ b/support/coding/check_style_guide.py @@ -308,6 +308,19 @@ def check_line_length(lines): +def check_empty_character_at_end(lines): + # Disable this check in non-strict mode + if not is_strict_mode: + return '' + + index = [i + 1 for i, s in enumerate(lines) if len(s) > 1 and s[-2] == ' '] + if len(index) > 0: + return index + else: + return '' + + + previousSymbols = {} def check_header_file(file, component): with open(file, 'r+', encoding="utf8") as f: @@ -392,10 +405,13 @@ def check_header_file(file, component): if line_length: print(file, '\t', 'Line length exceeded: ', line_length) + empty_character_at_end = check_empty_character_at_end(lines) + if empty_character_at_end: + print(file, '\t', 'Empty character at end: ', empty_character_at_end) def check_inline_file(file, component): - with open(file, 'r+') as f: + with open(file, 'r+', encoding="utf8") as f: lines = f.readlines() copyright = check_copyright(lines) @@ -434,10 +450,14 @@ def check_inline_file(file, component): if line_length: print(file, '\t', 'Line length exceeded: ', line_length) + empty_character_at_end = check_empty_character_at_end(lines) + if empty_character_at_end: + print(file, '\t', 'Empty character at end: ', empty_character_at_end) + def check_source_file(file, component): - with open(file, 'r+') as f: + with open(file, 'r+', encoding="utf8") as f: lines = f.readlines() header = check_glm_header(lines, file) @@ -469,6 +489,10 @@ def check_source_file(file, component): if line_length: print(file, '\t', 'Line length exceeded: ', line_length) + empty_character_at_end = check_empty_character_at_end(lines) + if empty_character_at_end: + print(file, '\t', 'Empty character at end: ', empty_character_at_end) + def check_files(positiveList, negativeList, component, check_function):