From ce608edde518d78b32112f7c1af40261c59cdf48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0toura=C4=8D?= <525032@mail.muni.cz> Date: Fri, 13 Oct 2023 21:08:07 +0200 Subject: [PATCH] added ortho/persp switch and raycast for ortho --- src/algo/src/raycast.cpp | 49 ++++++++++++++++--- src/controls/include/controls/control_hub.hpp | 2 +- src/controls/src/control_hub.cpp | 3 ++ src/gfx/include/gfx/camera.hpp | 4 ++ src/gfx/src/render.cpp | 14 ++++-- 5 files changed, 60 insertions(+), 12 deletions(-) diff --git a/src/algo/src/raycast.cpp b/src/algo/src/raycast.cpp index 078c515..82d3bec 100644 --- a/src/algo/src/raycast.cpp +++ b/src/algo/src/raycast.cpp @@ -72,12 +72,8 @@ node_ptr find_intersection(const std::vector<node_ptr> &scene, glm::vec3 ray_pos return nearest_node; } -std::pair<glm::vec3, glm::vec3> get_pick_ray(const scene_ptr &scene, const osi::Mouse &mouse, const osi::Window &window) +std::pair<glm::vec3, glm::vec3> get_pick_ray_perspective(const camera_ptr &camera, const glm::mat4 view, const osi::Mouse &mouse, const osi::Window &window) { - camera_ptr camera = scene->getActiveCameras()[0].lock(); // Should be changed to which viewport is in focus - glm::mat4 view = get_view_matrix(camera); - glm::mat4 projection = get_projection_matrix(camera); - // https://gamedev.stackexchange.com/questions/12360/how-do-you-determine-which-object-surface-the-users-pointing-at-with-lwjgl/12370#12370 //get the mouse position in screenSpace coords float aspect_ratio = camera->getWindowSize().x / camera->getWindowSize().y; @@ -110,9 +106,48 @@ std::pair<glm::vec3, glm::vec3> get_pick_ray(const scene_ptr &scene, const osi:: ray_direction = camera->getFrame()->getRotation() * ray_direction; - /* VISUAL REPRESENTATION OF RAY */ + /* VISUAL REPRESENTATION OF RAY */ // addRay(ray_position, ray_direction); ray_direction = glm::normalize(ray_direction); - return {ray_position, ray_direction};} \ No newline at end of file + return {ray_position, ray_direction}; +} + +std::pair<glm::vec3, glm::vec3> get_pick_ray_ortho(const camera_ptr &camera, const glm::mat4 view, const osi::Mouse &mouse, const osi::Window &window) +{ + // https://stackoverflow.com/a/66813405 + + // get x and y coordinates relative to frustum width and height. + // glOrthoWidth and glOrthoHeight are the sizeX and sizeY values + // you created your projection matrix with. If your frustum has a width of 100, + // x would become -50 when the mouse is left and +50 when the mouse is right. + + // NOTE: the / 2.0f / 128.0f corresponds to dividing numbers in render.cpp (get_projection_matrix) + float x = +(2.0f * (float) mouse.pos().x / window.size().x - 1) * (window.size().x / 2.0f / 128.0f); + float y = -(2.0f * (float) mouse.pos().y / window.size().y - 1) * (window.size().y / 2.0f / 128.0f); + + // Now, you want to calculate the camera's local right and up vectors + // (depending on the camera's current view direction): + glm::vec3 cameraRight = camera->getFrame()->getRotationAxisX(); + glm::vec3 cameraUp = camera->getFrame()->getRotationAxisY(); + + // Finally, calculate the ray origin: + glm::vec3 ray_position = camera->getFrame()->getPosition() + cameraRight * x + cameraUp * y; + glm::vec3 ray_direction = -camera->getFrame()->getRotationAxisZ();; + + ray_direction = glm::normalize(ray_direction); + + return {ray_position, ray_direction}; +} + +std::pair<glm::vec3, glm::vec3> get_pick_ray(const scene_ptr &scene, const osi::Mouse &mouse, const osi::Window &window) +{ + camera_ptr camera = scene->getActiveCameras()[0].lock(); // Should be changed to which viewport is in focus + glm::mat4 view = get_view_matrix(camera); + glm::mat4 projection = get_projection_matrix(camera); + + + return camera->isPerspective() ? get_pick_ray_perspective(camera, view, mouse, window) + : get_pick_ray_ortho(camera, view, mouse, window); +} \ No newline at end of file diff --git a/src/controls/include/controls/control_hub.hpp b/src/controls/include/controls/control_hub.hpp index f516589..f7b8b86 100644 --- a/src/controls/include/controls/control_hub.hpp +++ b/src/controls/include/controls/control_hub.hpp @@ -45,7 +45,7 @@ public: const osi::Window &window, bool &editor_running); - /* Methods for manul in-code control */ + /* Methods for manual in-code control */ void rotate_cam(glm::vec3 rotation); void rotate_obj(glm::vec3 rotation); diff --git a/src/controls/src/control_hub.cpp b/src/controls/src/control_hub.cpp index 40f0a11..3b240db 100644 --- a/src/controls/src/control_hub.cpp +++ b/src/controls/src/control_hub.cpp @@ -45,6 +45,9 @@ void ControlHub::processInput(const scene_ptr &scene, const osi::Keyboard &keybo active_camera_type->keyboardMove(keyboard.down()); } + if (keyboard.just_pressed().contains("C")) + scene->getActiveCameras()[0].lock()->setPerspective(!scene->getActiveCameras()[0].lock()->isPerspective()); + // int fill_mode = keyboard.down().contains("X") ? GL_LINE : GL_FILL; // TO DO: put elsewhere // glPolygonMode(GL_FRONT_AND_BACK, fill_mode); // ASSUMPTION(glGetError() == GL_NO_ERROR); diff --git a/src/gfx/include/gfx/camera.hpp b/src/gfx/include/gfx/camera.hpp index c3727e8..d8930c6 100644 --- a/src/gfx/include/gfx/camera.hpp +++ b/src/gfx/include/gfx/camera.hpp @@ -14,6 +14,7 @@ class Camera : public ObjectBase { float FOV = 45.0f; glm::u32vec2 window_size = glm::u32vec2{0, 0}; + bool is_perspective = true; frame_weak_ptr frame; @@ -26,6 +27,9 @@ public: glm::vec2 getWindowSize() const; void setWindowSize(glm::u32vec2 _window_size); + bool isPerspective() const { return is_perspective; } + void setPerspective(bool _is_perspective) { is_perspective = _is_perspective; } + frame_ptr getFrame() const { frame_ptr f = frame.lock(); diff --git a/src/gfx/src/render.cpp b/src/gfx/src/render.cpp index 78d7101..4d808eb 100644 --- a/src/gfx/src/render.cpp +++ b/src/gfx/src/render.cpp @@ -69,10 +69,16 @@ glm::mat4 get_view_matrix(camera_ptr camera) glm::mat4 get_projection_matrix(camera_ptr camera) { - return glm::perspective(glm::radians(camera->getFOV()), - camera->getWindowSize().x / camera->getWindowSize().y, - 0.1f, - 100.0f); + return camera->isPerspective() ? + glm::perspective(glm::radians(camera->getFOV()), + camera->getWindowSize().x / camera->getWindowSize().y, + 0.1f, + 100.0f) + : + glm::ortho(-camera->getWindowSize().x / 2.0f / 128.0f, camera->getWindowSize().x / 2.0f / 128.0f, + -camera->getWindowSize().y / 2.0f / 128.0f, camera->getWindowSize().y / 2.0f / 128.0f, + 0.1f, + 100.0f); } void draw_objects(std::map<std::string, shader_ptr> &my_shaders, std::vector<light_ptr> lights, -- GitLab