From ae95727cac8006837a2444fa58bae353be42e5a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0toura=C4=8D?= <525032@mail.muni.cz> Date: Fri, 2 Jun 2023 12:07:29 +0200 Subject: [PATCH] scuffed object selection implemented (needs fixes) --- src/studio/include/studio/simulator.hpp | 5 + src/studio/src/simulator.cpp | 133 +++++++++++++++++++++--- 2 files changed, 122 insertions(+), 16 deletions(-) diff --git a/src/studio/include/studio/simulator.hpp b/src/studio/include/studio/simulator.hpp index 09a8a8f..1989e1f 100644 --- a/src/studio/include/studio/simulator.hpp +++ b/src/studio/include/studio/simulator.hpp @@ -53,8 +53,11 @@ struct Simulator : public osi::Simulator void create_scene(); void process_input(); + void intersect_axis(glm::vec3 rayPosition, glm::vec3 rayDirection, std::pair<glm::vec3, glm::vec3> LH, float t_small, float t_big); + std::pair<float, float> intersect(glm::vec3 rayPosition, glm::vec3 rayDirection, std::pair<glm::vec3, glm::vec3> LH); void find_intersection(glm::vec3 rayPosition, glm::vec3 rayDirection); void add_ray(glm::vec3 rayPosition, glm::vec3 rayDirection); + void display_selection_AABB(node_ptr node); void select_object(); void process_mouse(); @@ -63,6 +66,7 @@ private: /* CONTROLS */ int active_object_idx = -1; // FTO DO: vector of active objects + node_ptr active_object; int object_ctrl_type = 0; int active_camera_type = 0; @@ -74,6 +78,7 @@ private: /* SCENE */ std::vector<node_ptr> scene; node_ptr selection; + node_ptr selection_AABB; std::vector<light_ptr> lights; diff --git a/src/studio/src/simulator.cpp b/src/studio/src/simulator.cpp index 1846a17..f3335d8 100644 --- a/src/studio/src/simulator.cpp +++ b/src/studio/src/simulator.cpp @@ -10,6 +10,8 @@ #include <vector> #include <glm/gtc/constants.hpp> +#include <limits> +#include <algorithm> namespace studio { std::vector<float> obj_vertices = @@ -241,28 +243,28 @@ void Simulator::create_scene() 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))); + // 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))); + // 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))); + // 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)}))); @@ -296,10 +298,11 @@ void Simulator::process_input() if (!window().has_keyboard_focus()) return; - if (keyboard().down().contains("O")) + if (keyboard().down().contains("O") && selection) { for (auto &controller : obj_controls) { + controller->setFrame(selection->getFrame()); controller->setStep(timer().dt()); controller->move(keyboard().down()); } @@ -315,10 +318,62 @@ void Simulator::process_input() ASSUMPTION(glGetError() == GL_NO_ERROR); } +void Simulator::intersect_axis(glm::vec3 rayPosition, glm::vec3 rayDirection, std::pair<glm::vec3, glm::vec3> LH, float t_small, float t_big) +{ + +} + +std::pair<float, float> Simulator::intersect(glm::vec3 rayPosition, glm::vec3 rayDirection, std::pair<glm::vec3, glm::vec3> LH) +{ + float tx; + float tX; + if (rayDirection.x == 0 && LH.first.x <= rayPosition.x && rayPosition.x <= LH.second.x) + { + tx = -std::numeric_limits<float>::infinity(); + tX = std::numeric_limits<float>::infinity(); + } + else + { + tx = glm::min((LH.first.x - rayPosition.x) / rayDirection.x, (LH.second.x - rayPosition.x) / rayDirection.x); + tX = glm::max((LH.first.x - rayPosition.x) / rayDirection.x, (LH.second.x - rayPosition.x) / rayDirection.x); + } + + float ty; + float tY; + if (rayDirection.y == 0 && LH.first.y <= rayPosition.y && rayPosition.y <= LH.second.y) + { + ty = -std::numeric_limits<float>::infinity(); + tY = std::numeric_limits<float>::infinity(); + } + else + { + ty = glm::min((LH.first.y - rayPosition.y) / rayDirection.y, (LH.second.y - rayPosition.y) / rayDirection.y); + tY = glm::max((LH.first.y - rayPosition.y) / rayDirection.y, (LH.second.y - rayPosition.y) / rayDirection.y); + } + + float tz; + float tZ; + if (rayDirection.z == 0 && LH.first.z <= rayPosition.z && rayPosition.z <= LH.second.z) + { + tz = -std::numeric_limits<float>::infinity(); + tZ = std::numeric_limits<float>::infinity(); + } + else + { + tz = glm::min((LH.first.z - rayPosition.z) / rayDirection.z, (LH.second.z - rayPosition.z) / rayDirection.z); + tZ = glm::max((LH.first.z - rayPosition.z) / rayDirection.z, (LH.second.z - rayPosition.z) / rayDirection.z); + } + + float t0 = glm::max(tx, glm::max(ty, tz)); + float t1 = glm::min(tX, glm::min(tY, tZ)); + + return {t0, t1}; +} + void Simulator::find_intersection(glm::vec3 rayPosition, glm::vec3 rayDirection) { node_ptr nearest_node = nullptr; - float nearest_t = 0; + float nearest_t = std::numeric_limits<float>::infinity(); for (auto &node : scene) { for (auto &object : node->getObjects()) @@ -328,11 +383,55 @@ void Simulator::find_intersection(glm::vec3 rayPosition, glm::vec3 rayDirection) continue; auto LH = obj->getAABB().getLH(); - // float t = intersect(rayPosition, rayDirection, LH); - // if (t < nearest_t) - // nearest_t = t; + auto t = intersect(rayPosition, rayDirection, LH); + if (t.second > t.first || t.second < 0) + continue; + if (t.first < 0 && t.second < nearest_t) + { + nearest_t = t.second; + nearest_node = node; + } + else if (t.first < nearest_t) + { + nearest_t = t.first; + nearest_node = node; + } } } + if (nearest_node) + { + selection = nearest_node; + display_selection_AABB(nearest_node); + } + else + { + selection = nullptr; + if (selection_AABB) + { + // Not node tree compatible + auto it = std::find(scene.begin(), scene.end(), selection_AABB); + if (it != scene.end()) + scene.erase(it); + selection_AABB = nullptr; + } + } +} + +void Simulator::display_selection_AABB(node_ptr node) +{ + scene.emplace_back(std::make_shared<Node>(node->getFrame())); + selection_AABB = scene.back(); + for (auto &object : node->getObjects()) + { + auto obj = dynamic_pointer_cast<Object>(object); + if (!obj) + continue; + + std::cout << "added AABB into scene" << std::endl; + Object obj_bbox(obj->getAABB().getVertices(), obj->getAABB().getIndices(), std::vector<float>{}, glm::vec3(0.5f, 1, 0.31f), "basic"); + obj_bbox.setDrawMode(GL_LINES); + scene.back()->addObject(std::make_shared<Object>(std::move(obj_bbox))); + } } void Simulator::add_ray(glm::vec3 rayPosition, glm::vec3 rayDirection) @@ -415,7 +514,7 @@ void Simulator::select_object() //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); ?????????????? + // Matrix4f.transform(invView, cameraSpaceNear, worldSpaceNear); ?????????????? glm::vec4 worldSpaceNear = invView * cameraSpaceNear; // Matrix4f.transform(invView, cameraSpaceFar, worldSpaceFar); ??????????????? glm::vec4 worldSpaceFar = cameraSpaceFar * worldSpaceFar; @@ -430,6 +529,8 @@ void Simulator::select_object() rayDirection = glm::normalize(rayDirection); std::cout << "rayDirection vector is: " << rayDirection.x << ", " << rayDirection.y << ", " << rayDirection.z << std::endl << std::endl; + + find_intersection(rayPosition, rayDirection); } void Simulator::process_mouse() -- GitLab