From 42303d5f477a32da3e99101c5374013013219db1 Mon Sep 17 00:00:00 2001 From: Martin Felis Date: Sat, 1 Apr 2023 22:53:53 +0200 Subject: [PATCH] Store the input values of nodes if they are non-zero. --- src/AnimGraph/AnimGraphData.h | 23 ++++++++ src/AnimGraph/AnimGraphEditor.cc | 10 ++-- src/AnimGraph/AnimGraphResource.cc | 92 +++++++++++++++++++----------- 3 files changed, 87 insertions(+), 38 deletions(-) diff --git a/src/AnimGraph/AnimGraphData.h b/src/AnimGraph/AnimGraphData.h index 0c3cbf3..3a6b478 100644 --- a/src/AnimGraph/AnimGraphData.h +++ b/src/AnimGraph/AnimGraphData.h @@ -165,6 +165,29 @@ struct Socket { SocketReference m_reference = {0}; SocketFlags m_flags = SocketFlagNone; size_t m_type_size = 0; + + template + void SetValue(const T value) { + if constexpr (std::is_same::value) { + m_value.flag = value; + } + + if constexpr (std::is_same::value) { + m_value.float_value = value; + } + + if constexpr (std::is_same::value) { + m_value.vec3 = value; + } + + if constexpr (std::is_same::value) { + m_value.quat = value; + } + + if constexpr (std::is_same::value) { + m_value_string = value; + } + } }; template diff --git a/src/AnimGraph/AnimGraphEditor.cc b/src/AnimGraph/AnimGraphEditor.cc index 4d29f65..81b0f0f 100644 --- a/src/AnimGraph/AnimGraphEditor.cc +++ b/src/AnimGraph/AnimGraphEditor.cc @@ -344,10 +344,10 @@ void AnimGraphEditorUpdate() { ImNodes::EndNodeTitleBar(); // Inputs - const std::vector& node_inputs = + 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]; + Socket& socket = node_inputs[j]; ImColor socket_color = ImColor(255, 255, 255, 255); if (socket.m_flags & SocketFlagAffectsTime) { @@ -364,10 +364,12 @@ void AnimGraphEditorUpdate() { sGraphGresource.isSocketConnected(node_resource, socket.m_name); if (!socket_connected && (socket.m_type == SocketType::SocketTypeFloat)) { ImGui::SameLine(); - float socket_value = 0.f; + float socket_value = socket.m_value.float_value; ImGui::PushItemWidth( 130.0f - ImGui::CalcTextSize(socket.m_name.c_str()).x); - ImGui::DragFloat("##hidelabel", &socket_value, 0.01f); + if (ImGui::DragFloat("##hidelabel", &socket_value, 0.01f)) { + socket.SetValue(socket_value); + } ImGui::PopItemWidth(); } diff --git a/src/AnimGraph/AnimGraphResource.cc b/src/AnimGraph/AnimGraphResource.cc index 33aa117..ac59df2 100644 --- a/src/AnimGraph/AnimGraphResource.cc +++ b/src/AnimGraph/AnimGraphResource.cc @@ -5,6 +5,7 @@ #include "AnimGraphResource.h" #include +#include #include "3rdparty/json/json.hpp" @@ -27,7 +28,9 @@ json sSocketToJson(const Socket& socket) { result["name"] = socket.m_name; result["type"] = sSocketTypeToStr(socket.m_type); - if (socket.m_reference.ptr != nullptr) { + if (socket.m_type == SocketType::SocketTypeString && socket.m_value_string.size() > 0) { + result["value"] = socket.m_value_string; + } else if (socket.m_value.flag) { if (socket.m_type == SocketType::SocketTypeBool) { result["value"] = socket.m_value.flag; } else if (socket.m_type == SocketType::SocketTypeAnimation) { @@ -42,8 +45,6 @@ json sSocketToJson(const Socket& socket) { result["value"][1] = socket.m_value.quat.v[1]; result["value"][2] = socket.m_value.quat.v[2]; result["value"][3] = socket.m_value.quat.v[3]; - } else if (socket.m_type == SocketType::SocketTypeString) { - result["value"] = socket.m_value_string; } else { std::cerr << "Invalid socket type '" << static_cast(socket.m_type) << "'." << std::endl; @@ -59,25 +60,46 @@ Socket sJsonToSocket(const json& json_data) { result.m_name = json_data["name"]; std::string type_string = json_data["type"]; + bool have_value = json_data.contains("value"); if (type_string == "Bool") { result.m_type = SocketType::SocketTypeBool; result.m_type_size = sizeof(bool); + if (have_value) { + result.m_value.flag = json_data["value"]; + } } else if (type_string == "Animation") { result.m_type = SocketType::SocketTypeAnimation; result.m_type_size = sizeof(AnimData); } else if (type_string == "Float") { result.m_type = SocketType::SocketTypeFloat; result.m_type_size = sizeof(float); + if (have_value) { + result.m_value.float_value = json_data["value"]; + } } else if (type_string == "Vec3") { result.m_type = SocketType::SocketTypeVec3; result.m_type_size = sizeof(Vec3); + if (have_value) { + result.m_value.vec3.x = json_data["value"][0]; + result.m_value.vec3.y = json_data["value"][1]; + result.m_value.vec3.z = json_data["value"][2]; + } } else if (type_string == "Quat") { result.m_type = SocketType::SocketTypeQuat; result.m_type_size = sizeof(Quat); + if (have_value) { + result.m_value.quat.x = json_data["value"][0]; + result.m_value.quat.y = json_data["value"][1]; + result.m_value.quat.z = json_data["value"][2]; + result.m_value.quat.w = json_data["value"][3]; + } } else if (type_string == "String") { result.m_type = SocketType::SocketTypeString; result.m_type_size = sizeof(std::string); + if (have_value) { + result.m_value_string = json_data["value"]; + } } else { std::cerr << "Invalid socket type '" << type_string << "'." << std::endl; } @@ -88,7 +110,10 @@ Socket sJsonToSocket(const json& json_data) { // // AnimGraphNode <-> json // -json sAnimGraphNodeToJson(const AnimNodeResource& node) { +json sAnimGraphNodeToJson( + const AnimNodeResource& node, + int node_index, + const std::vector& connections) { json result; result["name"] = node.m_name; @@ -99,6 +124,27 @@ json sAnimGraphNodeToJson(const AnimNodeResource& node) { result["position"][j] = node.m_position[j]; } + for (size_t j = 0, n = node.m_socket_accessor->m_inputs.size(); j < n; j++) { + const Socket& socket = node.m_socket_accessor->m_inputs[j]; + + if (socket.m_type == SocketType::SocketTypeAnimation) { + continue; + } + + bool socket_connected = false; + for (size_t k = 0, m = connections.size(); k < m; k++) { + if (connections[k].source_node_index == node_index + && connections[k].source_socket_name == socket.m_name) { + socket_connected = true; + break; + } + } + + if (!socket_connected) { + result["inputs"][socket.m_name] = sSocketToJson(socket); + } + } + for (size_t j = 0, n = node.m_socket_accessor->m_properties.size(); j < n; j++) { Socket& property = node.m_socket_accessor->m_properties[j]; @@ -123,36 +169,14 @@ AnimNodeResource sAnimGraphNodeFromJson(const json& json_node) { for (size_t j = 0, n = result.m_socket_accessor->m_properties.size(); j < n; j++) { Socket& property = result.m_socket_accessor->m_properties[j]; - json json_property = json_node["properties"][property.m_name]; + property = sJsonToSocket(json_node["properties"][property.m_name]); + } - if (sSocketTypeToStr(property.m_type) == json_property["type"]) { - if (property.m_type == SocketType::SocketTypeBool) { - property.m_value.flag = json_property["value"]; - } else if (property.m_type == SocketType::SocketTypeAnimation) { - } else if (property.m_type == SocketType::SocketTypeFloat) { - property.m_value.float_value = json_property["value"]; - } else if (property.m_type == SocketType::SocketTypeVec3) { - property.m_value.vec3.v[0] = json_property["value"][0]; - property.m_value.vec3.v[1] = json_property["value"][1]; - property.m_value.vec3.v[2] = json_property["value"][2]; - } else if (property.m_type == SocketType::SocketTypeQuat) { - Quat* property_quat = reinterpret_cast(property.m_reference.ptr); - property.m_value.quat.v[0] = json_property["value"][0]; - property.m_value.quat.v[1] = json_property["value"][1]; - property.m_value.quat.v[2] = json_property["value"][2]; - property.m_value.quat.v[3] = json_property["value"][3]; - } else if (property.m_type == SocketType::SocketTypeString) { - property.m_value_string = json_property["value"].get(); - } else { - std::cerr << "Invalid type for property '" << property.m_name - << "'. Cannot parse json to type '" - << static_cast(property.m_type) << std::endl; - break; - } - } else { - std::cerr << "Invalid type for property '" << property.m_name - << "': expected " << sSocketTypeToStr(property.m_type) - << " but got " << json_property["type"] << std::endl; + for (size_t j = 0, n = result.m_socket_accessor->m_inputs.size(); j < n; + j++) { + Socket& input = result.m_socket_accessor->m_inputs[j]; + if (json_node.contains("inputs") && json_node["inputs"].contains(input.m_name)) { + input = sJsonToSocket(json_node["inputs"][input.m_name]); } } @@ -226,7 +250,7 @@ bool AnimGraphResource::saveToFile(const char* filename) const { for (size_t i = 0; i < m_nodes.size(); i++) { const AnimNodeResource& node = m_nodes[i]; - result["nodes"][i] = sAnimGraphNodeToJson(node); + result["nodes"][i] = sAnimGraphNodeToJson(node, i, m_connections); } for (size_t i = 0; i < m_connections.size(); i++) {