From 9a35d6b1d8ebb1f1a1ba85f18ec6ca9d3aafdbe2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20=C5=A0toura=C4=8D?= <525032@mail.muni.cz>
Date: Sat, 3 Jun 2023 09:46:42 +0200
Subject: [PATCH] better code decomposition of the picking process

---
 src/gfx/include/gfx/aabb.hpp            |  5 ++++
 src/gfx/include/gfx/render.hpp          |  2 ++
 src/gfx/src/aabb.cpp                    | 13 +++++++++
 src/gfx/src/render.cpp                  | 27 ++++++++++-------
 src/studio/include/studio/simulator.hpp |  2 +-
 src/studio/src/simulator.cpp            | 39 +++++++------------------
 6 files changed, 49 insertions(+), 39 deletions(-)

diff --git a/src/gfx/include/gfx/aabb.hpp b/src/gfx/include/gfx/aabb.hpp
index 654bb9a..d222de0 100644
--- a/src/gfx/include/gfx/aabb.hpp
+++ b/src/gfx/include/gfx/aabb.hpp
@@ -6,6 +6,10 @@
 #include <vector>
 #include <array>
 #include <utility>
+#include <memory>
+#include <gfx/node.hpp>
+
+using node_ptr = std::shared_ptr<Node>;
 
 class AABB
 {
@@ -20,6 +24,7 @@ public:
     std::pair<glm::vec3, glm::vec3> const &getLH() const { return LH; }
     std::vector<float> getVertices() const;
     std::vector<unsigned int> getIndices() const;
+    std::pair<glm::vec3, glm::vec3> getLHWorld(node_ptr node) const;
 };
 
 #endif
\ No newline at end of file
diff --git a/src/gfx/include/gfx/render.hpp b/src/gfx/include/gfx/render.hpp
index 1c2a719..4a823da 100644
--- a/src/gfx/include/gfx/render.hpp
+++ b/src/gfx/include/gfx/render.hpp
@@ -22,6 +22,8 @@ using light_ptr = std::shared_ptr<Light>;
 std::vector<float> generate_grid_vertices(int span);
 std::vector<unsigned int> generate_grid_indices(int span);
 void send_matrices_to_shader(Shader &myShader, glm::mat4 &model, glm::mat4 &view, glm::mat4 &projection);
+glm::mat4 get_view_matrix(camera_ptr camera);
+glm::mat4 get_projection_matrix(camera_ptr camera);
 
 void gfx_draw(std::map<std::string, shader_ptr> &myShaders, 
               std::vector<light_ptr> lights,
diff --git a/src/gfx/src/aabb.cpp b/src/gfx/src/aabb.cpp
index df3d185..a72d2c5 100644
--- a/src/gfx/src/aabb.cpp
+++ b/src/gfx/src/aabb.cpp
@@ -61,4 +61,17 @@ std::vector<unsigned int> AABB::getIndices() const
              2, 4, 2, 6,
              3, 5, 3, 6
             };
+}
+
+std::pair<glm::vec3, glm::vec3> AABB::getLHWorld(node_ptr node) const
+{
+    std::pair<glm::vec3, glm::vec3> LH_world;
+
+    auto node_trans = node->getFrame()->getTranslationMat();
+    auto node_scale = node->getFrame()->getScaleMat();
+
+    LH_world.first = node_trans * node_scale * glm::vec4(LH.first, 1);
+    LH_world.second = node_trans * node_scale * glm::vec4(LH.second, 1);
+
+    return LH_world;
 }
\ No newline at end of file
diff --git a/src/gfx/src/render.cpp b/src/gfx/src/render.cpp
index 6f64f6e..e3566db 100644
--- a/src/gfx/src/render.cpp
+++ b/src/gfx/src/render.cpp
@@ -69,6 +69,21 @@ void send_matrices_to_shader(Shader &myShader, glm::mat4 &model, glm::mat4 &view
     ASSUMPTION(glGetError() == GL_NO_ERROR);
 }
 
+glm::mat4 get_view_matrix(camera_ptr camera)
+{
+    return glm::lookAt(camera->getFrame()->getPosition(), 
+                       camera->getFrame()->getPosition() + -camera->getFrame()->getRotationAxisZ(), 
+                       glm::vec3(0.0f, 1.0f, 0.0f));
+}
+
+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);
+}
+
 void draw_objects(std::map<std::string, shader_ptr> &myShaders, std::vector<light_ptr> lights,
                   camera_ptr camera,
                   const std::vector<node_ptr> &scene,
@@ -138,16 +153,8 @@ void gfx_draw(std::map<std::string, shader_ptr> &myShaders,
     //                    glm::vec3(0.0f, 1.0f, 0.0f));
     /* ---------------------------------------------------------------- */
 
-    glm::mat4 view;
-    view = glm::lookAt(camera->getFrame()->getPosition(), 
-                       camera->getFrame()->getPosition() + -camera->getFrame()->getRotationAxisZ(), 
-                       glm::vec3(0.0f, 1.0f, 0.0f));
-
-    glm::mat4 projection;
-    projection = glm::perspective(glm::radians(camera->getFOV()), 
-                                  camera->getWindowSize().x / camera->getWindowSize().y, 
-                                  0.1f, 
-                                  100.0f);
+    glm::mat4 view = get_view_matrix(camera);
+    glm::mat4 projection = get_projection_matrix(camera);
 
     glEnable(GL_DEPTH_TEST);
     ASSUMPTION(glGetError() == GL_NO_ERROR);
diff --git a/src/studio/include/studio/simulator.hpp b/src/studio/include/studio/simulator.hpp
index 7a5f234..278875a 100644
--- a/src/studio/include/studio/simulator.hpp
+++ b/src/studio/include/studio/simulator.hpp
@@ -54,7 +54,7 @@ struct Simulator : public osi::Simulator
     void process_input();
 
     void add_ray(glm::vec3 rayPosition, glm::vec3 rayDirection);
-    void display_selection_AABB(node_ptr node);
+    void add_selection_AABB(node_ptr node);
 
     std::pair<float, float> intersect_axis(float rayDirection_a, float rayPosition_a, float LH_first_a, float LH_second_a);
     std::pair<float, float> intersect(glm::vec3 rayPosition, glm::vec3 rayDirection, std::pair<glm::vec3, glm::vec3> LH);
diff --git a/src/studio/src/simulator.cpp b/src/studio/src/simulator.cpp
index ed4751b..c353219 100644
--- a/src/studio/src/simulator.cpp
+++ b/src/studio/src/simulator.cpp
@@ -241,29 +241,18 @@ void Simulator::create_scene()
     Object cube(lit_cube_vertices, lit_cube_indices, lit_cube_normals);
     scene.emplace_back(std::make_shared<Node>(std::make_shared<Frame>(Frame{})));
     scene.back()->addObject(std::make_shared<Object>(std::move(cube))); // TO DO: No move constructor?
-    /* ADD CUBE AABB */
-    // Object cube_bbox(cube.getAABB().getVertices(), cube.getAABB().getIndices(), std::vector<float>{}, glm::vec3(0.5f, 1, 0.31f), "basic");
-    // cube_bbox.setDrawMode(GL_LINES);
-    // // scene.emplace_back(std::make_shared<Node>(std::make_shared<Frame>(scene.back()->getFrame()->getPosition())));
-    // scene.back()->addObject(std::make_shared<Object>(std::move(cube_bbox))); 
 
     // AXIS OBJECT
     Object axis(axis_obj_vertices, axis_obj_indices, axis_obj_normals);
     axis.setShaderType("basic");
     scene.emplace_back(std::make_shared<Node>(std::make_shared<Frame>(Frame{glm::vec3(3, 2, 0)})));
     scene.back()->addObject(std::make_shared<Object>(std::move(axis)));
-    // Object axis_bbox(axis.getAABB().getVertices(), axis.getAABB().getIndices(), std::vector<float>{}, glm::vec3(0.5f, 1, 0.31f), "basic");
-    // axis_bbox.setDrawMode(GL_LINES);
-    // scene.back()->addObject(std::make_shared<Object>(std::move(axis_bbox)));
 
     // TRIANGLE
     Object triangle(triangle_vertices, triangle_indices);
     triangle.setShaderType("basic");
     scene.emplace_back(std::make_shared<Node>(std::make_shared<Frame>(Frame{glm::vec3(-2, 1, 0)})));
     scene.back()->addObject(std::make_shared<Object>(std::move(triangle)));
-    // Object triangle_bbox(triangle.getAABB().getVertices(), triangle.getAABB().getIndices(), std::vector<float>{}, glm::vec3(0.5f, 1, 0.31f), "basic");
-    // triangle_bbox.setDrawMode(GL_LINES);
-    // scene.back()->addObject(std::make_shared<Object>(std::move(triangle_bbox)));
 
     /* ADD LIGHT CUBE AND ITS LIGHT */
     scene.emplace_back(std::make_shared<Node>(std::make_shared<Frame>(Frame{glm::vec3(1.2f, 2.0f, 2.0f)})));
@@ -328,7 +317,7 @@ void Simulator::add_ray(glm::vec3 rayPosition, glm::vec3 rayDirection)
     scene.back()->addObject(std::move(ray));
 }
 
-void Simulator::display_selection_AABB(node_ptr node)
+void Simulator::add_selection_AABB(node_ptr node)
 {
     scene.emplace_back(std::make_shared<Node>(node->getFrame()));
     selection_AABB = scene.back();
@@ -388,10 +377,9 @@ node_ptr Simulator::find_intersection(glm::vec3 rayPosition, glm::vec3 rayDirect
             if (!obj || !obj->is_selectable())
                 continue;
             
-            auto LH = obj->getAABB().getLH();
-            LH.first = node->getFrame()->getTranslationMat() * node->getFrame()->getScaleMat() * glm::vec4(LH.first, 1);
-            LH.second = node->getFrame()->getTranslationMat() * node->getFrame()->getScaleMat() * glm::vec4(LH.second, 1);
-            auto [ t0, t1 ] = intersect(rayPosition, rayDirection, LH);
+            auto LH_world = obj->getAABB().getLHWorld(node);
+            auto [ t0, t1 ] = intersect(rayPosition, rayDirection, LH_world);
+
             if ( t1 < t0 || t1 < 0)
                 continue;
             if (t0 < 0 && t1 < nearest_t)
@@ -412,15 +400,9 @@ node_ptr Simulator::find_intersection(glm::vec3 rayPosition, glm::vec3 rayDirect
 
 std::pair<glm::vec3, glm::vec3> Simulator::get_pick_ray()
 {
-    camera_ptr camera = active_cameras[0];
-
-    glm::mat4 view = glm::lookAt(camera->getFrame()->getPosition(), 
-                                 camera->getFrame()->getPosition() + -camera->getFrame()->getRotationAxisZ(), 
-                                 glm::vec3(0.0f, 1.0f, 0.0f));
-    glm::mat4 projection = glm::perspective(glm::radians(camera->getFOV()), 
-                                            camera->getWindowSize().x / camera->getWindowSize().y, 
-                                            0.1f, 
-                                            100.0f);
+    camera_ptr camera = active_cameras[0]; // 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
@@ -476,7 +458,7 @@ void Simulator::manage_selection(node_ptr nearest_node)
         return;
     }
     selection = nearest_node;
-    display_selection_AABB(nearest_node);
+    add_selection_AABB(nearest_node);
 }
 
 void Simulator::select_object()
@@ -485,12 +467,13 @@ void Simulator::select_object()
         return;
 
     auto [ rayPosition, rayDirection ] = get_pick_ray();
-    std::cout << "rayDirection vector is: " << rayDirection.x << ", " << rayDirection.y << ", " << rayDirection.z << std::endl << std::endl;
+    std::cout << "rayDirection vector is: " 
+              << rayDirection.x << ", " << rayDirection.y << ", " << rayDirection.z 
+              << std::endl << std::endl;
 
     auto nearest_node = find_intersection(rayPosition, rayDirection);
 
     manage_selection(nearest_node);
-
 }
 
 void Simulator::process_mouse()
-- 
GitLab