Basic node properties editor.

AnimGraphEditor
Martin Felis 2022-02-18 22:24:19 +01:00
parent 0d0b181ebb
commit ee6a8eb29a
3 changed files with 94 additions and 10 deletions

View File

@ -26,6 +26,52 @@ ImNodesPinShape sGetSocketShapeFromSocketType(const SocketType& socket_type) {
return ImNodesPinShape_Quad;
}
void AnimGraphEditorRenderSidebar(AnimNodeResource& node_resource) {
ImGui::Text("[%s]", node_resource.m_type_name.c_str());
char node_name_buffer[256];
memset(node_name_buffer, 0, sizeof(node_name_buffer));
strncpy(
node_name_buffer,
node_resource.m_name.c_str(),
std::min(node_resource.m_name.size(), sizeof(node_name_buffer)));
if (ImGui::InputText("Name", node_name_buffer, sizeof(node_name_buffer))) {
node_resource.m_name = node_name_buffer;
}
int num_properties = node_resource.m_socket_accessor->m_properties.size();
for (int i = 0; i < num_properties; i++) {
Socket& property = node_resource.m_socket_accessor->m_properties[i];
if (property.m_type == SocketType::SocketTypeFloat) {
ImGui::SliderFloat(
property.m_name.c_str(),
reinterpret_cast<float*>(property.m_value.ptr),
-100.f,
100.f);
} else if (property.m_type == SocketType::SocketTypeBool) {
ImGui::Checkbox(
property.m_name.c_str(),
reinterpret_cast<bool*>(property.m_value.ptr));
} else if (property.m_type == SocketType::SocketTypeString) {
std::string* property_string =
reinterpret_cast<std::string*>(property.m_value.ptr);
char string_buf[256];
memset(string_buf, 0, sizeof(string_buf));
strncpy(
string_buf,
property_string->c_str(),
std::min(property_string->size(), sizeof(string_buf)));
if (ImGui::InputText(
property.m_name.c_str(),
string_buf,
sizeof(string_buf))) {
(*property_string) = string_buf;
}
}
}
}
void AnimGraphEditorUpdate() {
static AnimGraphResource graph_resource = AnimGraphResource();
@ -58,6 +104,11 @@ void AnimGraphEditorUpdate() {
ImGui::EndMenuBar();
ImGui::Columns(2);
//
// Node editor canvas
//
ImNodes::BeginNodeEditor();
// Popup menu
@ -128,7 +179,8 @@ void AnimGraphEditorUpdate() {
ImColor(255, 255, 255, 255));
ImGui::Text(socket.m_name.c_str());
ImNodes::PushAttributeFlag(ImNodesAttributeFlags_EnableLinkDetachWithDragClick);
ImNodes::PushAttributeFlag(
ImNodesAttributeFlags_EnableLinkDetachWithDragClick);
ImNodes::EndInputAttribute();
}
@ -142,19 +194,21 @@ void AnimGraphEditorUpdate() {
sGetSocketShapeFromSocketType(socket.m_type),
ImColor(255, 255, 255, 255));
ImGui::Text(socket.m_name.c_str());
ImNodes::PushAttributeFlag(ImNodesAttributeFlags_EnableLinkDetachWithDragClick);
ImNodes::PushAttributeFlag(
ImNodesAttributeFlags_EnableLinkDetachWithDragClick);
ImNodes::EndInputAttribute();
}
// Graph output node
if (i == 0) {
if (ImGui::Button("+Output")) {
AnimNodeResource& graph_output_node = graph_resource.getGraphOutputNode();
AnimNodeResource& graph_output_node =
graph_resource.getGraphOutputNode();
static float bla = 0.f;
std::string socket_name = "Output";
socket_name +=
std::to_string(graph_output_node.m_socket_accessor->m_inputs.size());
socket_name += std::to_string(
graph_output_node.m_socket_accessor->m_inputs.size());
graph_output_node.m_socket_accessor->RegisterInput<float>(
socket_name,
nullptr);
@ -165,8 +219,8 @@ void AnimGraphEditorUpdate() {
static float bla = 0.f;
std::string socket_name = "Input";
socket_name +=
std::to_string(graph_input_node.m_socket_accessor->m_outputs.size());
socket_name += std::to_string(
graph_input_node.m_socket_accessor->m_outputs.size());
graph_input_node.m_socket_accessor->RegisterOutput<float>(
socket_name,
nullptr);
@ -220,6 +274,25 @@ void AnimGraphEditorUpdate() {
// Handle link detachements.
int link_id = 0;
if (ImNodes::IsLinkDestroyed(&link_id)) {
graph_resource.m_connections.erase(graph_resource.m_connections.begin() + link_id);
graph_resource.m_connections.erase(
graph_resource.m_connections.begin() + link_id);
}
int selected_nodes[ImNodes::NumSelectedNodes()];
ImNodes::GetSelectedNodes(selected_nodes);
//
// Sidebar
//
ImGui::NextColumn();
if (ImNodes::NumSelectedNodes() == 1) {
if (selected_nodes[0] < graph_resource.m_nodes.size()) {
AnimNodeResource& selected_node =
graph_resource.m_nodes[selected_nodes[0]];
AnimGraphEditorRenderSidebar(selected_node);
}
}
ImGui::Columns(1);
}

View File

@ -144,6 +144,14 @@ AnimGraphConnection sAnimGraphConnectionFromJson(const json& json_node) {
void AnimGraphResource::clear() {
m_name = "";
clearNodes();
m_connections.clear();
initGraphConnectors();
}
void AnimGraphResource::clearNodes() {
for (size_t i = 0; i < m_nodes.size(); i++) {
delete m_nodes[i].m_socket_accessor;
m_nodes[i].m_socket_accessor = nullptr;
@ -151,13 +159,13 @@ void AnimGraphResource::clear() {
m_nodes[i].m_anim_node = nullptr;
}
m_nodes.clear();
}
void AnimGraphResource::initGraphConnectors() {
m_nodes.push_back(AnimNodeResourceFactory("BlendTree"));
m_nodes[0].m_name = "Outputs";
m_nodes.push_back(AnimNodeResourceFactory("BlendTree"));
m_nodes[1].m_name = "Inputs";
m_connections.clear();
}
bool AnimGraphResource::saveToFile(const char* filename) const {
@ -220,6 +228,7 @@ bool AnimGraphResource::loadFromFile(const char* filename) {
}
clear();
clearNodes();
m_name = json_data["name"];
for (size_t i = 0; i < json_data["nodes"].size(); i++) {

View File

@ -337,6 +337,8 @@ struct AnimGraphResource {
AnimGraphResource() { clear(); }
void clear();
void clearNodes();
void initGraphConnectors();
bool saveToFile(const char* filename) const;
bool loadFromFile(const char* filename);