From bb674cdbb69f2dedecf52dfcd52f6de6e754e8b7 Mon Sep 17 00:00:00 2001 From: trotFunky Date: Mon, 14 Oct 2019 18:46:32 +0200 Subject: [PATCH 1/3] Added some operators to the vector classes --- src/types.h | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) diff --git a/src/types.h b/src/types.h index 6c3349e..1e69e15 100644 --- a/src/types.h +++ b/src/types.h @@ -15,6 +15,48 @@ struct CoordinatesVector { T coordinates[N]; + // Use SFINAE to declare the function if and only if the type is arithmetic + template + typename std::enable_if::value,CoordinatesVector>::type + operator*(const Scalar& scalar) + { + CoordinatesVector result; + for (unsigned int i = 0;i& op) + { + CoordinatesVector result; + for (unsigned int i = 0;i& op) + { + CoordinatesVector result; + for (unsigned int i = 0;i& original) + { + if (this != &original) + { + std::copy(std::begin(original.coordinates), std::end(original.coordinates), std::begin(coordinates)); + } + return *this; + } + friend std::fstream& operator>>(std::fstream& stream, CoordinatesVector& vector) { for (unsigned int i = 0;i T& x = coordinates[0]; T& y = coordinates[1]; + // Use SFINAE to declare the function if and only if the type is a scalar + template + typename std::enable_if::value,CoordinatesVector>::type + operator*(const Scalar& scalar) + { + CoordinatesVector result; + for (unsigned int i = 0;i<2;i++) + { + result.coordinates[i] = coordinates[i] * scalar; + } + } + + CoordinatesVector operator+(const CoordinatesVector& op) + { + CoordinatesVector result; + result.x = x + op.x; + result.y = y + op.y; + + return result; + } + + CoordinatesVector operator-(const CoordinatesVector& op) + { + CoordinatesVector result; + result.x = x - op.x; + result.y = y - op.y; + + return result; + } + + CoordinatesVector& operator=(const CoordinatesVector& original) + { + if (this != &original) + { + std::copy(std::begin(original.coordinates), std::end(original.coordinates), std::begin(coordinates)); + } + return *this; + } + friend std::fstream& operator>>(std::fstream& stream, CoordinatesVector& vec2) { stream >> vec2.x >> vec2.y; @@ -49,6 +130,47 @@ struct CoordinatesVector T& y = coordinates[1]; T& z = coordinates[2]; + // Use SFINAE to declare the function if and only if the type is a scalar + template + typename std::enable_if::value,CoordinatesVector>::type + operator*(const Scalar& scalar) + { + CoordinatesVector result; + for (unsigned int i = 0;i<3;i++) + { + result.coordinates[i] = coordinates[i] * scalar; + } + } + + CoordinatesVector operator+(const CoordinatesVector& op) + { + CoordinatesVector result; + result.x = x + op.x; + result.y = y + op.y; + result.z = z + op.z; + + return result; + } + + CoordinatesVector operator-(const CoordinatesVector& op) + { + CoordinatesVector result; + result.x = x - op.x; + result.y = y - op.y; + result.z = z - op.z; + + return result; + } + + CoordinatesVector& operator=(const CoordinatesVector& original) + { + if (this != &original) + { + std::copy(std::begin(original.coordinates), std::end(original.coordinates), std::begin(coordinates)); + } + return *this; + } + friend std::fstream& operator>>(std::fstream& stream, CoordinatesVector& vec3) { stream >> vec3.x >> vec3.y >> vec3.z; From 5c90d15869a6852438ef695003658d2fe934f184 Mon Sep 17 00:00:00 2001 From: trotFunky Date: Mon, 14 Oct 2019 21:34:14 +0200 Subject: [PATCH 2/3] Refactored specialized templates to avoid duplicates --- src/types.h | 110 +++++++++++++--------------------------------------- 1 file changed, 28 insertions(+), 82 deletions(-) diff --git a/src/types.h b/src/types.h index 1e69e15..a47d514 100644 --- a/src/types.h +++ b/src/types.h @@ -69,122 +69,68 @@ struct CoordinatesVector template -struct CoordinatesVector +struct Vec2 : public CoordinatesVector { - T coordinates[2]; - T& x = coordinates[0]; - T& y = coordinates[1]; + T& x = CoordinatesVector::coordinates[0]; + T& y = CoordinatesVector::coordinates[1]; - // Use SFINAE to declare the function if and only if the type is a scalar - template - typename std::enable_if::value,CoordinatesVector>::type - operator*(const Scalar& scalar) + Vec2() = default; + + // Cast-copy constructor in order to use the operators of the mother class. + Vec2(const CoordinatesVector& origin) { - CoordinatesVector result; - for (unsigned int i = 0;i<2;i++) + if (this != &origin) { - result.coordinates[i] = coordinates[i] * scalar; + std::copy(std::begin(origin.coordinates),std::end(origin.coordinates),std::begin(CoordinatesVector::coordinates)); } } - CoordinatesVector operator+(const CoordinatesVector& op) + Vec2& operator=(const Vec2& origin) { - CoordinatesVector result; - result.x = x + op.x; - result.y = y + op.y; - - return result; - } - - CoordinatesVector operator-(const CoordinatesVector& op) - { - CoordinatesVector result; - result.x = x - op.x; - result.y = y - op.y; - - return result; - } - - CoordinatesVector& operator=(const CoordinatesVector& original) - { - if (this != &original) + if (this != &origin) { - std::copy(std::begin(original.coordinates), std::end(original.coordinates), std::begin(coordinates)); + std::copy(std::begin(origin.coordinates), std::end(origin.coordinates), std::begin(CoordinatesVector::coordinates)); } return *this; } - - friend std::fstream& operator>>(std::fstream& stream, CoordinatesVector& vec2) - { - stream >> vec2.x >> vec2.y; - return stream; - } }; template -struct CoordinatesVector +struct Vec3 : CoordinatesVector { - T coordinates[3]; - T& x = coordinates[0]; - T& y = coordinates[1]; - T& z = coordinates[2]; + T& x = CoordinatesVector::coordinates[0]; + T& y = CoordinatesVector::coordinates[1]; + T& z = CoordinatesVector::coordinates[2]; - // Use SFINAE to declare the function if and only if the type is a scalar - template - typename std::enable_if::value,CoordinatesVector>::type - operator*(const Scalar& scalar) + Vec3() = default; + + // Cast-copy constructor in order to use the operators of the mother class. + Vec3(const CoordinatesVector& origin) { - CoordinatesVector result; - for (unsigned int i = 0;i<3;i++) + if (this != &origin) { - result.coordinates[i] = coordinates[i] * scalar; + std::copy(std::begin(origin.coordinates),std::end(origin.coordinates),std::begin(CoordinatesVector::coordinates)); } } - CoordinatesVector operator+(const CoordinatesVector& op) - { - CoordinatesVector result; - result.x = x + op.x; - result.y = y + op.y; - result.z = z + op.z; - - return result; - } - - CoordinatesVector operator-(const CoordinatesVector& op) - { - CoordinatesVector result; - result.x = x - op.x; - result.y = y - op.y; - result.z = z - op.z; - - return result; - } - - CoordinatesVector& operator=(const CoordinatesVector& original) + Vec3& operator=(const Vec3& original) { if (this != &original) { - std::copy(std::begin(original.coordinates), std::end(original.coordinates), std::begin(coordinates)); + std::copy(std::begin(original.coordinates), std::end(original.coordinates), std::begin(CoordinatesVector::coordinates)); } return *this; } - - friend std::fstream& operator>>(std::fstream& stream, CoordinatesVector& vec3) - { - stream >> vec3.x >> vec3.y >> vec3.z; - return stream; - } }; // Define aliases for common types -typedef CoordinatesVector Vec2i; -typedef CoordinatesVector Vec2f; +typedef Vec2 Vec2i; +typedef Vec2 Vec2f; -typedef CoordinatesVector Vec3i; -typedef CoordinatesVector Vec3f; +typedef Vec3 Vec3i; +typedef Vec3 Vec3f; #endif //TESTS_OPENGL_TYPES_H From 52acb4044c032a9965e39e45e2edfc7b06a64d5c Mon Sep 17 00:00:00 2001 From: trotFunky Date: Mon, 14 Oct 2019 21:48:49 +0200 Subject: [PATCH 3/3] Added mouse movement and click support --- src/KeyStateManager.cpp | 74 +++++++++++++++++++++++++++++++++++++++++ src/KeyStateManager.h | 22 +++++++++++- src/main.cpp | 8 +++-- 3 files changed, 101 insertions(+), 3 deletions(-) diff --git a/src/KeyStateManager.cpp b/src/KeyStateManager.cpp index 788ab67..9bf68e9 100644 --- a/src/KeyStateManager.cpp +++ b/src/KeyStateManager.cpp @@ -5,8 +5,15 @@ #include "KeyStateManager.h" #include +// Initialize static members + std::map KeyStateManager::ascii_keys_status = {}; std::map KeyStateManager::special_keys_status = {}; +std::map KeyStateManager::mouse_button_status = {}; + +Vec2i KeyStateManager::current_mouse_delta; +Vec2i KeyStateManager::last_mouse_delta; +Vec2i KeyStateManager::last_mouse_position; void KeyStateManager::register_glut_callbacks() { @@ -14,8 +21,16 @@ void KeyStateManager::register_glut_callbacks() glutKeyboardUpFunc(KeyStateManager::key_up); glutSpecialFunc(KeyStateManager::special_key_press); glutSpecialUpFunc(KeyStateManager::special_key_up); + + glutMouseFunc(KeyStateManager::mouse_click); + glutPassiveMotionFunc(KeyStateManager::mouse_movement); + glutMotionFunc(KeyStateManager::mouse_movement); } +// ================== +// Keyboard +// ================== + bool KeyStateManager::is_key_pressed(unsigned char key) { if (ascii_keys_status.find(key) == ascii_keys_status.end()) @@ -37,21 +52,25 @@ bool KeyStateManager::is_special_key_pressed(int key) void KeyStateManager::key_press(unsigned char event_key, int mouse_x, int mouse_y) { update_key(event_key,true); + mouse_movement(mouse_x,mouse_y); } void KeyStateManager::key_up(unsigned char event_key, int mouse_x, int mouse_y) { update_key(event_key,false); + mouse_movement(mouse_x,mouse_y); } void KeyStateManager::special_key_press(int event_key, int mouse_x, int mouse_y) { update_special_key(event_key,true); + mouse_movement(mouse_x,mouse_y); } void KeyStateManager::special_key_up(int event_key, int mouse_x, int mouse_y) { update_special_key(event_key,false); + mouse_movement(mouse_x,mouse_y); } void KeyStateManager::update_key(unsigned char event_key, bool new_status) @@ -77,3 +96,58 @@ void KeyStateManager::update_special_key(int event_key, bool new_status) special_keys_status.insert({event_key,new_status}); } } + +// ================== +// Mouse +// ================== + +void KeyStateManager::mouse_movement(int mouse_x, int mouse_y) +{ + Vec2i current_frame; + current_frame.x = mouse_x; + current_frame.y = mouse_y; + + Vec2i frame_delta = current_frame - last_mouse_position; + current_mouse_delta.x += frame_delta.x; + current_mouse_delta.y += frame_delta.y; + + last_mouse_position = current_frame; + + std::cout << frame_delta.x << "," << frame_delta.y << std::endl; +} + +void KeyStateManager::mouse_click(int mouse_button, int button_state, int mouse_x, int mouse_y) +{ + bool new_status = button_state == GLUT_DOWN; + + if (mouse_button_status.find(mouse_button) != mouse_button_status.end()) + { + mouse_button_status.at(mouse_button) = new_status; + } + else + { + mouse_button_status.insert({mouse_button,new_status}); + } + mouse_movement(mouse_x,mouse_y); +} + +bool KeyStateManager::is_mouse_button_pressed(int mouse_button) +{ + + if (mouse_button_status.find(mouse_button) == mouse_button_status.end()) + { + return false; + } + return mouse_button_status.at(mouse_button); +} + +const Vec2i& KeyStateManager::get_mouse_delta(bool update) +{ + if (update) + { + last_mouse_delta = current_mouse_delta; + current_mouse_delta.x = 0; + current_mouse_delta.y = 0; + } + return last_mouse_delta; +} \ No newline at end of file diff --git a/src/KeyStateManager.h b/src/KeyStateManager.h index cb0693a..f7aedbd 100644 --- a/src/KeyStateManager.h +++ b/src/KeyStateManager.h @@ -8,8 +8,10 @@ #include #include +#include "types.h" -/// Handles the key events from glut and keep the status of keys up to date. + +/// Handles the key and mouse events from glut and keep their status up to date. /// "Static class" class KeyStateManager { public: @@ -21,16 +23,34 @@ public: static bool is_key_pressed(unsigned char key); static bool is_special_key_pressed(int key); + static bool is_mouse_button_pressed(int mouse_button); + + /// Updates and returns the movement of the mouse. + /// \param update If true, updates the mouse delta that will be returned + /// \return Updated displacement on each axis between the two last updates. + static const Vec2i& get_mouse_delta(bool update = false); + // Glut callbacks for input events static void key_press(unsigned char event_key, int mouse_x, int mouse_y); static void key_up(unsigned char event_key, int mouse_x, int mouse_y); static void special_key_press(int event_key, int mouse_x, int mouse_y); static void special_key_up(int event_key, int mouse_x, int mouse_y); + static void mouse_click(int mouse_button, int button_state, int mouse_x, int mouse_y); + /// Accumulates the movements of the mouse + static void mouse_movement(int mouse_x, int mouse_y); + private: // The maps are used to keep track of the keys which were pressed or released during runtime. static std::map ascii_keys_status; static std::map special_keys_status; + static std::map mouse_button_status; + + // Updated by callback + static Vec2i current_mouse_delta; + // Updated on user request + static Vec2i last_mouse_delta; + static Vec2i last_mouse_position; // These functions are called by *_press and *_up to update their values static void update_key(unsigned char event_key, bool new_status); diff --git a/src/main.cpp b/src/main.cpp index 8efa7a8..3195bc4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -13,7 +13,11 @@ static Texture raptor_texture; void manage_inputs() { - if (KeyStateManager::is_key_pressed(' ')) + if (KeyStateManager::is_mouse_button_pressed(GLUT_LEFT_BUTTON)) + { + glClearColor(0,0,0.5,1); + } + else if (KeyStateManager::is_key_pressed(' ')) { glClearColor(0.5,0,0,1); } @@ -46,7 +50,7 @@ void display() glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - gluLookAt(7.5, 7.5, 7.5, + gluLookAt(10, 7.5, 10, 0, 0, 1, 0, 1, 0);