From 5fcc8792a2bb86c124fb766880cb915ab857e6b4 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Thu, 16 Jul 2015 14:32:09 +0200 Subject: [PATCH 001/122] Updated OpenSpace Version Rename capitalized include to non-capitalized --- CMakeLists.txt | 2 +- ext/ghoul | 2 +- src/network/parallelconnection.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fddfbac00d..528220db4c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,7 +40,7 @@ include(${OPENSPACE_EXT_DIR}/ghoul/ext/CopySharedLibraries.cmake) test_compiler_compatibility() cleanup_project() set_build_output_directories() -configure_openspace_version(0 2 0 "prerelease-6") +configure_openspace_version(0 3 0 "prerelease-8") option(OPENSPACE_WARNINGS_AS_ERRORS "Treat warnings as errors" OFF) option(OPENSPACE_DISABLE_EXTERNAL_WARNINGS "Disable warnings in external libraries" ON) diff --git a/ext/ghoul b/ext/ghoul index edae006863..5c150e1268 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit edae006863ea174600f45451f1b1c9eb7b317e0e +Subproject commit 5c150e1268c6c2a5ddbf768348925c9ab2f19eab diff --git a/src/network/parallelconnection.cpp b/src/network/parallelconnection.cpp index 26329206e7..8c86721a47 100644 --- a/src/network/parallelconnection.cpp +++ b/src/network/parallelconnection.cpp @@ -55,7 +55,7 @@ #endif //openspace includes -#include +#include #include #include #include From a59ed82ec56754a92df9facf10c9b1a726d24e04 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Thu, 16 Jul 2015 14:39:51 +0200 Subject: [PATCH 002/122] Linux compile fix --- src/network/parallelconnection.cpp | 2013 ++++++++++++++-------------- 1 file changed, 1007 insertions(+), 1006 deletions(-) diff --git a/src/network/parallelconnection.cpp b/src/network/parallelconnection.cpp index 8c86721a47..d894f3fda7 100644 --- a/src/network/parallelconnection.cpp +++ b/src/network/parallelconnection.cpp @@ -63,1091 +63,1092 @@ #include //lua functions -#include "ParallelConnection_lua.inl" +#include "parallelconnection_lua.inl" -namespace{ +namespace { const std::string _loggerCat = "ParallelConnection"; } namespace openspace { - namespace network{ + +namespace network { - ParallelConnection::ParallelConnection(): - _passCode(0), - _port("20501"), - _address("127.0.0.1"), - _name("Local Connection"), - _clientSocket(INVALID_SOCKET), - _connectionThread(nullptr), - _broadcastThread(nullptr), - _sendThread(nullptr), - _listenThread(nullptr), - _handlerThread(nullptr), - _isRunning(true), - _isHost(false), - _isConnected(false), - _tryConnect(false), - _performDisconnect(false), - _latestTimeKeyframeValid(false), - _initializationTimejumpRequired(false) +ParallelConnection::ParallelConnection() + : _passCode(0) + , _port("20501") + , _address("127.0.0.1") + , _name("Local Connection") + , _clientSocket(INVALID_SOCKET) + , _connectionThread(nullptr) + , _broadcastThread(nullptr) + , _sendThread(nullptr) + , _listenThread(nullptr) + , _handlerThread(nullptr) + , _isRunning(true) + , _isHost(false) + , _isConnected(false) + , _tryConnect(false) + , _performDisconnect(false) + , _latestTimeKeyframeValid(false) + , _initializationTimejumpRequired(false) +{ + //create handler thread + _handlerThread = new (std::nothrow) std::thread(&ParallelConnection::threadManagement, this); +} + +ParallelConnection::~ParallelConnection(){ + + //signal that a disconnect should occur + signalDisconnect(); + + //signal that execution has stopped + _isRunning.store(false); + + //join handler + _handlerThread->join(); + + //and delete handler + delete _handlerThread; +} + +void ParallelConnection::threadManagement(){ + //while we're still running + while(_isRunning.load()){ { - //create handler thread - _handlerThread = new (std::nothrow) std::thread(&ParallelConnection::threadManagement, this); - } - - ParallelConnection::~ParallelConnection(){ - - //signal that a disconnect should occur - signalDisconnect(); - - //signal that execution has stopped - _isRunning.store(false); - - //join handler - _handlerThread->join(); - - //and delete handler - delete _handlerThread; - } - - void ParallelConnection::threadManagement(){ - //while we're still running - while(_isRunning.load()){ - { - //lock disconnect mutex mutex - //not really needed since no data is modified but conditions need a mutex - std::unique_lock unqlock(_disconnectMutex); - //wait for a signal to disconnect - _disconnectCondition.wait(unqlock); + //lock disconnect mutex mutex + //not really needed since no data is modified but conditions need a mutex + std::unique_lock unqlock(_disconnectMutex); + //wait for a signal to disconnect + _disconnectCondition.wait(unqlock); - //perform actual disconnect - disconnect(); + //perform actual disconnect + disconnect(); - } - } } + } +} - void ParallelConnection::signalDisconnect(){ - //signal handler thread to disconnect - _disconnectCondition.notify_all(); - } +void ParallelConnection::signalDisconnect(){ + //signal handler thread to disconnect + _disconnectCondition.notify_all(); +} - void ParallelConnection::closeSocket(){ +void ParallelConnection::closeSocket(){ - /* - Windows shutdown options - * SD_RECIEVE - * SD_SEND - * SD_BOTH + /* + Windows shutdown options + * SD_RECIEVE + * SD_SEND + * SD_BOTH - Linux & Mac shutdown options - * SHUT_RD (Disables further receive operations) - * SHUT_WR (Disables further send operations) - * SHUT_RDWR (Disables further send and receive operations) - */ + Linux & Mac shutdown options + * SHUT_RD (Disables further receive operations) + * SHUT_WR (Disables further send operations) + * SHUT_RDWR (Disables further send and receive operations) + */ #ifdef __WIN32__ - shutdown(_clientSocket, SD_BOTH); - closesocket(_clientSocket); + shutdown(_clientSocket, SD_BOTH); + closesocket(_clientSocket); #else - shutdown(_clientSocket, SHUT_RDWR); - close(_clientSocket); + shutdown(_clientSocket, SHUT_RDWR); + close(_clientSocket); #endif - _clientSocket = INVALID_SOCKET; - } + _clientSocket = INVALID_SOCKET; +} - void ParallelConnection::disconnect(){ - //we're disconnecting +void ParallelConnection::disconnect(){ + //we're disconnecting - if (_clientSocket != INVALID_SOCKET){ + if (_clientSocket != INVALID_SOCKET){ - //must be run before trying to join communication threads, else the threads are stuck trying to receive data - closeSocket(); + //must be run before trying to join communication threads, else the threads are stuck trying to receive data + closeSocket(); - //tell connection thread to stop trying to connect - _tryConnect.store(false); + //tell connection thread to stop trying to connect + _tryConnect.store(false); - //tell send thread to stop sending and listen thread to stop listenin - _isConnected.store(false); + //tell send thread to stop sending and listen thread to stop listenin + _isConnected.store(false); - //tell broadcast thread to stop broadcasting (we're no longer host) - _isHost.store(false); + //tell broadcast thread to stop broadcasting (we're no longer host) + _isHost.store(false); - //signal send thread to stop waiting and finish current run - _sendCondition.notify_all(); + //signal send thread to stop waiting and finish current run + _sendCondition.notify_all(); - //join connection thread and delete it - if(_connectionThread != nullptr){ - _connectionThread->join(); - delete _connectionThread; - _connectionThread = nullptr; - } - - //join send thread and delete it - if (_sendThread != nullptr){ - _sendThread->join(); - delete _sendThread; - _sendThread = nullptr; - } - - //join listen thread and delete it - if( _listenThread != nullptr){ - _listenThread->join(); - delete _listenThread; - _listenThread = nullptr; - } - - //join broadcast thread and delete it - if(_broadcastThread != nullptr){ - _broadcastThread->join(); - delete _broadcastThread; - _broadcastThread = nullptr; - } - - // disconnect and cleanup completed - _performDisconnect.store(false); - } + //join connection thread and delete it + if(_connectionThread != nullptr){ + _connectionThread->join(); + delete _connectionThread; + _connectionThread = nullptr; } + + //join send thread and delete it + if (_sendThread != nullptr){ + _sendThread->join(); + delete _sendThread; + _sendThread = nullptr; + } + + //join listen thread and delete it + if( _listenThread != nullptr){ + _listenThread->join(); + delete _listenThread; + _listenThread = nullptr; + } + + //join broadcast thread and delete it + if(_broadcastThread != nullptr){ + _broadcastThread->join(); + delete _broadcastThread; + _broadcastThread = nullptr; + } + + // disconnect and cleanup completed + _performDisconnect.store(false); + } +} - void ParallelConnection::clientConnect(){ +void ParallelConnection::clientConnect(){ - //we're already connected (or already trying to connect), do nothing (dummy check) - if(_isConnected.load() || _tryConnect.load()){ - return; - } + //we're already connected (or already trying to connect), do nothing (dummy check) + if(_isConnected.load() || _tryConnect.load()){ + return; + } - if (!initNetworkAPI()){ - LERROR("Failed to initialize network API for Parallel Connection"); - return; - } + if (!initNetworkAPI()){ + LERROR("Failed to initialize network API for Parallel Connection"); + return; + } - struct addrinfo *addresult = NULL, *ptr = NULL, hints; - #ifdef __WIN32__ //WinSock - ZeroMemory(&hints, sizeof(hints)); - #else - memset(&hints, 0, sizeof(hints)); - #endif - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - hints.ai_flags = AI_PASSIVE; + struct addrinfo *addresult = NULL, *ptr = NULL, hints; + #ifdef __WIN32__ //WinSock + ZeroMemory(&hints, sizeof(hints)); + #else + memset(&hints, 0, sizeof(hints)); + #endif + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + hints.ai_flags = AI_PASSIVE; - // Resolve the local address and port to be used by the server - int result = getaddrinfo(_address.c_str(), _port.c_str(), &hints, &addresult); - if (result != 0) - { - LERROR("Failed to parse hints for Parallel Connection"); - return; - } + // Resolve the local address and port to be used by the server + int result = getaddrinfo(_address.c_str(), _port.c_str(), &hints, &addresult); + if (result != 0) + { + LERROR("Failed to parse hints for Parallel Connection"); + return; + } - //we're not connected - _isConnected.store(false); + //we're not connected + _isConnected.store(false); - //we want to try and establish a connection - _tryConnect.store(true); + //we want to try and establish a connection + _tryConnect.store(true); - //start connection thread - _connectionThread = new (std::nothrow) std::thread(&ParallelConnection::establishConnection, this, addresult); + //start connection thread + _connectionThread = new (std::nothrow) std::thread(&ParallelConnection::establishConnection, this, addresult); +} + +void ParallelConnection::establishConnection(addrinfo *info){ + + _clientSocket = socket(info->ai_family, info->ai_socktype, info->ai_protocol); + + if (_clientSocket == INVALID_SOCKET){ + freeaddrinfo(info); + LERROR("Failed to create client socket, disconnecting."); + + //signal a disconnect + signalDisconnect(); + } + + int flag = 1; + int result; + + //set no delay + result = setsockopt(_clientSocket, /* socket affected */ + IPPROTO_TCP, /* set option at TCP level */ + TCP_NODELAY, /* name of option */ + (char *)&flag, /* the cast is historical cruft */ + sizeof(int)); /* length of option value */ + + //set send timeout + int timeout = 0; + result = setsockopt( + _clientSocket, + SOL_SOCKET, + SO_SNDTIMEO, + (char *)&timeout, + sizeof(timeout)); + + //set receive timeout + result = setsockopt( + _clientSocket, + SOL_SOCKET, + SO_RCVTIMEO, + (char *)&timeout, + sizeof(timeout)); + + result = setsockopt(_clientSocket, SOL_SOCKET, SO_REUSEADDR, (char*)&flag, sizeof(int)); + if (result == SOCKET_ERROR) + LERROR("Failed to set socket option 'reuse address'. Error code: " << _ERRNO); + + result = setsockopt(_clientSocket, SOL_SOCKET, SO_KEEPALIVE, (char*)&flag, sizeof(int)); + if (result == SOCKET_ERROR) + LERROR("Failed to set socket option 'keep alive'. Error code: " << _ERRNO); + + + //while the connection thread is still running + while (_tryConnect.load()){ + + LINFO("Attempting to connect to server "<< _address << " on port " << _port); + + //try to connect + result = connect(_clientSocket, info->ai_addr, (int)info->ai_addrlen); + + //if the connection was successfull + if (result != SOCKET_ERROR) + { + + LINFO("Connection established with server at ip: "<< _address); + + //we're connected + _isConnected.store(true); + + //start sending messages + _sendThread = new (std::nothrow) std::thread(&ParallelConnection::sendFunc, this); + + //start listening for communication + _listenThread = new (std::nothrow) std::thread(&ParallelConnection::listenCommunication, this); + + //we no longer need to try to establish connection + _tryConnect.store(false); + + //send authentication + sendAuthentication(); } - - void ParallelConnection::establishConnection(addrinfo *info){ - - _clientSocket = socket(info->ai_family, info->ai_socktype, info->ai_protocol); - - if (_clientSocket == INVALID_SOCKET){ - freeaddrinfo(info); - LERROR("Failed to create client socket, disconnecting."); - - //signal a disconnect - signalDisconnect(); - } - - int flag = 1; - int result; - - //set no delay - result = setsockopt(_clientSocket, /* socket affected */ - IPPROTO_TCP, /* set option at TCP level */ - TCP_NODELAY, /* name of option */ - (char *)&flag, /* the cast is historical cruft */ - sizeof(int)); /* length of option value */ - - //set send timeout - int timeout = 0; - result = setsockopt( - _clientSocket, - SOL_SOCKET, - SO_SNDTIMEO, - (char *)&timeout, - sizeof(timeout)); - - //set receive timeout - result = setsockopt( - _clientSocket, - SOL_SOCKET, - SO_RCVTIMEO, - (char *)&timeout, - sizeof(timeout)); - - result = setsockopt(_clientSocket, SOL_SOCKET, SO_REUSEADDR, (char*)&flag, sizeof(int)); - if (result == SOCKET_ERROR) - LERROR("Failed to set socket option 'reuse address'. Error code: " << _ERRNO); - - result = setsockopt(_clientSocket, SOL_SOCKET, SO_KEEPALIVE, (char*)&flag, sizeof(int)); - if (result == SOCKET_ERROR) - LERROR("Failed to set socket option 'keep alive'. Error code: " << _ERRNO); - - - //while the connection thread is still running - while (_tryConnect.load()){ - - LINFO("Attempting to connect to server "<< _address << " on port " << _port); - - //try to connect - result = connect(_clientSocket, info->ai_addr, (int)info->ai_addrlen); - - //if the connection was successfull - if (result != SOCKET_ERROR) - { - - LINFO("Connection established with server at ip: "<< _address); - - //we're connected - _isConnected.store(true); - - //start sending messages - _sendThread = new (std::nothrow) std::thread(&ParallelConnection::sendFunc, this); - - //start listening for communication - _listenThread = new (std::nothrow) std::thread(&ParallelConnection::listenCommunication, this); - - //we no longer need to try to establish connection - _tryConnect.store(false); - - //send authentication - sendAuthentication(); - } #ifdef __WIN32__ - //on windows: try to connect once per second - std::this_thread::sleep_for(std::chrono::seconds(1)); + //on windows: try to connect once per second + std::this_thread::sleep_for(std::chrono::seconds(1)); #else - if(!_isConnected.load()){ - //on unix disconnect and display error message if we're not connected - LERROR("Failed to establish a connection with server "<< _address << " on port " << _port<<", terminating connection."); + if(!_isConnected.load()){ + //on unix disconnect and display error message if we're not connected + LERROR("Failed to establish a connection with server "<< _address << " on port " << _port<<", terminating connection."); - //signal disconnect - signalDisconnect(); + //signal disconnect + signalDisconnect(); - //stop loop - break; - } -#endif - } - - //cleanup - freeaddrinfo(info); - } - - void ParallelConnection::sendAuthentication(){ - //length of this nodes name - uint16_t namelen = static_cast(_name.length()); - - //total size of the buffer, header + size of passcodde + namelength + size of namelength - int size = headerSize() + sizeof(uint32_t) + sizeof(namelen) + static_cast(namelen); - - //create and reserve buffer - std::vector buffer; - buffer.reserve(size); - - //write header to buffer - writeHeader(buffer, MessageTypes::Authentication); - - //write passcode to buffer - buffer.insert(buffer.end(), reinterpret_cast(&_passCode), reinterpret_cast(&_passCode) + sizeof(uint32_t)); - - //write the length of the nodes name to buffer - buffer.insert(buffer.end(), reinterpret_cast(&namelen), reinterpret_cast(&namelen) + sizeof(uint16_t)); - - //write this nodes name to buffer - buffer.insert(buffer.end(), _name.begin(), _name.end()); - - //send buffer - queueMessage(buffer); - } - - void ParallelConnection::delegateDecoding(uint32_t type){ - switch (type){ - case MessageTypes::Authentication: - //not used - break; - case MessageTypes::Initialization: - initializationMessageReceived(); - break; - case MessageTypes::Data: - dataMessageReceived(); - break; - case MessageTypes::Script: - //not used - break; - case MessageTypes::HostInfo: - hostInfoMessageReceived(); - break; - case MessageTypes::InitializationRequest: - initializationRequestMessageReceived(); - break; - default: - //unknown message type - break; - } - } - - void ParallelConnection::initializationMessageReceived(){ - - int result; - - uint32_t id, datasize; - uint16_t numscripts; - - std::vector buffer; - buffer.resize(sizeof(id)); - - //read id - result = receiveData(_clientSocket, buffer, sizeof(id), 0); - if (result < 0){ - //error - } - id = *(reinterpret_cast(buffer.data())); - - //read datalength - result = receiveData(_clientSocket, buffer, sizeof(datasize), 0); - if (result < 0){ - //error - } - datasize = *(reinterpret_cast(buffer.data())); - - buffer.clear(); - buffer.resize(sizeof(uint16_t)); - //read number of scripts - result = receiveData(_clientSocket, buffer, sizeof(numscripts), 0); - if(result < 0){ - //error - } - numscripts = *(reinterpret_cast(buffer.data())); - - //length of current script - uint16_t scriptlen; - - buffer.clear(); - buffer.resize(sizeof(scriptlen)); - - //holder for current script - std::string script; - - for(int n = 0; n < numscripts; ++n){ - //read length of script - result = receiveData(_clientSocket, buffer, sizeof(numscripts), 0); - if(result < 0){ - //error - } - scriptlen = *(reinterpret_cast(buffer.data())); - - //resize buffer - buffer.clear(); - buffer.resize(scriptlen); - - //read script - result = receiveData(_clientSocket, buffer, scriptlen, 0); - - //assign current script - script.clear(); - script.assign(buffer.begin(), buffer.end()); - - //queue received script - OsEng.scriptEngine()->queueScript(script); - } - - //we've gone through all scripts, initialization is done - buffer.clear(); - writeHeader(buffer, MessageTypes::InitializationCompleted); - - //let the server know - queueMessage(buffer); - - //we also need to force a time jump just to ensure that the server and client are synced - _initializationTimejumpRequired.store(true); - - } - - void ParallelConnection::dataMessageReceived(){ - int result; - uint16_t msglen; - uint16_t type; - - //create a buffer to hold the size of streamdata message - std::vector buffer; - buffer.resize(sizeof(type)); - - //read type of data message - result = receiveData(_clientSocket, buffer, sizeof(type), 0); - - if (result <= 0){ - //error - LERROR("Failed to read type of data message received."); - return; - } - - //the type of data message received - type =(*(reinterpret_cast(buffer.data()))); - - //read size of streamdata message - result = receiveData(_clientSocket, buffer, sizeof(msglen), 0); - - if (result <= 0){ - //error - LERROR("Failed to read size of data message received."); - return; - } - - //the size in bytes of the streamdata message - msglen = (*(reinterpret_cast(buffer.data()))); - - //resize the buffer to be able to read the streamdata - buffer.clear(); - buffer.resize(msglen); - - //read the data into buffer - result = receiveData(_clientSocket, buffer, msglen, 0); - - if (result <= 0){ - //error - LERROR("Failed to read data message."); - return; - } - - //which type of data message was received? - switch(type){ - case network::datamessagestructures::PositionData:{ - //position data message - //create and read a position keyframe from the data buffer - network::datamessagestructures::PositionKeyframe kf; - kf.deserialize(buffer); - - //add the keyframe to the interaction handler - OsEng.interactionHandler()->addKeyframe(kf); - break; - } - case network::datamessagestructures::TimeData:{ - //time data message - //create and read a time keyframe from the data buffer - network::datamessagestructures::TimeKeyframe tf; - tf.deserialize(buffer); - - //lock mutex and assign latest time keyframe parameters - _timeKeyframeMutex.lock(); - - _latestTimeKeyframe._dt = tf._dt; - _latestTimeKeyframe._time = tf._time; - _latestTimeKeyframe._paused = tf._paused; - - //ensure that we never miss a timejump - //if last keyframe required a jump and that keyframe has not been used yet - if(_latestTimeKeyframe._requiresTimeJump && _latestTimeKeyframeValid){ - //do nothing to the boolean. Old value must be executed - }else{ - //either the latest keyframe didnt require a jump, or we have already spent that keyframe. - //in either case we can go ahead and write the bool value of newest frame - _latestTimeKeyframe._requiresTimeJump = tf._requiresTimeJump; - } - - //if we're just initialized we need to perform a time jump as soon as a valid keyframe has been received - if(_initializationTimejumpRequired.load() && _latestTimeKeyframeValid){ - _latestTimeKeyframe._requiresTimeJump = true; - _initializationTimejumpRequired.store(false); - } - - //unlock mutex - _timeKeyframeMutex.unlock(); - - //the keyframe is now valid for use - _latestTimeKeyframeValid.store(true); - - break; - } - case network::datamessagestructures::ScriptData:{ - //script data message - //create and read a script message from data buffer - network::datamessagestructures::ScriptMessage sm; - sm.deserialize(buffer); - - //Que script to be executed by script engine - OsEng.scriptEngine()->queueScript(sm._script); - break; - } - default:{ - LERROR("Unidentified data message with identifier " << type << " received in parallel connection."); - break; - } - } - } - - void ParallelConnection::queueMessage(std::vector message){ - { - std::unique_lock unqlock(_sendBufferMutex); - _sendBuffer.push_back(message); - _sendCondition.notify_all(); - } + //stop loop + break; } - - void ParallelConnection::sendFunc(){ - int result; - //while we're connected - while(_isConnected.load()){ - { - //wait for signal then lock mutex and send first queued message - std::unique_lock unqlock(_sendBufferMutex); - _sendCondition.wait_for(unqlock, std::chrono::milliseconds(500)); +#endif + } + + //cleanup + freeaddrinfo(info); +} + +void ParallelConnection::sendAuthentication(){ + //length of this nodes name + uint16_t namelen = static_cast(_name.length()); + + //total size of the buffer, header + size of passcodde + namelength + size of namelength + int size = headerSize() + sizeof(uint32_t) + sizeof(namelen) + static_cast(namelen); + + //create and reserve buffer + std::vector buffer; + buffer.reserve(size); + + //write header to buffer + writeHeader(buffer, MessageTypes::Authentication); + + //write passcode to buffer + buffer.insert(buffer.end(), reinterpret_cast(&_passCode), reinterpret_cast(&_passCode) + sizeof(uint32_t)); + + //write the length of the nodes name to buffer + buffer.insert(buffer.end(), reinterpret_cast(&namelen), reinterpret_cast(&namelen) + sizeof(uint16_t)); + + //write this nodes name to buffer + buffer.insert(buffer.end(), _name.begin(), _name.end()); + + //send buffer + queueMessage(buffer); +} + +void ParallelConnection::delegateDecoding(uint32_t type){ + switch (type){ + case MessageTypes::Authentication: + //not used + break; + case MessageTypes::Initialization: + initializationMessageReceived(); + break; + case MessageTypes::Data: + dataMessageReceived(); + break; + case MessageTypes::Script: + //not used + break; + case MessageTypes::HostInfo: + hostInfoMessageReceived(); + break; + case MessageTypes::InitializationRequest: + initializationRequestMessageReceived(); + break; + default: + //unknown message type + break; + } +} + +void ParallelConnection::initializationMessageReceived(){ + + int result; + + uint32_t id, datasize; + uint16_t numscripts; + + std::vector buffer; + buffer.resize(sizeof(id)); + + //read id + result = receiveData(_clientSocket, buffer, sizeof(id), 0); + if (result < 0){ + //error + } + id = *(reinterpret_cast(buffer.data())); + + //read datalength + result = receiveData(_clientSocket, buffer, sizeof(datasize), 0); + if (result < 0){ + //error + } + datasize = *(reinterpret_cast(buffer.data())); + + buffer.clear(); + buffer.resize(sizeof(uint16_t)); + //read number of scripts + result = receiveData(_clientSocket, buffer, sizeof(numscripts), 0); + if(result < 0){ + //error + } + numscripts = *(reinterpret_cast(buffer.data())); + + //length of current script + uint16_t scriptlen; + + buffer.clear(); + buffer.resize(sizeof(scriptlen)); + + //holder for current script + std::string script; + + for(int n = 0; n < numscripts; ++n){ + //read length of script + result = receiveData(_clientSocket, buffer, sizeof(numscripts), 0); + if(result < 0){ + //error + } + scriptlen = *(reinterpret_cast(buffer.data())); + + //resize buffer + buffer.clear(); + buffer.resize(scriptlen); + + //read script + result = receiveData(_clientSocket, buffer, scriptlen, 0); + + //assign current script + script.clear(); + script.assign(buffer.begin(), buffer.end()); + + //queue received script + OsEng.scriptEngine()->queueScript(script); + } + + //we've gone through all scripts, initialization is done + buffer.clear(); + writeHeader(buffer, MessageTypes::InitializationCompleted); + + //let the server know + queueMessage(buffer); + + //we also need to force a time jump just to ensure that the server and client are synced + _initializationTimejumpRequired.store(true); + +} + +void ParallelConnection::dataMessageReceived(){ + int result; + uint16_t msglen; + uint16_t type; + + //create a buffer to hold the size of streamdata message + std::vector buffer; + buffer.resize(sizeof(type)); + + //read type of data message + result = receiveData(_clientSocket, buffer, sizeof(type), 0); + + if (result <= 0){ + //error + LERROR("Failed to read type of data message received."); + return; + } + + //the type of data message received + type =(*(reinterpret_cast(buffer.data()))); + + //read size of streamdata message + result = receiveData(_clientSocket, buffer, sizeof(msglen), 0); + + if (result <= 0){ + //error + LERROR("Failed to read size of data message received."); + return; + } + + //the size in bytes of the streamdata message + msglen = (*(reinterpret_cast(buffer.data()))); + + //resize the buffer to be able to read the streamdata + buffer.clear(); + buffer.resize(msglen); + + //read the data into buffer + result = receiveData(_clientSocket, buffer, msglen, 0); + + if (result <= 0){ + //error + LERROR("Failed to read data message."); + return; + } + + //which type of data message was received? + switch(type){ + case network::datamessagestructures::PositionData:{ + //position data message + //create and read a position keyframe from the data buffer + network::datamessagestructures::PositionKeyframe kf; + kf.deserialize(buffer); - if(!_sendBuffer.empty()){ - while(!_sendBuffer.empty()){ - result = send(_clientSocket, _sendBuffer.front().data(), _sendBuffer.front().size(), 0); - _sendBuffer.erase(_sendBuffer.begin()); + //add the keyframe to the interaction handler + OsEng.interactionHandler()->addKeyframe(kf); + break; + } + case network::datamessagestructures::TimeData:{ + //time data message + //create and read a time keyframe from the data buffer + network::datamessagestructures::TimeKeyframe tf; + tf.deserialize(buffer); + + //lock mutex and assign latest time keyframe parameters + _timeKeyframeMutex.lock(); + + _latestTimeKeyframe._dt = tf._dt; + _latestTimeKeyframe._time = tf._time; + _latestTimeKeyframe._paused = tf._paused; + + //ensure that we never miss a timejump + //if last keyframe required a jump and that keyframe has not been used yet + if(_latestTimeKeyframe._requiresTimeJump && _latestTimeKeyframeValid){ + //do nothing to the boolean. Old value must be executed + }else{ + //either the latest keyframe didnt require a jump, or we have already spent that keyframe. + //in either case we can go ahead and write the bool value of newest frame + _latestTimeKeyframe._requiresTimeJump = tf._requiresTimeJump; + } + + //if we're just initialized we need to perform a time jump as soon as a valid keyframe has been received + if(_initializationTimejumpRequired.load() && _latestTimeKeyframeValid){ + _latestTimeKeyframe._requiresTimeJump = true; + _initializationTimejumpRequired.store(false); + } + + //unlock mutex + _timeKeyframeMutex.unlock(); + + //the keyframe is now valid for use + _latestTimeKeyframeValid.store(true); + + break; + } + case network::datamessagestructures::ScriptData:{ + //script data message + //create and read a script message from data buffer + network::datamessagestructures::ScriptMessage sm; + sm.deserialize(buffer); + + //Que script to be executed by script engine + OsEng.scriptEngine()->queueScript(sm._script); + break; + } + default:{ + LERROR("Unidentified data message with identifier " << type << " received in parallel connection."); + break; + } + } +} + +void ParallelConnection::queueMessage(std::vector message){ + { + std::unique_lock unqlock(_sendBufferMutex); + _sendBuffer.push_back(message); + _sendCondition.notify_all(); + } +} + +void ParallelConnection::sendFunc(){ + int result; + //while we're connected + while(_isConnected.load()){ + { + //wait for signal then lock mutex and send first queued message + std::unique_lock unqlock(_sendBufferMutex); + _sendCondition.wait_for(unqlock, std::chrono::milliseconds(500)); + + if(!_sendBuffer.empty()){ + while(!_sendBuffer.empty()){ + result = send(_clientSocket, _sendBuffer.front().data(), _sendBuffer.front().size(), 0); + _sendBuffer.erase(_sendBuffer.begin()); - //make sure everything went well - if (result == SOCKET_ERROR){ - //failed to send message - LERROR("Failed to send message.\nError: " << _ERRNO << " detected in connection, disconnecting."); + //make sure everything went well + if (result == SOCKET_ERROR){ + //failed to send message + LERROR("Failed to send message.\nError: " << _ERRNO << " detected in connection, disconnecting."); - //signal that a disconnect should be performed - signalDisconnect(); - } - } + //signal that a disconnect should be performed + signalDisconnect(); } } - } } - - void ParallelConnection::hostInfoMessageReceived(){ - //create buffer - std::vector hostflag; - //resize to hold a flag saying if we're host or not - hostflag.resize(1); - - //read data into buffer - int result = receiveData(_clientSocket, hostflag, 1, 0); - - //enough data was read - if (result > 0){ - //we've been assigned as host - if (hostflag.at(0) == 1){ - - //we're already host, do nothing (dummy check) - if (_isHost.load()){ - return; - } - else{ - - //we're the host - _isHost.store(true); + } +} + +void ParallelConnection::hostInfoMessageReceived(){ + //create buffer + std::vector hostflag; + //resize to hold a flag saying if we're host or not + hostflag.resize(1); + + //read data into buffer + int result = receiveData(_clientSocket, hostflag, 1, 0); - //start broadcasting - _broadcastThread = new (std::nothrow) std::thread(&ParallelConnection::broadcast, this); - } - } - else{ //we've been assigned as client + //enough data was read + if (result > 0){ + + //we've been assigned as host + if (hostflag.at(0) == 1){ - //we were broadcasting but should stop now - if (_isHost.load()){ - - //stop broadcast loop - _isHost.store(false); - - //and delete broadcasting thread - if (_broadcastThread != nullptr){ - _broadcastThread->join(); - delete _broadcastThread; - _broadcastThread = nullptr; - } - } - else{ - //we were not broadcasting so nothing to do - } - - //clear buffered any keyframes - OsEng.interactionHandler()->clearKeyframes(); - - //request init package from the host - int size = headerSize(); - std::vector buffer; - buffer.reserve(size); - - //write header - writeHeader(buffer, MessageTypes::InitializationRequest); - - //send message - queueMessage(buffer); - } + //we're already host, do nothing (dummy check) + if (_isHost.load()){ + return; } else{ - LERROR("Error " << _ERRNO << " detected in connection, disconnecting."); - signalDisconnect(); + + //we're the host + _isHost.store(true); + + //start broadcasting + _broadcastThread = new (std::nothrow) std::thread(&ParallelConnection::broadcast, this); } } + else{ //we've been assigned as client + + //we were broadcasting but should stop now + if (_isHost.load()){ - void ParallelConnection::initializationRequestMessageReceived(){ - - //get current state as scripts - std::vector scripts; - std::map::iterator state_it; - { - //mutex protect - std::lock_guard lock(_currentStateMutex); - - for(state_it = _currentState.begin(); - state_it != _currentState.end(); - ++state_it){ - scripts.push_back(scriptFromPropertyAndValue(state_it->first, state_it->second)); - } - } - - //get requester ID + //stop broadcast loop + _isHost.store(false); + + //and delete broadcasting thread + if (_broadcastThread != nullptr){ + _broadcastThread->join(); + delete _broadcastThread; + _broadcastThread = nullptr; + } + } + else{ + //we were not broadcasting so nothing to do + } + + //clear buffered any keyframes + OsEng.interactionHandler()->clearKeyframes(); + + //request init package from the host + int size = headerSize(); std::vector buffer; - buffer.resize(sizeof(uint32_t)); - receiveData(_clientSocket, buffer, sizeof(uint32_t), 0); - uint32_t requesterID = *reinterpret_cast(buffer.data()); - - //total number of scripts sent - uint16_t numscripts = 0; - - //temporary buffers - std::vector scriptbuffer; - std::vector tmpbuffer; - - //serialize and encode all scripts into scriptbuffer - std::vector::iterator script_it; - network::datamessagestructures::ScriptMessage sm; - for(script_it = scripts.begin(); - script_it != scripts.end(); - ++script_it){ - sm._script = *script_it; - sm._scriptlen = script_it->length(); - - //serialize current script - tmpbuffer.clear(); - sm.serialize(tmpbuffer); - - //and insert into full buffer - scriptbuffer.insert(scriptbuffer.end(), tmpbuffer.begin(), tmpbuffer.end()); - - //increment number of scripts - numscripts++; - } - + buffer.reserve(size); + //write header - buffer.clear(); - writeHeader(buffer, MessageTypes::Initialization); - - //write client ID to receive init message - buffer.insert(buffer.end(), reinterpret_cast(&requesterID), reinterpret_cast(&requesterID) + sizeof(uint32_t)); - - //write total size of data chunk - uint32_t totlen = static_cast(scriptbuffer.size()); - buffer.insert(buffer.end(), reinterpret_cast(&totlen), reinterpret_cast(&totlen) + sizeof(uint32_t)); - - //write number of scripts - buffer.insert(buffer.end(), reinterpret_cast(&numscripts), reinterpret_cast(&numscripts) + sizeof(uint16_t)); - - //write all scripts - buffer.insert(buffer.end(), scriptbuffer.begin(), scriptbuffer.end()); - - //queue message - queueMessage(buffer); - } + writeHeader(buffer, MessageTypes::InitializationRequest); - void ParallelConnection::listenCommunication(){ - - //create basic buffer for receiving first part of messages - std::vector buffer; - //size of the header - buffer.resize(headerSize()); - - int result; - - //while we're still connected - while (_isConnected.load()){ - //receive the first parts of a message - result = receiveData(_clientSocket, buffer, headerSize(), 0); - - //if enough data was received - if (result > 0){ - - //make sure that header matches this version of OpenSpace - if (buffer[0] == 'O' && //Open - buffer[1] == 'S' && //Space - buffer[2] == OPENSPACE_VERSION_MAJOR && // major version - buffer[3] == OPENSPACE_VERSION_MINOR // minor version - ) - { - //parse type - uint32_t type = (*(reinterpret_cast(&buffer[4]))); - - //and delegate decoding depending on type - delegateDecoding(type); - } - else{ - LERROR("Error: Client OpenSpace version " << OPENSPACE_VERSION_MAJOR << ", " << OPENSPACE_VERSION_MINOR << " does not match server version " << buffer[2] <<", " << buffer[3] << std::endl << "Message not decoded."); - } - } - else{ - if (result == 0){ - //connection rejected - LERROR("Parallel connection rejected, disconnecting..."); - } - else{ - LERROR("Error " << _ERRNO << " detected in connection, disconnecting!"); - } - - //signal that a disconnect should be performed - signalDisconnect(); - break; - } - } - - } - - int ParallelConnection::receiveData(_SOCKET & socket, std::vector &buffer, int length, int flags){ - int result = 0; - int received = 0; - while (result < length){ - received = recv(socket, buffer.data() + result, length - result, flags); - - if (received > 0){ - result += received; - received = 0; - } - else{ - //error receiving - result = received; - break; - } - } - - return result; - } - - void ParallelConnection::setPort(const std::string &port){ - _port = port; - } - - void ParallelConnection::setAddress(const std::string &address){ - _address = address; - } - - void ParallelConnection::setName(const std::string& name){ - _name = name; - } - - bool ParallelConnection::isHost(){ - return _isHost.load(); - } - - void ParallelConnection::requestHostship(const std::string &password){ - std::vector buffer; - buffer.reserve(headerSize()); - - uint32_t passcode = hash(password); - - //write header - writeHeader(buffer, MessageTypes::HostshipRequest); - - //write passcode - buffer.insert(buffer.end(), reinterpret_cast(&passcode), reinterpret_cast(&passcode) + sizeof(uint32_t)); - //send message queueMessage(buffer); - } - - void ParallelConnection::setPassword(const std::string& pwd){ - _passCode = hash(pwd); } + } + else{ + LERROR("Error " << _ERRNO << " detected in connection, disconnecting."); + signalDisconnect(); + } +} - bool ParallelConnection::initNetworkAPI(){ - #if defined(__WIN32__) - WSADATA wsaData; - WORD version; - int error; - - version = MAKEWORD(2, 2); - - error = WSAStartup(version, &wsaData); - - if (error != 0 || - LOBYTE(wsaData.wVersion) != 2 || - HIBYTE(wsaData.wVersion) != 2) - { - /* incorrect WinSock version */ - LERROR("Failed to init winsock API."); - //WSACleanup(); - return false; - } - #else - //No init needed on unix - #endif - - return true; - } - - void ParallelConnection::preSynchronization(){ +void ParallelConnection::initializationRequestMessageReceived(){ - //if we're the host - if(_isHost){ - //get current time parameters and create a keyframe - network::datamessagestructures::TimeKeyframe tf; - tf._dt = Time::ref().deltaTime(); - tf._paused = Time::ref().paused(); - tf._requiresTimeJump = Time::ref().timeJumped(); - tf._time = Time::ref().currentTime(); + //get current state as scripts + std::vector scripts; + std::map::iterator state_it; + { + //mutex protect + std::lock_guard lock(_currentStateMutex); - //create a buffer and serialize message - std::vector tbuffer; - tf.serialize(tbuffer); - - //get the size of the keyframebuffer - uint16_t msglen = static_cast(tbuffer.size()); - - //the type of data message - uint16_t type = static_cast(network::datamessagestructures::TimeData); - - //create the full buffer - std::vector buffer; - buffer.reserve(headerSize() + sizeof(type) + sizeof(msglen) + msglen); - - //write header - writeHeader(buffer, MessageTypes::Data); - - //type of message - buffer.insert(buffer.end(), reinterpret_cast(&type), reinterpret_cast(&type) + sizeof(type)); - - //size of message - buffer.insert(buffer.end(), reinterpret_cast(&msglen), reinterpret_cast(&msglen) + sizeof(msglen)); - - //actual message - buffer.insert(buffer.end(), tbuffer.begin(), tbuffer.end()); - - //send message - queueMessage(buffer); - } - else{ - //if we're not the host and we have a valid keyframe (one that hasnt been used before) - if(_latestTimeKeyframeValid.load()){ - - //lock mutex and retrieve parameters from latest keyframe - _timeKeyframeMutex.lock(); - - double dt = _latestTimeKeyframe._dt; - double time = _latestTimeKeyframe._time; - bool jump = _latestTimeKeyframe._requiresTimeJump; - bool paused = _latestTimeKeyframe._paused; - - _timeKeyframeMutex.unlock(); - - //this keyframe is now spent - _latestTimeKeyframeValid.store(false); - - //assign latest params - Time::ref().setDeltaTime(dt); - Time::ref().setTime(time, jump); - Time::ref().setPause(paused); - - } - } + for(state_it = _currentState.begin(); + state_it != _currentState.end(); + ++state_it){ + scripts.push_back(scriptFromPropertyAndValue(state_it->first, state_it->second)); } - - void ParallelConnection::scriptMessage(const std::string propIdentifier, const std::string propValue){ + } - //save script as current state - { - //mutex protect - std::lock_guard lock(_currentStateMutex); - _currentState[propIdentifier] = propValue; - } + //get requester ID + std::vector buffer; + buffer.resize(sizeof(uint32_t)); + receiveData(_clientSocket, buffer, sizeof(uint32_t), 0); + uint32_t requesterID = *reinterpret_cast(buffer.data()); - //if we're connected and we're the host, also send the script - if(_isConnected.load() && _isHost.load()){ - //construct script - std::string script = scriptFromPropertyAndValue(propIdentifier, propValue); - - //create a script message - network::datamessagestructures::ScriptMessage sm; - sm._script = script; - sm._scriptlen = static_cast(script.length()); - - //create a buffer for the script - std::vector sbuffer; - - //fill the script buffer - sm.serialize(sbuffer); - - //get the size of the keyframebuffer - uint16_t msglen = static_cast(sbuffer.size()); - - //the type of message - uint16_t type = static_cast(network::datamessagestructures::ScriptData); - - //create the full buffer - std::vector buffer; - buffer.reserve(headerSize() + sizeof(type) + sizeof(msglen) + msglen); - - //write header - writeHeader(buffer, MessageTypes::Data); - - //type of message - buffer.insert(buffer.end(), reinterpret_cast(&type), reinterpret_cast(&type) + sizeof(type)); - - //size of message - buffer.insert(buffer.end(), reinterpret_cast(&msglen), reinterpret_cast(&msglen) + sizeof(msglen)); - - //actual message - buffer.insert(buffer.end(), sbuffer.begin(), sbuffer.end()); - - //send message - queueMessage(buffer); - } + //total number of scripts sent + uint16_t numscripts = 0; + + //temporary buffers + std::vector scriptbuffer; + std::vector tmpbuffer; + + //serialize and encode all scripts into scriptbuffer + std::vector::iterator script_it; + network::datamessagestructures::ScriptMessage sm; + for(script_it = scripts.begin(); + script_it != scripts.end(); + ++script_it){ + sm._script = *script_it; + sm._scriptlen = script_it->length(); - } - - std::string ParallelConnection::scriptFromPropertyAndValue(const std::string property, const std::string value){ - //consruct script - std::string script = "openspace.setPropertyValue(\"" + property + "\"," + value + ");"; - return script; - } - - void ParallelConnection::broadcast(){ + //serialize current script + tmpbuffer.clear(); + sm.serialize(tmpbuffer); + + //and insert into full buffer + scriptbuffer.insert(scriptbuffer.end(), tmpbuffer.begin(), tmpbuffer.end()); + + //increment number of scripts + numscripts++; + } + + //write header + buffer.clear(); + writeHeader(buffer, MessageTypes::Initialization); + + //write client ID to receive init message + buffer.insert(buffer.end(), reinterpret_cast(&requesterID), reinterpret_cast(&requesterID) + sizeof(uint32_t)); + + //write total size of data chunk + uint32_t totlen = static_cast(scriptbuffer.size()); + buffer.insert(buffer.end(), reinterpret_cast(&totlen), reinterpret_cast(&totlen) + sizeof(uint32_t)); + + //write number of scripts + buffer.insert(buffer.end(), reinterpret_cast(&numscripts), reinterpret_cast(&numscripts) + sizeof(uint16_t)); + + //write all scripts + buffer.insert(buffer.end(), scriptbuffer.begin(), scriptbuffer.end()); + + //queue message + queueMessage(buffer); +} + +void ParallelConnection::listenCommunication(){ - //while we're still connected and we're the host - while (_isConnected.load() && _isHost.load()){ + //create basic buffer for receiving first part of messages + std::vector buffer; + //size of the header + buffer.resize(headerSize()); + + int result; + + //while we're still connected + while (_isConnected.load()){ + //receive the first parts of a message + result = receiveData(_clientSocket, buffer, headerSize(), 0); - //create a keyframe with current position and orientation of camera - network::datamessagestructures::PositionKeyframe kf; - kf._position = OsEng.interactionHandler()->camera()->position(); - kf._viewRotationQuat = glm::quat_cast(OsEng.interactionHandler()->camera()->viewRotationMatrix()); - - //timestamp as current runtime of OpenSpace instance - kf._timeStamp = OsEng.runTime(); - - //create a buffer for the keyframe - std::vector kfBuffer; + //if enough data was received + if (result > 0){ - //fill the keyframe buffer - kf.serialize(kfBuffer); - - //get the size of the keyframebuffer - uint16_t msglen = static_cast(kfBuffer.size()); - - //the type of message - uint16_t type = static_cast(network::datamessagestructures::PositionData); - - //create the full buffer - std::vector buffer; - buffer.reserve(headerSize() + sizeof(type) + sizeof(msglen) + msglen); - - //write header - writeHeader(buffer, MessageTypes::Data); - - //type of message - buffer.insert(buffer.end(), reinterpret_cast(&type), reinterpret_cast(&type) + sizeof(type)); + //make sure that header matches this version of OpenSpace + if (buffer[0] == 'O' && //Open + buffer[1] == 'S' && //Space + buffer[2] == OPENSPACE_VERSION_MAJOR && // major version + buffer[3] == OPENSPACE_VERSION_MINOR // minor version + ) + { + //parse type + uint32_t type = (*(reinterpret_cast(&buffer[4]))); - //size of message - buffer.insert(buffer.end(), reinterpret_cast(&msglen), reinterpret_cast(&msglen) + sizeof(msglen)); - - //actual message - buffer.insert(buffer.end(), kfBuffer.begin(), kfBuffer.end()); - - //send message - queueMessage(buffer); - - //100 ms sleep - send keyframes 10 times per second - std::this_thread::sleep_for(std::chrono::milliseconds(100)); + //and delegate decoding depending on type + delegateDecoding(type); } - } - - void ParallelConnection::writeHeader(std::vector &buffer, uint32_t messageType){ - //make sure the buffer is large enough to hold at least the header - if(buffer.size() < headerSize()){ - buffer.reserve(headerSize()); + else{ + LERROR("Error: Client OpenSpace version " << OPENSPACE_VERSION_MAJOR << ", " << OPENSPACE_VERSION_MINOR << " does not match server version " << buffer[2] <<", " << buffer[3] << std::endl << "Message not decoded."); } - - //get the current running version of openspace - uint8_t versionMajor = static_cast(OPENSPACE_VERSION_MAJOR); - uint8_t versionMinor = static_cast(OPENSPACE_VERSION_MINOR); - - //insert header into buffer - buffer.insert(buffer.end(), 'O'); - buffer.insert(buffer.end(), 'S'); - buffer.insert(buffer.end(), versionMajor); - buffer.insert(buffer.end(), versionMinor); - buffer.insert(buffer.end(), reinterpret_cast(&messageType), reinterpret_cast(&messageType) + sizeof(messageType)); - } - - int ParallelConnection::headerSize(){ - //minor and major version (as uint8_t -> 1 byte) + two bytes for the chars 'O' and 'S' + 4 bytes for type of message - return 2 * sizeof(uint8_t) + 2 + sizeof(uint32_t); - } + } + else{ + if (result == 0){ + //connection rejected + LERROR("Parallel connection rejected, disconnecting..."); + } + else{ + LERROR("Error " << _ERRNO << " detected in connection, disconnecting!"); + } - scripting::ScriptEngine::LuaLibrary ParallelConnection::luaLibrary() { - return { - "parallel", - { - { - "setPort", - &luascriptfunctions::setPort, - "number", - "Set the port for the parallel connection" - }, - { - "setAddress", - &luascriptfunctions::setAddress, - "string", - "Set the address for the parallel connection" - }, - { - "setPassword", - &luascriptfunctions::setPassword, - "string", - "Set the password for the parallel connection" - }, - { - "setDisplayName", - &luascriptfunctions::setDisplayName, - "string", - "Set your display name for the parallel connection" - }, - { - "connect", - &luascriptfunctions::connect, - "", - "Connect to parallel" - }, - { - "disconnect", - &luascriptfunctions::disconnect, - "", - "Disconnect from parallel" - }, - { - "requestHostship", - &luascriptfunctions::requestHostship, - "string", - "Request to be the host for this session" - }, - } - }; - } + //signal that a disconnect should be performed + signalDisconnect(); + break; + } + } + +} + +int ParallelConnection::receiveData(_SOCKET & socket, std::vector &buffer, int length, int flags){ + int result = 0; + int received = 0; + while (result < length){ + received = recv(socket, buffer.data() + result, length - result, flags); + + if (received > 0){ + result += received; + received = 0; + } + else{ + //error receiving + result = received; + break; + } + } + + return result; +} - } // namespace network +void ParallelConnection::setPort(const std::string &port){ + _port = port; +} + +void ParallelConnection::setAddress(const std::string &address){ + _address = address; +} + +void ParallelConnection::setName(const std::string& name){ + _name = name; +} + +bool ParallelConnection::isHost(){ + return _isHost.load(); +} + +void ParallelConnection::requestHostship(const std::string &password){ + std::vector buffer; + buffer.reserve(headerSize()); + + uint32_t passcode = hash(password); + + //write header + writeHeader(buffer, MessageTypes::HostshipRequest); + + //write passcode + buffer.insert(buffer.end(), reinterpret_cast(&passcode), reinterpret_cast(&passcode) + sizeof(uint32_t)); + + //send message + queueMessage(buffer); +} + +void ParallelConnection::setPassword(const std::string& pwd){ + _passCode = hash(pwd); +} + +bool ParallelConnection::initNetworkAPI(){ + #if defined(__WIN32__) + WSADATA wsaData; + WORD version; + int error; + + version = MAKEWORD(2, 2); + + error = WSAStartup(version, &wsaData); + + if (error != 0 || + LOBYTE(wsaData.wVersion) != 2 || + HIBYTE(wsaData.wVersion) != 2) + { + /* incorrect WinSock version */ + LERROR("Failed to init winsock API."); + //WSACleanup(); + return false; + } + #else + //No init needed on unix + #endif + + return true; +} + +void ParallelConnection::preSynchronization(){ + + //if we're the host + if(_isHost){ + //get current time parameters and create a keyframe + network::datamessagestructures::TimeKeyframe tf; + tf._dt = Time::ref().deltaTime(); + tf._paused = Time::ref().paused(); + tf._requiresTimeJump = Time::ref().timeJumped(); + tf._time = Time::ref().currentTime(); + + //create a buffer and serialize message + std::vector tbuffer; + tf.serialize(tbuffer); + + //get the size of the keyframebuffer + uint16_t msglen = static_cast(tbuffer.size()); + + //the type of data message + uint16_t type = static_cast(network::datamessagestructures::TimeData); + + //create the full buffer + std::vector buffer; + buffer.reserve(headerSize() + sizeof(type) + sizeof(msglen) + msglen); + + //write header + writeHeader(buffer, MessageTypes::Data); + + //type of message + buffer.insert(buffer.end(), reinterpret_cast(&type), reinterpret_cast(&type) + sizeof(type)); + + //size of message + buffer.insert(buffer.end(), reinterpret_cast(&msglen), reinterpret_cast(&msglen) + sizeof(msglen)); + + //actual message + buffer.insert(buffer.end(), tbuffer.begin(), tbuffer.end()); + + //send message + queueMessage(buffer); + } + else{ + //if we're not the host and we have a valid keyframe (one that hasnt been used before) + if(_latestTimeKeyframeValid.load()){ + + //lock mutex and retrieve parameters from latest keyframe + _timeKeyframeMutex.lock(); + + double dt = _latestTimeKeyframe._dt; + double time = _latestTimeKeyframe._time; + bool jump = _latestTimeKeyframe._requiresTimeJump; + bool paused = _latestTimeKeyframe._paused; + + _timeKeyframeMutex.unlock(); + + //this keyframe is now spent + _latestTimeKeyframeValid.store(false); + + //assign latest params + Time::ref().setDeltaTime(dt); + Time::ref().setTime(time, jump); + Time::ref().setPause(paused); + + } + } +} + +void ParallelConnection::scriptMessage(const std::string propIdentifier, const std::string propValue){ + + //save script as current state + { + //mutex protect + std::lock_guard lock(_currentStateMutex); + _currentState[propIdentifier] = propValue; + } + + //if we're connected and we're the host, also send the script + if(_isConnected.load() && _isHost.load()){ + //construct script + std::string script = scriptFromPropertyAndValue(propIdentifier, propValue); + + //create a script message + network::datamessagestructures::ScriptMessage sm; + sm._script = script; + sm._scriptlen = static_cast(script.length()); + + //create a buffer for the script + std::vector sbuffer; + + //fill the script buffer + sm.serialize(sbuffer); + + //get the size of the keyframebuffer + uint16_t msglen = static_cast(sbuffer.size()); + + //the type of message + uint16_t type = static_cast(network::datamessagestructures::ScriptData); + + //create the full buffer + std::vector buffer; + buffer.reserve(headerSize() + sizeof(type) + sizeof(msglen) + msglen); + + //write header + writeHeader(buffer, MessageTypes::Data); + + //type of message + buffer.insert(buffer.end(), reinterpret_cast(&type), reinterpret_cast(&type) + sizeof(type)); + + //size of message + buffer.insert(buffer.end(), reinterpret_cast(&msglen), reinterpret_cast(&msglen) + sizeof(msglen)); + + //actual message + buffer.insert(buffer.end(), sbuffer.begin(), sbuffer.end()); + + //send message + queueMessage(buffer); + } + +} + +std::string ParallelConnection::scriptFromPropertyAndValue(const std::string property, const std::string value){ + //consruct script + std::string script = "openspace.setPropertyValue(\"" + property + "\"," + value + ");"; + return script; +} + +void ParallelConnection::broadcast(){ + + //while we're still connected and we're the host + while (_isConnected.load() && _isHost.load()){ + + //create a keyframe with current position and orientation of camera + network::datamessagestructures::PositionKeyframe kf; + kf._position = OsEng.interactionHandler()->camera()->position(); + kf._viewRotationQuat = glm::quat_cast(OsEng.interactionHandler()->camera()->viewRotationMatrix()); + + //timestamp as current runtime of OpenSpace instance + kf._timeStamp = OsEng.runTime(); + + //create a buffer for the keyframe + std::vector kfBuffer; + + //fill the keyframe buffer + kf.serialize(kfBuffer); + + //get the size of the keyframebuffer + uint16_t msglen = static_cast(kfBuffer.size()); + + //the type of message + uint16_t type = static_cast(network::datamessagestructures::PositionData); + + //create the full buffer + std::vector buffer; + buffer.reserve(headerSize() + sizeof(type) + sizeof(msglen) + msglen); + + //write header + writeHeader(buffer, MessageTypes::Data); + + //type of message + buffer.insert(buffer.end(), reinterpret_cast(&type), reinterpret_cast(&type) + sizeof(type)); + + //size of message + buffer.insert(buffer.end(), reinterpret_cast(&msglen), reinterpret_cast(&msglen) + sizeof(msglen)); + + //actual message + buffer.insert(buffer.end(), kfBuffer.begin(), kfBuffer.end()); + + //send message + queueMessage(buffer); + + //100 ms sleep - send keyframes 10 times per second + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } +} + +void ParallelConnection::writeHeader(std::vector &buffer, uint32_t messageType){ + //make sure the buffer is large enough to hold at least the header + if(buffer.size() < headerSize()){ + buffer.reserve(headerSize()); + } + + //get the current running version of openspace + uint8_t versionMajor = static_cast(OPENSPACE_VERSION_MAJOR); + uint8_t versionMinor = static_cast(OPENSPACE_VERSION_MINOR); + + //insert header into buffer + buffer.insert(buffer.end(), 'O'); + buffer.insert(buffer.end(), 'S'); + buffer.insert(buffer.end(), versionMajor); + buffer.insert(buffer.end(), versionMinor); + buffer.insert(buffer.end(), reinterpret_cast(&messageType), reinterpret_cast(&messageType) + sizeof(messageType)); +} + +int ParallelConnection::headerSize(){ + //minor and major version (as uint8_t -> 1 byte) + two bytes for the chars 'O' and 'S' + 4 bytes for type of message + return 2 * sizeof(uint8_t) + 2 + sizeof(uint32_t); +} + +scripting::ScriptEngine::LuaLibrary ParallelConnection::luaLibrary() { + return { + "parallel", + { + { + "setPort", + &luascriptfunctions::setPort, + "number", + "Set the port for the parallel connection" + }, + { + "setAddress", + &luascriptfunctions::setAddress, + "string", + "Set the address for the parallel connection" + }, + { + "setPassword", + &luascriptfunctions::setPassword, + "string", + "Set the password for the parallel connection" + }, + { + "setDisplayName", + &luascriptfunctions::setDisplayName, + "string", + "Set your display name for the parallel connection" + }, + { + "connect", + &luascriptfunctions::connect, + "", + "Connect to parallel" + }, + { + "disconnect", + &luascriptfunctions::disconnect, + "", + "Disconnect from parallel" + }, + { + "requestHostship", + &luascriptfunctions::requestHostship, + "string", + "Request to be the host for this session" + }, + } + }; +} + +} // namespace network } // namespace openspace From 0ed8a360717ecd24f9c60c7d57315a9d1279a753 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Thu, 16 Jul 2015 20:37:42 +0200 Subject: [PATCH 003/122] Change from CheckCXXCompilerFlag to CXX_STANDARD --- support/cmake/module_definition.cmake | 36 ++++++--------------------- support/cmake/support_macros.cmake | 27 +++----------------- 2 files changed, 11 insertions(+), 52 deletions(-) diff --git a/support/cmake/module_definition.cmake b/support/cmake/module_definition.cmake index ee16a9e8dd..3afdc344bc 100644 --- a/support/cmake/module_definition.cmake +++ b/support/cmake/module_definition.cmake @@ -76,6 +76,9 @@ endmacro () # Set the compiler settings that are common to all modules function (set_common_compile_settings target_name) + set_property(TARGET ${project} PROPERTY CXX_STANDARD 11) + set_property(TARGET ${project} PROPERTY CXX_STANDARD_REQUIRED On) + if (MSVC) target_compile_options(${library_name} PUBLIC "/MP" # Enabling multi-threaded compilation @@ -83,47 +86,22 @@ function (set_common_compile_settings target_name) "/wd4127" # constant conditional expression [used for do/while semicolon swallowing] "/wd4201" # nameless struct/union [standard is ubiquitous] "/wd4505" # Unreferenced function was removed - "/W4" + "/W4" # Warning level ) if (OPENSPACE_WARNINGS_AS_ERRORS) target_compile_options(${library_name} PUBLIC "/Wx") endif () elseif (APPLE) target_compile_definitions(${library_name} PUBLIC "__APPLE__") - - include (CheckCXXCompilerFlag) - CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11) - CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X) - mark_as_advanced(COMPILER_SUPPORTS_CXX11, COMPILER_SUPPORTS_CXX0X) - if (COMPILER_SUPPORTS_CXX11) - target_compile_options(${library_name} PUBLIC "-std=c++11") - elseif (COMPILER_SUPPORTS_CXX0X) - target_compile_options(${library_name} PUBLIC "-std=c++0x") - else () - message(FATAL_ERROR "Compiler does not have C++11 support") - endif () - target_compile_options(${library_name} PUBLIC "-stdlib=libc++") if (OPENSPACE_WARNINGS_AS_ERRORS) target_compile_options(${library_name} PUBLIC "-Werror") endif () elseif (UNIX) - include (CheckCXXCompilerFlag) - CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11) - CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X) - mark_as_advanced(COMPILER_SUPPORTS_CXX11, COMPILER_SUPPORTS_CXX0X) - if (COMPILER_SUPPORTS_CXX11) - target_compile_options(${library_name} PUBLIC "-std=c++11") - elseif (COMPILER_SUPPORTS_CXX0X) - target_compile_options(${library_name} PUBLIC "-std=c++0x") - else () - message(FATAL_ERROR "Compiler does not have C++11 support") - endif () - target_compile_options(${library_name} PUBLIC "-ggdb" "-Wall" "-Wno-long-long" "-pedantic" "-Wextra") if (OPENSPACE_WARNINGS_AS_ERRORS) target_compile_options(${library_name} PUBLIC "-Werror") - endif () + endif () endif () endfunction () @@ -131,6 +109,7 @@ endfunction () # Propagate the include directives from the libOpenSpace target into this module function (set_openspace_settings target_name) + # Get the include directories from the OpenSpace library get_property( OPENSPACE_INCLUDE_DIR TARGET libOpenSpace @@ -156,7 +135,7 @@ endfunction () # Loads the dependencies from 'include.cmake' and deals with them function (handle_dependencies target_name module_name) - if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/include.cmake") + if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/include.cmake") include(${CMAKE_CURRENT_SOURCE_DIR}/include.cmake) # Handle OpenSpace dependencies @@ -186,6 +165,7 @@ endfunction () +# Writes the modulename.cmake containing the MODULE_NAME and MODULE_PATH function (write_module_name module_name) string(TOLOWER ${module_name} module_name_lower) diff --git a/support/cmake/support_macros.cmake b/support/cmake/support_macros.cmake index 9ed1a86d9b..9de4c3e51f 100644 --- a/support/cmake/support_macros.cmake +++ b/support/cmake/support_macros.cmake @@ -76,6 +76,9 @@ endfunction () function (set_compile_settings project) + set_property(TARGET ${project} PROPERTY CXX_STANDARD 11) + set_property(TARGET ${project} PROPERTY CXX_STANDARD_REQUIRED On) + if (MSVC) target_compile_options(${project} PUBLIC "/MP" "/wd4201" "/wd4127") if (OPENSPACE_WARNINGS_AS_ERRORS) @@ -84,18 +87,6 @@ function (set_compile_settings project) elseif (APPLE) target_compile_definitions(${project} PUBLIC "__APPLE__") - include (CheckCXXCompilerFlag) - CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11) - CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X) - mark_as_advanced(COMPILER_SUPPORTS_CXX11, COMPILER_SUPPORTS_CXX0X) - if (COMPILER_SUPPORTS_CXX11) - target_compile_options(${project} PUBLIC "-std=c++11") - elseif (COMPILER_SUPPORTS_CXX0X) - target_compile_options(${project} PUBLIC "-std=c++0x") - else () - message(FATAL_ERROR "Compiler does not have C++11 support") - endif () - if (OPENSPACE_WARNINGS_AS_ERRORS) target_compile_options(${project} PUBLIC "-Werror") endif () @@ -115,18 +106,6 @@ function (set_compile_settings project) ${APP_SERVICES_LIBRARY} ) elseif (UNIX) - include (CheckCXXCompilerFlag) - CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11) - CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X) - mark_as_advanced(COMPILER_SUPPORTS_CXX11, COMPILER_SUPPORTS_CXX0X) - if (COMPILER_SUPPORTS_CXX11) - target_compile_options(${project} PUBLIC "-std=c++11") - elseif (COMPILER_SUPPORTS_CXX0X) - target_compile_options(${project} PUBLIC "-std=c++0x") - else () - message(FATAL_ERROR "Compiler does not have C++11 support") - endif () - if (OPENSPACE_WARNINGS_AS_ERRORS) target_compile_options(${project} PUBLIC "-Werror") endif () From 359b66b2ed792074732d1c21f7b9aff31a321c8f Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Fri, 17 Jul 2015 13:50:37 +0200 Subject: [PATCH 004/122] Updated externals --- data | 2 +- ext/ghoul | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/data b/data index ddcba938fb..78d9d66bd0 160000 --- a/data +++ b/data @@ -1 +1 @@ -Subproject commit ddcba938fbda7ec5cc1e8d06be0fc47e199b0f4f +Subproject commit 78d9d66bd028c750e7fa9c8cd7b016519ed51f63 diff --git a/ext/ghoul b/ext/ghoul index 5c150e1268..c1c66477bb 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 5c150e1268c6c2a5ddbf768348925c9ab2f19eab +Subproject commit c1c66477bb3577a26c6618c1da82da5346ba858b From 8a573a7cb8322b507c5219119436db96b362c7a0 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Fri, 17 Jul 2015 14:03:38 +0200 Subject: [PATCH 005/122] Added an icon to the OpenSpace executable --- apps/OpenSpace/CMakeLists.txt | 9 ++++++++- apps/OpenSpace/openspace.ico | Bin 0 -> 67338 bytes apps/OpenSpace/openspace.png | Bin 0 -> 62688 bytes apps/OpenSpace/openspace.rc | 1 + 4 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 apps/OpenSpace/openspace.ico create mode 100644 apps/OpenSpace/openspace.png create mode 100644 apps/OpenSpace/openspace.rc diff --git a/apps/OpenSpace/CMakeLists.txt b/apps/OpenSpace/CMakeLists.txt index a49ee281e8..45f08811fe 100644 --- a/apps/OpenSpace/CMakeLists.txt +++ b/apps/OpenSpace/CMakeLists.txt @@ -25,7 +25,14 @@ set(APPLICATION_NAME OpenSpace) set(APPLICATION_LINK_TO_OPENSPACE ON) -add_executable(${APPLICATION_NAME} ${OPENSPACE_APPS_DIR}/OpenSpace/main.cpp) +if (WIN32) + set(RESOURCE_FILE ${OPENSPACE_APPS_DIR}/OpenSpace/openspace.rc) +endif () + +add_executable(${APPLICATION_NAME} + ${OPENSPACE_APPS_DIR}/OpenSpace/main.cpp + ${RESOURCE_FILE} +) target_include_directories(${APPLICATION_NAME} PUBLIC ${OPENSPACE_BASE_DIR}/include) target_link_libraries(${APPLICATION_NAME} libOpenSpace) diff --git a/apps/OpenSpace/openspace.ico b/apps/OpenSpace/openspace.ico new file mode 100644 index 0000000000000000000000000000000000000000..c57d8ce77bb4eed67f5bf1be26662f034189bc4d GIT binary patch literal 67338 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 VrjTo|JvRUV002ovPDHLkV1h2Lnz8@@ literal 0 HcmV?d00001 diff --git a/apps/OpenSpace/openspace.png b/apps/OpenSpace/openspace.png new file mode 100644 index 0000000000000000000000000000000000000000..f991048d87f24069d788e4067dcc4b53c673f1f8 GIT binary patch literal 62688 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

6H(}e`Q4I^jVhT@1 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 Date: Fri, 17 Jul 2015 14:06:12 +0200 Subject: [PATCH 006/122] Fix in CXX_STANDARD definition for modules in Apple and Unix --- support/cmake/module_definition.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/support/cmake/module_definition.cmake b/support/cmake/module_definition.cmake index 3afdc344bc..5e26fd581e 100644 --- a/support/cmake/module_definition.cmake +++ b/support/cmake/module_definition.cmake @@ -76,8 +76,8 @@ endmacro () # Set the compiler settings that are common to all modules function (set_common_compile_settings target_name) - set_property(TARGET ${project} PROPERTY CXX_STANDARD 11) - set_property(TARGET ${project} PROPERTY CXX_STANDARD_REQUIRED On) + set_property(TARGET ${library_name} PROPERTY CXX_STANDARD 11) + set_property(TARGET ${library_name} PROPERTY CXX_STANDARD_REQUIRED On) if (MSVC) target_compile_options(${library_name} PUBLIC From 6801c4e9a90065f6f4856b2c89c25903945021e0 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Fri, 17 Jul 2015 14:15:13 +0200 Subject: [PATCH 007/122] Continue using CheckCXXCompilerFlag on unix --- support/cmake/module_definition.cmake | 12 ++++++++++++ support/cmake/support_macros.cmake | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/support/cmake/module_definition.cmake b/support/cmake/module_definition.cmake index 5e26fd581e..330eba1992 100644 --- a/support/cmake/module_definition.cmake +++ b/support/cmake/module_definition.cmake @@ -98,6 +98,18 @@ function (set_common_compile_settings target_name) target_compile_options(${library_name} PUBLIC "-Werror") endif () elseif (UNIX) + include (CheckCXXCompilerFlag) + CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11) + CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X) + mark_as_advanced(COMPILER_SUPPORTS_CXX11, COMPILER_SUPPORTS_CXX0X) + if (COMPILER_SUPPORTS_CXX11) + target_compile_options(${library_name} PUBLIC "-std=c++11") + elseif (COMPILER_SUPPORTS_CXX0X) + target_compile_options(${library_name} PUBLIC "-std=c++0x") + else () + message(FATAL_ERROR "Compiler does not have C++11 support") + endif () + target_compile_options(${library_name} PUBLIC "-ggdb" "-Wall" "-Wno-long-long" "-pedantic" "-Wextra") if (OPENSPACE_WARNINGS_AS_ERRORS) target_compile_options(${library_name} PUBLIC "-Werror") diff --git a/support/cmake/support_macros.cmake b/support/cmake/support_macros.cmake index 9de4c3e51f..dff35e5e66 100644 --- a/support/cmake/support_macros.cmake +++ b/support/cmake/support_macros.cmake @@ -106,6 +106,18 @@ function (set_compile_settings project) ${APP_SERVICES_LIBRARY} ) elseif (UNIX) + include (CheckCXXCompilerFlag) + CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11) + CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X) + mark_as_advanced(COMPILER_SUPPORTS_CXX11, COMPILER_SUPPORTS_CXX0X) + if (COMPILER_SUPPORTS_CXX11) + target_compile_options(${project} PUBLIC "-std=c++11") + elseif (COMPILER_SUPPORTS_CXX0X) + target_compile_options(${project} PUBLIC "-std=c++0x") + else () + message(FATAL_ERROR "Compiler does not have C++11 support") + endif () + if (OPENSPACE_WARNINGS_AS_ERRORS) target_compile_options(${project} PUBLIC "-Werror") endif () From 35e95b94e788308f91fb95460635496282981661 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 5 Oct 2015 00:07:38 +0200 Subject: [PATCH 008/122] First version to update OpenSpace to the new SGCT version --- apps/OpenSpace/main.cpp | 7 ++-- src/abuffer/abuffer.cpp | 5 +-- src/abuffer/abuffervisualizer.cpp | 50 +++++++++++++------------- src/engine/openspaceengine.cpp | 10 +++--- src/interaction/luaconsole.cpp | 11 +++--- src/interaction/mousecontroller.cpp | 12 +++---- src/rendering/renderengine.cpp | 55 +++++++++++++++++------------ 7 files changed, 84 insertions(+), 66 deletions(-) diff --git a/apps/OpenSpace/main.cpp b/apps/OpenSpace/main.cpp index 47960b86b8..da70145529 100644 --- a/apps/OpenSpace/main.cpp +++ b/apps/OpenSpace/main.cpp @@ -128,7 +128,8 @@ int main(int argc, char** argv) { _sgctEngine->setExternalControlCallback(mainExternalControlCallback); _sgctEngine->setCharCallbackFunction(mainCharCallback); - _sgctEngine->setFisheyeClearColor(0.f, 0.f, 0.f); + + // _sgctEngine->setFisheyeClearColor(0.f, 0.f, 0.f); // set encode and decode functions // NOTE: starts synchronizing before init functions @@ -214,13 +215,13 @@ void mainRenderFunc() { mat4 userMatrix = translate(mat4(1.f), _sgctEngine->getDefaultUserPtr()->getPos()); mat4 sceneMatrix = _sgctEngine->getModelMatrix(); - mat4 viewMatrix = _sgctEngine->getActiveViewMatrix() * userMatrix; + mat4 viewMatrix = _sgctEngine->getCurrentViewMatrix() * userMatrix; //dont shift nav-direction on master, makes it very tricky to navigate @JK if (!OsEng.ref().isMaster()) viewMatrix = viewMatrix * sceneMatrix; - mat4 projectionMatrix = _sgctEngine->getActiveProjectionMatrix(); + mat4 projectionMatrix = _sgctEngine->getCurrentProjectionMatrix(); OsEng.render(projectionMatrix, viewMatrix); } diff --git a/src/abuffer/abuffer.cpp b/src/abuffer/abuffer.cpp index afadda50fa..e39821ca6f 100644 --- a/src/abuffer/abuffer.cpp +++ b/src/abuffer/abuffer.cpp @@ -331,8 +331,9 @@ void ABuffer::invalidateABuffer() { } void ABuffer::updateDimensions() { - _width = sgct::Engine::instance()->getActiveWindowPtr()->getXFramebufferResolution(); - _height = sgct::Engine::instance()->getActiveWindowPtr()->getYFramebufferResolution(); + _width = sgct::Engine::instance()->getCurrentWindowPtr()->getXFramebufferResolution(); + _height = sgct::Engine::instance()->getCurrentWindowPtr()->getYFramebufferResolution(); + _totalPixels = _width * _height; } diff --git a/src/abuffer/abuffervisualizer.cpp b/src/abuffer/abuffervisualizer.cpp index a24ddbc3b6..95f01a7683 100644 --- a/src/abuffer/abuffervisualizer.cpp +++ b/src/abuffer/abuffervisualizer.cpp @@ -113,7 +113,7 @@ void ABufferVisualizer::render() { modelMatrix = glm::translate(modelMatrix, glm::vec3(0, 0, -1)); modelMatrix = modelMatrix * rotation; - _pointcloudProgram->setUniform("ViewProjection", sgct::Engine::instance()->getActiveModelViewProjectionMatrix()); + _pointcloudProgram->setUniform("ViewProjection", sgct::Engine::instance()->getCurrentModelViewProjectionMatrix()); _pointcloudProgram->setUniform("ModelTransform", modelMatrix); #if defined(MARKER_POINTS) @@ -145,30 +145,30 @@ void ABufferVisualizer::render() { const glm::mat4 scale = glm::scale(glm::mat4(1.0), glm::vec3(0.04, 0.04, 0.04)); glm::mat4 translate, mvp; - translate = glm::translate(glm::mat4(1.0), glm::vec3(0, 0, 0)); - mvp = sgct::Engine::instance()->getActiveModelViewProjectionMatrix()*modelMatrix*translate*rotationText*scale; - Freetype::print3d(fontLight, mvp, "(0,0,0)"); - translate = glm::translate(glm::mat4(1.0), glm::vec3(0, 0, 1)); - mvp = sgct::Engine::instance()->getActiveModelViewProjectionMatrix()*modelMatrix*translate*rotationText*scale; - Freetype::print3d(fontLight, mvp, "(0,0,1)"); - translate = glm::translate(glm::mat4(1.0), glm::vec3(0, 1, 0)); - mvp = sgct::Engine::instance()->getActiveModelViewProjectionMatrix()*modelMatrix*translate*rotationText*scale; - Freetype::print3d(fontLight, mvp, "(0,1,0)"); - translate = glm::translate(glm::mat4(1.0), glm::vec3(1, 0, 0)); - mvp = sgct::Engine::instance()->getActiveModelViewProjectionMatrix()*modelMatrix*translate*rotationText*scale; - Freetype::print3d(fontLight, mvp, "(1,0,0)"); - translate = glm::translate(glm::mat4(1.0), glm::vec3(0, 1, 1)); - mvp = sgct::Engine::instance()->getActiveModelViewProjectionMatrix()*modelMatrix*translate*rotationText*scale; - Freetype::print3d(fontLight, mvp, "(0,1,1)"); - translate = glm::translate(glm::mat4(1.0), glm::vec3(1, 0, 1)); - mvp = sgct::Engine::instance()->getActiveModelViewProjectionMatrix()*modelMatrix*translate*rotationText*scale; - Freetype::print3d(fontLight, mvp, "(1,0,1)"); - translate = glm::translate(glm::mat4(1.0), glm::vec3(1, 1, 0)); - mvp = sgct::Engine::instance()->getActiveModelViewProjectionMatrix()*modelMatrix*translate*rotationText*scale; - Freetype::print3d(fontLight, mvp, "(1,1,0)"); - translate = glm::translate(glm::mat4(1.0), glm::vec3(1, 1, 1)); - mvp = sgct::Engine::instance()->getActiveModelViewProjectionMatrix()*modelMatrix*translate*rotationText*scale; - Freetype::print3d(fontLight, mvp, "(1,1,1)"); +// translate = glm::translate(glm::mat4(1.0), glm::vec3(0, 0, 0)); +// mvp = sgct::Engine::instance()->getCurrentModelViewProjectionMatrix()*modelMatrix*translate*rotationText*scale; +// Freetype::print3d(fontLight, mvp, "(0,0,0)"); +// translate = glm::translate(glm::mat4(1.0), glm::vec3(0, 0, 1)); +// mvp = sgct::Engine::instance()->getCurrentModelViewProjectionMatrix()*modelMatrix*translate*rotationText*scale; +// Freetype::print3d(fontLight, mvp, "(0,0,1)"); +// translate = glm::translate(glm::mat4(1.0), glm::vec3(0, 1, 0)); +// mvp = sgct::Engine::instance()->getCurrentModelViewProjectionMatrix()*modelMatrix*translate*rotationText*scale; +// Freetype::print3d(fontLight, mvp, "(0,1,0)"); +// translate = glm::translate(glm::mat4(1.0), glm::vec3(1, 0, 0)); +// mvp = sgct::Engine::instance()->getCurrentModelViewProjectionMatrix()*modelMatrix*translate*rotationText*scale; +// Freetype::print3d(fontLight, mvp, "(1,0,0)"); +// translate = glm::translate(glm::mat4(1.0), glm::vec3(0, 1, 1)); +// mvp = sgct::Engine::instance()->getCurrentModelViewProjectionMatrix()*modelMatrix*translate*rotationText*scale; +// Freetype::print3d(fontLight, mvp, "(0,1,1)"); +// translate = glm::translate(glm::mat4(1.0), glm::vec3(1, 0, 1)); +// mvp = sgct::Engine::instance()->getCurrentModelViewProjectionMatrix()*modelMatrix*translate*rotationText*scale; +// Freetype::print3d(fontLight, mvp, "(1,0,1)"); +// translate = glm::translate(glm::mat4(1.0), glm::vec3(1, 1, 0)); +// mvp = sgct::Engine::instance()->getCurrentModelViewProjectionMatrix()*modelMatrix*translate*rotationText*scale; +// Freetype::print3d(fontLight, mvp, "(1,1,0)"); +// translate = glm::translate(glm::mat4(1.0), glm::vec3(1, 1, 1)); +// mvp = sgct::Engine::instance()->getCurrentModelViewProjectionMatrix()*modelMatrix*translate*rotationText*scale; +// Freetype::print3d(fontLight, mvp, "(1,1,1)"); } void ABufferVisualizer::initializeMarkers() { diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index c154334a07..62cf9539d5 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -690,10 +690,12 @@ void OpenSpaceEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 if (_isMaster) { // If currently writing a command, render it to screen - sgct::SGCTWindow* w = sgct::Engine::instance()->getActiveWindowPtr(); - if (_isMaster && !w->isUsingFisheyeRendering() && _console->isVisible()) { - _console->render(); - } + sgct::SGCTWindow* w = sgct::Engine::instance()->getCurrentWindowPtr(); + // !w->isUsingFisheyeRendering() does not exist anymore ---abock + // if (_isMaster && !w->isUsingFisheyeRendering() && _console->isVisible()) { + if (_isMaster && _console->isVisible()) { + _console->render(); + } if (_gui->isEnabled()) _gui->endFrame(); diff --git a/src/interaction/luaconsole.cpp b/src/interaction/luaconsole.cpp index 66d9afa687..cc2c283477 100644 --- a/src/interaction/luaconsole.cpp +++ b/src/interaction/luaconsole.cpp @@ -286,7 +286,7 @@ void LuaConsole::charCallback(unsigned int codepoint) { void LuaConsole::render() { const float font_size = 10.0f; int x1, xSize, y1, ySize; - sgct::Engine::instance()->getActiveWindowPtr()->getCurrentViewportPixelCoords(x1, y1, xSize, ySize); + sgct::Engine::instance()->getCurrentWindowPtr()->getCurrentViewportPixelCoords(x1, y1, xSize, ySize); float startY = static_cast(ySize) - 2.0f * font_size; startY = startY - font_size * 15.0f * 2.0f; @@ -294,8 +294,10 @@ void LuaConsole::render() { const glm::vec4 green(0, 1, 0, 1); const glm::vec4 white(1, 1, 1, 1); const sgct_text::Font* font = sgct_text::FontManager::instance()->getFont(constants::fonts::keyMono, static_cast(font_size)); - Freetype::print(font, 15.0f, startY, red, "$"); - Freetype::print(font, 15.0f + font_size, startY, white, "%s", _commands.at(_activeCommand).c_str()); +// sgct_text::print(font, 15.0f, startY, red, "$"); +// sgct_text::print(font, 15.0f + font_size, startY, white, "%s", _commands.at(_activeCommand).c_str()); + sgct_text::print(font, 15.0f, startY, "$"); + sgct_text::print(font, 15.0f + font_size, startY, "%s", _commands.at(_activeCommand).c_str()); size_t n = std::count(_commands.at(_activeCommand).begin(), _commands.at(_activeCommand).begin() + _inputPosition, '\n'); size_t p = _commands.at(_activeCommand).find_last_of('\n', _inputPosition); @@ -318,7 +320,8 @@ void LuaConsole::render() { std::stringstream ss; ss << "%" << linepos + 1 << "s"; - Freetype::print(font, 15.0f + font_size*0.5f, startY - (font_size)*(n + 1)*3.0f / 2.0f, green, ss.str().c_str(), "^"); +// sgct_text::print(font, 15.0f + font_size*0.5f, startY - (font_size)*(n + 1)*3.0f / 2.0f, green, ss.str().c_str(), "^"); + sgct_text::print(font, 15.0f + font_size*0.5f, startY - (font_size)*(n + 1)*3.0f / 2.0f, ss.str().c_str(), "^"); } unsigned int LuaConsole::commandInputButton() { diff --git a/src/interaction/mousecontroller.cpp b/src/interaction/mousecontroller.cpp index 85df8ff359..790bf9e283 100644 --- a/src/interaction/mousecontroller.cpp +++ b/src/interaction/mousecontroller.cpp @@ -72,8 +72,8 @@ glm::vec3 MouseController::mapToCamera(glm::vec3 trackballPos) { void MouseController::trackballRotate(int x, int y) { // Normalize mouse coordinates to [0,1] - float width = static_cast(sgct::Engine::instance()->getActiveXResolution()); - float height = static_cast(sgct::Engine::instance()->getActiveYResolution()); + float width = static_cast(sgct::Engine::instance()->getCurrentXResolution()); + float height = static_cast(sgct::Engine::instance()->getCurrentYResolution()); glm::vec2 mousePos = glm::vec2((float)x / width, (float)y / height); mousePos = glm::clamp(mousePos, -0.5, 1.5); // Ugly fix #1: Camera position becomes NaN on mouse values outside [-0.5, 1.5] @@ -167,7 +167,7 @@ void OrbitalMouseController::button(MouseAction action, MouseButton button) { if (action == MouseAction::Press){ _leftMouseButtonDown = true; double mouseX, mouseY; - sgct::Engine::instance()->getMousePos(sgct::Engine::instance()->getActiveWindowPtr()->getId(), &mouseX, &mouseY); + sgct::Engine::instance()->getMousePos(sgct::Engine::instance()->getCurrentWindowPtr()->getId(), &mouseX, &mouseY); _previousCursorPos[MouseButtons::ButtonLeft] = glm::vec2(static_cast(mouseX), static_cast(mouseY)); } else if (action == MouseAction::Release) { @@ -179,7 +179,7 @@ void OrbitalMouseController::button(MouseAction action, MouseButton button) { if (action == MouseAction::Press){ _rightMouseButtonDown = true; double mouseX, mouseY; - sgct::Engine::instance()->getMousePos(sgct::Engine::instance()->getActiveWindowPtr()->getId(), &mouseX, &mouseY); + sgct::Engine::instance()->getMousePos(sgct::Engine::instance()->getCurrentWindowPtr()->getId(), &mouseX, &mouseY); _previousCursorPos[MouseButtons::ButtonRight] = glm::vec2(static_cast(mouseX), static_cast(mouseY)); } else if (action == MouseAction::Release) { @@ -191,7 +191,7 @@ void OrbitalMouseController::button(MouseAction action, MouseButton button) { if (action == MouseAction::Press){ _middleMouseButtonDown = true; double mouseX, mouseY; - sgct::Engine::instance()->getMousePos(sgct::Engine::instance()->getActiveWindowPtr()->getId(), &mouseX, &mouseY); + sgct::Engine::instance()->getMousePos(sgct::Engine::instance()->getCurrentWindowPtr()->getId(), &mouseX, &mouseY); _previousCursorPos[MouseButtons::ButtonMiddle] = glm::vec2(static_cast(mouseX), static_cast(mouseY)); } else if (action == MouseAction::Release) { @@ -203,7 +203,7 @@ void OrbitalMouseController::button(MouseAction action, MouseButton button) { } void OrbitalMouseController::move(float x, float y) { - int winID = sgct::Engine::instance()->getActiveWindowPtr()->getId(); + int winID = sgct::Engine::instance()->getCurrentWindowPtr()->getId(); double mouseX, mouseY; sgct::Engine::instance()->getMousePos(winID, &mouseX, &mouseY); _currentCursorPos = glm::vec2(static_cast(mouseX), static_cast(mouseY)); diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 97bf046d7c..3ecd0094ea 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -193,7 +193,7 @@ bool RenderEngine::initialize() { bool RenderEngine::initializeGL() { // LDEBUG("RenderEngine::initializeGL()"); - sgct::SGCTWindow* wPtr = sgct::Engine::instance()->getActiveWindowPtr(); + sgct::SGCTWindow* wPtr = sgct::Engine::instance()->getCurrentWindowPtr(); // TODO: Fix the power scaled coordinates in such a way that these // values can be set to more realistic values @@ -205,7 +205,7 @@ bool RenderEngine::initializeGL() { // calculating the maximum field of view for the camera, used to // determine visibility of objects in the scene graph - if (wPtr->isUsingFisheyeRendering()) { +/* if (sgct::Engine::instance()->getCurrentRenderTarget() == sgct::Engine::NonLinearBuffer) { // fisheye mode, looking upwards to the "dome" glm::vec4 upDirection(0, 1, 0, 0); @@ -220,19 +220,19 @@ bool RenderEngine::initializeGL() { _mainCamera->setMaxFov(wPtr->getFisheyeFOV()); _mainCamera->setLookUpVector(glm::vec3(0.0, 1.0, 0.0)); } - else { + else {*/ // get corner positions, calculating the forth to easily calculate center glm::vec3 corners[4]; - corners[0] = wPtr->getCurrentViewport()->getViewPlaneCoords( - sgct_core::Viewport::LowerLeft); + /*corners[0] = wPtr->getCurrentViewport()->getViewPlaneCoords( + sgct_core::SGCTProjectionPlane::LowerLeft); corners[1] = wPtr->getCurrentViewport()->getViewPlaneCoords( - sgct_core::Viewport::UpperLeft); + sgct_core::SGCTProjectionPlane::UpperLeft); corners[2] = wPtr->getCurrentViewport()->getViewPlaneCoords( - sgct_core::Viewport::UpperRight); + sgct_core::SGCTProjectionPlane::UpperRight); corners[3] = glm::vec3(corners[2][0], corners[0][1], corners[2][2]); + */ const glm::vec3 center = (corners[0] + corners[1] + corners[2] + corners[3]) / 4.0f; - //#if 0 // // @TODO Remove the ifdef when the next SGCT version is released that requests the @@ -267,7 +267,7 @@ bool RenderEngine::initializeGL() { } } _mainCamera->setMaxFov(maxFov); - } + //} LINFO("Initializing ABuffer"); _abuffer->initialize(); @@ -347,8 +347,9 @@ void RenderEngine::postSynchronizationPreDraw() { void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &viewMatrix) { // We need the window pointer - sgct::SGCTWindow* w = sgct::Engine::instance()->getActiveWindowPtr(); - if (w->isUsingFisheyeRendering()) + sgct::SGCTWindow* w = sgct::Engine::instance()->getCurrentWindowPtr(); + + if (sgct::Engine::instance()->getCurrentRenderTarget() == sgct::Engine::NonLinearBuffer) _abuffer->clear(); // SGCT resets certain settings @@ -399,8 +400,10 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi #if 1 #define PrintText(__i__, __format__, ...) Freetype::print(font, 10.f, static_cast(startY - font_size_mono * __i__ * 2), __format__, __VA_ARGS__); -#define PrintColorTextArg(__i__, __format__, __size__, __color__, ...) Freetype::print(font, __size__, static_cast(startY - font_size_mono * __i__ * 2), __color__, __format__, __VA_ARGS__); -#define PrintColorText(__i__, __format__, __size__, __color__) Freetype::print(font, __size__, static_cast(startY - font_size_mono * __i__ * 2), __color__, __format__); +#define PrintColorTextArg(__i__, __format__, __size__, __color__, ...) Freetype::print(font, __size__, static_cast(startY - font_size_mono * __i__ * 2), __format__, __VA_ARGS__); +#define PrintColorText(__i__, __format__, __size__, __color__) Freetype::print(font, __size__, static_cast(startY - font_size_mono * __i__ * 2), __format__); + //#define PrintColorTextArg(__i__, __format__, __size__, __color__, ...) Freetype::print(font, __size__, static_cast(startY - font_size_mono * __i__ * 2), __color__, __format__, __VA_ARGS__); + //#define PrintColorText(__i__, __format__, __size__, __color__) Freetype::print(font, __size__, static_cast(startY - font_size_mono * __i__ * 2), __color__, __format__); if (_onScreenInformation._node != -1) { //int thisId = sgct_core::ClusterManager::instance()->getThisNodeId(); @@ -415,7 +418,8 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi } // Print some useful information on the master viewport - if (OsEng.ref().isMaster() && !w->isUsingFisheyeRendering()) { + + if (OsEng.ref().isMaster() && sgct::Engine::instance()->getCurrentRenderTarget() != sgct::Engine::NonLinearBuffer) { // TODO: Adjust font_size properly when using retina screen const int font_size_mono = 10; @@ -429,7 +433,7 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi if (_showInfo) { const sgct_text::Font* font = fontMono; int x1, xSize, y1, ySize; - sgct::Engine::instance()->getActiveWindowPtr()->getCurrentViewportPixelCoords(x1, y1, xSize, ySize); + sgct::Engine::instance()->getCurrentWindowPtr()->getCurrentViewportPixelCoords(x1, y1, xSize, ySize); int startY = ySize - 2 * font_size_time; //const glm::vec2& scaling = _mainCamera->scaling(); //const glm::vec3& viewdirection = _mainCamera->viewDirection(); @@ -450,7 +454,8 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi if (timeString.size() > 11) // This should never happen, but it's an emergency hack ---abock timeString[11] = ' '; - Freetype::print(fontTime, 10, static_cast(startY - font_size_mono * line++ * 2), glm::vec4(1), "Date: %s", timeString.c_str()); +// Freetype::print(fontTime, 10, static_cast(startY - font_size_mono * line++ * 2), glm::vec4(1), "Date: %s", timeString.c_str()); + Freetype::print(fontTime, 10, static_cast(startY - font_size_mono * line++ * 2), "Date: %s", timeString.c_str()); glm::vec4 targetColor(0.00, 0.75, 1.00, 1); double dt = Time::ref().deltaTime(); @@ -609,7 +614,8 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi const std::string& message = e->message.substr(0, msg_length); nr += std::count(message.begin(), message.end(), '\n'); - Freetype::print(font, 10.f, static_cast(font_size_light * nr * 2), white*alpha, +// Freetype::print(font, 10.f, static_cast(font_size_light * nr * 2), white*alpha, + Freetype::print(font, 10.f, static_cast(font_size_light * nr * 2), "%-14s %s%s", // Format e->timeString.c_str(), // Time string e->category.substr(0, category_length).c_str(), // Category string (up to category_length) @@ -625,11 +631,16 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi if (e->level == ghoul::logging::LogManager::LogLevel::Fatal) color = blue; - Freetype::print(font, static_cast(10 + 39 * font_with_light), static_cast(font_size_light * nr * 2), color*alpha, "%s", lvl.c_str()); + Freetype::print(font, static_cast(10 + 39 * font_with_light), static_cast(font_size_light * nr * 2), "%s", lvl.c_str()); - Freetype::print(font, static_cast(10 + 53 * font_with_light), static_cast(font_size_light * nr * 2), white*alpha, "%s", message.c_str()); - ++nr; + Freetype::print(font, static_cast(10 + 53 * font_with_light), static_cast(font_size_light * nr * 2), "%s", message.c_str()); + +// Freetype::print(font, static_cast(10 + 39 * font_with_light), static_cast(font_size_light * nr * 2), color*alpha, "%s", lvl.c_str()); + + +// Freetype::print(font, static_cast(10 + 53 * font_with_light), static_cast(font_size_light * nr * 2), white*alpha, "%s", message.c_str()); + ++nr; } } } @@ -728,8 +739,8 @@ void RenderEngine::startFading(int direction, float fadeDuration) { void RenderEngine::generateGlslConfig() { ghoul_assert(_abuffer != nullptr, "ABuffer not initialized"); LDEBUG("Generating GLSLS config, expect shader recompilation"); - int xSize = sgct::Engine::instance()->getActiveWindowPtr()->getXFramebufferResolution();; - int ySize = sgct::Engine::instance()->getActiveWindowPtr()->getYFramebufferResolution();; + int xSize = sgct::Engine::instance()->getCurrentWindowPtr()->getXFramebufferResolution();; + int ySize = sgct::Engine::instance()->getCurrentWindowPtr()->getYFramebufferResolution();; // TODO: Make this file creation dynamic and better in every way // TODO: If the screen size changes it is enough if this file is regenerated to From 410e0137eb7e9c90368ac0aa9e5d8c67f188da24 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 5 Oct 2015 00:36:09 +0200 Subject: [PATCH 009/122] Updated single_fisheye configuration file to use new SGCT format Correctly set clear color for nonlinear projections --- apps/OpenSpace/main.cpp | 20 +++++++++++++++----- config/sgct/single_fisheye.xml | 16 +++++++++++----- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/apps/OpenSpace/main.cpp b/apps/OpenSpace/main.cpp index da70145529..3646512c7f 100644 --- a/apps/OpenSpace/main.cpp +++ b/apps/OpenSpace/main.cpp @@ -128,9 +128,6 @@ int main(int argc, char** argv) { _sgctEngine->setExternalControlCallback(mainExternalControlCallback); _sgctEngine->setCharCallbackFunction(mainCharCallback); - - // _sgctEngine->setFisheyeClearColor(0.f, 0.f, 0.f); - // set encode and decode functions // NOTE: starts synchronizing before init functions sgct::SharedData::instance()->setEncodeFunction(mainEncodeFun); @@ -162,8 +159,6 @@ int main(int argc, char** argv) { return EXIT_FAILURE; } - - // Main loop LDEBUG("Starting rendering loop"); _sgctEngine->render(); @@ -197,6 +192,21 @@ void mainInitFunc() { std::cin.ignore(100); exit(EXIT_FAILURE); } + + // Set the clear color for all non-linear projection viewports + size_t nWindows = _sgctEngine->getNumberOfWindows(); + for (size_t i = 0; i < nWindows; ++i) { + sgct::SGCTWindow* w = _sgctEngine->getWindowPtr(i); + size_t nViewports = nViewports = w->getNumberOfViewports(); + for (size_t j = 0; j < nViewports; ++j) { + sgct_core::Viewport* v = w->getViewport(j); + ghoul_assert(v != nullptr, "Number of reported viewports was incorrect"); + sgct_core::NonLinearProjection* p = v->getNonLinearProjectionPtr(); + if (p) + p->setClearColor(0.f, 0.f, 0.f); + } + } + } void mainPreSyncFunc() { diff --git a/config/sgct/single_fisheye.xml b/config/sgct/single_fisheye.xml index befe6cded7..3d8d5446e8 100644 --- a/config/sgct/single_fisheye.xml +++ b/config/sgct/single_fisheye.xml @@ -1,10 +1,10 @@ - - + + - + - + + + + + + + - + \ No newline at end of file From cb27e3777884be8cb679d461c745345e1e8940af Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 5 Oct 2015 14:40:21 +0200 Subject: [PATCH 010/122] Fixes to make the new GLM version compatible --- ext/ghoul | 2 +- src/interaction/interactionhandler.cpp | 2 +- src/interaction/mousecontroller.cpp | 2 +- src/properties/matrixproperty.cpp | 18 +++++++++--------- src/properties/vectorproperty.cpp | 8 ++++---- src/util/camera.cpp | 2 +- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index c1c66477bb..85b73b3249 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit c1c66477bb3577a26c6618c1da82da5346ba858b +Subproject commit 85b73b32499150f19e6db3fba37418f92e3c507e diff --git a/src/interaction/interactionhandler.cpp b/src/interaction/interactionhandler.cpp index f8f3b37c0d..51f8fe3945 100644 --- a/src/interaction/interactionhandler.cpp +++ b/src/interaction/interactionhandler.cpp @@ -499,7 +499,7 @@ void InteractionHandler::orbit(const float &dx, const float &dy, const float &dz lockControls(); - glm::vec3 cameraUp = glm::normalize((glm::inverse(_camera->viewRotationMatrix()) * glm::vec4(_camera->lookUpVector(), 0))).xyz; + glm::vec3 cameraUp = glm::normalize((glm::inverse(_camera->viewRotationMatrix()) * glm::vec4(_camera->lookUpVector(), 0))).xyz(); glm::vec3 cameraRight = glm::cross(_camera->viewDirection(), cameraUp); glm::mat4 transform; diff --git a/src/interaction/mousecontroller.cpp b/src/interaction/mousecontroller.cpp index 790bf9e283..98c93c593a 100644 --- a/src/interaction/mousecontroller.cpp +++ b/src/interaction/mousecontroller.cpp @@ -76,7 +76,7 @@ void MouseController::trackballRotate(int x, int y) { float height = static_cast(sgct::Engine::instance()->getCurrentYResolution()); glm::vec2 mousePos = glm::vec2((float)x / width, (float)y / height); - mousePos = glm::clamp(mousePos, -0.5, 1.5); // Ugly fix #1: Camera position becomes NaN on mouse values outside [-0.5, 1.5] + mousePos = glm::clamp(mousePos, -0.5f, 1.5f); // Ugly fix #1: Camera position becomes NaN on mouse values outside [-0.5, 1.5] //mousePos[1] = 0.5; // Ugly fix #2: Tempoarily only allow rotation around y glm::vec3 curTrackballPos = mapToTrackball(mousePos); diff --git a/src/properties/matrixproperty.cpp b/src/properties/matrixproperty.cpp index dc8a86b44a..a26c868808 100644 --- a/src/properties/matrixproperty.cpp +++ b/src/properties/matrixproperty.cpp @@ -39,8 +39,8 @@ namespace properties { [](lua_State* state, bool& success) -> __TYPE__ { \ __TYPE__ result; \ int number = 1; \ - for (__TYPE__::size_type i = 0; i < __TYPE__::row_size(); ++i) { \ - for (__TYPE__::size_type j = 0; j < __TYPE__::col_size(); ++j) { \ + for (glm::length_t i = 0; i < __TYPE__::rows; ++i) { \ + for (glm::length_t j = 0; j < __TYPE__::cols; ++j) { \ lua_getfield(state, -1, std::to_string(number).c_str()); \ if (lua_isnumber(state, -1) != 1) { \ success = false; \ @@ -61,8 +61,8 @@ namespace properties { [](lua_State* state, __TYPE__ value) -> bool { \ lua_newtable(state); \ int number = 1; \ - for (__TYPE__::size_type i = 0; i < __TYPE__::row_size(); ++i) { \ - for (__TYPE__::size_type j = 0; j < __TYPE__::col_size(); ++j) { \ + for (glm::length_t i = 0; i < __TYPE__::rows; ++i) { \ + for (glm::length_t j = 0; j < __TYPE__::cols; ++j) { \ lua_pushnumber(state, static_cast(value[i][j])); \ lua_setfield(state, -2, std::to_string(number).c_str()); \ ++number; \ @@ -75,13 +75,13 @@ namespace properties { [](std::string value, bool& success) -> __TYPE__ { \ __TYPE__ result; \ std::vector tokens = ghoul::tokenizeString(value, ','); \ - if (tokens.size() != (__TYPE__::row_size() * __TYPE__::col_size())) { \ + if (tokens.size() != (__TYPE__::rows * __TYPE__::cols)) { \ success = false; \ return result; \ } \ int number = 0; \ - for (__TYPE__::size_type i = 0; i < __TYPE__::row_size(); ++i) { \ - for (__TYPE__::size_type j = 0; j < __TYPE__::col_size(); ++j) { \ + for (glm::length_t i = 0; i < __TYPE__::rows; ++i) { \ + for (glm::length_t j = 0; j < __TYPE__::cols; ++j) { \ std::stringstream s(tokens[number]); \ __TYPE__::value_type v; \ s >> v; \ @@ -102,8 +102,8 @@ namespace properties { #define DEFAULT_TO_STRING_LAMBDA(__TYPE__) \ [](std::string& outValue, __TYPE__ inValue) -> bool { \ outValue = ""; \ - for (__TYPE__::size_type i = 0; i < __TYPE__::row_size(); ++i) { \ - for (__TYPE__::size_type j = 0; j < __TYPE__::col_size(); ++j) { \ + for (glm::length_t i = 0; i < __TYPE__::rows; ++i) { \ + for (glm::length_t j = 0; j < __TYPE__::cols; ++j) { \ outValue += std::to_string(inValue[i][j]) + ","; \ } \ outValue.pop_back(); \ diff --git a/src/properties/vectorproperty.cpp b/src/properties/vectorproperty.cpp index 8d3264c016..89b893b5c1 100644 --- a/src/properties/vectorproperty.cpp +++ b/src/properties/vectorproperty.cpp @@ -39,7 +39,7 @@ namespace properties { [](lua_State * state, bool& success) -> __TYPE__ { \ __TYPE__ result; \ lua_pushnil(state); \ - for (__TYPE__::size_type i = 0; i < result.length(); ++i) { \ + for (glm::length_t i = 0; i < __TYPE__::components; ++i) { \ int success = lua_next(state, -2); \ if (success != 1) { \ success = false; \ @@ -61,7 +61,7 @@ namespace properties { [](lua_State * state, __TYPE__ value) -> bool { \ lua_newtable(state); \ int number = 1; \ - for (__TYPE__::size_type i = 0; i < value.length(); ++i) { \ + for (glm::length_t i = 0; i < __TYPE__::components; ++i) { \ lua_pushnumber(state, static_cast(value[i])); \ lua_setfield(state, -2, std::to_string(number).c_str()); \ ++number; \ @@ -77,7 +77,7 @@ namespace properties { success = false; \ return result; \ } \ - for (__TYPE__::size_type i = 0; i < result.length(); ++i) { \ + for (glm::length_t i = 0; i < __TYPE__::components; ++i) { \ std::stringstream s(tokens[i]); \ __TYPE__::value_type v; \ s >> v; \ @@ -95,7 +95,7 @@ namespace properties { #define DEFAULT_TO_STRING_LAMBDA(__TYPE__) \ [](std::string& outValue, __TYPE__ inValue) -> bool { \ outValue = "{"; \ - for (__TYPE__::size_type i = 0; i < inValue.length(); ++i) \ + for (glm::length_t i = 0; i < __TYPE__::components; ++i) \ outValue += std::to_string(inValue[i]) + ","; \ outValue.pop_back(); \ outValue += "}"; \ diff --git a/src/util/camera.cpp b/src/util/camera.cpp index 3e4ef52b1d..b4d108076d 100644 --- a/src/util/camera.cpp +++ b/src/util/camera.cpp @@ -147,7 +147,7 @@ void Camera::compileViewRotationMatrix() // the camera matrix needs to be rotated inverse to the world // _viewDirection = glm::rotate(glm::inverse(_viewRotation), _cameraDirection); //_viewDirection = (glm::inverse(_localViewRotationMatrix) * glm::vec4(_cameraDirection, 0.f)).xyz; - _viewDirection = (glm::inverse(_localViewRotationMatrix) * glm::vec4(_cameraDirection, 0.f)).xyz; + _viewDirection = (glm::inverse(_localViewRotationMatrix) * glm::vec4(_cameraDirection, 0.f)).xyz(); _viewDirection = glm::normalize(_viewDirection); } From d4da374c231fd879d8313330e92b3636af2b4b22 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Thu, 8 Oct 2015 22:59:36 +0200 Subject: [PATCH 011/122] Reenable colored font rendering --- apps/OpenSpace/main.cpp | 2 +- src/abuffer/abuffervisualizer.cpp | 48 +++++++++++++++---------------- src/interaction/luaconsole.cpp | 9 ++---- src/rendering/renderengine.cpp | 20 +++++-------- 4 files changed, 35 insertions(+), 44 deletions(-) diff --git a/apps/OpenSpace/main.cpp b/apps/OpenSpace/main.cpp index 3646512c7f..f2463d53c7 100644 --- a/apps/OpenSpace/main.cpp +++ b/apps/OpenSpace/main.cpp @@ -203,7 +203,7 @@ void mainInitFunc() { ghoul_assert(v != nullptr, "Number of reported viewports was incorrect"); sgct_core::NonLinearProjection* p = v->getNonLinearProjectionPtr(); if (p) - p->setClearColor(0.f, 0.f, 0.f); + p->setClearColor(glm::vec4(0.f, 0.f, 0.f, 1.f)); } } diff --git a/src/abuffer/abuffervisualizer.cpp b/src/abuffer/abuffervisualizer.cpp index 95f01a7683..7b1aaf528b 100644 --- a/src/abuffer/abuffervisualizer.cpp +++ b/src/abuffer/abuffervisualizer.cpp @@ -145,30 +145,30 @@ void ABufferVisualizer::render() { const glm::mat4 scale = glm::scale(glm::mat4(1.0), glm::vec3(0.04, 0.04, 0.04)); glm::mat4 translate, mvp; -// translate = glm::translate(glm::mat4(1.0), glm::vec3(0, 0, 0)); -// mvp = sgct::Engine::instance()->getCurrentModelViewProjectionMatrix()*modelMatrix*translate*rotationText*scale; -// Freetype::print3d(fontLight, mvp, "(0,0,0)"); -// translate = glm::translate(glm::mat4(1.0), glm::vec3(0, 0, 1)); -// mvp = sgct::Engine::instance()->getCurrentModelViewProjectionMatrix()*modelMatrix*translate*rotationText*scale; -// Freetype::print3d(fontLight, mvp, "(0,0,1)"); -// translate = glm::translate(glm::mat4(1.0), glm::vec3(0, 1, 0)); -// mvp = sgct::Engine::instance()->getCurrentModelViewProjectionMatrix()*modelMatrix*translate*rotationText*scale; -// Freetype::print3d(fontLight, mvp, "(0,1,0)"); -// translate = glm::translate(glm::mat4(1.0), glm::vec3(1, 0, 0)); -// mvp = sgct::Engine::instance()->getCurrentModelViewProjectionMatrix()*modelMatrix*translate*rotationText*scale; -// Freetype::print3d(fontLight, mvp, "(1,0,0)"); -// translate = glm::translate(glm::mat4(1.0), glm::vec3(0, 1, 1)); -// mvp = sgct::Engine::instance()->getCurrentModelViewProjectionMatrix()*modelMatrix*translate*rotationText*scale; -// Freetype::print3d(fontLight, mvp, "(0,1,1)"); -// translate = glm::translate(glm::mat4(1.0), glm::vec3(1, 0, 1)); -// mvp = sgct::Engine::instance()->getCurrentModelViewProjectionMatrix()*modelMatrix*translate*rotationText*scale; -// Freetype::print3d(fontLight, mvp, "(1,0,1)"); -// translate = glm::translate(glm::mat4(1.0), glm::vec3(1, 1, 0)); -// mvp = sgct::Engine::instance()->getCurrentModelViewProjectionMatrix()*modelMatrix*translate*rotationText*scale; -// Freetype::print3d(fontLight, mvp, "(1,1,0)"); -// translate = glm::translate(glm::mat4(1.0), glm::vec3(1, 1, 1)); -// mvp = sgct::Engine::instance()->getCurrentModelViewProjectionMatrix()*modelMatrix*translate*rotationText*scale; -// Freetype::print3d(fontLight, mvp, "(1,1,1)"); + translate = glm::translate(glm::mat4(1.0), glm::vec3(0, 0, 0)); + mvp = sgct::Engine::instance()->getCurrentModelViewProjectionMatrix()*modelMatrix*translate*rotationText*scale; + Freetype::print3d(fontLight, mvp, "(0,0,0)"); + translate = glm::translate(glm::mat4(1.0), glm::vec3(0, 0, 1)); + mvp = sgct::Engine::instance()->getCurrentModelViewProjectionMatrix()*modelMatrix*translate*rotationText*scale; + Freetype::print3d(fontLight, mvp, "(0,0,1)"); + translate = glm::translate(glm::mat4(1.0), glm::vec3(0, 1, 0)); + mvp = sgct::Engine::instance()->getCurrentModelViewProjectionMatrix()*modelMatrix*translate*rotationText*scale; + Freetype::print3d(fontLight, mvp, "(0,1,0)"); + translate = glm::translate(glm::mat4(1.0), glm::vec3(1, 0, 0)); + mvp = sgct::Engine::instance()->getCurrentModelViewProjectionMatrix()*modelMatrix*translate*rotationText*scale; + Freetype::print3d(fontLight, mvp, "(1,0,0)"); + translate = glm::translate(glm::mat4(1.0), glm::vec3(0, 1, 1)); + mvp = sgct::Engine::instance()->getCurrentModelViewProjectionMatrix()*modelMatrix*translate*rotationText*scale; + Freetype::print3d(fontLight, mvp, "(0,1,1)"); + translate = glm::translate(glm::mat4(1.0), glm::vec3(1, 0, 1)); + mvp = sgct::Engine::instance()->getCurrentModelViewProjectionMatrix()*modelMatrix*translate*rotationText*scale; + Freetype::print3d(fontLight, mvp, "(1,0,1)"); + translate = glm::translate(glm::mat4(1.0), glm::vec3(1, 1, 0)); + mvp = sgct::Engine::instance()->getCurrentModelViewProjectionMatrix()*modelMatrix*translate*rotationText*scale; + Freetype::print3d(fontLight, mvp, "(1,1,0)"); + translate = glm::translate(glm::mat4(1.0), glm::vec3(1, 1, 1)); + mvp = sgct::Engine::instance()->getCurrentModelViewProjectionMatrix()*modelMatrix*translate*rotationText*scale; + Freetype::print3d(fontLight, mvp, "(1,1,1)"); } void ABufferVisualizer::initializeMarkers() { diff --git a/src/interaction/luaconsole.cpp b/src/interaction/luaconsole.cpp index cc2c283477..211c02dfbb 100644 --- a/src/interaction/luaconsole.cpp +++ b/src/interaction/luaconsole.cpp @@ -294,10 +294,8 @@ void LuaConsole::render() { const glm::vec4 green(0, 1, 0, 1); const glm::vec4 white(1, 1, 1, 1); const sgct_text::Font* font = sgct_text::FontManager::instance()->getFont(constants::fonts::keyMono, static_cast(font_size)); -// sgct_text::print(font, 15.0f, startY, red, "$"); -// sgct_text::print(font, 15.0f + font_size, startY, white, "%s", _commands.at(_activeCommand).c_str()); - sgct_text::print(font, 15.0f, startY, "$"); - sgct_text::print(font, 15.0f + font_size, startY, "%s", _commands.at(_activeCommand).c_str()); + sgct_text::print(font, 15.0f, startY, red, "$"); + sgct_text::print(font, 15.0f + font_size, startY, white, "%s", _commands.at(_activeCommand).c_str()); size_t n = std::count(_commands.at(_activeCommand).begin(), _commands.at(_activeCommand).begin() + _inputPosition, '\n'); size_t p = _commands.at(_activeCommand).find_last_of('\n', _inputPosition); @@ -320,8 +318,7 @@ void LuaConsole::render() { std::stringstream ss; ss << "%" << linepos + 1 << "s"; -// sgct_text::print(font, 15.0f + font_size*0.5f, startY - (font_size)*(n + 1)*3.0f / 2.0f, green, ss.str().c_str(), "^"); - sgct_text::print(font, 15.0f + font_size*0.5f, startY - (font_size)*(n + 1)*3.0f / 2.0f, ss.str().c_str(), "^"); + sgct_text::print(font, 15.0f + font_size*0.5f, startY - (font_size)*(n + 1)*3.0f / 2.0f, green, ss.str().c_str(), "^"); } unsigned int LuaConsole::commandInputButton() { diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 3ecd0094ea..eddd725b90 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -400,10 +400,10 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi #if 1 #define PrintText(__i__, __format__, ...) Freetype::print(font, 10.f, static_cast(startY - font_size_mono * __i__ * 2), __format__, __VA_ARGS__); -#define PrintColorTextArg(__i__, __format__, __size__, __color__, ...) Freetype::print(font, __size__, static_cast(startY - font_size_mono * __i__ * 2), __format__, __VA_ARGS__); -#define PrintColorText(__i__, __format__, __size__, __color__) Freetype::print(font, __size__, static_cast(startY - font_size_mono * __i__ * 2), __format__); - //#define PrintColorTextArg(__i__, __format__, __size__, __color__, ...) Freetype::print(font, __size__, static_cast(startY - font_size_mono * __i__ * 2), __color__, __format__, __VA_ARGS__); - //#define PrintColorText(__i__, __format__, __size__, __color__) Freetype::print(font, __size__, static_cast(startY - font_size_mono * __i__ * 2), __color__, __format__); + //#define PrintColorTextArg(__i__, __format__, __size__, __color__, ...) Freetype::print(font, __size__, static_cast(startY - font_size_mono * __i__ * 2), __format__, __VA_ARGS__); + //#define PrintColorText(__i__, __format__, __size__, __color__) Freetype::print(font, __size__, static_cast(startY - font_size_mono * __i__ * 2), __format__); + #define PrintColorTextArg(__i__, __format__, __size__, __color__, ...) Freetype::print(font, __size__, static_cast(startY - font_size_mono * __i__ * 2), __color__, __format__, __VA_ARGS__); + #define PrintColorText(__i__, __format__, __size__, __color__) Freetype::print(font, __size__, static_cast(startY - font_size_mono * __i__ * 2), __color__, __format__); if (_onScreenInformation._node != -1) { //int thisId = sgct_core::ClusterManager::instance()->getThisNodeId(); @@ -614,8 +614,7 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi const std::string& message = e->message.substr(0, msg_length); nr += std::count(message.begin(), message.end(), '\n'); -// Freetype::print(font, 10.f, static_cast(font_size_light * nr * 2), white*alpha, - Freetype::print(font, 10.f, static_cast(font_size_light * nr * 2), + Freetype::print(font, 10.f, static_cast(font_size_light * nr * 2), white*alpha, "%-14s %s%s", // Format e->timeString.c_str(), // Time string e->category.substr(0, category_length).c_str(), // Category string (up to category_length) @@ -631,15 +630,10 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi if (e->level == ghoul::logging::LogManager::LogLevel::Fatal) color = blue; - Freetype::print(font, static_cast(10 + 39 * font_with_light), static_cast(font_size_light * nr * 2), "%s", lvl.c_str()); - - - Freetype::print(font, static_cast(10 + 53 * font_with_light), static_cast(font_size_light * nr * 2), "%s", message.c_str()); - -// Freetype::print(font, static_cast(10 + 39 * font_with_light), static_cast(font_size_light * nr * 2), color*alpha, "%s", lvl.c_str()); + Freetype::print(font, static_cast(10 + 39 * font_with_light), static_cast(font_size_light * nr * 2), color*alpha, "%s", lvl.c_str()); -// Freetype::print(font, static_cast(10 + 53 * font_with_light), static_cast(font_size_light * nr * 2), white*alpha, "%s", message.c_str()); + Freetype::print(font, static_cast(10 + 53 * font_with_light), static_cast(font_size_light * nr * 2), white*alpha, "%s", message.c_str()); ++nr; } } From 1ca4b9c285550a943fb06474e1caf9f8c7426270 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 13 Oct 2015 00:15:44 +0200 Subject: [PATCH 012/122] Enable NOMINMAX compiler defintions in Windows on default --- modules/base/rendering/renderabletrail.cpp | 6 ++++-- support/cmake/module_definition.cmake | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/modules/base/rendering/renderabletrail.cpp b/modules/base/rendering/renderabletrail.cpp index 399e678afb..e9bdfa2e25 100644 --- a/modules/base/rendering/renderabletrail.cpp +++ b/modules/base/rendering/renderabletrail.cpp @@ -33,6 +33,9 @@ #include #include +#include +#include + /* TODO for this class: * In order to add geometry shader (for pretty-draw), @@ -68,7 +71,7 @@ RenderableTrail::RenderableTrail(const ghoul::Dictionary& dictionary) , _vaoID(0) , _vBufferID(0) , _needsSweep(true) - , _oldTime(std::numeric_limits::max()) + , _oldTime(std::numeric_limits::max()) { _successfullDictionaryFetch &= dictionary.getValue(keyBody, _target); _successfullDictionaryFetch &= dictionary.getValue(keyObserver, _observer); @@ -76,7 +79,6 @@ RenderableTrail::RenderableTrail(const ghoul::Dictionary& dictionary) _successfullDictionaryFetch &= dictionary.getValue(keyTropicalOrbitPeriod, _tropic); _successfullDictionaryFetch &= dictionary.getValue(keyEarthOrbitRatio, _ratio); _successfullDictionaryFetch &= dictionary.getValue(keyDayLength, _day); - // values in modfiles set from here // http://nssdc.gsfc.nasa.gov/planetary/factsheet/marsfact.html diff --git a/support/cmake/module_definition.cmake b/support/cmake/module_definition.cmake index 330eba1992..6b3ae6281a 100644 --- a/support/cmake/module_definition.cmake +++ b/support/cmake/module_definition.cmake @@ -88,6 +88,7 @@ function (set_common_compile_settings target_name) "/wd4505" # Unreferenced function was removed "/W4" # Warning level ) + target_compile_definitions(${library_name} PUBLIC "NOMINMAX") if (OPENSPACE_WARNINGS_AS_ERRORS) target_compile_options(${library_name} PUBLIC "/Wx") endif () From f8f48acb98d86587293f042a23fb62a644d06937 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 20 Oct 2015 23:30:40 +0200 Subject: [PATCH 013/122] Implementation of the windowhandler interface --- apps/OpenSpace/main.cpp | 2 + include/openspace/engine/openspaceengine.h | 7 +- include/openspace/engine/sgctwindow.h | 39 + include/openspace/engine/window.h | 37 + .../shaders/projectionPass_fs.glsl | 1 + .../shaders/projectionPass_vs.glsl | 1 + src/CMakeLists.txt | 4 + src/engine/openspaceengine.cpp | 59 +- src/engine/openspaceengine.cpp.orig | 814 ------------------ src/engine/sgctwindow.cpp | 0 src/engine/window.cpp | 0 src/rendering/renderengine.cpp | 70 +- tests/main.cpp | 3 +- 13 files changed, 171 insertions(+), 866 deletions(-) create mode 100644 include/openspace/engine/sgctwindow.h create mode 100644 include/openspace/engine/window.h delete mode 100644 src/engine/openspaceengine.cpp.orig create mode 100644 src/engine/sgctwindow.cpp create mode 100644 src/engine/window.cpp diff --git a/apps/OpenSpace/main.cpp b/apps/OpenSpace/main.cpp index f2463d53c7..626f379290 100644 --- a/apps/OpenSpace/main.cpp +++ b/apps/OpenSpace/main.cpp @@ -23,6 +23,7 @@ ****************************************************************************************/ #include +#include #include #include #include @@ -86,6 +87,7 @@ int main(int argc, char** argv) { std::vector sgctArguments; const bool success = openspace::OpenSpaceEngine::create( argc, argv, + new openspace::SGCTWindow, sgctArguments ); if (!success) diff --git a/include/openspace/engine/openspaceengine.h b/include/openspace/engine/openspaceengine.h index 1da8cbc773..db100da693 100644 --- a/include/openspace/engine/openspaceengine.h +++ b/include/openspace/engine/openspaceengine.h @@ -46,6 +46,7 @@ class GUI; class RenderEngine; class SyncBuffer; class ModuleEngine; +class Window; namespace interaction { class InteractionHandler; @@ -67,7 +68,7 @@ namespace properties { class OpenSpaceEngine { public: - static bool create(int argc, char** argv, std::vector& sgctArguments); + static bool create(int argc, char** argv, Window* windowHandler, std::vector& sgctArguments); static void destroy(); static OpenSpaceEngine& ref(); @@ -89,6 +90,7 @@ public: ModuleEngine* moduleEngine(); network::ParallelConnection* parallelConnection(); properties::PropertyOwner* globalPropertyOwner(); + Window* windowWrapper(); gui::GUI* gui(); @@ -113,7 +115,7 @@ public: void runSettingsScripts(); private: - OpenSpaceEngine(std::string programName); + OpenSpaceEngine(std::string programName, Window* windowHandler); ~OpenSpaceEngine(); OpenSpaceEngine(const OpenSpaceEngine& rhs) = delete; @@ -137,6 +139,7 @@ private: ModuleEngine* _moduleEngine; gui::GUI* _gui; network::ParallelConnection* _parallelConnection; + Window* _windowWrapper; properties::PropertyOwner* _globalPropertyNamespace; diff --git a/include/openspace/engine/sgctwindow.h b/include/openspace/engine/sgctwindow.h new file mode 100644 index 0000000000..6d65802d21 --- /dev/null +++ b/include/openspace/engine/sgctwindow.h @@ -0,0 +1,39 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2015 * + * * + * 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 __SGCTWINDOW_H__ +#define __SGCTWINDOW_H__ + +#include + +namespace openspace { + +class SGCTWindow : public Window { +public: + +}; + +} // namespace openspace + +#endif // __SGCTWINDOW_H__ diff --git a/include/openspace/engine/window.h b/include/openspace/engine/window.h new file mode 100644 index 0000000000..323b9b4511 --- /dev/null +++ b/include/openspace/engine/window.h @@ -0,0 +1,37 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2015 * + * * + * 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 __WINDOW_H__ +#define __WINDOW_H__ + +namespace openspace { + +class Window { +public: + +}; + +} // namespace openspace + +#endif // _WINDOW_H__ diff --git a/modules/newhorizons/shaders/projectionPass_fs.glsl b/modules/newhorizons/shaders/projectionPass_fs.glsl index bd2d19f935..8232fb9e5d 100644 --- a/modules/newhorizons/shaders/projectionPass_fs.glsl +++ b/modules/newhorizons/shaders/projectionPass_fs.glsl @@ -23,6 +23,7 @@ ****************************************************************************************/ #version __CONTEXT__ + uniform sampler2D projectTexture; uniform sampler2D currentTexture; diff --git a/modules/newhorizons/shaders/projectionPass_vs.glsl b/modules/newhorizons/shaders/projectionPass_vs.glsl index 77c197a10c..166c67d394 100644 --- a/modules/newhorizons/shaders/projectionPass_vs.glsl +++ b/modules/newhorizons/shaders/projectionPass_vs.glsl @@ -23,6 +23,7 @@ ****************************************************************************************/ #version __CONTEXT__ + uniform mat4 ProjectorMatrix; uniform mat4 ModelTransform; uniform vec2 _scaling; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1f09313c1f..764e069b86 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -33,7 +33,9 @@ set(OPENSPACE_SOURCE ${OPENSPACE_BASE_DIR}/src/engine/downloadmanager.cpp ${OPENSPACE_BASE_DIR}/src/engine/logfactory.cpp ${OPENSPACE_BASE_DIR}/src/engine/moduleengine.cpp + ${OPENSPACE_BASE_DIR}/src/engine/sgctwindow.cpp ${OPENSPACE_BASE_DIR}/src/engine/openspaceengine.cpp + ${OPENSPACE_BASE_DIR}/src/engine/window.cpp ${OPENSPACE_BASE_DIR}/src/interaction/controller.cpp ${OPENSPACE_BASE_DIR}/src/interaction/deviceidentifier.cpp ${OPENSPACE_BASE_DIR}/src/interaction/interactionhandler.cpp @@ -97,7 +99,9 @@ set(OPENSPACE_HEADER ${OPENSPACE_BASE_DIR}/include/openspace/engine/downloadmanager.h ${OPENSPACE_BASE_DIR}/include/openspace/engine/logfactory.h ${OPENSPACE_BASE_DIR}/include/openspace/engine/moduleengine.h + ${OPENSPACE_BASE_DIR}/include/openspace/engine/sgctwindow.h ${OPENSPACE_BASE_DIR}/include/openspace/engine/openspaceengine.h + ${OPENSPACE_BASE_DIR}/include/openspace/engine/window.h ${OPENSPACE_BASE_DIR}/include/openspace/interaction/controller.h ${OPENSPACE_BASE_DIR}/include/openspace/interaction/deviceidentifier.h ${OPENSPACE_BASE_DIR}/include/openspace/interaction/interactionhandler.h diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 62cf9539d5..859af4b274 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -101,7 +101,7 @@ namespace openspace { OpenSpaceEngine* OpenSpaceEngine::_engine = nullptr; -OpenSpaceEngine::OpenSpaceEngine(std::string programName) +OpenSpaceEngine::OpenSpaceEngine(std::string programName, Window* windowHandler) : _configurationManager(new ConfigurationManager) , _interactionHandler(new interaction::InteractionHandler) , _renderEngine(new RenderEngine) @@ -112,6 +112,7 @@ OpenSpaceEngine::OpenSpaceEngine(std::string programName) , _moduleEngine(new ModuleEngine) , _gui(new gui::GUI) , _parallelConnection(new network::ParallelConnection) + , _windowWrapper(windowHandler) , _globalPropertyNamespace(new properties::PropertyOwner) , _isMaster(false) , _runTime(0.0) @@ -128,19 +129,43 @@ OpenSpaceEngine::OpenSpaceEngine(std::string programName) OpenSpaceEngine::~OpenSpaceEngine() { _gui->deinitializeGL(); - delete _parallelConnection; - delete _configurationManager; - delete _interactionHandler; - delete _renderEngine; - delete _scriptEngine; - delete _networkEngine; - delete _commandlineParser; - delete _console; - delete _moduleEngine; - delete _gui; + delete _globalPropertyNamespace; + _globalPropertyNamespace = nullptr; - if(_syncBuffer) - delete _syncBuffer; + delete _windowWrapper; + _windowWrapper = nullptr; + + delete _parallelConnection; + _parallelConnection = nullptr; + + delete _configurationManager; + _configurationManager = nullptr; + + delete _interactionHandler; + _interactionHandler = nullptr; + + delete _renderEngine; + _renderEngine = nullptr; + + delete _scriptEngine; + _scriptEngine = nullptr; + + delete _networkEngine; + _networkEngine = nullptr; + + delete _commandlineParser; + _commandlineParser = nullptr; + + delete _console; + _console = nullptr; + + delete _moduleEngine; + _moduleEngine = nullptr; + + delete _gui; + _gui = nullptr; + + delete _syncBuffer; _syncBuffer = nullptr; } @@ -151,6 +176,7 @@ OpenSpaceEngine& OpenSpaceEngine::ref() { bool OpenSpaceEngine::create( int argc, char** argv, + Window* windowHandler, std::vector& sgctArguments) { ghoul::initialize(); @@ -182,7 +208,7 @@ bool OpenSpaceEngine::create( // Create other objects LDEBUG("Creating OpenSpaceEngine"); - _engine = new OpenSpaceEngine(std::string(argv[0])); + _engine = new OpenSpaceEngine(std::string(argv[0]), windowHandler); // Query modules for commandline arguments const bool gatherSuccess = _engine->gatherCommandlineArguments(); @@ -830,4 +856,9 @@ properties::PropertyOwner* OpenSpaceEngine::globalPropertyOwner() { return _globalPropertyNamespace; } +Window* OpenSpaceEngine::windowWrapper() { + ghoul_assert(_windowWrapper, "Window Wrapper"); + return _windowWrapper; +} + } // namespace openspace diff --git a/src/engine/openspaceengine.cpp.orig b/src/engine/openspaceengine.cpp.orig deleted file mode 100644 index e2f7ebd71a..0000000000 --- a/src/engine/openspaceengine.cpp.orig +++ /dev/null @@ -1,814 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2015 * - * * - * 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 - -#define SGCT_WINDOWS_INCLUDE -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -<<<<<<< HEAD -#include -======= -#include ->>>>>>> develop - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// std -#include -#include - -#ifdef OPENSPACE_MODULE_ONSCREENGUI_ENABLED -#include -#endif - -#ifdef _MSC_VER -#ifdef OPENSPACE_ENABLE_VLD -#include -#endif -#endif - -using namespace openspace::scripting; -using namespace ghoul::filesystem; -using namespace ghoul::logging; -using namespace ghoul::cmdparser; - -namespace { - const std::string _loggerCat = "OpenSpaceEngine"; - const std::string _configurationFile = "openspace.cfg"; - const std::string _sgctDefaultConfigFile = "${SGCT}/single.xml"; - const std::string _defaultCacheLocation = "${BASE_PATH}/cache"; - - const std::string _sgctConfigArgumentCommand = "-config"; - - const int CacheVersion = 1; - const int DownloadVersion = 1; - - struct { - std::string configurationName; - std::string sgctConfigurationName; - } commandlineArgumentPlaceholders; -} - -namespace openspace { - -OpenSpaceEngine* OpenSpaceEngine::_engine = nullptr; - -OpenSpaceEngine::OpenSpaceEngine(std::string programName) - : _configurationManager(new ConfigurationManager) - , _interactionHandler(new interaction::InteractionHandler) - , _renderEngine(new RenderEngine) - , _scriptEngine(new scripting::ScriptEngine) - , _networkEngine(new NetworkEngine) - , _commandlineParser(new ghoul::cmdparser::CommandlineParser(programName, true)) - , _console(new LuaConsole) - , _moduleEngine(new ModuleEngine) - , _gui(new gui::GUI) - , _isMaster(false) - , _runTime(0.0) - , _syncBuffer(nullptr) - , _parallelConnection(new network::ParallelConnection) -{ - FactoryManager::initialize(); - SpiceManager::initialize(); - Time::initialize(); - ghoul::systemcapabilities::SystemCapabilities::initialize(); -} - -OpenSpaceEngine::~OpenSpaceEngine() { - _gui->deinitializeGL(); - - delete _parallelConnection; - delete _configurationManager; - delete _interactionHandler; - delete _renderEngine; - delete _scriptEngine; - delete _networkEngine; - delete _commandlineParser; - delete _console; - delete _moduleEngine; - delete _gui; - - if(_syncBuffer) - delete _syncBuffer; - _syncBuffer = nullptr; -} - -OpenSpaceEngine& OpenSpaceEngine::ref() { - ghoul_assert(_engine, "OpenSpaceEngine not created"); - return *_engine; -} - -bool OpenSpaceEngine::create( - int argc, char** argv, - std::vector& sgctArguments) -{ - ghoul::initialize(); - - ghoul_assert(!_engine, "OpenSpaceEngine was already created"); - - // Initialize the LogManager and add the console log as this will be used every time - // and we need a fall back if something goes wrong between here and when we add the - // logs from the configuration file. If the user requested as specific loglevel in the - // configuration file, we will deinitialize this LogManager and reinitialize it later - // with the correct LogLevel - LogManager::initialize(LogManager::LogLevel::Debug, true); - LogMgr.addLog(new ConsoleLog); - - LDEBUG("Initialize FileSystem"); - -#ifdef __APPLE__ - ghoul::filesystem::File app(argv[0]); - std::string dirName = app.directoryName(); - LINFO("Setting starting directory to '" << dirName << "'"); - FileSys.setCurrentDirectory(dirName); -#endif - - // Sanity check of values - if (argc < 1 || argv == nullptr) { - LFATAL("No arguments were passed to this function"); - return false; - } - - // Create other objects - LDEBUG("Creating OpenSpaceEngine"); - _engine = new OpenSpaceEngine(std::string(argv[0])); - - // Query modules for commandline arguments - const bool gatherSuccess = _engine->gatherCommandlineArguments(); - if (!gatherSuccess) - return false; - - // Parse commandline arguments - _engine->_commandlineParser->setCommandLine(argc, argv, &sgctArguments); - const bool executeSuccess = _engine->_commandlineParser->execute(); - if (!executeSuccess) - return false; - - // Find configuration - std::string configurationFilePath = commandlineArgumentPlaceholders.configurationName; - if (configurationFilePath.empty()) { - LDEBUG("Finding configuration"); - const bool findConfigurationSuccess = - OpenSpaceEngine::findConfiguration(configurationFilePath); - if (!findConfigurationSuccess) { - LFATAL("Could not find OpenSpace configuration file!"); - return false; - } - } - configurationFilePath = absPath(configurationFilePath); - LINFO("Configuration Path: '" << configurationFilePath << "'"); - - // Loading configuration from disk - LDEBUG("Loading configuration from disk"); - const bool configLoadSuccess = _engine->configurationManager()->loadFromFile( - configurationFilePath); - if (!configLoadSuccess) { - LFATAL("Loading of configuration file '" << configurationFilePath << "' failed"); - return false; - } - - // Initialize the requested logs from the configuration file - _engine->configureLogging(); - - LINFOC("OpenSpace Version", - OPENSPACE_VERSION_MAJOR << "." << - OPENSPACE_VERSION_MINOR << "." << - OPENSPACE_VERSION_PATCH << " (" << OPENSPACE_VERSION_STRING << ")"); - - // Create directories that doesn't exist - auto tokens = FileSys.tokens(); - for (const std::string& token : tokens) { - if (!FileSys.directoryExists(token)) { - std::string p = absPath(token); - LDEBUG("Directory '" << p << "' does not exist, creating."); - if (!FileSys.createDirectory(p, true)) - LERROR("Directory '" << p << "' could not be created"); - } - } - - // Register modules - _engine->_moduleEngine->create(); - - // Create the cachemanager - FileSys.createCacheManager(absPath("${" + ConfigurationManager::KeyCache + "}"), CacheVersion); - _engine->_console->initialize(); - - // Register the provided shader directories - ghoul::opengl::ShaderObject::addIncludePath("${SHADERS}"); - - _engine->_syncBuffer = new SyncBuffer(1024); - - // Determining SGCT configuration file - LDEBUG("Determining SGCT configuration file"); - std::string sgctConfigurationPath = _sgctDefaultConfigFile; - _engine->configurationManager()->getValue( - ConfigurationManager::KeyConfigSgct, sgctConfigurationPath); - - if (!commandlineArgumentPlaceholders.sgctConfigurationName.empty()) { - LDEBUG("Overwriting SGCT configuration file with commandline argument: " << - commandlineArgumentPlaceholders.sgctConfigurationName); - sgctConfigurationPath = commandlineArgumentPlaceholders.sgctConfigurationName; - } - - // Prepend the outgoing sgctArguments with the program name - // as well as the configuration file that sgct is supposed to use - sgctArguments.insert(sgctArguments.begin(), argv[0]); - sgctArguments.insert(sgctArguments.begin() + 1, _sgctConfigArgumentCommand); - sgctArguments.insert(sgctArguments.begin() + 2, absPath(sgctConfigurationPath)); - - return true; -} - -void OpenSpaceEngine::destroy() { - _engine->_moduleEngine->deinitialize(); - _engine->_moduleEngine->destroy(); - _engine->_console->deinitialize(); - - _engine->_scriptEngine->deinitialize(); - delete _engine; - ghoul::systemcapabilities::SystemCapabilities::deinitialize(); - FactoryManager::deinitialize(); - Time::deinitialize(); - SpiceManager::deinitialize(); - - FileSystem::deinitialize(); - LogManager::deinitialize(); - - ghoul::deinitialize(); -} - -bool OpenSpaceEngine::initialize() { - // clear the screen so the user don't have to see old buffer contents from the - // graphics card - clearAllWindows(); - - // Detect and log OpenCL and OpenGL versions and available devices - SysCap.addComponent(new ghoul::systemcapabilities::GeneralCapabilitiesComponent); - SysCap.addComponent(new ghoul::systemcapabilities::OpenGLCapabilitiesComponent); - SysCap.detectCapabilities(); - - using Verbosity = ghoul::systemcapabilities::SystemCapabilitiesComponent::Verbosity; - Verbosity verbosity = Verbosity::Default; - if (configurationManager()->hasKeyAndValue(ConfigurationManager::KeyCapabilitiesVerbosity)) { - std::map verbosityMap = { - { "Minimal", Verbosity::Minimal }, - { "Default", Verbosity::Default }, - { "Full", Verbosity::Full } - }; - - std::string v = configurationManager()->value(ConfigurationManager::KeyCapabilitiesVerbosity); - if (verbosityMap.find(v) != verbosityMap.end()) - verbosity = verbosityMap[v]; - } - SysCap.logCapabilities(verbosity); - - std::string requestURL = ""; - bool success = configurationManager()->getValue(ConfigurationManager::KeyDownloadRequestURL, requestURL); - if (success) - DownloadManager::initialize(requestURL, DownloadVersion); - - // Load SPICE time kernel - success = loadSpiceKernels(); - if (!success) - return false; - - // Register Lua script functions - LDEBUG("Registering Lua libraries"); - _scriptEngine->addLibrary(RenderEngine::luaLibrary()); - _scriptEngine->addLibrary(Scene::luaLibrary()); - _scriptEngine->addLibrary(Time::luaLibrary()); - _scriptEngine->addLibrary(interaction::InteractionHandler::luaLibrary()); - _scriptEngine->addLibrary(LuaConsole::luaLibrary()); - _scriptEngine->addLibrary(gui::GUI::luaLibrary()); - _scriptEngine->addLibrary(network::ParallelConnection::luaLibrary()); - - // TODO: Maybe move all scenegraph and renderengine stuff to initializeGL - scriptEngine()->initialize(); - - // If a LuaDocumentationFile was specified, generate it now - const bool hasType = configurationManager()->hasKey(ConfigurationManager::KeyLuaDocumentationType); - const bool hasFile = configurationManager()->hasKey(ConfigurationManager::KeyLuaDocumentationFile); - if (hasType && hasFile) { - std::string luaDocumentationType; - configurationManager()->getValue(ConfigurationManager::KeyLuaDocumentationType, luaDocumentationType); - std::string luaDocumentationFile; - configurationManager()->getValue(ConfigurationManager::KeyLuaDocumentationFile, luaDocumentationFile); - - luaDocumentationFile = absPath(luaDocumentationFile); - _scriptEngine->writeDocumentation(luaDocumentationFile, luaDocumentationType); - } - - bool disableMasterRendering = false; - configurationManager()->getValue( - ConfigurationManager::KeyDisableMasterRendering, disableMasterRendering); - _renderEngine->setDisableRenderingOnMaster(disableMasterRendering); - - - // Load scenegraph - Scene* sceneGraph = new Scene; - _renderEngine->setSceneGraph(sceneGraph); - - // initialize the RenderEngine - _renderEngine->initialize(); - sceneGraph->initialize(); - - std::string sceneDescriptionPath; - success = configurationManager()->getValue( - ConfigurationManager::KeyConfigScene, sceneDescriptionPath); - if (success) - sceneGraph->scheduleLoadSceneFile(sceneDescriptionPath); - - _interactionHandler->setKeyboardController(new interaction::KeyboardControllerFixed); - _interactionHandler->setMouseController(new interaction::OrbitalMouseController); - - // Run start up scripts - runStartupScripts(); - - // Load a light and a monospaced font - loadFonts(); - - LINFO("Initializing GUI"); - _gui->initialize(); - - // Initialize modules - _moduleEngine->initialize(); - - LINFO("Finished initializing"); - return true; -} - -bool OpenSpaceEngine::isInitialized() { - return _engine != nullptr; -} - -void OpenSpaceEngine::clearAllWindows() { - size_t n = sgct::Engine::instance()->getNumberOfWindows(); - for (size_t i = 0; i < n; ++i) { - glClearColor(0, 0, 0, 0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - GLFWwindow* win = sgct::Engine::instance()->getWindowPtr(i)->getWindowHandle(); - glfwSwapBuffers(win); - } -} - -bool OpenSpaceEngine::gatherCommandlineArguments() { - // TODO: Get commandline arguments from all modules - - commandlineArgumentPlaceholders.configurationName = ""; - CommandlineCommand* configurationFileCommand = new SingleCommand( - &commandlineArgumentPlaceholders.configurationName, "-config", "-c", - "Provides the path to the OpenSpace configuration file"); - _commandlineParser->addCommand(configurationFileCommand); - - commandlineArgumentPlaceholders.sgctConfigurationName = ""; - CommandlineCommand* sgctConfigFileCommand = new SingleCommand( - &commandlineArgumentPlaceholders.sgctConfigurationName, "-sgct", "-s", - "Provides the path to the SGCT configuration file, overriding the value set in" - "the OpenSpace configuration file"); - _commandlineParser->addCommand(sgctConfigFileCommand); - - return true; -} - -bool OpenSpaceEngine::findConfiguration(std::string& filename) { - using ghoul::filesystem::Directory; - - Directory directory = FileSys.currentDirectory(); - std::string configurationName = _configurationFile; - - while (true) { - std::string&& fullPath = FileSys.pathByAppendingComponent(directory, - configurationName); - bool exists = FileSys.fileExists(fullPath); - if (exists) { - filename = fullPath; - return true; - } - - Directory nextDirectory = directory.parentDirectory(true); - - if (directory.path() == nextDirectory.path()) - // We have reached the root of the file system and did not find the file - return false; - directory = nextDirectory; - } -} - -bool OpenSpaceEngine::loadSpiceKernels() { - // Load time kernel - std::string timeKernel; - bool success = configurationManager()->getValue(ConfigurationManager::KeySpiceTimeKernel, timeKernel); - // Move this to configurationmanager::completenesscheck ---abock - if (!success) { - LERROR("Configuration file does not contain a '" << ConfigurationManager::KeySpiceTimeKernel << "'"); - return false; - } - SpiceManager::KernelIdentifier id = - SpiceManager::ref().loadKernel(timeKernel); - if (id == SpiceManager::KernelFailed) { - LERROR("Error loading time kernel '" << timeKernel << "'"); - return false; - } - - // Load SPICE leap second kernel - std::string leapSecondKernel; - success = configurationManager()->getValue(ConfigurationManager::KeySpiceLeapsecondKernel, leapSecondKernel); - if (!success) { - // Move this to configurationmanager::completenesscheck ---abock - LERROR("Configuration file does not have a '" << ConfigurationManager::KeySpiceLeapsecondKernel << "'"); - return false; - } - id = SpiceManager::ref().loadKernel(std::move(leapSecondKernel)); - if (id == SpiceManager::KernelFailed) { - LERROR("Error loading leap second kernel '" << leapSecondKernel << "'"); - return false; - } - return true; -} - -void OpenSpaceEngine::runScripts(const ghoul::Dictionary& scripts) { - for (size_t i = 1; i <= scripts.size(); ++i) { - std::stringstream stream; - stream << i; - const std::string& key = stream.str(); - const bool hasKey = scripts.hasKeyAndValue(key); - if (!hasKey) { - LERROR("The startup scripts have to be declared in a simple array format." - " Startup scripts did not contain the key '" << key << "'"); - break; - } - - std::string scriptPath; - scripts.getValue(key, scriptPath); - std::string&& absoluteScriptPath = absPath(scriptPath); - _engine->scriptEngine()->runScriptFile(absoluteScriptPath); - - //@JK - //temporary solution to ensure that startup scripts may be syncrhonized over parallel connection - std::ifstream scriptFile; - scriptFile.open(absoluteScriptPath.c_str()); - std::string line; - - while(getline(scriptFile,line)){ - //valid line and not a comment - if(line.size() > 0 && line.at(0) != '-'){ - std::string lib, func; - if(_engine->scriptEngine()->parseLibraryAndFunctionNames(lib, func, line) && - _engine->scriptEngine()->shouldScriptBeSent(lib, func)){ - _engine->scriptEngine()->cacheScript(lib, func, line); - } - } - } - } -} - - -void OpenSpaceEngine::runStartupScripts() { - ghoul::Dictionary scripts; - configurationManager()->getValue( - ConfigurationManager::KeyStartupScript, scripts); - runScripts(scripts); -} - -void OpenSpaceEngine::runSettingsScripts() { - ghoul::Dictionary scripts; - configurationManager()->getValue( - ConfigurationManager::KeySettingsScript, scripts); - runScripts(scripts); -} - -void OpenSpaceEngine::loadFonts() { - sgct_text::FontManager::FontPath local = sgct_text::FontManager::FontPath::FontPath_Local; - - ghoul::Dictionary fonts; - configurationManager()->getValue(ConfigurationManager::KeyFonts, fonts); - - for (const std::string& key : fonts.keys()) { - std::string font; - fonts.getValue(key, font); - font = absPath(font); - if(!FileSys.fileExists(font)) { - LERROR("Could not find font '" << font << "'"); - continue; - } - - LINFO("Registering font '" << font << "' with key '" << key << "'"); - sgct_text::FontManager::instance()->addFont(key, font, local); - } -} - -void OpenSpaceEngine::configureLogging() { - if (configurationManager()->hasKeyAndValue(ConfigurationManager::KeyLogLevel)) { - std::string logLevel; - configurationManager()->getValue(ConfigurationManager::KeyLogLevel, logLevel); - - bool immediateFlush = false; - configurationManager()->getValue(ConfigurationManager::KeyLogImmediateFlush, immediateFlush); - - LogManager::LogLevel level = LogManager::levelFromString(logLevel); - LogManager::deinitialize(); - LogManager::initialize(level, immediateFlush); - LogMgr.addLog(new ConsoleLog); - } - - if (configurationManager()->hasKeyAndValue(ConfigurationManager::KeyLogs)) { - ghoul::Dictionary logs; - configurationManager()->getValue(ConfigurationManager::KeyLogs, logs); - - for (size_t i = 1; i <= logs.size(); ++i) { - ghoul::Dictionary logInfo; - logs.getValue(std::to_string(i), logInfo); - - Log* log = LogFactory::createLog(logInfo); - - if (log) - LogMgr.addLog(log); - } - } -} - -ConfigurationManager* OpenSpaceEngine::configurationManager() { - ghoul_assert(_configurationManager != nullptr, "ConfigurationManager is nullptr"); - return _configurationManager; -} - -interaction::InteractionHandler* OpenSpaceEngine::interactionHandler() { - ghoul_assert(_interactionHandler != nullptr, "InteractionHandler is nullptr"); - return _interactionHandler; -} - -RenderEngine* OpenSpaceEngine::renderEngine() { - ghoul_assert(_renderEngine != nullptr, "RenderEngine is nullptr"); - return _renderEngine; -} - -ScriptEngine* OpenSpaceEngine::scriptEngine() { - ghoul_assert(_scriptEngine != nullptr, "ScriptEngine is nullptr"); - return _scriptEngine; -} - -LuaConsole* OpenSpaceEngine::console() { - ghoul_assert(_console != nullptr, "LuaConsole is nullptr"); - return _console; -} - -gui::GUI* OpenSpaceEngine::gui() { - ghoul_assert(_gui != nullptr, "GUI is nullptr"); - return _gui; -} - -bool OpenSpaceEngine::initializeGL() { - LINFO("Initializing Rendering Engine"); - bool success = _renderEngine->initializeGL(); - LINFO("Initializing OnScreen GUI GL"); - _gui->initializeGL(); - LINFO("Finished initializing OpenGL"); - return success; -} - -bool OpenSpaceEngine::isMaster(){ - return _isMaster; -} - -void OpenSpaceEngine::setMaster(bool master){ - _isMaster = master; -} - -double OpenSpaceEngine::runTime(){ - return _runTime; -} - -void OpenSpaceEngine::setRunTime(double d){ - _runTime = d; -} - -void OpenSpaceEngine::preSynchronization() { - FileSys.triggerFilesystemEvents(); - if (_isMaster) { - //const double dt = sgct::Engine::instance()->getDt(); - const double dt = sgct::Engine::instance()->getAvgDt(); - - Time::ref().advanceTime(dt); - Time::ref().preSynchronization(); - - _interactionHandler->update(dt); - _parallelConnection->update(dt); - //_interactionHandler.lockControls(); - - _scriptEngine->preSynchronization(); - _renderEngine->preSynchronization(); - } -} - -void OpenSpaceEngine::postSynchronizationPreDraw() { - Time::ref().postSynchronizationPreDraw(); - - _scriptEngine->postSynchronizationPreDraw(); - _renderEngine->postSynchronizationPreDraw(); - - - if (_isMaster && _gui->isEnabled()) { - double posX, posY; - sgct::Engine::instance()->getMousePos(0, &posX, &posY); - - int x,y; - sgct::Engine::instance()->getWindowPtr(0)->getFinalFBODimensions(x, y); - - int button0 = sgct::Engine::instance()->getMouseButton(0, 0); - int button1 = sgct::Engine::instance()->getMouseButton(0, 1); - bool buttons[2] = { button0 != 0, button1 != 0 }; - - double dt = std::max(sgct::Engine::instance()->getDt(), 1.0/60.0); - _gui->startFrame(static_cast(dt), glm::vec2(glm::ivec2(x,y)), glm::vec2(posX, posY), buttons); - } -} - -void OpenSpaceEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &viewMatrix) { - _renderEngine->render(projectionMatrix, viewMatrix); - - if (_isMaster) { - // If currently writing a command, render it to screen - sgct::SGCTWindow* w = sgct::Engine::instance()->getActiveWindowPtr(); - if (_isMaster && !w->isUsingFisheyeRendering() && _console->isVisible()) { - _console->render(); - } - - if (_gui->isEnabled()) - _gui->endFrame(); - } -} - -void OpenSpaceEngine::postDraw() { - if (_isMaster) - //_interactionHandler.unlockControls(); - - _renderEngine->postDraw(); -} - -void OpenSpaceEngine::keyboardCallback(int key, int action) { - if (_isMaster) { - if (_gui->isEnabled()) { - bool isConsumed = _gui->keyCallback(key, action); - if (isConsumed) - return; - } - - if (static_cast(key) == _console->commandInputButton() && (action == SGCT_PRESS || action == SGCT_REPEAT)) - _console->toggleVisibility(); - - if (!_console->isVisible()) { - _interactionHandler->keyboardCallback(key, action); - } - else { - _console->keyboardCallback(key, action); - } - } -} - -void OpenSpaceEngine::charCallback(unsigned int codepoint) { - if (_isMaster) { - if (_gui->isEnabled()) { - bool isConsumed = _gui->charCallback(codepoint); - if (isConsumed) - return; - } - - if (_console->isVisible()) { - _console->charCallback(codepoint); - } - } -} - -void OpenSpaceEngine::mouseButtonCallback(int key, int action) { - if (_isMaster) { - if (_gui->isEnabled()) { - bool isConsumed = _gui->mouseButtonCallback(key, action); - if (isConsumed && action != SGCT_RELEASE) - return; - } - - _interactionHandler->mouseButtonCallback(key, action); - } -} - -void OpenSpaceEngine::mousePositionCallback(double x, double y) { - if (_isMaster) { - _interactionHandler->mousePositionCallback(x, y); - } -} - -void OpenSpaceEngine::mouseScrollWheelCallback(double pos) { - if (_isMaster) { - if (_gui->isEnabled()) { - bool isConsumed = _gui->mouseWheelCallback(pos); - if (isConsumed) - return; - } - - _interactionHandler->mouseScrollWheelCallback(pos); - } -} - -void OpenSpaceEngine::encode() { - if (_syncBuffer) { - Time::ref().serialize(_syncBuffer); - _scriptEngine->serialize(_syncBuffer); - _renderEngine->serialize(_syncBuffer); - - _syncBuffer->write(); - } - _networkEngine->publishStatusMessage(); - _networkEngine->sendMessages(); -} - -void OpenSpaceEngine::decode() { - if (_syncBuffer) { - _syncBuffer->read(); - - Time::ref().deserialize(_syncBuffer); - _scriptEngine->deserialize(_syncBuffer); - _renderEngine->deserialize(_syncBuffer); - } -} - -void OpenSpaceEngine::externalControlCallback(const char* receivedChars, - int size, int clientId) -{ - if (size == 0) - return; - - _networkEngine->handleMessage(std::string(receivedChars, size)); -} - -void OpenSpaceEngine::enableBarrier() { - sgct::SGCTWindow::setBarrier(true); -} - -void OpenSpaceEngine::disableBarrier() { - sgct::SGCTWindow::setBarrier(false); -} - -NetworkEngine* OpenSpaceEngine::networkEngine() { - return _networkEngine; -} - -ModuleEngine* OpenSpaceEngine::moduleEngine() { - return _moduleEngine; -} - -network::ParallelConnection* OpenSpaceEngine::parallelConnection() { - ghoul_assert(_parallelConnection != nullptr, "ParallelConnection is nullptr"); - return _parallelConnection; -} - -} // namespace openspace diff --git a/src/engine/sgctwindow.cpp b/src/engine/sgctwindow.cpp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/engine/window.cpp b/src/engine/window.cpp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index eddd725b90..e79bd4677d 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -485,7 +485,7 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi #ifdef OPENSPACE_MODULE_NEWHORIZONS_ENABLED if (openspace::ImageSequencer2::ref().isReady()) { double remaining = openspace::ImageSequencer2::ref().getNextCaptureTime() - currentTime; - double t = 1.0 - remaining / openspace::ImageSequencer2::ref().getIntervalLength(); + float t = static_cast(1.0 - remaining / openspace::ImageSequencer2::ref().getIntervalLength()); std::string progress = "|"; int g = static_cast((t* 24) + 1); g = std::max(g, 0); @@ -1252,40 +1252,40 @@ void RenderEngine::changeViewPoint(std::string origin) { // return; //} - //if (origin == "67P") { - // SceneGraphNode* rosettaNode = scene()->sceneGraphNode("Rosetta"); - // SceneGraphNode* cgNode = scene()->sceneGraphNode("67P"); - // //jupiterBarycenterNode->setParent(solarSystemBarycenterNode); - // //plutoBarycenterNode->setParent(solarSystemBarycenterNode); - // solarSystemBarycenterNode->setParent(cgNode); - // rosettaNode->setParent(cgNode); - // - // ghoul::Dictionary solarDictionary = - // { - // { std::string("Type"), std::string("Spice") }, - // { std::string("Body"), std::string("SUN") }, - // { std::string("Reference"), std::string("GALACTIC") }, - // { std::string("Observer"), std::string("CHURYUMOV-GERASIMENKO") }, - // { std::string("Kernels"), ghoul::Dictionary() } - // }; - // solarSystemBarycenterNode->setEphemeris(new SpiceEphemeris(solarDictionary)); - // - // ghoul::Dictionary rosettaDictionary = - // { - // { std::string("Type"), std::string("Spice") }, - // { std::string("Body"), std::string("ROSETTA") }, - // { std::string("Reference"), std::string("GALACTIC") }, - // { std::string("Observer"), std::string("CHURYUMOV-GERASIMENKO") }, - // { std::string("Kernels"), ghoul::Dictionary() } - // }; - // - // cgNode->setParent(scene()->sceneGraphNode("SolarSystem")); - // rosettaNode->setEphemeris(new SpiceEphemeris(rosettaDictionary)); - // cgNode->setEphemeris(new StaticEphemeris); - // - // return; - // - //} + if (origin == "67P") { + SceneGraphNode* rosettaNode = scene()->sceneGraphNode("Rosetta"); + SceneGraphNode* cgNode = scene()->sceneGraphNode("67P"); + //jupiterBarycenterNode->setParent(solarSystemBarycenterNode); + //plutoBarycenterNode->setParent(solarSystemBarycenterNode); + solarSystemBarycenterNode->setParent(cgNode); + rosettaNode->setParent(cgNode); + + ghoul::Dictionary solarDictionary = + { + { std::string("Type"), std::string("Spice") }, + { std::string("Body"), std::string("SUN") }, + { std::string("Reference"), std::string("GALACTIC") }, + { std::string("Observer"), std::string("CHURYUMOV-GERASIMENKO") }, + { std::string("Kernels"), ghoul::Dictionary() } + }; + solarSystemBarycenterNode->setEphemeris(new SpiceEphemeris(solarDictionary)); + + ghoul::Dictionary rosettaDictionary = + { + { std::string("Type"), std::string("Spice") }, + { std::string("Body"), std::string("ROSETTA") }, + { std::string("Reference"), std::string("GALACTIC") }, + { std::string("Observer"), std::string("CHURYUMOV-GERASIMENKO") }, + { std::string("Kernels"), ghoul::Dictionary() } + }; + + cgNode->setParent(scene()->sceneGraphNode("SolarSystem")); + rosettaNode->setEphemeris(new SpiceEphemeris(rosettaDictionary)); + cgNode->setEphemeris(new StaticEphemeris); + + return; + + } LFATAL("This function is being misused with an argument of '" << origin << "'"); } diff --git a/tests/main.cpp b/tests/main.cpp index 40252d4f44..c8c43078ff 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -36,6 +36,7 @@ //#include //#include #include +#include #include #include #include @@ -53,7 +54,7 @@ namespace { int main(int argc, char** argv) { std::vector args; - openspace::OpenSpaceEngine::create(argc, argv, args); + openspace::OpenSpaceEngine::create(argc, argv, new openspace::Window, args); testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); From 26ea512910d28f41cdc62a8aa37297d35e46ed09 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 25 Oct 2015 11:27:41 -0500 Subject: [PATCH 014/122] Set Interaction sensitivity to 1 on default --- ext/ghoul | 2 +- modules/newhorizons/rendering/renderablefov.cpp | 2 +- src/interaction/interactionhandler.cpp | 2 +- src/interaction/mousecontroller.cpp | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index 85b73b3249..9bd660cc60 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 85b73b32499150f19e6db3fba37418f92e3c507e +Subproject commit 9bd660cc60a6a4d5c96b5e583f4bdb0efd848034 diff --git a/modules/newhorizons/rendering/renderablefov.cpp b/modules/newhorizons/rendering/renderablefov.cpp index 421a9d59dd..51ddcdcc13 100644 --- a/modules/newhorizons/rendering/renderablefov.cpp +++ b/modules/newhorizons/rendering/renderablefov.cpp @@ -442,7 +442,7 @@ void RenderableFov::computeIntercepts(const RenderData& data){ _interceptTag[_bounds.size()] = _interceptTag[0]; fovSurfaceIntercept(_interceptTag, _bounds); - glm::vec3 aim = (_spacecraftRotation * glm::vec4(_boresight, 1)).xyz; + glm::vec3 aim = (_spacecraftRotation * glm::vec4(_boresight, 1)).xyz(); psc position; SpiceManager::ref().getTargetPosition(_fovTarget, _spacecraft, diff --git a/src/interaction/interactionhandler.cpp b/src/interaction/interactionhandler.cpp index 51f8fe3945..55c90177a9 100644 --- a/src/interaction/interactionhandler.cpp +++ b/src/interaction/interactionhandler.cpp @@ -250,7 +250,7 @@ InteractionHandler::InteractionHandler() , _focusNode(nullptr) , _deltaTime(0.0) , _validKeyLua(false) - , _controllerSensitivity(10.f) + , _controllerSensitivity(1.f) , _invertRoll(false) , _invertRotation(false) , _keyboardController(nullptr) diff --git a/src/interaction/mousecontroller.cpp b/src/interaction/mousecontroller.cpp index 98c93c593a..ba816eb91b 100644 --- a/src/interaction/mousecontroller.cpp +++ b/src/interaction/mousecontroller.cpp @@ -208,13 +208,13 @@ void OrbitalMouseController::move(float x, float y) { sgct::Engine::instance()->getMousePos(winID, &mouseX, &mouseY); _currentCursorPos = glm::vec2(static_cast(mouseX), static_cast(mouseY)); - if (_leftMouseButtonDown){ + if (_leftMouseButtonDown) { _currentCursorDiff[MouseButtons::ButtonLeft] = (_currentCursorPos - _previousCursorPos[MouseButtons::ButtonLeft]) / glm::vec2(static_cast(sgct::Engine::instance()->getWindowPtr(winID)->getXResolution()), static_cast(sgct::Engine::instance()->getWindowPtr(winID)->getYResolution())); } - if (_rightMouseButtonDown){ + if (_rightMouseButtonDown) { _currentCursorDiff[MouseButtons::ButtonRight] = (_currentCursorPos - _previousCursorPos[MouseButtons::ButtonRight]) / glm::vec2(static_cast(sgct::Engine::instance()->getWindowPtr(winID)->getXResolution()), static_cast(sgct::Engine::instance()->getWindowPtr(winID)->getYResolution())); } - if (_middleMouseButtonDown){ + if (_middleMouseButtonDown) { _currentCursorDiff[MouseButtons::ButtonMiddle] = (_currentCursorPos - _previousCursorPos[MouseButtons::ButtonMiddle]) / glm::vec2(static_cast(sgct::Engine::instance()->getWindowPtr(winID)->getXResolution()), static_cast(sgct::Engine::instance()->getWindowPtr(winID)->getYResolution())); } } From 5456b5ee8539a464bc468c485ebcc4cd0e90d224 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 25 Oct 2015 13:50:39 -0500 Subject: [PATCH 015/122] Started change moving from explicit SGCT functions to wrapper class --- apps/OpenSpace/main.cpp | 4 +- include/openspace/engine/openspaceengine.h | 10 +-- .../{sgctwindow.h => sgctwindowhandler.h} | 20 +++-- .../engine/{window.h => windowhandler.h} | 21 +++++- src/CMakeLists.txt | 8 +- src/engine/openspaceengine.cpp | 41 ++++------- src/engine/sgctwindowhandler.cpp | 73 +++++++++++++++++++ src/engine/window.cpp | 0 .../{sgctwindow.cpp => windowhandler.cpp} | 0 9 files changed, 133 insertions(+), 44 deletions(-) rename include/openspace/engine/{sgctwindow.h => sgctwindowhandler.h} (80%) rename include/openspace/engine/{window.h => windowhandler.h} (81%) create mode 100644 src/engine/sgctwindowhandler.cpp delete mode 100644 src/engine/window.cpp rename src/engine/{sgctwindow.cpp => windowhandler.cpp} (100%) diff --git a/apps/OpenSpace/main.cpp b/apps/OpenSpace/main.cpp index 626f379290..cbac1f3d1a 100644 --- a/apps/OpenSpace/main.cpp +++ b/apps/OpenSpace/main.cpp @@ -23,7 +23,7 @@ ****************************************************************************************/ #include -#include +#include #include #include #include @@ -87,7 +87,7 @@ int main(int argc, char** argv) { std::vector sgctArguments; const bool success = openspace::OpenSpaceEngine::create( argc, argv, - new openspace::SGCTWindow, + new openspace::SGCTWindowHandler, sgctArguments ); if (!success) diff --git a/include/openspace/engine/openspaceengine.h b/include/openspace/engine/openspaceengine.h index db100da693..315b92f020 100644 --- a/include/openspace/engine/openspaceengine.h +++ b/include/openspace/engine/openspaceengine.h @@ -46,7 +46,7 @@ class GUI; class RenderEngine; class SyncBuffer; class ModuleEngine; -class Window; +class WindowHandler; namespace interaction { class InteractionHandler; @@ -68,7 +68,7 @@ namespace properties { class OpenSpaceEngine { public: - static bool create(int argc, char** argv, Window* windowHandler, std::vector& sgctArguments); + static bool create(int argc, char** argv, WindowHandler* windowHandler, std::vector& sgctArguments); static void destroy(); static OpenSpaceEngine& ref(); @@ -90,7 +90,7 @@ public: ModuleEngine* moduleEngine(); network::ParallelConnection* parallelConnection(); properties::PropertyOwner* globalPropertyOwner(); - Window* windowWrapper(); + WindowHandler* windowWrapper(); gui::GUI* gui(); @@ -115,7 +115,7 @@ public: void runSettingsScripts(); private: - OpenSpaceEngine(std::string programName, Window* windowHandler); + OpenSpaceEngine(std::string programName, WindowHandler* windowHandler); ~OpenSpaceEngine(); OpenSpaceEngine(const OpenSpaceEngine& rhs) = delete; @@ -139,7 +139,7 @@ private: ModuleEngine* _moduleEngine; gui::GUI* _gui; network::ParallelConnection* _parallelConnection; - Window* _windowWrapper; + WindowHandler* _windowHandler; properties::PropertyOwner* _globalPropertyNamespace; diff --git a/include/openspace/engine/sgctwindow.h b/include/openspace/engine/sgctwindowhandler.h similarity index 80% rename from include/openspace/engine/sgctwindow.h rename to include/openspace/engine/sgctwindowhandler.h index 6d65802d21..271e689789 100644 --- a/include/openspace/engine/sgctwindow.h +++ b/include/openspace/engine/sgctwindowhandler.h @@ -22,18 +22,28 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#ifndef __SGCTWINDOW_H__ -#define __SGCTWINDOW_H__ +#ifndef __SGCTWINDOWHANDLER_H__ +#define __SGCTWINDOWHANDLER_H__ -#include +#include namespace openspace { -class SGCTWindow : public Window { +class SGCTWindowHandler : public WindowHandler { public: + void setBarrier(bool enabled) override; + void clearAllWindows() override; + + double averageDeltaTime() override; + glm::vec2 mousePosition() override; + glm::ivec2 currentWindowSize() override; + glm::ivec2 currentWindowResolution() override; + + + // void forEachWindow(std::function function) override; }; } // namespace openspace -#endif // __SGCTWINDOW_H__ +#endif // __SGCTWINDOWHANDLER_H__ diff --git a/include/openspace/engine/window.h b/include/openspace/engine/windowhandler.h similarity index 81% rename from include/openspace/engine/window.h rename to include/openspace/engine/windowhandler.h index 323b9b4511..19119d8bc6 100644 --- a/include/openspace/engine/window.h +++ b/include/openspace/engine/windowhandler.h @@ -22,14 +22,29 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#ifndef __WINDOW_H__ -#define __WINDOW_H__ +#ifndef __WINDOWHANDLER_H__ +#define __WINDOWHANDLER_H__ + +#include + +#include namespace openspace { -class Window { +class WindowHandler { public: + virtual void setBarrier(bool enabled) = 0; + virtual void clearAllWindows() = 0; + virtual double averageDeltaTime() = 0; + virtual glm::vec2 mousePosition() = 0; + virtual glm::ivec2 currentWindowSize() = 0; + virtual glm::ivec2 currentWindowResolution() = 0; + + + + //virtual void forEachWindow(std::function function) = 0; + }; } // namespace openspace diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 764e069b86..f4e59f7eac 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -33,9 +33,9 @@ set(OPENSPACE_SOURCE ${OPENSPACE_BASE_DIR}/src/engine/downloadmanager.cpp ${OPENSPACE_BASE_DIR}/src/engine/logfactory.cpp ${OPENSPACE_BASE_DIR}/src/engine/moduleengine.cpp - ${OPENSPACE_BASE_DIR}/src/engine/sgctwindow.cpp + ${OPENSPACE_BASE_DIR}/src/engine/sgctwindowhandler.cpp ${OPENSPACE_BASE_DIR}/src/engine/openspaceengine.cpp - ${OPENSPACE_BASE_DIR}/src/engine/window.cpp + ${OPENSPACE_BASE_DIR}/src/engine/windowhandler.cpp ${OPENSPACE_BASE_DIR}/src/interaction/controller.cpp ${OPENSPACE_BASE_DIR}/src/interaction/deviceidentifier.cpp ${OPENSPACE_BASE_DIR}/src/interaction/interactionhandler.cpp @@ -99,9 +99,9 @@ set(OPENSPACE_HEADER ${OPENSPACE_BASE_DIR}/include/openspace/engine/downloadmanager.h ${OPENSPACE_BASE_DIR}/include/openspace/engine/logfactory.h ${OPENSPACE_BASE_DIR}/include/openspace/engine/moduleengine.h - ${OPENSPACE_BASE_DIR}/include/openspace/engine/sgctwindow.h + ${OPENSPACE_BASE_DIR}/include/openspace/engine/sgctwindowhandler.h ${OPENSPACE_BASE_DIR}/include/openspace/engine/openspaceengine.h - ${OPENSPACE_BASE_DIR}/include/openspace/engine/window.h + ${OPENSPACE_BASE_DIR}/include/openspace/engine/windowhandler.h ${OPENSPACE_BASE_DIR}/include/openspace/interaction/controller.h ${OPENSPACE_BASE_DIR}/include/openspace/interaction/deviceidentifier.h ${OPENSPACE_BASE_DIR}/include/openspace/interaction/interactionhandler.h diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 859af4b274..e534d36071 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -32,6 +32,7 @@ #include #include +#include #include #include #include @@ -101,7 +102,7 @@ namespace openspace { OpenSpaceEngine* OpenSpaceEngine::_engine = nullptr; -OpenSpaceEngine::OpenSpaceEngine(std::string programName, Window* windowHandler) +OpenSpaceEngine::OpenSpaceEngine(std::string programName, WindowHandler* windowHandler) : _configurationManager(new ConfigurationManager) , _interactionHandler(new interaction::InteractionHandler) , _renderEngine(new RenderEngine) @@ -112,7 +113,7 @@ OpenSpaceEngine::OpenSpaceEngine(std::string programName, Window* windowHandler) , _moduleEngine(new ModuleEngine) , _gui(new gui::GUI) , _parallelConnection(new network::ParallelConnection) - , _windowWrapper(windowHandler) + , _windowHandler(windowHandler) , _globalPropertyNamespace(new properties::PropertyOwner) , _isMaster(false) , _runTime(0.0) @@ -132,8 +133,8 @@ OpenSpaceEngine::~OpenSpaceEngine() { delete _globalPropertyNamespace; _globalPropertyNamespace = nullptr; - delete _windowWrapper; - _windowWrapper = nullptr; + delete _windowHandler; + _windowHandler = nullptr; delete _parallelConnection; _parallelConnection = nullptr; @@ -176,7 +177,7 @@ OpenSpaceEngine& OpenSpaceEngine::ref() { bool OpenSpaceEngine::create( int argc, char** argv, - Window* windowHandler, + WindowHandler* windowHandler, std::vector& sgctArguments) { ghoul::initialize(); @@ -422,13 +423,7 @@ bool OpenSpaceEngine::isInitialized() { } void OpenSpaceEngine::clearAllWindows() { - size_t n = sgct::Engine::instance()->getNumberOfWindows(); - for (size_t i = 0; i < n; ++i) { - glClearColor(0, 0, 0, 0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - GLFWwindow* win = sgct::Engine::instance()->getWindowPtr(i)->getWindowHandle(); - glfwSwapBuffers(win); - } + _windowHandler->clearAllWindows(); } bool OpenSpaceEngine::gatherCommandlineArguments() { @@ -672,8 +667,7 @@ void OpenSpaceEngine::setRunTime(double d){ void OpenSpaceEngine::preSynchronization() { FileSys.triggerFilesystemEvents(); if (_isMaster) { - //const double dt = sgct::Engine::instance()->getDt(); - const double dt = sgct::Engine::instance()->getAvgDt(); + double dt = _windowHandler->averageDeltaTime(); Time::ref().advanceTime(dt); Time::ref().preSynchronization(); @@ -696,18 +690,15 @@ void OpenSpaceEngine::postSynchronizationPreDraw() { if (_isMaster && _gui->isEnabled()) { - double posX, posY; - sgct::Engine::instance()->getMousePos(0, &posX, &posY); - - int x,y; - sgct::Engine::instance()->getWindowPtr(0)->getFinalFBODimensions(x, y); + glm::vec2 mousePosition = _windowHandler->mousePosition(); + glm::ivec2 windowResolution = _windowHandler->currentWindowResolution(); int button0 = sgct::Engine::instance()->getMouseButton(0, 0); int button1 = sgct::Engine::instance()->getMouseButton(0, 1); bool buttons[2] = { button0 != 0, button1 != 0 }; double dt = std::max(sgct::Engine::instance()->getDt(), 1.0/60.0); - _gui->startFrame(static_cast(dt), glm::vec2(glm::ivec2(x,y)), glm::vec2(posX, posY), buttons); + _gui->startFrame(static_cast(dt), glm::vec2(windowResolution), mousePosition, buttons); } } @@ -831,11 +822,11 @@ void OpenSpaceEngine::externalControlCallback(const char* receivedChars, } void OpenSpaceEngine::enableBarrier() { - sgct::SGCTWindow::setBarrier(true); + _windowHandler->setBarrier(true); } void OpenSpaceEngine::disableBarrier() { - sgct::SGCTWindow::setBarrier(false); + _windowHandler->setBarrier(false); } NetworkEngine* OpenSpaceEngine::networkEngine() { @@ -856,9 +847,9 @@ properties::PropertyOwner* OpenSpaceEngine::globalPropertyOwner() { return _globalPropertyNamespace; } -Window* OpenSpaceEngine::windowWrapper() { - ghoul_assert(_windowWrapper, "Window Wrapper"); - return _windowWrapper; +WindowHandler* OpenSpaceEngine::windowWrapper() { + ghoul_assert(_windowHandler, "Window Wrapper"); + return _windowHandler; } } // namespace openspace diff --git a/src/engine/sgctwindowhandler.cpp b/src/engine/sgctwindowhandler.cpp new file mode 100644 index 0000000000..f60af53d05 --- /dev/null +++ b/src/engine/sgctwindowhandler.cpp @@ -0,0 +1,73 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2015 * + * * + * 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 "sgct.h" + +#include + +namespace openspace { + +void SGCTWindowHandler::setBarrier(bool enabled) { + sgct::SGCTWindow::setBarrier(enabled); +} + +void SGCTWindowHandler::clearAllWindows() { + size_t n = sgct::Engine::instance()->getNumberOfWindows(); + for (size_t i = 0; i < n; ++i) { + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + GLFWwindow* win = sgct::Engine::instance()->getWindowPtr(i)->getWindowHandle(); + glfwSwapBuffers(win); + } +} + +double SGCTWindowHandler::averageDeltaTime() { + return sgct::Engine::instance()->getAvgDt(); +} + +glm::vec2 SGCTWindowHandler::mousePosition() { + double posX, posY; + sgct::Engine::instance()->getMousePos(0, &posX, &posY); + return glm::vec2(posX, posY); +} + +glm::ivec2 SGCTWindowHandler::currentWindowSize() { + return glm::ivec2(0); +} + +glm::ivec2 SGCTWindowHandler::currentWindowResolution() { + int x,y; + sgct::Engine::instance()->getWindowPtr(0)->getFinalFBODimensions(x, y); + return glm::ivec2(x, y); +} + +//void forEachWindow(std::function function) { +// size_t n = sgct::Engine::instance()->getNumberOfWindows(); +// for (size_t i = 0; i < n; ++i) +// function(); +//} + +} // namespace openspace + diff --git a/src/engine/window.cpp b/src/engine/window.cpp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/engine/sgctwindow.cpp b/src/engine/windowhandler.cpp similarity index 100% rename from src/engine/sgctwindow.cpp rename to src/engine/windowhandler.cpp From d84edc40907df3dfae6d5ece0420b9bd4bda8d82 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 25 Oct 2015 17:34:03 -0500 Subject: [PATCH 016/122] More work on transitioning to windowwrapper for keyboard and mouse interaction --- apps/OpenSpace/main.cpp | 7 +- include/openspace/engine/openspaceengine.h | 9 +- include/openspace/engine/sgctwindowhandler.h | 3 + include/openspace/engine/windowhandler.h | 3 + .../interaction/interactionhandler.h | 9 +- include/openspace/interaction/luaconsole.h | 6 +- .../openspace/interaction/mousecontroller.h | 20 +- include/openspace/util/keys.h | 422 ++++++++++++------ .../openspace/{interaction => util}/mouse.h | 66 ++- modules/onscreengui/include/gui.h | 11 +- modules/onscreengui/src/gui.cpp | 25 +- openspace.cfg | 2 +- src/CMakeLists.txt | 2 +- src/engine/openspaceengine.cpp | 37 +- src/engine/sgctwindowhandler.cpp | 30 +- src/interaction/interactionhandler.cpp | 168 +------ src/interaction/interactionhandler_lua.inl | 4 +- src/interaction/luaconsole.cpp | 34 +- src/interaction/mousecontroller.cpp | 39 +- 19 files changed, 498 insertions(+), 399 deletions(-) rename include/openspace/{interaction => util}/mouse.h (56%) diff --git a/apps/OpenSpace/main.cpp b/apps/OpenSpace/main.cpp index cbac1f3d1a..97672c3e3d 100644 --- a/apps/OpenSpace/main.cpp +++ b/apps/OpenSpace/main.cpp @@ -248,12 +248,15 @@ void mainExternalControlCallback(const char* receivedChars, int size) { void mainKeyboardCallback(int key, int action) { if (OsEng.isMaster()) - OsEng.keyboardCallback(key, action); + OsEng.keyboardCallback(openspace::Key(key), + openspace::KeyModifier::NoModifier, // TODO: fix ---abock + openspace::KeyAction(action)); } void mainMouseButtonCallback(int key, int action) { if (OsEng.isMaster()) - OsEng.mouseButtonCallback(key, action); + OsEng.mouseButtonCallback(openspace::MouseButton(key), + openspace::MouseAction(action)); } void mainMousePosCallback(double x, double y) { diff --git a/include/openspace/engine/openspaceengine.h b/include/openspace/engine/openspaceengine.h index 315b92f020..ec5144e1f4 100644 --- a/include/openspace/engine/openspaceengine.h +++ b/include/openspace/engine/openspaceengine.h @@ -25,9 +25,13 @@ #ifndef __OPENSPACEENGINE_H__ #define __OPENSPACEENGINE_H__ + #include #include +#include +#include + #include #include @@ -100,9 +104,10 @@ public: void postSynchronizationPreDraw(); void render(const glm::mat4 &projectionMatrix, const glm::mat4 &viewMatrix); void postDraw(); - void keyboardCallback(int key, int action); +// void keyboardCallback(int key, int action); + void keyboardCallback(Key key, KeyModifier mod, KeyAction action); void charCallback(unsigned int codepoint); - void mouseButtonCallback(int key, int action); + void mouseButtonCallback(MouseButton button, MouseAction action); void mousePositionCallback(double x, double y); void mouseScrollWheelCallback(double pos); void externalControlCallback(const char* receivedChars, int size, int clientId); diff --git a/include/openspace/engine/sgctwindowhandler.h b/include/openspace/engine/sgctwindowhandler.h index 271e689789..b0d903ac86 100644 --- a/include/openspace/engine/sgctwindowhandler.h +++ b/include/openspace/engine/sgctwindowhandler.h @@ -36,8 +36,11 @@ public: double averageDeltaTime() override; glm::vec2 mousePosition() override; + uint32_t mouseButtons(int maxNumber) override; glm::ivec2 currentWindowSize() override; glm::ivec2 currentWindowResolution() override; + + bool isRegularRendering() override; // void forEachWindow(std::function function) override; diff --git a/include/openspace/engine/windowhandler.h b/include/openspace/engine/windowhandler.h index 19119d8bc6..156f141305 100644 --- a/include/openspace/engine/windowhandler.h +++ b/include/openspace/engine/windowhandler.h @@ -27,6 +27,7 @@ #include +#include #include namespace openspace { @@ -36,9 +37,11 @@ public: virtual void setBarrier(bool enabled) = 0; virtual void clearAllWindows() = 0; virtual double averageDeltaTime() = 0; + virtual uint32_t mouseButtons(int maxNumber = 8) = 0; virtual glm::vec2 mousePosition() = 0; virtual glm::ivec2 currentWindowSize() = 0; virtual glm::ivec2 currentWindowResolution() = 0; + virtual bool isRegularRendering() = 0; diff --git a/include/openspace/interaction/interactionhandler.h b/include/openspace/interaction/interactionhandler.h index 8ddd17f56f..23b6195a04 100644 --- a/include/openspace/interaction/interactionhandler.h +++ b/include/openspace/interaction/interactionhandler.h @@ -79,6 +79,7 @@ #include #include #include +#include #include @@ -109,8 +110,8 @@ public: void setCamera(Camera* camera); const Camera* const camera() const; - void keyboardCallback(int key, int action); - void mouseButtonCallback(int button, int action); + void keyboardCallback(Key key, KeyAction action); + void mouseButtonCallback(MouseButton button, MouseAction action); void mousePositionCallback(double x, double y); void mouseScrollWheelCallback(double pos); @@ -131,7 +132,7 @@ public: void setRotation(const glm::quat& rotation); void resetKeyBindings(); - void bindKey(int key, const std::string& lua); + void bindKey(Key key, std::string lua); void setInteractionSensitivity(float sensitivity); float interactionSensitivity() const; @@ -170,7 +171,7 @@ private: std::mutex _mutex; bool _validKeyLua; - std::multimap _keyLua; + std::multimap _keyLua; float _controllerSensitivity; bool _invertRoll; diff --git a/include/openspace/interaction/luaconsole.h b/include/openspace/interaction/luaconsole.h index dd07cfea01..63673394fe 100644 --- a/include/openspace/interaction/luaconsole.h +++ b/include/openspace/interaction/luaconsole.h @@ -27,6 +27,8 @@ #include +#include + #include #include @@ -40,12 +42,12 @@ public: void initialize(); void deinitialize(); - void keyboardCallback(int key, int action); + void keyboardCallback(Key key, KeyAction action); void charCallback(unsigned int codepoint); void render(); - unsigned int commandInputButton(); + Key commandInputButton(); bool isVisible() const; void setVisible(bool visible); diff --git a/include/openspace/interaction/mousecontroller.h b/include/openspace/interaction/mousecontroller.h index 25b93ddf92..24f6089bd0 100644 --- a/include/openspace/interaction/mousecontroller.h +++ b/include/openspace/interaction/mousecontroller.h @@ -27,7 +27,7 @@ #include -#include +#include #include @@ -39,7 +39,7 @@ public: MouseController(); virtual ~MouseController() {} - virtual void button(MouseAction action, MouseButton button) = 0; + virtual void button(MouseButton button, MouseAction action) = 0; virtual void move(float x, float y) = 0; virtual void scrollWheel(int pos) = 0; virtual void update(const double& dt) = 0; @@ -59,13 +59,13 @@ class TrackballMouseController : public MouseController { public: TrackballMouseController(); - void button(MouseAction action, MouseButton button); + void button(MouseButton button, MouseAction action) override; - void move(float x, float y); + void move(float x, float y) override; - void scrollWheel(int pos); + void scrollWheel(int pos) override; - void update(const double& dt); + void update(const double& dt) override; protected: bool _leftMouseButtonDown; @@ -76,13 +76,13 @@ class OrbitalMouseController : public MouseController { public: OrbitalMouseController(); - void button(MouseAction action, MouseButton button); + void button(MouseButton button, MouseAction action) override; - void move(float x, float y); + void move(float x, float y) override; - void scrollWheel(int pos); + void scrollWheel(int pos) override; - void update(const double& dt); + void update(const double& dt) override; protected: bool _leftMouseButtonDown; diff --git a/include/openspace/util/keys.h b/include/openspace/util/keys.h index 9129f742a5..60ba85011b 100644 --- a/include/openspace/util/keys.h +++ b/include/openspace/util/keys.h @@ -22,150 +22,314 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ +// This file is based on the definitions as presented in the GLFW library: +/************************************************************************* + * GLFW 3.1 - www.glfw.org + * A library for OpenGL, window and input + *------------------------------------------------------------------------ + * Copyright (c) 2002-2006 Marcus Geelnard + * Copyright (c) 2006-2010 Camilla Berglund + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would + * be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not + * be misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + * + *************************************************************************/ + #ifndef __KEYS_H__ #define __KEYS_H__ -#include +// All values that are defined here are compatible with (and are based on) the +// definitions GLFW v3.1 namespace openspace { enum class KeyAction { - Press = SGCT_PRESS, - Release = SGCT_RELEASE, - Repeat = SGCT_REPEAT + Release = 0, + Press = 1, + Repeat = 2 }; enum class KeyModifier { NoModifier = 0, - Shift = GLFW_MOD_SHIFT, - Control = GLFW_MOD_CONTROL, - Alt = GLFW_MOD_ALT, - Super = GLFW_MOD_SUPER + Shift = 0x0001, + Control = 0x0002, + Alt = 0x0004, + Super = 0x0008 }; enum class Key { - Unknown = SGCT_KEY_UNKNOWN, - Space = SGCT_KEY_SPACE, - Apostrophe = SGCT_KEY_APOSTROPHE, - Comma = SGCT_KEY_COMMA, - Minus = SGCT_KEY_MINUS, - Period = SGCT_KEY_PERIOD, - Slash = SGCT_KEY_SLASH, - Num0 = SGCT_KEY_0, - Num1 = SGCT_KEY_1, - Num2 = SGCT_KEY_2, - Num3 = SGCT_KEY_3, - Num4 = SGCT_KEY_4, - Num5 = SGCT_KEY_5, - Num6 = SGCT_KEY_6, - Num7 = SGCT_KEY_7, - Num8 = SGCT_KEY_8, - Num9 = SGCT_KEY_9, - SemiColon = SGCT_KEY_SEMICOLON, - Equal = SGCT_KEY_EQUAL, - A = SGCT_KEY_A, - B = SGCT_KEY_B, - C = SGCT_KEY_C, - D = SGCT_KEY_D, - E = SGCT_KEY_E, - F = SGCT_KEY_F, - G = SGCT_KEY_G, - H = SGCT_KEY_H, - I = SGCT_KEY_I, - J = SGCT_KEY_J, - K = SGCT_KEY_K, - L = SGCT_KEY_L, - M = SGCT_KEY_M, - N = SGCT_KEY_N, - O = SGCT_KEY_O, - P = SGCT_KEY_P, - Q = SGCT_KEY_Q, - R = SGCT_KEY_R, - S = SGCT_KEY_S, - T = SGCT_KEY_T, - U = SGCT_KEY_U, - V = SGCT_KEY_V, - W = SGCT_KEY_W, - X = SGCT_KEY_X, - Y = SGCT_KEY_Y, - Z = SGCT_KEY_Z, - LeftBracket = SGCT_KEY_LEFT_BRACKET, - BackSlash = SGCT_KEY_BACKSLASH, - RightBracket = SGCT_KEY_RIGHT_BRACKET, - GraveAccent = SGCT_KEY_GRAVE_ACCENT, - World1 = SGCT_KEY_WORLD_1, - World2 = SGCT_KEY_WORLD_2, - Escape = SGCT_KEY_ESC, - Enter = SGCT_KEY_ENTER, - Tab = SGCT_KEY_TAB, - BackSpace = SGCT_KEY_BACKSPACE, - Insert = SGCT_KEY_INSERT, - Delete = SGCT_KEY_DELETE, - Right = SGCT_KEY_RIGHT, - Left = SGCT_KEY_LEFT, - Down = SGCT_KEY_DOWN, - Up = SGCT_KEY_UP, - PageUp = SGCT_KEY_PAGE_UP, - PageDown = SGCT_KEY_PAGE_DOWN, - Home = SGCT_KEY_HOME, - End = SGCT_KEY_END, - CapsLock = SGCT_KEY_CAPS_LOCK, - ScrollLock = SGCT_KEY_SCROLL_LOCK, - NumLock = SGCT_KEY_NUM_LOCK, - PrintScreen = SGCT_KEY_PRINT_SCREEN, - Pause = SGCT_KEY_PAUSE, - F1 = SGCT_KEY_F1, - F2 = SGCT_KEY_F2, - F3 = SGCT_KEY_F3, - F4 = SGCT_KEY_F4, - F5 = SGCT_KEY_F5, - F6 = SGCT_KEY_F6, - F7 = SGCT_KEY_F7, - F8 = SGCT_KEY_F8, - F9 = SGCT_KEY_F9, - F10 = SGCT_KEY_F10, - F11 = SGCT_KEY_F11, - F12 = SGCT_KEY_F12, - F13 = SGCT_KEY_F13, - F14 = SGCT_KEY_F14, - F15 = SGCT_KEY_F15, - F16 = SGCT_KEY_F16, - F17 = SGCT_KEY_F17, - F18 = SGCT_KEY_F18, - F19 = SGCT_KEY_F19, - F20 = SGCT_KEY_F20, - F21 = SGCT_KEY_F21, - F22 = SGCT_KEY_F22, - F23 = SGCT_KEY_F23, - F24 = SGCT_KEY_F24, - F25 = SGCT_KEY_F25, - Keypad0 = SGCT_KEY_KP_0, - Keypad1 = SGCT_KEY_KP_1, - Keypad2 = SGCT_KEY_KP_2, - Keypad3 = SGCT_KEY_KP_3, - Keypad4 = SGCT_KEY_KP_4, - Keypad5 = SGCT_KEY_KP_5, - Keypad6 = SGCT_KEY_KP_6, - Keypad7 = SGCT_KEY_KP_7, - Keypad8 = SGCT_KEY_KP_8, - Keypad9 = SGCT_KEY_KP_9, - KeypadDecimal = SGCT_KEY_KP_DECIMAL, - KeypadDivide = SGCT_KEY_KP_DIVIDE, - KeypadMultiply = SGCT_KEY_KP_MULTIPLY, - KeypadSubtract = SGCT_KEY_KP_SUBTRACT, - KeypadAdd = SGCT_KEY_KP_ADD, - KeypadEnter = SGCT_KEY_KP_ENTER, - LeftShift = SGCT_KEY_LEFT_SHIFT, - LeftControl = SGCT_KEY_LEFT_CONTROL, - LeftAlt = SGCT_KEY_LEFT_ALT, - LeftSuper = SGCT_KEY_LEFT_SUPER, - RightShift = SGCT_KEY_RIGHT_SHIFT, - RightControl = SGCT_KEY_RIGHT_CONTROL, - RightAlt = SGCT_KEY_RIGHT_ALT, - RightSuper = SGCT_KEY_RIGHT_SUPER, - Menu = SGCT_KEY_MENU, - Last = SGCT_KEY_LAST + Unknown = -1, + Space = 32, + Apostrophe = 39, + Comma = 44, + Minus = 45, + Period = 46, + Slash = 47, + Num0 = 48, + Num1 = 49, + Num2 = 50, + Num3 = 51, + Num4 = 52, + Num5 = 53, + Num6 = 54, + Num7 = 55, + Num8 = 56, + Num9 = 57, + SemiColon = 59, + Equal = 61, + A = 65, + B = 66, + C = 67, + D = 68, + E = 69, + F = 70, + G = 71, + H = 72, + I = 73, + J = 74, + K = 75, + L = 76, + M = 77, + N = 78, + O = 79, + P = 80, + Q = 81, + R = 82, + S = 83, + T = 84, + U = 85, + V = 86, + W = 87, + X = 88, + Y = 89, + Z = 90, + LeftBracket = 91, + BackSlash = 92, + RightBracket = 93, + GraveAccent = 96, + World1 = 161, + World2 = 162, + Escape = 256, + Enter = 257, + Tab = 258, + BackSpace = 259, + Insert = 260, + Delete = 261, + Right = 262, + Left = 263, + Down = 264, + Up = 265, + PageUp = 266, + PageDown = 267, + Home = 268, + End = 269, + CapsLock = 280, + ScrollLock = 281, + NumLock = 282, + PrintScreen = 283, + Pause = 284, + F1 = 290, + F2 = 291, + F3 = 292, + F4 = 293, + F5 = 294, + F6 = 295, + F7 = 296, + F8 = 297, + F9 = 298, + F10 = 299, + F11 = 300, + F12 = 301, + F13 = 302, + F14 = 303, + F15 = 304, + F16 = 305, + F17 = 306, + F18 = 307, + F19 = 308, + F20 = 309, + F21 = 310, + F22 = 311, + F23 = 312, + F24 = 313, + F25 = 314, + Keypad0 = 320, + Keypad1 = 321, + Keypad2 = 322, + Keypad3 = 323, + Keypad4 = 324, + Keypad5 = 325, + Keypad6 = 326, + Keypad7 = 327, + Keypad8 = 328, + Keypad9 = 329, + KeypadDecimal = 330, + KeypadDivide = 331, + KeypadMultiply = 332, + KeypadSubtract = 333, + KeypadAdd = 334, + KeypadEnter = 335, + LeftShift = 340, + LeftControl = 341, + LeftAlt = 342, + LeftSuper = 343, + RightShift = 344, + RightControl = 345, + RightAlt = 346, + RightSuper = 347, + Menu = 348, + Last = Menu }; + +static const std::map KeyMapping = { + { "SPACE", Key::Space }, + { "APOSTROPHE", Key::Apostrophe }, + { "COMMA", Key::Comma }, + { "MINUS", Key::Minus }, + { "PERIOD", Key::Period }, + { "SLASH", Key::Slash }, + { "0", Key::Num0 }, + { "1", Key::Num1 }, + { "2", Key::Num2 }, + { "3", Key::Num3 }, + { "4", Key::Num4 }, + { "5", Key::Num5 }, + { "6", Key::Num6 }, + { "7", Key::Num7 }, + { "8", Key::Num8 }, + { "9", Key::Num9 }, + { "SEMICOLON", Key::SemiColon }, + { "EQUAL", Key::Equal }, + { "A", Key::A }, + { "B", Key::B }, + { "C", Key::C }, + { "D", Key::D }, + { "E", Key::E }, + { "F", Key::F }, + { "G", Key::G }, + { "H", Key::H }, + { "I", Key::I }, + { "J", Key::J }, + { "K", Key::K }, + { "L", Key::L }, + { "M", Key::M }, + { "N", Key::N }, + { "O", Key::O }, + { "P", Key::P }, + { "Q", Key::Q }, + { "R", Key::R }, + { "S", Key::S }, + { "T", Key::T }, + { "U", Key::U }, + { "V", Key::V }, + { "W", Key::W }, + { "X", Key::X }, + { "Y", Key::Y }, + { "Z", Key::Z }, + { "LEFT_BRACKET", Key::LeftBracket }, + { "BACKSLASH", Key::BackSlash }, + { "RIGHT_BRACKET", Key::RightBracket }, + { "GRAVE_ACCENT", Key::GraveAccent }, + { "WORLD_1", Key::World1 }, + { "WORLD_2", Key::World2 }, + { "ESC", Key::Escape }, + { "ESCAPE", Key::Escape}, + { "ENTER", Key::Enter }, + { "TAB", Key::Tab }, + { "BACKSPACE", Key::BackSpace }, + { "INSERT", Key::Insert }, + { "DEL", Key::Delete }, + { "DELETE", Key::Delete }, + { "RIGHT", Key::Right }, + { "LEFT", Key::Left }, + { "DOWN", Key::Down }, + { "UP", Key::Up }, + { "PAGEUP", Key::PageUp }, + { "PAGEDOWN", Key::PageDown }, + { "PAGE_UP", Key::PageUp }, + { "PAGE_DOWN", Key::PageDown }, + { "HOME", Key::Home }, + { "END", Key::End }, + { "CAPS_LOCK", Key::CapsLock }, + { "SCROLL_LOCK", Key::ScrollLock }, + { "NUM_LOCK", Key::NumLock }, + { "PRINT_SCREEN", Key::PrintScreen }, + { "PAUSE", Key::Pause }, + { "F1", Key::F1 }, + { "F2", Key::F2 }, + { "F3", Key::F3 }, + { "F4", Key::F4 }, + { "F5", Key::F5 }, + { "F6", Key::F6 }, + { "F7", Key::F7 }, + { "F8", Key::F8 }, + { "F9", Key::F9 }, + { "F10", Key::F10 }, + { "F11", Key::F11 }, + { "F12", Key::F12 }, + { "F13", Key::F13 }, + { "F14", Key::F14 }, + { "F15", Key::F15 }, + { "F16", Key::F16 }, + { "F17", Key::F17 }, + { "F18", Key::F18 }, + { "F19", Key::F19 }, + { "F20", Key::F20 }, + { "F21", Key::F21 }, + { "F22", Key::F22 }, + { "F23", Key::F23 }, + { "F24", Key::F24 }, + { "F25", Key::F25 }, + { "KP_0", Key::Keypad0 }, + { "KP_1", Key::Keypad1 }, + { "KP_2", Key::Keypad2 }, + { "KP_3", Key::Keypad3 }, + { "KP_4", Key::Keypad4 }, + { "KP_5", Key::Keypad5 }, + { "KP_6", Key::Keypad6 }, + { "KP_7", Key::Keypad7 }, + { "KP_8", Key::Keypad8 }, + { "KP_9", Key::Keypad9 }, + { "KP_DECIMAL", Key::KeypadDecimal }, + { "KP_DIVIDE", Key::KeypadDivide }, + { "KP_MULTIPLY", Key::KeypadMultiply }, + { "KP_SUBTRACT", Key::KeypadSubtract }, + { "KP_ADD", Key::KeypadAdd }, + { "KP_ENTER", Key::KeypadEnter }, + { "KP_EQUAL", Key::KeypadEnter }, + { "LSHIFT", Key::LeftShift }, + { "LEFT_SHIFT", Key::LeftShift }, + { "LCTRL", Key::LeftControl }, + { "LEFT_CONTROL", Key::LeftControl }, + { "LALT", Key::LeftAlt }, + { "LEFT_ALT", Key::LeftAlt }, + { "LEFT_SUPER", Key::LeftSuper }, + { "RSHIFT", Key::RightShift }, + { "RIGHT_SHIFT", Key::RightShift }, + { "RCTRL", Key::RightControl }, + { "RIGHT_CONTROL", Key::RightControl }, + { "RALT", Key::RightAlt }, + { "RIGHT_ALT", Key::RightAlt }, + { "RIGHT_SUPER", Key::RightSuper }, + { "MENU", Key::Menu } +}; + } // namespace openspace diff --git a/include/openspace/interaction/mouse.h b/include/openspace/util/mouse.h similarity index 56% rename from include/openspace/interaction/mouse.h rename to include/openspace/util/mouse.h index bba0b56e5f..73c5aa940a 100644 --- a/include/openspace/interaction/mouse.h +++ b/include/openspace/util/mouse.h @@ -22,36 +22,64 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ +// This file is based on the definitions as presented in the GLFW library: +/************************************************************************* + * GLFW 3.1 - www.glfw.org + * A library for OpenGL, window and input + *------------------------------------------------------------------------ + * Copyright (c) 2002-2006 Marcus Geelnard + * Copyright (c) 2006-2010 Camilla Berglund + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would + * be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not + * be misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + * + *************************************************************************/ + +// All values that are defined here are compatible with (and are based on) the +// definitions GLFW v3.1 + #ifndef __MOUSE_H__ #define __MOUSE_H__ -#include - namespace openspace { -namespace interaction { enum class MouseAction { - Press = SGCT_PRESS, - Release = SGCT_RELEASE, - Repeat = SGCT_REPEAT + Release = 0, + Press = 1, + Repeat = 2 }; enum class MouseButton { - Left = SGCT_MOUSE_BUTTON_LEFT, - Right = SGCT_MOUSE_BUTTON_RIGHT, - Middle = SGCT_MOUSE_BUTTON_MIDDLE, - //Button1 = SGCT_MOUSE_BUTTON_1, - //Button2 = SGCT_MOUSE_BUTTON_2, - //Button3 = SGCT_MOUSE_BUTTON_3, - //Button4 = SGCT_MOUSE_BUTTON_4, - //Button5 = SGCT_MOUSE_BUTTON_5, - //Button6 = SGCT_MOUSE_BUTTON_6, - //Button7 = SGCT_MOUSE_BUTTON_7, - //Button8 = SGCT_MOUSE_BUTTON_8, - ButtonLast = SGCT_MOUSE_BUTTON_LAST, + Button1 = 0, + Button2 = 1, + Button3 = 2, + Button4 = 3, + Button5 = 4, + Button6 = 5, + Button7 = 6, + Button8 = 8, + Last = Button8, + Left = Button1, + Right = Button2, + Middle = Button3 }; -} // namespace interaction } // namespace openspace #endif // __MOUSE_H__ diff --git a/modules/onscreengui/include/gui.h b/modules/onscreengui/include/gui.h index 00e2c623cb..c835a5ff66 100644 --- a/modules/onscreengui/include/gui.h +++ b/modules/onscreengui/include/gui.h @@ -32,6 +32,9 @@ #include #include +#include +#include + namespace openspace { namespace gui { @@ -49,12 +52,14 @@ public: void initializeGL(); void deinitializeGL(); - bool mouseButtonCallback(int key, int action); + bool mouseButtonCallback(MouseButton button, MouseAction action); +// bool mouseButtonCallback(int key, int action); bool mouseWheelCallback(double position); - bool keyCallback(int key, int action); + bool keyCallback(Key key, KeyAction action); +// bool keyCallback(int key, int action); bool charCallback(unsigned int character); - void startFrame(float deltaTime, const glm::vec2& windowSize, const glm::vec2& mousePos, bool mouseButtonsPressed[2]); + void startFrame(float deltaTime, const glm::vec2& windowSize, const glm::vec2& mousePos, uint32_t mouseButtons); void endFrame(); void renderMainWindow(); diff --git a/modules/onscreengui/src/gui.cpp b/modules/onscreengui/src/gui.cpp index 752881d563..81a503fb35 100644 --- a/modules/onscreengui/src/gui.cpp +++ b/modules/onscreengui/src/gui.cpp @@ -257,7 +257,7 @@ void GUI::deinitializeGL() { void GUI::startFrame(float deltaTime, const glm::vec2& windowSize, const glm::vec2& mousePos, - bool mouseButtonsPressed[2]) + uint32_t mouseButtonsPressed) { ImGuiIO& io = ImGui::GetIO(); @@ -268,8 +268,8 @@ void GUI::startFrame(float deltaTime, #else io.MousePos = ImVec2(mousePos.x, mousePos.y); #endif - io.MouseDown[0] = mouseButtonsPressed[0]; - io.MouseDown[1] = mouseButtonsPressed[1]; + io.MouseDown[0] = mouseButtonsPressed & (1 << 0); + io.MouseDown[1] = mouseButtonsPressed & (1 << 1); ImGui::NewFrame(); } @@ -287,7 +287,8 @@ void GUI::endFrame() { ImGui::Render(); } -bool GUI::mouseButtonCallback(int key, int action) { +bool GUI::mouseButtonCallback(MouseButton button, MouseAction action) { +//bool GUI::mouseButtonCallback(int key, int action) { ImGuiIO& io = ImGui::GetIO(); bool consumeEvent = io.WantCaptureMouse; return consumeEvent; @@ -302,14 +303,20 @@ bool GUI::mouseWheelCallback(double position) { return consumeEvent; } -bool GUI::keyCallback(int key, int action) { +bool GUI::keyCallback(Key key, KeyAction action) { +//bool GUI::keyCallback(int key, int action) { ImGuiIO& io = ImGui::GetIO(); bool consumeEvent = io.WantCaptureKeyboard; if (consumeEvent) { - if (action == SGCT_PRESS) - io.KeysDown[key] = true; - if (action == SGCT_RELEASE) - io.KeysDown[key] = false; + int keyIndex = static_cast(key); + if (keyIndex < 0) + LERROR("Pressed key of index '" << keyIndex << "' was negative"); + else { + if (action == KeyAction::Press) + io.KeysDown[keyIndex] = true; + if (action == KeyAction::Release) + io.KeysDown[keyIndex] = false; + } } return consumeEvent; } diff --git a/openspace.cfg b/openspace.cfg index 6c9f304463..cad9aaf1f8 100644 --- a/openspace.cfg +++ b/openspace.cfg @@ -7,7 +7,7 @@ return { -- Sets the scene that is to be loaded by OpenSpace. A scene file is a description -- of all entities that will be visible during an instance of OpenSpace - Scene = "${SCENE}/default_nh.scene", + Scene = "${SCENE}/default.scene", Paths = { SGCT = "${BASE_PATH}/config/sgct", diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f4e59f7eac..268023182c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -107,7 +107,6 @@ set(OPENSPACE_HEADER ${OPENSPACE_BASE_DIR}/include/openspace/interaction/interactionhandler.h ${OPENSPACE_BASE_DIR}/include/openspace/interaction/keyboardcontroller.h ${OPENSPACE_BASE_DIR}/include/openspace/interaction/luaconsole.h - ${OPENSPACE_BASE_DIR}/include/openspace/interaction/mouse.h ${OPENSPACE_BASE_DIR}/include/openspace/interaction/mousecontroller.h ${OPENSPACE_BASE_DIR}/include/openspace/interaction/externalcontrol/externalconnectioncontroller.h ${OPENSPACE_BASE_DIR}/include/openspace/interaction/externalcontrol/externalcontrol.h @@ -148,6 +147,7 @@ set(OPENSPACE_HEADER ${OPENSPACE_BASE_DIR}/include/openspace/util/factorymanager.h ${OPENSPACE_BASE_DIR}/include/openspace/util/factorymanager.inl ${OPENSPACE_BASE_DIR}/include/openspace/util/keys.h + ${OPENSPACE_BASE_DIR}/include/openspace/util/mouse.h ${OPENSPACE_BASE_DIR}/include/openspace/util/openspacemodule.h ${OPENSPACE_BASE_DIR}/include/openspace/util/powerscaledcoordinate.h ${OPENSPACE_BASE_DIR}/include/openspace/util/powerscaledscalar.h diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index e534d36071..791bdd8253 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -689,44 +689,33 @@ void OpenSpaceEngine::postSynchronizationPreDraw() { _renderEngine->postSynchronizationPreDraw(); - if (_isMaster && _gui->isEnabled()) { + if (_isMaster && _gui->isEnabled() && _windowHandler->isRegularRendering()) { glm::vec2 mousePosition = _windowHandler->mousePosition(); glm::ivec2 windowResolution = _windowHandler->currentWindowResolution(); + uint32_t mouseButtons = _windowHandler->mouseButtons(2); + + double dt = _windowHandler->averageDeltaTime(); - int button0 = sgct::Engine::instance()->getMouseButton(0, 0); - int button1 = sgct::Engine::instance()->getMouseButton(0, 1); - bool buttons[2] = { button0 != 0, button1 != 0 }; - - double dt = std::max(sgct::Engine::instance()->getDt(), 1.0/60.0); - _gui->startFrame(static_cast(dt), glm::vec2(windowResolution), mousePosition, buttons); + _gui->startFrame(static_cast(dt), glm::vec2(windowResolution), mousePosition, mouseButtons); } } void OpenSpaceEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &viewMatrix) { _renderEngine->render(projectionMatrix, viewMatrix); - if (_isMaster) { - // If currently writing a command, render it to screen - sgct::SGCTWindow* w = sgct::Engine::instance()->getCurrentWindowPtr(); - // !w->isUsingFisheyeRendering() does not exist anymore ---abock - // if (_isMaster && !w->isUsingFisheyeRendering() && _console->isVisible()) { - if (_isMaster && _console->isVisible()) { + if (_isMaster && _windowHandler->isRegularRendering()) { + if (_console->isVisible()) _console->render(); - } - if (_gui->isEnabled()) _gui->endFrame(); } } void OpenSpaceEngine::postDraw() { - //if (_isMaster) - //_interactionHandler.unlockControls(); - _renderEngine->postDraw(); } -void OpenSpaceEngine::keyboardCallback(int key, int action) { +void OpenSpaceEngine::keyboardCallback(Key key, KeyModifier mod, KeyAction action) { if (_isMaster) { if (_gui->isEnabled()) { bool isConsumed = _gui->keyCallback(key, action); @@ -734,7 +723,7 @@ void OpenSpaceEngine::keyboardCallback(int key, int action) { return; } - if (static_cast(key) == _console->commandInputButton() && (action == SGCT_PRESS || action == SGCT_REPEAT)) + if (key == _console->commandInputButton() && (action == KeyAction::Press || action == KeyAction::Release)) _console->toggleVisibility(); if (!_console->isVisible()) { @@ -760,15 +749,15 @@ void OpenSpaceEngine::charCallback(unsigned int codepoint) { } } -void OpenSpaceEngine::mouseButtonCallback(int key, int action) { +void OpenSpaceEngine::mouseButtonCallback(MouseButton button, MouseAction action) { if (_isMaster) { if (_gui->isEnabled()) { - bool isConsumed = _gui->mouseButtonCallback(key, action); - if (isConsumed && action != SGCT_RELEASE) + bool isConsumed = _gui->mouseButtonCallback(button, action); + if (isConsumed && action != MouseAction::Release) return; } - _interactionHandler->mouseButtonCallback(key, action); + _interactionHandler->mouseButtonCallback(button, action); } } diff --git a/src/engine/sgctwindowhandler.cpp b/src/engine/sgctwindowhandler.cpp index f60af53d05..c2e8d3062c 100644 --- a/src/engine/sgctwindowhandler.cpp +++ b/src/engine/sgctwindowhandler.cpp @@ -48,20 +48,44 @@ double SGCTWindowHandler::averageDeltaTime() { } glm::vec2 SGCTWindowHandler::mousePosition() { + int id = sgct::Engine::instance()->getCurrentWindowPtr()->getId(); double posX, posY; - sgct::Engine::instance()->getMousePos(0, &posX, &posY); + sgct::Engine::instance()->getMousePos(id, &posX, &posY); return glm::vec2(posX, posY); } +uint32_t SGCTWindowHandler::mouseButtons(int maxNumber) { + int id = sgct::Engine::instance()->getCurrentWindowPtr()->getId(); + uint32_t result = 0; + for (int i = 0; i < maxNumber; ++i) { + bool button = (sgct::Engine::instance()->getMouseButton(id, i) != 0); + if (button) + result |= (1 << i); + + } + return result; +} + glm::ivec2 SGCTWindowHandler::currentWindowSize() { - return glm::ivec2(0); + return glm::ivec2(sgct::Engine::instance()->getCurrentWindowPtr()->getXResolution(), + sgct::Engine::instance()->getCurrentWindowPtr()->getYResolution()); } glm::ivec2 SGCTWindowHandler::currentWindowResolution() { int x,y; - sgct::Engine::instance()->getWindowPtr(0)->getFinalFBODimensions(x, y); + sgct::Engine::instance()->getCurrentWindowPtr()->getFinalFBODimensions(x, y); return glm::ivec2(x, y); } + +bool SGCTWindowHandler::isRegularRendering() { + // TODO: Needs to implement the nonlinear rendering check ---abock + + // sgct::SGCTWindow* w = sgct::Engine::instance()->getCurrentWindowPtr(); + // !w->isUsingFisheyeRendering() does not exist anymore ---abock + // if (_isMaster && !w->isUsingFisheyeRendering() && _console->isVisible()) { + + return true; +} //void forEachWindow(std::function function) { // size_t n = sgct::Engine::instance()->getNumberOfWindows(); diff --git a/src/interaction/interactionhandler.cpp b/src/interaction/interactionhandler.cpp index 55c90177a9..1dc3bd9953 100644 --- a/src/interaction/interactionhandler.cpp +++ b/src/interaction/interactionhandler.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -37,149 +38,16 @@ namespace { const std::string _loggerCat = "InteractionHandler"; - int stringToKey(std::string s) { - - static std::map m = { - { "SPACE", SGCT_KEY_SPACE }, - { "APOSTROPHE", SGCT_KEY_APOSTROPHE }, - { "COMMA", SGCT_KEY_COMMA }, - { "MINUS", SGCT_KEY_MINUS }, - { "PERIOD", SGCT_KEY_PERIOD }, - { "APOSTROPHE", SGCT_KEY_SLASH }, - { "0", SGCT_KEY_0 }, - { "1", SGCT_KEY_1 }, - { "2", SGCT_KEY_2 }, - { "3", SGCT_KEY_3 }, - { "4", SGCT_KEY_4 }, - { "5", SGCT_KEY_5 }, - { "6", SGCT_KEY_6 }, - { "7", SGCT_KEY_7 }, - { "8", SGCT_KEY_8 }, - { "9", SGCT_KEY_9 }, - { "SEMICOLON", SGCT_KEY_SEMICOLON }, - { "EQUAL", SGCT_KEY_EQUAL }, - { "A", SGCT_KEY_A }, - { "B", SGCT_KEY_B }, - { "C", SGCT_KEY_C }, - { "D", SGCT_KEY_D }, - { "E", SGCT_KEY_E }, - { "F", SGCT_KEY_F }, - { "G", SGCT_KEY_G }, - { "H", SGCT_KEY_H }, - { "I", SGCT_KEY_I }, - { "J", SGCT_KEY_J }, - { "K", SGCT_KEY_K }, - { "L", SGCT_KEY_L }, - { "M", SGCT_KEY_M }, - { "N", SGCT_KEY_N }, - { "O", SGCT_KEY_O }, - { "P", SGCT_KEY_P }, - { "Q", SGCT_KEY_Q }, - { "R", SGCT_KEY_R }, - { "S", SGCT_KEY_S }, - { "T", SGCT_KEY_T }, - { "U", SGCT_KEY_U }, - { "V", SGCT_KEY_V }, - { "W", SGCT_KEY_W }, - { "X", SGCT_KEY_X }, - { "Y", SGCT_KEY_Y }, - { "Z", SGCT_KEY_Z }, - { "LEFT_BRACKET", SGCT_KEY_LEFT_BRACKET }, - { "BACKSLASH", SGCT_KEY_BACKSLASH }, - { "RIGHT_BRACKET", SGCT_KEY_RIGHT_BRACKET }, - { "GRAVE_ACCENT", SGCT_KEY_GRAVE_ACCENT }, - { "WORLD_1", SGCT_KEY_WORLD_1 }, - { "WORLD_2", SGCT_KEY_WORLD_2 }, - { "ESC", SGCT_KEY_ESC }, - { "ESCAPE", SGCT_KEY_ESCAPE }, - { "ENTER", SGCT_KEY_ENTER }, - { "TAB", SGCT_KEY_TAB }, - { "BACKSPACE", SGCT_KEY_BACKSPACE }, - { "INSERT", SGCT_KEY_INSERT }, - { "DEL", SGCT_KEY_DEL }, - { "DELETE", SGCT_KEY_DELETE }, - { "RIGHT", SGCT_KEY_RIGHT }, - { "LEFT", SGCT_KEY_LEFT }, - { "DOWN", SGCT_KEY_DOWN }, - { "UP", SGCT_KEY_UP }, - { "PAGEUP", SGCT_KEY_PAGEUP }, - { "PAGEDOWN", SGCT_KEY_PAGEDOWN }, - { "PAGE_UP", SGCT_KEY_PAGE_UP }, - { "PAGE_DOWN", SGCT_KEY_PAGE_DOWN }, - { "HOME", SGCT_KEY_HOME }, - { "END", SGCT_KEY_END }, - { "CAPS_LOCK", SGCT_KEY_CAPS_LOCK }, - { "SCROLL_LOCK", SGCT_KEY_SCROLL_LOCK }, - { "NUM_LOCK", SGCT_KEY_NUM_LOCK }, - { "PRINT_SCREEN", SGCT_KEY_PRINT_SCREEN }, - { "PAUSE", SGCT_KEY_PAUSE }, - { "F1", SGCT_KEY_F1 }, - { "F2", SGCT_KEY_F2 }, - { "F3", SGCT_KEY_F3 }, - { "F4", SGCT_KEY_F4 }, - { "F5", SGCT_KEY_F5 }, - { "F6", SGCT_KEY_F6 }, - { "F7", SGCT_KEY_F7 }, - { "F8", SGCT_KEY_F8 }, - { "F9", SGCT_KEY_F9 }, - { "F10", SGCT_KEY_F10 }, - { "F11", SGCT_KEY_F11 }, - { "F12", SGCT_KEY_F12 }, - { "F13", SGCT_KEY_F13 }, - { "F14", SGCT_KEY_F14 }, - { "F15", SGCT_KEY_F15 }, - { "F16", SGCT_KEY_F16 }, - { "F17", SGCT_KEY_F17 }, - { "F18", SGCT_KEY_F18 }, - { "F19", SGCT_KEY_F19 }, - { "F20", SGCT_KEY_F20 }, - { "F21", SGCT_KEY_F21 }, - { "F22", SGCT_KEY_F22 }, - { "F23", SGCT_KEY_F23 }, - { "F24", SGCT_KEY_F24 }, - { "F25", SGCT_KEY_F25 }, - { "KP_0", SGCT_KEY_KP_0 }, - { "KP_1", SGCT_KEY_KP_1 }, - { "KP_2", SGCT_KEY_KP_2 }, - { "KP_3", SGCT_KEY_KP_3 }, - { "KP_4", SGCT_KEY_KP_4 }, - { "KP_5", SGCT_KEY_KP_5 }, - { "KP_6", SGCT_KEY_KP_6 }, - { "KP_7", SGCT_KEY_KP_7 }, - { "KP_8", SGCT_KEY_KP_8 }, - { "KP_9", SGCT_KEY_KP_9 }, - { "KP_DECIMAL", SGCT_KEY_KP_DECIMAL }, - { "KP_DIVIDE", SGCT_KEY_KP_DIVIDE }, - { "KP_MULTIPLY", SGCT_KEY_KP_MULTIPLY }, - { "KP_SUBTRACT", SGCT_KEY_KP_SUBTRACT }, - { "KP_ADD", SGCT_KEY_KP_ADD }, - { "KP_ENTER", SGCT_KEY_KP_ENTER }, - { "KP_EQUAL", SGCT_KEY_KP_EQUAL }, - { "LSHIFT", SGCT_KEY_LSHIFT }, - { "LEFT_SHIFT", SGCT_KEY_LEFT_SHIFT }, - { "LCTRL", SGCT_KEY_LCTRL }, - { "LEFT_CONTROL", SGCT_KEY_LEFT_CONTROL }, - { "LALT", SGCT_KEY_LALT }, - { "LEFT_ALT", SGCT_KEY_LEFT_ALT }, - { "LEFT_SUPER", SGCT_KEY_LEFT_SUPER }, - { "RSHIFT", SGCT_KEY_RSHIFT }, - { "RIGHT_SHIFT", SGCT_KEY_RIGHT_SHIFT }, - { "RCTRL", SGCT_KEY_RCTRL }, - { "RIGHT_CONTROL", SGCT_KEY_RIGHT_CONTROL }, - { "RALT", SGCT_KEY_RALT }, - { "RIGHT_ALT", SGCT_KEY_RIGHT_ALT }, - { "RIGHT_SUPER", SGCT_KEY_RIGHT_SUPER }, - { "MENU", SGCT_KEY_MENU } - }; + openspace::Key stringToKey(std::string s) { // key only uppercase std::transform(s.begin(), s.end(), s.begin(), ::toupper); // default is unknown - int key = SGCT_KEY_UNKNOWN; - auto it = m.find(s); - if (it != m.end()) - key = m[s]; - return key; + auto it = openspace::KeyMapping.find(s); + if (it != openspace::KeyMapping.end()) + return it->second; + else + return openspace::Key::Unknown; } } @@ -479,9 +347,9 @@ const Camera* const InteractionHandler::camera() const { // } //} -void InteractionHandler::mouseButtonCallback(int button, int action) { +void InteractionHandler::mouseButtonCallback(MouseButton button, MouseAction action) { if (_mouseController) - _mouseController->button(MouseAction(action), MouseButton(button)); + _mouseController->button(button, action); } void InteractionHandler::mousePositionCallback(double x, double y) { @@ -768,11 +636,11 @@ void InteractionHandler::lookAt(const glm::quat& rotation) // } //} // -void InteractionHandler::keyboardCallback(int key, int action) { +void InteractionHandler::keyboardCallback(Key key, KeyAction action) { // TODO package in script const float speed = _controllerSensitivity; const float dt = static_cast(_deltaTime); - if (action == SGCT_PRESS || action == SGCT_REPEAT) { + if (action == KeyAction::Press || action == KeyAction::Repeat) { /*if (key == SGCT_KEY_S) { glm::vec3 euler(speed * dt, 0.0, 0.0); @@ -800,32 +668,32 @@ void InteractionHandler::keyboardCallback(int key, int action) { if (key == SGCT_KEY_X) { Time::ref().advanceTime(-sgct::Engine::instance()->getDt()); }*/ - if (key == 262) { + if (key == Key::Right) { glm::vec3 euler(0.0, speed * dt*0.4, 0.0); glm::quat rot = glm::quat(euler); rotateDelta(rot); } - if (key == 263) { + if (key == Key::Left) { glm::vec3 euler(0.0, -speed * dt*0.4, 0.0); glm::quat rot = glm::quat(euler); rotateDelta(rot); } - if (key == 264) { + if (key == Key::Down) { glm::vec3 euler(speed * dt*0.4, 0.0, 0.0); glm::quat rot = glm::quat(euler); rotateDelta(rot); } - if (key == 265) { + if (key == Key::Up) { glm::vec3 euler(-speed * dt*0.4, 0.0, 0.0); glm::quat rot = glm::quat(euler); rotateDelta(rot); } - if (key == SGCT_KEY_KP_SUBTRACT) { + if (key == Key::KeypadSubtract) { glm::vec2 s = OsEng.renderEngine()->camera()->scaling(); s[1] -= 0.5f; OsEng.renderEngine()->camera()->setScaling(s); } - if (key == SGCT_KEY_KP_ADD) { + if (key == Key::KeypadAdd) { glm::vec2 s = OsEng.renderEngine()->camera()->scaling(); s[1] += 0.5f; OsEng.renderEngine()->camera()->setScaling(s); @@ -886,7 +754,7 @@ void InteractionHandler::resetKeyBindings() { _validKeyLua = false; } -void InteractionHandler::bindKey(int key, const std::string& lua) { +void InteractionHandler::bindKey(Key key, std::string lua) { _keyLua.insert(std::make_pair(key, lua)); } diff --git a/src/interaction/interactionhandler_lua.inl b/src/interaction/interactionhandler_lua.inl index ee87c72341..c735aefb61 100644 --- a/src/interaction/interactionhandler_lua.inl +++ b/src/interaction/interactionhandler_lua.inl @@ -76,9 +76,9 @@ int bindKey(lua_State* L) { if (command.empty()) return luaL_error(L, "Command string is empty"); - int iKey = stringToKey(key); + openspace::Key iKey = stringToKey(key); - if (iKey == SGCT_KEY_UNKNOWN) { + if (iKey == openspace::Key::Unknown) { LERROR("Could not find key '"<< key <<"'"); return 0; } diff --git a/src/interaction/luaconsole.cpp b/src/interaction/luaconsole.cpp index 211c02dfbb..2d26a6be72 100644 --- a/src/interaction/luaconsole.cpp +++ b/src/interaction/luaconsole.cpp @@ -103,8 +103,8 @@ void LuaConsole::deinitialize() { } } -void LuaConsole::keyboardCallback(int key, int action) { - if (action == SGCT_PRESS || action == SGCT_REPEAT) { +void LuaConsole::keyboardCallback(Key key, KeyAction action) { + if (action == KeyAction::Press || action == KeyAction::Release) { const size_t windowIndex = sgct::Engine::instance()->getFocusedWindowIndex(); const bool modifierControl = sgct::Engine::instance()->getKey(windowIndex, SGCT_KEY_LEFT_CONTROL) || sgct::Engine::instance()->getKey(windowIndex, SGCT_KEY_RIGHT_CONTROL); @@ -112,37 +112,37 @@ void LuaConsole::keyboardCallback(int key, int action) { sgct::Engine::instance()->getKey(windowIndex, SGCT_KEY_RIGHT_SHIFT); // Paste from clipboard - if (modifierControl && (key == SGCT_KEY_V)) + if (modifierControl && (key == Key::V)) addToCommand(ghoul::clipboardText()); // Copy to clipboard - if (modifierControl && (key == SGCT_KEY_C)) + if (modifierControl && (key == Key::C)) ghoul::setClipboardText(_commands.at(_activeCommand)); // Go to the previous character - if ((key == SGCT_KEY_LEFT) && (_inputPosition > 0)) + if ((key == Key::Left) && (_inputPosition > 0)) --_inputPosition; // Go to the next character - if ((key == SGCT_KEY_RIGHT) && _inputPosition < _commands.at(_activeCommand).length()) + if ((key == Key::Right) && _inputPosition < _commands.at(_activeCommand).length()) ++_inputPosition; // Go to previous command - if (key == SGCT_KEY_UP) { + if (key == Key::Up) { if (_activeCommand > 0) --_activeCommand; _inputPosition = _commands.at(_activeCommand).length(); } // Go to next command (the last is empty) - if (key == SGCT_KEY_DOWN) { + if (key == Key::Down) { if (_activeCommand < _commands.size() - 1) ++_activeCommand; _inputPosition = _commands.at(_activeCommand).length(); } // Remove character before _inputPosition - if (key == SGCT_KEY_BACKSPACE) { + if (key == Key::BackSpace) { if (_inputPosition > 0) { _commands.at(_activeCommand).erase(_inputPosition - 1, 1); --_inputPosition; @@ -150,18 +150,18 @@ void LuaConsole::keyboardCallback(int key, int action) { } // Remove character after _inputPosition - if ((key == SGCT_KEY_DELETE) && (_inputPosition <= _commands.at(_activeCommand).size())) + if ((key == Key::Delete) && (_inputPosition <= _commands.at(_activeCommand).size())) _commands.at(_activeCommand).erase(_inputPosition, 1); // Go to the beginning of command string - if (key == SGCT_KEY_HOME) + if (key == Key::Home) _inputPosition = 0; // Go to the end of command string - if (key == SGCT_KEY_END) + if (key == Key::End) _inputPosition = _commands.at(_activeCommand).size(); - if (key == SGCT_KEY_ENTER) { + if (key == Key::Enter) { // SHIFT+ENTER == new line if (modifierShift) addToCommand("\n"); @@ -188,7 +188,7 @@ void LuaConsole::keyboardCallback(int key, int action) { } } - if (key == SGCT_KEY_TAB) { + if (key == Key::Tab) { // We get a list of all the available commands and initially find the first // command that starts with how much we typed sofar. We store the index so // that in subsequent "tab" presses, we will discard previous commands. This @@ -265,7 +265,7 @@ void LuaConsole::keyboardCallback(int key, int action) { } void LuaConsole::charCallback(unsigned int codepoint) { - if (codepoint == commandInputButton()) + if (codepoint == static_cast(commandInputButton())) return; #ifndef WIN32 @@ -321,10 +321,10 @@ void LuaConsole::render() { sgct_text::print(font, 15.0f + font_size*0.5f, startY - (font_size)*(n + 1)*3.0f / 2.0f, green, ss.str().c_str(), "^"); } -unsigned int LuaConsole::commandInputButton() { +Key LuaConsole::commandInputButton() { // Button left of 1 and above TAB // How to deal with different keyboard languages? ---abock - return SGCT_KEY_GRAVE_ACCENT; + return Key::GraveAccent; } void LuaConsole::addToCommand(std::string c) { diff --git a/src/interaction/mousecontroller.cpp b/src/interaction/mousecontroller.cpp index ba816eb91b..a860cc4b01 100644 --- a/src/interaction/mousecontroller.cpp +++ b/src/interaction/mousecontroller.cpp @@ -25,6 +25,7 @@ #include #include +#include #include @@ -72,9 +73,8 @@ glm::vec3 MouseController::mapToCamera(glm::vec3 trackballPos) { void MouseController::trackballRotate(int x, int y) { // Normalize mouse coordinates to [0,1] - float width = static_cast(sgct::Engine::instance()->getCurrentXResolution()); - float height = static_cast(sgct::Engine::instance()->getCurrentYResolution()); - glm::vec2 mousePos = glm::vec2((float)x / width, (float)y / height); + glm::vec2 res = OsEng.windowWrapper()->currentWindowSize(); + glm::vec2 mousePos = glm::vec2((float)x / res.x, (float)y / res.y); mousePos = glm::clamp(mousePos, -0.5f, 1.5f); // Ugly fix #1: Camera position becomes NaN on mouse values outside [-0.5, 1.5] //mousePos[1] = 0.5; // Ugly fix #2: Tempoarily only allow rotation around y @@ -116,7 +116,7 @@ TrackballMouseController::TrackballMouseController() , _leftMouseButtonDown(false) {} -void TrackballMouseController::button(MouseAction action, MouseButton button) { +void TrackballMouseController::button(MouseButton button, MouseAction action) { if (button == MouseButton::Left && action == MouseAction::Press) _leftMouseButtonDown = true; else if (button == MouseButton::Left && action == MouseAction::Release) { @@ -162,13 +162,11 @@ OrbitalMouseController::OrbitalMouseController() } } -void OrbitalMouseController::button(MouseAction action, MouseButton button) { +void OrbitalMouseController::button(MouseButton button, MouseAction action) { if (button == MouseButton::Left){ if (action == MouseAction::Press){ _leftMouseButtonDown = true; - double mouseX, mouseY; - sgct::Engine::instance()->getMousePos(sgct::Engine::instance()->getCurrentWindowPtr()->getId(), &mouseX, &mouseY); - _previousCursorPos[MouseButtons::ButtonLeft] = glm::vec2(static_cast(mouseX), static_cast(mouseY)); + _previousCursorPos[MouseButtons::ButtonLeft] = OsEng.windowWrapper()->mousePosition(); } else if (action == MouseAction::Release) { _leftMouseButtonDown = false; @@ -178,9 +176,7 @@ void OrbitalMouseController::button(MouseAction action, MouseButton button) { else if (button == MouseButton::Right){ if (action == MouseAction::Press){ _rightMouseButtonDown = true; - double mouseX, mouseY; - sgct::Engine::instance()->getMousePos(sgct::Engine::instance()->getCurrentWindowPtr()->getId(), &mouseX, &mouseY); - _previousCursorPos[MouseButtons::ButtonRight] = glm::vec2(static_cast(mouseX), static_cast(mouseY)); + _previousCursorPos[MouseButtons::ButtonRight] = OsEng.windowWrapper()->mousePosition(); } else if (action == MouseAction::Release) { _rightMouseButtonDown = false; @@ -190,9 +186,7 @@ void OrbitalMouseController::button(MouseAction action, MouseButton button) { else if (button == MouseButton::Middle){ if (action == MouseAction::Press){ _middleMouseButtonDown = true; - double mouseX, mouseY; - sgct::Engine::instance()->getMousePos(sgct::Engine::instance()->getCurrentWindowPtr()->getId(), &mouseX, &mouseY); - _previousCursorPos[MouseButtons::ButtonMiddle] = glm::vec2(static_cast(mouseX), static_cast(mouseY)); + _previousCursorPos[MouseButtons::ButtonMiddle] = OsEng.windowWrapper()->mousePosition(); } else if (action == MouseAction::Release) { _middleMouseButtonDown = false; @@ -203,19 +197,22 @@ void OrbitalMouseController::button(MouseAction action, MouseButton button) { } void OrbitalMouseController::move(float x, float y) { - int winID = sgct::Engine::instance()->getCurrentWindowPtr()->getId(); - double mouseX, mouseY; - sgct::Engine::instance()->getMousePos(winID, &mouseX, &mouseY); - _currentCursorPos = glm::vec2(static_cast(mouseX), static_cast(mouseY)); + _currentCursorPos = OsEng.windowWrapper()->mousePosition(); if (_leftMouseButtonDown) { - _currentCursorDiff[MouseButtons::ButtonLeft] = (_currentCursorPos - _previousCursorPos[MouseButtons::ButtonLeft]) / glm::vec2(static_cast(sgct::Engine::instance()->getWindowPtr(winID)->getXResolution()), static_cast(sgct::Engine::instance()->getWindowPtr(winID)->getYResolution())); + glm::vec2 diff = _currentCursorPos - _previousCursorPos[MouseButtons::ButtonLeft]; + glm::vec2 res = OsEng.windowWrapper()->currentWindowSize(); + _currentCursorDiff[MouseButtons::ButtonLeft] = diff / res; } if (_rightMouseButtonDown) { - _currentCursorDiff[MouseButtons::ButtonRight] = (_currentCursorPos - _previousCursorPos[MouseButtons::ButtonRight]) / glm::vec2(static_cast(sgct::Engine::instance()->getWindowPtr(winID)->getXResolution()), static_cast(sgct::Engine::instance()->getWindowPtr(winID)->getYResolution())); + glm::vec2 diff = _currentCursorPos - _previousCursorPos[MouseButtons::ButtonRight]; + glm::vec2 res = OsEng.windowWrapper()->currentWindowSize(); + _currentCursorDiff[MouseButtons::ButtonRight] = diff / res; } if (_middleMouseButtonDown) { - _currentCursorDiff[MouseButtons::ButtonMiddle] = (_currentCursorPos - _previousCursorPos[MouseButtons::ButtonMiddle]) / glm::vec2(static_cast(sgct::Engine::instance()->getWindowPtr(winID)->getXResolution()), static_cast(sgct::Engine::instance()->getWindowPtr(winID)->getYResolution())); + glm::vec2 diff = _currentCursorPos - _previousCursorPos[MouseButtons::ButtonMiddle]; + glm::vec2 res = OsEng.windowWrapper()->currentWindowSize(); + _currentCursorDiff[MouseButtons::ButtonMiddle] = diff / res; } } From 49dbb1ce2046de9d2e43e0a881f2614538074884 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 26 Oct 2015 09:19:28 -0500 Subject: [PATCH 017/122] More work on converting to SGCT window handler Adapting to change in SGCT key callback handling --- apps/OpenSpace/main.cpp | 13 ++++++----- include/openspace/abuffer/abuffer.h | 4 +++- include/openspace/engine/openspaceengine.h | 4 ++-- include/openspace/engine/sgctwindowhandler.h | 14 +++++++----- include/openspace/engine/windowhandler.h | 13 ++++++----- .../interaction/interactionhandler.h | 2 +- include/openspace/interaction/luaconsole.h | 4 ++-- modules/onscreengui/include/gui.h | 4 ++-- modules/onscreengui/src/gui.cpp | 4 ++-- src/abuffer/abuffer.cpp | 14 +++--------- src/abuffer/abuffervisualizer.cpp | 22 +++++++++++-------- src/engine/openspaceengine.cpp | 15 ++++++------- src/engine/sgctwindowhandler.cpp | 16 +++++++++----- src/interaction/interactionhandler.cpp | 14 ++++++------ src/interaction/luaconsole.cpp | 19 ++++++---------- 15 files changed, 81 insertions(+), 81 deletions(-) diff --git a/apps/OpenSpace/main.cpp b/apps/OpenSpace/main.cpp index 97672c3e3d..9dc5eef84f 100644 --- a/apps/OpenSpace/main.cpp +++ b/apps/OpenSpace/main.cpp @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -38,8 +39,8 @@ void mainPreSyncFunc(); void mainPostSyncPreDrawFunc(); void mainRenderFunc(); void mainPostDrawFunc(); -void mainKeyboardCallback(int key, int action); -void mainCharCallback(unsigned int codepoint); +void mainKeyboardCallback(int key, int scancode, int action, int mods); +void mainCharCallback(unsigned int codepoint, int mods); void mainMouseButtonCallback(int key, int action); void mainMousePosCallback(double x, double y); void mainMouseScrollCallback(double posX, double posY); @@ -246,10 +247,10 @@ void mainExternalControlCallback(const char* receivedChars, int size) { OsEng.externalControlCallback(receivedChars, size, 0); } -void mainKeyboardCallback(int key, int action) { +void mainKeyboardCallback(int key, int, int action, int mods) { if (OsEng.isMaster()) OsEng.keyboardCallback(openspace::Key(key), - openspace::KeyModifier::NoModifier, // TODO: fix ---abock + openspace::KeyModifier(mods), openspace::KeyAction(action)); } @@ -269,9 +270,9 @@ void mainMouseScrollCallback(double posX, double posY) { OsEng.mouseScrollWheelCallback(posY); } -void mainCharCallback(unsigned int codepoint) { +void mainCharCallback(unsigned int codepoint, int mods) { if (OsEng.isMaster()) - OsEng.charCallback(codepoint); + OsEng.charCallback(codepoint, openspace::KeyModifier(mods)); } void mainEncodeFun() { diff --git a/include/openspace/abuffer/abuffer.h b/include/openspace/abuffer/abuffer.h index 6252ffc06c..03ff58e0c9 100644 --- a/include/openspace/abuffer/abuffer.h +++ b/include/openspace/abuffer/abuffer.h @@ -84,7 +84,9 @@ protected: void openspaceSamplers(); void openspaceTransferFunction(); - unsigned int _width, _height, _totalPixels; + int _width; + int _height; + int _totalPixels; void updateDimensions(); diff --git a/include/openspace/engine/openspaceengine.h b/include/openspace/engine/openspaceengine.h index ec5144e1f4..309f735cdb 100644 --- a/include/openspace/engine/openspaceengine.h +++ b/include/openspace/engine/openspaceengine.h @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -50,7 +51,6 @@ class GUI; class RenderEngine; class SyncBuffer; class ModuleEngine; -class WindowHandler; namespace interaction { class InteractionHandler; @@ -106,7 +106,7 @@ public: void postDraw(); // void keyboardCallback(int key, int action); void keyboardCallback(Key key, KeyModifier mod, KeyAction action); - void charCallback(unsigned int codepoint); + void charCallback(unsigned int codepoint, KeyModifier mod); void mouseButtonCallback(MouseButton button, MouseAction action); void mousePositionCallback(double x, double y); void mouseScrollWheelCallback(double pos); diff --git a/include/openspace/engine/sgctwindowhandler.h b/include/openspace/engine/sgctwindowhandler.h index b0d903ac86..d7da63f406 100644 --- a/include/openspace/engine/sgctwindowhandler.h +++ b/include/openspace/engine/sgctwindowhandler.h @@ -34,13 +34,15 @@ public: void setBarrier(bool enabled) override; void clearAllWindows() override; - double averageDeltaTime() override; - glm::vec2 mousePosition() override; - uint32_t mouseButtons(int maxNumber) override; - glm::ivec2 currentWindowSize() override; - glm::ivec2 currentWindowResolution() override; + double averageDeltaTime() const override; + glm::vec2 mousePosition() const override; + uint32_t mouseButtons(int maxNumber) const override; + glm::ivec2 currentWindowSize() const override; + glm::ivec2 currentWindowResolution() const override; - bool isRegularRendering() override; + bool isRegularRendering() const override; + + glm::mat4 viewProjectionMatrix() const override; // void forEachWindow(std::function function) override; diff --git a/include/openspace/engine/windowhandler.h b/include/openspace/engine/windowhandler.h index 156f141305..82c44901f0 100644 --- a/include/openspace/engine/windowhandler.h +++ b/include/openspace/engine/windowhandler.h @@ -36,13 +36,14 @@ class WindowHandler { public: virtual void setBarrier(bool enabled) = 0; virtual void clearAllWindows() = 0; - virtual double averageDeltaTime() = 0; - virtual uint32_t mouseButtons(int maxNumber = 8) = 0; - virtual glm::vec2 mousePosition() = 0; - virtual glm::ivec2 currentWindowSize() = 0; - virtual glm::ivec2 currentWindowResolution() = 0; - virtual bool isRegularRendering() = 0; + virtual double averageDeltaTime() const = 0; + virtual uint32_t mouseButtons(int maxNumber = 8) const = 0; + virtual glm::vec2 mousePosition() const = 0; + virtual glm::ivec2 currentWindowSize() const = 0; + virtual glm::ivec2 currentWindowResolution() const = 0; + virtual bool isRegularRendering() const = 0; + virtual glm::mat4 viewProjectionMatrix() const = 0; diff --git a/include/openspace/interaction/interactionhandler.h b/include/openspace/interaction/interactionhandler.h index 23b6195a04..820854ed73 100644 --- a/include/openspace/interaction/interactionhandler.h +++ b/include/openspace/interaction/interactionhandler.h @@ -110,7 +110,7 @@ public: void setCamera(Camera* camera); const Camera* const camera() const; - void keyboardCallback(Key key, KeyAction action); + void keyboardCallback(Key key, KeyModifier modifier, KeyAction action); void mouseButtonCallback(MouseButton button, MouseAction action); void mousePositionCallback(double x, double y); void mouseScrollWheelCallback(double pos); diff --git a/include/openspace/interaction/luaconsole.h b/include/openspace/interaction/luaconsole.h index 63673394fe..b4c3d0406d 100644 --- a/include/openspace/interaction/luaconsole.h +++ b/include/openspace/interaction/luaconsole.h @@ -42,8 +42,8 @@ public: void initialize(); void deinitialize(); - void keyboardCallback(Key key, KeyAction action); - void charCallback(unsigned int codepoint); + void keyboardCallback(Key key, KeyModifier modifier, KeyAction action); + void charCallback(unsigned int codepoint, KeyModifier modifier); void render(); diff --git a/modules/onscreengui/include/gui.h b/modules/onscreengui/include/gui.h index c835a5ff66..0359ead253 100644 --- a/modules/onscreengui/include/gui.h +++ b/modules/onscreengui/include/gui.h @@ -55,9 +55,9 @@ public: bool mouseButtonCallback(MouseButton button, MouseAction action); // bool mouseButtonCallback(int key, int action); bool mouseWheelCallback(double position); - bool keyCallback(Key key, KeyAction action); + bool keyCallback(Key key, KeyModifier modifier, KeyAction action); // bool keyCallback(int key, int action); - bool charCallback(unsigned int character); + bool charCallback(unsigned int character, KeyModifier modifier); void startFrame(float deltaTime, const glm::vec2& windowSize, const glm::vec2& mousePos, uint32_t mouseButtons); void endFrame(); diff --git a/modules/onscreengui/src/gui.cpp b/modules/onscreengui/src/gui.cpp index 81a503fb35..ddcd52079d 100644 --- a/modules/onscreengui/src/gui.cpp +++ b/modules/onscreengui/src/gui.cpp @@ -303,7 +303,7 @@ bool GUI::mouseWheelCallback(double position) { return consumeEvent; } -bool GUI::keyCallback(Key key, KeyAction action) { +bool GUI::keyCallback(Key key, KeyModifier modifier, KeyAction action) { //bool GUI::keyCallback(int key, int action) { ImGuiIO& io = ImGui::GetIO(); bool consumeEvent = io.WantCaptureKeyboard; @@ -321,7 +321,7 @@ bool GUI::keyCallback(Key key, KeyAction action) { return consumeEvent; } -bool GUI::charCallback(unsigned int character) { +bool GUI::charCallback(unsigned int character, KeyModifier modifier) { ImGuiIO& io = ImGui::GetIO(); bool consumeEvent = io.WantCaptureKeyboard; diff --git a/src/abuffer/abuffer.cpp b/src/abuffer/abuffer.cpp index e39821ca6f..7f95ba302c 100644 --- a/src/abuffer/abuffer.cpp +++ b/src/abuffer/abuffer.cpp @@ -140,15 +140,6 @@ void ABuffer::resolve(float blackoutFactor) { _transferFunctions.at(i).second->bind(); } - // Decrease stepsize in volumes if right click is pressed - // TODO: Let the interactionhandler handle this - //int val = sgct::Engine::getMouseButton(0, SGCT_MOUSE_BUTTON_RIGHT); - //float volumeStepFactor = (val) ? 0.2f: 1.0f; - //if(volumeStepFactor != _volumeStepFactor) { - // _volumeStepFactor = volumeStepFactor; - // _resolveShader->setUniform("volumeStepFactor", _volumeStepFactor); - //} - glBindVertexArray(_screenQuad); glDrawArrays(GL_TRIANGLES, 0, 6); @@ -331,8 +322,9 @@ void ABuffer::invalidateABuffer() { } void ABuffer::updateDimensions() { - _width = sgct::Engine::instance()->getCurrentWindowPtr()->getXFramebufferResolution(); - _height = sgct::Engine::instance()->getCurrentWindowPtr()->getYFramebufferResolution(); + glm::ivec2 res = OsEng.windowWrapper()->currentWindowResolution(); + _width = res.x; + _height = res.y; _totalPixels = _width * _height; } diff --git a/src/abuffer/abuffervisualizer.cpp b/src/abuffer/abuffervisualizer.cpp index 7b1aaf528b..000c147a2a 100644 --- a/src/abuffer/abuffervisualizer.cpp +++ b/src/abuffer/abuffervisualizer.cpp @@ -25,6 +25,9 @@ #include #include +#include +#include + #include #include @@ -113,7 +116,7 @@ void ABufferVisualizer::render() { modelMatrix = glm::translate(modelMatrix, glm::vec3(0, 0, -1)); modelMatrix = modelMatrix * rotation; - _pointcloudProgram->setUniform("ViewProjection", sgct::Engine::instance()->getCurrentModelViewProjectionMatrix()); + _pointcloudProgram->setUniform("ViewProjection", OsEng.windowWrapper()->viewProjectionMatrix()); _pointcloudProgram->setUniform("ModelTransform", modelMatrix); #if defined(MARKER_POINTS) @@ -145,29 +148,30 @@ void ABufferVisualizer::render() { const glm::mat4 scale = glm::scale(glm::mat4(1.0), glm::vec3(0.04, 0.04, 0.04)); glm::mat4 translate, mvp; + const glm::mat4 viewProjMatrix = OsEng.windowWrapper()->viewProjectionMatrix(); translate = glm::translate(glm::mat4(1.0), glm::vec3(0, 0, 0)); - mvp = sgct::Engine::instance()->getCurrentModelViewProjectionMatrix()*modelMatrix*translate*rotationText*scale; + mvp = viewProjMatrix*modelMatrix*translate*rotationText*scale; Freetype::print3d(fontLight, mvp, "(0,0,0)"); translate = glm::translate(glm::mat4(1.0), glm::vec3(0, 0, 1)); - mvp = sgct::Engine::instance()->getCurrentModelViewProjectionMatrix()*modelMatrix*translate*rotationText*scale; + mvp = viewProjMatrix*modelMatrix*translate*rotationText*scale; Freetype::print3d(fontLight, mvp, "(0,0,1)"); translate = glm::translate(glm::mat4(1.0), glm::vec3(0, 1, 0)); - mvp = sgct::Engine::instance()->getCurrentModelViewProjectionMatrix()*modelMatrix*translate*rotationText*scale; + mvp = viewProjMatrix*modelMatrix*translate*rotationText*scale; Freetype::print3d(fontLight, mvp, "(0,1,0)"); translate = glm::translate(glm::mat4(1.0), glm::vec3(1, 0, 0)); - mvp = sgct::Engine::instance()->getCurrentModelViewProjectionMatrix()*modelMatrix*translate*rotationText*scale; + mvp = viewProjMatrix*modelMatrix*translate*rotationText*scale; Freetype::print3d(fontLight, mvp, "(1,0,0)"); translate = glm::translate(glm::mat4(1.0), glm::vec3(0, 1, 1)); - mvp = sgct::Engine::instance()->getCurrentModelViewProjectionMatrix()*modelMatrix*translate*rotationText*scale; + mvp = viewProjMatrix*modelMatrix*translate*rotationText*scale; Freetype::print3d(fontLight, mvp, "(0,1,1)"); translate = glm::translate(glm::mat4(1.0), glm::vec3(1, 0, 1)); - mvp = sgct::Engine::instance()->getCurrentModelViewProjectionMatrix()*modelMatrix*translate*rotationText*scale; + mvp = viewProjMatrix*modelMatrix*translate*rotationText*scale; Freetype::print3d(fontLight, mvp, "(1,0,1)"); translate = glm::translate(glm::mat4(1.0), glm::vec3(1, 1, 0)); - mvp = sgct::Engine::instance()->getCurrentModelViewProjectionMatrix()*modelMatrix*translate*rotationText*scale; + mvp = viewProjMatrix*modelMatrix*translate*rotationText*scale; Freetype::print3d(fontLight, mvp, "(1,1,0)"); translate = glm::translate(glm::mat4(1.0), glm::vec3(1, 1, 1)); - mvp = sgct::Engine::instance()->getCurrentModelViewProjectionMatrix()*modelMatrix*translate*rotationText*scale; + mvp = viewProjMatrix*modelMatrix*translate*rotationText*scale; Freetype::print3d(fontLight, mvp, "(1,1,1)"); } diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 791bdd8253..9af7f581d6 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -32,7 +32,6 @@ #include #include -#include #include #include #include @@ -718,33 +717,33 @@ void OpenSpaceEngine::postDraw() { void OpenSpaceEngine::keyboardCallback(Key key, KeyModifier mod, KeyAction action) { if (_isMaster) { if (_gui->isEnabled()) { - bool isConsumed = _gui->keyCallback(key, action); + bool isConsumed = _gui->keyCallback(key, mod, action); if (isConsumed) return; } - if (key == _console->commandInputButton() && (action == KeyAction::Press || action == KeyAction::Release)) + if (key == _console->commandInputButton() && (action == KeyAction::Press || action == KeyAction::Repeat)) _console->toggleVisibility(); if (!_console->isVisible()) { - _interactionHandler->keyboardCallback(key, action); + _interactionHandler->keyboardCallback(key, mod, action); } else { - _console->keyboardCallback(key, action); + _console->keyboardCallback(key, mod, action); } } } -void OpenSpaceEngine::charCallback(unsigned int codepoint) { +void OpenSpaceEngine::charCallback(unsigned int codepoint, KeyModifier modifier) { if (_isMaster) { if (_gui->isEnabled()) { - bool isConsumed = _gui->charCallback(codepoint); + bool isConsumed = _gui->charCallback(codepoint, modifier); if (isConsumed) return; } if (_console->isVisible()) { - _console->charCallback(codepoint); + _console->charCallback(codepoint, modifier); } } } diff --git a/src/engine/sgctwindowhandler.cpp b/src/engine/sgctwindowhandler.cpp index c2e8d3062c..737aaa6a06 100644 --- a/src/engine/sgctwindowhandler.cpp +++ b/src/engine/sgctwindowhandler.cpp @@ -43,18 +43,18 @@ void SGCTWindowHandler::clearAllWindows() { } } -double SGCTWindowHandler::averageDeltaTime() { +double SGCTWindowHandler::averageDeltaTime() const { return sgct::Engine::instance()->getAvgDt(); } -glm::vec2 SGCTWindowHandler::mousePosition() { +glm::vec2 SGCTWindowHandler::mousePosition() const { int id = sgct::Engine::instance()->getCurrentWindowPtr()->getId(); double posX, posY; sgct::Engine::instance()->getMousePos(id, &posX, &posY); return glm::vec2(posX, posY); } -uint32_t SGCTWindowHandler::mouseButtons(int maxNumber) { +uint32_t SGCTWindowHandler::mouseButtons(int maxNumber) const { int id = sgct::Engine::instance()->getCurrentWindowPtr()->getId(); uint32_t result = 0; for (int i = 0; i < maxNumber; ++i) { @@ -66,18 +66,18 @@ uint32_t SGCTWindowHandler::mouseButtons(int maxNumber) { return result; } -glm::ivec2 SGCTWindowHandler::currentWindowSize() { +glm::ivec2 SGCTWindowHandler::currentWindowSize() const { return glm::ivec2(sgct::Engine::instance()->getCurrentWindowPtr()->getXResolution(), sgct::Engine::instance()->getCurrentWindowPtr()->getYResolution()); } -glm::ivec2 SGCTWindowHandler::currentWindowResolution() { +glm::ivec2 SGCTWindowHandler::currentWindowResolution() const { int x,y; sgct::Engine::instance()->getCurrentWindowPtr()->getFinalFBODimensions(x, y); return glm::ivec2(x, y); } -bool SGCTWindowHandler::isRegularRendering() { +bool SGCTWindowHandler::isRegularRendering() const { // TODO: Needs to implement the nonlinear rendering check ---abock // sgct::SGCTWindow* w = sgct::Engine::instance()->getCurrentWindowPtr(); @@ -86,6 +86,10 @@ bool SGCTWindowHandler::isRegularRendering() { return true; } + +glm::mat4 SGCTWindowHandler::viewProjectionMatrix() const { + return sgct::Engine::instance()->getCurrentModelViewProjectionMatrix(); +} //void forEachWindow(std::function function) { // size_t n = sgct::Engine::instance()->getNumberOfWindows(); diff --git a/src/interaction/interactionhandler.cpp b/src/interaction/interactionhandler.cpp index 1dc3bd9953..2a75c1fa8b 100644 --- a/src/interaction/interactionhandler.cpp +++ b/src/interaction/interactionhandler.cpp @@ -636,7 +636,7 @@ void InteractionHandler::lookAt(const glm::quat& rotation) // } //} // -void InteractionHandler::keyboardCallback(Key key, KeyAction action) { +void InteractionHandler::keyboardCallback(Key key, KeyModifier modifier, KeyAction action) { // TODO package in script const float speed = _controllerSensitivity; const float dt = static_cast(_deltaTime); @@ -668,32 +668,32 @@ void InteractionHandler::keyboardCallback(Key key, KeyAction action) { if (key == SGCT_KEY_X) { Time::ref().advanceTime(-sgct::Engine::instance()->getDt()); }*/ - if (key == Key::Right) { + if ((key == Key::Right) && (modifier == KeyModifier::NoModifier)) { glm::vec3 euler(0.0, speed * dt*0.4, 0.0); glm::quat rot = glm::quat(euler); rotateDelta(rot); } - if (key == Key::Left) { + if ((key == Key::Left) && (modifier == KeyModifier::NoModifier)) { glm::vec3 euler(0.0, -speed * dt*0.4, 0.0); glm::quat rot = glm::quat(euler); rotateDelta(rot); } - if (key == Key::Down) { + if ((key == Key::Down) && (modifier == KeyModifier::NoModifier)) { glm::vec3 euler(speed * dt*0.4, 0.0, 0.0); glm::quat rot = glm::quat(euler); rotateDelta(rot); } - if (key == Key::Up) { + if ((key == Key::Up) && (modifier == KeyModifier::NoModifier)) { glm::vec3 euler(-speed * dt*0.4, 0.0, 0.0); glm::quat rot = glm::quat(euler); rotateDelta(rot); } - if (key == Key::KeypadSubtract) { + if ((key == Key::KeypadSubtract) && (modifier == KeyModifier::NoModifier)) { glm::vec2 s = OsEng.renderEngine()->camera()->scaling(); s[1] -= 0.5f; OsEng.renderEngine()->camera()->setScaling(s); } - if (key == Key::KeypadAdd) { + if ((key == Key::KeypadAdd) && (modifier == KeyModifier::NoModifier)) { glm::vec2 s = OsEng.renderEngine()->camera()->scaling(); s[1] += 0.5f; OsEng.renderEngine()->camera()->setScaling(s); diff --git a/src/interaction/luaconsole.cpp b/src/interaction/luaconsole.cpp index 2d26a6be72..3990ae1795 100644 --- a/src/interaction/luaconsole.cpp +++ b/src/interaction/luaconsole.cpp @@ -103,13 +103,10 @@ void LuaConsole::deinitialize() { } } -void LuaConsole::keyboardCallback(Key key, KeyAction action) { - if (action == KeyAction::Press || action == KeyAction::Release) { - const size_t windowIndex = sgct::Engine::instance()->getFocusedWindowIndex(); - const bool modifierControl = sgct::Engine::instance()->getKey(windowIndex, SGCT_KEY_LEFT_CONTROL) || - sgct::Engine::instance()->getKey(windowIndex, SGCT_KEY_RIGHT_CONTROL); - const bool modifierShift = sgct::Engine::instance()->getKey(windowIndex, SGCT_KEY_LEFT_SHIFT) || - sgct::Engine::instance()->getKey(windowIndex, SGCT_KEY_RIGHT_SHIFT); +void LuaConsole::keyboardCallback(Key key, KeyModifier modifier, KeyAction action) { + if (action == KeyAction::Press || action == KeyAction::Repeat) { + const bool modifierControl = (modifier == KeyModifier::Control); + const bool modifierShift = (modifier == KeyModifier::Shift); // Paste from clipboard if (modifierControl && (key == Key::V)) @@ -264,18 +261,16 @@ void LuaConsole::keyboardCallback(Key key, KeyAction action) { } } -void LuaConsole::charCallback(unsigned int codepoint) { +void LuaConsole::charCallback(unsigned int codepoint, KeyModifier modifier) { if (codepoint == static_cast(commandInputButton())) return; #ifndef WIN32 - const size_t windowIndex = sgct::Engine::instance()->getFocusedWindowIndex(); - const bool mod_CONTROL = sgct::Engine::instance()->getKey(windowIndex, SGCT_KEY_LEFT_CONTROL) || - sgct::Engine::instance()->getKey(windowIndex, SGCT_KEY_RIGHT_CONTROL); + const bool modifierControl = (modifier == KeyModifier::Control); const int codepoint_C = 99; const int codepoint_V = 118; - if (mod_CONTROL && (codepoint == codepoint_C || codepoint == codepoint_V)) { + if (modifierControl && (codepoint == codepoint_C || codepoint == codepoint_V)) { return; } #endif From 062817b7fb31fa024aab98b3e181270f50cf3fff Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 26 Oct 2015 11:20:48 -0500 Subject: [PATCH 018/122] More work moving code to window wrapper Removing capability to show SGCT rendering information --- include/openspace/engine/sgctwindowhandler.h | 8 +++-- include/openspace/engine/windowhandler.h | 5 +++ include/openspace/rendering/renderengine.h | 4 +-- src/engine/openspaceengine.cpp | 3 +- src/engine/sgctwindowhandler.cpp | 25 +++++++++++++- src/interaction/luaconsole.cpp | 10 ++++-- src/network/networkengine.cpp | 34 ++++++++++++-------- src/rendering/renderengine.cpp | 23 ++++++------- src/rendering/renderengine_lua.inl | 18 ----------- 9 files changed, 74 insertions(+), 56 deletions(-) diff --git a/include/openspace/engine/sgctwindowhandler.h b/include/openspace/engine/sgctwindowhandler.h index d7da63f406..70db4b4fb8 100644 --- a/include/openspace/engine/sgctwindowhandler.h +++ b/include/openspace/engine/sgctwindowhandler.h @@ -43,10 +43,14 @@ public: bool isRegularRendering() const override; glm::mat4 viewProjectionMatrix() const override; - + void setNearFarClippingPlane(float near, float far) override; - // void forEachWindow(std::function function) override; + glm::ivec4 viewportPixelCoordinates() const override; + + bool isExternalControlConnected() const override; + void sendMessageToExternalControl(const std::vector& message) const override; + // void forEachWindow(std::function function) override; }; } // namespace openspace diff --git a/include/openspace/engine/windowhandler.h b/include/openspace/engine/windowhandler.h index 82c44901f0..d247644a6c 100644 --- a/include/openspace/engine/windowhandler.h +++ b/include/openspace/engine/windowhandler.h @@ -44,7 +44,12 @@ public: virtual bool isRegularRendering() const = 0; virtual glm::mat4 viewProjectionMatrix() const = 0; + virtual void setNearFarClippingPlane(float near, float far) = 0; + virtual glm::ivec4 viewportPixelCoordinates() const = 0; + + virtual bool isExternalControlConnected() const = 0; + virtual void sendMessageToExternalControl(const std::vector& message) const = 0; //virtual void forEachWindow(std::function function) = 0; diff --git a/include/openspace/rendering/renderengine.h b/include/openspace/rendering/renderengine.h index cde17ace1b..df1a5651fa 100644 --- a/include/openspace/rendering/renderengine.h +++ b/include/openspace/rendering/renderengine.h @@ -89,8 +89,6 @@ public: float globalBlackOutFactor(); void setGlobalBlackOutFactor(float factor); - void setSGCTRenderStatistics(bool visible); - void setDisableRenderingOnMaster(bool enabled); /** @@ -140,7 +138,7 @@ private: float _fadeDuration; float _currentFadeTime; int _fadeDirection; - bool _sgctRenderStatisticsVisible; +// bool _sgctRenderStatisticsVisible; bool _visualizeABuffer; ABufferVisualizer* _visualizer; diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 9af7f581d6..045c7edb0d 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -686,8 +686,7 @@ void OpenSpaceEngine::postSynchronizationPreDraw() { _scriptEngine->postSynchronizationPreDraw(); _renderEngine->postSynchronizationPreDraw(); - - + if (_isMaster && _gui->isEnabled() && _windowHandler->isRegularRendering()) { glm::vec2 mousePosition = _windowHandler->mousePosition(); glm::ivec2 windowResolution = _windowHandler->currentWindowResolution(); diff --git a/src/engine/sgctwindowhandler.cpp b/src/engine/sgctwindowhandler.cpp index 737aaa6a06..3ae0fcaeb0 100644 --- a/src/engine/sgctwindowhandler.cpp +++ b/src/engine/sgctwindowhandler.cpp @@ -90,7 +90,30 @@ bool SGCTWindowHandler::isRegularRendering() const { glm::mat4 SGCTWindowHandler::viewProjectionMatrix() const { return sgct::Engine::instance()->getCurrentModelViewProjectionMatrix(); } - + +void SGCTWindowHandler::setNearFarClippingPlane(float near, float far) { + sgct::Engine::instance()->setNearAndFarClippingPlanes(near, far); +} + +glm::ivec4 SGCTWindowHandler::viewportPixelCoordinates() const { + int x1, xSize, y1, ySize; + sgct::Engine::instance()->getCurrentWindowPtr()->getCurrentViewportPixelCoords(x1, + y1, + xSize, + ySize); + return glm::ivec4(x1, xSize, y1, ySize); +} + +bool SGCTWindowHandler::isExternalControlConnected() const { + return sgct::Engine::instance()->isExternalControlConnected(); +} + +void SGCTWindowHandler::sendMessageToExternalControl(const std::vector& message) const { + sgct::Engine::instance()->sendMessageToExternalControl( + message.data(), + message.size()); +} + //void forEachWindow(std::function function) { // size_t n = sgct::Engine::instance()->getNumberOfWindows(); // for (size_t i = 0; i < n; ++i) diff --git a/src/interaction/luaconsole.cpp b/src/interaction/luaconsole.cpp index 3990ae1795..dbb2d8fb0d 100644 --- a/src/interaction/luaconsole.cpp +++ b/src/interaction/luaconsole.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -280,8 +281,13 @@ void LuaConsole::charCallback(unsigned int codepoint, KeyModifier modifier) { void LuaConsole::render() { const float font_size = 10.0f; - int x1, xSize, y1, ySize; - sgct::Engine::instance()->getCurrentWindowPtr()->getCurrentViewportPixelCoords(x1, y1, xSize, ySize); + + glm::ivec4 viewportPixelCoordinates = OsEng.windowWrapper()->viewportPixelCoordinates(); + int x1 = viewportPixelCoordinates.x; + int xSize = viewportPixelCoordinates.y; + int y1 = viewportPixelCoordinates.z; + int ySize = viewportPixelCoordinates.w; + float startY = static_cast(ySize) - 2.0f * font_size; startY = startY - font_size * 15.0f * 2.0f; diff --git a/src/network/networkengine.cpp b/src/network/networkengine.cpp index 747a78083a..6916acc8bc 100644 --- a/src/network/networkengine.cpp +++ b/src/network/networkengine.cpp @@ -87,7 +87,7 @@ bool NetworkEngine::handleMessage(const std::string& message) { } void NetworkEngine::publishStatusMessage() { - if (!_shouldPublishStatusMessage || !sgct::Engine::instance()->isExternalControlConnected()) + if (!_shouldPublishStatusMessage || !OsEng.windowWrapper()->isExternalControlConnected()) return; // Protocol: // 8 bytes: time as a ET double @@ -164,7 +164,7 @@ void NetworkEngine::publishMessage(MessageIdentifier identifier, std::vectorisExternalControlConnected()) + if (!OsEng.windowWrapper()->isExternalControlConnected()) return; for (Message& m : _messagesToSend) { @@ -180,10 +180,11 @@ void NetworkEngine::sendMessages() { // Prepending the message identifier to the front m.body.insert(m.body.begin(), identifier.data.begin(), identifier.data.end()); - sgct::Engine::instance()->sendMessageToExternalControl( - m.body.data(), - static_cast(m.body.size()) - ); + OsEng.windowWrapper()->sendMessageToExternalControl(m.body); +// sgct::Engine::instance()->sendMessageToExternalControl( +// m.body.data(), +// static_cast(m.body.size()) +// ); //LINFO("Sent message: (s=" << m.body.size() << "): " << std::string(m.body.begin(), m.body.end())); } @@ -202,10 +203,11 @@ void NetworkEngine::sendInitialInformation() { std::vector payload = m.body; payload.insert(payload.begin(), identifier.data.begin(), identifier.data.end()); - sgct::Engine::instance()->sendMessageToExternalControl( - payload.data(), - static_cast(payload.size()) - ); + OsEng.windowWrapper()->sendMessageToExternalControl(payload); +// sgct::Engine::instance()->sendMessageToExternalControl( +// payload.data(), +// static_cast(payload.size()) +// ); LINFO("Sent initial message: (s=" << m.body.size() << ") [i=" << identifier.value << "]"); std::this_thread::sleep_for(std::chrono::milliseconds(SleepTime)); @@ -220,10 +222,14 @@ void NetworkEngine::sendInitialInformation() { } identifier; identifier.value = _initialMessageFinishedIdentifier; - sgct::Engine::instance()->sendMessageToExternalControl( - identifier.data.data(), - 2 - ); + std::vector d; + d.insert(d.begin(), identifier.data.begin(), identifier.data.end()); + + OsEng.windowWrapper()->sendMessageToExternalControl(d); +// sgct::Engine::instance()->sendMessageToExternalControl( +// identifier.data.data(), +// 2 +// ); _shouldPublishStatusMessage = true; } diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index e79bd4677d..64b88f6158 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -103,7 +103,7 @@ RenderEngine::RenderEngine() , _fadeDuration(2.f) , _currentFadeTime(0.f) , _fadeDirection(0) - , _sgctRenderStatisticsVisible(false) + // , _sgctRenderStatisticsVisible(false) , _visualizeABuffer(false) , _visualizer(nullptr) { @@ -193,14 +193,20 @@ bool RenderEngine::initialize() { bool RenderEngine::initializeGL() { // LDEBUG("RenderEngine::initializeGL()"); - sgct::SGCTWindow* wPtr = sgct::Engine::instance()->getCurrentWindowPtr(); +// sgct::SGCTWindow* wPtr = sgct::Engine::instance()->getCurrentWindowPtr(); // 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 // development - sgct::Engine::instance()->setNearAndFarClippingPlanes(0.001f, 1000.0f); + OsEng.windowWrapper()->setNearFarClippingPlane(0.001f, 1000.f); + + // ALL OF THIS HAS TO BE CHECKED + // ---abock + + +// sgct::Engine::instance()->setNearAndFarClippingPlanes(0.001f, 1000.0f); // sgct::Engine::instance()->setNearAndFarClippingPlanes(0.1f, 30.0f); // calculating the maximum field of view for the camera, used to @@ -289,7 +295,6 @@ void RenderEngine::preSynchronization() { } void RenderEngine::postSynchronizationPreDraw() { - sgct::Engine::instance()->setStatsGraphVisibility(_sgctRenderStatisticsVisible); //temporary fade funtionality if (_fadeDirection != 0) { if (_currentFadeTime > _fadeDuration){ @@ -788,12 +793,6 @@ scripting::ScriptEngine::LuaLibrary RenderEngine::luaLibrary() { "bool", "Toggles the showing of render information on-screen text" }, - { - "showSGCTRenderStatistics", - &luascriptfunctions::showSGCTRenderStatistics, - "bool", - "Toggles the visibility of the SGCT rendering information" - }, { "setPerformanceMeasurement", &luascriptfunctions::setPerformanceMeasurement, @@ -1290,10 +1289,6 @@ void RenderEngine::changeViewPoint(std::string origin) { LFATAL("This function is being misused with an argument of '" << origin << "'"); } -void RenderEngine::setSGCTRenderStatistics(bool visible) { - _sgctRenderStatisticsVisible = visible; -} - void RenderEngine::setDisableRenderingOnMaster(bool enabled) { _disableMasterRendering = enabled; } diff --git a/src/rendering/renderengine_lua.inl b/src/rendering/renderengine_lua.inl index 70410eaa87..7d0ea22a00 100644 --- a/src/rendering/renderengine_lua.inl +++ b/src/rendering/renderengine_lua.inl @@ -87,24 +87,6 @@ int showRenderInformation(lua_State* L) { return 0; } -/** - * \ingroup LuaScripts - * showSGCTRenderStatistics(bool): - * Set the rendering of the SGCTRenderStatistics - */ -int showSGCTRenderStatistics(lua_State* L) { - int nArguments = lua_gettop(L); - if (nArguments != 1) - return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments); - - const int type = lua_type(L, -1); - if (type != LUA_TBOOLEAN) - return luaL_error(L, "Expected argument of type 'bool'"); - bool b = lua_toboolean(L, -1) != 0; - OsEng.renderEngine()->setSGCTRenderStatistics(b); - return 0; -} - /** * \ingroup LuaScripts * visualizeABuffer(bool): From 77857975a423909fdea4bbc243de9735286ad1ad Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 26 Oct 2015 11:44:16 -0500 Subject: [PATCH 019/122] Changing the RenderEngine to use the SGCT window wrapper --- include/openspace/engine/sgctwindowhandler.h | 9 ++++- include/openspace/engine/windowhandler.h | 6 +++ src/engine/sgctwindowhandler.cpp | 18 +++++++++ src/rendering/renderengine.cpp | 41 +++++++++----------- src/util/screenlog.cpp | 6 ++- 5 files changed, 54 insertions(+), 26 deletions(-) diff --git a/include/openspace/engine/sgctwindowhandler.h b/include/openspace/engine/sgctwindowhandler.h index 70db4b4fb8..a3a84476cf 100644 --- a/include/openspace/engine/sgctwindowhandler.h +++ b/include/openspace/engine/sgctwindowhandler.h @@ -33,7 +33,9 @@ class SGCTWindowHandler : public WindowHandler { public: void setBarrier(bool enabled) override; void clearAllWindows() override; - + bool windowHasResized() const override; + + double time() const override; double averageDeltaTime() const override; glm::vec2 mousePosition() const override; uint32_t mouseButtons(int maxNumber) const override; @@ -50,6 +52,11 @@ public: bool isExternalControlConnected() const override; void sendMessageToExternalControl(const std::vector& message) const override; + bool isSimpleRendering() const override; + + void takeScreenshot() const override; + + // void forEachWindow(std::function function) override; }; diff --git a/include/openspace/engine/windowhandler.h b/include/openspace/engine/windowhandler.h index d247644a6c..ff19c000ac 100644 --- a/include/openspace/engine/windowhandler.h +++ b/include/openspace/engine/windowhandler.h @@ -36,6 +36,8 @@ class WindowHandler { public: virtual void setBarrier(bool enabled) = 0; virtual void clearAllWindows() = 0; + virtual bool windowHasResized() const = 0; + virtual double time() const = 0; virtual double averageDeltaTime() const = 0; virtual uint32_t mouseButtons(int maxNumber = 8) const = 0; virtual glm::vec2 mousePosition() const = 0; @@ -51,6 +53,10 @@ public: virtual bool isExternalControlConnected() const = 0; virtual void sendMessageToExternalControl(const std::vector& message) const = 0; + // true for single viewport, single window; false otherwise + virtual bool isSimpleRendering() const = 0; + + virtual void takeScreenshot() const = 0; //virtual void forEachWindow(std::function function) = 0; diff --git a/src/engine/sgctwindowhandler.cpp b/src/engine/sgctwindowhandler.cpp index 3ae0fcaeb0..8b97b6a452 100644 --- a/src/engine/sgctwindowhandler.cpp +++ b/src/engine/sgctwindowhandler.cpp @@ -42,6 +42,14 @@ void SGCTWindowHandler::clearAllWindows() { glfwSwapBuffers(win); } } + +bool SGCTWindowHandler::windowHasResized() const { + return sgct::Engine::instance()->getCurrentWindowPtr()->isWindowResized(); +} + +double SGCTWindowHandler::time() const { + return sgct::Engine::instance()->getTime(); +} double SGCTWindowHandler::averageDeltaTime() const { return sgct::Engine::instance()->getAvgDt(); @@ -114,6 +122,16 @@ void SGCTWindowHandler::sendMessageToExternalControl(const std::vector& me message.size()); } +bool SGCTWindowHandler::isSimpleRendering() const { + return (sgct::Engine::instance()->getCurrentRenderTarget() != sgct::Engine::NonLinearBuffer); + +} + +void SGCTWindowHandler::takeScreenshot() const { + sgct::Engine::instance()->takeScreenshot(); +} + + //void forEachWindow(std::function function) { // size_t n = sgct::Engine::instance()->getNumberOfWindows(); // for (size_t i = 0; i < n; ++i) diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 64b88f6158..60816f355f 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -306,22 +306,15 @@ void RenderEngine::postSynchronizationPreDraw() { _globalBlackOutFactor = glm::smoothstep(1.f, 0.f, _currentFadeTime / _fadeDuration); else _globalBlackOutFactor = glm::smoothstep(0.f, 1.f, _currentFadeTime / _fadeDuration); - _currentFadeTime += static_cast(sgct::Engine::instance()->getAvgDt()); + _currentFadeTime += static_cast(OsEng.windowWrapper()->averageDeltaTime()); } } if (_mainCamera) _mainCamera->postSynchronizationPreDraw(); - sgct_core::SGCTNode* thisNode = sgct_core::ClusterManager::instance()->getThisNodePtr(); - bool updateAbuffer = false; - for (unsigned int i = 0; i < thisNode->getNumberOfWindows(); i++) { - if (sgct::Engine::instance()->getWindowPtr(i)->isWindowResized()) { - updateAbuffer = true; - break; - } - } - if (updateAbuffer) { + bool windowResized = OsEng.windowWrapper()->windowHasResized(); + if (windowResized) { generateGlslConfig(); _abuffer->reinitialize(); } @@ -352,9 +345,10 @@ void RenderEngine::postSynchronizationPreDraw() { void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &viewMatrix) { // We need the window pointer - sgct::SGCTWindow* w = sgct::Engine::instance()->getCurrentWindowPtr(); +// sgct::SGCTWindow* w = sgct::Engine::instance()->getCurrentWindowPtr(); - if (sgct::Engine::instance()->getCurrentRenderTarget() == sgct::Engine::NonLinearBuffer) + if (!OsEng.windowWrapper()->isSimpleRendering()) +// if (sgct::Engine::instance()->getCurrentRenderTarget() == sgct::Engine::NonLinearBuffer) _abuffer->clear(); // SGCT resets certain settings @@ -424,8 +418,7 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi // Print some useful information on the master viewport - if (OsEng.ref().isMaster() && sgct::Engine::instance()->getCurrentRenderTarget() != sgct::Engine::NonLinearBuffer) { - + if (OsEng.ref().isMaster() && OsEng.windowWrapper()->isSimpleRendering()) { // TODO: Adjust font_size properly when using retina screen const int font_size_mono = 10; const int font_size_time = 15; @@ -437,8 +430,11 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi if (_showInfo) { const sgct_text::Font* font = fontMono; - int x1, xSize, y1, ySize; - sgct::Engine::instance()->getCurrentWindowPtr()->getCurrentViewportPixelCoords(x1, y1, xSize, ySize); + glm::ivec4 pixelCoords = OsEng.windowWrapper()->viewportPixelCoordinates(); + int x1 = pixelCoords.x; + int xSize = pixelCoords.y; + int y1 = pixelCoords.z; + int ySize = pixelCoords.w; int startY = ySize - 2 * font_size_time; //const glm::vec2& scaling = _mainCamera->scaling(); //const glm::vec3& viewdirection = _mainCamera->viewDirection(); @@ -477,7 +473,7 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi float distToSurf = glm::length(nhPos.vec3()) - radius; PrintText(line++, "Distance to Pluto: % .1f (KM)", distToSurf); - PrintText(line++, "Avg. Frametime: %.5f", sgct::Engine::instance()->getAvgDt()); + PrintText(line++, "Avg. Frametime: %.5f", OsEng.windowWrapper()->averageDeltaTime()); //PrintText(line++, "Drawtime: %.5f", sgct::Engine::instance()->getDrawTime()); //PrintText(line++, "Frametime: %.5f", sgct::Engine::instance()->getDt()); @@ -596,7 +592,7 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi for (auto& it = entries.first; it != entries.second; ++it) { const ScreenLog::LogEntry* e = &(*it); - const double t = sgct::Engine::instance()->getTime(); + const double t = OsEng.windowWrapper()->time(); float diff = static_cast(t - e->timeStamp); // Since all log entries are ordered, once one is exceeding TTL, all have @@ -650,7 +646,7 @@ void RenderEngine::postDraw() { if (Time::ref().timeJumped()) Time::ref().setTimeJumped(false); if (_takeScreenshot) { - sgct::Engine::instance()->takeScreenshot(); + OsEng.windowWrapper()->takeScreenshot(); _takeScreenshot = false; } @@ -738,8 +734,7 @@ void RenderEngine::startFading(int direction, float fadeDuration) { void RenderEngine::generateGlslConfig() { ghoul_assert(_abuffer != nullptr, "ABuffer not initialized"); LDEBUG("Generating GLSLS config, expect shader recompilation"); - int xSize = sgct::Engine::instance()->getCurrentWindowPtr()->getXFramebufferResolution();; - int ySize = sgct::Engine::instance()->getCurrentWindowPtr()->getYFramebufferResolution();; + glm::ivec2 size = OsEng.windowWrapper()->currentWindowResolution(); // TODO: Make this file creation dynamic and better in every way // TODO: If the screen size changes it is enough if this file is regenerated to @@ -747,8 +742,8 @@ void RenderEngine::generateGlslConfig() { std::ofstream os(absPath("${SHADERS_GENERATED}/constants.hglsl")); os << "#ifndef CONSTANTS_HGLSL\n" << "#define CONSTANTS_HGLSL\n" - << "#define SCREEN_WIDTH " << xSize << "\n" - << "#define SCREEN_HEIGHT " << ySize << "\n" + << "#define SCREEN_WIDTH " << size.x << "\n" + << "#define SCREEN_HEIGHT " << size.y << "\n" << "#define MAX_LAYERS " << ABuffer::MAX_LAYERS << "\n" << "#define ABUFFER_FRAMEBUFFER " << ABUFFER_FRAMEBUFFER << "\n" << "#define ABUFFER_SINGLE_LINKED " << ABUFFER_SINGLE_LINKED << "\n" diff --git a/src/util/screenlog.cpp b/src/util/screenlog.cpp index efe454bd1e..eecc81d9cd 100644 --- a/src/util/screenlog.cpp +++ b/src/util/screenlog.cpp @@ -24,8 +24,10 @@ #include +#include +#include + #include -#include // sgct::Engine::instance()->getTime() namespace openspace { @@ -33,7 +35,7 @@ ScreenLog::ScreenLog() {} void ScreenLog::log(ghoul::logging::LogManager::LogLevel level, const std::string& category, const std::string& message) { if (level >= ghoul::logging::LogManager::LogLevel::Info) - _entries.emplace_back(level, sgct::Engine::instance()->getTime(), Log::getTimeString(), category, message); + _entries.emplace_back(level, OsEng.windowWrapper()->time(), Log::getTimeString(), category, message); // Once reaching maximum size, reduce to half if (_entries.size() > MaximumSize) { From f3fd055db801f54743bae70a6215845de0c3a27a Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 26 Oct 2015 15:00:46 -0500 Subject: [PATCH 020/122] Rename WindowHandler to WindowWrapper --- apps/OpenSpace/main.cpp | 4 +- include/openspace/engine/openspaceengine.h | 10 +- .../sgctwindowwrapper.h} | 10 +- .../windowwrapper.h} | 6 +- src/CMakeLists.txt | 7 +- src/abuffer/abuffervisualizer.cpp | 2 +- src/engine/openspaceengine.cpp | 38 +- src/engine/windowhandler.cpp | 0 .../sgctwindowwrapper.cpp} | 36 +- src/interaction/deviceidentifier.cpp | 17 - src/interaction/interactionhandler.cpp | 594 +----------------- src/interaction/luaconsole.cpp | 2 +- src/interaction/mousecontroller.cpp | 3 - src/network/networkengine.cpp | 14 - src/rendering/renderengine.cpp | 3 - src/util/screenlog.cpp | 1 - 16 files changed, 59 insertions(+), 688 deletions(-) rename include/openspace/engine/{sgctwindowhandler.h => wrapper/sgctwindowwrapper.h} (94%) rename include/openspace/engine/{windowhandler.h => wrapper/windowwrapper.h} (97%) delete mode 100644 src/engine/windowhandler.cpp rename src/engine/{sgctwindowhandler.cpp => wrapper/sgctwindowwrapper.cpp} (83%) diff --git a/apps/OpenSpace/main.cpp b/apps/OpenSpace/main.cpp index 9dc5eef84f..e5a268c0cc 100644 --- a/apps/OpenSpace/main.cpp +++ b/apps/OpenSpace/main.cpp @@ -23,7 +23,7 @@ ****************************************************************************************/ #include -#include +#include #include #include #include @@ -88,7 +88,7 @@ int main(int argc, char** argv) { std::vector sgctArguments; const bool success = openspace::OpenSpaceEngine::create( argc, argv, - new openspace::SGCTWindowHandler, + new openspace::SGCTWindowWrapper, sgctArguments ); if (!success) diff --git a/include/openspace/engine/openspaceengine.h b/include/openspace/engine/openspaceengine.h index 309f735cdb..9cfaf867b8 100644 --- a/include/openspace/engine/openspaceengine.h +++ b/include/openspace/engine/openspaceengine.h @@ -29,7 +29,7 @@ #include #include -#include +#include #include #include @@ -72,7 +72,7 @@ namespace properties { class OpenSpaceEngine { public: - static bool create(int argc, char** argv, WindowHandler* windowHandler, std::vector& sgctArguments); + static bool create(int argc, char** argv, WindowWrapper* windowWrapper, std::vector& sgctArguments); static void destroy(); static OpenSpaceEngine& ref(); @@ -94,7 +94,7 @@ public: ModuleEngine* moduleEngine(); network::ParallelConnection* parallelConnection(); properties::PropertyOwner* globalPropertyOwner(); - WindowHandler* windowWrapper(); + WindowWrapper* windowWrapper(); gui::GUI* gui(); @@ -120,7 +120,7 @@ public: void runSettingsScripts(); private: - OpenSpaceEngine(std::string programName, WindowHandler* windowHandler); + OpenSpaceEngine(std::string programName, WindowWrapper* windowWrapper); ~OpenSpaceEngine(); OpenSpaceEngine(const OpenSpaceEngine& rhs) = delete; @@ -144,7 +144,7 @@ private: ModuleEngine* _moduleEngine; gui::GUI* _gui; network::ParallelConnection* _parallelConnection; - WindowHandler* _windowHandler; + WindowWrapper* _windowWrapper; properties::PropertyOwner* _globalPropertyNamespace; diff --git a/include/openspace/engine/sgctwindowhandler.h b/include/openspace/engine/wrapper/sgctwindowwrapper.h similarity index 94% rename from include/openspace/engine/sgctwindowhandler.h rename to include/openspace/engine/wrapper/sgctwindowwrapper.h index a3a84476cf..2396a5c8c5 100644 --- a/include/openspace/engine/sgctwindowhandler.h +++ b/include/openspace/engine/wrapper/sgctwindowwrapper.h @@ -22,14 +22,14 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#ifndef __SGCTWINDOWHANDLER_H__ -#define __SGCTWINDOWHANDLER_H__ +#ifndef __SGCTWINDOWWRAPPER_H__ +#define __SGCTWINDOWWRAPPER_H__ -#include +#include namespace openspace { -class SGCTWindowHandler : public WindowHandler { +class SGCTWindowWrapper : public WindowWrapper { public: void setBarrier(bool enabled) override; void clearAllWindows() override; @@ -62,4 +62,4 @@ public: } // namespace openspace -#endif // __SGCTWINDOWHANDLER_H__ +#endif // __SGCTWINDOWWRAPPER_H__ diff --git a/include/openspace/engine/windowhandler.h b/include/openspace/engine/wrapper/windowwrapper.h similarity index 97% rename from include/openspace/engine/windowhandler.h rename to include/openspace/engine/wrapper/windowwrapper.h index ff19c000ac..4d6c28a8e2 100644 --- a/include/openspace/engine/windowhandler.h +++ b/include/openspace/engine/wrapper/windowwrapper.h @@ -22,8 +22,8 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#ifndef __WINDOWHANDLER_H__ -#define __WINDOWHANDLER_H__ +#ifndef __WINDOWWRAPPER_H__ +#define __WINDOWWRAPPER_H__ #include @@ -32,7 +32,7 @@ namespace openspace { -class WindowHandler { +class WindowWrapper { public: virtual void setBarrier(bool enabled) = 0; virtual void clearAllWindows() = 0; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 268023182c..82332c1fc5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -33,9 +33,8 @@ set(OPENSPACE_SOURCE ${OPENSPACE_BASE_DIR}/src/engine/downloadmanager.cpp ${OPENSPACE_BASE_DIR}/src/engine/logfactory.cpp ${OPENSPACE_BASE_DIR}/src/engine/moduleengine.cpp - ${OPENSPACE_BASE_DIR}/src/engine/sgctwindowhandler.cpp ${OPENSPACE_BASE_DIR}/src/engine/openspaceengine.cpp - ${OPENSPACE_BASE_DIR}/src/engine/windowhandler.cpp + ${OPENSPACE_BASE_DIR}/src/engine/wrapper/sgctwindowwrapper.cpp ${OPENSPACE_BASE_DIR}/src/interaction/controller.cpp ${OPENSPACE_BASE_DIR}/src/interaction/deviceidentifier.cpp ${OPENSPACE_BASE_DIR}/src/interaction/interactionhandler.cpp @@ -99,9 +98,9 @@ set(OPENSPACE_HEADER ${OPENSPACE_BASE_DIR}/include/openspace/engine/downloadmanager.h ${OPENSPACE_BASE_DIR}/include/openspace/engine/logfactory.h ${OPENSPACE_BASE_DIR}/include/openspace/engine/moduleengine.h - ${OPENSPACE_BASE_DIR}/include/openspace/engine/sgctwindowhandler.h ${OPENSPACE_BASE_DIR}/include/openspace/engine/openspaceengine.h - ${OPENSPACE_BASE_DIR}/include/openspace/engine/windowhandler.h + ${OPENSPACE_BASE_DIR}/include/openspace/engine/wrapper/sgctwindowwrapper.h + ${OPENSPACE_BASE_DIR}/include/openspace/engine/wrapper/windowwrapper.h ${OPENSPACE_BASE_DIR}/include/openspace/interaction/controller.h ${OPENSPACE_BASE_DIR}/include/openspace/interaction/deviceidentifier.h ${OPENSPACE_BASE_DIR}/include/openspace/interaction/interactionhandler.h diff --git a/src/abuffer/abuffervisualizer.cpp b/src/abuffer/abuffervisualizer.cpp index 000c147a2a..7bb79ba2c6 100644 --- a/src/abuffer/abuffervisualizer.cpp +++ b/src/abuffer/abuffervisualizer.cpp @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 045c7edb0d..0c88b860b4 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -101,7 +101,7 @@ namespace openspace { OpenSpaceEngine* OpenSpaceEngine::_engine = nullptr; -OpenSpaceEngine::OpenSpaceEngine(std::string programName, WindowHandler* windowHandler) +OpenSpaceEngine::OpenSpaceEngine(std::string programName, WindowWrapper* windowWrapper) : _configurationManager(new ConfigurationManager) , _interactionHandler(new interaction::InteractionHandler) , _renderEngine(new RenderEngine) @@ -112,7 +112,7 @@ OpenSpaceEngine::OpenSpaceEngine(std::string programName, WindowHandler* windowH , _moduleEngine(new ModuleEngine) , _gui(new gui::GUI) , _parallelConnection(new network::ParallelConnection) - , _windowHandler(windowHandler) + , _windowWrapper(windowWrapper) , _globalPropertyNamespace(new properties::PropertyOwner) , _isMaster(false) , _runTime(0.0) @@ -132,8 +132,8 @@ OpenSpaceEngine::~OpenSpaceEngine() { delete _globalPropertyNamespace; _globalPropertyNamespace = nullptr; - delete _windowHandler; - _windowHandler = nullptr; + delete _windowWrapper; + _windowWrapper = nullptr; delete _parallelConnection; _parallelConnection = nullptr; @@ -176,7 +176,7 @@ OpenSpaceEngine& OpenSpaceEngine::ref() { bool OpenSpaceEngine::create( int argc, char** argv, - WindowHandler* windowHandler, + WindowWrapper* windowWrapper, std::vector& sgctArguments) { ghoul::initialize(); @@ -208,7 +208,7 @@ bool OpenSpaceEngine::create( // Create other objects LDEBUG("Creating OpenSpaceEngine"); - _engine = new OpenSpaceEngine(std::string(argv[0]), windowHandler); + _engine = new OpenSpaceEngine(std::string(argv[0]), windowWrapper); // Query modules for commandline arguments const bool gatherSuccess = _engine->gatherCommandlineArguments(); @@ -422,7 +422,7 @@ bool OpenSpaceEngine::isInitialized() { } void OpenSpaceEngine::clearAllWindows() { - _windowHandler->clearAllWindows(); + _windowWrapper->clearAllWindows(); } bool OpenSpaceEngine::gatherCommandlineArguments() { @@ -666,7 +666,7 @@ void OpenSpaceEngine::setRunTime(double d){ void OpenSpaceEngine::preSynchronization() { FileSys.triggerFilesystemEvents(); if (_isMaster) { - double dt = _windowHandler->averageDeltaTime(); + double dt = _windowWrapper->averageDeltaTime(); Time::ref().advanceTime(dt); Time::ref().preSynchronization(); @@ -687,12 +687,12 @@ void OpenSpaceEngine::postSynchronizationPreDraw() { _scriptEngine->postSynchronizationPreDraw(); _renderEngine->postSynchronizationPreDraw(); - if (_isMaster && _gui->isEnabled() && _windowHandler->isRegularRendering()) { - glm::vec2 mousePosition = _windowHandler->mousePosition(); - glm::ivec2 windowResolution = _windowHandler->currentWindowResolution(); - uint32_t mouseButtons = _windowHandler->mouseButtons(2); + if (_isMaster && _gui->isEnabled() && _windowWrapper->isRegularRendering()) { + glm::vec2 mousePosition = _windowWrapper->mousePosition(); + glm::ivec2 windowResolution = _windowWrapper->currentWindowResolution(); + uint32_t mouseButtons = _windowWrapper->mouseButtons(2); - double dt = _windowHandler->averageDeltaTime(); + double dt = _windowWrapper->averageDeltaTime(); _gui->startFrame(static_cast(dt), glm::vec2(windowResolution), mousePosition, mouseButtons); } @@ -701,7 +701,7 @@ void OpenSpaceEngine::postSynchronizationPreDraw() { void OpenSpaceEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &viewMatrix) { _renderEngine->render(projectionMatrix, viewMatrix); - if (_isMaster && _windowHandler->isRegularRendering()) { + if (_isMaster && _windowWrapper->isRegularRendering()) { if (_console->isVisible()) _console->render(); if (_gui->isEnabled()) @@ -809,11 +809,11 @@ void OpenSpaceEngine::externalControlCallback(const char* receivedChars, } void OpenSpaceEngine::enableBarrier() { - _windowHandler->setBarrier(true); + _windowWrapper->setBarrier(true); } void OpenSpaceEngine::disableBarrier() { - _windowHandler->setBarrier(false); + _windowWrapper->setBarrier(false); } NetworkEngine* OpenSpaceEngine::networkEngine() { @@ -834,9 +834,9 @@ properties::PropertyOwner* OpenSpaceEngine::globalPropertyOwner() { return _globalPropertyNamespace; } -WindowHandler* OpenSpaceEngine::windowWrapper() { - ghoul_assert(_windowHandler, "Window Wrapper"); - return _windowHandler; +WindowWrapper* OpenSpaceEngine::windowWrapper() { + ghoul_assert(_windowWrapper, "Window Wrapper"); + return _windowWrapper; } } // namespace openspace diff --git a/src/engine/windowhandler.cpp b/src/engine/windowhandler.cpp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/engine/sgctwindowhandler.cpp b/src/engine/wrapper/sgctwindowwrapper.cpp similarity index 83% rename from src/engine/sgctwindowhandler.cpp rename to src/engine/wrapper/sgctwindowwrapper.cpp index 8b97b6a452..d24920f091 100644 --- a/src/engine/sgctwindowhandler.cpp +++ b/src/engine/wrapper/sgctwindowwrapper.cpp @@ -25,15 +25,15 @@ #include #include "sgct.h" -#include +#include namespace openspace { -void SGCTWindowHandler::setBarrier(bool enabled) { +void SGCTWindowWrapper::setBarrier(bool enabled) { sgct::SGCTWindow::setBarrier(enabled); } -void SGCTWindowHandler::clearAllWindows() { +void SGCTWindowWrapper::clearAllWindows() { size_t n = sgct::Engine::instance()->getNumberOfWindows(); for (size_t i = 0; i < n; ++i) { glClearColor(0, 0, 0, 0); @@ -43,26 +43,26 @@ void SGCTWindowHandler::clearAllWindows() { } } -bool SGCTWindowHandler::windowHasResized() const { +bool SGCTWindowWrapper::windowHasResized() const { return sgct::Engine::instance()->getCurrentWindowPtr()->isWindowResized(); } -double SGCTWindowHandler::time() const { +double SGCTWindowWrapper::time() const { return sgct::Engine::instance()->getTime(); } -double SGCTWindowHandler::averageDeltaTime() const { +double SGCTWindowWrapper::averageDeltaTime() const { return sgct::Engine::instance()->getAvgDt(); } -glm::vec2 SGCTWindowHandler::mousePosition() const { +glm::vec2 SGCTWindowWrapper::mousePosition() const { int id = sgct::Engine::instance()->getCurrentWindowPtr()->getId(); double posX, posY; sgct::Engine::instance()->getMousePos(id, &posX, &posY); return glm::vec2(posX, posY); } -uint32_t SGCTWindowHandler::mouseButtons(int maxNumber) const { +uint32_t SGCTWindowWrapper::mouseButtons(int maxNumber) const { int id = sgct::Engine::instance()->getCurrentWindowPtr()->getId(); uint32_t result = 0; for (int i = 0; i < maxNumber; ++i) { @@ -74,18 +74,18 @@ uint32_t SGCTWindowHandler::mouseButtons(int maxNumber) const { return result; } -glm::ivec2 SGCTWindowHandler::currentWindowSize() const { +glm::ivec2 SGCTWindowWrapper::currentWindowSize() const { return glm::ivec2(sgct::Engine::instance()->getCurrentWindowPtr()->getXResolution(), sgct::Engine::instance()->getCurrentWindowPtr()->getYResolution()); } -glm::ivec2 SGCTWindowHandler::currentWindowResolution() const { +glm::ivec2 SGCTWindowWrapper::currentWindowResolution() const { int x,y; sgct::Engine::instance()->getCurrentWindowPtr()->getFinalFBODimensions(x, y); return glm::ivec2(x, y); } -bool SGCTWindowHandler::isRegularRendering() const { +bool SGCTWindowWrapper::isRegularRendering() const { // TODO: Needs to implement the nonlinear rendering check ---abock // sgct::SGCTWindow* w = sgct::Engine::instance()->getCurrentWindowPtr(); @@ -95,15 +95,15 @@ bool SGCTWindowHandler::isRegularRendering() const { return true; } -glm::mat4 SGCTWindowHandler::viewProjectionMatrix() const { +glm::mat4 SGCTWindowWrapper::viewProjectionMatrix() const { return sgct::Engine::instance()->getCurrentModelViewProjectionMatrix(); } -void SGCTWindowHandler::setNearFarClippingPlane(float near, float far) { +void SGCTWindowWrapper::setNearFarClippingPlane(float near, float far) { sgct::Engine::instance()->setNearAndFarClippingPlanes(near, far); } -glm::ivec4 SGCTWindowHandler::viewportPixelCoordinates() const { +glm::ivec4 SGCTWindowWrapper::viewportPixelCoordinates() const { int x1, xSize, y1, ySize; sgct::Engine::instance()->getCurrentWindowPtr()->getCurrentViewportPixelCoords(x1, y1, @@ -112,22 +112,22 @@ glm::ivec4 SGCTWindowHandler::viewportPixelCoordinates() const { return glm::ivec4(x1, xSize, y1, ySize); } -bool SGCTWindowHandler::isExternalControlConnected() const { +bool SGCTWindowWrapper::isExternalControlConnected() const { return sgct::Engine::instance()->isExternalControlConnected(); } -void SGCTWindowHandler::sendMessageToExternalControl(const std::vector& message) const { +void SGCTWindowWrapper::sendMessageToExternalControl(const std::vector& message) const { sgct::Engine::instance()->sendMessageToExternalControl( message.data(), message.size()); } -bool SGCTWindowHandler::isSimpleRendering() const { +bool SGCTWindowWrapper::isSimpleRendering() const { return (sgct::Engine::instance()->getCurrentRenderTarget() != sgct::Engine::NonLinearBuffer); } -void SGCTWindowHandler::takeScreenshot() const { +void SGCTWindowWrapper::takeScreenshot() const { sgct::Engine::instance()->takeScreenshot(); } diff --git a/src/interaction/deviceidentifier.cpp b/src/interaction/deviceidentifier.cpp index 408402129b..6743dc4e57 100644 --- a/src/interaction/deviceidentifier.cpp +++ b/src/interaction/deviceidentifier.cpp @@ -58,20 +58,8 @@ void DeviceIdentifier::scanDevices() { // sgct/glfw supports 16 joysticks, scans all of them for (int i = 0; i < MAXDEVICES; ++i) { - // check for device on position i - // const char* joystickName = sgct::Engine::getJoystickName(SGCT_JOYSTICK_1 + i); - - // int joystickPresent = sgct::Engine::getJoystickParam( GLFW_JOYSTICK_1 + i, GLFW_PRESENT ); - //numberOfAxes_[i] = sgct::Engine::getJoystickParam( GLFW_JOYSTICK_1 + i, GLFW_AXES ); - //numberOfButtons_[i] = sgct::Engine::getJoystickParam( GLFW_JOYSTICK_1 + i, GLFW_BUTTONS ); - - // joystick found void* joystickName = NULL; if( joystickName != NULL ) { -// sgct::Engine::getJoystickAxes(SGCT_JOYSTICK_1 + i, &numberOfAxes_[i]); -// sgct::Engine::getJoystickButtons(SGCT_JOYSTICK_1 + i, &numberOfButtons_[i]); - - // allocate axesPos_[i] = new float[numberOfAxes_[i]]; @@ -121,11 +109,6 @@ void DeviceIdentifier::update() { void DeviceIdentifier::update(const int device) { assert(this_); if(inputDevice_[device] != InputDevice::NONE) { - // const float* axesPos = sgct::Engine::getJoystickAxes(GLFW_JOYSTICK_1+device, &(numberOfAxes_[device]) ); - - //axesPos_[device] - //const unsigned char* buttons = sgct::Engine::getJoystickButtons( GLFW_JOYSTICK_1+device, &(numberOfButtons_[device]) ); - //buttons_[device] } } diff --git a/src/interaction/interactionhandler.cpp b/src/interaction/interactionhandler.cpp index 2a75c1fa8b..24846fd233 100644 --- a/src/interaction/interactionhandler.cpp +++ b/src/interaction/interactionhandler.cpp @@ -524,150 +524,17 @@ void InteractionHandler::distanceDelta(const PowerScaledScalar& distance, size_t d2[1] *= 0.85f; distanceDelta(d2, iterations + 1); } -// -//} -// -//void InteractionHandler::lookAt(const glm::quat &rotation) { -// //assert(this_); -// lockControls(); -//======= - //if (glm::angle(newdir, dir) < 90.0f) - //_camera->setPosition(relative); -//>>>>>>> feature/interactionhandler - - //unlockControls(); } void InteractionHandler::lookAt(const glm::quat& rotation) { } -//<<<<<<< HEAD -//void InteractionHandler::update(const double dt) { -// //assert(this_); -// // setting dt_ for use in callbacks -// _dt = dt; -// if (_enabled && _camera) { -// // fetch data from joysticks -// DeviceIdentifier::ref().update(); -// -// // update all controllers -// for (size_t i = 0; i < _controllers.size(); ++i) { -// _controllers[i]->update(); -// } -// } -//} -// -//double InteractionHandler::dt() { -// //assert(this_); -// return _dt; -//} -// -//glm::vec3 InteractionHandler::mapToTrackball(glm::vec2 mousePos) { -// const float RADIUS = 0.5; // Sphere radius -// glm::vec3 out = glm::vec3(mousePos.x-0.5, -1.0*(mousePos.y-0.5), 0); -// -// // Mapping according to Holroyds trackball -// // Piece-wise sphere + hyperbolic sheet -// if (out.x*out.x + out.y*out.y <= RADIUS*RADIUS/2.0) { -// //Spherical Region -// out.z = RADIUS*RADIUS - (out.x*out.x + out.y*out.y); -// out.z = out.z > 0.0f ? sqrtf(out.z) : 0.0f; -// } else { //Hyperbolic Region - for smooth z values -// out.z = (RADIUS*RADIUS)/(2.0f*sqrt(out.x*out.x + out.y*out.y)); -// } -// -// return glm::normalize(out); -//} -// -//glm::vec3 InteractionHandler::mapToCamera(glm::vec3 trackballPos) { -//// return glm::vec3((sgct::Engine::instance()->getActiveViewMatrix() * glm::vec4(trackballPos,0))); -// -// //Get x,y,z axis vectors of current camera view -// glm::vec3 currentViewYaxis = glm::normalize(_camera->lookUpVector()); -// psc viewDir = _camera->position() - _node->worldPosition(); -// glm::vec3 currentViewZaxis = glm::normalize(viewDir.vec3()); -// glm::vec3 currentViewXaxis = glm::normalize(glm::cross(currentViewYaxis, currentViewZaxis)); -// -// //mapping to camera co-ordinate -// currentViewXaxis*=trackballPos.x; -// currentViewYaxis*=trackballPos.y; -// currentViewZaxis*=trackballPos.z; -// return (currentViewXaxis + currentViewYaxis + currentViewZaxis); -//} -// -//void InteractionHandler::trackballRotate(int x, int y) { -// // Normalize mouse coordinates to [0,1] -// float width = static_cast(sgct::Engine::instance()->getActiveXResolution()); -// float height = static_cast(sgct::Engine::instance()->getActiveYResolution()); -// glm::vec2 mousePos = glm::vec2((float)x/width, (float)y/height); -// -// mousePos = glm::clamp(mousePos, -0.5, 1.5); // Ugly fix #1: Camera position becomes NaN on mouse values outside [-0.5, 1.5] -// //mousePos[1] = 0.5; // Ugly fix #2: Tempoarily only allow rotation around y -// -// glm::vec3 curTrackballPos = mapToTrackball(mousePos); -//// LDEBUG(mousePos.x << ", " << mousePos.y << " = " << curTrackballPos.x << ", " << curTrackballPos.y << ", " << curTrackballPos.z); -// -// // Disable movement on the first click for extra smoothness -// if (!_isMouseBeingPressedAndHeld) { -// _lastTrackballPos = curTrackballPos; -// _isMouseBeingPressedAndHeld = true; -// } -// -// if (curTrackballPos != _lastTrackballPos) { -// // calculate rotation angle (in radians) -// float rotationAngle = glm::angle(curTrackballPos, _lastTrackballPos); -// rotationAngle *= static_cast(dt())*100.0f; -// -// // Map trackballpos to camera -//// glm::vec3 trackballMappedToCamera = mapToCamera(_lastTrackballPos - curTrackballPos); -//// psc currentCamPos = camera_->getPosition(); -//// glm::vec3 nextCamPos = currentCamPos.getVec3f() + trackballMappedToCamera; -//// glm::vec3 rotationAxis = glm::cross(currentCamPos.getVec3f(), nextCamPos); -// -// glm::vec3 rotationAxis = glm::cross(_lastTrackballPos, curTrackballPos); -// rotationAxis = glm::normalize(rotationAxis); -// glm::quat quaternion = glm::angleAxis(rotationAngle, rotationAxis); -// -// // Apply quaternion to camera -// orbit(quaternion); -// -// _lastTrackballPos = curTrackballPos; -// } -//} -// void InteractionHandler::keyboardCallback(Key key, KeyModifier modifier, KeyAction action) { // TODO package in script const float speed = _controllerSensitivity; const float dt = static_cast(_deltaTime); if (action == KeyAction::Press || action == KeyAction::Repeat) { - - /*if (key == SGCT_KEY_S) { - glm::vec3 euler(speed * dt, 0.0, 0.0); - glm::quat rot = glm::quat(euler); - orbitDelta(rot); - } - if (key == SGCT_KEY_W) { - glm::vec3 euler(-speed * dt, 0.0, 0.0); - glm::quat rot = glm::quat(euler); - orbitDelta(rot); - } - if (key == SGCT_KEY_A) { - glm::vec3 euler(0.0, -speed * dt, 0.0); - glm::quat rot = glm::quat(euler); - orbitDelta(rot); - } - if (key == SGCT_KEY_D) { - glm::vec3 euler(0.0, speed * dt, 0.0); - glm::quat rot = glm::quat(euler); - orbitDelta(rot); - } - if (key == SGCT_KEY_Z) { - Time::ref().advanceTime(sgct::Engine::instance()->getDt()); - } - if (key == SGCT_KEY_X) { - Time::ref().advanceTime(-sgct::Engine::instance()->getDt()); - }*/ if ((key == Key::Right) && (modifier == KeyModifier::NoModifier)) { glm::vec3 euler(0.0, speed * dt*0.4, 0.0); glm::quat rot = glm::quat(euler); @@ -879,463 +746,6 @@ void InteractionHandler::clearKeyframes(){ _keyframes.clear(); _keyframeMutex.unlock(); } -} // namespace interaction -//>>>>>>> feature/interactionhandler -} // namespace openspace -// -//// open space includes -//#include -//#include -//#include -////#include -////#include -//#include -//#include -//#include -//#include -// -//#include -// -//#include -// -//namespace { -// const std::string _loggerCat = "InteractionHandler"; -//} -// -//namespace openspace { -//namespace interaction { -// -//InteractionHandler::InteractionHandler() -// : _camera(nullptr) -// , _node(nullptr) -// , _dt(0.0) -// , _lastTrackballPos(0.f) -// , _leftMouseButtonDown(false) -// , _isMouseBeingPressedAndHeld(false) -//{ -//} -// -//InteractionHandler::~InteractionHandler() { -// //for (size_t i = 0; i < _controllers.size(); ++i) { -// // delete _controllers[i]; -// //} -//} -// -////void InteractionHandler::init() { -//// assert( ! this_); -//// this_ = new InteractionHandler(); -////} -//// -////void InteractionHandler::deinit() { -//// assert(this_); -//// delete this_; -//// this_ = nullptr; -////} -//// -////InteractionHandler& InteractionHandler::ref() { -//// assert(this_); -//// return *this_; -////} -// -////bool InteractionHandler::isInitialized() { -//// return this_ != nullptr; -////} -// -////void InteractionHandler::connectDevices() { -//// //assert(this_); -//// assert(DeviceIdentifier::ref().isInitialized()); -//// -//// // for each device found -//// for(int i = 0; i < DeviceIdentifier::ref().numberOfDevices(); ++i) { -//// -//// // TODO -//// //if(DeviceIdentifier::ref().type(i) == InputDevice::XBOX) { -//// -//// // // found xbox, use xbox python controller -//// // JoystickExternalControl *joystickexcontrol = new JoystickExternalControl(RELATIVE_PATH"pyinput/Xbox.py"); -//// // joystickexcontrol->setInputDevice(i); -//// // addExternalControl(joystickexcontrol); -//// -//// //} else if(DeviceIdentifier::ref().type(i) == InputDevice::SPACENAVIGATOR) { -//// -//// // // found SpaceNavigator, use SpaceNavigator python controller -//// // JoystickExternalControl *joystickexcontrol = new JoystickExternalControl(RELATIVE_PATH"pyinput/SpaceNavigator.py"); -//// // joystickexcontrol->setInputDevice(i); -//// // addExternalControl(joystickexcontrol); -//// //} -//// -//// } -////} -//// -////void InteractionHandler::addExternalControl(ExternalControl* controller) { -//// //assert(this_); -//// if (controller != nullptr) { -//// _controllers.push_back(controller); -//// } -////} -// -//void InteractionHandler::setCamera(Camera *camera) { -// //assert(this_); -// _camera = camera; -//} -// -//Camera * InteractionHandler::getCamera() const { -// return _camera; -//} -// -//const psc InteractionHandler::getOrigin() const { -// if(_node) -// return _node->worldPosition(); -// return psc(); -//} -// -//void InteractionHandler::lockControls() { -// //assert(this_); -// _cameraGuard.lock(); -//} -// -//void InteractionHandler::unlockControls() { -// //assert(this_); -// _cameraGuard.unlock(); -//} -// -//void InteractionHandler::setFocusNode(SceneGraphNode *node) { -// //assert(this_); -// _node = node; -//} -// -//void InteractionHandler::rotate(const glm::quat &rotation) { -// //assert(this_); -// lockControls(); -// _camera->rotate(rotation); -// unlockControls(); -//} -// -//void InteractionHandler::orbit(const glm::quat &rotation) { -// //assert(this_); -// lockControls(); -// -// // the camera position -// psc relative = _camera->position(); -// -// // should be changed to something more dynamic =) -// psc origin; -// if (_node) { -// origin = _node->worldPosition(); -// } -// -// psc relative_origin_coordinate = relative - origin; -// //glm::mat4 rotation_matrix = glm::mat4_cast(glm::inverse(rotation)); -// //relative_origin_coordinate = relative_origin_coordinate.vec4() * glm::inverse(rotation); -// relative_origin_coordinate = glm::inverse(rotation) * relative_origin_coordinate.vec4(); -// relative = relative_origin_coordinate + origin; -// -// _camera->setPosition(relative); -// //camera_->rotate(rotation); -// //camera_->setRotation(glm::mat4_cast(rotation)); -// -// glm::mat4 la = glm::lookAt(_camera->position().vec3(), origin.vec3(), glm::rotate(rotation, _camera->lookUpVector())); -// _camera->setRotation(la); -// //camera_->setLookUpVector(); -// -// unlockControls(); -//} -// -//void InteractionHandler::distance(const PowerScaledScalar &distance) { -// //assert(this_); -// lockControls(); -// -// psc relative = _camera->position(); -// const psc origin = (_node) ? _node->worldPosition() : psc(); -// -// psc relative_origin_coordinate = relative - origin; -// const glm::vec3 dir(relative_origin_coordinate.direction()); -// glm:: vec3 newdir = dir * distance[0]; -// relative_origin_coordinate = newdir; -// relative_origin_coordinate[3] = distance[1]; -// relative = relative + relative_origin_coordinate; -// -// relative_origin_coordinate = relative - origin; -// newdir = relative_origin_coordinate.direction(); -// -// // update only if on the same side of the origin -// if(glm::angle(newdir, dir) < 90.0f) -// _camera->setPosition(relative); -// -// unlockControls(); -//} -// -//void InteractionHandler::lookAt(const glm::quat &rotation) { -// //assert(this_); -// lockControls(); -// -// unlockControls(); -//} -// -//void InteractionHandler::setRotation(const glm::quat &rotation) { -// //assert(this_); -// lockControls(); -// -// unlockControls(); -//} -// -//void InteractionHandler::update(const double dt) { -// //assert(this_); -// // setting dt_ for use in callbacks -// _dt = dt; -// if (_camera) { -// // fetch data from joysticks -// DeviceIdentifier::ref().update(); -// -// //// update all controllers -// //for (size_t i = 0; i < _controllers.size(); ++i) { -// // _controllers[i]->update(); -// //} -// } -//} -// -//double InteractionHandler::getDt() { -// //assert(this_); -// return _dt; -//} -// -//glm::vec3 InteractionHandler::mapToTrackball(glm::vec2 mousePos) { -// const float RADIUS = 0.5; // Sphere radius -// glm::vec3 out = glm::vec3(mousePos.x-0.5, -1.0*(mousePos.y-0.5), 0); -// -// // Mapping according to Holroyds trackball -// // Piece-wise sphere + hyperbolic sheet -// if (out.x*out.x + out.y*out.y <= RADIUS*RADIUS/2.0) { -// //Spherical Region -// out.z = RADIUS*RADIUS - (out.x*out.x + out.y*out.y); -// out.z = out.z > 0.0 ? sqrtf(out.z) : 0.0; -// } else { //Hyperbolic Region - for smooth z values -// out.z = (RADIUS*RADIUS)/(2.0*sqrt(out.x*out.x + out.y*out.y)); -// } -// -// return glm::normalize(out); -//} -// -//glm::vec3 InteractionHandler::mapToCamera(glm::vec3 trackballPos) { -//// return glm::vec3((sgct::Engine::instance()->getActiveViewMatrix() * glm::vec4(trackballPos,0))); -// -// //Get x,y,z axis vectors of current camera view -// glm::vec3 currentViewYaxis = glm::normalize(_camera->lookUpVector()); -// psc viewDir = _camera->position() - _node->worldPosition(); -// glm::vec3 currentViewZaxis = glm::normalize(viewDir.vec3()); -// glm::vec3 currentViewXaxis = glm::normalize(glm::cross(currentViewYaxis, currentViewZaxis)); -// -// //mapping to camera co-ordinate -// currentViewXaxis*=trackballPos.x; -// currentViewYaxis*=trackballPos.y; -// currentViewZaxis*=trackballPos.z; -// return (currentViewXaxis + currentViewYaxis + currentViewZaxis); -//} -// -//void InteractionHandler::trackballRotate(int x, int y) { -// // Normalize mouse coordinates to [0,1] -// float width = sgct::Engine::instance()->getActiveXResolution(); -// float height = sgct::Engine::instance()->getActiveYResolution(); -// glm::vec2 mousePos = glm::vec2((float)x/width, (float)y/height); -// -// mousePos = glm::clamp(mousePos, -0.5, 1.5); // Ugly fix #1: Camera position becomes NaN on mouse values outside [-0.5, 1.5] -// //mousePos[1] = 0.5; // Ugly fix #2: Tempoarily only allow rotation around y -// -// glm::vec3 curTrackballPos = mapToTrackball(mousePos); -//// LDEBUG(mousePos.x << ", " << mousePos.y << " = " << curTrackballPos.x << ", " << curTrackballPos.y << ", " << curTrackballPos.z); -// -// // Disable movement on the first click for extra smoothness -// if (!_isMouseBeingPressedAndHeld) { -// _lastTrackballPos = curTrackballPos; -// _isMouseBeingPressedAndHeld = true; -// } -// -// if (curTrackballPos != _lastTrackballPos) { -// // calculate rotation angle (in radians) -// float rotationAngle = glm::angle(curTrackballPos, _lastTrackballPos); -// rotationAngle *= getDt()*100.0f; -// -// // Map trackballpos to camera -//// glm::vec3 trackballMappedToCamera = mapToCamera(_lastTrackballPos - curTrackballPos); -//// psc currentCamPos = camera_->getPosition(); -//// glm::vec3 nextCamPos = currentCamPos.getVec3f() + trackballMappedToCamera; -//// glm::vec3 rotationAxis = glm::cross(currentCamPos.getVec3f(), nextCamPos); -// -// glm::vec3 rotationAxis = glm::cross(_lastTrackballPos, curTrackballPos); -// rotationAxis = glm::normalize(rotationAxis); -// glm::quat quaternion = glm::angleAxis(rotationAngle, rotationAxis); -// -// // Apply quaternion to camera -// orbit(quaternion); -// -// _lastTrackballPos = curTrackballPos; -// } -//} -//double acc = 1; -// -//void InteractionHandler::keyboardCallback(int key, int action) { -// // TODO package in script -// const double speed = 2.75; -// const double dt = getDt(); -// if(action == SGCT_PRESS || action == SGCT_REPEAT) { -// if (key == SGCT_KEY_S) { -// glm::vec3 euler(speed * dt, 0.0, 0.0); -// glm::quat rot = glm::quat(euler); -// orbit(rot); -// } -// if (key == SGCT_KEY_W) { -// glm::vec3 euler(-speed * dt, 0.0, 0.0); -// glm::quat rot = glm::quat(euler); -// orbit(rot); -// } -// if (key == SGCT_KEY_A) { -// glm::vec3 euler(0.0, -speed * dt, 0.0); -// glm::quat rot = glm::quat(euler); -// orbit(rot); -// } -// if (key == SGCT_KEY_D) { -// glm::vec3 euler(0.0, speed * dt, 0.0); -// glm::quat rot = glm::quat(euler); -// orbit(rot); -// } -// if (key == SGCT_KEY_Q) { -// Time::ref().advanceTime(dt); -// } -// if (key == 262) { -// glm::vec3 euler(0.0, speed * dt, 0.0); -// glm::quat rot = glm::quat(euler); -// rotate(rot); -// } -// if (key == 263) { -// glm::vec3 euler(0.0, -speed * dt, 0.0); -// glm::quat rot = glm::quat(euler); -// rotate(rot); -// } -// if (key == 264) { -// glm::vec3 euler(speed * dt, 0.0, 0.0); -// glm::quat rot = glm::quat(euler); -// rotate(rot); -// } -// if (key == 265) { -// glm::vec3 euler(-speed * dt, 0.0, 0.0); -// glm::quat rot = glm::quat(euler); -// rotate(rot); -// } -// if (key == SGCT_KEY_R) { -// PowerScaledScalar dist(-speed * dt, 0.0); -// distance(dist); -// } -// if (key == SGCT_KEY_F) { -// PowerScaledScalar dist(speed * dt, 0.0); -// distance(dist); -// } -// if (key == SGCT_KEY_T) { -// PowerScaledScalar dist(-speed * pow(10, 11) * dt, 0.0); -// distance(dist); -// } -// if (key == SGCT_KEY_G) { -// acc += 0.001; -// PowerScaledScalar dist(speed * pow(10, 8 * acc) * dt, 0.0); -// distance(dist); -// } -// if (key == SGCT_KEY_Y) { -// PowerScaledScalar dist(-speed * 100.0 * dt, 6.0); -// distance(dist); -// } -// if (key == SGCT_KEY_H) { -// PowerScaledScalar dist(speed * 100.0 * dt, 6.0); -// distance(dist); -// } -// -// if (key == SGCT_KEY_KP_SUBTRACT) { -// glm::vec2 s = OsEng.renderEngine().camera()->scaling(); -// s[1] -= 0.5; -// OsEng.renderEngine().camera()->setScaling(s); -// } -// if (key == SGCT_KEY_KP_ADD) { -// glm::vec2 s = OsEng.renderEngine().camera()->scaling(); -// s[1] += 0.5; -// OsEng.renderEngine().camera()->setScaling(s); -// } -// } -// /* -// if (key == '1') { -// SceneGraphNode* node = getSceneGraphNode("sun"); -// -// setFocusNode(node); -// getCamera()->setPosition(node->getWorldPosition() + psc(0.0, 0.0, 0.5, 10.0)); -// getCamera()->setCameraDirection(glm::vec3(0.0, 0.0, -1.0)); -// } -// -// if (key == '2') { -// SceneGraphNode* node = getSceneGraphNode("earth"); -// -// setFocusNode(node); -// getCamera()->setPosition(node->getWorldPosition() + psc(0.0, 0.0, 1.0, 8.0)); -// getCamera()->setCameraDirection(glm::vec3(0.0, 0.0, -1.0)); -// } -// -// -// if (key == '3') { -// SceneGraphNode* node = getSceneGraphNode("moon"); -// -// setFocusNode(node); -// getCamera()->setPosition(node->getWorldPosition() + psc(0.0, 0.0, 0.5, 8.0)); -// getCamera()->setCameraDirection(glm::vec3(0.0, 0.0, -1.0)); -// } -//*/ -// // std::pair >::iterator, std::multimap >::iterator> ret; -// if(action == SGCT_PRESS) { -// auto ret = _keyCallbacks.equal_range(key); -// for (auto it=ret.first; it!=ret.second; ++it) -// it->second(); -// } -// -// -//} -// -//void InteractionHandler::mouseButtonCallback(int key, int action) { -// //if(mouseControl_ != nullptr) { -// // mouseControl_->mouseButtonCallback(key,action); -// //} -// if (key == SGCT_MOUSE_BUTTON_LEFT && action == SGCT_PRESS) -// _leftMouseButtonDown = true; -// else if (key == SGCT_MOUSE_BUTTON_LEFT && action == SGCT_RELEASE) { -// _leftMouseButtonDown = false; -// _isMouseBeingPressedAndHeld = false; -// } -//} -// -//void InteractionHandler::mousePositionCallback(int x, int y) { -// if (_leftMouseButtonDown) -// trackballRotate(x,y); -// -// //if(mouseControl_ != nullptr) { -// // mouseControl_->mousePosCallback(x,y); -// //} -//} -// -//void InteractionHandler::mouseScrollWheelCallback(int pos) { -// //if(mouseControl_ != nullptr) { -// // mouseControl_->mouseScrollCallback(pos); -// //} -// const double speed = 4.75; -// const double dt = getDt(); -// if(pos < 0) { -// PowerScaledScalar dist(speed * dt, 0.0); -// distance(dist); -// } else if(pos > 0) { -// PowerScaledScalar dist(-speed * dt, 0.0); -// distance(dist); -// } -//} -// -////void InteractionHandler::addKeyCallback(int key, std::function f) { -//// //std::map > > _keyCallbacks; -//// -//// _keyCallbacks.insert(std::make_pair(key, f)); -////} -// -//} // namespace interaction -//} // namespace openspace +} // namespace interaction +} // namespace openspace diff --git a/src/interaction/luaconsole.cpp b/src/interaction/luaconsole.cpp index dbb2d8fb0d..9ee06c90b1 100644 --- a/src/interaction/luaconsole.cpp +++ b/src/interaction/luaconsole.cpp @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include diff --git a/src/interaction/mousecontroller.cpp b/src/interaction/mousecontroller.cpp index a860cc4b01..98b6577d55 100644 --- a/src/interaction/mousecontroller.cpp +++ b/src/interaction/mousecontroller.cpp @@ -25,7 +25,6 @@ #include #include -#include #include @@ -56,8 +55,6 @@ glm::vec3 MouseController::mapToTrackball(glm::vec2 mousePos) { } glm::vec3 MouseController::mapToCamera(glm::vec3 trackballPos) { - // return glm::vec3((sgct::Engine::instance()->getActiveViewMatrix() * glm::vec4(trackballPos,0))); - //Get x,y,z axis vectors of current camera view glm::vec3 currentViewYaxis = glm::normalize(_handler->camera()->lookUpVector()); psc viewDir = _handler->camera()->position() - _handler->focusNode()->worldPosition(); diff --git a/src/network/networkengine.cpp b/src/network/networkengine.cpp index 6916acc8bc..062547237d 100644 --- a/src/network/networkengine.cpp +++ b/src/network/networkengine.cpp @@ -181,11 +181,6 @@ void NetworkEngine::sendMessages() { // Prepending the message identifier to the front m.body.insert(m.body.begin(), identifier.data.begin(), identifier.data.end()); OsEng.windowWrapper()->sendMessageToExternalControl(m.body); -// sgct::Engine::instance()->sendMessageToExternalControl( -// m.body.data(), -// static_cast(m.body.size()) -// ); - //LINFO("Sent message: (s=" << m.body.size() << "): " << std::string(m.body.begin(), m.body.end())); } _messagesToSend.clear(); @@ -204,10 +199,6 @@ void NetworkEngine::sendInitialInformation() { std::vector payload = m.body; payload.insert(payload.begin(), identifier.data.begin(), identifier.data.end()); OsEng.windowWrapper()->sendMessageToExternalControl(payload); -// sgct::Engine::instance()->sendMessageToExternalControl( -// payload.data(), -// static_cast(payload.size()) -// ); LINFO("Sent initial message: (s=" << m.body.size() << ") [i=" << identifier.value << "]"); std::this_thread::sleep_for(std::chrono::milliseconds(SleepTime)); @@ -226,11 +217,6 @@ void NetworkEngine::sendInitialInformation() { d.insert(d.begin(), identifier.data.begin(), identifier.data.end()); OsEng.windowWrapper()->sendMessageToExternalControl(d); -// sgct::Engine::instance()->sendMessageToExternalControl( -// identifier.data.data(), -// 2 -// ); - _shouldPublishStatusMessage = true; } diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 60816f355f..dbc085ae0c 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -192,9 +192,6 @@ bool RenderEngine::initialize() { } bool RenderEngine::initializeGL() { - // LDEBUG("RenderEngine::initializeGL()"); -// sgct::SGCTWindow* wPtr = sgct::Engine::instance()->getCurrentWindowPtr(); - // TODO: Fix the power scaled coordinates in such a way that these // values can be set to more realistic values diff --git a/src/util/screenlog.cpp b/src/util/screenlog.cpp index eecc81d9cd..acd858a2db 100644 --- a/src/util/screenlog.cpp +++ b/src/util/screenlog.cpp @@ -25,7 +25,6 @@ #include #include -#include #include From 20861d68adb0e17acd8fc1f1188d52760c0d229e Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 26 Oct 2015 15:10:15 -0500 Subject: [PATCH 021/122] Changing WindowWrapper from pointer to reference --- include/openspace/engine/openspaceengine.h | 2 +- src/abuffer/abuffer.cpp | 2 +- src/abuffer/abuffervisualizer.cpp | 4 ++-- src/engine/openspaceengine.cpp | 5 +++-- src/interaction/luaconsole.cpp | 2 +- src/interaction/mousecontroller.cpp | 16 ++++++++-------- src/network/networkengine.cpp | 10 +++++----- src/rendering/renderengine.cpp | 20 ++++++++++---------- src/util/screenlog.cpp | 2 +- 9 files changed, 32 insertions(+), 31 deletions(-) diff --git a/include/openspace/engine/openspaceengine.h b/include/openspace/engine/openspaceengine.h index 9cfaf867b8..aadbb731b2 100644 --- a/include/openspace/engine/openspaceengine.h +++ b/include/openspace/engine/openspaceengine.h @@ -94,7 +94,7 @@ public: ModuleEngine* moduleEngine(); network::ParallelConnection* parallelConnection(); properties::PropertyOwner* globalPropertyOwner(); - WindowWrapper* windowWrapper(); + WindowWrapper& windowWrapper(); gui::GUI* gui(); diff --git a/src/abuffer/abuffer.cpp b/src/abuffer/abuffer.cpp index 7f95ba302c..cd9933edd7 100644 --- a/src/abuffer/abuffer.cpp +++ b/src/abuffer/abuffer.cpp @@ -322,7 +322,7 @@ void ABuffer::invalidateABuffer() { } void ABuffer::updateDimensions() { - glm::ivec2 res = OsEng.windowWrapper()->currentWindowResolution(); + glm::ivec2 res = OsEng.windowWrapper().currentWindowResolution(); _width = res.x; _height = res.y; diff --git a/src/abuffer/abuffervisualizer.cpp b/src/abuffer/abuffervisualizer.cpp index 7bb79ba2c6..d96868daa7 100644 --- a/src/abuffer/abuffervisualizer.cpp +++ b/src/abuffer/abuffervisualizer.cpp @@ -116,7 +116,7 @@ void ABufferVisualizer::render() { modelMatrix = glm::translate(modelMatrix, glm::vec3(0, 0, -1)); modelMatrix = modelMatrix * rotation; - _pointcloudProgram->setUniform("ViewProjection", OsEng.windowWrapper()->viewProjectionMatrix()); + _pointcloudProgram->setUniform("ViewProjection", OsEng.windowWrapper().viewProjectionMatrix()); _pointcloudProgram->setUniform("ModelTransform", modelMatrix); #if defined(MARKER_POINTS) @@ -148,7 +148,7 @@ void ABufferVisualizer::render() { const glm::mat4 scale = glm::scale(glm::mat4(1.0), glm::vec3(0.04, 0.04, 0.04)); glm::mat4 translate, mvp; - const glm::mat4 viewProjMatrix = OsEng.windowWrapper()->viewProjectionMatrix(); + const glm::mat4 viewProjMatrix = OsEng.windowWrapper().viewProjectionMatrix(); translate = glm::translate(glm::mat4(1.0), glm::vec3(0, 0, 0)); mvp = viewProjMatrix*modelMatrix*translate*rotationText*scale; Freetype::print3d(fontLight, mvp, "(0,0,0)"); diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 0c88b860b4..f8d1bdbf19 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -182,6 +182,7 @@ bool OpenSpaceEngine::create( ghoul::initialize(); ghoul_assert(!_engine, "OpenSpaceEngine was already created"); + ghoul_assert(windowWrapper != nullptr, "No Window Wrapper was provided"); // Initialize the LogManager and add the console log as this will be used every time // and we need a fall back if something goes wrong between here and when we add the @@ -834,9 +835,9 @@ properties::PropertyOwner* OpenSpaceEngine::globalPropertyOwner() { return _globalPropertyNamespace; } -WindowWrapper* OpenSpaceEngine::windowWrapper() { +WindowWrapper& OpenSpaceEngine::windowWrapper() { ghoul_assert(_windowWrapper, "Window Wrapper"); - return _windowWrapper; + return *_windowWrapper; } } // namespace openspace diff --git a/src/interaction/luaconsole.cpp b/src/interaction/luaconsole.cpp index 9ee06c90b1..0fca943962 100644 --- a/src/interaction/luaconsole.cpp +++ b/src/interaction/luaconsole.cpp @@ -282,7 +282,7 @@ void LuaConsole::charCallback(unsigned int codepoint, KeyModifier modifier) { void LuaConsole::render() { const float font_size = 10.0f; - glm::ivec4 viewportPixelCoordinates = OsEng.windowWrapper()->viewportPixelCoordinates(); + glm::ivec4 viewportPixelCoordinates = OsEng.windowWrapper().viewportPixelCoordinates(); int x1 = viewportPixelCoordinates.x; int xSize = viewportPixelCoordinates.y; int y1 = viewportPixelCoordinates.z; diff --git a/src/interaction/mousecontroller.cpp b/src/interaction/mousecontroller.cpp index 98b6577d55..d465ae0d89 100644 --- a/src/interaction/mousecontroller.cpp +++ b/src/interaction/mousecontroller.cpp @@ -70,7 +70,7 @@ glm::vec3 MouseController::mapToCamera(glm::vec3 trackballPos) { void MouseController::trackballRotate(int x, int y) { // Normalize mouse coordinates to [0,1] - glm::vec2 res = OsEng.windowWrapper()->currentWindowSize(); + glm::vec2 res = OsEng.windowWrapper().currentWindowSize(); glm::vec2 mousePos = glm::vec2((float)x / res.x, (float)y / res.y); mousePos = glm::clamp(mousePos, -0.5f, 1.5f); // Ugly fix #1: Camera position becomes NaN on mouse values outside [-0.5, 1.5] @@ -163,7 +163,7 @@ void OrbitalMouseController::button(MouseButton button, MouseAction action) { if (button == MouseButton::Left){ if (action == MouseAction::Press){ _leftMouseButtonDown = true; - _previousCursorPos[MouseButtons::ButtonLeft] = OsEng.windowWrapper()->mousePosition(); + _previousCursorPos[MouseButtons::ButtonLeft] = OsEng.windowWrapper().mousePosition(); } else if (action == MouseAction::Release) { _leftMouseButtonDown = false; @@ -173,7 +173,7 @@ void OrbitalMouseController::button(MouseButton button, MouseAction action) { else if (button == MouseButton::Right){ if (action == MouseAction::Press){ _rightMouseButtonDown = true; - _previousCursorPos[MouseButtons::ButtonRight] = OsEng.windowWrapper()->mousePosition(); + _previousCursorPos[MouseButtons::ButtonRight] = OsEng.windowWrapper().mousePosition(); } else if (action == MouseAction::Release) { _rightMouseButtonDown = false; @@ -183,7 +183,7 @@ void OrbitalMouseController::button(MouseButton button, MouseAction action) { else if (button == MouseButton::Middle){ if (action == MouseAction::Press){ _middleMouseButtonDown = true; - _previousCursorPos[MouseButtons::ButtonMiddle] = OsEng.windowWrapper()->mousePosition(); + _previousCursorPos[MouseButtons::ButtonMiddle] = OsEng.windowWrapper().mousePosition(); } else if (action == MouseAction::Release) { _middleMouseButtonDown = false; @@ -194,21 +194,21 @@ void OrbitalMouseController::button(MouseButton button, MouseAction action) { } void OrbitalMouseController::move(float x, float y) { - _currentCursorPos = OsEng.windowWrapper()->mousePosition(); + _currentCursorPos = OsEng.windowWrapper().mousePosition(); if (_leftMouseButtonDown) { glm::vec2 diff = _currentCursorPos - _previousCursorPos[MouseButtons::ButtonLeft]; - glm::vec2 res = OsEng.windowWrapper()->currentWindowSize(); + glm::vec2 res = OsEng.windowWrapper().currentWindowSize(); _currentCursorDiff[MouseButtons::ButtonLeft] = diff / res; } if (_rightMouseButtonDown) { glm::vec2 diff = _currentCursorPos - _previousCursorPos[MouseButtons::ButtonRight]; - glm::vec2 res = OsEng.windowWrapper()->currentWindowSize(); + glm::vec2 res = OsEng.windowWrapper().currentWindowSize(); _currentCursorDiff[MouseButtons::ButtonRight] = diff / res; } if (_middleMouseButtonDown) { glm::vec2 diff = _currentCursorPos - _previousCursorPos[MouseButtons::ButtonMiddle]; - glm::vec2 res = OsEng.windowWrapper()->currentWindowSize(); + glm::vec2 res = OsEng.windowWrapper().currentWindowSize(); _currentCursorDiff[MouseButtons::ButtonMiddle] = diff / res; } } diff --git a/src/network/networkengine.cpp b/src/network/networkengine.cpp index 062547237d..322927dc65 100644 --- a/src/network/networkengine.cpp +++ b/src/network/networkengine.cpp @@ -87,7 +87,7 @@ bool NetworkEngine::handleMessage(const std::string& message) { } void NetworkEngine::publishStatusMessage() { - if (!_shouldPublishStatusMessage || !OsEng.windowWrapper()->isExternalControlConnected()) + if (!_shouldPublishStatusMessage || !OsEng.windowWrapper().isExternalControlConnected()) return; // Protocol: // 8 bytes: time as a ET double @@ -164,7 +164,7 @@ void NetworkEngine::publishMessage(MessageIdentifier identifier, std::vectorisExternalControlConnected()) + if (!OsEng.windowWrapper().isExternalControlConnected()) return; for (Message& m : _messagesToSend) { @@ -180,7 +180,7 @@ void NetworkEngine::sendMessages() { // Prepending the message identifier to the front m.body.insert(m.body.begin(), identifier.data.begin(), identifier.data.end()); - OsEng.windowWrapper()->sendMessageToExternalControl(m.body); + OsEng.windowWrapper().sendMessageToExternalControl(m.body); } _messagesToSend.clear(); @@ -198,7 +198,7 @@ void NetworkEngine::sendInitialInformation() { std::vector payload = m.body; payload.insert(payload.begin(), identifier.data.begin(), identifier.data.end()); - OsEng.windowWrapper()->sendMessageToExternalControl(payload); + OsEng.windowWrapper().sendMessageToExternalControl(payload); LINFO("Sent initial message: (s=" << m.body.size() << ") [i=" << identifier.value << "]"); std::this_thread::sleep_for(std::chrono::milliseconds(SleepTime)); @@ -216,7 +216,7 @@ void NetworkEngine::sendInitialInformation() { std::vector d; d.insert(d.begin(), identifier.data.begin(), identifier.data.end()); - OsEng.windowWrapper()->sendMessageToExternalControl(d); + OsEng.windowWrapper().sendMessageToExternalControl(d); _shouldPublishStatusMessage = true; } diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index dbc085ae0c..cae6430530 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -197,7 +197,7 @@ bool RenderEngine::initializeGL() { // set the close clip plane and the far clip plane to extreme values while in // development - OsEng.windowWrapper()->setNearFarClippingPlane(0.001f, 1000.f); + OsEng.windowWrapper().setNearFarClippingPlane(0.001f, 1000.f); // ALL OF THIS HAS TO BE CHECKED // ---abock @@ -303,14 +303,14 @@ void RenderEngine::postSynchronizationPreDraw() { _globalBlackOutFactor = glm::smoothstep(1.f, 0.f, _currentFadeTime / _fadeDuration); else _globalBlackOutFactor = glm::smoothstep(0.f, 1.f, _currentFadeTime / _fadeDuration); - _currentFadeTime += static_cast(OsEng.windowWrapper()->averageDeltaTime()); + _currentFadeTime += static_cast(OsEng.windowWrapper().averageDeltaTime()); } } if (_mainCamera) _mainCamera->postSynchronizationPreDraw(); - bool windowResized = OsEng.windowWrapper()->windowHasResized(); + bool windowResized = OsEng.windowWrapper().windowHasResized(); if (windowResized) { generateGlslConfig(); _abuffer->reinitialize(); @@ -344,7 +344,7 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi // We need the window pointer // sgct::SGCTWindow* w = sgct::Engine::instance()->getCurrentWindowPtr(); - if (!OsEng.windowWrapper()->isSimpleRendering()) + if (!OsEng.windowWrapper().isSimpleRendering()) // if (sgct::Engine::instance()->getCurrentRenderTarget() == sgct::Engine::NonLinearBuffer) _abuffer->clear(); @@ -415,7 +415,7 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi // Print some useful information on the master viewport - if (OsEng.ref().isMaster() && OsEng.windowWrapper()->isSimpleRendering()) { + if (OsEng.ref().isMaster() && OsEng.windowWrapper().isSimpleRendering()) { // TODO: Adjust font_size properly when using retina screen const int font_size_mono = 10; const int font_size_time = 15; @@ -427,7 +427,7 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi if (_showInfo) { const sgct_text::Font* font = fontMono; - glm::ivec4 pixelCoords = OsEng.windowWrapper()->viewportPixelCoordinates(); + glm::ivec4 pixelCoords = OsEng.windowWrapper().viewportPixelCoordinates(); int x1 = pixelCoords.x; int xSize = pixelCoords.y; int y1 = pixelCoords.z; @@ -470,7 +470,7 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi float distToSurf = glm::length(nhPos.vec3()) - radius; PrintText(line++, "Distance to Pluto: % .1f (KM)", distToSurf); - PrintText(line++, "Avg. Frametime: %.5f", OsEng.windowWrapper()->averageDeltaTime()); + PrintText(line++, "Avg. Frametime: %.5f", OsEng.windowWrapper().averageDeltaTime()); //PrintText(line++, "Drawtime: %.5f", sgct::Engine::instance()->getDrawTime()); //PrintText(line++, "Frametime: %.5f", sgct::Engine::instance()->getDt()); @@ -589,7 +589,7 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi for (auto& it = entries.first; it != entries.second; ++it) { const ScreenLog::LogEntry* e = &(*it); - const double t = OsEng.windowWrapper()->time(); + const double t = OsEng.windowWrapper().time(); float diff = static_cast(t - e->timeStamp); // Since all log entries are ordered, once one is exceeding TTL, all have @@ -643,7 +643,7 @@ void RenderEngine::postDraw() { if (Time::ref().timeJumped()) Time::ref().setTimeJumped(false); if (_takeScreenshot) { - OsEng.windowWrapper()->takeScreenshot(); + OsEng.windowWrapper().takeScreenshot(); _takeScreenshot = false; } @@ -731,7 +731,7 @@ void RenderEngine::startFading(int direction, float fadeDuration) { void RenderEngine::generateGlslConfig() { ghoul_assert(_abuffer != nullptr, "ABuffer not initialized"); LDEBUG("Generating GLSLS config, expect shader recompilation"); - glm::ivec2 size = OsEng.windowWrapper()->currentWindowResolution(); + glm::ivec2 size = OsEng.windowWrapper().currentWindowResolution(); // TODO: Make this file creation dynamic and better in every way // TODO: If the screen size changes it is enough if this file is regenerated to diff --git a/src/util/screenlog.cpp b/src/util/screenlog.cpp index acd858a2db..fdffd770f0 100644 --- a/src/util/screenlog.cpp +++ b/src/util/screenlog.cpp @@ -34,7 +34,7 @@ ScreenLog::ScreenLog() {} void ScreenLog::log(ghoul::logging::LogManager::LogLevel level, const std::string& category, const std::string& message) { if (level >= ghoul::logging::LogManager::LogLevel::Info) - _entries.emplace_back(level, OsEng.windowWrapper()->time(), Log::getTimeString(), category, message); + _entries.emplace_back(level, OsEng.windowWrapper().time(), Log::getTimeString(), category, message); // Once reaching maximum size, reduce to half if (_entries.size() > MaximumSize) { From 390f5be4a8b6e881b0fb3601c4d958682a5077b2 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 26 Oct 2015 16:14:38 -0500 Subject: [PATCH 022/122] Removing includes of sgct.h --- include/openspace/engine/openspaceengine.h | 2 +- modules/base/rendering/renderablemodel.cpp | 1 - modules/base/rendering/renderableplanet.cpp | 2 - .../rendering/renderablemodelprojection.cpp | 1 - .../rendering/renderableplanetprojection.cpp | 1 - modules/onscreengui/src/gui.cpp | 38 +++++++++---------- src/abuffer/abuffer.cpp | 2 - src/engine/openspaceengine.cpp | 2 - src/interaction/deviceidentifier.cpp | 3 -- src/network/networkengine.cpp | 2 - src/util/camera.cpp | 5 --- 11 files changed, 19 insertions(+), 40 deletions(-) diff --git a/include/openspace/engine/openspaceengine.h b/include/openspace/engine/openspaceengine.h index aadbb731b2..62ea47e478 100644 --- a/include/openspace/engine/openspaceengine.h +++ b/include/openspace/engine/openspaceengine.h @@ -69,7 +69,7 @@ namespace network { namespace properties { class PropertyOwner; } - + class OpenSpaceEngine { public: static bool create(int argc, char** argv, WindowWrapper* windowWrapper, std::vector& sgctArguments); diff --git a/modules/base/rendering/renderablemodel.cpp b/modules/base/rendering/renderablemodel.cpp index 5c5c00aa6f..4fb5c67ee5 100644 --- a/modules/base/rendering/renderablemodel.cpp +++ b/modules/base/rendering/renderablemodel.cpp @@ -39,7 +39,6 @@ #include #include -#include #define _USE_MATH_DEFINES #include diff --git a/modules/base/rendering/renderableplanet.cpp b/modules/base/rendering/renderableplanet.cpp index ff5fc0228b..19f03e4c37 100644 --- a/modules/base/rendering/renderableplanet.cpp +++ b/modules/base/rendering/renderableplanet.cpp @@ -39,8 +39,6 @@ #include #include -#include - namespace { const std::string _loggerCat = "RenderablePlanet"; diff --git a/modules/newhorizons/rendering/renderablemodelprojection.cpp b/modules/newhorizons/rendering/renderablemodelprojection.cpp index 573cff0d7e..2214121792 100644 --- a/modules/newhorizons/rendering/renderablemodelprojection.cpp +++ b/modules/newhorizons/rendering/renderablemodelprojection.cpp @@ -34,7 +34,6 @@ #include #include -#include #include "imgui.h" #define _USE_MATH_DEFINES diff --git a/modules/newhorizons/rendering/renderableplanetprojection.cpp b/modules/newhorizons/rendering/renderableplanetprojection.cpp index 4c9cb3018e..7f3ee36aa1 100644 --- a/modules/newhorizons/rendering/renderableplanetprojection.cpp +++ b/modules/newhorizons/rendering/renderableplanetprojection.cpp @@ -40,7 +40,6 @@ #include #include -#include #include #include #include diff --git a/modules/onscreengui/src/gui.cpp b/modules/onscreengui/src/gui.cpp index ddcd52079d..ae6d7453aa 100644 --- a/modules/onscreengui/src/gui.cpp +++ b/modules/onscreengui/src/gui.cpp @@ -26,9 +26,7 @@ #include -// This needs to be included first due to Windows.h / winsock2.h complications -#define SGCT_WINDOWS_INCLUDE -#include +#include #include @@ -168,23 +166,23 @@ void GUI::initialize() { //io.IniSavingRate = 5.f; io.DeltaTime = 1.f / 60.f; //io.PixelCenterOffset = 0.5f; - io.KeyMap[ImGuiKey_Tab] = SGCT_KEY_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array. - io.KeyMap[ImGuiKey_LeftArrow] = SGCT_KEY_LEFT; - io.KeyMap[ImGuiKey_RightArrow] = SGCT_KEY_RIGHT; - io.KeyMap[ImGuiKey_UpArrow] = SGCT_KEY_UP; - io.KeyMap[ImGuiKey_DownArrow] = SGCT_KEY_DOWN; - io.KeyMap[ImGuiKey_Home] = SGCT_KEY_HOME; - io.KeyMap[ImGuiKey_End] = SGCT_KEY_END; - io.KeyMap[ImGuiKey_Delete] = SGCT_KEY_DELETE; - io.KeyMap[ImGuiKey_Backspace] = SGCT_KEY_BACKSPACE; - io.KeyMap[ImGuiKey_Enter] = SGCT_KEY_ENTER; - io.KeyMap[ImGuiKey_Escape] = SGCT_KEY_ESCAPE; - io.KeyMap[ImGuiKey_A] = SGCT_KEY_A; - io.KeyMap[ImGuiKey_C] = SGCT_KEY_C; - io.KeyMap[ImGuiKey_V] = SGCT_KEY_V; - io.KeyMap[ImGuiKey_X] = SGCT_KEY_X; - io.KeyMap[ImGuiKey_Y] = SGCT_KEY_Y; - io.KeyMap[ImGuiKey_Z] = SGCT_KEY_Z; + io.KeyMap[ImGuiKey_Tab] = static_cast(Key::Tab); + io.KeyMap[ImGuiKey_LeftArrow] = static_cast(Key::Left); + io.KeyMap[ImGuiKey_RightArrow] = static_cast(Key::Right); + io.KeyMap[ImGuiKey_UpArrow] = static_cast(Key::Up); + io.KeyMap[ImGuiKey_DownArrow] = static_cast(Key::Down); + io.KeyMap[ImGuiKey_Home] = static_cast(Key::Home); + io.KeyMap[ImGuiKey_End] = static_cast(Key::End); + io.KeyMap[ImGuiKey_Delete] = static_cast(Key::Delete); + io.KeyMap[ImGuiKey_Backspace] = static_cast(Key::BackSpace); + io.KeyMap[ImGuiKey_Enter] = static_cast(Key::Enter); + io.KeyMap[ImGuiKey_Escape] = static_cast(Key::Escape); + io.KeyMap[ImGuiKey_A] = static_cast(Key::A); + io.KeyMap[ImGuiKey_C] = static_cast(Key::C); + io.KeyMap[ImGuiKey_V] = static_cast(Key::V); + io.KeyMap[ImGuiKey_X] = static_cast(Key::X); + io.KeyMap[ImGuiKey_Y] = static_cast(Key::Y); + io.KeyMap[ImGuiKey_Z] = static_cast(Key::Z); io.RenderDrawListsFn = ImImpl_RenderDrawLists; //io.SetClipboardTextFn = ImImpl_SetClipboardTextFn; // @TODO implement? ---abock diff --git a/src/abuffer/abuffer.cpp b/src/abuffer/abuffer.cpp index cd9933edd7..9af9eda690 100644 --- a/src/abuffer/abuffer.cpp +++ b/src/abuffer/abuffer.cpp @@ -31,8 +31,6 @@ #include #include -#include - #include #include #include diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index f8d1bdbf19..aaffd14cae 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -26,8 +26,6 @@ #include -#define SGCT_WINDOWS_INCLUDE -#include #include #include diff --git a/src/interaction/deviceidentifier.cpp b/src/interaction/deviceidentifier.cpp index 6743dc4e57..a6d16cb42a 100644 --- a/src/interaction/deviceidentifier.cpp +++ b/src/interaction/deviceidentifier.cpp @@ -2,9 +2,6 @@ // open space includes #include -// sgct includes -//#include "sgct.h" - #include namespace openspace { diff --git a/src/network/networkengine.cpp b/src/network/networkengine.cpp index 322927dc65..83265ec2be 100644 --- a/src/network/networkengine.cpp +++ b/src/network/networkengine.cpp @@ -33,8 +33,6 @@ #include -#include "sgct.h" - namespace { const std::string _loggerCat = "NetworkEngine"; diff --git a/src/util/camera.cpp b/src/util/camera.cpp index b4d108076d..c67170f5b3 100644 --- a/src/util/camera.cpp +++ b/src/util/camera.cpp @@ -26,15 +26,10 @@ #include #include -// sgct includes -#include "sgct.h" - #include #include - namespace openspace { - Camera::Camera() : _maxFov(0.f) From 48d8d9e029d0c22227d2733c27ca56398d09a3be Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 26 Oct 2015 16:33:54 -0500 Subject: [PATCH 023/122] Update Ghoul version --- ext/ghoul | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/ghoul b/ext/ghoul index 9bd660cc60..0e816d93e9 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 9bd660cc60a6a4d5c96b5e583f4bdb0efd848034 +Subproject commit 0e816d93e9f7016caf1451400d20c27eae8b9bc7 From c644f5adcb704b4e5908964ad50a96fc2f79f6c8 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 27 Oct 2015 14:10:21 -0500 Subject: [PATCH 024/122] Updated ghoul version Place window in default configuration file in the top left --- config/sgct/single.xml | 2 +- ext/ghoul | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/sgct/single.xml b/config/sgct/single.xml index fabd2d3177..6e24842b3e 100644 --- a/config/sgct/single.xml +++ b/config/sgct/single.xml @@ -14,7 +14,7 @@ - + diff --git a/ext/ghoul b/ext/ghoul index 0e816d93e9..effa72d369 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 0e816d93e9f7016caf1451400d20c27eae8b9bc7 +Subproject commit effa72d369a2c0e3ea164c549a9305913012267e From 26520ed63b979a293f97a717db9c93ad034f4012 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 27 Oct 2015 14:24:09 -0500 Subject: [PATCH 025/122] Compile fix for the new GLM version --- modules/volume/rendering/renderablevolumegl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/volume/rendering/renderablevolumegl.cpp b/modules/volume/rendering/renderablevolumegl.cpp index de1deeb89f..b738995cab 100644 --- a/modules/volume/rendering/renderablevolumegl.cpp +++ b/modules/volume/rendering/renderablevolumegl.cpp @@ -112,7 +112,7 @@ RenderableVolumeGL::RenderableVolumeGL(const ghoul::Dictionary& dictionary) glm::vec4 scalingVec4(_boxScaling, _w); success = dictionary.getValue(KeyBoxScaling, scalingVec4); if (success) { - _boxScaling = scalingVec4.xyz; + _boxScaling = scalingVec4.xyz(); _w = scalingVec4.w; } else { From 327e2560be187b3c7e503a6cf3b28b45b18ddd79 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 27 Oct 2015 14:48:19 -0500 Subject: [PATCH 026/122] Remove X11 preprocessor defines for mouse buttons --- include/openspace/util/mouse.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/include/openspace/util/mouse.h b/include/openspace/util/mouse.h index 73c5aa940a..896f4396d5 100644 --- a/include/openspace/util/mouse.h +++ b/include/openspace/util/mouse.h @@ -65,6 +65,16 @@ enum class MouseAction { Repeat = 2 }; +// The X11 library header files define Button1-Button5 as defines, so they have to be +// removed before we can use them as unqualified identifiers for the enum ---abock +#ifdef unix +#undef Button1 +#undef Button2 +#undef Button3 +#undef Button4 +#undef Button5 +#endif // unix + enum class MouseButton { Button1 = 0, Button2 = 1, From 1149a0d38054701c22e7516507bf2af159be751f Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 27 Oct 2015 15:03:46 -0500 Subject: [PATCH 027/122] Compile fix for unit test cases where no windowwrapper is needed --- .../engine/wrapper/dummywindowwrapper.h | 64 +++++++++++++ .../openspace/engine/wrapper/windowwrapper.h | 1 + src/CMakeLists.txt | 2 + src/engine/wrapper/dummywindowwrapper.cpp | 89 +++++++++++++++++++ tests/main.cpp | 4 +- 5 files changed, 158 insertions(+), 2 deletions(-) create mode 100644 include/openspace/engine/wrapper/dummywindowwrapper.h create mode 100644 src/engine/wrapper/dummywindowwrapper.cpp diff --git a/include/openspace/engine/wrapper/dummywindowwrapper.h b/include/openspace/engine/wrapper/dummywindowwrapper.h new file mode 100644 index 0000000000..19946483d3 --- /dev/null +++ b/include/openspace/engine/wrapper/dummywindowwrapper.h @@ -0,0 +1,64 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2015 * + * * + * 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 __DUMMYWINDOWWRAPPER_H__ +#define __DUMMYWINDOWWRAPPER_H__ + +#include + +namespace openspace { + +class DummyWindowWrapper : public WindowWrapper { +public: + void setBarrier(bool enabled) override; + void clearAllWindows() override; + bool windowHasResized() const override; + double time() const override; + double averageDeltaTime() const override; + uint32_t mouseButtons(int maxNumber = 8) const override; + glm::vec2 mousePosition() const override; + glm::ivec2 currentWindowSize() const override; + glm::ivec2 currentWindowResolution() const override; + bool isRegularRendering() const override; + + glm::mat4 viewProjectionMatrix() const override; + void setNearFarClippingPlane(float near, float far) override; + + glm::ivec4 viewportPixelCoordinates() const override; + + bool isExternalControlConnected() const override; + void sendMessageToExternalControl(const std::vector& message) const override; + + // true for single viewport, single window; false otherwise + bool isSimpleRendering() const override; + + void takeScreenshot() const override; + + //virtual void forEachWindow(std::function function) = 0; + +}; + +} // namespace openspace + +#endif // __DUMMYWINDOWWRAPPER_H__ diff --git a/include/openspace/engine/wrapper/windowwrapper.h b/include/openspace/engine/wrapper/windowwrapper.h index 4d6c28a8e2..af62e55cc6 100644 --- a/include/openspace/engine/wrapper/windowwrapper.h +++ b/include/openspace/engine/wrapper/windowwrapper.h @@ -29,6 +29,7 @@ #include #include +#include namespace openspace { diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 82332c1fc5..7de686959d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -34,6 +34,7 @@ set(OPENSPACE_SOURCE ${OPENSPACE_BASE_DIR}/src/engine/logfactory.cpp ${OPENSPACE_BASE_DIR}/src/engine/moduleengine.cpp ${OPENSPACE_BASE_DIR}/src/engine/openspaceengine.cpp + ${OPENSPACE_BASE_DIR}/src/engine/wrapper/dummywindowwrapper.cpp ${OPENSPACE_BASE_DIR}/src/engine/wrapper/sgctwindowwrapper.cpp ${OPENSPACE_BASE_DIR}/src/interaction/controller.cpp ${OPENSPACE_BASE_DIR}/src/interaction/deviceidentifier.cpp @@ -99,6 +100,7 @@ set(OPENSPACE_HEADER ${OPENSPACE_BASE_DIR}/include/openspace/engine/logfactory.h ${OPENSPACE_BASE_DIR}/include/openspace/engine/moduleengine.h ${OPENSPACE_BASE_DIR}/include/openspace/engine/openspaceengine.h + ${OPENSPACE_BASE_DIR}/include/openspace/engine/wrapper/dummywindowwrapper.h ${OPENSPACE_BASE_DIR}/include/openspace/engine/wrapper/sgctwindowwrapper.h ${OPENSPACE_BASE_DIR}/include/openspace/engine/wrapper/windowwrapper.h ${OPENSPACE_BASE_DIR}/include/openspace/interaction/controller.h diff --git a/src/engine/wrapper/dummywindowwrapper.cpp b/src/engine/wrapper/dummywindowwrapper.cpp new file mode 100644 index 0000000000..fb569b594e --- /dev/null +++ b/src/engine/wrapper/dummywindowwrapper.cpp @@ -0,0 +1,89 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2015 * + * * + * 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 { + +void DummyWindowWrapper::setBarrier(bool enabled) {} + +void DummyWindowWrapper::clearAllWindows() {} + +bool DummyWindowWrapper::windowHasResized() const { + return false; +} + +double DummyWindowWrapper::time() const { + return 0.0; +} + +double DummyWindowWrapper::averageDeltaTime() const { + return 0.0; +} + +glm::vec2 DummyWindowWrapper::mousePosition() const { + return glm::vec2(0.f); +} + +uint32_t DummyWindowWrapper::mouseButtons(int maxNumber) const { + return 0; +} + +glm::ivec2 DummyWindowWrapper::currentWindowSize() const { + return glm::ivec2(0); +} + +glm::ivec2 DummyWindowWrapper::currentWindowResolution() const { + return glm::ivec2(0); +} + +bool DummyWindowWrapper::isRegularRendering() const { + return true; +} + +glm::mat4 DummyWindowWrapper::viewProjectionMatrix() const { + return glm::mat4(1.f); +} + +void DummyWindowWrapper::setNearFarClippingPlane(float near, float far) {} + +glm::ivec4 DummyWindowWrapper::viewportPixelCoordinates() const { + return glm::ivec4(0); +} + +bool DummyWindowWrapper::isExternalControlConnected() const { + return false; +} + +void DummyWindowWrapper::sendMessageToExternalControl(const std::vector& message) const { +} + +bool DummyWindowWrapper::isSimpleRendering() const { + return true; +} + +void DummyWindowWrapper::takeScreenshot() const {} + +} // namespace openspace + diff --git a/tests/main.cpp b/tests/main.cpp index c8c43078ff..fcc276adc3 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -36,7 +36,7 @@ //#include //#include #include -#include +#include #include #include #include @@ -54,7 +54,7 @@ namespace { int main(int argc, char** argv) { std::vector args; - openspace::OpenSpaceEngine::create(argc, argv, new openspace::Window, args); + openspace::OpenSpaceEngine::create(argc, argv, new openspace::DummyWindowWrapper, args); testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); From dfd177a9aef5508dae070cdc82dc3835002b04b7 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Fri, 30 Oct 2015 22:54:49 -0500 Subject: [PATCH 028/122] Updated ghoul version --- ext/ghoul | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/ghoul b/ext/ghoul index effa72d369..f9c8ce793b 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit effa72d369a2c0e3ea164c549a9305913012267e +Subproject commit f9c8ce793b58062b2b6c8973f50f22b9ecd89436 From bbb622f555cca2a682563ee67ae648f19419c94c Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 2 Nov 2015 21:40:45 -0500 Subject: [PATCH 029/122] Initial work on integrating fontrendering into ghoul --- ext/ghoul | 2 +- include/openspace/engine/openspaceengine.h | 11 ++++++- include/openspace/rendering/renderengine.h | 8 ++++- include/openspace/util/keys.h | 3 ++ src/engine/openspaceengine.cpp | 37 ++++++++++++++++++++++ src/rendering/renderengine.cpp | 16 +++++++++- 6 files changed, 73 insertions(+), 4 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index f9c8ce793b..42837d0083 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit f9c8ce793b58062b2b6c8973f50f22b9ecd89436 +Subproject commit 42837d00835a618643a5e237241d9e3310feaf4d diff --git a/include/openspace/engine/openspaceengine.h b/include/openspace/engine/openspaceengine.h index 62ea47e478..f44b4cb4ad 100644 --- a/include/openspace/engine/openspaceengine.h +++ b/include/openspace/engine/openspaceengine.h @@ -27,12 +27,14 @@ #include -#include #include #include #include +#include +#include + #include #include @@ -40,6 +42,10 @@ namespace ghoul { namespace cmdparser { class CommandlineParser; } +namespace fontrendering { + class FontManager; +} + } namespace openspace { @@ -95,6 +101,7 @@ public: network::ParallelConnection* parallelConnection(); properties::PropertyOwner* globalPropertyOwner(); WindowWrapper& windowWrapper(); + ghoul::fontrendering::FontManager& fontManager(); gui::GUI* gui(); @@ -128,6 +135,7 @@ private: bool gatherCommandlineArguments(); bool loadSpiceKernels(); void loadFonts(); + void loadFonts2(); void runScripts(const ghoul::Dictionary& scripts); void runStartupScripts(); void configureLogging(); @@ -145,6 +153,7 @@ private: gui::GUI* _gui; network::ParallelConnection* _parallelConnection; WindowWrapper* _windowWrapper; + ghoul::fontrendering::FontManager*_fontManager; properties::PropertyOwner* _globalPropertyNamespace; diff --git a/include/openspace/rendering/renderengine.h b/include/openspace/rendering/renderengine.h index df1a5651fa..ec05ed1035 100644 --- a/include/openspace/rendering/renderengine.h +++ b/include/openspace/rendering/renderengine.h @@ -31,7 +31,11 @@ #include namespace ghoul { - class SharedMemory; +namespace fontrendering { + class Font; +} + +class SharedMemory; } namespace openspace { @@ -131,6 +135,8 @@ private: bool _doPerformanceMeasurements; ghoul::SharedMemory* _performanceMemory; + + ghoul::fontrendering::Font* _mainFont; void generateGlslConfig(); diff --git a/include/openspace/util/keys.h b/include/openspace/util/keys.h index 60ba85011b..65cde31f49 100644 --- a/include/openspace/util/keys.h +++ b/include/openspace/util/keys.h @@ -57,6 +57,9 @@ // All values that are defined here are compatible with (and are based on) the // definitions GLFW v3.1 +#include +#include + namespace openspace { enum class KeyAction { diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index aaffd14cae..27d21eaaf2 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -57,6 +57,7 @@ #include #include #include +#include // std #include @@ -405,6 +406,7 @@ bool OpenSpaceEngine::initialize() { // Load a light and a monospaced font loadFonts(); + loadFonts2(); LINFO("Initializing GUI"); _gui->initialize(); @@ -577,6 +579,36 @@ void OpenSpaceEngine::loadFonts() { } } +void OpenSpaceEngine::loadFonts2() { + ghoul::Dictionary fonts; + configurationManager()->getValue(ConfigurationManager::KeyFonts, fonts); + + _fontManager = new ghoul::fontrendering::FontManager; + for (const std::string& key : fonts.keys()) { + std::string font; + fonts.getValue(key, font); + font = absPath(font); + + if(!FileSys.fileExists(font)) { + LERROR("Could not find font '" << font << "'"); + continue; + } + + LINFO("Registering font '" << font << "' with key '" << key << "'"); + bool success = _fontManager->registerFont(key, font); + + if (!success) + LERROR("Error registering font '" << font << "' with key '" << key << "'"); + } + + bool initSuccess = ghoul::fontrendering::FontRenderer::initialize(); + if (!initSuccess) + LERROR("Error initializing default font renderer"); + + ghoul::fontrendering::FontRenderer::defaultRenderer()->setWindowSize(glm::vec2(_windowWrapper->currentWindowSize())); + +} + void OpenSpaceEngine::configureLogging() { if (configurationManager()->hasKeyAndValue(ConfigurationManager::KeyLogLevel)) { std::string logLevel; @@ -837,5 +869,10 @@ WindowWrapper& OpenSpaceEngine::windowWrapper() { ghoul_assert(_windowWrapper, "Window Wrapper"); return *_windowWrapper; } + +ghoul::fontrendering::FontManager& OpenSpaceEngine::fontManager() { + ghoul_assert(_fontManager, "Font Manager"); + return *_fontManager; +} } // namespace openspace diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index cae6430530..e9e9553d00 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -50,6 +50,8 @@ #include #include #include +#include +#include #include #ifdef GHOUL_USE_DEVIL @@ -199,6 +201,8 @@ bool RenderEngine::initializeGL() { // development OsEng.windowWrapper().setNearFarClippingPlane(0.001f, 1000.f); + _mainFont = OsEng.fontManager().font(constants::fonts::keyMono, 10); + // ALL OF THIS HAS TO BE CHECKED // ---abock @@ -457,7 +461,17 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi glm::vec4 targetColor(0.00, 0.75, 1.00, 1); double dt = Time::ref().deltaTime(); - PrintColorTextArg(line++, "Simulation increment (s): %.0f", 10, glm::vec4(1), dt); + + using namespace ghoul::fontrendering; + FontRenderer::defaultRenderer()->render( + *_mainFont, + glm::vec2(10.f, static_cast(startY / 2 - font_size_mono * line++ * 2)), + glm::vec4(1.f), + "Simulation increment (s): %.0f", + dt + ); + +// PrintColorTextArg(line++, "Simulation increment (s): %.0f", 10, glm::vec4(1), dt); psc nhPos; double lt; From c61d1cc86156e66c4f9bb49a3e444c9a96bd771f Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 3 Nov 2015 20:53:01 -0500 Subject: [PATCH 030/122] Use correct window parameter for font rendering --- ext/ghoul | 2 +- src/engine/openspaceengine.cpp | 2 +- src/rendering/renderengine.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index 42837d0083..56bde8fbde 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 42837d00835a618643a5e237241d9e3310feaf4d +Subproject commit 56bde8fbdedcc38dce77e87c21c02d1d3d83ac35 diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 27d21eaaf2..6d9b6e0b99 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -605,7 +605,7 @@ void OpenSpaceEngine::loadFonts2() { if (!initSuccess) LERROR("Error initializing default font renderer"); - ghoul::fontrendering::FontRenderer::defaultRenderer()->setWindowSize(glm::vec2(_windowWrapper->currentWindowSize())); + ghoul::fontrendering::FontRenderer::defaultRenderer()->setWindowSize(glm::vec2(_windowWrapper->currentWindowResolution())); } diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index e9e9553d00..17152a10ec 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -201,7 +201,7 @@ bool RenderEngine::initializeGL() { // development OsEng.windowWrapper().setNearFarClippingPlane(0.001f, 1000.f); - _mainFont = OsEng.fontManager().font(constants::fonts::keyMono, 10); + _mainFont = OsEng.fontManager().font(constants::fonts::keyMono, 20); // ALL OF THIS HAS TO BE CHECKED // ---abock @@ -465,7 +465,7 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi using namespace ghoul::fontrendering; FontRenderer::defaultRenderer()->render( *_mainFont, - glm::vec2(10.f, static_cast(startY / 2 - font_size_mono * line++ * 2)), + glm::vec2(10.f, static_cast(startY - font_size_mono * line++ * 2)), glm::vec4(1.f), "Simulation increment (s): %.0f", dt From 177ec6d568f8fd2f12b6a9f061511a1d306904a6 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Wed, 11 Nov 2015 00:32:30 -0500 Subject: [PATCH 031/122] Apply new changes to Fontrendering --- ext/ghoul | 2 +- src/engine/openspaceengine.cpp | 4 ++-- src/rendering/renderengine.cpp | 5 ++++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index 56bde8fbde..e2170b1bd2 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 56bde8fbdedcc38dce77e87c21c02d1d3d83ac35 +Subproject commit e2170b1bd2acdd46a23029729b8fbad18fa39c69 diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 6d9b6e0b99..3410f646f9 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -595,7 +595,7 @@ void OpenSpaceEngine::loadFonts2() { } LINFO("Registering font '" << font << "' with key '" << key << "'"); - bool success = _fontManager->registerFont(key, font); + bool success = _fontManager->registerFontPath(key, font); if (!success) LERROR("Error registering font '" << font << "' with key '" << key << "'"); @@ -605,7 +605,7 @@ void OpenSpaceEngine::loadFonts2() { if (!initSuccess) LERROR("Error initializing default font renderer"); - ghoul::fontrendering::FontRenderer::defaultRenderer()->setWindowSize(glm::vec2(_windowWrapper->currentWindowResolution())); + ghoul::fontrendering::FontRenderer::defaultRenderer().setWindowSize(glm::vec2(_windowWrapper->currentWindowResolution())); } diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 17152a10ec..da8a05b227 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -462,14 +462,17 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi glm::vec4 targetColor(0.00, 0.75, 1.00, 1); double dt = Time::ref().deltaTime(); + if (_mainFont) { using namespace ghoul::fontrendering; - FontRenderer::defaultRenderer()->render( + FontRenderer::defaultRenderer().render( *_mainFont, glm::vec2(10.f, static_cast(startY - font_size_mono * line++ * 2)), glm::vec4(1.f), + glm::vec4(0.f, 0.f, 0.f, 1.f), "Simulation increment (s): %.0f", dt ); + } // PrintColorTextArg(line++, "Simulation increment (s): %.0f", 10, glm::vec4(1), dt); From a7807e5581077fe1a539f82da2a44f7da6c1e0ff Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Fri, 13 Nov 2015 18:18:42 -0500 Subject: [PATCH 032/122] Updated Ghoul version --- ext/ghoul | 2 +- src/engine/openspaceengine.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ext/ghoul b/ext/ghoul index e2170b1bd2..f9fade558b 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit e2170b1bd2acdd46a23029729b8fbad18fa39c69 +Subproject commit f9fade558b471e67371ee5e55442d9c397d3ff7c diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 3410f646f9..71efb9b864 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -584,6 +584,7 @@ void OpenSpaceEngine::loadFonts2() { configurationManager()->getValue(ConfigurationManager::KeyFonts, fonts); _fontManager = new ghoul::fontrendering::FontManager; + for (const std::string& key : fonts.keys()) { std::string font; fonts.getValue(key, font); From 2cf7dfb27df87e77aa88d7e06d88995f95bfda15 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 16 Nov 2015 19:21:05 -0500 Subject: [PATCH 033/122] Changed RenderEngine to use Ghoul fontrendering instead of SGCT --- ext/ghoul | 2 +- include/openspace/rendering/renderengine.h | 2 - src/engine/openspaceengine.cpp | 3 +- src/rendering/renderengine.cpp | 469 ++++++++++++--------- src/util/time.cpp | 1 - 5 files changed, 266 insertions(+), 211 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index f9fade558b..f6dbd18a66 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit f9fade558b471e67371ee5e55442d9c397d3ff7c +Subproject commit f6dbd18a665b3b13cef7f70310f1c6fc416a7c5f diff --git a/include/openspace/rendering/renderengine.h b/include/openspace/rendering/renderengine.h index ec05ed1035..c0a517ae1d 100644 --- a/include/openspace/rendering/renderengine.h +++ b/include/openspace/rendering/renderengine.h @@ -136,8 +136,6 @@ private: bool _doPerformanceMeasurements; ghoul::SharedMemory* _performanceMemory; - ghoul::fontrendering::Font* _mainFont; - void generateGlslConfig(); float _globalBlackOutFactor; diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 71efb9b864..071dea96b5 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -583,7 +583,8 @@ void OpenSpaceEngine::loadFonts2() { ghoul::Dictionary fonts; configurationManager()->getValue(ConfigurationManager::KeyFonts, fonts); - _fontManager = new ghoul::fontrendering::FontManager; + const glm::ivec3 fontAtlasSize{1024, 1024, 1}; + _fontManager = new ghoul::fontrendering::FontManager(fontAtlasSize); for (const std::string& key : fonts.keys()) { std::string font; diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index da8a05b227..9d03f449bf 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -201,8 +201,6 @@ bool RenderEngine::initializeGL() { // development OsEng.windowWrapper().setNearFarClippingPlane(0.001f, 1000.f); - _mainFont = OsEng.fontManager().font(constants::fonts::keyMono, 20); - // ALL OF THIS HAS TO BE CHECKED // ---abock @@ -420,238 +418,297 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi // Print some useful information on the master viewport if (OsEng.ref().isMaster() && OsEng.windowWrapper().isSimpleRendering()) { - // TODO: Adjust font_size properly when using retina screen - const int font_size_mono = 10; - const int font_size_time = 15; - const int font_size_light = 8; - const int font_with_light = static_cast(font_size_light*0.7); - const sgct_text::Font* fontLight = sgct_text::FontManager::instance()->getFont(constants::fonts::keyLight, font_size_light); - const sgct_text::Font* fontMono = sgct_text::FontManager::instance()->getFont(constants::fonts::keyMono, font_size_mono); - const sgct_text::Font* fontTime = sgct_text::FontManager::instance()->getFont(constants::fonts::keyMono, font_size_time); + // TODO: Adjust font_size properly when using retina screen + const float fontSizeMono = 10.f; + const float fontSizeTime = 15.f; - if (_showInfo) { - const sgct_text::Font* font = fontMono; - glm::ivec4 pixelCoords = OsEng.windowWrapper().viewportPixelCoordinates(); - int x1 = pixelCoords.x; - int xSize = pixelCoords.y; - int y1 = pixelCoords.z; - int ySize = pixelCoords.w; - int startY = ySize - 2 * font_size_time; - //const glm::vec2& scaling = _mainCamera->scaling(); - //const glm::vec3& viewdirection = _mainCamera->viewDirection(); - //const psc& position = _mainCamera->position(); - //const psc& origin = OsEng.interactionHandler()->focusNode()->worldPosition(); - //const PowerScaledScalar& pssl = (position - origin).length(); - - // Next 2 lines neccesary for instrument switching to work. - // GUI PRINT - // Using a macro to shorten line length and increase readability + using Font = ghoul::fontrendering::Font; + using ghoul::fontrendering::RenderFont; + + Font* fontMono = OsEng.fontManager().font(constants::fonts::keyMono, fontSizeMono); + Font* fontTime = OsEng.fontManager().font(constants::fonts::keyMono, fontSizeTime); + + if (fontMono && fontTime) { + if (_showInfo) { + double currentTime = Time::ref().currentTime(); + + glm::vec2 penPosition = glm::vec2(10.f, OsEng.windowWrapper().viewportPixelCoordinates().w); - int line = 0; - - double currentTime = Time::ref().currentTime(); + penPosition.y -= fontTime->height(); + RenderFont(fontTime, + penPosition, + "Date: %s", + Time::ref().currentTimeUTC().c_str() + ); + + penPosition.y -= fontMono->height(); + RenderFont(fontMono, + penPosition, + "Simulation increment (s): %.0f", + Time::ref().deltaTime() + ); - //PrintText(line++, "Date: %s", Time::ref().currentTimeUTC().c_str()); - std::string timeString = Time::ref().currentTimeUTC(); - if (timeString.size() > 11) - // This should never happen, but it's an emergency hack ---abock - timeString[11] = ' '; -// Freetype::print(fontTime, 10, static_cast(startY - font_size_mono * line++ * 2), glm::vec4(1), "Date: %s", timeString.c_str()); - Freetype::print(fontTime, 10, static_cast(startY - font_size_mono * line++ * 2), "Date: %s", timeString.c_str()); - - glm::vec4 targetColor(0.00, 0.75, 1.00, 1); - double dt = Time::ref().deltaTime(); - - if (_mainFont) { - using namespace ghoul::fontrendering; - FontRenderer::defaultRenderer().render( - *_mainFont, - glm::vec2(10.f, static_cast(startY - font_size_mono * line++ * 2)), - glm::vec4(1.f), - glm::vec4(0.f, 0.f, 0.f, 1.f), - "Simulation increment (s): %.0f", - dt - ); - } + + glm::vec4 targetColor(0.00, 0.75, 1.00, 1); -// PrintColorTextArg(line++, "Simulation increment (s): %.0f", 10, glm::vec4(1), dt); + psc nhPos; + double lt; + SpiceManager::ref().getTargetPosition("PLUTO", "NEW HORIZONS", "GALACTIC", "NONE", currentTime, nhPos, lt); + float a, b, c; + SpiceManager::ref().getPlanetEllipsoid("PLUTO", a, b, c); + float radius = (a + b) / 2.f; + float distToSurf = glm::length(nhPos.vec3()) - radius; + + penPosition.y -= fontMono->height(); + RenderFont(fontMono, + penPosition, + "Distance to Pluto: % .1f (KM)", + distToSurf + ); + + penPosition.y -= fontMono->height(); + RenderFont(fontMono, + penPosition, + "Avg. Frametime: %.5f", + OsEng.windowWrapper().averageDeltaTime() + ); + + + #ifdef OPENSPACE_MODULE_NEWHORIZONS_ENABLED + if (openspace::ImageSequencer2::ref().isReady()) { + double remaining = openspace::ImageSequencer2::ref().getNextCaptureTime() - currentTime; + float t = static_cast(1.0 - remaining / openspace::ImageSequencer2::ref().getIntervalLength()); + std::string progress = "|"; + int g = static_cast((t* 24) + 1); + g = std::max(g, 0); + for (int i = 0; i < g; i++) + progress.append("-"); + progress.append(">"); + for (int i = 0; i < 25 - g; i++) + progress.append(" "); - psc nhPos; - double lt; - SpiceManager::ref().getTargetPosition("PLUTO", "NEW HORIZONS", "GALACTIC", "NONE", currentTime, nhPos, lt); - //nhPos[3] += 3; - float a, b, c; - SpiceManager::ref().getPlanetEllipsoid("PLUTO", a, b, c); - float radius = (a + b) / 2.f; + std::string str = ""; + openspace::SpiceManager::ref().getDateFromET(openspace::ImageSequencer2::ref().getNextCaptureTime(), str, "YYYY MON DD HR:MN:SC"); - float distToSurf = glm::length(nhPos.vec3()) - radius; - PrintText(line++, "Distance to Pluto: % .1f (KM)", distToSurf); + glm::vec4 active(0.6, 1, 0.00, 1); + glm::vec4 brigther_active(0.9, 1, 0.75, 1); - PrintText(line++, "Avg. Frametime: %.5f", OsEng.windowWrapper().averageDeltaTime()); - - //PrintText(line++, "Drawtime: %.5f", sgct::Engine::instance()->getDrawTime()); - //PrintText(line++, "Frametime: %.5f", sgct::Engine::instance()->getDt()); - //PrintText(i++, "Origin: (% .5f, % .5f, % .5f, % .5f)", origin[0], origin[1], origin[2], origin[3]); - //PrintText(i++, "Cam pos: (% .5f, % .5f, % .5f, % .5f)", position[0], position[1], position[2], position[3]); - //PrintText(i++, "View dir: (% .5f, % .5f, % .5f)", viewdirection[0], viewdirection[1], viewdirection[2]); - //PrintText(i++, "Cam->origin: (% .15f, % .4f)", pssl[0], pssl[1]); - //PrintText(i++, "Scaling: (% .5f, % .5f)", scaling[0], scaling[1]); + progress.append("|"); + if (remaining > 0) { + brigther_active *= (1 - t); + + penPosition.y -= fontMono->height(); + RenderFont(fontMono, + penPosition, + active * t + brigther_active, + "Next instrument activity:" + ); + + penPosition.y -= fontMono->height(); + RenderFont(fontMono, + penPosition, + active * t + brigther_active, + "%.0f s %s %.1f %%", + remaining, progress.c_str(), t * 100 + ); -#ifdef OPENSPACE_MODULE_NEWHORIZONS_ENABLED - if (openspace::ImageSequencer2::ref().isReady()) { - double remaining = openspace::ImageSequencer2::ref().getNextCaptureTime() - currentTime; - float t = static_cast(1.0 - remaining / openspace::ImageSequencer2::ref().getIntervalLength()); - std::string progress = "|"; - int g = static_cast((t* 24) + 1); - g = std::max(g, 0); - for (int i = 0; i < g; i++) - progress.append("-"); - progress.append(">"); - for (int i = 0; i < 25 - g; i++) - progress.append(" "); + penPosition.y -= fontMono->height(); + RenderFont(fontMono, + penPosition, + active, + "Data acquisition time: %s", + str.c_str() + ); + } + std::pair nextTarget = ImageSequencer2::ref().getNextTarget(); + std::pair currentTarget = ImageSequencer2::ref().getCurrentTarget(); - std::string str = ""; - openspace::SpiceManager::ref().getDateFromET(openspace::ImageSequencer2::ref().getNextCaptureTime(), str, "YYYY MON DD HR:MN:SC"); + if (currentTarget.first > 0.0) { + int timeleft = static_cast(nextTarget.first - currentTime); - glm::vec4 active(0.6, 1, 0.00, 1); - glm::vec4 brigther_active(0.9, 1, 0.75, 1); + int hour = timeleft / 3600; + int second = timeleft % 3600; + int minute = second / 60; + second = second % 60; - progress.append("|"); - if (remaining > 0) { - brigther_active *= (1 - t); - PrintColorText(line++, "Next instrument activity:", 10, active*t + brigther_active); - PrintColorTextArg(line++, "%.0f s %s %.1f %%", 10, active*t + brigther_active, remaining, progress.c_str(), t * 100); - PrintColorTextArg(line++, "Data acquisition time: %s", 10, active, str.c_str()); - } - std::pair nextTarget = ImageSequencer2::ref().getNextTarget(); - std::pair currentTarget = ImageSequencer2::ref().getCurrentTarget(); + std::string hh, mm, ss, coundtown; - if (currentTarget.first > 0.0) { - int timeleft = static_cast(nextTarget.first - currentTime); + if (hour < 10) hh.append("0"); + if (minute < 10) mm.append("0"); + if (second < 10) ss.append("0"); - int hour = timeleft / 3600; - int second = timeleft % 3600; - int minute = second / 60; - second = second % 60; + hh.append(std::to_string(hour)); + mm.append(std::to_string(minute)); + ss.append(std::to_string(second)); + + penPosition.y -= fontMono->height(); + RenderFont(fontMono, + penPosition, + targetColor, + "Data acquisition adjacency: [%s:%s:%s]", + hh.c_str(), mm.c_str(), ss.c_str() + ); - std::string hh, mm, ss, coundtown; + + penPosition.y -= fontMono->height(); + std::pair> incidentTargets = ImageSequencer2::ref().getIncidentTargetList(2); + std::string space; + glm::vec4 color; + size_t isize = incidentTargets.second.size(); + for (size_t p = 0; p < isize; p++){ + double t = static_cast(p + 1) / static_cast(isize + 1); + t = (p > isize / 2) ? 1 - t : t; + t += 0.3; + color = (p == isize / 2) ? targetColor : glm::vec4(t, t, t, 1); + + RenderFont(fontMono, + penPosition, + color, + "%s%s", + space.c_str(), incidentTargets.second[p].c_str() + ); + + + for (int k = 0; k < incidentTargets.second[p].size() + 2; k++) + space += " "; + } + + std::map activeMap = ImageSequencer2::ref().getActiveInstruments(); + glm::vec4 firing(0.58-t, 1-t, 1-t, 1); + glm::vec4 notFiring(0.5, 0.5, 0.5, 1); - if (hour < 10) hh.append("0"); - if (minute < 10) mm.append("0"); - if (second < 10) ss.append("0"); + penPosition.y -= fontMono->height(); + RenderFont(fontMono, + penPosition, + active, + "Active Instruments:" + ); - hh.append(std::to_string(hour)); - mm.append(std::to_string(minute)); - ss.append(std::to_string(second)); - - PrintColorTextArg(line++, "Data acquisition adjacency: [%s:%s:%s]", 10, targetColor, hh.c_str(), mm.c_str(), ss.c_str()); - - std::pair> incidentTargets = ImageSequencer2::ref().getIncidentTargetList(2); - std::string space; - glm::vec4 color; - size_t isize = incidentTargets.second.size(); - for (size_t p = 0; p < isize; p++){ - double t = static_cast(p + 1) / static_cast(isize + 1); - t = (p > isize / 2) ? 1 - t : t; - t += 0.3; - color = (p == isize / 2) ? targetColor : glm::vec4(t, t, t, 1); - PrintColorTextArg(line, "%s%s", 10, color, space.c_str(), incidentTargets.second[p].c_str()); - for (int k = 0; k < incidentTargets.second[p].size() + 2; k++) - space += " "; - } - line++; - - std::map activeMap = ImageSequencer2::ref().getActiveInstruments(); - glm::vec4 firing(0.58-t, 1-t, 1-t, 1); - glm::vec4 notFiring(0.5, 0.5, 0.5, 1); - PrintColorText(line++, "Active Instruments: ", 10, active); - for (auto t : activeMap){ - if (t.second == false){ - PrintColorText(line, "| |", 10, glm::vec4(0.3, 0.3, 0.3, 1)); - PrintColorTextArg(line++, " %5s", 10, glm::vec4(0.3, 0.3, 0.3, 1), t.first.c_str()); - } - else{ - PrintColorText(line, "|", 10, glm::vec4(0.3, 0.3, 0.3, 1)); - if (t.first == "NH_LORRI"){ - PrintColorText(line, " + ", 10, firing); - } - PrintColorText(line, " |", 10, glm::vec4(0.3, 0.3, 0.3, 1)); - PrintColorTextArg(line++, " %5s", 10, active, t.first.c_str()); - } - } + for (auto t : activeMap){ + penPosition.y -= fontMono->height(); + if (t.second == false) { + RenderFont(fontMono, + penPosition, + glm::vec4(0.3, 0.3, 0.3, 1), + "| |" + ); + RenderFont(fontMono, + penPosition, + glm::vec4(0.3, 0.3, 0.3, 1), + " %5s", + t.first.c_str() + ); + + } + else{ + RenderFont(fontMono, + penPosition, + glm::vec4(0.3, 0.3, 0.3, 1), + "|" + ); + if (t.first == "NH_LORRI") { + RenderFont(fontMono, + penPosition, + firing, + " + " + ); + } + RenderFont(fontMono, + penPosition, + glm::vec4(0.3, 0.3, 0.3, 1), + " |" + ); + RenderFont(fontMono, + penPosition, + active, + " %5s", + t.first.c_str() + ); + } + } + } } - } -#endif + #endif -#undef PrintText - } + #undef PrintText + } + if (_showScreenLog) { + const float fontSizeLight = 7.f; + Font* fontLight = OsEng.fontManager().font(constants::fonts::keyLight, 7.f); + const int max = 10; + const int category_length = 20; + const int msg_length = 140; + const float ttl = 15.f; + const float fade = 5.f; + auto entries = _log->last(max); - if (_showScreenLog) - { - const sgct_text::Font* font = fontLight; - const int max = 10; - const int category_length = 20; - const int msg_length = 140; - const float ttl = 15.f; - const float fade = 5.f; - auto entries = _log->last(max); + const glm::vec4 white(0.9, 0.9, 0.9, 1); + const glm::vec4 red(1, 0, 0, 1); + const glm::vec4 yellow(1, 1, 0, 1); + const glm::vec4 green(0, 1, 0, 1); + const glm::vec4 blue(0, 0, 1, 1); - const glm::vec4 white(0.9, 0.9, 0.9, 1); - const glm::vec4 red(1, 0, 0, 1); - const glm::vec4 yellow(1, 1, 0, 1); - const glm::vec4 green(0, 1, 0, 1); - const glm::vec4 blue(0, 0, 1, 1); + size_t nr = 1; + for (auto& it = entries.first; it != entries.second; ++it) { + const ScreenLog::LogEntry* e = &(*it); - size_t nr = 1; - for (auto& it = entries.first; it != entries.second; ++it) { - const ScreenLog::LogEntry* e = &(*it); + const double t = OsEng.windowWrapper().time(); + float diff = static_cast(t - e->timeStamp); - const double t = OsEng.windowWrapper().time(); - float diff = static_cast(t - e->timeStamp); + // Since all log entries are ordered, once one is exceeding TTL, all have + if (diff > ttl) + break; - // Since all log entries are ordered, once one is exceeding TTL, all have - if (diff > ttl) - break; + float alpha = 1; + float ttf = ttl - fade; + if (diff > ttf) { + diff = diff - ttf; + float p = 0.8f - diff / fade; + alpha = (p <= 0.f) ? 0.f : pow(p, 0.3f); + } - float alpha = 1; - float ttf = ttl - fade; - if (diff > ttf) { - diff = diff - ttf; - float p = 0.8f - diff / fade; - alpha = (p <= 0.f) ? 0.f : pow(p, 0.3f); - } + // Since all log entries are ordered, once one exceeds alpha, all have + if (alpha <= 0.0) + break; - // Since all log entries are ordered, once one exceeds alpha, all have - if (alpha <= 0.0) - break; + const std::string lvl = "(" + ghoul::logging::LogManager::stringFromLevel(e->level) + ")"; + const std::string& message = e->message.substr(0, msg_length); + nr += std::count(message.begin(), message.end(), '\n'); - const std::string lvl = "(" + ghoul::logging::LogManager::stringFromLevel(e->level) + ")"; - const std::string& message = e->message.substr(0, msg_length); - nr += std::count(message.begin(), message.end(), '\n'); + RenderFont(fontLight, + glm::vec2(10.f, fontSizeLight * nr * 2), + white * alpha, + "%-14s %s%s", // Format + e->timeString.c_str(), // Time string + e->category.substr(0, category_length).c_str(), // Category string (up to category_length) + e->category.length() > 20 ? "..." : ""); // Pad category with "..." if exceeds category_length + + glm::vec4 color = white; + if (e->level == ghoul::logging::LogManager::LogLevel::Debug) + color = green; + if (e->level == ghoul::logging::LogManager::LogLevel::Warning) + color = yellow; + if (e->level == ghoul::logging::LogManager::LogLevel::Error) + color = red; + if (e->level == ghoul::logging::LogManager::LogLevel::Fatal) + color = blue; - Freetype::print(font, 10.f, static_cast(font_size_light * nr * 2), white*alpha, - "%-14s %s%s", // Format - e->timeString.c_str(), // Time string - e->category.substr(0, category_length).c_str(), // Category string (up to category_length) - e->category.length() > 20 ? "..." : ""); // Pad category with "..." if exceeds category_length + const float font_with_light = 5; + RenderFont(fontLight, + glm::vec2(static_cast(10 + 39 * font_with_light), fontSizeLight * nr * 2), + color * alpha, + "%s", // Format + lvl.c_str()); // Pad category with "..." if exceeds category_length - glm::vec4 color = white; - if (e->level == ghoul::logging::LogManager::LogLevel::Debug) - color = green; - if (e->level == ghoul::logging::LogManager::LogLevel::Warning) - color = yellow; - if (e->level == ghoul::logging::LogManager::LogLevel::Error) - color = red; - if (e->level == ghoul::logging::LogManager::LogLevel::Fatal) - color = blue; - - Freetype::print(font, static_cast(10 + 39 * font_with_light), static_cast(font_size_light * nr * 2), color*alpha, "%s", lvl.c_str()); - - - Freetype::print(font, static_cast(10 + 53 * font_with_light), static_cast(font_size_light * nr * 2), white*alpha, "%s", message.c_str()); - ++nr; - } - } + RenderFont(fontLight, + glm::vec2(static_cast(10 + 53 * font_with_light), fontSizeLight * nr * 2), + white * alpha, + "%s", // Format + message.c_str()); // Pad category with "..." if exceeds category_length + ++nr; + } + } + } } #endif } diff --git a/src/util/time.cpp b/src/util/time.cpp index 89c1c796cc..362d6ecc33 100644 --- a/src/util/time.cpp +++ b/src/util/time.cpp @@ -123,7 +123,6 @@ void Time::setTime(std::string time, bool requireJump) { std::string Time::currentTimeUTC() const { std::string date; - //SpiceManager::ref().getDateFromET(_time, date); SpiceManager::ref().getDateFromET(_syncedTime, date); return date; } From 5ce55c1ba497fbca389f2e21d0ab3f5b558d6506 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 16 Nov 2015 19:21:49 -0500 Subject: [PATCH 034/122] Remove unnecessary Boost libraries from libtorrent compilation --- apps/Launcher/ext/libtorrent/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/Launcher/ext/libtorrent/CMakeLists.txt b/apps/Launcher/ext/libtorrent/CMakeLists.txt index 1cbdeb7355..a326a058e9 100644 --- a/apps/Launcher/ext/libtorrent/CMakeLists.txt +++ b/apps/Launcher/ext/libtorrent/CMakeLists.txt @@ -187,10 +187,11 @@ endif () # Boost set(Boost_USE_STATIC_LIBS ON) if (NOT DEFINED Boost_INCLUDE_DIR OR NOT DEFINED Boost_LIBRARIES) - find_package(Boost COMPONENTS system thread date_time chrono) + find_package(Boost COMPONENTS system chrono REQUIRED) endif () target_include_directories(libtorrent PUBLIC ${Boost_INCLUDE_DIR}) target_link_libraries(libtorrent ${Boost_LIBRARIES}) +message(${Boost_LIBRARIES}) if (WIN32) target_link_libraries(libtorrent wsock32 ws2_32 Iphlpapi.lib) From 4f7ab5321ff6ec391b7c8a263af919f3ea6b9b45 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 17 Nov 2015 17:31:43 -0500 Subject: [PATCH 035/122] Cleanup RenderEngine to completely rely on Ghoul font rendering --- ext/ghoul | 2 +- include/openspace/rendering/renderengine.h | 4 + src/rendering/renderengine.cpp | 381 ++++++++++----------- 3 files changed, 186 insertions(+), 201 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index f6dbd18a66..19c3dcc66e 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit f6dbd18a665b3b13cef7f70310f1c6fc416a7c5f +Subproject commit 19c3dcc66e7fa55637c80142da6ce56eb50b6e8a diff --git a/include/openspace/rendering/renderengine.h b/include/openspace/rendering/renderengine.h index c0a517ae1d..5164ebd4da 100644 --- a/include/openspace/rendering/renderengine.h +++ b/include/openspace/rendering/renderengine.h @@ -143,6 +143,10 @@ private: float _currentFadeTime; int _fadeDirection; // bool _sgctRenderStatisticsVisible; + + ghoul::fontrendering::Font* _fontInfo = nullptr; + ghoul::fontrendering::Font* _fontDate = nullptr; + ghoul::fontrendering::Font* _fontLog = nullptr; bool _visualizeABuffer; ABufferVisualizer* _visualizer; diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 9d03f449bf..6e440b9c70 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -52,6 +52,7 @@ #include #include #include +#include #include #ifdef GHOUL_USE_DEVIL @@ -201,6 +202,17 @@ bool RenderEngine::initializeGL() { // development OsEng.windowWrapper().setNearFarClippingPlane(0.001f, 1000.f); + + const float fontSizeTime = 15.f; + _fontDate = OsEng.fontManager().font(constants::fonts::keyMono, fontSizeTime); + const float fontSizeMono = 10.f; + _fontInfo = OsEng.fontManager().font(constants::fonts::keyMono, fontSizeMono); + const float fontSizeLight = 8.f; + _fontLog = OsEng.fontManager().font(constants::fonts::keyLight, fontSizeLight); + + + + // ALL OF THIS HAS TO BE CHECKED // ---abock @@ -396,27 +408,7 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi } } -#if 1 -#define PrintText(__i__, __format__, ...) Freetype::print(font, 10.f, static_cast(startY - font_size_mono * __i__ * 2), __format__, __VA_ARGS__); - //#define PrintColorTextArg(__i__, __format__, __size__, __color__, ...) Freetype::print(font, __size__, static_cast(startY - font_size_mono * __i__ * 2), __format__, __VA_ARGS__); - //#define PrintColorText(__i__, __format__, __size__, __color__) Freetype::print(font, __size__, static_cast(startY - font_size_mono * __i__ * 2), __format__); - #define PrintColorTextArg(__i__, __format__, __size__, __color__, ...) Freetype::print(font, __size__, static_cast(startY - font_size_mono * __i__ * 2), __color__, __format__, __VA_ARGS__); - #define PrintColorText(__i__, __format__, __size__, __color__) Freetype::print(font, __size__, static_cast(startY - font_size_mono * __i__ * 2), __color__, __format__); - - if (_onScreenInformation._node != -1) { - //int thisId = sgct_core::ClusterManager::instance()->getThisNodeId(); - - //if (thisId == _onScreenInformation._node) { - //const unsigned int font_size_mono = _onScreenInformation._size; - //int x1, xSize, y1, ySize; - //const sgct_text::Font* font = sgct_text::FontManager::instance()->getFont(constants::fonts::keyMono, font_size_mono); - //sgct::Engine::instance()->getActiveWindowPtr()->getCurrentViewportPixelCoords(x1, y1, xSize, ySize); - //int startY = ySize - 2 * font_size_mono; - //} - } - // Print some useful information on the master viewport - if (OsEng.ref().isMaster() && OsEng.windowWrapper().isSimpleRendering()) { // TODO: Adjust font_size properly when using retina screen const float fontSizeMono = 10.f; @@ -425,29 +417,37 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi using Font = ghoul::fontrendering::Font; using ghoul::fontrendering::RenderFont; - Font* fontMono = OsEng.fontManager().font(constants::fonts::keyMono, fontSizeMono); - Font* fontTime = OsEng.fontManager().font(constants::fonts::keyMono, fontSizeTime); - if (fontMono && fontTime) { - if (_showInfo) { - double currentTime = Time::ref().currentTime(); - - glm::vec2 penPosition = glm::vec2(10.f, OsEng.windowWrapper().viewportPixelCoordinates().w); + if (_showInfo && _fontDate && _fontInfo) { + double currentTime = Time::ref().currentTime(); + + glm::vec2 penPosition = glm::vec2( + 10.f, + OsEng.windowWrapper().viewportPixelCoordinates().w + ); + penPosition.y -= _fontDate->height(); - penPosition.y -= fontTime->height(); - RenderFont(fontTime, - penPosition, - "Date: %s", - Time::ref().currentTimeUTC().c_str() - ); - - penPosition.y -= fontMono->height(); - RenderFont(fontMono, - penPosition, - "Simulation increment (s): %.0f", - Time::ref().deltaTime() - ); + RenderFontCr(_fontDate, + penPosition, + "Date: %s", + Time::ref().currentTimeUTC().c_str() + ); + + RenderFontCr(_fontInfo, + penPosition, + "Simulation increment (s): %.0f", + Time::ref().deltaTime() + ); + RenderFontCr(_fontInfo, + penPosition, + "Avg. Frametime: %.5f", + OsEng.windowWrapper().averageDeltaTime() + ); + +#ifdef OPENSPACE_MODULE_NEWHORIZONS_ENABLED + if (openspace::ImageSequencer2::ref().isReady()) { + penPosition.y -= 25.f; glm::vec4 targetColor(0.00, 0.75, 1.00, 1); @@ -459,182 +459,163 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi float radius = (a + b) / 2.f; float distToSurf = glm::length(nhPos.vec3()) - radius; - penPosition.y -= fontMono->height(); - RenderFont(fontMono, + RenderFont(_fontInfo, penPosition, "Distance to Pluto: % .1f (KM)", distToSurf ); + penPosition.y -= _fontInfo->height(); + - penPosition.y -= fontMono->height(); - RenderFont(fontMono, - penPosition, - "Avg. Frametime: %.5f", - OsEng.windowWrapper().averageDeltaTime() - ); - - - #ifdef OPENSPACE_MODULE_NEWHORIZONS_ENABLED - if (openspace::ImageSequencer2::ref().isReady()) { - double remaining = openspace::ImageSequencer2::ref().getNextCaptureTime() - currentTime; - float t = static_cast(1.0 - remaining / openspace::ImageSequencer2::ref().getIntervalLength()); - std::string progress = "|"; - int g = static_cast((t* 24) + 1); - g = std::max(g, 0); - for (int i = 0; i < g; i++) - progress.append("-"); - progress.append(">"); - for (int i = 0; i < 25 - g; i++) - progress.append(" "); + double remaining = openspace::ImageSequencer2::ref().getNextCaptureTime() - currentTime; + float t = static_cast(1.0 - remaining / openspace::ImageSequencer2::ref().getIntervalLength()); + std::string progress = "|"; + int g = static_cast((t* 24) + 1); + g = std::max(g, 0); + for (int i = 0; i < g; i++) + progress.append("-"); + progress.append(">"); + for (int i = 0; i < 25 - g; i++) + progress.append(" "); - std::string str = ""; - openspace::SpiceManager::ref().getDateFromET(openspace::ImageSequencer2::ref().getNextCaptureTime(), str, "YYYY MON DD HR:MN:SC"); + std::string str = ""; + openspace::SpiceManager::ref().getDateFromET(openspace::ImageSequencer2::ref().getNextCaptureTime(), str, "YYYY MON DD HR:MN:SC"); - glm::vec4 active(0.6, 1, 0.00, 1); - glm::vec4 brigther_active(0.9, 1, 0.75, 1); + glm::vec4 active(0.6, 1, 0.00, 1); + glm::vec4 brigther_active(0.9, 1, 0.75, 1); - progress.append("|"); - if (remaining > 0) { - brigther_active *= (1 - t); + progress.append("|"); + if (remaining > 0) { + brigther_active *= (1 - t); + + RenderFontCr(_fontInfo, + penPosition, + active * t + brigther_active, + "Next instrument activity:" + ); + + RenderFontCr(_fontInfo, + penPosition, + active * t + brigther_active, + "%.0f s %s %.1f %%", + remaining, progress.c_str(), t * 100 + ); + + RenderFontCr(_fontInfo, + penPosition, + active, + "Data acquisition time: %s", + str.c_str() + ); + } + std::pair nextTarget = ImageSequencer2::ref().getNextTarget(); + std::pair currentTarget = ImageSequencer2::ref().getCurrentTarget(); + + if (currentTarget.first > 0.0) { + int timeleft = static_cast(nextTarget.first - currentTime); + + int hour = timeleft / 3600; + int second = timeleft % 3600; + int minute = second / 60; + second = second % 60; + + std::string hh, mm, ss, coundtown; + + if (hour < 10) hh.append("0"); + if (minute < 10) mm.append("0"); + if (second < 10) ss.append("0"); + + hh.append(std::to_string(hour)); + mm.append(std::to_string(minute)); + ss.append(std::to_string(second)); + + RenderFontCr(_fontInfo, + penPosition, + targetColor, + "Data acquisition adjacency: [%s:%s:%s]", + hh.c_str(), mm.c_str(), ss.c_str() + ); + + + std::pair> incidentTargets = ImageSequencer2::ref().getIncidentTargetList(2); + std::string space; + glm::vec4 color; + size_t isize = incidentTargets.second.size(); + for (size_t p = 0; p < isize; p++){ + double t = static_cast(p + 1) / static_cast(isize + 1); + t = (p > isize / 2) ? 1 - t : t; + t += 0.3; + color = (p == isize / 2) ? targetColor : glm::vec4(t, t, t, 1); - penPosition.y -= fontMono->height(); - RenderFont(fontMono, + RenderFont(_fontInfo, penPosition, - active * t + brigther_active, - "Next instrument activity:" + color, + "%s%s", + space.c_str(), incidentTargets.second[p].c_str() ); - penPosition.y -= fontMono->height(); - RenderFont(fontMono, - penPosition, - active * t + brigther_active, - "%.0f s %s %.1f %%", - remaining, progress.c_str(), t * 100 - ); - - penPosition.y -= fontMono->height(); - RenderFont(fontMono, - penPosition, - active, - "Data acquisition time: %s", - str.c_str() - ); + + for (int k = 0; k < incidentTargets.second[p].size() + 2; k++) + space += " "; } - std::pair nextTarget = ImageSequencer2::ref().getNextTarget(); - std::pair currentTarget = ImageSequencer2::ref().getCurrentTarget(); + penPosition.y -= _fontInfo->height(); + + std::map activeMap = ImageSequencer2::ref().getActiveInstruments(); + glm::vec4 firing(0.58-t, 1-t, 1-t, 1); + glm::vec4 notFiring(0.5, 0.5, 0.5, 1); - if (currentTarget.first > 0.0) { - int timeleft = static_cast(nextTarget.first - currentTime); + RenderFontCr(_fontInfo, + penPosition, + active, + "Active Instruments:" + ); - int hour = timeleft / 3600; - int second = timeleft % 3600; - int minute = second / 60; - second = second % 60; - - std::string hh, mm, ss, coundtown; - - if (hour < 10) hh.append("0"); - if (minute < 10) mm.append("0"); - if (second < 10) ss.append("0"); - - hh.append(std::to_string(hour)); - mm.append(std::to_string(minute)); - ss.append(std::to_string(second)); - - penPosition.y -= fontMono->height(); - RenderFont(fontMono, - penPosition, - targetColor, - "Data acquisition adjacency: [%s:%s:%s]", - hh.c_str(), mm.c_str(), ss.c_str() - ); - - - penPosition.y -= fontMono->height(); - std::pair> incidentTargets = ImageSequencer2::ref().getIncidentTargetList(2); - std::string space; - glm::vec4 color; - size_t isize = incidentTargets.second.size(); - for (size_t p = 0; p < isize; p++){ - double t = static_cast(p + 1) / static_cast(isize + 1); - t = (p > isize / 2) ? 1 - t : t; - t += 0.3; - color = (p == isize / 2) ? targetColor : glm::vec4(t, t, t, 1); - - RenderFont(fontMono, + for (auto t : activeMap){ + if (t.second == false) { + RenderFont(_fontInfo, penPosition, - color, - "%s%s", - space.c_str(), incidentTargets.second[p].c_str() + glm::vec4(0.3, 0.3, 0.3, 1), + "| |" + ); + RenderFontCr(_fontInfo, + penPosition, + glm::vec4(0.3, 0.3, 0.3, 1), + " %5s", + t.first.c_str() ); - - for (int k = 0; k < incidentTargets.second[p].size() + 2; k++) - space += " "; } - - std::map activeMap = ImageSequencer2::ref().getActiveInstruments(); - glm::vec4 firing(0.58-t, 1-t, 1-t, 1); - glm::vec4 notFiring(0.5, 0.5, 0.5, 1); - - penPosition.y -= fontMono->height(); - RenderFont(fontMono, - penPosition, - active, - "Active Instruments:" - ); - - for (auto t : activeMap){ - penPosition.y -= fontMono->height(); - if (t.second == false) { - RenderFont(fontMono, + else{ + RenderFont(_fontInfo, + penPosition, + glm::vec4(0.3, 0.3, 0.3, 1), + "|" + ); + if (t.first == "NH_LORRI") { + RenderFont(_fontInfo, penPosition, - glm::vec4(0.3, 0.3, 0.3, 1), - "| |" - ); - RenderFont(fontMono, - penPosition, - glm::vec4(0.3, 0.3, 0.3, 1), - " %5s", - t.first.c_str() - ); - - } - else{ - RenderFont(fontMono, - penPosition, - glm::vec4(0.3, 0.3, 0.3, 1), - "|" - ); - if (t.first == "NH_LORRI") { - RenderFont(fontMono, - penPosition, - firing, - " + " - ); - } - RenderFont(fontMono, - penPosition, - glm::vec4(0.3, 0.3, 0.3, 1), - " |" - ); - RenderFont(fontMono, - penPosition, - active, - " %5s", - t.first.c_str() + firing, + " + " ); } + RenderFont(_fontInfo, + penPosition, + glm::vec4(0.3, 0.3, 0.3, 1), + " |" + ); + RenderFontCr(_fontInfo, + penPosition, + active, + " %5s", + t.first.c_str() + ); } } } - #endif - - #undef PrintText + } +#endif } if (_showScreenLog) { - const float fontSizeLight = 7.f; - Font* fontLight = OsEng.fontManager().font(constants::fonts::keyLight, 7.f); const int max = 10; const int category_length = 20; const int msg_length = 140; @@ -656,8 +637,8 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi float diff = static_cast(t - e->timeStamp); // Since all log entries are ordered, once one is exceeding TTL, all have - if (diff > ttl) - break; +// if (diff > ttl) +// break; float alpha = 1; float ttf = ttl - fade; @@ -666,6 +647,8 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi float p = 0.8f - diff / fade; alpha = (p <= 0.f) ? 0.f : pow(p, 0.3f); } + + alpha = 1.f; // Since all log entries are ordered, once one exceeds alpha, all have if (alpha <= 0.0) @@ -675,8 +658,8 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi const std::string& message = e->message.substr(0, msg_length); nr += std::count(message.begin(), message.end(), '\n'); - RenderFont(fontLight, - glm::vec2(10.f, fontSizeLight * nr * 2), + RenderFont(_fontLog, + glm::vec2(10.f, _fontLog->pointSize() * nr * 2), white * alpha, "%-14s %s%s", // Format e->timeString.c_str(), // Time string @@ -693,24 +676,22 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi if (e->level == ghoul::logging::LogManager::LogLevel::Fatal) color = blue; - const float font_with_light = 5; - RenderFont(fontLight, - glm::vec2(static_cast(10 + 39 * font_with_light), fontSizeLight * nr * 2), +// const float font_with_light = 5; + RenderFont(_fontLog, + glm::vec2(static_cast(10 + 39 * _fontLog->pointSize()), _fontLog->pointSize() * nr * 2), color * alpha, "%s", // Format lvl.c_str()); // Pad category with "..." if exceeds category_length - RenderFont(fontLight, - glm::vec2(static_cast(10 + 53 * font_with_light), fontSizeLight * nr * 2), + RenderFont(_fontLog, + glm::vec2(static_cast(10 + 53 * _fontLog->pointSize()), _fontLog->pointSize() * nr * 2), white * alpha, "%s", // Format message.c_str()); // Pad category with "..." if exceeds category_length ++nr; } - } } } -#endif } void RenderEngine::postDraw() { From f7f5f2e262520d7eb9706b9235dfa77ce29e0bde Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 17 Nov 2015 22:56:13 -0500 Subject: [PATCH 036/122] Started cleanup of SpiceManager Clean boost message output Update to new Ghoul with cppformat library --- apps/Launcher/ext/libtorrent/CMakeLists.txt | 1 - ext/ghoul | 2 +- include/openspace/util/spicemanager.h | 27 +++++++++++-------- modules/base/ephemeris/spiceephemeris.cpp | 4 +-- src/engine/openspaceengine.cpp | 6 ++--- src/util/spicemanager.cpp | 29 ++++++++++++--------- 6 files changed, 38 insertions(+), 31 deletions(-) diff --git a/apps/Launcher/ext/libtorrent/CMakeLists.txt b/apps/Launcher/ext/libtorrent/CMakeLists.txt index a326a058e9..2cecbdd97e 100644 --- a/apps/Launcher/ext/libtorrent/CMakeLists.txt +++ b/apps/Launcher/ext/libtorrent/CMakeLists.txt @@ -191,7 +191,6 @@ if (NOT DEFINED Boost_INCLUDE_DIR OR NOT DEFINED Boost_LIBRARIES) endif () target_include_directories(libtorrent PUBLIC ${Boost_INCLUDE_DIR}) target_link_libraries(libtorrent ${Boost_LIBRARIES}) -message(${Boost_LIBRARIES}) if (WIN32) target_link_libraries(libtorrent wsock32 ws2_32 Iphlpapi.lib) diff --git a/ext/ghoul b/ext/ghoul index 19c3dcc66e..b2278ce9d3 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 19c3dcc66e7fa55637c80142da6ce56eb50b6e8a +Subproject commit b2278ce9d387a7f6179d3045ce349fecffc81976 diff --git a/include/openspace/util/spicemanager.h b/include/openspace/util/spicemanager.h index 1a8df376ac..6c521e257d 100644 --- a/include/openspace/util/spicemanager.h +++ b/include/openspace/util/spicemanager.h @@ -25,9 +25,6 @@ #ifndef __SPICEMANAGER_H__ #define __SPICEMANAGER_H__ -#include "SpiceUsr.h" -#include "SpiceZpr.h" - #include #include @@ -41,26 +38,34 @@ #include #include +#include "SpiceUsr.h" +#include "SpiceZpr.h" + namespace openspace { class SpiceManager : public ghoul::Singleton { friend class ghoul::Singleton; public: - typedef std::array TransformMatrix; - typedef unsigned int KernelIdentifier; + using TransformMatrix = std::array; + using KernelHandle = unsigned int; - static const KernelIdentifier KernelFailed = KernelIdentifier(-1); + static const KernelHandle InvalidKernel = KernelHandle(-1); /** * Loads one or more SPICE kernels into a program. The provided path can either be a * binary, text-kernel, or meta-kernel which gets loaded into the kernel pool. The - * loading is done by passing the filePath to the furnsh_c + * loading is done by passing the \p filePath to the furnsh_c * function. http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/furnsh_c.html * \param filePath The path to the kernel that should be loaded * \return The loaded kernel's unique identifier that can be used to unload the kernel + * \pre \p filePath is a non-empty absolute or relative path pointing to an + * existing file that contains a SPICE kernel + * \post The kernel is loaded or has its reference counter incremented and the handle + * to the kernel is returned if the SPICE kernel is valid, or \a KernelInvalid if the + * kernel is invalid */ - KernelIdentifier loadKernel(const std::string& filePath); + KernelHandle loadKernel(std::string filePath); /** * Function to find and store the intervals covered by a ck file, this is done @@ -107,7 +112,7 @@ public: * \param kernelId The unique identifier that was returned from the call to * loadKernel which loaded the kernel */ - void unloadKernel(KernelIdentifier kernelId); + void unloadKernel(KernelHandle kernelId); /** * Unloads a SPICE kernel identified by the filePath which was used in @@ -694,7 +699,7 @@ public: protected: struct KernelInformation { std::string path; /// The path from which the kernel was loaded - KernelIdentifier id; /// A unique identifier for each kernel + KernelHandle id; /// A unique identifier for each kernel int refCount; /// How many parts loaded this kernel and are interested in it }; @@ -717,7 +722,7 @@ protected: const static bool _showErrors = false; /// The last assigned kernel-id, used to determine the next free kernel id - KernelIdentifier _lastAssignedKernel; + KernelHandle _lastAssignedKernel; }; } // namespace openspace diff --git a/modules/base/ephemeris/spiceephemeris.cpp b/modules/base/ephemeris/spiceephemeris.cpp index 2fb45ddf2a..3ae196b043 100644 --- a/modules/base/ephemeris/spiceephemeris.cpp +++ b/modules/base/ephemeris/spiceephemeris.cpp @@ -62,8 +62,8 @@ SpiceEphemeris::SpiceEphemeris(const ghoul::Dictionary& dictionary) if (!success) LERROR("'" << KeyKernels << "' has to be an array-style table"); - SpiceManager::KernelIdentifier id = SpiceManager::ref().loadKernel(kernel); - _kernelsLoadedSuccessfully &= (id != SpiceManager::KernelFailed); + SpiceManager::KernelHandle id = SpiceManager::ref().loadKernel(kernel); + _kernelsLoadedSuccessfully &= (id != SpiceManager::InvalidKernel); } } diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 071dea96b5..313139d1f7 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -485,9 +485,9 @@ bool OpenSpaceEngine::loadSpiceKernels() { LERROR("Configuration file does not contain a '" << ConfigurationManager::KeySpiceTimeKernel << "'"); return false; } - SpiceManager::KernelIdentifier id = + SpiceManager::KernelHandle id = SpiceManager::ref().loadKernel(timeKernel); - if (id == SpiceManager::KernelFailed) { + if (id == SpiceManager::InvalidKernel) { LERROR("Error loading time kernel '" << timeKernel << "'"); return false; } @@ -501,7 +501,7 @@ bool OpenSpaceEngine::loadSpiceKernels() { return false; } id = SpiceManager::ref().loadKernel(std::move(leapSecondKernel)); - if (id == SpiceManager::KernelFailed) { + if (id == SpiceManager::InvalidKernel) { LERROR("Error loading leap second kernel '" << leapSecondKernel << "'"); return false; } diff --git a/src/util/spicemanager.cpp b/src/util/spicemanager.cpp index f1f028935c..61aa4b984a 100644 --- a/src/util/spicemanager.cpp +++ b/src/util/spicemanager.cpp @@ -26,11 +26,14 @@ #include #include +#include #include #include +#include + #define MAXOBJ 64 #define WINSIZ 10000 @@ -59,17 +62,17 @@ SpiceManager::~SpiceManager() { } -SpiceManager::KernelIdentifier SpiceManager::loadKernel(const std::string& filePath) { - if (filePath.empty()) { - LERROR("No filename provided"); - return KernelFailed; - } - - std::string&& path = absPath(filePath); +SpiceManager::KernelHandle SpiceManager::loadKernel(std::string filePath) { + ghoul_assert(!filePath.empty(), "Empty file path"); + ghoul_assert(FileSys.fileExists(filePath), + fmt::format("File '{}' does not exist", filePath) + ); + + std::string path = absPath(filePath); if (!FileSys.fileExists(path)) { LERROR("Kernel file '" << path << "' does not exist"); - return KernelFailed; + return InvalidKernel; } // We need to set the current directory as meta-kernels are usually defined relative @@ -81,7 +84,7 @@ SpiceManager::KernelIdentifier SpiceManager::loadKernel(const std::string& fileP if (!FileSys.directoryExists(fileDirectory)) { LERROR("Could not find directory for kernel '" << path << "'"); - return KernelFailed; + return InvalidKernel; } auto it = std::find_if( @@ -97,7 +100,7 @@ SpiceManager::KernelIdentifier SpiceManager::loadKernel(const std::string& fileP return it->id; } - KernelIdentifier kernelId = ++_lastAssignedKernel; + KernelHandle kernelId = ++_lastAssignedKernel; FileSys.setCurrentDirectory(fileDirectory); @@ -123,12 +126,12 @@ SpiceManager::KernelIdentifier SpiceManager::loadKernel(const std::string& fileP LERROR("Error loading kernel '" + path + "'"); LERROR("Spice reported: " + std::string(msg)); reset_c(); - return KernelFailed; + return InvalidKernel; } bool hasError = checkForError("Error loading kernel '" + path + "'"); if (hasError) - return KernelFailed; + return InvalidKernel; else { KernelInformation&& info = { path, std::move(kernelId), 1 }; _loadedKernels.push_back(info); @@ -240,7 +243,7 @@ bool SpiceManager::hasCkCoverage(std::string frame, double& et) const return idSuccess && hasCoverage; } -void SpiceManager::unloadKernel(KernelIdentifier kernelId) { +void SpiceManager::unloadKernel(KernelHandle kernelId) { auto it = std::find_if(_loadedKernels.begin(), _loadedKernels.end(), [&kernelId](const KernelInformation& info) { return info.id == kernelId ; }); From d1ca5bd941ebd33ab8dfea9edebc88eff3324c22 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Wed, 18 Nov 2015 01:15:58 -0500 Subject: [PATCH 037/122] More cleanup of SpiceManager --- include/openspace/util/spicemanager.h | 48 +++++----- src/util/spicemanager.cpp | 133 ++++++++++++++------------ 2 files changed, 96 insertions(+), 85 deletions(-) diff --git a/include/openspace/util/spicemanager.h b/include/openspace/util/spicemanager.h index 6c521e257d..5e0ab83759 100644 --- a/include/openspace/util/spicemanager.h +++ b/include/openspace/util/spicemanager.h @@ -57,7 +57,10 @@ public: * binary, text-kernel, or meta-kernel which gets loaded into the kernel pool. The * loading is done by passing the \p filePath to the furnsh_c * function. http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/furnsh_c.html - * \param filePath The path to the kernel that should be loaded + * Kernels can safely be loaded multiple times and are reference counted + * \param filePath The path to the kernel that should be loaded. This path will be + * passed to absPath to convert a relative path to an absolute path + * before usage * \return The loaded kernel's unique identifier that can be used to unload the kernel * \pre \p filePath is a non-empty absolute or relative path pointing to an * existing file that contains a SPICE kernel @@ -67,26 +70,6 @@ public: */ KernelHandle loadKernel(std::string filePath); - /** - * Function to find and store the intervals covered by a ck file, this is done - * by using mainly the ckcov_c and ckobj_c functions. - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/ckobj_c.html , - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/ckcov_c.html - * \param filePath The path to the kernel that should be examined - * \return true if the operation was successful - */ - bool findCkCoverage(const std::string& path); - - /** - * Function to find and store the intervals covered by a spk file, this is done - * by using mainly the spkcov_c and spkobj_c functions. - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/spkobj_c.html , - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/spkcov_c.html - * \param filePath The path to the kernel that should be examined - * \return true if the operation was successful - */ - bool findSpkCoverage(const std::string& path); - /** * \return true if SPK kernels have been loaded to cover target * for time et @@ -708,6 +691,27 @@ protected: SpiceManager& operator=(const SpiceManager& r) = delete; SpiceManager(SpiceManager&& r) = delete; ~SpiceManager(); + + /** + * Function to find and store the intervals covered by a ck file, this is done + * by using mainly the ckcov_c and ckobj_c functions. + * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/ckobj_c.html , + * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/ckcov_c.html + * \param filePath The path to the kernel that should be examined + * \return true if the operation was successful + */ + bool findCkCoverage(const std::string& path); + + /** + * Function to find and store the intervals covered by a spk file, this is done + * by using mainly the spkcov_c and spkobj_c functions. + * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/spkobj_c.html , + * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/spkcov_c.html + * \param filePath The path to the kernel that should be examined + * \return true if the operation was successful + */ + bool findSpkCoverage(const std::string& path); + /// A list of all loaded kernels std::vector _loadedKernels; @@ -722,7 +726,7 @@ protected: const static bool _showErrors = false; /// The last assigned kernel-id, used to determine the next free kernel id - KernelHandle _lastAssignedKernel; + KernelHandle _lastAssignedKernel = KernelHandle(0); }; } // namespace openspace diff --git a/src/util/spicemanager.cpp b/src/util/spicemanager.cpp index 61aa4b984a..702227b526 100644 --- a/src/util/spicemanager.cpp +++ b/src/util/spicemanager.cpp @@ -39,13 +39,16 @@ namespace { const std::string _loggerCat = "SpiceManager"; + + // The value comes from + // http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/getmsg_c.html + // as the maximum message length + const unsigned SpiceErrorBufferSize = 1841; } namespace openspace { -SpiceManager::SpiceManager() - : _lastAssignedKernel(0) -{ +SpiceManager::SpiceManager() { // Set the SPICE library to not exit the program if an error occurs erract_c("SET", 0, const_cast("REPORT")); // But we do not want SPICE to print the errors, we will fetch them ourselves @@ -63,111 +66,116 @@ SpiceManager::~SpiceManager() { SpiceManager::KernelHandle SpiceManager::loadKernel(std::string filePath) { + // Preconditions: + // !filePath.empty() + // filePath exists + // Directory(filePath) exists ghoul_assert(!filePath.empty(), "Empty file path"); - ghoul_assert(FileSys.fileExists(filePath), - fmt::format("File '{}' does not exist", filePath) + ghoul_assert( + FileSys.fileExists(filePath), + fmt::format( + "File '{}' ('{}') does not exist", + filePath, + absPath(filePath) + ) + ); + ghoul_assert( + FileSys.directoryExists(ghoul::filesystem::File(filePath).directoryName()), + fmt::format( + "File '{}' exists, but directory '{}' doesn't", + absPath(filePath), + ghoul::filesystem::File(filePath).directoryName() + ) ); std::string path = absPath(filePath); - - if (!FileSys.fileExists(path)) { - LERROR("Kernel file '" << path << "' does not exist"); - return InvalidKernel; - } - - // We need to set the current directory as meta-kernels are usually defined relative - // to the directory they reside in. The directory change is not necessary for regular - // kernels - - ghoul::filesystem::Directory currentDirectory = FileSys.currentDirectory(); - std::string&& fileDirectory = ghoul::filesystem::File(path).directoryName(); - - if (!FileSys.directoryExists(fileDirectory)) { - LERROR("Could not find directory for kernel '" << path << "'"); - return InvalidKernel; - } - auto it = std::find_if( _loadedKernels.begin(), _loadedKernels.end(), [path](const KernelInformation& info) { return info.path == path; }); - if (it != _loadedKernels.end()) - { + if (it != _loadedKernels.end()) { it->refCount++; - LDEBUG("Kernel '" << path << "' was already loaded. " - "New reference count: " << it->refCount); + LDEBUG( + fmt::format( + "Kernel '{}' was already loaded. New reference count: {}", + path, + it->refCount + ) + ); return it->id; } - KernelHandle kernelId = ++_lastAssignedKernel; - + // We need to set the current directory as meta-kernels are usually defined relative + // to the directory they reside in. The directory change is not necessary for regular + // kernels + ghoul::filesystem::Directory currentDirectory = FileSys.currentDirectory(); + std::string fileDirectory = ghoul::filesystem::File(path, true).directoryName(); FileSys.setCurrentDirectory(fileDirectory); LINFO("Loading SPICE kernel '" << path << "'"); - // Load the kernel + // Load the kernel furnsh_c(path.c_str()); - std::string fileExtension = path.substr(path.size() - 3); - if (fileExtension == ".bc" || fileExtension == ".BC") { // binary ck kernel - findCkCoverage(path); - } - else if (fileExtension == "bsp" || fileExtension == "BSP") { // binary spk kernel - findSpkCoverage(path); - } + // Reset the current directory to the previous one + FileSys.setCurrentDirectory(currentDirectory); - - // Reset the current directory to the previous one - FileSys.setCurrentDirectory(currentDirectory); - int failed = failed_c(); + SpiceBoolean failed = failed_c(); if (failed) { - char msg[1024]; - getmsg_c ( "LONG", 1024, msg ); - LERROR("Error loading kernel '" + path + "'"); - LERROR("Spice reported: " + std::string(msg)); + char* buffer = new char[SpiceErrorBufferSize]; + getmsg_c("LONG", SpiceErrorBufferSize, buffer); + LERROR(fmt::format("Error loading kernel '{}'", path)); + LERROR(fmt::format("Spice reported: {}", buffer)); reset_c(); + delete[] buffer; return InvalidKernel; } + + std::string fileExtension = ghoul::filesystem::File(path, true).fileExtension(); + bool success = true; + if (fileExtension == ".bc" || fileExtension == ".BC") + success = findCkCoverage(path); // binary ck kernel + else if (fileExtension == "bsp" || fileExtension == "BSP") + success = findSpkCoverage(path); // binary spk kernel - bool hasError = checkForError("Error loading kernel '" + path + "'"); - if (hasError) - return InvalidKernel; + if (!success) + return InvalidKernel; else { - KernelInformation&& info = { path, std::move(kernelId), 1 }; - _loadedKernels.push_back(info); + KernelHandle kernelId = ++_lastAssignedKernel; + ghoul_assert(kernelId != 0, fmt::format("Kernel Handle wrapped around to 0")); + _loadedKernels.push_back({std::move(path), kernelId, 1}); return kernelId; } } bool SpiceManager::findCkCoverage(const std::string& path) { - SpiceInt frame, numberOfIntervals; - SpiceDouble b, e; - std::pair tempInterval; SPICEINT_CELL(ids, MAXOBJ); SPICEDOUBLE_CELL(cover, WINSIZ); ckobj_c(path.c_str(), &ids); for (SpiceInt i = 0; i < card_c(&ids); ++i) { - frame = SPICE_CELL_ELEM_I(&ids, i); + SpiceInt frame = SPICE_CELL_ELEM_I(&ids, i); scard_c(0, &cover); ckcov_c(path.c_str(), frame, SPICEFALSE, "SEGMENT", 0.0, "TDB", &cover); //Get the number of intervals in the coverage window. - numberOfIntervals = wncard_c(&cover); + SpiceInt numberOfIntervals = wncard_c(&cover); for (SpiceInt j = 0; j < numberOfIntervals; ++j) { //Get the endpoints of the jth interval. + SpiceDouble b, e; wnfetd_c(&cover, j, &b, &e); - tempInterval = std::make_pair(b, e); _ckCoverageTimes[frame].insert(e); _ckCoverageTimes[frame].insert(b); - _ckIntervals[frame].push_back(tempInterval); + _ckIntervals[frame].emplace_back(b, e); } } - return true; + + bool success = checkForError("Error finding Ck Converage"); + return success; } bool SpiceManager::findSpkCoverage(const std::string& path) { @@ -196,11 +204,11 @@ bool SpiceManager::findSpkCoverage(const std::string& path) { _spkIntervals[obj].push_back(tempInterval); } } - return true; + bool success = checkForError("Error finding Spk Converage"); + return success; } -bool SpiceManager::hasSpkCoverage(std::string target, double& et) const -{ +bool SpiceManager::hasSpkCoverage(std::string target, double& et) const { int id; bool idSuccess = getNaifId(target, id); bool hasCoverage = false; @@ -221,8 +229,7 @@ bool SpiceManager::hasSpkCoverage(std::string target, double& et) const return idSuccess && hasCoverage; } -bool SpiceManager::hasCkCoverage(std::string frame, double& et) const -{ +bool SpiceManager::hasCkCoverage(std::string frame, double& et) const { int id; bool idSuccess = getFrameId(frame, id); bool hasCoverage = false; From fad2c642f8a8ec7d43fb97a406435aaa26b8d0f7 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Wed, 18 Nov 2015 16:20:15 -0500 Subject: [PATCH 038/122] Cleanup of SpiceManager by introducing exceptions Catch exceptions in RenderableShadowCylinder and LabelParser Catch exceptions in RenderableFov and Hongkangparser --- ext/ghoul | 2 +- include/openspace/util/spicemanager.h | 205 +++--- modules/base/ephemeris/spiceephemeris.cpp | 10 +- .../newhorizons/rendering/renderablefov.cpp | 31 +- .../rendering/renderableshadowcylinder.cpp | 1 - modules/newhorizons/util/hongkangparser.cpp | 3 +- modules/newhorizons/util/labelparser.cpp | 9 +- src/engine/openspaceengine.cpp | 8 - src/util/spicemanager.cpp | 610 ++++++++---------- 9 files changed, 440 insertions(+), 439 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index b2278ce9d3..970f159ed9 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit b2278ce9d387a7f6179d3045ce349fecffc81976 +Subproject commit 970f159ed93dd1f922b272a3344a93b4120c1616 diff --git a/include/openspace/util/spicemanager.h b/include/openspace/util/spicemanager.h index 5e0ab83759..909131a050 100644 --- a/include/openspace/util/spicemanager.h +++ b/include/openspace/util/spicemanager.h @@ -29,10 +29,12 @@ #include #include +#include #include #include +#include #include #include #include @@ -50,113 +52,149 @@ public: using TransformMatrix = std::array; using KernelHandle = unsigned int; - static const KernelHandle InvalidKernel = KernelHandle(-1); - + class SpiceKernelException : public ghoul::RuntimeError { + public: + explicit SpiceKernelException(const std::string& msg); + }; + /** * Loads one or more SPICE kernels into a program. The provided path can either be a * binary, text-kernel, or meta-kernel which gets loaded into the kernel pool. The * loading is done by passing the \p filePath to the furnsh_c - * function. http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/furnsh_c.html - * Kernels can safely be loaded multiple times and are reference counted + * function. Kernels can safely be loaded multiple times and are reference counted. * \param filePath The path to the kernel that should be loaded. This path will be * passed to absPath to convert a relative path to an absolute path * before usage * \return The loaded kernel's unique identifier that can be used to unload the kernel + * \throws SpiceKernelException If the loading of the kernel \p filePath failed * \pre \p filePath is a non-empty absolute or relative path pointing to an * existing file that contains a SPICE kernel * \post The kernel is loaded or has its reference counter incremented and the handle * to the kernel is returned if the SPICE kernel is valid, or \a KernelInvalid if the * kernel is invalid + * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/furnsh_c.html */ KernelHandle loadKernel(std::string filePath); /** - * \return true if SPK kernels have been loaded to cover target - * for time et - * \param target, the body to be examined - * \param et, the time when body is possibly covered - */ - - bool hasSpkCoverage(std::string target, double& et) const; - - /** - * \return true if CK kernels have been loaded to cover frame - * for time et - * \param frame, the frame to be examined - * \param et, the time when frame is possibly covered - */ - bool hasCkCoverage(std::string frame, double& et) const; - - /** - * Unloads a SPICE kernel identified by the kernelId which was returned - * by the loading call to loadKernel. The unloading is done by calling the + * Unloads a SPICE kernel identified by the \p kernelId which was returned by the + * loading call to #loadKernel. The unloading is done by calling the * unload_c function. - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/unload_c.html. * \param kernelId The unique identifier that was returned from the call to - * loadKernel which loaded the kernel + * #loadKernel which loaded the kernel + * \pre \p kernelId must be a valid handle and cannot be equal to + * KernelHandle(0) + * \post The kernel identified by \p kernelId is unloaded + * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/unload_c.html */ void unloadKernel(KernelHandle kernelId); - - /** - * Unloads a SPICE kernel identified by the filePath which was used in - * the loading call to loadKernel. The unloading is done by calling the - * unload_c function. - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/unload_c.html. - * \param filePath The path of the kernel that should be unloaded, it has to refer to - * a file that was loaded in using the loadKernel method - */ - void unloadKernel(const std::string& filePath); /** - * Determines whether values exist for some item for any body, - * identified by it's naifId, in the kernel pool by passing it to the - * bodfnd_c function. - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bodfnd_c.html - * For a description on NAIF IDs, see - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html. + * Unloads a SPICE kernel identified by the \p filePath which was used in the + * loading call to #loadKernel. The unloading is done by calling the + * unload_c function. + * \param filePath The path of the kernel that should be unloaded. The filePath must + * have been previously used to successfully load a kernel, or a SpiceKernelException + * is thrown + * \pre \p filePath cannot be empty + * \post The kernel identified by \p filePath is unloaded or nothing happens if + * \p filePath was not used to load a kernel + * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/unload_c.html + */ + void unloadKernel(std::string filePath); + + /** + * Returns whether a given \p target has an Spk kernel covering it at the designated + * \p et ephemeris time. + * \param target The body to be examined. The target has to name a valid SPICE object + * with respect to the kernels that have been loaded + * \param et The time for which the coverage should be checked + * \return true if SPK kernels have been loaded to cover \p target at the + * time \p et, false otherwise. + * \pre \p target must be a non-empty string that names a valid SPICE object + * \throws SpiceKernelException If \p target is not a valid NAIF target + */ + bool hasSpkCoverage(const std::string& target, double et) const; + + /** + * Returns whether a given \p frame has a CK kernel covering it at the designated + * \p et ephemeris time. + * \param frame The frame to be examined. The \p frame has to name a valid frame with + * respect to the kernels that have been loaded + * \param et The time for which the coverage should be checked + * \return true if SPK kernels have been loaded to cover \p target at the + * time \p et , false otherwise. + * \pre \p target must be a non-empty string that names a valid SPICE object + * \throws SpiceKernelException If \p frame is not a valid frame + */ + bool hasCkCoverage(const std::string& frame, double et) const; + + /** + * Determines whether values exist for some \p item for any body, identified by its + * \p naifId, in the kernel pool by passing it to the bodfnd_c function. * \param naifId NAIF ID code of body * \param item The item to find * \return true if the function succeeded, false otherwise + * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bodfnd_c.html + * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html */ bool hasValue(int naifId, const std::string& item) const; /** - * Determines whether values exist for some item for any - * body in the kernel pool by passing it to the bodfnd_c - * function. - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bodfnd_c.html + * Determines whether values exist for some \p item for any \p body in the kernel pool + * by passing it to the bodfnd_c function. * \param body The name of the body that should be sampled - * \param item The item to find + * \param item The item to find in the \p body * \return true if the function succeeded, false otherwise + * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bodfnd_c.html + * \throws SpiceKernelException If \p body is not a valid type + * \pre \p body and \item must be non-empty and \p body must name a valid Spice object */ bool hasValue(const std::string& body, const std::string& item) const; /** - * Returns the NAIF ID for a specific body. For a description on NAIF IDs, see - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html. The - * id will only be set if the retrieval was successful, otherwise it will - * remain unchanged. + * Returns the NAIF ID for a specific \p body using the bods2c_c + * function. * \param body The body name that should be retrieved - * \param id The ID of the body will be stored in this variable. The + * \return The ID of the body will be stored in this variable. The * value will only be changed if the retrieval was successful - * \return true if the body was found, false - * otherwise + * \throws SpiceKernelException If \p body is not a valid type + * \pre \p body must be not-empty + * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bods2c_c.html + * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html */ - bool getNaifId(const std::string& body, int& id) const; + int naifId(const std::string& body) const; /** - * Returns the NAIF ID for a specific frame using namfrm_c(), see - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/namfrm_c.html. - * The id will only be set if the retrieval was successful, - * otherwise it will remain unchanged. - * \param frame The frame name that should be retrieved - * \param id The ID of the frame will be stored in this variable. The - * value will only be changed if the retrieval was successful - * \return true if the frame was found, false + * Checks whether the specified \p body has a valid NAIF ID using the currently loaded + * Spice kernels. + * \param body The body for which the presence of a valid ID should be checked + * \return true if the \p body has a NAIF ID, false * otherwise + * \pre \p body must be non-empty */ - bool getFrameId(const std::string& frame, int& id) const; + bool hasNaifId(const std::string& body) const; + + /** + * Returns the NAIF ID for a specific frame using namfrm_c. + * \param frame The frame name that should be retrieved + * \return The NAIF ID of the \p frame + * \throws SpiceKernelException If \p frame is not a valid frame + * \pre \p frame must be not-empty + * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/namfrm_c.html + */ + int frameId(const std::string& frame) const; + /** + * Checks whether the specified \p frame has a valid NAIF ID using the currently + * loaded Spice kernels. + * \param frame The frame for which the presence of a valid ID should be checked + * \return true if the \p frame has a NAIF ID, false + * otherwise + * \pre \p frame must be non-empty + */ + bool hasFrameId(const std::string& frame) const; + /** * Retrieves a single value for a certain body. This method * succeeds iff body is the name of a valid body, value @@ -175,7 +213,7 @@ public: * value is a valid item for the body and the retrieved * value is only a single value. false otherwise */ - bool getValue(const std::string& body, const std::string& value, double& v) const; + void getValue(const std::string& body, const std::string& value, double& v) const; /** * Retrieves a value with three components for a certain @@ -195,7 +233,7 @@ public: * value is a valid item for the body and the retrieved * value is only a single value. false otherwise */ - bool getValue(const std::string& body, const std::string& value, glm::dvec3& v) const; + void getValue(const std::string& body, const std::string& value, glm::dvec3& v) const; /** * Retrieves a value with four components for a certain @@ -215,7 +253,7 @@ public: * value is a valid item for the body and the retrieved * value is only a single value. false otherwise */ - bool getValue(const std::string& body, const std::string& value, glm::dvec4& v) const; + void getValue(const std::string& body, const std::string& value, glm::dvec4& v) const; /** * Retrieves a value with an arbitrary number of components for a certain @@ -238,11 +276,23 @@ public: * value is a valid item for the body and the retrieved * value is only a single value. false otherwise */ - bool getValue(const std::string& body, const std::string& value, + void getValue(const std::string& body, const std::string& value, std::vector& v) const; - bool spacecraftClockToET(const std::string& craftIdCode, double& craftTicks, double& et); + /** + * Converts the value \p craftTicks of the internal clock for the spacecraft + * identified by \p craft into standard ephemeris time and returns the value. + * \param craft The NAIF ID of the craft for which the time should be converted + * \param craftTicks The internal clock ticks for the specified craft + * \return The converted ephemeris time + * \throws SpiceKernelException If the name \p craft is not a valid name + * available through all loaded kernels, if the craft is not supported by any of the + * loaded kernel, or if the provided \p craftTicks is not a valid tick time for the + * specific spacecraft + * \pre \craftIdCode may not be empty and need to name a valid craft + */ + double spacecraftClockToET(const std::string& craft, double craftTicks); /** * Converts the timeString representing a date to a double precision @@ -656,16 +706,6 @@ public: */ std::string frameFromBody(const std::string body) const; - /** - * This method checks if one of the previous SPICE methods has failed. If it has, the - * errorMessage is used to log an error along with the original SPICE - * error message. - * \param errorMessage The error message that will be logged if the method fails. If - * the argument is empty, no error message will be logged - * \return true if an error occurred, false otherwise - */ - static bool checkForError(std::string errorMessage); - /** * This method uses the SPICE kernels to get the radii of bodies defined as a * triaxial ellipsoid. The benefit of this is to be able to create more accurate @@ -699,8 +739,10 @@ protected: * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/ckcov_c.html * \param filePath The path to the kernel that should be examined * \return true if the operation was successful + * \pre \p path must be nonempty and be an existing file + * \post Coverage times are stored only if loading was successful */ - bool findCkCoverage(const std::string& path); + void findCkCoverage(const std::string& path); /** * Function to find and store the intervals covered by a spk file, this is done @@ -709,10 +751,11 @@ protected: * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/spkcov_c.html * \param filePath The path to the kernel that should be examined * \return true if the operation was successful + * \pre \p path must be nonempty and be an existing file + * \post Coverage times are stored only if loading was successful */ - bool findSpkCoverage(const std::string& path); + void findSpkCoverage(const std::string& path); - /// A list of all loaded kernels std::vector _loadedKernels; // Map: id, vector of pairs. Pair: Start time, end time; diff --git a/modules/base/ephemeris/spiceephemeris.cpp b/modules/base/ephemeris/spiceephemeris.cpp index 3ae196b043..b4ec10e344 100644 --- a/modules/base/ephemeris/spiceephemeris.cpp +++ b/modules/base/ephemeris/spiceephemeris.cpp @@ -62,8 +62,14 @@ SpiceEphemeris::SpiceEphemeris(const ghoul::Dictionary& dictionary) if (!success) LERROR("'" << KeyKernels << "' has to be an array-style table"); - SpiceManager::KernelHandle id = SpiceManager::ref().loadKernel(kernel); - _kernelsLoadedSuccessfully &= (id != SpiceManager::InvalidKernel); + try { + SpiceManager::KernelHandle id = SpiceManager::ref().loadKernel(kernel); + _kernelsLoadedSuccessfully = true; + } + catch (const SpiceManager::SpiceKernelException& e) { + LERROR("Could not load SPICE kernel: " << e.what()); + _kernelsLoadedSuccessfully = false; + } } } diff --git a/modules/newhorizons/rendering/renderablefov.cpp b/modules/newhorizons/rendering/renderablefov.cpp index 51ddcdcc13..0059a4ec2a 100644 --- a/modules/newhorizons/rendering/renderablefov.cpp +++ b/modules/newhorizons/rendering/renderablefov.cpp @@ -101,21 +101,24 @@ RenderableFov::RenderableFov(const ghoul::Dictionary& dictionary) void RenderableFov::allocateData() { std::string shape, instrument; // fetch data for specific instrument (shape, boresight, bounds etc) - bool found = openspace::SpiceManager::ref().getFieldOfView(_instrumentID, shape, instrument, _boresight, _bounds); - if (!found) { - LERROR("Could not locate instrument"); - return; - } - _stride = 8; + try { + SpiceManager::ref().getFieldOfView(_instrumentID, shape, instrument, _boresight, _bounds); - _projectionBounds.resize(_bounds.size()); - int initBoundPoints = 2 * (_bounds.size() + 1); - _fovBounds.resize(initBoundPoints*_stride); - _vBoundsSize = static_cast(_fovBounds.size()); - // allocate second vbo data - _fovPlane.resize(40); - _vPlaneSize = 40; - _isteps = 10; // Interpolation steps per intersecting segment + _stride = 8; + + _projectionBounds.resize(_bounds.size()); + int initBoundPoints = 2 * (_bounds.size() + 1); + _fovBounds.resize(initBoundPoints*_stride); + _vBoundsSize = static_cast(_fovBounds.size()); + // allocate second vbo data + _fovPlane.resize(40); + _vPlaneSize = 40; + _isteps = 10; // Interpolation steps per intersecting segment + + } + catch (const SpiceManager::SpiceKernelException& e) { + LERROR(e.what()); + } } RenderableFov::~RenderableFov() { diff --git a/modules/newhorizons/rendering/renderableshadowcylinder.cpp b/modules/newhorizons/rendering/renderableshadowcylinder.cpp index e0cda86132..1e82e75e30 100644 --- a/modules/newhorizons/rendering/renderableshadowcylinder.cpp +++ b/modules/newhorizons/rendering/renderableshadowcylinder.cpp @@ -88,7 +88,6 @@ bool RenderableShadowCylinder::isReady() const { bool RenderableShadowCylinder::initialize() { glGenVertexArrays(1, &_vao); // generate array glGenBuffers(1, &_vbo); // generate buffer - createCylinder(); bool completeSuccess = true; _shader = ghoul::opengl::ProgramObject::Build("ShadowProgram", diff --git a/modules/newhorizons/util/hongkangparser.cpp b/modules/newhorizons/util/hongkangparser.cpp index 38687886a3..f85cac48e3 100644 --- a/modules/newhorizons/util/hongkangparser.cpp +++ b/modules/newhorizons/util/hongkangparser.cpp @@ -118,7 +118,8 @@ void HongKangParser::writeUTCEventFile(const Image image){ bool HongKangParser::create(){ //check input for errors. int tmp; - bool hasObserver = SpiceManager::ref().getNaifId(_spacecraft, tmp); + bool hasObserver = SpiceManager::ref().hasNaifId(_spacecraft); + tmp = SpiceManager::ref().naifId(_spacecraft); if (!hasObserver){ LERROR("SPICE navigation system has no pooled observer: '" << _spacecraft << "' in kernel" << "Please check that all necessary kernels are loaded"<< diff --git a/modules/newhorizons/util/labelparser.cpp b/modules/newhorizons/util/labelparser.cpp index 565fc53329..7a8ef3047c 100644 --- a/modules/newhorizons/util/labelparser.cpp +++ b/modules/newhorizons/util/labelparser.cpp @@ -211,7 +211,14 @@ bool LabelParser::create() { read = line.substr(0, line.find_first_of(" ")); if (read == "STOP_TIME"){ std::string stop = line.substr(line.find("=") + 2); - stop.erase(std::remove(stop.begin(), stop.end(), ' '), stop.end()); + stop.erase( + std::remove_if( + stop.begin(), + stop.end(), + [](char c) { return c == ' ' || c == '\r'; } + ), + stop.end() + ); openspace::SpiceManager::ref().getETfromDate(stop, _stopTime); count++; } diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 313139d1f7..ea7e9f8f68 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -487,10 +487,6 @@ bool OpenSpaceEngine::loadSpiceKernels() { } SpiceManager::KernelHandle id = SpiceManager::ref().loadKernel(timeKernel); - if (id == SpiceManager::InvalidKernel) { - LERROR("Error loading time kernel '" << timeKernel << "'"); - return false; - } // Load SPICE leap second kernel std::string leapSecondKernel; @@ -501,10 +497,6 @@ bool OpenSpaceEngine::loadSpiceKernels() { return false; } id = SpiceManager::ref().loadKernel(std::move(leapSecondKernel)); - if (id == SpiceManager::InvalidKernel) { - LERROR("Error loading leap second kernel '" << leapSecondKernel << "'"); - return false; - } return true; } diff --git a/src/util/spicemanager.cpp b/src/util/spicemanager.cpp index 702227b526..71369b59c8 100644 --- a/src/util/spicemanager.cpp +++ b/src/util/spicemanager.cpp @@ -27,16 +27,13 @@ #include #include #include +#include #include #include - #include -#define MAXOBJ 64 -#define WINSIZ 10000 - namespace { const std::string _loggerCat = "SpiceManager"; @@ -44,9 +41,30 @@ namespace { // http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/getmsg_c.html // as the maximum message length const unsigned SpiceErrorBufferSize = 1841; + + // This method checks if one of the previous SPICE methods has failed. If it has, an + // exception with the SPICE error message is thrown + void throwOnSpiceError(std::string errorMessage) { + SpiceBoolean failed = failed_c(); + if (failed) { + char buffer[SpiceErrorBufferSize]; + getmsg_c("LONG", SpiceErrorBufferSize, buffer); + reset_c(); + throw openspace::SpiceManager::SpiceKernelException( + errorMessage + ": " + buffer + ); + } + } } +using fmt::format; +using std::string; + namespace openspace { + +SpiceManager::SpiceKernelException::SpiceKernelException(const string& msg) + : ghoul::RuntimeError(msg, "Spice") +{} SpiceManager::SpiceManager() { // Set the SPICE library to not exit the program if an error occurs @@ -65,15 +83,11 @@ SpiceManager::~SpiceManager() { } -SpiceManager::KernelHandle SpiceManager::loadKernel(std::string filePath) { - // Preconditions: - // !filePath.empty() - // filePath exists - // Directory(filePath) exists +SpiceManager::KernelHandle SpiceManager::loadKernel(string filePath) { ghoul_assert(!filePath.empty(), "Empty file path"); ghoul_assert( FileSys.fileExists(filePath), - fmt::format( + format( "File '{}' ('{}') does not exist", filePath, absPath(filePath) @@ -81,14 +95,14 @@ SpiceManager::KernelHandle SpiceManager::loadKernel(std::string filePath) { ); ghoul_assert( FileSys.directoryExists(ghoul::filesystem::File(filePath).directoryName()), - fmt::format( + format( "File '{}' exists, but directory '{}' doesn't", absPath(filePath), ghoul::filesystem::File(filePath).directoryName() ) ); - std::string path = absPath(filePath); + string path = absPath(filePath); auto it = std::find_if( _loadedKernels.begin(), _loadedKernels.end(), @@ -97,7 +111,7 @@ SpiceManager::KernelHandle SpiceManager::loadKernel(std::string filePath) { if (it != _loadedKernels.end()) { it->refCount++; LDEBUG( - fmt::format( + format( "Kernel '{}' was already loaded. New reference count: {}", path, it->refCount @@ -110,7 +124,7 @@ SpiceManager::KernelHandle SpiceManager::loadKernel(std::string filePath) { // to the directory they reside in. The directory change is not necessary for regular // kernels ghoul::filesystem::Directory currentDirectory = FileSys.currentDirectory(); - std::string fileDirectory = ghoul::filesystem::File(path, true).directoryName(); + string fileDirectory = ghoul::filesystem::File(path, true).directoryName(); FileSys.setCurrentDirectory(fileDirectory); LINFO("Loading SPICE kernel '" << path << "'"); @@ -120,291 +134,196 @@ SpiceManager::KernelHandle SpiceManager::loadKernel(std::string filePath) { // Reset the current directory to the previous one FileSys.setCurrentDirectory(currentDirectory); - SpiceBoolean failed = failed_c(); - if (failed) { - char* buffer = new char[SpiceErrorBufferSize]; - getmsg_c("LONG", SpiceErrorBufferSize, buffer); - LERROR(fmt::format("Error loading kernel '{}'", path)); - LERROR(fmt::format("Spice reported: {}", buffer)); - reset_c(); - delete[] buffer; - return InvalidKernel; - } + throwOnSpiceError("Kernel loading"); - std::string fileExtension = ghoul::filesystem::File(path, true).fileExtension(); - bool success = true; + string fileExtension = ghoul::filesystem::File(path, true).fileExtension(); if (fileExtension == ".bc" || fileExtension == ".BC") - success = findCkCoverage(path); // binary ck kernel + findCkCoverage(path); // binary ck kernel else if (fileExtension == "bsp" || fileExtension == "BSP") - success = findSpkCoverage(path); // binary spk kernel + findSpkCoverage(path); // binary spk kernel - if (!success) - return InvalidKernel; - else { - KernelHandle kernelId = ++_lastAssignedKernel; - ghoul_assert(kernelId != 0, fmt::format("Kernel Handle wrapped around to 0")); - _loadedKernels.push_back({std::move(path), kernelId, 1}); - return kernelId; - } -} - -bool SpiceManager::findCkCoverage(const std::string& path) { - SPICEINT_CELL(ids, MAXOBJ); - SPICEDOUBLE_CELL(cover, WINSIZ); - - ckobj_c(path.c_str(), &ids); - - for (SpiceInt i = 0; i < card_c(&ids); ++i) { - SpiceInt frame = SPICE_CELL_ELEM_I(&ids, i); - - scard_c(0, &cover); - ckcov_c(path.c_str(), frame, SPICEFALSE, "SEGMENT", 0.0, "TDB", &cover); - - //Get the number of intervals in the coverage window. - SpiceInt numberOfIntervals = wncard_c(&cover); - - for (SpiceInt j = 0; j < numberOfIntervals; ++j) { - //Get the endpoints of the jth interval. - SpiceDouble b, e; - wnfetd_c(&cover, j, &b, &e); - - _ckCoverageTimes[frame].insert(e); - _ckCoverageTimes[frame].insert(b); - _ckIntervals[frame].emplace_back(b, e); - } - } - - bool success = checkForError("Error finding Ck Converage"); - return success; -} - -bool SpiceManager::findSpkCoverage(const std::string& path) { - SpiceInt obj, numberOfIntervals; - SpiceDouble b, e; - std::pair tempInterval; - SPICEINT_CELL(ids, MAXOBJ); - SPICEDOUBLE_CELL(cover, WINSIZ); - - spkobj_c(path.c_str(), &ids); - for (SpiceInt i = 0; i < card_c(&ids); ++i) { - obj = SPICE_CELL_ELEM_I(&ids, i); - - scard_c(0, &cover); - spkcov_c(path.c_str(), obj, &cover); - //Get the number of intervals in the coverage window. - numberOfIntervals = wncard_c(&cover); - - for (SpiceInt j = 0; j < numberOfIntervals; ++j) { - //Get the endpoints of the jth interval. - wnfetd_c(&cover, j, &b, &e); - tempInterval = std::make_pair(b, e); - //insert all into coverage time set, the windows could be merged @AA - _spkCoverageTimes[obj].insert(e); - _spkCoverageTimes[obj].insert(b); - _spkIntervals[obj].push_back(tempInterval); - } - } - bool success = checkForError("Error finding Spk Converage"); - return success; -} - -bool SpiceManager::hasSpkCoverage(std::string target, double& et) const { - int id; - bool idSuccess = getNaifId(target, id); - bool hasCoverage = false; - - std::vector< std::pair > intervalVector; - if (_spkIntervals.find(id) == _spkIntervals.end()) - return false; - else - intervalVector = _spkIntervals.find(id)->second; - - for (auto vecElement : intervalVector) { - if (vecElement.first < et && vecElement.second > et) { - hasCoverage = true; - return idSuccess && hasCoverage; - } - } - - return idSuccess && hasCoverage; -} - -bool SpiceManager::hasCkCoverage(std::string frame, double& et) const { - int id; - bool idSuccess = getFrameId(frame, id); - bool hasCoverage = false; - - std::vector< std::pair > intervalVector; - if (_ckIntervals.find(id) == _ckIntervals.end()) - return false; - else - intervalVector = _ckIntervals.find(id)->second; - - for (auto vecElement : intervalVector) { - if (vecElement.first < et && vecElement.second > et) { - hasCoverage = true; - return idSuccess && hasCoverage; - } - } - - return idSuccess && hasCoverage; + KernelHandle kernelId = ++_lastAssignedKernel; + ghoul_assert(kernelId != 0, fmt::format("Kernel Handle wrapped around to 0")); + _loadedKernels.push_back({std::move(path), kernelId, 1}); + return kernelId; } void SpiceManager::unloadKernel(KernelHandle kernelId) { + ghoul_assert(kernelId <= _lastAssignedKernel, "Invalid unassigned kernel"); + ghoul_assert(kernelId != KernelHandle(0), "Invalid zero handle"); + auto it = std::find_if(_loadedKernels.begin(), _loadedKernels.end(), - [&kernelId](const KernelInformation& info) { return info.id == kernelId ; }); + [&kernelId](const KernelInformation& info) { return info.id == kernelId; }); if (it != _loadedKernels.end()) { - // If there is only one part interested in the kernel, we can unload it + // If there was only one part interested in the kernel, we can unload it if (it->refCount == 1) { // No need to check for errors as we do not allow empty path names - LINFO("Unloading SPICE kernel '" << it->path << "'"); + LINFO(format("Unloading SPICE kernel '{}'", it->path)); unload_c(it->path.c_str()); _loadedKernels.erase(it); } + // Otherwise, we hold on to it, but reduce the reference counter by 1 else { - // Otherwise, we hold on to it, but reduce the reference counter by 1 it->refCount--; - LDEBUG("Reducing reference counter. New reference count: " << it->refCount); + LDEBUG(format("Reducing reference counter to: {}", it->refCount)); } } } -void SpiceManager::unloadKernel(const std::string& filePath) { - if (filePath.empty()) { - LERROR("No file path provided"); - return; - } - std::string&& path = absPath(filePath); +void SpiceManager::unloadKernel(string filePath) { + ghoul_assert(!filePath.empty(), "Empty filename"); + + string path = absPath(filePath); auto it = std::find_if(_loadedKernels.begin(), _loadedKernels.end(), [&path](const KernelInformation& info) { return info.path == path; }); - - if (it != _loadedKernels.end()) { - // If there is only one part interested in the kernel, we can unload it + + if (it == _loadedKernels.end()) + throw SpiceKernelException("Kernel unloading failed"); + else { + // If there was only one part interested in the kernel, we can unload it if (it->refCount == 1) { - LINFO("Unloading SPICE kernel '" << path << "'"); + LINFO(format("Unloading SPICE kernel '{}'", path)); unload_c(path.c_str()); _loadedKernels.erase(it); } else { // Otherwise, we hold on to it, but reduce the reference counter by 1 it->refCount--; - LDEBUG("Reducing reference counter. New reference count: " << it->refCount); + LDEBUG(format("Reducing reference counter to: {}", it->refCount)); } } } -bool SpiceManager::hasValue(int naifId, const std::string& item) const { - return (bodfnd_c(naifId, item.c_str()) == SPICETRUE); +bool SpiceManager::hasSpkCoverage(const string& target, double et) const { + ghoul_assert(!target.empty(), "Empty target"); + + int id = naifId(target); + auto it = _spkIntervals.find(id); + if (it != _spkIntervals.end()) { + std::vector> intervalVector = it->second; + for (const auto& vecElement : intervalVector) { + if (vecElement.first < et && vecElement.second > et) + return true; + } + } + return false; } -bool SpiceManager::hasValue(const std::string& body, const std::string& item) const { - int id; - bool success = getNaifId(body, id); - if (success) - return hasValue(id, item); - else - return false; +bool SpiceManager::hasCkCoverage(const string& frame, double et) const { + ghoul_assert(!frame.empty(), "Empty target"); + + int id = frameId(frame); + + auto it = _ckIntervals.find(id); + if (it != _ckIntervals.end()) { + std::vector> intervalVector = it->second; + for (const auto& i : intervalVector) { + if (i.first < et && i.second > et) + return true; + } + } + return false; } -bool SpiceManager::getNaifId(const std::string& body, int& id) const { - if (body.empty()) { - LERROR("No body was provided"); - return false; - } - else { - SpiceBoolean success; -// SpiceInt sid = id; - bods2c_c(body.c_str(), &id, &success); -// id = sid; - if (success == SPICEFALSE) - LERROR("Could not find NAIF ID of body '" + body + "'"); - return (success == SPICETRUE); - } +bool SpiceManager::hasValue(int naifId, const string& item) const { + return bodfnd_c(naifId, item.c_str()); } -bool SpiceManager::getFrameId(const std::string& frame, int& id) const { - if (frame.empty()) { - LERROR("No frame was provided"); - return false; - } - else { - namfrm_c(frame.c_str(), &id); - bool hasError = SpiceManager::checkForError("Error getting id for frame '" + frame + "'"); - return !hasError; - } +bool SpiceManager::hasValue(const string& body, const string& item) const { + ghoul_assert(!body.empty(), "Empty body"); + ghoul_assert(!item.empty(), "Empty item"); + + int id = naifId(body); + return hasValue(id, item); } -bool getValueInternal(const std::string& body, const std::string& value, int S, +int SpiceManager::naifId(const string& body) const { + ghoul_assert(!body.empty(), "Empty body"); + + SpiceBoolean success; + int id; + bods2c_c(body.c_str(), &id, &success); + if (!success) + throw SpiceKernelException(format("Could not find NAIF ID of body '{}'", body)); + return id; +} + +bool SpiceManager::hasNaifId(const string& body) const { + ghoul_assert(!body.empty(), "Empty body"); + + SpiceBoolean success; + int id; + bods2c_c(body.c_str(), &id, &success); + return success; +} + +int SpiceManager::frameId(const string& frame) const { + ghoul_assert(!frame.empty(), "Empty frame"); + + int id; + namfrm_c(frame.c_str(), &id); + if (id == 0) + throw SpiceKernelException(format("Could not find NAIF ID of frame '{}'", frame)); + return id; +} + +bool SpiceManager::hasFrameId(const string& frame) const { + ghoul_assert(!frame.empty(), "Empty frame"); + + int id; + namfrm_c(frame.c_str(), &id); + return id != 0; +} + +void getValueInternal(const string& body, const string& value, int size, double* v) { - - if (body.empty()) { - LERROR("No body was provided"); - return false; - } - if (value.empty()) { - LERROR("No value was provided"); - return false; - } + ghoul_assert(!body.empty(), "Empty body"); + ghoul_assert(!value.empty(), "Empty value"); + ghoul_assert(v != nullptr, "Empty value pointer"); SpiceInt n; - bodvrd_c(body.c_str(), value.c_str(), S, &n, v); + bodvrd_c(body.c_str(), value.c_str(), size, &n, v); - bool hasError = SpiceManager::checkForError("Error getting value '" + value + + throwOnSpiceError("Error getting value '" + value + "' for body '" + body + "'"); - return !hasError; } -bool SpiceManager::getValue(const std::string& body, const std::string& value, - double& v) const +void SpiceManager::getValue(const string& body, const string& value, double& v) const { + getValueInternal(body, value, 1, &v); +} + +void SpiceManager::getValue(const string& body, const string& value, + glm::dvec3& v) const { - return getValueInternal(body, value, 1, &v); + getValueInternal(body, value, 3, glm::value_ptr(v)); } -bool SpiceManager::getValue(const std::string& body, const std::string& value, - glm::dvec3& v) const -{ - return getValueInternal(body, value, 3, glm::value_ptr(v)); -} - -bool SpiceManager::getValue(const std::string& body, const std::string& value, +void SpiceManager::getValue(const string& body, const string& value, glm::dvec4& v) const { - return getValueInternal(body, value, 4, glm::value_ptr(v)); + getValueInternal(body, value, 4, glm::value_ptr(v)); } -bool SpiceManager::getValue(const std::string& body, const std::string& value, +void SpiceManager::getValue(const string& body, const string& value, std::vector& v) const { - if (body.empty()) { - LERROR("No body was provided"); - return false; - } - if (value.empty()) { - LERROR("No value was provided"); - return false; - } - if (v.size() == 0) { - LERROR("Array for values has to be preallocaed"); - return false; - } - - SpiceInt n; - bodvrd_c(body.c_str(), value.c_str(), static_cast(v.size()), &n, &v[0]); - - bool hasError = checkForError("Error getting value '" + value + "' for body '" + - body + "'"); - return !hasError; + ghoul_assert(!v.empty(), "Array for values has to be preallocaed"); + getValueInternal(body, value, v.size(), v.data()); } -bool SpiceManager::spacecraftClockToET(const std::string& craftIdCode, double& craftTicks, double& et){ - int craftID = -1; - getNaifId(craftIdCode, craftID); - sct2e_c(craftID, craftTicks, &et); - bool hasError = checkForError("Error transforming spacecraft clock of '" + craftIdCode + "' at time " + std::to_string(craftTicks)); - return !hasError; +double SpiceManager::spacecraftClockToET(const string& craft, double craftTicks) { + ghoul_assert(!craft.empty(), "Empty craft"); + int craftId = naifId(craft); + double et; + sct2e_c(craftId, craftTicks, &et); + throwOnSpiceError(format( + "Error transforming spacecraft clock of '{}' at time {}", + craft, craftTicks) + ); + return et; } bool SpiceManager::getETfromDate(const std::string& timeString, @@ -416,8 +335,8 @@ bool SpiceManager::getETfromDate(const std::string& timeString, } str2et_c(timeString.c_str(), &ephemerisTime); - bool hasError = checkForError("Error converting date '" + timeString + "'"); - return !hasError; + throwOnSpiceError("Error converting date '" + timeString + "'"); + return true; } bool SpiceManager::getDateFromET(double ephemerisTime, std::string& date, @@ -432,13 +351,13 @@ bool SpiceManager::getDateFromET(double ephemerisTime, std::string& date, SpiceChar buffer[BufferSize]; timout_c(ephemerisTime, format.c_str(), BufferSize - 1, buffer); - bool hasError = checkForError( - "Error converting ephemeris time '" + - std::to_string(ephemerisTime) + - "' to date with format '" + format + "'"); - if (!hasError) - date = std::string(buffer); - return !hasError; + throwOnSpiceError("Error converting ephemeris time '" + + std::to_string(ephemerisTime) + + "' to date with format '" + format + "'" + ); + + date = std::string(buffer); + return true; } bool SpiceManager::getTargetPosition(const std::string& target, @@ -514,7 +433,8 @@ bool SpiceManager::getEstimatedPosition(const double time, const std::string tar { int idTarget, idObserver; - bool targetFound = getNaifId(target, idTarget); + bool targetFound = hasNaifId(target); + idTarget = naifId(target); if (idTarget == 0) { //SOLAR SYSTEM BARYCENTER special case, no def. in kernels targetPosition[0] = 0.f; targetPosition[1] = 0.f; @@ -525,7 +445,8 @@ bool SpiceManager::getEstimatedPosition(const double time, const std::string tar double pos[3] = { 0.0, 0.0, 0.0 }; - bool observerFound = getNaifId(observer, idObserver); + bool observerFound = hasNaifId(observer); + idObserver = naifId(observer); if (!targetFound || !observerFound || (idTarget == idObserver)) { return false; } @@ -571,7 +492,7 @@ bool SpiceManager::getEstimatedPosition(const double time, const std::string tar targetPosition = PowerScaledCoordinate::CreatePowerScaledCoordinate(pos[0], pos[1], pos[2]); - checkForError("Error estimating positin for target: " + target + ", or observer: " + observer); + throwOnSpiceError("Error estimating positin for target: " + target + ", or observer: " + observer); return targetFound && observerFound; } @@ -584,11 +505,9 @@ bool SpiceManager::frameConversion(glm::dvec3& v, const std::string& from, const // get rotation matrix from frame A - frame B pxform_c(from.c_str(), to.c_str(), ephemerisTime, (double(*)[3])glm::value_ptr(transform)); - bool hasError = checkForError("Error converting from frame '" + from + + throwOnSpiceError("Error converting from frame '" + from + "' to frame '" + to + "' at time " + std::to_string(ephemerisTime)); - if (hasError) - return false; - // re-express vector in new frame + // re-express vector in new frame mxv_c((double(*)[3])glm::value_ptr(transform), glm::value_ptr(v), glm::value_ptr(v)); return true; } @@ -620,10 +539,10 @@ bool SpiceManager::targetWithinFieldOfView(const std::string& instrument, &visible); isVisible = (visible == SPICETRUE); - bool hasError = checkForError("Checking if target '" + target + + throwOnSpiceError("Checking if target '" + target + "' is in view of instrument '" + instrument + "' failed"); - return !hasError; + return true; } bool SpiceManager::targetWithinFieldOfView(const std::string& instrument, @@ -649,10 +568,10 @@ bool SpiceManager::targetWithinFieldOfView(const std::string& instrument, &visible); isVisible = (visible == SPICETRUE); - bool hasError = checkForError("Checking if target '" + target + + throwOnSpiceError("Checking if target '" + target + "' is in view of instrument '" + instrument + "' failed"); - return !hasError; + return true; } @@ -704,14 +623,11 @@ bool SpiceManager::getSurfaceIntercept(const std::string& target, isVisible = (found == SPICETRUE); - bool hasError = checkForError("Error retrieving surface intercept on target '" + target + "'" + + throwOnSpiceError("Error retrieving surface intercept on target '" + target + "'" + "viewed from observer '" + observer + "' in " + "reference frame '" + bodyfixed + "' at time '" + std::to_string(ephemerisTime) + "'"); - if (hasError) - return false; - if (convert) frameConversion(srfvec, bodyfixed, referenceFrame, ephemerisTime); @@ -738,15 +654,13 @@ bool SpiceManager::getTargetState(const std::string& target, spkezr_c(target.c_str(), ephemerisTime, referenceFrame.c_str(), aberrationCorrection.c_str(), observer.c_str(), buffer, &lightTime); - bool hasError = checkForError("Error retrieving state of target '" + target + "'" + + throwOnSpiceError("Error retrieving state of target '" + target + "'" + "viewed from observer '" + observer + "' in " + "reference frame '" + referenceFrame + "' at time '" + std::to_string(ephemerisTime) + "'"); - if (!hasError) { - memmove(glm::value_ptr(targetPosition), buffer, sizeof(double) * 3); - memmove(glm::value_ptr(targetVelocity), buffer + 3, sizeof(double) * 3); - } - return !hasError; + memmove(glm::value_ptr(targetPosition), buffer, sizeof(double) * 3); + memmove(glm::value_ptr(targetVelocity), buffer + 3, sizeof(double) * 3); + return true; } // Not called at the moment @AA @@ -765,22 +679,15 @@ bool SpiceManager::getTargetState(const std::string& target, spkezr_c(target.c_str(), ephemerisTime, referenceFrame.c_str(), aberrationCorrection.c_str(), observer.c_str(), state, &lightTime); - bool hasError = checkForError("Error retrieving state of target '" + target + "'" + + throwOnSpiceError("Error retrieving state of target '" + target + "'" + "viewed from observer '" + observer + "' in " + "reference frame '" + referenceFrame + "' at time '" + std::to_string(ephemerisTime) + "'"); - if (!hasError) { - position = PowerScaledCoordinate::CreatePowerScaledCoordinate(state[0], state[1], state[2]); - velocity = PowerScaledCoordinate::CreatePowerScaledCoordinate(state[3], state[4], state[5]); - } - else - { - position = PowerScaledCoordinate::CreatePowerScaledCoordinate(0.0, 0.0, 0.0); - velocity = PowerScaledCoordinate::CreatePowerScaledCoordinate(0, 0, 0); - } + position = PowerScaledCoordinate::CreatePowerScaledCoordinate(state[0], state[1], state[2]); + velocity = PowerScaledCoordinate::CreatePowerScaledCoordinate(state[3], state[4], state[5]); - return !hasError; + return true; } // Not called at the moment @AA @@ -792,10 +699,10 @@ bool SpiceManager::getStateTransformMatrix(const std::string& fromFrame, sxform_c(fromFrame.c_str(), toFrame.c_str(), ephemerisTime, (double(*)[6])stateMatrix.data()); - bool hasError = checkForError("Error retrieved state transform matrix from frame '" + + throwOnSpiceError("Error retrieved state transform matrix from frame '" + fromFrame + "' to frame '" + toFrame + "' at time '" + std::to_string(ephemerisTime) + "'"); - return !hasError; + return true; } bool SpiceManager::getPositionTransformMatrix(const std::string& fromFrame, @@ -803,21 +710,14 @@ bool SpiceManager::getPositionTransformMatrix(const std::string& fromFrame, double ephemerisTime, glm::dmat3& positionMatrix) const { - bool success = false, estimated = false; + bool estimated = false; pxform_c(fromFrame.c_str(), toFrame.c_str(), ephemerisTime, (double(*)[3])glm::value_ptr(positionMatrix)); - success = !(failed_c()); + SpiceBoolean success = !(failed_c()); + reset_c(); if (!success) { - reset_c(); - estimated = getEstimatedTransformMatrix(ephemerisTime, fromFrame, toFrame, positionMatrix); - } - if (_showErrors) { - bool hasError = checkForError("Error retrieving position transform matrix from " - "frame '" + fromFrame + "' to frame '" + toFrame + - "' at time '" + std::to_string(ephemerisTime)); - if (hasError) - return false; + estimated = getEstimatedTransformMatrix(ephemerisTime, fromFrame, toFrame, positionMatrix); } positionMatrix = glm::transpose(positionMatrix); @@ -834,13 +734,13 @@ bool SpiceManager::getPositionTransformMatrix(const std::string& fromFrame, pxfrm2_c(fromFrame.c_str(), toFrame.c_str(), ephemerisTimeFrom, ephemerisTimeTo, (double(*)[3])glm::value_ptr(positionMatrix)); - bool hasError = checkForError("Error retrieving position transform matrix from " + throwOnSpiceError("Error retrieving position transform matrix from " "frame '" + fromFrame + "' to frame '" + toFrame + "' from time '" + std::to_string(ephemerisTimeFrom) + " to time '" + std::to_string(ephemerisTimeTo) + "'"); positionMatrix = glm::transpose(positionMatrix); - return !hasError; + return true; } @@ -849,11 +749,13 @@ bool SpiceManager::getEstimatedTransformMatrix(const double time, const std::str { int idFrame; - bool frameFound = getFrameId(fromFrame, idFrame); + bool frameFound = hasFrameId(fromFrame); if (!frameFound) { return false; } - if (_ckCoverageTimes.find(idFrame) == _ckCoverageTimes.end()){ // no coverage + idFrame = frameId(fromFrame); + + if (_ckCoverageTimes.find(idFrame) == _ckCoverageTimes.end()){ // no coverage return false; } @@ -892,10 +794,10 @@ bool SpiceManager::getEstimatedTransformMatrix(const double time, const std::str } } } - bool hasError = checkForError("Error estimating transform matrix from frame: " + throwOnSpiceError("Error estimating transform matrix from frame: " + fromFrame + ", to frame: " + toFrame); - return !hasError; + return true; } @@ -904,10 +806,11 @@ bool SpiceManager::getFieldOfView(const std::string& instrument, std::string& fo std::vector& bounds) const { int id; - bool success = getNaifId(instrument, id); + bool success = hasNaifId(instrument); if (!success) return false; else + id = naifId(instrument); return getFieldOfView(id, fovShape, frameName, boresightVector, bounds); } @@ -937,10 +840,8 @@ bool SpiceManager::getFieldOfView(int instrument, (double(*)[3])boundsArr // the bounds ); - bool hasError = checkForError("Error getting Field-of-View parameters for " + throwOnSpiceError("Error getting Field-of-View parameters for " "instrument '" + std::to_string(instrument) + "'"); - if (hasError) - return false; bounds.resize(nrReturned); for (int i = 0; i < nrReturned; ++i) { @@ -980,10 +881,8 @@ bool SpiceManager::getTerminatorEllipse(const int numberOfPoints, glm::value_ptr(observerPosition), (double(*)[3])tpoints.data() ); - bool hasError = checkForError("Error getting " + terminatorType + + throwOnSpiceError("Error getting " + terminatorType + "terminator for'" + target + "'"); - if (hasError) - return false; for (int i = 0; i < numberOfPoints; i++){ psc point = psc::CreatePowerScaledCoordinate(tpoints[i][0], tpoints[i][1], tpoints[i][2]); @@ -995,7 +894,6 @@ bool SpiceManager::getTerminatorEllipse(const int numberOfPoints, } std::string SpiceManager::frameFromBody(const std::string body) const { - for (auto pair : _frameByBody) { if (pair.first == body) { return pair.second; @@ -1022,34 +920,12 @@ bool SpiceManager::addFrame(const std::string body, const std::string frame) { } } -bool SpiceManager::checkForError(std::string errorMessage) { - - int failed = failed_c(); - if (failed && _showErrors) { - static char msg[1024]; - if (!errorMessage.empty()) { - getmsg_c("LONG", 1024, msg); - LWARNING(errorMessage); - LWARNING("Spice reported: " + std::string(msg)); - } - reset_c(); - return true; - } - else if (failed) { - reset_c(); - return false; - } - else - return false; -} - bool SpiceManager::getPlanetEllipsoid(std::string planetName, float &a, float &b, float &c) { - SpiceDouble radii[3]; SpiceInt n = -1; int id = -1; - getNaifId(planetName, id); + id = naifId(planetName); if (bodfnd_c(id, "RADII")) { bodvrd_c(planetName.c_str(), "RADII", 3, &n, radii); a = static_cast(radii[0]); @@ -1063,8 +939,82 @@ bool SpiceManager::getPlanetEllipsoid(std::string planetName, float &a, float &b c = 1.f; } - bool hasError = checkForError("Error retrieving planet radii of " + planetName); - return !hasError; + throwOnSpiceError("Error retrieving planet radii of " + planetName); + return true; +} + +void SpiceManager::findCkCoverage(const std::string& path) { + ghoul_assert(!path.empty(), "Empty file path"); + ghoul_assert(FileSys.fileExists(path), format("File '{}' does not exist", path)); + + const unsigned int MaxObj = 64; + const unsigned int WinSiz = 10000; + + SPICEINT_CELL(ids, MaxObj); + SPICEDOUBLE_CELL(cover, WinSiz); + + ckobj_c(path.c_str(), &ids); + throwOnSpiceError("Error finding Ck Converage"); + + for (SpiceInt i = 0; i < card_c(&ids); ++i) { + SpiceInt frame = SPICE_CELL_ELEM_I(&ids, i); + + scard_c(0, &cover); + ckcov_c(path.c_str(), frame, SPICEFALSE, "SEGMENT", 0.0, "TDB", &cover); + throwOnSpiceError("Error finding Ck Converage"); + + //Get the number of intervals in the coverage window. + SpiceInt numberOfIntervals = wncard_c(&cover); + + for (SpiceInt j = 0; j < numberOfIntervals; ++j) { + //Get the endpoints of the jth interval. + SpiceDouble b, e; + wnfetd_c(&cover, j, &b, &e); + throwOnSpiceError("Error finding Ck Converage"); + + _ckCoverageTimes[frame].insert(e); + _ckCoverageTimes[frame].insert(b); + _ckIntervals[frame].emplace_back(b, e); + } + } } +void SpiceManager::findSpkCoverage(const std::string& path) { + ghoul_assert(!path.empty(), "Empty file path"); + ghoul_assert(FileSys.fileExists(path), format("File '{}' does not exist", path)); + + const unsigned int MaxObj = 64; + const unsigned int WinSiz = 10000; + + SPICEINT_CELL(ids, MaxObj); + SPICEDOUBLE_CELL(cover, WinSiz); + + spkobj_c(path.c_str(), &ids); + throwOnSpiceError("Error finding Spk Converage"); + + for (SpiceInt i = 0; i < card_c(&ids); ++i) { + SpiceInt obj = SPICE_CELL_ELEM_I(&ids, i); + + scard_c(0, &cover); + spkcov_c(path.c_str(), obj, &cover); + throwOnSpiceError("Error finding Spk Converage"); + + //Get the number of intervals in the coverage window. + SpiceInt numberOfIntervals = wncard_c(&cover); + + for (SpiceInt j = 0; j < numberOfIntervals; ++j) { + //Get the endpoints of the jth interval. + SpiceDouble b, e; + wnfetd_c(&cover, j, &b, &e); + throwOnSpiceError("Error finding Spk Converage"); + + //insert all into coverage time set, the windows could be merged @AA + _spkCoverageTimes[obj].insert(e); + _spkCoverageTimes[obj].insert(b); + _spkIntervals[obj].emplace_back(b, e); + } + } +} + + } From 11fec9387b37218c1b38ed3a1bffea3ec5d03621 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Thu, 19 Nov 2015 13:40:44 -0500 Subject: [PATCH 039/122] More changes on the documentation and Exception handling in SpiceManager Change some interfaces on SpiceManager Removed target position return in powerscaled coordinates and only use glm::dvec4 instead as the Spice library does not have higher accuracy anyway --- ext/ghoul | 2 +- include/openspace/util/spicemanager.h | 262 +++++++++--------- modules/base/rendering/renderablemodel.cpp | 9 +- modules/base/rendering/renderablepath.cpp | 11 +- modules/base/rendering/renderableplanet.cpp | 6 +- modules/base/rendering/renderabletrail.cpp | 20 +- .../newhorizons/rendering/renderablefov.cpp | 7 +- .../rendering/renderablemodelprojection.cpp | 9 +- .../rendering/renderableplaneprojection.cpp | 5 +- .../rendering/renderableplanetprojection.cpp | 10 +- modules/newhorizons/util/hongkangparser.cpp | 32 +-- modules/newhorizons/util/labelparser.cpp | 4 +- modules/newhorizons/util/sequenceparser.cpp | 6 +- src/rendering/renderable.cpp | 6 +- src/rendering/renderengine.cpp | 11 +- src/util/spicemanager.cpp | 134 ++++----- src/util/time.cpp | 6 +- 17 files changed, 285 insertions(+), 255 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index 970f159ed9..21e9aa96f6 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 970f159ed93dd1f922b272a3344a93b4120c1616 +Subproject commit 21e9aa96f62fc7aea06dc61827db2acc8ad02024 diff --git a/include/openspace/util/spicemanager.h b/include/openspace/util/spicemanager.h index 909131a050..b3c73cd94f 100644 --- a/include/openspace/util/spicemanager.h +++ b/include/openspace/util/spicemanager.h @@ -66,12 +66,13 @@ public: * passed to absPath to convert a relative path to an absolute path * before usage * \return The loaded kernel's unique identifier that can be used to unload the kernel - * \throws SpiceKernelException If the loading of the kernel \p filePath failed - * \pre \p filePath is a non-empty absolute or relative path pointing to an - * existing file that contains a SPICE kernel + * \throws SpiceKernelException If the loading of the kernel \p filePath failed if, + * for example, \p filePath is not a valid SPICE kernel + * \pre \p filePath must not be empty. + * \pre \p filePath must be an absolute or relative path pointing to an existing file. * \post The kernel is loaded or has its reference counter incremented and the handle - * to the kernel is returned if the SPICE kernel is valid, or \a KernelInvalid if the - * kernel is invalid + * to the kernel is returned. The returned value is never equal to + * KernelHandle(0). * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/furnsh_c.html */ KernelHandle loadKernel(std::string filePath); @@ -82,9 +83,9 @@ public: * unload_c function. * \param kernelId The unique identifier that was returned from the call to * #loadKernel which loaded the kernel - * \pre \p kernelId must be a valid handle and cannot be equal to - * KernelHandle(0) - * \post The kernel identified by \p kernelId is unloaded + * \pre \p kernelId must be a valid handle. + * \pre \p kernelId cannot be equal to KernelHandle(0). + * \post The kernel identified by \p kernelId is unloaded. * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/unload_c.html */ void unloadKernel(KernelHandle kernelId); @@ -93,12 +94,11 @@ public: * Unloads a SPICE kernel identified by the \p filePath which was used in the * loading call to #loadKernel. The unloading is done by calling the * unload_c function. - * \param filePath The path of the kernel that should be unloaded. The filePath must - * have been previously used to successfully load a kernel, or a SpiceKernelException - * is thrown - * \pre \p filePath cannot be empty - * \post The kernel identified by \p filePath is unloaded or nothing happens if - * \p filePath was not used to load a kernel + * \param filePath The path of the kernel that should be unloaded. + * \throws SpiceKernelException If the \p filePath has not been previously used to + * successfully load a kernel. + * \pre \p filePath must not be empty. + * \post The kernel identified by \p filePath is unloaded. * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/unload_c.html */ void unloadKernel(std::string filePath); @@ -111,8 +111,8 @@ public: * \param et The time for which the coverage should be checked * \return true if SPK kernels have been loaded to cover \p target at the * time \p et, false otherwise. - * \pre \p target must be a non-empty string that names a valid SPICE object - * \throws SpiceKernelException If \p target is not a valid NAIF target + * \throws SpiceKernelException If \p target does not name a valid SPICE object + * \pre \p target must not be empty. */ bool hasSpkCoverage(const std::string& target, double et) const; @@ -124,7 +124,8 @@ public: * \param et The time for which the coverage should be checked * \return true if SPK kernels have been loaded to cover \p target at the * time \p et , false otherwise. - * \pre \p target must be a non-empty string that names a valid SPICE object + * \throws SpiceKernelException If \p target does not name a valid SPICE object + * \pre \p target must not be empty. * \throws SpiceKernelException If \p frame is not a valid frame */ bool hasCkCoverage(const std::string& frame, double et) const; @@ -146,9 +147,10 @@ public: * \param body The name of the body that should be sampled * \param item The item to find in the \p body * \return true if the function succeeded, false otherwise + * \throws SpiceKernelException If \p body does not name a valid SPICE object. + * \pre \p body must not be empty. + * \pre \item must not be empty. * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bodfnd_c.html - * \throws SpiceKernelException If \p body is not a valid type - * \pre \p body and \item must be non-empty and \p body must name a valid Spice object */ bool hasValue(const std::string& body, const std::string& item) const; @@ -158,8 +160,8 @@ public: * \param body The body name that should be retrieved * \return The ID of the body will be stored in this variable. The * value will only be changed if the retrieval was successful - * \throws SpiceKernelException If \p body is not a valid type - * \pre \p body must be not-empty + * \throws SpiceKernelException If \p body does not name a valid SPICE object. + * \pre \p body must not be empty. * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bods2c_c.html * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html */ @@ -171,7 +173,7 @@ public: * \param body The body for which the presence of a valid ID should be checked * \return true if the \p body has a NAIF ID, false * otherwise - * \pre \p body must be non-empty + * \pre \p body must not be empty. */ bool hasNaifId(const std::string& body) const; @@ -179,8 +181,8 @@ public: * Returns the NAIF ID for a specific frame using namfrm_c. * \param frame The frame name that should be retrieved * \return The NAIF ID of the \p frame - * \throws SpiceKernelException If \p frame is not a valid frame - * \pre \p frame must be not-empty + * \throws SpiceKernelException If \p frame is not a valid frame. + * \pre \p frame must not be empty. * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/namfrm_c.html */ int frameId(const std::string& frame) const; @@ -191,90 +193,109 @@ public: * \param frame The frame for which the presence of a valid ID should be checked * \return true if the \p frame has a NAIF ID, false * otherwise - * \pre \p frame must be non-empty + * \pre \p frame must not be empty. */ bool hasFrameId(const std::string& frame) const; /** - * Retrieves a single value for a certain body. This method - * succeeds iff body is the name of a valid body, value - * is a value associated with the body, and the value consists of only a single - * double value. If all conditions are true, the value is retrieved using - * the method bodvrd_c and stored in v - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bodvrd_c.html. If one of - * the conditions is false an error is logged and the value v is - * unchanged. For a description on NAIF IDs, see - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html. + * Retrieves a single \p value for a certain \p body. This method succeeds iff \p body + * is the name of a valid body, \p value is a value associated with the body, and the + * value consists of only a single double value. If all conditions are + * true, the value is retrieved using the method bodvrd_c and stored in + * \p v. * \param body The name of the body whose value should be retrieved or the NAIF ID of * this body - * \param value The value of that should be retrieved, this value is case-sensitive + * \param value The value that should be retrieved, this value is case-sensitive * \param v The destination for the retrieved value - * \return true if the body named a valid body, - * value is a valid item for the body and the retrieved - * value is only a single value. false otherwise + * \throws SpiceKernelException If the \p body does not name a valid body, \t value + * is not a valid item for the \p body or the retrieved value is not a single value. + * \pre \p body must not be empty. + * \pre \p value must not be empty. + * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bodvrd_c.html + * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html */ void getValue(const std::string& body, const std::string& value, double& v) const; /** - * Retrieves a value with three components for a certain - * body. This method succeeds iff body is the name of a - * valid body, value is a value associated with the body, and the value - * consists of three double values. If all conditions are true, the value - * is retrieved using the method bodvrd_c and stored in v - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bodvrd_c.html. If one of - * the conditions is false an error is logged and the value v is - * unchanged. For a description on NAIF IDs, see - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html. + * Retrieves a \p value with two components for a certain \p body. This method + * succeeds iff \p body is the name of a valid body, \p value is a value associated + * with the body, and the value consists of two double values. + * If all conditions are true, the value is retrieved using the method + * bodvrd_c and stored in \p v. * \param body The name of the body whose value should be retrieved or the NAIF ID of - * the body - * \param value The value of that should be retrieved, this value is case-sensitive - * \param v The destination for the retrieved values - * \return true if the body named a valid body, - * value is a valid item for the body and the retrieved - * value is only a single value. false otherwise + * this body + * \param value The value that should be retrieved, this value is case-sensitive + * \param v The destination for the retrieved value + * \throws SpiceKernelException If the \p body does not name a valid body, \t value + * is not a valid item for the \p body or the retrieved value is not a two-component + * value. + * \pre \p body must not be empty. + * \pre \p value must not be empty. + * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bodvrd_c.html + * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html + */ + void getValue(const std::string& body, const std::string& value, glm::dvec2& v) const; + + + /** + * Retrieves a \p value with three components for a certain \p body. This method + * succeeds iff \p body is the name of a valid body, \p value is a value associated + * with the body, and the value consists of three double values. + * If all conditions are true, the value is retrieved using the method + * bodvrd_c and stored in \p v. + * \param body The name of the body whose value should be retrieved or the NAIF ID of + * this body + * \param value The value that should be retrieved, this value is case-sensitive + * \param v The destination for the retrieved value + * \throws SpiceKernelException If the \p body does not name a valid body, \t value + * is not a valid item for the \p body or the retrieved value is not a three-component + * value. + * \pre \p body must not be empty. + * \pre \p value must not be empty. + * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bodvrd_c.html + * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html */ void getValue(const std::string& body, const std::string& value, glm::dvec3& v) const; /** - * Retrieves a value with four components for a certain - * body. This method succeeds iff body is the name of a - * valid body, value is a value associated with the body, and the value - * consists of four double values. If all conditions are true, the value - * is retrieved using the method bodvrd_c and stored in v - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bodvrd_c.html. If one of - * the conditions is false an error is logged and the value v is - * unchanged. For a description on NAIF IDs, see - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html. + * Retrieves a \p value with four components for a certain \p body. This method + * succeeds iff \p body is the name of a valid body, \p value is a value associated + * with the body, and the value consists of four double values. + * If all conditions are true, the value is retrieved using the method + * bodvrd_c and stored in \p v. * \param body The name of the body whose value should be retrieved or the NAIF ID of - * the body - * \param value The value of that should be retrieved, this value is case-sensitive - * \param v The destination for the retrieved values - * \return true if the body named a valid body, - * value is a valid item for the body and the retrieved - * value is only a single value. false otherwise + * this body + * \param value The value that should be retrieved, this value is case-sensitive + * \param v The destination for the retrieved value + * \throws SpiceKernelException If the \p body does not name a valid body, \t value + * is not a valid item for the \p body or the retrieved value is not a four-component + * value. + * \pre \p body must not be empty. + * \pre \p value must not be empty. + * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bodvrd_c.html + * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html */ void getValue(const std::string& body, const std::string& value, glm::dvec4& v) const; /** - * Retrieves a value with an arbitrary number of components for a certain - * body. This method succeeds body is a valid body, - * value is a value associated with the body, and the value consists of a - * number of double values. The requested number is equal to the - * size of the passed vector v which means that this vector - * has to be preallocated. If all conditions are true, the value is retrieved using - * the method bodvrd_c and stored in v - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bodvrd_c.html. If one of - * the conditions is false an error is logged and the value v is - * unchanged. For a description on NAIF IDs, see - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html. - * \param body The body whose information should be retrieved or the NAIF ID of that - * body - * \param value The value of that should be retrieved, this value is case-sensitive - * \param v The destination for the retrieved values. The size of this vector - * determines how many values will be retrieved - * \return true if the body named a valid body, - * value is a valid item for the body and the retrieved - * value is only a single value. false otherwise + * Retrieves a \p value with an arbitrary number of components for a certain \p body. + * This method succeeds iff \p body is the name of a valid body, \p value is a value + * associated with the body, and the value consists of the correct number of + * double values. If all conditions are true, the value is retrieved + * using the method bodvrd_c and stored in \p v. + * \param body The name of the body whose value should be retrieved or the NAIF ID of + * this body + * \param value The value that should be retrieved, this value is case-sensitive + * \param v The destination for the retrieved value. The vector must be + * preallocated to the correct size of components that should be retrieved + * \throws SpiceKernelException If the \p body does not name a valid body, \t value + * is not a valid item for the \p body or the retrieved value does not contain the + * correct number of components + * value. + * \pre \p body must not be empty. + * \pre \p value must not be empty. + * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bodvrd_c.html + * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html */ void getValue(const std::string& body, const std::string& value, std::vector& v) const; @@ -290,52 +311,42 @@ public: * available through all loaded kernels, if the craft is not supported by any of the * loaded kernel, or if the provided \p craftTicks is not a valid tick time for the * specific spacecraft - * \pre \craftIdCode may not be empty and need to name a valid craft + * \pre \craftIdCode must not be empty */ double spacecraftClockToET(const std::string& craft, double craftTicks); /** - * Converts the timeString representing a date to a double precision - * value representing the ephemerisTime; that is the number of TDB - * seconds past the J2000 epoch. For further details, please refer to - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/str2et_c.html. If an error - * occurs, an error is logged, the method returns false and the - * ephemerisTime remains unchanged. + * Converts the \p timeString representing a date to a double precision + * value representing the ephemeris time; that is the number of TDB + * seconds past the J2000 epoch. * \param timeString A string representing the time to be converted - * \param ephemerisTime The destination for the converted time; the number of TDB - * seconds past the J2000 epoch, representing the passed epochString - * \return true if the epochString is a valid string and - * the conversion succeeded, false otherwise + * \return The converted time; the number of TDB seconds past the J2000 epoch, + * representing the passed \p timeString + * \throws SpiceKernelException If \p timeString is not a valid timestring according + * to the str2et_c function (see the Particulars section of the linked + * webpage). + * \pre \t timeString must not be empty + * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/str2et_c.html */ - bool getETfromDate(const std::string& timeString, double& ephemerisTime) const; + double ephemerisTimeFromDate(const std::string& timeString) const; /** - * Converts the passed ephemerisTime into a human-readable - * date string with a specific format. For details on the - * formatting, refer to - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/timout_c.html. In case of - * an error, date will not be modified, an error will be logged and the - * method returns false. + * Converts the passed \p ephemerisTime into a human-readable date string with a + * specific \t format. * \param ephemerisTime The ephemeris time, that is the number of TDB seconds past the * J2000 epoch - * \param date The destination for the converted date. This will only be changed if - * the conversion succeeded - * \param format The format string describing the output format for the - * date - * \return true if the conversion succeeded, false otherwise + * \param format The format string describing the output format + * \return The destination for the converted date. + * \pre \t format must not be empty + * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/timout_c.html */ - bool getDateFromET(double ephemerisTime, std::string& date, - const std::string& format = "YYYY MON DDTHR:MN:SC.### ::RND") const; - + std::string dateFromEphemerisTime(double ephemerisTime, + const std::string& formatString = "YYYY MON DDTHR:MN:SC.### ::RND") const; /** - * Returns the position of a target body relative to an - * observer in a specific referenceFrame, optionally - * corrected for light time (planetary aberration) and stellar aberration - * (aberrationCorrection). For further details, refer to - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/spkpos_c.html. For more - * information on NAIF IDs, refer to - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html + * Returns the \t position of a \t target body relative to an \t observer in a + * specific \t referenceFrame, optionally corrected for \t lightTime (planetary + * aberration) and stellar aberration (\t aberrationCorrection). * \param target The target body name or the target body's NAIF ID * \param observer The observing body name or the observing body's NAIF ID * \param referenceFrame The reference frame of the output position vector @@ -351,6 +362,8 @@ public: * observer and the target. If the method fails, the lightTime is unchanged * \return true if the function was successful, false * otherwise + * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/spkpos_c.html + * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html */ bool getTargetPosition(const std::string& target, const std::string& observer, @@ -359,15 +372,6 @@ public: double ephemerisTime, glm::dvec3& position, double& lightTime) const; - - bool getTargetPosition(const std::string& target, - const std::string& observer, - const std::string& referenceFrame, - const std::string& aberrationCorrection, - double ephemerisTime, - psc& position, - double& lightTime) const; - /** * If a position is requested for an uncovered time in the SPK kernels, * this function will insert a position in modelPosition. diff --git a/modules/base/rendering/renderablemodel.cpp b/modules/base/rendering/renderablemodel.cpp index 4fb5c67ee5..964c5bc4bf 100644 --- a/modules/base/rendering/renderablemodel.cpp +++ b/modules/base/rendering/renderablemodel.cpp @@ -183,8 +183,9 @@ void RenderableModel::render(const RenderData& data) { else _alpha = 1.0f; - psc tmppos; - SpiceManager::ref().getTargetPosition(_target, "SUN", "GALACTIC", "NONE", time, tmppos, lt); + glm::dvec3 p; + SpiceManager::ref().getTargetPosition(_target, "SUN", "GALACTIC", "NONE", time, p, lt); + psc tmppos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); glm::vec3 cam_dir = glm::normalize(data.camera.position().vec3() - tmppos.vec3()); _programObject->setUniform("cam_dir", cam_dir); _programObject->setUniform("transparency", _alpha); @@ -245,7 +246,9 @@ void RenderableModel::update(const UpdateData& data) { openspace::SpiceManager::ref().getPositionTransformMatrix(_source, _destination, _time, _stateMatrix); double lt; - openspace::SpiceManager::ref().getTargetPosition("SUN", _target, "GALACTIC", "NONE", _time, _sunPosition, lt); + glm::dvec3 p; + openspace::SpiceManager::ref().getTargetPosition("SUN", _target, "GALACTIC", "NONE", _time, p, lt); + _sunPosition = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); } void RenderableModel::loadTexture() { diff --git a/modules/base/rendering/renderablepath.cpp b/modules/base/rendering/renderablepath.cpp index 300b34ecbf..fc257a2074 100644 --- a/modules/base/rendering/renderablepath.cpp +++ b/modules/base/rendering/renderablepath.cpp @@ -109,9 +109,8 @@ bool RenderablePath::initialize() { bool intervalSet = hasTimeInterval(); if (intervalSet) { getInterval(_start, _stop); - std::string stop, start; - SpiceManager::ref().getDateFromET(_start, start); - SpiceManager::ref().getDateFromET(_stop, stop); + std::string start = SpiceManager::ref().dateFromEphemerisTime(_start); + std::string stop = SpiceManager::ref().dateFromEphemerisTime(_stop); } return completeSuccess; @@ -215,15 +214,17 @@ void RenderablePath::calculatePath(std::string observer) { double lightTime; // bool correctPosition = true; - psc pscPos; double currentTime = _start; _vertexArray.resize(segments); + psc pscPos; //float r, g, b; //float g = _lineColor[1]; //float b = _lineColor[2]; for (int i = 0; i < segments; i++) { - SpiceManager::ref().getTargetPosition(_target, observer, _frame, "NONE", currentTime, pscPos, lightTime); + glm::dvec3 p; + SpiceManager::ref().getTargetPosition(_target, observer, _frame, "NONE", currentTime, p, lightTime); + pscPos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); pscPos[3] += 3; //if (!correctPosition) { diff --git a/modules/base/rendering/renderableplanet.cpp b/modules/base/rendering/renderableplanet.cpp index 19f03e4c37..ee14c7fcbc 100644 --- a/modules/base/rendering/renderableplanet.cpp +++ b/modules/base/rendering/renderableplanet.cpp @@ -180,9 +180,11 @@ void RenderablePlanet::render(const RenderData& data) //glm::mat4 modelview = data.camera.viewMatrix()*data.camera.modelMatrix(); //glm::vec3 camSpaceEye = (-(modelview*data.position.vec4())).xyz; - psc sun_pos; + double lt; - openspace::SpiceManager::ref().getTargetPosition("SUN", _target, "GALACTIC", "NONE", _time, sun_pos, lt); + glm::dvec3 p; + openspace::SpiceManager::ref().getTargetPosition("SUN", _target, "GALACTIC", "NONE", _time, p, lt); + psc sun_pos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); // setup the data to the shader // _programObject->setUniform("camdir", camSpaceEye); diff --git a/modules/base/rendering/renderabletrail.cpp b/modules/base/rendering/renderabletrail.cpp index e9bdfa2e25..9abb87ad63 100644 --- a/modules/base/rendering/renderabletrail.cpp +++ b/modules/base/rendering/renderabletrail.cpp @@ -201,7 +201,6 @@ void RenderableTrail::update(const UpdateData& data) { if (_programObject->isDirty()) _programObject->rebuildFromFile(); double lightTime = 0.0; - psc pscPos; bool intervalSet = hasTimeInterval(); double start = DBL_MIN; @@ -217,13 +216,17 @@ void RenderableTrail::update(const UpdateData& data) { double deltaTime = std::abs(data.time - _oldTime); int nValues = static_cast(floor(deltaTime / _increment)); + glm::dvec3 p; // Update the floating current time if (start > data.time) - SpiceManager::ref().getTargetPosition(_target, _observer, _frame, "NONE", start, pscPos, lightTime); + SpiceManager::ref().getTargetPosition(_target, _observer, _frame, "NONE", start, p, lightTime); else if (end < data.time) - SpiceManager::ref().getTargetPosition(_target, _observer, _frame, "NONE", end, pscPos, lightTime); + SpiceManager::ref().getTargetPosition(_target, _observer, _frame, "NONE", end, p, lightTime); else - SpiceManager::ref().getTargetPosition(_target, _observer, _frame, "NONE", data.time, pscPos, lightTime); + SpiceManager::ref().getTargetPosition(_target, _observer, _frame, "NONE", data.time, p, lightTime); + + psc pscPos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); + pscPos[3] += 3; // KM to M _vertexArray[0] = { pscPos[0], pscPos[1], pscPos[2], pscPos[3] }; @@ -243,7 +246,9 @@ void RenderableTrail::update(const UpdateData& data) { et = start; else if (end < et) et = end; - SpiceManager::ref().getTargetPosition(_target, _observer, _frame, "NONE", et, pscPos, lightTime); + glm::dvec3 p; + SpiceManager::ref().getTargetPosition(_target, _observer, _frame, "NONE", et, p, lightTime); + pscPos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); pscPos[3] += 3; _vertexArray[i] = { pscPos[0], pscPos[1], pscPos[2], pscPos[3] }; } @@ -283,7 +288,6 @@ void RenderableTrail::fullYearSweep(double time) { _oldTime = time; - psc pscPos; _vertexArray.resize(segments+2); for (int i = 0; i < segments+2; i++) { if (start > time && intervalSet) { @@ -293,7 +297,9 @@ void RenderableTrail::fullYearSweep(double time) { time = end; } - SpiceManager::ref().getTargetPosition(_target, _observer, _frame, "NONE", time, pscPos, lightTime); + glm::dvec3 p; + SpiceManager::ref().getTargetPosition(_target, _observer, _frame, "NONE", time, p, lightTime); + psc pscPos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); pscPos[3] += 3; _vertexArray[i] = {pscPos[0], pscPos[1], pscPos[2], pscPos[3]}; diff --git a/modules/newhorizons/rendering/renderablefov.cpp b/modules/newhorizons/rendering/renderablefov.cpp index 0059a4ec2a..aa501b5e7b 100644 --- a/modules/newhorizons/rendering/renderablefov.cpp +++ b/modules/newhorizons/rendering/renderablefov.cpp @@ -446,7 +446,7 @@ void RenderableFov::computeIntercepts(const RenderData& data){ fovSurfaceIntercept(_interceptTag, _bounds); glm::vec3 aim = (_spacecraftRotation * glm::vec4(_boresight, 1)).xyz(); - psc position; + glm::dvec3 position; SpiceManager::ref().getTargetPosition(_fovTarget, _spacecraft, _frame, @@ -454,13 +454,14 @@ void RenderableFov::computeIntercepts(const RenderData& data){ _time, position, _lt); - pss length = position.length(); + psc p = PowerScaledCoordinate::CreatePowerScaledCoordinate(position.x, position.y, position.z); + pss length = p.length(); if (length[0] < DBL_EPSILON) { _drawFOV = false; return; } //if aimed 80 deg away from target, dont draw white square - if (glm::dot(glm::normalize(aim), glm::normalize(position.vec3())) < 0.2){ + if (glm::dot(glm::normalize(aim), glm::normalize(p.vec3())) < 0.2){ _drawFOV = false; } } diff --git a/modules/newhorizons/rendering/renderablemodelprojection.cpp b/modules/newhorizons/rendering/renderablemodelprojection.cpp index 2214121792..12725cb38c 100644 --- a/modules/newhorizons/rendering/renderablemodelprojection.cpp +++ b/modules/newhorizons/rendering/renderablemodelprojection.cpp @@ -354,7 +354,9 @@ void RenderableModelProjection::update(const UpdateData& data) { openspace::SpiceManager::ref().getPositionTransformMatrix(_source, _destination, _time, _stateMatrix); double lt; - openspace::SpiceManager::ref().getTargetPosition("SUN", _target, "GALACTIC", "NONE", _time, _sunPosition, lt); + glm::dvec3 p; + openspace::SpiceManager::ref().getTargetPosition("SUN", _target, "GALACTIC", "NONE", _time, p, lt); + _sunPosition = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); } void RenderableModelProjection::imageProjectGPU() { @@ -427,8 +429,9 @@ void RenderableModelProjection::attitudeParameters(double time) { return; double lightTime; - psc position; //observer target - found = SpiceManager::ref().getTargetPosition(_projectorID, _projecteeID, _destination, _aberration, time, position, lightTime); + glm::dvec3 p; + found = SpiceManager::ref().getTargetPosition(_projectorID, _projecteeID, _destination, _aberration, time, p, lightTime); + psc position = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); position[3] += (3 + _camScaling[1]); glm::vec3 cpos = position.vec3(); diff --git a/modules/newhorizons/rendering/renderableplaneprojection.cpp b/modules/newhorizons/rendering/renderableplaneprojection.cpp index d4d335b881..c3a037988e 100644 --- a/modules/newhorizons/rendering/renderableplaneprojection.cpp +++ b/modules/newhorizons/rendering/renderableplaneprojection.cpp @@ -321,9 +321,10 @@ std::string RenderablePlaneProjection::findClosestTarget(double currentTime) { std::string closestTarget = ""; - psc spacecraftPos; + glm::dvec3 p; double lt; - SpiceManager::ref().getTargetPosition(_spacecraft, "SSB", GalacticFrame, "NONE", currentTime, spacecraftPos, lt); + SpiceManager::ref().getTargetPosition(_spacecraft, "SSB", GalacticFrame, "NONE", currentTime, p, lt); + psc spacecraftPos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); for (auto node : nodes) diff --git a/modules/newhorizons/rendering/renderableplanetprojection.cpp b/modules/newhorizons/rendering/renderableplanetprojection.cpp index 7f3ee36aa1..3e1fe3805d 100644 --- a/modules/newhorizons/rendering/renderableplanetprojection.cpp +++ b/modules/newhorizons/rendering/renderableplanetprojection.cpp @@ -430,8 +430,9 @@ void RenderablePlanetProjection::attitudeParameters(double time){ if (!found) return ; - psc position; //observer target - found = SpiceManager::ref().getTargetPosition(_projectorID, _projecteeID, _mainFrame, _aberration, time, position, lightTime); + glm::dvec3 p; + found = SpiceManager::ref().getTargetPosition(_projectorID, _projecteeID, _mainFrame, _aberration, time, p, lightTime); + psc position = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); //change to KM and add psc camera scaling. position[3] += (3 + _camScaling[1]); @@ -508,9 +509,10 @@ void RenderablePlanetProjection::render(const RenderData& data){ attitudeParameters(_time); _imageTimes.clear(); - psc sun_pos; double lt; - openspace::SpiceManager::ref().getTargetPosition("SUN", _projecteeID, "GALACTIC", "NONE", _time, sun_pos, lt); + glm::dvec3 p; + openspace::SpiceManager::ref().getTargetPosition("SUN", _projecteeID, "GALACTIC", "NONE", _time, p, lt); + psc sun_pos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); // Main renderpass _programObject->activate(); diff --git a/modules/newhorizons/util/hongkangparser.cpp b/modules/newhorizons/util/hongkangparser.cpp index f85cac48e3..04be8da049 100644 --- a/modules/newhorizons/util/hongkangparser.cpp +++ b/modules/newhorizons/util/hongkangparser.cpp @@ -99,20 +99,18 @@ void HongKangParser::findPlaybookSpecifiedTarget(std::string line, std::string& } void HongKangParser::writeUTCEventFile(const Image image){ - std::string time_beg; - std::string time_end; - SpiceManager::ref().getDateFromET(image.startTime, time_beg); - SpiceManager::ref().getDateFromET(image.stopTime, time_end, "HR:MN:SC.### ::RND"); + std::string time_beg = SpiceManager::ref().dateFromEphemerisTime(image.startTime); + std::string time_end = SpiceManager::ref().dateFromEphemerisTime(image.stopTime); - _eventsAsUTCFile << std::fixed - << std::setw(10) << time_beg << "->" - << std::setw(10) << time_end - << std::setw(10) << (int)getMetFromET(image.startTime) << "->" - << std::setw(10) << (int)getMetFromET(image.stopTime) - << std::setw(10) << image.target << std::setw(10); - for (auto instrument : image.activeInstruments){ - _eventsAsUTCFile << " " << instrument; - } + _eventsAsUTCFile << std::fixed + << std::setw(10) << time_beg << "->" + << std::setw(10) << time_end + << std::setw(10) << (int)getMetFromET(image.startTime) << "->" + << std::setw(10) << (int)getMetFromET(image.stopTime) + << std::setw(10) << image.target << std::setw(10); + for (auto instrument : image.activeInstruments){ + _eventsAsUTCFile << " " << instrument; + } } bool HongKangParser::create(){ @@ -324,8 +322,8 @@ double HongKangParser::getETfromMet(std::string line){ double HongKangParser::getETfromMet(double met){ double diff; - double referenceET; - openspace::SpiceManager::ref().getETfromDate("2015-07-14T11:50:00.00", referenceET); + double referenceET = + SpiceManager::ref().ephemerisTimeFromDate("2015-07-14T11:50:00.00"); double et = referenceET; //_metRef += 3; // MET reference time is off by 3 sec? @@ -342,8 +340,8 @@ double HongKangParser::getETfromMet(double met){ double HongKangParser::getMetFromET(double et){ double met; - double referenceET; - openspace::SpiceManager::ref().getETfromDate("2015-07-14T11:50:00.00", referenceET); + double referenceET = + SpiceManager::ref().ephemerisTimeFromDate("2015-07-14T11:50:00.00"); if (et >= referenceET){ met = _metRef + (et - referenceET); diff --git a/modules/newhorizons/util/labelparser.cpp b/modules/newhorizons/util/labelparser.cpp index 7a8ef3047c..bf9abb39ce 100644 --- a/modules/newhorizons/util/labelparser.cpp +++ b/modules/newhorizons/util/labelparser.cpp @@ -204,7 +204,7 @@ bool LabelParser::create() { if (read == "START_TIME"){ std::string start = line.substr(line.find("=") + 2); start.erase(std::remove(start.begin(), start.end(), ' '), start.end()); - openspace::SpiceManager::ref().getETfromDate(start, _startTime); + _startTime = SpiceManager::ref().ephemerisTimeFromDate(start); count++; getline(file, line); @@ -219,7 +219,7 @@ bool LabelParser::create() { ), stop.end() ); - openspace::SpiceManager::ref().getETfromDate(stop, _stopTime); + _stopTime = SpiceManager::ref().ephemerisTimeFromDate(stop); count++; } else{ diff --git a/modules/newhorizons/util/sequenceparser.cpp b/modules/newhorizons/util/sequenceparser.cpp index af2842092b..114befdb4c 100644 --- a/modules/newhorizons/util/sequenceparser.cpp +++ b/modules/newhorizons/util/sequenceparser.cpp @@ -131,10 +131,8 @@ void SequenceParser::sendPlaybookInformation(const std::string& name) { writeToBuffer(buffer, currentWriteLocation, image.startTime); writeToBuffer(buffer, currentWriteLocation, image.stopTime); - std::string timeBegin; - std::string timeEnd; - SpiceManager::ref().getDateFromET(image.startTime, timeBegin); - SpiceManager::ref().getDateFromET(image.stopTime, timeEnd); + std::string timeBegin = SpiceManager::ref().dateFromEphemerisTime(image.startTime); + std::string timeEnd = SpiceManager::ref().dateFromEphemerisTime(image.stopTime); writeToBuffer(buffer, currentWriteLocation, timeBegin); writeToBuffer(buffer, currentWriteLocation, timeEnd); diff --git a/src/rendering/renderable.cpp b/src/rendering/renderable.cpp index 7de7c556e4..31d1d1e66a 100644 --- a/src/rendering/renderable.cpp +++ b/src/rendering/renderable.cpp @@ -136,9 +136,9 @@ bool Renderable::hasBody() { bool Renderable::getInterval(double& start, double& end) { if (_startTime != "" && _endTime != "") { - bool successStart = openspace::SpiceManager::ref().getETfromDate(_startTime, start); - bool successEnd = openspace::SpiceManager::ref().getETfromDate(_endTime, end); - return successStart && successEnd; + start = SpiceManager::ref().ephemerisTimeFromDate(_startTime); + end = SpiceManager::ref().ephemerisTimeFromDate(_endTime); + return true; } else return false; diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 6e440b9c70..f5b7326fa3 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -451,9 +451,10 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi glm::vec4 targetColor(0.00, 0.75, 1.00, 1); - psc nhPos; double lt; - SpiceManager::ref().getTargetPosition("PLUTO", "NEW HORIZONS", "GALACTIC", "NONE", currentTime, nhPos, lt); + glm::dvec3 p; + SpiceManager::ref().getTargetPosition("PLUTO", "NEW HORIZONS", "GALACTIC", "NONE", currentTime, p, lt); + psc nhPos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); float a, b, c; SpiceManager::ref().getPlanetEllipsoid("PLUTO", a, b, c); float radius = (a + b) / 2.f; @@ -478,8 +479,10 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi for (int i = 0; i < 25 - g; i++) progress.append(" "); - std::string str = ""; - openspace::SpiceManager::ref().getDateFromET(openspace::ImageSequencer2::ref().getNextCaptureTime(), str, "YYYY MON DD HR:MN:SC"); + std::string str = SpiceManager::ref().dateFromEphemerisTime( + ImageSequencer2::ref().getNextCaptureTime(), + "YYYY MON DD HR:MN:SC" + ); glm::vec4 active(0.6, 1, 0.00, 1); glm::vec4 brigther_active(0.9, 1, 0.75, 1); diff --git a/src/util/spicemanager.cpp b/src/util/spicemanager.cpp index 71369b59c8..4c7effc223 100644 --- a/src/util/spicemanager.cpp +++ b/src/util/spicemanager.cpp @@ -179,8 +179,11 @@ void SpiceManager::unloadKernel(string filePath) { auto it = std::find_if(_loadedKernels.begin(), _loadedKernels.end(), [&path](const KernelInformation& info) { return info.path == path; }); - if (it == _loadedKernels.end()) - throw SpiceKernelException("Kernel unloading failed"); + if (it == _loadedKernels.end()) { + throw SpiceKernelException( + format("'{}' did not correspond to a loaded kernel", path) + ); + } else { // If there was only one part interested in the kernel, we can unload it if (it->refCount == 1) { @@ -256,6 +259,7 @@ bool SpiceManager::hasNaifId(const string& body) const { SpiceBoolean success; int id; bods2c_c(body.c_str(), &id, &success); + reset_c(); return success; } @@ -287,14 +291,24 @@ void getValueInternal(const string& body, const string& value, int size, SpiceInt n; bodvrd_c(body.c_str(), value.c_str(), size, &n, v); - throwOnSpiceError("Error getting value '" + value + - "' for body '" + body + "'"); + throwOnSpiceError( + format("Error getting value '{}' for body '{}'", + value, + body + ) + ); } void SpiceManager::getValue(const string& body, const string& value, double& v) const { getValueInternal(body, value, 1, &v); } +void SpiceManager::getValue(const string& body, const string& value, + glm::dvec2& v) const +{ + getValueInternal(body, value, 2, glm::value_ptr(v)); +} + void SpiceManager::getValue(const string& body, const string& value, glm::dvec3& v) const { @@ -311,11 +325,13 @@ void SpiceManager::getValue(const string& body, const string& value, std::vector& v) const { ghoul_assert(!v.empty(), "Array for values has to be preallocaed"); + getValueInternal(body, value, v.size(), v.data()); } double SpiceManager::spacecraftClockToET(const string& craft, double craftTicks) { ghoul_assert(!craft.empty(), "Empty craft"); + int craftId = naifId(craft); double et; sct2e_c(craftId, craftTicks, &et); @@ -326,38 +342,32 @@ double SpiceManager::spacecraftClockToET(const string& craft, double craftTicks) return et; } -bool SpiceManager::getETfromDate(const std::string& timeString, - double& ephemerisTime) const -{ - if (timeString.empty()) { - LERROR("No time string was provided"); - return false; - } - - str2et_c(timeString.c_str(), &ephemerisTime); - throwOnSpiceError("Error converting date '" + timeString + "'"); - return true; +double SpiceManager::ephemerisTimeFromDate(const std::string& timeString) const { + ghoul_assert(!timeString.empty(), "Empty timeString"); + + double et; + str2et_c(timeString.c_str(), &et); + throwOnSpiceError(format("Error converting date '{}'", timeString)); + return et; } -bool SpiceManager::getDateFromET(double ephemerisTime, std::string& date, - const std::string& format) const +string SpiceManager::dateFromEphemerisTime(double ephemerisTime, + const string& formatString) const { - static const int BufferSize = 256; + ghoul_assert(!formatString.empty(), "Format is empty"); - if (format.empty()) { - LERROR("No format string was provided for the date conversion"); - return false; - } - SpiceChar buffer[BufferSize]; - - timout_c(ephemerisTime, format.c_str(), BufferSize - 1, buffer); - throwOnSpiceError("Error converting ephemeris time '" + - std::to_string(ephemerisTime) + - "' to date with format '" + format + "'" + static const int BufferSize = 256; + SpiceChar buffer[BufferSize]; + timout_c(ephemerisTime, formatString.c_str(), BufferSize - 1, buffer); + throwOnSpiceError( + format("Error converting ephemeris time '{}' to date with format '{}'", + ephemerisTime, + formatString + ) ); - - date = std::string(buffer); - return true; + + return std::string(buffer); + } bool SpiceManager::getTargetPosition(const std::string& target, @@ -396,37 +406,37 @@ bool SpiceManager::getTargetPosition(const std::string& target, return targetHasCoverage && observerHasCoverage; } -bool SpiceManager::getTargetPosition(const std::string& target, - const std::string& observer, - const std::string& referenceFrame, - const std::string& aberrationCorrection, - double ephemerisTime, - psc& position, - double& lightTime) const -{ - double pos[3] = { 0.0, 0.0, 0.0}; - - bool targetHasCoverage = hasSpkCoverage(target, ephemerisTime); - bool observerHasCoverage = hasSpkCoverage(observer, ephemerisTime); - if (!targetHasCoverage && !observerHasCoverage){ - position = PowerScaledCoordinate::CreatePowerScaledCoordinate(pos[0], pos[1], pos[2]); - return false; - } - else if (targetHasCoverage && observerHasCoverage){ - spkpos_c(target.c_str(), ephemerisTime, referenceFrame.c_str(), - aberrationCorrection.c_str(), observer.c_str(), pos, &lightTime); - position = PowerScaledCoordinate::CreatePowerScaledCoordinate(pos[0], pos[1], pos[2]); - } - else if (targetHasCoverage) {// observer has no coverage - getEstimatedPosition(ephemerisTime, observer, target, position); - position = position*(-1.f); // inverse estimated position because the observer is "target" argument in funciton - } - else {// target has no coverage - getEstimatedPosition(ephemerisTime, target, observer, position); - } - - return targetHasCoverage && observerHasCoverage; -} +//bool SpiceManager::getTargetPosition(const std::string& target, +// const std::string& observer, +// const std::string& referenceFrame, +// const std::string& aberrationCorrection, +// double ephemerisTime, +// psc& position, +// double& lightTime) const +//{ +// double pos[3] = { 0.0, 0.0, 0.0}; +// +// bool targetHasCoverage = hasSpkCoverage(target, ephemerisTime); +// bool observerHasCoverage = hasSpkCoverage(observer, ephemerisTime); +// if (!targetHasCoverage && !observerHasCoverage){ +// position = PowerScaledCoordinate::CreatePowerScaledCoordinate(pos[0], pos[1], pos[2]); +// return false; +// } +// else if (targetHasCoverage && observerHasCoverage){ +// spkpos_c(target.c_str(), ephemerisTime, referenceFrame.c_str(), +// aberrationCorrection.c_str(), observer.c_str(), pos, &lightTime); +// position = PowerScaledCoordinate::CreatePowerScaledCoordinate(pos[0], pos[1], pos[2]); +// } +// else if (targetHasCoverage) {// observer has no coverage +// getEstimatedPosition(ephemerisTime, observer, target, position); +// position = position*(-1.f); // inverse estimated position because the observer is "target" argument in funciton +// } +// else {// target has no coverage +// getEstimatedPosition(ephemerisTime, target, observer, position); +// } +// +// return targetHasCoverage && observerHasCoverage; +//} bool SpiceManager::getEstimatedPosition(const double time, const std::string target, const std::string observer, psc& targetPosition) const diff --git a/src/util/time.cpp b/src/util/time.cpp index 362d6ecc33..cba7e17bb5 100644 --- a/src/util/time.cpp +++ b/src/util/time.cpp @@ -117,14 +117,12 @@ bool Time::togglePause() { } void Time::setTime(std::string time, bool requireJump) { - SpiceManager::ref().getETfromDate(std::move(time), _time); + _time = SpiceManager::ref().ephemerisTimeFromDate(std::move(time)); _timeJumped = requireJump; } std::string Time::currentTimeUTC() const { - std::string date; - SpiceManager::ref().getDateFromET(_syncedTime, date); - return date; + return SpiceManager::ref().dateFromEphemerisTime(_syncedTime); } void Time::serialize(SyncBuffer* syncBuffer){ From 16897bb8d4e0af838ae7777898bf51f85b953d71 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Thu, 19 Nov 2015 15:33:57 -0500 Subject: [PATCH 040/122] Make the aberration correction specification for targetPosition in SpiceManager explicit by including a seprate class for it --- ext/ghoul | 2 +- include/openspace/util/spicemanager.h | 103 ++++++++++++++---- modules/base/ephemeris/spiceephemeris.cpp | 5 +- modules/base/rendering/renderablemodel.cpp | 8 +- modules/base/rendering/renderablepath.cpp | 4 +- modules/base/rendering/renderableplanet.cpp | 4 +- modules/base/rendering/renderabletrail.cpp | 23 ++-- .../newhorizons/rendering/renderablefov.cpp | 13 ++- modules/newhorizons/rendering/renderablefov.h | 3 +- .../rendering/renderablemodelprojection.cpp | 19 ++-- .../rendering/renderablemodelprojection.h | 3 +- .../rendering/renderableplaneprojection.cpp | 16 ++- .../rendering/renderableplanetprojection.cpp | 11 +- .../rendering/renderableplanetprojection.h | 3 +- .../rendering/renderableshadowcylinder.cpp | 8 +- .../rendering/renderableshadowcylinder.h | 3 +- src/rendering/renderengine.cpp | 4 +- src/util/spicemanager.cpp | 87 ++++++++++++--- 18 files changed, 227 insertions(+), 92 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index 21e9aa96f6..5c11a98058 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 21e9aa96f62fc7aea06dc61827db2acc8ad02024 +Subproject commit 5c11a98058a10078c7802006563a9d8989bd7e27 diff --git a/include/openspace/util/spicemanager.h b/include/openspace/util/spicemanager.h index b3c73cd94f..3be9fa982e 100644 --- a/include/openspace/util/spicemanager.h +++ b/include/openspace/util/spicemanager.h @@ -57,6 +57,64 @@ public: explicit SpiceKernelException(const std::string& msg); }; + /** + * Specifies the aberration correction method for the #targetPosition function. + * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/spkpos_c.html + */ + class AberrationCorrection { + public: + /// The type of the aberration correction + enum class Type { + None = 0, ///< No correction (NONE) + LightTime, ///< One-way light time (LT) + LightTimeStellar, ///< One-way light time and stellar (LT+S) + ConvergedNewtonian, ///< Converged newtonian light time (CN) + ConvergedNewtonianStellar ///< Converged newtonian + stellar (CN+S) + }; + /// The direction of the aberration correct + enum class Direction { + Reception = 0, + Transmission + }; + + /** + * Default constructor initializing the AberrationCorrection to Type::None with a + * Drection::Reception + */ + AberrationCorrection() = default; + + /** + * Constructor initializing the AberrationCorrection to the provided \p type and + * \p direction + * \param type The type of the aberration correction (AberrationCorrection::Type) + * \param direction The used direction (AberrationCorrection::Direction) + */ + AberrationCorrection(Type type, Direction direction); + + /** + * Converts one of the valid aberration correction strings into its enumeration + * format. The valid strings are: + * NONE, LT, LT+S, CN, + * CN+S, XLT, XLT+S, XCN, and + * XCN+S. + * \param identifier The identifier that should be converted into the enumeration + * Type and Direction + * \pre The \p identifier must not be empty and be of one of the valid strings + */ + explicit AberrationCorrection(const std::string& identifier); + + /** + * Returns the string representation of this Aberration Correction + * \return The string representation of this Aberration correction + */ + operator std::string() const; + + /// The type of aberration correction + Type type = Type::None; + /// The direction of the aberration correction + Direction direction = Direction::Reception; + }; + /** * Loads one or more SPICE kernels into a program. The provided path can either be a * binary, text-kernel, or meta-kernel which gets loaded into the kernel pool. The @@ -344,34 +402,37 @@ public: const std::string& formatString = "YYYY MON DDTHR:MN:SC.### ::RND") const; /** - * Returns the \t position of a \t target body relative to an \t observer in a - * specific \t referenceFrame, optionally corrected for \t lightTime (planetary - * aberration) and stellar aberration (\t aberrationCorrection). + * Returns the \p position of a \p target body relative to an \p observer in a + * specific \p referenceFrame, optionally corrected for \p lightTime (planetary + * aberration) and stellar aberration (\p aberrationCorrection). * \param target The target body name or the target body's NAIF ID * \param observer The observing body name or the observing body's NAIF ID * \param referenceFrame The reference frame of the output position vector - * \param aberrationCorrection The aberration correction flag out of the list of - * values (NONE, LT, LT+S, CN, - * CN+S for the reception case or XLT, XLT+S, - * XCN, or XCN+S for the transmission case. + * \param aberrationCorrection The aberration correction used for the position + * calculation * \param ephemerisTime The time at which the position is to be queried - * \param position The output containing the position of the target; if the method - * fails, the target position is unchanged - * \param lightTime If the aberrationCorrection is different from - * NONE, this variable will contain the one-way light time between the - * observer and the target. If the method fails, the lightTime is unchanged - * \return true if the function was successful, false - * otherwise + * \param lightTime If the \p aberrationCorrection is different from + * AbberationCorrection::Type::None, this variable will contain the light time between + * the observer and the target. + * \return The position of the \p target relative to the \p observer in the specified + * \p referenceFrame + * \throws SpiceKernelException If the \p target or \p observer do not name a valid + * NAIF object, \p referenceFrame does not name a valid reference frame or if there is + * not sufficient data available to compute the position or neither the target nor the + * observer have coverage. + * \pre \p target must not be empty + * \pre \p observer must not be empty + * \pre \p referenceFrame must not be empty + * \post If an exception is thrown, \p lightTime will not be modified * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/spkpos_c.html * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html */ - bool getTargetPosition(const std::string& target, - const std::string& observer, - const std::string& referenceFrame, - const std::string& aberrationCorrection, - double ephemerisTime, - glm::dvec3& position, - double& lightTime) const; + glm::dvec3 targetPosition(const std::string& target, + const std::string& observer, + const std::string& referenceFrame, + AberrationCorrection abberationCorrection, + double ephemerisTime, + double& lightTime) const; /** * If a position is requested for an uncovered time in the SPK kernels, * this function will insert a position in modelPosition. diff --git a/modules/base/ephemeris/spiceephemeris.cpp b/modules/base/ephemeris/spiceephemeris.cpp index b4ec10e344..85e12f474f 100644 --- a/modules/base/ephemeris/spiceephemeris.cpp +++ b/modules/base/ephemeris/spiceephemeris.cpp @@ -81,10 +81,9 @@ void SpiceEphemeris::update(const UpdateData& data) { if (!_kernelsLoadedSuccessfully) return; - glm::dvec3 position(0,0,0); double lightTime = 0.0; - SpiceManager::ref().getTargetPosition(_targetName, _originName, - "GALACTIC", "NONE", data.time, position, lightTime); + glm::dvec3 position = SpiceManager::ref().targetPosition(_targetName, _originName, + "GALACTIC", SpiceManager::AberrationCorrection(), data.time, lightTime); //double interval = openspace::ImageSequencer2::ref().getIntervalLength(); //if (_ghosting == "TRUE" && interval > 60){ diff --git a/modules/base/rendering/renderablemodel.cpp b/modules/base/rendering/renderablemodel.cpp index 964c5bc4bf..d76787cf3b 100644 --- a/modules/base/rendering/renderablemodel.cpp +++ b/modules/base/rendering/renderablemodel.cpp @@ -183,8 +183,8 @@ void RenderableModel::render(const RenderData& data) { else _alpha = 1.0f; - glm::dvec3 p; - SpiceManager::ref().getTargetPosition(_target, "SUN", "GALACTIC", "NONE", time, p, lt); + glm::dvec3 p = + SpiceManager::ref().targetPosition(_target, "SUN", "GALACTIC", SpiceManager::AberrationCorrection(), time, lt); psc tmppos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); glm::vec3 cam_dir = glm::normalize(data.camera.position().vec3() - tmppos.vec3()); _programObject->setUniform("cam_dir", cam_dir); @@ -246,8 +246,8 @@ void RenderableModel::update(const UpdateData& data) { openspace::SpiceManager::ref().getPositionTransformMatrix(_source, _destination, _time, _stateMatrix); double lt; - glm::dvec3 p; - openspace::SpiceManager::ref().getTargetPosition("SUN", _target, "GALACTIC", "NONE", _time, p, lt); + glm::dvec3 p = + openspace::SpiceManager::ref().targetPosition("SUN", _target, "GALACTIC", SpiceManager::AberrationCorrection(), _time, lt); _sunPosition = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); } diff --git a/modules/base/rendering/renderablepath.cpp b/modules/base/rendering/renderablepath.cpp index fc257a2074..784caa4ba2 100644 --- a/modules/base/rendering/renderablepath.cpp +++ b/modules/base/rendering/renderablepath.cpp @@ -222,8 +222,8 @@ void RenderablePath::calculatePath(std::string observer) { //float g = _lineColor[1]; //float b = _lineColor[2]; for (int i = 0; i < segments; i++) { - glm::dvec3 p; - SpiceManager::ref().getTargetPosition(_target, observer, _frame, "NONE", currentTime, p, lightTime); + glm::dvec3 p = + SpiceManager::ref().targetPosition(_target, observer, _frame, SpiceManager::AberrationCorrection(), currentTime, lightTime); pscPos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); pscPos[3] += 3; diff --git a/modules/base/rendering/renderableplanet.cpp b/modules/base/rendering/renderableplanet.cpp index ee14c7fcbc..7ef837325c 100644 --- a/modules/base/rendering/renderableplanet.cpp +++ b/modules/base/rendering/renderableplanet.cpp @@ -182,8 +182,8 @@ void RenderablePlanet::render(const RenderData& data) double lt; - glm::dvec3 p; - openspace::SpiceManager::ref().getTargetPosition("SUN", _target, "GALACTIC", "NONE", _time, p, lt); + glm::dvec3 p = + SpiceManager::ref().targetPosition("SUN", _target, "GALACTIC", SpiceManager::AberrationCorrection(), _time, lt); psc sun_pos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); // setup the data to the shader diff --git a/modules/base/rendering/renderabletrail.cpp b/modules/base/rendering/renderabletrail.cpp index 9abb87ad63..9ce516c87b 100644 --- a/modules/base/rendering/renderabletrail.cpp +++ b/modules/base/rendering/renderabletrail.cpp @@ -219,11 +219,11 @@ void RenderableTrail::update(const UpdateData& data) { glm::dvec3 p; // Update the floating current time if (start > data.time) - SpiceManager::ref().getTargetPosition(_target, _observer, _frame, "NONE", start, p, lightTime); + p = SpiceManager::ref().targetPosition(_target, _observer, _frame, SpiceManager::AberrationCorrection(), start, lightTime); else if (end < data.time) - SpiceManager::ref().getTargetPosition(_target, _observer, _frame, "NONE", end, p, lightTime); + p = SpiceManager::ref().targetPosition(_target, _observer, _frame, SpiceManager::AberrationCorrection(), end, lightTime); else - SpiceManager::ref().getTargetPosition(_target, _observer, _frame, "NONE", data.time, p, lightTime); + p = SpiceManager::ref().targetPosition(_target, _observer, _frame, SpiceManager::AberrationCorrection(), data.time, lightTime); psc pscPos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); @@ -246,8 +246,8 @@ void RenderableTrail::update(const UpdateData& data) { et = start; else if (end < et) et = end; - glm::dvec3 p; - SpiceManager::ref().getTargetPosition(_target, _observer, _frame, "NONE", et, p, lightTime); + glm::dvec3 p = + SpiceManager::ref().targetPosition(_target, _observer, _frame, SpiceManager::AberrationCorrection(), et, lightTime); pscPos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); pscPos[3] += 3; _vertexArray[i] = { pscPos[0], pscPos[1], pscPos[2], pscPos[3] }; @@ -289,6 +289,7 @@ void RenderableTrail::fullYearSweep(double time) { _oldTime = time; _vertexArray.resize(segments+2); + glm::dvec3 p; for (int i = 0; i < segments+2; i++) { if (start > time && intervalSet) { time = start; @@ -297,8 +298,16 @@ void RenderableTrail::fullYearSweep(double time) { time = end; } - glm::dvec3 p; - SpiceManager::ref().getTargetPosition(_target, _observer, _frame, "NONE", time, p, lightTime); + try { + p = + SpiceManager::ref().targetPosition(_target, _observer, _frame, SpiceManager::AberrationCorrection(), time, lightTime); + } + catch (const SpiceManager::SpiceKernelException& e) { + // This fires for PLUTO BARYCENTER and SUN and uses the only value sometimes? + // ---abock +// LERROR(e.what()); + } + psc pscPos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); pscPos[3] += 3; diff --git a/modules/newhorizons/rendering/renderablefov.cpp b/modules/newhorizons/rendering/renderablefov.cpp index aa501b5e7b..5a398a5773 100644 --- a/modules/newhorizons/rendering/renderablefov.cpp +++ b/modules/newhorizons/rendering/renderablefov.cpp @@ -80,7 +80,9 @@ RenderableFov::RenderableFov(const ghoul::Dictionary& dictionary) success = dictionary.getValue(keyInstrumentMethod, _method); ghoul_assert(success, ""); - success = dictionary.getValue(keyInstrumentAberration, _aberrationCorrection); + std::string a = "NONE"; + success = dictionary.getValue(keyInstrumentAberration, a); + a = SpiceManager::AberrationCorrection(a); ghoul_assert(success, ""); ghoul::Dictionary potentialTargets; @@ -241,8 +243,8 @@ psc RenderableFov::checkForIntercept(glm::dvec3 ray) { } // Orthogonal projection next to planets surface psc RenderableFov::orthogonalProjection(glm::dvec3 vecFov) { - glm::dvec3 vecToTarget; - SpiceManager::ref().getTargetPosition(_fovTarget, _spacecraft, _frame, _aberrationCorrection, _time, vecToTarget, _lt); + glm::dvec3 vecToTarget = + SpiceManager::ref().targetPosition(_fovTarget, _spacecraft, _frame, _aberrationCorrection, _time, _lt); openspace::SpiceManager::ref().frameConversion(vecFov, _instrumentID, _frame, _time); glm::dvec3 p = openspace::SpiceManager::ref().orthogonalProjection(vecToTarget, vecFov); @@ -446,13 +448,12 @@ void RenderableFov::computeIntercepts(const RenderData& data){ fovSurfaceIntercept(_interceptTag, _bounds); glm::vec3 aim = (_spacecraftRotation * glm::vec4(_boresight, 1)).xyz(); - glm::dvec3 position; - SpiceManager::ref().getTargetPosition(_fovTarget, + glm::dvec3 position = + SpiceManager::ref().targetPosition(_fovTarget, _spacecraft, _frame, _aberrationCorrection, _time, - position, _lt); psc p = PowerScaledCoordinate::CreatePowerScaledCoordinate(position.x, position.y, position.z); pss length = p.length(); diff --git a/modules/newhorizons/rendering/renderablefov.h b/modules/newhorizons/rendering/renderablefov.h index 5d16737c22..0b2179dd3a 100644 --- a/modules/newhorizons/rendering/renderablefov.h +++ b/modules/newhorizons/rendering/renderablefov.h @@ -36,6 +36,7 @@ #include //#include #include +#include namespace openspace { class RenderableFov : public Renderable{ @@ -96,7 +97,7 @@ public: std::string _frame; std::string _instrumentID; std::string _method; - std::string _aberrationCorrection; + SpiceManager::AberrationCorrection _aberrationCorrection; std::string _fovTarget; glm::dvec3 ipoint, ivec; glm::dvec3 _previousHalf; diff --git a/modules/newhorizons/rendering/renderablemodelprojection.cpp b/modules/newhorizons/rendering/renderablemodelprojection.cpp index 12725cb38c..a2670285b0 100644 --- a/modules/newhorizons/rendering/renderablemodelprojection.cpp +++ b/modules/newhorizons/rendering/renderablemodelprojection.cpp @@ -136,11 +136,12 @@ RenderableModelProjection::RenderableModelProjection(const ghoul::Dictionary& di completeSuccess &= dictionary.getValue(keyInstrumentNear, _nearPlane); completeSuccess &= dictionary.getValue(keyInstrumentFar, _farPlane); ghoul_assert(completeSuccess, "All neccessary attributes not found in modfile"); - - completeSuccess = dictionary.getValue(keyProjAberration, _aberration); - if (!completeSuccess) - _aberration = "NONE"; - + + std::string a = "NONE"; + bool s = dictionary.getValue(keyProjAberration, a); + _aberration = SpiceManager::AberrationCorrection(a); + completeSuccess &= s; + openspace::SpiceManager::ref().addFrame(_target, _source); setBoundingSphere(pss(1.f, 9.f)); @@ -354,8 +355,8 @@ void RenderableModelProjection::update(const UpdateData& data) { openspace::SpiceManager::ref().getPositionTransformMatrix(_source, _destination, _time, _stateMatrix); double lt; - glm::dvec3 p; - openspace::SpiceManager::ref().getTargetPosition("SUN", _target, "GALACTIC", "NONE", _time, p, lt); + glm::dvec3 p = + openspace::SpiceManager::ref().targetPosition("SUN", _target, "GALACTIC", SpiceManager::AberrationCorrection(), _time, lt); _sunPosition = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); } @@ -429,8 +430,8 @@ void RenderableModelProjection::attitudeParameters(double time) { return; double lightTime; - glm::dvec3 p; - found = SpiceManager::ref().getTargetPosition(_projectorID, _projecteeID, _destination, _aberration, time, p, lightTime); + glm::dvec3 p = + SpiceManager::ref().targetPosition(_projectorID, _projecteeID, _destination, _aberration, time, lightTime); psc position = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); position[3] += (3 + _camScaling[1]); diff --git a/modules/newhorizons/rendering/renderablemodelprojection.h b/modules/newhorizons/rendering/renderablemodelprojection.h index 4508094e30..9f24290222 100644 --- a/modules/newhorizons/rendering/renderablemodelprojection.h +++ b/modules/newhorizons/rendering/renderablemodelprojection.h @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -104,7 +105,7 @@ namespace openspace { std::string _instrumentID; std::string _projectorID; std::string _projecteeID; - std::string _aberration; + SpiceManager::AberrationCorrection _aberration; std::vector _potentialTargets; float _fovy; float _aspectRatio; diff --git a/modules/newhorizons/rendering/renderableplaneprojection.cpp b/modules/newhorizons/rendering/renderableplaneprojection.cpp index c3a037988e..1ba59f60f9 100644 --- a/modules/newhorizons/rendering/renderableplaneprojection.cpp +++ b/modules/newhorizons/rendering/renderableplaneprojection.cpp @@ -228,12 +228,18 @@ void RenderablePlaneProjection::updatePlane(const Image img, double currentTime) return; } - glm::dvec3 vecToTarget; double lt; psc projection[4]; - SpiceManager::ref().getTargetPosition(_target.body, _spacecraft, GalacticFrame, "CN+S", currentTime, vecToTarget, lt); - // The apparent position, CN+S, makes image align best with target + glm::dvec3 vecToTarget = SpiceManager::ref().targetPosition( + _target.body, + _spacecraft, + GalacticFrame, + { SpiceManager::AberrationCorrection::Type::ConvergedNewtonianStellar, SpiceManager::AberrationCorrection::Direction::Reception }, + currentTime, + lt + ); + // The apparent position, CN+S, makes image align best with target for (int j = 0; j < bounds.size(); ++j) { openspace::SpiceManager::ref().frameConversion(bounds[j], frame, GalacticFrame, currentTime); @@ -321,9 +327,9 @@ std::string RenderablePlaneProjection::findClosestTarget(double currentTime) { std::string closestTarget = ""; - glm::dvec3 p; double lt; - SpiceManager::ref().getTargetPosition(_spacecraft, "SSB", GalacticFrame, "NONE", currentTime, p, lt); + glm::dvec3 p = + SpiceManager::ref().targetPosition(_spacecraft, "SSB", GalacticFrame, SpiceManager::AberrationCorrection(), currentTime, lt); psc spacecraftPos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); diff --git a/modules/newhorizons/rendering/renderableplanetprojection.cpp b/modules/newhorizons/rendering/renderableplanetprojection.cpp index 3e1fe3805d..3bca6c46c6 100644 --- a/modules/newhorizons/rendering/renderableplanetprojection.cpp +++ b/modules/newhorizons/rendering/renderableplanetprojection.cpp @@ -120,7 +120,9 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& bool b1 = dictionary.getValue(keyInstrument, _instrumentID); bool b2 = dictionary.getValue(keyProjObserver, _projectorID); bool b3 = dictionary.getValue(keyProjTarget, _projecteeID); - bool b4 = dictionary.getValue(keyProjAberration, _aberration); + std::string a = "NONE"; + bool b4 = dictionary.getValue(keyProjAberration, a); + _aberration = SpiceManager::AberrationCorrection(a); bool b5 = dictionary.getValue(keyInstrumentFovy, _fovy); bool b6 = dictionary.getValue(keyInstrumentAspect, _aspectRatio); bool b7 = dictionary.getValue(keyInstrumentNear, _nearPlane); @@ -430,8 +432,7 @@ void RenderablePlanetProjection::attitudeParameters(double time){ if (!found) return ; - glm::dvec3 p; - found = SpiceManager::ref().getTargetPosition(_projectorID, _projecteeID, _mainFrame, _aberration, time, p, lightTime); + glm::dvec3 p = SpiceManager::ref().targetPosition(_projectorID, _projecteeID, _mainFrame, _aberration, time, lightTime); psc position = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); //change to KM and add psc camera scaling. @@ -510,8 +511,8 @@ void RenderablePlanetProjection::render(const RenderData& data){ _imageTimes.clear(); double lt; - glm::dvec3 p; - openspace::SpiceManager::ref().getTargetPosition("SUN", _projecteeID, "GALACTIC", "NONE", _time, p, lt); + glm::dvec3 p = + openspace::SpiceManager::ref().targetPosition("SUN", _projecteeID, "GALACTIC", SpiceManager::AberrationCorrection(), _time, lt); psc sun_pos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); // Main renderpass diff --git a/modules/newhorizons/rendering/renderableplanetprojection.h b/modules/newhorizons/rendering/renderableplanetprojection.h index 031a67da06..be5d2d0523 100644 --- a/modules/newhorizons/rendering/renderableplanetprojection.h +++ b/modules/newhorizons/rendering/renderableplanetprojection.h @@ -40,6 +40,7 @@ #include #include #include +#include #include @@ -117,7 +118,7 @@ private: std::string _instrumentID; std::string _projectorID; std::string _projecteeID; - std::string _aberration; + SpiceManager::AberrationCorrection _aberration; std::vector _potentialTargets; // @TODO copy-n-paste from renderablefov diff --git a/modules/newhorizons/rendering/renderableshadowcylinder.cpp b/modules/newhorizons/rendering/renderableshadowcylinder.cpp index 1e82e75e30..4e4d346ec6 100644 --- a/modules/newhorizons/rendering/renderableshadowcylinder.cpp +++ b/modules/newhorizons/rendering/renderableshadowcylinder.cpp @@ -71,7 +71,9 @@ namespace openspace { ghoul_assert(success, ""); success = dictionary.getValue(_keyMainFrame, _mainFrame); ghoul_assert(success, ""); - success = dictionary.getValue(_keyAberration, _aberration); + std::string a = "NONE"; + success = dictionary.getValue(_keyAberration, a); + _aberration = SpiceManager::AberrationCorrection(a); ghoul_assert(success, ""); } @@ -166,9 +168,9 @@ void RenderableShadowCylinder::createCylinder() { observerPosition, terminatorPoints); - glm::dvec3 vecLightSource; double lt; - bool performs = SpiceManager::ref().getTargetPosition(_body, _lightSource, _mainFrame, _aberration, _time, vecLightSource, lt); + glm::dvec3 vecLightSource = + SpiceManager::ref().targetPosition(_body, _lightSource, _mainFrame, _aberration, _time, lt); glm::dmat3 _stateMatrix; openspace::SpiceManager::ref().getPositionTransformMatrix(_bodyFrame, _mainFrame, _time, _stateMatrix); diff --git a/modules/newhorizons/rendering/renderableshadowcylinder.h b/modules/newhorizons/rendering/renderableshadowcylinder.h index b5caac7f9f..1aaa94551d 100644 --- a/modules/newhorizons/rendering/renderableshadowcylinder.h +++ b/modules/newhorizons/rendering/renderableshadowcylinder.h @@ -30,6 +30,7 @@ #include #include #include +#include namespace ghoul { namespace filesystem { @@ -87,7 +88,7 @@ namespace openspace { std::string _body; std::string _bodyFrame; std::string _mainFrame; - std::string _aberration; + SpiceManager::AberrationCorrection _aberration; double _time; }; diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index f5b7326fa3..64ec5b4b04 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -452,8 +452,8 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi glm::vec4 targetColor(0.00, 0.75, 1.00, 1); double lt; - glm::dvec3 p; - SpiceManager::ref().getTargetPosition("PLUTO", "NEW HORIZONS", "GALACTIC", "NONE", currentTime, p, lt); + glm::dvec3 p = + SpiceManager::ref().targetPosition("PLUTO", "NEW HORIZONS", "GALACTIC", SpiceManager::AberrationCorrection(), currentTime, lt); psc nhPos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); float a, b, c; SpiceManager::ref().getPlanetEllipsoid("PLUTO", a, b, c); diff --git a/src/util/spicemanager.cpp b/src/util/spicemanager.cpp index 4c7effc223..02e1847115 100644 --- a/src/util/spicemanager.cpp +++ b/src/util/spicemanager.cpp @@ -62,9 +62,52 @@ using std::string; namespace openspace { + SpiceManager::SpiceKernelException::SpiceKernelException(const string& msg) : ghoul::RuntimeError(msg, "Spice") {} + +SpiceManager::AberrationCorrection::AberrationCorrection(Type t, Direction d) + : type(t) + , direction(d) +{} + +SpiceManager::AberrationCorrection::AberrationCorrection(const std::string& identifier) { + static const std::map> Mapping = { + { "NONE" , { Type::None, Direction::Reception } }, + { "LT" , { Type::LightTime, Direction::Reception } }, + { "LT+S" , { Type::LightTimeStellar, Direction::Reception } }, + { "CN" , { Type::ConvergedNewtonian, Direction::Reception } }, + { "CN+S" , { Type::ConvergedNewtonianStellar, Direction::Reception } }, + { "XLT" , { Type::LightTime, Direction::Transmission } }, + { "XLT+S" , { Type::LightTimeStellar, Direction::Transmission } }, + { "XCN" , { Type::ConvergedNewtonian, Direction::Transmission } }, + { "XCN+S" , { Type::ConvergedNewtonianStellar, Direction::Transmission } } + }; + + auto it = Mapping.find(identifier); + + ghoul_assert(!identifier.empty(), "Identifier may not be empty"); + ghoul_assert(it != Mapping.end(), format("Invalid identifer '{}'", identifier)); + + type = it->second.first; + direction = it->second.second; +} + +SpiceManager::AberrationCorrection::operator string() const { + switch (type) { + case Type::None: + return "NONE"; + case Type::LightTime: + return (direction == Direction::Reception) ? "LT" : "XLT"; + case Type::LightTimeStellar: + return (direction == Direction::Reception) ? "LT+S" : "XLT+S"; + case Type::ConvergedNewtonian: + return (direction == Direction::Reception) ? "CN" : "XCN"; + case Type::ConvergedNewtonianStellar: + return (direction == Direction::Reception) ? "CN+S" : "XCN+S"; + } +} SpiceManager::SpiceManager() { // Set the SPICE library to not exit the program if an error occurs @@ -370,40 +413,48 @@ string SpiceManager::dateFromEphemerisTime(double ephemerisTime, } -bool SpiceManager::getTargetPosition(const std::string& target, - const std::string& observer, - const std::string& referenceFrame, - const std::string& aberrationCorrection, - double ephemerisTime, - glm::dvec3& position, - double& lightTime) const +glm::dvec3 SpiceManager::targetPosition(const std::string& target, + const std::string& observer, + const std::string& referenceFrame, + AberrationCorrection abberationCorrection, + double ephemerisTime, + double& lightTime) const { - psc pscPosition = PowerScaledCoordinate::CreatePowerScaledCoordinate(position[0], position[1], position[2]); + ghoul_assert(!target.empty(), "Target is not empty"); + ghoul_assert(!observer.empty(), "Observer is not empty"); + ghoul_assert(!referenceFrame.empty(), "Reference frame is not empty"); bool targetHasCoverage = hasSpkCoverage(target, ephemerisTime); bool observerHasCoverage = hasSpkCoverage(observer, ephemerisTime); if (!targetHasCoverage && !observerHasCoverage){ - return false; + throw SpiceKernelException( + format("Neither the target '{}' nor observer '{}' has SPK coverage", + target, + observer + ) + ); } - else if (targetHasCoverage && observerHasCoverage){ + else if (targetHasCoverage && observerHasCoverage) { + std::string correction = abberationCorrection; + glm::dvec3 position; spkpos_c(target.c_str(), ephemerisTime, referenceFrame.c_str(), - aberrationCorrection.c_str(), observer.c_str(), glm::value_ptr(position), + correction.c_str(), observer.c_str(), glm::value_ptr(position), &lightTime); + throwOnSpiceError(format("Error getting target position from '{}' to '{}' in reference frame '{}", target, observer, referenceFrame)); + return position; } else if (targetHasCoverage) {// observer has no coverage + psc pscPosition; getEstimatedPosition(ephemerisTime, observer, target, pscPosition); pscPosition = pscPosition*(-1.f); // inverse estimated position because the observer is "target" argument in funciton - position = pscPosition.vec3(); + return pscPosition.vec3(); } else { // target has no coverage + psc pscPosition; getEstimatedPosition(ephemerisTime, target, observer, pscPosition); - position = pscPosition.vec3(); + return pscPosition.vec3(); + } - - if (position[0] == 0.0 || position[1] == 0.0 || position[2] == 0.0) - return false; - - return targetHasCoverage && observerHasCoverage; } //bool SpiceManager::getTargetPosition(const std::string& target, From 12fdb2368481b70b69ffe8d9052400850c56cfa2 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Thu, 19 Nov 2015 16:29:33 -0500 Subject: [PATCH 041/122] More cleanup in SpiceManager --- include/openspace/util/spicemanager.h | 128 +++--- .../newhorizons/rendering/renderablefov.cpp | 27 +- modules/newhorizons/rendering/renderablefov.h | 1 - .../rendering/renderableplaneprojection.cpp | 8 +- .../rendering/renderableshadowcylinder.cpp | 2 +- src/util/spicemanager.cpp | 430 ++++++++++-------- 6 files changed, 318 insertions(+), 278 deletions(-) diff --git a/include/openspace/util/spicemanager.h b/include/openspace/util/spicemanager.h index 3be9fa982e..cb0ce77afa 100644 --- a/include/openspace/util/spicemanager.h +++ b/include/openspace/util/spicemanager.h @@ -107,14 +107,14 @@ public: * Returns the string representation of this Aberration Correction * \return The string representation of this Aberration correction */ - operator std::string() const; + operator const char*() const; /// The type of aberration correction Type type = Type::None; /// The direction of the aberration correction Direction direction = Direction::Reception; }; - + /** * Loads one or more SPICE kernels into a program. The provided path can either be a * binary, text-kernel, or meta-kernel which gets loaded into the kernel pool. The @@ -420,81 +420,59 @@ public: * NAIF object, \p referenceFrame does not name a valid reference frame or if there is * not sufficient data available to compute the position or neither the target nor the * observer have coverage. - * \pre \p target must not be empty - * \pre \p observer must not be empty - * \pre \p referenceFrame must not be empty - * \post If an exception is thrown, \p lightTime will not be modified + * \pre \p target must not be empty. + * \pre \p observer must not be empty. + * \pre \p referenceFrame must not be empty. + * \post If an exception is thrown, \p lightTime will not be modified. * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/spkpos_c.html * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html */ glm::dvec3 targetPosition(const std::string& target, - const std::string& observer, - const std::string& referenceFrame, - AberrationCorrection abberationCorrection, - double ephemerisTime, - double& lightTime) const; - /** - * If a position is requested for an uncovered time in the SPK kernels, - * this function will insert a position in modelPosition. - * If the coverage has not yet started, the first position will be retrieved, - * If the coverage has ended, the last position will be retrieved - * If time is in a coverage gap, the position will be interpolated - * \param time, for which an estimated position is desirable - * \param target, the body which is missing SPK data for this time - * \param origin, the observer, the position will be retrieved in relation to this body - * \param modelPosition, the position of the body, passed by reference - * \return true if an estimated position is found - */ - bool getEstimatedPosition(const double time, const std::string target, const std::string origin, psc& modelPosition) const; + const std::string& observer, const std::string& referenceFrame, + AberrationCorrection aberrationCorrection, double ephemerisTime, + double& lightTime) const; /** - * This helper method converts a 3 dimensional vector from one reference frame to another. - * \param v The vector to be converted + * This method returns the transformation matrix that defines the transformation from + * the reference frame \p from to the reference frame \p to. As both reference frames + * may be non-inertial, the \p ephemerisTime has to be specified. * \param from The frame to be converted from * \param to The frame to be converted to - * \param ephemerisTime Time at which to get rotational matrix that transforms vector - * \return true if the conversion succeeded, false otherwise + * \param ephemerisTime Time at which to get the transformation matrix + * \return The transformation matrix + * \throws SpiceKernelException If the transformation matrix between \p from and \p to + * cannot be determined. + * \pre \p from must not be empty. + * \pre \p to must not be empty. */ - bool frameConversion(glm::dvec3& v, const std::string& from, const std::string& to, double ephemerisTime) const; + glm::dmat3 frameTransformationMatrix(const std::string& from, + const std::string& to, double ephemerisTime) const; /** - * Finds the projection of one vector onto another vector. - * All vectors are 3-dimensional. - * \param v1 The vector to be projected. - * \param v2 The vector onto which v1 is to be projected. - * \return The projection of v1 onto v2. - */ - glm::dvec3 orthogonalProjection(glm::dvec3& v1, glm::dvec3& v2); - - /** - * Given an observer and a direction vector defining a ray, compute - * the surface intercept of the ray on a target body at a specified - * epoch, optionally corrected for light time and stellar - * aberration. - * \param target Name of target body. - * \param observer Name of observing body. - * \param fovFrame Reference frame of ray's direction vector. - * \param bodyFixedFrame Body-fixed, body-centered target body frame. - * \param method Computation method. - * \param aberrationCorrection Aberration correction. - * \param ephemerisTime Epoch in ephemeris seconds past J2000 TDB. - * \param targetEpoch Intercept epoch. - * \param directionVector Ray's direction vector. - * \param surfaceIntercept Surface intercept point on the target body. - * \param surfaceVector Vector from observer to intercept point. - * \param isVisible Flag indicating whether intercept was found. - * \return true if not error occurred, false otherwise - * For further details, refer to - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/sincpt_c.html + * Given an \p observer and a direction vector \p directionVector defining a ray, + * compute the surface intercept of the ray on a \p target body at a specified + * \p targetEpoch, optionally corrected for aberrations (\p aberrationCorrection). + * \param target Name of target body + * \param observer Name of observing body + * \param fovFrame Reference frame of the ray's direction vector + * \param bodyFixedFrame Body-fixed, body-centered target body frame + * \param method Computation method + * \param aberrationCorrection Aberration correction + * \param ephemerisTime Intercept time in ephemeris seconds past J2000 TDB + * \param directionVector Ray's direction vector + * \param surfaceIntercept Surface intercept point on the target body + * \param surfaceVector Vector from observer to intercept point + * \param isVisible Flag indicating whether intercept was found + * \return true if not error occurred, false otherwise + * For further details, refer to + * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/sincpt_c.html */ bool getSurfaceIntercept(const std::string& target, const std::string& observer, const std::string& fovFrame, const std::string& bodyFixedFrame, - const std::string& method, - const std::string& aberrationCorrection, + AberrationCorrection aberrationCorrection, double ephemerisTime, - double& targetEpoch, glm::dvec3& directionVector, glm::dvec3& surfaceIntercept, glm::dvec3& surfaceVector, @@ -784,7 +762,7 @@ public: */ bool getPlanetEllipsoid(std::string planetName, float &a, float &b, float &c); -protected: +private: struct KernelInformation { std::string path; /// The path from which the kernel was loaded KernelHandle id; /// A unique identifier for each kernel @@ -821,6 +799,34 @@ protected: */ void findSpkCoverage(const std::string& path); + /** + * If a position is requested for an uncovered time in the SPK kernels, this function + * will return an estimated position. If the coverage has not yet started, the first + * position will be retrieved. If the coverage has ended, the last position will be + * retrieved. If \p time is in a coverage gap, the position will be interpolated. + * \param target The body which is missing SPK data for this time + * \param observer The observer. The position will be retrieved in relation to this body + * \param referenceFrame The reference frame of the output position vector + * \param aberrationCorrection The aberration correction used for the position + * calculation + * \param ephemerisTime The time for which an estimated position is desirable + * \param lightTime If the \p aberrationCorrection is different from + * AbberationCorrection::Type::None, this variable will contain the light time between + * the observer and the target. + * \return The position of the \p target relative to the \p origin + * \throws SpiceKernelException If the \p target or \p origin are not valid NAIF + * objects or if there is no position for the \p target at any time + * \pre \p target must not be empty + * \pre \p observer must not be empty + * \pre \p referenceFrame must not be empty + * \pre \p target and \p observer must be different + * \post If an exception is thrown, \p lightTime will not be modified + */ + glm::dvec3 getEstimatedPosition(const std::string& target, + const std::string& observer, const std::string& referenceFrame, + AberrationCorrection aberrationCorrection, double ephemerisTime, + double& lightTime) const; + /// A list of all loaded kernels std::vector _loadedKernels; // Map: id, vector of pairs. Pair: Start time, end time; diff --git a/modules/newhorizons/rendering/renderablefov.cpp b/modules/newhorizons/rendering/renderablefov.cpp index 5a398a5773..1d0f6c5ffb 100644 --- a/modules/newhorizons/rendering/renderablefov.cpp +++ b/modules/newhorizons/rendering/renderablefov.cpp @@ -38,6 +38,7 @@ #include #include +#include #include #include @@ -232,8 +233,8 @@ glm::dvec3 RenderableFov::interpolate(glm::dvec3 p0, glm::dvec3 p1, float t) { psc RenderableFov::checkForIntercept(glm::dvec3 ray) { bool intercepted = false; openspace::SpiceManager::ref().getSurfaceIntercept(_fovTarget, _spacecraft, _instrumentID, - _frame, _method, _aberrationCorrection, - _time, _targetEpoch, ray, ipoint, ivec, intercepted); + _frame, _aberrationCorrection, + _time, ray, ipoint, ivec, intercepted); ivec *= 0.9999;// because fov lands exactly on top of surface we need to move it out slightly _interceptVector = PowerScaledCoordinate::CreatePowerScaledCoordinate(ivec[0], ivec[1], ivec[2]); @@ -243,10 +244,10 @@ psc RenderableFov::checkForIntercept(glm::dvec3 ray) { } // Orthogonal projection next to planets surface psc RenderableFov::orthogonalProjection(glm::dvec3 vecFov) { - glm::dvec3 vecToTarget = - SpiceManager::ref().targetPosition(_fovTarget, _spacecraft, _frame, _aberrationCorrection, _time, _lt); - openspace::SpiceManager::ref().frameConversion(vecFov, _instrumentID, _frame, _time); - glm::dvec3 p = openspace::SpiceManager::ref().orthogonalProjection(vecToTarget, vecFov); + glm::dvec3 vecToTarget = + SpiceManager::ref().targetPosition(_fovTarget, _spacecraft, _frame, _aberrationCorrection, _time, _lt); + vecFov = SpiceManager::ref().frameTransformationMatrix(_instrumentID, _frame, _time) * vecFov; + glm::dvec3 p = glm::proj(vecToTarget, vecFov); psc projection = PowerScaledCoordinate::CreatePowerScaledCoordinate(p[0], p[1], p[2]); projection[3] += 3; @@ -259,8 +260,8 @@ glm::dvec3 RenderableFov::bisection(glm::dvec3 p1, glm::dvec3 p2, double toleran glm::dvec3 half = interpolate(p1, p2, 0.5f); bool intercepted = false; openspace::SpiceManager::ref().getSurfaceIntercept(_fovTarget, _spacecraft, _instrumentID, - _frame, _method, _aberrationCorrection, - _time, _targetEpoch, half, ipoint, ivec, intercepted); + _frame, _aberrationCorrection, + _time, half, ipoint, ivec, intercepted); if (glm::distance(_previousHalf, half) < tolerance){ _previousHalf = glm::dvec3(0); return half; @@ -302,8 +303,8 @@ void RenderableFov::fovSurfaceIntercept(bool H[], std::vector bounds glm::dvec3 half = interpolate(current, next, 0.5f); bool intercepted; openspace::SpiceManager::ref().getSurfaceIntercept(_fovTarget, _spacecraft, _instrumentID, - _frame, _method, _aberrationCorrection, - _time, _targetEpoch, half, ipoint, ivec, intercepted); + _frame, _aberrationCorrection, + _time, half, ipoint, ivec, intercepted); if (intercepted){ // find the two outer most points of intersection glm::dvec3 root1 = bisection(half, current, tolerance); @@ -400,7 +401,7 @@ void RenderableFov::determineTarget(){ _potentialTargets[i], _spacecraft, _method, - _aberrationCorrection, + std::string(_aberrationCorrection), _time, _withinFOV); if (success && _withinFOV){ @@ -417,8 +418,8 @@ void RenderableFov::computeIntercepts(const RenderData& data){ int r = (i == _bounds.size()) ? 0 : i; // compute surface intercept openspace::SpiceManager::ref().getSurfaceIntercept(_fovTarget, _spacecraft, _instrumentID, - _frame, _method, _aberrationCorrection, - _time, _targetEpoch, _bounds[r], ipoint, ivec, _interceptTag[r]); + _frame, _aberrationCorrection, + _time, _bounds[r], ipoint, ivec, _interceptTag[r]); // if not found, use the orthogonal projected point if (!_interceptTag[r]) _projectionBounds[r] = orthogonalProjection(_bounds[r]); diff --git a/modules/newhorizons/rendering/renderablefov.h b/modules/newhorizons/rendering/renderablefov.h index 0b2179dd3a..d1290351f7 100644 --- a/modules/newhorizons/rendering/renderablefov.h +++ b/modules/newhorizons/rendering/renderablefov.h @@ -107,7 +107,6 @@ public: std::vector _bounds; std::vector _potentialTargets; bool _drawFOV; - double _targetEpoch; double _lt; // GPU diff --git a/modules/newhorizons/rendering/renderableplaneprojection.cpp b/modules/newhorizons/rendering/renderableplaneprojection.cpp index 1ba59f60f9..3d25ded0a4 100644 --- a/modules/newhorizons/rendering/renderableplaneprojection.cpp +++ b/modules/newhorizons/rendering/renderableplaneprojection.cpp @@ -37,6 +37,8 @@ #include #include +#include + namespace { const std::string _loggerCat = "RenderablePlaneProjection"; const std::string KeySpacecraft = "Spacecraft"; @@ -242,13 +244,13 @@ void RenderablePlaneProjection::updatePlane(const Image img, double currentTime) // The apparent position, CN+S, makes image align best with target for (int j = 0; j < bounds.size(); ++j) { - openspace::SpiceManager::ref().frameConversion(bounds[j], frame, GalacticFrame, currentTime); - glm::dvec3 cornerPosition = openspace::SpiceManager::ref().orthogonalProjection(vecToTarget, bounds[j]); + bounds[j] = SpiceManager::ref().frameTransformationMatrix(frame, GalacticFrame, currentTime) * bounds[j]; + glm::dvec3 cornerPosition = glm::proj(vecToTarget, bounds[j]); if (!_moving) { cornerPosition -= vecToTarget; } - openspace::SpiceManager::ref().frameConversion(cornerPosition, GalacticFrame, _target.frame, currentTime); + cornerPosition = SpiceManager::ref().frameTransformationMatrix(GalacticFrame, _target.frame, currentTime) * cornerPosition; projection[j] = PowerScaledCoordinate::CreatePowerScaledCoordinate(cornerPosition[0], cornerPosition[1], cornerPosition[2]); projection[j][3] += 3; diff --git a/modules/newhorizons/rendering/renderableshadowcylinder.cpp b/modules/newhorizons/rendering/renderableshadowcylinder.cpp index 4e4d346ec6..1e60f381c9 100644 --- a/modules/newhorizons/rendering/renderableshadowcylinder.cpp +++ b/modules/newhorizons/rendering/renderableshadowcylinder.cpp @@ -162,7 +162,7 @@ void RenderableShadowCylinder::createCylinder() { _observer, _body, _bodyFrame, - _aberration, + std::string(_aberration), _time, targetEpoch, observerPosition, diff --git a/src/util/spicemanager.cpp b/src/util/spicemanager.cpp index 02e1847115..3e6e96e4f4 100644 --- a/src/util/spicemanager.cpp +++ b/src/util/spicemanager.cpp @@ -66,6 +66,8 @@ namespace openspace { SpiceManager::SpiceKernelException::SpiceKernelException(const string& msg) : ghoul::RuntimeError(msg, "Spice") {} + + SpiceManager::AberrationCorrection::AberrationCorrection(Type t, Direction d) : type(t) @@ -73,7 +75,7 @@ SpiceManager::AberrationCorrection::AberrationCorrection(Type t, Direction d) {} SpiceManager::AberrationCorrection::AberrationCorrection(const std::string& identifier) { - static const std::map> Mapping = { + const static std::map> Mapping = { { "NONE" , { Type::None, Direction::Reception } }, { "LT" , { Type::LightTime, Direction::Reception } }, { "LT+S" , { Type::LightTimeStellar, Direction::Reception } }, @@ -84,7 +86,7 @@ SpiceManager::AberrationCorrection::AberrationCorrection(const std::string& iden { "XCN" , { Type::ConvergedNewtonian, Direction::Transmission } }, { "XCN+S" , { Type::ConvergedNewtonianStellar, Direction::Transmission } } }; - + auto it = Mapping.find(identifier); ghoul_assert(!identifier.empty(), "Identifier may not be empty"); @@ -94,7 +96,7 @@ SpiceManager::AberrationCorrection::AberrationCorrection(const std::string& iden direction = it->second.second; } -SpiceManager::AberrationCorrection::operator string() const { +SpiceManager::AberrationCorrection::operator const char*() const { switch (type) { case Type::None: return "NONE"; @@ -416,14 +418,14 @@ string SpiceManager::dateFromEphemerisTime(double ephemerisTime, glm::dvec3 SpiceManager::targetPosition(const std::string& target, const std::string& observer, const std::string& referenceFrame, - AberrationCorrection abberationCorrection, + AberrationCorrection aberrationCorrection, double ephemerisTime, double& lightTime) const { ghoul_assert(!target.empty(), "Target is not empty"); ghoul_assert(!observer.empty(), "Observer is not empty"); ghoul_assert(!referenceFrame.empty(), "Reference frame is not empty"); - + bool targetHasCoverage = hasSpkCoverage(target, ephemerisTime); bool observerHasCoverage = hasSpkCoverage(observer, ephemerisTime); if (!targetHasCoverage && !observerHasCoverage){ @@ -435,149 +437,139 @@ glm::dvec3 SpiceManager::targetPosition(const std::string& target, ); } else if (targetHasCoverage && observerHasCoverage) { - std::string correction = abberationCorrection; glm::dvec3 position; - spkpos_c(target.c_str(), ephemerisTime, referenceFrame.c_str(), - correction.c_str(), observer.c_str(), glm::value_ptr(position), - &lightTime); - throwOnSpiceError(format("Error getting target position from '{}' to '{}' in reference frame '{}", target, observer, referenceFrame)); + spkpos_c( + target.c_str(), + ephemerisTime, + referenceFrame.c_str(), + aberrationCorrection, + observer.c_str(), + glm::value_ptr(position), + &lightTime + ); + throwOnSpiceError(format( + "Error getting target position from '{}' to '{}' in reference frame '{}", + target, + observer, + referenceFrame + )); return position; } - else if (targetHasCoverage) {// observer has no coverage - psc pscPosition; - getEstimatedPosition(ephemerisTime, observer, target, pscPosition); - pscPosition = pscPosition*(-1.f); // inverse estimated position because the observer is "target" argument in funciton - return pscPosition.vec3(); - } - else { // target has no coverage - psc pscPosition; - getEstimatedPosition(ephemerisTime, target, observer, pscPosition); - return pscPosition.vec3(); - - } + else if (targetHasCoverage) { + // observer has no coverage + return getEstimatedPosition( + observer, + target, + referenceFrame, + aberrationCorrection, + ephemerisTime, + lightTime + ) * -1.0; + } + else { + // target has no coverage + return getEstimatedPosition( + target, + observer, + referenceFrame, + aberrationCorrection, + ephemerisTime, + lightTime + ); + } } -//bool SpiceManager::getTargetPosition(const std::string& target, -// const std::string& observer, -// const std::string& referenceFrame, -// const std::string& aberrationCorrection, -// double ephemerisTime, -// psc& position, -// double& lightTime) const -//{ -// double pos[3] = { 0.0, 0.0, 0.0}; -// -// bool targetHasCoverage = hasSpkCoverage(target, ephemerisTime); -// bool observerHasCoverage = hasSpkCoverage(observer, ephemerisTime); -// if (!targetHasCoverage && !observerHasCoverage){ -// position = PowerScaledCoordinate::CreatePowerScaledCoordinate(pos[0], pos[1], pos[2]); -// return false; -// } -// else if (targetHasCoverage && observerHasCoverage){ -// spkpos_c(target.c_str(), ephemerisTime, referenceFrame.c_str(), -// aberrationCorrection.c_str(), observer.c_str(), pos, &lightTime); -// position = PowerScaledCoordinate::CreatePowerScaledCoordinate(pos[0], pos[1], pos[2]); -// } -// else if (targetHasCoverage) {// observer has no coverage -// getEstimatedPosition(ephemerisTime, observer, target, position); -// position = position*(-1.f); // inverse estimated position because the observer is "target" argument in funciton -// } -// else {// target has no coverage -// getEstimatedPosition(ephemerisTime, target, observer, position); -// } -// -// return targetHasCoverage && observerHasCoverage; -//} - -bool SpiceManager::getEstimatedPosition(const double time, const std::string target, - const std::string observer, psc& targetPosition) const +glm::dmat3 SpiceManager::frameTransformationMatrix(const std::string& from, + const std::string& to, + double ephemerisTime) const { + ghoul_assert(!from.empty(), "From must not be empty"); + ghoul_assert(!to.empty(), "To must not be empty"); + + // get rotation matrix from frame A - frame B + glm::dmat3 transform; + pxform_c( + from.c_str(), + to.c_str(), + ephemerisTime, + reinterpret_cast(glm::value_ptr(transform)) + ); - int idTarget, idObserver; - bool targetFound = hasNaifId(target); - idTarget = naifId(target); - if (idTarget == 0) { //SOLAR SYSTEM BARYCENTER special case, no def. in kernels - targetPosition[0] = 0.f; - targetPosition[1] = 0.f; - targetPosition[2] = 0.f; - targetPosition[3] = 0.f; - return true; - } - - double pos[3] = { 0.0, 0.0, 0.0 }; + throwOnSpiceError( + format("Error converting from frame '{}' to frame '{}' at time '{}'", + from, to, ephemerisTime + ) + ); - bool observerFound = hasNaifId(observer); - idObserver = naifId(observer); - if (!targetFound || !observerFound || (idTarget == idObserver)) { - return false; - } - double lt, earlier, later, difference, quote; - double pos_earlier[3] = { 0.0, 0.0, 0.0 }; - double pos_later[3] = { 0.0, 0.0, 0.0 }; - if (_spkCoverageTimes.find(idTarget) == _spkCoverageTimes.end()){ // no coverage - LWARNING("No position for " + target + " at any time, was the correct SPK Kernels loaded?"); - targetPosition = PowerScaledCoordinate::CreatePowerScaledCoordinate(pos[0], pos[1], pos[2]); - return false; - } - - std::set coveredTimes = _spkCoverageTimes.find(idTarget)->second; - - std::set::iterator first = coveredTimes.begin(); - std::set::iterator last = coveredTimes.end(); - - if (coveredTimes.lower_bound(time) == first) { // coverage later, fetch first position - spkpos_c(target.c_str(), (*first), "GALACTIC", - "NONE", observer.c_str(), pos, <); - } - else if (coveredTimes.upper_bound(time) == last) { // coverage earlier, fetch last position - spkpos_c(target.c_str(), *(coveredTimes.rbegin()), "GALACTIC", - "NONE", observer.c_str(), pos, <); - - } - else { // coverage both earlier and later, interpolate these positions - earlier = *std::prev((coveredTimes.lower_bound(time))); - later = *(coveredTimes.upper_bound(time)); - - spkpos_c(target.c_str(), earlier, "GALACTIC", - "NONE", observer.c_str(), pos_earlier, <); - spkpos_c(target.c_str(), later, "GALACTIC", - "NONE", observer.c_str(), pos_later, <); - - //linear interpolation - difference = later - earlier; - quote = (time - earlier) / difference; - pos[0] = (pos_earlier[0]*(1-quote) + pos_later[0]*quote); - pos[1] = (pos_earlier[1]*(1-quote) + pos_later[1]*quote); - pos[2] = (pos_earlier[2]*(1-quote) + pos_later[2]*quote); - } - - - targetPosition = PowerScaledCoordinate::CreatePowerScaledCoordinate(pos[0], pos[1], pos[2]); - throwOnSpiceError("Error estimating positin for target: " + target + ", or observer: " + observer); - - return targetFound && observerFound; + // The rox-major, column-major order are switched in GLM and SPICE, so we have to + // transpose the matrix before we can return it + return glm::transpose(transform); } -// do NOT remove this method. -bool SpiceManager::frameConversion(glm::dvec3& v, const std::string& from, const std::string& to, double ephemerisTime) const{ - glm::dmat3 transform; - if (from == to) - return true; - // get rotation matrix from frame A - frame B - pxform_c(from.c_str(), to.c_str(), ephemerisTime, (double(*)[3])glm::value_ptr(transform)); - - throwOnSpiceError("Error converting from frame '" + from + - "' to frame '" + to + "' at time " + std::to_string(ephemerisTime)); - // re-express vector in new frame - mxv_c((double(*)[3])glm::value_ptr(transform), glm::value_ptr(v), glm::value_ptr(v)); +bool SpiceManager::getSurfaceIntercept(const std::string& target, + const std::string& observer, + const std::string& fovFrame, + const std::string& referenceFrame, + AberrationCorrection aberrationCorrection, + double ephemerisTime, + glm::dvec3& directionVector, + glm::dvec3& surfaceIntercept, + glm::dvec3& surfaceVector, + bool& isVisible + ) const +{ + const std::string ComputationMethod = "ELLIPSOID"; + + // make pretty latr + double dvec[3], spoint[3], et; + glm::dvec3 srfvec; + int found; + bool convert; + + dvec[0] = directionVector[0]; + dvec[1] = directionVector[1]; + dvec[2] = directionVector[2]; + + // allow client specify non-inertial frame. + std::string bodyfixed = "IAU_"; + convert = (referenceFrame.find(bodyfixed) == std::string::npos); + if (convert) { + bodyfixed = frameFromBody(target); + } else { + bodyfixed = referenceFrame; + } + + sincpt_c(ComputationMethod.c_str(), + target.c_str(), + ephemerisTime, + bodyfixed.c_str(), + aberrationCorrection, + observer.c_str(), + fovFrame.c_str(), + dvec, + spoint, + &et, + glm::value_ptr(srfvec), + &found); + + isVisible = (found == SPICETRUE); + + throwOnSpiceError("Error retrieving surface intercept on target '" + target + "'" + + "viewed from observer '" + observer + "' in " + + "reference frame '" + bodyfixed + "' at time '" + + std::to_string(ephemerisTime) + "'"); + + if (convert) + srfvec = SpiceManager::ref().frameTransformationMatrix(bodyfixed, referenceFrame, ephemerisTime) * srfvec; + + if (found){ + memcpy(glm::value_ptr(directionVector), dvec, sizeof(dvec)); + memcpy(glm::value_ptr(surfaceIntercept), spoint, sizeof(spoint)); + surfaceVector = srfvec; + } return true; } -glm::dvec3 SpiceManager::orthogonalProjection(glm::dvec3& v1, glm::dvec3& v2){ - glm::dvec3 projected; - vproj_c(glm::value_ptr(v1), glm::value_ptr(v2), glm::value_ptr(projected)); - return projected; -} bool SpiceManager::targetWithinFieldOfView(const std::string& instrument, const std::string& target, @@ -636,70 +628,6 @@ bool SpiceManager::targetWithinFieldOfView(const std::string& instrument, } -bool SpiceManager::getSurfaceIntercept(const std::string& target, - const std::string& observer, - const std::string& fovInstrument, - const std::string& referenceFrame, - const std::string& method, - const std::string& aberrationCorrection, - double ephemerisTime, - double& targetEpoch, - glm::dvec3& directionVector, - glm::dvec3& surfaceIntercept, - glm::dvec3& surfaceVector, - bool& isVisible - ) const -{ - // make pretty latr - double dvec[3], spoint[3], et; - glm::dvec3 srfvec; - int found; - bool convert; - - dvec[0] = directionVector[0]; - dvec[1] = directionVector[1]; - dvec[2] = directionVector[2]; - - // allow client specify non-inertial frame. - std::string bodyfixed = "IAU_"; - convert = (referenceFrame.find(bodyfixed) == std::string::npos); - if (convert) { - bodyfixed = frameFromBody(target); - } else { - bodyfixed = referenceFrame; - } - - sincpt_c(method.c_str(), - target.c_str(), - ephemerisTime, - bodyfixed.c_str(), - aberrationCorrection.c_str(), - observer.c_str(), - fovInstrument.c_str(), - dvec, - spoint, - &et, - glm::value_ptr(srfvec), - &found); - - isVisible = (found == SPICETRUE); - - throwOnSpiceError("Error retrieving surface intercept on target '" + target + "'" + - "viewed from observer '" + observer + "' in " + - "reference frame '" + bodyfixed + "' at time '" + - std::to_string(ephemerisTime) + "'"); - - if (convert) - frameConversion(srfvec, bodyfixed, referenceFrame, ephemerisTime); - - if (found){ - memcpy(glm::value_ptr(directionVector), dvec, sizeof(dvec)); - memcpy(glm::value_ptr(surfaceIntercept), spoint, sizeof(spoint)); - surfaceVector = srfvec; - } - return true; -} - // Not called at the moment @AA bool SpiceManager::getTargetState(const std::string& target, const std::string& observer, @@ -1076,6 +1004,110 @@ void SpiceManager::findSpkCoverage(const std::string& path) { } } } + +glm::dvec3 SpiceManager::getEstimatedPosition(const std::string& target, + const std::string& observer, + const std::string& referenceFrame, + AberrationCorrection aberrationCorrection, + double ephemerisTime, + double& lightTime) const +{ + ghoul_assert(!target.empty(), "Target must not be empty"); + ghoul_assert(!observer.empty(), "Observer must not be empty"); + ghoul_assert(!referenceFrame.empty(), "Reference frame must not be empty"); + ghoul_assert(target != observer, "Target and observer must be different"); + + int targetId = naifId(target); + + if (targetId == 0) { + // SOLAR SYSTEM BARYCENTER special case, no definition in kernels + return glm::dvec3(0.0); + } + + if (_spkCoverageTimes.find(targetId) == _spkCoverageTimes.end()) { + // no coverage + throw SpiceKernelException(format("No position for '{}' at any time", target)); + } + + + int observerId = naifId(observer); + std::set coveredTimes = _spkCoverageTimes.find(targetId)->second; + + glm::dvec3 pos; + if (coveredTimes.lower_bound(ephemerisTime) == coveredTimes.begin()) { + // coverage later, fetch first position + spkpos_c( + target.c_str(), + *(coveredTimes.begin()), + referenceFrame.c_str(), + aberrationCorrection, + observer.c_str(), + glm::value_ptr(pos), + &lightTime + ); + throwOnSpiceError(format( + "Error estimating position for target '{}' with observer '{}' in frame '{}'", + target, observer, referenceFrame + )); + } + else if (coveredTimes.upper_bound(ephemerisTime) == coveredTimes.end()) { + // coverage earlier, fetch last position + spkpos_c( + target.c_str(), + *(coveredTimes.rbegin()), + referenceFrame.c_str(), + aberrationCorrection, + observer.c_str(), + glm::value_ptr(pos), + &lightTime + ); + throwOnSpiceError(format( + "Error estimating position for target '{}' with observer '{}' in frame '{}'", + target, observer, referenceFrame + )); + } + else { + // coverage both earlier and later, interpolate these positions + glm::dvec3 posEarlier; + double ltEarlier; + double timeEarlier = *std::prev((coveredTimes.lower_bound(ephemerisTime))); + spkpos_c( + target.c_str(), + timeEarlier, + referenceFrame.c_str(), + aberrationCorrection, + observer.c_str(), + glm::value_ptr(posEarlier), + <Earlier + ); + + glm::dvec3 posLater; + double ltLater; + double timeLater = *(coveredTimes.upper_bound(ephemerisTime)); + spkpos_c( + target.c_str(), + timeLater, + referenceFrame.c_str(), + aberrationCorrection, + observer.c_str(), + glm::value_ptr(posLater), + <Later + ); + throwOnSpiceError(format( + "Error estimating position for target '{}' with observer '{}' in frame '{}'", + target, observer, referenceFrame + )); + + // linear interpolation + double timeDifference = timeLater - timeEarlier; + double t = (ephemerisTime - timeEarlier) / timeDifference; + pos = posEarlier * (1.0 - t) + posLater * t; + lightTime = ltEarlier * (1.0 - t) + ltLater * t; + } + + return pos; } + +} // namespace openspace From 2c84368b0b98244dec6980e24cb52c030bbdd46c Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Thu, 19 Nov 2015 23:35:09 -0500 Subject: [PATCH 042/122] More cleaning of SpiceManager --- include/openspace/util/spicemanager.h | 368 +++++++------ modules/base/ephemeris/spiceephemeris.cpp | 3 +- .../renderableconstellationbounds.cpp | 5 +- modules/base/rendering/renderablemodel.cpp | 9 +- modules/base/rendering/renderablepath.cpp | 2 +- modules/base/rendering/renderableplanet.cpp | 4 +- .../rendering/renderablesphericalgrid.cpp | 5 +- modules/base/rendering/renderabletrail.cpp | 10 +- .../rendering/renderablecrawlingline.cpp | 3 +- .../newhorizons/rendering/renderablefov.cpp | 117 +++- modules/newhorizons/rendering/renderablefov.h | 1 - .../rendering/renderablemodelprojection.cpp | 11 +- .../rendering/renderableplaneprojection.cpp | 6 +- .../rendering/renderableplanetprojection.cpp | 6 +- .../rendering/renderableshadowcylinder.cpp | 6 +- modules/newhorizons/util/hongkangparser.cpp | 14 +- src/rendering/renderengine.cpp | 2 +- src/util/spicemanager.cpp | 500 +++++++++--------- 18 files changed, 588 insertions(+), 484 deletions(-) diff --git a/include/openspace/util/spicemanager.h b/include/openspace/util/spicemanager.h index cb0ce77afa..e01f29e51e 100644 --- a/include/openspace/util/spicemanager.h +++ b/include/openspace/util/spicemanager.h @@ -115,6 +115,12 @@ public: Direction direction = Direction::Reception; }; + /// The possible values for the method parameter of the targetInFieldOfView method + enum class FieldOfViewMethod { + Ellipsoid = 0, + Point + }; + /** * Loads one or more SPICE kernels into a program. The provided path can either be a * binary, text-kernel, or meta-kernel which gets loaded into the kernel pool. The @@ -448,192 +454,218 @@ public: glm::dmat3 frameTransformationMatrix(const std::string& from, const std::string& to, double ephemerisTime) const; + /// Struct that is used as the return value from the #getSurfaceIntercept method + struct SurfaceInterceptResult { + /** + * The closest surface intercept point on the target body in Cartesian Coordinates + * relative to the reference frame. + */ + glm::dvec3 surfaceIntercept; + + /** + * If the aberration correction is not AberrationCorrection::Type::None, this + * value contains the time for which the intercept was computed. Otherwise it is + * the same as the ephemerisTime. + */ + double interceptEpoch; + + /** + * The vector from the observer's position to the \p surfaceIntercept position in + * the provided reference frame. + */ + glm::dvec3 surfaceVector; + + /// true if the ray intersects the body, false otherwise + bool interceptFound; + }; + /** - * Given an \p observer and a direction vector \p directionVector defining a ray, - * compute the surface intercept of the ray on a \p target body at a specified + * Given an \p observer and a probing direction vector \p directionVector defining a + * ray, compute the surface intercept of the ray on a \p target body at a specified * \p targetEpoch, optionally corrected for aberrations (\p aberrationCorrection). - * \param target Name of target body - * \param observer Name of observing body + * \param target The name of target body + * \param observer The name of the observer * \param fovFrame Reference frame of the ray's direction vector - * \param bodyFixedFrame Body-fixed, body-centered target body frame - * \param method Computation method - * \param aberrationCorrection Aberration correction + * \param referenceFrame The reference frame in which the surface intercept and the + * surface vector are expressed + * \param aberrationCorrection The aberration correction method that is applied to + * compute the intercept * \param ephemerisTime Intercept time in ephemeris seconds past J2000 TDB - * \param directionVector Ray's direction vector + * \param directionVector Probing ray's direction * \param surfaceIntercept Surface intercept point on the target body * \param surfaceVector Vector from observer to intercept point * \param isVisible Flag indicating whether intercept was found * \return true if not error occurred, false otherwise - * For further details, refer to - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/sincpt_c.html + * \throws SpiceKernelException If the \p target or \p observer do not name the same + * NAIF object, the \p target or \p observer name the same NAIF object or are in the + * same location, the \p referenceFrame or \p fovFrame are not recognized, + * insufficient kernel information has been loaded. + * \pre \p target must not be empty. + * \pre \p observer must not be empty. + * \pre \p The \p target and \p observer must be different strings + * \pre \p fovFrame must not be empty. + * \pre \p referenceFrame must not be empty. + * \pre \p directionVector must not be the null vector + * \post The SurfaceInterceptResult does not contain any uninitialized values. + * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/sincpt_c.html */ - bool getSurfaceIntercept(const std::string& target, - const std::string& observer, - const std::string& fovFrame, - const std::string& bodyFixedFrame, - AberrationCorrection aberrationCorrection, - double ephemerisTime, - glm::dvec3& directionVector, - glm::dvec3& surfaceIntercept, - glm::dvec3& surfaceVector, - bool& isVisible - ) const; + SurfaceInterceptResult getSurfaceIntercept(const std::string& target, + const std::string& observer, const std::string& fovFrame, + const std::string& referenceFrame, AberrationCorrection aberrationCorrection, + double ephemerisTime, const glm::dvec3& directionVector) const; /** - * Determine if a specified ephemeris object is within the - * field-of-view (FOV) of a specified instrument at a given time. - * \param instrument Name or ID code string of the instrument. - * \param target Name or ID code string of the target. - * \param observer Name or ID code string of the observer. - * \param aberrationCorrection Aberration correction method. - * \param method Type of shape model used for the target. - * \param referenceFrame Body-fixed, body-centered frame for target body. - * \param targetEpoch Time of the observation (seconds past J2000). - * \param isVisible true if the target is visible - * \return The success of the function - * For further detail, refer to - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/fovtrg_c.html + * Determine whether a specific \p target is in the field-of-view of a specified + * \p instrument or an \p observer at a given time, using the reference frame + * \p referenceFrame. + * \param target The name or NAIF ID code string of the target + * \param observer The name or NAIF ID code string of the observer + * \param referenceFrame Body-fixed, body-centered frame for target body + * \param instrument The name or NAIF ID code string of the instrument + * \param method The type of shape model used for the target + * \param aberrationCorrection The aberration correction method + * \param ephemerisTime Time of the observation (seconds past J2000) + * \return true if the target is visible, false otherwise + * \throws SpiceKernelException If the \p target or \p observer do not name valid + * NAIF objects, the \p target or \p observer name the same NAIF object, the + * \p instrument does not name a valid NAIF object, or insufficient kernel information + * has been loaded. + * \pre \p target must not be empty. + * \pre \p observer must not be empty. + * \pre \p target and \p observer must not be different strings + * \pre \p referenceFrame must not be empty. + * \pre \p instrument must not be empty. + * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/fovtrg_c.html */ - bool targetWithinFieldOfView(const std::string& instrument, - const std::string& target, - const std::string& observer, - const std::string& method, - const std::string& referenceFrame, - const std::string& aberrationCorrection, - double& targetEpoch, - bool& isVisible - ) const; + bool isTargetInFieldOfView(const std::string& target, const std::string& observer, + const std::string& referenceFrame, const std::string& instrument, + FieldOfViewMethod method, AberrationCorrection aberrationCorrection, + double& ephemerisTime) const; + /** - * This method performs the same computation as the function its overloading - * with the exception that in doing so it assumes the inertial bodyfixed frame - * is that of 'IAU' type, allowing the client to omitt the - * referenceFrame for planetary objects. + * Determine whether a specific \p target is in the field-of-view of a specified + * \p instrument or an \p observer at a given time. The reference frame used is + * derived from the \p target by converting it into an IAU inertial + * reference frame. + * \param target The name or NAIF ID code string of the target + * \param observer The name or NAIF ID code string of the observer + * \param instrument The name or NAIF ID code string of the instrument + * \param method The type of shape model used for the target + * \param aberrationCorrection The aberration correction method + * \param ephemerisTime Time of the observation (seconds past J2000) + * \return true if the target is visible, false otherwise + * \throws SpiceKernelException If the \p target or \p observer do not name valid + * NAIF objects, the \p target or \p observer name the same NAIF object, the + * \p instrument does not name a valid NAIF object, or insufficient kernel information + * has been loaded. + * \pre \p target must not be empty. + * \pre \p observer must not be empty. + * \pre \p target and \p observer must not be different strings + * \pre \p referenceFrame must not be empty. + * \pre \p instrument must not be empty. + * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/fovtrg_c.html */ - bool targetWithinFieldOfView(const std::string& instrument, - const std::string& target, - const std::string& observer, - const std::string& method, - const std::string& aberrationCorrection, - double& targetEpoch, - bool& isVisible - ) const; - + bool isTargetInFieldOfView(const std::string& target, const std::string& observer, + const std::string& instrument, FieldOfViewMethod method, + AberrationCorrection aberrationCorrection, double& ephemerisTime) const; + + /// Struct that is used as the return value from the #getTargetState method + struct TargetStateResult { + /// The target position + glm::dvec3 position; + + /// The target velocity + glm::dvec3 velocity; + + /// One-way light time between target and observer if + /// the aberration correction is enabled + double lightTime; + }; + /** - * Returns the state vector (position and velocity) of a - * target body relative to an observer in a specific - * referenceFrame, optionally corrected for light time (planetary - * aberration) and stellar aberration (aberrationCorrection). For further - * details, refer to - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/spkezr_c.html. For more - * information on NAIF IDs, refer to - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html + * 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 * \param observer The observing body name or the observing body's NAIF ID * \param referenceFrame The reference frame of the output position vector - * \param aberrationCorrection The aberration correction flag out of the list of - * values (NONE, LT, LT+S, CN, - * CN+S for the reception case or XLT, XLT+S, - * XCN, or XCN+S for the transmission case. + * \param aberrationCorrection The aberration correction method * \param ephemerisTime The time at which the position is to be queried - * \param position The output containing the position of the target; if the method - * fails, the position is unchanged - * \param velocity The output containing the velocity of the target; if the method - * fails, the velocity is unchanged - * \param lightTime If the aberrationCorrection is different from - * NONE, this variable will contain the one-way light time between the - * observer and the target.If the method fails, the lightTime is unchanged - * \return true if the function was successful, false - * otherwise + * \return A TargetStateResult object that contains the position>, containing + * the position of the target; the velocity, containing the velocity of + * the target; and the lightTime, containing the one-way light time + * between the \p target and the \p observer. This method is only set if the + * \p aberrationCorrection is set to a valid different from AberrationCorrection::None + * \throws SpiceKernelException If the \p target or \p observer do not name a valid + * NAIF object, the \p referenceFrame is not a valid frame, or if there is + * insufficient kernel information. + * \pre \p target must not be empty. + * \pre \p observer must not be empty. + * \pre \p referenceFrame must not be empty. + * \post The resulting TargetStateResult is set to valid values; the + * lightTime is only set to a valid different from 0.0 if + * the \p aberrationCorrection is not AberrationCorrection::None. + * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/spkezr_c.html + * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html */ - bool getTargetState(const std::string& target, - const std::string& observer, - const std::string& referenceFrame, - const std::string& aberrationCorrection, - double ephemerisTime, - glm::dvec3& position, - glm::dvec3& velocity, - double& lightTime) const; - - bool getTargetState(const std::string& target, - const std::string& observer, - const std::string& referenceFrame, - const std::string& aberrationCorrection, - double ephemerisTime, - PowerScaledCoordinate& position, - PowerScaledCoordinate& velocity, - double& lightTime) const; + TargetStateResult getTargetState(const std::string& target, + const std::string& observer, const std::string& referenceFrame, + AberrationCorrection aberrationCorrection, double ephemerisTime) const; /** - * Returns the state transformation matrix used to convert from one frame to another - * at a specified ephemerisTime. For further details, please refer to - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/sxform_c.html. + * 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 + * \param destinationFrame The name of the destination reference frame + * \param ephemerisTime The time for which the transformation matrix should be + * returned + * \return The TransformMatrix containing the transformation matrix that defines the + * transformation from the \p sourceFrame to the \p destinationFrame + * \throws SpiceKernelException If the \p sourceFrame or the \p destinationFrame is + * not a valid frame + * \pre \p sourceFrame must not be empty. + * \pre \p destinatoinFrame must not be empty. + * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/sxform_c.html + */ + TransformMatrix getStateTransformMatrix(const std::string& sourceFrame, + const std::string& destinationFrame, double ephemerisTime) const; + + /** + * Returns the matrix that transforms position vectors from the source reference frame + * \p sourceFrame to the destination reference frame \p destinationFrame at the + * specific \p ephemerisTime. * \param sourceFrame The name of the source reference frame * \param destinationFrame The name of the destination reference frame * \param ephemerisTime The time at which the transformation matrix is to be queried - * \param transformationMatrix The output containing the TransformMatrix containing - * the transformation matrix that defines the transformation from the - * sourceFrame to the destinationFrame. If the method fails - * the transformationMatrix is unchanged - * \return true if the function was successful, false - * otherwise + * \return The transformation matrix that defines the transformation from the + * \p sourceFrame to the \p destinationFrame + * \throws SpiceKernelException If there is no coverage available for the specified + * \p sourceFrame, \p destinationFrame, \p ephemerisTime combination + * \pre \p sourceFrame must not be empty + * \pre \p destinationFrame must not be empty + * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/pxform_c.html */ - bool getStateTransformMatrix(const std::string& sourceFrame, - const std::string& destinationFrame, - double ephemerisTime, - TransformMatrix& transformationMatrix) const; + glm::dmat3 getPositionTransformMatrix(const std::string& sourceFrame, + const std::string& destinationFrame, double ephemerisTime) const; /** - * Returns the matrix that transforms position vectors from one reference frame to - * another at a specified ephemerisTime. For further details, please refer to - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/pxform_c.html. + * Returns the transformation matrix that transforms position vectors from the + * \p sourceFrame at the time \p ephemerisTimeFrom to the \p destinationFrame at the + * time \p ephemerisTimeTo. * \param sourceFrame The name of the source reference frame * \param destinationFrame The name of the destination reference frame - * \param ephemerisTime The time at which the transformation matrix is to be queried - * \param transformationMatrix The output containing the transformation matrix that - * defines the transformation from the sourceFrame to the - * destinationFrame. If the method fails the - * transformationMatrix is unchanged - * \return true if the function was successful, false - * otherwise + * \param ephemerisTimeFrom The time for the source reference frame + * \param ephemerisTimeTo The time for the destination reference frame + * \return Thetransformation matrix that maps between the \p sourceFrame at time + * \p ephemerisTimeFrom to the \p destinationFrame at the time \p ephemerisTimeTo. + * \throws SpiceKernelException If there is no coverage available for the specified + * \p sourceFrame and \p destinationFrame + * \pre \p sourceFrame must not be empty. + * \pre \p destinationFrame must not be empty. */ - bool getPositionTransformMatrix(const std::string& sourceFrame, - const std::string& destinationFrame, - double ephemerisTime, - glm::dmat3& transformationMatrix) const; - - /** - * The following overloaded function performs similar to its default - the exception being - * that it computes transformationMatrix with respect to local time offset - * between an observer and its target. This allows for the accountance of light travel of - * photons, e.g to account for instrument pointing offsets due to said phenomenon. - * \param sourceFrame The name of the source reference frame - * \param destinationFrame The name of the destination reference frame - * \param ephemerisTimeFrom Recorded/observed observation time - * \param ephemerisTimeTo Emission local target-time - * \param transformationMatrix The output containing the transformation matrix that - */ - - bool getPositionTransformMatrix(const std::string& sourceFrame, - const std::string& destinationFrame, - double ephemerisTimeFrom, - double ephemerisTimeTo, - glm::dmat3& transformationMatrix) const; - - /** - * If a transform matrix is requested for an uncovered time in the CK kernels, - * this function will insert a transform matrix in positionMatrix. - * If the coverage has not yet started, the first transform matrix will be retrieved, - * If the coverage has ended, the last transform matrix will be retrieved - * If time is in a coverage gap, the transform matrix will be interpolated - * \param time, for which an estimated transform matrix is desirable - * \param fromFrame, the transform matrix will be retrieved in relation to this frame - * \param toFrame, the frame missing CK data for this time - * \param positionMatrix, the estimated transform matrix of the frame, passed by reference - * \return true if an estimated transform matrix is found - */ - bool getEstimatedTransformMatrix(const double time, const std::string fromFrame, const std::string toFrame, glm::dmat3& positionMatrix) const; - - + glm::dmat3 getPositionTransformMatrix(const std::string& sourceFrame, + const std::string& destinationFrame, double ephemerisTimeFrom, + double ephemerisTimeTo) const; /** * Applies the transformationMatrix retrieved from @@ -823,9 +855,29 @@ private: * \post If an exception is thrown, \p lightTime will not be modified */ glm::dvec3 getEstimatedPosition(const std::string& target, - const std::string& observer, const std::string& referenceFrame, - AberrationCorrection aberrationCorrection, double ephemerisTime, - double& lightTime) const; + const std::string& observer, const std::string& referenceFrame, + AberrationCorrection aberrationCorrection, double ephemerisTime, + double& lightTime) const; + + /** + * If a transform matrix is requested for an uncovered time in the CK kernels, this + * function will an estimated matrix. If the coverage has not yet started, the first + * transform matrix will be retrieved. If the coverage has ended, the last transform + * matrix will be retrieved. If time is in a coverage gap, the transform + * matrix will be interpolated. + * \param fromFrame The transform matrix will be retrieved in relation to this frame + * \param toFrame The reference frame into which the resulting matrix will transformed + * \param time The time for which an estimated transform matrix is requested + * \return The estimated transform matrix of the frame + * \throws SpiceKernelException If there is no coverage available for the specified + * \p sourceFrame and \p destinationFrame or the reference frames do not name a valid + * NAIF frame. + * \pre \p fromFrame must not be empty + * \pre \p toFrame must not be empty + */ + glm::dmat3 getEstimatedTransformMatrix(const std::string& fromFrame, + const std::string& toFrame, double time) const; + /// A list of all loaded kernels std::vector _loadedKernels; diff --git a/modules/base/ephemeris/spiceephemeris.cpp b/modules/base/ephemeris/spiceephemeris.cpp index 85e12f474f..e687a512e2 100644 --- a/modules/base/ephemeris/spiceephemeris.cpp +++ b/modules/base/ephemeris/spiceephemeris.cpp @@ -82,8 +82,7 @@ void SpiceEphemeris::update(const UpdateData& data) { return; double lightTime = 0.0; - glm::dvec3 position = SpiceManager::ref().targetPosition(_targetName, _originName, - "GALACTIC", SpiceManager::AberrationCorrection(), data.time, lightTime); + glm::dvec3 position = SpiceManager::ref().targetPosition(_targetName, _originName, "GALACTIC", {}, data.time, lightTime); //double interval = openspace::ImageSequencer2::ref().getIntervalLength(); //if (_ghosting == "TRUE" && interval > 60){ diff --git a/modules/base/rendering/renderableconstellationbounds.cpp b/modules/base/rendering/renderableconstellationbounds.cpp index 52fa9785a7..558803e3ae 100644 --- a/modules/base/rendering/renderableconstellationbounds.cpp +++ b/modules/base/rendering/renderableconstellationbounds.cpp @@ -179,11 +179,10 @@ void RenderableConstellationBounds::update(const UpdateData& data) { if (_program->isDirty()) _program->rebuildFromFile(); - SpiceManager::ref().getPositionTransformMatrix( + _stateMatrix = SpiceManager::ref().getPositionTransformMatrix( _originReferenceFrame, "GALACTIC", - data.time, - _stateMatrix + data.time ); } diff --git a/modules/base/rendering/renderablemodel.cpp b/modules/base/rendering/renderablemodel.cpp index d76787cf3b..db13df15ae 100644 --- a/modules/base/rendering/renderablemodel.cpp +++ b/modules/base/rendering/renderablemodel.cpp @@ -184,7 +184,7 @@ void RenderableModel::render(const RenderData& data) { _alpha = 1.0f; glm::dvec3 p = - SpiceManager::ref().targetPosition(_target, "SUN", "GALACTIC", SpiceManager::AberrationCorrection(), time, lt); + SpiceManager::ref().targetPosition(_target, "SUN", "GALACTIC", {}, time, lt); psc tmppos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); glm::vec3 cam_dir = glm::normalize(data.camera.position().vec3() - tmppos.vec3()); _programObject->setUniform("cam_dir", cam_dir); @@ -242,12 +242,13 @@ void RenderableModel::update(const UpdateData& data) { //} // set spice-orientation in accordance to timestamp - if (!_source.empty()) - openspace::SpiceManager::ref().getPositionTransformMatrix(_source, _destination, _time, _stateMatrix); + if (!_source.empty()) { + _stateMatrix = SpiceManager::ref().getPositionTransformMatrix(_source, _destination, _time); + } double lt; glm::dvec3 p = - openspace::SpiceManager::ref().targetPosition("SUN", _target, "GALACTIC", SpiceManager::AberrationCorrection(), _time, lt); + openspace::SpiceManager::ref().targetPosition("SUN", _target, "GALACTIC", {}, _time, lt); _sunPosition = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); } diff --git a/modules/base/rendering/renderablepath.cpp b/modules/base/rendering/renderablepath.cpp index 784caa4ba2..ebefd57a2e 100644 --- a/modules/base/rendering/renderablepath.cpp +++ b/modules/base/rendering/renderablepath.cpp @@ -223,7 +223,7 @@ void RenderablePath::calculatePath(std::string observer) { //float b = _lineColor[2]; for (int i = 0; i < segments; i++) { glm::dvec3 p = - SpiceManager::ref().targetPosition(_target, observer, _frame, SpiceManager::AberrationCorrection(), currentTime, lightTime); + SpiceManager::ref().targetPosition(_target, observer, _frame, {}, currentTime, lightTime); pscPos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); pscPos[3] += 3; diff --git a/modules/base/rendering/renderableplanet.cpp b/modules/base/rendering/renderableplanet.cpp index 7ef837325c..9f074f0365 100644 --- a/modules/base/rendering/renderableplanet.cpp +++ b/modules/base/rendering/renderableplanet.cpp @@ -183,7 +183,7 @@ void RenderablePlanet::render(const RenderData& data) double lt; glm::dvec3 p = - SpiceManager::ref().targetPosition("SUN", _target, "GALACTIC", SpiceManager::AberrationCorrection(), _time, lt); + SpiceManager::ref().targetPosition("SUN", _target, "GALACTIC", {}, _time, lt); psc sun_pos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); // setup the data to the shader @@ -217,7 +217,7 @@ void RenderablePlanet::render(const RenderData& data) void RenderablePlanet::update(const UpdateData& data){ // set spice-orientation in accordance to timestamp - openspace::SpiceManager::ref().getPositionTransformMatrix(_frame, "GALACTIC", data.time, _stateMatrix); + _stateMatrix = SpiceManager::ref().getPositionTransformMatrix(_frame, "GALACTIC", data.time); _time = data.time; } diff --git a/modules/base/rendering/renderablesphericalgrid.cpp b/modules/base/rendering/renderablesphericalgrid.cpp index a1d0bce088..ff35d37c16 100644 --- a/modules/base/rendering/renderablesphericalgrid.cpp +++ b/modules/base/rendering/renderablesphericalgrid.cpp @@ -227,9 +227,8 @@ void RenderableSphericalGrid::render(const RenderData& data){ _gridProgram->deactivate(); } -void RenderableSphericalGrid::update(const UpdateData& data){ - - openspace::SpiceManager::ref().getPositionTransformMatrix("IAU_JUPITER", "GALACTIC", data.time, _parentMatrix); +void RenderableSphericalGrid::update(const UpdateData& data) { + _parentMatrix = SpiceManager::ref().getPositionTransformMatrix("IAU_JUPITER", "GALACTIC", data.time); } } \ No newline at end of file diff --git a/modules/base/rendering/renderabletrail.cpp b/modules/base/rendering/renderabletrail.cpp index 9ce516c87b..4bb2d5b9f8 100644 --- a/modules/base/rendering/renderabletrail.cpp +++ b/modules/base/rendering/renderabletrail.cpp @@ -219,11 +219,11 @@ void RenderableTrail::update(const UpdateData& data) { glm::dvec3 p; // Update the floating current time if (start > data.time) - p = SpiceManager::ref().targetPosition(_target, _observer, _frame, SpiceManager::AberrationCorrection(), start, lightTime); + p = SpiceManager::ref().targetPosition(_target, _observer, _frame, {}, start, lightTime); else if (end < data.time) - p = SpiceManager::ref().targetPosition(_target, _observer, _frame, SpiceManager::AberrationCorrection(), end, lightTime); + p = SpiceManager::ref().targetPosition(_target, _observer, _frame, {}, end, lightTime); else - p = SpiceManager::ref().targetPosition(_target, _observer, _frame, SpiceManager::AberrationCorrection(), data.time, lightTime); + p = SpiceManager::ref().targetPosition(_target, _observer, _frame, {}, data.time, lightTime); psc pscPos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); @@ -247,7 +247,7 @@ void RenderableTrail::update(const UpdateData& data) { else if (end < et) et = end; glm::dvec3 p = - SpiceManager::ref().targetPosition(_target, _observer, _frame, SpiceManager::AberrationCorrection(), et, lightTime); + SpiceManager::ref().targetPosition(_target, _observer, _frame, {}, et, lightTime); pscPos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); pscPos[3] += 3; _vertexArray[i] = { pscPos[0], pscPos[1], pscPos[2], pscPos[3] }; @@ -300,7 +300,7 @@ void RenderableTrail::fullYearSweep(double time) { try { p = - SpiceManager::ref().targetPosition(_target, _observer, _frame, SpiceManager::AberrationCorrection(), time, lightTime); + SpiceManager::ref().targetPosition(_target, _observer, _frame, {}, time, lightTime); } catch (const SpiceManager::SpiceKernelException& e) { // This fires for PLUTO BARYCENTER and SUN and uses the only value sometimes? diff --git a/modules/newhorizons/rendering/renderablecrawlingline.cpp b/modules/newhorizons/rendering/renderablecrawlingline.cpp index cfe9d7d6a2..2ed7a2aa49 100644 --- a/modules/newhorizons/rendering/renderablecrawlingline.cpp +++ b/modules/newhorizons/rendering/renderablecrawlingline.cpp @@ -148,8 +148,7 @@ void RenderableCrawlingLine::render(const RenderData& data) { void RenderableCrawlingLine::update(const UpdateData& data) { if (_program->isDirty()) _program->rebuildFromFile(); - glm::dmat3 transformMatrix = glm::dmat3(1); - openspace::SpiceManager::ref().getPositionTransformMatrix(_source, _referenceFrame, data.time, transformMatrix); + glm::dmat3 transformMatrix = SpiceManager::ref().getPositionTransformMatrix(_source, _referenceFrame, data.time); glm::mat4 tmp = glm::mat4(1); for (int i = 0; i < 3; i++) { diff --git a/modules/newhorizons/rendering/renderablefov.cpp b/modules/newhorizons/rendering/renderablefov.cpp index 1d0f6c5ffb..9649a5036b 100644 --- a/modules/newhorizons/rendering/renderablefov.cpp +++ b/modules/newhorizons/rendering/renderablefov.cpp @@ -78,8 +78,8 @@ RenderableFov::RenderableFov(const ghoul::Dictionary& dictionary) success = dictionary.getValue(keyInstrument, _instrumentID); ghoul_assert(success, ""); - success = dictionary.getValue(keyInstrumentMethod, _method); - ghoul_assert(success, ""); +// success = dictionary.getValue(keyInstrumentMethod, _method); +// ghoul_assert(success, ""); std::string a = "NONE"; success = dictionary.getValue(keyInstrumentAberration, a); @@ -231,11 +231,24 @@ glm::dvec3 RenderableFov::interpolate(glm::dvec3 p0, glm::dvec3 p1, float t) { // This method is the current bottleneck. psc RenderableFov::checkForIntercept(glm::dvec3 ray) { - bool intercepted = false; - openspace::SpiceManager::ref().getSurfaceIntercept(_fovTarget, _spacecraft, _instrumentID, - _frame, _aberrationCorrection, - _time, ray, ipoint, ivec, intercepted); - + std::string bodyfixed = "IAU_"; + bool convert = (_frame.find(bodyfixed) == std::string::npos); + if (convert) + bodyfixed = SpiceManager::ref().frameFromBody(_fovTarget); + else + bodyfixed = _frame; + + SpiceManager::SurfaceInterceptResult result = SpiceManager::ref().getSurfaceIntercept( + _fovTarget, _spacecraft, _instrumentID, bodyfixed, _aberrationCorrection, _time, ray); + + if (convert) { + result.surfaceVector = SpiceManager::ref().frameTransformationMatrix(bodyfixed, _frame, _time) * result.surfaceVector; + } + + ipoint = result.surfaceIntercept; + ivec = result.surfaceVector; + bool intercepted = result.interceptFound; + ivec *= 0.9999;// because fov lands exactly on top of surface we need to move it out slightly _interceptVector = PowerScaledCoordinate::CreatePowerScaledCoordinate(ivec[0], ivec[1], ivec[2]); _interceptVector[3] += 3; @@ -258,10 +271,26 @@ psc RenderableFov::orthogonalProjection(glm::dvec3 vecFov) { glm::dvec3 RenderableFov::bisection(glm::dvec3 p1, glm::dvec3 p2, double tolerance) { //check if point is on surface glm::dvec3 half = interpolate(p1, p2, 0.5f); - bool intercepted = false; - openspace::SpiceManager::ref().getSurfaceIntercept(_fovTarget, _spacecraft, _instrumentID, - _frame, _aberrationCorrection, - _time, half, ipoint, ivec, intercepted); + + std::string bodyfixed = "IAU_"; + bool convert = (_frame.find(bodyfixed) == std::string::npos); + if (convert) + bodyfixed = SpiceManager::ref().frameFromBody(_fovTarget); + else + bodyfixed = _frame; + + + SpiceManager::SurfaceInterceptResult result = SpiceManager::ref().getSurfaceIntercept( + _fovTarget, _spacecraft, _instrumentID, bodyfixed, _aberrationCorrection, _time, half); + + if (convert) { + result.surfaceVector = SpiceManager::ref().frameTransformationMatrix(bodyfixed, _frame, _time) * result.surfaceVector; + } + + ipoint = result.surfaceIntercept; + ivec = result.surfaceVector; + bool intercepted = result.interceptFound; + if (glm::distance(_previousHalf, half) < tolerance){ _previousHalf = glm::dvec3(0); return half; @@ -301,10 +330,28 @@ void RenderableFov::fovSurfaceIntercept(bool H[], std::vector bounds // IFF incident point is also non-interceptive BUT something is within FOV // we need then to check if this segment makes contact with surface glm::dvec3 half = interpolate(current, next, 0.5f); - bool intercepted; - openspace::SpiceManager::ref().getSurfaceIntercept(_fovTarget, _spacecraft, _instrumentID, - _frame, _aberrationCorrection, - _time, half, ipoint, ivec, intercepted); + + std::string bodyfixed = "IAU_"; + bool convert = (_frame.find(bodyfixed) == std::string::npos); + if (convert) + bodyfixed = SpiceManager::ref().frameFromBody(_fovTarget); + else + bodyfixed = _frame; + + + SpiceManager::SurfaceInterceptResult res = + SpiceManager::ref().getSurfaceIntercept(_fovTarget, _spacecraft, + _instrumentID, bodyfixed, _aberrationCorrection, _time, half); + + if (convert) { + res.surfaceVector = SpiceManager::ref().frameTransformationMatrix(bodyfixed, _frame, _time) * res.surfaceVector; + } + + ipoint = res.surfaceIntercept; + ivec = res.surfaceVector; + bool intercepted = res.interceptFound; + + if (intercepted){ // find the two outer most points of intersection glm::dvec3 root1 = bisection(half, current, tolerance); @@ -396,15 +443,15 @@ void RenderableFov::computeColors() { void RenderableFov::determineTarget(){ _fovTarget = _potentialTargets[0]; //default; for (int i = 0; i < _potentialTargets.size(); i++){ - bool success = openspace::SpiceManager::ref().targetWithinFieldOfView( + _withinFOV = openspace::SpiceManager::ref().isTargetInFieldOfView( + _potentialTargets[i], _spacecraft, + _instrumentID, - _potentialTargets[i], - _spacecraft, - _method, - std::string(_aberrationCorrection), - _time, - _withinFOV); - if (success && _withinFOV){ + SpiceManager::FieldOfViewMethod::Ellipsoid, + _aberrationCorrection, + _time + ); + if (_withinFOV){ _fovTarget = _potentialTargets[i]; break; } @@ -417,9 +464,25 @@ void RenderableFov::computeIntercepts(const RenderData& data){ for (int i = 0; i <= _bounds.size(); i++){ int r = (i == _bounds.size()) ? 0 : i; // compute surface intercept - openspace::SpiceManager::ref().getSurfaceIntercept(_fovTarget, _spacecraft, _instrumentID, - _frame, _aberrationCorrection, - _time, _bounds[r], ipoint, ivec, _interceptTag[r]); + std::string bodyfixed = "IAU_"; + bool convert = (_frame.find(bodyfixed) == std::string::npos); + if (convert) + bodyfixed = SpiceManager::ref().frameFromBody(_fovTarget); + else + bodyfixed = _frame; + + SpiceManager::SurfaceInterceptResult res = + SpiceManager::ref().getSurfaceIntercept(_fovTarget, _spacecraft, + _instrumentID, bodyfixed, _aberrationCorrection, _time, _bounds[r]); + + if (convert) { + res.surfaceVector = SpiceManager::ref().frameTransformationMatrix(bodyfixed, _frame, _time) * res.surfaceVector; + } + + ipoint = res.surfaceIntercept; + ivec = res.surfaceVector; + _interceptTag[r] = res.interceptFound; + // if not found, use the orthogonal projected point if (!_interceptTag[r]) _projectionBounds[r] = orthogonalProjection(_bounds[r]); @@ -510,7 +573,7 @@ void RenderableFov::render(const RenderData& data) { void RenderableFov::update(const UpdateData& data) { _time = data.time; - openspace::SpiceManager::ref().getPositionTransformMatrix(_instrumentID, _frame, data.time, _stateMatrix); + _stateMatrix = SpiceManager::ref().getPositionTransformMatrix(_instrumentID, _frame, data.time); _spacecraftRotation = glm::mat4(1); for (int i = 0; i < 3; i++){ for (int j = 0; j < 3; j++){ diff --git a/modules/newhorizons/rendering/renderablefov.h b/modules/newhorizons/rendering/renderablefov.h index d1290351f7..2327dc6cf6 100644 --- a/modules/newhorizons/rendering/renderablefov.h +++ b/modules/newhorizons/rendering/renderablefov.h @@ -96,7 +96,6 @@ public: std::string _observer; std::string _frame; std::string _instrumentID; - std::string _method; SpiceManager::AberrationCorrection _aberrationCorrection; std::string _fovTarget; glm::dvec3 ipoint, ivec; diff --git a/modules/newhorizons/rendering/renderablemodelprojection.cpp b/modules/newhorizons/rendering/renderablemodelprojection.cpp index a2670285b0..d6d4eaa7a1 100644 --- a/modules/newhorizons/rendering/renderablemodelprojection.cpp +++ b/modules/newhorizons/rendering/renderablemodelprojection.cpp @@ -351,12 +351,13 @@ void RenderableModelProjection::update(const UpdateData& data) { } // set spice-orientation in accordance to timestamp - if (!_source.empty()) - openspace::SpiceManager::ref().getPositionTransformMatrix(_source, _destination, _time, _stateMatrix); + if (!_source.empty()) { + _stateMatrix = SpiceManager::ref().getPositionTransformMatrix(_source, _destination, _time); + } double lt; glm::dvec3 p = - openspace::SpiceManager::ref().targetPosition("SUN", _target, "GALACTIC", SpiceManager::AberrationCorrection(), _time, lt); + openspace::SpiceManager::ref().targetPosition("SUN", _target, "GALACTIC", {}, _time, lt); _sunPosition = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); } @@ -406,8 +407,8 @@ void RenderableModelProjection::imageProjectGPU() { } void RenderableModelProjection::attitudeParameters(double time) { - openspace::SpiceManager::ref().getPositionTransformMatrix(_source, _destination, time, _stateMatrix); - openspace::SpiceManager::ref().getPositionTransformMatrix(_instrumentID, _destination, time, _instrumentMatrix); + _stateMatrix = SpiceManager::ref().getPositionTransformMatrix(_source, _destination, time); + _instrumentMatrix = SpiceManager::ref().getPositionTransformMatrix(_instrumentID, _destination, time); _transform = glm::mat4(1); diff --git a/modules/newhorizons/rendering/renderableplaneprojection.cpp b/modules/newhorizons/rendering/renderableplaneprojection.cpp index 3d25ded0a4..552ad2d7b6 100644 --- a/modules/newhorizons/rendering/renderableplaneprojection.cpp +++ b/modules/newhorizons/rendering/renderableplaneprojection.cpp @@ -166,7 +166,7 @@ void RenderablePlaneProjection::update(const UpdateData& data) { else _hasImage = true; - openspace::SpiceManager::ref().getPositionTransformMatrix(_target.frame, GalacticFrame, time, _stateMatrix); + _stateMatrix = SpiceManager::ref().getPositionTransformMatrix(_target.frame, GalacticFrame, time); double timePast = abs(img.startTime - _previousTime); @@ -331,7 +331,7 @@ std::string RenderablePlaneProjection::findClosestTarget(double currentTime) { double lt; glm::dvec3 p = - SpiceManager::ref().targetPosition(_spacecraft, "SSB", GalacticFrame, SpiceManager::AberrationCorrection(), currentTime, lt); + SpiceManager::ref().targetPosition(_spacecraft, "SSB", GalacticFrame, {}, currentTime, lt); psc spacecraftPos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); @@ -341,7 +341,7 @@ std::string RenderablePlaneProjection::findClosestTarget(double currentTime) { if (possibleTarget != nullptr) { hasBody = possibleTarget->hasBody(); if (hasBody && possibleTarget->getBody(targetBody)) { - openspace::SpiceManager::ref().targetWithinFieldOfView(_instrument, targetBody, _spacecraft, "ELLIPSOID", "NONE", currentTime, found); + found = SpiceManager::ref().isTargetInFieldOfView(targetBody, _spacecraft, _instrument, SpiceManager::FieldOfViewMethod::Ellipsoid, {}, currentTime); if (found){ targets.push_back(node->name()); // get name from propertyOwner distance = (node->worldPosition() - spacecraftPos).length(); diff --git a/modules/newhorizons/rendering/renderableplanetprojection.cpp b/modules/newhorizons/rendering/renderableplanetprojection.cpp index 3bca6c46c6..4ee9f68761 100644 --- a/modules/newhorizons/rendering/renderableplanetprojection.cpp +++ b/modules/newhorizons/rendering/renderableplanetprojection.cpp @@ -408,8 +408,8 @@ glm::mat4 RenderablePlanetProjection::computeProjectorMatrix(const glm::vec3 loc void RenderablePlanetProjection::attitudeParameters(double time){ // precomputations for shader - openspace::SpiceManager::ref().getPositionTransformMatrix(_frame, _mainFrame, _time, _stateMatrix); - openspace::SpiceManager::ref().getPositionTransformMatrix(_instrumentID, _mainFrame, time, _instrumentMatrix); + _stateMatrix = SpiceManager::ref().getPositionTransformMatrix(_frame, _mainFrame, _time); + _instrumentMatrix = SpiceManager::ref().getPositionTransformMatrix(_instrumentID, _mainFrame, time); _transform = glm::mat4(1); //90 deg rotation w.r.t spice req. @@ -512,7 +512,7 @@ void RenderablePlanetProjection::render(const RenderData& data){ double lt; glm::dvec3 p = - openspace::SpiceManager::ref().targetPosition("SUN", _projecteeID, "GALACTIC", SpiceManager::AberrationCorrection(), _time, lt); + openspace::SpiceManager::ref().targetPosition("SUN", _projecteeID, "GALACTIC", {}, _time, lt); psc sun_pos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); // Main renderpass diff --git a/modules/newhorizons/rendering/renderableshadowcylinder.cpp b/modules/newhorizons/rendering/renderableshadowcylinder.cpp index 1e60f381c9..71d67d3ffd 100644 --- a/modules/newhorizons/rendering/renderableshadowcylinder.cpp +++ b/modules/newhorizons/rendering/renderableshadowcylinder.cpp @@ -132,7 +132,7 @@ void RenderableShadowCylinder::render(const RenderData& data){ } void RenderableShadowCylinder::update(const UpdateData& data) { - openspace::SpiceManager::ref().getPositionTransformMatrix(_bodyFrame, _mainFrame, data.time, _stateMatrix); + _stateMatrix = SpiceManager::ref().getPositionTransformMatrix(_bodyFrame, _mainFrame, data.time); _time = data.time; if (_shader->isDirty()) _shader->rebuildFromFile(); @@ -172,10 +172,8 @@ void RenderableShadowCylinder::createCylinder() { glm::dvec3 vecLightSource = SpiceManager::ref().targetPosition(_body, _lightSource, _mainFrame, _aberration, _time, lt); - glm::dmat3 _stateMatrix; - openspace::SpiceManager::ref().getPositionTransformMatrix(_bodyFrame, _mainFrame, _time, _stateMatrix); + glm::dmat3 _stateMatrix = glm::inverse(SpiceManager::ref().getPositionTransformMatrix(_bodyFrame, _mainFrame, _time)); - _stateMatrix = glm::inverse(_stateMatrix); vecLightSource = _stateMatrix * vecLightSource; vecLightSource *= _shadowLength; diff --git a/modules/newhorizons/util/hongkangparser.cpp b/modules/newhorizons/util/hongkangparser.cpp index 04be8da049..757bb6a0e4 100644 --- a/modules/newhorizons/util/hongkangparser.cpp +++ b/modules/newhorizons/util/hongkangparser.cpp @@ -286,14 +286,14 @@ bool HongKangParser::augmentWithSpice(Image& image, double time = image.startTime; for (int k = 0; k < exposureTime; k++){ time += k; - success = openspace::SpiceManager::ref().targetWithinFieldOfView( + _withinFOV = SpiceManager::ref().isTargetInFieldOfView( + potentialTargets[i], + spacecraft, image.activeInstruments[j], - potentialTargets[i], - spacecraft, - "ELLIPSOID", - "NONE", - time, - _withinFOV); + SpiceManager::FieldOfViewMethod::Ellipsoid, + {}, + time + ); if (_withinFOV){ image.target = potentialTargets[i]; _withinFOV = false; diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 64ec5b4b04..63f7d9cc2b 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -453,7 +453,7 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi double lt; glm::dvec3 p = - SpiceManager::ref().targetPosition("PLUTO", "NEW HORIZONS", "GALACTIC", SpiceManager::AberrationCorrection(), currentTime, lt); + SpiceManager::ref().targetPosition("PLUTO", "NEW HORIZONS", "GALACTIC", {}, currentTime, lt); psc nhPos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); float a, b, c; SpiceManager::ref().getPlanetEllipsoid("PLUTO", a, b, c); diff --git a/src/util/spicemanager.cpp b/src/util/spicemanager.cpp index 3e6e96e4f4..36d116a2a2 100644 --- a/src/util/spicemanager.cpp +++ b/src/util/spicemanager.cpp @@ -55,6 +55,15 @@ namespace { ); } } + + const char* toString(openspace::SpiceManager::FieldOfViewMethod m) { + switch (m) { + case openspace::SpiceManager::FieldOfViewMethod::Ellipsoid: + return "ELLIPSOID"; + case openspace::SpiceManager::FieldOfViewMethod::Point: + return "POINT"; + } + } } using fmt::format; @@ -506,290 +515,194 @@ glm::dmat3 SpiceManager::frameTransformationMatrix(const std::string& from, return glm::transpose(transform); } -bool SpiceManager::getSurfaceIntercept(const std::string& target, - const std::string& observer, - const std::string& fovFrame, - const std::string& referenceFrame, - AberrationCorrection aberrationCorrection, - double ephemerisTime, - glm::dvec3& directionVector, - glm::dvec3& surfaceIntercept, - glm::dvec3& surfaceVector, - bool& isVisible - ) const +SpiceManager::SurfaceInterceptResult SpiceManager::getSurfaceIntercept( + const std::string& target, const std::string& observer, const std::string& fovFrame, + const std::string& referenceFrame, AberrationCorrection aberrationCorrection, + double ephemerisTime, const glm::dvec3& directionVector) const { + ghoul_assert(!target.empty(), "Target must not be empty"); + ghoul_assert(!observer.empty(), "Observer must not be empty"); + ghoul_assert(target != observer, "Target and observer must be different"); + ghoul_assert(!fovFrame.empty(), "FOV frame must not be empty"); + ghoul_assert(!referenceFrame.empty(), "Reference frame must not be empty"); + ghoul_assert(directionVector != glm::dvec3(0.0), "Direction vector must not be zero"); + const std::string ComputationMethod = "ELLIPSOID"; - // make pretty latr - double dvec[3], spoint[3], et; - glm::dvec3 srfvec; - int found; - bool convert; - - dvec[0] = directionVector[0]; - dvec[1] = directionVector[1]; - dvec[2] = directionVector[2]; - - // allow client specify non-inertial frame. - std::string bodyfixed = "IAU_"; - convert = (referenceFrame.find(bodyfixed) == std::string::npos); - if (convert) { - bodyfixed = frameFromBody(target); - } else { - bodyfixed = referenceFrame; - } + SurfaceInterceptResult result; + SpiceBoolean found; sincpt_c(ComputationMethod.c_str(), - target.c_str(), - ephemerisTime, - bodyfixed.c_str(), - aberrationCorrection, - observer.c_str(), - fovFrame.c_str(), - dvec, - spoint, - &et, - glm::value_ptr(srfvec), - &found); + target.c_str(), + ephemerisTime, + referenceFrame.c_str(), + aberrationCorrection, + observer.c_str(), + fovFrame.c_str(), + glm::value_ptr(directionVector), + glm::value_ptr(result.surfaceIntercept), + &result.interceptEpoch, + glm::value_ptr(result.surfaceVector), + &found + ); + result.interceptFound = (found == SPICETRUE); - isVisible = (found == SPICETRUE); - - throwOnSpiceError("Error retrieving surface intercept on target '" + target + "'" + - "viewed from observer '" + observer + "' in " + - "reference frame '" + bodyfixed + "' at time '" + - std::to_string(ephemerisTime) + "'"); - - if (convert) - srfvec = SpiceManager::ref().frameTransformationMatrix(bodyfixed, referenceFrame, ephemerisTime) * srfvec; - - if (found){ - memcpy(glm::value_ptr(directionVector), dvec, sizeof(dvec)); - memcpy(glm::value_ptr(surfaceIntercept), spoint, sizeof(spoint)); - surfaceVector = srfvec; - } - return true; + throwOnSpiceError(format( + "Error retrieving surface intercept on target '{}' viewed from observer '{}' in " + "reference frame '{}' at time '{}'", + target, observer, referenceFrame, ephemerisTime + )); + + return result; } - -bool SpiceManager::targetWithinFieldOfView(const std::string& instrument, - const std::string& target, - const std::string& observer, - const std::string& method, - const std::string& referenceFrame, - const std::string& aberrationCorrection, - double& targetEpoch, - bool& isVisible - ) const +bool SpiceManager::isTargetInFieldOfView(const std::string& target, + const std::string& observer, const std::string& referenceFrame, + const std::string& instrument, FieldOfViewMethod method, + AberrationCorrection aberrationCorrection, double& ephemerisTime) const { + ghoul_assert(!target.empty(), "Target must not be empty"); + ghoul_assert(!observer.empty(), "Observer must not be empty"); + ghoul_assert(target != observer, "Target and observer must be different"); + ghoul_assert(!referenceFrame.empty(), "Reference frame must not be empty"); + ghoul_assert(!instrument.empty(), "Instrument must not be empty"); + int visible; fovtrg_c(instrument.c_str(), - target.c_str(), - method.c_str(), - referenceFrame.c_str(), - aberrationCorrection.c_str(), - observer.c_str(), - &targetEpoch, - &visible); - isVisible = (visible == SPICETRUE); + target.c_str(), + toString(method), + referenceFrame.c_str(), + aberrationCorrection, + observer.c_str(), + &ephemerisTime, + &visible + ); - throwOnSpiceError("Checking if target '" + target + - "' is in view of instrument '" + instrument + "' failed"); + throwOnSpiceError(format( + "Checking if target '{}' is in view of instrument '{}' failed", + target, instrument + )); - return true; + return visible == SPICETRUE; } -bool SpiceManager::targetWithinFieldOfView(const std::string& instrument, - const std::string& target, - const std::string& observer, - const std::string& method, - const std::string& aberrationCorrection, - double& targetEpoch, - bool& isVisible - ) const{ - - int visible; - - std::string frame = frameFromBody(target); - - fovtrg_c(instrument.c_str(), - target.c_str(), - method.c_str(), - frame.c_str(), - aberrationCorrection.c_str(), - observer.c_str(), - &targetEpoch, - &visible); - isVisible = (visible == SPICETRUE); - - throwOnSpiceError("Checking if target '" + target + - "' is in view of instrument '" + instrument + "' failed"); - - return true; -} - - -// Not called at the moment @AA -bool SpiceManager::getTargetState(const std::string& target, - const std::string& observer, - const std::string& referenceFrame, - const std::string& aberrationCorrection, - double ephemerisTime, - glm::dvec3& targetPosition, - glm::dvec3& targetVelocity, - double& lightTime) const +bool SpiceManager::isTargetInFieldOfView(const std::string& target, + const std::string& observer, const std::string& instrument, + FieldOfViewMethod method, AberrationCorrection aberrationCorrection, + double& ephemerisTime) const { + return isTargetInFieldOfView( + target, + observer, + frameFromBody(target), + instrument, + method, + aberrationCorrection, + ephemerisTime + ); +} + +SpiceManager::TargetStateResult SpiceManager::getTargetState(const std::string& target, + const std::string& observer, const std::string& referenceFrame, + AberrationCorrection aberrationCorrection, double ephemerisTime) const +{ + ghoul_assert(!target.empty(), "Target must not be empty"); + ghoul_assert(!observer.empty(), "Observer must not be empty"); + ghoul_assert(!referenceFrame.empty(), "Reference frame must not be empty"); + + TargetStateResult result; + result.lightTime = 0.0; + double buffer[6]; + + spkezr_c( + target.c_str(), + ephemerisTime, + referenceFrame.c_str(), + aberrationCorrection, + observer.c_str(), + buffer, + &result.lightTime + ); + + throwOnSpiceError(format( + "Error retrieving state of target '{}' viewed from observer '{}' in reference " + "frame '{}' at time '{}'", + target, observer, referenceFrame, ephemerisTime + )); + + memmove(glm::value_ptr(result.position), buffer, sizeof(double) * 3); + memmove(glm::value_ptr(result.velocity), buffer + 3, sizeof(double) * 3); + return result; +} + +SpiceManager::TransformMatrix SpiceManager::getStateTransformMatrix( + const std::string& fromFrame, const std::string& toFrame, double ephemerisTime) const +{ + ghoul_assert(!fromFrame.empty(), "fromFrame must not be empty"); + ghoul_assert(!toFrame.empty(), "toFrame must not be empty"); - spkezr_c(target.c_str(), ephemerisTime, referenceFrame.c_str(), - aberrationCorrection.c_str(), observer.c_str(), buffer, &lightTime); - - throwOnSpiceError("Error retrieving state of target '" + target + "'" + - "viewed from observer '" + observer + "' in " + - "reference frame '" + referenceFrame + "' at time '" + - std::to_string(ephemerisTime) + "'"); - memmove(glm::value_ptr(targetPosition), buffer, sizeof(double) * 3); - memmove(glm::value_ptr(targetVelocity), buffer + 3, sizeof(double) * 3); - return true; + TransformMatrix m; + sxform_c( + fromFrame.c_str(), + toFrame.c_str(), + ephemerisTime, + reinterpret_cast(m.data()) + ); + throwOnSpiceError(format( + "Error retrieved state transform matrix from frame '{}' to frame '{}' at time " + "'{}'", + fromFrame, toFrame, ephemerisTime + )); + return m; } -// Not called at the moment @AA -bool SpiceManager::getTargetState(const std::string& target, - const std::string& observer, - const std::string& referenceFrame, - const std::string& aberrationCorrection, - double ephemerisTime, - PowerScaledCoordinate& position, - PowerScaledCoordinate& velocity, - double& lightTime) const +glm::dmat3 SpiceManager::getPositionTransformMatrix(const std::string& fromFrame, + const std::string& toFrame, double ephemerisTime) const { - double state[6]; - std::fill_n(state, 6, NULL); - - spkezr_c(target.c_str(), ephemerisTime, referenceFrame.c_str(), - aberrationCorrection.c_str(), observer.c_str(), state, &lightTime); - - throwOnSpiceError("Error retrieving state of target '" + target + "'" + - "viewed from observer '" + observer + "' in " + - "reference frame '" + referenceFrame + "' at time '" + - std::to_string(ephemerisTime) + "'"); - - position = PowerScaledCoordinate::CreatePowerScaledCoordinate(state[0], state[1], state[2]); - velocity = PowerScaledCoordinate::CreatePowerScaledCoordinate(state[3], state[4], state[5]); - - return true; -} - -// Not called at the moment @AA -bool SpiceManager::getStateTransformMatrix(const std::string& fromFrame, - const std::string& toFrame, - double ephemerisTime, - TransformMatrix& stateMatrix) const -{ - sxform_c(fromFrame.c_str(), toFrame.c_str(), - ephemerisTime, (double(*)[6])stateMatrix.data()); + ghoul_assert(!fromFrame.empty(), "fromFrame must not be empty"); + ghoul_assert(!toFrame.empty(), "toFrame must not be empty"); - throwOnSpiceError("Error retrieved state transform matrix from frame '" + - fromFrame + "' to frame '" + toFrame + "' at time '" + - std::to_string(ephemerisTime) + "'"); - return true; -} - -bool SpiceManager::getPositionTransformMatrix(const std::string& fromFrame, - const std::string& toFrame, - double ephemerisTime, - glm::dmat3& positionMatrix) const -{ - bool estimated = false; - pxform_c(fromFrame.c_str(), toFrame.c_str(), - ephemerisTime, (double(*)[3])glm::value_ptr(positionMatrix)); + glm::dmat3 result; + pxform_c( + fromFrame.c_str(), + toFrame.c_str(), + ephemerisTime, + reinterpret_cast(glm::value_ptr(result)) + ); SpiceBoolean success = !(failed_c()); reset_c(); - if (!success) { - estimated = getEstimatedTransformMatrix(ephemerisTime, fromFrame, toFrame, positionMatrix); - } + bool estimated = false; + if (!success) + result = getEstimatedTransformMatrix(fromFrame, toFrame, ephemerisTime); - positionMatrix = glm::transpose(positionMatrix); - - return estimated || success; + return glm::transpose(result); } -// Not called at the moment @AA -bool SpiceManager::getPositionTransformMatrix(const std::string& fromFrame, - const std::string& toFrame, - double ephemerisTimeFrom, - double ephemerisTimeTo, - glm::dmat3& positionMatrix) const{ - - pxfrm2_c(fromFrame.c_str(), toFrame.c_str(), ephemerisTimeFrom, ephemerisTimeTo, (double(*)[3])glm::value_ptr(positionMatrix)); - - throwOnSpiceError("Error retrieving position transform matrix from " - "frame '" + fromFrame + "' to frame '" + toFrame + - "' from time '" + std::to_string(ephemerisTimeFrom) + " to time '" - + std::to_string(ephemerisTimeTo) + "'"); - positionMatrix = glm::transpose(positionMatrix); - - return true; -} - - -bool SpiceManager::getEstimatedTransformMatrix(const double time, const std::string fromFrame, - const std::string toFrame, glm::dmat3& positionMatrix) const +glm::dmat3 SpiceManager::getPositionTransformMatrix(const std::string& fromFrame, + const std::string& toFrame, double ephemerisTimeFrom, double ephemerisTimeTo) const { - int idFrame; - - bool frameFound = hasFrameId(fromFrame); - if (!frameFound) { - return false; - } - idFrame = frameId(fromFrame); + ghoul_assert(!fromFrame.empty(), "fromFrame must not be empty"); + ghoul_assert(!toFrame.empty(), "toFrame must not be empty"); - if (_ckCoverageTimes.find(idFrame) == _ckCoverageTimes.end()){ // no coverage - return false; - } + glm::dmat3 result; - double earlier, later, difference, quote; - - std::set coveredTimes = _ckCoverageTimes.find(idFrame)->second; - - std::set::iterator first = coveredTimes.begin(); - std::set::iterator last = coveredTimes.end(); - - if (coveredTimes.lower_bound(time) == first) { // coverage later, fetch first transform - pxform_c(fromFrame.c_str(), toFrame.c_str(), - *first, (double(*)[3])glm::value_ptr(positionMatrix)); - } - else if (coveredTimes.upper_bound(time) == last) { // coverage earlier, fetch last transform - pxform_c(fromFrame.c_str(), toFrame.c_str(), - *(coveredTimes.rbegin()), (double(*)[3])glm::value_ptr(positionMatrix)); - } - else { // coverage both earlier and later, interpolate these transformations - earlier = *std::prev((coveredTimes.lower_bound(time))); - later = *(coveredTimes.upper_bound(time)); - - glm::dmat3 earlierTransform, laterTransform; - - pxform_c(fromFrame.c_str(), toFrame.c_str(), - earlier, (double(*)[3])glm::value_ptr(earlierTransform)); - pxform_c(fromFrame.c_str(), toFrame.c_str(), - later, (double(*)[3])glm::value_ptr(laterTransform)); - - difference = later - earlier; - quote = (time - earlier) / difference; - - for (int i = 0; i < 3; ++i) { - for (int j = 0; j < 3; ++j) { - positionMatrix[i][j] = (earlierTransform[i][j] * (1 - quote) + laterTransform[i][j] * quote); - } - } - } - throwOnSpiceError("Error estimating transform matrix from frame: " - + fromFrame + ", to frame: " + toFrame); - - return true; + pxfrm2_c( + fromFrame.c_str(), + toFrame.c_str(), + ephemerisTimeFrom, + ephemerisTimeTo, + reinterpret_cast(glm::value_ptr(result)) + ); + throwOnSpiceError(format( + "Error retrieving position transform matrix from '{}' at time '{}' to frame '{}' " + "at time '{}'", + fromFrame, ephemerisTimeFrom, toFrame, ephemerisTimeTo + )); + return glm::transpose(result); } - bool SpiceManager::getFieldOfView(const std::string& instrument, std::string& fovShape, std::string& frameName, glm::dvec3& boresightVector, std::vector& bounds) const @@ -1101,13 +1014,94 @@ glm::dvec3 SpiceManager::getEstimatedPosition(const std::string& target, )); // linear interpolation - double timeDifference = timeLater - timeEarlier; - double t = (ephemerisTime - timeEarlier) / timeDifference; + double t = (ephemerisTime - timeEarlier) / (timeLater - timeEarlier); pos = posEarlier * (1.0 - t) + posLater * t; lightTime = ltEarlier * (1.0 - t) + ltLater * t; } return pos; } + +glm::dmat3 SpiceManager::getEstimatedTransformMatrix(const std::string& fromFrame, + const std::string& toFrame, + double time) const +{ + glm::dmat3 result; + int idFrame = frameId(fromFrame); + + if (_ckCoverageTimes.find(idFrame) == _ckCoverageTimes.end()) { + // no coverage + throw SpiceKernelException(format( + "No data available for the transform matrix from '{}' to '{}' at any time", + fromFrame, toFrame + )); + } + + std::set coveredTimes = _ckCoverageTimes.find(idFrame)->second; + + if (coveredTimes.lower_bound(time) == coveredTimes.begin()) { + // coverage later, fetch first transform + pxform_c( + fromFrame.c_str(), + toFrame.c_str(), + *(coveredTimes.begin()), + reinterpret_cast(glm::value_ptr(result)) + ); + throwOnSpiceError(format( + "Error estimating transform matrix from frame '{}' to from '{}' at time '{}'", + fromFrame, toFrame, time + )); + + } + else if (coveredTimes.upper_bound(time) == coveredTimes.end()) { + // coverage earlier, fetch last transform + pxform_c( + fromFrame.c_str(), + toFrame.c_str(), + *(coveredTimes.rbegin()), + reinterpret_cast(glm::value_ptr(result)) + ); + throwOnSpiceError(format( + "Error estimating transform matrix from frame '{}' to from '{}' at time '{}'", + fromFrame, toFrame, time + )); + } + else { + // coverage both earlier and later, interpolate these transformations + double earlier = *std::prev((coveredTimes.lower_bound(time))); + double later = *(coveredTimes.upper_bound(time)); + + glm::dmat3 earlierTransform; + pxform_c( + fromFrame.c_str(), + toFrame.c_str(), + earlier, + reinterpret_cast(glm::value_ptr(earlierTransform)) + ); + throwOnSpiceError(format( + "Error estimating transform matrix from frame '{}' to from '{}' at time '{}'", + fromFrame, toFrame, time + )); + + glm::dmat3 laterTransform; + pxform_c( + fromFrame.c_str(), + toFrame.c_str(), + later, + reinterpret_cast(glm::value_ptr(laterTransform)) + ); + throwOnSpiceError(format( + "Error estimating transform matrix from frame '{}' to from '{}' at time '{}'", + fromFrame, toFrame, time + )); + + double t = (time - earlier) / (later - earlier); + result = earlierTransform * (1.0 - t) + laterTransform * t; + } + + return result; +} + + } // namespace openspace From 443963a151845e4c1a421e484b5dd280059f4174 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Fri, 20 Nov 2015 18:36:03 -0500 Subject: [PATCH 043/122] Finished cleanup of SpiceManager --- include/openspace/util/spicemanager.h | 237 +++++++++--------- .../renderableconstellationbounds.cpp | 2 +- modules/base/rendering/renderablemodel.cpp | 2 +- modules/base/rendering/renderableplanet.cpp | 2 +- .../rendering/renderablesphericalgrid.cpp | 2 +- .../rendering/renderablecrawlingline.cpp | 18 +- .../newhorizons/rendering/renderablefov.cpp | 16 +- .../rendering/renderablemodelprojection.cpp | 17 +- .../rendering/renderableplaneprojection.cpp | 18 +- .../rendering/renderableplanetprojection.cpp | 17 +- .../rendering/renderableshadowcylinder.cpp | 35 +-- src/rendering/renderengine.cpp | 6 +- src/util/powerscaledsphere.cpp | 16 +- src/util/spicemanager.cpp | 234 ++++++++--------- 14 files changed, 312 insertions(+), 310 deletions(-) diff --git a/include/openspace/util/spicemanager.h b/include/openspace/util/spicemanager.h index e01f29e51e..d5210e34c2 100644 --- a/include/openspace/util/spicemanager.h +++ b/include/openspace/util/spicemanager.h @@ -120,6 +120,12 @@ public: Ellipsoid = 0, Point }; + + + enum class TerminatorType { + Umbral = 0, + Penumbral + }; /** * Loads one or more SPICE kernels into a program. The provided path can either be a @@ -454,7 +460,7 @@ public: glm::dmat3 frameTransformationMatrix(const std::string& from, const std::string& to, double ephemerisTime) const; - /// Struct that is used as the return value from the #getSurfaceIntercept method + /// Struct that is used as the return value from the #surfaceIntercept method struct SurfaceInterceptResult { /** * The closest surface intercept point on the target body in Cartesian Coordinates @@ -509,7 +515,7 @@ public: * \post The SurfaceInterceptResult does not contain any uninitialized values. * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/sincpt_c.html */ - SurfaceInterceptResult getSurfaceIntercept(const std::string& target, + SurfaceInterceptResult surfaceIntercept(const std::string& target, const std::string& observer, const std::string& fovFrame, const std::string& referenceFrame, AberrationCorrection aberrationCorrection, double ephemerisTime, const glm::dvec3& directionVector) const; @@ -569,7 +575,7 @@ public: const std::string& instrument, FieldOfViewMethod method, AberrationCorrection aberrationCorrection, double& ephemerisTime) const; - /// Struct that is used as the return value from the #getTargetState method + /// Struct that is used as the return value from the #targetState method struct TargetStateResult { /// The target position glm::dvec3 position; @@ -608,7 +614,7 @@ public: * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/spkezr_c.html * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html */ - TargetStateResult getTargetState(const std::string& target, + TargetStateResult targetState(const std::string& target, const std::string& observer, const std::string& referenceFrame, AberrationCorrection aberrationCorrection, double ephemerisTime) const; @@ -627,7 +633,7 @@ public: * \pre \p destinatoinFrame must not be empty. * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/sxform_c.html */ - TransformMatrix getStateTransformMatrix(const std::string& sourceFrame, + TransformMatrix stateTransformMatrix(const std::string& sourceFrame, const std::string& destinationFrame, double ephemerisTime) const; /** @@ -645,7 +651,7 @@ public: * \pre \p destinationFrame must not be empty * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/pxform_c.html */ - glm::dmat3 getPositionTransformMatrix(const std::string& sourceFrame, + glm::dmat3 positionTransformMatrix(const std::string& sourceFrame, const std::string& destinationFrame, double ephemerisTime) const; /** @@ -663,148 +669,140 @@ public: * \pre \p sourceFrame must not be empty. * \pre \p destinationFrame must not be empty. */ - glm::dmat3 getPositionTransformMatrix(const std::string& sourceFrame, + glm::dmat3 positionTransformMatrix(const std::string& sourceFrame, const std::string& destinationFrame, double ephemerisTimeFrom, double ephemerisTimeTo) const; + /// The structure returned by the #fieldOfView methods + struct FieldOfViewResult { + /// The rough shape of the returned field of view + enum class Shape { + Polygon = 0, ///< The shape is a pyramedal polyhedron + Rectangle, ///< The shape is a rectangular pyramid + Circle, ///< The shape is circular + Ellipse ///< The shape is an ellipse + }; + + /// The shape of the returned field of view + Shape shape; + + /// The name of the reference frame in which the \m bounds are defined + std::string frameName; + + /// The direction towards the center of the field of view + glm::dvec3 boresightVector; + + /// The corners of the field of view's bounding box, not necessarily unit vectors + std::vector bounds; + }; /** - * Applies the transformationMatrix retrieved from - * getStateTransformMatrix to the position and velocity. The - * position and velocity parameters are used as input and - * output. - * \param position The position that should be transformed. The transformed position - * will be stored back in this parameter - * \param velocity The velocity that should be transformed. The transformed velocity - * will be stored back in this parameter - * \param transformationMatrix The 6x6 transformation matrix retrieved from - * getStateTransformMatrix that is used to transform the position and - * velocity vectors - */ - void applyTransformationMatrix(glm::dvec3& position, - glm::dvec3& velocity, - const TransformMatrix& transformationMatrix); - - /** - * This routine returns the field-of-view (FOV) parameters for a specified - * instrument. For further details, please refer to - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/getfov_c.html. + * This method returns the field-of-view (FOV) parameters for a specified + * \p instrument. * \param instrument The name of the instrument for which the FOV is to be retrieved - * \param fovShape The output containing the rough shape of the returned FOV. If the - * method fails, this value remains unchanged - * \param frameName The output containing the name of the frame in which the FOV - * bounds are computed. If the method fails, this value remains unchanged - * \param boresightVector The output containing the boresight, that is the vector for - * the center direction of the FOV. If the method fails, this value remains unchanged - * \param bounds The output containing the values defining the bounds of the FOV as - * explained by http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/getfov_c.html. - * If the method fails, this value remains unchanged - * \return true if the function was successful, false - * otherwise + * \return The FieldOfViewResult structure that contains information about the field + * of view. + * \throw SpiceKernelException If \p instrument does not name a valid NAIF object + * \pre \p instrument must not be empty + * \post The returned structure has all its values initialized + * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/getfov_c.html */ - bool getFieldOfView(const std::string& instrument, - std::string& fovShape, - std::string& frameName, - glm::dvec3& boresightVector, - std::vector& bounds) const; + FieldOfViewResult fieldOfView(const std::string& instrument) const; /** - * This routine returns the field-of-view (FOV) parameters for a specified - * instrument. For further details, please refer to - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/getfov_c.html. - * \param instrument The NAIF id of the instrument for which the FOV is to be - * retrieved. For more information on NAIF IDs, refer to - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html - * \param fovShape The output containing the rough shape of the returned FOV. If the - * method fails, this value remains unchanged - * \param frameName The output containing the name of the frame in which the FOV - * bounds are computed. If the method fails, this value remains unchanged - * \param boresightVector The output containing the boresight, that is the vector for - * the center direction of the FOV. If the method fails, this value remains unchanged - * \param bounds The output containing the values defining the bounds of the FOV as - * explained by http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/getfov_c.html. - * If the method fails, this value remains unchanged - * \return true if the function was successful, false - * otherwise + * This method returns the field-of-view (FOV) parameters for a specified + * \p instrument. The instrument must be a valid NAIF object index as returned by the + * #naifId method + * \param instrument The name of the instrument for which the FOV is to be retrieved + * \return The FieldOfViewResult structure that contains information about the field + * of view. + * \throw SpiceKernelException If \p instrument does not name a valid NAIF object + * \post The returned structure has all its values initialized + * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/getfov_c.html */ - bool getFieldOfView(int instrument, std::string& fovShape, std::string& frameName, - glm::dvec3& boresightVector, std::vector& bounds) const; + FieldOfViewResult fieldOfView(int instrument) const; + + /// The structure retuned by the #terminatorEllipse method + struct TerminatorEllipseResult { + /// The vector from the target body at \m targetEphemerisTime to the observer at + /// the original time + glm::dvec3 observerPosition; + + /// The full list of terminator points specified in the original reference frame + std::vector terminatorPoints; + + /// The local ephemeris time at the target, determined by the original + /// aberrationCorrection factor + double targetEphemerisTime; + }; /** - * This routine computes a set of points on the umbral or penumbral terminator of - * a specified target body, where SPICE models the target shape as an ellipsoid. - * \param numberOfPoints - number of points along terminator returned by this method - * \param terminatorType - is a string indicating the type of terminator to compute: - * umbral or penumbral. The umbral terminator is the boundary of the portion of the - * ellipsoid surface in total shadow. The penumbral terminator is the boundary of - * the portion of the surface that is completely illuminated. Note that in astronomy - * references, the unqualified word "terminator" refers to the umbral terminator. - * Here, the unqualified word refers to either type of terminator. - * \param lightSource - name of body acting as light source - * \param observer - name of bodserving body - * \param target - name of target body - * \param frame - name of the reference frame relative to which the output terminator - * points are expressed. - * \param aberrationCorrection - correction for light time and/or stellar aberration - * \param ephemerisTime - the epoch of participation of the observer - * \param targetEpoch - is the "target epoch.", time it takes for - * \param observerPosition - is the vector from the target body at targetEpoch - * \param terminatorPoints - an array of points on the umbral or penumbral terminator - * of the ellipsoid, as specified by the input argument `numberOfPoints' - * For further, more specific details please refer to - * http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/edterm_c.html + * This method computes a set of points on the umbral or penumbral terminator of + * a specified \p target, where SPICE models the target shape as an ellipsoid. + * \param target The name of target body + * \param observer The name of the observing body + * \param frame The name of the reference frame relative to which the output + * terminator points are expressed + * \param lightSource The name of body acting as light source + * \param terminatorType Indicates the type of terminator to compute. + * TerminatorType::Umbral is the boundary of the portion of the ellipsoid surface in + * total shadow. TerminatorType::Penumbral is the boundary of the portion of the + * surface that is completely illuminated. Note that in astronomy references, the + * unqualified word "terminator" refers to the umbral terminator. + * \param aberrationCorrection The aberration correction method that is used + * \param numberOfPoints The number of points along terminator that should be computed + * by this method + * \return A TerminatorEllipseResult structure that contains all outputs of this + * function + * \throws SpiceKernelException If the \p target, \p observer, or \p lightSource are + * not valid NAIF names, the \p frame is not a valid NAIF frame or there is + * insufficient kernel data loaded + * \pre \p target must not be empty + * \pre \p observer must not be empty + * \pre \p frame must not be empty + * \pre \p lightSource must not be empty + * \pre \p numberOfTerminatorPoints must be bigger or equal to 1 + * \post The returned structure has all its values initialized + * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/edterm_c.html */ - bool getTerminatorEllipse(const int numberOfPoints, - const std::string terminatorType, - const std::string lightSource, - const std::string observer, - const std::string target, - const std::string frame, - const std::string aberrationCorrection, - double ephemerisTime, - double& targetEpoch, - glm::dvec3& observerPosition, - std::vector& terminatorPoints); - + TerminatorEllipseResult terminatorEllipse(const std::string& target, + const std::string& observer, const std::string& frame, + const std::string& lightSource, TerminatorType terminatorType, + AberrationCorrection aberrationCorrection, double ephemerisTime, + int numberOfTerminatorPoints); + /** - * This function adds a frame to a body + * This function adds a frame to a body * \param body - the name of the body * \param frame - the name of the frame * \return false if the arguments are empty + * \todo I think this function should die ---abock */ - bool addFrame(const std::string body, const std::string frame); + bool addFrame(std::string body, std::string frame); /** * 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 + * \todo I think this function should die ---abock */ std::string frameFromBody(const std::string body) const; - /** - * This method uses the SPICE kernels to get the radii of bodies defined as a - * triaxial ellipsoid. The benefit of this is to be able to create more accurate - * planet shapes, which is desirable when projecting images with SPICE intersection - * methods - * \param planetName - the name of the body, should be recognizable by SPICE - * \param a - equatorial radius 1 - * \param b - equatorial radius 2 - * \param c - polar radius - * \return true if SPICE reports no errors - */ - bool getPlanetEllipsoid(std::string planetName, float &a, float &b, float &c); - private: + /// Struct storing the information about all loaded kernels struct KernelInformation { std::string path; /// The path from which the kernel was loaded KernelHandle id; /// A unique identifier for each kernel int refCount; /// How many parts loaded this kernel and are interested in it }; + /// Default constructor setting values for SPICE to not terminate on error SpiceManager(); SpiceManager(const SpiceManager& c) = delete; SpiceManager& operator=(const SpiceManager& r) = delete; SpiceManager(SpiceManager&& r) = delete; + + /// Default destructor that resets the SPICE settings ~SpiceManager(); /** @@ -881,16 +879,15 @@ private: /// A list of all loaded kernels std::vector _loadedKernels; - // Map: id, vector of pairs. Pair: Start time, end time; - std::map > > _ckIntervals; - std::map > > _spkIntervals; - std::map > _ckCoverageTimes; - std::map > _spkCoverageTimes; - // Vector of pairs: Body, Frame - std::vector< std::pair > _frameByBody; - const static bool _showErrors = false; - + // Map: id, vector of pairs. Pair: Start time, end time; + std::map>> _ckIntervals; + std::map>> _spkIntervals; + std::map> _ckCoverageTimes; + std::map> _spkCoverageTimes; + // Vector of pairs: Body, Frame + std::vector> _frameByBody; + /// The last assigned kernel-id, used to determine the next free kernel id KernelHandle _lastAssignedKernel = KernelHandle(0); }; diff --git a/modules/base/rendering/renderableconstellationbounds.cpp b/modules/base/rendering/renderableconstellationbounds.cpp index 558803e3ae..0a8cd007a9 100644 --- a/modules/base/rendering/renderableconstellationbounds.cpp +++ b/modules/base/rendering/renderableconstellationbounds.cpp @@ -179,7 +179,7 @@ void RenderableConstellationBounds::update(const UpdateData& data) { if (_program->isDirty()) _program->rebuildFromFile(); - _stateMatrix = SpiceManager::ref().getPositionTransformMatrix( + _stateMatrix = SpiceManager::ref().positionTransformMatrix( _originReferenceFrame, "GALACTIC", data.time diff --git a/modules/base/rendering/renderablemodel.cpp b/modules/base/rendering/renderablemodel.cpp index db13df15ae..6cba9c1b4e 100644 --- a/modules/base/rendering/renderablemodel.cpp +++ b/modules/base/rendering/renderablemodel.cpp @@ -243,7 +243,7 @@ void RenderableModel::update(const UpdateData& data) { // set spice-orientation in accordance to timestamp if (!_source.empty()) { - _stateMatrix = SpiceManager::ref().getPositionTransformMatrix(_source, _destination, _time); + _stateMatrix = SpiceManager::ref().positionTransformMatrix(_source, _destination, _time); } double lt; diff --git a/modules/base/rendering/renderableplanet.cpp b/modules/base/rendering/renderableplanet.cpp index 9f074f0365..65d78eb81d 100644 --- a/modules/base/rendering/renderableplanet.cpp +++ b/modules/base/rendering/renderableplanet.cpp @@ -217,7 +217,7 @@ void RenderablePlanet::render(const RenderData& data) void RenderablePlanet::update(const UpdateData& data){ // set spice-orientation in accordance to timestamp - _stateMatrix = SpiceManager::ref().getPositionTransformMatrix(_frame, "GALACTIC", data.time); + _stateMatrix = SpiceManager::ref().positionTransformMatrix(_frame, "GALACTIC", data.time); _time = data.time; } diff --git a/modules/base/rendering/renderablesphericalgrid.cpp b/modules/base/rendering/renderablesphericalgrid.cpp index ff35d37c16..24a26d912e 100644 --- a/modules/base/rendering/renderablesphericalgrid.cpp +++ b/modules/base/rendering/renderablesphericalgrid.cpp @@ -228,7 +228,7 @@ void RenderableSphericalGrid::render(const RenderData& data){ } void RenderableSphericalGrid::update(const UpdateData& data) { - _parentMatrix = SpiceManager::ref().getPositionTransformMatrix("IAU_JUPITER", "GALACTIC", data.time); + _parentMatrix = SpiceManager::ref().positionTransformMatrix("IAU_JUPITER", "GALACTIC", data.time); } } \ No newline at end of file diff --git a/modules/newhorizons/rendering/renderablecrawlingline.cpp b/modules/newhorizons/rendering/renderablecrawlingline.cpp index 2ed7a2aa49..1e5fcb7025 100644 --- a/modules/newhorizons/rendering/renderablecrawlingline.cpp +++ b/modules/newhorizons/rendering/renderablecrawlingline.cpp @@ -148,7 +148,7 @@ void RenderableCrawlingLine::render(const RenderData& data) { void RenderableCrawlingLine::update(const UpdateData& data) { if (_program->isDirty()) _program->rebuildFromFile(); - glm::dmat3 transformMatrix = SpiceManager::ref().getPositionTransformMatrix(_source, _referenceFrame, data.time); + glm::dmat3 transformMatrix = SpiceManager::ref().positionTransformMatrix(_source, _referenceFrame, data.time); glm::mat4 tmp = glm::mat4(1); for (int i = 0; i < 3; i++) { @@ -159,13 +159,17 @@ void RenderableCrawlingLine::update(const UpdateData& data) { _positions[SourcePosition] = PowerScaledCoordinate::CreatePowerScaledCoordinate(0, 0, 0); - std::string shape, instrument; - std::vector bounds; glm::dvec3 boresight; - - bool found = openspace::SpiceManager::ref().getFieldOfView(_source, shape, instrument, boresight, bounds); - if (!found) - LERROR("Could not find field of view for instrument"); + try { + SpiceManager::FieldOfViewResult res = + SpiceManager::ref().fieldOfView(_source); + boresight = res.boresightVector; + + } + catch (const SpiceManager::SpiceKernelException& e) { + LERROR(e.what()); + } + glm::vec4 target(boresight[0], boresight[1], boresight[2], 12); target = tmp * target; diff --git a/modules/newhorizons/rendering/renderablefov.cpp b/modules/newhorizons/rendering/renderablefov.cpp index 9649a5036b..371df7ab72 100644 --- a/modules/newhorizons/rendering/renderablefov.cpp +++ b/modules/newhorizons/rendering/renderablefov.cpp @@ -102,10 +102,12 @@ RenderableFov::RenderableFov(const ghoul::Dictionary& dictionary) } void RenderableFov::allocateData() { - std::string shape, instrument; // fetch data for specific instrument (shape, boresight, bounds etc) try { - SpiceManager::ref().getFieldOfView(_instrumentID, shape, instrument, _boresight, _bounds); + SpiceManager::FieldOfViewResult res = SpiceManager::ref().fieldOfView(_instrumentID); + + _bounds = std::move(res.bounds); + _boresight = std::move(res.boresightVector); _stride = 8; @@ -238,7 +240,7 @@ psc RenderableFov::checkForIntercept(glm::dvec3 ray) { else bodyfixed = _frame; - SpiceManager::SurfaceInterceptResult result = SpiceManager::ref().getSurfaceIntercept( + SpiceManager::SurfaceInterceptResult result = SpiceManager::ref().surfaceIntercept( _fovTarget, _spacecraft, _instrumentID, bodyfixed, _aberrationCorrection, _time, ray); if (convert) { @@ -280,7 +282,7 @@ glm::dvec3 RenderableFov::bisection(glm::dvec3 p1, glm::dvec3 p2, double toleran bodyfixed = _frame; - SpiceManager::SurfaceInterceptResult result = SpiceManager::ref().getSurfaceIntercept( + SpiceManager::SurfaceInterceptResult result = SpiceManager::ref().surfaceIntercept( _fovTarget, _spacecraft, _instrumentID, bodyfixed, _aberrationCorrection, _time, half); if (convert) { @@ -340,7 +342,7 @@ void RenderableFov::fovSurfaceIntercept(bool H[], std::vector bounds SpiceManager::SurfaceInterceptResult res = - SpiceManager::ref().getSurfaceIntercept(_fovTarget, _spacecraft, + SpiceManager::ref().surfaceIntercept(_fovTarget, _spacecraft, _instrumentID, bodyfixed, _aberrationCorrection, _time, half); if (convert) { @@ -472,7 +474,7 @@ void RenderableFov::computeIntercepts(const RenderData& data){ bodyfixed = _frame; SpiceManager::SurfaceInterceptResult res = - SpiceManager::ref().getSurfaceIntercept(_fovTarget, _spacecraft, + SpiceManager::ref().surfaceIntercept(_fovTarget, _spacecraft, _instrumentID, bodyfixed, _aberrationCorrection, _time, _bounds[r]); if (convert) { @@ -573,7 +575,7 @@ void RenderableFov::render(const RenderData& data) { void RenderableFov::update(const UpdateData& data) { _time = data.time; - _stateMatrix = SpiceManager::ref().getPositionTransformMatrix(_instrumentID, _frame, data.time); + _stateMatrix = SpiceManager::ref().positionTransformMatrix(_instrumentID, _frame, data.time); _spacecraftRotation = glm::mat4(1); for (int i = 0; i < 3; i++){ for (int j = 0; j < 3; j++){ diff --git a/modules/newhorizons/rendering/renderablemodelprojection.cpp b/modules/newhorizons/rendering/renderablemodelprojection.cpp index d6d4eaa7a1..5343c277e7 100644 --- a/modules/newhorizons/rendering/renderablemodelprojection.cpp +++ b/modules/newhorizons/rendering/renderablemodelprojection.cpp @@ -352,7 +352,7 @@ void RenderableModelProjection::update(const UpdateData& data) { // set spice-orientation in accordance to timestamp if (!_source.empty()) { - _stateMatrix = SpiceManager::ref().getPositionTransformMatrix(_source, _destination, _time); + _stateMatrix = SpiceManager::ref().positionTransformMatrix(_source, _destination, _time); } double lt; @@ -407,8 +407,8 @@ void RenderableModelProjection::imageProjectGPU() { } void RenderableModelProjection::attitudeParameters(double time) { - _stateMatrix = SpiceManager::ref().getPositionTransformMatrix(_source, _destination, time); - _instrumentMatrix = SpiceManager::ref().getPositionTransformMatrix(_instrumentID, _destination, time); + _stateMatrix = SpiceManager::ref().positionTransformMatrix(_source, _destination, time); + _instrumentMatrix = SpiceManager::ref().positionTransformMatrix(_instrumentID, _destination, time); _transform = glm::mat4(1); @@ -423,12 +423,13 @@ void RenderableModelProjection::attitudeParameters(double time) { } _transform = _transform * rotPropX * rotPropY * rotPropZ; - std::string shape, instrument; - std::vector bounds; glm::dvec3 boresight; - bool found = openspace::SpiceManager::ref().getFieldOfView(_instrumentID, shape, instrument, boresight, bounds); - if (!found) - return; + try { + SpiceManager::FieldOfViewResult res = SpiceManager::ref().fieldOfView(_instrumentID); + boresight = std::move(res.boresightVector); + } catch (const SpiceManager::SpiceKernelException& e) { + return; + } double lightTime; glm::dvec3 p = diff --git a/modules/newhorizons/rendering/renderableplaneprojection.cpp b/modules/newhorizons/rendering/renderableplaneprojection.cpp index 552ad2d7b6..367fa04cc2 100644 --- a/modules/newhorizons/rendering/renderableplaneprojection.cpp +++ b/modules/newhorizons/rendering/renderableplaneprojection.cpp @@ -166,7 +166,7 @@ void RenderablePlaneProjection::update(const UpdateData& data) { else _hasImage = true; - _stateMatrix = SpiceManager::ref().getPositionTransformMatrix(_target.frame, GalacticFrame, time); + _stateMatrix = SpiceManager::ref().positionTransformMatrix(_target.frame, GalacticFrame, time); double timePast = abs(img.startTime - _previousTime); @@ -209,7 +209,7 @@ void RenderablePlaneProjection::loadTexture() { void RenderablePlaneProjection::updatePlane(const Image img, double currentTime) { - std::string shape, frame; + std::string frame; std::vector bounds; glm::dvec3 boresight; @@ -224,11 +224,15 @@ void RenderablePlaneProjection::updatePlane(const Image img, double currentTime) setTarget(target); - bool found = openspace::SpiceManager::ref().getFieldOfView(_instrument, shape, frame, boresight, bounds); - if (!found) { - LERROR("Could not locate instrument"); - return; - } + try { + SpiceManager::FieldOfViewResult res = SpiceManager::ref().fieldOfView(_instrument); + + frame = std::move(res.frameName); + bounds = std::move(res.bounds); + boresight = std::move(res.boresightVector); + } catch (const SpiceManager::SpiceKernelException& e) { + LERROR(e.what()); + } double lt; psc projection[4]; diff --git a/modules/newhorizons/rendering/renderableplanetprojection.cpp b/modules/newhorizons/rendering/renderableplanetprojection.cpp index 4ee9f68761..4f8941d90d 100644 --- a/modules/newhorizons/rendering/renderableplanetprojection.cpp +++ b/modules/newhorizons/rendering/renderableplanetprojection.cpp @@ -408,8 +408,8 @@ glm::mat4 RenderablePlanetProjection::computeProjectorMatrix(const glm::vec3 loc void RenderablePlanetProjection::attitudeParameters(double time){ // precomputations for shader - _stateMatrix = SpiceManager::ref().getPositionTransformMatrix(_frame, _mainFrame, _time); - _instrumentMatrix = SpiceManager::ref().getPositionTransformMatrix(_instrumentID, _mainFrame, time); + _stateMatrix = SpiceManager::ref().positionTransformMatrix(_frame, _mainFrame, _time); + _instrumentMatrix = SpiceManager::ref().positionTransformMatrix(_instrumentID, _mainFrame, time); _transform = glm::mat4(1); //90 deg rotation w.r.t spice req. @@ -424,13 +424,14 @@ void RenderablePlanetProjection::attitudeParameters(double time){ } _transform = _transform * rot * roty * rotProp; - std::string shape, instrument; - std::vector bounds; glm::dvec3 bs; - bool found = openspace::SpiceManager::ref().getFieldOfView(_instrumentID, shape, instrument, bs, bounds); - //if (!found) LERROR("Could not locate instrument"); - if (!found) - return ; + try { + SpiceManager::FieldOfViewResult res = SpiceManager::ref().fieldOfView(_instrumentID); + bs = std::move(res.boresightVector); + } + catch (const SpiceManager::SpiceKernelException& e) { + return; + } glm::dvec3 p = SpiceManager::ref().targetPosition(_projectorID, _projecteeID, _mainFrame, _aberration, time, lightTime); psc position = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); diff --git a/modules/newhorizons/rendering/renderableshadowcylinder.cpp b/modules/newhorizons/rendering/renderableshadowcylinder.cpp index 71d67d3ffd..5f1715289b 100644 --- a/modules/newhorizons/rendering/renderableshadowcylinder.cpp +++ b/modules/newhorizons/rendering/renderableshadowcylinder.cpp @@ -132,7 +132,7 @@ void RenderableShadowCylinder::render(const RenderData& data){ } void RenderableShadowCylinder::update(const UpdateData& data) { - _stateMatrix = SpiceManager::ref().getPositionTransformMatrix(_bodyFrame, _mainFrame, data.time); + _stateMatrix = SpiceManager::ref().positionTransformMatrix(_bodyFrame, _mainFrame, data.time); _time = data.time; if (_shader->isDirty()) _shader->rebuildFromFile(); @@ -156,23 +156,30 @@ void RenderableShadowCylinder::createCylinder() { double targetEpoch; glm::dvec3 observerPosition; std::vector terminatorPoints; - SpiceManager::ref().getTerminatorEllipse(_numberOfPoints, - _terminatorType, - _lightSource, - _observer, - _body, - _bodyFrame, - std::string(_aberration), - _time, - targetEpoch, - observerPosition, - terminatorPoints); - + SpiceManager::TerminatorType t; + if (_terminatorType == "UMBRAL") + t = SpiceManager::TerminatorType::Umbral; + else if (_terminatorType == "PENUMBRAL") + t = SpiceManager::TerminatorType::Penumbral; + + auto res = SpiceManager::ref().terminatorEllipse(_body, _observer, _bodyFrame, + _lightSource, t, _aberration, _time, _numberOfPoints); + + targetEpoch = res.targetEphemerisTime; + observerPosition = std::move(res.observerPosition); + + std::vector ps = std::move(res.terminatorPoints); + for (auto&& p : ps) { + PowerScaledCoordinate psc = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); + psc[3] += 3; + terminatorPoints.push_back(psc); + } + double lt; glm::dvec3 vecLightSource = SpiceManager::ref().targetPosition(_body, _lightSource, _mainFrame, _aberration, _time, lt); - glm::dmat3 _stateMatrix = glm::inverse(SpiceManager::ref().getPositionTransformMatrix(_bodyFrame, _mainFrame, _time)); + glm::dmat3 _stateMatrix = glm::inverse(SpiceManager::ref().positionTransformMatrix(_bodyFrame, _mainFrame, _time)); vecLightSource = _stateMatrix * vecLightSource; diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 63f7d9cc2b..64d6e2f631 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -456,7 +456,11 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi SpiceManager::ref().targetPosition("PLUTO", "NEW HORIZONS", "GALACTIC", {}, currentTime, lt); psc nhPos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); float a, b, c; - SpiceManager::ref().getPlanetEllipsoid("PLUTO", a, b, c); + glm::dvec3 radii; + SpiceManager::ref().getValue("PLUTO", "RADII", radii); + a = radii.x; + b = radii.y; + c = radii.z; float radius = (a + b) / 2.f; float distToSurf = glm::length(nhPos.vec3()) - radius; diff --git a/src/util/powerscaledsphere.cpp b/src/util/powerscaledsphere.cpp index 84b0c15c19..198a972f34 100644 --- a/src/util/powerscaledsphere.cpp +++ b/src/util/powerscaledsphere.cpp @@ -139,8 +139,20 @@ PowerScaledSphere::PowerScaledSphere(properties::Vec4Property &radius, int segme "The size of the Vertex needs to be 64 for performance"); float a, b, c, powerscale; - bool accutareRadius = SpiceManager::ref().getPlanetEllipsoid(planetName, a, b, c); - + bool accutareRadius; + try { + glm::dvec3 radii; + SpiceManager::ref().getValue(planetName, "RADII", radii); + a = radii.x; + b = radii.y; + c = radii.z; + accutareRadius = true; + } + catch (const SpiceManager::SpiceKernelException& e) { + LWARNING("Could not find radius for body " << planetName); + accutareRadius = false; + } + if (accutareRadius) { PowerScaledCoordinate powerScaledRadii = psc::CreatePowerScaledCoordinate(a, b, c); powerScaledRadii[3] += 3; // SPICE returns radii in km diff --git a/src/util/spicemanager.cpp b/src/util/spicemanager.cpp index 36d116a2a2..ea3561b92c 100644 --- a/src/util/spicemanager.cpp +++ b/src/util/spicemanager.cpp @@ -406,7 +406,7 @@ double SpiceManager::ephemerisTimeFromDate(const std::string& timeString) const } string SpiceManager::dateFromEphemerisTime(double ephemerisTime, - const string& formatString) const + const string& formatString) const { ghoul_assert(!formatString.empty(), "Format is empty"); @@ -424,12 +424,9 @@ string SpiceManager::dateFromEphemerisTime(double ephemerisTime, } -glm::dvec3 SpiceManager::targetPosition(const std::string& target, - const std::string& observer, - const std::string& referenceFrame, - AberrationCorrection aberrationCorrection, - double ephemerisTime, - double& lightTime) const +glm::dvec3 SpiceManager::targetPosition(const string& target, const string& observer, + const string& referenceFrame, AberrationCorrection aberrationCorrection, + double ephemerisTime, double& lightTime) const { ghoul_assert(!target.empty(), "Target is not empty"); ghoul_assert(!observer.empty(), "Observer is not empty"); @@ -488,9 +485,8 @@ glm::dvec3 SpiceManager::targetPosition(const std::string& target, } } -glm::dmat3 SpiceManager::frameTransformationMatrix(const std::string& from, - const std::string& to, - double ephemerisTime) const +glm::dmat3 SpiceManager::frameTransformationMatrix(const string& from, const string& to, + double ephemerisTime) const { ghoul_assert(!from.empty(), "From must not be empty"); ghoul_assert(!to.empty(), "To must not be empty"); @@ -515,9 +511,9 @@ glm::dmat3 SpiceManager::frameTransformationMatrix(const std::string& from, return glm::transpose(transform); } -SpiceManager::SurfaceInterceptResult SpiceManager::getSurfaceIntercept( - const std::string& target, const std::string& observer, const std::string& fovFrame, - const std::string& referenceFrame, AberrationCorrection aberrationCorrection, +SpiceManager::SurfaceInterceptResult SpiceManager::surfaceIntercept( + const string& target, const string& observer, const string& fovFrame, + const string& referenceFrame, AberrationCorrection aberrationCorrection, double ephemerisTime, const glm::dvec3& directionVector) const { ghoul_assert(!target.empty(), "Target must not be empty"); @@ -556,9 +552,8 @@ SpiceManager::SurfaceInterceptResult SpiceManager::getSurfaceIntercept( return result; } -bool SpiceManager::isTargetInFieldOfView(const std::string& target, - const std::string& observer, const std::string& referenceFrame, - const std::string& instrument, FieldOfViewMethod method, +bool SpiceManager::isTargetInFieldOfView(const string& target, const string& observer, + const string& referenceFrame, const string& instrument, FieldOfViewMethod method, AberrationCorrection aberrationCorrection, double& ephemerisTime) const { ghoul_assert(!target.empty(), "Target must not be empty"); @@ -586,10 +581,9 @@ bool SpiceManager::isTargetInFieldOfView(const std::string& target, return visible == SPICETRUE; } -bool SpiceManager::isTargetInFieldOfView(const std::string& target, - const std::string& observer, const std::string& instrument, - FieldOfViewMethod method, AberrationCorrection aberrationCorrection, - double& ephemerisTime) const +bool SpiceManager::isTargetInFieldOfView(const string& target, const string& observer, + const string& instrument, FieldOfViewMethod method, + AberrationCorrection aberrationCorrection, double& ephemerisTime) const { return isTargetInFieldOfView( target, @@ -602,8 +596,8 @@ bool SpiceManager::isTargetInFieldOfView(const std::string& target, ); } -SpiceManager::TargetStateResult SpiceManager::getTargetState(const std::string& target, - const std::string& observer, const std::string& referenceFrame, +SpiceManager::TargetStateResult SpiceManager::targetState(const string& target, + const string& observer, const string& referenceFrame, AberrationCorrection aberrationCorrection, double ephemerisTime) const { ghoul_assert(!target.empty(), "Target must not be empty"); @@ -636,8 +630,8 @@ SpiceManager::TargetStateResult SpiceManager::getTargetState(const std::string& return result; } -SpiceManager::TransformMatrix SpiceManager::getStateTransformMatrix( - const std::string& fromFrame, const std::string& toFrame, double ephemerisTime) const +SpiceManager::TransformMatrix SpiceManager::stateTransformMatrix(const string& fromFrame, + const string& toFrame, double ephemerisTime) const { ghoul_assert(!fromFrame.empty(), "fromFrame must not be empty"); ghoul_assert(!toFrame.empty(), "toFrame must not be empty"); @@ -657,8 +651,8 @@ SpiceManager::TransformMatrix SpiceManager::getStateTransformMatrix( return m; } -glm::dmat3 SpiceManager::getPositionTransformMatrix(const std::string& fromFrame, - const std::string& toFrame, double ephemerisTime) const +glm::dmat3 SpiceManager::positionTransformMatrix(const string& fromFrame, + const string& toFrame, double ephemerisTime) const { ghoul_assert(!fromFrame.empty(), "fromFrame must not be empty"); ghoul_assert(!toFrame.empty(), "toFrame must not be empty"); @@ -680,8 +674,8 @@ glm::dmat3 SpiceManager::getPositionTransformMatrix(const std::string& fromFrame return glm::transpose(result); } -glm::dmat3 SpiceManager::getPositionTransformMatrix(const std::string& fromFrame, - const std::string& toFrame, double ephemerisTimeFrom, double ephemerisTimeTo) const +glm::dmat3 SpiceManager::positionTransformMatrix(const string& fromFrame, + const string& toFrame, double ephemerisTimeFrom, double ephemerisTimeTo) const { ghoul_assert(!fromFrame.empty(), "fromFrame must not be empty"); ghoul_assert(!toFrame.empty(), "toFrame must not be empty"); @@ -703,96 +697,104 @@ glm::dmat3 SpiceManager::getPositionTransformMatrix(const std::string& fromFrame return glm::transpose(result); } -bool SpiceManager::getFieldOfView(const std::string& instrument, std::string& fovShape, - std::string& frameName, glm::dvec3& boresightVector, - std::vector& bounds) const +SpiceManager::FieldOfViewResult SpiceManager::fieldOfView(const string& instrument) const { - int id; - bool success = hasNaifId(instrument); - if (!success) - return false; - else - id = naifId(instrument); - return getFieldOfView(id, fovShape, frameName, boresightVector, bounds); + ghoul_assert(!instrument.empty(), "Instrument must not be empty"); + return fieldOfView(naifId(instrument)); } +SpiceManager::FieldOfViewResult SpiceManager::fieldOfView(int instrument) const { + static const int MaxBoundsSize = 20; + static const int BufferSize = 128; -bool SpiceManager::getFieldOfView(int instrument, - std::string& fovShape, - std::string& frameName, - glm::dvec3& boresightVector, - std::vector& bounds) const -{ - static const int maxBoundsSize = 20; - static const int bufferSize = 128; - static char fovShapeBuffer[bufferSize]; - static char frameNameBuffer[bufferSize]; + FieldOfViewResult res; SpiceInt nrReturned; - double boundsArr[maxBoundsSize][3]; + double boundsArr[MaxBoundsSize][3]; + char fovShapeBuffer[BufferSize]; + char frameNameBuffer[BufferSize]; + getfov_c(instrument, // instrument id + MaxBoundsSize, // maximum size for the bounds vector + BufferSize, // maximum size for the fov shape buffer + BufferSize, // maximum size for the frame name buffer + fovShapeBuffer, // the fov shape buffer + frameNameBuffer, // the frame name buffer + glm::value_ptr(res.boresightVector), // the boresight vector + &nrReturned, // the number of returned array values + boundsArr // the bounds + ); + + throwOnSpiceError(format( + "Error getting field-of-view parameters for instrument '{}'", instrument + )); - getfov_c(instrument, // instrument id - maxBoundsSize, // maximum size for the bounds vector - bufferSize, // maximum size for the fov shape buffer - bufferSize, // maximum size for the frame name buffer - fovShapeBuffer, // the fov shape buffer - frameNameBuffer, // the frame name buffer - glm::value_ptr(boresightVector), // the boresight vector - &nrReturned, // the number of array values returned for the bounds - (double(*)[3])boundsArr // the bounds - ); + res.bounds.reserve(nrReturned); + for (int i = 0; i < nrReturned; ++i) + res.bounds.emplace_back(boundsArr[i][0], boundsArr[i][1], boundsArr[i][2]); - throwOnSpiceError("Error getting Field-of-View parameters for " - "instrument '" + std::to_string(instrument) + "'"); + string shape = string(fovShapeBuffer); + static const std::map Map = { + { "POLYGON", FieldOfViewResult::Shape::Polygon }, + { "RECTANGLE" , FieldOfViewResult::Shape::Rectangle }, + { "CIRCLE", FieldOfViewResult::Shape::Circle }, + { "ELLIPSE", FieldOfViewResult::Shape::Ellipse } + }; + res.shape = Map.at(shape); + res.frameName = string(frameNameBuffer); - bounds.resize(nrReturned); - for (int i = 0; i < nrReturned; ++i) { - bounds[i] = glm::dvec3(boundsArr[i][0], - boundsArr[i][1], - boundsArr[i][2]); - } - - fovShape = std::string(fovShapeBuffer); - frameName = std::string(frameNameBuffer); - - return true; + return res; } -bool SpiceManager::getTerminatorEllipse(const int numberOfPoints, - const std::string terminatorType, - const std::string lightSource, - const std::string observer, - const std::string target, - const std::string frame, - const std::string aberrationCorrection, - double ephemerisTime, - double& targetEpoch, - glm::dvec3& observerPosition, - std::vector& terminatorPoints) + +SpiceManager::TerminatorEllipseResult SpiceManager::terminatorEllipse( + const string& target, const string& observer, const string& frame, + const string& lightSource, TerminatorType terminatorType, + AberrationCorrection aberrationCorrection, double ephemerisTime, + int numberOfTerminatorPoints) { - std::vector> tpoints(numberOfPoints); + ghoul_assert(!target.empty(), "Target must not be empty"); + ghoul_assert(!observer.empty(), "Observer must not be empty"); + ghoul_assert(!frame.empty(), "Frame must not be empty"); + ghoul_assert(!lightSource.empty(), "Light source must not be empty"); + ghoul_assert(numberOfTerminatorPoints >= 1, "Terminator points must be >= 1"); + + TerminatorEllipseResult res; + + // Warning: This assumes std::vector to have all values memory contiguous + res.terminatorPoints.resize(numberOfTerminatorPoints); - edterm_c(terminatorType.c_str(), + static const std::map Map = { + { TerminatorType::Umbral, "UMBRAL" }, + { TerminatorType::Penumbral, "PENUMBRAL" } + }; + string s = Map.at(terminatorType); + + edterm_c(s.c_str(), lightSource.c_str(), target.c_str(), ephemerisTime, frame.c_str(), - aberrationCorrection.c_str(), + aberrationCorrection, observer.c_str(), - numberOfPoints, - &targetEpoch, - glm::value_ptr(observerPosition), - (double(*)[3])tpoints.data() ); + numberOfTerminatorPoints, + &res.targetEphemerisTime, + glm::value_ptr(res.observerPosition), + (double(*)[3])res.terminatorPoints.data() + ); + throwOnSpiceError(format( + "Error getting terminator ellipse for target '{}' from observer '{}' in frame " + "'{}' with light source '{}' at time '{}'", + target, observer, frame, lightSource, ephemerisTime + )); + return res; +} - throwOnSpiceError("Error getting " + terminatorType + - "terminator for'" + target + "'"); - - for (int i = 0; i < numberOfPoints; i++){ - psc point = psc::CreatePowerScaledCoordinate(tpoints[i][0], tpoints[i][1], tpoints[i][2]); - point[3] += 3; - terminatorPoints.push_back(point); - } - - return true; +bool SpiceManager::addFrame(std::string body, std::string frame) { + if (body == "" || frame == "") + return false; + else { + _frameByBody.push_back(std::make_pair(body, frame)); + return true; + } } std::string SpiceManager::frameFromBody(const std::string body) const { @@ -813,38 +815,6 @@ std::string SpiceManager::frameFromBody(const std::string body) const { return frame; } -bool SpiceManager::addFrame(const std::string body, const std::string frame) { - if (body == "" || frame == "") - return false; - else { - _frameByBody.push_back(std::make_pair(body, frame)); - return true; - } -} - -bool SpiceManager::getPlanetEllipsoid(std::string planetName, float &a, float &b, float &c) { - SpiceDouble radii[3]; - SpiceInt n = -1; - int id = -1; - - id = naifId(planetName); - if (bodfnd_c(id, "RADII")) { - bodvrd_c(planetName.c_str(), "RADII", 3, &n, radii); - a = static_cast(radii[0]); - b = static_cast(radii[1]); - c = static_cast(radii[2]); - } - else { - LWARNING("Could not find SPICE data for the shape of " + planetName + ", using modfile value"); - a = 1.f; - b = 1.f; - c = 1.f; - } - - throwOnSpiceError("Error retrieving planet radii of " + planetName); - return true; -} - void SpiceManager::findCkCoverage(const std::string& path) { ghoul_assert(!path.empty(), "Empty file path"); ghoul_assert(FileSys.fileExists(path), format("File '{}' does not exist", path)); From a087fe47e3820f2f4374a8c4dd102dc8c98beb19 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sat, 21 Nov 2015 10:39:26 -0500 Subject: [PATCH 044/122] Add fromString methods for enums --- include/openspace/util/spicemanager.h | 24 +++++++++++++++- src/util/spicemanager.cpp | 41 ++++++++++++++++++++++----- 2 files changed, 57 insertions(+), 8 deletions(-) diff --git a/include/openspace/util/spicemanager.h b/include/openspace/util/spicemanager.h index d5210e34c2..edfe308e8c 100644 --- a/include/openspace/util/spicemanager.h +++ b/include/openspace/util/spicemanager.h @@ -114,18 +114,40 @@ public: /// The direction of the aberration correction Direction direction = Direction::Reception; }; - + /// The possible values for the method parameter of the targetInFieldOfView method enum class FieldOfViewMethod { Ellipsoid = 0, Point }; + /** + * Returns the FieldOfViewMethod for the passed string. The allowed strings are + * ELLIPSOID and POINT. All other values will result in an + * exception. + * \param method The field of view method + * \throws std::out_of_range if \p method is not a valid string + * \pre \p method must not be empty + * \return The field of view method enum + */ + static FieldOfViewMethod fieldOfViewMethodFromString(const std::string& method); + /// The possible values for terminator type method of the terminatorEllipse method enum class TerminatorType { Umbral = 0, Penumbral }; + + /** + * Returns the TerminatorType for the passed string. The allowed strings are + * UMBRAL and PENUMBRAL. All other values will result in an + * exception. + * \param type The terminator type + * \param The terminator type enum + * \throws std::out_of_range if \p type is not a valid string + * \pre \p type must not be empty + */ + static TerminatorType terminatorTypeFromString(const std::string& type); /** * Loads one or more SPICE kernels into a program. The provided path can either be a diff --git a/src/util/spicemanager.cpp b/src/util/spicemanager.cpp index ea3561b92c..191d257b78 100644 --- a/src/util/spicemanager.cpp +++ b/src/util/spicemanager.cpp @@ -64,6 +64,15 @@ namespace { return "POINT"; } } + + const char* toString(openspace::SpiceManager::TerminatorType t) { + switch (t) { + case openspace::SpiceManager::TerminatorType::Umbral: + return "UMBRAL"; + case openspace::SpiceManager::TerminatorType::Penumbral: + return "PENUMBRAL"; + } + } } using fmt::format; @@ -119,6 +128,30 @@ SpiceManager::AberrationCorrection::operator const char*() const { return (direction == Direction::Reception) ? "CN+S" : "XCN+S"; } } + +SpiceManager::FieldOfViewMethod SpiceManager::fieldOfViewMethodFromString( + const string& method) +{ + const static std::map Mapping = { + { "ELLIPSOID", FieldOfViewMethod::Ellipsoid }, + { "POINT", FieldOfViewMethod::Point } + }; + + ghoul_assert(!method.empty(), "Method must not be empty"); + + return Mapping.at(method); +} + +SpiceManager::TerminatorType SpiceManager::terminatorTypeFromString( const string& type) { + const static std::map Mapping = { + { "UMBRAL", TerminatorType::Umbral }, + { "PENUMBRAL", TerminatorType::Penumbral } + }; + + ghoul_assert(!type.empty(), "Type must not be empty"); + + return Mapping.at(type); +} SpiceManager::SpiceManager() { // Set the SPICE library to not exit the program if an error occurs @@ -762,13 +795,7 @@ SpiceManager::TerminatorEllipseResult SpiceManager::terminatorEllipse( // Warning: This assumes std::vector to have all values memory contiguous res.terminatorPoints.resize(numberOfTerminatorPoints); - static const std::map Map = { - { TerminatorType::Umbral, "UMBRAL" }, - { TerminatorType::Penumbral, "PENUMBRAL" } - }; - string s = Map.at(terminatorType); - - edterm_c(s.c_str(), + edterm_c(toString(terminatorType), lightSource.c_str(), target.c_str(), ephemerisTime, From 2cc1a91fad312d03e58c0151b50bb1a6809ea91f Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sat, 21 Nov 2015 23:15:48 -0500 Subject: [PATCH 045/122] Rename SpiceKernelException to SpiceException --- include/openspace/util/spicemanager.h | 62 +++++++++---------- modules/base/ephemeris/spiceephemeris.cpp | 2 +- modules/base/rendering/renderabletrail.cpp | 2 +- .../rendering/renderablecrawlingline.cpp | 2 +- .../newhorizons/rendering/renderablefov.cpp | 2 +- .../rendering/renderablemodelprojection.cpp | 2 +- .../rendering/renderableplaneprojection.cpp | 2 +- .../rendering/renderableplanetprojection.cpp | 2 +- src/util/powerscaledsphere.cpp | 2 +- src/util/spicemanager.cpp | 16 ++--- 10 files changed, 47 insertions(+), 47 deletions(-) diff --git a/include/openspace/util/spicemanager.h b/include/openspace/util/spicemanager.h index edfe308e8c..bc05f17cc6 100644 --- a/include/openspace/util/spicemanager.h +++ b/include/openspace/util/spicemanager.h @@ -52,9 +52,9 @@ public: using TransformMatrix = std::array; using KernelHandle = unsigned int; - class SpiceKernelException : public ghoul::RuntimeError { + class SpiceException : public ghoul::RuntimeError { public: - explicit SpiceKernelException(const std::string& msg); + explicit SpiceException(const std::string& msg); }; /** @@ -158,7 +158,7 @@ public: * passed to absPath to convert a relative path to an absolute path * before usage * \return The loaded kernel's unique identifier that can be used to unload the kernel - * \throws SpiceKernelException If the loading of the kernel \p filePath failed if, + * \throws SpiceException If the loading of the kernel \p filePath failed if, * for example, \p filePath is not a valid SPICE kernel * \pre \p filePath must not be empty. * \pre \p filePath must be an absolute or relative path pointing to an existing file. @@ -187,7 +187,7 @@ public: * loading call to #loadKernel. The unloading is done by calling the * unload_c function. * \param filePath The path of the kernel that should be unloaded. - * \throws SpiceKernelException If the \p filePath has not been previously used to + * \throws SpiceException If the \p filePath has not been previously used to * successfully load a kernel. * \pre \p filePath must not be empty. * \post The kernel identified by \p filePath is unloaded. @@ -203,7 +203,7 @@ public: * \param et The time for which the coverage should be checked * \return true if SPK kernels have been loaded to cover \p target at the * time \p et, false otherwise. - * \throws SpiceKernelException If \p target does not name a valid SPICE object + * \throws SpiceException If \p target does not name a valid SPICE object * \pre \p target must not be empty. */ bool hasSpkCoverage(const std::string& target, double et) const; @@ -216,9 +216,9 @@ public: * \param et The time for which the coverage should be checked * \return true if SPK kernels have been loaded to cover \p target at the * time \p et , false otherwise. - * \throws SpiceKernelException If \p target does not name a valid SPICE object + * \throws SpiceException If \p target does not name a valid SPICE object or \p frame + * is not a valid frame * \pre \p target must not be empty. - * \throws SpiceKernelException If \p frame is not a valid frame */ bool hasCkCoverage(const std::string& frame, double et) const; @@ -239,7 +239,7 @@ public: * \param body The name of the body that should be sampled * \param item The item to find in the \p body * \return true if the function succeeded, false otherwise - * \throws SpiceKernelException If \p body does not name a valid SPICE object. + * \throws SpiceException If \p body does not name a valid SPICE object. * \pre \p body must not be empty. * \pre \item must not be empty. * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bodfnd_c.html @@ -252,7 +252,7 @@ public: * \param body The body name that should be retrieved * \return The ID of the body will be stored in this variable. The * value will only be changed if the retrieval was successful - * \throws SpiceKernelException If \p body does not name a valid SPICE object. + * \throws SpiceException If \p body does not name a valid SPICE object. * \pre \p body must not be empty. * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/bods2c_c.html * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html @@ -273,7 +273,7 @@ public: * Returns the NAIF ID for a specific frame using namfrm_c. * \param frame The frame name that should be retrieved * \return The NAIF ID of the \p frame - * \throws SpiceKernelException If \p frame is not a valid frame. + * \throws SpiceException If \p frame is not a valid frame. * \pre \p frame must not be empty. * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/namfrm_c.html */ @@ -299,7 +299,7 @@ public: * this body * \param value The value that should be retrieved, this value is case-sensitive * \param v The destination for the retrieved value - * \throws SpiceKernelException If the \p body does not name a valid body, \t value + * \throws SpiceException If the \p body does not name a valid body, \t value * is not a valid item for the \p body or the retrieved value is not a single value. * \pre \p body must not be empty. * \pre \p value must not be empty. @@ -318,7 +318,7 @@ public: * this body * \param value The value that should be retrieved, this value is case-sensitive * \param v The destination for the retrieved value - * \throws SpiceKernelException If the \p body does not name a valid body, \t value + * \throws SpiceException If the \p body does not name a valid body, \t value * is not a valid item for the \p body or the retrieved value is not a two-component * value. * \pre \p body must not be empty. @@ -339,7 +339,7 @@ public: * this body * \param value The value that should be retrieved, this value is case-sensitive * \param v The destination for the retrieved value - * \throws SpiceKernelException If the \p body does not name a valid body, \t value + * \throws SpiceException If the \p body does not name a valid body, \t value * is not a valid item for the \p body or the retrieved value is not a three-component * value. * \pre \p body must not be empty. @@ -359,7 +359,7 @@ public: * this body * \param value The value that should be retrieved, this value is case-sensitive * \param v The destination for the retrieved value - * \throws SpiceKernelException If the \p body does not name a valid body, \t value + * \throws SpiceException If the \p body does not name a valid body, \t value * is not a valid item for the \p body or the retrieved value is not a four-component * value. * \pre \p body must not be empty. @@ -380,7 +380,7 @@ public: * \param value The value that should be retrieved, this value is case-sensitive * \param v The destination for the retrieved value. The vector must be * preallocated to the correct size of components that should be retrieved - * \throws SpiceKernelException If the \p body does not name a valid body, \t value + * \throws SpiceException If the \p body does not name a valid body, \t value * is not a valid item for the \p body or the retrieved value does not contain the * correct number of components * value. @@ -399,7 +399,7 @@ public: * \param craft The NAIF ID of the craft for which the time should be converted * \param craftTicks The internal clock ticks for the specified craft * \return The converted ephemeris time - * \throws SpiceKernelException If the name \p craft is not a valid name + * \throws SpiceException If the name \p craft is not a valid name * available through all loaded kernels, if the craft is not supported by any of the * loaded kernel, or if the provided \p craftTicks is not a valid tick time for the * specific spacecraft @@ -414,7 +414,7 @@ public: * \param timeString A string representing the time to be converted * \return The converted time; the number of TDB seconds past the J2000 epoch, * representing the passed \p timeString - * \throws SpiceKernelException If \p timeString is not a valid timestring according + * \throws SpiceException If \p timeString is not a valid timestring according * to the str2et_c function (see the Particulars section of the linked * webpage). * \pre \t timeString must not be empty @@ -450,7 +450,7 @@ public: * the observer and the target. * \return The position of the \p target relative to the \p observer in the specified * \p referenceFrame - * \throws SpiceKernelException If the \p target or \p observer do not name a valid + * \throws SpiceException If the \p target or \p observer do not name a valid * NAIF object, \p referenceFrame does not name a valid reference frame or if there is * not sufficient data available to compute the position or neither the target nor the * observer have coverage. @@ -474,7 +474,7 @@ public: * \param to The frame to be converted to * \param ephemerisTime Time at which to get the transformation matrix * \return The transformation matrix - * \throws SpiceKernelException If the transformation matrix between \p from and \p to + * \throws SpiceException If the transformation matrix between \p from and \p to * cannot be determined. * \pre \p from must not be empty. * \pre \p to must not be empty. @@ -524,7 +524,7 @@ public: * \param surfaceVector Vector from observer to intercept point * \param isVisible Flag indicating whether intercept was found * \return true if not error occurred, false otherwise - * \throws SpiceKernelException If the \p target or \p observer do not name the same + * \throws SpiceException If the \p target or \p observer do not name the same * NAIF object, the \p target or \p observer name the same NAIF object or are in the * same location, the \p referenceFrame or \p fovFrame are not recognized, * insufficient kernel information has been loaded. @@ -554,7 +554,7 @@ public: * \param aberrationCorrection The aberration correction method * \param ephemerisTime Time of the observation (seconds past J2000) * \return true if the target is visible, false otherwise - * \throws SpiceKernelException If the \p target or \p observer do not name valid + * \throws SpiceException If the \p target or \p observer do not name valid * NAIF objects, the \p target or \p observer name the same NAIF object, the * \p instrument does not name a valid NAIF object, or insufficient kernel information * has been loaded. @@ -582,7 +582,7 @@ public: * \param aberrationCorrection The aberration correction method * \param ephemerisTime Time of the observation (seconds past J2000) * \return true if the target is visible, false otherwise - * \throws SpiceKernelException If the \p target or \p observer do not name valid + * \throws SpiceException If the \p target or \p observer do not name valid * NAIF objects, the \p target or \p observer name the same NAIF object, the * \p instrument does not name a valid NAIF object, or insufficient kernel information * has been loaded. @@ -624,7 +624,7 @@ public: * the target; and the lightTime, containing the one-way light time * between the \p target and the \p observer. This method is only set if the * \p aberrationCorrection is set to a valid different from AberrationCorrection::None - * \throws SpiceKernelException If the \p target or \p observer do not name a valid + * \throws SpiceException If the \p target or \p observer do not name a valid * NAIF object, the \p referenceFrame is not a valid frame, or if there is * insufficient kernel information. * \pre \p target must not be empty. @@ -649,7 +649,7 @@ public: * returned * \return The TransformMatrix containing the transformation matrix that defines the * transformation from the \p sourceFrame to the \p destinationFrame - * \throws SpiceKernelException If the \p sourceFrame or the \p destinationFrame is + * \throws SpiceException If the \p sourceFrame or the \p destinationFrame is * not a valid frame * \pre \p sourceFrame must not be empty. * \pre \p destinatoinFrame must not be empty. @@ -667,7 +667,7 @@ public: * \param ephemerisTime The time at which the transformation matrix is to be queried * \return The transformation matrix that defines the transformation from the * \p sourceFrame to the \p destinationFrame - * \throws SpiceKernelException If there is no coverage available for the specified + * \throws SpiceException If there is no coverage available for the specified * \p sourceFrame, \p destinationFrame, \p ephemerisTime combination * \pre \p sourceFrame must not be empty * \pre \p destinationFrame must not be empty @@ -686,7 +686,7 @@ public: * \param ephemerisTimeTo The time for the destination reference frame * \return Thetransformation matrix that maps between the \p sourceFrame at time * \p ephemerisTimeFrom to the \p destinationFrame at the time \p ephemerisTimeTo. - * \throws SpiceKernelException If there is no coverage available for the specified + * \throws SpiceException If there is no coverage available for the specified * \p sourceFrame and \p destinationFrame * \pre \p sourceFrame must not be empty. * \pre \p destinationFrame must not be empty. @@ -723,7 +723,7 @@ public: * \param instrument The name of the instrument for which the FOV is to be retrieved * \return The FieldOfViewResult structure that contains information about the field * of view. - * \throw SpiceKernelException If \p instrument does not name a valid NAIF object + * \throw SpiceException If \p instrument does not name a valid NAIF object * \pre \p instrument must not be empty * \post The returned structure has all its values initialized * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/getfov_c.html @@ -737,7 +737,7 @@ public: * \param instrument The name of the instrument for which the FOV is to be retrieved * \return The FieldOfViewResult structure that contains information about the field * of view. - * \throw SpiceKernelException If \p instrument does not name a valid NAIF object + * \throw SpiceException If \p instrument does not name a valid NAIF object * \post The returned structure has all its values initialized * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/getfov_c.html */ @@ -775,7 +775,7 @@ public: * by this method * \return A TerminatorEllipseResult structure that contains all outputs of this * function - * \throws SpiceKernelException If the \p target, \p observer, or \p lightSource are + * \throws SpiceException If the \p target, \p observer, or \p lightSource are * not valid NAIF names, the \p frame is not a valid NAIF frame or there is * insufficient kernel data loaded * \pre \p target must not be empty @@ -866,7 +866,7 @@ private: * AbberationCorrection::Type::None, this variable will contain the light time between * the observer and the target. * \return The position of the \p target relative to the \p origin - * \throws SpiceKernelException If the \p target or \p origin are not valid NAIF + * \throws SpiceException If the \p target or \p origin are not valid NAIF * objects or if there is no position for the \p target at any time * \pre \p target must not be empty * \pre \p observer must not be empty @@ -889,7 +889,7 @@ private: * \param toFrame The reference frame into which the resulting matrix will transformed * \param time The time for which an estimated transform matrix is requested * \return The estimated transform matrix of the frame - * \throws SpiceKernelException If there is no coverage available for the specified + * \throws SpiceException If there is no coverage available for the specified * \p sourceFrame and \p destinationFrame or the reference frames do not name a valid * NAIF frame. * \pre \p fromFrame must not be empty diff --git a/modules/base/ephemeris/spiceephemeris.cpp b/modules/base/ephemeris/spiceephemeris.cpp index e687a512e2..cd94ef2fa7 100644 --- a/modules/base/ephemeris/spiceephemeris.cpp +++ b/modules/base/ephemeris/spiceephemeris.cpp @@ -66,7 +66,7 @@ SpiceEphemeris::SpiceEphemeris(const ghoul::Dictionary& dictionary) SpiceManager::KernelHandle id = SpiceManager::ref().loadKernel(kernel); _kernelsLoadedSuccessfully = true; } - catch (const SpiceManager::SpiceKernelException& e) { + catch (const SpiceManager::SpiceException& e) { LERROR("Could not load SPICE kernel: " << e.what()); _kernelsLoadedSuccessfully = false; } diff --git a/modules/base/rendering/renderabletrail.cpp b/modules/base/rendering/renderabletrail.cpp index 4bb2d5b9f8..0445483fd1 100644 --- a/modules/base/rendering/renderabletrail.cpp +++ b/modules/base/rendering/renderabletrail.cpp @@ -302,7 +302,7 @@ void RenderableTrail::fullYearSweep(double time) { p = SpiceManager::ref().targetPosition(_target, _observer, _frame, {}, time, lightTime); } - catch (const SpiceManager::SpiceKernelException& e) { + catch (const SpiceManager::SpiceException& e) { // This fires for PLUTO BARYCENTER and SUN and uses the only value sometimes? // ---abock // LERROR(e.what()); diff --git a/modules/newhorizons/rendering/renderablecrawlingline.cpp b/modules/newhorizons/rendering/renderablecrawlingline.cpp index 1e5fcb7025..90bf87bc09 100644 --- a/modules/newhorizons/rendering/renderablecrawlingline.cpp +++ b/modules/newhorizons/rendering/renderablecrawlingline.cpp @@ -166,7 +166,7 @@ void RenderableCrawlingLine::update(const UpdateData& data) { boresight = res.boresightVector; } - catch (const SpiceManager::SpiceKernelException& e) { + catch (const SpiceManager::SpiceException& e) { LERROR(e.what()); } diff --git a/modules/newhorizons/rendering/renderablefov.cpp b/modules/newhorizons/rendering/renderablefov.cpp index 371df7ab72..f37c9be9c2 100644 --- a/modules/newhorizons/rendering/renderablefov.cpp +++ b/modules/newhorizons/rendering/renderablefov.cpp @@ -121,7 +121,7 @@ void RenderableFov::allocateData() { _isteps = 10; // Interpolation steps per intersecting segment } - catch (const SpiceManager::SpiceKernelException& e) { + catch (const SpiceManager::SpiceException& e) { LERROR(e.what()); } } diff --git a/modules/newhorizons/rendering/renderablemodelprojection.cpp b/modules/newhorizons/rendering/renderablemodelprojection.cpp index 5343c277e7..04d16386d8 100644 --- a/modules/newhorizons/rendering/renderablemodelprojection.cpp +++ b/modules/newhorizons/rendering/renderablemodelprojection.cpp @@ -427,7 +427,7 @@ void RenderableModelProjection::attitudeParameters(double time) { try { SpiceManager::FieldOfViewResult res = SpiceManager::ref().fieldOfView(_instrumentID); boresight = std::move(res.boresightVector); - } catch (const SpiceManager::SpiceKernelException& e) { + } catch (const SpiceManager::SpiceException& e) { return; } diff --git a/modules/newhorizons/rendering/renderableplaneprojection.cpp b/modules/newhorizons/rendering/renderableplaneprojection.cpp index 367fa04cc2..c5cbd1f66f 100644 --- a/modules/newhorizons/rendering/renderableplaneprojection.cpp +++ b/modules/newhorizons/rendering/renderableplaneprojection.cpp @@ -230,7 +230,7 @@ void RenderablePlaneProjection::updatePlane(const Image img, double currentTime) frame = std::move(res.frameName); bounds = std::move(res.bounds); boresight = std::move(res.boresightVector); - } catch (const SpiceManager::SpiceKernelException& e) { + } catch (const SpiceManager::SpiceException& e) { LERROR(e.what()); } diff --git a/modules/newhorizons/rendering/renderableplanetprojection.cpp b/modules/newhorizons/rendering/renderableplanetprojection.cpp index 4f8941d90d..c3d8a5a24c 100644 --- a/modules/newhorizons/rendering/renderableplanetprojection.cpp +++ b/modules/newhorizons/rendering/renderableplanetprojection.cpp @@ -429,7 +429,7 @@ void RenderablePlanetProjection::attitudeParameters(double time){ SpiceManager::FieldOfViewResult res = SpiceManager::ref().fieldOfView(_instrumentID); bs = std::move(res.boresightVector); } - catch (const SpiceManager::SpiceKernelException& e) { + catch (const SpiceManager::SpiceException& e) { return; } diff --git a/src/util/powerscaledsphere.cpp b/src/util/powerscaledsphere.cpp index 198a972f34..c1635a8f9f 100644 --- a/src/util/powerscaledsphere.cpp +++ b/src/util/powerscaledsphere.cpp @@ -148,7 +148,7 @@ PowerScaledSphere::PowerScaledSphere(properties::Vec4Property &radius, int segme c = radii.z; accutareRadius = true; } - catch (const SpiceManager::SpiceKernelException& e) { + catch (const SpiceManager::SpiceException& e) { LWARNING("Could not find radius for body " << planetName); accutareRadius = false; } diff --git a/src/util/spicemanager.cpp b/src/util/spicemanager.cpp index 191d257b78..f5f7586e7a 100644 --- a/src/util/spicemanager.cpp +++ b/src/util/spicemanager.cpp @@ -50,7 +50,7 @@ namespace { char buffer[SpiceErrorBufferSize]; getmsg_c("LONG", SpiceErrorBufferSize, buffer); reset_c(); - throw openspace::SpiceManager::SpiceKernelException( + throw openspace::SpiceManager::SpiceException( errorMessage + ": " + buffer ); } @@ -81,7 +81,7 @@ using std::string; namespace openspace { -SpiceManager::SpiceKernelException::SpiceKernelException(const string& msg) +SpiceManager::SpiceException::SpiceException(const string& msg) : ghoul::RuntimeError(msg, "Spice") {} @@ -267,7 +267,7 @@ void SpiceManager::unloadKernel(string filePath) { [&path](const KernelInformation& info) { return info.path == path; }); if (it == _loadedKernels.end()) { - throw SpiceKernelException( + throw SpiceException( format("'{}' did not correspond to a loaded kernel", path) ); } @@ -336,7 +336,7 @@ int SpiceManager::naifId(const string& body) const { int id; bods2c_c(body.c_str(), &id, &success); if (!success) - throw SpiceKernelException(format("Could not find NAIF ID of body '{}'", body)); + throw SpiceException(format("Could not find NAIF ID of body '{}'", body)); return id; } @@ -356,7 +356,7 @@ int SpiceManager::frameId(const string& frame) const { int id; namfrm_c(frame.c_str(), &id); if (id == 0) - throw SpiceKernelException(format("Could not find NAIF ID of frame '{}'", frame)); + throw SpiceException(format("Could not find NAIF ID of frame '{}'", frame)); return id; } @@ -468,7 +468,7 @@ glm::dvec3 SpiceManager::targetPosition(const string& target, const string& obse bool targetHasCoverage = hasSpkCoverage(target, ephemerisTime); bool observerHasCoverage = hasSpkCoverage(observer, ephemerisTime); if (!targetHasCoverage && !observerHasCoverage){ - throw SpiceKernelException( + throw SpiceException( format("Neither the target '{}' nor observer '{}' has SPK coverage", target, observer @@ -936,7 +936,7 @@ glm::dvec3 SpiceManager::getEstimatedPosition(const std::string& target, if (_spkCoverageTimes.find(targetId) == _spkCoverageTimes.end()) { // no coverage - throw SpiceKernelException(format("No position for '{}' at any time", target)); + throw SpiceException(format("No position for '{}' at any time", target)); } @@ -1028,7 +1028,7 @@ glm::dmat3 SpiceManager::getEstimatedTransformMatrix(const std::string& fromFram if (_ckCoverageTimes.find(idFrame) == _ckCoverageTimes.end()) { // no coverage - throw SpiceKernelException(format( + throw SpiceException(format( "No data available for the transform matrix from '{}' to '{}' at any time", fromFrame, toFrame )); From 01c1586616f9fbe55acbf15005eefa75cf70f82e Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 22 Nov 2015 02:53:44 -0500 Subject: [PATCH 046/122] Updated OpenSpace's requirement to C++14 Adopted changes from Ghoul cleanup --- ext/ghoul | 2 +- src/engine/openspaceengine.cpp | 43 +++++++++++++++--------------- support/cmake/support_macros.cmake | 2 +- 3 files changed, 24 insertions(+), 23 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index 5c11a98058..246f3a0417 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 5c11a98058a10078c7802006563a9d8989bd7e27 +Subproject commit 246f3a041751cf48a7321b04c80884e57cb50431 diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index ea7e9f8f68..cc16bef537 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -59,8 +59,8 @@ #include #include -// std #include +#include #include #ifdef OPENSPACE_MODULE_ONSCREENGUI_ENABLED @@ -211,15 +211,17 @@ bool OpenSpaceEngine::create( _engine = new OpenSpaceEngine(std::string(argv[0]), windowWrapper); // Query modules for commandline arguments - const bool gatherSuccess = _engine->gatherCommandlineArguments(); + bool gatherSuccess = _engine->gatherCommandlineArguments(); if (!gatherSuccess) return false; // Parse commandline arguments - _engine->_commandlineParser->setCommandLine(argc, argv, &sgctArguments); - const bool executeSuccess = _engine->_commandlineParser->execute(); - if (!executeSuccess) - return false; + sgctArguments = *(_engine->_commandlineParser->setCommandLine(argc, argv)); + bool showHelp = _engine->_commandlineParser->execute(); + if (showHelp) { + _engine->_commandlineParser->displayHelp(); + return false; + } // Find configuration std::string configurationFilePath = commandlineArgumentPlaceholders.configurationName; @@ -428,26 +430,25 @@ void OpenSpaceEngine::clearAllWindows() { bool OpenSpaceEngine::gatherCommandlineArguments() { // TODO: Get commandline arguments from all modules - + commandlineArgumentPlaceholders.configurationName = ""; - CommandlineCommand* configurationFileCommand = new SingleCommand( - &commandlineArgumentPlaceholders.configurationName, "-config", "-c", - "Provides the path to the OpenSpace configuration file"); - _commandlineParser->addCommand(configurationFileCommand); + _commandlineParser->addCommand(std::make_unique>( + &commandlineArgumentPlaceholders.configurationName, "-config", "-c", + "Provides the path to the OpenSpace configuration file" + )); commandlineArgumentPlaceholders.sgctConfigurationName = ""; - CommandlineCommand* sgctConfigFileCommand = new SingleCommand( - &commandlineArgumentPlaceholders.sgctConfigurationName, "-sgct", "-s", - "Provides the path to the SGCT configuration file, overriding the value set in" - "the OpenSpace configuration file"); - _commandlineParser->addCommand(sgctConfigFileCommand); + _commandlineParser->addCommand(std::make_unique>( + &commandlineArgumentPlaceholders.sgctConfigurationName, "-sgct", "-s", + "Provides the path to the SGCT configuration file, overriding the value set in " + "the OpenSpace configuration file" + )); commandlineArgumentPlaceholders.sceneName = ""; - CommandlineCommand* sceneFileCommand = new SingleCommand( - &commandlineArgumentPlaceholders.sceneName, "-scene", "", - "Provides the path to the scene file, overriding the value set in the OpenSpace" - " configuration file"); - _commandlineParser->addCommand(sceneFileCommand); + _commandlineParser->addCommand(std::make_unique>( + &commandlineArgumentPlaceholders.sceneName, "-scene", "", "Provides the path to " + "the scene file, overriding the value set in the OpenSpace configuration file" + )); return true; } diff --git a/support/cmake/support_macros.cmake b/support/cmake/support_macros.cmake index dff35e5e66..59e62b45bc 100644 --- a/support/cmake/support_macros.cmake +++ b/support/cmake/support_macros.cmake @@ -76,7 +76,7 @@ endfunction () function (set_compile_settings project) - set_property(TARGET ${project} PROPERTY CXX_STANDARD 11) + set_property(TARGET ${project} PROPERTY CXX_STANDARD 14) set_property(TARGET ${project} PROPERTY CXX_STANDARD_REQUIRED On) if (MSVC) From 3806318b0da2dad99fdf3656773a97baea2adffc Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 22 Nov 2015 21:26:02 -0500 Subject: [PATCH 047/122] Applied Ghoul cleanups --- ext/ghoul | 2 +- include/openspace/util/spicemanager.h | 3 +-- modules/base/rendering/modelgeometry.cpp | 3 +-- modules/base/rendering/renderablestars.cpp | 3 +-- modules/onscreengui/src/gui.cpp | 4 ++-- modules/volume/rendering/renderablevolume.cpp | 5 +++-- src/interaction/luaconsole.cpp | 2 +- 7 files changed, 10 insertions(+), 12 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index 246f3a0417..7cbe2871c8 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 246f3a041751cf48a7321b04c80884e57cb50431 +Subproject commit 7cbe2871c85dba64d5341560d8e1ef5d1f57e496 diff --git a/include/openspace/util/spicemanager.h b/include/openspace/util/spicemanager.h index bc05f17cc6..bee2f11b8a 100644 --- a/include/openspace/util/spicemanager.h +++ b/include/openspace/util/spicemanager.h @@ -52,8 +52,7 @@ public: using TransformMatrix = std::array; using KernelHandle = unsigned int; - class SpiceException : public ghoul::RuntimeError { - public: + struct SpiceException : public ghoul::RuntimeError { explicit SpiceException(const std::string& msg); }; diff --git a/modules/base/rendering/modelgeometry.cpp b/modules/base/rendering/modelgeometry.cpp index 155b34e76a..1fa6720cf1 100644 --- a/modules/base/rendering/modelgeometry.cpp +++ b/modules/base/rendering/modelgeometry.cpp @@ -146,8 +146,7 @@ void ModelGeometry::deinitialize() { } bool ModelGeometry::loadObj(const std::string& filename) { - std::string cachedFile = ""; - FileSys.cacheManager()->getCachedFile(filename, cachedFile, true); + std::string cachedFile = FileSys.cacheManager()->cachedFilename(filename, true); bool hasCachedFile = FileSys.fileExists(cachedFile); if (hasCachedFile) { diff --git a/modules/base/rendering/renderablestars.cpp b/modules/base/rendering/renderablestars.cpp index a9a4cc8832..d3da22ce01 100644 --- a/modules/base/rendering/renderablestars.cpp +++ b/modules/base/rendering/renderablestars.cpp @@ -349,8 +349,7 @@ void RenderableStars::update(const UpdateData& data) { bool RenderableStars::loadData() { std::string _file = _speckFile; - std::string cachedFile = ""; - FileSys.cacheManager()->getCachedFile(_file, cachedFile, true); + std::string cachedFile = FileSys.cacheManager()->cachedFilename(_file, true); bool hasCachedFile = FileSys.fileExists(cachedFile); if (hasCachedFile) { diff --git a/modules/onscreengui/src/gui.cpp b/modules/onscreengui/src/gui.cpp index ae6d7453aa..ac26504e73 100644 --- a/modules/onscreengui/src/gui.cpp +++ b/modules/onscreengui/src/gui.cpp @@ -150,8 +150,8 @@ void GUI::setEnabled(bool enabled) { } void GUI::initialize() { - std::string cachedFile; - FileSys.cacheManager()->getCachedFile(configurationFile, "", cachedFile, true); + std::string cachedFile = FileSys.cacheManager()->cachedFilename(configurationFile, + "", true); char* buffer = new char[cachedFile.size() + 1]; diff --git a/modules/volume/rendering/renderablevolume.cpp b/modules/volume/rendering/renderablevolume.cpp index e9f1d2e60a..3794ed0e5c 100644 --- a/modules/volume/rendering/renderablevolume.cpp +++ b/modules/volume/rendering/renderablevolume.cpp @@ -140,9 +140,10 @@ ghoul::opengl::Texture* RenderableVolume::loadVolume( std::stringstream ss; ss << "." << dimensions[0] << "x" << dimensions[1] << "x" << dimensions[2] << "." << "." << variableCacheString << ".cache"; - std::string cachepath; // = filepath + ss.str(); + // = filepath + ss.str(); ghoul::filesystem::File ghlFile(filepath); - FileSys.cacheManager()->getCachedFile(ghlFile.baseName(), ss.str(), cachepath, true); + std::string cachepath = FileSys.cacheManager()->cachedFilename(ghlFile.baseName(), + ss.str(), true); if (cache && FileSys.fileExists(cachepath)) { #define VOLUME_LOAD_PROGRESSBAR diff --git a/src/interaction/luaconsole.cpp b/src/interaction/luaconsole.cpp index 0fca943962..ab4eb35f14 100644 --- a/src/interaction/luaconsole.cpp +++ b/src/interaction/luaconsole.cpp @@ -67,7 +67,7 @@ LuaConsole::~LuaConsole() { void LuaConsole::initialize() { - FileSys.cacheManager()->getCachedFile(historyFile, "", _filename, true); + _filename = FileSys.cacheManager()->cachedFilename(historyFile, "", true); std::ifstream file(absPath(_filename), std::ios::binary | std::ios::in); if (file.good()) { From 94663e7bf75be7d6bb90071d42e558a7dc068e9d Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 23 Nov 2015 12:03:08 -0500 Subject: [PATCH 048/122] Updated Ghoul version --- ext/ghoul | 2 +- src/engine/downloadmanager.cpp | 2 +- src/engine/openspaceengine.cpp | 3 +-- src/properties/property.cpp | 4 ++-- src/properties/propertyowner.cpp | 2 +- 5 files changed, 6 insertions(+), 7 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index 7cbe2871c8..f0cd30b929 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 7cbe2871c85dba64d5341560d8e1ef5d1f57e496 +Subproject commit f0cd30b9293776a09b927cbbb0041f7f45da44cb diff --git a/src/engine/downloadmanager.cpp b/src/engine/downloadmanager.cpp index fc48441157..884831dbdd 100644 --- a/src/engine/downloadmanager.cpp +++ b/src/engine/downloadmanager.cpp @@ -205,7 +205,7 @@ std::vector DownloadManager::downloadRequestFiles( DownloadProgressCallback progressCallback) { std::vector futures; - bool s = FileSys.createDirectory(destination, true); + FileSys.createDirectory(destination, true); // TODO: Check s ---abock // TODO: Escaping is necessary ---abock const std::string fullRequest =_requestURL + "?" + diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index cc16bef537..68b3fd3081 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -260,8 +260,7 @@ bool OpenSpaceEngine::create( if (!FileSys.directoryExists(token)) { std::string p = absPath(token); LDEBUG("Directory '" << p << "' does not exist, creating."); - if (!FileSys.createDirectory(p, true)) - LERROR("Directory '" << p << "' could not be created"); + FileSys.createDirectory(p, true); } } diff --git a/src/properties/property.cpp b/src/properties/property.cpp index cb839c9c10..3115fdefc1 100644 --- a/src/properties/property.cpp +++ b/src/properties/property.cpp @@ -115,7 +115,7 @@ bool Property::setStringValue(std::string value) { std::string Property::guiName() const { std::string result; _metaData.getValue(_metaDataKeyGuiName, result); - return std::move(result); + return result; } std::string Property::description() const { @@ -129,7 +129,7 @@ void Property::setGroupIdentifier(std::string groupId) { std::string Property::groupIdentifier() const { std::string result; _metaData.getValue(_metaDataKeyGroup, result); - return std::move(result); + return result; } void Property::setVisible(bool state) { diff --git a/src/properties/propertyowner.cpp b/src/properties/propertyowner.cpp index 3872831d17..ae753170cc 100644 --- a/src/properties/propertyowner.cpp +++ b/src/properties/propertyowner.cpp @@ -67,7 +67,7 @@ std::vector PropertyOwner::propertiesRecursive() const { props.insert(props.end(), p.begin(), p.end()); } - return std::move(props); + return props; } Property* PropertyOwner::property(const std::string& id) const { From 293faf8ca95a53f1b316e2408a2df46b07cca99c Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 23 Nov 2015 20:18:38 -0500 Subject: [PATCH 049/122] Adopted cleaned up fontrendering code --- ext/ghoul | 2 +- include/openspace/rendering/renderengine.h | 6 ++-- src/network/parallelconnection.cpp | 3 ++ src/rendering/renderengine.cpp | 38 +++++++++++----------- 4 files changed, 26 insertions(+), 23 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index f0cd30b929..821877ddfb 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit f0cd30b9293776a09b927cbbb0041f7f45da44cb +Subproject commit 821877ddfb79ef11731010364b758977b55f76b3 diff --git a/include/openspace/rendering/renderengine.h b/include/openspace/rendering/renderengine.h index 5164ebd4da..bab2a4ee05 100644 --- a/include/openspace/rendering/renderengine.h +++ b/include/openspace/rendering/renderengine.h @@ -144,9 +144,9 @@ private: int _fadeDirection; // bool _sgctRenderStatisticsVisible; - ghoul::fontrendering::Font* _fontInfo = nullptr; - ghoul::fontrendering::Font* _fontDate = nullptr; - ghoul::fontrendering::Font* _fontLog = nullptr; + std::shared_ptr _fontInfo = nullptr; + std::shared_ptr _fontDate = nullptr; + std::shared_ptr _fontLog = nullptr; bool _visualizeABuffer; ABufferVisualizer* _visualizer; diff --git a/src/network/parallelconnection.cpp b/src/network/parallelconnection.cpp index d894f3fda7..9f24d40a95 100644 --- a/src/network/parallelconnection.cpp +++ b/src/network/parallelconnection.cpp @@ -112,6 +112,9 @@ ParallelConnection::~ParallelConnection(){ } void ParallelConnection::threadManagement(){ + // The _disconnectCondition.wait(unqlock) stalls + // How about moving this out of the thread and into the destructor? ---abock + //while we're still running while(_isRunning.load()){ { diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 64d6e2f631..06ca518def 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -427,19 +427,19 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi ); penPosition.y -= _fontDate->height(); - RenderFontCr(_fontDate, + RenderFontCr(*_fontDate, penPosition, "Date: %s", Time::ref().currentTimeUTC().c_str() ); - RenderFontCr(_fontInfo, + RenderFontCr(*_fontInfo, penPosition, "Simulation increment (s): %.0f", Time::ref().deltaTime() ); - RenderFontCr(_fontInfo, + RenderFontCr(*_fontInfo, penPosition, "Avg. Frametime: %.5f", OsEng.windowWrapper().averageDeltaTime() @@ -464,7 +464,7 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi float radius = (a + b) / 2.f; float distToSurf = glm::length(nhPos.vec3()) - radius; - RenderFont(_fontInfo, + RenderFont(*_fontInfo, penPosition, "Distance to Pluto: % .1f (KM)", distToSurf @@ -495,20 +495,20 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi if (remaining > 0) { brigther_active *= (1 - t); - RenderFontCr(_fontInfo, + RenderFontCr(*_fontInfo, penPosition, active * t + brigther_active, "Next instrument activity:" ); - RenderFontCr(_fontInfo, + RenderFontCr(*_fontInfo, penPosition, active * t + brigther_active, "%.0f s %s %.1f %%", remaining, progress.c_str(), t * 100 ); - RenderFontCr(_fontInfo, + RenderFontCr(*_fontInfo, penPosition, active, "Data acquisition time: %s", @@ -536,7 +536,7 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi mm.append(std::to_string(minute)); ss.append(std::to_string(second)); - RenderFontCr(_fontInfo, + RenderFontCr(*_fontInfo, penPosition, targetColor, "Data acquisition adjacency: [%s:%s:%s]", @@ -554,7 +554,7 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi t += 0.3; color = (p == isize / 2) ? targetColor : glm::vec4(t, t, t, 1); - RenderFont(_fontInfo, + RenderFont(*_fontInfo, penPosition, color, "%s%s", @@ -571,7 +571,7 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi glm::vec4 firing(0.58-t, 1-t, 1-t, 1); glm::vec4 notFiring(0.5, 0.5, 0.5, 1); - RenderFontCr(_fontInfo, + RenderFontCr(*_fontInfo, penPosition, active, "Active Instruments:" @@ -579,12 +579,12 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi for (auto t : activeMap){ if (t.second == false) { - RenderFont(_fontInfo, + RenderFont(*_fontInfo, penPosition, glm::vec4(0.3, 0.3, 0.3, 1), "| |" ); - RenderFontCr(_fontInfo, + RenderFontCr(*_fontInfo, penPosition, glm::vec4(0.3, 0.3, 0.3, 1), " %5s", @@ -593,24 +593,24 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi } else{ - RenderFont(_fontInfo, + RenderFont(*_fontInfo, penPosition, glm::vec4(0.3, 0.3, 0.3, 1), "|" ); if (t.first == "NH_LORRI") { - RenderFont(_fontInfo, + RenderFont(*_fontInfo, penPosition, firing, " + " ); } - RenderFont(_fontInfo, + RenderFont(*_fontInfo, penPosition, glm::vec4(0.3, 0.3, 0.3, 1), " |" ); - RenderFontCr(_fontInfo, + RenderFontCr(*_fontInfo, penPosition, active, " %5s", @@ -665,7 +665,7 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi const std::string& message = e->message.substr(0, msg_length); nr += std::count(message.begin(), message.end(), '\n'); - RenderFont(_fontLog, + RenderFont(*_fontLog, glm::vec2(10.f, _fontLog->pointSize() * nr * 2), white * alpha, "%-14s %s%s", // Format @@ -684,13 +684,13 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi color = blue; // const float font_with_light = 5; - RenderFont(_fontLog, + RenderFont(*_fontLog, glm::vec2(static_cast(10 + 39 * _fontLog->pointSize()), _fontLog->pointSize() * nr * 2), color * alpha, "%s", // Format lvl.c_str()); // Pad category with "..." if exceeds category_length - RenderFont(_fontLog, + RenderFont(*_fontLog, glm::vec2(static_cast(10 + 53 * _fontLog->pointSize()), _fontLog->pointSize() * nr * 2), white * alpha, "%s", // Format From a9ba03d143a5d46a51f0853973c526bb488ed43f Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 23 Nov 2015 22:10:37 -0500 Subject: [PATCH 050/122] Updated Ghoul version --- ext/ghoul | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/ghoul b/ext/ghoul index 821877ddfb..c040a8b62b 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 821877ddfb79ef11731010364b758977b55f76b3 +Subproject commit c040a8b62baed9f3a989656c42cd3294cffb68ef From fbc501450a4ffe30e8b143c60b3092b72a46e930 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 23 Nov 2015 22:24:13 -0500 Subject: [PATCH 051/122] Updated support files to enable SPICE on MSVC14 --- src/engine/wrapper/sgctwindowwrapper.cpp | 3 +++ support/cmake/FindSGCT.cmake | 2 ++ support/cmake/FindSpice.cmake | 9 ++++++--- support/cmake/support_macros.cmake | 2 +- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/engine/wrapper/sgctwindowwrapper.cpp b/src/engine/wrapper/sgctwindowwrapper.cpp index d24920f091..3ea2257658 100644 --- a/src/engine/wrapper/sgctwindowwrapper.cpp +++ b/src/engine/wrapper/sgctwindowwrapper.cpp @@ -27,6 +27,9 @@ #include +#undef near +#undef far + namespace openspace { void SGCTWindowWrapper::setBarrier(bool enabled) { diff --git a/support/cmake/FindSGCT.cmake b/support/cmake/FindSGCT.cmake index 4a01c0a15e..eedf04c3f2 100644 --- a/support/cmake/FindSGCT.cmake +++ b/support/cmake/FindSGCT.cmake @@ -46,6 +46,8 @@ if(WIN32) set(SGCT_LIBRARY_FOLDER "${SGCT_ROOT_DIR}/lib/msvc11") elseif (MSVC12) set(SGCT_LIBRARY_FOLDER "${SGCT_ROOT_DIR}/lib/msvc12") + elseif (MSVC14) + set(SGCT_LIBRARY_FOLDER "${SGCT_ROOT_DIR}/lib/msvc14") endif (MSVC10) if (CMAKE_CL_64) diff --git a/support/cmake/FindSpice.cmake b/support/cmake/FindSpice.cmake index 5c63a4c5ab..388d196354 100644 --- a/support/cmake/FindSpice.cmake +++ b/support/cmake/FindSpice.cmake @@ -1,9 +1,12 @@ - - set(SPICE_INCLUDE_DIR "${SPICE_ROOT_DIR}/include") if(WIN32) - set(SPICE_LIBRARY "${SPICE_ROOT_DIR}/lib/msvc12/cspice.lib") + if (${MSVC_VERSION} EQUAL 1800) + set(SPICE_LIBRARY "${SPICE_ROOT_DIR}/lib/msvc12/cspice.lib") + endif () + if (${MSVC_VERSION} EQUAL 1900) + set(SPICE_LIBRARY "${SPICE_ROOT_DIR}/lib/msvc14/cspice.lib") + endif () elseif(APPLE) set(SPICE_LIBRARY "${SPICE_ROOT_DIR}/lib/gcc_osx/cspice.a") else() diff --git a/support/cmake/support_macros.cmake b/support/cmake/support_macros.cmake index dff35e5e66..1904a4cf54 100644 --- a/support/cmake/support_macros.cmake +++ b/support/cmake/support_macros.cmake @@ -140,7 +140,7 @@ function (add_external_dependencies) set_property(TARGET lz4 PROPERTY FOLDER "External") set_property(TARGET tinyobjloader PROPERTY FOLDER "External") - # # SGCT + # SGCT find_package(SGCT REQUIRED) target_include_directories(libOpenSpace SYSTEM PUBLIC ${SGCT_INCLUDE_DIRECTORIES}) target_link_libraries(libOpenSpace ${SGCT_LIBRARIES}) From 383c7028a8b4747d29038ab3d699ec57cb5f6058 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 24 Nov 2015 18:15:23 -0500 Subject: [PATCH 052/122] Applied changes in texture reading io classes to OpenSpace --- ext/ghoul | 2 +- modules/base/rendering/renderablemodel.cpp | 4 +--- modules/base/rendering/renderablemodel.h | 2 +- modules/base/rendering/renderableplane.cpp | 11 ++++------ modules/base/rendering/renderableplane.h | 2 +- modules/base/rendering/renderableplanet.cpp | 10 ++------- modules/base/rendering/renderableplanet.h | 4 ++-- modules/base/rendering/renderablesphere.cpp | 7 ++----- modules/base/rendering/renderablesphere.h | 2 +- modules/base/rendering/renderablestars.cpp | 12 ++++------- modules/base/rendering/renderablestars.h | 4 ++-- modules/newhorizons/newhorizonsmodule.cpp | 2 -- .../rendering/renderablemodelprojection.cpp | 21 ++++--------------- .../rendering/renderablemodelprojection.h | 8 +++---- .../rendering/renderableplaneprojection.cpp | 8 +++---- .../rendering/renderableplaneprojection.h | 9 ++++---- .../rendering/renderableplanetprojection.cpp | 16 ++++---------- .../rendering/renderableplanetprojection.h | 10 ++++----- modules/volume/rendering/renderablevolume.cpp | 2 +- src/rendering/renderengine.cpp | 6 +++--- 20 files changed, 50 insertions(+), 92 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index c040a8b62b..ca2362fb5a 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit c040a8b62baed9f3a989656c42cd3294cffb68ef +Subproject commit ca2362fb5a8b7a4a2543c3c1c8ca1ed51a10f19c diff --git a/modules/base/rendering/renderablemodel.cpp b/modules/base/rendering/renderablemodel.cpp index 6cba9c1b4e..34d588437d 100644 --- a/modules/base/rendering/renderablemodel.cpp +++ b/modules/base/rendering/renderablemodel.cpp @@ -149,7 +149,6 @@ bool RenderableModel::deinitialize() { delete _geometry; _geometry = nullptr; } - delete _texture; _texture = nullptr; delete _programObject; @@ -253,10 +252,9 @@ void RenderableModel::update(const UpdateData& data) { } void RenderableModel::loadTexture() { - delete _texture; _texture = nullptr; if (_colorTexturePath.value() != "") { - _texture = ghoul::io::TextureReader::ref().loadTexture(absPath(_colorTexturePath)); + _texture = std::move(ghoul::io::TextureReader::ref().loadTexture(absPath(_colorTexturePath))); if (_texture) { LDEBUG("Loaded texture from '" << absPath(_colorTexturePath) << "'"); _texture->uploadTexture(); diff --git a/modules/base/rendering/renderablemodel.h b/modules/base/rendering/renderablemodel.h index 968f27a149..cd1025f958 100644 --- a/modules/base/rendering/renderablemodel.h +++ b/modules/base/rendering/renderablemodel.h @@ -60,7 +60,7 @@ private: properties::BoolProperty _performFade; properties::FloatProperty _fading; ghoul::opengl::ProgramObject* _programObject; - ghoul::opengl::Texture* _texture; + std::unique_ptr _texture; modelgeometry::ModelGeometry* _geometry; diff --git a/modules/base/rendering/renderableplane.cpp b/modules/base/rendering/renderableplane.cpp index ef7108646b..ae07fa66f7 100644 --- a/modules/base/rendering/renderableplane.cpp +++ b/modules/base/rendering/renderableplane.cpp @@ -166,7 +166,6 @@ bool RenderablePlane::deinitialize() { if (!_projectionListener){ // its parents job to kill texture // iff projectionlistener - delete _texture; _texture = nullptr; } @@ -190,8 +189,8 @@ void RenderablePlane::render(const RenderData& data) { //get parent node-texture and set with correct dimensions SceneGraphNode* textureNode = OsEng.renderEngine()->scene()->sceneGraphNode(_nodeName)->parent(); if (textureNode != nullptr){ - RenderablePlanetProjection *t = static_cast(textureNode->renderable()); - _texture = t->baseTexture(); + RenderablePlanetProjection* t = static_cast(textureNode->renderable()); + _texture = std::unique_ptr(t->baseTexture()); float h = _texture->height(); float w = _texture->width(); float scale = h / w; @@ -229,7 +228,7 @@ void RenderablePlane::update(const UpdateData& data) { void RenderablePlane::loadTexture() { if (_texturePath.value() != "") { - ghoul::opengl::Texture* texture = ghoul::io::TextureReader::ref().loadTexture(absPath(_texturePath)); + std::unique_ptr texture = ghoul::io::TextureReader::ref().loadTexture(absPath(_texturePath)); if (texture) { LDEBUG("Loaded texture from '" << absPath(_texturePath) << "'"); texture->uploadTexture(); @@ -237,9 +236,7 @@ void RenderablePlane::loadTexture() { // Textures of planets looks much smoother with AnisotropicMipMap rather than linear texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear); - if (_texture) - delete _texture; - _texture = texture; + _texture = std::move(texture); delete _textureFile; _textureFile = new ghoul::filesystem::File(_texturePath); diff --git a/modules/base/rendering/renderableplane.h b/modules/base/rendering/renderableplane.h index e4301cd7f0..136b999a2d 100644 --- a/modules/base/rendering/renderableplane.h +++ b/modules/base/rendering/renderableplane.h @@ -78,7 +78,7 @@ private: ghoul::opengl::ProgramObject* _shader; bool _textureIsDirty; - ghoul::opengl::Texture* _texture; + std::unique_ptr _texture; ghoul::filesystem::File* _textureFile; GLuint _quad; GLuint _vertexPositionBuffer; diff --git a/modules/base/rendering/renderableplanet.cpp b/modules/base/rendering/renderableplanet.cpp index 65d78eb81d..ffd2db0fd5 100644 --- a/modules/base/rendering/renderableplanet.cpp +++ b/modules/base/rendering/renderableplanet.cpp @@ -138,10 +138,6 @@ bool RenderablePlanet::deinitialize() { _geometry->deinitialize(); delete _geometry; } - if (_texture) - delete _texture; - if (_nightTexture) - delete _nightTexture; _geometry = nullptr; _texture = nullptr; @@ -222,10 +218,9 @@ void RenderablePlanet::update(const UpdateData& data){ } void RenderablePlanet::loadTexture() { - delete _texture; _texture = nullptr; if (_colorTexturePath.value() != "") { - _texture = ghoul::io::TextureReader::ref().loadTexture(absPath(_colorTexturePath)); + _texture = std::move(ghoul::io::TextureReader::ref().loadTexture(absPath(_colorTexturePath))); if (_texture) { LDEBUG("Loaded texture from '" << _colorTexturePath << "'"); _texture->uploadTexture(); @@ -237,10 +232,9 @@ void RenderablePlanet::loadTexture() { } } if (_hasNightTexture) { - delete _nightTexture; _nightTexture = nullptr; if (_nightTexturePath != "") { - _nightTexture = ghoul::io::TextureReader::ref().loadTexture(absPath(_nightTexturePath)); + _nightTexture = std::move(ghoul::io::TextureReader::ref().loadTexture(absPath(_nightTexturePath))); if (_nightTexture) { LDEBUG("Loaded texture from '" << _nightTexturePath << "'"); _nightTexture->uploadTexture(); diff --git a/modules/base/rendering/renderableplanet.h b/modules/base/rendering/renderableplanet.h index 9ce978fe72..69cb48ef52 100644 --- a/modules/base/rendering/renderableplanet.h +++ b/modules/base/rendering/renderableplanet.h @@ -63,8 +63,8 @@ protected: private: properties::StringProperty _colorTexturePath; ghoul::opengl::ProgramObject* _programObject; - ghoul::opengl::Texture* _texture; - ghoul::opengl::Texture* _nightTexture; + std::unique_ptr _texture; + std::unique_ptr _nightTexture; planetgeometry::PlanetGeometry* _geometry; properties::BoolProperty _performShading; properties::IntProperty _rotation; diff --git a/modules/base/rendering/renderablesphere.cpp b/modules/base/rendering/renderablesphere.cpp index 18ee8780e4..cc2804aa0f 100644 --- a/modules/base/rendering/renderablesphere.cpp +++ b/modules/base/rendering/renderablesphere.cpp @@ -131,7 +131,6 @@ bool RenderableSphere::deinitialize() { delete _sphere; _sphere = nullptr; - delete _texture; _texture = nullptr; delete _shader; @@ -182,7 +181,7 @@ void RenderableSphere::update(const UpdateData& data) { void RenderableSphere::loadTexture() { if (_texturePath.value() != "") { - ghoul::opengl::Texture* texture = ghoul::io::TextureReader::ref().loadTexture(_texturePath); + std::unique_ptr texture = ghoul::io::TextureReader::ref().loadTexture(_texturePath); if (texture) { LDEBUG("Loaded texture from '" << absPath(_texturePath) << "'"); texture->uploadTexture(); @@ -192,9 +191,7 @@ void RenderableSphere::loadTexture() { //texture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear); - if (_texture) - delete _texture; - _texture = texture; + _texture = std::move(texture); } } } diff --git a/modules/base/rendering/renderablesphere.h b/modules/base/rendering/renderablesphere.h index 06f15ae1ab..1cc484d090 100644 --- a/modules/base/rendering/renderablesphere.h +++ b/modules/base/rendering/renderablesphere.h @@ -62,7 +62,7 @@ private: properties::FloatProperty _transparency; ghoul::opengl::ProgramObject* _shader; - ghoul::opengl::Texture* _texture; + std::unique_ptr _texture; PowerScaledSphere* _sphere; diff --git a/modules/base/rendering/renderablestars.cpp b/modules/base/rendering/renderablestars.cpp index d3da22ce01..b4ba656c74 100644 --- a/modules/base/rendering/renderablestars.cpp +++ b/modules/base/rendering/renderablestars.cpp @@ -137,7 +137,6 @@ RenderableStars::RenderableStars(const ghoul::Dictionary& dictionary) RenderableStars::~RenderableStars() { delete _psfTextureFile; delete _colorTextureFile; - delete _colorTexture; } bool RenderableStars::isReady() const { @@ -165,11 +164,10 @@ bool RenderableStars::deinitialize() { glDeleteVertexArrays(1, &_vao); _vao = 0; - delete _pointSpreadFunctionTexture; _pointSpreadFunctionTexture = nullptr; + _colorTexture = nullptr; - if(_program) - delete _program; + delete _program; _program = nullptr; return true; } @@ -312,10 +310,9 @@ void RenderableStars::update(const UpdateData& data) { if (_pointSpreadFunctionTextureIsDirty) { LDEBUG("Reloading Point Spread Function texture"); - delete _pointSpreadFunctionTexture; _pointSpreadFunctionTexture = nullptr; if (_pointSpreadFunctionTexturePath.value() != "") { - _pointSpreadFunctionTexture = ghoul::io::TextureReader::ref().loadTexture(absPath(_pointSpreadFunctionTexturePath)); + _pointSpreadFunctionTexture = std::move(ghoul::io::TextureReader::ref().loadTexture(absPath(_pointSpreadFunctionTexturePath))); if (_pointSpreadFunctionTexture) { LDEBUG("Loaded texture from '" << absPath(_pointSpreadFunctionTexturePath) << "'"); _pointSpreadFunctionTexture->uploadTexture(); @@ -330,10 +327,9 @@ void RenderableStars::update(const UpdateData& data) { if (_colorTextureIsDirty) { LDEBUG("Reloading Color Texture"); - delete _colorTexture; _colorTexture = nullptr; if (_colorTexturePath.value() != "") { - _colorTexture = ghoul::io::TextureReader::ref().loadTexture(absPath(_colorTexturePath)); + _colorTexture = std::move(ghoul::io::TextureReader::ref().loadTexture(absPath(_colorTexturePath))); if (_colorTexture) { LDEBUG("Loaded texture from '" << absPath(_colorTexturePath) << "'"); _colorTexture->uploadTexture(); diff --git a/modules/base/rendering/renderablestars.h b/modules/base/rendering/renderablestars.h index 542a604850..f69ddab5b3 100644 --- a/modules/base/rendering/renderablestars.h +++ b/modules/base/rendering/renderablestars.h @@ -63,11 +63,11 @@ private: bool saveCachedFile(const std::string& file) const; properties::StringProperty _pointSpreadFunctionTexturePath; - ghoul::opengl::Texture* _pointSpreadFunctionTexture; + std::unique_ptr _pointSpreadFunctionTexture; bool _pointSpreadFunctionTextureIsDirty; properties::StringProperty _colorTexturePath; - ghoul::opengl::Texture* _colorTexture; + std::unique_ptr _colorTexture; bool _colorTextureIsDirty; properties::OptionProperty _colorOption; diff --git a/modules/newhorizons/newhorizonsmodule.cpp b/modules/newhorizons/newhorizonsmodule.cpp index caf960247f..9d5b3967a4 100644 --- a/modules/newhorizons/newhorizonsmodule.cpp +++ b/modules/newhorizons/newhorizonsmodule.cpp @@ -44,7 +44,6 @@ #include - namespace openspace { NewHorizonsModule::NewHorizonsModule() @@ -58,7 +57,6 @@ bool NewHorizonsModule::create() { ImageSequencer2::initialize(); - FactoryManager::ref().addFactory(new ghoul::TemplateFactory); FactoryManager::ref().addFactory(new ghoul::TemplateFactory); diff --git a/modules/newhorizons/rendering/renderablemodelprojection.cpp b/modules/newhorizons/rendering/renderablemodelprojection.cpp index 04d16386d8..3e9dcccee0 100644 --- a/modules/newhorizons/rendering/renderablemodelprojection.cpp +++ b/modules/newhorizons/rendering/renderablemodelprojection.cpp @@ -274,15 +274,6 @@ bool RenderableModelProjection::deinitialize() { delete _geometry; } - if (_texture) - delete _texture; - if (_textureProj) - delete _textureProj; - if (_textureOriginal) - delete _textureOriginal; - if (_textureWhiteSquare) - delete _textureWhiteSquare; - _geometry = nullptr; _texture = nullptr; _textureProj = nullptr; @@ -488,30 +479,27 @@ void RenderableModelProjection::project() { } void RenderableModelProjection::loadTexture() { - delete _texture; _texture = nullptr; if (_colorTexturePath.value() != "") { - _texture = ghoul::io::TextureReader::ref().loadTexture(absPath(_colorTexturePath)); + _texture = std::move(ghoul::io::TextureReader::ref().loadTexture(absPath(_colorTexturePath))); if (_texture) { LDEBUG("Loaded texture from '" << absPath(_colorTexturePath) << "'"); _texture->uploadTexture(); _texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear); } } - delete _textureOriginal; _textureOriginal = nullptr; if (_colorTexturePath.value() != "") { - _textureOriginal = ghoul::io::TextureReader::ref().loadTexture(absPath(_colorTexturePath)); + _textureOriginal = std::move(ghoul::io::TextureReader::ref().loadTexture(absPath(_colorTexturePath))); if (_textureOriginal) { LDEBUG("Loaded texture from '" << absPath(_colorTexturePath) << "'"); _textureOriginal->uploadTexture(); _textureOriginal->setFilter(ghoul::opengl::Texture::FilterMode::Linear); } } - delete _textureWhiteSquare; _textureWhiteSquare = nullptr; if (_defaultProjImage != "") { - _textureWhiteSquare = ghoul::io::TextureReader::ref().loadTexture(absPath(_defaultProjImage)); + _textureWhiteSquare = std::move(ghoul::io::TextureReader::ref().loadTexture(absPath(_defaultProjImage))); if (_textureWhiteSquare) { _textureWhiteSquare->uploadTexture(); _textureWhiteSquare->setFilter(ghoul::opengl::Texture::FilterMode::Linear); @@ -520,10 +508,9 @@ void RenderableModelProjection::loadTexture() { } void RenderableModelProjection::loadProjectionTexture() { - delete _textureProj; _textureProj = nullptr; if (_projectionTexturePath.value() != "") { - _textureProj = ghoul::io::TextureReader::ref().loadTexture(absPath(_projectionTexturePath)); + _textureProj = std::move(ghoul::io::TextureReader::ref().loadTexture(absPath(_projectionTexturePath))); if (_textureProj) { _textureProj->uploadTexture(); _textureProj->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); diff --git a/modules/newhorizons/rendering/renderablemodelprojection.h b/modules/newhorizons/rendering/renderablemodelprojection.h index 9f24290222..eefe191cd5 100644 --- a/modules/newhorizons/rendering/renderablemodelprojection.h +++ b/modules/newhorizons/rendering/renderablemodelprojection.h @@ -80,10 +80,10 @@ namespace openspace { ghoul::opengl::ProgramObject* _programObject; ghoul::opengl::ProgramObject* _fboProgramObject; - ghoul::opengl::Texture* _texture; - ghoul::opengl::Texture* _textureOriginal; - ghoul::opengl::Texture* _textureProj; - ghoul::opengl::Texture* _textureWhiteSquare; + std::unique_ptr _texture; + std::unique_ptr _textureOriginal; + std::unique_ptr _textureProj; + std::unique_ptr _textureWhiteSquare; modelgeometry::ModelGeometry* _geometry; diff --git a/modules/newhorizons/rendering/renderableplaneprojection.cpp b/modules/newhorizons/rendering/renderableplaneprojection.cpp index c5cbd1f66f..5be5dbf4f4 100644 --- a/modules/newhorizons/rendering/renderableplaneprojection.cpp +++ b/modules/newhorizons/rendering/renderableplaneprojection.cpp @@ -119,7 +119,7 @@ bool RenderablePlaneProjection::deinitialize() { _quad = 0; glDeleteBuffers(1, &_vertexPositionBuffer); _vertexPositionBuffer = 0; - delete _texture; + _texture = nullptr; return true; } @@ -190,15 +190,13 @@ void RenderablePlaneProjection::update(const UpdateData& data) { void RenderablePlaneProjection::loadTexture() { if (_texturePath != "") { - ghoul::opengl::Texture* texture = ghoul::io::TextureReader::ref().loadTexture(absPath(_texturePath)); + std::unique_ptr texture = ghoul::io::TextureReader::ref().loadTexture(absPath(_texturePath)); if (texture) { texture->uploadTexture(); // TODO: AnisotropicMipMap crashes on ATI cards ---abock //texture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear); - if (_texture) - delete _texture; - _texture = texture; + _texture = std::move(texture); delete _textureFile; _textureFile = new ghoul::filesystem::File(_texturePath); diff --git a/modules/newhorizons/rendering/renderableplaneprojection.h b/modules/newhorizons/rendering/renderableplaneprojection.h index 5fc819ea1b..3373aae724 100644 --- a/modules/newhorizons/rendering/renderableplaneprojection.h +++ b/modules/newhorizons/rendering/renderableplaneprojection.h @@ -32,6 +32,8 @@ #include #include +#include + namespace ghoul { namespace filesystem { class File; @@ -52,12 +54,10 @@ struct target { }; class RenderablePlaneProjection : public Renderable { - - public: RenderablePlaneProjection(const ghoul::Dictionary& dictionary); ~RenderablePlaneProjection(); - + bool initialize() override; bool deinitialize() override; @@ -81,7 +81,8 @@ private: ghoul::opengl::ProgramObject* _shader; bool _textureIsDirty; - ghoul::opengl::Texture* _texture; + std::unique_ptr _texture = nullptr; +// ghoul::opengl::Texture* _texture; ghoul::filesystem::File* _textureFile; GLuint _quad; GLuint _vertexPositionBuffer; diff --git a/modules/newhorizons/rendering/renderableplanetprojection.cpp b/modules/newhorizons/rendering/renderableplanetprojection.cpp index c3d8a5a24c..87fcb36f07 100644 --- a/modules/newhorizons/rendering/renderableplanetprojection.cpp +++ b/modules/newhorizons/rendering/renderableplanetprojection.cpp @@ -305,13 +305,9 @@ bool RenderablePlanetProjection::auxiliaryRendertarget(){ } bool RenderablePlanetProjection::deinitialize(){ - delete _texture; _texture = nullptr; - delete _textureProj; _textureProj = nullptr; - delete _textureOriginal; _textureOriginal = nullptr; - delete _textureWhiteSquare; _textureWhiteSquare = nullptr; delete _geometry; _geometry = nullptr; @@ -561,10 +557,9 @@ void RenderablePlanetProjection::update(const UpdateData& data){ } void RenderablePlanetProjection::loadProjectionTexture() { - delete _textureProj; _textureProj = nullptr; if (_colorTexturePath.value() != "") { - _textureProj = ghoul::io::TextureReader::ref().loadTexture(absPath(_projectionTexturePath)); + _textureProj = std::move(ghoul::io::TextureReader::ref().loadTexture(absPath(_projectionTexturePath))); if (_textureProj) { _textureProj->uploadTexture(); // TODO: AnisotropicMipMap crashes on ATI cards ---abock @@ -576,28 +571,25 @@ void RenderablePlanetProjection::loadProjectionTexture() { } void RenderablePlanetProjection::loadTexture() { - delete _texture; _texture = nullptr; if (_colorTexturePath.value() != "") { - _texture = ghoul::io::TextureReader::ref().loadTexture(_colorTexturePath); + _texture = std::move(ghoul::io::TextureReader::ref().loadTexture(_colorTexturePath)); if (_texture) { _texture->uploadTexture(); _texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear); } } - delete _textureOriginal; _textureOriginal = nullptr; if (_colorTexturePath.value() != "") { - _textureOriginal = ghoul::io::TextureReader::ref().loadTexture(_colorTexturePath); + _textureOriginal = std::move(ghoul::io::TextureReader::ref().loadTexture(_colorTexturePath)); if (_textureOriginal) { _textureOriginal->uploadTexture(); _textureOriginal->setFilter(ghoul::opengl::Texture::FilterMode::Linear); } } - delete _textureWhiteSquare; _textureWhiteSquare = nullptr; if (_colorTexturePath.value() != "") { - _textureWhiteSquare = ghoul::io::TextureReader::ref().loadTexture(_defaultProjImage); + _textureWhiteSquare = std::move(ghoul::io::TextureReader::ref().loadTexture(_defaultProjImage)); if (_textureWhiteSquare) { _textureWhiteSquare->uploadTexture(); _textureWhiteSquare->setFilter(ghoul::opengl::Texture::FilterMode::Linear); diff --git a/modules/newhorizons/rendering/renderableplanetprojection.h b/modules/newhorizons/rendering/renderableplanetprojection.h index be5d2d0523..b2230845c7 100644 --- a/modules/newhorizons/rendering/renderableplanetprojection.h +++ b/modules/newhorizons/rendering/renderableplanetprojection.h @@ -70,7 +70,7 @@ public: void render(const RenderData& data) override; void update(const UpdateData& data) override; - ghoul::opengl::Texture* baseTexture() { return _texture; }; + ghoul::opengl::Texture* baseTexture() { return _texture.get(); }; protected: @@ -98,10 +98,10 @@ private: ghoul::opengl::ProgramObject* _programObject; ghoul::opengl::ProgramObject* _fboProgramObject; - ghoul::opengl::Texture* _texture; - ghoul::opengl::Texture* _textureOriginal; - ghoul::opengl::Texture* _textureProj; - ghoul::opengl::Texture* _textureWhiteSquare; + std::unique_ptr _texture; + std::unique_ptr _textureOriginal; + std::unique_ptr _textureProj; + std::unique_ptr _textureWhiteSquare; planetgeometryprojection::PlanetGeometryProjection* _geometry; glm::vec2 _camScaling; diff --git a/modules/volume/rendering/renderablevolume.cpp b/modules/volume/rendering/renderablevolume.cpp index 3794ed0e5c..a042df4a26 100644 --- a/modules/volume/rendering/renderablevolume.cpp +++ b/modules/volume/rendering/renderablevolume.cpp @@ -296,7 +296,7 @@ ghoul::opengl::Texture* RenderableVolume::loadTransferFunction(const std::string // check if not a txt based texture if ( ! hasExtension(filepath, "txt")) { - ghoul::opengl::Texture* t = ghoul::io::TextureReader::ref().loadTexture(f); + ghoul::opengl::Texture* t = ghoul::io::TextureReader::ref().loadTexture(f).get(); t->setWrapping(wrappingmode); return t; } diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 06ca518def..7e8cc38ec2 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -182,13 +182,13 @@ bool RenderEngine::initialize() { OsEng.interactionHandler()->setCamera(_mainCamera); #ifdef GHOUL_USE_DEVIL - ghoul::io::TextureReader::ref().addReader(new ghoul::io::impl::TextureReaderDevIL); + ghoul::io::TextureReader::ref().addReader(std::make_shared()); #endif // GHOUL_USE_DEVIL #ifdef GHOUL_USE_FREEIMAGE - ghoul::io::TextureReader::ref().addReader(new ghoul::io::impl::TextureReaderFreeImage); + ghoul::io::TextureReader::ref().addReader(std::make_shared()); #endif // GHOUL_USE_FREEIMAGE - ghoul::io::TextureReader::ref().addReader(new ghoul::io::impl::TextureReaderCMAP); + ghoul::io::TextureReader::ref().addReader(std::make_shared()); return true; From 0fceda663a152167aae5362904394ae81e26e9d4 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 24 Nov 2015 21:48:26 -0500 Subject: [PATCH 053/122] Updated Ghoul version --- ext/ghoul | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/ghoul b/ext/ghoul index ca2362fb5a..cc62884f16 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit ca2362fb5a8b7a4a2543c3c1c8ca1ed51a10f19c +Subproject commit cc62884f167498da1674c56f787dde08faec7ea0 From 5c6943477ac80ae7ec2ff480c75f628860409609 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 30 Nov 2015 14:32:06 -0500 Subject: [PATCH 054/122] Updated Ghoul Applied new Ghoul changes --- ext/ghoul | 2 +- modules/volume/rendering/renderablevolume.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index cc62884f16..6567991e2d 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit cc62884f167498da1674c56f787dde08faec7ea0 +Subproject commit 6567991e2d2f12929c6fec4e10cff28e21595af6 diff --git a/modules/volume/rendering/renderablevolume.h b/modules/volume/rendering/renderablevolume.h index 9bf86468fb..bab2ad8de2 100644 --- a/modules/volume/rendering/renderablevolume.h +++ b/modules/volume/rendering/renderablevolume.h @@ -29,7 +29,7 @@ #include // ghoul includes -#include +#include // Forward declare to minimize dependencies namespace ghoul { From 999f198aa33d791d0cb6d8e47a7d64c3ab6ff899 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 30 Nov 2015 15:01:02 -0500 Subject: [PATCH 055/122] Updated tinyobjloader and applied the changes --- ext/ghoul | 2 +- modules/base/rendering/wavefrontgeometry.cpp | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index 6567991e2d..68ec5fef09 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 6567991e2d2f12929c6fec4e10cff28e21595af6 +Subproject commit 68ec5fef095ddc79f1d75057ea3a917816352556 diff --git a/modules/base/rendering/wavefrontgeometry.cpp b/modules/base/rendering/wavefrontgeometry.cpp index 092a1bae10..39041eda42 100644 --- a/modules/base/rendering/wavefrontgeometry.cpp +++ b/modules/base/rendering/wavefrontgeometry.cpp @@ -53,9 +53,10 @@ void WavefrontGeometry::deinitialize() { bool WavefrontGeometry::loadModel(const std::string& filename) { std::vector shapes; std::vector materials; - std::string err = tinyobj::LoadObj(shapes, materials, filename.c_str(), filename.c_str()); + std::string err; + bool success = tinyobj::LoadObj(shapes, materials, err, filename.c_str(), filename.c_str()); - if (!err.empty()) { + if (!success) { LERROR(err); return false; } From 0006e83f4bbb91eac2060cd25deb1874dac472dd Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 30 Nov 2015 17:50:26 -0500 Subject: [PATCH 056/122] Updated Ghoul Adapted to cleanup in Ghoul --- ext/ghoul | 2 +- include/openspace/engine/logfactory.h | 3 ++- src/engine/logfactory.cpp | 12 +++++++----- src/engine/openspaceengine.cpp | 8 ++++---- src/rendering/renderengine.cpp | 5 +++-- 5 files changed, 17 insertions(+), 13 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index 68ec5fef09..62d6b98d7d 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 68ec5fef095ddc79f1d75057ea3a917816352556 +Subproject commit 62d6b98d7d33535d31f7029f0118c074ada5810d diff --git a/include/openspace/engine/logfactory.h b/include/openspace/engine/logfactory.h index 8b67a2f1dd..ab615b4236 100644 --- a/include/openspace/engine/logfactory.h +++ b/include/openspace/engine/logfactory.h @@ -26,6 +26,7 @@ #define __LOGFACTORY_H__ #include +#include namespace ghoul { namespace logging { @@ -37,7 +38,7 @@ namespace openspace { class LogFactory { public: - static ghoul::logging::Log* createLog(const ghoul::Dictionary& dictionary); + static std::unique_ptr createLog(const ghoul::Dictionary& dictionary); }; } // namespace openspace diff --git a/src/engine/logfactory.cpp b/src/engine/logfactory.cpp index 4f493a3363..6e668993de 100644 --- a/src/engine/logfactory.cpp +++ b/src/engine/logfactory.cpp @@ -45,7 +45,7 @@ namespace { namespace openspace { -ghoul::logging::Log* LogFactory::createLog(const ghoul::Dictionary& dictionary) { +std::unique_ptr LogFactory::createLog(const ghoul::Dictionary& dictionary) { std::string type; bool typeSuccess = dictionary.getValue(keyType, type); if (!typeSuccess) { @@ -74,12 +74,14 @@ ghoul::logging::Log* LogFactory::createLog(const ghoul::Dictionary& dictionary) dictionary.getValue(keyLogLevelStamping, logLevelStamp); if (type == valueHtmlLog) { - return new ghoul::logging::HTMLLog( - filename, append, timeStamp, dateStamp, categoryStamp, logLevelStamp); + return std::make_unique( + filename, append, timeStamp, dateStamp, categoryStamp, logLevelStamp + ); } else if (type == valueTextLog) { - return new ghoul::logging::TextLog( - filename, append, timeStamp, dateStamp, categoryStamp, logLevelStamp); + return std::make_unique( + filename, append, timeStamp, dateStamp, categoryStamp, logLevelStamp + ); } else { LERROR("Log with type '" << type << "' did not name a valid log"); diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 68b3fd3081..890257e21f 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -189,7 +189,7 @@ bool OpenSpaceEngine::create( // configuration file, we will deinitialize this LogManager and reinitialize it later // with the correct LogLevel LogManager::initialize(LogManager::LogLevel::Debug, true); - LogMgr.addLog(new ConsoleLog); + LogMgr.addLog(std::make_unique()); LDEBUG("Initialize FileSystem"); @@ -614,7 +614,7 @@ void OpenSpaceEngine::configureLogging() { LogManager::LogLevel level = LogManager::levelFromString(logLevel); LogManager::deinitialize(); LogManager::initialize(level, immediateFlush); - LogMgr.addLog(new ConsoleLog); + LogMgr.addLog(std::make_unique()); } if (configurationManager()->hasKeyAndValue(ConfigurationManager::KeyLogs)) { @@ -625,10 +625,10 @@ void OpenSpaceEngine::configureLogging() { ghoul::Dictionary logInfo; logs.getValue(std::to_string(i), logInfo); - Log* log = LogFactory::createLog(logInfo); + std::unique_ptr log = LogFactory::createLog(logInfo); if (log) - LogMgr.addLog(log); + LogMgr.addLog(std::move(log)); } } } diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 7e8cc38ec2..bb27f80ec1 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -290,8 +290,9 @@ bool RenderEngine::initializeGL() { _abuffer->initialize(); LINFO("Initializing Log"); - _log = new ScreenLog(); - ghoul::logging::LogManager::ref().addLog(_log); + std::unique_ptr log = std::make_unique(); + _log = log.get(); + ghoul::logging::LogManager::ref().addLog(std::move(log)); LINFO("Initializing Visualizer"); _visualizer = new ABufferVisualizer(); From ba35b834f7e14415ecf0c70df04dd16aecfc768a Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Wed, 2 Dec 2015 22:47:15 -0500 Subject: [PATCH 057/122] Update Ghoul Adapted to new ghoul version --- ext/ghoul | 2 +- src/engine/configurationmanager.cpp | 6 ++++-- src/scene/scenegraph.cpp | 16 +++++++++++----- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index 62d6b98d7d..fed2001d06 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 62d6b98d7d33535d31f7029f0118c074ada5810d +Subproject commit fed2001d06211d5636452500870f83d1adb10ba2 diff --git a/src/engine/configurationmanager.cpp b/src/engine/configurationmanager.cpp index e8a423df53..b6fb131298 100644 --- a/src/engine/configurationmanager.cpp +++ b/src/engine/configurationmanager.cpp @@ -78,8 +78,10 @@ bool ConfigurationManager::loadFromFile(const std::string& filename) { FileSys.registerPathToken(basePathToken, basePath); // Loading the configuration file into ourselves - const bool loadingSuccess = ghoul::lua::loadDictionaryFromFile(filename, *this); - if (!loadingSuccess) { + try { + ghoul::lua::loadDictionaryFromFile(filename, *this); + } + catch (...) { LERROR("Loading dictionary from file failed"); return false; } diff --git a/src/scene/scenegraph.cpp b/src/scene/scenegraph.cpp index 33a9bf607d..6f00479de4 100644 --- a/src/scene/scenegraph.cpp +++ b/src/scene/scenegraph.cpp @@ -90,9 +90,12 @@ bool SceneGraph::loadFromFile(const std::string& sceneDescription) { // Load dictionary ghoul::Dictionary sceneDictionary; - bool success = ghoul::lua::loadDictionaryFromFile(absSceneFile, sceneDictionary); - if (!success) + try { + ghoul::lua::loadDictionaryFromFile(absSceneFile, sceneDictionary); + } + catch (...) { return false; + } std::string sceneDescriptionDirectory = ghoul::filesystem::File(absSceneFile, true).directoryName(); @@ -116,7 +119,7 @@ bool SceneGraph::loadFromFile(const std::string& sceneDescription) { } ghoul::Dictionary moduleDictionary; - success = sceneDictionary.getValue(KeyModules, moduleDictionary); + bool success = sceneDictionary.getValue(KeyModules, moduleDictionary); if (!success) // There are no modules that are loaded return true; @@ -182,9 +185,12 @@ bool SceneGraph::loadFromFile(const std::string& sceneDescription) { } ghoul::Dictionary moduleDictionary; - bool s = ghoul::lua::loadDictionaryFromFile(moduleFile, moduleDictionary, state); - if (!s) + try { + ghoul::lua::loadDictionaryFromFile(moduleFile, moduleDictionary, state); + } + catch (...) { continue; + } std::vector keys = moduleDictionary.keys(); for (const std::string& key : keys) { From 875de328aaa4387bbfcde657884a55a5626cf886 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 7 Dec 2015 18:54:17 -0500 Subject: [PATCH 058/122] Update Ghoul version Make the modules depend on C++14 Change the OpenSpace code to the new Ghoul version --- ext/ghoul | 2 +- include/openspace/properties/templateproperty.inl | 2 ++ modules/newhorizons/util/instrumentdecoder.cpp | 3 +++ modules/newhorizons/util/sequenceparser.cpp | 2 ++ src/properties/propertyowner.cpp | 2 ++ support/cmake/module_definition.cmake | 2 +- 6 files changed, 11 insertions(+), 2 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index fed2001d06..b1178c91df 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit fed2001d06211d5636452500870f83d1adb10ba2 +Subproject commit b1178c91df24be443b4028a06c55741a91952038 diff --git a/include/openspace/properties/templateproperty.inl b/include/openspace/properties/templateproperty.inl index 396c05613f..91bf536d7a 100644 --- a/include/openspace/properties/templateproperty.inl +++ b/include/openspace/properties/templateproperty.inl @@ -22,6 +22,8 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ +#include + namespace openspace { namespace properties { diff --git a/modules/newhorizons/util/instrumentdecoder.cpp b/modules/newhorizons/util/instrumentdecoder.cpp index 9ad3a20022..f290631215 100644 --- a/modules/newhorizons/util/instrumentdecoder.cpp +++ b/modules/newhorizons/util/instrumentdecoder.cpp @@ -24,6 +24,9 @@ #include +#include +#include + namespace { const std::string _loggerCat = "InstrumentDecoder"; const std::string keyDetector = "DetectorType"; diff --git a/modules/newhorizons/util/sequenceparser.cpp b/modules/newhorizons/util/sequenceparser.cpp index 114befdb4c..1a8d2d8554 100644 --- a/modules/newhorizons/util/sequenceparser.cpp +++ b/modules/newhorizons/util/sequenceparser.cpp @@ -28,6 +28,8 @@ #include #include +#include + namespace { const std::string _loggerCat = "SequenceParser"; const std::string keyTranslation = "DataInputTranslation"; diff --git a/src/properties/propertyowner.cpp b/src/properties/propertyowner.cpp index ae753170cc..b3492c7bd6 100644 --- a/src/properties/propertyowner.cpp +++ b/src/properties/propertyowner.cpp @@ -24,6 +24,8 @@ #include +#include + #include #include diff --git a/support/cmake/module_definition.cmake b/support/cmake/module_definition.cmake index 6b3ae6281a..fc8555475c 100644 --- a/support/cmake/module_definition.cmake +++ b/support/cmake/module_definition.cmake @@ -76,7 +76,7 @@ endmacro () # Set the compiler settings that are common to all modules function (set_common_compile_settings target_name) - set_property(TARGET ${library_name} PROPERTY CXX_STANDARD 11) + set_property(TARGET ${library_name} PROPERTY CXX_STANDARD 14) set_property(TARGET ${library_name} PROPERTY CXX_STANDARD_REQUIRED On) if (MSVC) From cd3a819541be651c08f589dfff87b93d66e002e3 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Wed, 9 Dec 2015 14:41:50 -0500 Subject: [PATCH 059/122] Updating Ghoul version Applying new Ghoul changes --- ext/ghoul | 2 +- include/openspace/abuffer/abuffer.h | 2 +- include/openspace/abuffer/abuffervisualizer.h | 2 +- include/openspace/scene/scene.h | 2 +- include/openspace/util/factorymanager.inl | 2 + .../renderableconstellationbounds.cpp | 3 +- .../rendering/renderableconstellationbounds.h | 2 +- modules/base/rendering/renderablemodel.cpp | 3 +- modules/base/rendering/renderablemodel.h | 2 +- modules/base/rendering/renderablepath.cpp | 4 +- modules/base/rendering/renderablepath.h | 2 +- modules/base/rendering/renderableplane.cpp | 3 +- modules/base/rendering/renderableplane.h | 2 +- modules/base/rendering/renderablesphere.cpp | 3 +- modules/base/rendering/renderablesphere.h | 2 +- modules/base/rendering/renderablestars.cpp | 3 +- modules/base/rendering/renderablestars.h | 2 +- modules/base/rendering/renderabletrail.cpp | 7 +-- modules/base/rendering/renderabletrail.h | 3 +- .../rendering/renderablefieldlines.cpp | 2 +- .../rendering/renderablefieldlines.h | 2 +- .../rendering/renderablecrawlingline.cpp | 2 +- .../rendering/renderablecrawlingline.h | 2 +- .../newhorizons/rendering/renderablefov.cpp | 2 +- modules/newhorizons/rendering/renderablefov.h | 2 +- .../rendering/renderablemodelprojection.cpp | 2 +- .../rendering/renderablemodelprojection.h | 4 +- .../rendering/renderableplaneprojection.cpp | 2 +- .../rendering/renderableplaneprojection.h | 2 +- .../rendering/renderableplanetprojection.cpp | 10 ++-- .../rendering/renderableplanetprojection.h | 4 +- .../rendering/renderableshadowcylinder.cpp | 3 +- .../rendering/renderableshadowcylinder.h | 2 +- modules/onscreengui/src/gui.cpp | 4 +- .../src/guiperformancecomponent.cpp | 3 +- src/abuffer/abuffer.cpp | 31 +++++-------- src/abuffer/abuffervisualizer.cpp | 2 - src/interaction/interactionhandler.cpp | 8 +--- src/interaction/keyboardcontroller.cpp | 7 +-- src/rendering/renderengine.cpp | 6 ++- src/scene/scene.cpp | 46 +++++++++---------- src/scene/scenegraphnode.cpp | 14 +++--- 42 files changed, 93 insertions(+), 120 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index b1178c91df..b5976438ea 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit b1178c91df24be443b4028a06c55741a91952038 +Subproject commit b5976438ea22ab0e9cf46a2e77ea6a7d6233eeca diff --git a/include/openspace/abuffer/abuffer.h b/include/openspace/abuffer/abuffer.h index 03ff58e0c9..0baef3ab5e 100644 --- a/include/openspace/abuffer/abuffer.h +++ b/include/openspace/abuffer/abuffer.h @@ -93,7 +93,7 @@ protected: GLuint _screenQuad; bool _validShader; - ghoul::opengl::ProgramObject* _resolveShader; + std::unique_ptr _resolveShader; std::vector > _volumes; std::vector > _transferFunctions; diff --git a/include/openspace/abuffer/abuffervisualizer.h b/include/openspace/abuffer/abuffervisualizer.h index 7b776184d4..a75b93fc1c 100644 --- a/include/openspace/abuffer/abuffervisualizer.h +++ b/include/openspace/abuffer/abuffervisualizer.h @@ -60,7 +60,7 @@ private: GLsizei _markersSize; GLuint _imarkers; GLsizei _imarkersSize; - ghoul::opengl::ProgramObject* _pointcloudProgram; + std::unique_ptr _pointcloudProgram; }; // ABufferVisualizer } // namespace openspace diff --git a/include/openspace/scene/scene.h b/include/openspace/scene/scene.h index 8c1fa224d0..93963268c6 100644 --- a/include/openspace/scene/scene.h +++ b/include/openspace/scene/scene.h @@ -125,7 +125,7 @@ private: std::mutex _programUpdateLock; std::set _programsToUpdate; - std::vector _programs; + std::vector> _programs; typedef std::map NodeMap; typedef std::multimap DependencyMap; diff --git a/include/openspace/util/factorymanager.inl b/include/openspace/util/factorymanager.inl index 6d25abd9f7..f46eb55df7 100644 --- a/include/openspace/util/factorymanager.inl +++ b/include/openspace/util/factorymanager.inl @@ -22,6 +22,8 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ +#include + namespace openspace { template diff --git a/modules/base/rendering/renderableconstellationbounds.cpp b/modules/base/rendering/renderableconstellationbounds.cpp index 0a8cd007a9..e3d29c8a92 100644 --- a/modules/base/rendering/renderableconstellationbounds.cpp +++ b/modules/base/rendering/renderableconstellationbounds.cpp @@ -138,7 +138,6 @@ bool RenderableConstellationBounds::deinitialize() { glDeleteVertexArrays(1, &_vao); _vao = 0; - delete _program; _program = nullptr; return true; } @@ -154,7 +153,7 @@ void RenderableConstellationBounds::render(const RenderData& data) { glm::mat4 viewMatrix = data.camera.viewMatrix(); glm::mat4 projectionMatrix = data.camera.projectionMatrix(); - setPscUniforms(_program, &data.camera, data.position); + setPscUniforms(_program.get(), &data.camera, data.position); _program->setUniform("exponent", _distance); _program->setUniform("ViewProjection", data.camera.viewProjectionMatrix()); diff --git a/modules/base/rendering/renderableconstellationbounds.h b/modules/base/rendering/renderableconstellationbounds.h index 08299054f8..9b86d88634 100644 --- a/modules/base/rendering/renderableconstellationbounds.h +++ b/modules/base/rendering/renderableconstellationbounds.h @@ -101,7 +101,7 @@ private: std::string _vertexFilename; ///< The filename containing the constellation bounds std::string _constellationFilename; ///< The file containing constellation names - ghoul::opengl::ProgramObject* _program; + std::unique_ptr _program; /// The list of all loaded constellation bounds std::vector _constellationBounds; diff --git a/modules/base/rendering/renderablemodel.cpp b/modules/base/rendering/renderablemodel.cpp index 34d588437d..f13f9953bb 100644 --- a/modules/base/rendering/renderablemodel.cpp +++ b/modules/base/rendering/renderablemodel.cpp @@ -151,7 +151,6 @@ bool RenderableModel::deinitialize() { } _texture = nullptr; - delete _programObject; _programObject = nullptr; return true; } @@ -191,7 +190,7 @@ void RenderableModel::render(const RenderData& data) { _programObject->setUniform("sun_pos", _sunPosition.vec3()); _programObject->setUniform("ViewProjection", data.camera.viewProjectionMatrix()); _programObject->setUniform("ModelTransform", transform); - setPscUniforms(_programObject, &data.camera, data.position); + setPscUniforms(_programObject.get(), &data.camera, data.position); _programObject->setUniform("_performShading", _performShading); diff --git a/modules/base/rendering/renderablemodel.h b/modules/base/rendering/renderablemodel.h index cd1025f958..e32f5de9f0 100644 --- a/modules/base/rendering/renderablemodel.h +++ b/modules/base/rendering/renderablemodel.h @@ -59,7 +59,7 @@ private: properties::StringProperty _colorTexturePath; properties::BoolProperty _performFade; properties::FloatProperty _fading; - ghoul::opengl::ProgramObject* _programObject; + std::unique_ptr _programObject; std::unique_ptr _texture; modelgeometry::ModelGeometry* _geometry; diff --git a/modules/base/rendering/renderablepath.cpp b/modules/base/rendering/renderablepath.cpp index ebefd57a2e..12bd455431 100644 --- a/modules/base/rendering/renderablepath.cpp +++ b/modules/base/rendering/renderablepath.cpp @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -123,7 +122,6 @@ bool RenderablePath::deinitialize() { glDeleteBuffers(1, &_vBufferID); _vBufferID = 0; - delete _programObject; _programObject = nullptr; return true; @@ -158,7 +156,7 @@ void RenderablePath::render(const RenderData& data) { _programObject->setUniform("ModelTransform", transform); _programObject->setUniform("color", _lineColor); _programObject->setUniform("lastPosition", _lastPosition); - setPscUniforms(_programObject, &data.camera, data.position); + setPscUniforms(_programObject.get(), &data.camera, data.position); if (_drawLine) { glLineWidth(_lineWidth); diff --git a/modules/base/rendering/renderablepath.h b/modules/base/rendering/renderablepath.h index 03637503a5..141a91c3b1 100644 --- a/modules/base/rendering/renderablepath.h +++ b/modules/base/rendering/renderablepath.h @@ -68,7 +68,7 @@ private: properties::FloatProperty _lineWidth; properties::BoolProperty _drawLine; - ghoul::opengl::ProgramObject* _programObject; + std::unique_ptr _programObject; bool _successfullDictionaryFetch; diff --git a/modules/base/rendering/renderableplane.cpp b/modules/base/rendering/renderableplane.cpp index ae07fa66f7..a3c27a1e96 100644 --- a/modules/base/rendering/renderableplane.cpp +++ b/modules/base/rendering/renderableplane.cpp @@ -172,7 +172,6 @@ bool RenderablePlane::deinitialize() { delete _textureFile; _textureFile = nullptr; - delete _shader; _shader = nullptr; return true; @@ -200,7 +199,7 @@ void RenderablePlane::render(const RenderData& data) { _shader->setUniform("ViewProjection", data.camera.viewProjectionMatrix()); _shader->setUniform("ModelTransform", transform); - setPscUniforms(_shader, &data.camera, data.position); + setPscUniforms(_shader.get(), &data.camera, data.position); ghoul::opengl::TextureUnit unit; unit.activate(); diff --git a/modules/base/rendering/renderableplane.h b/modules/base/rendering/renderableplane.h index 136b999a2d..8a61cd1c03 100644 --- a/modules/base/rendering/renderableplane.h +++ b/modules/base/rendering/renderableplane.h @@ -76,7 +76,7 @@ private: bool _planeIsDirty; - ghoul::opengl::ProgramObject* _shader; + std::unique_ptr _shader; bool _textureIsDirty; std::unique_ptr _texture; ghoul::filesystem::File* _textureFile; diff --git a/modules/base/rendering/renderablesphere.cpp b/modules/base/rendering/renderablesphere.cpp index cc2804aa0f..e3a20dfabd 100644 --- a/modules/base/rendering/renderablesphere.cpp +++ b/modules/base/rendering/renderablesphere.cpp @@ -133,7 +133,6 @@ bool RenderableSphere::deinitialize() { _texture = nullptr; - delete _shader; _shader = nullptr; return true; @@ -152,7 +151,7 @@ void RenderableSphere::render(const RenderData& data) { _shader->setUniform("ViewProjection", data.camera.viewProjectionMatrix()); _shader->setUniform("ModelTransform", transform); - setPscUniforms(_shader, &data.camera, data.position); + setPscUniforms(_shader.get(), &data.camera, data.position); _shader->setUniform("alpha", _transparency); diff --git a/modules/base/rendering/renderablesphere.h b/modules/base/rendering/renderablesphere.h index 1cc484d090..0eade6acb1 100644 --- a/modules/base/rendering/renderablesphere.h +++ b/modules/base/rendering/renderablesphere.h @@ -61,7 +61,7 @@ private: properties::FloatProperty _transparency; - ghoul::opengl::ProgramObject* _shader; + std::unique_ptr _shader; std::unique_ptr _texture; PowerScaledSphere* _sphere; diff --git a/modules/base/rendering/renderablestars.cpp b/modules/base/rendering/renderablestars.cpp index b4ba656c74..7a676d9b10 100644 --- a/modules/base/rendering/renderablestars.cpp +++ b/modules/base/rendering/renderablestars.cpp @@ -167,7 +167,6 @@ bool RenderableStars::deinitialize() { _pointSpreadFunctionTexture = nullptr; _colorTexture = nullptr; - delete _program; _program = nullptr; return true; } @@ -198,7 +197,7 @@ void RenderableStars::render(const RenderData& data) { _program->setUniform("scaleFactor", _scaleFactor); _program->setUniform("minBillboardSize", _minBillboardSize); - setPscUniforms(_program, &data.camera, data.position); + setPscUniforms(_program.get(), &data.camera, data.position); _program->setUniform("scaling", scaling); ghoul::opengl::TextureUnit psfUnit; diff --git a/modules/base/rendering/renderablestars.h b/modules/base/rendering/renderablestars.h index f69ddab5b3..d3c618af1f 100644 --- a/modules/base/rendering/renderablestars.h +++ b/modules/base/rendering/renderablestars.h @@ -76,7 +76,7 @@ private: properties::FloatProperty _scaleFactor; properties::FloatProperty _minBillboardSize; - ghoul::opengl::ProgramObject* _program; + std::unique_ptr _program; std::string _speckFile; diff --git a/modules/base/rendering/renderabletrail.cpp b/modules/base/rendering/renderabletrail.cpp index 0445483fd1..b158cb3ad7 100644 --- a/modules/base/rendering/renderabletrail.cpp +++ b/modules/base/rendering/renderabletrail.cpp @@ -29,7 +29,6 @@ #include #include #include -#include #include #include @@ -102,10 +101,6 @@ RenderableTrail::RenderableTrail(const ghoul::Dictionary& dictionary) _distanceFade = 1.0; } -RenderableTrail::~RenderableTrail() { - delete _programObject; -} - bool RenderableTrail::initialize() { if (!_successfullDictionaryFetch) { LERROR("The following keys need to be set in the Dictionary. Cannot initialize!"); @@ -149,7 +144,7 @@ void RenderableTrail::render(const RenderData& data) { // setup the data to the shader _programObject->setUniform("ViewProjection", data.camera.viewProjectionMatrix()); _programObject->setUniform("ModelTransform", transform); - setPscUniforms(_programObject, &data.camera, data.position); + setPscUniforms(_programObject.get(), &data.camera, data.position); _programObject->setUniform("color", _lineColor); _programObject->setUniform("nVertices", static_cast(_vertexArray.size())); diff --git a/modules/base/rendering/renderabletrail.h b/modules/base/rendering/renderabletrail.h index c42adf3dc6..147b2097ff 100644 --- a/modules/base/rendering/renderabletrail.h +++ b/modules/base/rendering/renderabletrail.h @@ -43,7 +43,6 @@ namespace openspace { class RenderableTrail : public Renderable { public: RenderableTrail(const ghoul::Dictionary& dictionary); - ~RenderableTrail(); bool initialize() override; bool deinitialize() override; @@ -66,7 +65,7 @@ private: properties::FloatProperty _lineWidth; properties::BoolProperty _showTimestamps; - ghoul::opengl::ProgramObject* _programObject; + std::unique_ptr _programObject; bool _successfullDictionaryFetch; diff --git a/modules/fieldlines/rendering/renderablefieldlines.cpp b/modules/fieldlines/rendering/renderablefieldlines.cpp index 69ca17ca64..3e82ac773b 100644 --- a/modules/fieldlines/rendering/renderablefieldlines.cpp +++ b/modules/fieldlines/rendering/renderablefieldlines.cpp @@ -225,7 +225,7 @@ void RenderableFieldlines::render(const RenderData& data) { _program->setUniform("modelViewProjection", data.camera.viewProjectionMatrix()); _program->setUniform("modelTransform", glm::mat4(1.0)); _program->setUniform("cameraViewDir", data.camera.viewDirection()); - setPscUniforms(_program, &data.camera, data.position); + setPscUniforms(_program.get(), &data.camera, data.position); _program->setUniform("classification", _classification); if (!_classification) diff --git a/modules/fieldlines/rendering/renderablefieldlines.h b/modules/fieldlines/rendering/renderablefieldlines.h index bd37f69b30..f78df3d647 100644 --- a/modules/fieldlines/rendering/renderablefieldlines.h +++ b/modules/fieldlines/rendering/renderablefieldlines.h @@ -75,7 +75,7 @@ private: properties::OptionProperty _seedPointSource; properties::StringProperty _seedPointSourceFile; - ghoul::opengl::ProgramObject* _program; + std::unique_ptr _program; ghoul::Dictionary _vectorFieldInfo; ghoul::Dictionary _fieldlineInfo; diff --git a/modules/newhorizons/rendering/renderablecrawlingline.cpp b/modules/newhorizons/rendering/renderablecrawlingline.cpp index 90bf87bc09..1747bfecef 100644 --- a/modules/newhorizons/rendering/renderablecrawlingline.cpp +++ b/modules/newhorizons/rendering/renderablecrawlingline.cpp @@ -129,7 +129,7 @@ void RenderableCrawlingLine::render(const RenderData& data) { _program->setUniform("_alpha", alpha); _program->setUniform("color", _lineColor); - setPscUniforms(_program, &data.camera, data.position); + setPscUniforms(_program.get(), &data.camera, data.position); glBindVertexArray(_vao); glBindBuffer(GL_ARRAY_BUFFER, _vbo); diff --git a/modules/newhorizons/rendering/renderablecrawlingline.h b/modules/newhorizons/rendering/renderablecrawlingline.h index 57356d9792..61d6b83bbe 100644 --- a/modules/newhorizons/rendering/renderablecrawlingline.h +++ b/modules/newhorizons/rendering/renderablecrawlingline.h @@ -42,7 +42,7 @@ public: void update(const UpdateData& data) override; private: - ghoul::opengl::ProgramObject* _program; + std::unique_ptr _program; std::string _instrumentName; std::string _source; diff --git a/modules/newhorizons/rendering/renderablefov.cpp b/modules/newhorizons/rendering/renderablefov.cpp index f37c9be9c2..0ca3ab8bbc 100644 --- a/modules/newhorizons/rendering/renderablefov.cpp +++ b/modules/newhorizons/rendering/renderablefov.cpp @@ -541,7 +541,7 @@ void RenderableFov::render(const RenderData& data) { // setup the data to the shader _programObject->setUniform("ViewProjection", data.camera.viewProjectionMatrix()); _programObject->setUniform("ModelTransform", glm::mat4(1)); - setPscUniforms(_programObject, &data.camera, data.position); + setPscUniforms(_programObject.get(), &data.camera, data.position); if (openspace::ImageSequencer2::ref().isReady()) _drawFOV = ImageSequencer2::ref().instrumentActive(_instrumentID); diff --git a/modules/newhorizons/rendering/renderablefov.h b/modules/newhorizons/rendering/renderablefov.h index 2327dc6cf6..a2802ab4f2 100644 --- a/modules/newhorizons/rendering/renderablefov.h +++ b/modules/newhorizons/rendering/renderablefov.h @@ -56,7 +56,7 @@ public: // properties properties::FloatProperty _lineWidth; properties::BoolProperty _drawSolid; - ghoul::opengl::ProgramObject* _programObject; + std::unique_ptr _programObject; ghoul::opengl::Texture* _texture; openspace::SceneGraphNode* _targetNode; diff --git a/modules/newhorizons/rendering/renderablemodelprojection.cpp b/modules/newhorizons/rendering/renderablemodelprojection.cpp index 3e9dcccee0..76472ca906 100644 --- a/modules/newhorizons/rendering/renderablemodelprojection.cpp +++ b/modules/newhorizons/rendering/renderablemodelprojection.cpp @@ -318,7 +318,7 @@ void RenderableModelProjection::render(const RenderData& data) { _viewProjection = data.camera.viewProjectionMatrix(); _programObject->setUniform("ViewProjection", _viewProjection); _programObject->setUniform("ModelTransform", _transform); - setPscUniforms(_programObject, &data.camera, data.position); + setPscUniforms(_programObject.get(), &data.camera, data.position); textureBind(); _geometry->render(); diff --git a/modules/newhorizons/rendering/renderablemodelprojection.h b/modules/newhorizons/rendering/renderablemodelprojection.h index eefe191cd5..017bee0e32 100644 --- a/modules/newhorizons/rendering/renderablemodelprojection.h +++ b/modules/newhorizons/rendering/renderablemodelprojection.h @@ -77,8 +77,8 @@ namespace openspace { properties::IntProperty _rotationY; properties::IntProperty _rotationZ; - ghoul::opengl::ProgramObject* _programObject; - ghoul::opengl::ProgramObject* _fboProgramObject; + std::unique_ptr _programObject; + std::unique_ptr _fboProgramObject; std::unique_ptr _texture; std::unique_ptr _textureOriginal; diff --git a/modules/newhorizons/rendering/renderableplaneprojection.cpp b/modules/newhorizons/rendering/renderableplaneprojection.cpp index 5be5dbf4f4..d4cc1ad2c9 100644 --- a/modules/newhorizons/rendering/renderableplaneprojection.cpp +++ b/modules/newhorizons/rendering/renderableplaneprojection.cpp @@ -141,7 +141,7 @@ void RenderablePlaneProjection::render(const RenderData& data) { _shader->setUniform("ViewProjection", data.camera.viewProjectionMatrix()); _shader->setUniform("ModelTransform", transform); - setPscUniforms(_shader, &data.camera, data.position); + setPscUniforms(_shader.get(), &data.camera, data.position); ghoul::opengl::TextureUnit unit; unit.activate(); diff --git a/modules/newhorizons/rendering/renderableplaneprojection.h b/modules/newhorizons/rendering/renderableplaneprojection.h index 3373aae724..c13eda6d8b 100644 --- a/modules/newhorizons/rendering/renderableplaneprojection.h +++ b/modules/newhorizons/rendering/renderableplaneprojection.h @@ -79,7 +79,7 @@ private: glm::dmat3 _stateMatrix; std::string _frame; - ghoul::opengl::ProgramObject* _shader; + std::unique_ptr _shader; bool _textureIsDirty; std::unique_ptr _texture = nullptr; // ghoul::opengl::Texture* _texture; diff --git a/modules/newhorizons/rendering/renderableplanetprojection.cpp b/modules/newhorizons/rendering/renderableplanetprojection.cpp index 87fcb36f07..486e5578cb 100644 --- a/modules/newhorizons/rendering/renderableplanetprojection.cpp +++ b/modules/newhorizons/rendering/renderableplanetprojection.cpp @@ -245,10 +245,10 @@ bool RenderablePlanetProjection::initialize() { return false; } - if (_fboProgramObject == nullptr) - completeSuccess - &= OsEng.ref().configurationManager()->getValue("fboPassProgram", _fboProgramObject); - + _fboProgramObject = ghoul::opengl::ProgramObject::Build("fboPassProgram", + "${SHADERS}/fboPass_vs.glsl", + "${SHADERS}/fboPass_fs.glsl"); + loadTexture(); loadProjectionTexture(); completeSuccess &= (_texture != nullptr); @@ -520,7 +520,7 @@ void RenderablePlanetProjection::render(const RenderData& data){ _programObject->setUniform("ViewProjection" , data.camera.viewProjectionMatrix()); _programObject->setUniform("ModelTransform" , _transform); _programObject->setUniform("boresight" , _boresight); - setPscUniforms(_programObject, &data.camera, data.position); + setPscUniforms(_programObject.get(), &data.camera, data.position); textureBind(); diff --git a/modules/newhorizons/rendering/renderableplanetprojection.h b/modules/newhorizons/rendering/renderableplanetprojection.h index b2230845c7..a66bb12442 100644 --- a/modules/newhorizons/rendering/renderableplanetprojection.h +++ b/modules/newhorizons/rendering/renderableplanetprojection.h @@ -95,8 +95,8 @@ private: properties::BoolProperty _performProjection; properties::BoolProperty _clearAllProjections; - ghoul::opengl::ProgramObject* _programObject; - ghoul::opengl::ProgramObject* _fboProgramObject; + std::unique_ptr _programObject; + std::unique_ptr _fboProgramObject; std::unique_ptr _texture; std::unique_ptr _textureOriginal; diff --git a/modules/newhorizons/rendering/renderableshadowcylinder.cpp b/modules/newhorizons/rendering/renderableshadowcylinder.cpp index 5f1715289b..3a35d48011 100644 --- a/modules/newhorizons/rendering/renderableshadowcylinder.cpp +++ b/modules/newhorizons/rendering/renderableshadowcylinder.cpp @@ -105,7 +105,6 @@ bool RenderableShadowCylinder::deinitialize() { _vao = 0; glDeleteBuffers(1, &_vbo); _vbo = 0; - delete _shader; _shader = nullptr; return true; } @@ -122,7 +121,7 @@ void RenderableShadowCylinder::render(const RenderData& data){ _shader->setUniform("ViewProjection", data.camera.viewProjectionMatrix()); _shader->setUniform("ModelTransform", _transform); - setPscUniforms(_shader, &data.camera, data.position); + setPscUniforms(_shader.get(), &data.camera, data.position); glBindVertexArray(_vao); glDrawArrays(GL_TRIANGLE_STRIP, 0, static_cast(_vertices.size())); diff --git a/modules/newhorizons/rendering/renderableshadowcylinder.h b/modules/newhorizons/rendering/renderableshadowcylinder.h index 1aaa94551d..8993fc9467 100644 --- a/modules/newhorizons/rendering/renderableshadowcylinder.h +++ b/modules/newhorizons/rendering/renderableshadowcylinder.h @@ -73,7 +73,7 @@ namespace openspace { properties::IntProperty _numberOfPoints; properties::FloatProperty _shadowLength; - ghoul::opengl::ProgramObject* _shader; + std::unique_ptr _shader; glm::dmat3 _stateMatrix; diff --git a/modules/onscreengui/src/gui.cpp b/modules/onscreengui/src/gui.cpp index ac26504e73..0caa5a48bc 100644 --- a/modules/onscreengui/src/gui.cpp +++ b/modules/onscreengui/src/gui.cpp @@ -53,7 +53,7 @@ namespace { size_t vboMaxSize = 20000; GLuint vao = 0; GLuint vbo = 0; - ghoul::opengl::ProgramObject* _program; + std::unique_ptr _program; static void ImImpl_RenderDrawLists(ImDrawList** const commandLists, int nCommandLists) { if (nCommandLists == 0) @@ -240,8 +240,6 @@ void GUI::initializeGL() { } void GUI::deinitializeGL() { - if (_program) - delete _program; _program = nullptr; if (vao) glDeleteVertexArrays(1, &vao); diff --git a/modules/onscreengui/src/guiperformancecomponent.cpp b/modules/onscreengui/src/guiperformancecomponent.cpp index 094349193e..0d6e07558b 100644 --- a/modules/onscreengui/src/guiperformancecomponent.cpp +++ b/modules/onscreengui/src/guiperformancecomponent.cpp @@ -87,7 +87,8 @@ void GuiPerformanceComponent::render() { _performanceMemory = new ghoul::SharedMemory(RenderEngine::PerformanceMeasurementSharedData); - PerformanceLayout* layout = reinterpret_cast(_performanceMemory->pointer()); + void* ptr = _performanceMemory; + PerformanceLayout* layout = reinterpret_cast(ptr); for (int i = 0; i < layout->nEntries; ++i) { const PerformanceLayout::PerformanceLayoutEntry& entry = layout->entries[i]; diff --git a/src/abuffer/abuffer.cpp b/src/abuffer/abuffer.cpp index 9af9eda690..7f7b5396af 100644 --- a/src/abuffer/abuffer.cpp +++ b/src/abuffer/abuffer.cpp @@ -60,9 +60,7 @@ ABuffer::ABuffer() } ABuffer::~ABuffer() { - delete _resolveShader; - - for (auto file: _samplerFiles) + for (auto file : _samplerFiles) delete file; } @@ -172,22 +170,17 @@ int ABuffer::addSamplerfile(const std::string& filename) { bool ABuffer::updateShader() { if (_resolveShader == nullptr) return false; - bool s = _resolveShader->rebuildFromFile(); - if (s) { - int startAt = 0; - for (int i = 0; i < _volumes.size(); ++i) { - _resolveShader->setUniform(_volumes.at(i).first, i); - startAt = i + 1; - } - for (int i = 0; i < _transferFunctions.size(); ++i) { - _resolveShader->setUniform(_transferFunctions.at(i).first, startAt + i); - } - LINFO("Successfully updated ABuffer resolve shader!"); - } - else { - LWARNING("Couldn't update ABuffer resolve shader"); - } - return s; + _resolveShader->rebuildFromFile(); + int startAt = 0; + for (int i = 0; i < _volumes.size(); ++i) { + _resolveShader->setUniform(_volumes.at(i).first, i); + startAt = i + 1; + } + for (int i = 0; i < _transferFunctions.size(); ++i) { + _resolveShader->setUniform(_transferFunctions.at(i).first, startAt + i); + } + LINFO("Successfully updated ABuffer resolve shader!"); + return true; } void ABuffer::generateShaderSource() { diff --git a/src/abuffer/abuffervisualizer.cpp b/src/abuffer/abuffervisualizer.cpp index d96868daa7..b1082cc521 100644 --- a/src/abuffer/abuffervisualizer.cpp +++ b/src/abuffer/abuffervisualizer.cpp @@ -58,8 +58,6 @@ ABufferVisualizer::~ABufferVisualizer() { glDeleteVertexArrays(1, &_pointcloud); if (_markers) glDeleteVertexArrays(1, &_markers); - if (_pointcloudProgram) - delete _pointcloudProgram; } void ABufferVisualizer::updateData(const std::vector& data) { diff --git a/src/interaction/interactionhandler.cpp b/src/interaction/interactionhandler.cpp index 24846fd233..2e8a5784f9 100644 --- a/src/interaction/interactionhandler.cpp +++ b/src/interaction/interactionhandler.cpp @@ -32,7 +32,6 @@ #include #include -#include #include namespace { @@ -245,9 +244,6 @@ void InteractionHandler::update(double deltaTime) { if (_keyframes.size() > 4){ //wait until enough samples are buffered hasKeys = true; - ghoul::Interpolator positionInterpCR; - ghoul::Interpolator positionInterpLin; - ghoul::Interpolator quatInterpLin; openspace::network::datamessagestructures::PositionKeyframe p0, p1, p2, p3; @@ -268,10 +264,10 @@ void InteractionHandler::update(double deltaTime) { //glm::dvec4 v = positionInterpCR.interpolate(fact, _keyframes[0]._position.dvec4(), _keyframes[1]._position.dvec4(), _keyframes[2]._position.dvec4(), _keyframes[3]._position.dvec4()); - glm::dvec4 v = positionInterpLin.interpolate(fact, p1._position.dvec4(), p2._position.dvec4()); + glm::dvec4 v = ghoul::interpolateLinear(fact, p1._position.dvec4(), p2._position.dvec4()); pos = psc(v.x, v.y, v.z, v.w); - q = quatInterpLin.interpolate(fact, p1._viewRotationQuat, p2._viewRotationQuat); + q = ghoul::interpolateLinear(fact, p1._viewRotationQuat, p2._viewRotationQuat); //we're done with this sample interval if (_currentKeyframeTime >= p2._timeStamp){ diff --git a/src/interaction/keyboardcontroller.cpp b/src/interaction/keyboardcontroller.cpp index 213392f5df..10eecfa151 100644 --- a/src/interaction/keyboardcontroller.cpp +++ b/src/interaction/keyboardcontroller.cpp @@ -32,7 +32,8 @@ #include #include #include -#include + +#include namespace { const std::string _loggerCat = "KeyboardController"; @@ -169,7 +170,7 @@ void KeyboardControllerLua::keyPressed(KeyAction action, Key key, KeyModifier mo return; } - auto start = ghoul::HighResClock::now(); + auto start = std::chrono::high_resolution_clock::now(); lua_getfield(s, -1, keyToString(key, modifier).c_str()); if (!lua_isnil(s, -1)) @@ -177,7 +178,7 @@ void KeyboardControllerLua::keyPressed(KeyAction action, Key key, KeyModifier mo else LINFO("Key not found"); - auto end = ghoul::HighResClock::now(); + auto end = std::chrono::high_resolution_clock::now(); LINFO("Keyboard timing: " << std::chrono::duration_cast(end - start).count() << "ns"); diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index bb27f80ec1..f5b66df4e9 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -919,7 +919,8 @@ void RenderEngine::storePerformanceMeasurements() { ghoul::SharedMemory::create(PerformanceMeasurementSharedData, totalSize); _performanceMemory = new ghoul::SharedMemory(PerformanceMeasurementSharedData); - PerformanceLayout* layout = reinterpret_cast(_performanceMemory->pointer()); + void* ptr = _performanceMemory; + PerformanceLayout* layout = reinterpret_cast(ptr); layout->version = Version; layout->nValuesPerEntry = nValues; layout->nEntries = nNodes; @@ -944,7 +945,8 @@ void RenderEngine::storePerformanceMeasurements() { } } - PerformanceLayout* layout = reinterpret_cast(_performanceMemory->pointer()); + void* ptr = _performanceMemory; + PerformanceLayout* layout = reinterpret_cast(ptr); _performanceMemory->acquireLock(); for (int i = 0; i < nNodes; ++i) { SceneGraphNode* node = scene()->allSceneGraphNodes()[i]; diff --git a/src/scene/scene.cpp b/src/scene/scene.cpp index 4dd7d32384..ae850d3465 100644 --- a/src/scene/scene.cpp +++ b/src/scene/scene.cpp @@ -84,8 +84,6 @@ bool Scene::initialize() { using ghoul::opengl::ShaderObject; using ghoul::opengl::ProgramObject; - ProgramObject* tmpProgram; - ghoul::opengl::ProgramObject::ProgramObjectCallback cb = [this](ghoul::opengl::ProgramObject* program) { _programUpdateLock.lock(); _programsToUpdate.insert(program); @@ -93,40 +91,40 @@ bool Scene::initialize() { }; // fboPassthrough program - tmpProgram = ProgramObject::Build("fboPassProgram", + std::unique_ptr prg = ProgramObject::Build("fboPassProgram", "${SHADERS}/fboPass_vs.glsl", "${SHADERS}/fboPass_fs.glsl"); - if (!tmpProgram) return false; - tmpProgram->setProgramObjectCallback(cb); - _programs.push_back(tmpProgram); - OsEng.ref().configurationManager()->setValue("fboPassProgram", tmpProgram); + if (!prg) return false; + prg->setProgramObjectCallback(cb); + OsEng.ref().configurationManager()->setValue("fboPassProgram", prg.get()); + _programs.push_back(std::move(prg)); // pscstandard - tmpProgram = ProgramObject::Build("pscstandard", + prg = ProgramObject::Build("pscstandard", "${SHADERS}/pscstandard_vs.glsl", "${SHADERS}/pscstandard_fs.glsl"); - if( ! tmpProgram) return false; - tmpProgram->setProgramObjectCallback(cb); - _programs.push_back(tmpProgram); - OsEng.ref().configurationManager()->setValue("pscShader", tmpProgram); + if (! prg) return false; + prg->setProgramObjectCallback(cb); + OsEng.ref().configurationManager()->setValue("pscShader", prg.get()); + _programs.push_back(std::move(prg)); // Night texture program - tmpProgram = ProgramObject::Build("nightTextureProgram", + prg = ProgramObject::Build("nightTextureProgram", "${SHADERS}/nighttexture_vs.glsl", "${SHADERS}/nighttexture_fs.glsl"); - if (!tmpProgram) return false; - tmpProgram->setProgramObjectCallback(cb); - _programs.push_back(tmpProgram); - OsEng.ref().configurationManager()->setValue("nightTextureProgram", tmpProgram); + if (!prg) return false; + prg->setProgramObjectCallback(cb); + OsEng.ref().configurationManager()->setValue("nightTextureProgram", prg.get()); + _programs.push_back(std::move(prg)); // RaycastProgram - tmpProgram = ProgramObject::Build("RaycastProgram", + prg = ProgramObject::Build("RaycastProgram", "${SHADERS}/exitpoints.vert", "${SHADERS}/exitpoints.frag"); - if (!tmpProgram) return false; - tmpProgram->setProgramObjectCallback(cb); - _programs.push_back(tmpProgram); - OsEng.ref().configurationManager()->setValue("RaycastProgram", tmpProgram); + if (!prg) return false; + prg->setProgramObjectCallback(cb); + OsEng.ref().configurationManager()->setValue("RaycastProgram", prg.get()); + _programs.push_back(std::move(prg)); return true; } @@ -136,8 +134,6 @@ bool Scene::deinitialize() { // clean up all programs _programsToUpdate.clear(); - for (ghoul::opengl::ProgramObject* program : _programs) - delete program; _programs.clear(); return true; } @@ -175,7 +171,7 @@ void Scene::render(const RenderData& data) { if (!emptyProgramsToUpdate) { LDEBUG("Setting uniforms"); // Ignore attribute locations - for (ghoul::opengl::ProgramObject* program : _programs) + for (const auto& program : _programs) program->setIgnoreSubroutineUniformLocationError(true); } diff --git a/src/scene/scenegraphnode.cpp b/src/scene/scenegraphnode.cpp index 40d3817230..9ae75532f3 100644 --- a/src/scene/scenegraphnode.cpp +++ b/src/scene/scenegraphnode.cpp @@ -34,7 +34,6 @@ #include #include #include -#include #include #include @@ -43,6 +42,7 @@ #include #include +#include namespace { const std::string _loggerCat = "SceneGraphNode"; @@ -177,12 +177,12 @@ void SceneGraphNode::update(const UpdateData& data) { if (_ephemeris) { if (data.doPerformanceMeasurement) { glFinish(); - ghoul::HighResClock::time_point start = ghoul::HighResClock::now(); + auto start = std::chrono::high_resolution_clock::now(); _ephemeris->update(data); glFinish(); - ghoul::HighResClock::time_point end = ghoul::HighResClock::now(); + auto end = std::chrono::high_resolution_clock::now(); _performanceRecord.updateTimeEphemeris = (end - start).count(); } else @@ -192,12 +192,12 @@ void SceneGraphNode::update(const UpdateData& data) { if (_renderable && _renderable->isReady()) { if (data.doPerformanceMeasurement) { glFinish(); - ghoul::HighResClock::time_point start = ghoul::HighResClock::now(); + auto start = std::chrono::high_resolution_clock::now(); _renderable->update(data); glFinish(); - ghoul::HighResClock::time_point end = ghoul::HighResClock::now(); + auto end = std::chrono::high_resolution_clock::now(); _performanceRecord.updateTimeRenderable = (end - start).count(); } else @@ -254,12 +254,12 @@ void SceneGraphNode::render(const RenderData& data) { if (_renderableVisible && _renderable->isVisible() && _renderable->isReady() && _renderable->isEnabled()) { if (data.doPerformanceMeasurement) { glFinish(); - ghoul::HighResClock::time_point start = ghoul::HighResClock::now(); + auto start = std::chrono::high_resolution_clock::now(); _renderable->render(newData); glFinish(); - ghoul::HighResClock::time_point end = ghoul::HighResClock::now(); + auto end = std::chrono::high_resolution_clock::now(); _performanceRecord.renderTime = (end - start).count(); } else From e5a3a7a80b6894e8dc10bacdfead74b43b2253b2 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Wed, 9 Dec 2015 19:10:59 -0500 Subject: [PATCH 060/122] Updating Ghoul version Adapting OpenSpaceEngine to new Ghoul API --- ext/ghoul | 2 +- src/engine/openspaceengine.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index b5976438ea..e39984d41d 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit b5976438ea22ab0e9cf46a2e77ea6a7d6233eeca +Subproject commit e39984d41d6108b9fe38b50202972ac7c6cb7435 diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 890257e21f..80db9dceb8 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -272,7 +272,7 @@ bool OpenSpaceEngine::create( _engine->_console->initialize(); // Register the provided shader directories - ghoul::opengl::ShaderObject::addIncludePath("${SHADERS}"); + ghoul::opengl::ShaderPreprocessor::addIncludePath("${SHADERS}"); _engine->_syncBuffer = new SyncBuffer(1024); From ae55078ff8375cce5de39bfa6ac311efc63bcde5 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Fri, 11 Dec 2015 16:50:21 -0500 Subject: [PATCH 061/122] Updated Ghoul version Adapted to changed Ghoul API Reenable fading of ScreenLog messages --- ext/ghoul | 2 +- modules/base/rendering/renderablestars.cpp | 1 + shaders/PowerScaling/powerScalingMath.hglsl | 2 +- src/engine/openspaceengine.cpp | 2 +- src/rendering/renderengine.cpp | 2 -- 5 files changed, 4 insertions(+), 5 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index e39984d41d..49a2ef9adc 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit e39984d41d6108b9fe38b50202972ac7c6cb7435 +Subproject commit 49a2ef9adcf469019cd0598c742e38be007d379c diff --git a/modules/base/rendering/renderablestars.cpp b/modules/base/rendering/renderablestars.cpp index 7a676d9b10..da562905eb 100644 --- a/modules/base/rendering/renderablestars.cpp +++ b/modules/base/rendering/renderablestars.cpp @@ -150,6 +150,7 @@ bool RenderableStars::initialize() { "${MODULE_BASE}/shaders/star_vs.glsl", "${MODULE_BASE}/shaders/star_fs.glsl", "${MODULE_BASE}/shaders/star_ge.glsl"); + if (!_program) return false; completeSuccess &= loadData(); diff --git a/shaders/PowerScaling/powerScalingMath.hglsl b/shaders/PowerScaling/powerScalingMath.hglsl index 583ff34f36..0e2e9e1a5e 100644 --- a/shaders/PowerScaling/powerScalingMath.hglsl +++ b/shaders/PowerScaling/powerScalingMath.hglsl @@ -65,4 +65,4 @@ vec4 z_normalization(vec4 v_in) { return v_out; } -#endif \ No newline at end of file +#endif diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 80db9dceb8..c6685206e8 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -272,7 +272,7 @@ bool OpenSpaceEngine::create( _engine->_console->initialize(); // Register the provided shader directories - ghoul::opengl::ShaderPreprocessor::addIncludePath("${SHADERS}"); + ghoul::opengl::ShaderPreprocessor::addIncludePath(absPath("${SHADERS}")); _engine->_syncBuffer = new SyncBuffer(1024); diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index f5b66df4e9..3cdd9e5971 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -656,8 +656,6 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi alpha = (p <= 0.f) ? 0.f : pow(p, 0.3f); } - alpha = 1.f; - // Since all log entries are ordered, once one exceeds alpha, all have if (alpha <= 0.0) break; From 8260f5701d639f30d395501bf70e7b0708430b76 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sat, 12 Dec 2015 13:29:09 -0500 Subject: [PATCH 062/122] Updated Ghoul Adapted to Ghoul API change --- ext/ghoul | 2 +- src/engine/openspaceengine.cpp | 10 +++++++--- src/rendering/renderengine.cpp | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index 49a2ef9adc..c478ec84d5 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 49a2ef9adcf469019cd0598c742e38be007d379c +Subproject commit c478ec84d584d4cd843ec2e472d7e84b4ec91791 diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index c6685206e8..3d445a13ff 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -56,7 +56,7 @@ #include #include #include -#include +#include #include #include @@ -321,8 +321,12 @@ bool OpenSpaceEngine::initialize() { clearAllWindows(); // Detect and log OpenCL and OpenGL versions and available devices - SysCap.addComponent(new ghoul::systemcapabilities::GeneralCapabilitiesComponent); - SysCap.addComponent(new ghoul::systemcapabilities::OpenGLCapabilitiesComponent); + SysCap.addComponent( + std::make_unique() + ); + SysCap.addComponent( + std::make_unique() + ); SysCap.detectCapabilities(); using Verbosity = ghoul::systemcapabilities::SystemCapabilitiesComponent::Verbosity; diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 3cdd9e5971..a7161f578f 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -143,7 +143,7 @@ bool RenderEngine::initialize() { // The default rendering method has a requirement of OpenGL 4.3, so if we are // below that, we will fall back to frame buffer operation - if (OpenGLCap.openGLVersion() < Version(4,3)) { + if (OpenGLCap.openGLVersion() < Version{4,3}) { LINFO("Falling back to framebuffer implementation due to OpenGL limitations"); renderingMethod = "ABufferFrameBuffer"; } From e26f1d41a4b1da315e63e8a7a659dce8de66c7e5 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 13 Dec 2015 22:01:42 -0800 Subject: [PATCH 063/122] Updated Ghoul version Started cleaning up OpenSpace --- ext/ghoul | 2 +- include/openspace/engine/logfactory.h | 32 +- include/openspace/engine/openspaceengine.h | 102 +++---- modules/base/rendering/renderableplane.cpp | 2 +- modules/base/rendering/renderableplanet.cpp | 4 +- .../rendering/renderablesphericalgrid.cpp | 2 +- .../rendering/renderableplaneprojection.cpp | 8 +- modules/newhorizons/util/sequenceparser.cpp | 4 +- modules/onscreengui/src/gui.cpp | 12 +- .../onscreengui/src/guiorigincomponent.cpp | 6 +- .../src/guiperformancecomponent.cpp | 2 +- .../onscreengui/src/guipropertycomponent.cpp | 8 +- modules/onscreengui/src/guitimecomponent.cpp | 2 +- .../volume/rendering/renderablevolumegl.cpp | 8 +- src/abuffer/abuffer.cpp | 1 + src/engine/logfactory.cpp | 26 +- src/engine/openspaceengine.cpp | 281 ++++++++---------- src/interaction/interactionhandler.cpp | 12 +- src/interaction/interactionhandler_lua.inl | 22 +- src/interaction/keyboardcontroller.cpp | 8 +- src/interaction/luaconsole.cpp | 4 +- src/interaction/luaconsole_lua.inl | 6 +- src/interaction/mousecontroller.cpp | 7 +- src/network/networkengine.cpp | 4 +- src/network/parallelconnection.cpp | 12 +- src/network/parallelconnection_lua.inl | 14 +- src/query/query.cpp | 4 +- src/rendering/renderengine.cpp | 7 +- src/rendering/renderengine_lua.inl | 12 +- src/scene/scene.cpp | 30 +- src/scene/scene_lua.inl | 4 +- src/scene/scenegraph.cpp | 4 +- src/scripting/scriptengine.cpp | 2 +- src/util/screenlog.cpp | 1 + 34 files changed, 304 insertions(+), 351 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index c478ec84d5..212f1efd5d 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit c478ec84d584d4cd843ec2e472d7e84b4ec91791 +Subproject commit 212f1efd5d9ecd1e84937a01ee9f04a0e10b8a58 diff --git a/include/openspace/engine/logfactory.h b/include/openspace/engine/logfactory.h index ab615b4236..2af0fde8df 100644 --- a/include/openspace/engine/logfactory.h +++ b/include/openspace/engine/logfactory.h @@ -25,21 +25,35 @@ #ifndef __LOGFACTORY_H__ #define __LOGFACTORY_H__ -#include #include namespace ghoul { -namespace logging { - class Log; -} // logging -} // ghoul + class Dictionary; + namespace logging { + class Log; + } +} namespace openspace { -class LogFactory { -public: - static std::unique_ptr createLog(const ghoul::Dictionary& dictionary); -}; +/** + * This function provides the capabilities to create a new ghoul::logging::Log from the + * provided ghoul::Dictionary%. The Dictionary must at least contain a Type + * value that determines the type of the created Log. Currently the types + * HTML and Text are supported which create a + * ghoul::logging::TextLog%, and ghoul::logging::HTMLLog respectively with both also + * require the FileName value for the location at which the logfile should be + * created . Both logs can be customized using the Append, + * TimeStamping, DateStamping, CategoryStamping, + * and LogLevelStamping values. + * \param dictionary The dictionary from which the ghoul::logging::Log should be created + * \return The created ghoul::logging::Log + * \post The return value will not be nullptr + * \throw ghoul::RuntimeError If there was an error creating the ghoul::logging::Log + * \sa ghoul::logging::TextLeg + * \sa ghoul::logging::HTMLLog + */ +std::unique_ptr createLog(const ghoul::Dictionary& dictionary); } // namespace openspace diff --git a/include/openspace/engine/openspaceengine.h b/include/openspace/engine/openspaceengine.h index f44b4cb4ad..7879b20cd9 100644 --- a/include/openspace/engine/openspaceengine.h +++ b/include/openspace/engine/openspaceengine.h @@ -25,27 +25,19 @@ #ifndef __OPENSPACEENGINE_H__ #define __OPENSPACEENGINE_H__ - -#include - -#include #include #include -#include +#include #include +#include #include #include namespace ghoul { -namespace cmdparser { - class CommandlineParser; -} -namespace fontrendering { - class FontManager; -} - +namespace cmdparser { class CommandlineParser; } +namespace fontrendering { class FontManager; } } namespace openspace { @@ -57,28 +49,17 @@ class GUI; class RenderEngine; class SyncBuffer; class ModuleEngine; +class WindowWrapper; -namespace interaction { - class InteractionHandler; -} -namespace gui { - class GUI; -} -namespace scripting { - class ScriptEngine; -} - -namespace network { - class ParallelConnection; -} - -namespace properties { - class PropertyOwner; -} +namespace interaction { class InteractionHandler; } +namespace gui { class GUI; } +namespace scripting { class ScriptEngine; } +namespace network { class ParallelConnection; } +namespace properties { class PropertyOwner; } class OpenSpaceEngine { public: - static bool create(int argc, char** argv, WindowWrapper* windowWrapper, std::vector& sgctArguments); + static bool create(int argc, char** argv, std::unique_ptr windowWrapper, std::vector& sgctArguments); static void destroy(); static OpenSpaceEngine& ref(); @@ -91,27 +72,25 @@ public: static bool findConfiguration(std::string& filename); // Guaranteed to return a valid pointer - ConfigurationManager* configurationManager(); - interaction::InteractionHandler* interactionHandler(); - RenderEngine* renderEngine(); - scripting::ScriptEngine* scriptEngine(); - NetworkEngine* networkEngine(); - LuaConsole* console(); - ModuleEngine* moduleEngine(); - network::ParallelConnection* parallelConnection(); - properties::PropertyOwner* globalPropertyOwner(); + ConfigurationManager& configurationManager(); + interaction::InteractionHandler& interactionHandler(); + RenderEngine& renderEngine(); + scripting::ScriptEngine& scriptEngine(); + NetworkEngine& networkEngine(); + LuaConsole& console(); + ModuleEngine& moduleEngine(); + network::ParallelConnection& parallelConnection(); + properties::PropertyOwner& globalPropertyOwner(); WindowWrapper& windowWrapper(); ghoul::fontrendering::FontManager& fontManager(); - - gui::GUI* gui(); + gui::GUI& gui(); // SGCT callbacks bool initializeGL(); void preSynchronization(); void postSynchronizationPreDraw(); - void render(const glm::mat4 &projectionMatrix, const glm::mat4 &viewMatrix); + void render(const glm::mat4& projectionMatrix, const glm::mat4& viewMatrix); void postDraw(); -// void keyboardCallback(int key, int action); void keyboardCallback(Key key, KeyModifier mod, KeyAction action); void charCallback(unsigned int codepoint, KeyModifier mod); void mouseButtonCallback(MouseButton button, MouseAction action); @@ -127,40 +106,39 @@ public: void runSettingsScripts(); private: - OpenSpaceEngine(std::string programName, WindowWrapper* windowWrapper); + OpenSpaceEngine(std::string programName, std::unique_ptr windowWrapper); ~OpenSpaceEngine(); - OpenSpaceEngine(const OpenSpaceEngine& rhs) = delete; void clearAllWindows(); bool gatherCommandlineArguments(); bool loadSpiceKernels(); - void loadFonts(); - void loadFonts2(); + void loadFonts(); void runScripts(const ghoul::Dictionary& scripts); void runStartupScripts(); void configureLogging(); - static OpenSpaceEngine* _engine; - ConfigurationManager* _configurationManager; - interaction::InteractionHandler* _interactionHandler; - RenderEngine* _renderEngine; - scripting::ScriptEngine* _scriptEngine; - NetworkEngine* _networkEngine; - ghoul::cmdparser::CommandlineParser* _commandlineParser; - LuaConsole* _console; - ModuleEngine* _moduleEngine; - gui::GUI* _gui; - network::ParallelConnection* _parallelConnection; - WindowWrapper* _windowWrapper; - ghoul::fontrendering::FontManager*_fontManager; + std::unique_ptr _configurationManager; + std::unique_ptr _interactionHandler; + std::unique_ptr _renderEngine; + std::unique_ptr _scriptEngine; + std::unique_ptr _networkEngine; + std::unique_ptr _commandlineParser; + std::unique_ptr _console; + std::unique_ptr _moduleEngine; + std::unique_ptr _gui; + std::unique_ptr _parallelConnection; + std::unique_ptr _windowWrapper; + std::unique_ptr _fontManager; - properties::PropertyOwner* _globalPropertyNamespace; + std::unique_ptr _globalPropertyNamespace; bool _isMaster; double _runTime; - SyncBuffer* _syncBuffer; + std::unique_ptr _syncBuffer; + + static OpenSpaceEngine* _engine; }; #define OsEng (openspace::OpenSpaceEngine::ref()) diff --git a/modules/base/rendering/renderableplane.cpp b/modules/base/rendering/renderableplane.cpp index a3c27a1e96..096f972cee 100644 --- a/modules/base/rendering/renderableplane.cpp +++ b/modules/base/rendering/renderableplane.cpp @@ -186,7 +186,7 @@ void RenderablePlane::render(const RenderData& data) { _shader->activate(); if (_projectionListener){ //get parent node-texture and set with correct dimensions - SceneGraphNode* textureNode = OsEng.renderEngine()->scene()->sceneGraphNode(_nodeName)->parent(); + SceneGraphNode* textureNode = OsEng.renderEngine().scene()->sceneGraphNode(_nodeName)->parent(); if (textureNode != nullptr){ RenderablePlanetProjection* t = static_cast(textureNode->renderable()); _texture = std::unique_ptr(t->baseTexture()); diff --git a/modules/base/rendering/renderableplanet.cpp b/modules/base/rendering/renderableplanet.cpp index ffd2db0fd5..84e0f99aa5 100644 --- a/modules/base/rendering/renderableplanet.cpp +++ b/modules/base/rendering/renderableplanet.cpp @@ -123,9 +123,9 @@ RenderablePlanet::~RenderablePlanet() { bool RenderablePlanet::initialize() { if (_programObject == nullptr && _hasNightTexture) - OsEng.ref().configurationManager()->getValue("nightTextureProgram", _programObject); + OsEng.ref().configurationManager().getValue("nightTextureProgram", _programObject); else if (_programObject == nullptr) - OsEng.ref().configurationManager()->getValue("pscShader", _programObject); + OsEng.ref().configurationManager().getValue("pscShader", _programObject); loadTexture(); _geometry->initialize(this); diff --git a/modules/base/rendering/renderablesphericalgrid.cpp b/modules/base/rendering/renderablesphericalgrid.cpp index 24a26d912e..41a4228589 100644 --- a/modules/base/rendering/renderablesphericalgrid.cpp +++ b/modules/base/rendering/renderablesphericalgrid.cpp @@ -166,7 +166,7 @@ bool RenderableSphericalGrid::deinitialize(){ bool RenderableSphericalGrid::initialize(){ bool completeSuccess = true; if (_gridProgram == nullptr) - completeSuccess &= OsEng.ref().configurationManager()->getValue("GridProgram", _gridProgram); + completeSuccess &= OsEng.ref().configurationManager().getValue("GridProgram", _gridProgram); // Initialize and upload to graphics card glGenVertexArrays(1, &_vaoID); diff --git a/modules/newhorizons/rendering/renderableplaneprojection.cpp b/modules/newhorizons/rendering/renderableplaneprojection.cpp index d4cc1ad2c9..6c8cc6e0b2 100644 --- a/modules/newhorizons/rendering/renderableplaneprojection.cpp +++ b/modules/newhorizons/rendering/renderableplaneprojection.cpp @@ -259,8 +259,8 @@ void RenderablePlaneProjection::updatePlane(const Image img, double currentTime) } if (!_moving) { - SceneGraphNode* thisNode = OsEng.renderEngine()->scene()->sceneGraphNode(_name); - SceneGraphNode* newParent = OsEng.renderEngine()->scene()->sceneGraphNode(_target.node); + SceneGraphNode* thisNode = OsEng.renderEngine().scene()->sceneGraphNode(_name); + SceneGraphNode* newParent = OsEng.renderEngine().scene()->sceneGraphNode(_target.node); if (thisNode != nullptr && newParent != nullptr) thisNode->setParent(newParent); } @@ -294,7 +294,7 @@ void RenderablePlaneProjection::setTarget(std::string body) { if (body == "") return; - std::vector nodes = OsEng.renderEngine()->scene()->allSceneGraphNodes(); + std::vector nodes = OsEng.renderEngine().scene()->allSceneGraphNodes(); Renderable* possibleTarget; bool hasBody, found = false; std::string targetBody; @@ -321,7 +321,7 @@ std::string RenderablePlaneProjection::findClosestTarget(double currentTime) { std::vector targets; - std::vector nodes = OsEng.renderEngine()->scene()->allSceneGraphNodes(); + std::vector nodes = OsEng.renderEngine().scene()->allSceneGraphNodes(); Renderable* possibleTarget; std::string targetBody; bool hasBody, found = false; diff --git a/modules/newhorizons/util/sequenceparser.cpp b/modules/newhorizons/util/sequenceparser.cpp index 1a8d2d8554..fa4c7f0ea7 100644 --- a/modules/newhorizons/util/sequenceparser.cpp +++ b/modules/newhorizons/util/sequenceparser.cpp @@ -77,7 +77,7 @@ void writeToBuffer(std::vector& buffer, size_t& currentWriteL void SequenceParser::sendPlaybookInformation(const std::string& name) { std::string fullName = PlaybookIdentifierName + "_" + name; - _messageIdentifier = OsEng.networkEngine()->identifier(fullName); + _messageIdentifier = OsEng.networkEngine().identifier(fullName); std::vector buffer(1024); size_t currentWriteLocation = 0; @@ -165,7 +165,7 @@ void SequenceParser::sendPlaybookInformation(const std::string& name) { buffer.resize(currentWriteLocation); //OsEng.networkEngine()->publishMessage(PlaybookIdentifier, buffer); - OsEng.networkEngine()->setInitialConnectionMessage(_messageIdentifier, buffer); + OsEng.networkEngine().setInitialConnectionMessage(_messageIdentifier, buffer); } } \ No newline at end of file diff --git a/modules/onscreengui/src/gui.cpp b/modules/onscreengui/src/gui.cpp index 0caa5a48bc..9abed3ed75 100644 --- a/modules/onscreengui/src/gui.cpp +++ b/modules/onscreengui/src/gui.cpp @@ -384,11 +384,11 @@ void GUI::renderMainWindow() { bool toJupiter = ImGui::Button("Coordinate System to Jupiter"); if (toSun) - OsEng.scriptEngine()->queueScript("openspace.setPropertyValue('Interaction.coordinateSystem', 'Sun');"); + OsEng.scriptEngine().queueScript("openspace.setPropertyValue('Interaction.coordinateSystem', 'Sun');"); if (toPluto) - OsEng.scriptEngine()->queueScript("openspace.setPropertyValue('Interaction.coordinateSystem', 'Pluto');"); + OsEng.scriptEngine().queueScript("openspace.setPropertyValue('Interaction.coordinateSystem', 'Pluto');"); if (toJupiter) - OsEng.scriptEngine()->queueScript("openspace.setPropertyValue('Interaction.coordinateSystem', 'Jupiter');"); + OsEng.scriptEngine().queueScript("openspace.setPropertyValue('Interaction.coordinateSystem', 'Jupiter');"); ImGui::Checkbox("Help", &_help._isEnabled); @@ -536,7 +536,7 @@ int show(lua_State* L) { if (nArguments != 0) return luaL_error(L, "Expected %i arguments, got %i", 0, nArguments); - OsEng.gui()->setEnabled(true); + OsEng.gui().setEnabled(true); return 0; } @@ -550,7 +550,7 @@ int hide(lua_State* L) { if (nArguments != 0) return luaL_error(L, "Expected %i arguments, got %i", 0, nArguments); - OsEng.gui()->setEnabled(false); + OsEng.gui().setEnabled(false); return 0; } @@ -564,7 +564,7 @@ int toggle(lua_State* L) { if (nArguments != 0) return luaL_error(L, "Expected %i arguments, got %i", 0, nArguments); - OsEng.gui()->setEnabled(!OsEng.gui()->isEnabled()); + OsEng.gui().setEnabled(!OsEng.gui().isEnabled()); return 0; } diff --git a/modules/onscreengui/src/guiorigincomponent.cpp b/modules/onscreengui/src/guiorigincomponent.cpp index e07a1c9aee..34abe5940c 100644 --- a/modules/onscreengui/src/guiorigincomponent.cpp +++ b/modules/onscreengui/src/guiorigincomponent.cpp @@ -39,9 +39,9 @@ namespace openspace { namespace gui { void GuiOriginComponent::render() { - const SceneGraphNode* currentFocus = OsEng.interactionHandler()->focusNode(); + const SceneGraphNode* currentFocus = OsEng.interactionHandler().focusNode(); - std::vector nodes = OsEng.renderEngine()->scene()->allSceneGraphNodes(); + std::vector nodes = OsEng.renderEngine().scene()->allSceneGraphNodes(); std::sort(nodes.begin(), nodes.end(), [](SceneGraphNode* lhs, SceneGraphNode* rhs) { return lhs->name() < rhs->name(); }); auto it = std::find(nodes.begin(), nodes.end(), currentFocus); ghoul_assert(it != nodes.end(), "Focus node not found"); @@ -57,7 +57,7 @@ void GuiOriginComponent::render() { if (result) { LINFO("openspace.setPropertyValue('Interaction.origin', '" + nodes[position]->name() + "');"); - OsEng.scriptEngine()->queueScript("openspace.setPropertyValue('Interaction.origin', '" + nodes[position]->name() + "');"); + OsEng.scriptEngine().queueScript("openspace.setPropertyValue('Interaction.origin', '" + nodes[position]->name() + "');"); } } diff --git a/modules/onscreengui/src/guiperformancecomponent.cpp b/modules/onscreengui/src/guiperformancecomponent.cpp index 0d6e07558b..f76967314b 100644 --- a/modules/onscreengui/src/guiperformancecomponent.cpp +++ b/modules/onscreengui/src/guiperformancecomponent.cpp @@ -76,7 +76,7 @@ void GuiPerformanceComponent::render() { }; ImGui::Begin("Performance", &_isEnabled); - if (OsEng.renderEngine()->doesPerformanceMeasurements() && + if (OsEng.renderEngine().doesPerformanceMeasurements() && ghoul::SharedMemory::exists(RenderEngine::PerformanceMeasurementSharedData)) { ImGui::SliderFloat2("Min values, max Value", _minMaxValues, 0.f, 10000.f); diff --git a/modules/onscreengui/src/guipropertycomponent.cpp b/modules/onscreengui/src/guipropertycomponent.cpp index 15b3977e2b..9f44f84138 100644 --- a/modules/onscreengui/src/guipropertycomponent.cpp +++ b/modules/onscreengui/src/guipropertycomponent.cpp @@ -48,7 +48,7 @@ namespace { void executeScript(const std::string& id, const std::string& value) { std::string script = "openspace.setPropertyValue('" + id + "', " + value + ");"; - OsEng.scriptEngine()->queueScript(script); + OsEng.scriptEngine().queueScript(script); } void renderBoolProperty(Property* prop, const std::string& ownerName) { @@ -432,17 +432,17 @@ void GuiPropertyComponent::render() { ImGui::Begin("Properties", &_isEnabled, size, 0.5f); if (ImGui::CollapsingHeader("OnScreen GUI")) { - glm::vec2& pos = OsEng.renderEngine()->_onScreenInformation._position; + glm::vec2& pos = OsEng.renderEngine()._onScreenInformation._position; Vec2Property::ValueType value = pos; ImGui::SliderFloat2("Position", &value.x, -1.f, 1.f); pos = value; - unsigned int& size = OsEng.renderEngine()->_onScreenInformation._size; + unsigned int& size = OsEng.renderEngine()._onScreenInformation._size; int sizeValue = static_cast(size); ImGui::SliderInt("Size", &sizeValue, 0, 36); size = static_cast(sizeValue); - int& node = OsEng.renderEngine()->_onScreenInformation._node; + int& node = OsEng.renderEngine()._onScreenInformation._node; int iValue = node; ImGui::SliderInt("Node#", &iValue, 0, 30); node = iValue; diff --git a/modules/onscreengui/src/guitimecomponent.cpp b/modules/onscreengui/src/guitimecomponent.cpp index 85c0d90d1c..959d0a7a11 100644 --- a/modules/onscreengui/src/guitimecomponent.cpp +++ b/modules/onscreengui/src/guitimecomponent.cpp @@ -42,7 +42,7 @@ void GuiTimeComponent::render() { bool changed = ImGui::SliderFloat("Delta Time", &deltaTime, -100.f, 100.f); if (changed) - OsEng.scriptEngine()->queueScript("openspace.time.setDeltaTime(" + std::to_string(deltaTime) + ")"); + OsEng.scriptEngine().queueScript("openspace.time.setDeltaTime(" + std::to_string(deltaTime) + ")"); //char dateBuffer[512] = {}; diff --git a/modules/volume/rendering/renderablevolumegl.cpp b/modules/volume/rendering/renderablevolumegl.cpp index b738995cab..2ff94ce6d7 100644 --- a/modules/volume/rendering/renderablevolumegl.cpp +++ b/modules/volume/rendering/renderablevolumegl.cpp @@ -177,13 +177,13 @@ bool RenderableVolumeGL::initialize() { if(_filename != "") { _volume = loadVolume(_filename, _hintsDictionary); _volume->uploadTexture(); - OsEng.renderEngine()->aBuffer()->addVolume(_volumeName, _volume); + OsEng.renderEngine().aBuffer()->addVolume(_volumeName, _volume); } if(_transferFunctionPath != "") { _transferFunction = loadTransferFunction(_transferFunctionPath); _transferFunction->uploadTexture(); - OsEng.renderEngine()->aBuffer()->addTransferFunction(_transferFunctionName, _transferFunction); + OsEng.renderEngine().aBuffer()->addTransferFunction(_transferFunctionName, _transferFunction); auto textureCallback = [this](const ghoul::filesystem::File& file) { _updateTransferfunction = true; @@ -192,9 +192,9 @@ bool RenderableVolumeGL::initialize() { } // add the sampler and get the ID - _id = OsEng.renderEngine()->aBuffer()->addSamplerfile(_samplerFilename); + _id = OsEng.renderEngine().aBuffer()->addSamplerfile(_samplerFilename); - OsEng.configurationManager()->getValue("RaycastProgram", _boxProgram); + OsEng.configurationManager().getValue("RaycastProgram", _boxProgram); // ============================ // GEOMETRY (box) diff --git a/src/abuffer/abuffer.cpp b/src/abuffer/abuffer.cpp index 7f7b5396af..8a48854b1e 100644 --- a/src/abuffer/abuffer.cpp +++ b/src/abuffer/abuffer.cpp @@ -24,6 +24,7 @@ #include #include +#include #include #include diff --git a/src/engine/logfactory.cpp b/src/engine/logfactory.cpp index 6e668993de..c318e74ac8 100644 --- a/src/engine/logfactory.cpp +++ b/src/engine/logfactory.cpp @@ -24,13 +24,13 @@ #include +#include +#include +#include #include #include -#include namespace { - const std::string _loggerCat = "LogFactory"; - const std::string keyType = "Type"; const std::string keyFilename = "FileName"; const std::string keyAppend = "Append"; @@ -45,20 +45,21 @@ namespace { namespace openspace { -std::unique_ptr LogFactory::createLog(const ghoul::Dictionary& dictionary) { +std::unique_ptr createLog(const ghoul::Dictionary& dictionary) { std::string type; bool typeSuccess = dictionary.getValue(keyType, type); if (!typeSuccess) { - LERROR("Requested log did not contain a key '" << keyType << "'"); - return nullptr; + throw ghoul::RuntimeError( + "Requested log did not contain key '" + keyType + "'", "LogFactory" + ); } std::string filename; bool filenameSuccess = dictionary.getValue(keyFilename, filename); if (!filenameSuccess) { - LERROR("Requested log of type '" << keyType << "' did not contain a key '" - << keyFilename << "'"); - return nullptr; + throw ghoul::RuntimeError( + "Requested log did not contain key '" + keyFilename + "'", "LogFactory" + ); } filename = absPath(filename); @@ -84,9 +85,10 @@ std::unique_ptr LogFactory::createLog(const ghoul::Dictiona ); } else { - LERROR("Log with type '" << type << "' did not name a valid log"); - return nullptr; + throw ghoul::RuntimeError( + "Log with type '" + type + "' did not name a valid log", "LogFactory" + ); } } - + } // namespace openspace diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 3d445a13ff..b6e0e49533 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -24,12 +24,13 @@ #include -#include - #include #include +#include #include +#include +#include #include #include #include @@ -39,28 +40,24 @@ #include #include #include +#include +#include #include #include -#include -#include -#include #include -#include -#include #include #include #include #include #include +#include +#include #include #include #include #include -#include -#include -#include #include #ifdef OPENSPACE_MODULE_ONSCREENGUI_ENABLED @@ -100,7 +97,8 @@ namespace openspace { OpenSpaceEngine* OpenSpaceEngine::_engine = nullptr; -OpenSpaceEngine::OpenSpaceEngine(std::string programName, WindowWrapper* windowWrapper) +OpenSpaceEngine::OpenSpaceEngine(std::string programName, + std::unique_ptr windowWrapper) : _configurationManager(new ConfigurationManager) , _interactionHandler(new interaction::InteractionHandler) , _renderEngine(new RenderEngine) @@ -111,14 +109,14 @@ OpenSpaceEngine::OpenSpaceEngine(std::string programName, WindowWrapper* windowW , _moduleEngine(new ModuleEngine) , _gui(new gui::GUI) , _parallelConnection(new network::ParallelConnection) - , _windowWrapper(windowWrapper) + , _windowWrapper(std::move(windowWrapper)) , _globalPropertyNamespace(new properties::PropertyOwner) , _isMaster(false) , _runTime(0.0) - , _syncBuffer(nullptr) + , _syncBuffer(new SyncBuffer(1024)) { - _interactionHandler->setPropertyOwner(_globalPropertyNamespace); - _globalPropertyNamespace->addPropertySubOwner(_interactionHandler); + _interactionHandler->setPropertyOwner(_globalPropertyNamespace.get()); + _globalPropertyNamespace->addPropertySubOwner(_interactionHandler.get()); FactoryManager::initialize(); SpiceManager::initialize(); Time::initialize(); @@ -128,43 +126,18 @@ OpenSpaceEngine::OpenSpaceEngine(std::string programName, WindowWrapper* windowW OpenSpaceEngine::~OpenSpaceEngine() { _gui->deinitializeGL(); - delete _globalPropertyNamespace; _globalPropertyNamespace = nullptr; - - delete _windowWrapper; _windowWrapper = nullptr; - - delete _parallelConnection; _parallelConnection = nullptr; - - delete _configurationManager; _configurationManager = nullptr; - - delete _interactionHandler; _interactionHandler = nullptr; - - delete _renderEngine; _renderEngine = nullptr; - - delete _scriptEngine; _scriptEngine = nullptr; - - delete _networkEngine; _networkEngine = nullptr; - - delete _commandlineParser; _commandlineParser = nullptr; - - delete _console; _console = nullptr; - - delete _moduleEngine; _moduleEngine = nullptr; - - delete _gui; _gui = nullptr; - - delete _syncBuffer; _syncBuffer = nullptr; } @@ -173,15 +146,14 @@ OpenSpaceEngine& OpenSpaceEngine::ref() { return *_engine; } -bool OpenSpaceEngine::create( - int argc, char** argv, - WindowWrapper* windowWrapper, - std::vector& sgctArguments) +bool OpenSpaceEngine::create(int argc, char** argv, + std::unique_ptr windowWrapper, + std::vector& sgctArguments) { - ghoul::initialize(); - ghoul_assert(!_engine, "OpenSpaceEngine was already created"); ghoul_assert(windowWrapper != nullptr, "No Window Wrapper was provided"); + + ghoul::initialize(); // Initialize the LogManager and add the console log as this will be used every time // and we need a fall back if something goes wrong between here and when we add the @@ -208,7 +180,7 @@ bool OpenSpaceEngine::create( // Create other objects LDEBUG("Creating OpenSpaceEngine"); - _engine = new OpenSpaceEngine(std::string(argv[0]), windowWrapper); + _engine = new OpenSpaceEngine(std::string(argv[0]), std::move(windowWrapper)); // Query modules for commandline arguments bool gatherSuccess = _engine->gatherCommandlineArguments(); @@ -239,7 +211,7 @@ bool OpenSpaceEngine::create( // Loading configuration from disk LDEBUG("Loading configuration from disk"); - const bool configLoadSuccess = _engine->configurationManager()->loadFromFile( + const bool configLoadSuccess = _engine->configurationManager().loadFromFile( configurationFilePath); if (!configLoadSuccess) { LFATAL("Loading of configuration file '" << configurationFilePath << "' failed"); @@ -268,18 +240,18 @@ bool OpenSpaceEngine::create( _engine->_moduleEngine->create(); // Create the cachemanager - FileSys.createCacheManager(absPath("${" + ConfigurationManager::KeyCache + "}"), CacheVersion); + FileSys.createCacheManager( + absPath("${" + ConfigurationManager::KeyCache + "}"), CacheVersion + ); _engine->_console->initialize(); // Register the provided shader directories ghoul::opengl::ShaderPreprocessor::addIncludePath(absPath("${SHADERS}")); - _engine->_syncBuffer = new SyncBuffer(1024); - // Determining SGCT configuration file LDEBUG("Determining SGCT configuration file"); std::string sgctConfigurationPath = _sgctDefaultConfigFile; - _engine->configurationManager()->getValue( + _engine->configurationManager().getValue( ConfigurationManager::KeyConfigSgct, sgctConfigurationPath); if (!commandlineArgumentPlaceholders.sgctConfigurationName.empty()) { @@ -331,21 +303,21 @@ bool OpenSpaceEngine::initialize() { using Verbosity = ghoul::systemcapabilities::SystemCapabilitiesComponent::Verbosity; Verbosity verbosity = Verbosity::Default; - if (configurationManager()->hasKeyAndValue(ConfigurationManager::KeyCapabilitiesVerbosity)) { + if (configurationManager().hasKeyAndValue(ConfigurationManager::KeyCapabilitiesVerbosity)) { std::map verbosityMap = { { "Minimal", Verbosity::Minimal }, { "Default", Verbosity::Default }, { "Full", Verbosity::Full } }; - std::string v = configurationManager()->value(ConfigurationManager::KeyCapabilitiesVerbosity); + std::string v = configurationManager().value(ConfigurationManager::KeyCapabilitiesVerbosity); if (verbosityMap.find(v) != verbosityMap.end()) verbosity = verbosityMap[v]; } SysCap.logCapabilities(verbosity); std::string requestURL = ""; - bool success = configurationManager()->getValue(ConfigurationManager::KeyDownloadRequestURL, requestURL); + bool success = configurationManager().getValue(ConfigurationManager::KeyDownloadRequestURL, requestURL); if (success) DownloadManager::initialize(requestURL, DownloadVersion); @@ -365,23 +337,23 @@ bool OpenSpaceEngine::initialize() { _scriptEngine->addLibrary(network::ParallelConnection::luaLibrary()); // TODO: Maybe move all scenegraph and renderengine stuff to initializeGL - scriptEngine()->initialize(); + scriptEngine().initialize(); // If a LuaDocumentationFile was specified, generate it now - const bool hasType = configurationManager()->hasKey(ConfigurationManager::KeyLuaDocumentationType); - const bool hasFile = configurationManager()->hasKey(ConfigurationManager::KeyLuaDocumentationFile); + const bool hasType = configurationManager().hasKey(ConfigurationManager::KeyLuaDocumentationType); + const bool hasFile = configurationManager().hasKey(ConfigurationManager::KeyLuaDocumentationFile); if (hasType && hasFile) { std::string luaDocumentationType; - configurationManager()->getValue(ConfigurationManager::KeyLuaDocumentationType, luaDocumentationType); + configurationManager().getValue(ConfigurationManager::KeyLuaDocumentationType, luaDocumentationType); std::string luaDocumentationFile; - configurationManager()->getValue(ConfigurationManager::KeyLuaDocumentationFile, luaDocumentationFile); + configurationManager().getValue(ConfigurationManager::KeyLuaDocumentationFile, luaDocumentationFile); luaDocumentationFile = absPath(luaDocumentationFile); _scriptEngine->writeDocumentation(luaDocumentationFile, luaDocumentationType); } bool disableMasterRendering = false; - configurationManager()->getValue( + configurationManager().getValue( ConfigurationManager::KeyDisableMasterRendering, disableMasterRendering); _renderEngine->setDisableRenderingOnMaster(disableMasterRendering); @@ -396,7 +368,7 @@ bool OpenSpaceEngine::initialize() { std::string sceneDescriptionPath = ""; if (commandlineArgumentPlaceholders.sceneName.empty()) { - success = configurationManager()->getValue( + success = configurationManager().getValue( ConfigurationManager::KeyConfigScene, sceneDescriptionPath); } else @@ -410,8 +382,7 @@ bool OpenSpaceEngine::initialize() { runStartupScripts(); // Load a light and a monospaced font - loadFonts(); - loadFonts2(); + loadFonts(); LINFO("Initializing GUI"); _gui->initialize(); @@ -483,7 +454,7 @@ bool OpenSpaceEngine::findConfiguration(std::string& filename) { bool OpenSpaceEngine::loadSpiceKernels() { // Load time kernel std::string timeKernel; - bool success = configurationManager()->getValue(ConfigurationManager::KeySpiceTimeKernel, timeKernel); + bool success = configurationManager().getValue(ConfigurationManager::KeySpiceTimeKernel, timeKernel); // Move this to configurationmanager::completenesscheck ---abock if (!success) { LERROR("Configuration file does not contain a '" << ConfigurationManager::KeySpiceTimeKernel << "'"); @@ -494,7 +465,7 @@ bool OpenSpaceEngine::loadSpiceKernels() { // Load SPICE leap second kernel std::string leapSecondKernel; - success = configurationManager()->getValue(ConfigurationManager::KeySpiceLeapsecondKernel, leapSecondKernel); + success = configurationManager().getValue(ConfigurationManager::KeySpiceLeapsecondKernel, leapSecondKernel); if (!success) { // Move this to configurationmanager::completenesscheck ---abock LERROR("Configuration file does not have a '" << ConfigurationManager::KeySpiceLeapsecondKernel << "'"); @@ -519,7 +490,7 @@ void OpenSpaceEngine::runScripts(const ghoul::Dictionary& scripts) { std::string scriptPath; scripts.getValue(key, scriptPath); std::string&& absoluteScriptPath = absPath(scriptPath); - _engine->scriptEngine()->runScriptFile(absoluteScriptPath); + _engine->scriptEngine().runScriptFile(absoluteScriptPath); //@JK //temporary solution to ensure that startup scripts may be syncrhonized over parallel connection @@ -531,9 +502,9 @@ void OpenSpaceEngine::runScripts(const ghoul::Dictionary& scripts) { //valid line and not a comment if(line.size() > 0 && line.at(0) != '-'){ std::string lib, func; - if(_engine->scriptEngine()->parseLibraryAndFunctionNames(lib, func, line) && - _engine->scriptEngine()->shouldScriptBeSent(lib, func)){ - _engine->scriptEngine()->cacheScript(lib, func, line); + if(_engine->scriptEngine().parseLibraryAndFunctionNames(lib, func, line) && + _engine->scriptEngine().shouldScriptBeSent(lib, func)){ + _engine->scriptEngine().cacheScript(lib, func, line); } } } @@ -543,51 +514,31 @@ void OpenSpaceEngine::runScripts(const ghoul::Dictionary& scripts) { void OpenSpaceEngine::runStartupScripts() { ghoul::Dictionary scripts; - configurationManager()->getValue( + configurationManager().getValue( ConfigurationManager::KeyStartupScript, scripts); runScripts(scripts); } void OpenSpaceEngine::runSettingsScripts() { ghoul::Dictionary scripts; - configurationManager()->getValue( + configurationManager().getValue( ConfigurationManager::KeySettingsScript, scripts); runScripts(scripts); } void OpenSpaceEngine::loadFonts() { - sgct_text::FontManager::FontPath local = sgct_text::FontManager::FontPath::FontPath_Local; - - ghoul::Dictionary fonts; - configurationManager()->getValue(ConfigurationManager::KeyFonts, fonts); - - for (const std::string& key : fonts.keys()) { - std::string font; - fonts.getValue(key, font); - font = absPath(font); - if(!FileSys.fileExists(font)) { - LERROR("Could not find font '" << font << "'"); - continue; - } - - LINFO("Registering font '" << font << "' with key '" << key << "'"); - sgct_text::FontManager::instance()->addFont(key, font, local); - } -} - -void OpenSpaceEngine::loadFonts2() { ghoul::Dictionary fonts; - configurationManager()->getValue(ConfigurationManager::KeyFonts, fonts); + configurationManager().getValue(ConfigurationManager::KeyFonts, fonts); const glm::ivec3 fontAtlasSize{1024, 1024, 1}; - _fontManager = new ghoul::fontrendering::FontManager(fontAtlasSize); + _fontManager = std::make_unique(fontAtlasSize); for (const std::string& key : fonts.keys()) { std::string font; fonts.getValue(key, font); font = absPath(font); - if(!FileSys.fileExists(font)) { + if (!FileSys.fileExists(font)) { LERROR("Could not find font '" << font << "'"); continue; } @@ -608,12 +559,12 @@ void OpenSpaceEngine::loadFonts2() { } void OpenSpaceEngine::configureLogging() { - if (configurationManager()->hasKeyAndValue(ConfigurationManager::KeyLogLevel)) { + if (configurationManager().hasKeyAndValue(ConfigurationManager::KeyLogLevel)) { std::string logLevel; - configurationManager()->getValue(ConfigurationManager::KeyLogLevel, logLevel); + configurationManager().getValue(ConfigurationManager::KeyLogLevel, logLevel); bool immediateFlush = false; - configurationManager()->getValue(ConfigurationManager::KeyLogImmediateFlush, immediateFlush); + configurationManager().getValue(ConfigurationManager::KeyLogImmediateFlush, immediateFlush); LogManager::LogLevel level = LogManager::levelFromString(logLevel); LogManager::deinitialize(); @@ -621,52 +572,24 @@ void OpenSpaceEngine::configureLogging() { LogMgr.addLog(std::make_unique()); } - if (configurationManager()->hasKeyAndValue(ConfigurationManager::KeyLogs)) { + if (configurationManager().hasKeyAndValue(ConfigurationManager::KeyLogs)) { ghoul::Dictionary logs; - configurationManager()->getValue(ConfigurationManager::KeyLogs, logs); + configurationManager().getValue(ConfigurationManager::KeyLogs, logs); for (size_t i = 1; i <= logs.size(); ++i) { ghoul::Dictionary logInfo; logs.getValue(std::to_string(i), logInfo); - std::unique_ptr log = LogFactory::createLog(logInfo); - - if (log) - LogMgr.addLog(std::move(log)); + try { + LogMgr.addLog(createLog(logInfo)); + } + catch (const ghoul::RuntimeError& e) { + LERRORC(e.component, e.message); + } } } } -ConfigurationManager* OpenSpaceEngine::configurationManager() { - ghoul_assert(_configurationManager != nullptr, "ConfigurationManager is nullptr"); - return _configurationManager; -} - -interaction::InteractionHandler* OpenSpaceEngine::interactionHandler() { - ghoul_assert(_interactionHandler != nullptr, "InteractionHandler is nullptr"); - return _interactionHandler; -} - -RenderEngine* OpenSpaceEngine::renderEngine() { - ghoul_assert(_renderEngine != nullptr, "RenderEngine is nullptr"); - return _renderEngine; -} - -ScriptEngine* OpenSpaceEngine::scriptEngine() { - ghoul_assert(_scriptEngine != nullptr, "ScriptEngine is nullptr"); - return _scriptEngine; -} - -LuaConsole* OpenSpaceEngine::console() { - ghoul_assert(_console != nullptr, "LuaConsole is nullptr"); - return _console; -} - -gui::GUI* OpenSpaceEngine::gui() { - ghoul_assert(_gui != nullptr, "GUI is nullptr"); - return _gui; -} - bool OpenSpaceEngine::initializeGL() { LINFO("Initializing Rendering Engine"); bool success = _renderEngine->initializeGL(); @@ -701,11 +624,8 @@ void OpenSpaceEngine::preSynchronization() { Time::ref().preSynchronization(); _interactionHandler->update(dt); - - _scriptEngine->preSynchronization(); - + _scriptEngine->preSynchronization(); _renderEngine->preSynchronization(); - _parallelConnection->preSynchronization(); } } @@ -765,7 +685,7 @@ void OpenSpaceEngine::keyboardCallback(Key key, KeyModifier mod, KeyAction actio void OpenSpaceEngine::charCallback(unsigned int codepoint, KeyModifier modifier) { if (_isMaster) { if (_gui->isEnabled()) { - bool isConsumed = _gui->charCallback(codepoint, modifier); + const bool isConsumed = _gui->charCallback(codepoint, modifier); if (isConsumed) return; } @@ -779,7 +699,7 @@ void OpenSpaceEngine::charCallback(unsigned int codepoint, KeyModifier modifier) void OpenSpaceEngine::mouseButtonCallback(MouseButton button, MouseAction action) { if (_isMaster) { if (_gui->isEnabled()) { - bool isConsumed = _gui->mouseButtonCallback(button, action); + const bool isConsumed = _gui->mouseButtonCallback(button, action); if (isConsumed && action != MouseAction::Release) return; } @@ -797,7 +717,7 @@ void OpenSpaceEngine::mousePositionCallback(double x, double y) { void OpenSpaceEngine::mouseScrollWheelCallback(double pos) { if (_isMaster) { if (_gui->isEnabled()) { - bool isConsumed = _gui->mouseWheelCallback(pos); + const bool isConsumed = _gui->mouseWheelCallback(pos); if (isConsumed) return; } @@ -808,9 +728,9 @@ void OpenSpaceEngine::mouseScrollWheelCallback(double pos) { void OpenSpaceEngine::encode() { if (_syncBuffer) { - Time::ref().serialize(_syncBuffer); - _scriptEngine->serialize(_syncBuffer); - _renderEngine->serialize(_syncBuffer); + Time::ref().serialize(_syncBuffer.get()); + _scriptEngine->serialize(_syncBuffer.get()); + _renderEngine->serialize(_syncBuffer.get()); _syncBuffer->write(); } @@ -822,14 +742,14 @@ void OpenSpaceEngine::decode() { if (_syncBuffer) { _syncBuffer->read(); - Time::ref().deserialize(_syncBuffer); - _scriptEngine->deserialize(_syncBuffer); - _renderEngine->deserialize(_syncBuffer); + Time::ref().deserialize(_syncBuffer.get()); + _scriptEngine->deserialize(_syncBuffer.get()); + _renderEngine->deserialize(_syncBuffer.get()); } } -void OpenSpaceEngine::externalControlCallback(const char* receivedChars, - int size, int clientId) +void OpenSpaceEngine::externalControlCallback(const char* receivedChars, int size, + int clientId) { if (size == 0) return; @@ -845,31 +765,66 @@ void OpenSpaceEngine::disableBarrier() { _windowWrapper->setBarrier(false); } -NetworkEngine* OpenSpaceEngine::networkEngine() { - return _networkEngine; +NetworkEngine& OpenSpaceEngine::networkEngine() { + ghoul_assert(_networkEngine, "NetworkEngine must not be nullptr"); + return *_networkEngine; } -ModuleEngine* OpenSpaceEngine::moduleEngine() { - return _moduleEngine; +ModuleEngine& OpenSpaceEngine::moduleEngine() { + ghoul_assert(_moduleEngine, "ModuleEngine must not be nullptr"); + return *_moduleEngine; +} + +ConfigurationManager& OpenSpaceEngine::configurationManager() { + ghoul_assert(_configurationManager, "ConfigurationManager must not be nullptr"); + return *_configurationManager; +} + +interaction::InteractionHandler& OpenSpaceEngine::interactionHandler() { + ghoul_assert(_interactionHandler, "InteractionHandler must not be nullptr"); + return *_interactionHandler; +} + +RenderEngine& OpenSpaceEngine::renderEngine() { + ghoul_assert(_renderEngine, "RenderEngine must not be nullptr"); + return *_renderEngine; +} + +ScriptEngine& OpenSpaceEngine::scriptEngine() { + ghoul_assert(_scriptEngine, "ScriptEngine must not be nullptr"); + return *_scriptEngine; +} + +LuaConsole& OpenSpaceEngine::console() { + ghoul_assert(_console, "LuaConsole must not be nullptr"); + return *_console; +} + +gui::GUI& OpenSpaceEngine::gui() { + ghoul_assert(_gui, "GUI must not be nullptr"); + return *_gui; +} + +network::ParallelConnection& OpenSpaceEngine::parallelConnection() { + ghoul_assert(_parallelConnection, "ParallelConnection must not be nullptr"); + return *_parallelConnection; } -network::ParallelConnection* OpenSpaceEngine::parallelConnection() { - ghoul_assert(_parallelConnection != nullptr, "ParallelConnection is nullptr"); - return _parallelConnection; -} - -properties::PropertyOwner* OpenSpaceEngine::globalPropertyOwner() { - ghoul_assert(_globalPropertyNamespace, "Global Property Namespace"); - return _globalPropertyNamespace; +properties::PropertyOwner& OpenSpaceEngine::globalPropertyOwner() { + ghoul_assert( + _globalPropertyNamespace, + "Global Property Namespace must not be nullptr" + ); + return *_globalPropertyNamespace; } WindowWrapper& OpenSpaceEngine::windowWrapper() { - ghoul_assert(_windowWrapper, "Window Wrapper"); + ghoul_assert(_windowWrapper, "Window Wrapper must not be nullptr"); return *_windowWrapper; } ghoul::fontrendering::FontManager& OpenSpaceEngine::fontManager() { - ghoul_assert(_fontManager, "Font Manager"); + ghoul_assert(_fontManager, "Font Manager must not be nullptr"); return *_fontManager; } diff --git a/src/interaction/interactionhandler.cpp b/src/interaction/interactionhandler.cpp index 2e8a5784f9..74f09ae4a1 100644 --- a/src/interaction/interactionhandler.cpp +++ b/src/interaction/interactionhandler.cpp @@ -139,7 +139,7 @@ InteractionHandler::InteractionHandler() addProperty(_origin); _coordinateSystem.onChange([this](){ - OsEng.renderEngine()->changeViewPoint(_coordinateSystem.value()); + OsEng.renderEngine().changeViewPoint(_coordinateSystem.value()); }); addProperty(_coordinateSystem); } @@ -552,14 +552,14 @@ void InteractionHandler::keyboardCallback(Key key, KeyModifier modifier, KeyActi rotateDelta(rot); } if ((key == Key::KeypadSubtract) && (modifier == KeyModifier::NoModifier)) { - glm::vec2 s = OsEng.renderEngine()->camera()->scaling(); + glm::vec2 s = OsEng.renderEngine().camera()->scaling(); s[1] -= 0.5f; - OsEng.renderEngine()->camera()->setScaling(s); + OsEng.renderEngine().camera()->setScaling(s); } if ((key == Key::KeypadAdd) && (modifier == KeyModifier::NoModifier)) { - glm::vec2 s = OsEng.renderEngine()->camera()->scaling(); + glm::vec2 s = OsEng.renderEngine().camera()->scaling(); s[1] += 0.5f; - OsEng.renderEngine()->camera()->setScaling(s); + OsEng.renderEngine().camera()->setScaling(s); } // iterate over key bindings @@ -567,7 +567,7 @@ void InteractionHandler::keyboardCallback(Key key, KeyModifier modifier, KeyActi auto ret = _keyLua.equal_range(key); for (auto it = ret.first; it != ret.second; ++it) { //OsEng.scriptEngine()->runScript(it->second); - OsEng.scriptEngine()->queueScript(it->second); + OsEng.scriptEngine().queueScript(it->second); if (!_validKeyLua) { break; } diff --git a/src/interaction/interactionhandler_lua.inl b/src/interaction/interactionhandler_lua.inl index c735aefb61..3ec1b507df 100644 --- a/src/interaction/interactionhandler_lua.inl +++ b/src/interaction/interactionhandler_lua.inl @@ -51,7 +51,7 @@ int setOrigin(lua_State* L) { return 0; } - OsEng.interactionHandler()->setFocusNode(node); + OsEng.interactionHandler().setFocusNode(node); return 0; } @@ -84,7 +84,7 @@ int bindKey(lua_State* L) { } - OsEng.interactionHandler()->bindKey(iKey, command); + OsEng.interactionHandler().bindKey(iKey, command); return 0; } @@ -102,7 +102,7 @@ int clearKeys(lua_State* L) { if (nArguments != 0) return luaL_error(L, "Expected %i arguments, got %i", 0, nArguments); - OsEng.interactionHandler()->resetKeyBindings(); + OsEng.interactionHandler().resetKeyBindings(); return 0; } @@ -117,7 +117,7 @@ int dt(lua_State* L) { if (nArguments != 0) return luaL_error(L, "Expected %i arguments, got %i", 0, nArguments); - lua_pushnumber(L,OsEng.interactionHandler()->deltaTime()); + lua_pushnumber(L,OsEng.interactionHandler().deltaTime()); return 1; } @@ -134,7 +134,7 @@ int distance(lua_State* L) { double d1 = luaL_checknumber(L, -2); double d2 = luaL_checknumber(L, -1); PowerScaledScalar dist(static_cast(d1), static_cast(d2)); - OsEng.interactionHandler()->distanceDelta(dist); + OsEng.interactionHandler().distanceDelta(dist); return 0; } @@ -149,7 +149,7 @@ int setInteractionSensitivity(lua_State* L) { return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments); float sensitivity = static_cast(luaL_checknumber(L, -1)); - OsEng.interactionHandler()->setInteractionSensitivity(sensitivity); + OsEng.interactionHandler().setInteractionSensitivity(sensitivity); return 0; } @@ -159,7 +159,7 @@ int setInteractionSensitivity(lua_State* L) { * Returns the current, global interaction sensitivity */ int interactionSensitivity(lua_State* L) { - float sensitivity = OsEng.interactionHandler()->interactionSensitivity(); + float sensitivity = OsEng.interactionHandler().interactionSensitivity(); lua_pushnumber(L, sensitivity); return 1; } @@ -175,7 +175,7 @@ int setInvertRoll(lua_State* L) { return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments); bool invert = lua_toboolean(L, -1) == 1; - OsEng.interactionHandler()->setInvertRoll(invert); + OsEng.interactionHandler().setInvertRoll(invert); return 0; } @@ -185,7 +185,7 @@ int setInvertRoll(lua_State* L) { * Returns the current setting for inversion of roll movement */ int invertRoll(lua_State* L) { - bool invert = OsEng.interactionHandler()->invertRoll(); + bool invert = OsEng.interactionHandler().invertRoll(); lua_pushboolean(L, invert); return 1; } @@ -201,7 +201,7 @@ int setInvertRotation(lua_State* L) { return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments); bool invert = lua_toboolean(L, -1) == 1; - OsEng.interactionHandler()->setInvertRotation(invert); + OsEng.interactionHandler().setInvertRotation(invert); return 0; } @@ -211,7 +211,7 @@ int setInvertRotation(lua_State* L) { * Returns the current setting for inversion of rotation movement */ int invertRotation(lua_State* L) { - bool invert = OsEng.interactionHandler()->invertRotation(); + bool invert = OsEng.interactionHandler().invertRotation(); lua_pushboolean(L, invert); return 1; } diff --git a/src/interaction/keyboardcontroller.cpp b/src/interaction/keyboardcontroller.cpp index 10eecfa151..9328a88c95 100644 --- a/src/interaction/keyboardcontroller.cpp +++ b/src/interaction/keyboardcontroller.cpp @@ -117,14 +117,14 @@ void KeyboardControllerFixed::keyPressed(KeyAction action, Key key, KeyModifier } if (key == Key::KeypadSubtract) { - glm::vec2 s = OsEng.renderEngine()->camera()->scaling(); + glm::vec2 s = OsEng.renderEngine().camera()->scaling(); s[1] -= 0.5; - OsEng.renderEngine()->camera()->setScaling(s); + OsEng.renderEngine().camera()->setScaling(s); } if (key == Key::KeypadAdd) { - glm::vec2 s = OsEng.renderEngine()->camera()->scaling(); + glm::vec2 s = OsEng.renderEngine().camera()->scaling(); s[1] += 0.5; - OsEng.renderEngine()->camera()->setScaling(s); + OsEng.renderEngine().camera()->setScaling(s); } } /* diff --git a/src/interaction/luaconsole.cpp b/src/interaction/luaconsole.cpp index ab4eb35f14..38076ee860 100644 --- a/src/interaction/luaconsole.cpp +++ b/src/interaction/luaconsole.cpp @@ -171,7 +171,7 @@ void LuaConsole::keyboardCallback(Key key, KeyModifier modifier, KeyAction actio else { if (_commands.at(_activeCommand) != "") { //OsEng.scriptEngine()->runScript(_commands.at(_activeCommand)); - OsEng.scriptEngine()->queueScript(_commands.at(_activeCommand)); + OsEng.scriptEngine().queueScript(_commands.at(_activeCommand)); if (!_commandsHistory.empty() && _commands.at(_activeCommand) != _commandsHistory.at(_commandsHistory.size() - 1)) _commandsHistory.push_back(_commands.at(_activeCommand)); @@ -197,7 +197,7 @@ void LuaConsole::keyboardCallback(Key key, KeyModifier modifier, KeyAction actio // find the value before the one that was previously found if (_autoCompleteInfo.lastIndex != NoAutoComplete && modifierShift) _autoCompleteInfo.lastIndex -= 2; - std::vector allCommands = OsEng.scriptEngine()->allLuaFunctions(); + std::vector allCommands = OsEng.scriptEngine().allLuaFunctions(); std::sort(allCommands.begin(), allCommands.end()); std::string currentCommand = _commands.at(_activeCommand); diff --git a/src/interaction/luaconsole_lua.inl b/src/interaction/luaconsole_lua.inl index 368855d411..2507bf4089 100644 --- a/src/interaction/luaconsole_lua.inl +++ b/src/interaction/luaconsole_lua.inl @@ -36,7 +36,7 @@ int show(lua_State* L) { if (nArguments != 0) return luaL_error(L, "Expected %i arguments, got %i", 0, nArguments); - OsEng.console()->setVisible(true); + OsEng.console().setVisible(true); return 0; } @@ -50,7 +50,7 @@ int hide(lua_State* L) { if (nArguments != 0) return luaL_error(L, "Expected %i arguments, got %i", 0, nArguments); - OsEng.console()->setVisible(false); + OsEng.console().setVisible(false); return 0; } @@ -64,7 +64,7 @@ int toggle(lua_State* L) { if (nArguments != 0) return luaL_error(L, "Expected %i arguments, got %i", 0, nArguments); - OsEng.console()->toggleVisibility(); + OsEng.console().toggleVisibility(); return 0; } diff --git a/src/interaction/mousecontroller.cpp b/src/interaction/mousecontroller.cpp index d465ae0d89..274fcb9b1f 100644 --- a/src/interaction/mousecontroller.cpp +++ b/src/interaction/mousecontroller.cpp @@ -25,6 +25,7 @@ #include #include +#include #include @@ -218,9 +219,9 @@ void OrbitalMouseController::scrollWheel(int pos) { } void OrbitalMouseController::update(const double& dt){ - const float interactionSpeed = OsEng.interactionHandler()->interactionSensitivity(); - const bool rotationInvert = OsEng.interactionHandler()->invertRotation(); - const bool rollInvert = OsEng.interactionHandler()->invertRoll(); + const float interactionSpeed = OsEng.interactionHandler().interactionSensitivity(); + const bool rotationInvert = OsEng.interactionHandler().invertRotation(); + const bool rollInvert = OsEng.interactionHandler().invertRoll(); //if (_leftMouseButtonDown || _rightMouseButtonDown || _middleMouseButtonDown){ _handler->orbit( diff --git a/src/network/networkengine.cpp b/src/network/networkengine.cpp index 83265ec2be..24d089d0af 100644 --- a/src/network/networkengine.cpp +++ b/src/network/networkengine.cpp @@ -23,9 +23,9 @@ ****************************************************************************************/ #include - #include #include +#include #include #include @@ -67,7 +67,7 @@ bool NetworkEngine::handleMessage(const std::string& message) { { std::string script = message.substr(1); //LINFO("Received Lua Script: '" << script << "'"); - OsEng.scriptEngine()->queueScript(script); + OsEng.scriptEngine().queueScript(script); return true; } case MessageTypeExternalControlConnected: diff --git a/src/network/parallelconnection.cpp b/src/network/parallelconnection.cpp index 9f24d40a95..e1157cf53d 100644 --- a/src/network/parallelconnection.cpp +++ b/src/network/parallelconnection.cpp @@ -470,7 +470,7 @@ void ParallelConnection::initializationMessageReceived(){ script.assign(buffer.begin(), buffer.end()); //queue received script - OsEng.scriptEngine()->queueScript(script); + OsEng.scriptEngine().queueScript(script); } //we've gone through all scripts, initialization is done @@ -540,7 +540,7 @@ void ParallelConnection::dataMessageReceived(){ kf.deserialize(buffer); //add the keyframe to the interaction handler - OsEng.interactionHandler()->addKeyframe(kf); + OsEng.interactionHandler().addKeyframe(kf); break; } case network::datamessagestructures::TimeData:{ @@ -587,7 +587,7 @@ void ParallelConnection::dataMessageReceived(){ sm.deserialize(buffer); //Que script to be executed by script engine - OsEng.scriptEngine()->queueScript(sm._script); + OsEng.scriptEngine().queueScript(sm._script); break; } default:{ @@ -682,7 +682,7 @@ void ParallelConnection::hostInfoMessageReceived(){ } //clear buffered any keyframes - OsEng.interactionHandler()->clearKeyframes(); + OsEng.interactionHandler().clearKeyframes(); //request init package from the host int size = headerSize(); @@ -1037,8 +1037,8 @@ void ParallelConnection::broadcast(){ //create a keyframe with current position and orientation of camera network::datamessagestructures::PositionKeyframe kf; - kf._position = OsEng.interactionHandler()->camera()->position(); - kf._viewRotationQuat = glm::quat_cast(OsEng.interactionHandler()->camera()->viewRotationMatrix()); + kf._position = OsEng.interactionHandler().camera()->position(); + kf._viewRotationQuat = glm::quat_cast(OsEng.interactionHandler().camera()->viewRotationMatrix()); //timestamp as current runtime of OpenSpace instance kf._timeStamp = OsEng.runTime(); diff --git a/src/network/parallelconnection_lua.inl b/src/network/parallelconnection_lua.inl index 059129e20a..7fd5cd7afb 100644 --- a/src/network/parallelconnection_lua.inl +++ b/src/network/parallelconnection_lua.inl @@ -45,7 +45,7 @@ int setPort(lua_State* L) { int value = lua_tonumber(L, -1); std::string port = std::to_string(value); if(OsEng.isMaster()){ - OsEng.parallelConnection()->setPort(port); + OsEng.parallelConnection().setPort(port); } return 0; } @@ -71,7 +71,7 @@ int setAddress(lua_State* L) { if (type == LUA_TSTRING) { std::string address = luaL_checkstring(L, -1); if(OsEng.isMaster()){ - OsEng.parallelConnection()->setAddress(address); + OsEng.parallelConnection().setAddress(address); } return 0; } @@ -97,7 +97,7 @@ int setPassword(lua_State* L) { if (type == LUA_TSTRING) { std::string pwd = luaL_checkstring(L, -1); if(OsEng.isMaster()){ - OsEng.parallelConnection()->setPassword(pwd); + OsEng.parallelConnection().setPassword(pwd); } return 0; } @@ -123,7 +123,7 @@ int setDisplayName(lua_State* L) { if (type == LUA_TSTRING) { std::string name = luaL_checkstring(L, -1); if(OsEng.isMaster()){ - OsEng.parallelConnection()->setName(name); + OsEng.parallelConnection().setName(name); } return 0; } @@ -142,7 +142,7 @@ int connect(lua_State* L) { if (nArguments != 0) return luaL_error(L, "Expected %i arguments, got %i", 0, nArguments); if(OsEng.isMaster()){ - OsEng.parallelConnection()->clientConnect(); + OsEng.parallelConnection().clientConnect(); } return 0; } @@ -153,7 +153,7 @@ int disconnect(lua_State* L) { if (nArguments != 0) return luaL_error(L, "Expected %i arguments, got %i", 0, nArguments); if(OsEng.isMaster()){ - OsEng.parallelConnection()->signalDisconnect(); + OsEng.parallelConnection().signalDisconnect(); } return 0; } @@ -171,7 +171,7 @@ int requestHostship(lua_State* L) { if (type == LUA_TSTRING) { std::string pwd = luaL_checkstring(L, -1); if(OsEng.isMaster()){ - OsEng.parallelConnection()->requestHostship(pwd); + OsEng.parallelConnection().requestHostship(pwd); } return 0; } diff --git a/src/query/query.cpp b/src/query/query.cpp index f0fa4a087e..7b0a20db4c 100644 --- a/src/query/query.cpp +++ b/src/query/query.cpp @@ -38,7 +38,7 @@ namespace { } Scene* sceneGraph() { - return OsEng.renderEngine()->scene(); + return OsEng.renderEngine().scene(); } SceneGraphNode* sceneGraphNode(const std::string& name) { @@ -52,7 +52,7 @@ Renderable* renderable(const std::string& name) { } properties::Property* property(const std::string& uri) { - properties::Property* globalProp = OsEng.globalPropertyOwner()->property(uri); + properties::Property* globalProp = OsEng.globalPropertyOwner().property(uri); if (globalProp) { return globalProp; } diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index a7161f578f..a1317bd135 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -53,6 +53,7 @@ #include #include #include +#include #include #ifdef GHOUL_USE_DEVIL @@ -136,8 +137,8 @@ bool RenderEngine::initialize() { std::string renderingMethod = DefaultRenderingMethod; // If the user specified a rendering method that he would like to use, use that - if (OsEng.configurationManager()->hasKeyAndValue(KeyRenderingMethod)) - renderingMethod = OsEng.configurationManager()->value(KeyRenderingMethod); + if (OsEng.configurationManager().hasKeyAndValue(KeyRenderingMethod)) + renderingMethod = OsEng.configurationManager().value(KeyRenderingMethod); else { using Version = ghoul::systemcapabilities::OpenGLCapabilitiesComponent::Version; @@ -179,7 +180,7 @@ bool RenderEngine::initialize() { _mainCamera = new Camera(); _mainCamera->setScaling(glm::vec2(1.0, -8.0)); _mainCamera->setPosition(psc(0.f, 0.f, 1.499823f, 11.f)); - OsEng.interactionHandler()->setCamera(_mainCamera); + OsEng.interactionHandler().setCamera(_mainCamera); #ifdef GHOUL_USE_DEVIL ghoul::io::TextureReader::ref().addReader(std::make_shared()); diff --git a/src/rendering/renderengine_lua.inl b/src/rendering/renderengine_lua.inl index 7d0ea22a00..d166317f5a 100644 --- a/src/rendering/renderengine_lua.inl +++ b/src/rendering/renderengine_lua.inl @@ -47,7 +47,7 @@ int takeScreenshot(lua_State* L) { int nArguments = lua_gettop(L); if (nArguments != 0) return luaL_error(L, "Expected %i arguments, got %i", 0, nArguments); - OsEng.renderEngine()->takeScreenshot(); + OsEng.renderEngine().takeScreenshot(); return 0; } @@ -65,7 +65,7 @@ int visualizeABuffer(lua_State* L) { if (type != LUA_TBOOLEAN) return luaL_error(L, "Expected argument of type 'bool'"); bool b = lua_toboolean(L, -1) != 0; - OsEng.renderEngine()->toggleVisualizeABuffer(b); + OsEng.renderEngine().toggleVisualizeABuffer(b); return 0; } @@ -83,7 +83,7 @@ int showRenderInformation(lua_State* L) { if (type != LUA_TBOOLEAN) return luaL_error(L, "Expected argument of type 'bool'"); bool b = lua_toboolean(L, -1) != 0; - OsEng.renderEngine()->toggleInfoText(b); + OsEng.renderEngine().toggleInfoText(b); return 0; } @@ -98,7 +98,7 @@ int setPerformanceMeasurement(lua_State* L) { return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments); bool b = lua_toboolean(L, -1) != 0; - OsEng.renderEngine()->setPerformanceMeasurements(b); + OsEng.renderEngine().setPerformanceMeasurements(b); return 0; } @@ -114,7 +114,7 @@ int fadeIn(lua_State* L) { double t = luaL_checknumber(L, -1); - OsEng.renderEngine()->startFading(1, static_cast(t)); + OsEng.renderEngine().startFading(1, static_cast(t)); return 0; } /** @@ -129,7 +129,7 @@ int fadeOut(lua_State* L) { double t = luaL_checknumber(L, -1); - OsEng.renderEngine()->startFading(-1, static_cast(t)); + OsEng.renderEngine().startFading(-1, static_cast(t)); return 0; } diff --git a/src/scene/scene.cpp b/src/scene/scene.cpp index ae850d3465..996cdb6af0 100644 --- a/src/scene/scene.cpp +++ b/src/scene/scene.cpp @@ -96,7 +96,7 @@ bool Scene::initialize() { "${SHADERS}/fboPass_fs.glsl"); if (!prg) return false; prg->setProgramObjectCallback(cb); - OsEng.ref().configurationManager()->setValue("fboPassProgram", prg.get()); + OsEng.ref().configurationManager().setValue("fboPassProgram", prg.get()); _programs.push_back(std::move(prg)); // pscstandard @@ -105,7 +105,7 @@ bool Scene::initialize() { "${SHADERS}/pscstandard_fs.glsl"); if (! prg) return false; prg->setProgramObjectCallback(cb); - OsEng.ref().configurationManager()->setValue("pscShader", prg.get()); + OsEng.ref().configurationManager().setValue("pscShader", prg.get()); _programs.push_back(std::move(prg)); // Night texture program @@ -114,7 +114,7 @@ bool Scene::initialize() { "${SHADERS}/nighttexture_fs.glsl"); if (!prg) return false; prg->setProgramObjectCallback(cb); - OsEng.ref().configurationManager()->setValue("nightTextureProgram", prg.get()); + OsEng.ref().configurationManager().setValue("nightTextureProgram", prg.get()); _programs.push_back(std::move(prg)); // RaycastProgram @@ -123,7 +123,7 @@ bool Scene::initialize() { "${SHADERS}/exitpoints.frag"); if (!prg) return false; prg->setProgramObjectCallback(cb); - OsEng.ref().configurationManager()->setValue("RaycastProgram", prg.get()); + OsEng.ref().configurationManager().setValue("RaycastProgram", prg.get()); _programs.push_back(std::move(prg)); return true; @@ -140,12 +140,12 @@ bool Scene::deinitialize() { void Scene::update(const UpdateData& data) { if (!_sceneGraphToLoad.empty()) { - OsEng.renderEngine()->scene()->clearSceneGraph(); + OsEng.renderEngine().scene()->clearSceneGraph(); bool success = loadSceneInternal(_sceneGraphToLoad); _sceneGraphToLoad = ""; if (!success) return; - OsEng.renderEngine()->aBuffer()->invalidateABuffer(); + OsEng.renderEngine().aBuffer()->invalidateABuffer(); } for (SceneGraphNode* node : _graph.nodes()) node->update(data); @@ -257,7 +257,7 @@ bool Scene::loadSceneInternal(const std::string& sceneDescriptionFilePath) { //_root->calculateBoundingSphere(); // set the camera position - Camera* c = OsEng.ref().renderEngine()->camera(); + Camera* c = OsEng.ref().renderEngine().camera(); //auto focusIterator = _allNodes.find(_focus); auto focusIterator = std::find_if( _graph.nodes().begin(), @@ -304,10 +304,10 @@ bool Scene::loadSceneInternal(const std::string& sceneDescriptionFilePath) { // c->setScaling(scaling); // Set the focus node for the interactionhandler - OsEng.interactionHandler()->setFocusNode(focusNode); + OsEng.interactionHandler().setFocusNode(focusNode); } else - OsEng.interactionHandler()->setFocusNode(_graph.rootNode()); + OsEng.interactionHandler().setFocusNode(_graph.rootNode()); glm::vec4 position; if (cameraDictionary.hasKey(KeyPositionObject) @@ -324,7 +324,7 @@ bool Scene::loadSceneInternal(const std::string& sceneDescriptionFilePath) { } // the camera position - const SceneGraphNode* fn = OsEng.interactionHandler()->focusNode(); + const SceneGraphNode* fn = OsEng.interactionHandler().focusNode(); // Check crash for when fn == nullptr glm::mat4 la = glm::lookAt(cameraPosition.vec3(), fn->worldPosition().vec3(), c->lookUpVector()); @@ -344,18 +344,18 @@ bool Scene::loadSceneInternal(const std::string& sceneDescriptionFilePath) { for (SceneGraphNode* node : _graph.nodes()) { std::vector properties = node->propertiesRecursive(); for (properties::Property* p : properties) { - OsEng.gui()->_property.registerProperty(p); + OsEng.gui()._property.registerProperty(p); } } // If a LuaDocumentationFile was specified, generate it now - const bool hasType = OsEng.configurationManager()->hasKey(ConfigurationManager::KeyPropertyDocumentationType); - const bool hasFile = OsEng.configurationManager()->hasKey(ConfigurationManager::KeyPropertyDocumentationFile); + const bool hasType = OsEng.configurationManager().hasKey(ConfigurationManager::KeyPropertyDocumentationType); + const bool hasFile = OsEng.configurationManager().hasKey(ConfigurationManager::KeyPropertyDocumentationFile); if (hasType && hasFile) { std::string propertyDocumentationType; - OsEng.configurationManager()->getValue(ConfigurationManager::KeyPropertyDocumentationType, propertyDocumentationType); + OsEng.configurationManager().getValue(ConfigurationManager::KeyPropertyDocumentationType, propertyDocumentationType); std::string propertyDocumentationFile; - OsEng.configurationManager()->getValue(ConfigurationManager::KeyPropertyDocumentationFile, propertyDocumentationFile); + OsEng.configurationManager().getValue(ConfigurationManager::KeyPropertyDocumentationFile, propertyDocumentationFile); propertyDocumentationFile = absPath(propertyDocumentationFile); writePropertyDocumentation(propertyDocumentationFile, propertyDocumentationType); diff --git a/src/scene/scene_lua.inl b/src/scene/scene_lua.inl index 79fbe882bf..269994832a 100644 --- a/src/scene/scene_lua.inl +++ b/src/scene/scene_lua.inl @@ -62,7 +62,7 @@ int property_setValue(lua_State* L) { //ensure properties are synced over parallel connection std::string value; prop->getStringValue(value); - OsEng.parallelConnection()->scriptMessage(prop->fullyQualifiedIdentifier(), value); + OsEng.parallelConnection().scriptMessage(prop->fullyQualifiedIdentifier(), value); } return 0; @@ -107,7 +107,7 @@ int loadScene(lua_State* L) { std::string sceneFile = luaL_checkstring(L, -1); - OsEng.renderEngine()->scene()->scheduleLoadSceneFile(sceneFile); + OsEng.renderEngine().scene()->scheduleLoadSceneFile(sceneFile); return 0; } diff --git a/src/scene/scenegraph.cpp b/src/scene/scenegraph.cpp index 6f00479de4..0934f01af4 100644 --- a/src/scene/scenegraph.cpp +++ b/src/scene/scenegraph.cpp @@ -125,7 +125,7 @@ bool SceneGraph::loadFromFile(const std::string& sceneDescription) { return true; lua_State* state = ghoul::lua::createNewLuaState(); - OsEng.scriptEngine()->initializeLuaState(state); + OsEng.scriptEngine().initializeLuaState(state); // Get the common directory bool commonFolderSpecified = sceneDictionary.hasKey(KeyCommonFolder); @@ -343,7 +343,7 @@ bool SceneGraph::sortTopologically() { } - RenderEngine::ABufferImplementation i = OsEng.renderEngine()->aBufferImplementation(); + RenderEngine::ABufferImplementation i = OsEng.renderEngine().aBufferImplementation(); if (i == RenderEngine::ABufferImplementation::FrameBuffer) { auto it = std::find_if( _topologicalSortedNodes.begin(), diff --git a/src/scripting/scriptengine.cpp b/src/scripting/scriptengine.cpp index 097697c54a..48413a9b41 100644 --- a/src/scripting/scriptengine.cpp +++ b/src/scripting/scriptengine.cpp @@ -156,7 +156,7 @@ bool ScriptEngine::runScript(const std::string& script) { } //if we're currently hosting the parallel session, find out if script should be synchronized. - if (OsEng.parallelConnection()->isHost()){ + if (OsEng.parallelConnection().isHost()){ std::string lib, func; if (parseLibraryAndFunctionNames(lib, func, script) && shouldScriptBeSent(lib, func)){ diff --git a/src/util/screenlog.cpp b/src/util/screenlog.cpp index fdffd770f0..106ad9e859 100644 --- a/src/util/screenlog.cpp +++ b/src/util/screenlog.cpp @@ -25,6 +25,7 @@ #include #include +#include #include From 2fce4717438e6c7277668a5e89d0c49a3222bb5d Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 14 Dec 2015 10:50:38 -0800 Subject: [PATCH 064/122] Started cleanup of module structure --- apps/OpenSpace/main.cpp | 55 +++---- ext/ghoul | 2 +- .../openspace/engine/configurationmanager.h | 15 +- include/openspace/engine/downloadmanager.h | 36 +++-- include/openspace/engine/logfactory.h | 6 +- include/openspace/engine/moduleengine.h | 23 +-- include/openspace/engine/openspaceengine.h | 17 +-- include/openspace/util/openspacemodule.h | 14 +- modules/base/basemodule.cpp | 8 +- modules/base/basemodule.h | 4 +- modules/fieldlines/fieldlinesmodule.cpp | 8 +- modules/fieldlines/fieldlinesmodule.h | 4 +- modules/kameleon/kameleonmodule.cpp | 8 -- modules/kameleon/kameleonmodule.h | 1 - modules/newhorizons/newhorizonsmodule.cpp | 8 +- modules/newhorizons/newhorizonsmodule.h | 4 +- modules/onscreengui/onscreenguimodule.cpp | 7 - modules/onscreengui/onscreenguimodule.h | 1 - modules/volume/volumemodule.cpp | 8 +- modules/volume/volumemodule.h | 4 +- src/engine/configurationmanager.cpp | 135 +++++++++++------- src/engine/downloadmanager.cpp | 114 +++++++-------- src/engine/moduleengine.cpp | 49 +++---- src/engine/openspaceengine.cpp | 52 ++----- src/util/openspacemodule.cpp | 17 ++- 25 files changed, 298 insertions(+), 302 deletions(-) diff --git a/apps/OpenSpace/main.cpp b/apps/OpenSpace/main.cpp index e5a268c0cc..770d60edfc 100644 --- a/apps/OpenSpace/main.cpp +++ b/apps/OpenSpace/main.cpp @@ -26,14 +26,14 @@ #include #include #include -#include -#include +#include +#include #include + #include sgct::Engine* _sgctEngine; -// function pointer declarations void mainInitFunc(); void mainPreSyncFunc(); void mainPostSyncPreDrawFunc(); @@ -49,12 +49,13 @@ void mainDecodeFun(); void mainExternalControlCallback(const char * receivedChars, int size); void mainLogCallback(const char* msg); -std::pair supportedOpenGLVersion () { +std::pair supportedOpenGLVersion() { glfwInit(); - //On OS X we need to explicitly set the version and specify that we are using CORE profile - //to be able to use glGetIntegerv(GL_MAJOR_VERSION, &major) and glGetIntegerv(GL_MINOR_VERSION, &minor) - //explicitly setting to OGL 3.3 CORE works since all Mac's now support at least 3.3 + // On OS X we need to explicitly set the version and specify that we are using CORE + // profile to be able to use glGetIntegerv(GL_MAJOR_VERSION, &major) and + // glGetIntegerv(GL_MINOR_VERSION, &minor) explicitly setting to OGL 3.3 CORE works + // since all Mac's now support at least 3.3 #ifdef __APPLE__ glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); @@ -75,8 +76,6 @@ std::pair supportedOpenGLVersion () { return { major, minor }; } -#include - namespace { const std::string _loggerCat = "main"; } @@ -88,7 +87,7 @@ int main(int argc, char** argv) { std::vector sgctArguments; const bool success = openspace::OpenSpaceEngine::create( argc, argv, - new openspace::SGCTWindowWrapper, + std::make_unique(), sgctArguments ); if (!success) @@ -147,10 +146,10 @@ int main(int argc, char** argv) { { { 4, 4 }, sgct::Engine::RunMode::OpenGL_4_4_Core_Profile }, { { 4, 5 }, sgct::Engine::RunMode::OpenGL_4_5_Core_Profile } }; - if (versionMapping.find(glVersion) == versionMapping.end()) { - LFATAL("Requested OpenGL version " << glVersion.first << "." << glVersion.second << " not supported"); - return EXIT_FAILURE; - } + ghoul_assert( + versionMapping.find(glVersion) != versionMapping.end(), + "Unknown OpenGL version. Missing statement in version mapping map" + ); sgct::Engine::RunMode rm = versionMapping[glVersion]; const bool initSuccess = _sgctEngine->init(rm); @@ -173,7 +172,7 @@ int main(int argc, char** argv) { LDEBUG("Destroying OpenSpaceEngine"); openspace::OpenSpaceEngine::destroy(); - // Clean up (de-allocate) + // Clean up (deallocate) LDEBUG("Destroying SGCT Engine"); delete _sgctEngine; @@ -191,8 +190,6 @@ void mainInitFunc() { if (!success) { LFATAL("Initializing OpenSpaceEngine failed"); - std::cout << "Press any key to continue..."; - std::cin.ignore(100); exit(EXIT_FAILURE); } @@ -248,16 +245,22 @@ void mainExternalControlCallback(const char* receivedChars, int size) { } void mainKeyboardCallback(int key, int, int action, int mods) { - if (OsEng.isMaster()) - OsEng.keyboardCallback(openspace::Key(key), - openspace::KeyModifier(mods), - openspace::KeyAction(action)); + if (OsEng.isMaster()) { + OsEng.keyboardCallback( + openspace::Key(key), + openspace::KeyModifier(mods), + openspace::KeyAction(action) + ); + } } void mainMouseButtonCallback(int key, int action) { - if (OsEng.isMaster()) - OsEng.mouseButtonCallback(openspace::MouseButton(key), - openspace::MouseAction(action)); + if (OsEng.isMaster()) { + OsEng.mouseButtonCallback( + openspace::MouseButton(key), + openspace::MouseAction(action) + ); + } } void mainMousePosCallback(double x, double y) { @@ -283,9 +286,9 @@ void mainDecodeFun() { OsEng.decode(); } -void mainLogCallback(const char* msg){ +void mainLogCallback(const char* msg) { std::string message = msg; - if (message == ".") + if (message.empty() || message == ".") // We don't want the empty '.' message that SGCT sends while it is waiting for // connections from other network nodes return; diff --git a/ext/ghoul b/ext/ghoul index 212f1efd5d..ff01cac350 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 212f1efd5d9ecd1e84937a01ee9f04a0e10b8a58 +Subproject commit ff01cac35077a6fe298f8b691466ee9cb704200b diff --git a/include/openspace/engine/configurationmanager.h b/include/openspace/engine/configurationmanager.h index c87c9183ab..46ce99a67f 100644 --- a/include/openspace/engine/configurationmanager.h +++ b/include/openspace/engine/configurationmanager.h @@ -29,11 +29,20 @@ namespace openspace { +/** + * The ConfigurationManager takes care of loading the major configuration file + * openspace.cfg and making it available to the rest of the application. The + * exposed keys in the ghoul::Dictionary are declared in this class as static constants. + * The findConfiguration method walks the filesystem from a provided starting point until + * it found the requested file or throws a ghoul::RuntimeError if it could not find the + * file. The loadFromFile method then loads the file into a ghoul::Dictionary format. + */ class ConfigurationManager : public ghoul::Dictionary { public: + /// The key that stores the subdirectory containing all predefined path tokens static const std::string KeyPaths; + /// static const std::string KeyCache; - static const std::string KeyCachePath; static const std::string KeyFonts; static const std::string KeyConfigSgct; static const std::string KeyLuaDocumentationType; @@ -53,7 +62,9 @@ public: static const std::string KeyDisableMasterRendering; static const std::string KeyDownloadRequestURL; - bool loadFromFile(const std::string& filename); + static std::string findConfiguration(const std::string& filename); + + void loadFromFile(const std::string& filename); private: bool checkCompleteness() const; diff --git a/include/openspace/engine/downloadmanager.h b/include/openspace/engine/downloadmanager.h index 1cb8a9d751..5825f3c8b9 100644 --- a/include/openspace/engine/downloadmanager.h +++ b/include/openspace/engine/downloadmanager.h @@ -26,12 +26,14 @@ #define __DOWNLOADMANAGER_H__ #include + #include #include -#include #include +#include #include +#include namespace openspace { @@ -58,42 +60,38 @@ public: bool abortDownload; }; - typedef std::function DownloadProgressCallback; - typedef std::function DownloadFinishedCallback; - typedef std::function&)> AsyncDownloadFinishedCallback; + using DownloadProgressCallback = std::function; + using DownloadFinishedCallback = std::function; + using AsyncDownloadFinishedCallback = + std::function&)>; - DownloadManager(std::string requestURL, int applicationVersion); + DownloadManager(std::string requestURL, int applicationVersion, + bool useMultithreadedDownload = true); // callers responsibility to delete // callbacks happen on a different thread - FileFuture* downloadFile( - const std::string& url, - const ghoul::filesystem::File& file, + FileFuture* downloadFile(const std::string& url, const ghoul::filesystem::File& file, bool overrideFile = true, DownloadFinishedCallback finishedCallback = DownloadFinishedCallback(), DownloadProgressCallback progressCallback = DownloadProgressCallback() ); - std::vector downloadRequestFiles( - const std::string& identifier, - const ghoul::filesystem::Directory& destination, - int version, + std::vector downloadRequestFiles(const std::string& identifier, + const ghoul::filesystem::Directory& destination, int version, bool overrideFiles = true, DownloadFinishedCallback finishedCallback = DownloadFinishedCallback(), DownloadProgressCallback progressCallback = DownloadProgressCallback() ); - void downloadRequestFilesAsync( - const std::string& identifier, - const ghoul::filesystem::Directory& destination, - int version, - bool overrideFiles, - AsyncDownloadFinishedCallback callback + void downloadRequestFilesAsync(const std::string& identifier, + const ghoul::filesystem::Directory& destination, int version, + bool overrideFiles, AsyncDownloadFinishedCallback callback ); private: - std::string _requestURL; + std::vector _requestURL; int _applicationVersion; + bool _useMultithreadedDownload; }; #define DlManager (openspace::DownloadManager::ref()) diff --git a/include/openspace/engine/logfactory.h b/include/openspace/engine/logfactory.h index 2af0fde8df..3df5af6d45 100644 --- a/include/openspace/engine/logfactory.h +++ b/include/openspace/engine/logfactory.h @@ -28,10 +28,8 @@ #include namespace ghoul { - class Dictionary; - namespace logging { - class Log; - } +class Dictionary; +namespace logging { class Log; } } namespace openspace { diff --git a/include/openspace/engine/moduleengine.h b/include/openspace/engine/moduleengine.h index 2ad6954846..1fefc57ef6 100644 --- a/include/openspace/engine/moduleengine.h +++ b/include/openspace/engine/moduleengine.h @@ -25,26 +25,33 @@ #ifndef __MODULEENGINE_H__ #define __MODULEENGINE_H__ +#include + +#include #include namespace openspace { -class OpenSpaceModule; - +/** + * The ModuleEngine is the central repository for registering and accessing + * OpenSpaceModule for the current application run. By create%ing the ModuleEngine, the + * default set of OpenSpaceModule%s as generated by CMake in the + * moduleregistration.h file is automatically registered and created. + */ class ModuleEngine { public: - bool create(); - bool destroy(); + void create(); + void destroy(); bool initialize(); bool deinitialize(); - void registerModules(std::vector modules); - void registerModule(OpenSpaceModule* module); - const std::vector modules() const; + void registerModules(std::vector> modules); + void registerModule(std::unique_ptr module); + std::vector modules() const; protected: - std::vector _modules; + std::vector> _modules; }; diff --git a/include/openspace/engine/openspaceengine.h b/include/openspace/engine/openspaceengine.h index 7879b20cd9..ac044533b5 100644 --- a/include/openspace/engine/openspaceengine.h +++ b/include/openspace/engine/openspaceengine.h @@ -59,17 +59,17 @@ namespace properties { class PropertyOwner; } class OpenSpaceEngine { public: - static bool create(int argc, char** argv, std::unique_ptr windowWrapper, std::vector& sgctArguments); + static bool create(int argc, char** argv, + std::unique_ptr windowWrapper, + std::vector& sgctArguments); static void destroy(); + static bool isInitialized(); static OpenSpaceEngine& ref(); - static bool isInitialized(); - bool initialize(); bool isMaster(); void setMaster(bool master); double runTime(); void setRunTime(double t); - static bool findConfiguration(std::string& filename); // Guaranteed to return a valid pointer ConfigurationManager& configurationManager(); @@ -86,6 +86,7 @@ public: gui::GUI& gui(); // SGCT callbacks + bool initialize(); bool initializeGL(); void preSynchronization(); void postSynchronizationPreDraw(); @@ -116,8 +117,8 @@ private: void runScripts(const ghoul::Dictionary& scripts); void runStartupScripts(); void configureLogging(); - - + + // Components std::unique_ptr _configurationManager; std::unique_ptr _interactionHandler; std::unique_ptr _renderEngine; @@ -131,13 +132,13 @@ private: std::unique_ptr _windowWrapper; std::unique_ptr _fontManager; + // Others std::unique_ptr _globalPropertyNamespace; + std::unique_ptr _syncBuffer; bool _isMaster; double _runTime; - std::unique_ptr _syncBuffer; - static OpenSpaceEngine* _engine; }; diff --git a/include/openspace/util/openspacemodule.h b/include/openspace/util/openspacemodule.h index 3a4ade1eaa..5677e46b65 100644 --- a/include/openspace/util/openspacemodule.h +++ b/include/openspace/util/openspacemodule.h @@ -34,15 +34,21 @@ public: OpenSpaceModule(std::string name); virtual ~OpenSpaceModule() = default; - virtual bool create(); - virtual bool destroy(); + void create(); + void destroy(); - virtual bool initialize(); - virtual bool deinitialize(); + bool initialize(); + bool deinitialize(); std::string name() const; protected: + virtual void internalCreate(); + virtual void internalDestroy(); + + virtual void internalInitialize(); + virtual void internalDeinitialize(); + std::string modulePath() const; const std::string _name; diff --git a/modules/base/basemodule.cpp b/modules/base/basemodule.cpp index 8280208f98..e6b2ddcd2a 100644 --- a/modules/base/basemodule.cpp +++ b/modules/base/basemodule.cpp @@ -55,11 +55,7 @@ BaseModule::BaseModule() : OpenSpaceModule("Base") {} -bool BaseModule::create() { - bool success = OpenSpaceModule::create(); - if (!success) - return false; - +void BaseModule::internalCreate() { FactoryManager::ref().addFactory(new ghoul::TemplateFactory); FactoryManager::ref().addFactory(new ghoul::TemplateFactory); @@ -89,8 +85,6 @@ bool BaseModule::create() { auto fModelGeometry = FactoryManager::ref().factory(); ghoul_assert(fModelGeometry, "Model geometry factory was not created"); fModelGeometry->registerClass("WavefrontGeometry"); - - return true; } } // namespace openspace diff --git a/modules/base/basemodule.h b/modules/base/basemodule.h index 597e6cf2af..1feaf32c99 100644 --- a/modules/base/basemodule.h +++ b/modules/base/basemodule.h @@ -32,7 +32,9 @@ namespace openspace { class BaseModule : public OpenSpaceModule { public: BaseModule(); - bool create() override; + +protected: + void internalCreate() override; }; } // namespace openspace diff --git a/modules/fieldlines/fieldlinesmodule.cpp b/modules/fieldlines/fieldlinesmodule.cpp index 4fcba99081..b0be3c52a3 100644 --- a/modules/fieldlines/fieldlinesmodule.cpp +++ b/modules/fieldlines/fieldlinesmodule.cpp @@ -37,17 +37,11 @@ FieldlinesModule::FieldlinesModule() : OpenSpaceModule("Fieldlines") {} -bool FieldlinesModule::create() { - bool success = OpenSpaceModule::create(); - if (!success) - return false; - +void FieldlinesModule::internalCreate() { auto fRenderable = FactoryManager::ref().factory(); ghoul_assert(fRenderable, "No renderable factory existed"); fRenderable->registerClass("RenderableFieldlines"); - - return true; } } // namespace openspace diff --git a/modules/fieldlines/fieldlinesmodule.h b/modules/fieldlines/fieldlinesmodule.h index 8edc1d6705..50deb9984d 100644 --- a/modules/fieldlines/fieldlinesmodule.h +++ b/modules/fieldlines/fieldlinesmodule.h @@ -32,7 +32,9 @@ namespace openspace { class FieldlinesModule : public OpenSpaceModule { public: FieldlinesModule(); - bool create() override; + +protected: + void internalCreate() override; }; } // namespace openspace diff --git a/modules/kameleon/kameleonmodule.cpp b/modules/kameleon/kameleonmodule.cpp index 1000b27184..244d86e513 100644 --- a/modules/kameleon/kameleonmodule.cpp +++ b/modules/kameleon/kameleonmodule.cpp @@ -30,12 +30,4 @@ KameleonModule::KameleonModule() : OpenSpaceModule("Kameleon") {} -bool KameleonModule::create() { - bool success = OpenSpaceModule::create(); - if (!success) - return false; - - return true; -} - } // namespace openspace diff --git a/modules/kameleon/kameleonmodule.h b/modules/kameleon/kameleonmodule.h index b99b5d3f77..979aba5dd9 100644 --- a/modules/kameleon/kameleonmodule.h +++ b/modules/kameleon/kameleonmodule.h @@ -32,7 +32,6 @@ namespace openspace { class KameleonModule : public OpenSpaceModule { public: KameleonModule(); - bool create() override; }; } // namespace openspace diff --git a/modules/newhorizons/newhorizonsmodule.cpp b/modules/newhorizons/newhorizonsmodule.cpp index 9d5b3967a4..f5b30cc86e 100644 --- a/modules/newhorizons/newhorizonsmodule.cpp +++ b/modules/newhorizons/newhorizonsmodule.cpp @@ -50,11 +50,7 @@ NewHorizonsModule::NewHorizonsModule() : OpenSpaceModule("NewHorizons") {} -bool NewHorizonsModule::create() { - bool success = OpenSpaceModule::create(); - if (!success) - return false; - +void NewHorizonsModule::internalCreate() { ImageSequencer2::initialize(); FactoryManager::ref().addFactory(new ghoul::TemplateFactory); @@ -76,8 +72,6 @@ bool NewHorizonsModule::create() { auto fDecoder = FactoryManager::ref().factory(); fDecoder->registerClass("Instrument"); fDecoder->registerClass("Target"); - - return true; } } // namespace openspace diff --git a/modules/newhorizons/newhorizonsmodule.h b/modules/newhorizons/newhorizonsmodule.h index 6ca4b49cda..f721f743b1 100644 --- a/modules/newhorizons/newhorizonsmodule.h +++ b/modules/newhorizons/newhorizonsmodule.h @@ -32,7 +32,9 @@ namespace openspace { class NewHorizonsModule : public OpenSpaceModule { public: NewHorizonsModule(); - bool create() override; + +protected: + void internalCreate() override; }; } // namespace openspace diff --git a/modules/onscreengui/onscreenguimodule.cpp b/modules/onscreengui/onscreenguimodule.cpp index 8518eef832..f34467f2bc 100644 --- a/modules/onscreengui/onscreenguimodule.cpp +++ b/modules/onscreengui/onscreenguimodule.cpp @@ -30,11 +30,4 @@ OnScreenGUIModule::OnScreenGUIModule() : OpenSpaceModule("OnScreenGUI") {} -bool OnScreenGUIModule::create() { - bool success = OpenSpaceModule::create(); - if (!success) - return false; - return true; -} - } // namespace openspace diff --git a/modules/onscreengui/onscreenguimodule.h b/modules/onscreengui/onscreenguimodule.h index affd7bb9d5..7ea96650b2 100644 --- a/modules/onscreengui/onscreenguimodule.h +++ b/modules/onscreengui/onscreenguimodule.h @@ -32,7 +32,6 @@ namespace openspace { class OnScreenGUIModule : public OpenSpaceModule { public: OnScreenGUIModule(); - bool create() override; }; } // namespace openspace diff --git a/modules/volume/volumemodule.cpp b/modules/volume/volumemodule.cpp index 274e408f6f..f2ff8b6b43 100644 --- a/modules/volume/volumemodule.cpp +++ b/modules/volume/volumemodule.cpp @@ -37,17 +37,11 @@ VolumeModule::VolumeModule() : OpenSpaceModule("Volume") {} -bool VolumeModule::create() { - bool success = OpenSpaceModule::create(); - if (!success) - return false; - +void VolumeModule::internalCreate() { auto fRenderable = FactoryManager::ref().factory(); ghoul_assert(fRenderable, "No renderable factory existed"); fRenderable->registerClass("RenderableVolumeGL"); - - return true; } } // namespace openspace diff --git a/modules/volume/volumemodule.h b/modules/volume/volumemodule.h index 1e57079063..415056c1e5 100644 --- a/modules/volume/volumemodule.h +++ b/modules/volume/volumemodule.h @@ -32,7 +32,9 @@ namespace openspace { class VolumeModule : public OpenSpaceModule { public: VolumeModule(); - bool create() override; + +protected: + void internalCreate() override; }; } // namespace openspace diff --git a/src/engine/configurationmanager.cpp b/src/engine/configurationmanager.cpp index b6fb131298..fe8c24987c 100644 --- a/src/engine/configurationmanager.cpp +++ b/src/engine/configurationmanager.cpp @@ -27,86 +27,109 @@ #include #include +#include #include #include -namespace { - const std::string _loggerCat = "ConfigurationManager"; +using std::string; - const std::string _keyBasePath = "BASE_PATH"; +namespace { + const string _configurationFile = "openspace.cfg"; + const string _keyBasePath = "BASE_PATH"; } namespace openspace { -const std::string ConfigurationManager::KeyPaths = "Paths"; -const std::string ConfigurationManager::KeyCache = "CACHE"; -const std::string ConfigurationManager::KeyCachePath = KeyPaths + "." + KeyCache; -const std::string ConfigurationManager::KeyFonts = "Fonts"; -const std::string ConfigurationManager::KeyConfigSgct = "SGCTConfig"; -const std::string ConfigurationManager::KeyLuaDocumentationType = "LuaDocumentationFile.Type"; -const std::string ConfigurationManager::KeyLuaDocumentationFile = "LuaDocumentationFile.File"; -const std::string ConfigurationManager::KeyPropertyDocumentationType = "PropertyDocumentationFile.Type"; -const std::string ConfigurationManager::KeyPropertyDocumentationFile = "PropertyDocumentationFile.File"; -const std::string ConfigurationManager::KeyConfigScene = "Scene"; -const std::string ConfigurationManager::KeyEnableGui = "EnableGUI"; -const std::string ConfigurationManager::KeyStartupScript = "StartupScripts"; -const std::string ConfigurationManager::KeySettingsScript = "SettingsScripts"; -const std::string ConfigurationManager::KeySpiceTimeKernel = "SpiceKernel.Time"; -const std::string ConfigurationManager::KeySpiceLeapsecondKernel = "SpiceKernel.LeapSecond"; -const std::string ConfigurationManager::KeyLogLevel = "Logging.LogLevel"; -const std::string ConfigurationManager::KeyLogImmediateFlush = "Logging.ImmediateFlush"; -const std::string ConfigurationManager::KeyLogs = "Logging.Logs"; -const std::string ConfigurationManager::KeyCapabilitiesVerbosity = "Logging.CapabilitiesVerbosity"; -const std::string ConfigurationManager::KeyDisableMasterRendering = "DisableRenderingOnMaster"; -const std::string ConfigurationManager::KeyDownloadRequestURL = "DownloadRequestURL"; +const string ConfigurationManager::KeyPaths = "Paths"; +const string ConfigurationManager::KeyCache = "CACHE"; +const string ConfigurationManager::KeyFonts = "Fonts"; +const string ConfigurationManager::KeyConfigSgct = "SGCTConfig"; +const string ConfigurationManager::KeyLuaDocumentationType = "LuaDocumentationFile.Type"; +const string ConfigurationManager::KeyLuaDocumentationFile = "LuaDocumentationFile.File"; +const string ConfigurationManager::KeyPropertyDocumentationType = + "PropertyDocumentationFile.Type"; +const string ConfigurationManager::KeyPropertyDocumentationFile = + "PropertyDocumentationFile.File"; +const string ConfigurationManager::KeyConfigScene = "Scene"; +const string ConfigurationManager::KeyEnableGui = "EnableGUI"; +const string ConfigurationManager::KeyStartupScript = "StartupScripts"; +const string ConfigurationManager::KeySettingsScript = "SettingsScripts"; +const string ConfigurationManager::KeySpiceTimeKernel = "SpiceKernel.Time"; +const string ConfigurationManager::KeySpiceLeapsecondKernel = "SpiceKernel.LeapSecond"; +const string ConfigurationManager::KeyLogLevel = "Logging.LogLevel"; +const string ConfigurationManager::KeyLogImmediateFlush = "Logging.ImmediateFlush"; +const string ConfigurationManager::KeyLogs = "Logging.Logs"; +const string ConfigurationManager::KeyCapabilitiesVerbosity = + "Logging.CapabilitiesVerbosity"; +const string ConfigurationManager::KeyDisableMasterRendering = "DisableRenderingOnMaster"; +const string ConfigurationManager::KeyDownloadRequestURL = "DownloadRequestURL"; -bool ConfigurationManager::loadFromFile(const std::string& filename) { +string ConfigurationManager::findConfiguration(const string& filename) { + using ghoul::filesystem::Directory; + + Directory directory = FileSys.currentDirectory(); + std::string configurationName = _configurationFile; + + while (true) { + std::string&& fullPath = FileSys.pathByAppendingComponent(directory, + configurationName); + bool exists = FileSys.fileExists(fullPath); + if (exists) + return fullPath; + + Directory nextDirectory = directory.parentDirectory(true); + + if (directory.path() == nextDirectory.path()) { + // We have reached the root of the file system and did not find the file + throw ghoul::RuntimeError( + "Could not find configuration file '" + filename + "'", + "ConfigurationManager" + ); + } + directory = nextDirectory; + } +} + +void ConfigurationManager::loadFromFile(const string& filename) { using ghoul::filesystem::FileSystem; - if (!FileSys.fileExists(filename)) { - LERROR("Could not find file '" << filename << "'"); - return false; - } + + if (!FileSys.fileExists(filename)) + throw ghoul::FileNotFoundError(filename, "ConfigurationManager"); // ${BASE_PATH} - std::string&& basePathToken = FileSystem::TokenOpeningBraces + _keyBasePath + string basePathToken = FileSystem::TokenOpeningBraces + _keyBasePath + FileSystem::TokenClosingBraces; // Retrieving the directory in which the configuration file lies - std::string absolutePath = FileSys.absolutePath(filename); - std::string basePath = ghoul::filesystem::File(absolutePath).directoryName(); + string absolutePath = FileSys.absolutePath(filename); + string basePath = ghoul::filesystem::File(absolutePath).directoryName(); FileSys.registerPathToken(basePathToken, basePath); // Loading the configuration file into ourselves - try { - ghoul::lua::loadDictionaryFromFile(filename, *this); - } - catch (...) { - LERROR("Loading dictionary from file failed"); - return false; - } + ghoul::lua::loadDictionaryFromFile(filename, *this); // Register all the paths - ghoul::Dictionary dictionary; - const bool success = getValue(KeyPaths, dictionary); - if (!success) { - LERROR("Configuration does not contain the key '" << KeyPaths << "'"); - return false; - } +// const bool hasPath = hasKeyAndValue(KeyPaths); +// if (!hasPath) { +// throw ghoul::RuntimeError( +// "Configuration does not contain the key '" + KeyPaths + "'", +// "ConfifgurationManager" +// ); +// } + ghoul::Dictionary dictionary = value(KeyPaths); std::vector pathKeys = dictionary.keys(); for (std::string key : pathKeys) { std::string p; if (dictionary.getValue(key, p)) { - std::string fullKey - = FileSystem::TokenOpeningBraces + key - + FileSystem::TokenClosingBraces; - LDEBUG("Registering path " << fullKey << ": " << p); + std::string fullKey = + FileSystem::TokenOpeningBraces + key + FileSystem::TokenClosingBraces; + LDEBUGC("ConfigurationManager", "Registering path " << fullKey << ": " << p); bool override = (basePathToken == fullKey); - if (override) - LINFO("Overriding base path with '" << p << "'"); + LINFOC("ConfigurationManager", "Overriding base path with '" << p << "'"); FileSys.registerPathToken(std::move(fullKey), std::move(p), override); } } @@ -125,7 +148,7 @@ bool ConfigurationManager::loadFromFile(const std::string& filename) { bool ConfigurationManager::checkCompleteness() const { std::vector requiredTokens = { KeyPaths, - KeyCachePath, + KeyPaths + "." + KeyCache, KeyFonts, KeyConfigSgct }; @@ -134,8 +157,12 @@ bool ConfigurationManager::checkCompleteness() const { for (const std::string& token : requiredTokens) { bool success = hasKey(token); - if (!success) - LFATAL("Configuration file did not contain required key '" << token << "'"); + if (!success) { + LFATALC( + "ConfigurationManager", + "Configuration file did not contain required key '" << token << "'" + ); + } totalSuccess &= success; } diff --git a/src/engine/downloadmanager.cpp b/src/engine/downloadmanager.cpp index 884831dbdd..7b038a11b1 100644 --- a/src/engine/downloadmanager.cpp +++ b/src/engine/downloadmanager.cpp @@ -62,9 +62,8 @@ namespace { } - int xferinfo(void* p, - curl_off_t dltotal, curl_off_t dlnow, - curl_off_t ultotal, curl_off_t ulnow) + int xferinfo(void* p, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, + curl_off_t ulnow) { if (dltotal == 0) return 0; @@ -121,43 +120,39 @@ DownloadManager::FileFuture::FileFuture(std::string file) , abortDownload(false) {} -DownloadManager::DownloadManager(std::string requestURL, int applicationVersion) - : _requestURL(std::move(requestURL)) - , _applicationVersion(std::move(applicationVersion)) +DownloadManager::DownloadManager(std::string requestURL, int applicationVersion, + bool useMultithreadedDownload) + : _applicationVersion(std::move(applicationVersion)) + , _useMultithreadedDownload(useMultithreadedDownload) { curl_global_init(CURL_GLOBAL_ALL); + + _requestURL.push_back(std::move(requestURL)); + // TODO: Check if URL is accessible ---abock // TODO: Allow for multiple requestURLs } DownloadManager::FileFuture* DownloadManager::downloadFile( - const std::string& url, - const ghoul::filesystem::File& file, - bool overrideFile, - DownloadFinishedCallback finishedCallback, - DownloadProgressCallback progressCallback) + const std::string& url, const ghoul::filesystem::File& file, bool overrideFile, + DownloadFinishedCallback finishedCallback, DownloadProgressCallback progressCallback) { if (!overrideFile && FileSys.fileExists(file)) return nullptr; - FileFuture* future = new FileFuture( - file.filename() - ); + FileFuture* future = new FileFuture(file.filename()); FILE* fp = fopen(file.path().c_str(), "wb"); - LDEBUG("Starting download for file: '" << url << - "' into file '" << file.path() << "'"); + LDEBUG("Start downloading file: '" << url << "' into file '" << file.path() << "'"); -#ifdef USE_MULTITHREADED_DOWNLOAD - std::thread t = std::thread([url, finishedCallback, progressCallback, future, fp]() { -#endif + auto downloadFunction = [url, finishedCallback, progressCallback, future, fp]() { CURL* curl = curl_easy_init(); if (curl) { curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeData); - + ProgressInformation p = { future, std::chrono::system_clock::now(), @@ -166,49 +161,51 @@ DownloadManager::FileFuture* DownloadManager::downloadFile( curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, xferinfo); curl_easy_setopt(curl, CURLOPT_XFERINFODATA, &p); curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L); - + CURLcode res = curl_easy_perform(curl); curl_easy_cleanup(curl); fclose(fp); - + if (res == CURLE_OK) future->isFinished = true; else future->errorMessage = curl_easy_strerror(res); - + if (finishedCallback) finishedCallback(*future); } -#ifdef USE_MULTITHREADED_DOWNLOAD - }); - + }; + + if (_useMultithreadedDownload) { + std::thread t = std::thread(downloadFunction); + #ifdef WIN32 - std::thread::native_handle_type h = t.native_handle(); - SetPriorityClass(h, IDLE_PRIORITY_CLASS); - SetThreadPriority(h, THREAD_PRIORITY_LOWEST); + std::thread::native_handle_type h = t.native_handle(); + SetPriorityClass(h, IDLE_PRIORITY_CLASS); + SetThreadPriority(h, THREAD_PRIORITY_LOWEST); #else - // TODO: Implement thread priority ---abock + // TODO: Implement thread priority ---abock #endif - - t.detach(); -#endif // USE_MULTITHREADED_DOWNLOAD - + + t.detach(); + } + else { + downloadFunction(); + } + return future; } std::vector DownloadManager::downloadRequestFiles( - const std::string& identifier, - const ghoul::filesystem::Directory& destination, - int version, - bool overrideFiles, - DownloadFinishedCallback finishedCallback, + const std::string& identifier, const ghoul::filesystem::Directory& destination, + int version, bool overrideFiles, DownloadFinishedCallback finishedCallback, DownloadProgressCallback progressCallback) { std::vector futures; FileSys.createDirectory(destination, true); // TODO: Check s ---abock // TODO: Escaping is necessary ---abock - const std::string fullRequest =_requestURL + "?" + + const std::string fullRequest =_requestURL.back() + "?" + RequestIdentifier + "=" + identifier + "&" + RequestFileVersion + "=" + std::to_string(version) + "&" + RequestApplicationVersion + "=" + std::to_string(_applicationVersion); @@ -259,37 +256,36 @@ std::vector DownloadManager::downloadRequestFiles( return futures; } -void DownloadManager::downloadRequestFilesAsync( - const std::string& identifier, - const ghoul::filesystem::Directory& destination, - int version, - bool overrideFiles, +void DownloadManager::downloadRequestFilesAsync(const std::string& identifier, + const ghoul::filesystem::Directory& destination, int version, bool overrideFiles, AsyncDownloadFinishedCallback callback) { -#ifdef USE_MULTITHREADED_DOWNLOAD - std::thread t = std::thread([this, identifier, destination, version, overrideFiles, callback](){ -#endif + auto downloadFunction = [this, identifier, destination, version, overrideFiles, callback](){ std::vector f = downloadRequestFiles( identifier, destination, version, overrideFiles ); - + callback(f); -#ifdef USE_MULTITHREADED_DOWNLOAD - }); - + }; + + if (_useMultithreadedDownload) { + std::thread t = std::thread(downloadFunction); + #ifdef WIN32 - std::thread::native_handle_type h = t.native_handle(); - SetPriorityClass(h, IDLE_PRIORITY_CLASS); - SetThreadPriority(h, THREAD_PRIORITY_LOWEST); + std::thread::native_handle_type h = t.native_handle(); + SetPriorityClass(h, IDLE_PRIORITY_CLASS); + SetThreadPriority(h, THREAD_PRIORITY_LOWEST); #else - // TODO: Implement thread priority ---abock + // TODO: Implement thread priority ---abock #endif - - t.detach(); -#endif // USE_MULTITHREADED_DOWNLOAD + + t.detach(); + } + else + downloadFunction(); } } // namespace openspace diff --git a/src/engine/moduleengine.cpp b/src/engine/moduleengine.cpp index d6888df8f9..520b7385e0 100644 --- a/src/engine/moduleengine.cpp +++ b/src/engine/moduleengine.cpp @@ -36,40 +36,30 @@ namespace { namespace openspace { -bool ModuleEngine::create() { +void ModuleEngine::create() { LDEBUG("Creating modules"); - registerModules(AllModules); + for (OpenSpaceModule* m : AllModules) + registerModule(std::unique_ptr(m)); - for (OpenSpaceModule* m : _modules) { - bool success = m->create(); - if (!success) { - LERROR("Could not initialize module '" << m->name() << "'"); - return false; - } - } + for (auto& m : _modules) + m->create(); LDEBUG("Finished creating modules"); return true; } -bool ModuleEngine::destroy() { +void ModuleEngine::destroy() { LDEBUG("Destroying modules"); - for (OpenSpaceModule* m : _modules) { - bool success = m->destroy(); - if (!success) { - LERROR("Could not deinitialize module '" << m->name() << "'"); - return false; - } - delete m; - } + for (auto& m : _modules) + m->destroy(); + _modules.clear(); LDEBUG("Finished destroying modules"); - return true; } bool ModuleEngine::initialize() { LDEBUG("Initializing modules"); - for (OpenSpaceModule* m : _modules) { + for (auto& m : _modules) { bool success = m->initialize(); if (!success) { LERROR("Could not initialize module '" << m->name() << "'"); @@ -83,7 +73,7 @@ bool ModuleEngine::initialize() { bool ModuleEngine::deinitialize() { LDEBUG("Deinitializing modules"); - for (OpenSpaceModule* m : _modules) { + for (auto& m : _modules) { bool success = m->deinitialize(); if (!success) { LERROR("Could not deinitialize module '" << m->name() << "'"); @@ -94,16 +84,23 @@ bool ModuleEngine::deinitialize() { return true; } -void ModuleEngine::registerModules(std::vector modules) { - _modules.insert(_modules.end(), modules.begin(), modules.end()); +void ModuleEngine::registerModules(std::vector> modules) { + _modules.insert( + _modules.end(), + std::make_move_iterator(modules.begin()), + std::make_move_iterator(modules.end()) + ); } -void ModuleEngine::registerModule(OpenSpaceModule* module) { +void ModuleEngine::registerModule(std::unique_ptr module) { _modules.push_back(std::move(module)); } -const std::vector ModuleEngine::modules() const { - return _modules; +std::vector ModuleEngine::modules() const { + std::vector result; + for (auto& m : _modules) + result.push_back(m.get()); + return result; } } // namespace openspace diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index b6e0e49533..18065662b7 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -77,7 +77,6 @@ using namespace ghoul::cmdparser; namespace { const std::string _loggerCat = "OpenSpaceEngine"; - const std::string _configurationFile = "openspace.cfg"; const std::string _sgctDefaultConfigFile = "${SGCT}/single.xml"; const std::string _defaultCacheLocation = "${BASE_PATH}/cache"; @@ -199,24 +198,27 @@ bool OpenSpaceEngine::create(int argc, char** argv, std::string configurationFilePath = commandlineArgumentPlaceholders.configurationName; if (configurationFilePath.empty()) { LDEBUG("Finding configuration"); - const bool findConfigurationSuccess = - OpenSpaceEngine::findConfiguration(configurationFilePath); - if (!findConfigurationSuccess) { - LFATAL("Could not find OpenSpace configuration file!"); - return false; - } + try { + configurationFilePath = + ConfigurationManager::findConfiguration(configurationFilePath); + } + catch (const ghoul::RuntimeError& e) { + LFATALC(e.component, e.message); + } } configurationFilePath = absPath(configurationFilePath); LINFO("Configuration Path: '" << configurationFilePath << "'"); // Loading configuration from disk LDEBUG("Loading configuration from disk"); - const bool configLoadSuccess = _engine->configurationManager().loadFromFile( - configurationFilePath); - if (!configLoadSuccess) { - LFATAL("Loading of configuration file '" << configurationFilePath << "' failed"); - return false; - } + try { + _engine->configurationManager().loadFromFile(configurationFilePath); + } + catch (const ghoul::RuntimeError& e) { + LFATAL("Loading of configuration file '" << configurationFilePath << "' failed"); + LFATALC(e.component, e.message); + return false; + } // Initialize the requested logs from the configuration file _engine->configureLogging(); @@ -427,30 +429,6 @@ bool OpenSpaceEngine::gatherCommandlineArguments() { return true; } -bool OpenSpaceEngine::findConfiguration(std::string& filename) { - using ghoul::filesystem::Directory; - - Directory directory = FileSys.currentDirectory(); - std::string configurationName = _configurationFile; - - while (true) { - std::string&& fullPath = FileSys.pathByAppendingComponent(directory, - configurationName); - bool exists = FileSys.fileExists(fullPath); - if (exists) { - filename = fullPath; - return true; - } - - Directory nextDirectory = directory.parentDirectory(true); - - if (directory.path() == nextDirectory.path()) - // We have reached the root of the file system and did not find the file - return false; - directory = nextDirectory; - } -} - bool OpenSpaceEngine::loadSpiceKernels() { // Load time kernel std::string timeKernel; diff --git a/src/util/openspacemodule.cpp b/src/util/openspacemodule.cpp index 35a3dee439..c95375e449 100644 --- a/src/util/openspacemodule.cpp +++ b/src/util/openspacemodule.cpp @@ -43,7 +43,7 @@ OpenSpaceModule::OpenSpaceModule(std::string name) ghoul_assert(!_name.empty(), "Empty module name is not allowed"); } -bool OpenSpaceModule::create() { +void OpenSpaceModule::create() { std::string moduleNameUpper = name(); std::transform(moduleNameUpper.begin(), moduleNameUpper.end(), moduleNameUpper.begin(), toupper); std::string moduleToken = @@ -55,11 +55,12 @@ bool OpenSpaceModule::create() { std::string path = modulePath(); LDEBUG("Registering module path: " << moduleToken << ": " << path); FileSys.registerPathToken(moduleToken, path); - return true; + + internalCreate(); } -bool OpenSpaceModule::destroy() { - return true; +void OpenSpaceModule::destroy() { + internalDestroy(); } std::string OpenSpaceModule::name() const { @@ -81,12 +82,18 @@ std::string OpenSpaceModule::modulePath() const { } bool OpenSpaceModule::initialize() { + internalInitialize(); return true; } bool OpenSpaceModule::deinitialize() { + internalDeinitialize(); return true; } - + +void OpenSpaceModule::internalCreate() {} +void OpenSpaceModule::internalDestroy() {} +void OpenSpaceModule::internalInitialize() {} +void OpenSpaceModule::internalDeinitialize() {} } // namespace openspace From 6eca5c0f68f190394710acb7585de4769e858f91 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 14 Dec 2015 11:46:44 -0800 Subject: [PATCH 065/122] More module cleanup --- include/openspace/engine/moduleengine.h | 44 +++++++++++--- include/openspace/util/openspacemodule.h | 52 +++++++++++++--- modules/base/basemodule.cpp | 2 +- modules/base/basemodule.h | 2 +- modules/fieldlines/fieldlinesmodule.cpp | 2 +- modules/fieldlines/fieldlinesmodule.h | 2 +- modules/newhorizons/newhorizonsmodule.cpp | 2 +- modules/newhorizons/newhorizonsmodule.h | 2 +- modules/volume/volumemodule.cpp | 2 +- modules/volume/volumemodule.h | 2 +- src/engine/moduleengine.cpp | 74 ++++++++--------------- src/engine/openspaceengine.cpp | 6 +- src/util/openspacemodule.cpp | 40 +++++------- 13 files changed, 128 insertions(+), 104 deletions(-) diff --git a/include/openspace/engine/moduleengine.h b/include/openspace/engine/moduleengine.h index 1fefc57ef6..e2ea3ac4a1 100644 --- a/include/openspace/engine/moduleengine.h +++ b/include/openspace/engine/moduleengine.h @@ -34,27 +34,51 @@ namespace openspace { /** * The ModuleEngine is the central repository for registering and accessing - * OpenSpaceModule for the current application run. By create%ing the ModuleEngine, the - * default set of OpenSpaceModule%s as generated by CMake in the + * OpenSpaceModule for the current application run. By initializing (#initialize) the + * ModuleEngine, the default set of OpenSpaceModule%s as generated by CMake in the * moduleregistration.h file is automatically registered and created. + * Additional OpenSpaceModule%s can be registered with the #registerModule function, which + * will internally call the OpenSpaceModule::initialize method. */ class ModuleEngine { public: - void create(); - void destroy(); + /** + * Registers all of the OpenSpaceModule%s which are created by the CMake configuration + * and stored in the moduleregistration.h file. For all of those modules + * the OpenSpaceModule::initialize method with will called. + * \throw ghoul::RuntimeError If two modules in the default modules have the same + * name + */ + void initialize(); + + /** + * Deinitializes all of the contained OpenSpaceModule%s by calling the + * OpenSpaceModule::deinitialize methods. + */ + void deinitialize(); - bool initialize(); - bool deinitialize(); - - void registerModules(std::vector> modules); + /** + * 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 + * previously + * \pre \p module must not be nullptr + */ void registerModule(std::unique_ptr module); + + /** + * Returns a list of all registered OpenSpaceModule%s that have been registered with + * this ModuleEngine. All returned OpenSpaceModule%s are guaranteed to be initialized. + * \return A list of all registered OpenSpaceModule%s + */ std::vector modules() const; -protected: +private: + /// The list of all registered OpenSpaceModule%s std::vector> _modules; }; - } // namespace openspace #endif // __MODULEENGINE_H__ diff --git a/include/openspace/util/openspacemodule.h b/include/openspace/util/openspacemodule.h index 5677e46b65..06e15d64f8 100644 --- a/include/openspace/util/openspacemodule.h +++ b/include/openspace/util/openspacemodule.h @@ -29,28 +29,64 @@ namespace openspace { +/** + * This class is the base class for an OpenSpace module. A module groups functionality + * into a useful granularity to be mostly used self-sufficiently. Each OpenSpaceModule + * needs a unique, nonempty name. + */ class OpenSpaceModule { public: + /** + * 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 + */ OpenSpaceModule(std::string name); + + /// Default destructor virtual ~OpenSpaceModule() = default; - void create(); - void destroy(); - - bool initialize(); - bool deinitialize(); + /** + * Initialization method that will register a token of the form + * ${MODULE_<>} for a specific <> that is set in + * the OpenSpaceModule constructor. This method will call the internalInitialize + * method for further customization for each subclass. + */ + void initialize(); + + /** + * Empty deinitialization method that will call the internalDeinitialize method for + * module-specific customization. + */ + void deinitialize(); + /** + * Returns the name for this OpenSpaceModule. + * \return THe name for this OpenSpaceModule + */ std::string name() const; protected: - virtual void internalCreate(); - virtual void internalDestroy(); - + /** + * Customization point for each derived class. The internalInitialize method is called + * by the initiailze method. + */ virtual void internalInitialize(); + + /** + * Customization point for each derived class. The internalDeinitialize method is + * called by the deinitialize method. + */ virtual void internalDeinitialize(); + /** + * Returns the path for this module, possibly containing ghoul::filesystem::FileSystem + * path tokens. + */ std::string modulePath() const; + /// The name of this OpenSpaceModule const std::string _name; }; diff --git a/modules/base/basemodule.cpp b/modules/base/basemodule.cpp index e6b2ddcd2a..4d3939941d 100644 --- a/modules/base/basemodule.cpp +++ b/modules/base/basemodule.cpp @@ -55,7 +55,7 @@ BaseModule::BaseModule() : OpenSpaceModule("Base") {} -void BaseModule::internalCreate() { +void BaseModule::internalInitialize() { FactoryManager::ref().addFactory(new ghoul::TemplateFactory); FactoryManager::ref().addFactory(new ghoul::TemplateFactory); diff --git a/modules/base/basemodule.h b/modules/base/basemodule.h index 1feaf32c99..aaafa504cc 100644 --- a/modules/base/basemodule.h +++ b/modules/base/basemodule.h @@ -34,7 +34,7 @@ public: BaseModule(); protected: - void internalCreate() override; + void internalInitialize() override; }; } // namespace openspace diff --git a/modules/fieldlines/fieldlinesmodule.cpp b/modules/fieldlines/fieldlinesmodule.cpp index b0be3c52a3..23928afba8 100644 --- a/modules/fieldlines/fieldlinesmodule.cpp +++ b/modules/fieldlines/fieldlinesmodule.cpp @@ -37,7 +37,7 @@ FieldlinesModule::FieldlinesModule() : OpenSpaceModule("Fieldlines") {} -void FieldlinesModule::internalCreate() { +void FieldlinesModule::internalInitialize() { auto fRenderable = FactoryManager::ref().factory(); ghoul_assert(fRenderable, "No renderable factory existed"); diff --git a/modules/fieldlines/fieldlinesmodule.h b/modules/fieldlines/fieldlinesmodule.h index 50deb9984d..782b8ff9fa 100644 --- a/modules/fieldlines/fieldlinesmodule.h +++ b/modules/fieldlines/fieldlinesmodule.h @@ -34,7 +34,7 @@ public: FieldlinesModule(); protected: - void internalCreate() override; + void internalInitialize() override; }; } // namespace openspace diff --git a/modules/newhorizons/newhorizonsmodule.cpp b/modules/newhorizons/newhorizonsmodule.cpp index f5b30cc86e..2a3e46a03e 100644 --- a/modules/newhorizons/newhorizonsmodule.cpp +++ b/modules/newhorizons/newhorizonsmodule.cpp @@ -50,7 +50,7 @@ NewHorizonsModule::NewHorizonsModule() : OpenSpaceModule("NewHorizons") {} -void NewHorizonsModule::internalCreate() { +void NewHorizonsModule::internalInitialize() { ImageSequencer2::initialize(); FactoryManager::ref().addFactory(new ghoul::TemplateFactory); diff --git a/modules/newhorizons/newhorizonsmodule.h b/modules/newhorizons/newhorizonsmodule.h index f721f743b1..003b68e961 100644 --- a/modules/newhorizons/newhorizonsmodule.h +++ b/modules/newhorizons/newhorizonsmodule.h @@ -34,7 +34,7 @@ public: NewHorizonsModule(); protected: - void internalCreate() override; + void internalInitialize() override; }; } // namespace openspace diff --git a/modules/volume/volumemodule.cpp b/modules/volume/volumemodule.cpp index f2ff8b6b43..38466ba610 100644 --- a/modules/volume/volumemodule.cpp +++ b/modules/volume/volumemodule.cpp @@ -37,7 +37,7 @@ VolumeModule::VolumeModule() : OpenSpaceModule("Volume") {} -void VolumeModule::internalCreate() { +void VolumeModule::internalInitialize() { auto fRenderable = FactoryManager::ref().factory(); ghoul_assert(fRenderable, "No renderable factory existed"); diff --git a/modules/volume/volumemodule.h b/modules/volume/volumemodule.h index 415056c1e5..3319dadb3a 100644 --- a/modules/volume/volumemodule.h +++ b/modules/volume/volumemodule.h @@ -34,7 +34,7 @@ public: VolumeModule(); protected: - void internalCreate() override; + void internalInitialize() override; }; } // namespace openspace diff --git a/src/engine/moduleengine.cpp b/src/engine/moduleengine.cpp index 520b7385e0..d85d6c55b2 100644 --- a/src/engine/moduleengine.cpp +++ b/src/engine/moduleengine.cpp @@ -24,11 +24,12 @@ #include +#include #include #include -#include +#include namespace { const std::string _loggerCat = "ModuleEngine"; @@ -36,63 +37,40 @@ namespace { namespace openspace { -void ModuleEngine::create() { - LDEBUG("Creating modules"); - +void ModuleEngine::initialize() { for (OpenSpaceModule* m : AllModules) registerModule(std::unique_ptr(m)); - - for (auto& m : _modules) - m->create(); - LDEBUG("Finished creating modules"); return true; } -void ModuleEngine::destroy() { - LDEBUG("Destroying modules"); - for (auto& m : _modules) - m->destroy(); +void ModuleEngine::deinitialize() { + LDEBUG("Deinitializing modules"); + for (auto& m : _modules) { + LDEBUG("Deinitialieing module '" << m->name() << "'"); + m->deinitialize(); + } _modules.clear(); LDEBUG("Finished destroying modules"); } -bool ModuleEngine::initialize() { - LDEBUG("Initializing modules"); - - for (auto& m : _modules) { - bool success = m->initialize(); - if (!success) { - LERROR("Could not initialize module '" << m->name() << "'"); - return false; - } - } - LDEBUG("Finished initializing modules"); - return true; -} - -bool ModuleEngine::deinitialize() { - LDEBUG("Deinitializing modules"); - - for (auto& m : _modules) { - bool success = m->deinitialize(); - if (!success) { - LERROR("Could not deinitialize module '" << m->name() << "'"); - return false; - } - } - LDEBUG("Finished Deinitializing modules"); - return true; -} - -void ModuleEngine::registerModules(std::vector> modules) { - _modules.insert( - _modules.end(), - std::make_move_iterator(modules.begin()), - std::make_move_iterator(modules.end()) - ); -} - void ModuleEngine::registerModule(std::unique_ptr module) { + ghoul_assert(module, "Module must not be nullptr"); + + auto it = std::find_if( + _modules.begin(), + _modules.end(), + [&module](std::unique_ptr& rhs) { + return rhs->name() == module->name(); + } + ); + if (it != _modules.end()) { + throw ghoul::RuntimeError( + "Module name '" + module->name() + "' was registered before", "ModuleEngine" + ); + } + + LDEBUG("Registering module '" << module->name() << "'"); + module->initialize(); _modules.push_back(std::move(module)); } diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 18065662b7..a99608fc4c 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -239,7 +239,7 @@ bool OpenSpaceEngine::create(int argc, char** argv, } // Register modules - _engine->_moduleEngine->create(); + _engine->_moduleEngine->initialize(); // Create the cachemanager FileSys.createCacheManager( @@ -273,7 +273,6 @@ bool OpenSpaceEngine::create(int argc, char** argv, void OpenSpaceEngine::destroy() { _engine->_moduleEngine->deinitialize(); - _engine->_moduleEngine->destroy(); _engine->_console->deinitialize(); _engine->_scriptEngine->deinitialize(); @@ -389,9 +388,6 @@ bool OpenSpaceEngine::initialize() { LINFO("Initializing GUI"); _gui->initialize(); - // Initialize modules - _moduleEngine->initialize(); - LINFO("Finished initializing"); return true; } diff --git a/src/util/openspacemodule.cpp b/src/util/openspacemodule.cpp index c95375e449..5c1eeb727c 100644 --- a/src/util/openspacemodule.cpp +++ b/src/util/openspacemodule.cpp @@ -33,34 +33,34 @@ namespace { const std::string _loggerCat = "OpenSpaceModule"; const std::string ModuleBaseToken = "MODULE_"; } -//ghoul::filesystem::FileSystem::TokenOpeningBraces -//ghoul::filesystem::FileSystem::TokenClosingBraces + namespace openspace { OpenSpaceModule::OpenSpaceModule(std::string name) : _name(std::move(name)) { - ghoul_assert(!_name.empty(), "Empty module name is not allowed"); + ghoul_assert(!_name.empty(), "Name must not be empty"); } -void OpenSpaceModule::create() { - std::string moduleNameUpper = name(); - std::transform(moduleNameUpper.begin(), moduleNameUpper.end(), moduleNameUpper.begin(), toupper); - std::string moduleToken = +void OpenSpaceModule::initialize() { + std::string upperName = name(); + std::transform(upperName.begin(), upperName.end(), upperName.begin(), toupper); + + std::string moduleToken = ghoul::filesystem::FileSystem::TokenOpeningBraces + ModuleBaseToken + - moduleNameUpper + + upperName + ghoul::filesystem::FileSystem::TokenClosingBraces; std::string path = modulePath(); LDEBUG("Registering module path: " << moduleToken << ": " << path); FileSys.registerPathToken(moduleToken, path); - internalCreate(); + internalInitialize(); } -void OpenSpaceModule::destroy() { - internalDestroy(); +void OpenSpaceModule::deinitialize() { + internalDeinitialize(); } std::string OpenSpaceModule::name() const { @@ -77,22 +77,12 @@ std::string OpenSpaceModule::modulePath() const { #ifdef EXTERNAL_MODULES_PATHS #endif - LERROR("Could not resolve path for module '" << name() << "'"); - return ""; + throw ghoul::RuntimeError( + "Could not resolve path for module '" + name() + "'", + "OpenSpaceModule" + ); } -bool OpenSpaceModule::initialize() { - internalInitialize(); - return true; -} - -bool OpenSpaceModule::deinitialize() { - internalDeinitialize(); - return true; -} - -void OpenSpaceModule::internalCreate() {} -void OpenSpaceModule::internalDestroy() {} void OpenSpaceModule::internalInitialize() {} void OpenSpaceModule::internalDeinitialize() {} From adfc7d244cfb27c678467525be66334c32b0df9f Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 14 Dec 2015 15:55:28 -0800 Subject: [PATCH 066/122] Cleanup of WindowWrapper classes --- .../engine/wrapper/dummywindowwrapper.h | 22 +--- .../engine/wrapper/sgctwindowwrapper.h | 11 +- .../openspace/engine/wrapper/windowwrapper.h | 124 +++++++++++++++--- include/openspace/util/screenlog.h | 13 +- src/CMakeLists.txt | 1 + src/engine/openspaceengine.cpp | 2 +- src/engine/wrapper/dummywindowwrapper.cpp | 32 +---- src/engine/wrapper/sgctwindowwrapper.cpp | 8 +- src/engine/wrapper/windowwrapper.cpp | 59 +++++++++ src/rendering/renderengine.cpp | 26 ++-- src/util/screenlog.cpp | 29 +++- 11 files changed, 230 insertions(+), 97 deletions(-) create mode 100644 src/engine/wrapper/windowwrapper.cpp diff --git a/include/openspace/engine/wrapper/dummywindowwrapper.h b/include/openspace/engine/wrapper/dummywindowwrapper.h index 19946483d3..e1cac32d10 100644 --- a/include/openspace/engine/wrapper/dummywindowwrapper.h +++ b/include/openspace/engine/wrapper/dummywindowwrapper.h @@ -29,34 +29,24 @@ namespace openspace { +/** + * DummyWindowWrapper that can be used if no actual rendering output is required, such as + * for console applications. The window sizes and resolutions will all be set to + * 0 and all graphics operations will be no-ops. + */ class DummyWindowWrapper : public WindowWrapper { public: - void setBarrier(bool enabled) override; - void clearAllWindows() override; + void clearAllWindows(const glm::vec4& clearColor) override; bool windowHasResized() const override; - double time() const override; double averageDeltaTime() const override; uint32_t mouseButtons(int maxNumber = 8) const override; glm::vec2 mousePosition() const override; glm::ivec2 currentWindowSize() const override; - glm::ivec2 currentWindowResolution() const override; - bool isRegularRendering() const override; glm::mat4 viewProjectionMatrix() const override; void setNearFarClippingPlane(float near, float far) override; - glm::ivec4 viewportPixelCoordinates() const override; - - bool isExternalControlConnected() const override; - void sendMessageToExternalControl(const std::vector& message) const override; - - // true for single viewport, single window; false otherwise - bool isSimpleRendering() const override; - void takeScreenshot() const override; - - //virtual void forEachWindow(std::function function) = 0; - }; } // namespace openspace diff --git a/include/openspace/engine/wrapper/sgctwindowwrapper.h b/include/openspace/engine/wrapper/sgctwindowwrapper.h index 2396a5c8c5..b74ba8abb2 100644 --- a/include/openspace/engine/wrapper/sgctwindowwrapper.h +++ b/include/openspace/engine/wrapper/sgctwindowwrapper.h @@ -29,13 +29,17 @@ namespace openspace { +/** + * WindowWrapper subclass wrapping the Simple Graphics Cluster Toolkit, forwarding all + * method calls to the specific functions in the Engine and SGCTWindow classes. + * \sa https://c-student.itn.liu.se/wiki/develop:sgct:sgct + */ class SGCTWindowWrapper : public WindowWrapper { public: void setBarrier(bool enabled) override; - void clearAllWindows() override; + void clearAllWindows(const glm::vec4& clearColor) override; bool windowHasResized() const override; - double time() const override; double averageDeltaTime() const override; glm::vec2 mousePosition() const override; uint32_t mouseButtons(int maxNumber) const override; @@ -55,9 +59,6 @@ public: bool isSimpleRendering() const override; void takeScreenshot() const override; - - - // void forEachWindow(std::function function) override; }; } // namespace openspace diff --git a/include/openspace/engine/wrapper/windowwrapper.h b/include/openspace/engine/wrapper/windowwrapper.h index af62e55cc6..cde0d28df5 100644 --- a/include/openspace/engine/wrapper/windowwrapper.h +++ b/include/openspace/engine/wrapper/windowwrapper.h @@ -33,34 +33,124 @@ namespace openspace { +/** + * A WindowWrapper is a class that handles the abstraction between OpenSpace and a + * specific window creation framework.
+ * Every new windowing framework needs to have its own WindowWrapper subclass exposing the + * required features. + */ class WindowWrapper { public: - virtual void setBarrier(bool enabled) = 0; - virtual void clearAllWindows() = 0; + /** + * This method enables or disables a framelock barrier. If the specific windowing + * framework does not provide a framelock, this method defaults to a no-op. + * \param enabled If true the framelock is enabled, false + * disables it + */ + virtual void setBarrier(bool enabled); + + /** + * This method clears all the rendering windows with the specified \p clearColor. In + * most OpenGL cases, this will end up with one or mode glClear calls. + * \param clearColor The color with which to clear all windows + */ + virtual void clearAllWindows(const glm::vec4& clearColor) = 0; + + /** + * Returns whether the current window has been resized recently. + * \return true if the current window has been resized recently, + * false otherwise + */ virtual bool windowHasResized() const = 0; - virtual double time() const = 0; - virtual double averageDeltaTime() const = 0; - virtual uint32_t mouseButtons(int maxNumber = 8) const = 0; - virtual glm::vec2 mousePosition() const = 0; - virtual glm::ivec2 currentWindowSize() const = 0; - virtual glm::ivec2 currentWindowResolution() const = 0; - virtual bool isRegularRendering() const = 0; + /** + * Returns the average frametime in seconds. + * \return The average frametime in seconds + */ + virtual double averageDeltaTime() const = 0; + + /** + * Returns the location of the mouse cursor in pixel screen coordinates. + * \return The location of the mouse cursor in pixel screen coordinates + */ + virtual glm::vec2 mousePosition() const = 0; + + /** + * Returns a bitmask of the status of all available mouse buttons. Bit i + * is 1 if mouse button i is pressed down; + * false otherwise. + * \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 = 0; + + /** + * Returns the size of the currently active window in pixel coordinates. + * \return The size of the currently active window in pixel coordinates + */ + virtual glm::ivec2 currentWindowSize() const = 0; + + /** + * Returns the resolution of the currently active window in pixel coordinates. + * \return The resolution of the currently active window in pixel coordinates + */ + virtual glm::ivec2 currentWindowResolution() const; + + /** + * Returns true if the current rendering method is regular, i.e., it is + * a flat projection without non-linear distortions. Returns false in + * other cases, for example fisheye projections. + * \return Whether the current rendering method is a regular method + */ + virtual bool isRegularRendering() const; + + /** + * Returns the currently employed view-projection matrix. + * \return The currently employed view-projection matrix + */ virtual glm::mat4 viewProjectionMatrix() const = 0; + + /** + * Sets the near and far clipping planes of the rendering window. + * \param near The near clipping plane + * \param far The far clipping plane + */ virtual void setNearFarClippingPlane(float near, float far) = 0; - virtual glm::ivec4 viewportPixelCoordinates() const = 0; + /** + * Returns the location and size of the current viewport (x, + * width, y, and height). If there is only a + * single viewport, x and y are 0 whereas + * width and height are equal to #currentWindowResolution. + * \return The location and size of the current viewport + */ + virtual glm::ivec4 viewportPixelCoordinates() const; - virtual bool isExternalControlConnected() const = 0; - virtual void sendMessageToExternalControl(const std::vector& message) const = 0; + /** + * Returns true if there is an external control connected, i.e., an + * application that can receive control commands. + * \return If there is an external control connected + */ + virtual bool isExternalControlConnected() const; - // true for single viewport, single window; false otherwise - virtual bool isSimpleRendering() const = 0; + /** + * Sends a \p message to an external control. + * \param message The message to be sent + */ + virtual void sendMessageToExternalControl(const std::vector& message) const; + /** + * Returns true if the rendering is a single viewport with an single + * window; false otherwise. + * \returns true if the rendering is a single viewport with an single + * widnow; false otherwise + */ + virtual bool isSimpleRendering() const; + + /** + * Advises the windowing system to take a screenshot. + */ virtual void takeScreenshot() const = 0; - - //virtual void forEachWindow(std::function function) = 0; - }; } // namespace openspace diff --git a/include/openspace/util/screenlog.h b/include/openspace/util/screenlog.h index 5acd66fc72..6133b4c345 100644 --- a/include/openspace/util/screenlog.h +++ b/include/openspace/util/screenlog.h @@ -26,6 +26,7 @@ #include #include #include // pair +#include namespace openspace { @@ -34,9 +35,9 @@ public: //typedef std::tuple LogEntry; struct LogEntry { - LogEntry(ghoul::logging::LogManager::LogLevel l, double t, std::string ts, std::string c, std::string m) : level(l), timeStamp(t), timeString(ts), category(c), message(m) {}; + LogEntry(ghoul::logging::LogManager::LogLevel l, std::chrono::time_point t, std::string ts, std::string c, std::string m) : level(l), timeStamp(t), timeString(ts), category(c), message(m) {}; ghoul::logging::LogManager::LogLevel level; - double timeStamp; + std::chrono::time_point timeStamp; std::string timeString; std::string category; std::string message; @@ -52,16 +53,18 @@ public: const size_t MaximumSize = 1000; - ScreenLog(); - + ScreenLog(std::chrono::seconds timeToLive); + + void removeExpiredEntries(); + virtual void log(ghoul::logging::LogManager::LogLevel level, const std::string& category, const std::string& message); const_range last(size_t n = 10); private: - std::vector _entries; + std::chrono::seconds _timeToLive; }; } \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7de686959d..a49a7edc3b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -36,6 +36,7 @@ set(OPENSPACE_SOURCE ${OPENSPACE_BASE_DIR}/src/engine/openspaceengine.cpp ${OPENSPACE_BASE_DIR}/src/engine/wrapper/dummywindowwrapper.cpp ${OPENSPACE_BASE_DIR}/src/engine/wrapper/sgctwindowwrapper.cpp + ${OPENSPACE_BASE_DIR}/src/engine/wrapper/windowwrapper.cpp ${OPENSPACE_BASE_DIR}/src/interaction/controller.cpp ${OPENSPACE_BASE_DIR}/src/interaction/deviceidentifier.cpp ${OPENSPACE_BASE_DIR}/src/interaction/interactionhandler.cpp diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index a99608fc4c..ac2ef92e54 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -397,7 +397,7 @@ bool OpenSpaceEngine::isInitialized() { } void OpenSpaceEngine::clearAllWindows() { - _windowWrapper->clearAllWindows(); + _windowWrapper->clearAllWindows(glm::vec4(0.f, 0.f, 0.f, 1.f)); } bool OpenSpaceEngine::gatherCommandlineArguments() { diff --git a/src/engine/wrapper/dummywindowwrapper.cpp b/src/engine/wrapper/dummywindowwrapper.cpp index fb569b594e..2c9d35d8dc 100644 --- a/src/engine/wrapper/dummywindowwrapper.cpp +++ b/src/engine/wrapper/dummywindowwrapper.cpp @@ -26,18 +26,12 @@ namespace openspace { -void DummyWindowWrapper::setBarrier(bool enabled) {} - -void DummyWindowWrapper::clearAllWindows() {} +void DummyWindowWrapper::clearAllWindows(const glm::vec4&) {} bool DummyWindowWrapper::windowHasResized() const { return false; } -double DummyWindowWrapper::time() const { - return 0.0; -} - double DummyWindowWrapper::averageDeltaTime() const { return 0.0; } @@ -54,36 +48,12 @@ glm::ivec2 DummyWindowWrapper::currentWindowSize() const { return glm::ivec2(0); } -glm::ivec2 DummyWindowWrapper::currentWindowResolution() const { - return glm::ivec2(0); -} - -bool DummyWindowWrapper::isRegularRendering() const { - return true; -} - glm::mat4 DummyWindowWrapper::viewProjectionMatrix() const { return glm::mat4(1.f); } void DummyWindowWrapper::setNearFarClippingPlane(float near, float far) {} -glm::ivec4 DummyWindowWrapper::viewportPixelCoordinates() const { - return glm::ivec4(0); -} - -bool DummyWindowWrapper::isExternalControlConnected() const { - return false; -} - -void DummyWindowWrapper::sendMessageToExternalControl(const std::vector& message) const { -} - -bool DummyWindowWrapper::isSimpleRendering() const { - return true; -} - void DummyWindowWrapper::takeScreenshot() const {} } // namespace openspace - diff --git a/src/engine/wrapper/sgctwindowwrapper.cpp b/src/engine/wrapper/sgctwindowwrapper.cpp index 3ea2257658..d32b13f1ea 100644 --- a/src/engine/wrapper/sgctwindowwrapper.cpp +++ b/src/engine/wrapper/sgctwindowwrapper.cpp @@ -36,10 +36,10 @@ void SGCTWindowWrapper::setBarrier(bool enabled) { sgct::SGCTWindow::setBarrier(enabled); } -void SGCTWindowWrapper::clearAllWindows() { +void SGCTWindowWrapper::clearAllWindows(const glm::vec4& clearColor) { size_t n = sgct::Engine::instance()->getNumberOfWindows(); for (size_t i = 0; i < n; ++i) { - glClearColor(0, 0, 0, 0); + glClearColor(clearColor.r, clearColor.g, clearColor.b, clearColor.a); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); GLFWwindow* win = sgct::Engine::instance()->getWindowPtr(i)->getWindowHandle(); glfwSwapBuffers(win); @@ -50,10 +50,6 @@ bool SGCTWindowWrapper::windowHasResized() const { return sgct::Engine::instance()->getCurrentWindowPtr()->isWindowResized(); } -double SGCTWindowWrapper::time() const { - return sgct::Engine::instance()->getTime(); -} - double SGCTWindowWrapper::averageDeltaTime() const { return sgct::Engine::instance()->getAvgDt(); } diff --git a/src/engine/wrapper/windowwrapper.cpp b/src/engine/wrapper/windowwrapper.cpp new file mode 100644 index 0000000000..de37cb639b --- /dev/null +++ b/src/engine/wrapper/windowwrapper.cpp @@ -0,0 +1,59 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2015 * + * * + * 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 { + +glm::ivec2 WindowWrapper::currentWindowResolution() const { + return currentWindowSize(); +} + +bool WindowWrapper::isRegularRendering() const { + return true; +} + +glm::ivec4 WindowWrapper::viewportPixelCoordinates() const { + return glm::ivec4( + 0, + currentWindowResolution().x, + 0, + currentWindowResolution().y + ); +} + +void WindowWrapper::setBarrier(bool) {} + +bool WindowWrapper::isExternalControlConnected() const { + return false; +} + +void WindowWrapper::sendMessageToExternalControl(const std::vector& message) const { +} + +bool WindowWrapper::isSimpleRendering() const { + return true; +} + +} // namespace openspace diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index a1317bd135..e249ce9d8b 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -85,6 +85,8 @@ namespace { const std::string KeyRenderingMethod = "RenderingMethod"; const std::string DefaultRenderingMethod = "ABufferSingleLinked"; + + std::chrono::seconds ScreenLogTimeToLive(15); } namespace openspace { @@ -291,7 +293,7 @@ bool RenderEngine::initializeGL() { _abuffer->initialize(); LINFO("Initializing Log"); - std::unique_ptr log = std::make_unique(); + std::unique_ptr log = std::make_unique(ScreenLogTimeToLive); _log = log.get(); ghoul::logging::LogManager::ref().addLog(std::move(log)); @@ -625,11 +627,12 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi #endif } if (_showScreenLog) { + _log->removeExpiredEntries(); + const int max = 10; const int category_length = 20; const int msg_length = 140; - const float ttl = 15.f; - const float fade = 5.f; + std::chrono::seconds fade(5); auto entries = _log->last(max); const glm::vec4 white(0.9, 0.9, 0.9, 1); @@ -639,21 +642,18 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi const glm::vec4 blue(0, 0, 1, 1); size_t nr = 1; + auto now = std::chrono::steady_clock::now(); for (auto& it = entries.first; it != entries.second; ++it) { const ScreenLog::LogEntry* e = &(*it); - const double t = OsEng.windowWrapper().time(); - float diff = static_cast(t - e->timeStamp); - - // Since all log entries are ordered, once one is exceeding TTL, all have -// if (diff > ttl) -// break; - + std::chrono::duration diff = now - e->timeStamp; + float alpha = 1; - float ttf = ttl - fade; + std::chrono::duration ttf = ScreenLogTimeToLive - fade; if (diff > ttf) { - diff = diff - ttf; - float p = 0.8f - diff / fade; + auto d = (diff - ttf).count(); + auto t = static_cast(d) / static_cast(fade.count()); + float p = 0.8f - t; alpha = (p <= 0.f) ? 0.f : pow(p, 0.3f); } diff --git a/src/util/screenlog.cpp b/src/util/screenlog.cpp index 106ad9e859..2016844016 100644 --- a/src/util/screenlog.cpp +++ b/src/util/screenlog.cpp @@ -31,11 +31,34 @@ namespace openspace { -ScreenLog::ScreenLog() {} +ScreenLog::ScreenLog(std::chrono::seconds timeToLive) + : _timeToLive(std::move(timeToLive)) +{} + +void ScreenLog::removeExpiredEntries() { + auto t = std::chrono::steady_clock::now(); + auto ttl = _timeToLive; + + _entries.erase( + std::remove_if( + _entries.begin(), + _entries.end(), + [t, ttl](const LogEntry& e) { return (t - e.timeStamp) > ttl; } + ), + _entries.end() + ); +} void ScreenLog::log(ghoul::logging::LogManager::LogLevel level, const std::string& category, const std::string& message) { - if (level >= ghoul::logging::LogManager::LogLevel::Info) - _entries.emplace_back(level, OsEng.windowWrapper().time(), Log::getTimeString(), category, message); + if (level >= ghoul::logging::LogManager::LogLevel::Info) { + _entries.emplace_back( + level, + std::chrono::steady_clock::now(), + Log::getTimeString(), + category, + message + ); + } // Once reaching maximum size, reduce to half if (_entries.size() > MaximumSize) { From c99666e75a0a7df6dc176f2d610d10cc4931cec3 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 14 Dec 2015 16:44:13 -0800 Subject: [PATCH 067/122] Cleaning ConfigurationManager and OpenSpaceEngine Updated Ghoul version --- ext/ghoul | 2 +- .../openspace/engine/configurationmanager.h | 64 ++++++++++++++++++- src/engine/configurationmanager.cpp | 20 +++--- src/engine/openspaceengine.cpp | 1 + 4 files changed, 72 insertions(+), 15 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index ff01cac350..aef83ca794 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit ff01cac35077a6fe298f8b691466ee9cb704200b +Subproject commit aef83ca794d1153c8537d19d16222a3a1075d4ab diff --git a/include/openspace/engine/configurationmanager.h b/include/openspace/engine/configurationmanager.h index 46ce99a67f..c20bf4eedd 100644 --- a/include/openspace/engine/configurationmanager.h +++ b/include/openspace/engine/configurationmanager.h @@ -41,32 +41,92 @@ class ConfigurationManager : public ghoul::Dictionary { public: /// The key that stores the subdirectory containing all predefined path tokens static const std::string KeyPaths; - /// + /// The key that stores the location to the cache directory used to store all the + /// permanent and non-permanent cached files static const std::string KeyCache; + /// The key that stores the main directory for fonts static const std::string KeyFonts; + /// The key that stores the location of the SGCT configuration file that is used on + /// application launch static const std::string KeyConfigSgct; + /// The key that stores the type of Lua documentation that should be stored static const std::string KeyLuaDocumentationType; + /// The key that stores the save location of the Lua documentation static const std::string KeyLuaDocumentationFile; + /// The key that stores the type of Property documentation that should be stored static const std::string KeyPropertyDocumentationType; + /// The key that stores the save location of the Property documentation static const std::string KeyPropertyDocumentationFile; + /// The key that stores the location of the scene file that is initially loaded static const std::string KeyConfigScene; - static const std::string KeyEnableGui; + /// The key that stores the subdirectory containing a list of all startup scripts to + /// be executed on application start before the scene file is loaded static const std::string KeyStartupScript; + /// The key that stores the subdirectory containing a list of all settings scripts to + /// be executed on application start and after the scene file is loaded static const std::string KeySettingsScript; + /// The key that stores the location of the SPICE time kernel to be loaded on + /// application start static const std::string KeySpiceTimeKernel; + /// The key that stores the location of the SPICE leapsecond kernel to be loaded on + /// application start static const std::string KeySpiceLeapsecondKernel; + /// The key that stores the desired LogLevel for the whole application + /// \sa ghoul::logging::LogManager static const std::string KeyLogLevel; + /// The key that stores whether the log should be immediately flushed after a n + /// \sa ghoul::logging::LogManager static const std::string KeyLogImmediateFlush; + /// The key that stores a subdirectory with a description for additional + /// ghoul::logging::Log%s to be created + /// \sa LogFactory static const std::string KeyLogs; + /// The key that stores the verbosity (None, Minimal, Default, Full) of the system + /// capabilities components static const std::string KeyCapabilitiesVerbosity; + /// The key that stores whether the master node should perform rendering just function + /// as a pure manager static const std::string KeyDisableMasterRendering; + /// The key that sets the request URL that is used to request additional data to be + /// downloaded static const std::string KeyDownloadRequestURL; + /** + * Iteratively walks the directory structure starting with \p filename to find the + * base name compoenent of \p filename. The directory structure is searched by first + * searching the current directory and then moving iteratively to the the parent + * directory. + * \param filename The fully qualified filename to be searched for + * \return The path to the file that was found with the same base name as \p filename + * but higher up in the file structure. + * \throw ghoul::RuntimeError If the configuration could not be found + * \pre \p filename must not be empty + */ static std::string findConfiguration(const std::string& filename); + /** + * Load the provided configuration file (\p filename) into this Dictionary. All paths + * that are specified in the configuration file will automatically be registered in + * the ghoul::filesystem::FileSystem. + * \param filename The filename to be loaded + * \throw ghoul::FileNotFoundException If the \p filename did not exist + * \throw ghoul::RuntimeError If the configuration file was not complete (i.e., did + * not specify the necessary keys KeyPaths, KeyPaths.KeyCache, KeyFonts, and + * KeyConfigSgct) + * \throw ghoul::lua::LuaRuntimeException If there was Lua-based error loading the + * configuration file + * \pre \p filename must not be empty + */ void loadFromFile(const std::string& filename); private: + /** + * Checks whether the loaded configuration file is complete, that is specifying the + * necessary keys KeyPaths, KeyPaths.KeyCache, KeyFonts, and KeyConfigSgct. The method + * will log fatal errors if a key is missing. + * \return true if the configuration file was complete; + * false otherwise + */ bool checkCompleteness() const; }; diff --git a/src/engine/configurationmanager.cpp b/src/engine/configurationmanager.cpp index fe8c24987c..d4c713f3ff 100644 --- a/src/engine/configurationmanager.cpp +++ b/src/engine/configurationmanager.cpp @@ -52,7 +52,6 @@ const string ConfigurationManager::KeyPropertyDocumentationType = const string ConfigurationManager::KeyPropertyDocumentationFile = "PropertyDocumentationFile.File"; const string ConfigurationManager::KeyConfigScene = "Scene"; -const string ConfigurationManager::KeyEnableGui = "EnableGUI"; const string ConfigurationManager::KeyStartupScript = "StartupScripts"; const string ConfigurationManager::KeySettingsScript = "SettingsScripts"; const string ConfigurationManager::KeySpiceTimeKernel = "SpiceKernel.Time"; @@ -66,6 +65,8 @@ const string ConfigurationManager::KeyDisableMasterRendering = "DisableRendering const string ConfigurationManager::KeyDownloadRequestURL = "DownloadRequestURL"; string ConfigurationManager::findConfiguration(const string& filename) { + ghoul_assert(!filename.empty(), "Filename must not be empty"); + using ghoul::filesystem::Directory; Directory directory = FileSys.currentDirectory(); @@ -110,13 +111,6 @@ void ConfigurationManager::loadFromFile(const string& filename) { ghoul::lua::loadDictionaryFromFile(filename, *this); // Register all the paths -// const bool hasPath = hasKeyAndValue(KeyPaths); -// if (!hasPath) { -// throw ghoul::RuntimeError( -// "Configuration does not contain the key '" + KeyPaths + "'", -// "ConfifgurationManager" -// ); -// } ghoul::Dictionary dictionary = value(KeyPaths); std::vector pathKeys = dictionary.keys(); @@ -135,14 +129,16 @@ void ConfigurationManager::loadFromFile(const string& filename) { } bool complete = checkCompleteness(); - if (!complete) - return false; + if (!complete) { + throw ghoul::RuntimeError( + "Configuration file '" + filename + "' was not complete", + "ConfigurationManager" + ); + } // Remove the Paths dictionary from the configuration manager as those paths might // change later and we don't want to be forced to keep our local copy up to date removeKey(KeyPaths); - - return true; } bool ConfigurationManager::checkCompleteness() const { diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index ac2ef92e54..a0bc517450 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -306,6 +306,7 @@ bool OpenSpaceEngine::initialize() { Verbosity verbosity = Verbosity::Default; if (configurationManager().hasKeyAndValue(ConfigurationManager::KeyCapabilitiesVerbosity)) { std::map verbosityMap = { + { "None", Verbosity::None }, { "Minimal", Verbosity::Minimal }, { "Default", Verbosity::Default }, { "Full", Verbosity::Full } From c92fc923f9f52a09010648564d31af40c93f7b3e Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 14 Dec 2015 17:21:22 -0800 Subject: [PATCH 068/122] Remove constants.h file Reenable LuaConsole rendering --- ext/ghoul | 2 +- .../openspace/engine/configurationmanager.h | 1 - include/openspace/rendering/renderengine.h | 3 + include/openspace/util/constants.h | 47 -------------- modules/base/rendering/renderablemodel.cpp | 5 +- modules/base/rendering/renderableplanet.cpp | 7 ++- .../base/rendering/simplespheregeometry.cpp | 4 +- .../rendering/renderablefieldlines.cpp | 5 +- .../rendering/renderablemodelprojection.cpp | 5 +- .../rendering/renderableplanetprojection.cpp | 5 +- .../simplespheregeometryprojection.cpp | 4 +- .../volume/rendering/renderablevolumegl.cpp | 3 +- src/abuffer/abuffervisualizer.cpp | 62 +++++++++---------- src/engine/configurationmanager.cpp | 2 - src/interaction/luaconsole.cpp | 20 ++++-- src/rendering/renderable.cpp | 7 ++- src/rendering/renderengine.cpp | 9 ++- 17 files changed, 83 insertions(+), 108 deletions(-) delete mode 100644 include/openspace/util/constants.h diff --git a/ext/ghoul b/ext/ghoul index aef83ca794..c8d2a2df4a 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit aef83ca794d1153c8537d19d16222a3a1075d4ab +Subproject commit c8d2a2df4aa62c929fa0dcc648c930956741add4 diff --git a/include/openspace/engine/configurationmanager.h b/include/openspace/engine/configurationmanager.h index c20bf4eedd..d9bb6cb499 100644 --- a/include/openspace/engine/configurationmanager.h +++ b/include/openspace/engine/configurationmanager.h @@ -100,7 +100,6 @@ public: * \return The path to the file that was found with the same base name as \p filename * but higher up in the file structure. * \throw ghoul::RuntimeError If the configuration could not be found - * \pre \p filename must not be empty */ static std::string findConfiguration(const std::string& filename); diff --git a/include/openspace/rendering/renderengine.h b/include/openspace/rendering/renderengine.h index bab2a4ee05..1a7c971cc7 100644 --- a/include/openspace/rendering/renderengine.h +++ b/include/openspace/rendering/renderengine.h @@ -59,6 +59,9 @@ public: }; static const std::string PerformanceMeasurementSharedData; + + static const std::string KeyFontMono; + static const std::string KeyFontLight; RenderEngine(); ~RenderEngine(); diff --git a/include/openspace/util/constants.h b/include/openspace/util/constants.h deleted file mode 100644 index 2c05890afb..0000000000 --- a/include/openspace/util/constants.h +++ /dev/null @@ -1,47 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2015 * - * * - * 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 __CONSTANTS_H__ -#define __CONSTANTS_H__ - -#include - -namespace openspace { -namespace constants { - -namespace fonts { - const std::string keySGCT = "SGCTFont"; - const std::string keyMono = "Mono"; - const std::string keyLight = "Light"; -} // namespace fonts - -namespace scenegraphnode { - const std::string keyName = "Name"; -} // namespace scenegraphnode - -} // namespace constants -} // namespace openspace - - -#endif // __CONSTANTS_H__ \ No newline at end of file diff --git a/modules/base/rendering/renderablemodel.cpp b/modules/base/rendering/renderablemodel.cpp index f13f9953bb..062169207a 100644 --- a/modules/base/rendering/renderablemodel.cpp +++ b/modules/base/rendering/renderablemodel.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -72,13 +73,13 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary) , _frameCount(0) { std::string name; - bool success = dictionary.getValue(constants::scenegraphnode::keyName, name); + bool success = dictionary.getValue(SceneGraphNode::KeyName, name); ghoul_assert(success, "Name was not passed to RenderableModel"); ghoul::Dictionary geometryDictionary; success = dictionary.getValue(keyGeometry, geometryDictionary); if (success) { - geometryDictionary.setValue(constants::scenegraphnode::keyName, name); + geometryDictionary.setValue(SceneGraphNode::KeyName, name); _geometry = modelgeometry::ModelGeometry::createFromDictionary(geometryDictionary); } diff --git a/modules/base/rendering/renderableplanet.cpp b/modules/base/rendering/renderableplanet.cpp index 84e0f99aa5..70ec4ef995 100644 --- a/modules/base/rendering/renderableplanet.cpp +++ b/modules/base/rendering/renderableplanet.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -65,9 +66,9 @@ RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary) , _hasNightTexture(false) { std::string name; - bool success = dictionary.getValue(constants::scenegraphnode::keyName, name); + bool success = dictionary.getValue(SceneGraphNode::KeyName, name); ghoul_assert(success, - "RenderablePlanet need the '" < #include #include +#include namespace { const std::string _loggerCat = "SimpleSphereGeometry"; @@ -48,12 +49,11 @@ SimpleSphereGeometry::SimpleSphereGeometry(const ghoul::Dictionary& dictionary) , _segments("segments", "Segments", 20, 1, 50) , _sphere(nullptr) { - using constants::scenegraphnode::keyName; using constants::simplespheregeometry::keyRadius; using constants::simplespheregeometry::keySegments; // The name is passed down from the SceneGraphNode - bool success = dictionary.getValue(keyName, _name); + bool success = dictionary.getValue(SceneGraphNode::KeyName, _name); assert(success); glm::vec4 radius; diff --git a/modules/fieldlines/rendering/renderablefieldlines.cpp b/modules/fieldlines/rendering/renderablefieldlines.cpp index 3e82ac773b..025b46977e 100644 --- a/modules/fieldlines/rendering/renderablefieldlines.cpp +++ b/modules/fieldlines/rendering/renderablefieldlines.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -91,12 +92,12 @@ RenderableFieldlines::RenderableFieldlines(const ghoul::Dictionary& dictionary) , _vertexPositionBuffer(0) { ghoul_assert( - dictionary.hasKeyAndValue(constants::scenegraphnode::keyName), + dictionary.hasKeyAndValue(SceneGraphNode::KeyName), "Renderable does not have a name" ); std::string name; - dictionary.getValue(constants::scenegraphnode::keyName, name); + dictionary.getValue(SceneGraphNode::KeyName, name); _loggerCat = "RenderableFieldlines [" + name + "]"; diff --git a/modules/newhorizons/rendering/renderablemodelprojection.cpp b/modules/newhorizons/rendering/renderablemodelprojection.cpp index 76472ca906..2ad84751d6 100644 --- a/modules/newhorizons/rendering/renderablemodelprojection.cpp +++ b/modules/newhorizons/rendering/renderablemodelprojection.cpp @@ -32,6 +32,7 @@ #include #include +#include #include #include "imgui.h" @@ -91,13 +92,13 @@ RenderableModelProjection::RenderableModelProjection(const ghoul::Dictionary& di , _programIsDirty(false) { std::string name; - bool success = dictionary.getValue(constants::scenegraphnode::keyName, name); + bool success = dictionary.getValue(SceneGraphNode::KeyName, name); ghoul_assert(success, "Name was not passed to RenderableModelProjection"); ghoul::Dictionary geometryDictionary; success = dictionary.getValue(keyGeometry, geometryDictionary); if (success) { - geometryDictionary.setValue(constants::scenegraphnode::keyName, name); + geometryDictionary.setValue(SceneGraphNode::KeyName, name); _geometry = modelgeometry::ModelGeometry::createFromDictionary(geometryDictionary); } diff --git a/modules/newhorizons/rendering/renderableplanetprojection.cpp b/modules/newhorizons/rendering/renderableplanetprojection.cpp index 486e5578cb..ab698cf771 100644 --- a/modules/newhorizons/rendering/renderableplanetprojection.cpp +++ b/modules/newhorizons/rendering/renderableplanetprojection.cpp @@ -32,6 +32,7 @@ #include //#include #include +#include #include #include @@ -99,7 +100,7 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& , _clearingImage(absPath("${OPENSPACE_DATA}/scene/common/textures/clear.png")) { std::string name; - bool success = dictionary.getValue(constants::scenegraphnode::keyName, name); + bool success = dictionary.getValue(SceneGraphNode::KeyName, name); ghoul_assert(success, ""); _defaultProjImage = absPath("textures/defaultProj.png"); @@ -108,7 +109,7 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& success = dictionary.getValue( keyGeometry, geometryDictionary); if (success) { - geometryDictionary.setValue(constants::scenegraphnode::keyName, name); + geometryDictionary.setValue(SceneGraphNode::KeyName, name); _geometry = planetgeometryprojection::PlanetGeometryProjection::createFromDictionary(geometryDictionary); } diff --git a/modules/newhorizons/rendering/simplespheregeometryprojection.cpp b/modules/newhorizons/rendering/simplespheregeometryprojection.cpp index 8d840a70a0..4d48460157 100644 --- a/modules/newhorizons/rendering/simplespheregeometryprojection.cpp +++ b/modules/newhorizons/rendering/simplespheregeometryprojection.cpp @@ -24,6 +24,7 @@ #include #include +#include namespace { const std::string _loggerCat = "SimpleSphereGeometryProjection"; @@ -47,12 +48,11 @@ SimpleSphereGeometryProjection::SimpleSphereGeometryProjection(const ghoul::Dict , _segments("segments", "Segments", 20, 1, 1000) , _planet(nullptr) { - using constants::scenegraphnode::keyName; using constants::simplespheregeometryprojection::keyRadius; using constants::simplespheregeometryprojection::keySegments; // The name is passed down from the SceneGraphNode - bool success = dictionary.getValue(keyName, _name); + bool success = dictionary.getValue(SceneGraphNode::KeyName, _name); assert(success); // removing "Projection"-suffix from name for SPICE compability, TODO: better solution @AA diff --git a/modules/volume/rendering/renderablevolumegl.cpp b/modules/volume/rendering/renderablevolumegl.cpp index 2ff94ce6d7..1a2ee524f0 100644 --- a/modules/volume/rendering/renderablevolumegl.cpp +++ b/modules/volume/rendering/renderablevolumegl.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -68,7 +69,7 @@ RenderableVolumeGL::RenderableVolumeGL(const ghoul::Dictionary& dictionary) , _id(-1) { std::string name; - bool success = dictionary.getValue(constants::scenegraphnode::keyName, name); + bool success = dictionary.getValue(SceneGraphNode::KeyName, name); assert(success); _filename = ""; diff --git a/src/abuffer/abuffervisualizer.cpp b/src/abuffer/abuffervisualizer.cpp index b1082cc521..f109c641bf 100644 --- a/src/abuffer/abuffervisualizer.cpp +++ b/src/abuffer/abuffervisualizer.cpp @@ -140,37 +140,37 @@ void ABufferVisualizer::render() { _pointcloudProgram->deactivate(); - const int font_size_light = 8; - const sgct_text::Font* fontLight = sgct_text::FontManager::instance()->getFont(constants::fonts::keyLight, font_size_light); - - const glm::mat4 scale = glm::scale(glm::mat4(1.0), glm::vec3(0.04, 0.04, 0.04)); - glm::mat4 translate, mvp; - - const glm::mat4 viewProjMatrix = OsEng.windowWrapper().viewProjectionMatrix(); - translate = glm::translate(glm::mat4(1.0), glm::vec3(0, 0, 0)); - mvp = viewProjMatrix*modelMatrix*translate*rotationText*scale; - Freetype::print3d(fontLight, mvp, "(0,0,0)"); - translate = glm::translate(glm::mat4(1.0), glm::vec3(0, 0, 1)); - mvp = viewProjMatrix*modelMatrix*translate*rotationText*scale; - Freetype::print3d(fontLight, mvp, "(0,0,1)"); - translate = glm::translate(glm::mat4(1.0), glm::vec3(0, 1, 0)); - mvp = viewProjMatrix*modelMatrix*translate*rotationText*scale; - Freetype::print3d(fontLight, mvp, "(0,1,0)"); - translate = glm::translate(glm::mat4(1.0), glm::vec3(1, 0, 0)); - mvp = viewProjMatrix*modelMatrix*translate*rotationText*scale; - Freetype::print3d(fontLight, mvp, "(1,0,0)"); - translate = glm::translate(glm::mat4(1.0), glm::vec3(0, 1, 1)); - mvp = viewProjMatrix*modelMatrix*translate*rotationText*scale; - Freetype::print3d(fontLight, mvp, "(0,1,1)"); - translate = glm::translate(glm::mat4(1.0), glm::vec3(1, 0, 1)); - mvp = viewProjMatrix*modelMatrix*translate*rotationText*scale; - Freetype::print3d(fontLight, mvp, "(1,0,1)"); - translate = glm::translate(glm::mat4(1.0), glm::vec3(1, 1, 0)); - mvp = viewProjMatrix*modelMatrix*translate*rotationText*scale; - Freetype::print3d(fontLight, mvp, "(1,1,0)"); - translate = glm::translate(glm::mat4(1.0), glm::vec3(1, 1, 1)); - mvp = viewProjMatrix*modelMatrix*translate*rotationText*scale; - Freetype::print3d(fontLight, mvp, "(1,1,1)"); +// const int font_size_light = 8; +// const sgct_text::Font* fontLight = sgct_text::FontManager::instance()->getFont(constants::fonts::keyLight, font_size_light); +// +// const glm::mat4 scale = glm::scale(glm::mat4(1.0), glm::vec3(0.04, 0.04, 0.04)); +// glm::mat4 translate, mvp; +// +// const glm::mat4 viewProjMatrix = OsEng.windowWrapper().viewProjectionMatrix(); +// translate = glm::translate(glm::mat4(1.0), glm::vec3(0, 0, 0)); +// mvp = viewProjMatrix*modelMatrix*translate*rotationText*scale; +// Freetype::print3d(fontLight, mvp, "(0,0,0)"); +// translate = glm::translate(glm::mat4(1.0), glm::vec3(0, 0, 1)); +// mvp = viewProjMatrix*modelMatrix*translate*rotationText*scale; +// Freetype::print3d(fontLight, mvp, "(0,0,1)"); +// translate = glm::translate(glm::mat4(1.0), glm::vec3(0, 1, 0)); +// mvp = viewProjMatrix*modelMatrix*translate*rotationText*scale; +// Freetype::print3d(fontLight, mvp, "(0,1,0)"); +// translate = glm::translate(glm::mat4(1.0), glm::vec3(1, 0, 0)); +// mvp = viewProjMatrix*modelMatrix*translate*rotationText*scale; +// Freetype::print3d(fontLight, mvp, "(1,0,0)"); +// translate = glm::translate(glm::mat4(1.0), glm::vec3(0, 1, 1)); +// mvp = viewProjMatrix*modelMatrix*translate*rotationText*scale; +// Freetype::print3d(fontLight, mvp, "(0,1,1)"); +// translate = glm::translate(glm::mat4(1.0), glm::vec3(1, 0, 1)); +// mvp = viewProjMatrix*modelMatrix*translate*rotationText*scale; +// Freetype::print3d(fontLight, mvp, "(1,0,1)"); +// translate = glm::translate(glm::mat4(1.0), glm::vec3(1, 1, 0)); +// mvp = viewProjMatrix*modelMatrix*translate*rotationText*scale; +// Freetype::print3d(fontLight, mvp, "(1,1,0)"); +// translate = glm::translate(glm::mat4(1.0), glm::vec3(1, 1, 1)); +// mvp = viewProjMatrix*modelMatrix*translate*rotationText*scale; +// Freetype::print3d(fontLight, mvp, "(1,1,1)"); } void ABufferVisualizer::initializeMarkers() { diff --git a/src/engine/configurationmanager.cpp b/src/engine/configurationmanager.cpp index d4c713f3ff..12afb65fa7 100644 --- a/src/engine/configurationmanager.cpp +++ b/src/engine/configurationmanager.cpp @@ -65,8 +65,6 @@ const string ConfigurationManager::KeyDisableMasterRendering = "DisableRendering const string ConfigurationManager::KeyDownloadRequestURL = "DownloadRequestURL"; string ConfigurationManager::findConfiguration(const string& filename) { - ghoul_assert(!filename.empty(), "Filename must not be empty"); - using ghoul::filesystem::Directory; Directory directory = FileSys.currentDirectory(); diff --git a/src/interaction/luaconsole.cpp b/src/interaction/luaconsole.cpp index 38076ee860..fed9010af4 100644 --- a/src/interaction/luaconsole.cpp +++ b/src/interaction/luaconsole.cpp @@ -32,6 +32,9 @@ #include #include #include +#include +#include +#include #include #include @@ -294,9 +297,16 @@ void LuaConsole::render() { const glm::vec4 red(1, 0, 0, 1); const glm::vec4 green(0, 1, 0, 1); const glm::vec4 white(1, 1, 1, 1); - const sgct_text::Font* font = sgct_text::FontManager::instance()->getFont(constants::fonts::keyMono, static_cast(font_size)); - sgct_text::print(font, 15.0f, startY, red, "$"); - sgct_text::print(font, 15.0f + font_size, startY, white, "%s", _commands.at(_activeCommand).c_str()); + std::shared_ptr font = OsEng.fontManager().font("Mono", font_size); +// const sgct_text::Font* font = sgct_text::FontManager::instance()->getFont(constants::fonts::keyMono, static_cast(font_size)); + + using ghoul::fontrendering::RenderFont; + + RenderFont(*font, glm::vec2(15.f, startY), red, "$"); + RenderFont(*font, glm::vec2(15.f + font_size, startY), white, "%s", _commands.at(_activeCommand).c_str()); + +// sgct_text::print(font, 15.0f, startY, red, "$"); +// sgct_text::print(font, 15.0f + font_size, startY, white, "%s", _commands.at(_activeCommand).c_str()); size_t n = std::count(_commands.at(_activeCommand).begin(), _commands.at(_activeCommand).begin() + _inputPosition, '\n'); size_t p = _commands.at(_activeCommand).find_last_of('\n', _inputPosition); @@ -319,7 +329,9 @@ void LuaConsole::render() { std::stringstream ss; ss << "%" << linepos + 1 << "s"; - sgct_text::print(font, 15.0f + font_size*0.5f, startY - (font_size)*(n + 1)*3.0f / 2.0f, green, ss.str().c_str(), "^"); + RenderFont(*font, glm::vec2(15.f + font_size * 0.5f, startY - (font_size)*(n + 1)*3.0f / 2.0f), green, ss.str().c_str(), "^"); + +// sgct_text::print(font, 15.0f + font_size*0.5f, startY - (font_size)*(n + 1)*3.0f / 2.0f, green, ss.str().c_str(), "^"); } Key LuaConsole::commandInputButton() { diff --git a/src/rendering/renderable.cpp b/src/rendering/renderable.cpp index 31d1d1e66a..eabf3a940b 100644 --- a/src/rendering/renderable.cpp +++ b/src/rendering/renderable.cpp @@ -28,6 +28,7 @@ #include #include #include +#include // ghoul #include @@ -48,7 +49,7 @@ namespace openspace { Renderable* Renderable::createFromDictionary(const ghoul::Dictionary& dictionary) { // The name is passed down from the SceneGraphNode std::string name; - bool success = dictionary.getValue(constants::scenegraphnode::keyName, name); + bool success = dictionary.getValue(SceneGraphNode::KeyName, name); assert(success); std::string renderableType; @@ -80,8 +81,8 @@ Renderable::Renderable(const ghoul::Dictionary& dictionary) setName("renderable"); #ifndef NDEBUG std::string name; - ghoul_assert(dictionary.getValue(constants::scenegraphnode::keyName, name), - "Scenegraphnode need to specify '" << constants::scenegraphnode::keyName + ghoul_assert(dictionary.getValue(SceneGraphNode::KeyName, name), + "Scenegraphnode need to specify '" << SceneGraphNode::KeyName << "' because renderables is going to use this for debugging!"); #endif diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index e249ce9d8b..9cee5b231c 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -94,6 +94,9 @@ namespace openspace { const std::string RenderEngine::PerformanceMeasurementSharedData = "OpenSpacePerformanceMeasurementSharedData"; +const std::string RenderEngine::KeyFontMono = "Mono"; +const std::string RenderEngine::KeyFontLight = "Light"; + RenderEngine::RenderEngine() : _mainCamera(nullptr) , _sceneGraph(nullptr) @@ -207,11 +210,11 @@ bool RenderEngine::initializeGL() { const float fontSizeTime = 15.f; - _fontDate = OsEng.fontManager().font(constants::fonts::keyMono, fontSizeTime); + _fontDate = OsEng.fontManager().font(KeyFontMono, fontSizeTime); const float fontSizeMono = 10.f; - _fontInfo = OsEng.fontManager().font(constants::fonts::keyMono, fontSizeMono); + _fontInfo = OsEng.fontManager().font(KeyFontMono, fontSizeMono); const float fontSizeLight = 8.f; - _fontLog = OsEng.fontManager().font(constants::fonts::keyLight, fontSizeLight); + _fontLog = OsEng.fontManager().font(KeyFontLight, fontSizeLight); From 177571195c43383d10830bd6aa820e77eae25c88 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 14 Dec 2015 17:36:15 -0800 Subject: [PATCH 069/122] Completely remove references to constants.h --- include/openspace/util/factorymanager.h | 26 +++++++++++++++---- modules/base/rendering/modelgeometry.cpp | 1 - modules/base/rendering/planetgeometry.cpp | 2 -- modules/base/rendering/renderablemodel.cpp | 1 - modules/base/rendering/renderablepath.cpp | 1 - modules/base/rendering/renderableplane.cpp | 1 - modules/base/rendering/renderableplanet.cpp | 1 - modules/base/rendering/renderablesphere.cpp | 1 - .../rendering/renderablesphericalgrid.cpp | 1 - modules/base/rendering/renderabletrail.cpp | 1 - .../base/rendering/simplespheregeometry.cpp | 1 - modules/base/rendering/wavefrontgeometry.cpp | 1 - .../rendering/renderablefieldlines.cpp | 1 - .../newhorizons/rendering/renderablefov.cpp | 1 - .../rendering/renderablemodelprojection.cpp | 1 - .../rendering/renderableplaneprojection.cpp | 1 - .../rendering/renderableplanetprojection.cpp | 1 - .../rendering/renderableshadowcylinder.cpp | 1 - .../simplespheregeometryprojection.cpp | 1 - modules/volume/rendering/renderablevolume.cpp | 1 - .../volume/rendering/renderablevolumegl.cpp | 1 - src/CMakeLists.txt | 1 - src/abuffer/abuffervisualizer.cpp | 1 - src/engine/configurationmanager.cpp | 2 -- src/engine/openspaceengine.cpp | 5 +++- src/interaction/luaconsole.cpp | 1 - src/rendering/renderable.cpp | 1 - src/rendering/renderengine.cpp | 1 - src/scene/ephemeris.cpp | 1 - src/scene/scene.cpp | 1 - src/scene/scenegraphnode.cpp | 1 - src/util/factorymanager.cpp | 20 ++++++-------- src/util/time.cpp | 1 - 33 files changed, 33 insertions(+), 50 deletions(-) diff --git a/include/openspace/util/factorymanager.h b/include/openspace/util/factorymanager.h index d9903c6712..ce74515a86 100644 --- a/include/openspace/util/factorymanager.h +++ b/include/openspace/util/factorymanager.h @@ -25,25 +25,41 @@ #ifndef __FACTORYMANAGER_H__ #define __FACTORYMANAGER_H__ -// ghoul includes #include namespace openspace { +/** + * Singleton factory class that handles a variety of ghoul::TemplateFactory%s and makes + * them available through the #addFactory and factory #methods. Each + * ghoul::TemplateFactory can only be added once and can be accessed by its type. + */ class FactoryManager { public: /** * Static initializer that initializes the static member. This needs to be done before - * the FactoryManager can be used. If the manager has been already initialized, an - * assertion will be triggered. + * the FactoryManager can be used. + * \pre The FactoryManager must not have been initialized before */ static void initialize(); + + /** + * Deinitializes the static member and all the registered ghoul::TemplateFactory%s. + * \pre The FactoryManager must have been initialized before + */ static void deinitialize(); /** - * This method returns a reference to the initialized FactoryManager. If the manager - * has not been initialized, an assertion will be triggered. + * Returns true if the static FactoryManager has already been + * initiailzed, false otherwise. + * \return The initialization status of the static FactoryManager + */ + static bool isInitialized(); + + /** + * This method returns a reference to the initialized FactoryManager. * \return An initialized reference to the singleton manager + * \pre The FactoryManager must have been initialized before */ static FactoryManager& ref(); diff --git a/modules/base/rendering/modelgeometry.cpp b/modules/base/rendering/modelgeometry.cpp index 1fa6720cf1..51e616955b 100644 --- a/modules/base/rendering/modelgeometry.cpp +++ b/modules/base/rendering/modelgeometry.cpp @@ -24,7 +24,6 @@ #include #include -#include #include #include diff --git a/modules/base/rendering/planetgeometry.cpp b/modules/base/rendering/planetgeometry.cpp index 062fb8db39..6498310cfd 100644 --- a/modules/base/rendering/planetgeometry.cpp +++ b/modules/base/rendering/planetgeometry.cpp @@ -24,8 +24,6 @@ #include #include -#include -#include namespace { const std::string _loggerCat = "PlanetGeometry"; diff --git a/modules/base/rendering/renderablemodel.cpp b/modules/base/rendering/renderablemodel.cpp index 062169207a..fc2606cd9f 100644 --- a/modules/base/rendering/renderablemodel.cpp +++ b/modules/base/rendering/renderablemodel.cpp @@ -27,7 +27,6 @@ // open space includes #include -#include #include #include diff --git a/modules/base/rendering/renderablepath.cpp b/modules/base/rendering/renderablepath.cpp index 12bd455431..a8d4b936ed 100644 --- a/modules/base/rendering/renderablepath.cpp +++ b/modules/base/rendering/renderablepath.cpp @@ -25,7 +25,6 @@ #include #include -#include #include #include #include diff --git a/modules/base/rendering/renderableplane.cpp b/modules/base/rendering/renderableplane.cpp index 096f972cee..447d04e076 100644 --- a/modules/base/rendering/renderableplane.cpp +++ b/modules/base/rendering/renderableplane.cpp @@ -26,7 +26,6 @@ #include #include #include -#include #include #include diff --git a/modules/base/rendering/renderableplanet.cpp b/modules/base/rendering/renderableplanet.cpp index 70ec4ef995..a6e49e24ef 100644 --- a/modules/base/rendering/renderableplanet.cpp +++ b/modules/base/rendering/renderableplanet.cpp @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include diff --git a/modules/base/rendering/renderablesphere.cpp b/modules/base/rendering/renderablesphere.cpp index e3a20dfabd..eb37cddacd 100644 --- a/modules/base/rendering/renderablesphere.cpp +++ b/modules/base/rendering/renderablesphere.cpp @@ -23,7 +23,6 @@ ****************************************************************************************/ #include -#include #include #include diff --git a/modules/base/rendering/renderablesphericalgrid.cpp b/modules/base/rendering/renderablesphericalgrid.cpp index 41a4228589..97023f1daa 100644 --- a/modules/base/rendering/renderablesphericalgrid.cpp +++ b/modules/base/rendering/renderablesphericalgrid.cpp @@ -26,7 +26,6 @@ #include #include -#include #include #define _USE_MATH_DEFINES diff --git a/modules/base/rendering/renderabletrail.cpp b/modules/base/rendering/renderabletrail.cpp index b158cb3ad7..e2871f8b6b 100644 --- a/modules/base/rendering/renderabletrail.cpp +++ b/modules/base/rendering/renderabletrail.cpp @@ -25,7 +25,6 @@ #include #include -#include #include #include #include diff --git a/modules/base/rendering/simplespheregeometry.cpp b/modules/base/rendering/simplespheregeometry.cpp index 132b2a9c9c..a4563abfd8 100644 --- a/modules/base/rendering/simplespheregeometry.cpp +++ b/modules/base/rendering/simplespheregeometry.cpp @@ -23,7 +23,6 @@ ****************************************************************************************/ #include -#include #include #include diff --git a/modules/base/rendering/wavefrontgeometry.cpp b/modules/base/rendering/wavefrontgeometry.cpp index 39041eda42..0b89cf1f54 100644 --- a/modules/base/rendering/wavefrontgeometry.cpp +++ b/modules/base/rendering/wavefrontgeometry.cpp @@ -24,7 +24,6 @@ #include -#include #include "ghoul/logging/logmanager.h" #include diff --git a/modules/fieldlines/rendering/renderablefieldlines.cpp b/modules/fieldlines/rendering/renderablefieldlines.cpp index 025b46977e..788caf06d2 100644 --- a/modules/fieldlines/rendering/renderablefieldlines.cpp +++ b/modules/fieldlines/rendering/renderablefieldlines.cpp @@ -26,7 +26,6 @@ #include #include #include -#include #include #include diff --git a/modules/newhorizons/rendering/renderablefov.cpp b/modules/newhorizons/rendering/renderablefov.cpp index 0ca3ab8bbc..2f251849bc 100644 --- a/modules/newhorizons/rendering/renderablefov.cpp +++ b/modules/newhorizons/rendering/renderablefov.cpp @@ -26,7 +26,6 @@ #include #include -#include #include #include diff --git a/modules/newhorizons/rendering/renderablemodelprojection.cpp b/modules/newhorizons/rendering/renderablemodelprojection.cpp index 2ad84751d6..6e1eb0d8d0 100644 --- a/modules/newhorizons/rendering/renderablemodelprojection.cpp +++ b/modules/newhorizons/rendering/renderablemodelprojection.cpp @@ -24,7 +24,6 @@ // open space includes #include -#include #include #include diff --git a/modules/newhorizons/rendering/renderableplaneprojection.cpp b/modules/newhorizons/rendering/renderableplaneprojection.cpp index 6c8cc6e0b2..e35a07095f 100644 --- a/modules/newhorizons/rendering/renderableplaneprojection.cpp +++ b/modules/newhorizons/rendering/renderableplaneprojection.cpp @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include diff --git a/modules/newhorizons/rendering/renderableplanetprojection.cpp b/modules/newhorizons/rendering/renderableplanetprojection.cpp index ab698cf771..af08012389 100644 --- a/modules/newhorizons/rendering/renderableplanetprojection.cpp +++ b/modules/newhorizons/rendering/renderableplanetprojection.cpp @@ -24,7 +24,6 @@ // open space includes #include -#include #include #include diff --git a/modules/newhorizons/rendering/renderableshadowcylinder.cpp b/modules/newhorizons/rendering/renderableshadowcylinder.cpp index 3a35d48011..050ec6f39d 100644 --- a/modules/newhorizons/rendering/renderableshadowcylinder.cpp +++ b/modules/newhorizons/rendering/renderableshadowcylinder.cpp @@ -26,7 +26,6 @@ #include #include #include -#include #include #include diff --git a/modules/newhorizons/rendering/simplespheregeometryprojection.cpp b/modules/newhorizons/rendering/simplespheregeometryprojection.cpp index 4d48460157..e8f1471848 100644 --- a/modules/newhorizons/rendering/simplespheregeometryprojection.cpp +++ b/modules/newhorizons/rendering/simplespheregeometryprojection.cpp @@ -23,7 +23,6 @@ ****************************************************************************************/ #include -#include #include namespace { diff --git a/modules/volume/rendering/renderablevolume.cpp b/modules/volume/rendering/renderablevolume.cpp index a042df4a26..431a6bbac2 100644 --- a/modules/volume/rendering/renderablevolume.cpp +++ b/modules/volume/rendering/renderablevolume.cpp @@ -26,7 +26,6 @@ #include #include #include -#include #include // ghoul includes diff --git a/modules/volume/rendering/renderablevolumegl.cpp b/modules/volume/rendering/renderablevolumegl.cpp index 1a2ee524f0..02017ac9f8 100644 --- a/modules/volume/rendering/renderablevolumegl.cpp +++ b/modules/volume/rendering/renderablevolumegl.cpp @@ -29,7 +29,6 @@ #include #include #include -#include #include #include diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a49a7edc3b..13b684c4b7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -145,7 +145,6 @@ set(OPENSPACE_HEADER ${OPENSPACE_BASE_DIR}/include/openspace/scripting/script_helper.h ${OPENSPACE_BASE_DIR}/include/openspace/scripting/scriptengine.h ${OPENSPACE_BASE_DIR}/include/openspace/util/camera.h - ${OPENSPACE_BASE_DIR}/include/openspace/util/constants.h ${OPENSPACE_BASE_DIR}/include/openspace/util/factorymanager.h ${OPENSPACE_BASE_DIR}/include/openspace/util/factorymanager.inl ${OPENSPACE_BASE_DIR}/include/openspace/util/keys.h diff --git a/src/abuffer/abuffervisualizer.cpp b/src/abuffer/abuffervisualizer.cpp index f109c641bf..3aca0d8f26 100644 --- a/src/abuffer/abuffervisualizer.cpp +++ b/src/abuffer/abuffervisualizer.cpp @@ -23,7 +23,6 @@ ****************************************************************************************/ #include -#include #include #include diff --git a/src/engine/configurationmanager.cpp b/src/engine/configurationmanager.cpp index 12afb65fa7..cf3a47ec33 100644 --- a/src/engine/configurationmanager.cpp +++ b/src/engine/configurationmanager.cpp @@ -24,8 +24,6 @@ #include -#include - #include #include #include diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index a0bc517450..a02cc07a64 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -37,10 +37,11 @@ #include #include #include +#include #include #include +#include #include -#include #include #include #include @@ -117,6 +118,8 @@ OpenSpaceEngine::OpenSpaceEngine(std::string programName, _interactionHandler->setPropertyOwner(_globalPropertyNamespace.get()); _globalPropertyNamespace->addPropertySubOwner(_interactionHandler.get()); FactoryManager::initialize(); + FactoryManager::ref().addFactory(new ghoul::TemplateFactory); + FactoryManager::ref().addFactory(new ghoul::TemplateFactory); SpiceManager::initialize(); Time::initialize(); ghoul::systemcapabilities::SystemCapabilities::initialize(); diff --git a/src/interaction/luaconsole.cpp b/src/interaction/luaconsole.cpp index fed9010af4..0cfdd6e6d2 100644 --- a/src/interaction/luaconsole.cpp +++ b/src/interaction/luaconsole.cpp @@ -23,7 +23,6 @@ ****************************************************************************************/ #include -#include #include #include diff --git a/src/rendering/renderable.cpp b/src/rendering/renderable.cpp index eabf3a940b..3769d0bd1d 100644 --- a/src/rendering/renderable.cpp +++ b/src/rendering/renderable.cpp @@ -24,7 +24,6 @@ // open space includes #include -#include #include #include #include diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 9cee5b231c..0919eba208 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include diff --git a/src/scene/ephemeris.cpp b/src/scene/ephemeris.cpp index f96f3aa299..2c2a47c3d9 100644 --- a/src/scene/ephemeris.cpp +++ b/src/scene/ephemeris.cpp @@ -23,7 +23,6 @@ ****************************************************************************************/ #include -#include #include namespace { diff --git a/src/scene/scene.cpp b/src/scene/scene.cpp index 996cdb6af0..52ba2e4b7a 100644 --- a/src/scene/scene.cpp +++ b/src/scene/scene.cpp @@ -33,7 +33,6 @@ #include #include #include -#include #include #include diff --git a/src/scene/scenegraphnode.cpp b/src/scene/scenegraphnode.cpp index 9ae75532f3..6496648958 100644 --- a/src/scene/scenegraphnode.cpp +++ b/src/scene/scenegraphnode.cpp @@ -25,7 +25,6 @@ // open space includes #include #include -#include // ghoul includes #include diff --git a/src/util/factorymanager.cpp b/src/util/factorymanager.cpp index 2323d2c626..e35db1fdc3 100644 --- a/src/util/factorymanager.cpp +++ b/src/util/factorymanager.cpp @@ -24,9 +24,6 @@ #include -#include -#include - #include namespace openspace { @@ -34,23 +31,22 @@ namespace openspace { FactoryManager* FactoryManager::_manager = nullptr; void FactoryManager::initialize() { - ghoul_assert(!_manager, "Factory Manager already initialized"); - if (_manager == nullptr) - _manager = new FactoryManager; - ghoul_assert(_manager, "Factory Manager was not correctly initialized"); - - _manager->addFactory(new ghoul::TemplateFactory); - _manager->addFactory(new ghoul::TemplateFactory); + ghoul_assert(!_manager, "Factory Manager must not have been initialized"); + _manager = new FactoryManager; } void FactoryManager::deinitialize() { - ghoul_assert(_manager, "No Factory Manager to deinitialize"); + ghoul_assert(_manager, "Factory Manager must have been initialized"); delete _manager; _manager = nullptr; } + +bool FactoryManager::isInitialized() { + return _manager != nullptr; +} FactoryManager& FactoryManager::ref() { - ghoul_assert(_manager, "No Factory Manager to dereference"); + ghoul_assert(_manager, "Factory Manager must have been initialized"); return *_manager; } diff --git a/src/util/time.cpp b/src/util/time.cpp index cba7e17bb5..536f185d85 100644 --- a/src/util/time.cpp +++ b/src/util/time.cpp @@ -26,7 +26,6 @@ #include #include -#include #include #include From 0735d0fc2dfac29949a6141f75eb011edcbe2e30 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 14 Dec 2015 17:55:24 -0800 Subject: [PATCH 070/122] More cleanup of FactoryManager --- include/openspace/util/factorymanager.h | 46 +++++++++++++++++++---- include/openspace/util/factorymanager.inl | 14 +++---- modules/base/basemodule.cpp | 4 +- modules/newhorizons/newhorizonsmodule.cpp | 4 +- modules/newhorizons/util/decoder.cpp | 1 + src/engine/openspaceengine.cpp | 8 +++- src/scene/ephemeris.cpp | 1 + src/util/factorymanager.cpp | 19 +++++----- 8 files changed, 65 insertions(+), 32 deletions(-) diff --git a/include/openspace/util/factorymanager.h b/include/openspace/util/factorymanager.h index ce74515a86..55f6f67ce0 100644 --- a/include/openspace/util/factorymanager.h +++ b/include/openspace/util/factorymanager.h @@ -25,8 +25,11 @@ #ifndef __FACTORYMANAGER_H__ #define __FACTORYMANAGER_H__ +#include #include +#include + namespace openspace { /** @@ -36,6 +39,23 @@ namespace openspace { */ class FactoryManager { public: + /// This exception is thrown if the ghoul::TemplateFactory could not be found in the + /// #factory method + struct FactoryNotFoundError : public ghoul::RuntimeError { + /** + * Constructor for FactoryNotFoundError, the \p type is a human-readable (-ish) + * type descriptor for the type T for the TemplateFactory that could + * not be found. + * \param type The type T for the TemplateFactory + * that could not be found + * \pre \p type must not be empty + */ + explicit FactoryNotFoundError(std::string type); + + /// The type describing the ghoul::TemplateFactory that could not be found + std::string type; + }; + /** * Static initializer that initializes the static member. This needs to be done before * the FactoryManager can be used. @@ -63,20 +83,30 @@ public: */ static FactoryManager& ref(); - void addFactory(ghoul::TemplateFactoryBase* factory); + /** + * Adds the passed \p factory to the FactoryManager. Factories may only be added once. + * \param factory The ghoul::TemplateFactory to add to this FactoryManager + * \pre \p factory must not be nullptr + */ + void addFactory(std::unique_ptr factory); + /** + * This method provides access to all registered ghoul::TemplateFactory%s through + * their type. The method will always return a proper ghoul::TemplateFactory or throw + * an error if the appropriate ghoul::TemplateFactory was not registered. + * \tparam T The type that the requested ghoul::TemplateFactory should create + * \return The ghoul::TemplateFactory that will create the pass type T + * \throw FactoryNotFoundError If the requested ghoul::TemplateFactory could not be + * found + */ template ghoul::TemplateFactory* factory() const; private: - FactoryManager() = default; - ~FactoryManager(); + /// Singleton member for the Factory Manager + static FactoryManager* _manager; - FactoryManager(const FactoryManager& c) = delete; - - static FactoryManager* _manager; ///< Singleton member - - std::vector _factories; + std::vector> _factories; }; } // namespace openspace diff --git a/include/openspace/util/factorymanager.inl b/include/openspace/util/factorymanager.inl index f46eb55df7..7f9989f619 100644 --- a/include/openspace/util/factorymanager.inl +++ b/include/openspace/util/factorymanager.inl @@ -22,20 +22,16 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#include - namespace openspace { template -ghoul::TemplateFactory* FactoryManager::factory() const -{ - for (ghoul::TemplateFactoryBase* factory : _factories) { +ghoul::TemplateFactory* FactoryManager::factory() const { + for (auto& factory : _factories) { if (factory->baseClassType() == typeid(T)) - return dynamic_cast*>(factory); + return dynamic_cast*>(factory.get()); } - LERRORC("FactoryManager", "Could not find factory for type '" << typeid(T).name() - << "'"); - return nullptr; + + throw FactoryNotFoundError(typeid(T).name()); } } // namespace openspace diff --git a/modules/base/basemodule.cpp b/modules/base/basemodule.cpp index 4d3939941d..17ab552544 100644 --- a/modules/base/basemodule.cpp +++ b/modules/base/basemodule.cpp @@ -56,8 +56,8 @@ BaseModule::BaseModule() {} void BaseModule::internalInitialize() { - FactoryManager::ref().addFactory(new ghoul::TemplateFactory); - FactoryManager::ref().addFactory(new ghoul::TemplateFactory); + FactoryManager::ref().addFactory(std::make_unique>()); + FactoryManager::ref().addFactory(std::make_unique>()); auto fRenderable = FactoryManager::ref().factory(); ghoul_assert(fRenderable, "Renderable factory was not created"); diff --git a/modules/newhorizons/newhorizonsmodule.cpp b/modules/newhorizons/newhorizonsmodule.cpp index 2a3e46a03e..5b49283792 100644 --- a/modules/newhorizons/newhorizonsmodule.cpp +++ b/modules/newhorizons/newhorizonsmodule.cpp @@ -53,8 +53,8 @@ NewHorizonsModule::NewHorizonsModule() void NewHorizonsModule::internalInitialize() { ImageSequencer2::initialize(); - FactoryManager::ref().addFactory(new ghoul::TemplateFactory); - FactoryManager::ref().addFactory(new ghoul::TemplateFactory); + FactoryManager::ref().addFactory(std::make_unique>()); + FactoryManager::ref().addFactory(std::make_unique>()); auto fRenderable = FactoryManager::ref().factory(); ghoul_assert(fRenderable, "No renderable factory existed"); diff --git a/modules/newhorizons/util/decoder.cpp b/modules/newhorizons/util/decoder.cpp index 2c68b90886..275a822f8b 100644 --- a/modules/newhorizons/util/decoder.cpp +++ b/modules/newhorizons/util/decoder.cpp @@ -24,6 +24,7 @@ #include #include +#include namespace { const std::string _loggerCat = "Decoder"; diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index a02cc07a64..34d29b9069 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -118,8 +118,12 @@ OpenSpaceEngine::OpenSpaceEngine(std::string programName, _interactionHandler->setPropertyOwner(_globalPropertyNamespace.get()); _globalPropertyNamespace->addPropertySubOwner(_interactionHandler.get()); FactoryManager::initialize(); - FactoryManager::ref().addFactory(new ghoul::TemplateFactory); - FactoryManager::ref().addFactory(new ghoul::TemplateFactory); + FactoryManager::ref().addFactory( + std::make_unique>() + ); + FactoryManager::ref().addFactory( + std::make_unique>() + ); SpiceManager::initialize(); Time::initialize(); ghoul::systemcapabilities::SystemCapabilities::initialize(); diff --git a/src/scene/ephemeris.cpp b/src/scene/ephemeris.cpp index 2c2a47c3d9..62f8753316 100644 --- a/src/scene/ephemeris.cpp +++ b/src/scene/ephemeris.cpp @@ -24,6 +24,7 @@ #include #include +#include namespace { const std::string _loggerCat = "Ephemeris"; diff --git a/src/util/factorymanager.cpp b/src/util/factorymanager.cpp index e35db1fdc3..bd5ea85722 100644 --- a/src/util/factorymanager.cpp +++ b/src/util/factorymanager.cpp @@ -29,6 +29,13 @@ namespace openspace { FactoryManager* FactoryManager::_manager = nullptr; + +FactoryManager::FactoryNotFoundError::FactoryNotFoundError(std::string t) + : ghoul::RuntimeError("Could not find TemplateFactory for type '" + t + "'") + , type(std::move(t)) +{ + ghoul_assert(!type.empty(), "Type must not be empty"); +} void FactoryManager::initialize() { ghoul_assert(!_manager, "Factory Manager must not have been initialized"); @@ -50,15 +57,9 @@ FactoryManager& FactoryManager::ref() { return *_manager; } -FactoryManager::~FactoryManager() { - for (ghoul::TemplateFactoryBase* factory : _factories) - delete factory; - _factories.clear(); -} - -void FactoryManager::addFactory(ghoul::TemplateFactoryBase* factory) { - _factories.push_back(factory); - +void FactoryManager::addFactory(std::unique_ptr factory) { + ghoul_assert(factory, "Factory must not be nullptr"); + _factories.push_back(std::move(factory)); } } // namespace openspace From 0895d6e6d022c9b2c04fd5af000632ff716a88f8 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Wed, 16 Dec 2015 17:23:17 -0800 Subject: [PATCH 071/122] Some cleanup of ScriptEngine --- ext/ghoul | 2 +- include/openspace/scripting/scriptengine.h | 64 +++++++++++------ src/scripting/scriptengine.cpp | 83 +++++++--------------- 3 files changed, 69 insertions(+), 80 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index c8d2a2df4a..776aa8e919 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit c8d2a2df4aa62c929fa0dcc648c930956741add4 +Subproject commit 776aa8e91984b22b7829626894150ce2aa926a87 diff --git a/include/openspace/scripting/scriptengine.h b/include/openspace/scripting/scriptengine.h index 5e804ac092..5347f6493c 100644 --- a/include/openspace/scripting/scriptengine.h +++ b/include/openspace/scripting/scriptengine.h @@ -27,48 +27,69 @@ #include -#include #include - -/** - * \defgroup LuaScripts Lua Scripts - */ +#include +#include namespace openspace { - class SyncBuffer; + +class SyncBuffer; namespace scripting { +/** + * The ScriptEngine is responsible for handling the execution of custom Lua functions and + * executing scripts (#runScript and #runScriptFile). Before usage, it has to be + * #initialize%d and #deinitialize%d. New ScriptEngine::Library%s consisting of + * ScriptEngine::Library::Function%s have to be added which can then be called using the + * openspace namespac prefix in Lua. The same functions can be exposed to + * other Lua states by passing them to the #initializeLuaState method. + */ class ScriptEngine { public: + /** + * This structure represents a Lua library, itself consisting of a unique \m name and + * an arbitrary number of \m functions + */ struct LuaLibrary { + /** + * This structure represents a Lua function with its \m name, \m function pointer + * \m argumentText describing the arguments this function takes, the \m helpText + * descripbing the function, and whether it should be shared in a parallel + * connection (\m parallelShared) + */ struct Function { + /// The name of the function std::string name; + /// The function pointer that is executed if the function is called lua_CFunction function; + /// A text describing the arugments to this function std::string argumentText; + /// A help text describing what the function does/ std::string helpText; + /// If true, this function will be shared with other parallel + /// connections bool parallelShared; - - Function(std::string n, lua_CFunction f, std::string a, std::string h , bool ps = false): - name(n), - function(f), - argumentText(a), - helpText(h), - parallelShared(ps) - { - - } }; + /// The name of the library std::string name; + /// The list of all functions for this library std::vector functions; + /// Comparison function that compares two LuaLibrary%s name bool operator<(const LuaLibrary& rhs) const; }; - ScriptEngine(); - ~ScriptEngine(); - - bool initialize(); + /** + * Initializes the internal Lua state and registers a common set of library functions + * \throw LuaRuntimeException If the creation of the new Lua state fails + */ + void initialize(); + + /** + * Cleans the internal Lua state and leaves the ScriptEngine in a state to be newly + * initialize%d. + */ void deinitialize(); void initializeLuaState(lua_State* state); @@ -109,7 +130,7 @@ private: void addBaseLibrary(); void remapPrintFunction(); - lua_State* _state; + lua_State* _state = nullptr; std::set _registeredLibraries; //sync variables @@ -121,7 +142,6 @@ private: //parallel variables std::map> _cachedScripts; std::mutex _cachedScriptsMutex; - }; } // namespace scripting diff --git a/src/scripting/scriptengine.cpp b/src/scripting/scriptengine.cpp index 48413a9b41..49ac3a53b0 100644 --- a/src/scripting/scriptengine.cpp +++ b/src/scripting/scriptengine.cpp @@ -55,35 +55,15 @@ bool ScriptEngine::LuaLibrary::operator<(const LuaLibrary& rhs) const { return name < rhs.name; } -ScriptEngine::ScriptEngine() - : _state(nullptr) -{ -} - -ScriptEngine::~ScriptEngine() { - //deinitialize(); -} - -bool ScriptEngine::initialize() { - LDEBUG("Adding base functions"); +void ScriptEngine::initialize() { + LDEBUG("Adding base library"); addBaseLibrary(); - - _state = luaL_newstate(); - LDEBUG("Creating Lua state"); - if (_state == nullptr) { - LFATAL("Error creating new Lua state: Memory allocation error"); - return false; - } - - LDEBUG("Open Lua libraries"); - luaL_openlibs(_state); - + LDEBUG("Creating new Lua state"); + _state = ghoul::lua::createNewLuaState(); + LDEBUG("Initializing Lua state"); initializeLuaState(_state); - - LDEBUG("Remap print function"); + LDEBUG("Remapping Print functions"); remapPrintFunction(); - - return true; } void ScriptEngine::deinitialize() { @@ -93,6 +73,16 @@ void ScriptEngine::deinitialize() { } } +void ScriptEngine::initializeLuaState(lua_State* state) { + LDEBUG("Create openspace base library"); + lua_newtable(state); + lua_setglobal(state, _openspaceLibraryName.c_str()); + + LDEBUG("Add OpenSpace modules"); + for (const LuaLibrary& lib : _registeredLibraries) + registerLuaLibrary(state, lib); +} + void ScriptEngine::addLibrary(LuaLibrary library) { auto sortFunc = [](const LuaLibrary::Function& lhs, const LuaLibrary::Function& rhs) { @@ -136,6 +126,15 @@ void ScriptEngine::addLibrary(LuaLibrary library) { } } +bool ScriptEngine::hasLibrary(const std::string& name) { + auto it = std::find_if( + _registeredLibraries.begin(), + _registeredLibraries.end(), + [name](const LuaLibrary& it) { return it.name == name; } + ); + return (it != _registeredLibraries.end()); +} + bool ScriptEngine::runScript(const std::string& script) { if (script.empty()){ LWARNING("Script was empty"); @@ -168,7 +167,6 @@ bool ScriptEngine::runScript(const std::string& script) { return true; } - bool ScriptEngine::runScriptFile(const std::string& filename) { if (filename.empty()) { LWARNING("Filename was empty"); @@ -194,8 +192,7 @@ bool ScriptEngine::runScriptFile(const std::string& filename) { return true; } -bool ScriptEngine::shouldScriptBeSent(const std::string &library, const std::string &function){ - +bool ScriptEngine::shouldScriptBeSent(const std::string& library, const std::string& function) { std::set::const_iterator libit; for (libit = _registeredLibraries.cbegin(); libit != _registeredLibraries.cend(); @@ -291,24 +288,6 @@ bool ScriptEngine::parseLibraryAndFunctionNames(std::string &library, std::strin return !function.empty(); } -bool ScriptEngine::hasLibrary(const std::string& name) -{ - auto it = std::find_if( - _registeredLibraries.begin(), - _registeredLibraries.end(), - [name](const LuaLibrary& it) { return it.name == name; } - ); - - return (it != _registeredLibraries.end()); - - - //for (const LuaLibrary& it : _registeredLibraries) { - // if (it.name == name) - // return true; - //} - //return false; -} - bool ScriptEngine::isLibraryNameAllowed(lua_State* state, const std::string& name) { bool result = false; lua_getglobal(state, _openspaceLibraryName.c_str()); @@ -452,16 +431,6 @@ void ScriptEngine::remapPrintFunction() { //ghoul::lua::logStack(_state); } -void ScriptEngine::initializeLuaState(lua_State* state) { - LDEBUG("Create openspace base library"); - lua_newtable(state); - lua_setglobal(state, _openspaceLibraryName.c_str()); - - LDEBUG("Add OpenSpace modules"); - for (const LuaLibrary& lib : _registeredLibraries) - registerLuaLibrary(state, lib); -} - bool ScriptEngine::registerLuaLibrary(lua_State* state, const LuaLibrary& library) { assert(state); if (library.functions.empty()) { From 1a4ea8763e8b622f6a711f0689ce6ea9b475a374 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Wed, 23 Dec 2015 14:41:17 -0500 Subject: [PATCH 072/122] Fix performance window access to SharedMemory --- ext/ghoul | 2 +- modules/onscreengui/src/guiperformancecomponent.cpp | 2 +- src/rendering/renderengine.cpp | 11 +++++++++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index 776aa8e919..badf68dbce 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 776aa8e91984b22b7829626894150ce2aa926a87 +Subproject commit badf68dbcef1c19c9e1ca33d0b4d2e4e8e161ea4 diff --git a/modules/onscreengui/src/guiperformancecomponent.cpp b/modules/onscreengui/src/guiperformancecomponent.cpp index f76967314b..2612798be7 100644 --- a/modules/onscreengui/src/guiperformancecomponent.cpp +++ b/modules/onscreengui/src/guiperformancecomponent.cpp @@ -87,7 +87,7 @@ void GuiPerformanceComponent::render() { _performanceMemory = new ghoul::SharedMemory(RenderEngine::PerformanceMeasurementSharedData); - void* ptr = _performanceMemory; + void* ptr = _performanceMemory->memory(); PerformanceLayout* layout = reinterpret_cast(ptr); for (int i = 0; i < layout->nEntries; ++i) { diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 0919eba208..357e43da82 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -917,10 +917,17 @@ void RenderEngine::storePerformanceMeasurements() { maxValues * sizeof(PerformanceLayout::PerformanceLayoutEntry); LINFO("Create shared memory of " << totalSize << " bytes"); + try { + ghoul::SharedMemory::remove(PerformanceMeasurementSharedData); + } + catch (const ghoul::SharedMemory::SharedMemoryError& e) { + LINFOC(e.component, e.what()); + } + ghoul::SharedMemory::create(PerformanceMeasurementSharedData, totalSize); _performanceMemory = new ghoul::SharedMemory(PerformanceMeasurementSharedData); - void* ptr = _performanceMemory; + void* ptr = _performanceMemory->memory(); PerformanceLayout* layout = reinterpret_cast(ptr); layout->version = Version; layout->nValuesPerEntry = nValues; @@ -946,7 +953,7 @@ void RenderEngine::storePerformanceMeasurements() { } } - void* ptr = _performanceMemory; + void* ptr = _performanceMemory->memory(); PerformanceLayout* layout = reinterpret_cast(ptr); _performanceMemory->acquireLock(); for (int i = 0; i < nNodes; ++i) { From 465715f652665b031ee0816b8716eca477de5af8 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Wed, 23 Dec 2015 16:26:24 -0500 Subject: [PATCH 073/122] Remove DummyWindowWrapper and implement default methods into WindowWrapper --- .../engine/wrapper/dummywindowwrapper.h | 54 ----------------- .../openspace/engine/wrapper/windowwrapper.h | 56 +++++++++++------- src/CMakeLists.txt | 2 - src/engine/wrapper/dummywindowwrapper.cpp | 59 ------------------- src/engine/wrapper/windowwrapper.cpp | 35 ++++++++++- 5 files changed, 67 insertions(+), 139 deletions(-) delete mode 100644 include/openspace/engine/wrapper/dummywindowwrapper.h delete mode 100644 src/engine/wrapper/dummywindowwrapper.cpp diff --git a/include/openspace/engine/wrapper/dummywindowwrapper.h b/include/openspace/engine/wrapper/dummywindowwrapper.h deleted file mode 100644 index e1cac32d10..0000000000 --- a/include/openspace/engine/wrapper/dummywindowwrapper.h +++ /dev/null @@ -1,54 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2015 * - * * - * 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 __DUMMYWINDOWWRAPPER_H__ -#define __DUMMYWINDOWWRAPPER_H__ - -#include - -namespace openspace { - -/** - * DummyWindowWrapper that can be used if no actual rendering output is required, such as - * for console applications. The window sizes and resolutions will all be set to - * 0 and all graphics operations will be no-ops. - */ -class DummyWindowWrapper : public WindowWrapper { -public: - void clearAllWindows(const glm::vec4& clearColor) override; - bool windowHasResized() const override; - double averageDeltaTime() const override; - uint32_t mouseButtons(int maxNumber = 8) const override; - glm::vec2 mousePosition() const override; - glm::ivec2 currentWindowSize() const override; - - glm::mat4 viewProjectionMatrix() const override; - void setNearFarClippingPlane(float near, float far) override; - - void takeScreenshot() const override; -}; - -} // namespace openspace - -#endif // __DUMMYWINDOWWRAPPER_H__ diff --git a/include/openspace/engine/wrapper/windowwrapper.h b/include/openspace/engine/wrapper/windowwrapper.h index cde0d28df5..9125e6f8d3 100644 --- a/include/openspace/engine/wrapper/windowwrapper.h +++ b/include/openspace/engine/wrapper/windowwrapper.h @@ -52,46 +52,53 @@ public: /** * This method clears all the rendering windows with the specified \p clearColor. In * most OpenGL cases, this will end up with one or mode glClear calls. + * This method defaults to a no-op. * \param clearColor The color with which to clear all windows */ - virtual void clearAllWindows(const glm::vec4& clearColor) = 0; + virtual void clearAllWindows(const glm::vec4& clearColor); /** - * Returns whether the current window has been resized recently. + * Returns whether the current window has been resized recently. On default, this + * method always returns false. * \return true if the current window has been resized recently, * false otherwise */ - virtual bool windowHasResized() const = 0; + virtual bool windowHasResized() const; /** - * Returns the average frametime in seconds. + * Returns the average frametime in seconds. On default, this method returns + * 0.0. * \return The average frametime in seconds */ - virtual double averageDeltaTime() const = 0; + virtual double averageDeltaTime() const; /** - * Returns the location of the mouse cursor in pixel screen coordinates. + * Returns the location of the mouse cursor in pixel screen coordinates. On default, + * this method returns 0,0. * \return The location of the mouse cursor in pixel screen coordinates */ - virtual glm::vec2 mousePosition() const = 0; + virtual glm::vec2 mousePosition() const; /** * Returns a bitmask of the status of all available mouse buttons. Bit i * is 1 if mouse button i is pressed down; - * false otherwise. + * 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 * \return A bitmask showing the status of all mouse buttons (up to \p maxNumber) */ - virtual uint32_t mouseButtons(int maxNumber = 8) const = 0; + virtual uint32_t mouseButtons(int maxNumber = 8) const; /** - * Returns the size of the currently active window in pixel coordinates. + * Returns the size of the currently active window in pixel coordinates. On default, + * this method returns a window size of 0,0. * \return The size of the currently active window in pixel coordinates */ - virtual glm::ivec2 currentWindowSize() const = 0; + virtual glm::ivec2 currentWindowSize() const; /** - * Returns the resolution of the currently active window in pixel coordinates. + * Returns the resolution of the currently active window in pixel coordinates. On + * default, this method returns the same size as #currentWindowSize. * \return The resolution of the currently active window in pixel coordinates */ virtual glm::ivec2 currentWindowResolution() const; @@ -99,23 +106,26 @@ public: /** * Returns true if the current rendering method is regular, i.e., it is * a flat projection without non-linear distortions. Returns false in - * other cases, for example fisheye projections. + * other cases, for example fisheye projections. On default, this method will return + * true. * \return Whether the current rendering method is a regular method */ virtual bool isRegularRendering() const; /** - * Returns the currently employed view-projection matrix. + * Returns the currently employed view-projection matrix. On default, this method will + * return the identity matrix. * \return The currently employed view-projection matrix */ - virtual glm::mat4 viewProjectionMatrix() const = 0; + virtual glm::mat4 viewProjectionMatrix() const; /** - * Sets the near and far clipping planes of the rendering window. + * Sets the near and far clipping planes of the rendering window. This method defaults + * to a no-op. * \param near The near clipping plane * \param far The far clipping plane */ - virtual void setNearFarClippingPlane(float near, float far) = 0; + virtual void setNearFarClippingPlane(float near, float far); /** * Returns the location and size of the current viewport (x, @@ -128,29 +138,31 @@ public: /** * Returns true if there is an external control connected, i.e., an - * application that can receive control commands. + * application that can receive control commands. On default, this method will return + * false. * \return If there is an external control connected */ virtual bool isExternalControlConnected() const; /** - * Sends a \p message to an external control. + * Sends a \p message to an external control. This method defaults to a no-op. * \param message The message to be sent */ virtual void sendMessageToExternalControl(const std::vector& message) const; /** * Returns true if the rendering is a single viewport with an single - * window; false otherwise. + * window; false otherwise. On default, this method returns + * true * \returns true if the rendering is a single viewport with an single * widnow; false otherwise */ virtual bool isSimpleRendering() const; /** - * Advises the windowing system to take a screenshot. + * Advises the windowing system to take a screenshot. This method defaults to a no-op. */ - virtual void takeScreenshot() const = 0; + virtual void takeScreenshot() const; }; } // namespace openspace diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 13b684c4b7..cb9a1b5cfe 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -34,7 +34,6 @@ set(OPENSPACE_SOURCE ${OPENSPACE_BASE_DIR}/src/engine/logfactory.cpp ${OPENSPACE_BASE_DIR}/src/engine/moduleengine.cpp ${OPENSPACE_BASE_DIR}/src/engine/openspaceengine.cpp - ${OPENSPACE_BASE_DIR}/src/engine/wrapper/dummywindowwrapper.cpp ${OPENSPACE_BASE_DIR}/src/engine/wrapper/sgctwindowwrapper.cpp ${OPENSPACE_BASE_DIR}/src/engine/wrapper/windowwrapper.cpp ${OPENSPACE_BASE_DIR}/src/interaction/controller.cpp @@ -101,7 +100,6 @@ set(OPENSPACE_HEADER ${OPENSPACE_BASE_DIR}/include/openspace/engine/logfactory.h ${OPENSPACE_BASE_DIR}/include/openspace/engine/moduleengine.h ${OPENSPACE_BASE_DIR}/include/openspace/engine/openspaceengine.h - ${OPENSPACE_BASE_DIR}/include/openspace/engine/wrapper/dummywindowwrapper.h ${OPENSPACE_BASE_DIR}/include/openspace/engine/wrapper/sgctwindowwrapper.h ${OPENSPACE_BASE_DIR}/include/openspace/engine/wrapper/windowwrapper.h ${OPENSPACE_BASE_DIR}/include/openspace/interaction/controller.h diff --git a/src/engine/wrapper/dummywindowwrapper.cpp b/src/engine/wrapper/dummywindowwrapper.cpp deleted file mode 100644 index 2c9d35d8dc..0000000000 --- a/src/engine/wrapper/dummywindowwrapper.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2015 * - * * - * 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 { - -void DummyWindowWrapper::clearAllWindows(const glm::vec4&) {} - -bool DummyWindowWrapper::windowHasResized() const { - return false; -} - -double DummyWindowWrapper::averageDeltaTime() const { - return 0.0; -} - -glm::vec2 DummyWindowWrapper::mousePosition() const { - return glm::vec2(0.f); -} - -uint32_t DummyWindowWrapper::mouseButtons(int maxNumber) const { - return 0; -} - -glm::ivec2 DummyWindowWrapper::currentWindowSize() const { - return glm::ivec2(0); -} - -glm::mat4 DummyWindowWrapper::viewProjectionMatrix() const { - return glm::mat4(1.f); -} - -void DummyWindowWrapper::setNearFarClippingPlane(float near, float far) {} - -void DummyWindowWrapper::takeScreenshot() const {} - -} // namespace openspace diff --git a/src/engine/wrapper/windowwrapper.cpp b/src/engine/wrapper/windowwrapper.cpp index de37cb639b..95056b11ae 100644 --- a/src/engine/wrapper/windowwrapper.cpp +++ b/src/engine/wrapper/windowwrapper.cpp @@ -26,14 +26,44 @@ namespace openspace { +void WindowWrapper::setBarrier(bool) {} + +void WindowWrapper::clearAllWindows(const glm::vec4& clearColor) {} + +bool WindowWrapper::windowHasResized() const { + return false; +} + +double WindowWrapper::averageDeltaTime() const { + return 0.0; +} + +glm::vec2 WindowWrapper::mousePosition() const { + return glm::vec2(0.f); +} + +uint32_t WindowWrapper::mouseButtons(int maxNumber) const { + return uint32_t(0); +} + +glm::ivec2 WindowWrapper::currentWindowSize() const { + return glm::ivec2(0); +} + glm::ivec2 WindowWrapper::currentWindowResolution() const { return currentWindowSize(); } - + bool WindowWrapper::isRegularRendering() const { return true; } +glm::mat4 WindowWrapper::viewProjectionMatrix() const { + return glm::mat4(1.f); +} + +void WindowWrapper::setNearFarClippingPlane(float near, float far) {} + glm::ivec4 WindowWrapper::viewportPixelCoordinates() const { return glm::ivec4( 0, @@ -43,7 +73,6 @@ glm::ivec4 WindowWrapper::viewportPixelCoordinates() const { ); } -void WindowWrapper::setBarrier(bool) {} bool WindowWrapper::isExternalControlConnected() const { return false; @@ -56,4 +85,6 @@ bool WindowWrapper::isSimpleRendering() const { return true; } +void WindowWrapper::takeScreenshot() const {} + } // namespace openspace From 52971caef584f658dc12f981843672c23146d45e Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Wed, 23 Dec 2015 17:18:59 -0500 Subject: [PATCH 074/122] Cleaning the ScreenLog --- include/openspace/util/screenlog.h | 90 ++++++++++++++++++++++-------- src/rendering/renderengine.cpp | 18 +++++- src/util/screenlog.cpp | 39 +++++-------- 3 files changed, 97 insertions(+), 50 deletions(-) diff --git a/include/openspace/util/screenlog.h b/include/openspace/util/screenlog.h index 6133b4c345..faf7cb417d 100644 --- a/include/openspace/util/screenlog.h +++ b/include/openspace/util/screenlog.h @@ -23,48 +23,92 @@ ****************************************************************************************/ #include -#include -#include -#include // pair + #include +#include namespace openspace { +/** + * The ScreenLog is an implementation of the ghoul::logging::Log abstract interface that + * can be used to present log messages in an on-screen GUI. For this, every incoming + * log message (#log) is tagged with the current time and all stored log messages can + * expire based on the time-to-live as specified in the constructor + * (#removeExpiredEntries). + */ class ScreenLog : public ghoul::logging::Log { public: - //typedef std::tuple LogEntry; - + /// Just a shortcut for the LogLevel access + using LogLevel = ghoul::logging::LogManager::LogLevel; + + /** + * This struct stores the incoming log entries with their \m level, \m timeString, + * \m category, \m message, and the generated \m timeStamp used for the expiry + * calculation. + */ struct LogEntry { - LogEntry(ghoul::logging::LogManager::LogLevel l, std::chrono::time_point t, std::string ts, std::string c, std::string m) : level(l), timeStamp(t), timeString(ts), category(c), message(m) {}; - ghoul::logging::LogManager::LogLevel level; + /// The ghoul::logging::LogManager::LogLevel of the log message + LogLevel level; + + /// The timepoint when the log message arrived at the ScreenLog std::chrono::time_point timeStamp; + + /// The time string as retrieved from the log message std::string timeString; + + /// The category as retrieved from the log message std::string category; + + /// The actual message of the log entry std::string message; }; - typedef std::vector::iterator iterator; - typedef std::vector::const_iterator const_iterator; - typedef std::vector::reverse_iterator reverse_iterator; - typedef std::vector::const_reverse_iterator const_reverse_iterator; - - typedef std::pair range; - typedef std::pair const_range; - - const size_t MaximumSize = 1000; - - ScreenLog(std::chrono::seconds timeToLive); + /** + * Constructor that creates a ScreenLog with the provided \p timeToLive, and the + * minimum \p logLevel that is stored. Log message with a lower + * ghoul::logging::LogManager::LogLevel are automatically discarded. + * \param timeToLive The time-to-live for the messages in this ScreenLog. Expired + * messages are removed whenever the #removeExpiredEntries method is called + * \param logLevel The minimum ghoul::logging::LogManager::LogLevel that messages must + * have in order to be stored in the ScreenLog + */ + ScreenLog(std::chrono::seconds timeToLive, LogLevel logLevel = LogLevel::Info); + /** + * Overwritten ghoul::loggling::Log method that is called whenever a new log message + * shall be stored. + * \param level The ghoul::logging::LogManager::LogLevel of the incoming log message + * \param category The category of the log message + * \param message The actual log message that was transmitted + */ + void log(ghoul::logging::LogManager::LogLevel level, const std::string& category, + const std::string& message) override; + + /** + * This method removes all the stored LogEntry%s that have expired, calculated by + * their timeStamp and the \m _timeToLive value. + * \post All entries retrieved by the #entries function have a timeStamp + * that is lower than the current time + \m _timeToLive. The current time used is the + * time when this method was last called + */ void removeExpiredEntries(); - virtual void log(ghoul::logging::LogManager::LogLevel level, const std::string& category, - const std::string& message); - - const_range last(size_t n = 10); + /** + * Returns the list of all stored LogEntry%s. + * \return The list of all stored LogEntry%s + */ + const std::vector& entries() const; private: + /// The list of all LogEntry%s stored by this ScreenLog std::vector _entries; + /// The time-to-live for the LogEntry%s in this ScreenLog. Is used by the + /// #removeExpiredEntries method to remove expired entries. std::chrono::seconds _timeToLive; + + /// The minimum LogLevel of messages + LogLevel _logLevel; }; -} \ No newline at end of file + +} // namespace openspace \ No newline at end of file diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 357e43da82..2f25bf2484 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -635,7 +635,21 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi const int category_length = 20; const int msg_length = 140; std::chrono::seconds fade(5); - auto entries = _log->last(max); + + auto entries = _log->entries(); + auto lastEntries = entries.size() > max ? std::make_pair(entries.rbegin(), entries.rbegin() + max) : std::make_pair(entries.rbegin(), entries.rend()); + +// if (entries.size() > max) + + //ScreenLog::const_range ScreenLog::last(size_t n) { + // if (_entries.size() > n) { + // return std::make_pair(_entries.rbegin(), _entries.rbegin() + n); + // } else { + // return std::make_pair(_entries.rbegin(), _entries.rend()); + // } + //} + +// auto entries = _log->last(max); const glm::vec4 white(0.9, 0.9, 0.9, 1); const glm::vec4 red(1, 0, 0, 1); @@ -645,7 +659,7 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi size_t nr = 1; auto now = std::chrono::steady_clock::now(); - for (auto& it = entries.first; it != entries.second; ++it) { + for (auto& it = lastEntries.first; it != lastEntries.second; ++it) { const ScreenLog::LogEntry* e = &(*it); std::chrono::duration diff = now - e->timeStamp; diff --git a/src/util/screenlog.cpp b/src/util/screenlog.cpp index 2016844016..7fe112a693 100644 --- a/src/util/screenlog.cpp +++ b/src/util/screenlog.cpp @@ -24,15 +24,13 @@ #include -#include -#include - -#include +using std::string; namespace openspace { - -ScreenLog::ScreenLog(std::chrono::seconds timeToLive) + +ScreenLog::ScreenLog(std::chrono::seconds timeToLive, LogLevel logLevel) : _timeToLive(std::move(timeToLive)) + , _logLevel(logLevel) {} void ScreenLog::removeExpiredEntries() { @@ -43,35 +41,26 @@ void ScreenLog::removeExpiredEntries() { std::remove_if( _entries.begin(), _entries.end(), - [t, ttl](const LogEntry& e) { return (t - e.timeStamp) > ttl; } + [&t, &ttl](const LogEntry& e) { return (t - e.timeStamp) > ttl; } ), _entries.end() ); } -void ScreenLog::log(ghoul::logging::LogManager::LogLevel level, const std::string& category, const std::string& message) { - if (level >= ghoul::logging::LogManager::LogLevel::Info) { - _entries.emplace_back( +void ScreenLog::log(LogLevel level, const string& category, const string& message) { + if (level >= _logLevel) { + _entries.push_back({ level, std::chrono::steady_clock::now(), Log::getTimeString(), category, message - ); + }); } - - // Once reaching maximum size, reduce to half - if (_entries.size() > MaximumSize) { - _entries.erase(_entries.begin(), _entries.begin() + MaximumSize / 2); - } +} + +const std::vector& ScreenLog::entries() const { + return _entries; } -ScreenLog::const_range ScreenLog::last(size_t n) { - if (_entries.size() > n) { - return std::make_pair(_entries.rbegin(), _entries.rbegin() + n); - } else { - return std::make_pair(_entries.rbegin(), _entries.rend()); - } -} - -} \ No newline at end of file +} // namespace openspace \ No newline at end of file From cdf228975a5058661046006155a167288e69ab6c Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Wed, 23 Dec 2015 17:44:05 -0500 Subject: [PATCH 075/122] Started cleanup of Time class --- include/openspace/util/time.h | 49 +++++++++--------- include/openspace/util/updatestructures.h | 9 ---- src/util/time.cpp | 62 +++++++---------------- 3 files changed, 43 insertions(+), 77 deletions(-) diff --git a/include/openspace/util/time.h b/include/openspace/util/time.h index 16906e4494..1f30ee69ac 100644 --- a/include/openspace/util/time.h +++ b/include/openspace/util/time.h @@ -26,8 +26,9 @@ #define __TIME_H__ #include -#include + #include +#include namespace openspace { @@ -49,6 +50,8 @@ namespace openspace { * 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 */ class SyncBuffer; @@ -59,18 +62,21 @@ public: * Initializes the Time singleton. * \return true if the initialization succeeded, false * otherwise + * \pre The Time singleton must not have been initialized */ - static bool initialize(); + static void initialize(); /** * Deinitializes the Time singleton. This method will not unload the kernel that was * possibly loaded during the initialize method. + * \pre The Time singleton must have been initialized */ static void deinitialize(); /** * Returns the reference to the Time singleton object. * \return The reference to the Time singleton object + * \pre The Time singleton must have been initialized */ static Time& ref(); @@ -86,7 +92,9 @@ public: * Sets the current time to the specified value in seconds past the J2000 epoch. This * value can be negative to represent dates before the epoch. * \param value The number of seconds after the J2000 epoch - * \param requireJump Wether or not the time change is big enough to require a time-jump, defaults to true as most calls to set time will require recomputation of planetary paths etc. + * \param requireJump Whether or not the time change is big enough to require a + * time-jump; defaults to true as most calls to set time will require recomputation of + * planetary paths etc. */ void setTime(double value, bool requireJump = true); @@ -95,7 +103,9 @@ public: * described in the Spice documentation * (http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/str2et_c.html) * \param time The time to be set as a date string - * \param requireJump Wether or not the time change is big enough to require a time-jump, defaults to true as most calls to set time will require recomputation of planetary paths etc. + * \param requireJump Whether or not the time change is big enough to require a + * time-jump; defaults to true as most calls to set time will require recomputation of + * planetary paths etc. */ void setTime(std::string time, bool requireJump = true); @@ -186,32 +196,25 @@ public: static scripting::ScriptEngine::LuaLibrary luaLibrary(); private: - /// Creates the time object. Only used in the initialize() method - Time(); - Time(const Time& src) = delete; - Time& operator=(const Time& rhs) = delete; - static Time* _instance; ///< The singleton instance - //sync variables - - //local copies - double _time; ///< The time stored as the number of seconds past the J2000 epoch - double _dt; - bool _timeJumped; - bool _timePaused; + //local copies + /// The time stored as the number of seconds past the J2000 epoch + double _time = -1.0; + double _dt = 1.0; + bool _timeJumped = false; + bool _timePaused = false; bool _jockeHasToFixThisLater; //shared copies - double _sharedTime; - double _sharedDt; - bool _sharedTimeJumped; + double _sharedTime = -1.0; + double _sharedDt = 1.0; + bool _sharedTimeJumped = false; //synced copies - double _syncedTime; - double _syncedDt; - bool _syncedTimeJumped; - + double _syncedTime = -1.0; + double _syncedDt = 1.0; + bool _syncedTimeJumped = false; std::mutex _syncMutex; }; diff --git a/include/openspace/util/updatestructures.h b/include/openspace/util/updatestructures.h index 74e6792fe6..faa10c9a4a 100644 --- a/include/openspace/util/updatestructures.h +++ b/include/openspace/util/updatestructures.h @@ -42,15 +42,6 @@ struct UpdateData { }; struct RenderData { - RenderData(const Camera& cam, psc pos, bool performance) - : camera(cam) - , position(std::move(pos)) - , doPerformanceMeasurement(std::move(performance)) - {} - - //RenderData() = default; - RenderData& operator=(const RenderData& rhs) = delete; - const Camera& camera; psc position; bool doPerformanceMeasurement; diff --git a/src/util/time.cpp b/src/util/time.cpp index 536f185d85..187d47d84b 100644 --- a/src/util/time.cpp +++ b/src/util/time.cpp @@ -24,54 +24,31 @@ #include -#include -#include #include #include #include - -#include -#include +#include #include "time_lua.inl" -namespace { - const std::string _loggerCat = "Time"; -} - namespace openspace { Time* Time::_instance = nullptr; -Time::Time() - : _time(-1.0) - , _dt(1.0) - , _timeJumped(false) - , _timePaused(false) - , _sharedTime(-1.0) - , _sharedDt(1.0) - , _sharedTimeJumped(false) - , _syncedTime(-1.0) - , _syncedDt(1.0) - , _syncedTimeJumped(false) -{ -} - -bool Time::initialize() { - assert( _instance == nullptr); - _instance = new Time(); - return true; +void Time::initialize() { + ghoul_assert(_instance == nullptr, "Static time must not have been ininitialized"); + _instance = new Time(); } void Time::deinitialize() { - assert(_instance); - delete _instance; - _instance = nullptr; + ghoul_assert(_instance, "Static time must have been ininitialized"); + delete _instance; + _instance = nullptr; } Time& Time::ref() { - assert(_instance); + ghoul_assert(_instance, "Static time must have been ininitialized"); return *_instance; } @@ -80,13 +57,11 @@ bool Time::isInitialized() { } void Time::setTime(double value, bool requireJump) { - _time = std::move(value); + _time = value; _timeJumped = requireJump; } double Time::currentTime() const { - assert(_instance); - //return _time; return _syncedTime; } @@ -98,11 +73,10 @@ double Time::advanceTime(double tickTime) { } void Time::setDeltaTime(double deltaT) { - _dt = std::move(deltaT); + _dt = deltaT; } double Time::deltaTime() const { - //return _dt; return _syncedDt; } @@ -124,7 +98,7 @@ std::string Time::currentTimeUTC() const { return SpiceManager::ref().dateFromEphemerisTime(_syncedTime); } -void Time::serialize(SyncBuffer* syncBuffer){ +void Time::serialize(SyncBuffer* syncBuffer) { _syncMutex.lock(); syncBuffer->encode(_sharedTime); @@ -134,7 +108,7 @@ void Time::serialize(SyncBuffer* syncBuffer){ _syncMutex.unlock(); } -void Time::deserialize(SyncBuffer* syncBuffer){ +void Time::deserialize(SyncBuffer* syncBuffer) { _syncMutex.lock(); syncBuffer->decode(_sharedTime); @@ -147,13 +121,12 @@ void Time::deserialize(SyncBuffer* syncBuffer){ _syncMutex.unlock(); } -void Time::postSynchronizationPreDraw(){ +void Time::postSynchronizationPreDraw() { _syncMutex.lock(); _syncedTime = _sharedTime; _syncedDt = _sharedDt; - //if (_sharedTimeJumped) - _syncedTimeJumped = _sharedTimeJumped; + _syncedTimeJumped = _sharedTimeJumped; if (_jockeHasToFixThisLater) { _syncedTimeJumped = true; @@ -163,7 +136,7 @@ void Time::postSynchronizationPreDraw(){ _syncMutex.unlock(); } -void Time::preSynchronization(){ +void Time::preSynchronization() { _syncMutex.lock(); _sharedTime = _time; @@ -174,15 +147,14 @@ void Time::preSynchronization(){ } bool Time::timeJumped() const { - //return _timeJumped; return _syncedTimeJumped; } -void Time::setTimeJumped(bool jumped){ +void Time::setTimeJumped(bool jumped) { _timeJumped = jumped; } -bool Time::paused() const{ +bool Time::paused() const { return _timePaused; } From c87fdfd38b2784c505b395054f8f3fcdf6026f45 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sat, 2 Jan 2016 21:40:15 +0100 Subject: [PATCH 076/122] Fixes for Windows Fixing shader paths for fieldlines rendering Update Kameleon to work with MSVC 2015 fix --- data | 2 +- ext/ghoul | 2 +- ext/spice/lib/msvc12/cspice.lib | Bin 9681480 -> 0 bytes ext/spice/lib/msvc14/cspice.lib | Bin 0 -> 9420742 bytes include/openspace/abuffer/abuffer.h | 1 + modules/base/rendering/renderabletrail.cpp | 2 +- .../rendering/renderablefieldlines.cpp | 6 +- modules/kameleon/ext/kameleon | 2 +- src/engine/moduleengine.cpp | 1 - src/engine/openspaceengine.cpp | 7 ++- src/rendering/renderengine.cpp | 31 +++++++--- src/scene/scene.cpp | 58 +++++++++++------- src/util/spicemanager.cpp | 8 +-- tests/main.cpp | 3 +- 14 files changed, 76 insertions(+), 47 deletions(-) delete mode 100644 ext/spice/lib/msvc12/cspice.lib create mode 100644 ext/spice/lib/msvc14/cspice.lib diff --git a/data b/data index 78d9d66bd0..aeea2eed41 160000 --- a/data +++ b/data @@ -1 +1 @@ -Subproject commit 78d9d66bd028c750e7fa9c8cd7b016519ed51f63 +Subproject commit aeea2eed41c80134548ec2fb1b79cfa363a7f924 diff --git a/ext/ghoul b/ext/ghoul index c8d2a2df4a..b69d211bf0 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit c8d2a2df4aa62c929fa0dcc648c930956741add4 +Subproject commit b69d211bf0fc84129d086855593f9acc39735262 diff --git a/ext/spice/lib/msvc12/cspice.lib b/ext/spice/lib/msvc12/cspice.lib deleted file mode 100644 index 131259ddec240a484e6f2e710c1204d591d51d7f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9681480 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 z%0A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

>c{t#Y}`%DMs8L%E>6wHg&C|{ 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�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%0D77W;~xUyzS+GgOl@W?`?___ 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

}T4#m>vGeVFPx&ZqkOK0I>=S+aKdM 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ΐ+6{HkOoq7KEJ2|h6Dm`=GMHe-~j zSw?BVuaqERlBdDCbOXWSv4L=`IvmGe4x>a>{EX77N-hJLc1*8tYwKvhb#T$by7~CS zS=N|Mq8$}2#yKa|kePj~Oj-y=g-_Boh7~4gvsvBoW{C1qP+!NBbU_O*=_0~wt6by9 z1!7Hs&bEb(&28rga20H5Ys8Y`{6?K<>oCoCw6x*EX#!)7vlfoG7EVCTuvKA$g)7p+ zx-P4$V}9qtMfQeUbL@VuoEeJ8A~n%a0vF>^-ob7z4qw`Oh^sahHp5s_^I?$L@zjbf zwX0=JYE|Qc7^*Cd7h7c$3JMBLH`dsr(B1b;!#$PEoPqcvZ>&Twz}Jm$gz@!PA2E@@ zuoZk@m`lGng|h%RD@@qokLddm<-tZ|@F2*8_2ytI5AHGt1w6Rj9E|qIOe%bY#WDN| ztGD5M_`zMfS%C6kg`G;A1*oE2WE2Z6Yv>?rXx2WSChkCE3i z`e0xaH!4iPfdZ81S8tRr5R|lQ4OF}Bx(-KnN;vIO#CCD7TP&>o?J8VfT=+cpBKQzvvXWF%FWIiZE7{;`OUow8HxqNzJN!Y2?9c z9GAiyTzSH!Jl_52L|0b&j&yeTnDuz+uH}I;o@L=NoTGUjD3&$CM=1m);7|ZWexsu& zJ$wxBz@`pD2$_4Q9HYBnP%6M5q`^Rgd>dj90oC2~_=S4|@4A6Scu&nFJibkjhk}}& z6~Hf3&yubmx>BboQQo{}Tj?8*d$%+fTRR~GF1~($)E z#5lntF1%vXbFLJhiZPMLFSQpaZpew>Jn;D!uGCl~MIOJ@-Xg^wVR|9>>ie!##7L3H zFO>(1Th4RgR2(raP=%UddTB1ozL%FsnL&} z+vZALX{5;Gm*P_w_w0T>>!c%HsoRVcc?KcaM@MI;ug)M_?;9ST4}Q)2ie}q}E0b5> z>uTOgj0f>hWoA?Wv#8zQ87>YL+wH*+~Dxi65X@_6R@J0P+m78rreRv6E8u zaNb35D3iab=)dlF_0VsOi9G&x;c+pfcm^?bo^rP5Ou5WRk!O(AT(_X9y~VCTYUu}p z$2|+~d*tL!xAYs09`Y#sjiIQW5epa3G5XRh^Ig_8kY##o^jUb=YKzlDjfp%8cf+LH z)iKD-qCE&mYU@q!Q#{B-ojD$u{`lHk&)Qn>M2(X-5_$XN2V$Roi%8ru8R!)I&RS!WqNyInTa*zAN>aks^;@>M&5UvwA3k^!ypq*1J*@c;P}Kj|5EVsc*0= z9Z1o0IC%OB0Mu^ukO#pd7Pfm%RO(?`ZFtiAG=N+;tkRz6UGfRFX!@>^B9FgaM}U%@ zwMf~lZywN)?@B#lq{yS11`jrjRsa;-nB%6oua+Junqx-bzU-Z!+gk9h)aW6PzdoZx zier!I$_+JVx>6NJiadTPRNB)!W40djXIE;uks?o~U{&6$=TV}^zP3-f;^IqPJsXT3 z@(i-@@S&;07x>Am=V;Nxxr@mk-fIw-3`pehx8fL3va>3giS$YC=Qp{fPc%~G@k@;c zB|FQum_LY8yOAP~Uuuj0!daXx#y+E$7*@v3G2oAZ78&!sHJH^`t3_ zJpLLMfZ_&zI{wc$t#@mfZ7yQu$rP{&0nz#i!o~ML?t0_K{N-1K4Rva@DW3DVsgU%1JZf&Z7$Lmt)h zvZ3gFNQteWY{6fS9G%W{P^ldm`(h$_oHfAG$6mP6)(d^6DdZVswYQx=r=bB*QUH{m zhBjyJOP`G=fzKULYny+t*3~SZ*dm`i{$8FeQf3fXkAHSgy(?8~>O&sC)D)l8^W#G$ zu2j2`B9B_E7nIu_%Y$tF7?fEKrKhudo;|0#R(*&(&g#NDo_SvP6}s!srgZZ7>pV@Q zzJXt+>`M-R$*v!~gv{wno4towj$jpWE5#lOhj4ab{iI`rHA^Mjz!#P$G^V zN^J*4lU>&Ppe*w7?893qBvgV@NXzX*1eIg{Yv-CWG55b)3Z_=ikVn#E0 z{JnFMPioMfU;mjaHP1+q2WLTANW`AH250r7c5YlS0hRPxwXp%O(tI}TS=iFr?cA0G zpn1uXw)*-;TNNox7ohaf`0HBZYEXg>rKhvru|@h>$$JEMt^V-fLsq!$y2G@KJbr7O z;**;CC;8ZoJiI$9=m?0E44dsl#$4z z_89}pN*t+u7J7%goCV%9HwZpAFlgJy(~q#V;9;QAOrBi@B@BrkdsO*@?$MW+i9E`& zhBb6%o6g3rg`K{ja^4yiK`J|I78M}P-!k$=TMKr;HJZuew^$eycUE6Jbmr@>)H_Cs zJbtN&NZE7mAJ;_Zxl(z1Arpx_eyL(m+_H8%BYT}Ib*zyh564DoSW=KJ?&UGnIhVa{ z$0QET_5^Xj%D=n^sc34jLy^~O)*A_8eJ{`mvF zm4lL5*}YbJ=V})=StCY9e!EoqMYwN={~1@$>^y}t8%3}`zI`_ zbn5)NkrEzXof9Hu_XX?hN_}LcgvVEB*3e&Pm=$g3ofPZ*T*0}0}1K0v^rOV z>ONck(F0Y7GhDwWqPTVZNe^Oe!pwd{dC{j{Y9<3}7ic1k67rr5fQ`iI&=Cox-U(i1V0pnw9>dm(W+oc1>)lsg^FxR|DWkL0Z@)cGT4#vug!lB~g z61Oj1N2#=aj8p_8L)i% zsVkT_sj*>dgWboIi;BtTg;urvk)0)y#LD2oNdC6zHmohlC^(woM6 zL$o)4q_z32ElU~^kdDqGh*H?rff0dVaCkHBgvaup1oof~2a790<(0*yRjwgi=czP9 zARb+LQ7B$n6|W46UllEYxPgvml?mVn*And;XIvJQ1gqj086{y)j6$C`Ra#*fcEyQM z8G<4P;b#RKqwDEuPnSXUKD3|Wuz=z7AXqWiZ_eh zr|N3OA=iV_3$@!@rcZ+7k5gvGz=xj5h1!`gLveAmyf_|>xd!(+RHau7%@0?UmSH04 zGioBet?bIe<%;J69;#}{L@l@&r&S3i1`N5N?Ky=8z;$Z+H1VBE32iASn$x%<#7?Xz zjlfT(*sZq2&GdRqrB}T)SXxn3Ru-!$3YPE{()3BO2uCN}sbrAab@tW6DK#7q#zG;4 z#7vY0;dO&(kfvAUb(B5UQ7Uvg=K}}6vGtdZ`B_{QEQ-a-%A-{&p$HxA#+M2K4sre= z$YHx%+E)uNi71g(k@BJ<1Spgy+RiEi2om`Z#7$HKMPk8 zhD4eLQK= zp3{BhA>L=7-PM6hXrFSp#%9c0vZQfAPj~xb9Sm4BWaL6?T6;SBtQD6YndS5xm=G(i zs)&|hMY(Xiug52pS5_2-%Q06joZyW9#)iIn4MP$>as8Dvxhfiqg%Pe3Lx|pVzS1T~ z;*oe&B3>3$A3J|$MOiozjaC)~)$`7mIkl>^G!~9lMS}J%p;KFy(qD~=ii4FH(`A)K zmF{)VT&~59FYS_-AyOJ7nTJ=n%rk$v- z1gn^MJeH_IL~YN6HMue#50z8~)hE!GH6a3Dzu)?Fej&LCdRsW(~;eQ#7A*Czx5f$Y2u`b zIPfI6s7;foj9V*dbZ^0usdIvCNiVkagFewLq`-l#E79TNqQqUS!v%RIhadskn{N#y6vD)J+YUYG(VrNIa4ZUOI z9}FMGs8G4wVRu+`RagFq)1%AYfT!;}W~;MU^7&YDYc%=ER<<)4&!5Yk;R4vURtWNg z-Ei}fBM}HjN6prUCa3GLD6)*ps&0%XImOzkt3U*>?>#keuoR% zh+jU5%aKoGmGAdB<`cyn*}6b!Z{t{Hvv9&HEe}X({6tl2FvdaL{zvP=ZRWHtP$DNh z|1yolKmD*!5$#P=!T))`Tx&n<4zwTMBkwm6xO!OoQJq*f>+Cki`X_oJd*a}6mdMWH z97R*_nfD1ESK>gDJt<^ce7fy@D$N}CX=%qtr~N(Kd0J{7)xx-J<~UDmK0Xt7-)}uK z@}R}8)ZtR1J~z*{nwk)FzS)qZ^me*7aU4jJ`grC$z87)ds-Al5m3W1!Z#ndPS_+W| zegoZI^*qu>G9f%C%qPE%HC-KZYFg&ocU#k9(b8xl9@n+0=(JZt z7_Th@kJUcKxlZ$He7IbVe};=ir)giNtMME5Kr}pkU5yXn0P`fd8qe#rRZ9*}?9{Z> zDp;R-)&3d`y&d|Z=0z_jsJ^b+cj8^~dh@=R{gdgc%_;3=!(*49>8i~U@WBB1IDvkY z#up5FM;OaF9sjsTl{W=5#45fX49x@J<0LplCVN+7a9Db|Y{#K#eCaVqe*nJ2()iM2 ztg;*KPvc83muLC!()iNLrM^vReChhg_xu3(c(LL8Q*X*-7hV9~%f#oIlc|H_?KALk zPbwz1tFQ6b10L=_#njjMW4UYXsaZJ9I87iU%AH^ z9_7qj?j~fO0KT1umqW3ya?c-z&71L$sjqS=|9!(FjQElBEv3Efp#KbfBW1yg_TaeB za>29A@bz1+;qjLH6<5>uL&vgz>uOr(_J43OjZf%in}sxEQUpS^_+oDp+qNw$mi)LP zxh0x>H*a}8MjIopF29;tUm?coQvv+k~HDcQX(n`%Ld~wwXqjcL( zKzA&36An@=6u~ys0g$<$^%l`6wYPV)UWR@BLAAOgM&aEz;z$(Qk_gje@IJ#9$AIs4t|L(OI0lU+vW! zMuf2|^H-v(-r^+FZbz=&4n{NO2~)T}mON`jEZG@|B`+8qOTHSKExTVwk*B*~7YmBx zHzJ6p2nm{pU*%f>6cpOU_@%cRb{fX7%3cd}ve3SdU-}j1h;JwT5_7D(@yi>x9N7U$ zWgo?HP-rjVcdDRQ@T>a108)M2V@CBI05nPXP5@HP6M-fOZ5q&cL2;l0LFWLe=H(8$ z94IKcYk^J>^g|#m_Z}eC{2YMHG%>&XJa7S$30_IrV4&QPhEtmUXYq{4uv>!XPJAe)rS;n!| zx-bNQTJl98-Y4W(uK?){^WTB=7M2%CEHK&d$!cKsZT;c_OHPEWZ8D4y}5BAzM#kEDD%$2W-MQ3W0+R#O+y{s?fBXk z5HD>yvEzdMnZL9i+n2O0IJX6QjWuE^dn@?9y8oZL#RNB4h~Re8^PzqO4UsSQBeBxc zoSrV7QBz!5TYZLpu^)-yi~VJ9AUL@!ge6M)R*V^Y8kCqsJ_5(L5b$tm*@L4u@HmQp z*li!bdbaZpOJ}?zf%GgH1EhR~K<)_U>e^1V06Kyd<>I(TXjwT~R!$K#EPI2W)n5Z5 z=KKWU8immaKS)QNK-N#vE0P=I$p@mzr_8tMS)MP`mp$0L0ou%V%K#P^+jcq|K&zpM z)%cpwq#6&P8hj#oIu=e#L5?Li+fN_4*5PF_iR&~Vy;RHt(&@AnNT=cpfb^oV6lgsD<;eEHdeOKI$EtZ9 zkUIc2;mA(S0BU(ftn+-KW$lHK0uzT@d%ZiP-B@3q0>2PVek`qmIm%MZo?>1d;#hW| zJ4~!TdvRb7f0ifOXd^y3mFK0bYY_i(EIu03%PcPuY8~21+t0SEop@1J>r?{iC3*&s z%FY3D+ux2OJ9PkP`xUW1=Ls!q_Z(|?Je%CTdPw^}@o}W*5e=^_?ju4Rm}GBDFbv1S zV|gFg@UoPh#mf>;>}#&5zbE}6W)3bqgM1G$2aD96M&o6lJ-Rc;d5D<@DwFW|9%AaF zMou0G5K}$W4N7xIOYv4%9ch{WLSk4f?CR48=}l)d1OKNF(~TbT!2Q494;?ra_Vr=qETe}!nLh9HS{_eG zpof-Zy7t%Gj-ZUDYmFZAWcqw9{i6YV>eRS|C$gjfq`YNu%(|br`9BemJzJ1Z9>0{F zQBDn)&%EI}w}xCSGm(cM0P#`pd8T}p&h#F5WPAbZx^S3jpq{7X84HSip5c{%XJm3l za_zJCHOK$eExpv}AINh4|y_u zB7hG9Ch*F|#5v0EsLtzOb{5ZC&M8MMTlbL8T54y!RY%&-3P7{>)yw{%y02cULZxf= zb7n2xC@=|+Z`R_O<+kFfX%FSOQX7nv@X%3xLV;+}TL^!hd3%waRgPZ{jjZ*zqUmOk zSkD?g2d34Tv!z?-U%&ie*MUx*Up7+0w{aqDbxWTX>~qKr0hDcxgv4PNT<#W ze#9g^K06-{s`d`^yXP-I-Iabk@`NMB`(zNG6?JQOR6;42eT|8(CaRv~SK zn(>_CyVTH<>bs;A9sCXO1oOUyZ4rXUcd0=r$~+&JP#?1pe9WXM^Le(L)2{uTCQX=z zw+u+GpVKusJvrSlWqPyv-|6S{Ta-aRr+3ZN%!#Y7Hz|y|Hp@&c{FCX8DKC#bh6hkm zrZ=X%cwRODK3+)Hr11rVFxXe|bGjeu{>^V@WNhG;@8o@~dEC>Ri@U?BbDh5xE%hC3 zoo!8Bfzj1t0#)tU)V5^_H;N9oEo_JTLI?Quse<3n39)41-SiP&$wZUewvvgD7`}nO zy@{dTN7W2xdNXzO;;~2sk0*l8n-BZ3g8iB!o_tcDEa2@x@^Riw>l1RLzWV?^P|$Z9 ze50`zS`j7Ic_PGn8ext1&dzU_hv36v$#czv@K@(-I06h@4CGja_~l|EM{fMN6haI! z{Bk_yNE{oz4PJ_4E^HBT3%|4-qHEz-Wq%69g*lgPc=9j5`XdVip)1M-S#B4MOV4n) z^y~wdo?+I0PY-K%x3G-FPWzYo^svr62dnRzJYE+MW=4^P<*s~s##PoM8Z~c!nbZpU zw?Chrj~h=qz?GuKne-+)eRnT_+zC9sBDPKJmx#?0`vey4WS{4mA3LR${$(uS$}6rlzK)Rxr(P zXB1B4YtdErnr8_YL#VH-(2sEf|B@#$68kCBRfy$21D;n?`S@_Zj*^jUI_YXE$l<=;=^3#R#7@#^vU0Qk5_;trzT zlxcOtQ|Q0}@Uh99A+GU`Jlfr zKz&~ffNvu7?azB&Ps%jzX_wdl_}Fh}r}3qa`$^!No5q)J7ha*S%D{&y`Kzo-AAq`l ztM|Qq?fD0nrCg42>fm(7bgEpUPLbb}9l_30YfA)-X!pc%`AQH}nypM^{~$ ze~qDUH1vSbSLfes=F-(l!{%FZfH1--ZJQLy8J3vdnS9 z9N%S*XPM)*=6J3-PMG6nb9}owZa2qk%<&>~yxANtHOEnNywV)cHOIG`C+gF$uFFsI!#qf@GY=e0josHy03w>=k$4v~FXd*U+-*gD#qA zm&IEmFSC{vGaswm&83oI-TqUtIU15T=Fa@37*u$@`vE-73VK4ewo#5Yc+p88=u6HF z?q1X^1#deHm4ceWj+1RQyhx^3Dw=%8OO(2)hCl8h4r9EVh{8#27L5=0DZXuhOIK(e z7m>oL(9VnYt`;8K?aFq$vmLiIS7mVb8gSI$-EL8D;v7?5trQxpgsur`!@Iq$YV<=yt%;~rYJb?`|WF3MT4e(@nrwM27h-6Jr4 za+8*NO)U9jthe?dRf}_iigvC)>0zVu;$P5pkfYCASxf?VabWTuU9zssZx>rV97Vm? zCG2XV(FHt+!%$?PHy;1`hag{HlZz&THrvu9(b6iQ3T#V<*72fm)D-uIrm-u?D6Qfn zg?u&==QXMsN0%;w;y8|1vbt!|HTa7ru7MU%cYq5=EA?orH0@CkmMUQjvo-L;W`&H3 zut{Mv;6{avim+bcERJ=~Kls240R~LOhjx~ZgCKJ^ngfaWu-+U<#D^{B0AF^Q`4ch$ zX`0i%F}S)jI|1HhQ?0I}(aU_+51X{&PiP%)6JyE8XjJz5&MWh82W#?Ak-XbJJom-D zj(cg@hEGE$y?jybiWe8$m3g%DeofFLv(So@?7Ip8QYg(a^G!^R2F-klzdenCRWS zVa0fAHA`-L@$?G8Mv&2W=N<1FE_w~mBC_)&;opkhh&kc6&-fApqR^`o-RI658LOYS z{Ku@jOrCb{paR3t1NLcLxO2t&uA};80Ygsm!|j9bgDx@dQ~+25Gyb@Tm&CeDcO`wq zE*QE8|Awkpe9%37#m?@%??d&hRd?odByZnSN;O9ubnaxExB5X=sP}mMTD^;QF55Y% zCqH$jok@%7XPe27Oz-zbcP{&QP|wKZQ<=Esyh?67_mL@_J9!SDyK_pk{u)P z`DHtOug+P|(VYD_Cs0<7=Q>4Hi8I*jxjgUk+MPRh+I?l_@a;nlz=DpGC9i+YP{uJ6 zfci-Cw|z|L%w?VU*Xdt5nOL8GCUg~mFE|A4kq}zPyA`7b6M8AfDjDnvZ+RF8p>Rr3wj&$dCFPvD9v#5!l}4QN7mt^kW0|Wlk1nDvUXeJdw)0>I4&tjC@KG}+>$xP$ zMU>}z93OTh;-Exzo(A_vBDx@ds%;bG%0xZO=!6TXOqP_;d3xLX$m-LU{5IaPWuIfG zeuG?fPyu7M0CckQkj8)-fg?0_m=d{=z)`Lq$tnVJdL#=8Gy`UVxU40hMUP}Tq2Z*E zCo2l`#RLx7KbVm=)1FYi$=H?Fi{jpDqa5o9kFUB#h5-54|Fkl@Gme@{cY|(sb5!Kr zZr*H;rJEtQ#vHFPdTuwzc0aGhaeUQ(<}YPFOfLO3V zG6P9}VG$(X+=xd?bbI$(SSsM<7#JBJ-$NDMCxLnY^K)r$<0J==j6F{p3Z3gB=$!!E$ENCTAkDzY@sl@kzRN@w(PRXUO4`1NrSoZ>H4W0yQ6Wa4YD!T@}_H7_7Z7oof z1pm!-Tfy5WA-P0%=Wo zlc+U40Z3~)1*l3SE(GFZs2pnzkhbz_AeH@3AeH?cP=)Xf!a$1)+8bzZK?eizvXEn) z3REsA45T%^4X8|Lj{s>In}D>8mw>d4kAX^sZzQ@;`SO93Z#|qU zRT8L3Xy0>aj{r><+Vc+WZ$Kvt?GuL<#F{}ZSp}pum~s{bBWDB9aYFke(6NI43N%L0r$DN25IR@&aWiYx zw*_54TKKq4Zm*zsfOIa|1E=B@LgRj6Zv&_Yw;~u{e9E$|BMeLDAO#rymdm3E zRT2;UY>QmfZKq6n1IUD4+@s|-PZdU6H%oOjDq_zcEfQq4If*mrR?dTt#;zDyoz`AE z_Smx9rlIQxx97~wP7Erb6lb3i_t&a9C zgyO~i){XPJn=E}+EPwETSf3WlANz4J;&;}}s4fYGivtKzSzH}1PSk3+N-JQU-_~)i zc;oQdwjCoA(RZeJrXQHLPkV*{Du;RXV-vn67G zBEGNTlu)B522LG&%Gi^~YJKHTta7Z@SN_BhaJ0569yq_QGl00Ib`V=TMzb9U7vVc+ z6j#ltt-{uqm8FQ`8H$w6sHsgAW6-p8?zKK3gRS%7G>>e{FNvYQ)Ck<%HI@c3LzaTS7;UDsbN zJaA7}szYRSu>~7?-h+!pvN%0S3)gI$?n?1uz@%35y5QpafU@`$mQr{9e#Kf>3Qd$G zJif9p_j}rP=B2@3x>7$iQo`eF7v_IR1@KGDW&OJSeOKxpP?&^A&=c~@A6k{^Px8wj zo3hPEp~nusPc(+LdH(L>;lbxViq}I%tmllwi*6YEYs-`ki?h;5+;mEvqNS0ZPdB=Y!6=atQsdg7&5U_x7J zp(&j_ekmDUSsZChpKLnhm#)-hMv6RsDPFYQvaXuA<|bE)pT{$i$1gP;6j!Qg(l0O! z?Hcl1VNT*|chxko>C>%7#IMIOJ@2vFSftFmX`Yh9`D87cDkr4AA) zT7YR%Fb2hTD}QYOd3N=Y6ows2KbK07Zm8RBf~$u&iA>}{tS9WP*9_lgO#x5_5^v3G zpF<#;on<>}Ty*4yv)!`zr8yIM{4G5cl3HY>xbPDbfsQ3QsnVV9WGK6@ypbC_+O^EQX_cLMk0^+ zBDQrqvC0CV^dIdc04X<;GLbn_qI<>nc3)>DT^)SFk^^yH2zGl=coVfW~{Q#H{UbpjfAt`YD!jTcT=V;xopeL zf^qsBpYI{nH`lea=KDyp=*cfg=kk%1%cIHTL8|vAbLN!RM6uB(e7nQVjrDrlvY@RM zD+r2pG%i3eHBr#UFBFKn8x~+F+FQ|wg5@!6LL9G*2Ib~z`XuM>%J(V8w2Ej|S+qD( z9(3-xeEE|j2-XlT3snZyfd0(VvS?AFvN#dc`!j!LB{o-1grf1F-UazHD@sC=rz!%@`Y1#);rP!0asw{^7G4TW3TUYEYZth6A>A3FbtWgDmPO~e6 z<>jTZqF8xx5I3VHl!ma%=I^{CM92ojL9p*jr%&|PI2sI>R+UB)h#upFs7bkJO{;Ub z82c6%RUxtsI$v&Q`zaWAw$rESt*u+_Xt1KPs-hwu_5|BVx!p}GHBuZbk05vqBC9xe zuP9gUgb{cEYXxsD7-+*2eE>aE8A+5Q(2d(n-%W8^aeaOW7AXlv!;u(*u#{)2h}=l0 z*2HP~RGcyhWl*L;0C+R4-7#lQXJdVLM@!dY1SD-cx1|x0U|b6451TF{uf1c@K)uSR zjV~OpUTyR$KT5pHmte_tDW_zlOkU-GbY^Ph>1&tAJ$QTRNkQ(p?74$y7T5VNrt!gB z+_TjH`Ro-lv7MG?@G5@_w-wu=&yKit4w(D$D&K;I{~KKVBXP0Nmsk1jSn40l?)^yOdyKFln_ zopz+?V}FdZ7wW)FnY_DM+^K1N!8EV(^T1b~#+UAmjbUnSNaIWQPA1>)2EfPh_f#5R zdj0r3<)s1evE09=@uk;~Pg>qg<4Z4>_4{xDd@MJcw|t(IsXw@&+ge3|Pv zVgP)+)5#wIAJ^_DrSYZP? zc1)+6wrp)VB8z@~?_i7gc=DBK^7*agqKDaa7>TY|FyH<2oj%|755r$!i@-In9S63b zP4c18IzA(_eevkkJs0`#Pdzh~915qtuIgnU?d+wb;YunW*(e_3$Zp-Vg@=B9ydsm+&-QeXlwv6`HJ{T2a!08W;qbmIA z_B2-@k1#&3?Zw_?onN>tRs2g-Ls_^r4qoV#s-x2*JvpX<~kt>Rr(PF`9axfNSY zZXDxikv*hMXLD>Vl0MvC$8LtBkB)-v)%5>b1M^U9Zan!g{ea+x6@f=?@;R`%u2>?^ zQ}R|^c1$T`gTA@`2E%O`8r?$aad?eTWENO0*`luSgGg^rcJk$>yu%~#zwPsUMv30@ zdHI7>Cu2M1lwMx24bM)~Pie1$Rb9&qwx8c;VOM*3om2WsDN-uEi?iAzpLSNSF0jw) zVK}Rcdn@-a-RT>hU1uO?w@f+RhybFeSrV>utFrJr^~24pLOB2vSA}x74aewoMo9WO zbVQmsq$oUh=mx)Us8$fWq3rMmTNUb{~mrlU;b;ZLFYDz~KLUHnO`j3G@HM;SL0-K>v*}dEr{K%+FGt)wmI(^scd4KRe!niL4!;))x&*%$2uk92 zk)Utm_k2NX@!KWnCj52^`Z<2t!W`=^{Aw8w0JRBiGk#kIZO1Ryu{qWb{4NyqA%0aN z3w2hBe4quAdmPZYf=&j~`Yixz7Fs7zqoAcg^8|5sXwCgOP@T}|Uah&mcXD3>QrW*b zxqk=B6^YM*@R%Pp-4~~p>N^;yPH4vfslGy>uLhN)ksk4Od zFF@L&!I)cT2@P8h7}{i@8A78ooAS*EsutQJhepRW?ZGP@+MPgE!uOCv`wU2Hm4!=? z)@mOht$hGUHIE0<(oP0a%@q!fj%%v9#i3mU#NnS~tpJJ(`W8^RpzDFOFMkJw*J0qJ z3tLRkn?PEtcY&fp%fY&#RM25SC4x={Y8Dg*Di)LgnkVQYCwDnekbe&ULHPCcv$84ZQg6e_v4DA9sS!fpkog`=lke;Ed zftCsFyFhxrJpjb#Lw5QmfI4F-qJ4Ou?>b`@7*=$exJ_n@4V9aBv{Qxq7tl%FcFLqz z-sD+FfQ34rG^~B;oq+so>nG4j-FC{PH-Jp7FLmyV^O>nHyOV^|S3NHOxV@oa*=11VqE>uak0$b6VGEpH0{cs@q?R+Qe(UzH}?6 z)cw69t=wnFkWtFuU%yr@iFMb$B!}JW#G3D~yK-jjHN@I0Ym_x)y*j<=UfFn@Uo#_- zsH(1|vzg~B<<7>SU8o(o7`;%xRW#Z;G zb_5pIb=5aF!UrwTQ@5bIG0@b}wlKhlzT;Y2>&ICgU9Fw-TluG_ae);+BMv9A>R31w zw@QnvBE_|_uvHzxgMctLe2x}tPCQggSG-syxau45g0t14u>B-?j%7kI&WMMqAr=c4 zk4||7K$o#N-d(kHbvHByIvZO%8_`gWaUGb~7{E8(9f9M=kFyf-P-Ss#RcUo75k*zR zV=PfU%L?+f#<-S-!>X5AJ9l!7dY?OUP-kbI!0zy+aSiYpoS$Dq;voFftpj~5(Bp3Y zflC8;IAWPP77b4-f?rpmB9_d5^>gNl4;jazQoPTjIU3wOXlzM~QiXVxEJ=8LTi;@0 zg%sx>K9fFuzfw$D=5&?wm14W{;<668^IF$$iAy=AA^7Lt>xU<|>&11&x@&P^Vfjp) zgP4TJ=UFAKb-cJvzU6muS8AdP$^7Rpi}#OiS)Hps!i!wHtWqN-JifB{T+ZES^41?+ z{x?_ZOd};c8N9gIgY1=e*5p6wN^zaV#A~$QJB??&Th@@Hj*PfcOOeMUJifBjvuXtL zSk`Y^t{?77eTO1Q!sBZf`@}74$CI7KC-O`O zP0Xry^^_Vt;$19E+)ivkTL5BSjv+)PbP5QqNyif(gKu;zJ)M@(i*T zE`n>alLCfIK8+MADGTbl5bnTcBPHEu3k>rc+q^tIxPY|ycHruPJMg(Si$y(NuMQal zGJaU_w|>9ma?8}lvNoDJlgBSbza`ffWb5wpdtE8sV=$4&FD2_A$LDYG;9D+prFJuh zB9C9{5Kvt2tLh7Xf`y@NRoJP4zy;U)JGHvDDGN+-nwF{Y& z0^n(wBbP)E#cRWnpu7D(?#4^zyJa!%5EFUesnf4_+F{_y<}Hh)z|+>DX z^l(sI`%KN+?kRn(ks^;@Dj-rkmzgf8{XK@WVYb#A5I_#>gAwHn9~nROa2@Y(+(-lD zS<=|y3`6B=Py_Z4g6o^j8A zv+x(L9^MTzktdV)RmMHEMq4q75*dkz%`%PJC~(yB<@bq(<@ z^3yy+qD8?(JQ6J_Nx*r=S;@l%MQ#B6o;vVBk^2D00c3J%C|;Jpe!4+j$@{!FGoeu1ZCTaB&5Oi}$X`SK+DU z@rn|Bx}-ZJhjFi@*}8jVTZU+^ee51tII*B`T7ZduK4*)c&)nH~GLofJf%krk6y9w; zXy0HcOP{gT?Ff`MoA~*p`0p@YS87_y-6K8sXUxADbI}HS$}|E&@})$B%*6%aTr3?s zCn{4M6LepGKIh^Q-T8b>hs5c!FF&8F!1KdYKA9;*RDO8X+yI^@Q~6T-O1M6K6FgaQ zm37L^pzm<-9GA+MqL0^!7Fwpc`~#X?*GB@>$r&X?z7~ z{XzTfOyf(p-*>^cFFVDPGPQ%3tRJWGrRy6FzPkp%M}1ocz{m6L?E&zy%RWluOSd1- z^O9=(cv7b849l%Z<4bSvvEZ9I06zA|(gE;M-<1R4<9NPr0DOG<^!owu$^1M3KHew3 zo5q(u{`iFCy)?db`<)KHy=w5|Ntwpq^~i4+0G~X$s`V%X%yho79V62C(%bO^@Ex4S zmp-m&zkAd8(B71F-F{fuJPf`U_#zRB>zuyUb+3VEhv9S9S1IczUKjSBNlk8&@tjib zJIFo&d_!q)r2fj?2RtJUUw`GEWO!7gS+Av(`*mc7!S{gS?XTR&z_Z!#^;hl(hG$ph zegVFVW+_*HaZ-4Fm z96Y<3mk|AxdyM^}!W5ioT(N&o0N<^Kx4&}l0?&hnufK9%F+96!@87`Ja+Y%SS8gYG zzHa#XEB8MP&#ub-A^7rfZ^_hOx#PfdqT%bW+*yW4HR^eU8`-bo&wM|0{99we;QJqb zn)463GmBYysixVOJg;cwCO`GZ^CTuUOOExWaK7%*_#=gZa#gAln7eC2&l(IjLFOLU! z2!~hscu`+fnU+VwuIeAI>c57&YTvH(?@E4G_TQC!|FsVULUHk7=+plHZ2fu`+P^!d z+el&&`*(!jfhp0yBm5?zEYF{XMHl^;6Y}?#{JHY?p8RI~rCa10`Fl$~eek$*{969S zrh_|B8eO)zV>6Ez8GVazyz>!K+6`qXC>6<%N&3hLaTh!87C#Ft`~(6U#MAwfEOYU9 z*~dfkF8#ydAgF_RwEq6&>Tj@l(d^&t{PR{KdLGkH#{FDE$oxEFJ+=2@Ye8f?UbBy5 zmu%r!c8_FO-SBnZ3mn$nH{wUKJf5R}FquNXn-31W1Y0uKmMmPq?cP1%lzd(O=Jdj` z5qLDU@WX8t|6!|ewhKoz=&sUUb zw<^*b-j|!ru3;aVmP%#VNt>`cGTdozM}d*vaE_isIqJUB{IY2aOjVqG*zW7+q)_Kb&ZWl_xAQs;RpE0>WoNl<$;mj zl7N4Rh%~ZKM0Tz>+nkNaIviPhXUxi5K__3?VH~B0?h3FDNv%=5_qzP`IF9%7WiS4$ z&L4r+aC*&=0RSU`9!owOch1decZx{26U%|mHKm5p6OK9e29Iq{`rz^- zFJ2QOn5;N=*zJXL|2i7UZt+nm3?{6AsXiy5B)GlPY1c)joV%~G^{}tC5WA0~N$sV+ zYiyKwPJ2V~PrbfzvKUVaO+!L=aWvXlNsng}|sd9O7 zKBhR(Cs96c+3PscFK~QaKSFAQQ~QMe#>H@apCq%i{dfDxXr(k6Urg;K;mSc1!FI zL9CRGC`$6TpURW^E}r!`F}X-|G&ww>b%cH`_NAjAbLez{Qw$%+$pXVZ12NX7@_i>i zfLqEEu^cMk!AcpKVh{5%oPMY1ztoyRlJa>R46UDMp)WV~?D<= z5v!zce8EtRE}Y!Ei8(ml2eC?6M(Lv3o)x-|v|+yB>S-3&}>_!+3=}$4}-R_ma9tXT4pbpZO zyS*2MQ$);Y7in2B2kdtGhk}|_v~0`u6nK%#ZggOgY(5j~^WtP|>ZutD%Y`O4!`MF4 z3I8P)65G$RyYJ}qdfHa`GG*`j&V}2kZ-Iey8}&^zmA#ER?q&)&MlN}92gsi7)b&n- z!!qaZJ9nl;{Y9XH+fn%d{sG?X!nH2E29UQAU|8c)R|0NS>QY0Ma0I|SuNE<=0KP~* z9>?~2B&y@qUi0a4G-bpid=J9OV4r$MCP2X9qbP6G7;`fRA$~5jgA@3)#`)Fjg$O63 zGlDGMNf_;3mfXSp4bgq2M5hSdHJV4xN4GlUj{|Kh{#o7|INlk_@G@)9-tuF3-rdaZ zu+I#&dT))rAQvUQHA4)89O6E767IL`QN*WpHhm=Mg4u8Jci3;aUQzVLO0Wm;4{#~| zNDsm80bopz?Hl!PGmo8)(eAMO0VbNutN1=YxI#0Sj2 zYHQy;sp*Z3#=jI5EBwGQT=G#YcSna-O_pZ&&OFZBT(Lfu!~y@jVPCtEgZsS9Juq`W zucF?WJ~N^R?)Z#7pg|*GH}B0Y8w$N*2irb&^Hz)1$PthV>zZ}v#$_K3O1}sCE>@D} z9tbT)cpw>E%kEju$!@27*&58d@?pF2sMSc+O7u$qzx|K)Kh7$rr|pvoRqv;#&56@* zPn&aF$BAtiXM>&@uHDaaU)8V>}0HvHbbS`>)$y^`QpN(pVoZ5b0-!@YBK3CZ*RUE%G;;dnYbFj>-6b& z-uS;h%{ce{>n}X1eR|J_1Mkx{;C1@+H-F32rz>$X1@Q0xE=G7N@YOFyM}M$$r*6>V zzntRk0$Z-wOMEl$9tC^j$$Iw@e7>_0*tt0B#Ywts+Y7kF*eZ2Bo_vz(Oow(K%cn$} zAx$ltM9Y;%n^(c|#S9rsN+uvp-1PcxYf>6?HjeO4bXZTjWUaT00-b9xOd+ zyCPk}BJBWa{%Zz~bo|wCXv%9{Eo+~@=l%7Ock|A`^NQJ<@Dyh~?z|u9In2A(?yVUb zT6LHV4_t|c;0}gsMllT5a>c7`OE)Jfw0X#XFWa&H#_!x<-Mc$zbVi@b7dTE``4AXHvM7R+tlB*mxp_!KBv8R-~8uId*6j_XWDyc3#UEbLeic)o#&S}!TT)Z zG$?7}lcRpq!N_H(o*e6OpuGkC0cbCvZ0pZJdkF3CK)Vb22#7lj=7`)7K?mcPXGV_2 z4U_oNE619I-z-5<{91xI0zbz=j>XIIXM)ZK`dCmSke0!ZpIA(^kTA;rO`YF(Bg6?)`_dAGhM|nxaCPhG6 z1|LFe8E-m#?>Xo*AT4(fyaIVuWQPN3X$Jyr5!$gpe-gw`Wi^+ZJZWwW=#P?{aB^oj zx%EKLOKvleTCxpDt#%QRTJ2Jx-wPi@Lp&qsS3ufcZU&|Hdkje1#$XWIwhw`{9gN7$ zrACf57%zPI0aK232+-4l#sWPhh+9QzU8VwQUHEyw)}%x$yPl&`NK(7f}1EhAo z8c6GME0EUZ0U)i*GeA5ua;z7CekbU4px+952WU@0j9or{39&SyBZI)}CpNZY}8^ACuY8-ZRE^eZ5(=>{O}-zR|nBDvgBYKx$) zK-#}=JGt*UxkGV>ali280jb21KwPQkSjRfFDA2Ekb~@1Af*7lDouJh~cM0N?H*Mt) zfwYyk18FPo0s5uzZ3fah{}pJ9&^`vznhqUm)Ak3_bNUb*T1K$NDvpj_e13wB>&Q`VYzdBhX(3eFSu!pwEG{ z+??G&!0d`E1dx_-m_s|-p-lk#e=z=^1bdkZN8Hq-Vf?IJBFAbe6ges8>q67ihJh-#fHF1L@50 zmP32rL7xL{6^Y$3t!j%70Mc^D03{`NJkVu=W&mkTTY$8^?Lc{wdp=N7&?P{t1bq`| zrJ(NtT?&+I-DD6V#X9I7AZ;b1f&N7#9s}AU=ry2k3VIu8g`kgtbVP7yenV)x1L;|@ z575_zHUbF$WBdj1=VC#Vfi4nM2DDnxTp*pzz7BMu(5?W|+3ZI^I-A`Nq~-n>kdDNM zfb@)d3P@+Omw?_7Ew2G-Y3~B97TU)^T0dUgaDe&^0n&2!0J=bE2Lde-bOex=I~qvK zEdq>L0BK!n9oifqJr|mQbWAREa=V?}3!U6$PHxi4z0sll1W3#H6_8$!egkyA z)btS`t?4Ept?7$ET7y@Bv zFwj0S=hOq~nzb9KU1XO4>6(@CVJ{aNTWtrblX8dSZbq$fD3Ds?2q3k_ zcp&YMsX%I%AduRn#-W|%&>Df%F6RKLUAlm@m5YJY23G@JE;aZ85a+8L>nA|p67+K* z9UB{f<_hf*poazh0qAi-F9XdHv>oWTf<6G!((;Der5yrfEDnV4aZuU>AhmcGkXn2N zkXrW&Ahqr_K-vpG22$((5=gCk50Kh^1CaL7?|{_ePXVdLUjK7|vq0Lb41ZE1_1g}lR;$GWShd<*Ahp_jpl5`y z6-cet4Ww4P5J;`|Z6LMU{{vF1tp!r6{R&8}b}x`x?Li>5+H*i^wby~vYI_`DTWvUy zTJ2CEwc2PPwa^qGwOW}&t9EF!fz)bsKx(yffwblAKx(xWK-^v%_wi2dbx!WhKx(zS zfvUtBzX4LKeFmiGLiT}nD-Q%xyNm`>t4##b^W!8SwNM=BL(w-2NNq3&NUhccq!wBP zr02p7KsuU!45W6s6-e!JACUIULqKYw$AQ#BTO8U}hxRUzTIfR{wNTawyOl$L)ItXX z={Pt7C@ytA9%zf8i9kAXP6E=AQwg-E3sSFpi71JGoZPG?f_ER`+-z;BhVbleGW)v{{o~V z@lBvfl6%M@c7GfV^pVgeJG8JvI}PY5$vq25M??pZj)RMUbQ~-Pnjn0a1AQ#$Dj*%% zHvnlFKLyfpe=pED;d=l`$Nf$q9rr^Hwa5LzKsxS^1JZFn1?WPNJrzjDeHGA$LOTmc z$NfAY9rrCjI_@t3(s6$ykdFIXfOOpd97tPvKah_5jX>JoO+eb-R~_1RhxR^@j{8r5 z)CM^t?N;svq&64{q~ksxNXLBv&=#rv6d)br3$Nlby*|LQ|r%DZqfld*0nv=T(=tQBd2GVhVjg$Kn&@{>2 z0(76CH=NwS;r6&c1xUwz7)ZzNX+S!5X94NBZv@h@`y-%BMc?f}a|QhhNM#=cQrSm= z=1A^lAeG$;q}Q$C0lODQ0%??bSd!4qAY;_q%{T$3c#D0g#UN6+qh4 ztATVpe-}v0xDiN4`<+0?S(IG|q@#U3&}gCk4oI~;1*Cj00;!g*KznBKne-b#=UGHM zfEoq82Q*vIM?kX#eFju3$U4HZ5`uDoP7pL@Z`_yS$WGkeK(`!Ml#7fJ_~&jp-aA-% zbMVLIQN(eXFWls!ZaZbti$OuXxr40SW@4P5MmI}!H7dda+35Ci5@*t_wKxd3@&`^V zu@1~S)f%>A?=5?7+I@X)`_Q>VXa*#@u;TQT%?Y#3*3m^(r88=ZD{HII7^C|?SIsbg zYa%wwjM6b8kDsNo8Fr^{D{JRtWP2}b&)3b~FQJXzaKtX4)TY>=c$U56wQNOQ72&?v z+~68J{DrG35;JN;Me$sZkUu zE-kJst`5}}heI{c6lt8_*xJ}p*VPzkT(F>}y|b;Q;lw~kT|-Mtpss`4X5+tcR=BaX ztD|l~U|w6pVo=(e0v(M_jUA1x_1y9sF>pa_uIn^{DioN}+IU_!g!tRl*3m*}m*FXb zHFtI&4>VzGZnnwZa=dd~z*POr;_9lI#o^kj>M>Sz-Qr_90}U*g(J3@mJ!-zvg4@*yvH5|fIuu6)pbGK?!%%`q@+4jfwBG7t?@6aFu!7tnW1OKjH&ue9nU&4WP~ql>}qan;0PZz zHlUqP3uZnIP3Mjp7bwA5(IsaZR>9XcQwcvof*85G)w-1)z&u48^9a^$SH4P04e zDp?{Yz6lA?(4un?&d9d;tvIRdc_D3=eS7Z(tJWV|fT6T;>d$Lr*l9T(+N6r^@C&2{ zEpQ6M8C>7d(7LcwH;!%Vo|CFQRn(br+-7+rC9rO0Qt@=cDB9mQUqM>qHwT>X%>jwt z40_S=RYf($)iaB$4JlDo6XTW%mOZ5vRYhXOHJIEZv6|XgWw>^XRJ(0nXJbbX&JqrJ z(+74JHMDegA+$nQ0K0aeOFMNiaH>YVP7I*L>Y3GnQv#z-3e<+GON(oX$NAKb4PXKo zYd3{wvgtDPAp3w*a9wMlvAwx*AwofPnxZ(B;sR6Gjc5wE0LZAq>4#Z$A;Lf`=J=72 z5sTZp1Fem`1hodbxxFMH8q>*nTI3o7GEHJGY+G<{OP4dj$0A|Ggn%_ls%BIoTE!@- zwQ0XL_kT*&Yn`g=g*sLV7q>q~FL`4#)(H4O?Ha5!LaV}C0oN$p0=QD)X27KiHvukE zxDl{j;d;Pkg?9nYRd_ofKX`-Qo4LJ00ywrRyq1{02Ef-42Nka&o~n2yae?Bc#G`@f zaF^ggz#Jgr-*WkcmpMTm3^O@Xd5~)k3V2|dgVFI-@%%tVa$`LCKs5PO;UinQQo?sZ zG{gpq;29g1zD!)W+37G~U3eXmtd%z4H@POf|t5#RUs#pCx zt3G7FRX@|Ix*}Gc4qw?;AE)U*b*vBlG6SZ;sk$Ooz5d@;_1rI0^;W0qidgl9zN!cR zdC{CayNYL{-0ZCMeZ>*YsQ_8lM^Yz_2Jar@yfS8IahGwX^?QuEMiHdOE7GecV?fQB zLJB2Bij+c9*kYydh=>nQTuJ~(JA9OrakK_yDvx*1OFof7EU6>#aB>jb>V6PjD^I{c z)z=*SJJ<@qcW|6%=kOt*x>1IPy|i_u8&~ISiXaJ(FB;EKP~AvP!5OEGa-}*%29L|g z<134;b<660H5UO1&2uDiouHub_{!Q%r0{ME+AJ&ZQsdpO)U}{636HNV_>FkVy5%=R zJkhRh6&ZD>^G8qGL!|QYi!QgmHTdv$x2*M`FbR*KXXKYZV$}|J1A0DQ%g*AGK+@)h z>)kjTuNfkF&=(%5y+CoJfxUm`kULx{J6;}n{8D^&=f?C{^1)|cbESB_W+D#;1rn#` zpWuN#?LNd;dLAg*S!^BC&*naRgDqoObw&?){H1fex^)gLyX#F?YNe4Pk6&sZk>Utp z`sJ|=PrFiUjTCtpha@#N5h(SG7t9gKbj#D`Zp0pcB%*tbX7Y&U&i3ZM^z18oIEtA3 z@q*}_%S0a0gNJT?>5*~UN3^1yMh|&J4<1wXrDuQexb5;sA{wb(YmvuqXS|X0NcrRQ z1dSAV{89&s6wfK9-DkWIB8R4W1IVNB8~Ae*l%$U+c^sW(>sj~1r+RD|ILjD4AJoSlz5Yl|qc}++kw^7RHxwPK%%khFrT}=nGXNiPyDg1A_bg6FQ!%T?NRdZr z9iSYHlPkTYBSjC#15?*!PfxIAu)&VeLmq$W@|ZtstjM6Y>#lv-m7-HL6L}ClsS8i= z?4fD}K#>4AZRZ&pDc*J+4k>q*IQrOkA9XeV-DoC{wrd|;+~#4*N^e&{^l-#7U3~ri zXoPK_BX~(f3gDl=^dmsY&N>FaOkaHO$M?HZGmI2@{8C4PlAU!iMUW2sVGNUjT^6JD zGLZ){ml(;)Hv=&5G4Q;X1s%ZJ#I2y*0_HEMF#-^4f3|sm?X!kFUM; ztXrReks^=375O4{8h)AHK4;_@R|=P3N#w~CeT$jguVAxN=Os(#v^ycYq|TU)+vj)K zLm>b?c;r|=q0>vDo|~X&jiU$AuG-oclg>mbCOU){;IFowls|zI@KHVjWwb-_+UF=z zomhW+ZCLe!+tT4&!XS}HVt+L_!R@4Uub!j9lbuyacBFfrzo6UI6ES+o{bcBvU$|0?rp!bhztnM{WM_S!nMlvSJ_%K} z&y@3w6nUf-O|8CGct1^u&@O$Wks{Bo zV!n+7Pj=RKsRZek1)tvI>Y+nC6M6ilp8!g>6PfMS-u;)lQd4u0i9{a1l#KE$_AJw< zXH5Q;E7f46$b)E&9WAX*PEfo6C`{Lb=T4{J@#wdyW1;tq^ICO0_}v=%W5>xh8^|Y* zzlOMAK+3*$`(rb1F*PKQ)@LUu?M{8XrSm+>&Z@*O)3bNHiXmzD&cQ}Kd6afKD6(n* zC3_cf4kwbwxeCXge+7$ETXUz;Odfx`aDsW-^@p?CaKX2w))*=BDD75IKB9#D^R{cU z=;67*H0|Qmr`s}?^@!0!o3Iypk!xp^~-e3_<3Ef)I&y! zJiCf&coKNrG1mF^th%i8q7D`ETYf90~WM-0?WO9Lq zOQq1JN!rG?Nl4OCK(LTjDAOP+a8OYZF9#1Eg>&%7RV@_SBDaFv6ja1pOBD(t6cF-% z-?jF4o9~-81@$~W&woG3%$l{=TKj%md+ohlIjd3XMqkW*uCkL-C_7C_*D{m=twOv?X*N>Y@R$c4HaJrF98l`9j=0zty zUOAr-Ih>=?y*=%*vuz$2GZ{Ig@#pg=fhjCN#S-_+)_oCkJ1*ZcT%_@H)c{ji@O5Rf z-h1ht&%0c|He94pNf9hVIiu7X-m#nSZAQsia1cJ}{@?#R{99Wt6t0j=7sbEyy&cYC zOG?n2KQYj_`Rsphv)9NW&92_ttQ9%m!YAG7&n!o>>>Rto$RUl4L<41kR{1l~yinlD zjqV;_ZSlrA4mob^J)`<2PapnA6BcQ>vKw61?+A*R7>&VF{zdp>LW7lfNv3()G<1Yp zB8ox8;SK_g?KB-n`!K;bIZ0jN&@ill?jBnNzKQAR9mv5j^fC?ta2g-4W+?$IdL-lv z{;VJFIrdqFbk2_rTeyTs_G*@r!o`eWTDmGecWy#tZ3RqV|_0$3P zmDf9QKHr2cG`={eh07afm+K0{B{aS`Glu>+qw_`RpT#HR{Nm#mBl8GpJ};DfZV1G= zQMl}UK4qwHS%VYjub9w<#uw*|aCzhGa`EU4ozVE=%ozIP+ysmp=c|sNi767}Om~lw z(-ep^=L2p&GtNy;oF6n?LgR~bi*R}4>~cM0xP-Hp&Wxcy&a;4V^ZDB8t5CJ=d_K^~ znH7k0n{avKJj;nQ4<*qFjW5op1M6>tE?24H5*lBe8AE@Z&k#9wJ}(@~Jm!bHzBu1>+as&oINxC8%n8K#oIsrCIC1{2 z;Sw5OoX-u!+2y*!a0!hs&Wzz$>mm5pz?uifKGB+KH8uA5Q93sooe`a3)uLLx;7qZi|A*{v<6M#oX|@nmg0hWE7Nj*YMVI<;6b*HprgO<$;1%UkD(>gjlOj)#YNN^KSgN+ADIJA%bxrj^O{HUBT~n#H zkTsRvK*KV$rt-ori9TN!50A#c^8SvVrTP45&YI6JZ<_nN!dXm;lhJr%W1=yYYV{Pj z$D%us=0pOuv7tVdXs(T_v3E_SvGzs@Ip*Gg#opT~?AmlRo@wTb^>uDYxklfC(CSms z=2W~smI1qM501?2g?LzmGh1O2?o=;Wok|9?w(Ts{tu4{!L~C7Z5>>Vtvc#qsMF#_L zlvYnorJ8`(RMG|2EYdvj^wkDctTjR;5sQ;Nc-w;{dkZfQLYlzzR(#9L@DqpXl@{=vmWGzzI)KnXV z#V)I~eV77KhJml$CC#@jt)(9uSl-dyxngHkt*X8`RomKt4nn6`{`e*uFcPHeqxMwC zi7tqDCNXOe4^(T1j0RK0|!YGHhub$V-S z%V}*%4CnC%Um_5f=DOzk+J;(_b#}MstzRK=F&$7kT3erq)yA4ox6~@UrqVGBuc;Kf za9?<}iD+GILtQMDNr9ubW`=Dr9!6Z<(ApG>CFAj^ZAb28@pASSVUyttFI?Wfq@x#G zYo@tPi)R|+O%09lC~E;{Cm3fykY@}s32VUE(Av@zOEVWUG(uS63eJT@+x3;8mSkahks-+03*|0etNtHlv$CfDR zK{%ngVRt$8(M)}9b1Ukcn;gIKc_1y*(ya}Rm`O;;-u|mG5lz-NW@=mNS~aF>uU=EB z2J4Jtczh+MB;Hw6s~cPElFf-&%1n9E&01*Al&rgllb$MT?%ed!_Jv)w&`bj!=;~P3 z-#vH%Hb{FHcl$A1VAy!G+OeCgRg$wdF-jxqFMXtf@X-cHplI?-146^;gu>J(O%Oh5 z#3*ssiX37=_=t&7;tmGtU2qA)M@)d%0>s4Z zZKwzN0P9JSNMu??Y2}Qn%8JTz{P4JGrKMF>Rgp+}RmF5g&)d86a}%uLwnt|zhf;{U zBy>|TU+frM-le~E$M70kacv{_o&dV8`O6lTP}L%CGd^t#7=yB+)`VKGCY1Q^K-QO_ zhOIW6s|Ns=?=5U=PaIsuKOHr<@)mKiNmcqS)J3;t>HCChtVx_X*Gi zBSVH<0g#xK&ocM1~hXc}}9YW7$%y zp!C4stgb;EcUm|wC$?ls z(AVA3HK#RxVpTF*k(R!}?xo!q@{C#>=WV;8w*ejBRz2kOSX=CLoCCTVh;(*qQ})G7_T^Oe z7hCXK9wzNXEpVS#Nv*kEp2SJ5xwqs_PzV{`a^i+0ABCL2Z++|n&tjU}!?O=>lon`Y zF6%I-STcAK>p2L?;5XYe&u;+anUPfXY5c0@4dW}}gO{y%oI_6XjH9=l?EvkI@Z^t( z$lf>>e%4l6+?Yt{1AB;y{d5g(gkSCnp26aVa!6=3A>*=g{NjIJXV1fcMdY?$m7JVMe7o+0U--bVUxi!vAabvXt*iwlHW7UUW%pHx@BK%?;;W3XP zYsL)n-4b(9%7QO{$f=(lCSsD9?dFG^`eELYOtSYy^CKiN+wcmSsQmAq0wT$AgTR}i zdS`gb-0f=K2!&zE$TGd&i z@}T<%IIgPdOFkE;f=$vny+j@gm1=YJO{t9~wEN*_E{h+go7)=S*~eT{Rxf)0VnPkurl+ z+!*vt>ZJYz&P^O*eEn8TyegcIJ&MYS<(0#_md~!K(QuIl>FQhDb)oFX=z@l|& zAAg9;jUgu^uC0jQ(rJZ}Od8l`ELyx1n-i(+j#b_XzyIXHJ$cvj z@n&d|v5V8xm=3C=?5@?;pc(B$R5D-yHZpFEMz0HE<_!$=&UbnLAzC3--Bd%LkBzuS zqd%C{ruqZ3_B_vCdhT-VIb%jSR-klTdq!mK`8zb0A*l)BYfoMY?sIw8p79(yS$n$2 zphUzAsBHVotk;zowOZFr^_;+?PpRweKr5~2y4p{cI{pi>>gf3+5xdAj!=F)|%J-36V2yK&YXY!5)&D31F9C;DQ;Prq@ z3>}+!*xHjL?s7u|P+Zs=kp1nIqo89Ce#a>2IPTpapeqfmp*gNS6rc;PjX5ejISM+C zRKFet9plGq4!tfc{}}G80lM(`y*mmzrgu+!P%?psl?VI%38SDR$&sU=;~aPTDCjtD zGz92^<<<`L3AJY zLEO;)t?om{fDftqFw<6dntmGY>54VipPq@GCWA)qhv$a0Trc^3S`4`v5A_nHbLCnd zlKAXQx;b%LIv&e}QrLTHp`JkcH|By=X9ZC{%xvGU;EzuQQ9ca!Nl%~UL-~GWTAJ(A zZKo%aKCJu0K0B4l+2#%ZvhkMC>a5uqy&{ z{sinQeY=vsEB;;O|E~CV9{Wfnmf2bAB9VW#{Ln(lL89xia!{c^u`_wbnN(}W&VXWb zC1wsOeSbJrj<*5z3La70iO&rs)ff{p*>9I@$L~z``z5&W5#P{d;+xv3N&E)itq7ld zTS&KNZOP624LlcZ#P0w;o!vr|s6m0kk_05zlx#7iqM`$y&laV!uaR_z;f@ID4WbJp ze!IcTv*q}G2&7YtC}nTNaN<5Tm4Pyr>nZV0AjXRz%YKwswT{W`<4_uI;x&)Pj7u6^H;vvJT~}dGh=054!iHgF|oTSk1w!A5sg&GX7em` zGJ9XDaI=UUPMrPT(2fIwlBj4ilA!;i>I?#nt~ArJ&VF1w`*w5V@}|JiOFnGtC7<=CtOO}TXiM=<0QYwGIjAKOPeJecb<; zrO5%j# z%wQPY4t%3=RcmcE!Qsi?&A^*}SX+}_gmzRU3izR|3X;}=g9FYU!C~T8s4dP@m1y^} zMZ}uRaWS=K+{QwDTiebv0p2|sza&!(0z;aP1nKP4g1?(9Y2&%A(q@}tvthJJWuGx< z<@AcXo9j&S`4U1 zpw9tPd0zmuRB+z}q#QQ`S|T{=N|j>+pmBoR42W8iBI}QUGzRYi>K2@Za?%*=321@f zINRwEXd0mT0@VVdD!Ir?1L9tKk<|w1T!FeA-{pX~%U5Jw?%=Kk#P&JH`Z}Nq;`?8K zIC$XU4?t%L^b?2fXAa$yfT(*YvbH*OuR3(^I=+SI-l+A)<7j}+6zF4sRPu3-?}>mI zmvL4#pfiMyH=StO_`KpQ!SN=M`2ukgroQ8f>^PqT=rr*?50K`;Wq_3K35Sk%SDY$z z=K^XKXc?dufi4529M=NU(z*#yMtpAv)F{w{4&5t&Qi6kG947;r-id%z%E^Edg3ADk z3v`a-`#C^S!CeoiMxgIGzE1)=MR30dG*h6zIlk4X!qtMS2c+doix~~~^MEwR{}<47 zq2rwfT00*HR3*3<0BP-HVzmX(UPbHQL_iCK?r1DDpZ=58Awrn!G5*1?0QQ0K5DG7(k zR?0(5_QC@lrPlZt_u9PYx-or4^9oz{U`E2tLoaX$z9-?|zOLTC_bV6jI@Z0r+WD26 zNzjCT_TJtfl4 zhCLt9dq24H7S$f=R-#@3HO7)HP|p?$dOUEk5i^Ycc(U!&?$vrf2Zl~)e4F9u*T7}x zOZEHLUFmZDL3nn(@&226Gk)Z9y=AyG_osR`TR3>>#yewp<$;SmG32y^PH23a{G2?v z>Ee-bH>{5uE}`+Ii_?a}f(SlI^4YI^#S_*EhD&JRi{ZmyEQ`6iyW9Sf=LOszqVsS2 z^L=YN(!eMqu&K@tpU%HI|5?NJ5%~DII8n%ViQv74i!^>NPD9+QT>RGo{?2fbMlQ+A zxo!#;G7GzW7vy+TAvMR@F!x_$199R=Ba(M=t>8q^XepD$f34t=MhXw(j)OW07WivWYo_l`d2b{D}co8Q;t$I#%yxwDHj-q5)t zo6o%BK@&P@6#TuxXzv%iuFNa>V3EwaN9Vsh>3t)IH2(N-=yxvz^Bbg;uycVU&92Nw z4h2ml**Wgl~8&DU?k#i)_?gdN!3!kPLIiv}@@M-5pJrR-2@rdrVZ+!Y$H-^1Nas)nX z%V8JE3>zA9?_q^s3G)qyCIT9m0#%lh9FC*;SnCe>*Wjg>fkDrimhAlYv$1Xq6 z5m1#qJ&9W{GOajXZB}n8d-SK^5T~xet|d!tW4K+N!qW=prbzteQP8oT9$>F%Ovqv5!rt&ZEI=3D50#9PZptX=*xo7v zbiww!7wD=2bkQiRyFQ4G>irP+e|bLFnVWq`BUN@U%t8(~R0n3TRelH`G#hvN8L>8) zwrvIyXLi%s?V0RLTku0{!_L7hDz)YY-TjAU*d}59e#tudzFmxNXfbvxe&b+o@#Nb} zZUk67`QDPN@ol!eMI7v0Xu&`uIBv7kI8F>j)Fef$gdUIG#kj>bCMAx-mMniWGyDl) z5#?q4ABX=5_&)^y5&XjpXc?ZETUL$#DE?EKHC2fjmEALCfV2@B5PB9QDenn*!qw-29s z?9e+6%Z~~p^%8DQb!-?u?^ud{JytxSXk)75{@06VZ^Vy@MH@py;|6$6Xm=lrsGsme zXow`w4RPeY1;vv#4847h=bA!>n?9?p~$4A&LF_%YM5 zy{Yhxv?+R+3x3)}I(8QoZrXrE0&KUcVM9~OF1=|uQBq(CGug*e*~j5C33+OPDiR>K zJ)5!{4Aa(k_R%LdtTobrijQ0gX0fa(2wK+6VdYdK&Eg+!fXz$CrgWh(F5HnAOse_e z$R_kY(V-o?DJRCWe1jN;l#`V0&0Y*#`Qval89$L}_NXVAD; z;Ky0aK72j#pF2)%!qOc-2lfy{ zkS=^mq6`0tJM%ZzwTKg~3B^ck-f-Pv_?_Y88&$zhy-65q22%uU!ZutwfU#(iHwzHl z(K`zc{wM6hze3IBG&u+6BqyZ>YiF_!Lxv`k-GI1Gx)IT~<1AU=l>HcbnHFMrcEP|N zaJLxPEAAEpd&=EnVDGtG4D3;Ni-EoDC>V0H&dp}_#C`#}L-h@*n#it{agQrFGuKd{P2$>rOpIK81sxE zcCQ}Vqc3z5kUJz`2toj2H611%9?l@O(;yc4g5dCnKDQJG|14Vg*(q!)d|>Md$eir` zZ#_4(W3Nlw~0x>o(NCtPD1*A6ikAy>A=-|6#(fg75{!XRfnnr3;Er+E{#f zGa3~z5-2cl7Z07Hm`Wr9^e1g7zWjN#R6ws44?O`0)F&Fh2a7N7Q@^dnLkrYT@*dRp z7hgU`{RC5d`CG_4@E&V;<-7RuF9Hkd2Z}Gh0?=^nu|qo=mZzPHBJqmdH4~ETqZopM zAQ6jiGsV_PxE(n=Abd;JOTMDelxhn+~7`egR=$Td$a-C5k!8Y zvRsc4i`LT~csqXL#}f$J7G=J5HGv?61vGEt|26z?1M;7$92F- zLZvfh&RFQYAkd^};v_dGCMM}&XF=0Aug?Up&mmr)h}Xv_t<>vN?d8GA1I#j#sjWSz zhfY(jMwIoT|GiE-#mFqc29QDi}PTVGUAdlU3@`o08 zfmhszkKOTJai9Fqv3nj8oV=s%&Xad;A09H!-HS|j$2s=lsDGt5LW1WASN3t=DK0(2 z#r3(nn%QX}KXwCQ2*X7yJ%MnrpeVa(bgau1ZqN}A#JX0ZYJ$$p`P>_*XsAym2+#W6 ziSOb`MiVkgH6c`YtRo}nHp#atRbbeE=>waAh|M|oob|MR_$B^v0Te!eAy5xKpAl#+ zKA#roJNSH3pdaG%34wl#PcCJOtUu$EB8#jy@cFnvZ{zbZfeMhuM+N!_Am!lGxIYsd z?d={C=omm71fn&ahEW6PLBZ7lx?iAKfPN~_Y(OgI(+=Hv4&7%Qy2~88|90qZcj)eO z=r%fZFF16xWz%q9ap>M~=*FRZH3r86`iaDf#{}*X=wv{eYxRKc7Tjr$@0pHoC!jmT zx7YC&HiAif(M--jLF=K$RzzQ1#Pw>Z9k z19Y?aTIiKEMI5d*MSNF@O~JQ9!E%7jbY?01XN56M(qtEwY*ctrTb_pw9|)9iU4D`YIrm$LBqj z<9 z1)AZ|MFA-<4{)%*L#_c@El>xbr2>5#kV@v0n98vN&=T?eEFdk9YXB+7R{<%=T$E|=?3iKc#<#+^;a{L^Sa{Lm|r-kmffVA9r<*BCQJwVD)gsfGL@qpNa7g_rO z(y}}bkcPp7Bg#<;NI6acv`9GOfV8B~0;FNg1*9Ac04WDAAzdgOgMhRitO2B9+z3cH z{u7XL`~c7b;rJ0CttA}6l;b`?%CQNMay$;GOE{hZr1fPRAmw-+kaD~YNI7WU-6aqLJs=I2j~HsW&jQkL zf8)^o36O^SDj*H_EkGLX2p|o2&yU#Q76W=*LOU2xw?JipRLaSKQi7{>d>a5Q5!|_e zHVCu;kcQR+NJCo=$fOdGrt-Uhl=puCX?h<9qSZi`pWKPoF8S+<~eAoh-g72iFEj?^(zIO*s7s{W z1V~f)LqM9!djV-Gp8_;P=>7mm>*)?aXs(Fgh(kBF*sie$1F90=V*phOQ~^kN>j5cm zGa!xC>43DhF94*x{ea4ZcL@K+0PINO@-h()_Chq`b2LX}EI%O%~ohK+3xu(9Z<73Xso(H5-wgOTq+W~2B`yL>ba>PViN;x3qtp)T8 zk&*!v5$Fm)G~Kh^3jp-Mqe2*HES}16ueLqGkQU+FrBP@f;Eoh(Qc{y{$=a9Arg)f3S7PQ-|QX+e58!6_n=MIYj`gq!I_31W3aK;IoJd3sWfz z4jf}0Sa6uN@49{Fjc;X64R-Y}wPHPyuKxbs{zz{Jo;1KE-;whd;pj(Xu>S&HzdhI+ z>1*#F!0$!)2SenTsSzIc>+Eh{*wZ^O*xeC1zkT532u}N1%`J&!DK7AiMcO;MdO9OL zy`5c?BV8-{aBDsU&+lE<(>V}1yL3u+Pma}-C#}Q$+pNOoNigt-P6t&ZbEsdRfk2n z*$#GTZ#d_q(kW$OjI$F{6INTImgR>T;&oB^wkq^{7JKHBC zPX{CI5gf)@h(hY@Uf4Yt%*f^sz;jHwmFezbIYfFFNNKlal95I20}BZ?!iToG*y(h{qlf($l zqD;1qZpx8UQ9(JCPSi&$N9w;nO68RlRUt`Y3mmN|JYwS)R5qQ0%6B_$(xm;Ord3l^ zS>^6#6Wf_z(hLfkR<+xL*e3jvs!A!U%E@v$BeUz0tDV&rJIybtQVXxbj?^e6r2|ny z`6Eh|PSK50P;(+tRqBsYg;oM5!$&Qttt>}Uxg@T_sRg5yl!(pt$EZxwR=&Gwo1M(f z?P*d4%1U=HxBGg}@9O92bFo~Tt6is6qJ5^dy(VJephB`OnQ8i$o-@ZpMBMA~F>fn` zbLQOj6IY1OLY^}(<4?{c983i}k&ewU&{Ko+6o_{`c(%+6MqQXfWXA^Wn<2(O67FhRO_n)t6{Fuu%Q+S-y;GVGd z6fQgVzgzy)B$un%a0!hsEJ=R>XP->-55Bo_tINfi9-ZcqH(i{Wy6LhmIsDr$7uWf8 zLgNbyi&&E``j0=f>2{ZEHBoRv6LN~%Yg|7bboowf{)b4>t7lLa9#ebCnF2faU*59z zaxvkG=45Dnh;jT_}_ZMf~3p!u)&hX&xIulxN405mmkZ1&*d6}`a?$=KNpq; z;5vn#a915X>FX|6(r}T+&&B#*SYX$S{%?KpewS;N;UbNnixXxytVcR8z>(WMfTLS) zxJbium3>Q{Bgs}IN6vnrDJjc%lS{w!Bcfe}cWJ*>gO{`Q^$yW7Z>BQt-ebY>3y zucvgPMh>e%*EN6J<$B$4k;cy@Du!ZN9T>W2~@DrD--Efh{&vm$P8E}6qjR}#0p=PX<^f=?_Hq3hm`y&+TfkiJC&I@4+15tFVH zKvV6faWdMb;q~@w9U1`Er+~TI7gj$oG)i$(F$_#A8jp+l4lpTr4E908p>eofhHPlRT-rdz;87s0>c9sp($ez~Fl2AJ)> z814XOlY?2(J}}rb-)@vp?l>V z4Xm5>dJ91EJl0@f|M#}`-M;mYA-dUT}mhyHP3T&_hemtnZDL;t(sB8{Kx zIN@r9 z@Ps1`YxvG?2I0cTZSNZw{`g0(oTQOM8hjEQ(G%APtO{5LVsr1QN`N%JCvUy&q`cJgS^ zbkMjruzbAlzi)KqOfhmu6L!Bz@HP|NT~f_DL5G3g8f!H|hX3voUA;%6Gomv*i+OV) z$aFq%WY+iQMi3uL)|(|&K`I|gsXUV0TS1I$bE!n$`y47VEp@dmu~<4v?YHk%1-vg_ z*VtH_!h_b)7~Vw}Jv!bcHj4C`O3|d_-FZ=^;~Os$>x~MD)+jEhZ)wS-<5AJD$$LlX z(_(nInVNGxx!l<$ZzNaR>T~ZK>xrgleO*&seQl~CDq2J3hvpp5(2MFkzzf~G8+-;2 zqvMtKTHIvP)S|ppp7Ysg(VmBKce?CN(UwF*vNn!qzp2zy0UiZ<7`w~e5KYx4o093; zCZydPxa!cum^%j?c9chbOFGls5S^W-?Toitnfxw~x5mNwlJLMpbpG>u|G-!IxLK*wRuLUzLY`x*u;> z4qQkROQiUOI2E0mL-q!M=8pX!w{8Q}RAL{%$)H3Mg@T=w1fF~6M!@d!mo=egW-|3j zd5XK-SL0KuXsWfbG1*dwYiyvZ7uktvsPhX@y%*s(^zJp4*fqez;r6zH6SJyheWtm- zF;N>;mA?_)(;HfHOT*E&V;FXfTzDWOGYAm2Qo4Z)w0}(c;izGg;c4YN|^&#_Obsmid}!S!+{Ey1AjHUi_x{ z{OV)Tx^z5U+t?g4%{S0=xo3u^EPHGiz`C8rn@mTOsaRdSwLVVCadh4I)Xv4-L#wH* zEC+jUO=T6nO|RgUfu5r^mT8ih$1(PV%BZMN8I^AITp5{YEiNO9ryEle4;}tO#gtd7 zn2IuuiYucbnrx|Ut#7W=cwo0IJR)V&RYJLw7*|FnTAzs5#hPP{CO@$E9WG^BwMr>N ze3&J!jD~1y3u2P0PlyZ|Ohc10LnTbBvNP3{(HL!MXl+fWGij9}V@9Zus#29wWwO;P zqbc3eSRb#`vXyPI@U&FgMT76$v^2(2b@dHeE92Y{%Oe88vxZcfVsWQM$;N1^uBo}H zw#DQr_rk)3RM=%3$kWDXbD}mGPocvhYjXm-VBs>#OALxmj%I4>8_;KI9mD=t zxP&s3lyW;Miy(vZ#GN$WB<4R&nM7S(U4ulBn_}V8rT)7OovN1|Sbzx*e>pbs<7k#)ITQnAm8~oEzbl81jR8D`<(2$NU?7kJM*?$nA zi$=Z6O!87Ov2hf12ZN4x=X+h){Yz9n?1OUfx-hx~2u=ym1@Eijl6qx;E|?A$84b9- zE-YV?Ah<3-hj2X`Ka^os$6j&PO1_Ee+4Q3)wFA!wb~C=3TZ04J!MdMd+Q`4OT6^7vKQlpw>}M-<$sCIm{M}d zVEOY478D=33K)cwz1T_(Jv72cQ%*VZ^&h0(dLq^Fc4qjz5uEkYFxM27r*MVFq;&Rl z9NF54Sf#QD=;J;k52l9JkBiNmQgZPTsVucc*0%rlh8r6`qhRYoTsYxAc(pC;y)X%B zTlwmd!Na`lUU=JqdR#5GhB+fWOL|SxK3$f|&cTCH*(JCkAv=i6CbFNwn@mFwMD)#< zt&CX-{;5DJ60=gO+KR-ml@)o6m||0DS0rZPRQVK%fhpT|k(dKh30fp(`o{}&5k8gU zGC-3BcR4;kF3?r@JXWAD;qz#L9>b?fei_hFf_o328pc@EpNQbb1JW=K1H|}^vyKDA z&9x$HisM@jh?|5(Ry80EgWKBdw~DL=hwfBB>{E)YGaNd;PNT8!2Ba|<1f)5{*S#kS z2R22|*44&G|Bol3CrsK)UR(i=2tb>c8F7(y541j5t|RDe@39#MOsZD>+Oi>-QWyTezy<8F0BuG ztH=Tv0JcYF^>uf2#bH(#Y47iEzksGaY5_>oQ4^IWq@@M3=QL6@**a!-B_AIu+MO2s zOU-_YOc8f2y!TE6;>*TzY%a8d20W}A9N({P`a-R1z(Wk(t_*ng|JK)@a!poP=jqtE z5tirHP7cC_1)K-aoxQI4FD}<9iiB#GT;{og4n;nev^ z6e;b^&&4`kSio5W-Kmj-(BSvbA97TSAZh$u+&d{OU|Xa+E&C)8HrG!TDJDIBuD#(? z=sdRZ-M^o?$mM#&aFNE(#Syu%AYuG(**O0Rmy7)c9ci$&fm?|?`YsTRD(VNi7ec`@ zH&2dnPN2_Jkma;1|9p!pd4Z8k8o3m{8`tRPk@FFeW2e9U{O|q5m2a6IhCx7ntmFZb?vBi z>Fe#PJ^BDFH`B>K(eB%8Dy4JxMl%_$%QV%uw8Ud>ws?E=KpgY#t{{h6 zvB8q4Yp5G_Brp`t#ZJd^cSY$b=^EqfQ3ZQ_bzKS7O?@Vwh_%%5x@=SET7-KGV*Y{! zfxD{9WC7`XOe-y|s=_7JWu?=nE0Sx=@z&b5M`!URG|pk@!q%3Ln3kgy_{_7md^d+K zY;73_|{zzS)UG+HvGdPj4mYuwtOf1D^V}|1eYxW#jkFTK}MVDO81rFZD9W1HF zQVk26x$E}_+0ppt982e5c$*RsXGul!1|UrVi{$;lLj-EY=Yayv#;44M zK9yqyAYCu42BaKU0b(61w64LYasZG+Zv3Vz!N0Bz6e2xW5rtL(PU07L?r9ZQ;Ja*m zA0`TAJ)IW5rVR}0ra8)cE@Jxd^N7=itdS8)@b*9KP6`W75?b%a)XuK? z%NCZ*B92{2VZmmvx4=^a&#FZXP3-{>KkAa(O^N-6b~Q{hdke*Q`z6vA7O-bxWw_~Q zk#2V;47*NoyP65V_OlzZ?wmGZxLAS0X2OgI-G5%%;+YAbu1GTz_RdLk-pfzATW7DB z;m%1GD$>k*cW(M3HK4$jGv%q*mbr3P89Ai!&xmv;%pQ;KnQxVU)#du8BF#*gKkhRa ze)(r{Iya{LptFlkXngZAog3R+j~;%@)o$opjUb&Hhnjy(D>pPO<*`-)DqoG(TX*1Q z-PIWyy->5myzCJfZ@PHQIi%YArfz~UD&?xWOiL!!kf@EST;Kex3L7r*)?{NdJ<*PQ zo-@)Z?42j;T6Jnbq3S<(ZhC3^!mir(fiA12>%3*%%jbGFZ{3tQ>hx(HUj4YmnMHeF zZ|{;(&n(Jkl;+MX_$KNJCSScRn<%#H4>hy!%=;;i<(BJKhG?x9p=3D&DK`vk%lT#& zKLX8thHhswi{F6e)m%Ey5fjFXtEZ13KMrMMhs!6A{rYs!%*v$;k#`#b`Es#(n~**D0`;pyz7W_FRl zTLU{hh9>$ z0yCVbs&3b_+E2!Rkvt$gNuXMM9xKpU_~dX@BsU3^2*l;WF#_Fy&!Yu;1D{6;#11?n z(4l~IB2xzF2*J$&q+!GXslt^?Q+5uvJ05^ea}*kf-)v0oIeSW=W6O7G6k>B{nhGTx z%C=pY+=GPjs6)qEhYs#*9ngvUwks$>W65uZtel*(Da7fXh5bo`xf=EZmvf9ZiQxm-t)1x|I4-hED1PWNEnU*{B_;Br+6k3AFj z>N{DbRNu+4Uh4ey4wtLma0!j?aHP(&SUt$~y9>T_yvy||!zDC6-Rj>_T4#mTac^nV)L!@zTiWLF#DZWZD?4J#>%yB_RPnb!Ijf& zR|XX4xj!FD=Xqs8Dj&+34cd}i<6eU?v%%`d1nhKU&CRqUkjAM~x(hE{FxUsh?r3LZ z<eS*IjvC-g?u`p8K6n$(uK^l7J_CVmo8_f#qRhE zp!r@dU5LDmp!s<&U5-3<*sp=+Bc^f}*y+gGr)S@Du-yOv(}m6O*aI99po1F}ZE#L(T+QjhHno1}^vO+FEC|orasEniBvs*%$b1Ozia78F)J8R`{FU z>s0vzDZGPlJupL`zy}V(XSX(GUrc3RPGw&+Zz&Y7x(cHCE&?7K=_$Z%%kIGB&QT7<_ZRJ)m?<Fc|oxzVvh6*-i+>wy&Pg~iKL-;Uvk66+K)&$4=o_QYfILuu+b*D z+=*0~9fi=)?RZI+dotQh#TO8;l!e}4Z?4+KV-v+*vxxHNhc6mC^zN8&t>ouXHfG&0 zT(r{BSyH9PMp;rr*-JHTg;b!=(k^0H|cyGk7gt^n& zxw}}H&CH*k;}ELj$v!!ieN^Pq)ANv#dAB92kDk!;5O8X8@puc?Ji^5_!CGl2sd6R7 zJ-}>8x3(x8nqQ!@=#1z?H5M zkkXy$;BInoKLDh>e{yi#*i+t50#e>aKx$%f1|X_6imbB%O%SB`4|ahg(O-3sXA0`W#%rn1QTl|#o(5taN7AWmb8ta0d?6n8M7V!<8j;6CX< zt$-@U_et<_IJF(kL3FL75Yx@!%w6j=8&Xb_TpEQK#}c6?6=mBlOfIJdkb6{-b=2Si zR#Ao2Qn~w(T$H6;tZoW%f}rvNIFy9Llwo(Gy-oi7)x?>VA+BN-7DrA9P@eSdVPtTqu0M@_DvVMYo)i16w>(h`s`la zBdtG}bHr^f*FmPZNyE@{kA6~Um7&pk=$&n{`*IKT-{dr z;g#y@BH-fsZkqYc8aCFt2L3+F3)Aq8S|9deol9(U_<+|EN8=yx>JRsFI~KDUz!jn0 z*O+snK9p455SwQc3oRmT4k&oXv46ltZV;<%0(p~UD&$T zwvJK?eCDxXINPZ|N*T7UWq)ykXOJVMtZQ>@7%qdXa?t%qyISc(^Q~9EgZSUZ1_DR& zu=OhYh{r**&CoHbLYK3iwnr6sJ8mV`)Bm>XH&Zu0^fS(s2R?5E#=lCt z8kq7olU$v>lge(@H!}y5o+-XOA(+7esWoSsttx#`PU6^QPqwAM*5@>BojAP(?L}mt z6BO7|rSON6KZ+F%Rtb1AFR`W*T6X-L#Ghv|@Oe3bXCI}1L}bhuENL6O5T9p#cHG82 znc{6dT+z+Do05gZ;pQuI8u8d&7`rV;2<*CVwM-#^%gD_nfoW(^!C&xkzTl;{3~Z+}V76j~m>%Xyp>=3vPixT}`mw%Ed*aD`X6RNUD zE=MBl%&@zvT`BMPU(@YT-cN!YIu7Y!%6oesdUH$=rccsM&K+yC*a@3d>6l%YcA$K z{IZ?K@aOhVi4UhdWd_5XA8T#HXYP~-J*u%}kddB0U2_E;je+paDug63tGMvO{`vij z2cY(MW(-!%(ypbx$$}eL&5{L!^A``g^9YYu|H6D;yET*OU%GH`+GuAIl{2cQV^oCW zOyWS9N${HVHj{y2Gl@B7G&dx9XA;>Qy0Do93+QZqcwE>_;&{~bxu9EPw6bZ?=bK4% zU;^LENjw~*5H^!wB^w6K*K+ARD<|^P`yPC3%%uy_RQ~}q1zZNeIpK!LI}$V}D>&HP!1#426017LsbVRGwSap;rQGW&sN*H~lgS&)*&4nu0q_e-`Q zxXhYwm%J$7x0gJJZ#*--?9>e6awB43j6kG$;ou-=z8sh(Y{r)~>Fm?yw~)o|Bt<&= ztRR!+BU^ceCf-UdUfs`NFwMnw0w-C>sD};F?~}uWC585h#@O&@N)C)=UyvIq#bS3H zbmM>B_AzH}t0CR>O9(N#aXdobvTf+?W0rp``$QO-1cY;s9UD>|52dn+2U^o>5|6?d zIFIP(y`qOkjzI(-4@N+!G^Ih=!}YHW?Kmd*#w{nP=Iy`K_2qA-*9<;r4cEUHO8YA> z?a=zdp^alxLw_j{p5oQNdmk^?k35hbdIh<=0YAjLIHoHDW<56#hISM#i*QO`+LV2~ zDf?gwHa<=zArUn#FilcyFCUWa zZuz|G6`i+yglc!oXS+Ago7Q|Lf9bsDrF2V2c#2p5!CN|;?9!2hqB*bP{4cTQlUu)z z@1Y%ImYq1EY%suz)^<3k$;=jnM z#b=8^oRDP%;*iRDyBe}L2(%oZ^#XknpLGH;$JF;`KuN*9gwKRPuj4Z&&>jdmD$rhl z)c0UOHG<<>k8^Jr+5`HeKuZ8|qpZjp0CciID*@50qR9G^7L6Nl&x?GjF zKOl`u1dxVS?)dV3L=7$J_%3vOdjKi#MUL;V<9iJt<^87Pd%xrRkmLJ|K1DYbxLO_!R>H#!Kpz{G8E6}BYl;a9O%5fba<+#bg z{kMbL;NTtxbhJo$63|fsy#R=7ydvv&fV9@ZUfn?h_m zoSM74Za*@l5N5eF3Squ&tp7+w*|rOldk{P!_mHvHA-|t#O?coGYg`*kAL>c@)R2{v zng)e9A?9itMFD415)KPPDGxmg2S5rwX^q=Hc5_i*;XGT1!6r}1AH#p4Iaqyqb7OPM znay>l#hQ|Bvs-aeoR9VNcP;4Z@9OEm5$*o=rFi5;9(L)#^}KlArSrrN+{UHv`g9NQ z5cg7^+0NyG7vG*4Sk~9q+t25Gx_j{cO8)>J%z->GeCktmr#02LO`95--McK((*+V7 z5nsj?OIPHA-evs`If&&rWhPxq5+l-_yEMUvw!neCBjwXxBB+iz#D-F`i8~dJdbwTzTg^eamgQTqxd-G+n<6JJb zb~-Mbz~x!oihjn~W?XUD$=`IjDul<@;dr31%r!M# z|J*^C^V^O8Q^MnHPI{KrToP(n%(;r8$vk+hCcr4 z8~@AY;@D0{8t34;U^HFc&{-qgtw{gD^=c!BG{}vv!KDKW?PNr9;!`YgY~P>UQw;;f#IG~7Pj*-giy zdoHkB(vGuUdB~M>i;+Vbf6ng*jJqwo_k|~4>2f`2xJa{y)!n}UJ&-qD=-AL3c`@BR z%LfL1n8EIW`Mu6{!;zfO_m|M^v`^hya)}%IA57?^*~7jn0x%urEa>m6@^a_<^`_tutXH!RN2=tvWG*Klx4+*^VuFi5sjanTpwJKmKXF_KB6AZ?Cpw}%xx z#zwzZhb96pXoIUN4GYV6thEUK?oeQMrD@G01xQC*>l<1c>zb2pn7Jc#Ak4g11K1$;C2Pvfy>c6 zYG2(@S(mA6u5E5;ipqfP+m$cJmCbdjbZsVzM&$FE(NLdkZD~#?xL>bX?DMZo#At5ADDy6Zt^#X0c2?;bLXi&Y$**&a0ahs@>Jivga7B?)+IVt*f2g zneII5(VgFh>bXnZ`C1`@?z{uQKU8zBdDk3hpI*)(G@EK2H&d3+b5xQAw`8 zRFbRW*RLd}nN5*JC3&?#RFZQEQe>?JR3;FW!ia^9Q6SDRm4ixhjY|ZO za!^UGzEqN{JSxf6mr8Q=rIK8EsU%llD#_KCN^<3;l3abMBv)T5$<>!ia`mN>Tz#n| zS6^hX@l64mBC&4;bb>(h0AXzjqE7=lPN4GueO#c=0y;*Ztb?OMTyZ~iaCmprI$G%N z0d$l=4+2u<_alI`HbK*7Ma7qzsV0G52aa=R+hGljxh{}$prcR}U8;7YT)H3WR}PKx zabl?IW>QhM?ZV_91kYV7zm<~ z4rrlEbF|Q<|2A4^R$*51KmYEvt9D-tz2LBpJ6*l&zN|}dY!&}_E%fF?Gq5VRTU>>N z^#5z2!?e)27Zq14dG&!_9UZ%xe4610OsNgf(9K|>z?pNlUG+~-y zdVdtdojPjvc2`%-y5?#c*ZFkC#~R6`*_EzX_1kuT>(>>>j2zW(d-G5=)m&QBePY6n ztef_;4VP-F{~5aCi3rn8yI)s)kqMnN{|H_2eiD|^4Ow?z+IFU!(*H1Fk!JUG#eR*q zUswG9jAYe#L%j8r!4S@;EB>QH69El%#da^j@*Qiv4}V*Y=hz23iedEOxw>Maa&*Nm zm7_j(sXW5{x?+(0V|B%O^|nwV$Dy-rNjJ9cTyHC{ggHv&3onEMcR@emX;j!BRD+vJ zH>XpXq^-d%HP^Sl<4#wg%VeXl>Sij0U%3(WtGdXUyOYvvjnkK3Fuk zwU`>7#X1NVrosI_=C3}NM}zx(4qZMC?k#rDWQ2xkaGyX=!#VBB1C{6&eC5;NPQ|qD zWKQki7=p5Gau3u;nH_tR0( zaXW3pDCr&<1szuePX_3M8e9(Me+^a869LL#Y#9^jm1R!Y7@5JA-@k`fzzm1~ZaN>Xl&4;CltWUG;Ki&Fv+9;&X4wB76&5 zB6~z)#z%`+7obTc%im1FmYNSIS*d&Q0k^#-IebY$GW*A5_LW%n6vPeuU`yQ;Qhu)=>_1hx3X3;eFwarRN zp1MA>rs6);2W||KpHFht2a5F6^&=aG){h<8ICHQhLC#CAmHYqP1Pwj7XKd)fv9M6i zO#V#CqTDS_E@g4>3M}c<28f5n-eaB*!nfh-m`_VpCS(|)Q?U0NX3I2@2${I?xI@o?>kUGI*}E$&~q z*+WuX9fX9mtq;kLwXutxHypJUH~;*y5{tQG?`$Qmq7b{sa<8JN7{J8LUyR(5mC*@Kl|_ z@mg(G|NOmO*4ceoIknDa_f1_tL)*f#k2BN^KKi)Tkr>&;vo=f>V=u|yIuRp2hLPCJ z$B|)~Saw74HR~{P@SITRIP3x3%Y~?(*2unL4$`aw3gP|wr<^6?7=iqUkHk=fk#6R=;?+07D?VH_GF-HpEk{eDKG;Lj%*iPUX$w4$l3}O82uOFI%03v$c%K`jGE-5WEs$NV#VKhaO>YNAg8j|=?^5_tK_OJ=I-zTtAC9&GP!J5*OXjOWaWY~0bYDq`-s$xjz?cF zp1t-d>6$uls~&t-iBG!Y5oR%bSBY=B2%BeW3!ghR1QQrR>Oe0sg^8>vOIyPMYPHgzI zV`IbT?-LvD-48UaWLsymp$6=Q>ar5Qw;i3Ed&@nQKxu~K@1r`LHMFCCd7#R8sX-It z9B=Q$ntMxbpzveDgvZQCj~I{$vk^eo0Ac{Uh>nmUh`kWP&H1CRwFzQL!-}%knj1>4 z&QGtE1@xpDdLK0~k$p2*u_UotTTlTL!yN^vu6Z&gW-h@-4U`s=$o?gdKy68h?3Uqy zJy21D?adQxb~_695H{hW?3Uo6K~HHw+(m_j8h8nwz9I@<^rsa_#yDrs%`kCsurer0uEZy-yZ0P>6XgaLE>ws~aj;GzMm0~6n z3!b66?I_iuHUfk* z!$*_uSm*ewhtpc?(OMt;JDMVzTWnEQ$z*Q(FMf9K9eHyzn9#JQte`J0|$c{L{p9OpRRZQI8l zts!&{2k@b{3kDBLuKr8$>MUGy#)Iz@<}FAJpFeCet>aj3!U4U zJ!U?R&XMcq)b$wON=q?LV@x&E{#7LrC}D8elq0L$f|E&SA906Ssn58w<`~X_NP0K< z1$#G@eBLFSf!)*28I-cD#8K*8qsw*qT$$q@Os>rJz#J0oB$+bDN1j^v^G=X~Xd8$A|_-qzv13sGsdK8~(QSwVb^@7_6#jU>k15)1z zAoZQ;_|`hUEspQqfa*jFkANiwdJ<5rKzkys>U$s{^*s`h`kn+RCUg~mJ}FQX&?f}C z43Nf(?M$svt^=g8y5I4A$nkx~@g0wGS9$jXq`V&kq`ap%zP!O&k3{nNO!fV=<9i+; z<^7D~dmEq%i66Dr8pcZw-K!4WMD!}^dk7$vax5SXgRhIJFW(Q-7+mc5{)gks6aUKl zJ;xVkdrS=8ap(##5-8oifHVxgT%}<|0cjXbj_%Axg9#rwxDSPq`38fRPxUNY094kR4-w??D+D=ZVmT+ z$9F%>_muZgK+1a@AmyFm_(lOKZ?Xr zH$ic%v3eYkN`3*5#_CPS_dP%=dGGPI@3DZCcM2foJ=yU+)A2nQkn%2ed@px=uL7jJ zUv+%%aD0CPNO>Q2e1GToz6?lt-*SA%qubM1?FUGCBY-qTd{IMvX97~*l;is;$G07j z^7c5ss~q1fAmzQ@@%^6Tdn+L2{juZwyyN?lyg<(Ysuk!ZK$8Xf6QGX^^a>yyA$9;d zR&d8pu;h~EBC8dU#`#P@+Ri%xX=s-@zH0!TB)r!+zPAA?5!@y~+G=M4;;x+S&IF*g zVG5xkIR~Qwzp=E?`aNvwp6V^M+WOF+x_gWm`z_@;#DNY6bTs}8t-}!p!?ImiIL21Y zkep?{(Ty6pjEnN22#s7)QMT>E{x66g7XT;u5*uIa|**q9)o}T0CsbWoV|{>G&d*XZIi9R{`Q`MGTe*2v~R@%{e|Ol zI7?-YFnbSW*~gcAmMxu+v(Lvw%$e(U9z^b4*n=lRaO~Qg*Vf0jofBI2p=NVHSquTN zoikUDCC5|K{!b1hXE*KjU(8pzivplzZvNjYJu*Tj3=&;uBRPDYg*zmn2 z3taOoG-PoYEE$$(#}z{x!ioqUR~~$A;wvuKQNYp(jqi}~p1`_?glFCHHB2!mn~vid zozVEgV%>J{SpLQy*VMRNY}<4~;|mJ|iYKhIuKDqDm+Mo)lm9?+guM7a=$lhX|r$$%r32R`>`p>ysD-D;>_|nCes)vLz?X)%>JpuPV*kOIaa0!jT-!d4> zqFGGvU@8ua;*Dajx!BGRNPh(K3Jch;&^`INieJ+tN8Rn_n>6_hzqS|}6QBQ&y*Gi6 zsyg4tZ^#G{mjG^v+aN(v6az^h5tW(DOfr+qW)ct-2_cJ6AjB*R)&+`C=@_-v*4nD2 zyH)Gb+KSd{SVXN$-RfS&Z*A+^BDJ`e|MQ&Xo;foUoi4vmzrWv~^U2)2_dU=1p8ec& z&VBDWJVR$udg$qfR;)*b?henjp6`CkgtbHIA!dm62{*dSM#eBbKJ0Id=~cn{`Og^5Q(zzk;aw_fQX=JO2x7?Z*RKdyAY{rl5LoA}(N^bnKl zgXGWtV4HJVlRpENF(2QG&=F(jk9e{buuajuQ{LBZ;#uRmcyU#gj!Dt6413vy_x)qb!z0DZ{sPT^38C(xQ-V(k7$^HEFB$Md}iPSR@uV zpCa2&X7eHPdFOR5>u6op=~|vmO-6!&Kqyx0lMip}JKm|G>YAGRSh5cLee;nnJ(b-Z z9=F<9tS(X$PbO;OQir9YA{MEO*VKlBKKW6#_z+mhRfl}haM16MhHFjC)5i!V-b!Ln zL%dM6FIJPNO~ylEX^1C>75W=)em0HmPQ&JI={a@SgVZeSQJ(QD`W9Q zxULqb*o#l0G5C<)`G4%J3O)N<=gF|GNpt!X_DoB;6i#8^Z7C;PGp~FW@3xflWu445 z4EeI#Qf{}UTxsdlin*;lU5i@V=OzQkPc5&GG#wvnYz}B9#)z6s@0+kN@b7$!&1dp% zOS#>aa(eSvVRpCMQVy-cf0r?3+ifW)Cag3bGlqxN=sR{>%DM01cU#J3nUn3dl-q47 zSA6kqOF2AEw7r7=E?Tu2`=i~Ka(IaBwv@|lS-0C#&e?4#XIa6)bZEDw+-^&`-Ij7N z<=bs3r!6*iTgrKy-Ij75XSb!C$JuQu=W%vh%6XjKmU7aPY`3MHJgnq@zoi^Do>4EW z|2s!_?6#Dn4UDjE!g|eaOF3HU?6#ES+TCtTIhhOp?^w#cFz?PbW8wC%TgrVH9sa1% z^S{DU&TPfzn#GaTy0B$YXNkqiu#__>*HX^ta?Rol%3@iTa>Uq{a^U=Lvy?-W{{LYq z7l{R8bv5chk=BJ7+tF3VL&;cuxIUsS<^JhoL12xt?3|Y6i?U7y8N^a=gE zor%k#ZwD~{$i!vnV|ovz$$y&5wf7wD#Y?kr*_Mmn0j?$smu<<%uS@=zh0E4Q+&g*T zXfgTsEL`@Ud~CL#WZ|;IWxfn$RgwbuT}$P`<&`R_rq* z1PurKatTiVtWk=oZil7cibKz(E^KPD9XeB6r+od-@uA2)1cECnBKLGdo|5=W5uXq4+QLBf?(Wu zcIlh!C|>xD4u5f{rv%&jh%TS9m4N@P_)pj~WFEHr83~5aBrd6~{whz2N?%9ugzYy1HCJuo|oe!rT#r_;#p-fz`B}Y*t^;mB0#S>(u2&ZJ_4`UyW z8yHROyRjbsvG2yJEo{p;7<``pO#j?7H;>0%H+~-R&GFfSisITSsJXZ<6;ubVUl7!J zxGoaZ8eGZuIG4J-t3kC3-gj}uBoDqn!nH+E3|ofr3sCa~kK3N`+dCYe4T>RpoP$Bl z5!5u-_Y~JR;`;LVAAY^-aaa$y;_7j(1;uBS$GI8QEJ6Jalnmn~P%?}+K*=yZ1T|CO z_QFGk&kv6?8Wejek8>iZ20`(JlZ2p72Nf4o52%=+t_LN<_#r46#%-Wv7#l&=3EVbN z5kb8PO6KW@pk$sFpf{EIw+|@EJHX}fTq?;c2PN~KC-Kz?eLN?nMNm;tGM{IGnlE@) zf(i)gYEadJ`aUSXpl$>uCGG$pt-%V3Fd&Lm}^ou&&8pB?Q-d!08g10>3Tmq&P*9~YnMy! zB&oM(h*R`W#W_6|)SpYYOx;-OEkCkLIHmx4p>hvTe9M;Wt}Zcyfukg-lcsw#(ZJRIXKdMQD=Kg_mUMjD7~${s~wll zUN62g?7^Ypy^8=?u&l4Mt)+W~cR?RdK5y+^){Rrjdx^()C_VW8zooMcSD}pu`}KIc zx|g-}wf1`3&+bEb>g@FM+Pjx2`AObLXHRc;-%^H!-2=u=az?&+{HklNKAZddz-^x) zLha#~onp+`tWp(;&+~b%Scr>0$kLMI3apV+FOvsG826rbtXe?UBFY~ zmn_0=1>B`zocCNDw}YtQ1xsRiO*h$e1#n1j^pN}`Q6~T-5oj%b> zvEk7PjP=Pr8=iT=GNtnV2}Y_`$b9}*1p9vQ&Z$P~bS1SXHCthE@@K+&cCY6SHBuZ< z&Y$-&Zfmyp4+v&2~G;w;#N^~l35TTEDwC@F!l!V(C7rlO4okinsmMVdnm_#^Y?6MGpLw7re zsPB+!BQ;)05tHjwqtD*31XTff$XZQzTmO$*jpmTjOiZqgG;o$y>q0B->7{cxqz2ns z<6Nbgn9ti<;|QUr30JzS=Ut9bmJ)ZaPy{ibx0Qt#7_*hd;)eCd8$G{KdWgxjl|}Z( z71)%bTtBKg;2r9`0Uc)OqBf`2o>AfM zvr!og)zn7og7tg@C`QLJj)-zwORs*b=k-o5FRiGWT2Wpx$a}ph)23Edi5Gi(uh%2q z>)jE+8jR|qbDb5nw;B+mWl5Lgy&eZB(=%{`z1JJYr+u2s^3I~qYX5q5mM-cbpJa8OR{wxn1_1&8Xj>F-H z^1w0Nr}Ds2-z$0GILLh?Pu$KtaANp-3Y4a~T<>$3FC+87F};W8iJOoIj^UQ)fnz#m z~IF_XiC3$vkl{=ZSkWPu$KtaI6PIX5fhr*{{+*Twj`3^D1IK=&GY=f~otp=a z>0Olvj_v%?Ja7#6TY2JskOz+WcS{~PhWo2LaLm8^^T07*9?JvAaG%cu$8`K54;;hY zo(GQlKF$Nj_!aqaNprc{8|(9^Ja7#6@H}x7^Tbu=fn&ae^1yMNlgz^99_O5vh07l2 zFx&-s;8?Gg=7D2*oRbHR<*_mk9OHLsp17;?z%ktK<$+^*Z^;A4^xl~#Zet!e#_!=g za2!8Bn+J}I9gatipW$O)V{H@K`- zyi>*tV7!uUZ13$|)Ol9VT>p|K-kCk^-8}{{cUElftfi;5bhkGy#HFof*^;*Q?z!=Q za)(8=_VsUBGhT?e^DyBNGik=S`t7dORToB5??zIuM^hj5CbT8kP{3YiIyK{Y&A6L| zuDBM$6@f|B>MdRV=6PpsUVY+)7ifdAyIsI%>U`_QFzgi9GZ35}wGd`nBMNX#63!K# z&*PqMgU7GH0B1?b>?n)?2gFTpNs>n_ZNN?HVRd?2@evo}7K&Oo22&5Li?017+$zs( z^FI*0_!H@+80+TJSDq>6Ul;BF1ZHPfP!?xB@&B#|i*JRc;^W~$b&{cCZ(RN10XRdE zkPEL);S?pdG3?aGCXPTC4;+9k>cWMOimZB|rfKBS@Wl~bO{oX`>&|R)@od7t`vDmO za`C`{mfY-7l*5@-v*}A*NKiTC1%L6tL6-d7{gk{gtm*e$1O+ zOMc;jN?sgQE#&2))jGqC{6ZQ2A(s4-gOvP|VLE(4x#7D7cBoAM5D-k6+LgFFRH(SPgf!nuGZt&~jT;fA#s7ei zk#QND9+$Ojm4_)^q%YUH^o{>6W->I8K@Eu2;(;Tj5*3haP-`!N@8L=p>Az`R`o@iy zn?XWG#%r7vuS+3+gwjR&G=OkyDiW#h+}s-Czl-Idb89UDROvRDwd@hRN*U>2!CPdQ zzHuX_6d}3vk`WtkMeHi@$0}WDmDPu}T-|540|QlS3E1q^=VzUH5=LQRyO0 zvt-mRL#`!BNj%bAy=(*MFN%Jq~`U(nb0oT9>|Yb(#F4m(*2Z>3SOc$x0XLU0RpEadnwA(o5=^YUz3o{3%Ko zX@W#$)ibRp}z_(Yo|a4qfz; zx~5yY-Ufe~(nWfX)}?P;U0f@YoesUEu9GZX+rh6?x=8a20#T0oM)v9`H!`R}l;z1% zi3*4jMTh?$u2o7G=`*x0edET<G}lx=}H&rGqo;#qjYWDHq;(}ttEgOOMNNYB%{^o<*@y&)&#MK2jIzZEYJ z_$Mn}q?@%aedFpfBMN#+UDcMZBJfX9x=7F0y7Y~!%d~BJNnHU;7r%Fzp>&aM(Yo{v zY6D3r8>DR7AV8I^suP?y`jjrx3$!kMg6 zy`-)hOBc;RtCcR&obQPGrEgqaChzGbb=6wB4h27;bdhccNDf)`ol+(ycuF5MAR7sw zN>jnS-~^R2(j7Wt`o@izX+-pr5sO$6D*->Gbdf$w>(V!_E|dB6lDg_FT@%2sQMyQT zf`?InA=i?mWZDE=rFHQ@y`}3oAZwK_(u;Jw^o<)YlSX>UcttH;rQnB^F4Di&y7Y~! z%M>KNq^_8ys~r4@(nb1StxMnJ&_yq)D{kqk1iwz{B7L9MrEgqarn1sY>PlF;P6EGP z=^{MZfKoVe0Odb8H0Z(Lm_!{{aB)o8^l3VuTABE3cH(l@RylSX<; zT}_s*B=||Ci}d|km%edznWrtiq^_Bkt|stLRk}!T)w=YJtIMR3UQ*XAOV@1h85G)#J|xqDko@{gBqB zZ`^p921zd&uQ^t{+Q6Twbdjc^uIQ!pjjPLy0_Y`moo?w`2>vXki}b@iN6A$)Ss0QrBEdR~PuRl`hgpYF+xq)nz(EdP!YpTDp3{pQCh< z9;bEb8&{X9_wXCOy9VPG!=|qGNLV3A}|Z&tcUuhF{njjPM7chF1fYO{1*0sezi z*m|*=4%%Jmx4v=XW%7$&GG1p{x~>JkRp}zV!24CHOW(M0w%zzHxP_`n7mq zDHNat2%tvOw(kIEkKj*=Nh7^vygIFTZ2N07hm(;b) z(sd8`iv8bAlrGZ6T9>|Yb(uOrFR81~()Bd>XDeN#L)FDH@AXX%UG$Q=&areo z2Y$EGMfy6eOW(M<%!8X=QrEebu9v{?QMyQ9e6i{$^o^^_)Cqb?UCS+9+raNtx=7#o zC#6f@xVlWd=p}Wnuynl!exK4sdX=FUUQ+iLt$4i+{<%sQ>91>D`o`5|+9SQBuJbKj+reM1bdkPD_tE+$hc0?aT^FS3 zisF6sgJ>663WNU&rIYl}FF%~mNlhw^IIjWuM<#WNY~t(n=WxT9>W|}pEVU()`duXT zTjhI430JwIcq7mCxG=UU`ldi_jil7EFxQIr;8!p%+u()w_m%yDU3hUG#W8IcmyAYe z*t!J<0l|_WcXGka1m5_fg^xy3kMdsb>jLl)-n_#CvdkMbIOa$SCjHy!zt{wbj67Ct>HAXi8WV2pa>K9)we{Mc^JX z>k*SQ1Bb(Ly8y~O&IC}+f;s`zJV8}~Izvz)P~2e1BX&GFO;D$TCuPq7HB0ciUEcYi zq`uXlq`rPoQr|V8W(o-(t~{;WBQU25st?z=pf1BTCa9mfyvIP*3En#{j~!dB;7tN0 zWfP!+g4gNtE(hfoyjxt}Z$a^MV~_I}msgBI<8-MHl+p*PQtESgmxHR1`dr>`K~0hR zTwXE8btg!DprpRpppFwfe3`9y8$lf-cw1fGc2GwN-YD1}NZFG?jT5|Pm$wd-SMY9f zdA|d7nBcwd^2TD^J4WyVprpP|PzMR#6)x{#Q2PtsOD=EdFnr-7coRTL*#=Pi3SO_v zyB^eDf;Zsu-UP*pi(P?=wCq$+{21Ni%yxNS0yRYNe&F(60JRHs#^b!}@(w{C%vENO zb22Cym$N{9D0u5!-p@hp6ujTLyj`IFCU|4f%SqXKQ0y77^N`EC8q_<2$M@wD_XkjK z3f>;*Z6)snP=6M@Q(fK{LA@q;*SWk0K)ot>Z@9eu@a%nA@G3w_ea)a=6uea~??F)P z-#pHvF7JI%zZ1NJF&dDv0Z>m0Uc1Y?9Mo?G?{=5>BB)0M?^Bm|G{({o30?%0)Yk)Q ztKfazx5DLpAJpA~cfZTq4(d+98#O}9o&@R+ z!JFsuE&+AB;N9r*UIBHB;O%sIUKqLEBzV=JWL%bjxly!%|<8=%;?dBpdSQnmtiN#78>(?ChyDo|e&yzjfbM?qa7 zcz<SDn=0>(vBHUesu;4OA}Uk63A zI*)Uw%X<~n7X_~nhDB2Lcu>m)FX8f5fa(*xZ@au_Ky?e=pIzQ4SlulXymC-d-#k!D z1aGCwyAjkP!F$Bz?F7{!c%w&a*=kU&g4gEqE(0}R@NRQ?e*|@=;CGSxy$<=sCvQM;`06iDlB*-4$-nF zf(i-VT$i^NRJGvU;PRdX#Sd9L&U-HJ@I&!FP4Il6WL&-gs!H%Kb$L&LnksnDxx68V zVHhBIC7`5i98{^`b-BE6fjVCB?s0j40(Gq56=C=wWv75TTJV}&-i4q_1aG~|dlA%F z!F$`~9e4yxpaicHl+?EX6cUQ`UhML20fj;Y?{Sysc=gV3`+-8Gh3{lgsQRFqK%pst zx*imoCaAxFLQ@At$1j()Yc1dx$>d844;lv@3U~$2?(01J+HmJLPw(Yy*s`~CbMHRR zkIVOW_IYy8?Zf5|O-B4Pn;V-#k$9s+GU%Tb3Hk*Yo!Jy>iby)?k4F6x5ePMeBo%2& z)ca49fLWo&CP_7gV#!dnd9u(^ooHwXMWb`XO|k)dEd?X>A#oRJOvDqC3^hdJiI`$1 zu!~ibr0f0BISL*2Hy{rBE)e!dgV^*+C~ET0sSPQKn7`H^h(^?1Q#cfhG&Us!EPy0L z8XCfGmW|}_hlZwbb4_G+DCk6*8fvP_q!vUZ5tpcjL{n&{R1)e2Vbge&%y|^SD3}KJ1xXKtr+OI)zf5Z>P$Z>4l6^cl*sR3E4l+O&*3-9VsG!j=) zY)CX>Ppr5ECld|2bn0eCBcUb%M}WalETMu7pr{&kc~(dK@qmmj;2r) zRYuZ?j4sSjGLkM^=Z`BbNfcbQsv`bms7bNIbCRe%D$_(XMZ_Ayx&Yv(stKYrN0wG7 z9tcJKL8T%ViK(iMkRuY|4>qtC>VnfDM?%8oW=-}Erl9UrIRw` zq`xte4EyB`0#?}+M!32V{2*OXQB!r^)cWIdVxgcCp4pH{O8pU;b-@rejF53g4pl2M zmeAD*jaUM)v3t`@l@&8l$SU!T{-&7?vdY!XOrqg5i2RHB8&p=Y83@*_kd}#s8UiyL zWSefBsp=~OYOeM-%n5|zT8j!ZlP!bKWqr zS)qnTR2Xy`F@IAaJmna*8C?c{@-a@+!uIZV?r7K2iT&}oi{7H1-uBK`Y@XNNdv1Gs zr?+=uJ2t`V?pd^~)4Qxg+;%U+Mthy@-qw~S*lFY}FLu}n`kTZj3`Do~b$4^0yfi6^ znB)yCY;Rr6{q>f%EN=Jq^danC>|Eqsv8+#S$4B|4%dih#hLRqJoe_?TMvqh>H1_qh z6S$~XY>J0S{l~V%<0##BlkhD?i(+AtiS2ph^UQH>eRf+)dSFYu$y4~?hZ7iQQg8e6 zUda&8xxxZI|NaEdiikfVx5Sfslr#&J$MIr$C4I{-Od=5$CLKcK*WNz)FthoVj)A~f zTXqc{%1EOt~64Y zlLbeNErls&T3Ef~=Oa^e41Y!uIAUxmrl`=}?CPF#3O+GXPg4Yr7+Xq|rYKYTC(75p zXr$gF3yv6DY9DY+Snbn)*=?k_l0Zj{ErrP4>qVIJPx0eEYn!ON|s?V$cy|OL1&m=;p>R zKKb|-BgHi{I$~@oOyD4;%d70EG2b;(jY^6bTM84lv~-;scw@Vf(i@l&V@q*tZ(?{@ zf9g&n^(_?^F}4(@W@$0}!=C%6kQrVd!1Qn!uo@fBF2{DjKpk& zcGfGs0)Y$Mp6p`bh_R(G>4Fq{2D-bC4b+*i_@bMR7+VUHEJ*1->h2*s(&|Qyk|M^I z;ylWPm3q4Xox4hovrtJ9V@p9bq}aykUZ4E^1x9MEk|M^I@`6)Xzyct zDKC6%sj=XgbiH=kr++n4_bVx4Y^fuKl#byeqn$^M6u;V_BgU2*2aZYCt)Gm%-bf8s zk1JwqsS-=-h7)c|7^&lx6fw5ccuVTb3u5I)DygK1v89d@Qo4P8=dxe@z)1BdDPn9X z&a_S6d(Mphv^syak|M^InjoZfjrwKTY$(=s<4z?-j4gGHB^4Za@*^Ylypkfumg4$= zX(=PG|K7bu>SHBEj4d@$Na<33@@u0$HBw_ZtbilNmO2g`(?=cr?9drTitFTb#Mn~D zgJbI9CuQ4FI6604loT7e=W6INfBd9ogk$2ljy>)mZwSmP)QMEOQBHH z($)8J;8!NB-zX_!Y^ljYN|*AAFL7N?$M7#oiWpmJijdMd|HF;`TaDC+q40zw#+E7r z$K?F2i{DMFhh<8N7+VSr15!FH@8(n9G+~{lq=>PlDuk3y*VGL)=NqZ>loTLekh z%WL>Ir(bEL7Aq-YY^jqism-<9zGtK^Q&Pm(Ql|(hUCK8V?Y-7W-L9mFv8B-9({kgB z;~GylQco!%L*6HYzD%Y^hoyrStHoAFWtrq+V50#Mn|{A*FlK zOXeK-j*%+l6bgkcDzvtkotOT~qh&iQR8 z?U^)E4=X8RY$*(Y(qgz@`S3%G)H_Ow7+VUeA*FNUuBQI0jMUz$$`E5qohqbs48L{q zlUEz5QYA%QOZ|BRuS%Hy>t{Z)dO^hwoB&2j(e)6cx zcNnR!D=A`ZshL7b=f>hI?nCFN!`h&vh_R(+SyDr9I^`}S^^%ez#+JfEE-mM~uUm>H zsKXKq0PrWqmYOZ3bk6Vj#vMl)sS?E|#+I5Rq*Qn5{G@UHg+{7INfBd9p@T*Yby(}i zd=EvcW7w+L#Mn}JT%}3PY`W|xMrw_cBF2`QE2LC4bv`)vkflcI$4ZJATk1?9rLx#L z60^wv87ssl#by+b$2W5D&C&rdq2u@+aK@@=-w(LA~w7Slpq@;+kr51r> zjv%=H+RM_)Yq63d#+LemC3RoZv<)V#Ym^i*wiJpdEr!1yvKS3l$M69qMT{-AL`dzA zE8V!Su0^xZQahCtF}BoFa0&}_9)9FMcZ`uba$jna=akt}o!}ZNZ^4TglIXA!N{Se4 zjo;k5tZN0e(0MaLUk08ji~rfD+-LNhuk;Xu^V+*RI$M^q_0eVO=>o4%9DG6FqvGfI zjh>s79%BCa;|0#PG+(s66azh-Qrg_m5%YP60CWRWSnvYjaQj?93kI#{pkm1-=JO5# z=mEy8_C!~HRAclcl^$Y-IN0ES@-(Sfyk!{bEQPDLlLd1O4wY4?1 z@kF&is8{tCBP_O$f zNL6hj7OamYWKx6?faM?e)rV^miD*y)v~55JCQ@6I2*>MXJhaJxg-Q5oW3}~xV6;vq zMq3hCpr|kDPb7oUS{ax$Ft89YU&3D-iPzNB3N^~^AOlht4aSpo;fPGMG)J%?QD1$? zUl$A|Wxhx&1q+dYY&3~uwBtgFYrJ5A;=Y>dy6W2c5YaQ6wM~PCiTPl{z^Wq4S(!Rm zkc6+UE{4(#$n0}1AS_Va7xUL8qy9P>mNtyAFiBsvKU|#*tFVl{goUcCu8RbMp`gye zM5E*ImA%ouHFV_{;xTA0}+>!UJrmHCYY!Q&zlOeAYn`<7NY79!@02WzYA z{YllhrLj&1Bp3-qg5jVnWo5%-L8^i^!9=`9J(YxIkL4fp)z{YJp;ImML>c^8kfbkO zAFQrU)Tq|$+5uUps!%u?4A+Kb6BE`!mOr0u)z$UYbuu9ILo^!7fCOq|_2EQ~tP0AO z$bv+D)q!v*R2!AWEKQ6oMA8=ygp=`PtyE$xk1SMGFjO6=iL06*?2#;g)Z0*PwLcU_ zok1@y&6F%e%ol`tQ#2TnonAy*FIf;&l|V398&ArrqK%p?OjV+`rmnumFT)Y0PL_XV zq&iX)L;=b+20J9nyDCy2OeX4*GCP7ai?aNYUp4;fXeg>Gk+7Ds5D8x_SQCijDI!8} zji@Y8Rkc4Ej|6Ju^GcXj+5X8|e=<;;lr=;cTv`5cU!6Y~Lx&vXtQN`M}4tSxH=q2N_lC@Wg)7<;beW#t$(oZvb^KI+K?Y7 z`NU**rp>-AOw<>wug4%xmbo+rvjA})`l-5TJRlRQZNw~06*`_+P24YwL|Bel{^)vZ z>uai$s_Rt-WflZAD;^95FwPK#rtQo!Fo;MEnv1Mj+Wag76Gi_W2>E6AtgX^43?DWz zG)vV(goLr0g_v3$3!)PW$VwQo8#T(M27|y*RF;dhY_r6Xsc5d%^{RiD25%Ok5(CKb1?Oh0i{lxzbcFVpPlY;YJo zN1z6Mi|q2V%>r$BtuI(p6Nv{RGIm+!f|=+!#q0dCJ!G2~ z+VGICK3*S7*69AsHaoPj$PyT1VuY!ht1uuo=7^c#WHjIpMr&mLWtu74VB}xCHX29& zFB);S`JxSv_^RWfNI06TGslQ!STIh>I!de>QkXu)YLJh@7!rs`hScONsdzmee=$r% zF-H_8kuxe5_26K!PW(@|ikwj)%_7}n#-;{BwRQFWSe(anHQJL-wQ8XXl?+VI(ql{(TXi6M*9vWptmFFFyrF?3WGPXXVSYd4zj8 zbo?2(bJP+r^$k`YR{^s=4VSC^j)wfbdN~<1U9S2P0RI`_4pxiEd*XhuaC?BcNZ|%c zFYD=b3IkF&5pG8NW&D1ah0AVlrNI3<4;-t>JGpQf^?or5bQf@6P_Ga?kQ*$$R|0dr z!VQ+*Lm_{U!hjSmS3chZpXY$PiV27NtbTIH!T1&!Kf1xfWqUggn3FPbIoikRz;tBd zGTIyUT?`Dr+@o{D&7tpS!0@|13zwmfRqrKWwrApU=-U^o>0|KwJbjhGL^E+Y^nC%C zb24!m@nb)9mBPr7Rr|=Or+hEGJ`0z9$^@(4&MX}2b4L9;1`mS0@aDh#Fc~WU4OahV z;UThs4-z=HJTlV3d|nC6RhhUP`SLSh?#;wy=wtPKNnsc+U9R@a=kI%2xa{_O9&p2t zpcdnNBeL_4!xny}nC`@>DH-|qF52&vz^xuDk!*j1<=?lD#EGT&(G8Y=l)qnL1Q3^8 z>E$E!)ht|g`Cg6q?Er3FiPXk?8Z3V8Z8lmPo4z+O&K_me;M(+3AjH4 zcjeL4B=c{ue7+5sd(v%9qc#jaj(t`o|66p91coW2LsC_%~R->@g8v@#04}Sp3)@oS-lQh)b?=W4_b^ z_Z5ZxtbBP5nC%KTSh&oWeKCJZce(O~{qBKTIG+y_u@i8Bw0~x_32#77JQ9~ctm#Ob ziPwQ~e=O8^q?f~hck$bT-`fA;={{+5&VTEKpD<3BDGIOaEg8Y{eZ1k+yW!Oj?ZTcl zseeRL&+WJ+{QeW+T@OwFO*r-8h5N03a921r7hCdRyPHZJ+v9EC9BtjS=E)0({|u53 zzm7a{*6g})-)QRt;nXvlV?@MOI1q{f$7!I);hTQ;=*(6*Hx&df9B0Vy!zIOX=JXcd zhZhfZira=c#pU=vWv{NxB(%O8PJI+kJtm?PUNEEF1*hzxH9IdH?H(AE8W!HQF+BaTt-*p_-t)I-NNnc7hLu?E`oretagN88oruRN z$CcffN7x;Y6O<2EK0-WBEv|gndBmOve2jXWMqDv40ChU9QeP)14k~0mt_P(ZtGvud zNfqIqG0M)zfc&Bq-}Oclff|1#IJqT5Lw7vpNgMHL|an0 z6e+oxgA>=yn)B=te+-PBW}UZE{UqS!eMc^&Hy?os6Gs zSe*20cLoTV{gPr9ut8=wEY(3RDH*}4Hkv1udHqdn9nsXQvb&9>K0$XIPVLY=ZaDQu zxb-2CzHsUTbYZxuKr+G-~M5>+gjN}?3vf?wQk?HhK1KnFB@1lNu^^6 z`e{@vA9o}Rv-SDsZk~=v%KnJ;Y8ZYVv1^NIgqMS-T{{SwOi3}BZGu-YX1Fs3$5M@H zD{{s(4RgkzKOQsXK(xKLC%AFc=efz0$jD5~%Y~BL_%)`$kHV-*hP#hr3E|XKC zUcqB0DZ9*LK%FgkT-Z89Q0yzD?1`XQlCl)pNVHoHLMBgAOddN^l%l7=@l<2G>0~4j zn$QR{gLo}oyu%{@q5DYPF9xR6GzSE#vA4Uq zanV^glrD<)k8SKmH_n`On!m|E3t3kgDtj%G`Y@8hbL7ov>%0EcOR?0`YaY6A!WDI? zlb)2-Mc0z)4;Lq%kL=nMoBquCuZFSL-X(~7>S2HJt&f@7^SIdAj!(e@qw9`FO$n|$ z3RR)fKhHlG$L^i6ncZGj6t%L{pL#Fa`f+H@&f?3ig(h}paHcEc`=w_5DTu={ql& z7)~{nc;C7~q*oqr8fF@7HBV_fCfgIf)n+Rv3A?Y;y;Ru4%P;eM6i6IWsbu#;dN-Lx5 zQs>_<_6>Y!7fQNyv&`P`^aqOr8zZ|0qSLpgo;&{qw&}{x8P^ow`m*XJ2L;LwZ;5!| zc;{{25ApjVejd>bej=zITxHWc57dtY?;>1f(_0IQ4bda^(~_f=t8p)zBkPfDj^76* z_1yqUHpkmR-GiTYH-eD)Eh*-AO7O-ih*$k*Q#Ke$@tMX@3Z2EcQnz-w^s*%6v(gKS z-3HxYdar|Dp+Hf$cDeL2?a+%|kN3b9eO}yY-As*%siZi%mAccBU@D{?ABhyY(c98_ z#Z~TwkW07Bk8~vIT=AC30(`1Fys5|;K4s|qe7m@o?(UWqdI0G4ssUqrn>Az{=UuR( zx4mbQV|9f7?zFxz$i6U)UZqHNh%+m}^vrQ?Ex-&qq>!Pw$)btmWe! zw}et#&|vyc-PIo+@;Vb6F8qCX^{q@? zq140Cb-2pCMT6_C15Tyd?5CO9+H~-?#u0F(|4iBOzQM?Gc)1*X0lVK=>nEW#?-XD5 z7Wid5%id9mYJDbLc$Me{qpg3(+$L7Iorkib>y;gYfBGZrcuxtfdCl#4)$9kIDtq3& zFe8hoUa0Vnl9kZEYqP)bZU6M&UvPdj6-3YbwMgngnXJ@RDg)G+rs!t6${q@@8@{ec z4>$%*pv)3~>gmC9NChD?{;fkq*gDIt{KnV_8Dn~Km1mo0Bkr5=^N8K?CJKr*SN2b= z*P8_IR+slnP_obZ6{vB-ml)Y+Jp@YjS&xH~eb(g8Q zKuLYvw?f8>>z$I~5*$~Lwc7$h_NkI8!ac|Ps*l1mOgKo<(O2Twn@Wm()Lr-$;s>XY zBy;JO$bx_D>HOohV&{+r2R(kkz6aat@~OErGYi8_+{2&OEaR zRyii0UT@Pv>~ORcz0rbpZ(ASs9D-=4x39Cey?g1RP7Kl7u=!C}U$0Uvd!txO7sh1h zisX;@s*OieaG~D`(KlO5G&936hwxfXjslS9$f07+ZwDr+wp&U+O z^oBuZtnhU;hEoH$$Jmbq!{}v4MN^wFQ2UwOVR?`dT;a_nD-p)7&B4My`KP~f!3DB8 zw?6aMWu`Zg8$auu;GhL#&B?)a$Q;=Vd`@RF_|lBsmtcN`eoPlZT3@oRl+$a>gP2da zaAc@6aWfZUWG8Y4DA`;WfMRFhan5piouFhV!oiSiuIGW0&2<$h*<3FHB|DLRP_nsR z1xo6>29#{1H@nn+Xil;dITn=cM7RmF>_oai$yl8WN@_XZ<*f!KJCRF3$yo8E3mL0# zfReGg4wURfz6VOi>L;M2zFR=aSh0Ijoe1K`E=9X1K*&x+QtT!k6}*B?dpnz+9_svh z%P?m{Q?WCq`@rq{ZyVJ$a{h=?KI+l9Y8EX|Z(lRjRL2+WU$84EjuZE%wiMsG5vw?& zOfl1SAIJ?X(Uk~ERTC7fEcfiEZ`qTB`G^w7bmvU*$mQ^RKBwXfIrK(t#4I`e35?m# zFA!ka&WshMiZgXeCv^)KqVi-u!8dZ(v9dgY{tlN9sll{`Lk-;*<*moLBxFEsfm?ZmH^}$jn_-~DN>;Fo~iTWQbSsq*`R+v!xky0)NEaV7izJ9LyI0-y+ zGwX|N1*d@8hM&i&!By707${ly8$iigHV2ffW%EJFTE^BQ>;4i@vX-&6Y{SnZrcJVL z{R#K7#(xA#)_87WC2Raqpri!1^_DTH0`+^LgUsaf7yAPR{^%9^PV;8WxG}=p97(AKBg`1-xz$rC zW|4%PffUM|2H~(&wBuk?=7*%1A8!htmZbFk&sqDbqe z;3fNy;F@csb)z5$U;h&8w@-?-j*n7rVBde_z{o3*e7TIfDZ*u3B>xGqUbjbTqkrP2 zVE_DrNUK~03uDa;OJj#cQx9^~pL$lUIH=Vz`9>oAz)+@@O9y*|*B#Dx8^|0!4zkzA zW&tQ00z3TI@bie-u&kQ675iNCKivoT$*hwUv+jMt`#-!k_AUaEYhzfX0(BtnWlK2> zRK9CtQuahhn3fX2op#(RUM5dcOkRQD>9w(%DS<)Pw9=<>Vr9$6!Ak3!5xin*{g8u_ z)bFvZRTJ)?xhs}>JeYb#RQ(jjAe%4(VM_>N{Ic?-A>O_sy>vVM(Y`(WsjY8$Quj~X z7%bctEqp4n`mKV#2Qiok7XCTB@zuiD8U1MLbykcqZbiY&vJ{-Y!}RJ?blp@oA`S)S z=?NKD!sHTKIJG^=As4ADG1iWRCWfT{1_zo_F1 z5#3QLx;x$~(!Pker)(GE{pmyuyB;iil55nPs9;p}%9Dz`eS7WNq!+0F5}y8W-!Qz` zD0}g(J%g$HgA+G}CqD1*_o3}?xu`C*X5hm8Vyy#MO4Dz-qI}qJ0j)n#u+>xMKo{EH z#8-obe~+wwpeS6peY$+OAOYSBjz`YFQGsJC!dRG-15-CwaA*Z*zbLBMx-vGIeWHq0 zHV|7kk>`0_0{@JBTMd?MHeYk8AA*w2rWOZ@+C_M}p)lm}x$p_N+AiHln8S&}0*?4>mu`4e z2(Q9|K3s`jbC*2i!GuI+x`u&k(sk*dV>b?U(^XCpIDxU!#R9d{WuyW^MozK|oz{hm zvAu3{t7J0to<(Q1V?iv9lWwNGr_jv4p6*xkU+r)pBVD8VPs|VpN)~lmn$z_R2d1z< zOSYW*lY5PxFDpI7xF5R@5+CNJsde{X-1`rsXT8!xjQ-eNsge1dWxSJ#wvH#bd!qj-|+l&C~Q*=nRX$E6b(E35;+Ei9P8 zD}GO2yz^corN{XKV}-?5W774+0egJgNc~KOB`{W42MH;*Xu5F|yq_4Uhn1ATut!?D z>>ORJnKhGTVVCJ>a0&~)h%42c?Y;AKQ#yZCnnyd-lit%FETlwx0kyUN#CJ!#rSqYZ z5*RBL9NpPHl9Ae9bprw;deKUt=@>&h&YWWv7F^CNegk!#NUjRhDOGw7$%^x#LQ2Q^ zoU0G{${}u?Pf=0=W5t={ShLl~bywf_p^?&C;R+1n%prwvjG-N8w*A6_0IuvAf3)hh z6(-J$ROp9i#hLS2Q(N}Ef7Fi;cjNp;B_%LcoV`Ly*On)$?k_e{S1Bohu{OFME2Nm) zbg@o_Z{z3y0bzL7eRg$gGyR#?Y_TUa3bWULSV z<(_dys$5A4j1?B2T&6W$d()%u8L0*(B`{W4Cs<*X{`zk?rcmd6my!|~D=fAM6V|K+ z=X_|SE>lthV}&)@l>*^By}eEz0lAU{^VW|e|JfNhAvD+XY z^k!3~F;iCm*+>^ zb?1cJ%H3Q&Nl6Kel|SrYO}X#ieA)MmRHKp-7^^I%Sz+C=*SSA3QeRL~0%L{6=a1?6 zU)a88wvoC>NePTq790ecjk|vHtvkPCa`o#?R}mwQV%I9Vr;4D z;Fzt`zkSPhzhb039E8FV!}03!MS3*vj#tZcnX&}!GCc{L!UC?lv%mZF%WwVFl<6@_ z^GR7{da{txWjgU#N=jg?l-3I= zJ=Wr=(n#H)qy$E!lsy_9V`!%|3eI4o%6pZbXjYtKLQ2P(qspio=f{)8 za2!<{sW+6Az*x06A*Ap?63*9J>NWMSP$?tE9_cY%c1lr%Na;=#2&?>@@4x(0Q#!{h zJ;|(;o+_ktN>?1%^PQxd(o>X_z*s455K_8yW`8pI>qcspk`fq}PKEAU7(+YGjY1FG z=AQW3WBz4IPh(b`n}n2(GfSt@jq}AyN?@!w&lFP1+hOS#sr8C2Fjncz5>f}?O1Gx+ zSSZ$g%deFbF?Q)NT|=EW;cwnE>7D-4IeneyF6wM6NoR>ZqC_uu>FogZz1rrl8rxV@ z2g89xeaI(22H=hg*7pEe+bK+rBJ!uhxYvi#khkddYmO7+fl+m&$#D=AF$`8KT?ZL^wR6N%4}22#=J{aV3`kTY*{Q>Y?HP$Y+9lWS6A~|A2#a4 zUN-TXta`3&-Lh(VxZa0t>}qSUyIgi9hmC=#;sMiJ_AYa)c>??QBx(ZKCr#vl8yzd@ z#_S-i`2w28x07T%bgHU-)geE2Ma7nK%;|Jt6O^p%MmR0BEU&ZxGyPPU!5UvJw*QQW z0=1u!E&2&U>kBtmszbhNoG2Q{&Wvdl!;P4XF?&(;tFYA2U1B;%#V?JO*6Tvd5x4qd zj&u!flXu*QZ2CKLTQI%Hurx}Kv{<-m)7uVuIh?H;!oHpXUzWH@rYoD)%UN*2&lMOw zGLeJESv9-d>DHdQM%DNd_3>(dAX#n4T;XKov9}UlWG%z1ES&PVY{3^!_}smfD#|8% zh2!2zdy2i4VwhEMfrKvol_~E}z)!zu;Jt7;_Evft9yehKobJTlO7>PXVlnh0J&sdg zpHn)J{)(0CYW!9McfZ1N6hGLv*LxxU2XSTu$A9A6=Cq|o@;PFxP#E6R30&HOF?n3k zI5`g-*RHDbz%kzXbTp8{F{ZR1b|K2y%R$cqIKB`7KSX*e9u$l`mFv%&6 z_A~dj731B^y4T6b;1eYHu&|gQ7AJ_@LwpX+w;LYkAY3^|@;GC0yqkK6 z5pVKaS_gfT&yq8T(M~(}l(UVVrBnh(j2${>#b$H)%a@*s9MhqHnIdq+*t1XO^HApp zxX$QU)ZNqTn=yIDjIr9F=f=L`xiJIzrWb&6 zJvV|n$B-ey<#=v94v(G;oOo`eRbR@E049L`RxhQq0T1>(2%vr?SjXVlMdx}RurV(M z=7LO|7|>EuIxcp68<-zw;?k--k?dOT2j=-qTn>Hj15?Pl3pZH&n7*;VR4E)g%UsW^ zw#U%)k5WqrLCwSsNZlwRxTS5}vp%oRUw!vMu3t7ncmcC-r=|zkYEJi8|}TN(2SF$CA|_wOuIhg0QMD3HOV& zHUC|03|@Ws_C^x*Z1qP4VHkP7ju<=u^Ly63;!Cf`HSIg+a6ham!-$60zrhPH6&{#( zxwk>s5PSWrKQ8DU4};?Vdqf2Jnaz${itiL@?O0d4tN54r3KXvfYYVvb$wRv|aK|lW zPe%KLB@?8LYw<5VBf`5jT@pO#9~TewZTI7Yn(1>(N`lBoZ}DYIVX1jHvqvWc8y(zb zXV=|ndDT>syvx0nQP(@VM47etV7vcf8C{u6@=Jzrq5NcU&5O&&sqYR`|G*c95)(}6 zkB}9NADc51!>O(OM4KfVF4IQY*OqMO{i-dj0`oSrn<>Ljnp92})Umjh3X1R7$^{j5 zsTP-742s==$60~vae`Wd>qJ3)4c7^RdIHy@1+@*=qXabsr8{0w`?%CxP)7>hB2W^y z9Mo9B`?AZs6qF2&1AnjZy$h5K?YE#fsqi@4T;9i^rU>5KpxC8r$7(LeTaqfm{XT*> zRzdKxQaC0gPU-|Vz_AB_-kfHO5bsQEyb&bIf_MtV{3Z}2S-Mg%{wXeGypWLaXa){UFC_T}F3OR!zciQY5D_nhe+-{TyAiuyRPdS>l0V5>30nUlQu@Is6#jKa1) z?zrpiUD)pJ>R#5`-XlK0z!!lnUh#pU!o!}jvt`L7d=-c<0lQn<+Pj*)-LSb_)YoMkL- zS@Y=l-yZX_Gc&dV2P1ptD_SbYkbXTuCX&H z>K_v}Qu=+5z*u3iW}C3i{L%WIMk>sJ-~`4BOOAq>e{53EmL30;kvfecZ~`N!v&5Ab zFUG~`V|flf3Jcgr(fKEyUTa3v%O%qx#+KR(9CHli+lQWapON~Rk|Jh^b5?urlBGS( ziszM_9-EUMACcz;%yqiQ9!sXp30{>lK4&CRg2?&)1Dz#{bA7UX^Tr3SKAnF>1%(FZtiKv17lI|3Y;dlZ1JLYWR2l4Yc!uLgI(RNJw1Ag=g#m-G4@V#lS@md zPMzxYPN|$$F4>&njdZ@!^l0Nq^gorNxO1-z-Xm+0Lg3#ZGrYGlaAJm+u`W`aLq@0{jx&9oT5yRvXTUwUJw3gR~A ziPHvDl%vZvbECc|^3?Zyp14=@#J!Ox?%h0bALfZG;Bzm{4VEu^=D?v2|0^>~_Rtsq z7iX4kTm3humTW<6ZJc3>4J(ty$B5m{u;1hJuQN|~6ptv|Q9MT!#g5{6+ci_X0)Xdu zf}--<@vvHw<<=`5#S>n~?=k$I5qlzVdN!Xk!7i}2Kqa4JP(MeEd7xT6@i|LeF1}UY zQ9M^6W-G*;$AErjNAYaUe@fm9{_lX_g!@N#6pzGb+PFqVNR-id^`H3J4}(uX;OD*y zbX&=Mku-kGy0CZxGJ!M9Ey?E12O^pry?ewwN6xG!;$F_X_=GDJzA(5`GplM)994OQ zr4yT^M;sHuIhx100N0}hwFcJ`L0ygOSV3{laJZmu#Z|6QzXFQmDv$GLT$vjlXDB+h zQG&w7VK=88$8~acBq@eJQt-q^p9`@aQTaa3@GFOQRrsI2z-f4D#--0+Idf#^l{4Z` ze0A)p&jJ{*!ao)<9d-Rh|UNsfBbEd$vg%ozFc6I%Pt$~DJPbOK|Ik=X;uu|NG^ zTodavQb&*lCooQX-;ycrxvetvv_(4BE|d0~N5B8H9;eBANj=2aqf6EVBeiDAviprx zgd%Xn*iv#_Pd;74xWA(k>L+xIWUAHe^oN@q#cQb>d()2@=gI@!V54{~)jxJ}+B*JM zrI7gAz>c9Dp=+tHzc(&wV)zp!MT{-Q-oWI>QKJre+emFxQpDI&avZJ0diGb7ziFhN zS5m~-QXF=hu)M1`ykn%^RZ_&*Qml_gs`I6-XB(+K3#1q^m<@EbHOqTmy%~B$>vxZd z?*H)*(Ru3<9INyYGsOAAiuRUnR}=L#cP#1c>uGP(+QmBzw|%jF40X7hgdRXP>k)n$ z!;H_xbE_G{P`v72;w$TDE324NS~{(*t-O44S%u+OO_|z0d2&TX)s(iX%2v%UFRkjR zm|WIg(ONaRZE`t>vr13L*+R@U| z+E&$GS#J0hRp}xs)22<$chp^0S&=sCK2VIhn^6~QRq5n=CU?-$esP|-gYv{3ktgoxJaH%FiJO)uj_(oE-C(2r+B|WI zJaMPx!2RDldysw3e`@xCtzy>AE;=o|>g@p(P4O{ZuLp~d@jZu27#oRjE&(#R0hie~ z;4=T4ud@Vq1dB%;g2}*k48u9VCS%^qt`|p70wad)Vv}bz&%m_fcD~{OspU_+Y)jyO((R4KiWw!=xSog$T?RGpD3$ zMI+MBSy`zlm}vjCB?HK_GVGRe#t7tQ&-PI9gupgj>L16YaR8SyZo{Q@eI)gV=FJ=` z1o88TD~8sf;<)+*bsDZS1T`O5e(B31BQNUlB(nRpPB)4#++-W zUe?i(KG7{T;pU#fTakpM!RJ4d?(FNWEX{W&J$YI=-eS@5{Z)~eNqaG4^`g?y<(f(B z*Q64G>mV~}ZX%oR2AfIiZC5ll*G!tryl0?)Z&9;zc9Vn6q@M@oj|#_sxn|O$n?*X) z-C#3m*y36)*G!8Kje~OFkg@+azE^SU(7!n|VhvyssEtWiy}gn*VkY!DC}+(;@tUXb zzdu=I@7CPJjWp#po3tvsfnxnvm8|D~moJ9)YJ~32g^EX9DqxsE+%LxPc-i6(-jibb zq~;8qf&@z{0ScBRC4BCZ5})9ff{Oz`gde5?BV-id^`Kzky~^Aurx%zhEEFkG(Z9P0 zF%%4L2YPME6^!tzEi3V_c{85_oSb-seHd-zJ;L7XU_n*lDo5K%P#nK`9L@{m7<(Ql z>h?GtxUx_8I4g0LzAuB~v&rN95m%}Cub|ARoDE1jj?Uz$TvF64p0rNEJ|1VE@=?w{ zJBDKHE!@h}PY=asHdU7XpEN-l^mRtptw%6zaCmt!SyHk}iPsrrz8Tbh-cXp~&^T$RTJ$=~3YEW3fo{aAH#2h~d4$?KM|HRPfh9+)W z5jE#r9EcBnpKEU(nNpFeuE&wZSkx}8x?vxoE$-@UT|VgEuw=5?u+QFbqV$G;fNA6*6Onwq z;qy%XY*(N+`~Z_K%jN40S^aV~9lE?kw*<1PObtuN+Z$MsdYhk#}C$va0Y; z=g{Smw=is3SK^<}q01xhvti5nGXCitx*U0Ius4KpaTEUO9J)O6UJhf^8~*7Wx*U0o z??*;s12F#S9J)O6sz5URh@!^1cR|@8r_u$YaN`12liirOP94#EIyJ z@K5K&BS&5YekGupolBQTUKeO?$fe7X7lypsK(oQn1@JrHsI3F|9~c^d;-Y!peCG7~ zyfKEreB~S6v1?8Zg02yCD}8kSx2A`H?zcWV|9KIb@SgY4MSbfy?B)+=VrRL0@wgcN zVIQ4ezoDSJ)<@^pk4@hVgP>!RX1_-bP+UI!Se`%Sljn~w)9-HkE+9jv+#9(K zI%CbPFVd>Oy2w1n0^|%DKDR{b)#uL0cmS?^neok&-ao}FB{`?nf5AZa8$-HAJBv*+v5h^j1?1+H#SG{( zJMs2h_v=HtPRK_n`U%+%yzGczw?Zsd#CoBDaH;on#WKUX_Z40H5u1#)O2}gOBeszAlRamj%ld!aLYpLR zlNf|UnZ@UrQlx}xxU@SM7D3qZhTHOrH|+i?THs{wy^;G-u~_SO3eUR827IIH^+Z-^ z)w?|s1>i}=SZ1=Q%t|CpIFfGc#?rlbc%welcM@V#-ha;Z{qg9VrQ5CzuG+Bt!@0HN zB;-;?lRdc}X^73Yk7{DDN<>!MdZP07$uBMgZ($`5b$=*`3L6idxv_mHGioC%SgiE$ zYY**@1)xF0oI`fs-72ZH=2s}MY(JUYcH)Lk zc{p;D-OiyTp1BESeqYyQ`ZIe{=B-6w_p-@C`*F!O2?NP9djkw$M4$Om=*DdrPEfjX z=~+#BZ47;)2&z!?dqi_DNi1`oq+RJgDw*z=%nkM3g|N%}ORmp4H_Mb=`No-@mgR3F zd6TuBvO5{;{sv^jPmm2y`%40eB?=}RP&8iY0q5;^W+Z^(z1w&6iGM?$xI ztYkhLGbwy~p?By&;`tttxMFnedI)8LC=|}?(Tt_Ks)doOQ5E{bi zi7=c{0`(Qh@kE+kGsxivZo-G|9-TlomQrNby@_F;NO{mvQ(|S}yr4O@r}5acG5sUQCdB#ZcZQ`=?W0b(*a=_7q4DGX+vsS$Y25lFT+ zXkRXQ+4!0qf|Z@v&EkbtyCX7Bf75nv8{i#U4A92z6#>||w3p5Ii)hJ<*rXnQKTAUC zcB#I7?*lG$f)(q&7T>D|pl0btH0{X%%gCNXWw=JLe@?1k(_R7@-UcX*2IxsNK#wgy zF7s4w8k1a9%WRicy)Uu?!J<4qiV@95CuyB7iW`lN5sJRZc%@{%uM;+s%NT?Q`b8>p z0t1v+5zB)$00}DYwjb*v3&G^JBdn1P2dt62p~)kl-XnmT@0AkK7om@n5_U*ZB-4)S zjFd{~6ICQWEKXBItlN7r8B963;BP`j*050Z33WkMrli9$+|O}KWQAzj7olgC#wtCJ z##EBL7tUVubp!Yk_a2v9lnc=qR;tip(I!?go zM@MG>bi9_#=ztCgdsa18XH}uG_IzusJ*yh4v#MkUslp+ieW%09EgSHYPtVF@X%}C# z+18=m)&XVGO!C;e&GR&RI{lJVV3OS7@*I#-GScm$>>#tEy?Z*kcG_p|!++39;Pbx) z;*#9G0?onaw*~6K=RE>_4WHiQ@B1-SOoW66$-O%KIXqFAE2+kWk)Hr~vAFG$8do5s>=UIKB;lZWZ1} z$G6Mzp;r^-7LP{ zfIcnIT0ox?=oUbl&R++_kx$V2wnO(nfHH!60?=xKb~?T<0a_)vHyqp$bc{C$ZWN&F z1v(B8Mh1`^aePm4d?x|APJGV>bhSV+Kw3(w0bM1yUO>wQ`VT-?3bYB3=Eq}zItBL= zKwlB)_kg%+7PS5f=;Hzs#g;&XFs=Wwknc#RX zR73kPpa%pu4bW17E(Nqipeq0^7U)($s{PjhT`suq0#aRm==eSZNHzVHt1>%_q4dXUID&;Of8pZ>FG#)!0I-Yz`x<5H|`y9GqsN^jo`7l6Q znvMpfd43`w>^%ZmNTe0=iUqs{m$Ppf$Zg(3-7N1X&8F|eM4|B z1JcwO0HmpL2Acnc;yV+N){g~%wA8I~pgurIBxv<*Ks5rmdY!k+>9o*j>++pvteP6v7ukd}x;4!29h0zmhRek%c`1j+!?vT-w@y9D{*K&ru8fV50r1cI;c zBI``ZrEJ^fllx(K;_4%OQsyiQgexR>8vKf^qac&AZI@3jC8}J?{5{%Xx0fj~Zr?NkRHj?sfmrwQ?@O-;EGjz(fT|T+R zDt9=pmwH<|XQv$H=aa3m8-409>(uSHTccOsVGVCSKaic5OatXS(t(Zvq*2&-i0SFF?S|EhKD9bdDKSpRiv_`?4plaw8PQ?7=^)pmu#fD-sG!oN#NIA45} z@FJywWxl`c=A{lN7xLf0{=x;idVUWTNW=~)QW4R7B;qr z+gp|_I%7%WWwG7q={3(6KN)CXCx+jOU`Ixt`;~;j(3*(yO-G!;QFztF7hZ zor`!8SI4sOr7hv5%a)#jdpehm%ervOs-0cmFe7{}q|b-QOP6&nZEkE^Zp4JgoLNyf zE8M!cacK)~@9Jo2!^JEeiW#-$57adQ@QYHe(5BtDG0xO_6g^V^m!k!!Ui zI*8F2-pz&YrJYMI#kE^YI@>!C%l3A?fU9-UnG?sMePU+c2=MIDQ}TEml4x=kMEBe@xqob|QK7tU zW^KbM))-O4MADx!?cpns+ha-*pPaNke?SOS#szG=t*j$lY^TwM ziRpE-66Fnb(>0A+m$x-8S=4+o3Ji-{fs~CWDigJd>9K}Hd2B}F6l+FP<6`J$3N4tm z$ofj@JD|`8I@USF!?I#e~Ll zw=w$~Z1qEjx)IQ+eV>@;ZjL+w7`mYrH}+-U^?XYiXgpy_>N)Yc`qYI% zm+MQ0OH(*IUKo=hEOt&z`5CXIzu|KIx8V{RPgoo$xcOCf%B)YjT#p$pq4C6vqbxTK zz47{m;Sw58SW-HjcrCi@(=WMU{l#!;3C@n!5fYXiug`b9^^D8KTQ=#0#uL{2fpz2c z!_}XA-Q_yUa0!hkULO!HcDhW%{eM2Y(&ZX!xP-#47waGT3jYPeMY?0Csg zG!QXiy>&+Kc9*NxaOrS0yUf$vk}T z{Gq)r*DHpLG;-g0bE~b6FLW8=2O32R&TD-X%?5bXl^TFF-1^+QWSJA!aE?Awx&k)m zq1F%QxNMfm2lh>zE1QFSv60j2zNd5-yB?4Yt-`wEtS#)tVD}SF@WFTAs;|%SVl)KAlZ%?an2a zlFnCMHMezY3{A|Lo52?wtg_lnXpLXP1O^Hi@g}#Q@=W9m&>)r zaFGVJslD@3Z|MF*0=RD$Hyzqk;heC>K#u!1X`9RS8N)>ywtj6(7qkEr7tWD$Ca|uY$0BE75@hRqkC8(fZ|LKNYlKL& ztiSwW&9_~y9~myvc)2DBmt9Z2XNCW4xJaYn4;^O2OD=bDifCuMVA>m77BA?sQDJbk zES`vL&Bh$~5Y9x=hhtQ_Wy>byQ%bhm2JUVxL zI-0JoDX&Y{`ET5f#9|IvJQc02N!6663DB6syME((<8OT0Bv^H(O|nfg=Eh)PaB**Z z+5|^PCEj|gisRAFx|%4=E>J{GJ5uO_FQSaj|<%n%89jmJ> zGXf>RJc=wr62R&(Z4zp$BekqNT3?@x$7*Wp-N?J<9l3QlI}IvoqqSA(ibO2&Hq|ew ziIr8>*2b%&wCR{fW(el5M{~QH7qz2qSMwlb>5Ew5*FMZCN`m59NUCNHmNSy{R+ zmPn+cY6$aqPOYx3PbXuQl~JeFQGcg+<=kC>fpZsPg_)lzol}tPu?mFFW0zu1vjw=f zYajf+?aQxd#ZwA=h7ZRv4tC#maq+|wkiqeU<|sL#xd!8uvrYGv?}X+$d+cCn3f)(* zIfpLa2~CdsK4S*8wzz!v72JVt`*Wb1#{LtIW|l%HFCPcZ{~9`q&UatIDB%AN8hZfZ z&`G}mPvdAh8iUUIOw+|XbU7#KD6a-I7w6LDk#{v{Zp@|2kw+8AS3&bYE?pjZ{|lPm z<JUuik#(VH)qr!O44n=`UXKs(&BR<$chVNA7r!|?q zI5?EfyoPzQ-V4E-dfbCU$=*97cYsv96Pe@hf9ne6R| zj7|48;~k|}_iTLqkj$oyyG|(D(c2IyNoM|61Uy1To&CS*NHor;qG%`=?^M$`yor=7 z-JN+W)VCg_X@p)6-v=A`qaU|K%%2}Rp$9)uTuQC`EASmkY)TGn9N3y%`5N8{v0|&^ z?|bX|p|R5QIuqP(9F09d`Pfzu6(y8-|0UQwjvM8SA~oDN{v;n~8ZZ8_fnY=x%{uTld^4>Pp(>2M}veiVNeiPNbZU7EfOlqwp~8CY;vG4m$aY#q(`<_Q{`ps zRCcx&l%G$wQi|+`n@QxPMmrM1KjT-4QPNlOE>EJTh6hiV3EzpAx$CEk{qHDUYoDX6FSXCY~txy ztA<$@!XJ|h8C^IxzK9vfMyYAYgOU+mM2tXQDi2Dj#02D}@}QJT3_xBg4@#-B6m@Mc zhRbJrA#wZSrI*i@__Z#$qRE*RO(;)Sm)BHPm*a6IoezDT z#7UaZw>xn%$}Sr0ylLX($x}FM(s|SSWZqPaW{74~x_tAdkJ!adNebTcR-HqaZ{EaK z=))YuXSsayrfX1Q#(?ft(=4;T7MeGWM&o-18(=t!E;Mhd2F*pebdu-7Dj#e$mV;(h zE?u5^#8*J`{am^{@_q>#`z@eC`mrlLgxx`w%QxR(aNL!h?efvF1rGb@qP`nL*a~1n zoX5S(=Pyzh-r@X3N+^mT@2d-+&l?ahhvASXm3gfuvn!eTSvvF5E~XlfS#tfK^OAWW z$eyX(8(9cUy7%@-E53z1k+~T2pgSWgfVltA;EB>>5-WPfowFn} zIG+p_%w5LwxZT)f=9y&gVsqGw$6=yo3h)qg(V%LYTCB`p)1|+=rqh|D^p_8uI{<<% z-{I&Dz}knnnzm;S8Q8q?jkkd7jrT>b9~LX^v^q}&x6ELYnIESzPvD*1bL?mhBrFLS zv!3p4!BqF30-fu8a}v(>m=HWK#DrlwFv;|Wyeo-WxrK?$GeC1UbA|d0{0C)jaJoP> z_&i0RkK! zi0)v+{qI)4db&FhJY1O$I^1tt_nW6&F1vKFo%QZ+V+nSL;4gpnsvo*s2OI9|ywbAH z{n72mx?Gh;L#CcLEH?FSSYN#EKGZ?eds%}S?o;qFZ=U>!%XK+Xa3k=KyjXZSUcSv< z;iTWS{1C^1>4DdKb&_D~^y0(|F)Fdg6gL_vr17rYvR=6_ou2o>4|cm;Y#ZoEgJC+h zsJ1y6g6*w zdQdt@b;iIhl?UY+%96%Alm&(XW4sE;3`R@JDpScg7AB&s{W=geUQ?^;E90rMbTaCw zTWCaEkt(aLjKvc6h&JUC!oJ@$*l}txZeVoBsUaDsK84y+Y7#l$ICZgIRt!xc`~DYl z=<qX1i&W#t>EPKB&xpu5AAS{jiGjZ=G2|8Fv5Es8EQPQ4p6kL1$j8CU)S zG`n)?a>l9b5QZV$j>kWp6K)=P=YS@eOP3>$jm~_~++gU~oaP&UegODBLjzD;z8lh* z6}S56{5O?-6m(zm(fP--l(*GK=a+)ND#DT64t#TDx0AmyG##JH?5@e|OJ`nAW?thpD$!j?YZ)i=&V}sp@hvhO zq)nZ}K_QbH82ZivVY=zg$S$B|!2Cok^JDQZ-5FZ@A^5I*gSPe1+V=sDWkUD!7st?3 zKL6?)@yv$)cwhi`aeY4a>ON;s{SzoRC5dD4I)avk0g?HA$jDv97|P zE|!G^HRE&nK$jGn0bzWGVb*eda`YCIQ{TFz@HBq25(ce5<5QOuUIR2m(y5K$sNO^AqbeiBc0^*=IXgv<-WPzRrbdo^N0U9F^&&Ho9&`W@H0m-T|T+& zQy_O#&>HnDrU4~ugxHo(S<1!m72<@z9v zHIx19o!{?z`*Vgb-_dZNJ4znxoZ+`0yWl~WYqV&6@Fjxw;-iXOu7k}PI2=HGWX)|T z&6;Ucny^@i4>V^u{Gr3M!n)9K$-Kg2N|*V7V@fao?%$`n8eVR=bk4vZ-Wh^_7IEM` z&zuhw1vuQGt9a|u+uRYkRunAsz~^9lo>`5G9CN#O&-3@;M@O22?ef(b0*5PfJ!d~w z7s!LrSl%g_U}@8P@dTlX}q%|V0?ytGZQL{M^hD56*VdB!g6+snLTxE4t?9i3T~+@ zuZUKa)nUI^8Fn5@13GPzp1(DFCMR*n8r#unlcXWVuDZ6Uq{us1aHuY?#~#2`ojpA( zf4d6~BP2^&KJHs_C^7RjowZ>H*ZA?1Cr=KCi;Kr+?bLc7Oqf5K@f&p9wk0RuOzxk# z;&3`jn}5Z@e@FglC~i0jX0@3a6`RUJGr3El|5E(Zu{q5*lVhLhp8@%2A{29*kp)m( zz8Mu8%&+_C{4*dnh2I_o9V_7$ADv%64iWt`Du1}_26*>Mwv!p(rS0w6xJdR71Fx{6 z8&GcEojayXU3iBxFSec8E;hY9nZhaPhMCh7c9qKhPSvIwuL|uF=OuZ#EiQ1tbBA0sRR4ZNYu_HV@t@H!J(jA)y#cw7{xcG3BoM@;^ZVCLk0+*=U67Z6{ADvM=CaYwmCfH3 z(-VogAj;=QTzPW(!TCW{h@aJuO$Ylr+K$-ju=a2a#;VTh#PJ5lE*w*^A7>fiAYWcl z;_}ZZZgD&2{ABl^#>X-*Vc%RTv(ro!V-JKu8P9A@W_IragsV1*FurC|n8<7tKj(tG zqeyAb7=;11VTQ>lbiLFRQ~Az0?lfLJ>{%yQL$VRFosRwd;3uAYCJk)w-gmfvh3Y2| zW3N!HHvuM_My|{p(i_hlnZz}P(PU=~MCvhJ?cOqe?&dIg==^(5Zr3gU^!%!e$LK>%0|^&N{ya z=tS}5eiEH^J_1PRn%e<=SbU$vr^@>&pkoEM8=oH%XfHlFH3?d8;*+g?(Bge^EHFCR zVNYf|&a-u%st{ww7QM&{968)NvU!AcWW%A>ktKkqk7`}Y8yc?EQ5TxExt3?T$0mc* zy;MiblJFQ@^3j2tJaCK0I9(q~eC*%5KE#fluBPb4A1TDmU-rfm)-C>PqOjJu7$*H* zB$8tM8^oA^?EZhZw(QgH?2l7xx`VA4-P?IN?v9h10_wQ%6y6}lVFKM_$9-tI%QaJx z(kc`kWYvU4)IB9PzV+tMxg+xhMhiMy4}F7J9m)CtUcT ztIvyyG&95l&wzA>NX_Y1uN{E`VW-#$rpoCIG5cN)w%tX6i16fooCmHjkV0cEYHw>= zh^dDRBdqm4lg-J&}?IVVL!C_)kOKUfkYcpEkPu3f6Bu zwMQ>h`+Q#ZVBeX4Wg)WXOww4GDbnQnidbbuEL|2=x!#qe%4D*-rmnVHSCYu*@yGnC zCRrJ;uf=J$-1!yTpTWcOP6PLYAmsPCt;&ciw3=8=~KO+zkSj=V5rw1MW+xpaBt z-2OVO==^gy7O4w; zbpAOZM?iCYbbfg(CZEhhhe7eXbgrj$`W?>o(wSe>^p+o!>YXtv)muH>d0?j%?Q|x9 z6ENw_AG`Mja0n*U_d4q4xf~mY*8T-xs`sMjQoWb&O!c&cJCV!>f;r;ss7GjvVZo# z|F9q7^BgPWdrss^%rTnh-;^0f$@3_AeD?;B;;agn!&GiMGLH*;7MA*2O>l-hWLX$lJVE!#CC+JUZ5YeSng~6g#%}8vJ9*p`wTJ z^6`1`(6{D9O5#O7rxsD6jrGqd8X^q+<$Qm`<%wsG?=K%h%7yU&rv$F(Y_gafs6q6` z#!6od_058=?uuRvD|(cW&L3kcm6o((>W1T`zYO*L1t}2kZwbgdK1gaDL&9qpOh(+{ z%>xIq{*i|ua*OM&r@xj)@o*O}n)xxx`64C-^oMJ_IyhP>p z&k0CEL^L5HSfQnS5x_EG5~H4p5x1EnbR?UHn$cPq>wY7^SVcm8Tz)J5dFX^F6*wpJ z3}ZALxX`zrD#Cul{<44xt3Nn`33a+$ybS^fK3&3>70TjQre4DrTK)@(5jtT7KCM-+ zgjRh4-;~>bKK2yqLog~hJ_x}~vvU}koshy{sh3H!jwu;Dk|M)zk5-{?fu{%s2o*rn z$k9{E!k!@m+e)eFnv1cJIJR0lXGNcrnE<rZT_G zT9HmRZB6y3S80mGGuZ1Hk0j9~prABh2^>Xl3iEi1q!?ZbNLrmkV*^|E9GWTO_RZeP z{oKcC&X|2CamvX_gj;VSHe2+#J(85)*ujbK*fuemrkYMjqWoMl!7i;y39x&El+Y=N zxdzFSmP`bWXYw)DolkPLc_9R0+P-oNn?bz@-nj#QI8sxzwG9ntPhaU?vHa1jN~Y z(5eHZc8rSwu@?_o&48GiL2D_XQw8Gf;VSQXK&J@qR6zFSEkIb)@UNByg_yJ)kGLz~ z)SM1#8fwxgH3tP_@n2;92HuoyyL@tK?@+mvNea3`a!-U`kx)^#?efXhmG9A`hFhby zoMMgaI2AX-o@NCbPM1`-!{O*jxoH$oh@2WuwnhvqUpPuRIyl4%mN2c|eQe$oQC_B^ zrcE{_;e4`{GVqb1)<**4tfTgR;JG7q;A+77RC(ecmxNxn46E~P%dWtknjP)9bXD%; z>|DyrRk4CU##nU{@qgudeb(Xt$~tDsSvkfS!@;UEULj^H|NRyl7R=+|x9#eq{_I+8 zY*`1h*eorY-|E_44mW|ZOd_nTAvYU2_n6(bukLMhxkeiJ+sc0 z!vO#tX;e1Pa;pm)49|4CnD)jcEsd}uyBHcq+S}}l0&T8t4;SoLlk5u58a&MEhrex7 zaV$}jd65##SS^rdb^>@%GNq18@>6+GN+mZid1ZM}N@dOpW{2oODOHwM9t#=uv^Np_ z^DgEouZvdJl~uuH7WZGT!v=oZB((6njiv*;3HY-kYO66NRhz6WE5mJ0a{4flh^xVi zF}SS#<5%e(@%GMEXigliM}+NBpe0QU2W#7!a@K_Lx(LRbT8$p~&$bl-{$9}RG;}QE`D`;>)%mTV0Vqz^&9km#C6bloj+XC{l_5a*md4A2s(BbUl{}) z<=rtzx^E4Fj^W-nNV>b+jm?9kI z$eO(FoVVZ0u1AvP+<5~GjRg0|w|NE^bL$QA`}W9oa==2godPp>PL#hvFTa6528{^u z&lx(JJ@|W<(BaWiyr*qYG?yoFTy$YFvo5m3(2s)W1NgV5*5FubUt|TqG^XXP+=Ks| z{J2-FQt94@Bm3m{?ee@FC0z*vUw!5^u&stq68jAR?gSX>dkBr}s>eb--^F+LHTUed zLOmIPu}u7){j~0^K$tMP+ymlF{5$*2CIn#a1*SiEeSh%LU9h<%n|9*))z9w&67qW_ zx@3Qjaq1t5MgODd<@htMiOih)_S@lvg;0nf{C3bnh41Z;_udk@4L@l2!52j{CCCNT zoj_%_UB2P4?p=q82I>EFgJ23%g|tZas=$X0DNkO2mhT?(`rtZ=F%46Uvir1QJhKxD z-Mb&g-OdrkkHt%O?&ech-TQ{xKPSu2VCUh*kHHjI6uNoi?vn&nWK$d|KZh8Kp`-{3 zYM4O-nVqB>8qd77=lBDV#WVX1-75#7 z+iU1vJP6&c?t!Bi?jH)!seLG(d9M4-GrRJ~Ku<_yc4<7HIB-1icqfu%8|-T|M{N8Z zETIqgY(TQ%QO{)mEx{rP7M*2sS$hawNZpO1<;espJ&ZSCpKP*J3e6!K`tNL5__)dD? z>1JngeYa|BbmH^X9Kp z7S~0hs3EMO%pnkJ5~3|$4Qd*2*|OPfFV8par4+Qq&&juGCPBXszcbq*p?>!YRJvqSOLym=_^EUo^^HxB~_`h?aL|9_zV6+ecxvUM9d zKuKmWQc0uhTLJCT8H{asn%*qXQV++V#Km8audQqLnFmW(f!h~ zW}US&h&oUj3Y$&4;QJv{eJ&q3totuTsB-?!>njXcYg=YtvT2)H1ksfdmU8wlBEF#R zw|jNZ3Y`46*-C)F>$unhUj?<(pbD+?{<3?+L5|h$UWhfegC+KpUWM&c z``0J-PZ;n!OYHyk>YkHY*@+$c#GPDkd|)Ryc7GC}or1%2lk^N5fdi?AD7jusK&t=9 z9#gm^s0WX+X?@c0*8CocGlHxnT@l80s zX+R0_y})(J`L_XS+tK<)#qj4Pc}|@5zDodUeq81Fu5o;C2BbQF+423J z-xmOBe*D$(Jp_eMwK^P-=EsKtsa9t?zMMU2ev~`Dvm9UE`>XkJ zndAE!Ak7cH{i|Ud4@hHv8Xyg$(($bYloahRa(p`+->U&>e(>#I<-N=Cz1Q*G==kzY zU(JtG0BL@d0Xkj6_yM3<0__K+`W2x^(s+ylq+y&4=ro}l2k2CRrT{uwplN_k5-0^| zj6kyiohVQfpc4e@1f*eH14z@k7m$W=Ga%)-1CZ`ozaNltd>@eJ+YbRL$BzLi2Q3uJ z@j4*o2*7TlTM38_cF@WIQvGfQq`Y4Pq`Z7B z_$ZhG>m5-@x&;ek8D{2&7gqW`4-KY|6JwxLwiZv+g~)#e0XA=y9mo=R62Ad(7?ZF9swTR zzxB$laE;5wIz@+uUi8-8DT1=NIGFwH5gKa5ou!xVrSl(ewU;5aRuM}YFBj9wT^L<; z%!g1VhL99)xqiurP8Mc=<9{@|8w1X}ozVOZHCs{9(smktlX* z@hWjT(s;Q-z_`a`F1xFv*yW;$i;gryq*k}JH<@UJbL5Nyjr(-n-{*BNcIEKa5jxU% zL)Qg*mQT7rbo>B&9c-OnFkHGopPfF^rUq=TKOXbU7hSF*!%iA+SRVk!)$myBjsJGJ z!iI}9UM`komuuRE+ploB?57V&!eMej|r8-q6{Px<{XmEP3f_m+KD0MH&US8;mK> z%eq>e;%tQt&C?Ez&BYyl>PW-O4JM$x(P8M0_HIA??Ui(AOG6eSYwG|Pst#}=K~=P} zvOZm1naX;)#@GM)j?G}-KwV{3Rb73Rd6viRoAIcR>74B&Gk83D+N7n+qV~ptvP3jl zA5T|TB(q-TF_$1nXYC8F;4KIhv1qcYB3@UQ#tS?Q&v{QO5>HQ?q&>YKk6z!8#0bDq zaY}7%Ratr59Ohvs?>Xx;p|&hhTV7V4ibB&tLwM4}Q8_sGB^$Fn98i>E3fRE8TK&k{VhRT)dwr=lE$ zc)b#JWfc|WwY5Zio>sQvDd36old8csro1f zHy*F4mC011I$l*9b;_vv^JfcEg9UW3kNt=U@ChCk8IJlD+Cj1n z9i~10rV9CXkgyGUi5+W}E3|{;P_gN_g!y)SjDz=ygP`M>pnec^Y~n8R(fN0BECAib zKDzunNVfRsqQ0Fb><@qBqw|N$Ug_CE&{5vc21)muLDKCS1Rcl9e;Fj*-v&X)V)vSl zE*eF}c~_pc>N0J_JKUkc;>@a)#_~XzyB&_@859LYpmLbR`EK&RMVzMSomX^UnMfvtlXb!O0U?@T?JEs&BRylPh?(9 zWM1H@jW95ffO`jfB1z-ROB?EeJcr1rLE`sp{;qd_&rv)58~&BBX6R_!+V^Fip*`NW z%u5=XEo63ZF`(&btcCT69;2Kf*3Byz1n;LlSP-N!LBzTThGYeUT@GvZ_r}*nLw(mU zq578%+@wMM)gK!k{IG-CTTr2Fs(swlG8WOmNta}Qx+f}H@JS@>uz(sk-O>~7Tq8F@ z#JcxmM?fsI-@op7IRcJlp4BMq(~uwc>qjzMKV0y5XJovDj0F~sY_S9q?`g$ieJ0)$ zHM>Z#?qeUniOI5OEc2#6c-qbFdo8gMLKc+r1Wz(Ic&_W1V0&as0YgT{_6JkWE*dC_ z%`;T8f8=V3UBOgcnkBrj3fWZH@qp6wShA_1Cz`zc>C-duQ+MK$cpm)0f><8?mt_SZ z+a<;`_b@6(?md=?->^T{z2&eN7xp(NyI;gK<0ub|4p!;y9s*S`?NDr<-_FKEfG}aLT%``Skuk=LfmZW>~DhqG-=y z-TR6jVEY@2%i7;A=*UIGee&HC*^BSkz@~WV5plE?xLnhcvs$;vR;0{fvbKLO*h@FY zLhH81GFx}^i4)&Kij9~LQZ1tWR7;opbXmqh<6M@s-8pC+p~{EG>9>4noLJ07Kge#u zpm*N_xcjxCork-Me@Rfm&JdC$7P?s?(=WK9&chtCJ=b=>Hl%YTQqa)sS={~FFd_mr z;vy4>e_itoh%@ob(hg4;2vQcJ3~x4-D@P7%v2D&;hrMX?Baj-$f6#gqpD}@+#^-qg z{T8353iWLO#6e5Y;$)fg%AnN)NI5cq zCJOHJfRy8#j_-E>#l-jfj_>1uh6`>VAeA>9{hZ1R0a6V<0!ZbJb9^TOI#YPd9A93X zt-Ni3P8Z+n9pBx6P7xemY9A}mGC&^{s0&a;pcQ~d3)BZFEYRlw=~4iWjTqeB4i496 z8r-7}4%hG-+%Fs)uN78#e|2yJfM~|n197Sq55%cfJP@aba~_BrEp(p%q*B%aQmt+S zM8ieU`YIqAS@1?4AeDC?Aew6s6db1uwo3p|^SeUK4KW#60j%tt94NNJdyjwaBRh`W za7^pb^FCOA)cAj@p}lNoCGG2R?3@pGEN^WIFIj|FWMR3(1wU=!Wo^wZZD(A%Jlv#4 z^@WXHyzX_;(&m;cX^s~T61KN25HtH2waDkeJLk$~mDkk6rjBbz+O1|1=Gfd3RBK0@ zvBtM7Xjfy2Of;iS%P@Cb)O`H(ZfjtG>6SeK3@{}FERkN9eS83g95n1Tylz}UQ~OCx z+qNq$?--(Coel*V|F-d+xvCid`84J=r-M_vFS-5go7x|`;G+$$(VV7DIu@UNrgn~X z>GpJYJmzwFP3>>@yc1iSLdJJHHAv$%w6PQyGQKZ_A027DTr`>&acxlCUGtv3)i$c( zX<36UWLVEOp0eL_jmus$`VWm9(hSawzQAylM7p1J_4&QQQrov@M&C8!+&f)4VHR6B z&h}Y4v9xF~Y-7CX!!Fb{WdGy`<96CSn3)(Z(s;R8YFtC@A3kvPqb}Ec!$le|7Y*WW zSYEUB4Tg&}F!cKjquF^ugSaclYskLU$RW)T3va0{z0$ejD4e5@w26*E{MRG)qGQtZ z!sRPQ4r#oxV4LfjiM=NKpBgUG9L(Iz_S}{8$YmCe=-HwF&B!5*H*__uv!v0j37v+{ z-sTD!Kn?3K6HhKtGU+3RS!crEHkWzL#L^UI-&@PsvU|ep|G+Aoj;5DoFNu3c{DQz@=071QTfB;(!qb~QG)4c4+cVf@62#V`-4Wp#{LR{wzh zW0fg{*&QoU>{k1R8c+MHfMxZe9J)f5)eOyaSuUSt^#SxPp8;Lk^nKq1eId*0>!?e^ zWQL5&3c7rjRaUo%p|OL`XIUlP6dzsGXOZM^J3RsUR#Zeo9#<5pO>13Bl6;S$hH^2zgu%f|A{K01H8aF~DZAn2&xF9$)#{CHsy zbZk{$_tE(+#HWF7zmLuz59)U^7ZS5vJ_|dG@^~MeKU`Lg$%CNdkg9YLbnINpe02VJ zFyGRHpksV5$w$}Ga%BhnY{zoC0Caa7TIySo6P(%)blH(KTL5QQ+I(_UKrw~ z?1Q|Tc=r_0#xem~_4`hSq*CdyLTf(^IN8sp8eh@~Co_+yGutE(*q8MZe3!Sc&1riN=c{pmn}XCk=pLHnq_N@R4%(%-js zaE==+wvU@Y0!6z+Xy6K3`A&r*l17F?4Vku;&rV98ebSc4fpa$d?)AtICu48MkDQF< z>q@+?EYx>2JYy^0*bWJywIlE&+nPwS2U$_$r9bPH>@(J zb@iWEASA^@Yo7z$Up2r~T=|-0_}I)-xjA(>`W(@gms{0mB%ln;-J1qB!OR^ieI^tC z#C{Dw*4xtueXQ%&@?t%x>lC!^4Y;*W%Y>kfKq*17fyWWsLqj+6sViJi_W(P&(v2)U zT8yrlj->#vJjSMbW0CrM6Gddkr^;7o6>o^u0yeO*lqE)#xbAMJ9+<+XCmv#wp4&u4 zrYy9Ho2Zp;qCz+k4E#-4C(EbLkb?RoR{cD*dL1GbFIC0X-pC)Cn(@+^R;ZtEjl}vd z99a2=I82BxR=*i4em>oI%51L({fe2e%#bCwl z`IgOsJ$8fBV9yyg%LJE2D~c?0C!Ocuw4d`e&JVIxHZn|{h2347VTXi;>&20IdgXp> z&fH5jvny!9f6$_;%>u>n*(gvFpYsHoj?aq)x&WU_*9vHk;I75zMFKHTE)-}jK1mz2 z*5h-wK(M1(=L_^*d^QNQ0iPceh{Z(dSn=xx_d9&n3G{b-D(`+kwSqeonXSAbKuUKU zplb2`D4;4pMb4jg=1Ft$;MXUjwA^{Wc(t@56wU_ZbKJIUr4g z7XWEW{u$7C3FB1<;@L074MEqZ>3k?4<=|DbDtR&>S}1}RZ&g%|DhK+Q1I+@YQZ5Fh zQknrNZz~{`cZ~zB0;DC8H!>a~VXOl*PN3V2?{MpGK+3xnkjncJAl2n(4)hxbdI6B? z@@GKG@g^Wm`w>A~-pPP8b;kkHGS0nb9}^AA9J-}|&JY~mX4I0yGiR#RCje0y~1vFeZDgYfLP(2{!Js*&Av;b0$#endK^4IS8Ug!9J5)k{fptTmz#R7d6khXQV z0eZjS@L|!yXuJ6UbTL*T>U4zQ0`DJgy}x0k_5PB>toKhpe8b4r!{+6?X|uL-$)zn= zIGrE%-m!^|)Lbyd#@j{B;kL%53tD*7=7h7ySPhMrE^Y}o;aLJcs?rvozo-olXl8TE z;ide{RaqB#hR1{#A{2WmwhKFBAx;H@TY)8fo%7NbJmIqRjHN9La44&*Wt^2q3~vW@ zcyrVq54CexnwBl?z>}YdWVnM7YA?+f5g!%KYc(uvX*cn24>z{8gmLX$>$3Ki=5WWd zuq;K}hr-HY@mM^LhpT3sVwK^2jBsN!_W!ms%)-gb3+`skNHi2UST-HeG%2O4+W93h z#v-XambTivE^TbL+W2v4%L4n^99rM)XLHKxDre3})HY1N;1p$x#iv`aVvOCzl7?55 zigRYP_F#>LO=xTcOQ0a;-z1}~v76D(V} zZpp92FWa>O(2}nZ!(Ar0Krmnh%h0cP|7l9`hID3AGV>I7TaE2c1`@@Oxf`$W?9!CY z$ARZC{0H%`=PCuj$5r^(5ENnv%LOMPT&f{(m*!aR(hL_roz6VgUo|9Ayg?E`#2*U= zSNs_KvRw}V6|WG*cMHxIAN@brJ@CTAZ*5f#xmRF3a{>;%JpQ?#fCwg)V*I-Y*f@O? z{-@ux0V#_SoH$Kfa)zxTo|{=&INaM(hy3;Uk?uZ#QHEP+@*LDV()gcP+K)Z&q@uIa z7%e_^_T846y^z3`w9wtCXHgg&X`pk~@&j|KD8PXx-DR(^`@pzQ+#>T$8ZXzOz!U|} zHU8m4>z;DCm|}FK@p6p-rYKNJPq-H15@4D=G&Jm}v*mmWn0kjMyKJz`x(5&+f9#^qx*Bq48y#u9@sciEZW^Y)_kiXP z3>Rtg9nj1Uo#|O<9|@0f(UIn0`$*VO7X?luIozMcI6bC}?{*V9q)yS+|{*;kJ8a@8#zoYjq&@heNJl$@%fXvaE zD{AgOiJ^y_J=fL`2Qmy7X;kOG05jXkcS=KZCGDYxHJBrShmZ~KuhAn{+H$e$&NPun z!^fMd99+6b07qd^^}r*Gnb!aex@)YL~qE?1f15*i-0oJ^w!9X0god^|8kfs^pb=J3el z{<_uGnG;C5<9#}FIOXd6)a4(VcD$qWC5B6AJUWMki{*xH!u6}qa=Dfnt}uLxsI#5S zGTrj(Jeo9tG5Dm;DL*%3Q!lFTj~Zd}$~Qyx!M*H^|4#EsdPqY?H|;d*YKiG`G< z?Oo2Zb28%?Z$ITXZEksV?)b{uXeAGaCadZT$hYTUwzfK5a}+GY<9QY7n#%IpsLXE> zddi)6`Sx^`S4Gp6@v3UoSeMcfAi)NJ6{&MAfjA(m_Rvxyav-IlsH z^EWjv_BOqW$R-xd2#W4(89#Z@dj*T9Ou)VrIG(~DCVK^GQ|B;=F5g~37!ACxz+S=P z96H%6n6u~SdyvF6iwDg(jU8*DJwLo7?t}QJ<5!_QfVro{^X&oT^f75^A`AIVKqg_l(`2gX$ zIJ3AKzm)(6AUUhL0vHnGH;(hgBUge=>`t=LCClujOPAht$$G9!VsR3;T8r5%I(IXN zDx7-YPD6aEb+`l&2iiedjpCFrC^mLZcW~bpJ~{mjTA#+Ja@+!l6KNfXvt-(iQw=ph zDa2ALlX>&r_DH<9eHh-`#=F~XqgrW9oS7Iu+4>h+rLw9KOL0+v>Qb%IOPYS`jwH>L z0?Ox(*y-brejoXD@h^&;kt7p=PG~%%Uk(;sE6_I@zq!}t;#iqZX!2N-=r@5M;;7I3 zMr;kUpN$a>>4m9`ailr$>&=*mK_6CTx~<1t`6UZH>JsLgGzI2CQw)hTC&R>$YB!*s z=9aY!h^*#TF(htmrXQhZp)wuelyoXpS0ArRN=L!spdE$XLQfie3w>7BODoz!S0K;- zT`lyTNF%n;+}lFOLRP4S9stc@rd8!vp%(fSLqmCVg<5E?_-4Czc?&Ih{%>lb7Z0|D zp2%b6E0D^j4bN(mrGXx+ZL&7d;a$uQ-vS1=i~LiXW$K~L@{NGBS^g9tw^?R!wB0|{ zEKmBkHp^6(HRjw2l~=$0W_k0=zs0rzHmG#()@FHV^~_KHlbYp8xy>>W-ewsX(<~bZ z%`zanS+0s#$E#x%3AHSlPBZeq6x*`R(W;9k7m5r zDp$m2rW?|!va?UbM|n-diQd6PHt4Yi_G0c$#3|`hI{P$P^j?S#|v**N@HFff= zF&2xLHiu`lbaY@3dHbB$;>F>a?JaHXF2S5xHFIVyIUj4vGZx~bxnkL39A}VVlQB%vD`tma-mz1R%&ZwC&x78FOoV-)of*Fj!uJ-1!%`$|di$%AVt~ ztPua&!E*en+RyxxTIG`5R+$KIs|<{3l?{Ye8Iav7r>fJbsBwL5!8T|B?G0>G)M>tbDSe5ki|TYl)qBPJl{%bnj|w zhUEFbsa3vguw&)%o}u#p=}7rHWVyDNislc_F8%8kpP zed_Ixl;dyoqXN9!N6OuQ3jN}r)Fv0_w#h_z+hkx&n`|Jo$$;!Oxu&ANDweD*x7*}m zPn$e(ux)b5SyM`M{LD7_2#am<7qO!zWy)qg3p4kXdt3nv^PU_!u`p*{_d*$5EPW`q zZM6I^#Xb+3ZTSDD*>!LZ_zKxM_*O#*|8x|cukEIt@eI(Mn@g9qY)*dacM)h7M+kzrXwXd^E!kV1LBrFT(yTYn^-n@GTnQ7WCf(9@$A=Xe2X+5)GXnN!!?%# zAffz7zVdeme7W|(Q^Bk5B}?WB9IVAbDO(d>6L_0=7;L(?nVVHR%*}(b?sFn|f^iQ? zc;=SM;I_VoNQqHh0;gBhc(F@%B1)~`k&dKs;4_DSCsxyjor?+xz>cV`-ELmh-o0-i z)YE|suoH_b9Kx6EpAj}lJ-BGFGlTiC4OoNm9SO5#a>Ycrck?`wlPb^%5oK&m&h3`N zOx$vaE@$*l_bV=BqMdmQ)?-Hx5MTL0Rp{t_|3DO@D) z9SXe}>cPe=*g0ng)0wSyoS6Vg{6MtgCWR%x9*l$bfJvS|dm19~d>O$&3g!I2Hv7{As>0`a0?ovya?Az9eY|?Gk6kJr5yL0fc!Jhn@OidCqmbe3cZ1eZ zfVk5uXr1KXSRA-i6SOKFTmv9#5wtD>G+dx1fF=uc10Z$`L5oFkqClSm#3^;q`ZAz# z0^Q}{cydy4TO1q@;wg>?@y-yA=K!55&;X!Q1Ue73Q)83>#115AoexNL;VxO#ER1G%_ zNadXdNagW>o#J8+uExR5c5uxOZW*94BDo9Di2|(vq`I*2=UQOUx)+d^gGT^qId~cn zhg!Bv0??&Zg_x6Ugo>=uhU7-`O`D-hqYwvAvir{>6=mB_{k=RKLP74Rpf&3GBdp$^mb~8@`5k>wNskiAWsGtaV=Fe6b>JKk z&ImOvYisLl?ZDee;Teg_+B&^q(Rm1or;4U0%58i?9!l~ac4@evKEX>K&C5vMOB`{T zqjO|P4-n}&7`ei6%sA`(>8XZ)ak{X@OzC#_$4UMJ-sk?ocejkP%r@F8S?MogEQnk$+mj5VG z{;eM0^vKCBKT@-t7l^K3Gcd!A>3%!|gjAWsj7UHC2#DmiPfD`;w9+bOl5X+Dh?zPnbV{A2mjD=>9 zS2HFmqRH|y+&Wlm-@s^kAna4cW@e`knpQGxlJr8l8rs%6aj6qjSv*>mtf|G5H7R$S zq%3W-&iuKHL0u?cQ3}u<5B7M)R<-4x@v3c%H!BkYumae zdTd=225;-)+Ay8h*2TdB-FvpK_iSCxtOI)APxaz0?|h;TvdS7 zor%Ux*Vd(WEw8Oh?OI-2m)erNwl1|Q(bmPuquRRE zlEWeUc)`)urPdx-{G{nsJp!TbIhCtxIvV zbt#UvF2&K-r8wHU6j#XBrMh@+U0M!k>(X+NYwO}RGO3>nPd9 zbv@RI)25Q;vuw>_*Ou)H?BdGg(B<33Mf>YT{K#_AJiEB=e4k~_1>IpBSHbn-ztAqO zmZL4}%NX*&jeNkV}_G-fzOzIS4wgvAjA6I?MvB5!{=Q z43`u2nr89p__xD70pl)*?PIFD>HSEJ_PG?@)1s+~j zj}0t4;mbW|?4I-24Gwb>o&w)+7>v{;Re2Wsgj?29j{dflR z6OI4g{_d}X=v<-ng(H;aX7?t%9Q{P**O?v(q_<}sgXph(qtwK){{-wYLwd$Ce~*{$ zGBLkqd9459*`X8SAhqM}SLnp7c<(zoYY-L0tGQv0C{}q{)FHqc%N&At9LOudo_}CoJ}_eQu1^#{ zk7uE0#Cva-uyL(HGoBIN0tsOh9q!f|k8e*QPGz2m_l6|{i#P1P1&v4P*3ha4Aa!7S zy1y@SFSI8E%bw9BiJz;1PGRpN_t)|F3iqNzsujem)Bv--6>dhJC4Fkm^ z8XK8UfctM;fzJb{HBDc3T08kf-pc5K8Ruj%GL!5akc@(W0kkUk%4~%g)_FUpx(Ci< z{z+?-l~KYD`rJfA2L7DfCVyx-??`7J&B-LmG$)fFwm?2XbbRv?_vDn6Y-vA5tC z#V#~rXA^llkftouC$UYl)yTvi!XDkwhrEyS$DN>bv{`3$%V{r#GXv9A9$P%B~%*NRC&Sk7TKG!1h!K{p~5V@U*A+jrJ62(;vJ3z?FsFf?I@j*u>4l94{qTZsG7upKrh9 z;)^z;#$D527Vwm;6LJSFL6#h?#iUQJ@2?8j-M|ei5ZZy+`NDcOdv>YpFT*2D(hwAA zL58`^cq)e-HNs;%VP`3F1rg|e{X9DtAdfV5pTG{m?yq;JHFY0-zMLtQI+z!0T{Qv?upzZzoi?Hg8D=JW~q%*%>Cwv^zsjzA5wj`m>+1e z-Cf|?YTI#P$FbqN#EZmm7Uc?P&y z#2DqF&E8y~&Ax7Re!Vpf%~p3*Fs2vIe=I~2U5Pr@ig&G=L#tL}xqeTOkp!g-*yE9T zjN%O-FWqTM#r0QoZw}t%j7#(MM77?yaX5ocB2T=s2pK8FEqBn~U%uZo|JU_P)X;L+ zV+k|6*ah*}dcXTC``tqws8DtV%+pGo?D}T41@?nK@&1bfEVvvldaAgc!xA8s$lGFQ z3&5GUp;LsT5n6!U8qbwBu7w7z`|$bysQVW9sH$u4Gh~4HVo*`>J?Pk?D2A5>qcW3B zk_jXbFK_0p z^<7KlC`hR>KuR40Nd0mhRH@S}m7PJQe$P^A7N~w7vD6nW_1BiV!%{zu)KJKgTuYk(r%Rg6yGA7W4fZ_tJ0Hm?@6+o)Ne*u~-)b9W) z7w9odeacc_v{YUrqki`Xq<)VAq<+gSb&92a)>3ZJ^rHjis)$)UR9W-In^Hr4B@QR3#q( zNF{$7kV#8REw$98mU@+?uC~;F0n#)YfXuGndp#hHgD+d$j{#{MJO@Zu_+JAwQBvzo zK%WulFMxEt{sTbc1h@BI?jDST0G%wjBP{L&i#x^Q5`abvU#-QRYx!mYg4!r~b1n7r zmbw(sNkY9E&rB1Wdvn_Rw zrQQKZbJ%J7xG{MqpeYjCjes=Vn*gcgZvj%tJ(jx3QlGcfy)cubk{1C|DVGAO6v-Wc zRLVL_{ko;zZK*o|sgzxSG+uaPoTlYaK$@0^02(QhM*z~a90_Qw;7$RgX<2P?Gc9hO z#VrP;X?X>pgVDA00^ zSCK;=<%TfXr&HwIht#EP*X5IYFo={3Nsk^Da@vnUjfv}ajTd@WUqda#>EL7VUnE=% z!*%)OA0eD04hcJlKz{Ka$){Xb6TrGTzT{&TnBFyD5AcGz7_EBAa0 zPRW$7pYCls;kF1mG%yHnv~Rfr%>hgWm(1m1|a5 z`vk(;_^qGc;Q3l3f{qSyYWSy;Fch! zWKn3Op}+RuKiTRnSifMf9Z+#tFB(yL{S3B-8WwxboVF@Xr6q_oGz<#Gj3%B5Bj0a*c*a`{y7 z8A_-xV;)hq$4A(gSI6tBrdHxK|70AE5)bfCPBX{&W806ke0p*}PWk7qpfQti+zYnh zfH-+V<@~s7nSqT!waMvIlhxCG=cW7F#Qtvt!V!!$m31}ADb-bRwxZcOu|3Vkv1QH1 zO>MTyO`JM?O3kz>b-Im*O{m}4p%rbXyBDagY+402{8YxJiS=`}m_0_V7hUG#FHcoZ zt4*Y;Kclq9?6 z-$(TS!rG!2^);<6E@aIBcO(7_Sz8=|)$WmI#hVRwA#00D@SKy)=WA3M4x6NQ@T|<{ z^K}o%$42yP;Q2{5UmkhSgJ)|tUmkfMg6H7FC>@m#{^dLJ$Quuycs5^_JXUEJ8Xn4{ z%V*8NMzbx4FTa(-O*wqIRtoG0+?vCeD~}cDT{(QY^4PF_H-|63wM7W|*zfY~hhj6d zcMe}}xa1q!4?cF64$k3=f0C^&q%Qe)SX;o@qTZTYY(vRP52#IVHRcvuQMfr@*r4VX z4X(LGB0WBqzB{%J=wSg8HEJZ;|T;;TOghZ-5MAi(6t*^ae3^%S(i5 zd$ARvM7l0U?n-7B^d?IGMl%b_;_o}=mxJucb=x5~b76SyTz7Uob7iQ|sViO_V8md+4W>`4i-2i?SUGHjm4gJb0agzDLaY_? zJ+dYSqYK6=Vu1M4zg@K?bKz&_Uf;*}o`7zdyHMHZ_X?x?y?yGj;`&SlO)aQGfi;v8 zhH6$}*NuCn`xc3;OxInA#J+uUO4s^y{Z*XXx2LgwPZeE%=2SXk%=qWROdQHeChZ;` znSM*`Jy5aik?1~p8&u-_`V7?5$d+AKK^E6bt_NBc(reR?a;*i+E6G^9S(U-^N;0+# z0!WeNl@iLwi!QH-P+CwNhFVm#fi%v#lg%!-Ad>^Vs@Fk~$nlI%tbg}n{d-fc6;Lz3 zQFBzvL@7LHs<=kmM@r1~M-AgcJjMI=bdl!?3&B`^^G7HIAU;>(r+2k{K=0;`-s3fH zJEerW@f}&ap?f%Z-vDpX=0tbI{qjOFf@F9SL4V}v$9h|Pr0d&AQHr`7!80XWOiIcU z+j=0qCAKV+h_xUxG2`@phk23pwR_Bqtgqc-UXTIun?!K#w$Qh7p=~P!U?KQ;F19sA zGJm1G+=bw^vO@00oy%|*m?fLJ*($J@V<^Z`2q9}NSmotohsj(%^lp}e*>L*9^KN3% z6QfwMb6J=*Iu?i6eCTp;VkXXz!g}1iM5eq~7T}nXBiCI8fwoG^Z-24LD-ATBV+mRw z?t10&9P>9}Gz*b0r5ZQFuxKm9)5PfY-p5O|)M06v$Q56tGO}cwrO`E@c5JvRr+vw< z9P_YS=NiktT(b>f@)WbiAykAFK7KM)tFSuAI9ZYLG}Eo7a0p`a@0BM4R(lx3?4zSOaZw-QQGjel1K@d274 ziKJqF-r5*dcMEzNtJ9NU56B|XwE_fG7>pg{LtUND%~QkCTXI+3Uqa%{TlKKCxT_^P zSMBPB_e+mV|03Jmg8rlgr#GWuq#7SjcXn=tO0aTdGrD~Z{AH)5Rdcsm9hI$B$HP~_ z#)(N7ngoJL~uace%s zvmMc|DgQ_a2EOEp!kQXo6XO8Qe_i3cQ)td`RTd1RxQ2uc}x3KXxY?ToFHch8z-Gu~OUq_y2*UZl0{ zF)vcaA2lyh#(!X5w2XV&`^+Kmfnv?F6|B<0W?8c^KKp6S!X3+Qxk4vea*G-&=CS(l zF?-f5RHF9@SRgV~jver>)+~g?+QJqnjYFg{KN2~d@day^7DSP2&C-x%&BE~z$V~xj z7Wu&4TC?yrZr``DipX!x;$!rzSy(;T!H`njsVe8t}Q@;wzyfa7!P3;`<1LN3YT%G;6LnO zX5TC(KL)5$aL?jdF3=zGtQP1kJeB$ZAf<9ZsninzDRmMcrE;M_spnW~qosZn1C|&P zSS61Fq~T5kq~Ts@sm+$!W~nz?>P?pVElYh3P?>!1NkwQ|1sV$|E)WM)8f%vUQVnR- zGFhnH&s8qa_bm0tmimaL{?1b0wAA-46{}uGgC+~z4M=qvg%DU6cmI2aI)&b}^(K!Q1OW9gLS{7~tq-EiM zEbak|d(z^5323xPc@2<;_D4X+3vL!5u0gnNDuBL?WM&&yR3yf9q}W1;P-Db06Qzi< zU6)U;&q${ImXI_4ju5$B`IM!;hFWMCpkwe~BwP%`b@}8UA)I0)1Np^!B%g9!O$g_c zubPAoD0U7A{a0w8clO#kc+0?^qJ{x={WXYb5yKSU@wOkUIZQI2ISkJ7j5jV?&^mg4 z(@`@z9B#>j2}V;}b7T9Z&HQpEN>PY8E$Bu!HP2acQH(P!&H(%uh1fd{y3skO)-u=7 z?U^|YbLfrmm7ekEFYUQGOwWyfzSuL$a5E(u8h)v7J&D=LGlzM6%E908e2oB&PIv+) zDyX*Mi@CK3|GTRGwV&r}JTP>^69|iC#yh3s;=P`~-1Ai>es+H%?ep(`?^(~+dB)dX zlpF{P6|FC<&v&g^=J{G+d-Z?spw`YvKsc*Gl6{cmiPwe~9Iju5{Mb7kR#r zbmCN|-*f_%Bs64=P8T$6xm}SCd4k3ZOi9n=;hBH6)VYQVj`Jtui#-2Za~OUd-FF+F z|GFo+m<0kZg8zT7In2pMGV8mKVh)osa{e9WFmKmvK;dTjrn}ilJ^--dxQk0&6c~S+ z9tgCTIze-oM~yG?6f%d|8j#E|-V9*=_vSF~89B_QL7julb zXbuBk#scHtX52ENY(Kj0BN;n&{YK=Cfj9>o~*kkdKah zu;}@Op6#G%`4O!R;%DK$plB-nt5o`lZHyBx+@(0581LvQ;w(};m41?wg+j%IWD1v& zM9<&Awv+9ZUPZz-QTt&`H`lS%(Vo9TOap0`oe(zt4H`S3E8a(e7a9~ z9VL0~Bi2zh=~t_}&mUUdeaZ0Z?#0nWJ&vHc9#O+B&ztdEohg5{I=#KNyRoObyL>%f zx8nB)wcS(i1pEfzTk-o+ZD#88fY$-ul1je}@OpsTQn)LvyZlH1i0jsJ@twJ58p9_3s?+j z6aKMQw=A~QS#c`1ShuH_aX0c)MgOq+Y#~FB-0RkmPoGe!iX)$jqp88Ic&o|iWmV&P zs?+BWuTEbQtxhiv1!QysV9FOKz zzVU#RkH$HQ>$bRW0b-5ex}yMS>!VOH-nI1^VOTCVzpM^C9)&ofJQV*$4!J1Xb@}AV z$ix{@JisY#*O96#o1uCV6=FT4vMJN$B%DvSa)z*fczDwx&hYw!o#EpTa)yTvaQ5#( z{qXV4wB)p)j9u2jtF|0_>YlftpLzVDuX}BwJ7>bU56&&Huz7PPpKVC(?fG(3PIv-y z3p&%H^8i?Xyzq#hdA`O&BAuCO@zuIAiz0IiYzqd5UyXad+&L5B353No^?C;PfAQ!a zdA{5^6X6NWW5_H@h;=;Ovyav;^L(*X(CJJ|{+_{dWxR9W;=zCD}eHk4237y6M<|Em^~4NI2bZk_-&W;w@)&r z_l&1D+eR`Fy#a;ZWZHfal?C zzC7|?2hWadzASmH_4Y#bbtJ1WIQt!Wn(p}URClWQtg}DMjRWW)H=rr3fz?(Ierwae!C{Swj^*Tk z8FvClIuAwpPj$Brt?6#vk{<9-9HJ7Foc4iTf=6`VYhn`vUUN=Q;`ONR@kd~m4lx4a?gbIkT^~EGG!p50 z4&Bd0>9AO&>v2Lj6cPP$#uK{Xb?EVr>|Pc-vFq{38aC6T9`4vVa@oF_@T88NlOt>D z5r!M_&@347tUM&vQt7p^TN$)kH7C;>6m4HU+nstEZ?Zq^cwF_d6SHuj!IW(KonV7v z-9N`K6`OpODmF5bxgV&4ihTjZk4LeJ^aWHr@%}5c<7B$>JRSZTWz2_5^PBZi=GyD+ zPl6jsT)JV&1&LK3I*8#UZ1^Z+`C%1Ze_wh~0{0BBOQ!G8%+UMP_8;SWvW+=g;4k5x z_=yAz`sjd<%1l#9FHW`+(TP?6>;>-9W3%Nf6gg^Ig$!|GGQAbbm1UA8A0ltWG~4Fn zJ^FI<9z0byJ|*F=X7){vvYJ<<&vq)ho{g+Yq1+_XEwPbFSt? zlE@6(x4XWxE`nnPac(Liru2iz>SfTXW7AbAWiho>&2LWrShhY;$7oaNFim<9P10L> zpMff=#wXIrPL%1@bu=p9usls2GM9x)-;JzZ1vN4&CQJMTba^}X(Avj+x@=?IWa@`Z z-i-^#80ZdTrja4R$QEcv_1%Jk*S z%836sKDtO755zR=SE&GIpQ62+OE;L(x@>tOvwT2b8Tq$9ZOo<(G>$BZJo7V;DXn;L z_oV&Y91O>z-n$8=v`n!~%|Wn@?W|jIjcUW1DUs<~h13aDA~|;5zo#y4^D2!#da|5g zils7Iok-N9HsW!CUTu^k=npx9fS{mgKoDo!qH=#av}Uu&&PMY1Tco|^EL@%2^T7Is z1nst+UgyQb-wDs0rK@w9xA&mqoOu7`#HfGRLIf4uq+Y%^O48DSiS#2oMr0SIf%tGQ zwW;^IicEVfluR${tV67hOuYYkMf&Z;`>*x(1fn9RP#zCSCQhX|qi~Jq5sLRn^~^~> z_I}dX(AiXsT-b!9GK~+mez5=Kwv~x{PY|WF@ex_c^j3%)*|B|Pu-qJzyPJW2B?eWA z&DD*MR%GT}<&{3#CepVm@H+e2rFYP#y*)P`J!fI zcGQf`Rt)ii>T|0Vg!rAw_|+1UFq=hkqFCi<=`vCL5~9jsYA zazuCZ?55cA2)}?V7S~uE%5FfGsF=i@F%;B|SF8#mtJgwlp3BS6sK~U0Ly1-Yl5SK^ zzu*i6lrZP8Cez#0Lwz{J{toiLo`zk(m+ehdH$H}rO|n$GY^J}X{fZ$>A!OvpnpSiz z(BXMNYAfwsT#w+;eTfyh**qtpDWaZR(6;L4hQ4cMdNDf&qT|@PLK~{MLho*lcnKrAn4Yo^bvEXzBg}fz zehTWK)8(mC$(?hePKHsC-4KLy+;u!^bgAx(*+zKP{jE~nD~}(a+YH?6RifVT*BuUZ zf+&U08-Jus@4&;@5t(VDJW7_=YU{P0o1=4vZl~qogyp_IhUpj|b5NbaSeys*aZG+L zeq~Qa1AxQ@iJ7x-hVZ%gkb3-w<&?KG1)7g%oj|R4)(UhPo;3oolBpKxT0GV74S-UD z`v#s>0&zg4&=w250H{)^r=xnP5GV<#OrSFXapoiJEVWebAy?{ZOMM5BhWigdsxuFb zIz#;K14wl~3{a`yjsY}LAU3RuqgjdK;ue>(xO$75X>r|vG+b`x&~R@8qz2e`0Mc-O z1W3cUACQLeh{Zi^alf*--&owAE$(j?cQ9sLRo>x%RNgUw2J07D>KIF%2&h=7mjcpw zUJj^CaNIDW@yxpumCCbEmHM2e!oI;!Kd{td)Q{?yr<S{}U&Qf2t)IVA(H-}V+E<*sRWNr@8 zFFM~+=UD0jOZ|$a{udyPtM6Fqla~4{AeH=@rS6TS(s1_&q;Yi=APsl2rB(t`$!A*X z)t1_Asb8_w^_KcGOMTi>hawYbxQ77JaASZp+=Qj30IAMrTk0*AdOINX`vXgT3eaeY z$=_SPKUuzAmXD{eDqj_#lf(zlQdOwkLf-_Wntm6M>T*9I)$|=peIJnO5=QN()KWm| zw+xWRU!A31W~nOxso!o(eb7=L1*G9VYpG$(d8_1o0IB4I0cp7BSn36qdWofe%~HQ% zsXwyRotD}QNVVD*^|DGn4v@wgD{@Q zfK=XLfJ{tUYMG_hS?V2@dKVy#t9vc=MN9p)rS7oQaYNj2PX(lYs{m=Z4VHS5rM6q@ zBbNHOrE;T+`hD9{|8A*8m|j-uG(aawuA6J2D=l;lpn9Qx3DB7WtpjwTK(_&^73kZ5 zvuNPG{cJO*YS81LS~T-KSfRjWKy>4^2t2}M3qaK z+YD(I_Zrh>-CIsW3RGz$Rj=0tRL~^3;v7$oT{EOzbM;FhZ)52qN zkBvf&_Sy3n0-}P)MlWf;d~vj`d2uVY`yhyx%S)qei`r+m&tJ4Kx@fM;(7q_zKCe02 z(mc04dfEJzmguGP7q!f8Zx$>>K@dueph!WMkey!kEI1+`GpueoLZMTo=Z=-fqZj58Za z?oq=trhc5ZJwB@jX4aw*iwoVbFTHZLLO4`-Jo2JA;o%L*a?CJ`tz!IE+ky?Tg4qQ6 zihus%%egi}VTZOWekBtk@ z%digJZu`vv}K7+>|Uu!}q zPcU@JOQCB`c+>_9J;(mM^HCCCnU^#1!dd0#Qz$RUqtIDcWmTql;CA(nc&Z&VIj>B(7bqeoYuhE>3jN za_=tC)ohNN=kQ3@0D(E^Kk`G%H)>YR` zO;*}-j&ZQE1}A-i$rDT$hesQeB>kMYtA4>PW!2U3>E(&qs$`{ig7O|oo=`QlqOz(i zm5fUtBe36XQh9k za3pojr-K7jfv-8&+zT9xxUc8^f_er+-)3WdpZT@Oti55*^8Ea??5N!R<5o14d zDf2|M6N$8}QkPVxccs#AVpks)VXg;$8)KjAmAB$WEbs8kS^pk+zdN>BesP1K{5~L8 zu8w=WJJMZDUv~nl(0V|L?jha9SX7zVJtWaxi`RW)IBFDUqcJ3`S)SOj3zt2&;-z$R zymM<`B{b1FLm{-I2qRn7qG}X5FG@&WH|2GbW3N+jxc`TEWKNVL^|(< za4LAM{Ni*r{HC4m!O#w?>9KfssOyy#Et&FgqWh==sflj6F1diH34T#jL84TyIzG36ms4`R zM0V_x=sp|CF$~FZNT$4y*E9THaic8*WX7W1AvfDrbiEPjYCzSNLXxgTL@@PmARG)8 zBpdM@RVE?P+&S|W_v_A+_67{rf=qk z?xB(w;ze&25OH-tL=ss62>{#M>;Cqy-d@QHXM@A6Ec#YBP2Lb=1FcY=!X;@O${(O3YLf~=DK6l5`&32|6y4%Zbq_i?mi(A(E}uuo0#=q~IU4M&6X zf2pBg1^0eOiGn=Jaad!}CN$CCQ%+V{rPiL6xKLJFd0i_fciG;Dou}}mu3_hQc%CHC zn|Pie(EE6PS|E-gmC7^il*;S1mAcYWud&p%minZn(%?@0zHX@;p{eA7s2G%b03el2 zs}rThEw$ECuLh*w@l8Pb9S;FgACCc2dCvk;d8Mdxlv)NzsnY=|b+M&hVX4XVlG ztfjtgsbQ1`mAnril{_4fO0Ke0-XpBk^DT8bpifCWUjyh^fxZgp7=c*xj1cHMfVgcW z?66Vdv~<{c6wqM;u{@`+hMgyn1lmb#+ z$^dZ$9(HN~sV-a)Re5s(sV;36x7^}7E$#-3`|!=V3sq z)suiYi-XUBW3SqEB>;4(L7`&2?F?&15V0Ps2cMjcp$d-e84s1Q3fs^3wrEs_n zZu;5v(<^5rrd3tgd*Mo>m-_C7J3TrEv%~hXw-cjt&HZp@TDH2rqITN!`pW5NPfPNC zIG&}2o8S5+Vsun4jJs_1Vod3_W40C((!kZv!`yCb+oCzM=U`@c{=%mDjhMY&9G#7c z>$bKft?is!rxuvqogKxgR^XAj?TV@3Xliz6dF!ej-%K)h#Kr%E8#-jpGC^+HS;|ZQY z@L3e%Fp6&Y(bs>^n^18FkK_qXN(~04$R0oT_=h!1JzsMv2#!2KU(B-J6y{U!jr^78 z>qqngN1i=Dz)7Zo3ry_&UgYY?ba&HKdxO`TF1_c_^t+yh9~wF2+4K9%IF>E46Ia#m zeDi-i$y3ot(2-|%lZYJC6|s&J_tx0+&_ba87k9CdL!MyFOGOc)=5%`x{^S4ge03RL z;yM&6v5XZ=lh_0J5tTmnhz0}!t$NqQRX?$i4JS=31myve$m;m0-S$zjy{1zcXk|%9zI?Mw ztYlgY5BccGhj09Zo@AtH`4MMF^duw9fMD9AI=y+)fF*lxW7Kr?4BRnTpxz#y&=Kdr z750-fqLh=3CJGS)&$ym!#91`$*{~0#5PRib&xR@LI<6A^|8vF>HDkVc>E4>{d)}aL z{MECkcun)}8g%AEx_`qNN2jPH)!l!_(L!&n!!7n${0LOYWKo*$jH8ytdvKn>gzVbk zhbUeDsoJ3npU&E$!IWtJ6sjFqYppbVg=z=p-me)RH&#E{wS%VRN30!En42n2!N47J zr|q%fpT((Xm?g#GKmWk_KT-i~!VM&>&0)Hpereh1bJe*w(6Hu+vgSA!7Th?WN4&^p z1ymg8CMR9swC~&7gS}aJTk$OK;hD*k(^_y`8n(;Tp=K$WwZW@T&O|_7eZoB8x<2ZY zVa3j{roEkE^?NzP#si))wDmtZSfG~7Shv0GJiF(0%R}i`u*Bka{dQNkFc;H3e&nH- zd%l8$1=8J)oObPqVNI=$-9Mgy!VxDOOUxiKf7I%t1qYD?I(vc$)Gfp)b5pAe@k}+d z!qw96J_t@!n>a?Q8TLVrmOjWL4C=2I&GPp_crjnV73hN;?nbI%mOhBjzK3Xv+L6Oo z(&M+^A>VTt_q+|hN7$c+y9@t?YNJ*p(lV1!ebq)cf#-YKd_Id3hQm((Q{Z_in=jAG z+TX!5gcBWbHrzb&P6W@yY`!dcEN$n2XKprM9(kSMxjvgOOCHt#9(W$f=F1~*D|r5t z&6h{s-k3=|inEDueSPm~;7MikWy$0B&IQk<*?f8QTMM3Bv-z^*@p~Tv&$HQldE~tV zo_}WZ<&k%oJD%qU!$}|5XS+ijSw`pZ#dB61F}`#v`oUKNzV;lx+?7raa(i<4a>Hdk z`D6}X?n-AD_@2(;L%4GmF9ylF*6g|fl$B0hPxcDyUck@bWTDUHTTy0JaDEP7u6`VJ zH{|f;elO)+oWu7?9+PO@{t`$=gp{urXHp@8)_C2EGdT}UAZTcN7)7GSSb)ODK zXOcW4og7pqGgT3DOoeteGSkC8oPS{<{fv6=>d{|)M%F%TUZpBeWjGCtvC#|F>1S%v z8*0!MYA~IcBU$_MteBPfO>C-gsCIf_F`mh8@z%}s#p?19S=z0_lp2?IC*v2JWmyM6 zRaPzTl}btMB@{1RJ&`rsMQRs$kICL$y8wZiMYUvFbzGO;x1(FM-i~8pp$P+@6l$+E z5t3NXL76C@;AA^PCrd>pu}@zS!zfX)Z+(bEAyn*uB?oD|x9=y{Hmcq`iqo6ik1kFs zYoc`XlIE_S_SyQH!un(DCK1B;N_2-5&jrew*i!Fhb!;W*?z`)Gb?jPTyF=PloX4T3 zT+)dBb{pLEjC58&Q8!ym0-Q|C2dI$5sD~4oGkcAmMLpdT3rv|IU`?cZMm>U;)ggYY zc;m_-b-9m^?qVdSe8l>@@ft~P!FqRMl#!AsdN|P?j%90&59OX!j74A=dmDtaGn7Z(VaB*AxVl zZEg*(d{><6t>WjD-3L8gbIUG@ zkV(2y2_(|h0}Uj@NwSGTnwh*()X{TQfwX(d3k#7E%ua!{!^a|ElPXy$$8>G=(luY| zF`Cr3DP%}JTXF1|gp@O@@i{5?s;8kzIWN&dZlYaR>y_xP?=wQos&p}6iF}iWZUV}J zy1!O4ur80|)GWWJ0L>62@|8Pfw#Azu3Uc?cWmrbD<9cdP;u<){4OU!6qPNDK{V`L$ zFWx?yH!JSu>s|V2FLr$2^D%ur`>6iN^F9an=M8|?p8~^5{D)-=7?+B|4%_al1S-RG zg+LtTFBj-sJe7I@peqE|jOXP7Ex>cBKulEThLJlh2N4W85NF|;o?(Y~HL5($9nKWo&j4w-n*hxb+#7&2c6R{M*xd<8V>eXfrp$0a z4dUY{K&ru~0qIwk1JbzX{eCL13y{jY0g%f34j`5C13;Qa4+7FS-3UnK{Tz_$_adN1 z3HLXEG~6A4^xOUdNOKNv1k~907a+}Rw5`xsI|h(ybvz)|>J&h#)oFlKd)_8^zJyk9 zp*et73T~0bT>(gQJMDusG}?oyE?)<9p7@{*hC<&5q&a&%AkDEq2c%lP07$j^Eg;ou zyXE6%bJg!d3xx-|k`D!>Iv)p!nie~!0#eBdKq{G=(p54oFB(L@7C@Q`mjTjLSP7_E zsJshNQ{l^i8U^=tKurRD8<3{L_W|jb(;7ol;eJ3GFT52|Q{h!Ws@3lRsaEd*Qmy_D zNWU^P$o-|N%{F?E9aiacOvA7CX`E;Pd58X-WF~*o(si?#xuDn+jaTmjt3EP z86SI;M<~WV_l zWOU6JJ+NLOK3%NvIQ}IEQi?)cbl|A{fV%3xdJ9WO(JNfo;X;nz3Jon6e6cW7;?|$s z`*&|MDGL^z@C2;TSlYd|$Se<&?lmGJGdi14S4X+VD zyWcW=+LH0_c)o5jzBt((+@37D+3m?q_Y8X6^YvZhOZE4s*M5{^)9c8i-p0W`u7*9v zm+%C>Yl!$_Q@~UXrq^@Em+%DADi@3&17VfEbz6_;Yu}K16P`d=2Z%5CyPn(c4IF~x#>Uacm+%C>>%c%*mp=G5 z`m3(5vBsD11j3R~B)zE3kdybj!}C>ce5oe>g@l77tV8GpE@)NB-2imtL8B7Va@|48o(?8 z=ClCjdSF<~dcN)ghUw{HIKXWQgvCKEH>7zyycz_B-G?~@Z}9+TEZ$g3JYTiI#4M)o zjq^u>uaM0vb)h3quw1b9E3!7P<)wG8apN6}DaIFhG%aoihDg;gzZL8QU|{NbU-2R^ ztSLRrUnoRe)JXmSm^d&V&oERwGlBImCj-+I!0?dqQ~=WmOoPQNp4GUZRRhA4Vfky4 zqk;2cY{uv6(Gcl(Vp0im=*XkxV)gk`~NgxFkQNwWR=IQA^W;*-P_E z0|_IpLZp^U3z8Ntnp?;hPA@1#n%`7VjY5$G4cptA3kjSzdtqKuYulxT1Wuk+9-mdx zm;L*c@@Z41*49on_U|Z2#y-Bat@+Zt!L=`HFBDu;b8Gv&e4bct^5tNH5Ljg8HV^Jh8Pij_}2W1V+N zzt5i-JGNw!X9KMFoF0xQA;wk(F5eD;f9E}?7onredrp6g&Ild5|AnmXzJeC(Hnv)D zWY4!lfZZvKMFK9L6%{)*TXOi~IaX9`eBa37%e59d5qy8h;meiBLF@sDU%#W364Kxk zx`RRU+DEh&(tA#eamVRU+6Xo9c2b<=fO|{-gd0k?;Pq9#w{$bWt$J^155Si|UB8Wy zNdx6L*798g<#Yu0$TeM$FKsK`eAPm3(vJ%tZU9ZT`@Z`WW?7WL72ex4+gmTP5c-Ywwkm810T+HH5 zwm6>Sz|tOe;($0Y5q7EoX}CPzsI1 zA!GABJ$lTWZKULVAKw2uZwxbrC^+)S>;tBw{bLyaSV-p|Spm}p4}EJ?q|86=ZmxkD zq$tD+n(o(CT~j@MmMK!k(=yM}#~gvqQSwRm(gQF2wm>G0vL?eIL#oA4c;K{%X$@1EGGF3T!+Vtc!-7P7FNq0e-1HSIdWzX4Io0fv z)Nk|dN%eL(aad(~H}l*3y~F90apSz+&0yJk@GfGKlMZzGdN(JAlxCj=_8y#{#g}jI z0jC&7xjEPf%y(nzpF#T!_+m_DI2PMNy&&2%JYe|vQ>Yj8vf-gTx_rGLX683@_&&+K z5zQMPu{XjPnSuYa@GrZkK8sr=qo_k=&(yD^wS{?a*L|R8>WWR|H_a%$F6%cb<*!hOVG5Q!{SWYz6(0++`?MDD`ST0=02|R80 z6=JAtCX1ZVegmET#(x1lk4|S0=GL^;uCD($TkV|nKNfYm!CyG;UWIUE@HmC2B>#b# zI2I7%+J_+%KSp_S*9aL2tPpN?{{Fe#{=n|m2!BxW0?vDJM;vZ{KwAGme?VJp4xi|L z^TU1q>iJ@)kWP5=oK!)Y+p=rx)`($pTTTmDN=9*P6Z@W#*Vf-{ZNC#f{Q|GGtuRu^ zGr(zUZeP-7PadUYw40|G7K!UYVo0QI%Y5`V0_~y`x=`zMj^PnT!-x3! zgpPq>OR;Fq#UHWNVTxfKeAYQ^Z8#RghW_-}+D!TIL^uA^A&iFC16+@B?+JaOblCh-#@6YfZH|BQ6UNX#432xFof><(mJri>WHasL_E!-{K%GPhI;XRig*YQOK z*O9Fq7amh;iZAmB#mUB&gD+4f8Cyn3)VSWDMTcw6i|T;k{5)sH>1_Pw$>?8g|2uY` zv3z72I1KNpYg%=Ozy@HK;kSv_kUs^q9rX5*MlI?o^q-5=Xap!zVd@lAe^zbM4-V*B!R-3^FPM4UKR z*6unxfBnY^2YKC={&sfWc>5bWJYT`i4uiK!JM3K01v@gtxLp$M{tz>r4{@$9^xlkf zF^w+5N?s7a%$<#M)SCPgBqU!J;6Z0++(d(6JPmSI;b}TM=oSS#J46IKJHROO91D#Z z=i{a30`s3%keE4BmG zFc>Am@cE|qfD%)MG2l5pn=fk*IZOTd;JGB5FONK4@%80wzASkhY5fR1&t&uEk@sit z?8@fLBkvHT>p1+=_4U1Hf``|J1^BY$anN<8;ZaT#e?H?Z;@RF_(+@uOV^;TrkDqx% z4qxtS4{P{a`oYIq<$rSca#xv72OqCU^Sd}!kNnf7q%qs&p2Ge~p4ZX3>Mdm{V}rd#1Hj&WuiHjGYN|3cNkux5OR*D$()5-t31IBY#EK+)XCT z?nGTSGdpwNX&`LFKd5Vk*AN10Jj^O!VB6;!s7>7rEk-LZG@#?7qgy4|B^paaQ{Y!bWT?*Se?OO~Hx>1#{E<6haZ7y4g4K=*D) z|E;3y&yh8UBJ$_fwtl`f7j(>$R%N96^2jakH zs{U0GN&c~8=aHA@-0BCL`0GN5JVuhwr|1D zxK}cZL)$k3qAdEdyF~R^rQW9#y-zb%Zv#(e<^m^E{;#~>ajIW29-N&i=LO*unU_DX zGo5FSXUg-(T&K$nP?Oe#PvM;z!7Tzd2lA{1 z<}RMVzeRpE3kGr~JG|BS$FaY7rUW`3&kBK9oRR`H;#n@x#dwwp)Q;z5fjaO!L!dQy zvdb2BzKo}Kz;6Mh)Nfhpk1XyXK&RqA>^x?1&jC^?F9Vt+)Hm?tR8!d5fv0NvH$W2v z$HS(_3v@Feb|b^ioq$FQ#I2i3eacdQWvOpj>fbDN0E(LWJra=mjR87I zKpGpD0n*sG5fD32uA2fthb;nR8$ah4}-3p@gE(WGOy8n>PJgD6yo5tL_wq|Q`McnXKE-W zcer{h2pj|)`||5E_k6he&nE{R8fKL(ZixBidvNawyQSVfmp}jGv8Oy=ZdnnYz`hCA zbDmwmAE!1v>G@(ArW2mPIsjwF3+s&gM<+aARpQ58t?=&$*-Lz}Ofsfw7u|TU=j%M< zOLzid?Jd5JFutn4dBp_J*8<~9cmm(W{;&64&z^btPS4j$<4bq~VTo=bH>@?o9{Gmn z>qg^C_4j`lJ5*j+p`kY{@qB&L_!6E#SWHRvMV2?Odm!TZ`l<0HJOV#%FgkVM@5)C& z@vOmvXGXI%q9f1l&Youd;9X#M;KD!roPN~3Wq!#sAYh9wb+NU>f2sTrfAxIrZE8^R z$V$#0T~5dLy(n~$2|0Dc+lWe6pA(E^^6dHklmkVwD=TO-a)FUdp557uu&yo&akxcy z@jtuPcpCBu2RicP+n++(PYsWzY2Pbdj0f+8@%`UmAH)5Ehm9Qa6jvtEeoC+t32^vdVZ_by)@O*{k&(B<^qG z`fnRUlbC5!Q>iK(i_S)I@&vSslP5^~=eLbP^N36K-1c$ugt+-yE}6Q9?PXJHrzPqt z5@waLazNw_2pUXG5Rt;H`!FMg&B)FsSUubUa9<)+DrVXbG`R3MG)&Cki|H$UcGj}x{ zZBvZx6I>yAtRTz4Gb5WXkGxj!EX(H0n!BQYH-YCT*?f8AJrAC(*?f8AeF&bz*kZ!5 z=E!IB!v-T}c*sYWZw`syJFXvmY--Efo|xpz;Dq0rq-=_z5UagU}rM1qLg$IiVXos9zQ9qBv|0BE!gn;3^6 z{Fd++(G~|j#kF9TdAz3(*Vmg*i0h(eXKW?vwQ8Q<{iL_9Nk7*@2B&#m!Y?NqQz;_| z0gQ|SiQi}(zw)ge56BvQIMVe5Pzbj^nQpm%W-?uKe*;1~7yosMOhs?SsHannTPSKh z_^OLuO!PjSSRZx8Ktat6%VG^RX`ZYotI+i@S2td2(wi8t_0cieiF8pGm$z@lFITVY z81?7!drDG>%Xw}NQE9M4kON3XaZK{XhPiZDDy%j_!W}~HeXL{SVTsbWB5UShHp}HR zv$6LMVR-2c!pR9N$pV<^l6-=REM^5vV5N})fKub05>8sx;WaU97B4qrqO63RWcSD& z_p{qP75`x|F`OdM=keqKD=h1Gl>(*lEEni{Jj(?7Hl7KAzK5qyVKHLZSq(c6;(4k- zoAA_0s;2Nne16fA@+DwF1aY%b@}A7p98rk4RTI`?#Ds*;yu!xvR!Qm=LWctvGAejEb|S*PK(4bf%qMJF9&9w6p4GB&w&? zpC#}0xZtMZEOQ#nv;_EZ#hB~kcxT$|1-uTdty!)OYinM-sO3`30%3PW^Fm$#))f8x zlIFI{-Kif)5*c2Y(f{aN5R;4Uzs`PPxk8xvVTlmO)RVa&8D@p$&0ttUBwH&_?(7h= zEtB_ObLP$1^Vy--fBnIA-n;?pAi6@cL+;GR6CM!%sit`C>&tCp>|$Sj@e!77ki;rsu1_vqSfu^2`mMuLTm) z?oW5QdDKmVJzp!0FLqgjGi=NQMKU{tTFx1G;RfFcIbSlqgh$}p4F&@g2ela7Jpqh= z4rf15ibCua&}|s{yE<=l|BxcZ;AMcbV9}-C1zuLNSG3)*-ZH*4^yW(%=VR1poXfM* zMTi`~KFmknzMtbCxba0#p8@=MIPwJNf~dcDqR4FrLD|MX(qll+G9W#*=4H7;ts9D#_7A}qfgR@L4aEVsovzwF7` zTeG8?o1*t)4Ti9SJnT~)CBuAZtW;z`v348e@FG*4Drxqv32_f*5R}d!1yDMl;~vc5 z;|idZ%bf`FaRpGyuY)n!T{8rMazqUb9)ExUBi}-tu*{8ddJ2YR4scrdgdl zfm^GzVfD6G@gBKErF#cm#aZ50w*_OVs=BVGEKySt4>rL8?Z=eYOf9dSGPOL;Ijlq? zj`&~P+_Ex{(a8@8f)V;ybcryxVJ3ZTn3TlK1v zyk~*gs{Y(qHx5!>L17$X3JJ?)p;@Tm;NkKs9lHSeW}(;^mKh%M(UI?yJFB2+`4MLo zVCRl)-sjeKPu&V@_HD3ie-AskUjppz_kIWOo3}B#FtX}+^xO?20kUCYB?Y8B^&yRu z;1yz=OS9{Q28W!%w;{$qKD$?+1uOGFQHYu`*G#!EjUk??*NxW9CsLjJ=J=#bX^)8e zT7B6*-bP%0FP-oNI%3id4Dn0p2F$zyhaeM2ceMVPt|DLD3SJu}T8tVN$+!Mn=Xlvu zz+zMofeP5W56ZVEv#F)OC4BstF%yyd;aI}=mig!e`c@nj(&a1Rcev50Ea>+Q1z$7n z7LJ|eqP75dE{iYUd^F>XV^qJ(Hy_ROWbXps{JoWvCIp3Qg6Zf{p3hz-T%nqPHQ43g z>CWc!u zD4cuW8$XNlp6pj+TMj3mmT~fl8$a4PC3Oo31^48%AuC}k2YDi$&3F;RJNm#p;x_!s zHXY79ZY45v5}r<`HB^(~klcwJo#bpFHu3xxZwzfSemQx^JWn-bs|+^HbjCOk;r0cY z6T^Ftyn8!%M&f(?6M(nG?w|}@)PtQim_p;1HIV`HruZ}!&Qmo+M3l;Ms+P{RqTydgJzk z@Kd@m($xtx0|;*F(Ezx8r@@mdVSqCbz|-7>gHP#te8pJNX|?DQ^tld!fM|WP0^NQi ze6BAh)D5U(=io@!?ToZcr_5zC+Fj+^Z8YBveiQA8xX##}^6rnb2gDc5M7cAM6Rs2z zjJ?Pj&dSj{#W5wYxrX@*TFa)I)y50n>zF(^+{4{PW#oYpr-19pi5JNeE6od1*z6Jl zMby03P&8dhR^Arm2IVmue6Ul-uQ7@0CyjLGK`8CP#7-hZH3SmmG;GX4nlWPFnaRfp zaD8cRk@N`W7D*C^ehX$O&TVXe?Vn7m;z-w*Oj%`R$Z!PPHYQFZHL@qu|KS z-`MfACMF5REmM;Jw}B0%@c77@7w7@eztkj=Cw%v*bSwQrjgOK_+^p5zl$}J-#ugV} z`e<}AiI#bhJuf$XZuvmsxNzArg=MLms**Bu>C2{Ac1e_!DF;i(&Typjdx%fj=EmVT z^V$y(7gQQc08eWidwSPoW+LLj#5~XHNv8Qtu1EZ(NMmG58U$igL=xj=eqV*S7Jf`> z=P3d;nOmfqW{B`E+u~O1?nO86piFAL#vnultF>(Xu~5S59`!xVPN?ituCnycPpALg zXPD;==l?##csu5h2c)Ih{{3CLXKsk>nfq_NZT|_w@iO}MZ}J@x;AV0pQ~wmc^&>0H zv~OkDElh@yEX9ms8}C`o5p9mQGEl6~Jw8Cb+9CREmz_ae|u(NU5&_I#zH8qK|cqKz{_J zd;`KRUl$7 zTV2Q5FkLE9h~LOLFmD;7*04emV@*pQ<=z+2k@zo?B?ZcMT|T+&9z!mzR3AM8$1oiU zD^+Tx3ljVtihuRV87zf{1JW=6NI3kZ%NK@nhV~9Sdxws8idqMhe2fFToDGeP8M@`s z{W$>$m%E{{an?c^YcW2H-N*^P zQ?uOxqVNO;h{!1L#W<(0EvG*N+g@_fF{jZ9ParHNvKQ8r&#mwEe2o`Bg>6QUpkMsY ztJyNu^HpVhG4_Hh5PK10zw5LY*Zt7*wYyaT#s=NEFD(C~=j#$hIvlZ46TN;(0EtyX z*XS#rjAyzp$&(Kkb8`;n8#$Qo=V0#5!EDIEJRQK~pFzfiym8bAgZ1%TsHJ1B8sz*2 zPcyBCLn+K)-JND_B1-3H11OzSb*EW#9IF)nW0SQqlPiniHp zq25+eZ~N$COtq>!-}X`Lb~R!2+rn*3$=IB8G!`Ol4`iId<(p9mhm>ZY1!fffo#$wb zKwvyaW2ELg$$o`q6ix$A%J4BO7n)m~Yk1u6_+*dR=SZ4=#1T8A3zLf@Q|Vu@D~N8~ zevF-Me5Co_@#x46oGD~w7nY?GHi|4=J`{>SdsLJjKUB0@5 zmM{TVpzin}i?7gZaRCgQ<{dsp8U7@;z`8aNPgpu!9 zm+&t%5>M4==Hz$z_!_`4BZsdpM;<3Df0)A;&*5Xney|^W>_ohihY!=spHQn!&AT75 z4xE8#S%!Z(z3yzBDAe(%y7T~?s9Vi@w_i@Bw-mr`Lk3>;VCiT6JT_;@DUQxPX#s0lL zUmf+xFLowJ^&~-Fy5q3rLk%i1YJ*^kVGy_!0?e?KcX@B*kQBCmfdht6@tX-SwJME@ zPPEVCu(IRPI@seCKB9LP0uT@8qji&ZD(zl2D{e?8 zJ_UH{0S` zE$&K-yT;;fu(+=R8Z1(7wbZ*T^@o6pg?g{0K5D5?0@5#k0g!(AtAO-7{s2h790DBH zzOEYyKnK+dF$5h{hxQ%h?2EI9_r0OGb#TL=x?`Pbuy%_c8-=Apv~B)H^V*|}=g(=G zzwjd98W$~W$Gr=NdTbO2#4nCwQNOjhv3>rf%`KOgf@R4j(4gTwk~Pcc+{VRUs$#E^$$RlIsF>cS8d1#O`0=dQX zAbA3kf1Jy)Z16}VV$3eAg14JgCE~cQqNWZPtgw)q&0P~v(qWpzqK^GtTGm~X6!^H& z!W$TKIBWvz=Z!1LWPD0RHO`+*)W)UMyEnSb$5t~I{K<0uG7CR1cbVVPgnK;PFecVj z*Cgwv)|Q!VWo6Sm)1daY*|~N)=3FN9r^LCt%Epw88Lt?%)9Hep&Q-{VtO@Dz^_yQ+ zlJ_joZ|;ws4m&us(>Y1=zGV19{ow?7Xw*i>>LlM-np2XO7#{M`eX_^WnwB52A1VFE zRCh~kXsWwCHk|!P9B;F|I{lIyh5VOoj3?ZQ(A!g!ek{f9B|q=3F#RWVx6n0f!GIgv zVB*p>iO$+E0vUQ!3|YPX<8_v!)_Yp*3fK7}t(`r_s#aFn{xUo5Q zKLu)xNfS>Qf-xa7aUdiGsG}69H^O}{I&+cb7awivN zhMD+Z5AH%WOA=kgI(8G`3e_yk!VAH(BAd@Q#ZUj7(!K>ecV_eXG6wnBr``yjUuW~> zk@rvV6tim!S4cm~`xJQ2$mYuYb{rjd@i4UlAIYAcEOIw;fu#nWYr8$+}Ql0*bdqA^b(U4�p8?pOQeUSXLdG} zJ`-8}7+PZ-I99qja@~CdlVf^mz1B*lv3qwOe)|sKaW8<>x@3A;XG0=AsAyx~o}LJL zY7$SGy>0P(!%=Ax)MH4*n!f%0B9A|W7J|>ZfX}0AGE4?LpL6fCo=@1I)$y8z z9*M$qeP=_usJlLPE{^ENHea40$=RySpq9dT>1y-NTv0kS($$7{ELog}jKUlRVGW5% z6||^pKz@Oo6C+7%b49KkkHg=XOxT0kfLsP0Q$?GLp6J+hMf(DG`VRQO)Yg5oJp@D< zwq$yf=1$!VEb~r&oO^kNi^H$kFT0)Qtw_hxO-lwPGK+e5Ow1%pJ`6-v&Pjjlo7;o? z66v=`wRAT0K7HTm&}Kk=2YW`RO936*VD;P*wL+~ z2AQ(n(hWxc$m$yqL#sZJ*g-!V(eetS<=xz9;aPC5Lhn$SWTt+fP!drZO|1HdXp<8S z^pi+GE9xZETT+c1dpDHcA|HS=4;ib~jgMsNj}LXPmAHwlX`}TfW2~$fnK8;pAGit{ z2BJGB@o76_6W^S4iTsO}2vwp;));}bj-Eu{vM$J$72_uF2DFmdvN%&ZepE6R+obh0 z^IC6D>FZE@WMuVPyhVTFNSCwvB-bHnAj%Dflk=0D&%!QL9M>_$1cI4*6OMUum z6MgE(Ox}$`^kWoCH9iJ)dVg*d>V2~GeWMigLBgFbB|#gt<>9WL%a3GoWEV2dP^dtd z_a$Ip+lywc=qMI(ex+Bgb845BKJ{6qM|M1XRj^DSnOmmmNrQ9CvnkC8j7s-zF5P4c z^cN77K*lmh42B{lrh>^)}lHQ=={NovC%wmqC})EzMF}XdK|%I(p)L z%UYcy3$-L=!O&7`9+Ab$7@e9-a$+wFF{1Mf#9rT`Z}vnZ1INlUHK(I?M{(+|K^5Ca z(%<5bafFN$FJcpMS0wr!fl5732B25{_{~XLDWU~Pq)$QJ&TL$amrM(?VB_Px8*#X8 zLpP2_WyAls$aO1Ou4bOmJ9n;oR!HW`5c+W?t9qr%&dC;cP)SYY^iJ<FfW(WrMLby^0U$}%%Y_e%Y<8-4EF6MclaKl&um z$z&AuZcLQEry3zKl2mFp`rN%I`UvxG_1O_-*eEP<94->xO(*n+4Bssz<6glL#SP_| zu8C!hS=%c22y10hVJ1z z4#P(@^lt9hITD4wAwYwVA-&uZ!UKNcVaI%4rFxoVY8OWn?E1{P188j%ucJ7D#2cSb|>2CmW{UlF}%x?SZ$Y@ z>v;fCPX8M=@By6kzcHdPXuq`kIHnIEie1FGp6!2=lWs&-?%Mwpm(dH&RV&_x!y%0gQK)!{$v{1MMuf!@QDx`&+v z1`bM10aEJOfRxHZ9F@Awr!b>Ypt2FtoWUc?2MpJQ|QnKFdR#sl3xIHEF4|a#HH;miiq_{i&t?(o$cu)NPhJ4hf{;o(f3A ztpcQyY22^Wg_e4`rLMQspIPb?mikvq-33TfW)RA~O8zt;l{^}dhC9hpue8*w0cno7 z&QkBT)E@y-zde?^ABI{gc^Dw|I|7i2NkE!1pR;@%oGIS|%hzrB?y-FL1Jdu@hoG(~a_ z_W>*Q97}Dq)E`>vy_UMsQeU^!KUnI!mO2&+qw z8ZFRXSoP8xZYUtFxef=Uwb=<4_kY=Y7x*ZPtAG4ivOq*Mc-MMcF)9dRAPEM8W;fYQ zcFE>a5)hRNAqkKYl9+4|6%h@nbcxuiReP~kt-aZ5TidF&eL+;PYQ41HT5GjeQfg~! zt9YsTeZObsx$X08613Xa|Nos&vU~Q-IcF}=>tQNm%9aazb!wbY^S{q!X zb@a6Lq>zJYAu`fUeyN!Yfklu)DT8C4!Gx`M<&xHJ7F#UTV1L#DdzT(Z&VbTYBogt{kw39v>!A_bO4_}p zI$`j3UMpO~wXUY6n{9?xIK$|YB-IWxPm_Fr8~YyXdcG|TKbUyj$qM4(t{LnO5uoi##Js1vyQYDy?($ln`@=!5*k-p7$hBO{kAQz$mUw7xrD}*mgLPc zviQ}PZ-T07*5Ri$m&(7>CY~KvPM})H9}qQG+eT=&Xe?>Om~D@o;`3?SF4o-Ub}wql zq;Z=FasbE)+^XYWm@%Qu&d+Gw-;+i%%i;Aw45V>$ z$!Kp~1aZamJJ#ADHBffjH83fg;G@0^_2w6*g3tW-eO=K&=<>kqmsyVfAUng3Gsv+tT%4?ly5@p3wPI#7! z)+$?BtIkR)>LS%Ob(J;RShaA5E9K&<>R4q}c{~~x&A}BntE!^5x*D$Y!q#I|@v4G& z(SklJRycj67Hl)87dvcT4;Krz(db+kO566gc}=p3J3|%=whJ@pvRSZIn?sbA>1V;# z4_OVMGj9ywOg)vBz5rn$Kj? z`N+EyH1}oFWmudsf4>CHpEK!vqYIWslMdqE!wbc_GkD&7{ka$7-9SX#h&_vxuWcIe!Fn9Q_xL zfR6H-M?go7ugyaj_E@lSrq|=4^IFbP7ktP==at8S>`4!u*K%$$=zi{@^U9;X`;HG? z=%Z_4Cw(WDVQ24WEJ4FHsA?WHH`n^EX>0E8?CHdudeYpxjk`|;=wM}28kw5}Jnwmorys+wsgk77 zI`!D3tc;C@zI z&cVxBBmI51BX2Gd9&-eG@-a6;!MZ;GCA?Jt&P*(s9RRpqm)lT>!0H{}h0 zAFOjepU5D}dW{r%X$cV`ysWrk1cy2D-IzxtvG%LD~@fj;$V9k z+z!hu<|EQS{y>;A6s*0Rj*yra?sM|lM*25=YuM*f;4H1(j!=W>e(`+P>)TlH*jap3 z-zbrxYAB0M>2!Ajus@UMgHF+wj-BS&*q<(Py#IK8wquLkYW}!F_rg(P zfuNr%x&ePHhnQWz@$0Qk;K!KSBxwq0DSdwn^!||h*nAgoM8$gBk3xlUog!$I;PXs@ z%JDg0paeeW3B)mnc?%lL@yV_%XspC%tw1S!)(C_tlU}Re07%K(42Y6~#zXj2sr|}= za*=&Sw?812?qPu9!f`Ahl`c=$s&vZ$sdQ^C9B1kZ$JsYWW?TgeC??Ps0kKp;;~Rjm zbO7jiEA}NT_7yAkAiRgC3*8J0T4F(cfRyA<0V)@|>i{Xqzq4Zh3`p(SykW&oz!;!- zaYjb-<^xi^=UTC=t=J7#?3V$lTs>vcJ#W$d(V`o)=q93*IaTsk0Z64g2hc3RodHOt zyBHAOGStgTK-8pz#^aDe9or0N15hjP3L-t%CX}14m8iR3{4(;Ib1yOreb>ghO zZ1NSQD{qK;kVMy!=!4Pz&?OJ-8?s5IQ_q~K)-NSniZ4W#Ae-IQC;sFXo2yE535_eQy@ZP|2)R~0_kBlN9Euo(#+8;@pl7#2uIu(& zc$A$MhdqYj7U=iQO~87Db;htxJ`IDDGIt$H-eiHEX?_3QTMxInuGU;C|4wgt`%sRx z@o?eWdw(Pky_+T8Zxk#gMrCH^$^UbzEPkoJnG=AFyLoaP}`P
^oxI8yIv!$3U9lHZVR0nw-F7k|V6!*_g0P8q#t| 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
(ia4PY!@JZb=!^5Gz` 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 z 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�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 o2M!J8a=9*}x0eh!>#p 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%0A^Uw;`o3>hhd`T2T&0wZ7w@bz4w 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%0AmiS}R)acy|;a7XL8-DWZDP2h2y&y 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