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