Skip to content
Snippets Groups Projects
Commit 08215c4e authored by Martin Štourač's avatar Martin Štourač
Browse files

added cube side higlighting (partially works)

parent f4e0d5ab
No related branches found
No related tags found
No related merge requests found
......@@ -7,6 +7,7 @@
#include <osi/window.hpp>
#include <utils/math.hpp>
#include <array>
#include <memory>
#include <utility>
#include <vector>
......@@ -16,7 +17,9 @@ using scene_ptr = std::shared_ptr<Scene>;
std::pair<float, float> intersect_axis(float ray_direction_a, float ray_position_a, float LH_first_a, float LH_second_a);
std::pair<float, float> intersect(glm::vec3 ray_position, glm::vec3 ray_direction, std::pair<glm::vec3, glm::vec3> LH);
// findIntersection uses functions 'intersect_axis' and 'intersect' and is NOT node tree compatible yet
node_ptr find_intersection(const std::vector<node_ptr> &scene, glm::vec3 ray_position, glm::vec3 ray_direction);
std::pair<glm::vec3, node_ptr> find_intersection(const std::vector<node_ptr> &scene, glm::vec3 ray_position, glm::vec3 ray_direction);
std::array<glm::vec3, 4> find_cube_side(node_ptr node, glm::vec3 hit_coords);
std::pair<glm::vec3, glm::vec3> get_pick_ray(const scene_ptr &scene, const osi::Mouse &mouse, const osi::Window &window);
......
#include <algo/raycast.hpp>
#include <edit/scene.hpp>
#include <gfx/camera.hpp>
#include <gfx/mesh.hpp>
#include <gfx/render.hpp>
#include <utils/math.hpp>
#include <algorithm>
#include <limits>
#include <map>
using scene_ptr = std::shared_ptr<Scene>;
std::pair<float, float> intersect_axis(float ray_direction_a, float ray_position_a,
float LH_first_a, float LH_second_a)
......@@ -39,7 +45,7 @@ std::pair<float, float> intersect(glm::vec3 ray_position, glm::vec3 ray_directio
return {t0, t1};
}
node_ptr find_intersection(const std::vector<node_ptr> &scene, glm::vec3 ray_position, glm::vec3 ray_direction)
std::pair<glm::vec3, node_ptr> find_intersection(const std::vector<node_ptr> &scene, glm::vec3 ray_position, glm::vec3 ray_direction)
{
node_ptr nearest_node = nullptr;
float nearest_t = std::numeric_limits<float>::infinity();
......@@ -69,7 +75,47 @@ node_ptr find_intersection(const std::vector<node_ptr> &scene, glm::vec3 ray_pos
}
}
return nearest_node;
return { ray_position + (nearest_t * ray_direction), nearest_node };
}
std::array<glm::vec3, 4> nearest_vertices(std::array<glm::vec3, 8> AABB_local, std::array<glm::vec3, 8> AABB_world, glm::vec3 hit_coords)
{
std::map<float, std::vector<glm::vec3>> candidates;
for (int i = 0; i < 8; ++i)
{
candidates[glm::distance(AABB_world[i], hit_coords)].emplace_back(AABB_local[i]);
}
std::array<glm::vec3, 4> result;
int i = 0;
for (auto [dist, vertices] : candidates)
{
for (auto vertex : vertices)
{
if (i >= 4)
break;
result[i] = vertex;
++i;
}
}
return result;
}
std::array<glm::vec3, 4> find_cube_side(node_ptr node, glm::vec3 hit_coords)
{
std::array<glm::vec3, 4> side_vertices;
for (auto &object : node->getObjects())
{
auto obj = dynamic_pointer_cast<Mesh>(object);
if (!obj)
continue;
auto AABB_local = obj->getAABB().getFullAABB();
auto AABB_world = obj->getAABB().getAABBWorld(node);
side_vertices = nearest_vertices(AABB_local, AABB_world , hit_coords);
break; // possibly not needed - should receive selection_AABB node
}
return side_vertices;
}
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)
......
......@@ -17,14 +17,17 @@ class AABB
std::array<glm::vec3, 8> full_bbox;
void findLH(std::vector<float> const &vertices);
void getFullAABB();
void createFullAABB();
public:
AABB(std::vector<float> const &vertices);
std::pair<glm::vec3, glm::vec3> const &getLH() const { return LH; }
std::array<glm::vec3, 8> const &getFullAABB() const { return full_bbox; }
std::vector<float> getVertices() const;
std::vector<unsigned int> getIndices() const;
std::pair<glm::vec3, glm::vec3> getLHWorld(node_ptr node) const;
std::array<glm::vec3, 8> getAABBWorld(node_ptr node) const;
};
#endif
\ No newline at end of file
......@@ -3,7 +3,7 @@
AABB::AABB(std::vector<float> const &vertices)
{
findLH(vertices);
getFullAABB();
createFullAABB();
}
void AABB::findLH(std::vector<float> const &vertices)
......@@ -24,7 +24,7 @@ void AABB::findLH(std::vector<float> const &vertices)
}
}
void AABB::getFullAABB()
void AABB::createFullAABB()
{
full_bbox[0] = LH.first;
......@@ -74,4 +74,19 @@ std::pair<glm::vec3, glm::vec3> AABB::getLHWorld(node_ptr node) const
LH_world.second = node_trans * node_scale * glm::vec4(LH.second, 1);
return LH_world;
}
std::array<glm::vec3, 8> AABB::getAABBWorld(node_ptr node) const
{
std::array<glm::vec3, 8> AABB_world;
auto node_trans = node->getFrame()->getTranslationMat();
auto node_scale = node->getFrame()->getScaleMat();
for (int i = 0; i < 8; ++i)
{
AABB_world[i] = node_trans * node_scale * glm::vec4(full_bbox[i], 1);
}
return AABB_world;
}
\ No newline at end of file
......@@ -81,11 +81,11 @@ public:
void setPrevPlaneIntersect(glm::vec3 _prev_plane_intersect) { prev_plane_intersect = _prev_plane_intersect; }
void doObjectAction(scene_ptr scene, ctrlhub_ptr controls);
void updateAxesCamera(scene_ptr scene, ctrlhub_ptr controls);
void changeOrthoCamAxes(scene_ptr scene, ctrlhub_ptr controls);
void changeLevel(scene_ptr scene, ctrlhub_ptr controls);
void adjustGridPosition(scene_ptr scene, ctrlhub_ptr controls, glm::vec3 position);
void adjustGridRotation(scene_ptr scene, ctrlhub_ptr controls, glm::vec3 rotation);
void adjustGridRotation(scene_ptr scene, ctrlhub_ptr controls, glm::quat rotation);
void selectObject(scene_ptr scene, ctrlhub_ptr controls);
void rotateObject(scene_ptr scene, ctrlhub_ptr controls);
......
......@@ -23,6 +23,7 @@ private:
std::vector<node_ptr> scene;
node_ptr selection;
node_ptr selection_AABB;
node_ptr side_higlight;
node_ptr pre_add_AABB;
node_ptr grid;
......@@ -90,12 +91,14 @@ public:
void addRay(glm::vec3 ray_position, glm::vec3 ray_direction);
void addSelectionAABB(node_ptr node);
void addPreAddAABB(node_ptr node, Frame position);
void addSideHighlight(node_ptr node, std::array<glm::vec3, 4> &side_vertices);
void findLights(const std::vector<node_ptr> &nodes);
void findCameras(const std::vector<node_ptr> &nodes);
void changeDrawMode(node_ptr node, unsigned int mode);
void manageSelection(node_ptr nearest_node); // Not node tree compatible
void manageHighlight(glm::vec3 hit_coord, node_ptr nearest_node);
};
#endif
\ No newline at end of file
......@@ -24,7 +24,7 @@ void Editor::doObjectAction(scene_ptr scene, ctrlhub_ptr controls)
}
}
void Editor::updateAxesCamera(scene_ptr scene, ctrlhub_ptr controls)
void Editor::changeOrthoCamAxes(scene_ptr scene, ctrlhub_ptr controls)
{
if (!keyboard.just_pressed().contains("I")
&& !keyboard.just_pressed().contains("K")
......@@ -32,13 +32,13 @@ void Editor::updateAxesCamera(scene_ptr scene, ctrlhub_ptr controls)
return;
glm::vec3 cam_levels = build_level.getAll();
std::array<glm::vec3, 3> rotations = { glm::vec3(0.0f, -90.0f, 0.0f), // L(x-depth)
glm::vec3(-90.0f, 0.0f, 0.0f), // I (y-depth) // FIX - breaks things
glm::vec3(0.0f, 180.0f, 0.0f) }; // K (z-depth)
std::array<glm::quat, 3> rotations = { glm::angleAxis(glm::radians(-90.0f), glm::vec3(0.0f, 1.0f, 0.0f)), // L(x-depth)
glm::angleAxis(glm::radians(-90.0f), glm::vec3(1.0f, 0.0f, 0.0f)), // I (y-depth) // FIX - breaks things
glm::angleAxis(glm::radians(180.0f), glm::vec3(0.0f, 1.0f, 0.0f)) }; // K (z-depth)
std::array<glm::vec3, 3> grid_rotations = { glm::vec3(-90.0f, -90.0f, 0.0f), // L(x-depth)
glm::vec3(0.0f, 0.0f, 0.0f), // I (y-depth)
glm::vec3(-90.0f, 0.0f, 0.0f) }; // K (z-depth)
std::array<glm::quat, 3> grid_rotations = {glm::angleAxis(glm::radians(-90.0f), glm::vec3(1.0f, 0.0f, 0.0f)) * glm::angleAxis(glm::radians(-90.0f), glm::vec3(0.0f, 1.0f, 0.0f)), // L(x-depth)
glm::quat(), // I (y-depth)
glm::angleAxis(glm::radians(-90.0f), glm::vec3(1.0f, 0.0f, 0.0f)) }; // K (z-depth)
std::uint8_t new_active = 0;
if (keyboard.just_pressed().contains("I"))
......@@ -51,16 +51,14 @@ void Editor::updateAxesCamera(scene_ptr scene, ctrlhub_ptr controls)
new_active = 0;
cam_levels[new_active] += new_active == 1 ? 5.0f : -5.0f; // +5 for up-down, else -5
build_level.setActiveIndex(new_active);
// build_level.setActiveIndex(new_active);
controls->getActiveCamCtrl()->setRotation(rotations[new_active]);
controls->getActiveCamCtrl()->setPos(cam_levels[0], cam_levels[1], cam_levels[2]);
// NOTE: grid could have its own controller ?
// scene->getGrid()->getFrame()->setRotationQuat(grid_rotations[new_active]);
adjustGridRotation(scene, controls, grid_rotations[new_active]);
// adjustGridRotation(scene, controls, grid_rotations[new_active]);
}
void Editor::changeLevel(scene_ptr scene, ctrlhub_ptr controls)
void Editor::changeLevel(scene_ptr scene, ctrlhub_ptr controls) // Unused & incorrect
{
auto prev_build_level = build_level;
if (keyboard.just_pressed().contains("P"))
......@@ -69,7 +67,7 @@ void Editor::changeLevel(scene_ptr scene, ctrlhub_ptr controls)
if (keyboard.just_pressed().contains("O"))
--build_level;
adjustGridPosition(scene, controls, build_level - prev_build_level);
// adjustGridPosition(scene, controls, build_level - prev_build_level);
}
void Editor::adjustGridPosition(scene_ptr scene, ctrlhub_ptr controls, glm::vec3 position)
......@@ -80,13 +78,12 @@ void Editor::adjustGridPosition(scene_ptr scene, ctrlhub_ptr controls, glm::vec3
controls->bindObject(prev_active_object);
}
void Editor::adjustGridRotation(scene_ptr scene, ctrlhub_ptr controls, glm::vec3 rotation)
void Editor::adjustGridRotation(scene_ptr scene, ctrlhub_ptr controls, glm::quat rotation)
{
auto prev_active_object = controls->getActiveObjCtrl()->getFrame();
controls->bindObject(scene->getGrid()->getFrame());
controls->getActiveObjCtrl()->setRotation(rotation);
controls->bindObject(prev_active_object);
}
void Editor::selectObject(scene_ptr scene, ctrlhub_ptr controls)
......@@ -96,9 +93,10 @@ void Editor::selectObject(scene_ptr scene, ctrlhub_ptr controls)
auto [ ray_position, ray_direction ] = get_pick_ray(scene, mouse, window);
auto nearest_node = find_intersection(scene->getScene(), ray_position, ray_direction);
auto [ hit_coord, nearest_node ] = find_intersection(scene->getScene(), ray_position, ray_direction);
scene->manageSelection(nearest_node);
scene->manageHighlight(hit_coord, nearest_node);
}
void Editor::rotateObject(scene_ptr scene, ctrlhub_ptr controls)
......@@ -129,7 +127,7 @@ void Editor::moveObject(scene_ptr scene, ctrlhub_ptr controls)
auto [ ray_position, ray_direction ] = get_pick_ray(scene, mouse, window);
// Initial click not onto the selected object
if (!object_moving && find_intersection(scene->getScene(), ray_position, ray_direction) != scene->getSelection())
if (!object_moving && find_intersection(scene->getScene(), ray_position, ray_direction).second != scene->getSelection())
return;
/* Controller setup */
......
#include <edit/scene.hpp>
#include <algo/raycast.hpp>
#include <gfx/shapes.hpp>
#include <gfx/render.hpp> // for grid vertices
#include <filein/obj_loader.hpp>
......@@ -21,16 +22,20 @@ void Scene::createScene()
addNode(Frame{});
addMesh(scene.back(), cube);
scene.back()->getFrame()->setScale(glm::vec3(0.5f, 0.5f, 0.5f));
addNode(glm::vec3(5, 1, -4));
addMesh(scene.back(), cube);
addNode(glm::vec3(2, 0, 1));
addNode(glm::vec3(1, 0, 1));
addMesh(scene.back(), cube);
addNode(glm::vec3(2, 2, 1));
scene.back()->getFrame()->setScale(glm::vec3(0.5f, 0.5f, 0.5f));
addNode(glm::vec3(1, 1, 1));
addMesh(scene.back(), cube);
addNode(glm::vec3(2, 2, 2));
scene.back()->getFrame()->setScale(glm::vec3(0.5f, 0.5f, 0.5f));
addNode(glm::vec3(1, 1, 2));
addMesh(scene.back(), cube);
scene.back()->getFrame()->setScale(glm::vec3(0.5f, 0.5f, 0.5f));
/* ADD AXIS OBJECT */
// Mesh axis(axis_obj_vertices, axis_obj_indices, axis_obj_normals);
......@@ -278,6 +283,27 @@ void Scene::addPreAddAABB(node_ptr node, Frame position)
addMesh(scene.back(), std::move(obj_bbox));
}
}
void Scene::addSideHighlight(node_ptr node, std::array<glm::vec3, 4> &side_vertices)
{
addNode(node->getFrame());
side_higlight = scene.back();
std::vector<float> vertices;
for (auto v : side_vertices)
{
vertices.emplace_back(v.x);
vertices.emplace_back(v.y);
vertices.emplace_back(v.z - 0.05f); // TO DO: determine which side and offset higlight in front
}
std::vector<float> normals;
std::vector<unsigned int> indices = { 0, 1, 2, 1, 2, 3 };
Mesh m(vertices, indices, std::vector<float>{}, glm::vec3(0.0f, 1.0f, 0.0f), "basic");
m.setSelectability(false);
addMesh(side_higlight, std::move(m));
}
void Scene::findLights(const std::vector<node_ptr> &nodes)
{
for (auto &node : nodes)
......@@ -328,3 +354,16 @@ void Scene::manageSelection(node_ptr nearest_node)
selection = nearest_node;
addSelectionAABB(nearest_node);
}
void Scene::manageHighlight(glm::vec3 hit_coord, node_ptr selection_AABB)
{
removeNode(side_higlight);
if (!selection_AABB)
{
side_higlight = nullptr;
return;
}
auto side_vertices = find_cube_side(selection_AABB, hit_coord);
addSideHighlight(selection_AABB, side_vertices);
}
......@@ -37,12 +37,14 @@ void Simulator::update()
controls->processInput(scene, keyboard(), timer(), window());
controls->processMouse(mouse(), window(), editor->getEditorRunning());
editor->updateAxesCamera(scene, controls);
editor->doObjectAction(scene, controls);
editor->changeLevel(scene, controls);
editor->changeOrthoCamAxes(scene, controls);
// editor->changeLevel(scene, controls);
auto cam_frame = scene->getActiveCameras()[0].lock()->getFrame()->getPosition();
std::cout << "Camera coords: X " << cam_frame.x << " | Y " << cam_frame.y << " | Z " << cam_frame.z << std::endl;
auto cam_front_vec = controls->getActiveCamCtrl()->getFrontVec();
// std::cout << "Camera coords: X " << cam_frame.x << " | Y " << cam_frame.y << " | Z " << cam_frame.z << std::endl;
// std::cout << "Camera frontVec: X " << cam_front_vec.x << " | Y " << cam_front_vec.y << " | Z " << cam_front_vec.z << std::endl;
/* Rotation around x-axis demo */
// controls->rotate_obj(glm::vec3(1.0f, 0.0f, 0.0f));
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment