From d67c9ffe8d1f8436a15f826eab6fc45d58bd142d Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 12 Oct 2014 23:51:33 +0200 Subject: [PATCH 1/7] Started changes for InteractionManager --- include/openspace/engine/openspaceengine.h | 4 +- include/openspace/interaction/controller.h | 58 ++ .../interaction/interactionhandler.h | 176 ++-- .../interaction/keyboardcontroller.h | 57 ++ include/openspace/interaction/keys.h | 170 ++++ include/openspace/interaction/mouse.h | 57 ++ .../openspace/interaction/mousecontroller.h | 45 + src/engine/openspaceengine.cpp | 4 +- src/interaction/controller.cpp | 0 src/interaction/interactionhandler.cpp | 944 +++++++++--------- src/interaction/keyboardcontroller.cpp | 0 src/interaction/mousecontroller.cpp | 24 + src/rendering/renderengine.cpp | 3 - src/scenegraph/scenegraphnode.cpp | 10 +- 14 files changed, 1004 insertions(+), 548 deletions(-) create mode 100644 include/openspace/interaction/controller.h create mode 100644 include/openspace/interaction/keyboardcontroller.h create mode 100644 include/openspace/interaction/keys.h create mode 100644 include/openspace/interaction/mouse.h create mode 100644 include/openspace/interaction/mousecontroller.h create mode 100644 src/interaction/controller.cpp create mode 100644 src/interaction/keyboardcontroller.cpp create mode 100644 src/interaction/mousecontroller.cpp diff --git a/include/openspace/engine/openspaceengine.h b/include/openspace/engine/openspaceengine.h index 4973bb4606..e39319db15 100644 --- a/include/openspace/engine/openspaceengine.h +++ b/include/openspace/engine/openspaceengine.h @@ -72,7 +72,7 @@ public: ConfigurationManager& configurationManager(); ghoul::opencl::CLContext& clContext(); - InteractionHandler& interactionHandler(); + interaction::InteractionHandler& interactionHandler(); RenderEngine& renderEngine(); scripting::ScriptEngine& scriptEngine(); @@ -100,7 +100,7 @@ private: static OpenSpaceEngine* _engine; ConfigurationManager _configurationManager; - InteractionHandler _interactionHandler; + interaction::InteractionHandler _interactionHandler; RenderEngine _renderEngine; scripting::ScriptEngine _scriptEngine; ghoul::cmdparser::CommandlineParser _commandlineParser; diff --git a/include/openspace/interaction/controller.h b/include/openspace/interaction/controller.h new file mode 100644 index 0000000000..a98b9dd557 --- /dev/null +++ b/include/openspace/interaction/controller.h @@ -0,0 +1,58 @@ +/***************************************************************************************** + * * + * 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 __CONTROLLER_H__ +#define __CONTROLLER_H__ + +namespace openspace { +namespace interaction { + +class InteractionHandler; + +class Controller { +public: + void setHandler(InteractionHandler* handler) { + _handler = handler; + } + +protected: + void orbitDelta(const glm::quat& rotation) { + } + void rotateDelta(const glm::quat& rotation) { + } + void distanceDelta(const PowerScaledScalar& distance) { + } + void lookAt(const glm::quat& rotation) { + } + void setRotation(const glm::quat& rotation) { + } + +private: + InteractionHandler* _handler; +}; + +} // namespace interaction +} // namespace openspace + +#endif // __CONTROLLER_H__ \ No newline at end of file diff --git a/include/openspace/interaction/interactionhandler.h b/include/openspace/interaction/interactionhandler.h index 80b867dd91..26f15ed6c7 100644 --- a/include/openspace/interaction/interactionhandler.h +++ b/include/openspace/interaction/interactionhandler.h @@ -1,91 +1,137 @@ -#ifndef INTERACTIONHANDLER_H -#define INTERACTIONHANDLER_H +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ -// open space includes -#include -#include -#include +#ifndef __INTERACTIONHANDLER_H__ +#define __INTERACTIONHANDLER_H__ + +#include +#include -// std includes -#include -#include #include -#include -#include -#include namespace openspace { +class Camera; +class SceneGraphNode; + +namespace interaction { + class InteractionHandler { public: - InteractionHandler(void); - InteractionHandler(const InteractionHandler& src); - InteractionHandler& operator=(const InteractionHandler& rhs); - virtual ~InteractionHandler(); + InteractionHandler() + : _camera(nullptr) + , _focusNode(nullptr) + , _keyboardController(nullptr) + , _mouseController(nullptr) + { + } - //static void init(); - //static void deinit(); - // static InteractionHandler& ref(); - //static bool isInitialized(); + ~InteractionHandler() { + delete _keyboardController; + delete _mouseController; + for (size_t i = 0; i < _controllers.size(); ++i) + delete _controllers[i]; - void enable(); - void disable(); - const bool isEnabled() const; + } - void connectDevices(); - void addExternalControl(ExternalControl* controller); + void setKeyboardController(KeyboardController* controller) { + delete _keyboardController; + _keyboardController = controller; + _keyboardController->setHandler(this); + } - void setCamera(Camera *camera = nullptr); - Camera * getCamera() const; - const psc getOrigin() const; - void lockControls(); - void unlockControls(); + void setMouseController(MouseController* controller) { + delete _mouseController; + _mouseController = controller; + _mouseController->setHandler(this); + } - void setFocusNode(SceneGraphNode *node); - - void orbit(const glm::quat &rotation); - void rotate(const glm::quat &rotation); - void distance(const PowerScaledScalar &distance); + void addController(Controller* controller) { + _controllers.push_back(controller); + controller->setHandler(this); + } - void lookAt(const glm::quat &rotation); - void setRotation(const glm::quat &rotation); + void lockControls() { + _mutex.lock(); + } - void update(const double dt); + void unlockControls() { + _mutex.unlock(); + } - double getDt(); + void update(double deltaTime) { + _deltaTime = deltaTime; + } - void keyboardCallback(int key, int action); - void mouseButtonCallback(int key, int action); - void mousePositionCallback(int x, int y); - void mouseScrollWheelCallback(int pos); + void setFocusNode(SceneGraphNode* node) { + _focusNode = node; + } + + void keyboardCallback(int key, int action) { + if (_keyboardController) + _keyboardController->keyPressed(KeyAction(action), Keys(key)); + } + + void mouseButtonCallback(int button, int action) { + if (_mouseController) + _mouseController->button(MouseAction(action), MouseButton(button)); + } + + void mousePositionCallback(int x, int y) { + if (_mouseController) + // TODO Remap screen coordinates to [0,1] + _mouseController->move(float(x), float(y)); + } + + void mouseScrollWheelCallback(int pos) { + if (_mouseController) + _mouseController->scrollWheel(float(pos)); + } - void addKeyCallback(int key, std::function f); - private: - glm::vec3 mapToTrackball(glm::vec2 mousePos); - glm::vec3 mapToCamera(glm::vec3 trackballPos); - void trackballRotate(int x, int y); + InteractionHandler(const InteractionHandler&) = delete; + InteractionHandler& operator=(const InteractionHandler&) = delete; + InteractionHandler(InteractionHandler&&) = delete; + InteractionHandler& operator=(InteractionHandler&&) = delete; - Camera* camera_; - bool enabled_; - SceneGraphNode *node_; - - double dt_; + Camera* _camera; + SceneGraphNode* _focusNode; + + double _deltaTime; + std::mutex _mutex; + + KeyboardController* _keyboardController; + MouseController* _mouseController; + std::vector _controllers; - glm::vec3 _lastTrackballPos; - bool _leftMouseButtonDown, _isMouseBeingPressedAndHeld; - - // used for calling when updating and deallocation - std::vector controllers_; - - // for locking and unlocking - std::mutex cameraGuard_; - - std::multimap > _keyCallbacks; - + // glm::vec3 mapToTrackball(glm::vec2 mousePos); + // glm::vec3 mapToCamera(glm::vec3 trackballPos); + // void trackballRotate(int x, int y); }; +} // namespace interaction } // namespace openspace -#endif +#endif // __INTERACTIONHANDLER_H__ diff --git a/include/openspace/interaction/keyboardcontroller.h b/include/openspace/interaction/keyboardcontroller.h new file mode 100644 index 0000000000..22314015ea --- /dev/null +++ b/include/openspace/interaction/keyboardcontroller.h @@ -0,0 +1,57 @@ +/***************************************************************************************** + * * + * 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 __KEYBOARDCONTROLLER_H__ +#define __KEYBOARDCONTROLLER_H__ + +#include + +#include + +namespace openspace { +namespace interaction { + +class KeyboardController : public Controller { +public: + virtual void keyPressed(KeyAction action, Keys key) = 0; +}; + +class KeyboardControllerFixed : public KeyboardController { +public: + void keyPressed(KeyAction action, Keys key) = 0 { + + } +}; + +class KeyboardControllerLua : public KeyboardController { +public: + void keyPressed(KeyAction action, Keys key) { + + } +}; + +} // namespace interaction +} // namespace openspace + +#endif // __KEYBOARDCONTROLLER_H__ diff --git a/include/openspace/interaction/keys.h b/include/openspace/interaction/keys.h new file mode 100644 index 0000000000..72f86ddd99 --- /dev/null +++ b/include/openspace/interaction/keys.h @@ -0,0 +1,170 @@ +/***************************************************************************************** + * * + * 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 __KEYS_H__ +#define __KEYS_H__ + +#include + +namespace openspace { +namespace interaction { + +enum class KeyAction { + Press = SGCT_PRESS, + Release = SGCT_RELEASE, + Repeat = SGCT_REPEAT +}; + +enum class Keys { + Unknown = SGCT_KEY_UNKNOWN, + Space = SGCT_KEY_SPACE, + Apostrophe = SGCT_KEY_APOSTROPHE, + Comma = SGCT_KEY_COMMA, + Minus = SGCT_KEY_MINUS, + Period = SGCT_KEY_PERIOD, + Slash = SGCT_KEY_SLASH, + Num0 = SGCT_KEY_0, + Num1 = SGCT_KEY_1, + Num2 = SGCT_KEY_2, + Num3 = SGCT_KEY_3, + Num4 = SGCT_KEY_4, + Num5 = SGCT_KEY_5, + Num6 = SGCT_KEY_6, + Num7 = SGCT_KEY_7, + Num8 = SGCT_KEY_8, + Num9 = SGCT_KEY_9, + SemiColon = SGCT_KEY_SEMICOLON, + Equal = SGCT_KEY_EQUAL, + A = SGCT_KEY_A, + B = SGCT_KEY_B, + C = SGCT_KEY_C, + D = SGCT_KEY_D, + E = SGCT_KEY_E, + F = SGCT_KEY_F, + G = SGCT_KEY_G, + H = SGCT_KEY_H, + I = SGCT_KEY_I, + J = SGCT_KEY_J, + K = SGCT_KEY_K, + L = SGCT_KEY_L, + M = SGCT_KEY_M, + N = SGCT_KEY_N, + O = SGCT_KEY_O, + P = SGCT_KEY_P, + Q = SGCT_KEY_Q, + R = SGCT_KEY_R, + S = SGCT_KEY_S, + T = SGCT_KEY_T, + U = SGCT_KEY_U, + V = SGCT_KEY_V, + W = SGCT_KEY_W, + X = SGCT_KEY_X, + Y = SGCT_KEY_Y, + Z = SGCT_KEY_Z, + LeftBracket = SGCT_KEY_LEFT_BRACKET, + BackSlash = SGCT_KEY_BACKSLASH, + RightBracket = SGCT_KEY_RIGHT_BRACKET, + GraveAccent = SGCT_KEY_GRAVE_ACCENT, + World1 = SGCT_KEY_WORLD_1, + World2 = SGCT_KEY_WORLD_2, + Escape = SGCT_KEY_ESC, + Enter = SGCT_KEY_ENTER, + Tab = SGCT_KEY_TAB, + BackSpace = SGCT_KEY_BACKSPACE, + Insert = SGCT_KEY_INSERT, + Delete = SGCT_KEY_DELETE, + Right = SGCT_KEY_RIGHT, + Left = SGCT_KEY_LEFT, + Down = SGCT_KEY_DOWN, + Up = SGCT_KEY_UP, + PageUp = SGCT_KEY_PAGE_UP, + PageDown = SGCT_KEY_PAGE_DOWN, + Home = SGCT_KEY_HOME, + End = SGCT_KEY_END, + CapsLock = SGCT_KEY_CAPS_LOCK, + ScrollLock = SGCT_KEY_SCROLL_LOCK, + NumLock = SGCT_KEY_NUM_LOCK, + PrintScreen = SGCT_KEY_PRINT_SCREEN, + Pause = SGCT_KEY_PAUSE, + F1 = SGCT_KEY_F1, + F2 = SGCT_KEY_F2, + F3 = SGCT_KEY_F3, + F4 = SGCT_KEY_F4, + F5 = SGCT_KEY_F5, + F6 = SGCT_KEY_F6, + F7 = SGCT_KEY_F7, + F8 = SGCT_KEY_F8, + F9 = SGCT_KEY_F9, + F10 = SGCT_KEY_F10, + F11 = SGCT_KEY_F11, + F12 = SGCT_KEY_F12, + F13 = SGCT_KEY_F13, + F14 = SGCT_KEY_F14, + F15 = SGCT_KEY_F15, + F16 = SGCT_KEY_F16, + F17 = SGCT_KEY_F17, + F18 = SGCT_KEY_F18, + F19 = SGCT_KEY_F19, + F20 = SGCT_KEY_F20, + F21 = SGCT_KEY_F21, + F22 = SGCT_KEY_F22, + F23 = SGCT_KEY_F23, + F24 = SGCT_KEY_F24, + F25 = SGCT_KEY_F25, + Keypad0 = SGCT_KEY_KP_0, + Keypad1 = SGCT_KEY_KP_1, + Keypad2 = SGCT_KEY_KP_2, + Keypad3 = SGCT_KEY_KP_3, + Keypad4 = SGCT_KEY_KP_4, + Keypad5 = SGCT_KEY_KP_5, + Keypad6 = SGCT_KEY_KP_6, + Keypad7 = SGCT_KEY_KP_7, + Keypad8 = SGCT_KEY_KP_8, + Keypad9 = SGCT_KEY_KP_9, + KeypadDecimal = SGCT_KEY_KP_DECIMAL, + KeypadDivide = SGCT_KEY_KP_DIVIDE, + KeypadMultiply = SGCT_KEY_KP_MULTIPLY, + KeypadSubtract = SGCT_KEY_KP_SUBTRACT, + KeypadAdd = SGCT_KEY_KP_ADD, + KeypadEnter = SGCT_KEY_KP_ENTER, + LeftShift = SGCT_KEY_LEFT_SHIFT, + LeftControl = SGCT_KEY_LEFT_CONTROL, + LeftAlt = SGCT_KEY_LEFT_ALT, + LeftSuper = SGCT_KEY_LEFT_SUPER, + RightShift = SGCT_KEY_RIGHT_SHIFT, + RightControl = SGCT_KEY_RIGHT_CONTROL, + RightAlt = SGCT_KEY_RIGHT_ALT, + RightSuper = SGCT_KEY_RIGHT_SUPER, + Menu = SGCT_KEY_MENU, + Last = SGCT_KEY_LAST, + Shift = LeftShift | RightShift, + Control = LeftControl | RightControl, + Alt = LeftAlt | RightAlt, + Super = LeftSuper | RightSuper +} + +} // namespace interaction +} // namespace openspace + +#endif // __KEYS_H__ diff --git a/include/openspace/interaction/mouse.h b/include/openspace/interaction/mouse.h new file mode 100644 index 0000000000..6c2d40cc14 --- /dev/null +++ b/include/openspace/interaction/mouse.h @@ -0,0 +1,57 @@ +/***************************************************************************************** + * * + * 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 __MOUSE_H__ +#define __MOUSE_H__ + +#include + +namespace openspace { +namespace interaction { + +enum class MouseAction { + Press = SGCT_PRESS, + Release = SGCT_RELEASE, + Repeat = SGCT_REPEAT +}; + +enum class MouseButton { + Left = SGCT_MOUSE_BUTTON_LEFT, + Right = SGCT_MOUSE_BUTTON_RIGHT, + Middle = SGCT_MOUSE_BUTTON_MIDDLE, + Button1 = SGCT_MOUSE_BUTTON_1, + Button2 = SGCT_MOUSE_BUTTON_2, + Button3 = SGCT_MOUSE_BUTTON_3, + Button4 = SGCT_MOUSE_BUTTON_4, + Button5 = SGCT_MOUSE_BUTTON_5, + Button6 = SGCT_MOUSE_BUTTON_6, + Button7 = SGCT_MOUSE_BUTTON_7, + Button8 = SGCT_MOUSE_BUTTON_8, + ButtonLast = SGCT_MOUSE_BUTTON_LAST, +} + +} // namespace interaction +} // namespace openspace + +#endif // __MOUSE_H__ diff --git a/include/openspace/interaction/mousecontroller.h b/include/openspace/interaction/mousecontroller.h new file mode 100644 index 0000000000..ebdd455e0e --- /dev/null +++ b/include/openspace/interaction/mousecontroller.h @@ -0,0 +1,45 @@ +/***************************************************************************************** + * * + * 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 __MOUSECONTROLLER_H__ +#define __MOUSECONTROLLER_H__ + +#include + +#include + +namespace openspace { +namespace interaction { + +class MouseController : public Controller { +public: + virtual void button(MouseAction action, MouseButton button) = 0; + virtual void move(float x, float y) = 0; + virtual void scrollWheel(float z) = 0; +}; + +} // namespace interaction +} // namespace openspace + +#endif // __MOUSECONTROLLER_H__ \ No newline at end of file diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index ec002b70cf..7d12dc3b73 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -307,7 +307,7 @@ bool OpenSpaceEngine::initialize() { // Initialize OpenSpace input devices DeviceIdentifier::init(); DeviceIdentifier::ref().scanDevices(); - _interactionHandler.connectDevices(); + //_interactionHandler.connectDevices(); // Run start up scripts ghoul::Dictionary scripts; @@ -341,7 +341,7 @@ ghoul::opencl::CLContext& OpenSpaceEngine::clContext() { return _context; } -InteractionHandler& OpenSpaceEngine::interactionHandler() { +interaction::InteractionHandler& OpenSpaceEngine::interactionHandler() { return _interactionHandler; } diff --git a/src/interaction/controller.cpp b/src/interaction/controller.cpp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/interaction/interactionhandler.cpp b/src/interaction/interactionhandler.cpp index 433e03b297..d4024dd9d4 100644 --- a/src/interaction/interactionhandler.cpp +++ b/src/interaction/interactionhandler.cpp @@ -1,475 +1,479 @@ - -// open space includes -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -// std includes -#include - -std::string _loggerCat = "InteractionHandler"; - -namespace openspace { - -InteractionHandler::InteractionHandler() { - // initiate pointers - camera_ = nullptr; - enabled_ = true; - node_ = nullptr; - dt_ = 0.0; - _lastTrackballPos = glm::vec3(0.0, 0.0, 0.5); - _leftMouseButtonDown = false; - _isMouseBeingPressedAndHeld = false; -} - -InteractionHandler::~InteractionHandler() { - for (size_t i = 0; i < controllers_.size(); ++i) { - delete controllers_[i]; - } -} - -//void InteractionHandler::init() { -// assert( ! this_); -// this_ = new InteractionHandler(); +///***************************************************************************************** +// * * +// * 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. * +// ****************************************************************************************/ +// +//// open space includes +//#include +//#include +//#include +////#include +////#include +//#include +//#include +//#include +//#include +// +//#include +// +//#include +// +//namespace { +// const std::string _loggerCat = "InteractionHandler"; //} // -//void InteractionHandler::deinit() { -// assert(this_); -// delete this_; -// this_ = nullptr; +//namespace openspace { +//namespace interaction { +// +//InteractionHandler::InteractionHandler() +// : _camera(nullptr) +// , _node(nullptr) +// , _dt(0.0) +// , _lastTrackballPos(0.f) +// , _leftMouseButtonDown(false) +// , _isMouseBeingPressedAndHeld(false) +//{ //} // -//InteractionHandler& InteractionHandler::ref() { -// assert(this_); -// return *this_; +//InteractionHandler::~InteractionHandler() { +// //for (size_t i = 0; i < _controllers.size(); ++i) { +// // delete _controllers[i]; +// //} //} - -//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_->worldPosition(); - return psc(); -} - -void InteractionHandler::lockControls() { - //assert(this_); - cameraGuard_.lock(); -} - -void InteractionHandler::unlockControls() { - //assert(this_); - cameraGuard_.unlock(); -} - -void InteractionHandler::setFocusNode(SceneGraphNode *node) { - //assert(this_); - node_ = node; -} - -void InteractionHandler::rotate(const glm::quat &rotation) { - //assert(this_); - lockControls(); - camera_->rotate(rotation); - unlockControls(); -} - -void InteractionHandler::orbit(const glm::quat &rotation) { - //assert(this_); - lockControls(); - - // the camera position - psc relative = camera_->position(); - - // should be changed to something more dynamic =) - psc origin; - if (node_) { - origin = node_->worldPosition(); - } - - psc relative_origin_coordinate = relative - origin; - //glm::mat4 rotation_matrix = glm::mat4_cast(glm::inverse(rotation)); - //relative_origin_coordinate = relative_origin_coordinate.vec4() * glm::inverse(rotation); - relative_origin_coordinate = glm::inverse(rotation) * relative_origin_coordinate.vec4(); - relative = relative_origin_coordinate + origin; - - camera_->setPosition(relative); - //camera_->rotate(rotation); - //camera_->setRotation(glm::mat4_cast(rotation)); - - glm::mat4 la = glm::lookAt(camera_->position().vec3(), origin.vec3(), glm::rotate(rotation, camera_->lookUpVector())); - camera_->setRotation(la); - //camera_->setLookUpVector(); - - unlockControls(); -} - -void InteractionHandler::distance(const PowerScaledScalar &distance) { - //assert(this_); - lockControls(); - - psc relative = camera_->position(); - const psc origin = (node_) ? node_->worldPosition() : psc(); - - psc relative_origin_coordinate = relative - origin; - const glm::vec3 dir(relative_origin_coordinate.direction()); - glm:: vec3 newdir = dir * distance[0]; - relative_origin_coordinate = newdir; - relative_origin_coordinate[3] = distance[1]; - relative = relative + relative_origin_coordinate; - - relative_origin_coordinate = relative - origin; - newdir = relative_origin_coordinate.direction(); - - // update only if on the same side of the origin - if(glm::angle(newdir, dir) < 90.0f) - camera_->setPosition(relative); - - unlockControls(); -} - -void InteractionHandler::lookAt(const glm::quat &rotation) { - //assert(this_); - lockControls(); - - unlockControls(); -} - -void InteractionHandler::setRotation(const glm::quat &rotation) { - //assert(this_); - lockControls(); - - unlockControls(); -} - -void InteractionHandler::update(const double dt) { - //assert(this_); - // setting dt_ for use in callbacks - dt_ = dt; - if (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_; -} - -glm::vec3 InteractionHandler::mapToTrackball(glm::vec2 mousePos) { - const float RADIUS = 0.5; // Sphere radius - glm::vec3 out = glm::vec3(mousePos.x-0.5, -1.0*(mousePos.y-0.5), 0); - - // Mapping according to Holroyds trackball - // Piece-wise sphere + hyperbolic sheet - if (out.x*out.x + out.y*out.y <= RADIUS*RADIUS/2.0) { - //Spherical Region - out.z = RADIUS*RADIUS - (out.x*out.x + out.y*out.y); - out.z = out.z > 0.0 ? sqrtf(out.z) : 0.0; - } else { //Hyperbolic Region - for smooth z values - out.z = (RADIUS*RADIUS)/(2.0*sqrt(out.x*out.x + out.y*out.y)); - } - - return glm::normalize(out); -} - -glm::vec3 InteractionHandler::mapToCamera(glm::vec3 trackballPos) { -// return glm::vec3((sgct::Engine::instance()->getActiveViewMatrix() * glm::vec4(trackballPos,0))); - - //Get x,y,z axis vectors of current camera view - glm::vec3 currentViewYaxis = glm::normalize(camera_->lookUpVector()); - psc viewDir = camera_->position() - node_->worldPosition(); - glm::vec3 currentViewZaxis = glm::normalize(viewDir.vec3()); - glm::vec3 currentViewXaxis = glm::normalize(glm::cross(currentViewYaxis, currentViewZaxis)); - - //mapping to camera co-ordinate - currentViewXaxis*=trackballPos.x; - currentViewYaxis*=trackballPos.y; - currentViewZaxis*=trackballPos.z; - return (currentViewXaxis + currentViewYaxis + currentViewZaxis); -} - -void InteractionHandler::trackballRotate(int x, int y) { - // Normalize mouse coordinates to [0,1] - float width = sgct::Engine::instance()->getActiveXResolution(); - float height = sgct::Engine::instance()->getActiveYResolution(); - glm::vec2 mousePos = glm::vec2((float)x/width, (float)y/height); - - mousePos = glm::clamp(mousePos, -0.5, 1.5); // Ugly fix #1: Camera position becomes NaN on mouse values outside [-0.5, 1.5] - //mousePos[1] = 0.5; // Ugly fix #2: Tempoarily only allow rotation around y - - glm::vec3 curTrackballPos = mapToTrackball(mousePos); -// LDEBUG(mousePos.x << ", " << mousePos.y << " = " << curTrackballPos.x << ", " << curTrackballPos.y << ", " << curTrackballPos.z); - - // Disable movement on the first click for extra smoothness - if (!_isMouseBeingPressedAndHeld) { - _lastTrackballPos = curTrackballPos; - _isMouseBeingPressedAndHeld = true; - } - - if (curTrackballPos != _lastTrackballPos) { - // calculate rotation angle (in radians) - float rotationAngle = glm::angle(curTrackballPos, _lastTrackballPos); - rotationAngle *= getDt()*100.0f; - - // Map trackballpos to camera -// glm::vec3 trackballMappedToCamera = mapToCamera(_lastTrackballPos - curTrackballPos); -// psc currentCamPos = camera_->getPosition(); -// glm::vec3 nextCamPos = currentCamPos.getVec3f() + trackballMappedToCamera; -// glm::vec3 rotationAxis = glm::cross(currentCamPos.getVec3f(), nextCamPos); - - glm::vec3 rotationAxis = glm::cross(_lastTrackballPos, curTrackballPos); - rotationAxis = glm::normalize(rotationAxis); - glm::quat quaternion = glm::angleAxis(rotationAngle, rotationAxis); - - // Apply quaternion to camera - orbit(quaternion); - - _lastTrackballPos = curTrackballPos; - } -} -double acc = 1; - -void InteractionHandler::keyboardCallback(int key, int action) { - // TODO package in script - const double speed = 2.75; - const double dt = getDt(); - if(action == SGCT_PRESS || action == SGCT_REPEAT) { - if (key == SGCT_KEY_S) { - glm::vec3 euler(speed * dt, 0.0, 0.0); - glm::quat rot = glm::quat(euler); - orbit(rot); - } - if (key == SGCT_KEY_W) { - glm::vec3 euler(-speed * dt, 0.0, 0.0); - glm::quat rot = glm::quat(euler); - orbit(rot); - } - if (key == SGCT_KEY_A) { - glm::vec3 euler(0.0, -speed * dt, 0.0); - glm::quat rot = glm::quat(euler); - orbit(rot); - } - if (key == SGCT_KEY_D) { - glm::vec3 euler(0.0, speed * dt, 0.0); - glm::quat rot = glm::quat(euler); - orbit(rot); - } - if (key == SGCT_KEY_Q) { - Time::ref().advanceTime(dt); - } - if (key == 262) { - glm::vec3 euler(0.0, speed * dt, 0.0); - glm::quat rot = glm::quat(euler); - rotate(rot); - } - if (key == 263) { - glm::vec3 euler(0.0, -speed * dt, 0.0); - glm::quat rot = glm::quat(euler); - rotate(rot); - } - if (key == 264) { - glm::vec3 euler(speed * dt, 0.0, 0.0); - glm::quat rot = glm::quat(euler); - rotate(rot); - } - if (key == 265) { - glm::vec3 euler(-speed * dt, 0.0, 0.0); - glm::quat rot = glm::quat(euler); - rotate(rot); - } - if (key == SGCT_KEY_R) { - PowerScaledScalar dist(-speed * dt, 0.0); - distance(dist); - } - if (key == SGCT_KEY_F) { - PowerScaledScalar dist(speed * dt, 0.0); - distance(dist); - } - if (key == SGCT_KEY_T) { - PowerScaledScalar dist(-speed * pow(10, 11) * dt, 0.0); - distance(dist); - } - if (key == SGCT_KEY_G) { - acc += 0.001; - PowerScaledScalar dist(speed * pow(10, 8 * acc) * dt, 0.0); - distance(dist); - } - if (key == SGCT_KEY_Y) { - PowerScaledScalar dist(-speed * 100.0 * dt, 6.0); - distance(dist); - } - if (key == SGCT_KEY_H) { - PowerScaledScalar dist(speed * 100.0 * dt, 6.0); - distance(dist); - } - - if (key == SGCT_KEY_KP_SUBTRACT) { - glm::vec2 s = OsEng.renderEngine().camera()->scaling(); - s[1] -= 0.5; - OsEng.renderEngine().camera()->setScaling(s); - } - if (key == SGCT_KEY_KP_ADD) { - glm::vec2 s = OsEng.renderEngine().camera()->scaling(); - s[1] += 0.5; - OsEng.renderEngine().camera()->setScaling(s); - } - } - /* - if (key == '1') { - SceneGraphNode* node = getSceneGraphNode("sun"); - - setFocusNode(node); - getCamera()->setPosition(node->getWorldPosition() + psc(0.0, 0.0, 0.5, 10.0)); - getCamera()->setCameraDirection(glm::vec3(0.0, 0.0, -1.0)); - } - - if (key == '2') { - SceneGraphNode* node = getSceneGraphNode("earth"); - - setFocusNode(node); - getCamera()->setPosition(node->getWorldPosition() + psc(0.0, 0.0, 1.0, 8.0)); - getCamera()->setCameraDirection(glm::vec3(0.0, 0.0, -1.0)); - } - - - if (key == '3') { - SceneGraphNode* node = getSceneGraphNode("moon"); - - setFocusNode(node); - getCamera()->setPosition(node->getWorldPosition() + psc(0.0, 0.0, 0.5, 8.0)); - getCamera()->setCameraDirection(glm::vec3(0.0, 0.0, -1.0)); - } -*/ - // std::pair >::iterator, std::multimap >::iterator> ret; - if(action == SGCT_PRESS) { - auto ret = _keyCallbacks.equal_range(key); - for (auto it=ret.first; it!=ret.second; ++it) - it->second(); - } - - -} - -void InteractionHandler::mouseButtonCallback(int key, int action) { - //if(mouseControl_ != nullptr) { - // mouseControl_->mouseButtonCallback(key,action); - //} - if (key == SGCT_MOUSE_BUTTON_LEFT && action == SGCT_PRESS) - _leftMouseButtonDown = true; - else if (key == SGCT_MOUSE_BUTTON_LEFT && action == SGCT_RELEASE) { - _leftMouseButtonDown = false; - _isMouseBeingPressedAndHeld = false; - } -} - -void InteractionHandler::mousePositionCallback(int x, int y) { - if (_leftMouseButtonDown) - trackballRotate(x,y); - - //if(mouseControl_ != nullptr) { - // mouseControl_->mousePosCallback(x,y); - //} -} - -void InteractionHandler::mouseScrollWheelCallback(int pos) { - //if(mouseControl_ != nullptr) { - // mouseControl_->mouseScrollCallback(pos); - //} - const double speed = 4.75; - const double dt = getDt(); - if(pos < 0) { - PowerScaledScalar dist(speed * dt, 0.0); - distance(dist); - } else if(pos > 0) { - PowerScaledScalar dist(-speed * dt, 0.0); - distance(dist); - } -} - -void InteractionHandler::addKeyCallback(int key, std::function f) { - //std::map > > _keyCallbacks; - - _keyCallbacks.insert(std::make_pair(key, f)); -} - -} // namespace openspace +// +////void InteractionHandler::init() { +//// assert( ! this_); +//// this_ = new InteractionHandler(); +////} +//// +////void InteractionHandler::deinit() { +//// assert(this_); +//// delete this_; +//// this_ = nullptr; +////} +//// +////InteractionHandler& InteractionHandler::ref() { +//// assert(this_); +//// return *this_; +////} +// +////bool InteractionHandler::isInitialized() { +//// return this_ != nullptr; +////} +// +////void InteractionHandler::connectDevices() { +//// //assert(this_); +//// assert(DeviceIdentifier::ref().isInitialized()); +//// +//// // for each device found +//// for(int i = 0; i < DeviceIdentifier::ref().numberOfDevices(); ++i) { +//// +//// // TODO +//// //if(DeviceIdentifier::ref().type(i) == InputDevice::XBOX) { +//// +//// // // found xbox, use xbox python controller +//// // JoystickExternalControl *joystickexcontrol = new JoystickExternalControl(RELATIVE_PATH"pyinput/Xbox.py"); +//// // joystickexcontrol->setInputDevice(i); +//// // addExternalControl(joystickexcontrol); +//// +//// //} else if(DeviceIdentifier::ref().type(i) == InputDevice::SPACENAVIGATOR) { +//// +//// // // found SpaceNavigator, use SpaceNavigator python controller +//// // JoystickExternalControl *joystickexcontrol = new JoystickExternalControl(RELATIVE_PATH"pyinput/SpaceNavigator.py"); +//// // joystickexcontrol->setInputDevice(i); +//// // addExternalControl(joystickexcontrol); +//// //} +//// +//// } +////} +//// +////void InteractionHandler::addExternalControl(ExternalControl* controller) { +//// //assert(this_); +//// if (controller != nullptr) { +//// _controllers.push_back(controller); +//// } +////} +// +//void InteractionHandler::setCamera(Camera *camera) { +// //assert(this_); +// _camera = camera; +//} +// +//Camera * InteractionHandler::getCamera() const { +// return _camera; +//} +// +//const psc InteractionHandler::getOrigin() const { +// if(_node) +// return _node->worldPosition(); +// return psc(); +//} +// +//void InteractionHandler::lockControls() { +// //assert(this_); +// _cameraGuard.lock(); +//} +// +//void InteractionHandler::unlockControls() { +// //assert(this_); +// _cameraGuard.unlock(); +//} +// +//void InteractionHandler::setFocusNode(SceneGraphNode *node) { +// //assert(this_); +// _node = node; +//} +// +//void InteractionHandler::rotate(const glm::quat &rotation) { +// //assert(this_); +// lockControls(); +// _camera->rotate(rotation); +// unlockControls(); +//} +// +//void InteractionHandler::orbit(const glm::quat &rotation) { +// //assert(this_); +// lockControls(); +// +// // the camera position +// psc relative = _camera->position(); +// +// // should be changed to something more dynamic =) +// psc origin; +// if (_node) { +// origin = _node->worldPosition(); +// } +// +// psc relative_origin_coordinate = relative - origin; +// //glm::mat4 rotation_matrix = glm::mat4_cast(glm::inverse(rotation)); +// //relative_origin_coordinate = relative_origin_coordinate.vec4() * glm::inverse(rotation); +// relative_origin_coordinate = glm::inverse(rotation) * relative_origin_coordinate.vec4(); +// relative = relative_origin_coordinate + origin; +// +// _camera->setPosition(relative); +// //camera_->rotate(rotation); +// //camera_->setRotation(glm::mat4_cast(rotation)); +// +// glm::mat4 la = glm::lookAt(_camera->position().vec3(), origin.vec3(), glm::rotate(rotation, _camera->lookUpVector())); +// _camera->setRotation(la); +// //camera_->setLookUpVector(); +// +// unlockControls(); +//} +// +//void InteractionHandler::distance(const PowerScaledScalar &distance) { +// //assert(this_); +// lockControls(); +// +// psc relative = _camera->position(); +// const psc origin = (_node) ? _node->worldPosition() : psc(); +// +// psc relative_origin_coordinate = relative - origin; +// const glm::vec3 dir(relative_origin_coordinate.direction()); +// glm:: vec3 newdir = dir * distance[0]; +// relative_origin_coordinate = newdir; +// relative_origin_coordinate[3] = distance[1]; +// relative = relative + relative_origin_coordinate; +// +// relative_origin_coordinate = relative - origin; +// newdir = relative_origin_coordinate.direction(); +// +// // update only if on the same side of the origin +// if(glm::angle(newdir, dir) < 90.0f) +// _camera->setPosition(relative); +// +// unlockControls(); +//} +// +//void InteractionHandler::lookAt(const glm::quat &rotation) { +// //assert(this_); +// lockControls(); +// +// unlockControls(); +//} +// +//void InteractionHandler::setRotation(const glm::quat &rotation) { +// //assert(this_); +// lockControls(); +// +// unlockControls(); +//} +// +//void InteractionHandler::update(const double dt) { +// //assert(this_); +// // setting dt_ for use in callbacks +// _dt = dt; +// if (_camera) { +// // fetch data from joysticks +// DeviceIdentifier::ref().update(); +// +// //// update all controllers +// //for (size_t i = 0; i < _controllers.size(); ++i) { +// // _controllers[i]->update(); +// //} +// } +//} +// +//double InteractionHandler::getDt() { +// //assert(this_); +// return _dt; +//} +// +//glm::vec3 InteractionHandler::mapToTrackball(glm::vec2 mousePos) { +// const float RADIUS = 0.5; // Sphere radius +// glm::vec3 out = glm::vec3(mousePos.x-0.5, -1.0*(mousePos.y-0.5), 0); +// +// // Mapping according to Holroyds trackball +// // Piece-wise sphere + hyperbolic sheet +// if (out.x*out.x + out.y*out.y <= RADIUS*RADIUS/2.0) { +// //Spherical Region +// out.z = RADIUS*RADIUS - (out.x*out.x + out.y*out.y); +// out.z = out.z > 0.0 ? sqrtf(out.z) : 0.0; +// } else { //Hyperbolic Region - for smooth z values +// out.z = (RADIUS*RADIUS)/(2.0*sqrt(out.x*out.x + out.y*out.y)); +// } +// +// return glm::normalize(out); +//} +// +//glm::vec3 InteractionHandler::mapToCamera(glm::vec3 trackballPos) { +//// return glm::vec3((sgct::Engine::instance()->getActiveViewMatrix() * glm::vec4(trackballPos,0))); +// +// //Get x,y,z axis vectors of current camera view +// glm::vec3 currentViewYaxis = glm::normalize(_camera->lookUpVector()); +// psc viewDir = _camera->position() - _node->worldPosition(); +// glm::vec3 currentViewZaxis = glm::normalize(viewDir.vec3()); +// glm::vec3 currentViewXaxis = glm::normalize(glm::cross(currentViewYaxis, currentViewZaxis)); +// +// //mapping to camera co-ordinate +// currentViewXaxis*=trackballPos.x; +// currentViewYaxis*=trackballPos.y; +// currentViewZaxis*=trackballPos.z; +// return (currentViewXaxis + currentViewYaxis + currentViewZaxis); +//} +// +//void InteractionHandler::trackballRotate(int x, int y) { +// // Normalize mouse coordinates to [0,1] +// float width = sgct::Engine::instance()->getActiveXResolution(); +// float height = sgct::Engine::instance()->getActiveYResolution(); +// glm::vec2 mousePos = glm::vec2((float)x/width, (float)y/height); +// +// mousePos = glm::clamp(mousePos, -0.5, 1.5); // Ugly fix #1: Camera position becomes NaN on mouse values outside [-0.5, 1.5] +// //mousePos[1] = 0.5; // Ugly fix #2: Tempoarily only allow rotation around y +// +// glm::vec3 curTrackballPos = mapToTrackball(mousePos); +//// LDEBUG(mousePos.x << ", " << mousePos.y << " = " << curTrackballPos.x << ", " << curTrackballPos.y << ", " << curTrackballPos.z); +// +// // Disable movement on the first click for extra smoothness +// if (!_isMouseBeingPressedAndHeld) { +// _lastTrackballPos = curTrackballPos; +// _isMouseBeingPressedAndHeld = true; +// } +// +// if (curTrackballPos != _lastTrackballPos) { +// // calculate rotation angle (in radians) +// float rotationAngle = glm::angle(curTrackballPos, _lastTrackballPos); +// rotationAngle *= getDt()*100.0f; +// +// // Map trackballpos to camera +//// glm::vec3 trackballMappedToCamera = mapToCamera(_lastTrackballPos - curTrackballPos); +//// psc currentCamPos = camera_->getPosition(); +//// glm::vec3 nextCamPos = currentCamPos.getVec3f() + trackballMappedToCamera; +//// glm::vec3 rotationAxis = glm::cross(currentCamPos.getVec3f(), nextCamPos); +// +// glm::vec3 rotationAxis = glm::cross(_lastTrackballPos, curTrackballPos); +// rotationAxis = glm::normalize(rotationAxis); +// glm::quat quaternion = glm::angleAxis(rotationAngle, rotationAxis); +// +// // Apply quaternion to camera +// orbit(quaternion); +// +// _lastTrackballPos = curTrackballPos; +// } +//} +//double acc = 1; +// +//void InteractionHandler::keyboardCallback(int key, int action) { +// // TODO package in script +// const double speed = 2.75; +// const double dt = getDt(); +// if(action == SGCT_PRESS || action == SGCT_REPEAT) { +// if (key == SGCT_KEY_S) { +// glm::vec3 euler(speed * dt, 0.0, 0.0); +// glm::quat rot = glm::quat(euler); +// orbit(rot); +// } +// if (key == SGCT_KEY_W) { +// glm::vec3 euler(-speed * dt, 0.0, 0.0); +// glm::quat rot = glm::quat(euler); +// orbit(rot); +// } +// if (key == SGCT_KEY_A) { +// glm::vec3 euler(0.0, -speed * dt, 0.0); +// glm::quat rot = glm::quat(euler); +// orbit(rot); +// } +// if (key == SGCT_KEY_D) { +// glm::vec3 euler(0.0, speed * dt, 0.0); +// glm::quat rot = glm::quat(euler); +// orbit(rot); +// } +// if (key == SGCT_KEY_Q) { +// Time::ref().advanceTime(dt); +// } +// if (key == 262) { +// glm::vec3 euler(0.0, speed * dt, 0.0); +// glm::quat rot = glm::quat(euler); +// rotate(rot); +// } +// if (key == 263) { +// glm::vec3 euler(0.0, -speed * dt, 0.0); +// glm::quat rot = glm::quat(euler); +// rotate(rot); +// } +// if (key == 264) { +// glm::vec3 euler(speed * dt, 0.0, 0.0); +// glm::quat rot = glm::quat(euler); +// rotate(rot); +// } +// if (key == 265) { +// glm::vec3 euler(-speed * dt, 0.0, 0.0); +// glm::quat rot = glm::quat(euler); +// rotate(rot); +// } +// if (key == SGCT_KEY_R) { +// PowerScaledScalar dist(-speed * dt, 0.0); +// distance(dist); +// } +// if (key == SGCT_KEY_F) { +// PowerScaledScalar dist(speed * dt, 0.0); +// distance(dist); +// } +// if (key == SGCT_KEY_T) { +// PowerScaledScalar dist(-speed * pow(10, 11) * dt, 0.0); +// distance(dist); +// } +// if (key == SGCT_KEY_G) { +// acc += 0.001; +// PowerScaledScalar dist(speed * pow(10, 8 * acc) * dt, 0.0); +// distance(dist); +// } +// if (key == SGCT_KEY_Y) { +// PowerScaledScalar dist(-speed * 100.0 * dt, 6.0); +// distance(dist); +// } +// if (key == SGCT_KEY_H) { +// PowerScaledScalar dist(speed * 100.0 * dt, 6.0); +// distance(dist); +// } +// +// if (key == SGCT_KEY_KP_SUBTRACT) { +// glm::vec2 s = OsEng.renderEngine().camera()->scaling(); +// s[1] -= 0.5; +// OsEng.renderEngine().camera()->setScaling(s); +// } +// if (key == SGCT_KEY_KP_ADD) { +// glm::vec2 s = OsEng.renderEngine().camera()->scaling(); +// s[1] += 0.5; +// OsEng.renderEngine().camera()->setScaling(s); +// } +// } +// /* +// if (key == '1') { +// SceneGraphNode* node = getSceneGraphNode("sun"); +// +// setFocusNode(node); +// getCamera()->setPosition(node->getWorldPosition() + psc(0.0, 0.0, 0.5, 10.0)); +// getCamera()->setCameraDirection(glm::vec3(0.0, 0.0, -1.0)); +// } +// +// if (key == '2') { +// SceneGraphNode* node = getSceneGraphNode("earth"); +// +// setFocusNode(node); +// getCamera()->setPosition(node->getWorldPosition() + psc(0.0, 0.0, 1.0, 8.0)); +// getCamera()->setCameraDirection(glm::vec3(0.0, 0.0, -1.0)); +// } +// +// +// if (key == '3') { +// SceneGraphNode* node = getSceneGraphNode("moon"); +// +// setFocusNode(node); +// getCamera()->setPosition(node->getWorldPosition() + psc(0.0, 0.0, 0.5, 8.0)); +// getCamera()->setCameraDirection(glm::vec3(0.0, 0.0, -1.0)); +// } +//*/ +// // std::pair >::iterator, std::multimap >::iterator> ret; +// if(action == SGCT_PRESS) { +// auto ret = _keyCallbacks.equal_range(key); +// for (auto it=ret.first; it!=ret.second; ++it) +// it->second(); +// } +// +// +//} +// +//void InteractionHandler::mouseButtonCallback(int key, int action) { +// //if(mouseControl_ != nullptr) { +// // mouseControl_->mouseButtonCallback(key,action); +// //} +// if (key == SGCT_MOUSE_BUTTON_LEFT && action == SGCT_PRESS) +// _leftMouseButtonDown = true; +// else if (key == SGCT_MOUSE_BUTTON_LEFT && action == SGCT_RELEASE) { +// _leftMouseButtonDown = false; +// _isMouseBeingPressedAndHeld = false; +// } +//} +// +//void InteractionHandler::mousePositionCallback(int x, int y) { +// if (_leftMouseButtonDown) +// trackballRotate(x,y); +// +// //if(mouseControl_ != nullptr) { +// // mouseControl_->mousePosCallback(x,y); +// //} +//} +// +//void InteractionHandler::mouseScrollWheelCallback(int pos) { +// //if(mouseControl_ != nullptr) { +// // mouseControl_->mouseScrollCallback(pos); +// //} +// const double speed = 4.75; +// const double dt = getDt(); +// if(pos < 0) { +// PowerScaledScalar dist(speed * dt, 0.0); +// distance(dist); +// } else if(pos > 0) { +// PowerScaledScalar dist(-speed * dt, 0.0); +// distance(dist); +// } +//} +// +////void InteractionHandler::addKeyCallback(int key, std::function f) { +//// //std::map > > _keyCallbacks; +//// +//// _keyCallbacks.insert(std::make_pair(key, f)); +////} +// +//} // namespace interaction +//} // namespace openspace diff --git a/src/interaction/keyboardcontroller.cpp b/src/interaction/keyboardcontroller.cpp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/interaction/mousecontroller.cpp b/src/interaction/mousecontroller.cpp new file mode 100644 index 0000000000..4a918dcff7 --- /dev/null +++ b/src/interaction/mousecontroller.cpp @@ -0,0 +1,24 @@ +/***************************************************************************************** + * * + * 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. * + ****************************************************************************************/ + diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 1a5ea93b7f..04d3617fa8 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -244,7 +244,6 @@ void RenderEngine::render() _abuffer->resolve(); glDisable(GL_BLEND); -#ifndef OPENSPACE_VIDEO_EXPORT // Print some useful information on the master viewport if (sgct::Engine::instance()->isMaster()) { // Apple usually has retina screens @@ -301,8 +300,6 @@ void RenderEngine::render() FONT_SIZE, FONT_SIZE * 2, "Scaling: (%.10f, %.2f)", scaling[0], scaling[1]); } -#endif - } SceneGraph* RenderEngine::sceneGraph() diff --git a/src/scenegraph/scenegraphnode.cpp b/src/scenegraph/scenegraphnode.cpp index 8a4f1acb67..21159af729 100644 --- a/src/scenegraph/scenegraphnode.cpp +++ b/src/scenegraph/scenegraphnode.cpp @@ -284,9 +284,6 @@ const std::vector& SceneGraphNode::children() const{ PowerScaledScalar SceneGraphNode::calculateBoundingSphere(){ // set the bounding sphere to 0.0 _boundingSphere = 0.0; - _boundingSphere = 1000.0; - _boundingSphere = 0.0; - if (_children.size() > 0) { // node PowerScaledScalar maxChild; @@ -296,8 +293,9 @@ PowerScaledScalar SceneGraphNode::calculateBoundingSphere(){ for (size_t i = 0; i < _children.size(); ++i) { // when positions is dynamic, change this part to fins the most distant // position - PowerScaledScalar child = _children.at(i)->position().length() - + _children.at(i)->calculateBoundingSphere(); + //PowerScaledScalar child = _children.at(i)->position().length() + // + _children.at(i)->calculateBoundingSphere(); + PowerScaledScalar child = _children.at(i)->calculateBoundingSphere(); if (child > maxChild) { maxChild = child; } @@ -311,7 +309,7 @@ PowerScaledScalar SceneGraphNode::calculateBoundingSphere(){ if(renderableBS > _boundingSphere) _boundingSphere = renderableBS; } - LWARNING(name() << ": " << _boundingSphere); + LINFO("Bounding Sphere of '" << name() << "': " << _boundingSphere); return _boundingSphere; } From d62e6296aaf0af3ca3a0797752fc86f52a6f6662 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 13 Oct 2014 00:27:20 +0200 Subject: [PATCH 2/7] More work on converting the old InteractionHandler to new methods --- include/openspace/interaction/controller.h | 83 ++++++++++++ .../interaction/interactionhandler.h | 2 + .../openspace/interaction/mousecontroller.h | 118 +++++++++++++++++- 3 files changed, 202 insertions(+), 1 deletion(-) diff --git a/include/openspace/interaction/controller.h b/include/openspace/interaction/controller.h index a98b9dd557..3a25ff2174 100644 --- a/include/openspace/interaction/controller.h +++ b/include/openspace/interaction/controller.h @@ -25,6 +25,11 @@ #ifndef __CONTROLLER_H__ #define __CONTROLLER_H__ +#include + +#include +#include + namespace openspace { namespace interaction { @@ -32,20 +37,98 @@ class InteractionHandler; class Controller { public: + Controller() : + _handler(nullptr) + {} + void setHandler(InteractionHandler* handler) { _handler = handler; } protected: + SceneGraphNode* focusNode() const { + assert(_handler); + return _handler->_focusNode; + } + + Camera* camera() const { + assert(_handler); + return _handler->_camera; + } + + + double deltaTime() const { + assert(_handler); + return _handler->_deltaTime; + } + void orbitDelta(const glm::quat& rotation) { + assert(_handler); + _handler->lockControls(); + + // the camera position + psc relative = _handler->_camera->position(); + + // should be changed to something more dynamic =) + psc origin; + if (_handler->_focusNode) { + origin = _handler->_focusNode->worldPosition(); + } + + psc relative_origin_coordinate = relative - origin; + //glm::mat4 rotation_matrix = glm::mat4_cast(glm::inverse(rotation)); + //relative_origin_coordinate = relative_origin_coordinate.vec4() * glm::inverse(rotation); + relative_origin_coordinate = glm::inverse(rotation) * relative_origin_coordinate.vec4(); + relative = relative_origin_coordinate + origin; + + _handler->_camera->setPosition(relative); + //camera_->rotate(rotation); + //camera_->setRotation(glm::mat4_cast(rotation)); + + glm::mat4 la = glm::lookAt(_handler->_camera->position().vec3(), origin.vec3(), glm::rotate(rotation, _handler->_camera->lookUpVector())); + _handler->_camera->setRotation(la); + //camera_->setLookUpVector(); + + _handler->unlockControls(); } + void rotateDelta(const glm::quat& rotation) { + assert(_handler); + _handler->lockControls(); + _handler->_camera->rotate(rotation); + _handler->unlockControls(); } + void distanceDelta(const PowerScaledScalar& distance) { + assert(_handler); + _handler->lockControls(); + + psc relative = _handler->_camera->position(); + const psc origin = (_handler->_focusNode) ? _handler->_focusNode->worldPosition() : psc(); + + psc relative_origin_coordinate = relative - origin; + const glm::vec3 dir(relative_origin_coordinate.direction()); + glm:: vec3 newdir = dir * distance[0]; + relative_origin_coordinate = newdir; + relative_origin_coordinate[3] = distance[1]; + relative = relative + relative_origin_coordinate; + + relative_origin_coordinate = relative - origin; + newdir = relative_origin_coordinate.direction(); + + // update only if on the same side of the origin + if(glm::angle(newdir, dir) < 90.0f) + _handler->_camera->setPosition(relative); + + _handler->unlockControls(); } + void lookAt(const glm::quat& rotation) { + assert(_handler); } + void setRotation(const glm::quat& rotation) { + assert(_handler); } private: diff --git a/include/openspace/interaction/interactionhandler.h b/include/openspace/interaction/interactionhandler.h index 26f15ed6c7..821bdf6003 100644 --- a/include/openspace/interaction/interactionhandler.h +++ b/include/openspace/interaction/interactionhandler.h @@ -110,6 +110,8 @@ public: } private: + friend class Controller; + InteractionHandler(const InteractionHandler&) = delete; InteractionHandler& operator=(const InteractionHandler&) = delete; InteractionHandler(InteractionHandler&&) = delete; diff --git a/include/openspace/interaction/mousecontroller.h b/include/openspace/interaction/mousecontroller.h index ebdd455e0e..fa66b18f40 100644 --- a/include/openspace/interaction/mousecontroller.h +++ b/include/openspace/interaction/mousecontroller.h @@ -29,14 +29,130 @@ #include +#include + namespace openspace { namespace interaction { class MouseController : public Controller { public: + MouseController() + : _lastTrackballPos(0.f) + , _isMouseBeingPressedAndHeld(false) + {} + virtual void button(MouseAction action, MouseButton button) = 0; virtual void move(float x, float y) = 0; - virtual void scrollWheel(float z) = 0; + virtual void scrollWheel(int pos) = 0; + +protected: + glm::vec3 _lastTrackballPos; + bool _isMouseBeingPressedAndHeld; + + glm::vec3 mapToTrackball(glm::vec2 mousePos) { + const float RADIUS = 0.5; // Sphere radius + glm::vec3 out = glm::vec3(mousePos.x-0.5, -1.0*(mousePos.y-0.5), 0); + + // Mapping according to Holroyds trackball + // Piece-wise sphere + hyperbolic sheet + if (out.x*out.x + out.y*out.y <= RADIUS*RADIUS/2.0) { + //Spherical Region + out.z = RADIUS*RADIUS - (out.x*out.x + out.y*out.y); + out.z = out.z > 0.0 ? sqrtf(out.z) : 0.0; + } else { //Hyperbolic Region - for smooth z values + out.z = (RADIUS*RADIUS)/(2.0*sqrt(out.x*out.x + out.y*out.y)); + } + + return glm::normalize(out); + } + + glm::vec3 mapToCamera(glm::vec3 trackballPos) { + // return glm::vec3((sgct::Engine::instance()->getActiveViewMatrix() * glm::vec4(trackballPos,0))); + + //Get x,y,z axis vectors of current camera view + glm::vec3 currentViewYaxis = glm::normalize(camera()->lookUpVector()); + psc viewDir = camera()->position() - focusNode()->worldPosition(); + glm::vec3 currentViewZaxis = glm::normalize(viewDir.vec3()); + glm::vec3 currentViewXaxis = glm::normalize(glm::cross(currentViewYaxis, currentViewZaxis)); + + //mapping to camera co-ordinate + currentViewXaxis*=trackballPos.x; + currentViewYaxis*=trackballPos.y; + currentViewZaxis*=trackballPos.z; + return (currentViewXaxis + currentViewYaxis + currentViewZaxis); + } + + void trackballRotate(int x, int y) { + // Normalize mouse coordinates to [0,1] + float width = sgct::Engine::instance()->getActiveXResolution(); + float height = sgct::Engine::instance()->getActiveYResolution(); + glm::vec2 mousePos = glm::vec2((float)x/width, (float)y/height); + + mousePos = glm::clamp(mousePos, -0.5, 1.5); // Ugly fix #1: Camera position becomes NaN on mouse values outside [-0.5, 1.5] + //mousePos[1] = 0.5; // Ugly fix #2: Tempoarily only allow rotation around y + + glm::vec3 curTrackballPos = mapToTrackball(mousePos); + // LDEBUG(mousePos.x << ", " << mousePos.y << " = " << curTrackballPos.x << ", " << curTrackballPos.y << ", " << curTrackballPos.z); + + // Disable movement on the first click for extra smoothness + if (!_isMouseBeingPressedAndHeld) { + _lastTrackballPos = curTrackballPos; + _isMouseBeingPressedAndHeld = true; + } + + if (curTrackballPos != _lastTrackballPos) { + // calculate rotation angle (in radians) + float rotationAngle = glm::angle(curTrackballPos, _lastTrackballPos); + rotationAngle *= deltaTime() * 100.0f; + + // Map trackballpos to camera + // glm::vec3 trackballMappedToCamera = mapToCamera(_lastTrackballPos - curTrackballPos); + // psc currentCamPos = camera_->getPosition(); + // glm::vec3 nextCamPos = currentCamPos.getVec3f() + trackballMappedToCamera; + // glm::vec3 rotationAxis = glm::cross(currentCamPos.getVec3f(), nextCamPos); + + glm::vec3 rotationAxis = glm::cross(_lastTrackballPos, curTrackballPos); + rotationAxis = glm::normalize(rotationAxis); + glm::quat quaternion = glm::angleAxis(rotationAngle, rotationAxis); + + // Apply quaternion to camera + orbitDelta(quaternion); + + _lastTrackballPos = curTrackballPos; + } + } +}; + +class OrbitMouseController : public MouseController { +public: + void button(MouseAction action, MouseButton button) { + if (button == MouseButton::Left && action == MouseAction::Press) + _leftMouseButtonDown = true; + else if (button == MouseButton::Left && action == MouseAction::Release) { + _leftMouseButtonDown = false; + _isMouseBeingPressedAndHeld = false; + } + } + + void move(float x, float y) { + if (_leftMouseButtonDown) + trackballRotate(x,y); + } + + void scrollWheel(int pos) { + const double speed = 4.75; + const double dt = deltaTime(); + if (pos < 0) { + PowerScaledScalar dist(speed * dt, 0.0); + distanceDelta(dist); + } else if(pos > 0) { + PowerScaledScalar dist(-speed * dt, 0.0); + distanceDelta(dist); + } + } + +protected: + bool _leftMouseButtonDown; }; } // namespace interaction From ff62c06320014b51319526bed0f7bd9836db0459 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 13 Oct 2014 00:39:46 +0200 Subject: [PATCH 3/7] Installed new InteractionHandler --- include/openspace/interaction/controller.h | 56 +------- .../interaction/keyboardcontroller.h | 2 +- .../openspace/interaction/mousecontroller.h | 2 +- src/engine/openspaceengine.cpp | 7 +- src/interaction/controller.cpp | 131 ++++++++++++++++++ 5 files changed, 144 insertions(+), 54 deletions(-) diff --git a/include/openspace/interaction/controller.h b/include/openspace/interaction/controller.h index 3a25ff2174..ca812baf65 100644 --- a/include/openspace/interaction/controller.h +++ b/include/openspace/interaction/controller.h @@ -41,63 +41,19 @@ public: _handler(nullptr) {} - void setHandler(InteractionHandler* handler) { - _handler = handler; - } + void setHandler(InteractionHandler* handler); protected: - SceneGraphNode* focusNode() const { - assert(_handler); - return _handler->_focusNode; - } + SceneGraphNode* focusNode() const; - Camera* camera() const { - assert(_handler); - return _handler->_camera; - } + Camera* camera() const; - double deltaTime() const { - assert(_handler); - return _handler->_deltaTime; - } + double deltaTime() const; - void orbitDelta(const glm::quat& rotation) { - assert(_handler); - _handler->lockControls(); - - // the camera position - psc relative = _handler->_camera->position(); + void orbitDelta(const glm::quat& rotation); - // should be changed to something more dynamic =) - psc origin; - if (_handler->_focusNode) { - origin = _handler->_focusNode->worldPosition(); - } - - psc relative_origin_coordinate = relative - origin; - //glm::mat4 rotation_matrix = glm::mat4_cast(glm::inverse(rotation)); - //relative_origin_coordinate = relative_origin_coordinate.vec4() * glm::inverse(rotation); - relative_origin_coordinate = glm::inverse(rotation) * relative_origin_coordinate.vec4(); - relative = relative_origin_coordinate + origin; - - _handler->_camera->setPosition(relative); - //camera_->rotate(rotation); - //camera_->setRotation(glm::mat4_cast(rotation)); - - glm::mat4 la = glm::lookAt(_handler->_camera->position().vec3(), origin.vec3(), glm::rotate(rotation, _handler->_camera->lookUpVector())); - _handler->_camera->setRotation(la); - //camera_->setLookUpVector(); - - _handler->unlockControls(); - } - - void rotateDelta(const glm::quat& rotation) { - assert(_handler); - _handler->lockControls(); - _handler->_camera->rotate(rotation); - _handler->unlockControls(); - } + void rotateDelta(const glm::quat& rotation); void distanceDelta(const PowerScaledScalar& distance) { assert(_handler); diff --git a/include/openspace/interaction/keyboardcontroller.h b/include/openspace/interaction/keyboardcontroller.h index 22314015ea..e6096478b2 100644 --- a/include/openspace/interaction/keyboardcontroller.h +++ b/include/openspace/interaction/keyboardcontroller.h @@ -39,7 +39,7 @@ public: class KeyboardControllerFixed : public KeyboardController { public: - void keyPressed(KeyAction action, Keys key) = 0 { + void keyPressed(KeyAction action, Keys key) { } }; diff --git a/include/openspace/interaction/mousecontroller.h b/include/openspace/interaction/mousecontroller.h index fa66b18f40..29527e600e 100644 --- a/include/openspace/interaction/mousecontroller.h +++ b/include/openspace/interaction/mousecontroller.h @@ -123,7 +123,7 @@ protected: } }; -class OrbitMouseController : public MouseController { +class TrackballMouseController : public MouseController { public: void button(MouseAction action, MouseButton button) { if (button == MouseButton::Left && action == MouseAction::Press) diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 7d12dc3b73..3106b4d87d 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -24,8 +24,9 @@ #include -#include #include +#include +#include #include #include #include @@ -307,7 +308,9 @@ bool OpenSpaceEngine::initialize() { // Initialize OpenSpace input devices DeviceIdentifier::init(); DeviceIdentifier::ref().scanDevices(); - //_interactionHandler.connectDevices(); + + _interactionHandler.setKeyboardController(new interaction::KeyboardControllerFixed); + _interactionHandler.setMouseController(new interaction::TrackballMouseController); // Run start up scripts ghoul::Dictionary scripts; diff --git a/src/interaction/controller.cpp b/src/interaction/controller.cpp index e69de29bb2..aee74159f9 100644 --- a/src/interaction/controller.cpp +++ b/src/interaction/controller.cpp @@ -0,0 +1,131 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include + +#include + +namespace openspace { +namespace interaction { + +void Controller::setHandler(InteractionHandler* handler) +{ + _handler = handler; +} + +SceneGraphNode* Controller::focusNode() const +{ + assert(_handler); + return _handler->_focusNode; +} + +Camera* Controller::camera() const +{ + assert(_handler); + return _handler->_camera; +} + +double Controller::deltaTime() const +{ + assert(_handler); + return _handler->_deltaTime; +} + +void openspace::interaction::Controller::orbitDelta(const glm::quat& rotation) +{ + assert(_handler); + _handler->lockControls(); + + // the camera position + psc relative = _handler->_camera->position(); + + // should be changed to something more dynamic =) + psc origin; + if (_handler->_focusNode) { + origin = _handler->_focusNode->worldPosition(); + } + + psc relative_origin_coordinate = relative - origin; + //glm::mat4 rotation_matrix = glm::mat4_cast(glm::inverse(rotation)); + //relative_origin_coordinate = relative_origin_coordinate.vec4() * glm::inverse(rotation); + relative_origin_coordinate = glm::inverse(rotation) * relative_origin_coordinate.vec4(); + relative = relative_origin_coordinate + origin; + + _handler->_camera->setPosition(relative); + //camera_->rotate(rotation); + //camera_->setRotation(glm::mat4_cast(rotation)); + + glm::mat4 la = glm::lookAt(_handler->_camera->position().vec3(), origin.vec3(), glm::rotate(rotation, _handler->_camera->lookUpVector())); + _handler->_camera->setRotation(la); + //camera_->setLookUpVector(); + + _handler->unlockControls(); +} + +void openspace::interaction::Controller::rotateDelta(const glm::quat& rotation) +{ + assert(_handler); + _handler->lockControls(); + _handler->_camera->rotate(rotation); + _handler->unlockControls(); +} + +void openspace::interaction::Controller::distanceDelta(const PowerScaledScalar& distance) +{ + assert(_handler); + _handler->lockControls(); + + psc relative = _handler->_camera->position(); + const psc origin = (_handler->_focusNode) ? _handler->_focusNode->worldPosition() : psc(); + + psc relative_origin_coordinate = relative - origin; + const glm::vec3 dir(relative_origin_coordinate.direction()); + glm::vec3 newdir = dir * distance[0]; + relative_origin_coordinate = newdir; + relative_origin_coordinate[3] = distance[1]; + relative = relative + relative_origin_coordinate; + + relative_origin_coordinate = relative - origin; + newdir = relative_origin_coordinate.direction(); + + // update only if on the same side of the origin + if (glm::angle(newdir, dir) < 90.0f) + _handler->_camera->setPosition(relative); + + _handler->unlockControls(); +} + +void openspace::interaction::Controller::lookAt(const glm::quat& rotation) +{ + assert(_handler); +} + +void openspace::interaction::Controller::setRotation(const glm::quat& rotation) +{ + assert(_handler); +} + +} // namespace interaction +} // namespace openspace + From c41b1b178a72303be02881f3dec2c6c33d8561be Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 13 Oct 2014 00:43:36 +0200 Subject: [PATCH 4/7] Added missing commit --- include/openspace/interaction/controller.h | 32 ++-------------------- 1 file changed, 3 insertions(+), 29 deletions(-) diff --git a/include/openspace/interaction/controller.h b/include/openspace/interaction/controller.h index ca812baf65..6675b1acb2 100644 --- a/include/openspace/interaction/controller.h +++ b/include/openspace/interaction/controller.h @@ -55,37 +55,11 @@ protected: void rotateDelta(const glm::quat& rotation); - void distanceDelta(const PowerScaledScalar& distance) { - assert(_handler); - _handler->lockControls(); - - psc relative = _handler->_camera->position(); - const psc origin = (_handler->_focusNode) ? _handler->_focusNode->worldPosition() : psc(); + void distanceDelta(const PowerScaledScalar& distance); - psc relative_origin_coordinate = relative - origin; - const glm::vec3 dir(relative_origin_coordinate.direction()); - glm:: vec3 newdir = dir * distance[0]; - relative_origin_coordinate = newdir; - relative_origin_coordinate[3] = distance[1]; - relative = relative + relative_origin_coordinate; + void lookAt(const glm::quat& rotation); - relative_origin_coordinate = relative - origin; - newdir = relative_origin_coordinate.direction(); - - // update only if on the same side of the origin - if(glm::angle(newdir, dir) < 90.0f) - _handler->_camera->setPosition(relative); - - _handler->unlockControls(); - } - - void lookAt(const glm::quat& rotation) { - assert(_handler); - } - - void setRotation(const glm::quat& rotation) { - assert(_handler); - } + void setRotation(const glm::quat& rotation); private: InteractionHandler* _handler; From 0518e8cf022c009bd192487986a4ce89203cf5d1 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 13 Oct 2014 10:29:04 +0200 Subject: [PATCH 5/7] Added fixed key mapping to KeyboardControl fixed Cleanup of code --- .../interaction/interactionhandler.h | 79 ++------- .../interaction/keyboardcontroller.h | 8 +- include/openspace/interaction/keys.h | 2 +- include/openspace/interaction/mouse.h | 2 +- .../openspace/interaction/mousecontroller.h | 106 ++---------- src/engine/openspaceengine.cpp | 6 +- .../externalcontrol/externalcontrol.cpp | 6 +- src/interaction/interactionhandler.cpp | 139 +++++++++++++--- src/interaction/keyboardcontroller.cpp | 152 ++++++++++++++++++ src/interaction/mousecontroller.cpp | 119 ++++++++++++++ src/rendering/renderengine.cpp | 2 +- 11 files changed, 423 insertions(+), 198 deletions(-) diff --git a/include/openspace/interaction/interactionhandler.h b/include/openspace/interaction/interactionhandler.h index 821bdf6003..c9fbde65f5 100644 --- a/include/openspace/interaction/interactionhandler.h +++ b/include/openspace/interaction/interactionhandler.h @@ -39,75 +39,28 @@ namespace interaction { class InteractionHandler { public: - InteractionHandler() - : _camera(nullptr) - , _focusNode(nullptr) - , _keyboardController(nullptr) - , _mouseController(nullptr) - { - } + InteractionHandler(); - ~InteractionHandler() { - delete _keyboardController; - delete _mouseController; - for (size_t i = 0; i < _controllers.size(); ++i) - delete _controllers[i]; + ~InteractionHandler(); - } + void setKeyboardController(KeyboardController* controller); + void setMouseController(MouseController* controller); + void addController(Controller* controller); - void setKeyboardController(KeyboardController* controller) { - delete _keyboardController; - _keyboardController = controller; - _keyboardController->setHandler(this); - } + void lockControls(); + void unlockControls(); - void setMouseController(MouseController* controller) { - delete _mouseController; - _mouseController = controller; - _mouseController->setHandler(this); - } + void update(double deltaTime); - void addController(Controller* controller) { - _controllers.push_back(controller); - controller->setHandler(this); - } + void setFocusNode(SceneGraphNode* node); + const SceneGraphNode* const focusNode() const; + void setCamera(Camera* camera); + const Camera* const camera() const; - void lockControls() { - _mutex.lock(); - } - - void unlockControls() { - _mutex.unlock(); - } - - void update(double deltaTime) { - _deltaTime = deltaTime; - } - - void setFocusNode(SceneGraphNode* node) { - _focusNode = node; - } - - void keyboardCallback(int key, int action) { - if (_keyboardController) - _keyboardController->keyPressed(KeyAction(action), Keys(key)); - } - - void mouseButtonCallback(int button, int action) { - if (_mouseController) - _mouseController->button(MouseAction(action), MouseButton(button)); - } - - void mousePositionCallback(int x, int y) { - if (_mouseController) - // TODO Remap screen coordinates to [0,1] - _mouseController->move(float(x), float(y)); - } - - void mouseScrollWheelCallback(int pos) { - if (_mouseController) - _mouseController->scrollWheel(float(pos)); - } + void keyboardCallback(int key, int action); + void mouseButtonCallback(int button, int action); + void mousePositionCallback(int x, int y); + void mouseScrollWheelCallback(int pos); private: friend class Controller; diff --git a/include/openspace/interaction/keyboardcontroller.h b/include/openspace/interaction/keyboardcontroller.h index e6096478b2..3b8d1b979f 100644 --- a/include/openspace/interaction/keyboardcontroller.h +++ b/include/openspace/interaction/keyboardcontroller.h @@ -39,16 +39,12 @@ public: class KeyboardControllerFixed : public KeyboardController { public: - void keyPressed(KeyAction action, Keys key) { - - } + void keyPressed(KeyAction action, Keys key); }; class KeyboardControllerLua : public KeyboardController { public: - void keyPressed(KeyAction action, Keys key) { - - } + void keyPressed(KeyAction action, Keys key); }; } // namespace interaction diff --git a/include/openspace/interaction/keys.h b/include/openspace/interaction/keys.h index 72f86ddd99..19e722577e 100644 --- a/include/openspace/interaction/keys.h +++ b/include/openspace/interaction/keys.h @@ -162,7 +162,7 @@ enum class Keys { Control = LeftControl | RightControl, Alt = LeftAlt | RightAlt, Super = LeftSuper | RightSuper -} +}; } // namespace interaction } // namespace openspace diff --git a/include/openspace/interaction/mouse.h b/include/openspace/interaction/mouse.h index 6c2d40cc14..2a4cca19d6 100644 --- a/include/openspace/interaction/mouse.h +++ b/include/openspace/interaction/mouse.h @@ -49,7 +49,7 @@ enum class MouseButton { Button7 = SGCT_MOUSE_BUTTON_7, Button8 = SGCT_MOUSE_BUTTON_8, ButtonLast = SGCT_MOUSE_BUTTON_LAST, -} +}; } // namespace interaction } // namespace openspace diff --git a/include/openspace/interaction/mousecontroller.h b/include/openspace/interaction/mousecontroller.h index 29527e600e..64f085d442 100644 --- a/include/openspace/interaction/mousecontroller.h +++ b/include/openspace/interaction/mousecontroller.h @@ -36,10 +36,7 @@ namespace interaction { class MouseController : public Controller { public: - MouseController() - : _lastTrackballPos(0.f) - , _isMouseBeingPressedAndHeld(false) - {} + MouseController(); virtual void button(MouseAction action, MouseButton button) = 0; virtual void move(float x, float y) = 0; @@ -49,107 +46,22 @@ protected: glm::vec3 _lastTrackballPos; bool _isMouseBeingPressedAndHeld; - glm::vec3 mapToTrackball(glm::vec2 mousePos) { - const float RADIUS = 0.5; // Sphere radius - glm::vec3 out = glm::vec3(mousePos.x-0.5, -1.0*(mousePos.y-0.5), 0); + glm::vec3 mapToTrackball(glm::vec2 mousePos); - // Mapping according to Holroyds trackball - // Piece-wise sphere + hyperbolic sheet - if (out.x*out.x + out.y*out.y <= RADIUS*RADIUS/2.0) { - //Spherical Region - out.z = RADIUS*RADIUS - (out.x*out.x + out.y*out.y); - out.z = out.z > 0.0 ? sqrtf(out.z) : 0.0; - } else { //Hyperbolic Region - for smooth z values - out.z = (RADIUS*RADIUS)/(2.0*sqrt(out.x*out.x + out.y*out.y)); - } + glm::vec3 mapToCamera(glm::vec3 trackballPos); - return glm::normalize(out); - } - - glm::vec3 mapToCamera(glm::vec3 trackballPos) { - // return glm::vec3((sgct::Engine::instance()->getActiveViewMatrix() * glm::vec4(trackballPos,0))); - - //Get x,y,z axis vectors of current camera view - glm::vec3 currentViewYaxis = glm::normalize(camera()->lookUpVector()); - psc viewDir = camera()->position() - focusNode()->worldPosition(); - glm::vec3 currentViewZaxis = glm::normalize(viewDir.vec3()); - glm::vec3 currentViewXaxis = glm::normalize(glm::cross(currentViewYaxis, currentViewZaxis)); - - //mapping to camera co-ordinate - currentViewXaxis*=trackballPos.x; - currentViewYaxis*=trackballPos.y; - currentViewZaxis*=trackballPos.z; - return (currentViewXaxis + currentViewYaxis + currentViewZaxis); - } - - void trackballRotate(int x, int y) { - // Normalize mouse coordinates to [0,1] - float width = sgct::Engine::instance()->getActiveXResolution(); - float height = sgct::Engine::instance()->getActiveYResolution(); - glm::vec2 mousePos = glm::vec2((float)x/width, (float)y/height); - - mousePos = glm::clamp(mousePos, -0.5, 1.5); // Ugly fix #1: Camera position becomes NaN on mouse values outside [-0.5, 1.5] - //mousePos[1] = 0.5; // Ugly fix #2: Tempoarily only allow rotation around y - - glm::vec3 curTrackballPos = mapToTrackball(mousePos); - // LDEBUG(mousePos.x << ", " << mousePos.y << " = " << curTrackballPos.x << ", " << curTrackballPos.y << ", " << curTrackballPos.z); - - // Disable movement on the first click for extra smoothness - if (!_isMouseBeingPressedAndHeld) { - _lastTrackballPos = curTrackballPos; - _isMouseBeingPressedAndHeld = true; - } - - if (curTrackballPos != _lastTrackballPos) { - // calculate rotation angle (in radians) - float rotationAngle = glm::angle(curTrackballPos, _lastTrackballPos); - rotationAngle *= deltaTime() * 100.0f; - - // Map trackballpos to camera - // glm::vec3 trackballMappedToCamera = mapToCamera(_lastTrackballPos - curTrackballPos); - // psc currentCamPos = camera_->getPosition(); - // glm::vec3 nextCamPos = currentCamPos.getVec3f() + trackballMappedToCamera; - // glm::vec3 rotationAxis = glm::cross(currentCamPos.getVec3f(), nextCamPos); - - glm::vec3 rotationAxis = glm::cross(_lastTrackballPos, curTrackballPos); - rotationAxis = glm::normalize(rotationAxis); - glm::quat quaternion = glm::angleAxis(rotationAngle, rotationAxis); - - // Apply quaternion to camera - orbitDelta(quaternion); - - _lastTrackballPos = curTrackballPos; - } - } + void trackballRotate(int x, int y); }; class TrackballMouseController : public MouseController { public: - void button(MouseAction action, MouseButton button) { - if (button == MouseButton::Left && action == MouseAction::Press) - _leftMouseButtonDown = true; - else if (button == MouseButton::Left && action == MouseAction::Release) { - _leftMouseButtonDown = false; - _isMouseBeingPressedAndHeld = false; - } - } + TrackballMouseController(); - void move(float x, float y) { - if (_leftMouseButtonDown) - trackballRotate(x,y); - } + void button(MouseAction action, MouseButton button); - void scrollWheel(int pos) { - const double speed = 4.75; - const double dt = deltaTime(); - if (pos < 0) { - PowerScaledScalar dist(speed * dt, 0.0); - distanceDelta(dist); - } else if(pos > 0) { - PowerScaledScalar dist(-speed * dt, 0.0); - distanceDelta(dist); - } - } + void move(float x, float y); + + void scrollWheel(int pos); protected: bool _leftMouseButtonDown; diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 3106b4d87d..f528652f9c 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -75,7 +75,7 @@ OpenSpaceEngine::OpenSpaceEngine(std::string programName) OpenSpaceEngine::~OpenSpaceEngine() { SpiceManager::deinitialize(); Time::deinitialize(); - DeviceIdentifier::deinit(); + //DeviceIdentifier::deinit(); FileSystem::deinitialize(); LogManager::deinitialize(); } @@ -306,8 +306,8 @@ bool OpenSpaceEngine::initialize() { sceneGraph->scheduleLoadSceneFile(sceneDescriptionPath); // Initialize OpenSpace input devices - DeviceIdentifier::init(); - DeviceIdentifier::ref().scanDevices(); + //DeviceIdentifier::init(); + //DeviceIdentifier::ref().scanDevices(); _interactionHandler.setKeyboardController(new interaction::KeyboardControllerFixed); _interactionHandler.setMouseController(new interaction::TrackballMouseController); diff --git a/src/interaction/externalcontrol/externalcontrol.cpp b/src/interaction/externalcontrol/externalcontrol.cpp index ff37ffd055..9060259c7f 100644 --- a/src/interaction/externalcontrol/externalcontrol.cpp +++ b/src/interaction/externalcontrol/externalcontrol.cpp @@ -17,15 +17,15 @@ void ExternalControl::update() { } void ExternalControl::rotate(const glm::quat &rotation) { - OsEng.interactionHandler().rotate(rotation); + //OsEng.interactionHandler().rotate(rotation); } void ExternalControl::orbit(const glm::quat &rotation) { - OsEng.interactionHandler().orbit(rotation); + //OsEng.interactionHandler().orbit(rotation); } void ExternalControl::distance(const PowerScaledScalar &distance) { - OsEng.interactionHandler().distance(distance); + //OsEng.interactionHandler().distance(distance); } diff --git a/src/interaction/interactionhandler.cpp b/src/interaction/interactionhandler.cpp index d4024dd9d4..bceb05d861 100644 --- a/src/interaction/interactionhandler.cpp +++ b/src/interaction/interactionhandler.cpp @@ -1,26 +1,119 @@ -///***************************************************************************************** -// * * -// * 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. * -// ****************************************************************************************/ +/***************************************************************************************** + * * + * 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 + +namespace openspace { +namespace interaction { + +InteractionHandler::InteractionHandler() + : _camera(nullptr) + , _focusNode(nullptr) + , _keyboardController(nullptr) + , _mouseController(nullptr) +{ +} + +InteractionHandler::~InteractionHandler() { + delete _keyboardController; + delete _mouseController; + for (size_t i = 0; i < _controllers.size(); ++i) + delete _controllers[i]; +} + +void InteractionHandler::setKeyboardController(KeyboardController* controller) { + assert(controller); + delete _keyboardController; + _keyboardController = controller; + _keyboardController->setHandler(this); +} + +void InteractionHandler::setMouseController(MouseController* controller) { + assert(controller); + delete _mouseController; + _mouseController = controller; + _mouseController->setHandler(this); +} + +void InteractionHandler::addController(Controller* controller) { + assert(controller); + _controllers.push_back(controller); + controller->setHandler(this); +} + +void InteractionHandler::lockControls() { + _mutex.lock(); +} + +void InteractionHandler::unlockControls() { + _mutex.unlock(); +} + +void InteractionHandler::update(double deltaTime) { + _deltaTime = deltaTime; +} + +void InteractionHandler::setFocusNode(SceneGraphNode* node) { + _focusNode = node; +} + +const SceneGraphNode* const InteractionHandler::focusNode() const { + return _focusNode; +} + +void InteractionHandler::setCamera(Camera* camera) { + assert(camera); + _camera = camera; +} +const Camera* const InteractionHandler::camera() const { + return _camera; +} + +void InteractionHandler::keyboardCallback(int key, int action) { + if (_keyboardController) + _keyboardController->keyPressed(KeyAction(action), Keys(key)); +} + +void InteractionHandler::mouseButtonCallback(int button, int action) { + if (_mouseController) + _mouseController->button(MouseAction(action), MouseButton(button)); +} + +void InteractionHandler::mousePositionCallback(int x, int y) { + if (_mouseController) + // TODO Remap screen coordinates to [0,1] + _mouseController->move(float(x), float(y)); +} + +void InteractionHandler::mouseScrollWheelCallback(int pos) { + if (_mouseController) + _mouseController->scrollWheel(float(pos)); +} + +} // namespace interaction +} // namespace openspace + // //// open space includes //#include diff --git a/src/interaction/keyboardcontroller.cpp b/src/interaction/keyboardcontroller.cpp index e69de29bb2..6aeb91d383 100644 --- a/src/interaction/keyboardcontroller.cpp +++ b/src/interaction/keyboardcontroller.cpp @@ -0,0 +1,152 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include + +#include +#include + +namespace openspace { +namespace interaction { + +void KeyboardControllerFixed::keyPressed(KeyAction action, Keys key) { + // TODO package in script + const double speed = 2.75; + const double dt = deltaTime(); + if(action == KeyAction::Press|| action == KeyAction::Repeat) { + if (key == Keys::S) { + glm::vec3 euler(speed * dt, 0.0, 0.0); + glm::quat rot = glm::quat(euler); + orbitDelta(rot); + } + if (key == Keys::W) { + glm::vec3 euler(-speed * dt, 0.0, 0.0); + glm::quat rot = glm::quat(euler); + orbitDelta(rot); + } + if (key == Keys::A) { + glm::vec3 euler(0.0, -speed * dt, 0.0); + glm::quat rot = glm::quat(euler); + orbitDelta(rot); + } + if (key == Keys::D) { + glm::vec3 euler(0.0, speed * dt, 0.0); + glm::quat rot = glm::quat(euler); + orbitDelta(rot); + } + if (key == Keys::Q) { + Time::ref().advanceTime(dt); + } + if (key == Keys::Right) { + glm::vec3 euler(0.0, speed * dt, 0.0); + glm::quat rot = glm::quat(euler); + rotateDelta(rot); + } + if (key == Keys::Left) { + glm::vec3 euler(0.0, -speed * dt, 0.0); + glm::quat rot = glm::quat(euler); + rotateDelta(rot); + } + if (key == Keys::Down) { + glm::vec3 euler(speed * dt, 0.0, 0.0); + glm::quat rot = glm::quat(euler); + rotateDelta(rot); + } + if (key == Keys::Up) { + glm::vec3 euler(-speed * dt, 0.0, 0.0); + glm::quat rot = glm::quat(euler); + rotateDelta(rot); + } + if (key == Keys::R) { + PowerScaledScalar dist(-speed * dt, 0.0); + distanceDelta(dist); + } + if (key == Keys::F) { + PowerScaledScalar dist(speed * dt, 0.0); + distanceDelta(dist); + } + if (key == Keys::T) { + PowerScaledScalar dist(-speed * pow(10, 11) * dt, 0.0); + distanceDelta(dist); + } + //if (key == Keys::G) { + // acc += 0.001; + // PowerScaledScalar dist(speed * pow(10, 8 * acc) * dt, 0.0); + // distanceDelta(dist); + //} + if (key == Keys::Y) { + PowerScaledScalar dist(-speed * 100.0 * dt, 6.0); + distanceDelta(dist); + } + if (key == Keys::H) { + PowerScaledScalar dist(speed * 100.0 * dt, 6.0); + distanceDelta(dist); + } + + if (key == Keys::KeypadSubtract) { + glm::vec2 s = OsEng.renderEngine().camera()->scaling(); + s[1] -= 0.5; + OsEng.renderEngine().camera()->setScaling(s); + } + if (key == Keys::KeypadAdd) { + glm::vec2 s = OsEng.renderEngine().camera()->scaling(); + s[1] += 0.5; + OsEng.renderEngine().camera()->setScaling(s); + } + } + /* + if (key == '1') { + SceneGraphNode* node = getSceneGraphNode("sun"); + + setFocusNode(node); + getCamera()->setPosition(node->getWorldPosition() + psc(0.0, 0.0, 0.5, 10.0)); + getCamera()->setCameraDirection(glm::vec3(0.0, 0.0, -1.0)); + } + + if (key == '2') { + SceneGraphNode* node = getSceneGraphNode("earth"); + + setFocusNode(node); + getCamera()->setPosition(node->getWorldPosition() + psc(0.0, 0.0, 1.0, 8.0)); + getCamera()->setCameraDirection(glm::vec3(0.0, 0.0, -1.0)); + } + + + if (key == '3') { + SceneGraphNode* node = getSceneGraphNode("moon"); + + setFocusNode(node); + getCamera()->setPosition(node->getWorldPosition() + psc(0.0, 0.0, 0.5, 8.0)); + getCamera()->setCameraDirection(glm::vec3(0.0, 0.0, -1.0)); + } + */ +} + +void KeyboardControllerLua::keyPressed(KeyAction action, Keys key) +{ + +} + +} // namespace interaction +} // namespace openspace \ No newline at end of file diff --git a/src/interaction/mousecontroller.cpp b/src/interaction/mousecontroller.cpp index 4a918dcff7..35a58c93f7 100644 --- a/src/interaction/mousecontroller.cpp +++ b/src/interaction/mousecontroller.cpp @@ -22,3 +22,122 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ +#include + +namespace openspace { +namespace interaction { + +MouseController::MouseController() + : _lastTrackballPos(0.f) + , _isMouseBeingPressedAndHeld(false) +{} + +glm::vec3 MouseController::mapToTrackball(glm::vec2 mousePos) { + const float RADIUS = 0.5; // Sphere radius + glm::vec3 out = glm::vec3(mousePos.x - 0.5, -1.0*(mousePos.y - 0.5), 0); + + // Mapping according to Holroyds trackball + // Piece-wise sphere + hyperbolic sheet + if (out.x*out.x + out.y*out.y <= RADIUS*RADIUS / 2.0) { + //Spherical Region + out.z = RADIUS*RADIUS - (out.x*out.x + out.y*out.y); + out.z = out.z > 0.0 ? sqrtf(out.z) : 0.0; + } + else { //Hyperbolic Region - for smooth z values + out.z = (RADIUS*RADIUS) / (2.0*sqrt(out.x*out.x + out.y*out.y)); + } + + return glm::normalize(out); +} + +glm::vec3 MouseController::mapToCamera(glm::vec3 trackballPos) { + // return glm::vec3((sgct::Engine::instance()->getActiveViewMatrix() * glm::vec4(trackballPos,0))); + + //Get x,y,z axis vectors of current camera view + glm::vec3 currentViewYaxis = glm::normalize(camera()->lookUpVector()); + psc viewDir = camera()->position() - focusNode()->worldPosition(); + glm::vec3 currentViewZaxis = glm::normalize(viewDir.vec3()); + glm::vec3 currentViewXaxis = glm::normalize(glm::cross(currentViewYaxis, currentViewZaxis)); + + //mapping to camera co-ordinate + currentViewXaxis *= trackballPos.x; + currentViewYaxis *= trackballPos.y; + currentViewZaxis *= trackballPos.z; + return (currentViewXaxis + currentViewYaxis + currentViewZaxis); +} + +void MouseController::trackballRotate(int x, int y) { + // Normalize mouse coordinates to [0,1] + float width = sgct::Engine::instance()->getActiveXResolution(); + float height = sgct::Engine::instance()->getActiveYResolution(); + glm::vec2 mousePos = glm::vec2((float)x / width, (float)y / height); + + mousePos = glm::clamp(mousePos, -0.5, 1.5); // Ugly fix #1: Camera position becomes NaN on mouse values outside [-0.5, 1.5] + //mousePos[1] = 0.5; // Ugly fix #2: Tempoarily only allow rotation around y + + glm::vec3 curTrackballPos = mapToTrackball(mousePos); + // LDEBUG(mousePos.x << ", " << mousePos.y << " = " << curTrackballPos.x << ", " << curTrackballPos.y << ", " << curTrackballPos.z); + + // Disable movement on the first click for extra smoothness + if (!_isMouseBeingPressedAndHeld) { + _lastTrackballPos = curTrackballPos; + _isMouseBeingPressedAndHeld = true; + } + + if (curTrackballPos != _lastTrackballPos) { + // calculate rotation angle (in radians) + float rotationAngle = glm::angle(curTrackballPos, _lastTrackballPos); + rotationAngle *= deltaTime() * 100.0f; + + // Map trackballpos to camera + // glm::vec3 trackballMappedToCamera = mapToCamera(_lastTrackballPos - curTrackballPos); + // psc currentCamPos = camera_->getPosition(); + // glm::vec3 nextCamPos = currentCamPos.getVec3f() + trackballMappedToCamera; + // glm::vec3 rotationAxis = glm::cross(currentCamPos.getVec3f(), nextCamPos); + + glm::vec3 rotationAxis = glm::cross(_lastTrackballPos, curTrackballPos); + rotationAxis = glm::normalize(rotationAxis); + glm::quat quaternion = glm::angleAxis(rotationAngle, rotationAxis); + + // Apply quaternion to camera + orbitDelta(quaternion); + + _lastTrackballPos = curTrackballPos; + } +} + + +TrackballMouseController::TrackballMouseController() + : MouseController() + , _leftMouseButtonDown(false) +{} + +void TrackballMouseController::button(MouseAction action, MouseButton button) { + if (button == MouseButton::Left && action == MouseAction::Press) + _leftMouseButtonDown = true; + else if (button == MouseButton::Left && action == MouseAction::Release) { + _leftMouseButtonDown = false; + _isMouseBeingPressedAndHeld = false; + } +} + +void TrackballMouseController::move(float x, float y) { + if (_leftMouseButtonDown) + trackballRotate(x, y); +} + +void TrackballMouseController::scrollWheel(int pos) { + const double speed = 4.75; + const double dt = deltaTime(); + if (pos < 0) { + PowerScaledScalar dist(speed * dt, 0.0); + distanceDelta(dist); + } + else if (pos > 0) { + PowerScaledScalar dist(-speed * dt, 0.0); + distanceDelta(dist); + } +} + +} // namespace interaction +} // namespace openspace diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 04d3617fa8..a30493002e 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -257,7 +257,7 @@ void RenderEngine::render() const glm::vec2 scaling = _mainCamera->scaling(); const glm::vec3 viewdirection = _mainCamera->viewDirection(); const psc position = _mainCamera->position(); - const psc origin = OsEng.interactionHandler().getOrigin(); + const psc origin = OsEng.interactionHandler().focusNode()->worldPosition(); const PowerScaledScalar pssl = (position - origin).length(); /* GUI PRINT */ From 8884f4cc36201cf91908d42920dd60974bd56607 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 13 Oct 2014 17:24:11 +0200 Subject: [PATCH 6/7] Started initial performance testing on Lua-based keyboard controller --- ext/ghoul | 2 +- scripts/default_keybinding.lua | 4 +++ src/engine/openspaceengine.cpp | 3 ++- src/interaction/interactionhandler.cpp | 22 ++++++++++++----- src/interaction/keyboardcontroller.cpp | 34 ++++++++++++++++++++++++-- 5 files changed, 55 insertions(+), 10 deletions(-) create mode 100644 scripts/default_keybinding.lua diff --git a/ext/ghoul b/ext/ghoul index 1f1386215e..7553b63a5b 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 1f1386215e517179f7a4e80e64693fd3ebc2b339 +Subproject commit 7553b63a5b78374726682997e3138584bda22675 diff --git a/scripts/default_keybinding.lua b/scripts/default_keybinding.lua new file mode 100644 index 0000000000..9ebf558a60 --- /dev/null +++ b/scripts/default_keybinding.lua @@ -0,0 +1,4 @@ +return { + w = function() print("w") end, + s = function() print("s") end +} diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index f528652f9c..44601aa0d1 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -309,7 +309,8 @@ bool OpenSpaceEngine::initialize() { //DeviceIdentifier::init(); //DeviceIdentifier::ref().scanDevices(); - _interactionHandler.setKeyboardController(new interaction::KeyboardControllerFixed); + //_interactionHandler.setKeyboardController(new interaction::KeyboardControllerFixed); + _interactionHandler.setKeyboardController(new interaction::KeyboardControllerLua); _interactionHandler.setMouseController(new interaction::TrackballMouseController); // Run start up scripts diff --git a/src/interaction/interactionhandler.cpp b/src/interaction/interactionhandler.cpp index bceb05d861..926a1b858f 100644 --- a/src/interaction/interactionhandler.cpp +++ b/src/interaction/interactionhandler.cpp @@ -24,6 +24,12 @@ #include +#include + +namespace { + const std::string _loggerCat = "InteractionHandler"; +} + namespace openspace { namespace interaction { @@ -91,24 +97,28 @@ const Camera* const InteractionHandler::camera() const { } void InteractionHandler::keyboardCallback(int key, int action) { - if (_keyboardController) - _keyboardController->keyPressed(KeyAction(action), Keys(key)); + if (_keyboardController) { + auto start = ghoul::HighResClock::now(); + _keyboardController->keyPressed(KeyAction(action), Keys(key)); + auto end = ghoul::HighResClock::now(); + LINFO("Keyboard timing: " << std::chrono::duration_cast(end - start).count() << "ns"); + } } void InteractionHandler::mouseButtonCallback(int button, int action) { if (_mouseController) - _mouseController->button(MouseAction(action), MouseButton(button)); + _mouseController->button(MouseAction(action), MouseButton(button)); } void InteractionHandler::mousePositionCallback(int x, int y) { if (_mouseController) - // TODO Remap screen coordinates to [0,1] - _mouseController->move(float(x), float(y)); + // TODO Remap screen coordinates to [0,1] + _mouseController->move(float(x), float(y)); } void InteractionHandler::mouseScrollWheelCallback(int pos) { if (_mouseController) - _mouseController->scrollWheel(float(pos)); + _mouseController->scrollWheel(float(pos)); } } // namespace interaction diff --git a/src/interaction/keyboardcontroller.cpp b/src/interaction/keyboardcontroller.cpp index 6aeb91d383..ec3ba81399 100644 --- a/src/interaction/keyboardcontroller.cpp +++ b/src/interaction/keyboardcontroller.cpp @@ -27,6 +27,11 @@ #include #include +#include +#include +#include +#include + namespace openspace { namespace interaction { @@ -143,8 +148,33 @@ void KeyboardControllerFixed::keyPressed(KeyAction action, Keys key) { */ } -void KeyboardControllerLua::keyPressed(KeyAction action, Keys key) -{ +void KeyboardControllerLua::keyPressed(KeyAction action, Keys key) { + std::string _loggerCat = "KeyboardControllerLua"; + + lua_State* s = luaL_newstate(); + luaL_openlibs(s); + + int status = luaL_loadfile(s, absPath("${SCRIPTS}/default_keybinding.lua").c_str()); + if (status != LUA_OK) { + LERROR("Error loading script: '" << lua_tostring(s, -1) << "'"); + return; + } + + if (lua_pcall(s, 0, LUA_MULTRET, 0)) { + LERROR("Error executing script: " << lua_tostring(s, -1)); + return; + } + + auto start = ghoul::HighResClock::now(); + + + lua_pushstring(s, "w"); + lua_gettable(s, -2); + lua_pcall(s, 0, 0, 0); + + auto end = ghoul::HighResClock::now(); + LINFO("Keyboard timing: " << std::chrono::duration_cast(end - start).count() << "ns"); + } From 86efb3573b9d502dd34ceec160006c92d1ef1d78 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 14 Oct 2014 00:08:26 +0200 Subject: [PATCH 7/7] More work in preparing for lua-based keyboard controller Modified ScriptManager to decouple adding libraries from registering libraries Allowing ScriptManager to register libraries to other lua states as well --- include/openspace/interaction/controller.h | 18 -- .../interaction/interactionhandler.h | 13 ++ .../interaction/keyboardcontroller.h | 9 +- include/openspace/interaction/keys.h | 16 +- include/openspace/scripting/scriptengine.h | 12 +- scripts/default_keybinding.lua | 4 +- src/engine/openspaceengine.cpp | 4 +- src/interaction/controller.cpp | 92 -------- src/interaction/interactionhandler.cpp | 75 ++++++- src/interaction/keyboardcontroller.cpp | 212 +++++++++++++++--- src/interaction/mousecontroller.cpp | 16 +- src/scripting/scriptengine.cpp | 119 +++++----- 12 files changed, 366 insertions(+), 224 deletions(-) diff --git a/include/openspace/interaction/controller.h b/include/openspace/interaction/controller.h index 6675b1acb2..357d1bfa45 100644 --- a/include/openspace/interaction/controller.h +++ b/include/openspace/interaction/controller.h @@ -44,24 +44,6 @@ public: void setHandler(InteractionHandler* handler); protected: - SceneGraphNode* focusNode() const; - - Camera* camera() const; - - - double deltaTime() const; - - void orbitDelta(const glm::quat& rotation); - - void rotateDelta(const glm::quat& rotation); - - void distanceDelta(const PowerScaledScalar& distance); - - void lookAt(const glm::quat& rotation); - - void setRotation(const glm::quat& rotation); - -private: InteractionHandler* _handler; }; diff --git a/include/openspace/interaction/interactionhandler.h b/include/openspace/interaction/interactionhandler.h index c9fbde65f5..0313a5c989 100644 --- a/include/openspace/interaction/interactionhandler.h +++ b/include/openspace/interaction/interactionhandler.h @@ -62,6 +62,19 @@ public: void mousePositionCallback(int x, int y); void mouseScrollWheelCallback(int pos); + double deltaTime() const; + + void orbitDelta(const glm::quat& rotation); + + void rotateDelta(const glm::quat& rotation); + + void distanceDelta(const PowerScaledScalar& distance); + + void lookAt(const glm::quat& rotation); + + void setRotation(const glm::quat& rotation); + + private: friend class Controller; diff --git a/include/openspace/interaction/keyboardcontroller.h b/include/openspace/interaction/keyboardcontroller.h index 3b8d1b979f..045fbcc0c1 100644 --- a/include/openspace/interaction/keyboardcontroller.h +++ b/include/openspace/interaction/keyboardcontroller.h @@ -34,17 +34,20 @@ namespace interaction { class KeyboardController : public Controller { public: - virtual void keyPressed(KeyAction action, Keys key) = 0; + virtual void keyPressed(KeyAction action, Key key, KeyModifier modifier) = 0; }; class KeyboardControllerFixed : public KeyboardController { public: - void keyPressed(KeyAction action, Keys key); + void keyPressed(KeyAction action, Key key, KeyModifier modifier); }; class KeyboardControllerLua : public KeyboardController { public: - void keyPressed(KeyAction action, Keys key); + void keyPressed(KeyAction action, Key key, KeyModifier modifier); + +protected: + std::string keyToString(Key key, KeyModifier mod) const; }; } // namespace interaction diff --git a/include/openspace/interaction/keys.h b/include/openspace/interaction/keys.h index 19e722577e..b380a7b789 100644 --- a/include/openspace/interaction/keys.h +++ b/include/openspace/interaction/keys.h @@ -36,7 +36,15 @@ enum class KeyAction { Repeat = SGCT_REPEAT }; -enum class Keys { +enum class KeyModifier { + None = 0, + Shift = GLFW_MOD_SHIFT, + Control = GLFW_MOD_CONTROL, + Alt = GLFW_MOD_ALT, + Super = GLFW_MOD_SUPER +}; + +enum class Key { Unknown = SGCT_KEY_UNKNOWN, Space = SGCT_KEY_SPACE, Apostrophe = SGCT_KEY_APOSTROPHE, @@ -157,11 +165,7 @@ enum class Keys { RightAlt = SGCT_KEY_RIGHT_ALT, RightSuper = SGCT_KEY_RIGHT_SUPER, Menu = SGCT_KEY_MENU, - Last = SGCT_KEY_LAST, - Shift = LeftShift | RightShift, - Control = LeftControl | RightControl, - Alt = LeftAlt | RightAlt, - Super = LeftSuper | RightSuper + Last = SGCT_KEY_LAST }; } // namespace interaction diff --git a/include/openspace/scripting/scriptengine.h b/include/openspace/scripting/scriptengine.h index 648bc0ca12..5d5a76eead 100644 --- a/include/openspace/scripting/scriptengine.h +++ b/include/openspace/scripting/scriptengine.h @@ -26,6 +26,7 @@ #define __SCRIPTENGINE_H__ #include + #include /** @@ -50,19 +51,24 @@ public: }; ScriptEngine(); - + bool initialize(); void deinitialize(); - bool addLibrary(const LuaLibrary& library); + void initializeLuaState(lua_State* state); + + void addLibrary(const LuaLibrary& library); bool hasLibrary(const std::string& name); bool runScript(const std::string& script); bool runScriptFile(const std::string& filename); + private: + bool registerLuaLibrary(lua_State* state, const LuaLibrary& library); + void addLibraryFunctions(lua_State* state, const LuaLibrary& library, bool replace); + bool isLibraryNameAllowed(const std::string& name); - void addLibraryFunctions(const LuaLibrary& library, bool replace); void addBaseLibrary(); void remapPrintFunction(); diff --git a/scripts/default_keybinding.lua b/scripts/default_keybinding.lua index 9ebf558a60..56943efb65 100644 --- a/scripts/default_keybinding.lua +++ b/scripts/default_keybinding.lua @@ -1,4 +1,4 @@ return { - w = function() print("w") end, - s = function() print("s") end + W = function() print("w") end, + S = function() print("s") end } diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 44601aa0d1..f5e642530a 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -283,14 +283,14 @@ bool OpenSpaceEngine::initialize() { FactoryManager::initialize(); - scriptEngine().initialize(); - // Register Lua script functions LDEBUG("Registering Lua libraries"); scriptEngine().addLibrary(RenderEngine::luaLibrary()); scriptEngine().addLibrary(SceneGraph::luaLibrary()); scriptEngine().addLibrary(Time::luaLibrary()); + scriptEngine().initialize(); + // Load scenegraph SceneGraph* sceneGraph = new SceneGraph; _renderEngine.setSceneGraph(sceneGraph); diff --git a/src/interaction/controller.cpp b/src/interaction/controller.cpp index aee74159f9..311fdfc6ac 100644 --- a/src/interaction/controller.cpp +++ b/src/interaction/controller.cpp @@ -34,98 +34,6 @@ void Controller::setHandler(InteractionHandler* handler) _handler = handler; } -SceneGraphNode* Controller::focusNode() const -{ - assert(_handler); - return _handler->_focusNode; -} - -Camera* Controller::camera() const -{ - assert(_handler); - return _handler->_camera; -} - -double Controller::deltaTime() const -{ - assert(_handler); - return _handler->_deltaTime; -} - -void openspace::interaction::Controller::orbitDelta(const glm::quat& rotation) -{ - assert(_handler); - _handler->lockControls(); - - // the camera position - psc relative = _handler->_camera->position(); - - // should be changed to something more dynamic =) - psc origin; - if (_handler->_focusNode) { - origin = _handler->_focusNode->worldPosition(); - } - - psc relative_origin_coordinate = relative - origin; - //glm::mat4 rotation_matrix = glm::mat4_cast(glm::inverse(rotation)); - //relative_origin_coordinate = relative_origin_coordinate.vec4() * glm::inverse(rotation); - relative_origin_coordinate = glm::inverse(rotation) * relative_origin_coordinate.vec4(); - relative = relative_origin_coordinate + origin; - - _handler->_camera->setPosition(relative); - //camera_->rotate(rotation); - //camera_->setRotation(glm::mat4_cast(rotation)); - - glm::mat4 la = glm::lookAt(_handler->_camera->position().vec3(), origin.vec3(), glm::rotate(rotation, _handler->_camera->lookUpVector())); - _handler->_camera->setRotation(la); - //camera_->setLookUpVector(); - - _handler->unlockControls(); -} - -void openspace::interaction::Controller::rotateDelta(const glm::quat& rotation) -{ - assert(_handler); - _handler->lockControls(); - _handler->_camera->rotate(rotation); - _handler->unlockControls(); -} - -void openspace::interaction::Controller::distanceDelta(const PowerScaledScalar& distance) -{ - assert(_handler); - _handler->lockControls(); - - psc relative = _handler->_camera->position(); - const psc origin = (_handler->_focusNode) ? _handler->_focusNode->worldPosition() : psc(); - - psc relative_origin_coordinate = relative - origin; - const glm::vec3 dir(relative_origin_coordinate.direction()); - glm::vec3 newdir = dir * distance[0]; - relative_origin_coordinate = newdir; - relative_origin_coordinate[3] = distance[1]; - relative = relative + relative_origin_coordinate; - - relative_origin_coordinate = relative - origin; - newdir = relative_origin_coordinate.direction(); - - // update only if on the same side of the origin - if (glm::angle(newdir, dir) < 90.0f) - _handler->_camera->setPosition(relative); - - _handler->unlockControls(); -} - -void openspace::interaction::Controller::lookAt(const glm::quat& rotation) -{ - assert(_handler); -} - -void openspace::interaction::Controller::setRotation(const glm::quat& rotation) -{ - assert(_handler); -} - } // namespace interaction } // namespace openspace diff --git a/src/interaction/interactionhandler.cpp b/src/interaction/interactionhandler.cpp index 926a1b858f..7802c73de4 100644 --- a/src/interaction/interactionhandler.cpp +++ b/src/interaction/interactionhandler.cpp @@ -99,7 +99,7 @@ const Camera* const InteractionHandler::camera() const { void InteractionHandler::keyboardCallback(int key, int action) { if (_keyboardController) { auto start = ghoul::HighResClock::now(); - _keyboardController->keyPressed(KeyAction(action), Keys(key)); + _keyboardController->keyPressed(KeyAction(action), Key(key), KeyModifier::None); auto end = ghoul::HighResClock::now(); LINFO("Keyboard timing: " << std::chrono::duration_cast(end - start).count() << "ns"); } @@ -121,6 +121,79 @@ void InteractionHandler::mouseScrollWheelCallback(int pos) { _mouseController->scrollWheel(float(pos)); } +void InteractionHandler::orbitDelta(const glm::quat& rotation) +{ + lockControls(); + + // the camera position + psc relative = _camera->position(); + + // should be changed to something more dynamic =) + psc origin; + if (_focusNode) { + origin = _focusNode->worldPosition(); + } + + psc relative_origin_coordinate = relative - origin; + //glm::mat4 rotation_matrix = glm::mat4_cast(glm::inverse(rotation)); + //relative_origin_coordinate = relative_origin_coordinate.vec4() * glm::inverse(rotation); + relative_origin_coordinate = glm::inverse(rotation) * relative_origin_coordinate.vec4(); + relative = relative_origin_coordinate + origin; + + _camera->setPosition(relative); + //camera_->rotate(rotation); + //camera_->setRotation(glm::mat4_cast(rotation)); + + glm::mat4 la = glm::lookAt(_camera->position().vec3(), origin.vec3(), glm::rotate(rotation, _camera->lookUpVector())); + _camera->setRotation(la); + //camera_->setLookUpVector(); + + unlockControls(); +} + +void InteractionHandler::rotateDelta(const glm::quat& rotation) +{ + lockControls(); + _camera->rotate(rotation); + unlockControls(); +} + +void InteractionHandler::distanceDelta(const PowerScaledScalar& distance) +{ + lockControls(); + + psc relative = _camera->position(); + const psc origin = (_focusNode) ? _focusNode->worldPosition() : psc(); + + psc relative_origin_coordinate = relative - origin; + const glm::vec3 dir(relative_origin_coordinate.direction()); + glm::vec3 newdir = dir * distance[0]; + relative_origin_coordinate = newdir; + relative_origin_coordinate[3] = distance[1]; + relative = relative + relative_origin_coordinate; + + relative_origin_coordinate = relative - origin; + newdir = relative_origin_coordinate.direction(); + + // update only if on the same side of the origin + if (glm::angle(newdir, dir) < 90.0f) + _camera->setPosition(relative); + + unlockControls(); +} + +void InteractionHandler::lookAt(const glm::quat& rotation) +{ +} + +void InteractionHandler::setRotation(const glm::quat& rotation) +{ +} + +double InteractionHandler::deltaTime() const { + return _deltaTime; +} + } // namespace interaction } // namespace openspace diff --git a/src/interaction/keyboardcontroller.cpp b/src/interaction/keyboardcontroller.cpp index ec3ba81399..e3788d7a77 100644 --- a/src/interaction/keyboardcontroller.cpp +++ b/src/interaction/keyboardcontroller.cpp @@ -35,86 +35,86 @@ namespace openspace { namespace interaction { -void KeyboardControllerFixed::keyPressed(KeyAction action, Keys key) { +void KeyboardControllerFixed::keyPressed(KeyAction action, Key key, KeyModifier modifier) { // TODO package in script const double speed = 2.75; - const double dt = deltaTime(); + const double dt = _handler->deltaTime(); if(action == KeyAction::Press|| action == KeyAction::Repeat) { - if (key == Keys::S) { + if (key == Key::S) { glm::vec3 euler(speed * dt, 0.0, 0.0); glm::quat rot = glm::quat(euler); - orbitDelta(rot); + _handler->orbitDelta(rot); } - if (key == Keys::W) { + if (key == Key::W) { glm::vec3 euler(-speed * dt, 0.0, 0.0); glm::quat rot = glm::quat(euler); - orbitDelta(rot); + _handler->orbitDelta(rot); } - if (key == Keys::A) { + if (key == Key::A) { glm::vec3 euler(0.0, -speed * dt, 0.0); glm::quat rot = glm::quat(euler); - orbitDelta(rot); + _handler->orbitDelta(rot); } - if (key == Keys::D) { + if (key == Key::D) { glm::vec3 euler(0.0, speed * dt, 0.0); glm::quat rot = glm::quat(euler); - orbitDelta(rot); + _handler->orbitDelta(rot); } - if (key == Keys::Q) { + if (key == Key::Q) { Time::ref().advanceTime(dt); } - if (key == Keys::Right) { + if (key == Key::Right) { glm::vec3 euler(0.0, speed * dt, 0.0); glm::quat rot = glm::quat(euler); - rotateDelta(rot); + _handler->rotateDelta(rot); } - if (key == Keys::Left) { + if (key == Key::Left) { glm::vec3 euler(0.0, -speed * dt, 0.0); glm::quat rot = glm::quat(euler); - rotateDelta(rot); + _handler->rotateDelta(rot); } - if (key == Keys::Down) { + if (key == Key::Down) { glm::vec3 euler(speed * dt, 0.0, 0.0); glm::quat rot = glm::quat(euler); - rotateDelta(rot); + _handler->rotateDelta(rot); } - if (key == Keys::Up) { + if (key == Key::Up) { glm::vec3 euler(-speed * dt, 0.0, 0.0); glm::quat rot = glm::quat(euler); - rotateDelta(rot); + _handler->rotateDelta(rot); } - if (key == Keys::R) { + if (key == Key::R) { PowerScaledScalar dist(-speed * dt, 0.0); - distanceDelta(dist); + _handler->distanceDelta(dist); } - if (key == Keys::F) { + if (key == Key::F) { PowerScaledScalar dist(speed * dt, 0.0); - distanceDelta(dist); + _handler->distanceDelta(dist); } - if (key == Keys::T) { + if (key == Key::T) { PowerScaledScalar dist(-speed * pow(10, 11) * dt, 0.0); - distanceDelta(dist); + _handler->distanceDelta(dist); } //if (key == Keys::G) { // acc += 0.001; // PowerScaledScalar dist(speed * pow(10, 8 * acc) * dt, 0.0); // distanceDelta(dist); //} - if (key == Keys::Y) { + if (key == Key::Y) { PowerScaledScalar dist(-speed * 100.0 * dt, 6.0); - distanceDelta(dist); + _handler->distanceDelta(dist); } - if (key == Keys::H) { + if (key == Key::H) { PowerScaledScalar dist(speed * 100.0 * dt, 6.0); - distanceDelta(dist); + _handler->distanceDelta(dist); } - if (key == Keys::KeypadSubtract) { + if (key == Key::KeypadSubtract) { glm::vec2 s = OsEng.renderEngine().camera()->scaling(); s[1] -= 0.5; OsEng.renderEngine().camera()->setScaling(s); } - if (key == Keys::KeypadAdd) { + if (key == Key::KeypadAdd) { glm::vec2 s = OsEng.renderEngine().camera()->scaling(); s[1] += 0.5; OsEng.renderEngine().camera()->setScaling(s); @@ -148,7 +148,7 @@ void KeyboardControllerFixed::keyPressed(KeyAction action, Keys key) { */ } -void KeyboardControllerLua::keyPressed(KeyAction action, Keys key) { +void KeyboardControllerLua::keyPressed(KeyAction action, Key key, KeyModifier modifier) { std::string _loggerCat = "KeyboardControllerLua"; lua_State* s = luaL_newstate(); @@ -167,10 +167,11 @@ void KeyboardControllerLua::keyPressed(KeyAction action, Keys key) { auto start = ghoul::HighResClock::now(); - - lua_pushstring(s, "w"); - lua_gettable(s, -2); - lua_pcall(s, 0, 0, 0); + lua_getfield(s, -1, keyToString(key, modifier).c_str()); + if (!lua_isnil(s, -1)) + lua_pcall(s, 0, 0, 0); + else + LINFO("Key not found"); auto end = ghoul::HighResClock::now(); LINFO("Keyboard timing: " << std::chrono::duration_cast(end - start).count() << "ns"); @@ -178,5 +179,144 @@ void KeyboardControllerLua::keyPressed(KeyAction action, Keys key) { } +std::string KeyboardControllerLua::keyToString(Key key, KeyModifier mod) const { + std::string result = ""; + int intMod = static_cast(mod); + if (intMod & static_cast(KeyModifier::Control)) + result += "CTRL + "; + if (intMod & static_cast(KeyModifier::Super)) + result += "SUPER + "; + if (intMod & static_cast(KeyModifier::Alt)) + result += "ALT + "; + if (intMod & static_cast(KeyModifier::Shift)) + result += "SHIFT + "; + + switch (key) { + case Key::Unknown: result += "Unknown"; break; + case Key::Space: result += "Space"; break; + case Key::Apostrophe: result += "Apostrophe"; break; + case Key::Comma: result += "Comma"; break; + case Key::Minus: result += "Minus"; break; + case Key::Period: result += "Period"; break; + case Key::Slash: result += "Slash"; break; + case Key::Num0: result += "0"; break; + case Key::Num1: result += "1"; break; + case Key::Num2: result += "2"; break; + case Key::Num3: result += "3"; break; + case Key::Num4: result += "4"; break; + case Key::Num5: result += "5"; break; + case Key::Num6: result += "6"; break; + case Key::Num7: result += "7"; break; + case Key::Num8: result += "8"; break; + case Key::Num9: result += "9"; break; + case Key::SemiColon: result += "SemiColon"; break; + case Key::Equal: result += "Equal"; break; + case Key::A: result += "A"; break; + case Key::B: result += "B"; break; + case Key::C: result += "C"; break; + case Key::D: result += "D"; break; + case Key::E: result += "E"; break; + case Key::F: result += "F"; break; + case Key::G: result += "G"; break; + case Key::H: result += "H"; break; + case Key::I: result += "I"; break; + case Key::J: result += "J"; break; + case Key::K: result += "K"; break; + case Key::L: result += "L"; break; + case Key::M: result += "M"; break; + case Key::N: result += "N"; break; + case Key::O: result += "O"; break; + case Key::P: result += "P"; break; + case Key::Q: result += "Q"; break; + case Key::R: result += "R"; break; + case Key::S: result += "S"; break; + case Key::T: result += "T"; break; + case Key::U: result += "U"; break; + case Key::V: result += "V"; break; + case Key::W: result += "W"; break; + case Key::X: result += "X"; break; + case Key::Y: result += "Y"; break; + case Key::Z: result += "Z"; break; + case Key::LeftBracket: result += "LeftBracket"; break; + case Key::BackSlash: result += "BackSlash"; break; + case Key::RightBracket: result += "RightBracket"; break; + case Key::GraveAccent: result += "GraveAccent"; break; + case Key::World1: result += "World1"; break; + case Key::World2: result += "World2"; break; + case Key::Escape: result += "Escape"; break; + case Key::Enter: result += "Enter"; break; + case Key::Tab: result += "Tab"; break; + case Key::BackSpace: result += "BackSpace"; break; + case Key::Insert: result += "Insert"; break; + case Key::Delete: result += "Delete"; break; + case Key::Right: result += "Right"; break; + case Key::Left: result += "Left"; break; + case Key::Down: result += "Down"; break; + case Key::Up: result += "Up"; break; + case Key::PageUp: result += "PageUp"; break; + case Key::PageDown: result += "PageDown"; break; + case Key::Home: result += "Home"; break; + case Key::End: result += "End"; break; + case Key::CapsLock: result += "CapsLock"; break; + case Key::ScrollLock: result += "ScrollLock"; break; + case Key::NumLock: result += "NumLock"; break; + case Key::PrintScreen: result += "PrintScreen"; break; + case Key::Pause: result += "Pause"; break; + case Key::F1: result += "F1"; break; + case Key::F2: result += "F2"; break; + case Key::F3: result += "F3"; break; + case Key::F4: result += "F4"; break; + case Key::F5: result += "F5"; break; + case Key::F6: result += "F6"; break; + case Key::F7: result += "F7"; break; + case Key::F8: result += "F8"; break; + case Key::F9: result += "F9"; break; + case Key::F10: result += "F10"; break; + case Key::F11: result += "F11"; break; + case Key::F12: result += "F12"; break; + case Key::F13: result += "F13"; break; + case Key::F14: result += "F14"; break; + case Key::F15: result += "F15"; break; + case Key::F16: result += "F16"; break; + case Key::F17: result += "F17"; break; + case Key::F18: result += "F18"; break; + case Key::F19: result += "F19"; break; + case Key::F20: result += "F20"; break; + case Key::F21: result += "F21"; break; + case Key::F22: result += "F22"; break; + case Key::F23: result += "F23"; break; + case Key::F24: result += "F24"; break; + case Key::F25: result += "F25"; break; + case Key::Keypad0: result += "Keypad0"; break; + case Key::Keypad1: result += "Keypad1"; break; + case Key::Keypad2: result += "Keypad2"; break; + case Key::Keypad3: result += "Keypad3"; break; + case Key::Keypad4: result += "Keypad4"; break; + case Key::Keypad5: result += "Keypad5"; break; + case Key::Keypad6: result += "Keypad6"; break; + case Key::Keypad7: result += "Keypad7"; break; + case Key::Keypad8: result += "Keypad8"; break; + case Key::Keypad9: result += "Keypad9"; break; + case Key::KeypadDecimal: result += "KeypadDecimal"; break; + case Key::KeypadDivide: result += "KeypadDivide"; break; + case Key::KeypadMultiply: result += "KeypadMultiply"; break; + case Key::KeypadSubtract: result += "KeypadSubtract"; break; + case Key::KeypadAdd: result += "KeypadAdd"; break; + case Key::KeypadEnter: result += "KeypadEnter"; break; + case Key::LeftShift: result += "LeftShift"; break; + case Key::LeftControl: result += "LeftControl"; break; + case Key::LeftAlt: result += "LeftAlt"; break; + case Key::LeftSuper: result += "LeftSuper"; break; + case Key::RightShift: result += "RightShift"; break; + case Key::RightControl: result += "RightControl"; break; + case Key::RightAlt: result += "RightAlt"; break; + case Key::RightSuper: result += "RightSuper"; break; + case Key::Menu: result += "Menu"; break; + default: + assert(false); + } + return std::move(result); +} + } // namespace interaction } // namespace openspace \ No newline at end of file diff --git a/src/interaction/mousecontroller.cpp b/src/interaction/mousecontroller.cpp index 35a58c93f7..9d089f4d15 100644 --- a/src/interaction/mousecontroller.cpp +++ b/src/interaction/mousecontroller.cpp @@ -24,6 +24,8 @@ #include +#include + namespace openspace { namespace interaction { @@ -54,8 +56,8 @@ glm::vec3 MouseController::mapToCamera(glm::vec3 trackballPos) { // return glm::vec3((sgct::Engine::instance()->getActiveViewMatrix() * glm::vec4(trackballPos,0))); //Get x,y,z axis vectors of current camera view - glm::vec3 currentViewYaxis = glm::normalize(camera()->lookUpVector()); - psc viewDir = camera()->position() - focusNode()->worldPosition(); + glm::vec3 currentViewYaxis = glm::normalize(_handler->camera()->lookUpVector()); + psc viewDir = _handler->camera()->position() - _handler->focusNode()->worldPosition(); glm::vec3 currentViewZaxis = glm::normalize(viewDir.vec3()); glm::vec3 currentViewXaxis = glm::normalize(glm::cross(currentViewYaxis, currentViewZaxis)); @@ -87,7 +89,7 @@ void MouseController::trackballRotate(int x, int y) { if (curTrackballPos != _lastTrackballPos) { // calculate rotation angle (in radians) float rotationAngle = glm::angle(curTrackballPos, _lastTrackballPos); - rotationAngle *= deltaTime() * 100.0f; + rotationAngle *= _handler->deltaTime() * 100.0f; // Map trackballpos to camera // glm::vec3 trackballMappedToCamera = mapToCamera(_lastTrackballPos - curTrackballPos); @@ -100,7 +102,7 @@ void MouseController::trackballRotate(int x, int y) { glm::quat quaternion = glm::angleAxis(rotationAngle, rotationAxis); // Apply quaternion to camera - orbitDelta(quaternion); + _handler->orbitDelta(quaternion); _lastTrackballPos = curTrackballPos; } @@ -128,14 +130,14 @@ void TrackballMouseController::move(float x, float y) { void TrackballMouseController::scrollWheel(int pos) { const double speed = 4.75; - const double dt = deltaTime(); + const double dt = _handler->deltaTime(); if (pos < 0) { PowerScaledScalar dist(speed * dt, 0.0); - distanceDelta(dist); + _handler->distanceDelta(dist); } else if (pos > 0) { PowerScaledScalar dist(-speed * dt, 0.0); - distanceDelta(dist); + _handler->distanceDelta(dist); } } diff --git a/src/scripting/scriptengine.cpp b/src/scripting/scriptengine.cpp index 098b543cc6..006e51d431 100644 --- a/src/scripting/scriptengine.cpp +++ b/src/scripting/scriptengine.cpp @@ -182,23 +182,20 @@ ScriptEngine::ScriptEngine() } bool ScriptEngine::initialize() { + LDEBUG("Adding base functions"); + addBaseLibrary(); + _state = luaL_newstate(); LDEBUG("Creating Lua state"); if (_state == nullptr) { LFATAL("Error creating new Lua state: Memory allocation error"); return false; } + LDEBUG("Open Lua libraries"); luaL_openlibs(_state); - - LDEBUG("Add OpenSpace modules"); - - LDEBUG("Create openspace base library"); - lua_newtable(_state); - lua_setglobal(_state, _openspaceLibraryName.c_str()); - - LDEBUG("Adding base functions"); - addBaseLibrary(); + + initializeLuaState(_state); LDEBUG("Remap print function"); remapPrintFunction(); @@ -211,42 +208,8 @@ void ScriptEngine::deinitialize() { _state = nullptr; } -bool ScriptEngine::addLibrary(const ScriptEngine::LuaLibrary& library) { - assert(_state); - if (library.functions.empty()) { - LERROR("Lua library '" << library.name << "' does not have any functions"); - return false; - } - - //ghoul::lua::logStack(_state); - lua_getglobal(_state, _openspaceLibraryName.c_str()); - //ghoul::lua::logStack(_state); - if (library.name.empty()) { - //ghoul::lua::logStack(_state); - addLibraryFunctions(library, true); - //ghoul::lua::logStack(_state); - lua_pop(_state, 1); - //ghoul::lua::logStack(_state); - } - else { - const bool allowed = isLibraryNameAllowed(library.name); - if (!allowed) - return false; - - //ghoul::lua::logStack(_state); - - lua_pushstring(_state, library.name.c_str()); - //ghoul::lua::logStack(_state); - lua_newtable(_state); - //ghoul::lua::logStack(_state); - addLibraryFunctions(library, false); - lua_settable(_state, _setTableOffset); - //ghoul::lua::logStack(_state); - - _registeredLibraries.insert(library); - } - - return true; +void ScriptEngine::addLibrary(const ScriptEngine::LuaLibrary& library) { + _registeredLibraries.insert(library); } bool ScriptEngine::runScript(const std::string& script) { @@ -350,26 +313,26 @@ bool ScriptEngine::isLibraryNameAllowed(const std::string& name) return result; } -void ScriptEngine::addLibraryFunctions(const LuaLibrary& library, bool replace) -{ +void ScriptEngine::addLibraryFunctions(lua_State* state, const LuaLibrary& library, bool replace) { + assert(state); for (LuaLibrary::Function p : library.functions) { if (!replace) { //ghoul::lua::logStack(_state); - lua_getfield(_state, -1, p.name.c_str()); + lua_getfield(state, -1, p.name.c_str()); //ghoul::lua::logStack(_state); - const bool isNil = lua_isnil(_state, -1); + const bool isNil = lua_isnil(state, -1); if (!isNil) { LERROR("Function name '" << p.name << "' was already assigned"); return; } - lua_pop(_state, 1); + lua_pop(state, 1); } //ghoul::lua::logStack(_state); - lua_pushstring(_state, p.name.c_str()); + lua_pushstring(state, p.name.c_str()); //ghoul::lua::logStack(_state); - lua_pushcfunction(_state, p.function); + lua_pushcfunction(state, p.function); //ghoul::lua::logStack(_state); - lua_settable(_state, _setTableOffset); + lua_settable(state, _setTableOffset); //ghoul::lua::logStack(_state); } } @@ -436,6 +399,54 @@ void ScriptEngine::remapPrintFunction() { // lua_settable(_state, _setTableOffset); //ghoul::lua::logStack(_state); } - + +void ScriptEngine::initializeLuaState(lua_State* state) { + LDEBUG("Create openspace base library"); + lua_newtable(_state); + lua_setglobal(_state, _openspaceLibraryName.c_str()); + + LDEBUG("Add OpenSpace modules"); + for (auto lib : _registeredLibraries) + registerLuaLibrary(state, lib); +} + +bool ScriptEngine::registerLuaLibrary(lua_State* state, const LuaLibrary& library) { + assert(state); + if (library.functions.empty()) { + LERROR("Lua library '" << library.name << "' does not have any functions"); + return false; + } + + //ghoul::lua::logStack(_state); + lua_getglobal(state, _openspaceLibraryName.c_str()); + //ghoul::lua::logStack(_state); + if (library.name.empty()) { + //ghoul::lua::logStack(_state); + addLibraryFunctions(state, library, true); + //ghoul::lua::logStack(_state); + lua_pop(state, 1); + //ghoul::lua::logStack(_state); + } + else { + const bool allowed = isLibraryNameAllowed(library.name); + if (!allowed) + return false; + + //ghoul::lua::logStack(_state); + + lua_pushstring(state, library.name.c_str()); + //ghoul::lua::logStack(_state); + lua_newtable(state); + //ghoul::lua::logStack(_state); + addLibraryFunctions(state, library, false); + lua_settable(state, _setTableOffset); + //ghoul::lua::logStack(_state); + + _registeredLibraries.insert(library); + } + return true; +} + + } // namespace scripting } // namespace openspace