AnimTestbed/src/AnimGraphEditor.cc

164 lines
5.0 KiB
C++
Raw Normal View History

//
// Created by martin on 11.02.22.
//
#include "AnimGraphEditor.h"
#include "AnimGraphResource.h"
#include "imnodes.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 = 1, 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();
// Popup menu
{
const bool open_popup =
ImGui::IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows)
&& ImNodes::IsEditorHovered()
&& ImGui::IsMouseReleased(ImGuiMouseButton_Right);
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(8.f, 8.f));
if (!ImGui::IsAnyItemHovered() && open_popup) {
ImGui::OpenPopup("add node");
}
if (ImGui::BeginPopup("add node")) {
const ImVec2 click_pos = ImGui::GetMousePosOnOpeningCurrentPopup();
std::string node_type_name = "";
if (ImGui::MenuItem("AnimSampler")) {
node_type_name = "AnimSampler";
}
if (ImGui::MenuItem("Blend2")) {
node_type_name = "Blend2";
}
if (ImGui::MenuItem("SpeedScale")) {
node_type_name = "SpeedScale";
}
if (node_type_name != "") {
AnimNodeResource node_resource =
AnimNodeResourceFactory(node_type_name);
size_t node_id = gGraphResource.m_nodes.size();
ImNodes::SetNodeScreenSpacePos(node_id, ImGui::GetMousePos());
gGraphResource.m_nodes.push_back(node_resource);
}
ImGui::EndPopup();
}
ImGui::PopStyleVar(ImGuiStyleVar_WindowPadding);
}
for (size_t i = 1, 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<Socket>& 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<Socket>& 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);
}
}