From 205ef0e7aaf0bc79572a6d90100b507b63264fd7 Mon Sep 17 00:00:00 2001 From: Teo-CD Date: Fri, 1 Nov 2019 18:27:01 +0100 Subject: [PATCH] Modified cursor grab behaviour Cursor is now trapped inside the window and will jump from one side to another when nearing the border. The cursor is now hidden to reinforce the illusion. Warping the cursor to the center did not work well at all on my Windows machine (Might be because it is much more powerful than my laptop) so I had to find another way. --- src/InputStatus.cpp | 42 +++++++++++++++++++++++++++++------------- src/InputStatus.h | 6 +++++- src/main.cpp | 19 +++++++++---------- 3 files changed, 43 insertions(+), 24 deletions(-) diff --git a/src/InputStatus.cpp b/src/InputStatus.cpp index 38a52d9..0ea26b8 100644 --- a/src/InputStatus.cpp +++ b/src/InputStatus.cpp @@ -6,7 +6,7 @@ // Initialize static members -Vec2i InputStatus::window_center; +Vec2i InputStatus::window_size; Vec2f InputStatus::mouse_sensitivity{100, 100}; std::map InputStatus::ascii_keys_status = {}; @@ -103,25 +103,41 @@ void InputStatus::update_special_key(int event_key, bool new_status) // Mouse // ================== +void InputStatus::keep_cursor_bounded(int mouse_x, int mouse_y) +{ + if (mouse_x < cursor_bounds_width) + { + glutWarpPointer(window_size.x - cursor_bounds_width, mouse_y); + } + else if (mouse_x > window_size.x - cursor_bounds_width) + { + glutWarpPointer(cursor_bounds_width, mouse_y); + } + + if (mouse_y < cursor_bounds_width) + { + glutWarpPointer(mouse_x, window_size.y - cursor_bounds_width); + } + else if (mouse_y > window_size.y - cursor_bounds_width) + { + glutWarpPointer(mouse_x, cursor_bounds_width); + } +} + void InputStatus::mouse_movement(int mouse_x, int mouse_y) { Vec2i current_frame; current_frame.x = mouse_x; current_frame.y = mouse_y; - // Prevent counting the glutWarpPointer movement into account - if (current_frame != window_center) - { - Vec2i frame_delta = current_frame - last_mouse_position; - // Prevent jumping around when entering the window - if (frame_delta.magnitude() < window_center.magnitude()/10) - { - current_mouse_delta.x += frame_delta.x; - current_mouse_delta.y += frame_delta.y; + keep_cursor_bounded(mouse_x, mouse_y); - // Re-center mouse - glutWarpPointer(window_center.x, window_center.y); - } + Vec2i frame_delta = current_frame - last_mouse_position; + // Prevent jumping around when entering the window + if (frame_delta.magnitude() < window_size.magnitude() / 10) + { + current_mouse_delta.x += frame_delta.x; + current_mouse_delta.y += frame_delta.y; } last_mouse_position = current_frame; diff --git a/src/InputStatus.h b/src/InputStatus.h index 600195d..f1db851 100644 --- a/src/InputStatus.h +++ b/src/InputStatus.h @@ -41,7 +41,7 @@ public: /// Accumulates the movements of the mouse static void mouse_movement(int mouse_x, int mouse_y); - static Vec2i window_center; + static Vec2i window_size; static Vec2f mouse_sensitivity; private: @@ -56,9 +56,13 @@ private: static Vec2i last_mouse_delta; static Vec2i last_mouse_position; + static constexpr int cursor_bounds_width = 5; + // These functions are called by *_press and *_up to update their values static void update_key(unsigned char event_key, bool new_status); static void update_special_key(int event_key, bool new_status); + + static void keep_cursor_bounded(int mouse_x, int mouse_y); }; diff --git a/src/main.cpp b/src/main.cpp index 44e89e1..5c7746f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -37,30 +37,30 @@ void manage_inputs() if (InputStatus::is_special_key_pressed(GLUT_KEY_RIGHT)) { timer_ticks += 5; - camera.translate({0,0,1}); + camera.translate({0,0,0.1}); } if (InputStatus::is_special_key_pressed(GLUT_KEY_LEFT)) { timer_ticks -= 5; - camera.translate({0,0,-1}); + camera.translate({0,0,-0.1}); } if (InputStatus::is_key_pressed(' ')) { - camera.translate({0,1,0}); + camera.translate({0,0.1,0}); } if (InputStatus::is_special_key_pressed(GLUT_KEY_PAGE_DOWN)) { - camera.translate({0,-1,0}); + camera.translate({0,-0.1,0}); } if (InputStatus::is_special_key_pressed(GLUT_KEY_UP)) { - camera.translate({1,0,0}); + camera.translate({0.1,0,0}); } if (InputStatus::is_special_key_pressed(GLUT_KEY_DOWN)) { - camera.translate({-1,0,0}); + camera.translate({-0.1,0,0}); } // Get mouse delta since last frame @@ -109,8 +109,8 @@ void reshape(int new_x, int new_y) glViewport(0,0,new_x,new_y); aspect_ratio = (double)new_x/new_y; - InputStatus::window_center.x = new_x / 2; - InputStatus::window_center.y = new_y / 2; + InputStatus::window_size.x = new_x; + InputStatus::window_size.y = new_y; } void update_angle(int value) @@ -126,12 +126,11 @@ int main(int argc, char** argv) glutInitDisplayMode(GLUT_RGB| GLUT_DEPTH | GLUT_DOUBLE); glutCreateWindow("OpenGL custom engine tests"); glutIgnoreKeyRepeat(true); + glutSetCursor(GLUT_CURSOR_NONE); // Init OpenGL glClearColor(0,0,0,1); glClearDepth(1.0); -// glEnable(GL_LIGHTING); -// glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); // Setup OPenGL to use textures