From 698abbce4b47575b727add03fee06b9fbe7b0118 Mon Sep 17 00:00:00 2001 From: Martin Felis Date: Wed, 1 May 2024 21:49:34 +0200 Subject: [PATCH] BlendTree input and output sockets can now be registered via the AnimGraphResource. --- src/AnimGraph/AnimGraphData.h | 4 +- src/AnimGraph/AnimGraphResource.h | 67 +++++++++++++++++++++++++++++++ tests/AnimGraphResourceTests.cc | 40 +++++++++++------- 3 files changed, 94 insertions(+), 17 deletions(-) diff --git a/src/AnimGraph/AnimGraphData.h b/src/AnimGraph/AnimGraphData.h index 9486545..323a091 100644 --- a/src/AnimGraph/AnimGraphData.h +++ b/src/AnimGraph/AnimGraphData.h @@ -161,7 +161,7 @@ struct Socket { SocketValue m_value = {0}; std::string m_value_string; union SocketReference { - void* ptr; + void* ptr = nullptr; void** ptr_ptr; }; SocketReference m_reference = {0}; @@ -418,7 +418,7 @@ struct NodeDescriptorBase { return socket->GetValue(); } - virtual void UpdateFlags(){}; + virtual void UpdateFlags() {}; protected: Socket* FindSocket(const char* name, std::vector& sockets) { diff --git a/src/AnimGraph/AnimGraphResource.h b/src/AnimGraph/AnimGraphResource.h index 3b73561..9f801bf 100644 --- a/src/AnimGraph/AnimGraphResource.h +++ b/src/AnimGraph/AnimGraphResource.h @@ -276,6 +276,73 @@ struct AnimGraphResource : AnimNodeResource { bool LoadFromFile(const char* filename); void CreateBlendTreeInstance(AnimGraphBlendTree& result) const; + + template + bool RegisterBlendTreeInputSocket(const std::string& socket_name) { + Socket socket; + socket.m_name = socket_name; + socket.m_type = GetSocketType(); + socket.m_type_size = sizeof(T); + + return RegisterBlendTreeInputSocket(socket); + } + + bool RegisterBlendTreeInputSocket(const Socket& socket) { + AnimNodeResource* input_node = m_blend_tree_resource.GetGraphInputNode(); + + std::vector input_sockets = + input_node->m_socket_accessor->m_outputs; + std::vector::const_iterator iter = std::find_if( + input_sockets.begin(), + input_sockets.end(), + [&socket](const Socket& input_socket) { + return socket.m_name == input_socket.m_name; + }); + + if (iter != input_sockets.end()) { + std::cerr << "Error: cannot register input socket as socket with name '" + << socket.m_name << "' already exists!" << std::endl; + return false; + } + + input_node->m_socket_accessor->m_outputs.push_back(socket); + m_socket_accessor->m_inputs = input_node->m_socket_accessor->m_outputs; + + return true; + } + + template + bool RegisterBlendTreeOutputSocket(const std::string& socket_name) { + Socket socket; + socket.m_name = socket_name; + socket.m_type = GetSocketType(); + socket.m_type_size = sizeof(T); + + return RegisterBlendTreeOutputSocket(socket); + } + + bool RegisterBlendTreeOutputSocket(const Socket& socket) { + AnimNodeResource* output_node = m_blend_tree_resource.GetGraphOutputNode(); + + std::vector output_sockets = + output_node->m_socket_accessor->m_inputs; + std::vector::const_iterator iter = std::find_if( + output_sockets.begin(), + output_sockets.end(), + [&socket](const Socket& input_socket) { + return socket.m_name == input_socket.m_name; + }); + + if (iter != output_sockets.end()) { + return false; + } + + output_node->m_socket_accessor->m_inputs.push_back(socket); + m_socket_accessor->m_outputs = output_node->m_socket_accessor->m_inputs; + + return true; + } + void CreateStateMachineInstance(AnimGraphStateMachine& result) const; private: diff --git a/tests/AnimGraphResourceTests.cc b/tests/AnimGraphResourceTests.cc index 65cd490..e79b192 100644 --- a/tests/AnimGraphResourceTests.cc +++ b/tests/AnimGraphResourceTests.cc @@ -304,21 +304,11 @@ class EmbeddedTreeBlend2GraphResource { embedded_blend_tree_resource = &embedded_graph->m_blend_tree_resource; // Embedded: outputs - AnimNodeResource* embedded_outputs = - embedded_blend_tree_resource->GetGraphOutputNode(); - embedded_outputs->m_socket_accessor->RegisterInput( - "AnimOutput", - nullptr); + embedded_graph->RegisterBlendTreeOutputSocket("AnimOutput"); // Embedded: inputs - AnimNodeResource* embedded_inputs = - embedded_blend_tree_resource->GetGraphInputNode(); - embedded_inputs->m_socket_accessor->RegisterOutput( - "AnimInput", - nullptr); - embedded_inputs->m_socket_accessor->RegisterOutput( - "BlendWeight", - nullptr); + embedded_graph->RegisterBlendTreeInputSocket("AnimInput"); + embedded_graph->RegisterBlendTreeInputSocket("BlendWeight"); // Embedded nodes embedded_blend2_node_index = embedded_blend_tree_resource->AddNode( @@ -343,7 +333,7 @@ class EmbeddedTreeBlend2GraphResource { // Embedded: setup connections REQUIRE(embedded_blend_tree_resource->ConnectSockets( - embedded_inputs, + embedded_blend_tree_resource->GetGraphInputNode(), "AnimInput", embedded_blend2_node_resource, "Input0")); @@ -358,7 +348,7 @@ class EmbeddedTreeBlend2GraphResource { embedded_blend_tree_resource->GetGraphOutputNode(), "AnimOutput")); REQUIRE(embedded_blend_tree_resource->ConnectSockets( - embedded_inputs, + embedded_blend_tree_resource->GetGraphInputNode(), "BlendWeight", embedded_blend2_node_resource, "Weight")); @@ -1341,4 +1331,24 @@ TEST_CASE_METHOD( } graph_context.freeAnimations(); +} + +TEST_CASE( + "Register AnimGraphResource Blendtree Sockets", + "[AnimGraphResource]") { + AnimNodeResource* blend_tree_anim_node_resource = + AnimNodeResourceFactory("BlendTree"); + AnimGraphResource* blend_tree_graph_resource = + dynamic_cast(blend_tree_anim_node_resource); + + Socket socket; + socket.m_name = "FloatSocket"; + socket.m_type = SocketType::SocketTypeFloat; + socket.m_reference.ptr = nullptr; + + CHECK(blend_tree_graph_resource->RegisterBlendTreeInputSocket(socket)); + CHECK(!blend_tree_graph_resource->RegisterBlendTreeInputSocket(socket)); + + CHECK(blend_tree_graph_resource->RegisterBlendTreeOutputSocket(socket)); + CHECK(!blend_tree_graph_resource->RegisterBlendTreeOutputSocket(socket)); } \ No newline at end of file