// // Created by martin on 11.02.22. // #include "AnimGraphEditor.h" #include "imnodes.h" #include "AnimGraphResource.h" static AnimGraphResource gGraphResource; constexpr int NodeInputAttributeFlag = 2 << 16; constexpr int NodeOutputAttributeFlag = 2 << 17; void AnimGraphEditorUpdate() { ImGui::BeginMenuBar(); if (ImGui::Button("Save")) { gGraphResource.saveToFile("editor_graph.json"); } if (ImGui::Button("Load")) { gGraphResource.loadFromFile("editor_graph.json"); for (size_t i = 0, n = gGraphResource.m_nodes.size(); i < n; i++) { const AnimNodeResource& node_resource = gGraphResource.m_nodes[i]; ImNodes::SetNodeGridSpacePos(i, ImVec2(node_resource.m_position[0], node_resource.m_position[1])); } } if (ImGui::Button("Clear")) { gGraphResource.clear(); } char graph_name_buffer[256]; memset (graph_name_buffer, 0, sizeof(graph_name_buffer)); strncpy (graph_name_buffer, gGraphResource.m_name.c_str(), sizeof(graph_name_buffer)); if (ImGui::InputText("Name", graph_name_buffer, sizeof(graph_name_buffer))) { gGraphResource.m_name = graph_name_buffer; } ImGui::EndMenuBar(); ImNodes::BeginNodeEditor(); if (ImGui::IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows) && ImNodes::IsEditorHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Right)) { AnimNodeResource node_resource = AnimNodeResourceFactory("Blend2"); size_t node_id = gGraphResource.m_nodes.size(); ImNodes::SetNodeScreenSpacePos(node_id, ImGui::GetMousePos()); gGraphResource.m_nodes.push_back(node_resource); } for (size_t i = 0, n = gGraphResource.m_nodes.size(); i < n; i++) { AnimNodeResource& node_resource = gGraphResource.m_nodes[i]; ImNodes::BeginNode(i); // Header ImNodes::BeginNodeTitleBar(); ImGui::TextUnformatted(node_resource.m_type_name.c_str()); ImNodes::EndNodeTitleBar(); // Inputs const std::vector& node_inputs =node_resource.m_socket_accessor->m_inputs; for (size_t j = 0, ni = node_inputs.size(); j < ni; j++) { const Socket& socket = node_inputs[j]; ImNodes::BeginInputAttribute(GenerateInputAttributeId(i, j)); ImGui::Text(socket.m_name.c_str()); ImNodes::EndInputAttribute(); } // Outputs const std::vector& node_outputs =node_resource.m_socket_accessor->m_outputs; for (size_t j = 0, ni = node_outputs.size(); j < ni; j++) { const Socket& socket = node_outputs[j]; ImNodes::BeginOutputAttribute(GenerateOutputAttributeId(i, j)); ImGui::Text(socket.m_name.c_str()); ImNodes::EndInputAttribute(); } // Save state in node resource ImVec2 node_pos = ImNodes::GetNodeGridSpacePos(i); node_resource.m_position[0] = node_pos[0]; node_resource.m_position[1] = node_pos[1]; ImNodes::EndNode(); } for (size_t i = 0, n = gGraphResource.m_connections.size(); i < n; i++) { const AnimGraphConnection& connection = gGraphResource.m_connections[i]; int start_attr, end_attr; start_attr = GenerateOutputAttributeId(connection.m_source_node_index, connection.m_source_socket_index); end_attr = GenerateInputAttributeId(connection.m_target_node_index, connection.m_target_socket_index); ImNodes::Link(i, start_attr, end_attr); } ImNodes::EndNodeEditor(); int start_attr, end_attr; if (ImNodes::IsLinkCreated(&start_attr, &end_attr)) { int node_start_id; int node_start_output_index; SplitOutputAttributeId(start_attr, &node_start_id, &node_start_output_index); int node_end_id; int node_end_input_index; SplitInputAttributeId(end_attr, &node_end_id, &node_end_input_index); std::cout << "Link created: " << node_start_id << ", " << node_start_output_index << " -> " << node_end_id << ", " << node_end_input_index << std::endl; AnimGraphConnection connection; connection.m_source_node_index = node_start_id; connection.m_source_socket_index = node_start_output_index; connection.m_target_node_index = node_end_id; connection.m_target_socket_index = node_end_input_index; gGraphResource.m_connections.push_back(connection); } }