diff --git a/src/edit/include/edit/editor.hpp b/src/edit/include/edit/editor.hpp index 5a91cf6e823f388711ec5915d4e470438ccbce3a..e1e2a11070b3c0d79f1782b4b4e06905afefe43b 100644 --- a/src/edit/include/edit/editor.hpp +++ b/src/edit/include/edit/editor.hpp @@ -476,7 +476,7 @@ private: void addRofiWorldNodeTreeToScene(const std::vector<node_ptr> &node_tree); void removeRofiWorldNodeTreeFromScene(const std::vector<node_ptr> &node_tree); - bool rebuildRofiWorldNodeTree(module_ptr module, rofiworld_ptr rofiworld); + bool rebuildRofiWorldNodeTree(module_ptr module, node_ptr root_node, rofiworld_ptr rofiworld); bool rebuildRofiWorldNodeTree(voxel_ptr voxel, node_ptr root_component_node, rofiworld_ptr rofiworld); /* COLLISION DETECTION */ diff --git a/src/edit/src/editor.cpp b/src/edit/src/editor.cpp index a1853a00f3e9cb8b1dfa4a90cb69567d602fb285..c3a84936f0b3a67e12d885e321f239ba057f4a3e 100644 --- a/src/edit/src/editor.cpp +++ b/src/edit/src/editor.cpp @@ -2365,7 +2365,7 @@ void Editor::manipulateModule() return; if (mouse.just_released().contains("MouseLeft")) - rebuildRofiWorldNodeTree(selected_module, rofiworld); + rebuildRofiWorldNodeTree(selected_module, selected_module->getNode(), rofiworld); if (is_removing_module) removeModule(selected_module); @@ -2431,7 +2431,8 @@ void Editor::connectModule() // Connect else if (checkConnectModuleValid(selected_connectors.first, selected_connectors.second)) { - rebuildRofiWorldNodeTree(rofiworld->getModuleWithNode(selected_connectors.first->getNode()), rofiworld); + auto source_node = selected_connectors.first->getNode(); + rebuildRofiWorldNodeTree(rofiworld->getModuleWithNode(source_node), source_node, rofiworld); voxel_graph->joinConnectors(selected_connectors.first, selected_connectors.second); @@ -2463,8 +2464,7 @@ bool Editor::checkConnectModuleValid(const connector_ptr fst_connector, const co auto snd_node = snd_connector->getNode(); if (fst_connector->isFull() - || snd_connector->isFull() - || !face_each_other(fst_node, snd_node, rofi::enum_to_vec(rofi::side::z_neg))) + || snd_connector->isFull()) return false; float epsilon = 0.0001f; @@ -2477,23 +2477,31 @@ bool Editor::checkConnectModuleValid(const connector_ptr fst_connector, const co void Editor::teleportModulesByConnectors(const connector_ptr source_connector, const connector_ptr destination_connector) { - auto first_con_node = source_connector->getNode(); - auto first_parent = first_con_node->getRootParent().lock(); - auto second_world_pos = destination_connector->getNode()->getPositionWorld(); - auto first_con_parent_diff = first_con_node->getPositionWorld() - first_parent->getPositionWorld(); - first_parent->setPosVec(second_world_pos - first_con_parent_diff); + const auto source_node = source_connector->getNode(); + const auto destination_node = destination_connector->getNode(); + const auto source_parent = source_node->getRootParent().lock(); - auto destination_facing = -destination_connector->getNode()->getRotationAxisZWorld(); - auto destination_north = destination_connector->getNode()->getRotationAxisXWorld(); - auto source_facing = -first_con_node->getRotationAxisZWorld(); - auto source_north = source_connector->getNode()->getRotationAxisXWorld(); + //Rotation - // rotate to face each other - // first_parent->rotateRotationQuat(glm::angleAxis) - - // rotate to selected cardinality - // auto north_delta = glm::orientedAngle(source_north, destination_north, ) - // first_parent->rotateRotationQuat(glm::angleAxis()) + // Rotate to equal plane + const auto &source_facing = source_node->getRotationAxisZWorld(); + const auto &destination_facing = destination_node->getRotationAxisZWorld(); + source_parent->rotateRotationQuat(glm::rotation(source_facing, -destination_facing)); + // Rotate North to North + const auto &source_north = source_connector->getNode()->getRotationAxisXWorld(); + const auto &destination_north = destination_node->getRotationAxisXWorld(); + const auto oriented_angle = glm::orientedAngle(source_north, destination_north, destination_facing); + + source_parent->rotateRotationQuat(glm::angleAxis(oriented_angle, destination_facing)); + // Rotate to selected cardinality + // Have to use -radians because carinality is from destination to source and this needs to rotate the source to the destination + source_parent->rotateRotationQuat(glm::angleAxis(-glm::radians(rofi::cardinal_to_degree(selected_cardinality)), destination_facing)); + + // Translation + + const auto &destination_world_pos = destination_node->getPositionWorld(); + const auto &source_world_pos = source_node->getPositionWorld(); + source_parent->translatePosVec(destination_world_pos - source_world_pos); } void Editor::rotateModule(module_ptr selected_module, glm::vec3 &rotation_angles) @@ -2607,11 +2615,11 @@ void Editor::removeRofiWorldNodeTreeFromScene(const std::vector<node_ptr> &node_ { return std::find(node_tree.begin(), node_tree.end(), node) != node_tree.end(); }); } -bool Editor::rebuildRofiWorldNodeTree(module_ptr module, rofiworld_ptr rofiworld) +bool Editor::rebuildRofiWorldNodeTree(module_ptr module, node_ptr root_node, rofiworld_ptr rofiworld) { removeRofiWorldNodeTreeFromScene(rofiworld->getNodeTree()); - rofiworld->rebuildNodeTree(module); + rofiworld->rebuildNodeTree(module, root_node); addRofiWorldNodeTreeToScene(rofiworld->getNodeTree()); diff --git a/src/gui/src/ui.cpp b/src/gui/src/ui.cpp index 95cc0861bb644d35bdb04645faff2ab71627bcee..fd507e7dc35163650d611c8c8b09236b6c155043 100644 --- a/src/gui/src/ui.cpp +++ b/src/gui/src/ui.cpp @@ -625,10 +625,10 @@ void module_rotation_ui(const osi::Window &window, edit::UIData &data) ImGui::DragFloat("Step", &data.module_rotation_step, 0.25f, 0.0f, 90.0f, "%.3f", ImGuiSliderFlags_AlwaysClamp); - glm::vec3 euler_angles; - euler_angles.x = glm::orientedAngle(glm::vec3(0.0f, 0.0f, 1.0f), data.selected_module->getNode()->getRotationAxisZLocal(), glm::vec3(1.0f, 0.0f, 0.0f)); - euler_angles.y = glm::orientedAngle(glm::vec3(1.0f, 0.0f, 0.0f), data.selected_module->getNode()->getRotationAxisXLocal(), glm::vec3(0.0f, 1.0f, 0.0f)); - euler_angles.z = glm::orientedAngle(glm::vec3(1.0f, 0.0f, 0.0f), data.selected_module->getNode()->getRotationAxisXLocal(), glm::vec3(0.0f, 0.0f, 1.0f)); + glm::vec3 euler_angles = glm::eulerAngles(data.selected_module->getNode()->getRotationWorld()); + // euler_angles.x = glm::orientedAngle(glm::vec3(0.0f, 0.0f, 1.0f), data.selected_module->getNode()->getRotationAxisZLocal(), glm::vec3(1.0f, 0.0f, 0.0f)); + // euler_angles.y = glm::orientedAngle(glm::vec3(1.0f, 0.0f, 0.0f), data.selected_module->getNode()->getRotationAxisXLocal(), glm::vec3(0.0f, 1.0f, 0.0f)); + // euler_angles.z = glm::orientedAngle(glm::vec3(1.0f, 0.0f, 0.0f), data.selected_module->getNode()->getRotationAxisXLocal(), glm::vec3(0.0f, 0.0f, 1.0f)); euler_angles = glm::degrees(euler_angles); glm::vec3 prev_euler_angles = euler_angles; diff --git a/src/rofi/include/rofi/connector.hpp b/src/rofi/include/rofi/connector.hpp index fa8bbf7e267aea1cc22d4d7da5ccad7952e9e6c2..9ee57d918729c40948896a6308c2d3f9e3032634 100644 --- a/src/rofi/include/rofi/connector.hpp +++ b/src/rofi/include/rofi/connector.hpp @@ -47,7 +47,7 @@ public: static connector_ptr copy(connector_ptr other_connector); static bool shares_module_link(connector_ptr fst_connector, connector_ptr snd_connector); - static cardinal get_mutual_orientation(connector_ptr fst_connector, connector_ptr snd_connector); + static cardinal get_mutual_orientation(connector_ptr source_connector, connector_ptr destination_connector); bool isFull() const { return !connection.first.expired() && !connection.second.expired(); } bool isEmpty() const { return connection.first.expired() && connection.second.expired(); } diff --git a/src/rofi/include/rofi/rofiworld.hpp b/src/rofi/include/rofi/rofiworld.hpp index ba1ac0a34f0875d0326bb91c2c35af165c582d13..613dffe0488abd4bea63675643487d983cd335e8 100644 --- a/src/rofi/include/rofi/rofiworld.hpp +++ b/src/rofi/include/rofi/rofiworld.hpp @@ -47,7 +47,7 @@ public: bool reachable(module_ptr fst_module, module_ptr snd_module) const; - bool rebuildNodeTree(module_ptr module); + bool rebuildNodeTree(module_ptr module, node_ptr root_node); bool rebuildNodeTree(voxel_ptr voxel, node_ptr root_node); bool detectCollision() const; diff --git a/src/rofi/src/connector.cpp b/src/rofi/src/connector.cpp index f90561cf232616841bc0c807fa42b16ff1895bc6..90199837c0f4b7d1bdfbfac1f0821288ae798604 100644 --- a/src/rofi/src/connector.cpp +++ b/src/rofi/src/connector.cpp @@ -75,15 +75,15 @@ bool Connector::shares_module_link(connector_ptr fst_connector, connector_ptr sn return false; } -cardinal Connector::get_mutual_orientation(connector_ptr fst_connector, connector_ptr snd_connector) +cardinal Connector::get_mutual_orientation(connector_ptr source_connector, connector_ptr destination_connector) { - ASSUMPTION(Connector::shares_module_link(fst_connector, snd_connector)); + ASSUMPTION(Connector::shares_module_link(source_connector, destination_connector)); - auto fst_north = fst_connector->getNode()->getRotationAxisXWorld(); - auto snd_north = snd_connector->getNode()->getRotationAxisXWorld(); - auto oriented_angle = glm::degrees(glm::orientedAngle(fst_north, - snd_north, - fst_connector->getNode()->getRotationAxisZWorld())); + auto source_north = source_connector->getNode()->getRotationAxisXWorld(); + auto destination_north = destination_connector->getNode()->getRotationAxisXWorld(); + auto oriented_angle = glm::degrees(glm::orientedAngle(destination_north, + source_north, + destination_connector->getNode()->getRotationAxisZWorld())); return degree_to_cardinal(oriented_angle); } @@ -387,14 +387,15 @@ cardinal degree_to_cardinal(float degree_angle) float epsilon = 0.001f; if (glm::epsilonEqual(degree_angle, 0.0f, epsilon)) return North; - if (glm::epsilonEqual(degree_angle, -90.0f, epsilon)) + if (glm::epsilonEqual(degree_angle, 90.0f, epsilon)) return East; if (glm::epsilonEqual(degree_angle, 180.0f, epsilon)) return South; - if (glm::epsilonEqual(degree_angle, 90.0f, epsilon)) + if (glm::epsilonEqual(degree_angle, -90.0f, epsilon)) return West; - ASSUMPTION(false); + ASSUMPTION(false); + return North; } float cardinal_to_degree(cardinal orientation) { @@ -404,11 +405,11 @@ float cardinal_to_degree(cardinal orientation) case North: return 0.0f; case East: - return -90.0f; + return 90.0f; case South: return 180.0f; case West: - return 90.0f; + return -90.0f; default: ASSUMPTION(false); return 0.0f; diff --git a/src/rofi/src/rofiworld.cpp b/src/rofi/src/rofiworld.cpp index 87c940487cce194b01686f2b12414ea5a0d21217..f9682c170728704a7ef0c9ee120d1d068df1987a 100644 --- a/src/rofi/src/rofiworld.cpp +++ b/src/rofi/src/rofiworld.cpp @@ -90,7 +90,7 @@ bool RofiWorld::reachable(module_ptr fst_module, module_ptr snd_module) const return found_modules.contains(snd_module); } -bool RofiWorld::rebuildNodeTree(module_ptr module) // NOTE: Maybe could use views if I knew how to. +bool RofiWorld::rebuildNodeTree(module_ptr module, node_ptr root_node) // NOTE: Maybe could use views if I knew how to. { std::set<module_ptr> found_modules; bool has_cycle = false; // Not being detected here @@ -104,7 +104,7 @@ bool RofiWorld::rebuildNodeTree(module_ptr module) // NOTE: Maybe could use view // found modules are set as children of selected module, their frame is automatically recalculated into selected module base std::vector<node_ptr> found_modules_nodes; std::ranges::transform(found_modules, std::back_inserter(found_modules_nodes), [](const auto m) { return m->getNode(); } ); - module->getNode()->extendChildren(found_modules_nodes, true); + root_node->extendChildren(found_modules_nodes, true); // Remaining modules are placed into the tree vector, including the selected module std::set<module_ptr> independent_modules; @@ -170,30 +170,16 @@ bool RofiWorld::detectCollision() const { for (const auto &voxel : module->getParts()->getVoxels()) { - for (const auto &object : voxel->getNode()->getObjects()) + + for (const auto &[module_node2, module2] : nodes_map) { - auto mesh = std::dynamic_pointer_cast<Mesh>(object); - if (!mesh) + if (module_node == module_node2) continue; - for (const auto &[module_node2, module2] : nodes_map) + for (const auto &voxel2 : module2->getParts()->getVoxels()) { - if (module_node == module_node2) - continue; - - for (const auto &voxel2 : module2->getParts()->getVoxels()) - { - for (const auto &object2 : voxel2->getNode()->getObjects()) - { - auto mesh2 = std::dynamic_pointer_cast<Mesh>(object2); - if (!mesh2) - continue; - - if (AABB_intersect(mesh->getAABB(), mesh2->getAABB(), voxel->getNode(), voxel2->getNode())) - return true; - - } - } + if (glm::distance(voxel->getNode()->getPositionWorld(), voxel2->getNode()->getPositionWorld()) < 0.86f) + return true; } } } diff --git a/src/utils/include/utils/math.hpp b/src/utils/include/utils/math.hpp index 9ff0162dfee2ca6e8739c9ff61fc98bf34571636..3666188427d4a54fc070de7a2e8409d13686fff2 100644 --- a/src/utils/include/utils/math.hpp +++ b/src/utils/include/utils/math.hpp @@ -18,4 +18,6 @@ #include "glm/gtc/epsilon.hpp" #include <glm/gtx/vector_angle.hpp> +#include <cmath> + #endif