From b91e7ec8bafbafec19d3780585f86293f597c7f6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20=C5=A0toura=C4=8D?= <525032@mail.muni.cz>
Date: Thu, 1 Jun 2023 20:50:23 +0200
Subject: [PATCH] raycast attenpts

---
 src/gfx/src/cam_control.cpp             |   2 +-
 src/studio/include/studio/simulator.hpp |   3 +
 src/studio/src/simulator.cpp            | 172 +++++++++++++++++++++---
 3 files changed, 160 insertions(+), 17 deletions(-)

diff --git a/src/gfx/src/cam_control.cpp b/src/gfx/src/cam_control.cpp
index af64499..2acfc79 100644
--- a/src/gfx/src/cam_control.cpp
+++ b/src/gfx/src/cam_control.cpp
@@ -45,7 +45,7 @@ void CameraController::process_mouse(const osi::Mouse &mouse, const osi::Window
     float xoffset = 0;
     float yoffset = 0;
 
-    if (mouse.down().contains("MouseLeft")
+    if (mouse.down().contains("MouseRight")
         && window.is_mouse_in_window())
     {
         glm::i32vec2 offset = mouse.pos_delta();
diff --git a/src/studio/include/studio/simulator.hpp b/src/studio/include/studio/simulator.hpp
index 423b8ee..48ae101 100644
--- a/src/studio/include/studio/simulator.hpp
+++ b/src/studio/include/studio/simulator.hpp
@@ -52,6 +52,9 @@ struct Simulator : public osi::Simulator
     void find_cameras(const std::vector<node_ptr> &scene);
     void create_scene();
     void process_input();
+
+    void add_ray(camera_ptr camera, glm::vec3 rayDirection);
+    void select_object();
     void process_mouse();
 
 private:    
diff --git a/src/studio/src/simulator.cpp b/src/studio/src/simulator.cpp
index 5c8e47f..4157040 100644
--- a/src/studio/src/simulator.cpp
+++ b/src/studio/src/simulator.cpp
@@ -9,6 +9,8 @@
 #include <iostream>
 #include <vector>
 
+#include <glm/gtc/constants.hpp>
+
 namespace studio {
 std::vector<float> obj_vertices =
     {
@@ -92,23 +94,28 @@ std::vector<float> getnormals(std::vector<unsigned int> &indices, std::vector<fl
     return normals;
 }
 
+// Triangle
+std::vector<float> triangle_vertices = { 0, -0.2f, 0.5f,  0.7f, 0.3f, 0,  -0.5f, 0.5f, 1 };
+std::vector<unsigned int> triangle_indices = { 0, 1, 2 };
+
 // Axis object
-// , object{{
-//           0, 0, 0,       1, -0.2f, 0,       1, 0.2f, 0,
-//           0, 0, 0,   -0.2f,     2, 0,    0.2f,    2, 0,
-//           0, 0, 0,   -0.2f,     0, 3,    0.2f,    0, 3,
-//          },
-//          {
-//           0, 1, 2,
-//           3, 4, 5,
-//           6, 7, 8
-//          },
-//          {
-//             0, 0, -1,   0, 0, -1,     0, 0, -1,
-//             0, 0, -1,   0, 0, -1,     0, 0, -1,
-//             0, 1,  0,   0, 1,  0,     0, 1,  0
-//          }
-//         }
+std::vector<float> axis_obj_vertices = 
+        {
+          0, 0, 0,       1, -0.2f, 0,       1, 0.2f, 0,
+          0, 0, 0,   -0.2f,     2, 0,    0.2f,    2, 0,
+          0, 0, 0,   -0.2f,     0, 3,    0.2f,    0, 3,
+        };
+
+std::vector<unsigned int> axis_obj_indices = 
+        { 0, 1, 2,
+          3, 4, 5,
+          6, 7, 8
+        };
+std::vector<float> axis_obj_normals = 
+          { 0, 0, -1,   0, 0, -1,     0, 0, -1,
+            0, 0, -1,   0, 0, -1,     0, 0, -1,
+            0, 1,  0,   0, 1,  0,     0, 1,  0
+          };
 
 Simulator::Simulator()
     : osi::Simulator()
@@ -236,8 +243,27 @@ void Simulator::create_scene()
     /* 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)})));
     scene.back()->addObject(std::make_shared<Object>(lit_cube_vertices, 
@@ -289,8 +315,122 @@ void Simulator::process_input()
     ASSUMPTION(glGetError() == GL_NO_ERROR);
 }
 
+void Simulator::add_ray(camera_ptr camera, glm::vec3 rayDirection)
+{
+    object_ptr ray = std::make_shared<Object>(Object{{0, 0, 0, rayDirection.x, rayDirection.y, rayDirection.z}, {0, 1}, {}, glm::vec3(0.5f, 1, 0.31f), "basic"});
+    ray->setDrawMode(GL_LINES);
+
+    frame_ptr ray_frame = std::make_shared<Frame>(camera->getFrame()->getPosition());
+    scene.emplace_back(std::make_shared<Node>(ray_frame));
+    scene.back()->addObject(std::move(ray));
+}
+
+void Simulator::select_object()
+{
+    if (!mouse().just_released().contains("MouseLeft"))
+        return;
+
+    /* ATTEMPT 1 */
+    // https://antongerdelan.net/opengl/raycasting.html
+    float x_ = mouse().pos().x - (window().size().x / 2) - 1.0f;
+    float y_ = 1.0f - mouse().pos().y - (window().size().y / 2);
+    float z_ = 1.0f;
+    glm::vec3 ray_ndc = glm::vec3(x_, y_, z_);
+    glm::vec4 ray_clip = glm::vec4(ray_ndc.x, ray_ndc.y, -1.0f, 1.0f);
+
+    camera_ptr camera = active_cameras[0];
+
+    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::vec4 ray_eye = glm::inverse(projection) * ray_clip;
+    ray_eye.z = -1.0f;
+    ray_eye.w = 0.0f;
+
+    glm::vec3 ray_wor = (glm::inverse(view) * ray_eye);
+    ray_wor = glm::normalize(ray_wor);
+
+    /* ATTEMPT 2 */
+    // WHITEBOARD
+    float u = static_cast<float>(mouse().pos().x - (window().size().x / 2.0f));
+    float v = static_cast<float>((window().size().y - mouse().pos().y) - (window().size().y / 2.0f));
+    glm::vec2 uv = glm::normalize(glm::vec2(u, v));
+
+    glm::vec3 camPos = camera->getFrame()->getPosition();
+    glm::vec3 P = camPos + 0.1f * -camera->getFrame()->getRotationAxisZ() + uv.x * camera->getFrame()->getRotationAxisX() + uv.y * camera->getFrame()->getRotationAxisY();
+    glm::vec3 w = P - camPos;
+    w = glm::normalize(w);
+    w.z = 1.0f;
+
+    // std::cout << "P point is: " << P.x << ", " << P.y << ", " << P.z << std::endl;
+    // std::cout << "camPos is: " << camPos.x << ", " << camPos.y << ", " << camPos.z << std::endl;
+    // std::cout << "w vector is: " << w.x << ", " << w.y << ", " << w.z << std::endl << std::endl;
+
+
+    /* ATTEMPT 3 */
+    // 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 ascpectRatio = camera->getWindowSize().x / camera->getWindowSize().y;
+    float screenSpaceX = ((float) mouse().pos().x / (window().size().x / 2) - 1.0f) * ascpectRatio;
+    float screenSpaceY = (1.0f - (float) mouse().pos().y / (window().size().y / 2));
+
+    float viewRatio = glm::tan((glm::pi<float>() / (180.f/camera->getFOV()) / 2.0f));  // * zoomFactor;
+
+    screenSpaceX = screenSpaceX * viewRatio;
+    screenSpaceY = screenSpaceY * viewRatio;
+
+    //Find the far and near camera spaces
+    float nearPlane = 0.1f;
+    float farPlane = 100.0f;
+    glm::vec4 cameraSpaceNear = glm::vec4(screenSpaceX * nearPlane, screenSpaceY * nearPlane, -nearPlane, 1);
+    glm::vec4 cameraSpaceFar = glm::vec4(screenSpaceX * farPlane,  screenSpaceY * farPlane,  -farPlane, 1);
+
+
+    //Unproject the 2D window into 3D to see where in 3D we're actually clicking
+    glm::mat4 tmpView = glm::mat4(view);
+    glm::mat4 invView = glm::inverse(tmpView);
+    //Matrix4f.transform(invView, cameraSpaceNear, worldSpaceNear); ??????????????
+    glm::vec4 worldSpaceNear = invView * cameraSpaceNear;
+    // Matrix4f.transform(invView, cameraSpaceFar, worldSpaceFar); ???????????????
+    glm::vec4 worldSpaceFar = cameraSpaceFar * worldSpaceFar;
+
+    //calculate the ray position and direction
+    glm::vec3 rayPosition = glm::vec3(worldSpaceNear.x, worldSpaceNear.y, worldSpaceNear.z);
+    glm::vec3 rayDirection = -glm::vec3(worldSpaceFar.x - worldSpaceNear.x, worldSpaceFar.y - worldSpaceNear.y, worldSpaceFar.z - worldSpaceNear.z);
+
+    rayDirection = camera->getFrame()->getRotation() * rayDirection;
+
+    add_ray(camera, rayDirection);
+    rayDirection = glm::normalize(rayDirection);
+
+    std::cout << "rayDirection vector is: " << rayDirection.x << ", " << rayDirection.y << ", " << rayDirection.z << std::endl << std::endl;
+    
+
+}
+
 void Simulator::process_mouse()
 {
     cam_controls[active_camera_type]->process_mouse(mouse(), window(), editor_running);
+    switch(control_state)
+    {
+        case state::select:
+            select_object();
+            break;
+        case state::move:
+            // happens in obj controller
+            break;
+        case state::rotate:
+            // happens in obj controller
+            break;
+        default:
+            break;
+    }
 }
 }
-- 
GitLab