From a44e38afa38ca98a7b7b6e9317967fbef7a3642c Mon Sep 17 00:00:00 2001 From: karl Date: Sun, 9 May 2021 19:47:44 +0200 Subject: [PATCH] Add basic collision detection for particle origin placement --- include/Gedeng/Camera.h | 5 +++++ include/Gedeng/Input.h | 17 ++++++++++++++++- include/Gedeng/Ray.h | 36 ++++++++++++++++++++++++++++++++++++ test/particle-demo/main.cpp | 8 ++++++-- 4 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 include/Gedeng/Ray.h diff --git a/include/Gedeng/Camera.h b/include/Gedeng/Camera.h index 2e27e34..e4355a7 100644 --- a/include/Gedeng/Camera.h +++ b/include/Gedeng/Camera.h @@ -7,6 +7,7 @@ #include #include "Gedeng/Logger.h" +#include "Gedeng/Ray.h" #include "Input.h" #include "Spatial.h" @@ -28,6 +29,10 @@ class Camera : public Spatial { return glm::inverse(get_matrix()); } + Ray get_view_ray() const { + return Ray(get_translation(), forward()); + } + private: glm::mat4 projection; }; diff --git a/include/Gedeng/Input.h b/include/Gedeng/Input.h index f990441..6237087 100644 --- a/include/Gedeng/Input.h +++ b/include/Gedeng/Input.h @@ -18,6 +18,7 @@ class Input { static void initialize(GLFWwindow *window) { glfwSetKeyCallback(window, key_callback); glfwSetCursorPosCallback(window, mouse_callback); + glfwSetMouseButtonCallback(window, mouse_button_callback); glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); is_mouse_active = true; @@ -28,7 +29,7 @@ class Input { static void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods) { if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) glfwSetWindowShouldClose(window, GLFW_TRUE); - Input::set_key_down(key, action == GLFW_RELEASE ? false : true); + set_key_down(key, action == GLFW_RELEASE ? false : true); } static void mouse_callback(GLFWwindow *window, double xpos, double ypos) { @@ -36,6 +37,10 @@ class Input { mouse_position.y = ypos; } + static void mouse_button_callback(GLFWwindow *window, int button, int action, int mods) { + set_mouse_down(button, action == GLFW_RELEASE ? false : true); + } + static void poll_input() { glfwPollEvents(); } @@ -48,12 +53,22 @@ class Input { return keys_down[key]; } + static void set_mouse_down(int button, bool down) { + mouse_down[button] = down; + } + + static bool is_mouse_down(int button) { + return mouse_down[button]; + } + static glm::vec2 get_mouse_position() { return is_mouse_active ? mouse_position : glm::vec2(0.0, 0.0); } private: inline static std::map keys_down; + inline static std::map mouse_down; + inline static glm::vec2 mouse_position; inline static bool is_mouse_active; }; diff --git a/include/Gedeng/Ray.h b/include/Gedeng/Ray.h new file mode 100644 index 0000000..36f5e24 --- /dev/null +++ b/include/Gedeng/Ray.h @@ -0,0 +1,36 @@ +#include +#include + +namespace Gedeng { + +class CollisionResult { + public: + explicit CollisionResult(bool is_colliding, glm::vec3 collision_position = glm::vec3(0, 0, 0)) + : is_colliding(is_colliding), collision_position(collision_position) { + } + + bool is_colliding; + glm::vec3 collision_position; +}; + +class Ray { + public: + glm::vec3 origin; + glm::vec3 direction; + + Ray(glm::vec3 origin, glm::vec3 direction) : origin(origin), direction(direction) { + } + + CollisionResult get_plane_collision(glm::vec3 normal = glm::vec3(0, 1, 0)) { + float denom = glm::dot(normal, direction); + + if (glm::abs(denom) > 0.0001f) { + float t = glm::dot(-origin, normal) / denom; + + if (t >= 0) return CollisionResult(true, origin + t * direction); + } + return CollisionResult(false); + } +}; + +} // namespace Gedeng \ No newline at end of file diff --git a/test/particle-demo/main.cpp b/test/particle-demo/main.cpp index 4732ee3..d656333 100644 --- a/test/particle-demo/main.cpp +++ b/test/particle-demo/main.cpp @@ -3,6 +3,7 @@ #include "Gedeng/QuadMesh.h" #include "Gedeng/TextLabel.h" #include "Gedeng/Vector3.h" +#include #define GEDENG_MAIN #include @@ -19,8 +20,8 @@ class ParticleApp : public Gedeng::Application { normal("Resources/Textures/PavingStones/PavingStones070_2K_Normal.jpg", Gedeng::Texture::Settings()), quad_mesh(Gedeng::QuadMesh(10.0)) { particles.set_position(glm::vec3(0.0f, 0.0f, -5.0f)); - particles.set_velocity(glm::vec3(-1, 0, -1), glm::vec3(1, 5, 1)); - particles.set_gravity(glm::vec3(0, -2, 0)); + particles.set_velocity(glm::vec3(-2, 4, -2), glm::vec3(2, 6, 2)); + particles.set_gravity(glm::vec3(0, -4, 0)); particles.set_color(glm::vec3(0.0f, 0.5f, 1.0f)); particles.set_lifetime(1.0f, 1.5f); particles.set_size(0.1); @@ -37,6 +38,9 @@ class ParticleApp : public Gedeng::Application { void fixed_update(double delta) override { // camera.rotate(delta * 180, glm::vec3(0.0, 1.0, 0.0)); camera.update(delta); + + if (Gedeng::Input::is_mouse_down(GLFW_MOUSE_BUTTON_LEFT)) + particles.set_position(camera.get_view_ray().get_plane_collision().collision_position); } void dynamic_update(double delta) override {