diff --git a/src/edit/include/edit/editor.hpp b/src/edit/include/edit/editor.hpp index 63725cea286494a504c95a26c5022cd434d36a02..5a91cf6e823f388711ec5915d4e470438ccbce3a 100644 --- a/src/edit/include/edit/editor.hpp +++ b/src/edit/include/edit/editor.hpp @@ -77,6 +77,9 @@ public: bool &connector_selected; bool &primary_axis; + bool &is_connecting_modules; + rofi::cardinal &selected_cardinality; + std::pair<connector_ptr, connector_ptr> &selected_connectors; bool &is_moving_module; glm::vec3 &module_position; bool &is_rotating_module; @@ -87,9 +90,12 @@ public: std::string &error_msg; double &error_start_second; - UIData(phase &_editor_phase, mode_I &_editor_mode_I, mode_II &_editor_mode_II, build_mode_I &_editor_build_mode_I, build_mode_II &_editor_build_mode_II, state &_control_state, bool &_ui_visible, - rofi::component &_chosen_component, rofi::connector_type &_chosen_con_type, std::vector<rofi::component> &_allowed_components, std::vector<module_ptr> &_modules, module_ptr &_selected_module, - bool &_connector_selected, bool &_voxel_selected, bool &_is_moving_module, glm::vec3 &_module_position, bool &_is_rotating_module, glm::vec3 &_module_rotation_angles, bool &_is_rotating_component, float &_component_rotation_angle, + UIData(phase &_editor_phase, mode_I &_editor_mode_I, mode_II &_editor_mode_II, build_mode_I &_editor_build_mode_I, build_mode_II &_editor_build_mode_II, + state &_control_state, bool &_ui_visible, rofi::component &_chosen_component, rofi::connector_type &_chosen_con_type, + std::vector<rofi::component> &_allowed_components, std::vector<module_ptr> &_modules, module_ptr &_selected_module, bool &_is_connecting_modules, + rofi::cardinal &_selected_cardinality, std::pair<connector_ptr, connector_ptr> &_selected_connectors, bool &_connector_selected, bool &_voxel_selected, + bool &_is_moving_module, glm::vec3 &_module_position, bool &_is_rotating_module, glm::vec3 &_module_rotation_angles, + bool &_is_rotating_component, float &_component_rotation_angle, std::string &_error_msg, double &_error_start_second, bool &_primary_axis) : editor_phase{_editor_phase}, @@ -104,6 +110,9 @@ public: allowed_components{_allowed_components}, modules{_modules}, selected_module{_selected_module}, + is_connecting_modules{_is_connecting_modules}, + selected_cardinality{_selected_cardinality}, + selected_connectors{_selected_connectors}, connector_selected{_connector_selected}, voxel_selected{_voxel_selected}, is_moving_module{_is_moving_module}, @@ -158,7 +167,7 @@ class Editor char module_type_buffer[256] = {0}; UIData ui = UIData{editor_phase, editor_mode_I, editor_mode_II, editor_build_mode_I, editor_build_mode_II, control_state, ui_visible, - chosen_component, chosen_con_type, allowed_components, modules, selected_module, + chosen_component, chosen_con_type, allowed_components, modules, selected_module, is_connecting_modules, selected_cardinality, selected_connectors, connector_selected, voxel_selected, is_moving_module, module_position, is_rotating_module, module_rotation_angles, is_rotating_component, component_rotation_angle, error_msg, error_start_second, primary_axis}; @@ -191,6 +200,7 @@ class Editor bool rofi_invalid_state = false; + rofi::cardinal selected_cardinality = rofi::cardinal::North; std::pair<connector_ptr, connector_ptr> selected_connectors = {nullptr, nullptr}; std::pair<glm::vec3, node_ptr> first_connector_highlights = {glm::vec3(0.0f), nullptr}; std::pair<glm::vec3, node_ptr> second_connector_highlights = {glm::vec3(0.0f), nullptr}; diff --git a/src/edit/src/editor.cpp b/src/edit/src/editor.cpp index 4950d4e0465f8b197521b2fd3ace4fe3353da7a6..f078a199fef1a92e7e3c3e9c1a354835c06c8762 100644 --- a/src/edit/src/editor.cpp +++ b/src/edit/src/editor.cpp @@ -1077,12 +1077,14 @@ void Editor::setModuleNodeHierarchy(voxel_graph_ptr vg, std::string type) auto rot_con = std::dynamic_pointer_cast<rofi::RotationConnector>(voxel->getRotationConnector().lock()); auto [fst, snd] = rot_con->getBoundConnectors(); - std::vector<node_ptr> connector_nodes = { rot_con->getNode(), fst.lock()->getNode(), snd.lock()->getNode() }; + auto rot_con_node = rot_con->getNode(); + std::vector<node_ptr> connector_nodes = { rot_con_node, fst.lock()->getNode(), snd.lock()->getNode() }; + std::vector<node_ptr> parent_nodes = { voxel_node, rot_con_node, rot_con_node }; - for (auto &connector_node : connector_nodes) + for (int i = 0; i < 3; ++i) { - if (!connector_node->getParent().expired()) - connector_node->getParent().lock()->transferChild(connector_node, voxel_node, true); + if (!connector_nodes[i]->getParent().expired()) + connector_nodes[i]->getParent().lock()->transferChild(connector_nodes[i], parent_nodes[i], true); } } } @@ -2147,7 +2149,19 @@ void Editor::controlAddModule() void Editor::controlConnectModule() { - is_connecting_modules = keyboard.down().contains("M"); + if (keyboard.just_pressed().contains("Escape")) + { + selected_connectors = {nullptr, nullptr}; + first_connector_highlights = {glm::vec3(0.0f), nullptr}; + second_connector_highlights = {glm::vec3(0.0f), nullptr}; + scene->manageSelection(nullptr); + scene->manageHighlight(glm::vec3(0.0f), nullptr); + scene->manageSecondarySelection({first_connector_highlights.second, second_connector_highlights.second}); + scene->manageSecondaryHighlights({first_connector_highlights}); + return; + } + + is_connecting_modules = keyboard.down().contains("M") || is_connecting_modules; } void Editor::controlManipulateModule() @@ -2468,13 +2482,17 @@ void Editor::teleportModulesByConnectors(const connector_ptr source_connector, c 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); + + // auto destination_facing = -destination_connector->getNode()->getRotationAxisZWorld(); + // auto source_facing = -first_con_node->getRotationAxisZWorld(); + } void Editor::rotateModule(module_ptr selected_module, glm::vec3 &rotation_angles) { if (rotation_angles.x != 0.0f) { - auto x_rotation = glm::angleAxis(glm::radians(rotation_angles.x), selected_module->getNode()->getRotationAxisXLocal()); + auto x_rotation = glm::angleAxis(glm::radians(rotation_angles.x), selected_module->getNode()->getRotationAxisXLocal()); selected_module->getNode()->rotateRotationQuat(x_rotation); } if (rotation_angles.y != 0.0f) diff --git a/src/gui/include/gui/ui.hpp b/src/gui/include/gui/ui.hpp index b473817804ebd2ffdd8b357a736a6513fd2ab01a..80a66c633878c2f2c1ce3899c310770b270dd65b 100644 --- a/src/gui/include/gui/ui.hpp +++ b/src/gui/include/gui/ui.hpp @@ -43,6 +43,7 @@ void build_toolbar_ui(const osi::Window &window, edit::UIData &data); void build_toolbar_buttons(edit::UIData &data); void set_build_toolbar_button_colors(edit::UIData &data); void module_selection_ui(const osi::Window &window, edit::UIData &data); +void module_connection_ui(const osi::Window &window, edit::UIData &data); void module_movement_ui(const osi::Window &window, edit::UIData &data); void module_rotation_ui(const osi::Window &window, edit::UIData &data); void component_rotation_ui(const osi::Window &window, edit::UIData &data); diff --git a/src/gui/src/ui.cpp b/src/gui/src/ui.cpp index f0d9e6847d354b1b100be2a602572753ba41d312..95cc0861bb644d35bdb04645faff2ab71627bcee 100644 --- a/src/gui/src/ui.cpp +++ b/src/gui/src/ui.cpp @@ -242,6 +242,7 @@ void mode_II_build_ui(const osi::Window &window, edit::UIData &data) { mode_II_build_selection_ui(window, data); module_selection_ui(window, data); + module_connection_ui(window, data); module_movement_ui(window, data); module_rotation_ui(window, data); component_rotation_ui(window, data); @@ -511,6 +512,73 @@ void module_selection_ui(const osi::Window &window, edit::UIData &data) ImGui::End(); } +void module_connection_ui(const osi::Window &window, edit::UIData &data) +{ + using namespace rofi; + if (data.editor_build_mode_II != edit::build_mode_II::connect_module + || data.selected_connectors.first == nullptr + || data.selected_connectors.second == nullptr) + { + data.is_connecting_modules = false; + return; + } + + auto fst_connector = data.selected_connectors.first; + auto snd_connector = data.selected_connectors.second; + + float size_x = static_cast<float>(window.size().x); + float size_y = static_cast<float>(window.size().y); + ImGui::SetNextWindowPos(ImVec2(size_x, size_y - 40.0f), ImGuiCond_Always, ImVec2(1.0f, 1.0f)); + + ImGui::Begin("Connect##ModuleConnectionMenu", NULL, ImGuiWindowFlags_NoMove + | ImGuiWindowFlags_NoResize + | ImGuiWindowFlags_NoCollapse + | ImGuiWindowFlags_AlwaysAutoResize); + + using enum cardinal; + + if (Connector::shares_module_link(fst_connector, snd_connector)) + { + ImGui::Text("Mutual Orientation:"); + std::string orientation; + switch(Connector::get_mutual_orientation(fst_connector, snd_connector)) + { + case North: + orientation = "North"; + break; + case East: + orientation = "East"; + break; + case South: + orientation = "South"; + break; + case West: + orientation = "West"; + break; + } + ImGui::Text(orientation.c_str()); + ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.7f, 0.0f, 0.0f, 1.0f)); + data.is_connecting_modules = ImGui::Button("Disconnect"); + ImGui::PopStyleColor(); + } + else + { + int selection = static_cast<int>(data.selected_cardinality); + ImGui::RadioButton("North", &selection, 0); + ImGui::RadioButton("East", &selection, 1); + ImGui::RadioButton("South", &selection, 2); + ImGui::RadioButton("West", &selection, 3); + data.selected_cardinality = selection == 0 ? North : selection == 1 ? East : selection == 2 ? South : West; + + ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.0f, 0.0f, 0.7f, 1.0f)); + data.is_connecting_modules = ImGui::Button("Connect"); + ImGui::PopStyleColor(); + } + + + ImGui::End(); +} + void module_movement_ui(const osi::Window &window, edit::UIData &data) { if (data.editor_build_mode_II != edit::build_mode_II::manipulate_module || !data.selected_module) diff --git a/src/rofi/include/rofi/connector.hpp b/src/rofi/include/rofi/connector.hpp index 0b1c171d1b93afc03fdc7e18773c89d15b3de1e2..13cc8315a323d3022f0a6fdae475a41b1bdee601 100644 --- a/src/rofi/include/rofi/connector.hpp +++ b/src/rofi/include/rofi/connector.hpp @@ -19,6 +19,7 @@ using connector_weak_ptr = std::weak_ptr<rofi::Connector>; enum class side { x_pos, x_neg, y_pos, y_neg, z_pos, z_neg, undefined }; enum class connector_type {fixed, open, rotation, shared_rotation, empty}; + enum cardinal { North, East, South, West }; class Connector : public ObjectBase { @@ -46,6 +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); 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 03ad704b6040d7a40491dd87a34d14a63e783b63..ba1ac0a34f0875d0326bb91c2c35af165c582d13 100644 --- a/src/rofi/include/rofi/rofiworld.hpp +++ b/src/rofi/include/rofi/rofiworld.hpp @@ -13,6 +13,8 @@ namespace rofi { +enum class slot { ApX, AnX, AnZ, BpX, BnX, BnZ }; + class RofiWorld { std::string name; diff --git a/src/rofi/src/connector.cpp b/src/rofi/src/connector.cpp index 2b02920d3c431b05ca0b13062e02e6bea8483ec5..bf78a040a6f8970611b7d3766201708a15df8bc0 100644 --- a/src/rofi/src/connector.cpp +++ b/src/rofi/src/connector.cpp @@ -2,6 +2,8 @@ #include <rofi/voxel.hpp> +#include <iostream> + namespace rofi { @@ -75,6 +77,29 @@ 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) +{ + 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())); + + std::cout << "oriented angle: " << oriented_angle << std::endl; + + float epsilon = 0.001f; + if (glm::epsilonEqual(oriented_angle, 0.0f, epsilon)) + return North; + if (glm::epsilonEqual(oriented_angle, -90.0f, epsilon)) + return East; + if (glm::epsilonEqual(oriented_angle, 180.0f, epsilon)) + return South; + if (glm::epsilonEqual(oriented_angle, 90.0f, epsilon)) + return West; + + ASSUMPTION(false); +} + bool Connector::hasModuleLink() const { return (!connection.first.expired() && std::dynamic_pointer_cast<ModuleLink>(connection.first.lock())) diff --git a/src/studio/src/simulator.cpp b/src/studio/src/simulator.cpp index cb3ca9a43c0fba6cd2e70398aca25e74e9baeb24..b458edc78f80f95b2cfeb871452840ae4934bf51 100644 --- a/src/studio/src/simulator.cpp +++ b/src/studio/src/simulator.cpp @@ -38,8 +38,7 @@ void Simulator::update() void Simulator::present() { - /* Present the state to the user (i.e., render objects) - * For now, we just clear screen buffers and show some gui widget. */ + /* Present the state to the user (i.e., render objects) */ show_ui(window(), editor->getUIData()); show_edit_error_msg(window(), editor->getUIData(), timer().passed_seconds());