Add basic collision detection for particle origin placement

This commit is contained in:
karl 2021-05-09 19:47:44 +02:00
parent 5637868200
commit a44e38afa3
4 changed files with 63 additions and 3 deletions

View File

@ -7,6 +7,7 @@
#include <glm/gtx/dual_quaternion.hpp> #include <glm/gtx/dual_quaternion.hpp>
#include "Gedeng/Logger.h" #include "Gedeng/Logger.h"
#include "Gedeng/Ray.h"
#include "Input.h" #include "Input.h"
#include "Spatial.h" #include "Spatial.h"
@ -28,6 +29,10 @@ class Camera : public Spatial {
return glm::inverse(get_matrix()); return glm::inverse(get_matrix());
} }
Ray get_view_ray() const {
return Ray(get_translation(), forward());
}
private: private:
glm::mat4 projection; glm::mat4 projection;
}; };

View File

@ -18,6 +18,7 @@ class Input {
static void initialize(GLFWwindow *window) { static void initialize(GLFWwindow *window) {
glfwSetKeyCallback(window, key_callback); glfwSetKeyCallback(window, key_callback);
glfwSetCursorPosCallback(window, mouse_callback); glfwSetCursorPosCallback(window, mouse_callback);
glfwSetMouseButtonCallback(window, mouse_button_callback);
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
is_mouse_active = true; is_mouse_active = true;
@ -28,7 +29,7 @@ class Input {
static void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods) { 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); 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) { static void mouse_callback(GLFWwindow *window, double xpos, double ypos) {
@ -36,6 +37,10 @@ class Input {
mouse_position.y = ypos; 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() { static void poll_input() {
glfwPollEvents(); glfwPollEvents();
} }
@ -48,12 +53,22 @@ class Input {
return keys_down[key]; 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() { static glm::vec2 get_mouse_position() {
return is_mouse_active ? mouse_position : glm::vec2(0.0, 0.0); return is_mouse_active ? mouse_position : glm::vec2(0.0, 0.0);
} }
private: private:
inline static std::map<int, bool> keys_down; inline static std::map<int, bool> keys_down;
inline static std::map<int, bool> mouse_down;
inline static glm::vec2 mouse_position; inline static glm::vec2 mouse_position;
inline static bool is_mouse_active; inline static bool is_mouse_active;
}; };

36
include/Gedeng/Ray.h Normal file
View File

@ -0,0 +1,36 @@
#include <glm/geometric.hpp>
#include <glm/glm.hpp>
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

View File

@ -3,6 +3,7 @@
#include "Gedeng/QuadMesh.h" #include "Gedeng/QuadMesh.h"
#include "Gedeng/TextLabel.h" #include "Gedeng/TextLabel.h"
#include "Gedeng/Vector3.h" #include "Gedeng/Vector3.h"
#include <GLFW/glfw3.h>
#define GEDENG_MAIN #define GEDENG_MAIN
#include <Gedeng.h> #include <Gedeng.h>
@ -19,8 +20,8 @@ class ParticleApp : public Gedeng::Application {
normal("Resources/Textures/PavingStones/PavingStones070_2K_Normal.jpg", Gedeng::Texture::Settings()), normal("Resources/Textures/PavingStones/PavingStones070_2K_Normal.jpg", Gedeng::Texture::Settings()),
quad_mesh(Gedeng::QuadMesh(10.0)) { quad_mesh(Gedeng::QuadMesh(10.0)) {
particles.set_position(glm::vec3(0.0f, 0.0f, -5.0f)); 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_velocity(glm::vec3(-2, 4, -2), glm::vec3(2, 6, 2));
particles.set_gravity(glm::vec3(0, -2, 0)); particles.set_gravity(glm::vec3(0, -4, 0));
particles.set_color(glm::vec3(0.0f, 0.5f, 1.0f)); particles.set_color(glm::vec3(0.0f, 0.5f, 1.0f));
particles.set_lifetime(1.0f, 1.5f); particles.set_lifetime(1.0f, 1.5f);
particles.set_size(0.1); particles.set_size(0.1);
@ -37,6 +38,9 @@ class ParticleApp : public Gedeng::Application {
void fixed_update(double delta) override { void fixed_update(double delta) override {
// camera.rotate(delta * 180, glm::vec3(0.0, 1.0, 0.0)); // camera.rotate(delta * 180, glm::vec3(0.0, 1.0, 0.0));
camera.update(delta); 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 { void dynamic_update(double delta) override {