From 006bd56ae6644b85ad205df4e17699e67d743c37 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Thu, 9 Jan 2014 19:19:01 +0100 Subject: [PATCH] General changes added OpenSpaceEngine added ConfigurationManager added query functions removed GLEW-related Windows warning added old external control classes more restructuring --- CMakeLists.txt | 1 + ext/ghoul | 2 +- modules/common/shaders/pscstandard_fs.glsl | 8 +- modules/common/shaders/pscstandard_vs.glsl | 2 +- scripts/config.lua | 6 + scripts/script.lua | 27 ++ src/CMakeLists.txt | 13 + src/configuration/configurationmanager.cpp | 137 ++++++++ src/configuration/configurationmanager.h | 51 +++ src/interaction/deviceidentifier.cpp | 157 +++++++++ src/interaction/deviceidentifier.h | 55 +++ .../externalconnectioncontroller.cpp | 12 + .../externalconnectioncontroller.h | 24 ++ .../externalcontrol/externalcontrol.cpp | 33 ++ .../externalcontrol/externalcontrol.h | 29 ++ .../joystickexternalcontrol.cpp | 63 ++++ .../joystickexternalcontrol.cpp.orig | 63 ++++ .../externalcontrol/joystickexternalcontrol.h | 28 ++ .../keyboardexternalcontrol.cpp | 62 ++++ .../keyboardexternalcontrol.cpp.orig | 62 ++++ .../externalcontrol/keyboardexternalcontrol.h | 25 ++ .../externalcontrol/mouseexternalcontrol.cpp | 79 +++++ .../mouseexternalcontrol.cpp.orig | 79 +++++ .../externalcontrol/mouseexternalcontrol.h | 28 ++ .../externalcontrol/pythonexternalcontrol.cpp | 147 ++++++++ .../externalcontrol/pythonexternalcontrol.h | 35 ++ .../externalcontrol/randomexternalcontrol.cpp | 59 ++++ .../externalcontrol/randomexternalcontrol.h | 26 ++ src/interaction/interactionhandler.cpp | 326 ++++++++++++++++++ src/interaction/interactionhandler.h | 89 +++++ src/main.cpp | 112 +++--- src/openspaceengine.cpp | 247 +++++++++++++ src/openspaceengine.h | 109 ++++++ src/query/query.cpp | 59 ++++ src/query/query.h | 41 +++ src/rendering/renderable.cpp | 32 ++ src/rendering/renderable.h | 32 ++ src/rendering/renderablebody.cpp | 74 ++++ src/rendering/renderablebody.h | 37 ++ src/rendering/renderableplanet.cpp | 71 ++++ src/rendering/renderableplanet.h | 37 ++ src/rendering/renderengine.cpp | 289 ++++++++++++++++ src/rendering/renderengine.h | 62 ++++ src/scenegraph/scenegraph.h | 1 + src/scenegraph/scenegraphloader.cpp | 14 +- src/scenegraph/scenegraphloader.h | 4 + src/util/camera.cpp | 97 ++++++ src/util/camera.h | 58 ++++ 48 files changed, 3050 insertions(+), 54 deletions(-) create mode 100644 scripts/config.lua create mode 100644 scripts/script.lua create mode 100644 src/configuration/configurationmanager.cpp create mode 100644 src/configuration/configurationmanager.h create mode 100644 src/interaction/deviceidentifier.cpp create mode 100644 src/interaction/deviceidentifier.h create mode 100644 src/interaction/externalcontrol/externalconnectioncontroller.cpp create mode 100644 src/interaction/externalcontrol/externalconnectioncontroller.h create mode 100644 src/interaction/externalcontrol/externalcontrol.cpp create mode 100644 src/interaction/externalcontrol/externalcontrol.h create mode 100644 src/interaction/externalcontrol/joystickexternalcontrol.cpp create mode 100644 src/interaction/externalcontrol/joystickexternalcontrol.cpp.orig create mode 100644 src/interaction/externalcontrol/joystickexternalcontrol.h create mode 100644 src/interaction/externalcontrol/keyboardexternalcontrol.cpp create mode 100644 src/interaction/externalcontrol/keyboardexternalcontrol.cpp.orig create mode 100644 src/interaction/externalcontrol/keyboardexternalcontrol.h create mode 100644 src/interaction/externalcontrol/mouseexternalcontrol.cpp create mode 100644 src/interaction/externalcontrol/mouseexternalcontrol.cpp.orig create mode 100644 src/interaction/externalcontrol/mouseexternalcontrol.h create mode 100644 src/interaction/externalcontrol/pythonexternalcontrol.cpp create mode 100644 src/interaction/externalcontrol/pythonexternalcontrol.h create mode 100644 src/interaction/externalcontrol/randomexternalcontrol.cpp create mode 100644 src/interaction/externalcontrol/randomexternalcontrol.h create mode 100644 src/interaction/interactionhandler.cpp create mode 100644 src/interaction/interactionhandler.h create mode 100644 src/openspaceengine.cpp create mode 100644 src/openspaceengine.h create mode 100644 src/query/query.cpp create mode 100644 src/query/query.h create mode 100644 src/rendering/renderable.cpp create mode 100644 src/rendering/renderable.h create mode 100644 src/rendering/renderablebody.cpp create mode 100644 src/rendering/renderablebody.h create mode 100644 src/rendering/renderableplanet.cpp create mode 100644 src/rendering/renderableplanet.h create mode 100644 src/rendering/renderengine.cpp create mode 100644 src/rendering/renderengine.h create mode 100644 src/util/camera.cpp create mode 100644 src/util/camera.h diff --git a/CMakeLists.txt b/CMakeLists.txt index f9f9c6c138..f8c1e07cda 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,6 +56,7 @@ set(DEPENDENT_LIBS ${DEPENDENT_LIBS} Ghoul) #set(SGCT_ROOT_DIR "C:/Program Files (x86)/SGCT/SGCT_2.0.5_x86") set(SGCT_ROOT_DIR "C:/Program Files/SGCT/SGCT_2.0.7") add_definitions(-D__WIN32__) +add_definitions(-DGLEW_STATIC) include_directories("${SGCT_ROOT_DIR}/include") #set(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} ${SGCT_ROOT_DOR}/bin/lib/msvc11) set(DEPENDENT_LIBS diff --git a/ext/ghoul b/ext/ghoul index 96e3209fc6..f61f47143f 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 96e3209fc661084bbe0d449ad850e48aad0a4e8e +Subproject commit f61f47143fea1b9f7b9dbd31932365c751004b3b diff --git a/modules/common/shaders/pscstandard_fs.glsl b/modules/common/shaders/pscstandard_fs.glsl index 345af2a123..99b734a58d 100644 --- a/modules/common/shaders/pscstandard_fs.glsl +++ b/modules/common/shaders/pscstandard_fs.glsl @@ -7,7 +7,7 @@ The above copyright notice and this permission notice shall be included in all c THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#version 150 +#version 400 core uniform mat4 ViewProjection; uniform mat4 ModelTransform; @@ -93,7 +93,7 @@ void main() } else { // where am I? // do I need to be discarded? - //discard; + // discard; } @@ -101,6 +101,8 @@ void main() gl_FragDepth = depth; // color - diffuse = texture2D(texture1, vs_st); + diffuse = texture2D(texture1, vs_st); + // diffuse = vec4(vs_position.xyz * pow(10, vs_position.w), 1.0); + // diffuse = vec4(vs_st, 0.0, 1.0); //diffuse = vec4(1.0,0.0,0.0,1.0); } \ No newline at end of file diff --git a/modules/common/shaders/pscstandard_vs.glsl b/modules/common/shaders/pscstandard_vs.glsl index 32ade96aba..b9e794908f 100644 --- a/modules/common/shaders/pscstandard_vs.glsl +++ b/modules/common/shaders/pscstandard_vs.glsl @@ -7,7 +7,7 @@ The above copyright notice and this permission notice shall be included in all c THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#version 150 +#version 400 core uniform mat4 ViewProjection; uniform mat4 ModelTransform; diff --git a/scripts/config.lua b/scripts/config.lua new file mode 100644 index 0000000000..52bc431f32 --- /dev/null +++ b/scripts/config.lua @@ -0,0 +1,6 @@ +-- fofo +{ + a = 0, + b = 1, + c = 2 +} \ No newline at end of file diff --git a/scripts/script.lua b/scripts/script.lua new file mode 100644 index 0000000000..985aa2c7a4 --- /dev/null +++ b/scripts/script.lua @@ -0,0 +1,27 @@ +--config = assert(loadfile("../../scripts/config.lua"))() + +io.input("../../scripts/config.lua") +file = io.read("*all") +config = assert(load("return " .. file))() + + +--t = {a=1, b="foo", c= 0.1 } + +--print(_G) +-- for key,value in pairs(_G) do print(key,value) end +-- a = {} +-- local x = 20 +-- for i=1,10 do + -- local y = 0 + -- a[i] = function () y=y+1; return x+y end +-- end +-- for key,value in pairs(a) do print(key,value()) end + +-- m = getmetatable(x) +--m = getfenv(m) +-- print(m) +--for key,value in pairs(m) do print(key,value) end + +-- for key,value in pairs(debug.getregistry()) do print(key,value) end +-- print (debug.getregistry()) +-- print(debug) \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0118be2219..80cbb421b4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -34,6 +34,12 @@ file(GLOB MAIN_HEADER ${SOURCE_ROOT_DIR}/*.h) set(OPENSPACE_HEADER ${OPENSPACE_HEADER} ${MAIN_HEADER}) source_group(Main FILES ${MAIN_SOURCE} ${MAIN_HEADER}) +file(GLOB CONFIGURATION_SOURCE ${SOURCE_ROOT_DIR}/configuration/*.cpp) +set(OPENSPACE_SOURCE ${OPENSPACE_SOURCE} ${CONFIGURATION_SOURCE}) +file(GLOB CONFIGURATION_HEADER ${HEADER_ROOT_DIR}/configuration/*.h) +set(OPENSPACE_HEADER ${OPENSPACE_HEADER} ${CONFIGURATION_HEADER}) +source_group(Configuration FILES ${CONFIGURATION_SOURCE} ${CONFIGURATION_HEADER}) + file(GLOB ENGINE_SOURCE ${SOURCE_ROOT_DIR}/engine/*.cpp) set(OPENSPACE_SOURCE ${OPENSPACE_SOURCE} ${ENGINE_SOURCE}) file(GLOB ENGINE_HEADER ${HEADER_ROOT_DIR}/engine/*.h) @@ -52,6 +58,13 @@ file(GLOB INTERACTION_EXTERNALCONTROL_HEADER ${HEADER_ROOT_DIR}/interaction/exte set(OPENSPACE_HEADER ${OPENSPACE_HEADER} ${INTERACTION_EXTERNALCONTROL_HEADER}) source_group(Interaction\\ExternalControl FILES ${INTERACTION_EXTERNALCONTROL_SOURCE} ${INTERACTION_EXTERNALCONTROL_HEADER}) +file(GLOB QUERY_SOURCE_CPP ${SOURCE_ROOT_DIR}/query/*.cpp) +file(GLOB QUERY_SOURCE_C ${SOURCE_ROOT_DIR}/query/*.c) +set(OPENSPACE_SOURCE ${OPENSPACE_SOURCE} ${QUERY_SOURCE_CPP} ${QUERY_SOURCE_C}) +file(GLOB QUERY_HEADER ${HEADER_ROOT_DIR}/query/*.h) +set(OPENSPACE_HEADER ${OPENSPACE_HEADER} ${QUERY_HEADER}) +source_group(Query FILES ${QUERY_SOURCE_CPP} ${QUERY_SOURCE_C} ${QUERY_HEADER}) + file(GLOB RENDERING_SOURCE ${SOURCE_ROOT_DIR}/rendering/*.cpp) set(OPENSPACE_SOURCE ${OPENSPACE_SOURCE} ${RENDERING_SOURCE}) file(GLOB RENDERING_HEADER ${HEADER_ROOT_DIR}/rendering/*.h) diff --git a/src/configuration/configurationmanager.cpp b/src/configuration/configurationmanager.cpp new file mode 100644 index 0000000000..e49c33912c --- /dev/null +++ b/src/configuration/configurationmanager.cpp @@ -0,0 +1,137 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include "configuration/configurationmanager.h" + +#include +#include +#include + +#include +#include + +namespace { + const std::string _loggerCat = "ConfigurationManager"; + + lua_State* _state = nullptr; +} + +using namespace ghoul::lua; + +namespace openspace { + + + +ConfigurationManager::ConfigurationManager() {} + + +ConfigurationManager::~ConfigurationManager() { + +} + +void ConfigurationManager::initialize() { + // TODO custom assert (ticket #5) + assert(_state == nullptr); + + _state = luaL_newstate(); + luaL_openlibs(_state); +} + +void ConfigurationManager::deinitialize() { + // TODO custom assert (ticket #5) + assert(_state != nullptr); + lua_close(_state); +} + + +void ConfigurationManager::loadConfiguration(const std::string& filename, + const std::string& position) +{ + // TODO custom assert (ticket #5) + assert(_state != nullptr); + + // load 'filename', prepent 'return', execute string, modify stack and execute + // separate script to apply the table of changes + std::ifstream file(filename); + if (!file.good()) { + LERROR("Error opening file '" << filename << "': Error code:" << + std::endl << file.rdstate()); + return; + } + + // load script code from 'filename' and prepend "return" + std::stringstream buffer; + buffer << file.rdbuf(); + std::string scriptText = "return " + buffer.str(); + + const int loadResult = luaL_loadstring(_state, scriptText.c_str()); + if (loadResult != 0) { + LERROR("Error loading script in file '" << filename << "'. Error:" << + std::endl << lua_tostring(_state, -1)); + return; + } + + LINFO("before"); + lua_logStack(_state); + + const int execResult = lua_pcall(_state, 0, LUA_MULTRET, 0); + if (execResult != 0) { + LERROR("Error executing script in file '" << filename << "'. Error:" << + std::endl << lua_tostring(_state, -1)); + return; + } + LINFO("after"); + lua_logStack(_state); + lua_logTable(_state); + + //lua_p + + const int load2Result = luaL_loadfile(_state, p("${SCRIPTS}/script.lua").c_str()); + if (load2Result != 0) { + LERROR("Error loading script in file '" << filename << "'. Error:" << + std::endl << lua_tostring(_state, -1)); + return; + } + LINFO("afterloading"); + lua_logStack(_state); + + +} + +template +bool ConfigurationManager::getValue(const std::string& key, T& value) { + // If none of the specializations fit, we don't know what to do + LERROR("Unsupported type for key '" << key << "'"); + return false; +} + +template +bool ConfigurationManager::setValue(const std::string& key, const T& value) { + // If none of the specializations fit, we don't know what to do + LERROR("Unsupported type for key '" << key << "'"); + return false; +} + + +} // namespace openspace diff --git a/src/configuration/configurationmanager.h b/src/configuration/configurationmanager.h new file mode 100644 index 0000000000..a5b1b4062f --- /dev/null +++ b/src/configuration/configurationmanager.h @@ -0,0 +1,51 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#ifndef __CONFIGURATIONMANAGER_H__ +#define __CONFIGURATIONMANAGER_H__ + +#include + +namespace openspace { + +class ConfigurationManager { +public: + ConfigurationManager(); + ~ConfigurationManager(); + + void initialize(); + void deinitialize(); + + void loadConfiguration(const std::string& filename, const std::string& position = ""); + + template + bool setValue(const std::string& key, const T& value); + + template + bool getValue(const std::string& key, T& value); +}; + +} // namespace openspace + +#endif // __CONFIGURATIONMANAGER_H__ diff --git a/src/interaction/deviceidentifier.cpp b/src/interaction/deviceidentifier.cpp new file mode 100644 index 0000000000..ecac780d05 --- /dev/null +++ b/src/interaction/deviceidentifier.cpp @@ -0,0 +1,157 @@ + +// open space includes +#include "deviceIdentifier.h" + +// sgct includes +#include "sgct.h" + +namespace openspace { + + +DeviceIdentifier* DeviceIdentifier::this_ = nullptr; + +DeviceIdentifier::DeviceIdentifier() { + + // scan for devices on init + devices_ = 0; + for(int i = 0; i < MAXDEVICES; ++i) { + inputDevice_[i] = InputDevice::NONE; + } +} + +DeviceIdentifier::~DeviceIdentifier() { + + // deallocates memory on exit + for(int i = 0; i < MAXDEVICES; ++i) { + if(inputDevice_[i] != InputDevice::NONE) { + delete axesPos_[i]; + delete buttons_[i]; + } + } +} + +void DeviceIdentifier::init() { + assert( ! this_); + this_ = new DeviceIdentifier(); +} + +void DeviceIdentifier::deinit() { + assert(this_); + delete this_; + this_ = nullptr; +} + +DeviceIdentifier& DeviceIdentifier::ref() { + assert(this_); + return *this_; +} + +bool DeviceIdentifier::isInitialized() { + return this_ != nullptr; +} + +void DeviceIdentifier::scanDevices() { + assert(this_); + + // 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 + 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]]; + buttons_[i] = new unsigned char[numberOfButtons_[i]]; + + // increment the device count + ++devices_; + + // identify what device it is + if(numberOfAxes_[i] == 6 && numberOfButtons_[i] == 10) { + printf("XBOX controller "); + inputDevice_[i] = InputDevice::XBOX; + } else if(numberOfAxes_[i] == 6 && numberOfButtons_[i] == 4) { + printf("SPACENAVIGATOR "); + inputDevice_[i] = InputDevice::SPACENAVIGATOR; + } else { + printf("UNKNOWN device "); + inputDevice_[i] = InputDevice::UNKNOWN; + } + printf("found at position %i, b=%i, a=%i\n", i, numberOfButtons_[i], numberOfAxes_[i]); + + + } else { + inputDevice_[i] = InputDevice::NONE; + } + + } +} + +const int DeviceIdentifier::numberOfDevices() const { + assert(this_); + return devices_; +} + +const InputDevice DeviceIdentifier::type(const int device) const { + assert(this_); + return inputDevice_[device]; +} + +void DeviceIdentifier::update() { + assert(this_); + for(int i = 0; i < devices_; ++i) { + update(i); + } +} + +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] + } +} + +const int DeviceIdentifier::getButtons(const int device, unsigned char **buttons) const { + assert(this_); + if(inputDevice_[device] != InputDevice::NONE) { + if(buttons) + *buttons = buttons_[device]; + return numberOfButtons_[device]; + } + return 0; +} + +const int DeviceIdentifier::getAxes(const int device, float **axespos) const { + assert(this_); + if(inputDevice_[device] != InputDevice::NONE) { + if(axespos) + *axespos = axesPos_[device]; + return numberOfAxes_[device]; + } + return 0; +} + +void DeviceIdentifier::get(const int device, unsigned char **buttons, float **axespos) const { + assert(this_); + if(inputDevice_[device] != InputDevice::NONE) { + *axespos = axesPos_[device]; + *buttons = buttons_[device]; + } +} + +} // namespace openspace \ No newline at end of file diff --git a/src/interaction/deviceidentifier.h b/src/interaction/deviceidentifier.h new file mode 100644 index 0000000000..c2174ab204 --- /dev/null +++ b/src/interaction/deviceidentifier.h @@ -0,0 +1,55 @@ +#ifndef DEVICEIDENTIFIER_H +#define DEVICEIDENTIFIER_H + +// std includes +#include +#include +#include + +namespace openspace { + +#define MAXDEVICES 16 + +enum class InputDevice {NONE, UNKNOWN, SPACENAVIGATOR, XBOX}; + +class DeviceIdentifier { +public: + static DeviceIdentifier& ref(); + virtual ~DeviceIdentifier(); + + static void init(); + static void deinit(); + static bool isInitialized(); + + void scanDevices(); + const int numberOfDevices() const; + const InputDevice type(const int device) const; + + void update(); + void update(const int device); + + const int getButtons(const int device, unsigned char **buttons = nullptr) const; + const int getAxes(const int device, float **axespos = nullptr) const; + void get(const int device, unsigned char **buttons, float **axespos) const; + +private: + // singleton + static DeviceIdentifier* this_; + DeviceIdentifier(void); + DeviceIdentifier(const DeviceIdentifier& src); + DeviceIdentifier& operator=(const DeviceIdentifier& rhs); + + + // member variables + int devices_; + std::array inputDevice_; + std::array numberOfAxes_; + std::array numberOfButtons_; + std::array axesPos_; + std::array buttons_; + +}; + +} // namespace openspace + +#endif \ No newline at end of file diff --git a/src/interaction/externalcontrol/externalconnectioncontroller.cpp b/src/interaction/externalcontrol/externalconnectioncontroller.cpp new file mode 100644 index 0000000000..54ec5ebac3 --- /dev/null +++ b/src/interaction/externalcontrol/externalconnectioncontroller.cpp @@ -0,0 +1,12 @@ +#include "interaction/externalcontrol/externalconnectioncontroller.h" + +namespace openspace { + +ExternalConnectionController::ExternalConnectionController() { +} + +ExternalConnectionController::~ExternalConnectionController() { + +} + +} // namespace openspace \ No newline at end of file diff --git a/src/interaction/externalcontrol/externalconnectioncontroller.h b/src/interaction/externalcontrol/externalconnectioncontroller.h new file mode 100644 index 0000000000..8eecd53f90 --- /dev/null +++ b/src/interaction/externalcontrol/externalconnectioncontroller.h @@ -0,0 +1,24 @@ +#ifndef EXTERNALCONNECTIONCONTROLLER_H +#define EXTERNALCONNECTIONCONTROLLER_H + +#include "interaction/externalcontrol/externalcontrol.h" +#include + +namespace openspace { + +class ExternalConnectionController: public ExternalControl { +public: + + // constructors & destructor + ExternalConnectionController(); + ~ExternalConnectionController(); + +private: + + std::vector controllers; + +}; + +} // namespace openspace + +#endif \ No newline at end of file diff --git a/src/interaction/externalcontrol/externalcontrol.cpp b/src/interaction/externalcontrol/externalcontrol.cpp new file mode 100644 index 0000000000..c3cf9b93a2 --- /dev/null +++ b/src/interaction/externalcontrol/externalcontrol.cpp @@ -0,0 +1,33 @@ +#include "interaction/externalcontrol/externalcontrol.h" +#include "interaction/interactionhandler.h" +#include "openspaceengine.h" +#include + +namespace openspace { + +ExternalControl::ExternalControl() { + +} + +ExternalControl::~ExternalControl() { +} + +void ExternalControl::update() { + +} + +void ExternalControl::rotate(const glm::quat &rotation) { + OsEng.interactionHandler().rotate(rotation); +} + +void ExternalControl::orbit(const glm::quat &rotation) { + OsEng.interactionHandler().orbit(rotation); +} + +void ExternalControl::distance(const pss &distance) { + OsEng.interactionHandler().distance(distance); +} + + +} // namespace openspace + diff --git a/src/interaction/externalcontrol/externalcontrol.h b/src/interaction/externalcontrol/externalcontrol.h new file mode 100644 index 0000000000..8b270bad7f --- /dev/null +++ b/src/interaction/externalcontrol/externalcontrol.h @@ -0,0 +1,29 @@ +#ifndef EXTERNALCONTROL_H +#define EXTERNALCONTROL_H + +#include "util/pss.h" +#include +#include + +namespace openspace { + +class ExternalControl { +public: + + // constructors & destructor + ExternalControl(); + ~ExternalControl(); + + virtual void update(); + + void rotate(const glm::quat &rotation); + void orbit(const glm::quat &rotation); + void distance(const pss &distance); + + +protected: +}; + +} // namespace openspace + +#endif \ No newline at end of file diff --git a/src/interaction/externalcontrol/joystickexternalcontrol.cpp b/src/interaction/externalcontrol/joystickexternalcontrol.cpp new file mode 100644 index 0000000000..7f2f543d3b --- /dev/null +++ b/src/interaction/externalcontrol/joystickexternalcontrol.cpp @@ -0,0 +1,63 @@ +//#include "externalcontrol/joystickexternalcontrol.h" +//#include "deviceidentifier.h" +// +//// workaround since Python debug does not work on windows +//#ifdef _DEBUG +//#undef _DEBUG +//#include +//#define _DEBUG +//#else +//#include +//#endif +// +//namespace openspace { +// +// +//JoystickExternalControl::JoystickExternalControl(const char *filename): PythonExternalControl(filename) { +//} +// +//void JoystickExternalControl::setInputDevice(const int device) { +// if(device >= 0 && device <= 16) { +// inputDevice_ = device; +// numberOfButtons_ = DeviceIdentifier::ref().getButtons(inputDevice_); +// numberOfAxes_ = DeviceIdentifier::ref().getAxes(inputDevice_); +// clear(); +// pyarrSize_ = numberOfButtons_ + numberOfAxes_; +// pyarr_ = new PyObject*[pyarrSize_]; +// } +// +//} +// +//void JoystickExternalControl::update() { +// +// if(inputDevice_ != -1) { +// float *axesPos; +// unsigned char *buttons; +// DeviceIdentifier::ref().getButtons(inputDevice_, &buttons); +// DeviceIdentifier::ref().getAxes(inputDevice_, &axesPos); +// +// // init array +// for(int i = 0; i < numberOfButtons_; ++i){ +// pyarr_[i] = PyLong_FromLong(buttons[i]); +// } +// for(int i = 0; i < numberOfAxes_; ++i){ +// pyarr_[i+numberOfButtons_] = PyFloat_FromDouble(axesPos[i]); +// } +// } +// +// run(); +// +// if(inputDevice_ != -1) { +// // cleanup +// for(int i = 0; i < pyarrSize_; ++i) { +// Py_DECREF(pyarr_[i]); +// } +// } +// +//} +// +//JoystickExternalControl::~JoystickExternalControl() { +//} +// +//} // namespace openspace +// diff --git a/src/interaction/externalcontrol/joystickexternalcontrol.cpp.orig b/src/interaction/externalcontrol/joystickexternalcontrol.cpp.orig new file mode 100644 index 0000000000..390295e748 --- /dev/null +++ b/src/interaction/externalcontrol/joystickexternalcontrol.cpp.orig @@ -0,0 +1,63 @@ +#include "externalcontrol/joystickexternalcontrol.h" +#include "deviceidentifier.h" + +// workaround since Python debug does not work on windows +#ifdef _DEBUG +#undef _DEBUG +#include +#define _DEBUG +#else +#include +#endif + +namespace openspace { + + +JoystickExternalControl::JoystickExternalControl(const char *filename): PythonExternalControl(filename) { +} + +void JoystickExternalControl::setInputDevice(const int device) { + if(device >= 0 && device <= 16) { + inputDevice_ = device; + numberOfButtons_ = DeviceIdentifier::ref().getButtons(inputDevice_); + numberOfAxes_ = DeviceIdentifier::ref().getAxes(inputDevice_); + clear(); + pyarrSize_ = numberOfButtons_ + numberOfAxes_; + pyarr_ = new PyObject*[pyarrSize_]; + } + +} + +void JoystickExternalControl::update() { + + if(inputDevice_ != -1) { + float *axesPos; + unsigned char *buttons; + DeviceIdentifier::ref().getButtons(inputDevice_, &buttons); + DeviceIdentifier::ref().getAxes(inputDevice_, &axesPos); + + // init array + for(int i = 0; i < numberOfButtons_; ++i){ + pyarr_[i] = PyLong_FromLong(buttons[i]); + } + for(int i = 0; i < numberOfAxes_; ++i){ + pyarr_[i+numberOfButtons_] = PyFloat_FromDouble(axesPos[i]); + } + } + + run(); + + if(inputDevice_ != -1) { + // cleanup + //for(int i = 0; i < pyarrSize_; ++i) { + // Py_XDECREF(pyarr_[i]); + //} + } + +} + +JoystickExternalControl::~JoystickExternalControl() { +} + +} // namespace openspace + diff --git a/src/interaction/externalcontrol/joystickexternalcontrol.h b/src/interaction/externalcontrol/joystickexternalcontrol.h new file mode 100644 index 0000000000..9416c6b202 --- /dev/null +++ b/src/interaction/externalcontrol/joystickexternalcontrol.h @@ -0,0 +1,28 @@ +//#ifndef JOYSTICKEXTERNALCONTROL_H +//#define JOYSTICKEXTERNALCONTROL_H +// +//#include "externalcontrol/pythonexternalcontrol.h" +// +//namespace openspace { +// +//class JoystickExternalControl: public PythonExternalControl { +//public: +// +// // constructors & destructor +// JoystickExternalControl(const char *filename); +// ~JoystickExternalControl(); +// +// void setInputDevice(const int device); +// void update(); +// +//private: +// +// // joystick +// int inputDevice_; +// int numberOfButtons_; +// int numberOfAxes_; +//}; +// +//} // namespace openspace +// +//#endif \ No newline at end of file diff --git a/src/interaction/externalcontrol/keyboardexternalcontrol.cpp b/src/interaction/externalcontrol/keyboardexternalcontrol.cpp new file mode 100644 index 0000000000..9715da5326 --- /dev/null +++ b/src/interaction/externalcontrol/keyboardexternalcontrol.cpp @@ -0,0 +1,62 @@ +//#include "externalcontrol/keyboardexternalcontrol.h" +// +//// workaround since Python debug does not work on windows +//#ifdef _DEBUG +//#undef _DEBUG +//#include +//#define _DEBUG +//#else +//#include +//#endif +// +// +//namespace openspace { +// +// +//KeyboardExternalControl::KeyboardExternalControl(const char *filename): PythonExternalControl(filename) { +// clear(); +// pyarrSize_ = 'Z' - 'A' + 80; // all letters, 69 special keys, space and 10 numbers +// pyarr_ = new PyObject*[pyarrSize_]; +// for(int i = 0; i < pyarrSize_; ++i) { +// pyarr_[i] = PyLong_FromLong(0); +// } +//} +// +//void KeyboardExternalControl::keyboardCallback(int key, int action) { +// +// //printf("key: %i\n",key); +// int pos = -1; +// if(key >= '0' && key <= '9') { +// pos = key - '0'; +// Py_XDECREF(pyarr_[pos]); +// pyarr_[pos] = PyLong_FromLong(action); +// } else if(key >= 'A' && key <= 'Z') { +// pos = key - 'A' + 10; +// Py_XDECREF(pyarr_[pos]); +// pyarr_[pos] = PyLong_FromLong(action); +// } else if (key > 256 && key < 256+69) { +// pos = key - 256 + 'Z'-'A' +10; +// Py_XDECREF(pyarr_[pos]); +// pyarr_[pos] = PyLong_FromLong(action); +// } else if (key == 32) { +// pos = 'Z' - 'A' + 11; +// Py_XDECREF(pyarr_[pos]); +// pyarr_[pos] = PyLong_FromLong(action); +// } +// //printf("pos: %i\n",pos); +//} +// +// +// +//void KeyboardExternalControl::update() { +// run(); +//} +// +//KeyboardExternalControl::~KeyboardExternalControl() { +// for(int i = 0; i < pyarrSize_; ++i) { +// Py_XDECREF(pyarr_[i]); +// } +//} +// +//} // namespace openspace +// diff --git a/src/interaction/externalcontrol/keyboardexternalcontrol.cpp.orig b/src/interaction/externalcontrol/keyboardexternalcontrol.cpp.orig new file mode 100644 index 0000000000..0b90506247 --- /dev/null +++ b/src/interaction/externalcontrol/keyboardexternalcontrol.cpp.orig @@ -0,0 +1,62 @@ +#include "externalcontrol/keyboardexternalcontrol.h" + +// workaround since Python debug does not work on windows +#ifdef _DEBUG +#undef _DEBUG +#include +#define _DEBUG +#else +#include +#endif + + +namespace openspace { + + +KeyboardExternalControl::KeyboardExternalControl(const char *filename): PythonExternalControl(filename) { + clear(); + pyarrSize_ = 'Z' - 'A' + 80; // all letters, 69 special keys, space and 10 numbers + pyarr_ = new PyObject*[pyarrSize_]; + for(int i = 0; i < pyarrSize_; ++i) { + pyarr_[i] = PyLong_FromLong(0); + } +} + +void KeyboardExternalControl::keyboardCallback(int key, int action) { + + //printf("key: %i\n",key); + int pos = -1; + if(key >= '0' && key <= '9') { + pos = key - '0'; + //Py_XDECREF(pyarr_[pos]); + pyarr_[pos] = PyLong_FromLong(action); + } else if(key >= 'A' && key <= 'Z') { + pos = key - 'A' + 10; + //Py_XDECREF(pyarr_[pos]); + pyarr_[pos] = PyLong_FromLong(action); + } else if (key > 256 && key < 256+69) { + pos = key - 256 + 'Z'-'A' +10; + //Py_XDECREF(pyarr_[pos]); + pyarr_[pos] = PyLong_FromLong(action); + } else if (key == 32) { + pos = 'Z' - 'A' + 11; + //Py_XDECREF(pyarr_[pos]); + pyarr_[pos] = PyLong_FromLong(action); + } + //printf("pos: %i\n",pos); +} + + + +void KeyboardExternalControl::update() { + run(); +} + +KeyboardExternalControl::~KeyboardExternalControl() { + //for(int i = 0; i < pyarrSize_; ++i) { + // Py_XDECREF(pyarr_[i]); + //} +} + +} // namespace openspace + diff --git a/src/interaction/externalcontrol/keyboardexternalcontrol.h b/src/interaction/externalcontrol/keyboardexternalcontrol.h new file mode 100644 index 0000000000..6e331e69b8 --- /dev/null +++ b/src/interaction/externalcontrol/keyboardexternalcontrol.h @@ -0,0 +1,25 @@ +//#ifndef KEYBOARDEXTERNALCONTROL_H +//#define KEYBOARDEXTERNALCONTROL_H +// +//#include "externalcontrol/pythonexternalcontrol.h" +// +//namespace openspace { +// +//class KeyboardExternalControl: public PythonExternalControl { +//public: +// +// // constructors & destructor +// KeyboardExternalControl(const char *filename); +// ~KeyboardExternalControl(); +// +// void update(); +// +// void keyboardCallback(int key, int action); +//private: +// int *keys_; +// +//}; +// +//} // namespace openspace +// +//#endif \ No newline at end of file diff --git a/src/interaction/externalcontrol/mouseexternalcontrol.cpp b/src/interaction/externalcontrol/mouseexternalcontrol.cpp new file mode 100644 index 0000000000..d9da0d00dc --- /dev/null +++ b/src/interaction/externalcontrol/mouseexternalcontrol.cpp @@ -0,0 +1,79 @@ +//#include "externalcontrol/mouseexternalcontrol.h" +// +//// workaround since Python debug does not work on windows +//#ifdef _DEBUG +//#undef _DEBUG +//#include +//#define _DEBUG +//#else +//#include +//#endif +// +// +//namespace openspace { +// +// +//MouseExternalControl::MouseExternalControl(const char *filename): PythonExternalControl(filename) { +// clear(); +// pyarrSize_ = 6*2; +// pyarr_ = new PyObject*[pyarrSize_]; +// x_ = 0; +// y_ = 0; +// pos_ = 0; +// button1_ = 0; +// button2_ = 0; +// button3_ = 0; +// for(int i = 0; i < pyarrSize_; ++i) { +// pyarr_[i] = PyLong_FromLong(0);; +// } +// +//} +// +//void MouseExternalControl::mouseButtonCallback(int key, int action) { +// if(key == 0) +// button1_ = action; +// if(key == 1) +// button2_ = action; +// if(key == 2) +// button3_ = action; +//} +// +//void MouseExternalControl::mousePosCallback(int x, int y) { +// x_ = x; +// y_ = y; +//} +// +//void MouseExternalControl::mouseScrollCallback(int pos) { +// pos_ = pos; +//} +// +//void MouseExternalControl::update() { +// +// pyarr_[6] = pyarr_[0]; +// pyarr_[7] = pyarr_[1]; +// pyarr_[8] = pyarr_[2]; +// pyarr_[9] = pyarr_[3]; +// pyarr_[10] = pyarr_[4]; +// pyarr_[11] = pyarr_[5]; +// pyarr_[0] = PyLong_FromLong(button1_); +// pyarr_[1] = PyLong_FromLong(button2_); +// pyarr_[2] = PyLong_FromLong(button3_); +// pyarr_[3] = PyLong_FromLong(pos_); +// pyarr_[4] = PyLong_FromLong(x_); +// pyarr_[5] = PyLong_FromLong(y_); +// +// run(); +// +// // cleanup +// for(int i = pyarrSize_ / 2; i < pyarrSize_; ++i) { +// Py_XDECREF(pyarr_[i]); +// } +// +//} +// +//MouseExternalControl::~MouseExternalControl() { +// +//} +// +//} // namespace openspace +// diff --git a/src/interaction/externalcontrol/mouseexternalcontrol.cpp.orig b/src/interaction/externalcontrol/mouseexternalcontrol.cpp.orig new file mode 100644 index 0000000000..b365a02c03 --- /dev/null +++ b/src/interaction/externalcontrol/mouseexternalcontrol.cpp.orig @@ -0,0 +1,79 @@ +#include "externalcontrol/mouseexternalcontrol.h" + +// workaround since Python debug does not work on windows +#ifdef _DEBUG +#undef _DEBUG +#include +#define _DEBUG +#else +#include +#endif + + +namespace openspace { + + +MouseExternalControl::MouseExternalControl(const char *filename): PythonExternalControl(filename) { + clear(); + pyarrSize_ = 6*2; + pyarr_ = new PyObject*[pyarrSize_]; + x_ = 0; + y_ = 0; + pos_ = 0; + button1_ = 0; + button2_ = 0; + button3_ = 0; + for(int i = 0; i < pyarrSize_; ++i) { + pyarr_[i] = PyLong_FromLong(0);; + } + +} + +void MouseExternalControl::mouseButtonCallback(int key, int action) { + if(key == 0) + button1_ = action; + if(key == 1) + button2_ = action; + if(key == 2) + button3_ = action; +} + +void MouseExternalControl::mousePosCallback(int x, int y) { + x_ = x; + y_ = y; +} + +void MouseExternalControl::mouseScrollCallback(int pos) { + pos_ = pos; +} + +void MouseExternalControl::update() { + + pyarr_[6] = pyarr_[0]; + pyarr_[7] = pyarr_[1]; + pyarr_[8] = pyarr_[2]; + pyarr_[9] = pyarr_[3]; + pyarr_[10] = pyarr_[4]; + pyarr_[11] = pyarr_[5]; + pyarr_[0] = PyLong_FromLong(button1_); + pyarr_[1] = PyLong_FromLong(button2_); + pyarr_[2] = PyLong_FromLong(button3_); + pyarr_[3] = PyLong_FromLong(pos_); + pyarr_[4] = PyLong_FromLong(x_); + pyarr_[5] = PyLong_FromLong(y_); + + run(); + + // cleanup + //for(int i = pyarrSize_ / 2; i < pyarrSize_; ++i) { + // Py_XDECREF(pyarr_[i]); + //} + +} + +MouseExternalControl::~MouseExternalControl() { + +} + +} // namespace openspace + diff --git a/src/interaction/externalcontrol/mouseexternalcontrol.h b/src/interaction/externalcontrol/mouseexternalcontrol.h new file mode 100644 index 0000000000..890a741733 --- /dev/null +++ b/src/interaction/externalcontrol/mouseexternalcontrol.h @@ -0,0 +1,28 @@ +//#ifndef MOUSEEXTERNALCONTROL_H +//#define MOUSEEXTERNALCONTROL_H +// +//#include "externalcontrol/pythonexternalcontrol.h" +// +//namespace openspace { +// +//class MouseExternalControl: public PythonExternalControl { +//public: +// +// // constructors & destructor +// MouseExternalControl(const char *filename); +// ~MouseExternalControl(); +// +// void update(); +// +// void mouseButtonCallback(int key, int action); +// void mousePosCallback(int x, int y); +// void mouseScrollCallback(int pos); +//private: +// +// int x_, y_, pos_, button1_, button2_, button3_; +// +//}; +// +//} // namespace openspace +// +//#endif \ No newline at end of file diff --git a/src/interaction/externalcontrol/pythonexternalcontrol.cpp b/src/interaction/externalcontrol/pythonexternalcontrol.cpp new file mode 100644 index 0000000000..ac95c3639a --- /dev/null +++ b/src/interaction/externalcontrol/pythonexternalcontrol.cpp @@ -0,0 +1,147 @@ +//#include "externalcontrol/pythonexternalcontrol.h" +// +//// workaround since Python debug does not work on windows +//#ifdef _DEBUG +//#undef _DEBUG +//#include +//#define _DEBUG +//#else +//#include +//#endif +// +//#include +//#include +//#include +//#include +//#include "deviceidentifier.h" +// +//#include "util/pss.h" +//#include "externalcontrol/externalcontrol.h" +//#include "interactionhandler.h" +// +//namespace openspace { +// +// +//// defining python callback functions +//static PyObject* pyexcontrol_numargs(PyObject *self, PyObject *args) { +// if(!PyArg_ParseTuple(args, ":pyexcontrol_numargs")) +// return NULL; +// return PyLong_FromLong(10); +//} +// +//static PyObject* pyexcontrol_message(PyObject *self, PyObject *args) +//{ +// char* text = 0; +// if(!PyArg_ParseTuple(args, "s:pyexcontrol_yeah",&text)) +// Py_RETURN_NONE; +// +// PythonExternalControl * ext = 0; +// ext->message(text); +// +// Py_RETURN_NONE; +//} +// +//static PyObject* pyexcontrol_rotateCamera(PyObject *self, PyObject *args) +//{ +// char* text = 0; +// float f1 = 0; +// float f2 = 0; +// float f3 = 0; +// float f4 = 0; +// if(!PyArg_ParseTuple(args, "fff:pyexcontrol_rotateCamera",&f1,&f2,&f3)) +// Py_RETURN_NONE; +// +// double dt = InteractionHandler::ref().getDt(); +// glm::vec3 EulerAngles(f1*dt,f2*dt, f3*dt); +// glm::quat rot = glm::quat(EulerAngles); +// ExternalControl * ext = 0; +// ext->rotate(rot); +// +// Py_RETURN_NONE; +//} +// +//static PyObject* pyexcontrol_orbitCamera(PyObject *self, PyObject *args) +//{ +// char* text = 0; +// float f1 = 0; +// float f2 = 0; +// float f3 = 0; +// if(!PyArg_ParseTuple(args, "fff:pyexcontrol_rotateCamera",&f1,&f2,&f3)) +// Py_RETURN_NONE; +// +// double dt = InteractionHandler::ref().getDt(); +// glm::vec3 EulerAngles(f1*dt,f2*dt, f3*dt); +// glm::quat rot = glm::quat(EulerAngles); +// ExternalControl * ext = 0; +// ext->orbit(rot); +// +// Py_RETURN_NONE; +//} +// +//static PyObject* pyexcontrol_distance(PyObject *self, PyObject *args) +//{ +// char* text = 0; +// float f1 = 0; +// float f2 = 0; +// if(!PyArg_ParseTuple(args, "ff:pyexcontrol_rotateCamera",&f1,&f2)) +// Py_RETURN_NONE; +// +// float dt = static_cast(InteractionHandler::ref().getDt()); +// pss dist(f1*dt,f2); +// ExternalControl * ext = 0; +// ext->distance(dist); +// +// Py_RETURN_NONE; +//} +// +//PyMethodDef* PythonExternalControl::getMethodDef() { +// // creating the python callback function table +// static PyMethodDef pyexcontrol_methods[] = { +// {"numargs", pyexcontrol_numargs, METH_VARARGS, "function"}, +// {"message", pyexcontrol_message, METH_VARARGS, "function"}, +// {"rotate", pyexcontrol_rotateCamera, METH_VARARGS, "function"}, +// {"orbit", pyexcontrol_orbitCamera, METH_VARARGS, "function"}, +// {"distance", pyexcontrol_distance, METH_VARARGS, "function"}, +// {NULL, NULL, 0, NULL} +// }; +// return pyexcontrol_methods; +//} +// +//void PythonExternalControl::message(const char *text) { +// +// printf("Input message from PythonScript: %s\n", text); +//} +// +//PythonExternalControl::PythonExternalControl(const char *filename) { +// pyarr_ = nullptr; +// ps_.load(filename, true); +//} +// +// +//void PythonExternalControl::update() { +// run(); +//} +// +//void PythonExternalControl::run() { +// if(pyarrSize_ > 0) +// ps_.run(pyarrSize_, pyarr_); +// else +// ps_.run(); +//} +// +// +//void PythonExternalControl::clear() { +// if(pyarr_ != nullptr) { +// // cleanup +// delete pyarr_; +// pyarr_ = nullptr; +// pyarrSize_ = 0; +// } +//} +// +//PythonExternalControl::~PythonExternalControl() { +// clear(); +//} +// +//} // namespace openspace +// diff --git a/src/interaction/externalcontrol/pythonexternalcontrol.h b/src/interaction/externalcontrol/pythonexternalcontrol.h new file mode 100644 index 0000000000..8a01d6f571 --- /dev/null +++ b/src/interaction/externalcontrol/pythonexternalcontrol.h @@ -0,0 +1,35 @@ +//#ifndef PYTHONEXTERNALCONTROL_H +//#define PYTHONEXTERNALCONTROL_H +// +//#include +//#include +// +//#include "externalcontrol/externalcontrol.h" +//#include "python/pythonscript.h" +// +//namespace openspace { +// +//class PythonExternalControl: public ExternalControl { +//public: +// +// // constructors & destructor +// PythonExternalControl(const char *filename); +// ~PythonExternalControl(); +// +// static PyMethodDef* getMethodDef(); +// +// void message(const char *text); +// virtual void update(); +// void clear(); +//private: +// PythonScript ps_; +// +//protected: +// void run(); +// int pyarrSize_; +// PyObject **pyarr_; +//}; +// +//} // namespace openspace +// +//#endif \ No newline at end of file diff --git a/src/interaction/externalcontrol/randomexternalcontrol.cpp b/src/interaction/externalcontrol/randomexternalcontrol.cpp new file mode 100644 index 0000000000..feca3b9b7d --- /dev/null +++ b/src/interaction/externalcontrol/randomexternalcontrol.cpp @@ -0,0 +1,59 @@ +#include "interaction/externalcontrol/randomexternalcontrol.h" + +#include +#ifndef __WIN32__ + #include +#endif + +namespace openspace { + +typedef struct +{ + bool *keepGoing; + double *dx; +} parm; + +void *updatedx(void * arg) { + parm *p = (parm*) arg; + bool *kg = p->keepGoing; + double *dx = p->dx; + while( *kg ) { + //printf("Hello world!\n"); + *dx = *dx + 0.5; + + // random sleep time + int diff = rand() % 200; + +#ifndef __WIN32__ + usleep(10000*diff); +#endif + } + delete p; + return NULL; +} + + +RandomExternalControl::RandomExternalControl() { + /* + inputGuard = PTHREAD_MUTEX_INITIALIZER; + + pthread_attr_t pthread_custom_attr; + pthread_attr_init(&pthread_custom_attr); + keepGoing_ = new bool; + *keepGoing_ = true; + parm *p = (parm*)malloc(sizeof(parm)); + p->keepGoing = keepGoing_; + p->dx = &dx_; + + pthread_create(&backgroundThread, &pthread_custom_attr, updatedx, (void*)p); + */ +} + +RandomExternalControl::~RandomExternalControl() { + *keepGoing_ = false; + //pthread_join(backgroundThread, NULL); + delete keepGoing_; +} + +} // namespace openspace + diff --git a/src/interaction/externalcontrol/randomexternalcontrol.h b/src/interaction/externalcontrol/randomexternalcontrol.h new file mode 100644 index 0000000000..6b5347b320 --- /dev/null +++ b/src/interaction/externalcontrol/randomexternalcontrol.h @@ -0,0 +1,26 @@ +#ifndef RANDOMEXTERNALCONTROL_H +#define RANDOMEXTERNALCONTROL_H + +#include +#include + +#include "interaction/externalcontrol/externalcontrol.h" + +namespace openspace { + +class RandomExternalControl: public ExternalControl { +public: + + // constructors & destructor + RandomExternalControl(); + ~RandomExternalControl(); + +private: + std::mutex inputGuard; + bool *keepGoing_; + std::thread *backgroundThread; +}; + +} // namespace openspace + +#endif \ No newline at end of file diff --git a/src/interaction/interactionhandler.cpp b/src/interaction/interactionhandler.cpp new file mode 100644 index 0000000000..2dbc178d1d --- /dev/null +++ b/src/interaction/interactionhandler.cpp @@ -0,0 +1,326 @@ + +// open space includes +#include "interactionhandler.h" +#include "deviceidentifier.h" +#include "externalcontrol/randomexternalcontrol.h" +#include "externalcontrol/joystickexternalcontrol.h" +#include "query/query.h" +#include "openspaceengine.h" + +// std includes +#include + +namespace openspace { + +InteractionHandler::InteractionHandler() { + + // initiate pointers + camera_ = nullptr; + enabled_ = true; + node_ = nullptr; + dt_ = 0.0; +} + +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::enable() { + //assert(this_); + enabled_ = true; +} + +void InteractionHandler::disable() { + //assert(this_); + enabled_ = false; +} + +const bool InteractionHandler::isEnabled() const { + //assert(this_); + if (camera_) + return false; + return enabled_; +} + +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 { + //assert(this_); + if (enabled_) + { + return camera_; + } + return nullptr; +} + +const psc InteractionHandler::getOrigin() const { + if(node_) + return node_->getWorldPosition(); + 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_->getPosition(); + + // should be changed to something more dynamic =) + psc origin; + if(node_) { + origin = node_->getWorldPosition(); + } + + psc relative_origin_coordinate = relative - origin; + glm::mat4 rotation_matrix = glm::mat4_cast(rotation); + relative_origin_coordinate = relative_origin_coordinate.mul(rotation_matrix); + relative = relative_origin_coordinate + origin; + + camera_->setPosition(relative); + + unlockControls(); +} + +void InteractionHandler::distance(const pss &distance) { + //assert(this_); + lockControls(); + + + psc relative = camera_->getPosition(); + psc origin; + if(node_) { + origin = node_->getWorldPosition(); + } + + psc relative_origin_coordinate = relative - origin; + glm::dvec3 dir = relative_origin_coordinate.getDirection(); + dir = dir * distance[0]; + relative_origin_coordinate = dir; + relative_origin_coordinate[3] = distance[1]; + relative = relative + relative_origin_coordinate; + + 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 (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::getDt() { + //assert(this_); + return dt_; +} + +void InteractionHandler::keyboardCallback(int key, int action) { + // TODO package in script + const double speed = 0.75; + const double dt = getDt(); + if (key == 'S') { + glm::vec3 euler(speed * dt, 0.0, 0.0); + glm::quat rot = glm::quat(euler); + orbit(rot); + } + if (key == 'W') { + glm::vec3 euler(-speed * dt, 0.0, 0.0); + glm::quat rot = glm::quat(euler); + orbit(rot); + } + if (key == 'A') { + glm::vec3 euler(0.0, -speed * dt, 0.0); + glm::quat rot = glm::quat(euler); + orbit(rot); + } + if (key == 'D') { + glm::vec3 euler(0.0, speed * dt, 0.0); + glm::quat rot = glm::quat(euler); + orbit(rot); + } + 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 == 'R') { + pss dist(-speed * dt, 8.0); + distance(dist); + } + if (key == 'F') { + pss dist(speed * dt, 8.0); + distance(dist); + } + 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)); + } + +} + +void InteractionHandler::mouseButtonCallback(int key, int action) { + //if(mouseControl_ != nullptr) { + // mouseControl_->mouseButtonCallback(key,action); + //} +} + +void InteractionHandler::mousePositionCallback(int x, int y) { + //if(mouseControl_ != nullptr) { + // mouseControl_->mousePosCallback(x,y); + //} +} + +void InteractionHandler::mouseScrollWheelCallback(int pos) { + //if(mouseControl_ != nullptr) { + // mouseControl_->mouseScrollCallback(pos); + //} +} + + +} // namespace openspace \ No newline at end of file diff --git a/src/interaction/interactionhandler.h b/src/interaction/interactionhandler.h new file mode 100644 index 0000000000..393fdea4a5 --- /dev/null +++ b/src/interaction/interactionhandler.h @@ -0,0 +1,89 @@ +#ifndef INTERACTIONHANDLER_H +#define INTERACTIONHANDLER_H + +// open space includes +#include "util/camera.h" +#include "externalcontrol/externalcontrol.h" +#include "scenegraph/scenegraphnode.h" + +// std includes +#include +#include +#include +#include + +// hack until we have a file/path manager +//#ifdef __WIN32__ +//#ifdef NDEBUG +//#define RELATIVE_PATH "" +//#else +//#define RELATIVE_PATH "../../../" +//#endif +//#else +//#define RELATIVE_PATH "../" +//#endif + +namespace openspace { + +class InteractionHandler { +public: + InteractionHandler(void); + InteractionHandler(const InteractionHandler& src); + InteractionHandler& operator=(const InteractionHandler& rhs); + virtual ~InteractionHandler(); + + //static void init(); + //static void deinit(); + // static InteractionHandler& ref(); + //static bool isInitialized(); + + void enable(); + void disable(); + const bool isEnabled() const; + + void connectDevices(); + void addExternalControl(ExternalControl* controller); + + void setCamera(Camera *camera = nullptr); + Camera * getCamera() const; + const psc getOrigin() const; + void lockControls(); + void unlockControls(); + + void setFocusNode(SceneGraphNode *node); + + void orbit(const glm::quat &rotation); + void rotate(const glm::quat &rotation); + void distance(const pss &distance); + + void lookAt(const glm::quat &rotation); + void setRotation(const glm::quat &rotation); + + void update(const double dt); + + double getDt(); + + void keyboardCallback(int key, int action); + void mouseButtonCallback(int key, int action); + void mousePositionCallback(int x, int y); + void mouseScrollWheelCallback(int pos); + +private: + + Camera *camera_; + bool enabled_; + SceneGraphNode *node_; + + double dt_; + + // used for calling when updating and deallocation + std::vector controllers_; + + // for locking and unlocking + std::mutex cameraGuard_; + +}; + +} // namespace openspace + +#endif \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index fe4f88182b..60c4ed9cc7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,6 @@ // open space includes -#include "engine/openspaceengine.h" +#include "openspaceengine.h" // sgct includes #include "sgct.h" @@ -14,6 +14,7 @@ #include #include #include +#include // graphics and openspace engines sgct::Engine * gEngine; @@ -82,65 +83,84 @@ static void stackDump (lua_State *L) { } int main(int argc, char **argv) { - ghoul::filesystem::FileSystem::initialize(); - //FileSys.registerPathToken("${BASE_PATH}", "../../.."); - FileSys.registerPathToken("${BASE_PATH}", "../.."); - FileSys.registerPathToken("${SCRIPTS}", "${BASE_PATH}/scripts"); +#if 0 + LARGE_INTEGER t1; + QueryPerformanceCounter(&t1); + lua_State* l = luaL_newstate(); + LARGE_INTEGER t2; + QueryPerformanceCounter(&t2); - //LARGE_INTEGER t1; - //QueryPerformanceCounter(&t1); - //lua_State* l = luaL_newstate(); - //LARGE_INTEGER t2; - //QueryPerformanceCounter(&t2); + luaL_openlibs(l); + LARGE_INTEGER t3; + QueryPerformanceCounter(&t3); - //luaL_openlibs(l); - //LARGE_INTEGER t3; - //QueryPerformanceCounter(&t3); - //if (luaL_loadfile(l, p("${SCRIPTS}/script.lua").c_str())) { - // std::cerr << lua_tostring(l, -1) << std::endl; - // return EXIT_SUCCESS; - //} - //LARGE_INTEGER t4; - //QueryPerformanceCounter(&t4); + //std::ifstream file("../../scripts/script.lua"); + //int length; + //file.seekg(0, std::ios::end); // go to the end + //length = file.tellg(); // report location (this is the length) + //file.seekg(0, std::ios::beg); // go back to the beginning + //char* buffer = new char[length]; // allocate memory for a buffer of appropriate dimension + //file.read(buffer, length); // read the whole file into the buffer + //file.close(); - //if (lua_pcall(l,0, LUA_MULTRET, 0)) { - // std::cerr << lua_tostring(l, -1) << std::endl; - // return EXIT_SUCCESS; - //} - //LARGE_INTEGER t5; - //QueryPerformanceCounter(&t5); + //if (luaL_loadstring(l, buffer)) { + if (luaL_loadfile(l, "../../scripts/script.lua")) { + std::cerr << lua_tostring(l, -1) << std::endl; + return EXIT_SUCCESS; + } + LARGE_INTEGER t4; + QueryPerformanceCounter(&t4); + + if (lua_pcall(l,0, LUA_MULTRET, 0)) { + std::cerr << lua_tostring(l, -1) << std::endl; + return EXIT_SUCCESS; + } + LARGE_INTEGER t5; + QueryPerformanceCounter(&t5); //stackDump(l); - //lua_getglobal(l, "t"); - //std::cout << lua_istable(l, -1) << std::endl; + lua_getglobal(l, "config"); + std::cout << "Table|Function|NIL|bool|thread|none|noneornil" << std::endl; + std::cout << lua_istable(l, -1) << "|" << + lua_isfunction(l, -1) << "|" << + lua_isnil(l, -1) << "|" << + lua_isboolean(l, -1) << "|" << + lua_isthread(l, -1) << "|" << + lua_isnone(l, -1) << "|" << + lua_isnoneornil(l, -1) << "|" << + std::endl; - //stackDump(l); - // - // - // - //lua_close(l); - //LARGE_INTEGER t6; - //QueryPerformanceCounter(&t6); + stackDump(l); + + + + lua_close(l); + LARGE_INTEGER t6; + QueryPerformanceCounter(&t6); - //// -------- - //LARGE_INTEGER freq; - //QueryPerformanceFrequency(&freq); + // -------- + LARGE_INTEGER freq; + QueryPerformanceFrequency(&freq); - //std::cout << "State: " << ((t2.QuadPart - t1.QuadPart) / double(freq.QuadPart)) * 1000 << std::endl; - //std::cout << "Libs : " << ((t3.QuadPart - t2.QuadPart) / double(freq.QuadPart)) * 1000 << std::endl; - //std::cout << "Load : " << ((t4.QuadPart - t3.QuadPart) / double(freq.QuadPart)) * 1000 << std::endl; - //std::cout << "Exec : " << ((t5.QuadPart - t4.QuadPart) / double(freq.QuadPart)) * 1000 << std::endl; - //std::cout << "Close: " << ((t6.QuadPart - t5.QuadPart) / double(freq.QuadPart)) * 1000 << std::endl; + std::cout << "State: " << ((t2.QuadPart - t1.QuadPart) / double(freq.QuadPart)) * 1000 << std::endl; + std::cout << "Libs : " << ((t3.QuadPart - t2.QuadPart) / double(freq.QuadPart)) * 1000 << std::endl; + std::cout << "Load : " << ((t4.QuadPart - t3.QuadPart) / double(freq.QuadPart)) * 1000 << std::endl; + std::cout << "Exec : " << ((t5.QuadPart - t4.QuadPart) / double(freq.QuadPart)) * 1000 << std::endl; + std::cout << "Close: " << ((t6.QuadPart - t5.QuadPart) / double(freq.QuadPart)) * 1000 << std::endl; - // - //exit(EXIT_SUCCESS); + + exit(EXIT_SUCCESS); + +#endif + + openspace::OpenSpaceEngine::create(argc, argv); char* cmd = "-config"; - const std::string pathStr = p("${BASE_PATH}/config/single.xml"); + const std::string pathStr = p("${BASE_PATH}/config/single_sbs_stereo.xml"); char* path = _strdup(pathStr.c_str()); char** newArgv = new char*[3]; int newArgc = 3; @@ -148,8 +168,6 @@ int main(int argc, char **argv) { newArgv[1] = cmd; newArgv[2] = path; - openspace::OpenSpaceEngine::create(argc, argv); - // allocate sgct- and openspace engine objects gEngine = new sgct::Engine( newArgc, newArgv ); diff --git a/src/openspaceengine.cpp b/src/openspaceengine.cpp new file mode 100644 index 0000000000..bf5441044f --- /dev/null +++ b/src/openspaceengine.cpp @@ -0,0 +1,247 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include "openspaceengine.h" + +// sgct header has to be included before all others due to Windows header +#include "sgct.h" + +#include "interaction/deviceidentifier.h" +#include "interaction/interactionhandler.h" +#include "rendering/renderengine.h" +#include "util/time.h" +#include "util//spice.h" + +#include +#include + +using namespace ghoul::filesystem; +using namespace ghoul::logging; + +namespace { + const std::string _loggerCat = "OpenSpaceEngine"; +} + +namespace openspace { + +OpenSpaceEngine* OpenSpaceEngine::_engine = nullptr; + +OpenSpaceEngine::OpenSpaceEngine() + : _configurationManager(nullptr) + , _interactionHandler(nullptr) + , _renderEngine(nullptr) + , _scriptEngine(nullptr) +{ + +} + +OpenSpaceEngine::~OpenSpaceEngine() { + delete _configurationManager; + delete _interactionHandler; + delete _renderEngine; + //delete _scriptEngine; + + Spice::deinit(); + Time::deinit(); + DeviceIdentifier::deinit(); + LogManager::deinitialize(); +} + +OpenSpaceEngine& OpenSpaceEngine::ref() { + assert(_engine); + return *_engine; +} + +void OpenSpaceEngine::create(int& argc, char**& argv) { + // TODO add parsing of configuration file, configuration file loading + LogManager::initialize(LogManager::LogLevel::Info); + LogMgr.addLog(new ConsoleLog); + + ghoul::filesystem::FileSystem::initialize(); + FileSys.registerPathToken("${BASE_PATH}", "../.."); + FileSys.registerPathToken("${SCRIPTS}", "${BASE_PATH}/scripts"); + + + // TODO custom assert (ticket #5) + assert(_engine == nullptr); + _engine = new OpenSpaceEngine; + _engine->_renderEngine = new RenderEngine; + + _engine->_interactionHandler = new InteractionHandler; + + _engine->_configurationManager = new ConfigurationManager; +} + +void OpenSpaceEngine::destroy() { + delete _engine; +} + +bool OpenSpaceEngine::initialize() { + _configurationManager->initialize(); + _configurationManager->loadConfiguration(p("${SCRIPTS}/config.lua")); + + Time::init(); + Spice::init(); + Spice::ref().loadDefaultKernels(); + + // TODO add scenegraph file name + _renderEngine->initialize(""); + + DeviceIdentifier::init(); + DeviceIdentifier::ref().scanDevices(); + + _engine->_interactionHandler->connectDevices(); + + return true; +} + +ConfigurationManager& OpenSpaceEngine::configurationManager() { + // TODO custom assert (ticket #5) + assert(_configurationManager != nullptr); + return *_configurationManager; +} + +InteractionHandler& OpenSpaceEngine::interactionHandler() { + // TODO custom assert (ticket #5) + assert(_configurationManager != nullptr); + return *_interactionHandler; +} + +RenderEngine& OpenSpaceEngine::renderEngine() { + // TODO custom assert (ticket #5) + assert(_configurationManager != nullptr); + return *_renderEngine; +} + +bool OpenSpaceEngine::initializeGL() { + return _renderEngine->initializeGL(); +} + +void OpenSpaceEngine::preSynchronization() { + if (sgct::Engine::instance()->isMaster()) { + const double dt = sgct::Engine::instance()->getDt(); + + _interactionHandler->update(dt); + _interactionHandler->lockControls(); + } +} + +void OpenSpaceEngine::postSynchronizationPreDraw() { + _renderEngine->postSynchronizationPreDraw(); +} + +void OpenSpaceEngine::render() { + _renderEngine->render(); +} + +void OpenSpaceEngine::postDraw() { + if (sgct::Engine::instance()->isMaster()) + _interactionHandler->unlockControls(); +} + +void OpenSpaceEngine::keyboardCallback(int key, int action) { + _interactionHandler->keyboardCallback(key, action); +} + +void OpenSpaceEngine::mouseButtonCallback(int key, int action) { + _interactionHandler->mouseButtonCallback(key, action); +} + +void OpenSpaceEngine::mousePositionCallback(int x, int y) { + _interactionHandler->mousePositionCallback(x, y); +} + +void OpenSpaceEngine::mouseScrollWheelCallback(int pos) { + _interactionHandler->mouseScrollWheelCallback(pos); +} + +} // namespace openspace + +/* +void RenderEngine::encode() { + + // allocate a sgct shared double for syncing + sgct::SharedDouble *shDouble = new sgct::SharedDouble(); + + // sync the time + shDouble->setVal(masterTime_); + sharedDataInstance_->writeDouble(shDouble); + + // check that the camera has been allocated + if(mainCamera_ != nullptr) { + + // sync position + psc campos = mainCamera_->getPosition(); + for(int i = 0; i < 4; i++) { + shDouble->setVal(campos[i]); + sharedDataInstance_->writeDouble(shDouble); + } + + // sync view direction + glm::quat camrot = mainCamera_->getRotation(); + for(int i = 0; i < 4; i++) { + shDouble->setVal(camrot[i]); + sharedDataInstance_->writeDouble(shDouble); + } + } + + // deallocate + delete shDouble; + +} + +void RenderEngine::decode() { + + // allocate a sgct shared double for syncing + sgct::SharedDouble *shDouble = new sgct::SharedDouble(); + + // sync the time + sharedDataInstance_->readDouble(shDouble); + masterTime_ = shDouble->getVal(); + + // check that the camera has been allocated + if(mainCamera_ != nullptr) { + + // sync position + psc campos; + for(int i = 0; i < 4; i++) { + sharedDataInstance_->readDouble(shDouble); + campos[i] = shDouble->getVal(); + } + mainCamera_->setPosition(campos); + + // sync view direction + glm::quat camrot; + for(int i = 0; i < 4; i++) { + sharedDataInstance_->readDouble(shDouble); + camrot[i] = static_cast(shDouble->getVal()); + } + mainCamera_->setRotation(camrot); + } + + // deallocate + delete shDouble; + +} +*/ diff --git a/src/openspaceengine.h b/src/openspaceengine.h new file mode 100644 index 0000000000..af6b68e656 --- /dev/null +++ b/src/openspaceengine.h @@ -0,0 +1,109 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#ifndef __OPENSPACEENGINE_H__ +#define __OPENSPACEENGINE_H__ + +#include "configuration/configurationmanager.h" +#include "interaction/interactionhandler.h" +#include "rendering/renderengine.h" + +namespace openspace { + +class ScriptEngine; + +class OpenSpaceEngine { +public: + static void create(int& argc, char**& argv); + static void destroy(); + static OpenSpaceEngine& ref(); + + bool initialize(); + + ConfigurationManager& configurationManager(); + InteractionHandler& interactionHandler(); + RenderEngine& renderEngine(); + + // SGCT callbacks + bool initializeGL(); + void preSynchronization(); + void postSynchronizationPreDraw(); + void render(); + void postDraw(); + void keyboardCallback(int key, int action); + void mouseButtonCallback(int key, int action); + void mousePositionCallback(int x, int y); + void mouseScrollWheelCallback(int pos); + +private: + OpenSpaceEngine(); + ~OpenSpaceEngine(); + + static OpenSpaceEngine* _engine; + + ConfigurationManager* _configurationManager; + InteractionHandler* _interactionHandler; + RenderEngine* _renderEngine; + ScriptEngine* _scriptEngine; +}; + +#define OsEng (openspace::OpenSpaceEngine::ref()) + + /* +class RenderEngine: public Object { +public: + + // constructors & destructor + RenderEngine(int argc, char **argv); + ~RenderEngine(); + + // sgct wrapped functions + bool init(); + void preSync(); + void postSyncPreDraw(); + void render(); + void postDraw(); + void keyboardCallback(int key, int action); + void mouseButtonCallback(int key, int action); + void mousePosCallback(int x, int y); + void mouseScrollCallback(int pos); + + // object extensions + virtual void encode(); + virtual void decode(); + +private: + double masterTime_; + Camera *mainCamera_; + //MouseExternalControl *mouseControl_; + //KeyboardExternalControl *keyboardControl_; + + SceneGraph *sceneGraph_; + glm::vec3 eyePosition_; +}; +*/ + +} // namespace openspace + +#endif // __OPENSPACEENGINE_H__ diff --git a/src/query/query.cpp b/src/query/query.cpp new file mode 100644 index 0000000000..d905337d17 --- /dev/null +++ b/src/query/query.cpp @@ -0,0 +1,59 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include "query/query.h" + +#include "openspaceengine.h" + +namespace openspace { + +namespace { + const std::string _loggerCat = "Query"; + + SceneGraphNode* getSceneGraphNode(SceneGraphNode* thisNode, const std::string& name) { + if (thisNode->nodeName() == name) + return thisNode; + else { + for (auto it : thisNode->children()) { + SceneGraphNode* childNode = getSceneGraphNode(it, name); + if (childNode != nullptr) + return childNode; + } + return nullptr; + } + } +} + +SceneGraph* getSceneGraph() { + return OsEng.renderEngine().sceneGraph(); +} + +SceneGraphNode* getSceneGraphNode(const std::string& name) { + SceneGraph* sceneGraph = getSceneGraph(); + + SceneGraphNode* rootNode = sceneGraph->root(); + return getSceneGraphNode(rootNode, name); +} + +} // namespace diff --git a/src/query/query.h b/src/query/query.h new file mode 100644 index 0000000000..3d2bbd1249 --- /dev/null +++ b/src/query/query.h @@ -0,0 +1,41 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#ifndef __QUERY_H__ +#define __QUERY_H__ + +#include + +namespace openspace { + +class SceneGraph; +class SceneGraphNode; + +SceneGraph* getSceneGraph(); + +SceneGraphNode* getSceneGraphNode(const std::string& name); + +} // namespace + +#endif // __QUERY_H__ \ No newline at end of file diff --git a/src/rendering/renderable.cpp b/src/rendering/renderable.cpp new file mode 100644 index 0000000000..0819ce804a --- /dev/null +++ b/src/rendering/renderable.cpp @@ -0,0 +1,32 @@ + +// open space includes +#include "renderable.h" + +namespace openspace { + +Renderable::Renderable() { + +} + +Renderable::Renderable(const pss &boundingSphere) { + boundingSphere_ = boundingSphere; +} + +Renderable::~Renderable() { + +} + +void Renderable::setBoundingSphere(const pss &boundingSphere) { + boundingSphere_ = boundingSphere; +} + +const pss& Renderable::getBoundingSphere() { + return boundingSphere_; +} + +void Renderable::update() { +} + + + +} // namespace openspace \ No newline at end of file diff --git a/src/rendering/renderable.h b/src/rendering/renderable.h new file mode 100644 index 0000000000..389437c4e7 --- /dev/null +++ b/src/rendering/renderable.h @@ -0,0 +1,32 @@ +#ifndef RENDERABLE_H +#define RENDERABLE_H + +// open space includes +#include "util/psc.h" +#include "util/pss.h" +#include "util/camera.h" + +namespace openspace { + +class Renderable { +public: + + // constructors & destructor + Renderable(); + Renderable(const pss &boundingSphere); + virtual ~Renderable(); + + void setBoundingSphere(const pss &boundingSphere); + const pss &getBoundingSphere(); + + virtual void render(const Camera *camera, const psc &thisPosition) = 0; + virtual void update(); + +private: + pss boundingSphere_; + +}; + +} // namespace openspace + +#endif \ No newline at end of file diff --git a/src/rendering/renderablebody.cpp b/src/rendering/renderablebody.cpp new file mode 100644 index 0000000000..aa1afda9ed --- /dev/null +++ b/src/rendering/renderablebody.cpp @@ -0,0 +1,74 @@ + +// open space includes +#include "renderablebody.h" + +namespace openspace { + +RenderableBody::RenderableBody(const pss &radius):Renderable(radius) { + programObject_ = nullptr; + texture_ = nullptr; + rad_ = radius[0] * pow(10,radius[1]); + + // setup a unit sphere + planet_ = new gl4::Sphere(1.0f,30); + planet_->init(); +} + +RenderableBody::~RenderableBody() { + delete planet_; +} + +void RenderableBody::setProgramObject(ghoul::opengl::ProgramObject *programObject = nullptr) { + assert(programObject) ; + programObject_ = programObject; +} + +void RenderableBody::setTexture(ghoul::opengl::Texture *texture) { + assert(texture); + texture_ = texture; +} + +void RenderableBody::render(const Camera *camera, const psc &thisPosition) { + + // check so that the shader is set + assert(programObject_); + assert(texture_); + + // activate shader + programObject_->activate(); + + // fetch data + psc currentPosition = thisPosition; + psc campos = camera->getPosition(); + glm::mat4 camrot = camera->getViewRotationMatrix(); + + // scale the planet to appropriate size since the planet is a unit sphere + glm::mat4 transform = glm::mat4(1); + transform = glm::scale(transform, glm::vec3(rad_,rad_,rad_)); + + // setup the data to the shader + programObject_->setUniform("ViewProjection", camera->getViewProjectionMatrix()); + programObject_->setUniform("ModelTransform", transform); + programObject_->setUniform("campos", campos.getVec4f()); + programObject_->setUniform("objpos", currentPosition.getVec4f()); + programObject_->setUniform("camrot", camrot); + programObject_->setUniform("scaling", camera->getScaling()); + + // if texture is availible, use it + glActiveTexture(GL_TEXTURE0); + texture_->bind(); + programObject_->setUniform("texture1", 0); + + // render + planet_->render(); + + // disable shader + programObject_->deactivate(); + +} + +void RenderableBody::update() { + +} + +} // namespace openspace \ No newline at end of file diff --git a/src/rendering/renderablebody.h b/src/rendering/renderablebody.h new file mode 100644 index 0000000000..110663de16 --- /dev/null +++ b/src/rendering/renderablebody.h @@ -0,0 +1,37 @@ +#ifndef RENDERABLEBODY_H +#define RENDERABLEBODY_H + +// open space includes +#include "renderable.h" +#include "util/sphere.h" + +// ghoul includes +#include "ghoul/opengl/programobject.h" +#include "ghoul/opengl/texture.h" + +namespace openspace { + +class RenderableBody: public Renderable { +public: + + // constructors & destructor + RenderableBody(const pss &radius); + ~RenderableBody(); + + void setProgramObject(ghoul::opengl::ProgramObject *programObject); + void setTexture(ghoul::opengl::Texture *texture); + + virtual void render(const Camera *camera, const psc &thisPosition); + virtual void update(); + +private: + ghoul::opengl::ProgramObject *programObject_; + ghoul::opengl::Texture *texture_; + double rad_; + + gl4::Sphere *planet_; +}; + +} // namespace openspace + +#endif \ No newline at end of file diff --git a/src/rendering/renderableplanet.cpp b/src/rendering/renderableplanet.cpp new file mode 100644 index 0000000000..31a33c98db --- /dev/null +++ b/src/rendering/renderableplanet.cpp @@ -0,0 +1,71 @@ + +// open space includes +#include "renderableplanet.h" + +namespace openspace { + +RenderablePlanet::RenderablePlanet(const pss &radius):Renderable(radius) { + programObject_ = nullptr; + texture_ = nullptr; + + // setup a unit sphere + planet_ = new Planet(radius,30); +} + +RenderablePlanet::~RenderablePlanet() { + delete planet_; +} + +void RenderablePlanet::setProgramObject(ghoul::opengl::ProgramObject *programObject = nullptr) { + assert(programObject) ; + programObject_ = programObject; +} + +void RenderablePlanet::setTexture(ghoul::opengl::Texture *texture) { + assert(texture); + texture_ = texture; +} + +void RenderablePlanet::render(const Camera *camera, const psc &thisPosition) { + + // check so that the shader is set + assert(programObject_); + assert(texture_); + + // activate shader + programObject_->activate(); + + // fetch data + psc currentPosition = thisPosition; + psc campos = camera->getPosition(); + glm::mat4 camrot = camera->getViewRotationMatrix(); + + // scale the planet to appropriate size since the planet is a unit sphere + glm::mat4 transform = glm::mat4(1); + + // setup the data to the shader + programObject_->setUniform("ViewProjection", camera->getViewProjectionMatrix()); + programObject_->setUniform("ModelTransform", transform); + programObject_->setUniform("campos", campos.getVec4f()); + programObject_->setUniform("objpos", currentPosition.getVec4f()); + programObject_->setUniform("camrot", camrot); + programObject_->setUniform("scaling", camera->getScaling()); + + //// if texture is availible, use it + glActiveTexture(GL_TEXTURE0); + texture_->bind(); + programObject_->setUniform("texture1", 0); + + // render + planet_->render(); + + // disable shader + programObject_->deactivate(); + +} + +void RenderablePlanet::update() { + +} + +} // namespace openspace \ No newline at end of file diff --git a/src/rendering/renderableplanet.h b/src/rendering/renderableplanet.h new file mode 100644 index 0000000000..70547af11a --- /dev/null +++ b/src/rendering/renderableplanet.h @@ -0,0 +1,37 @@ +#ifndef RENDERABLEPLANET_H +#define RENDERABLEPLANET_H + +// open space includes +#include "renderable.h" +#include "util/planet.h" + +// ghoul includes +#include "ghoul/opengl/programobject.h" +#include "ghoul/opengl/texture.h" + +namespace openspace { + +class RenderablePlanet: public Renderable { +public: + + // constructors & destructor + RenderablePlanet(const pss &radius); + ~RenderablePlanet(); + + void setProgramObject(ghoul::opengl::ProgramObject *programObject); + void setTexture(ghoul::opengl::Texture *texture); + + virtual void render(const Camera *camera, const psc &thisPosition); + virtual void update(); + +private: + ghoul::opengl::ProgramObject *programObject_; + ghoul::opengl::Texture *texture_; + double rad_; + + Planet *planet_; +}; + +} // namespace openspace + +#endif \ No newline at end of file diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp new file mode 100644 index 0000000000..fe3fb015b6 --- /dev/null +++ b/src/rendering/renderengine.cpp @@ -0,0 +1,289 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include "rendering/renderengine.h" + +#include "openspaceengine.h" +#include "scenegraph/scenegraph.h" +#include "scenegraph/scenegraphloader.h" +#include "util/camera.h" + +#include "sgct.h" + +namespace { + const std::string _loggerCat = "RenderEngine"; +} +namespace openspace { + +RenderEngine::RenderEngine() + : _mainCamera(nullptr) + , _sceneGraph(nullptr) +{ +} + +RenderEngine::~RenderEngine() { + delete _mainCamera; + delete _sceneGraph; +} + +bool RenderEngine::initialize(const std::string& sceneGraph) { + // init camera and set position + _mainCamera = new Camera(); + _mainCamera->setScaling(glm::vec2(1.0, -8.0)); + _mainCamera->setPosition(psc(0.0,0.0,1.499823,11.0)); // about the distance from the sun to our moon, will be overritten by the scenegraphloader + + // if master, setup interaction + if (sgct::Engine::instance()->isMaster()) { + OsEng.interactionHandler().setCamera(_mainCamera); + + // init interactionhandler and mouse interaction + //keyboardControl_ = new KeyboardExternalControl(RELATIVE_PATH"pyinput/keyboard.py"); + //mouseControl_ = new MouseExternalControl(RELATIVE_PATH"pyinput/mouse.py"); + //InteractionHandler::ref().addExternalControl(mouseControl_); // the interactionhandler is deallocating the object when it terminates + //InteractionHandler::ref().addExternalControl(keyboardControl_); // the interactionhandler is deallocating the object when it terminates + + } + + // init scenegraph + _sceneGraph = new SceneGraph; + _sceneGraph->init(); + //_sceneGraph = loadSceneGraph(sceneGraph); + + return true; +} + +bool RenderEngine::initializeGL() { + // GL settings + glEnable (GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + + // set the close clip plane and the far clip plane to extreme values while in development + sgct::Engine::instance()->setNearAndFarClippingPlanes(0.1f,100.0f); + //sgct::Engine::setNearAndFarClippingPlanes(0.1f,10000.0f); + //sgct::Engine::getPtr()->setNearAndFarClippingPlanes(0.1f,10000.0f); + + // calculating the maximum field of view for the camera, used to determine visibility of objects in the scene graph + if(sgct::Engine::instance()->getWindowPtr(0)->isUsingFisheyeRendering()) { + + // fisheye mode, looking upwards to the "dome" + glm::vec4 viewdir(0,1,0,0); + + // get the tilt and rotate the view + float tilt = sgct::Engine::instance()->getWindowPtr(0)->getFisheyeTilt(); + //tilt = tilt * 0.0174532925; // degrees to radians + glm::mat4 tiltMatrix = glm::rotate(glm::mat4(1.0f), tilt, glm::vec3(1.0f,0.0f,0.0f)); + viewdir = tiltMatrix * viewdir; + + // set the tilted view and the FOV + _mainCamera->setCameraDirection(glm::vec3(viewdir[0],viewdir[1],viewdir[2])); + //mainCamera_->setMaxFov(sgct_core::SGCTSettings::Instance()->getFisheyeFOV()); + _mainCamera->setMaxFov(sgct::Engine::instance()->getWindowPtr(0)->getFisheyeFOV()); + } else { + // get corner positions, calculating the forth to easily calculate center + glm::vec3 corners[4]; + corners[0] = sgct::Engine::instance()->getWindowPtr(0)->getCurrentViewport()->getViewPlaneCoords(sgct_core::Viewport::LowerLeft); + corners[1] = sgct::Engine::instance()->getWindowPtr(0)->getCurrentViewport()->getViewPlaneCoords(sgct_core::Viewport::UpperLeft); + corners[2] = sgct::Engine::instance()->getWindowPtr(0)->getCurrentViewport()->getViewPlaneCoords(sgct_core::Viewport::UpperRight); + corners[3] = glm::vec3(corners[2][0],corners[0][1],corners[2][2]); + glm::vec3 center = (corners[0] + corners[1] + corners[2] + corners[3]) / 4.0f; + + // set the eye position, useful during rendering + const glm::vec3 eyePosition = sgct_core::ClusterManager::instance()->getUserPtr()->getPos(); + + // get viewdirection, stores the direction in the camera, used for culling + glm::vec3 viewdir = glm::normalize(eyePosition- center); + _mainCamera->setCameraDirection(-viewdir); + + // set the initial fov to be 0.0 which means everything will be culled + float maxFov = 0.0f; + + // for each corner + for(int i = 0; i < 4; ++i) { + + // calculate radians to corner + glm::vec3 dir = glm::normalize(eyePosition- corners[i]); + float radsbetween = acos(glm::dot(viewdir, dir))/(glm::length(viewdir) * glm::length(dir)); + + // the angle to a corner is larger than the current maxima + if (radsbetween > maxFov) { + maxFov = radsbetween; + } + } + _mainCamera->setMaxFov(maxFov); + } + + // successful init + return true; +} + +void RenderEngine::postSynchronizationPreDraw() { + + // converts the quaternion used to rotation matrices + _mainCamera->compileViewRotationMatrix(); + + // update and evaluate the scene starting from the root node + _sceneGraph->update(); + _sceneGraph->evaluate(_mainCamera); +} + +void RenderEngine::render() { + + // preparing the camera can only be done in the render function + // since the SGCT get matrix functions is only valid in the render function + glm::mat4 projection = sgct::Engine::instance()->getActiveProjectionMatrix(); + glm::mat4 view = sgct::Engine::instance()->getActiveViewMatrix(); + const glm::vec3 eyePosition = sgct_core::ClusterManager::instance()->getUserPtr()->getPos(); + view = glm::translate(view, eyePosition); // make sure the eye is in the center + + // setup the camera for the current frame + _mainCamera->setViewProjectionMatrix(projection*view); + + // render the scene starting from the root node + _sceneGraph->render(_mainCamera); + + if (sgct::Engine::instance()->isMaster()) { + const glm::vec2 scaling = _mainCamera->getScaling(); + const glm::vec3 viewdirection = _mainCamera->getViewDirection(); + const psc position = _mainCamera->getPosition(); + Freetype::print(sgct_text::FontManager::instance()->getFont( "SGCTFont", 10 ), 10, 50, + "Position: (%.5f, %.5f, %.5f, %.5f)", position[0], position[1], position[2], position[3] + ); + Freetype::print(sgct_text::FontManager::instance()->getFont( "SGCTFont", 10 ), 10, 35, + "View direction: (%.3f, %.3f, %.3f)", viewdirection[0], viewdirection[1], viewdirection[2] + ); + Freetype::print(sgct_text::FontManager::instance()->getFont( "SGCTFont", 10 ), 10, 20, + "Scaling: (%.10f, %.2f)", scaling[0], scaling[1] + ); + + psc campos = _mainCamera->getPosition(); + psc origin = OsEng.interactionHandler().getOrigin(); + //psc campos = InteractionHandler::ref().getCamera()->getPosition(); + //psc origin = InteractionHandler::ref().getOrigin(); + psc relative = campos - origin; + pss pssl = relative.length(); + //mainCamera_->setScaling(glm::vec2(pssl[0], -pssl[1]+6)); + //mainCamera_->setScaling(glm::vec2(3000.0, -11.0f)); + Freetype::print(sgct_text::FontManager::instance()->getFont( "SGCTFont", 10 ), 10, 65, + "Distance to origin: (%.15f, %.2f)", pssl[0], pssl[1] + ); + } +} + +SceneGraph* RenderEngine::sceneGraph() { + // TODO custom assert (ticket #5) + assert(_sceneGraph); + return _sceneGraph; +} + + +/* +void RenderEngine::keyboardCallback(int key, int action) { + const double speed = 0.75; + if (key == 'S') { + double dt = InteractionHandler::ref().getDt(); + glm::vec3 euler(speed * dt, 0.0, 0.0); + glm::quat rot = glm::quat(euler); + InteractionHandler::ref().orbit(rot); + } + if (key == 'W') { + double dt = InteractionHandler::ref().getDt(); + glm::vec3 euler(-speed * dt, 0.0, 0.0); + glm::quat rot = glm::quat(euler); + InteractionHandler::ref().orbit(rot); + } + if (key == 'A') { + double dt = InteractionHandler::ref().getDt(); + glm::vec3 euler(0.0, -speed * dt, 0.0); + glm::quat rot = glm::quat(euler); + InteractionHandler::ref().orbit(rot); + } + if (key == 'D') { + double dt = InteractionHandler::ref().getDt(); + glm::vec3 euler(0.0, speed * dt, 0.0); + glm::quat rot = glm::quat(euler); + InteractionHandler::ref().orbit(rot); + } + if (key == 262) { + double dt = InteractionHandler::ref().getDt(); + glm::vec3 euler(0.0, speed * dt, 0.0); + glm::quat rot = glm::quat(euler); + InteractionHandler::ref().rotate(rot); + } + if (key == 263) { + double dt = InteractionHandler::ref().getDt(); + glm::vec3 euler(0.0, -speed * dt, 0.0); + glm::quat rot = glm::quat(euler); + InteractionHandler::ref().rotate(rot); + } + if (key == 264) { + double dt = InteractionHandler::ref().getDt(); + glm::vec3 euler(speed * dt, 0.0, 0.0); + glm::quat rot = glm::quat(euler); + InteractionHandler::ref().rotate(rot); + } + if (key == 265) { + double dt = InteractionHandler::ref().getDt(); + glm::vec3 euler(-speed * dt, 0.0, 0.0); + glm::quat rot = glm::quat(euler); + InteractionHandler::ref().rotate(rot); + } + if (key == 'R') { + double dt = InteractionHandler::ref().getDt(); + pss dist(3 * -speed * dt, 8.0); + InteractionHandler::ref().distance(dist); + } + if (key == 'F') { + double dt = InteractionHandler::ref().getDt(); + pss dist(3 * speed * dt, 8.0); + InteractionHandler::ref().distance(dist); + } + if (key == '1') { + SceneGraphNode* earth = sceneGraph_->root()->get("sun"); + + InteractionHandler::ref().setFocusNode(earth); + InteractionHandler::ref().getCamera()->setPosition(earth->getWorldPosition() + psc(0.0, 0.0, 0.5, 10.0)); + InteractionHandler::ref().getCamera()->setCameraDirection(glm::vec3(0.0, 0.0, -1.0)); + } + + if (key == '2') { + SceneGraphNode* earth = sceneGraph_->root()->get("earth"); + + InteractionHandler::ref().setFocusNode(earth); + InteractionHandler::ref().getCamera()->setPosition(earth->getWorldPosition() + psc(0.0, 0.0, 1.0, 8.0)); + InteractionHandler::ref().getCamera()->setCameraDirection(glm::vec3(0.0, 0.0, -1.0)); + } + + + if (key == '3') { + SceneGraphNode* earth = sceneGraph_->root()->get("moon"); + + InteractionHandler::ref().setFocusNode(earth); + InteractionHandler::ref().getCamera()->setPosition(earth->getWorldPosition() + psc(0.0, 0.0, 0.5, 8.0)); + InteractionHandler::ref().getCamera()->setCameraDirection(glm::vec3(0.0, 0.0, -1.0)); + } +} +*/ + +} // namespace openspace diff --git a/src/rendering/renderengine.h b/src/rendering/renderengine.h new file mode 100644 index 0000000000..c9e16e5648 --- /dev/null +++ b/src/rendering/renderengine.h @@ -0,0 +1,62 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#ifndef __RENDERENGINE_H__ +#define __RENDERENGINE_H__ + +#include "scenegraph/scenegraph.h" + +#include + +namespace openspace { + +class Camera; + +class RenderEngine { +public: + RenderEngine(); + ~RenderEngine(); + + bool initialize(const std::string& sceneGraph); + + SceneGraph* sceneGraph(); + + // sgct wrapped functions + bool initializeGL(); + void postSynchronizationPreDraw(); + void render(); + void postDraw(); + + // object extensions + //virtual void encode(); + //virtual void decode(); + +private: + Camera* _mainCamera; + SceneGraph* _sceneGraph; +}; + +} // namespace openspace + +#endif // __RENDERENGINE_H__ diff --git a/src/scenegraph/scenegraph.h b/src/scenegraph/scenegraph.h index 2897b30fd2..8e5e8f34d8 100644 --- a/src/scenegraph/scenegraph.h +++ b/src/scenegraph/scenegraph.h @@ -31,6 +31,7 @@ public: } SceneGraphNode* root() const { return root_; } + void setRoot(SceneGraphNode* root) { root_ = root; } private: diff --git a/src/scenegraph/scenegraphloader.cpp b/src/scenegraph/scenegraphloader.cpp index c1a4fe0cff..46d274b031 100644 --- a/src/scenegraph/scenegraphloader.cpp +++ b/src/scenegraph/scenegraphloader.cpp @@ -1,5 +1,5 @@ -#include "engine/openspaceengine.h" +#include "openspaceengine.h" // open space includes #include "scenegraph/scenegraphloader.h" #include "rendering/renderablebody.h" @@ -17,6 +17,16 @@ #include namespace openspace { + + +SceneGraph* loadSceneGraph(const std::string& sceneGraphPath) { + SceneGraph* result = new SceneGraph; + //result->setRo + + return result; +} + + SceneGraphLoader::SceneGraphLoader(std::vector *nodes, std::map *commonShaders) { root_ = nullptr; @@ -424,5 +434,5 @@ bool SceneGraphLoader::getShader(ghoul::opengl::ProgramObject **program, const s LERROR_SAFE("Could not load shader"); return false; } - + } // namespace openspace \ No newline at end of file diff --git a/src/scenegraph/scenegraphloader.h b/src/scenegraph/scenegraphloader.h index 133e2167b9..23e80b8345 100644 --- a/src/scenegraph/scenegraphloader.h +++ b/src/scenegraph/scenegraphloader.h @@ -18,6 +18,10 @@ namespace openspace { +class SceneGraph; + +SceneGraph* loadSceneGraph(const std::string& sceneGraphPath); + class SceneGraphLoader { public: diff --git a/src/util/camera.cpp b/src/util/camera.cpp new file mode 100644 index 0000000000..c95b2b5180 --- /dev/null +++ b/src/util/camera.cpp @@ -0,0 +1,97 @@ + +// open space includes +#include "camera.h" + +// sgct includes +#include "sgct.h" + +namespace openspace { + +Camera::Camera() { + //glm::vec3 EulerAngles(90, 45, 0); + scaling_ = glm::vec2(1.0,0.0); + glm::vec3 EulerAngles(0, 0, 0); + viewRotation_ = glm::quat(EulerAngles); + //printf("Camera: [%f, %f, %f, %f]\n", viewRotation_[0], viewRotation_[1], viewRotation_[2], viewRotation_[3]); +} + +Camera::~Camera() { + +} + +void Camera::setPosition(psc pos) { + position_ = pos; +} + +const psc& Camera::getPosition() const { + return position_; +} + + +void Camera::setViewProjectionMatrix(const glm::mat4 &viewProjectionMatrix) { + viewProjectionMatrix_ = viewProjectionMatrix; +} + +void Camera::setCameraDirection(const glm::vec3 &cameraDirection) { + cameraDirection_ = cameraDirection; +} + +const glm::mat4 & Camera::getViewProjectionMatrix() const { + return viewProjectionMatrix_; +} + +const glm::mat4 & Camera::getViewRotationMatrix() const { + return viewRotationMatrix_; +} + +void Camera::compileViewRotationMatrix() { + // convert from quaternion to rotationmatrix using glm + viewRotationMatrix_ = glm::mat4_cast(viewRotation_); + + // the camera matrix needs to be rotated inverse to the world + glm::mat4 camrotmatrix = glm::mat4_cast(glm::inverse(viewRotation_)); + glm::vec4 camdir(cameraDirection_[0],cameraDirection_[1],cameraDirection_[2],0); + camdir = camrotmatrix* camdir; + viewDirection_ = glm::normalize(glm::vec3(camdir[0],camdir[1],camdir[2])); +} + +void Camera::rotate(glm::quat rotation) { + viewRotation_ = rotation * viewRotation_; + viewRotation_ = glm::normalize(viewRotation_); +} + +void Camera::setRotation(glm::quat rotation) { + viewRotation_ = glm::normalize(rotation); +} + +const glm::quat & Camera::getRotation() const { + return viewRotation_; +} + +const glm::vec3 & Camera::getViewDirection() const { + return viewDirection_; +} + + +const float & Camera::getMaxFov() const { + return maxFov_; +} + +const float & Camera::getSinMaxFov() const { + return sinMaxFov_; +} + +void Camera::setMaxFov(const float &fov) { + maxFov_ = fov; + sinMaxFov_ = sin(maxFov_); +} + +void Camera::setScaling(const glm::vec2 &scaling) { + scaling_ = scaling; +} + +const glm::vec2 & Camera::getScaling() const { + return scaling_; +} + +} // namespace openspace \ No newline at end of file diff --git a/src/util/camera.h b/src/util/camera.h new file mode 100644 index 0000000000..1e94cce422 --- /dev/null +++ b/src/util/camera.h @@ -0,0 +1,58 @@ +#ifndef CAMERA_H +#define CAMERA_H + +// open space includes +#include "util/psc.h" + +// glm includes +#include +#include +#include +#include + +namespace openspace { + +class Camera { +public: + + // constructors & destructor + Camera(); + ~Camera(); + + void setPosition(psc pos); + const psc& getPosition() const; + + void setViewProjectionMatrix(const glm::mat4 &viewProjectionMatrix); + void setCameraDirection(const glm::vec3 &cameraDirection); + + const glm::mat4 & getViewProjectionMatrix() const; + const glm::mat4 & getViewRotationMatrix() const; + void compileViewRotationMatrix(); + + void rotate(glm::quat rotation); + void setRotation(glm::quat rotation); + const glm::quat & getRotation() const; + + const glm::vec3 & getViewDirection() const; + const float & getMaxFov() const; + const float & getSinMaxFov() const; + void setMaxFov(const float &fov); + void setScaling(const glm::vec2 &scaling); + const glm::vec2 & getScaling() const; + +private: + float maxFov_; + float sinMaxFov_; + psc position_; + glm::mat4 viewProjectionMatrix_; + glm::vec3 viewDirection_; + glm::vec3 cameraDirection_; + glm::vec2 scaling_; + + glm::quat viewRotation_; + glm::mat4 viewRotationMatrix_; // compiled from the quaternion +}; + +} // namespace openspace + +#endif \ No newline at end of file