diff --git a/engine/asset/include/asset_types.hpp b/engine/asset/include/asset_types.hpp index 258b430..c031491 100644 --- a/engine/asset/include/asset_types.hpp +++ b/engine/asset/include/asset_types.hpp @@ -6,6 +6,7 @@ #include "math.hpp" #include "material_nodes.hpp" #include "aabb.hpp" +#include "utility.hpp" class GFXBuffer; class GFXTexture; @@ -22,6 +23,24 @@ class Material : public Asset { public: std::vector> nodes; + void delete_node(MaterialNode* node) { + // disconnect all inputs from their node outputs + for(auto& input : node->inputs) { + if(input.is_connected()) + input.disconnect(); + } + + // disconnect all our outputs from other node's inputs + for(auto& output : node->outputs) { + if(output.is_connected()) + output.connected_connector->disconnect(); + } + + utility::erase_if(nodes, [node](std::unique_ptr& other_node) { + return node == other_node.get(); + }); + } + GFXPipeline* static_pipeline = nullptr; GFXPipeline* skinned_pipeline = nullptr; GFXPipeline* capture_pipeline = nullptr; diff --git a/engine/asset/include/material_nodes.hpp b/engine/asset/include/material_nodes.hpp index 57a8f08..1157c4d 100644 --- a/engine/asset/include/material_nodes.hpp +++ b/engine/asset/include/material_nodes.hpp @@ -15,6 +15,16 @@ struct MaterialConnector { MaterialConnector(std::string n, DataType t) : name(n), type(t) {} MaterialConnector(std::string n, DataType t, bool isn) : name(n), type(t), is_normal_map(isn) {} + bool is_connected() const { + return connected_connector != nullptr && connected_node != nullptr && connected_index != -1; + } + + void disconnect() { + connected_connector = nullptr; + connected_node = nullptr; + connected_index = -1; + } + std::string name; DataType type; diff --git a/tools/editor/src/materialeditor.cpp b/tools/editor/src/materialeditor.cpp index 8ef5eff..d057b54 100755 --- a/tools/editor/src/materialeditor.cpp +++ b/tools/editor/src/materialeditor.cpp @@ -146,6 +146,8 @@ void MaterialEditor::draw(CommonEditor* editor) { static MaterialConnector* drag_connector = nullptr; static int drag_index = 0; + std::vector deferred_deletions; + for(auto& node : material->nodes) { const auto rect = get_window_rect(*node); @@ -231,6 +233,13 @@ void MaterialEditor::draw(CommonEditor* editor) { dragging_connector = false; } + if(ImGui::BeginPopupContextItem()) { + if(ImGui::Selectable("Delete")) + deferred_deletions.push_back(node.get()); + + ImGui::EndPopup(); + } + if(dragging_connector && node.get() == dragging_node) { const auto output_rect = get_output_rect(*node, drag_index); draw_list->AddLine(output_rect.GetCenter(), ImGui::GetIO().MousePos, IM_COL32(255, 255, 255, 255)); @@ -253,6 +262,11 @@ void MaterialEditor::draw(CommonEditor* editor) { } } + for(auto& node : deferred_deletions) { + material->delete_node(node); + changed = true; + } + if(changed) recompile(*material);