From b21d4d814b1b8d3f032f40b0c3d7bd6ec2c75910 Mon Sep 17 00:00:00 2001
From: Sebastian Gaida <gaida@ca-digit.com>
Date: Tue, 25 May 2021 17:30:24 +0200
Subject: [PATCH] [#35] add panning feature

---
 include/vkcv/Window.hpp                       | 13 ++++++++++--
 .../include/vkcv/camera/CameraManager.hpp     | 12 ++++++-----
 .../camera/src/vkcv/camera/CameraManager.cpp  | 21 ++++++++++++-------
 src/vkcv/Window.cpp                           | 13 +++++++++++-
 4 files changed, 44 insertions(+), 15 deletions(-)

diff --git a/include/vkcv/Window.hpp b/include/vkcv/Window.hpp
index 6c0ddbcf..7428c7c7 100644
--- a/include/vkcv/Window.hpp
+++ b/include/vkcv/Window.hpp
@@ -12,7 +12,7 @@
 struct GLFWwindow;
 
 namespace vkcv {
-	
+
     class Window final {
     private:
         GLFWwindow *m_window;
@@ -32,6 +32,14 @@ namespace vkcv {
          */
         static void onMouseMoveEvent(GLFWwindow *window, double x, double y);
 
+        /**
+         * mouseButton callback for mouse buttons
+         * @param[in] button The [mouse button](@ref buttons) that was pressed or released.
+         * @param[in] action One of `GLFW_PRESS` or `GLFW_RELEASE`.  Future releases may add more actions.
+         * @param[in] mods Bit field describing which [modifier keys](@ref mods) were held down.
+         */
+        static void onMouseButtonEvent(GLFWwindow *callbackWindow, int button, int action, int mods);
+
         static void onMouseScrollEvent(GLFWwindow *callbackWindow, double xoffset, double yoffset);
 
         /**
@@ -83,6 +91,7 @@ namespace vkcv {
         /**
          * basic events of the window
          */
+        event< int, int, int> e_mouseButton;
         event< double, double > e_mouseMove;
         event< double, double > e_mouseScroll;
         event< int, int > e_resize;
@@ -132,5 +141,5 @@ namespace vkcv {
          */
         virtual ~Window();
     };
-    
+
 }
\ No newline at end of file
diff --git a/modules/camera/include/vkcv/camera/CameraManager.hpp b/modules/camera/include/vkcv/camera/CameraManager.hpp
index 6e4d577e..5fa84876 100644
--- a/modules/camera/include/vkcv/camera/CameraManager.hpp
+++ b/modules/camera/include/vkcv/camera/CameraManager.hpp
@@ -9,15 +9,16 @@ namespace vkcv{
 
     class CameraManager{
     private:
-        std::function <void(int, int, int ,int )> m_keyHandle;
-        std::function <void(double, double )> m_mouseMoveHandle;
-        std::function <void(double, double )> m_mouseScrollHandle;
+        std::function<void(int, int, int, int)> m_keyHandle;
+        std::function<void(double, double)> m_mouseMoveHandle;
+        std::function<void(double, double)> m_mouseScrollHandle;
+        std::function<void(int, int, int)> m_mouseButtonHandle;
 
         Window &m_window;
         Camera m_camera;
         float m_width;
         float m_height;
-        std::shared_ptr<vkcv::TrackballCamera> m_trackball;
+//        std::shared_ptr<vkcv::TrackballCamera> m_trackball;
         glm::vec3 m_up;
         glm::vec3 m_position;
         glm::vec3 m_front;
@@ -28,7 +29,7 @@ namespace vkcv{
         float m_pitch;
         float m_yaw;
 
-        bool m_firstMouse = true;
+        bool m_roationActive = false;
         double m_lastX ;
         double m_lastY ;
 
@@ -36,6 +37,7 @@ namespace vkcv{
         void keyCallback(int key, int scancode, int action, int mods);
         void scrollCallback( double offsetX, double offsetY);
         void mouseMoveCallback( double offsetX, double offsetY);
+        void mouseButtonCallback(int button, int action, int mods);
 
     public:
         CameraManager(Window &window, float width, float height);
diff --git a/modules/camera/src/vkcv/camera/CameraManager.cpp b/modules/camera/src/vkcv/camera/CameraManager.cpp
index 1219cd3a..7f51c431 100644
--- a/modules/camera/src/vkcv/camera/CameraManager.cpp
+++ b/modules/camera/src/vkcv/camera/CameraManager.cpp
@@ -8,7 +8,6 @@ namespace vkcv{
     m_window(window), m_width(width), m_height(height)
     {
 
-        glfwSetInputMode(m_window.getWindow(), GLFW_CURSOR, GLFW_CURSOR_DISABLED);
         m_camera.setPerspective( glm::radians(60.0f), m_width / m_height, 0.1f, 10.f);
         m_up = glm::vec3(0.0f, 1.0f, 0.0f);
         m_position = glm::vec3(0.0f, 0.0f, 0.0f);
@@ -26,7 +25,6 @@ namespace vkcv{
     CameraManager::CameraManager(Window &window, float width, float height, glm::vec3 up, glm::vec3 position, glm::vec3 front):
     m_window(window), m_width(width), m_height(height), m_up(up), m_position(position), m_front(front)
     {
-        glfwSetInputMode(m_window.getWindow(), GLFW_CURSOR, GLFW_CURSOR_DISABLED);
         m_camera.setPerspective( glm::radians(60.0f), m_width / m_height, 0.1f, 10.f);
         m_up = glm::vec3(0.0f, 1.0f, 0.0f);
         m_position = glm::vec3(0.0f, 0.0f, 0.0f);
@@ -45,21 +43,30 @@ namespace vkcv{
         m_keyHandle = m_window.e_key.add( [&](int key, int scancode, int action, int mods) { this->keyCallback(key, scancode, action, mods); });
         m_mouseMoveHandle = m_window.e_mouseMove.add( [&]( double offsetX, double offsetY) {this->mouseMoveCallback( offsetX, offsetY);} );
         m_mouseScrollHandle =  m_window.e_mouseScroll.add([&](double offsetX, double offsetY) {this->scrollCallback( offsetX, offsetY);} );
+        m_mouseButtonHandle = m_window.e_mouseButton.add([&] (int button, int action, int mods) {this->mouseButtonCallback( button,  action,  mods);});
+    }
 
+    void CameraManager::mouseButtonCallback(int button, int action, int mods){
+        if(button == GLFW_MOUSE_BUTTON_2 && m_roationActive == false && action == GLFW_PRESS){
+            glfwSetInputMode(m_window.getWindow(), GLFW_CURSOR, GLFW_CURSOR_DISABLED);
+            m_roationActive = true;
+        }else if(button == GLFW_MOUSE_BUTTON_2 && m_roationActive == true && action == GLFW_RELEASE){
+            glfwSetInputMode(m_window.getWindow(), GLFW_CURSOR, GLFW_CURSOR_NORMAL);
+            m_roationActive = false;
+        }
     }
 
     void CameraManager::mouseMoveCallback(double x, double y){
-        if (m_firstMouse) {
-            m_lastX = x;
-            m_lastY = y;
-            m_firstMouse = false;
-        }
 
         float xoffset = x - m_lastX;
         float yoffset = m_lastY - y;
         m_lastX = x;
         m_lastY = y;
 
+        if(!m_roationActive){
+            return;
+        }
+
         float sensitivity = 0.1f;
         xoffset *= sensitivity;
         yoffset *= sensitivity;
diff --git a/src/vkcv/Window.cpp b/src/vkcv/Window.cpp
index 202f8d7e..c21271b7 100644
--- a/src/vkcv/Window.cpp
+++ b/src/vkcv/Window.cpp
@@ -46,6 +46,8 @@ namespace vkcv {
         glfwSetWindowUserPointer(m_window, this);
 
         // combine Callbacks with Events
+        glfwSetMouseButtonCallback(m_window, Window::onMouseButtonEvent);
+
         glfwSetCursorPosCallback(m_window, Window::onMouseMoveEvent);
 
         glfwSetWindowSizeCallback(m_window, Window::onResize);
@@ -59,6 +61,15 @@ namespace vkcv {
         glfwPollEvents();
     }
 
+    void Window::onMouseButtonEvent(GLFWwindow *callbackWindow, int button, int action, int mods) {
+
+        auto window = static_cast<Window *>(glfwGetWindowUserPointer(callbackWindow));
+
+        if (window != nullptr) {
+            window->e_mouseButton(button, action, mods);
+        }
+    }
+
     void Window::onMouseMoveEvent(GLFWwindow *callbackWindow, double x, double y) {
 
         auto window = static_cast<Window *>(glfwGetWindowUserPointer(callbackWindow));
@@ -113,4 +124,4 @@ namespace vkcv {
     GLFWwindow *Window::getWindow() const {
         return m_window;
     }
-}
+}
\ No newline at end of file
-- 
GitLab