From bd304bde4e2da15a4aebc3bedbee6ea0427df7e0 Mon Sep 17 00:00:00 2001 From: Martin Felis Date: Sat, 19 Feb 2022 00:25:51 +0100 Subject: [PATCH] Give access to node inputs in runtime graph, initial works for marking of active nodes. --- src/AnimGraphResource.cc | 6 ++++ src/AnimGraphResource.h | 58 ++++++++++++++++++++++++++++++--- tests/AnimGraphResourceTests.cc | 12 +++++-- 3 files changed, 69 insertions(+), 7 deletions(-) diff --git a/src/AnimGraphResource.cc b/src/AnimGraphResource.cc index 177a957..7864282 100644 --- a/src/AnimGraphResource.cc +++ b/src/AnimGraphResource.cc @@ -351,6 +351,12 @@ bool AnimGraphResource::loadFromFile(const char* filename) { return true; } +void AnimGraph::MarkActiveNodes() { + m_frame_counter++; + + // TODO: start from output and trigger updating of the frame counter. +} + void* AnimGraph::GetOutput(const std::string& name) const { Socket* socket = m_socket_accessor->FindInputSocket(name); if (socket == nullptr) { diff --git a/src/AnimGraphResource.h b/src/AnimGraphResource.h index 469f20d..4a40399 100644 --- a/src/AnimGraphResource.h +++ b/src/AnimGraphResource.h @@ -89,9 +89,15 @@ struct AnimNode { bool m_is_time_synced; float m_time_now; float m_time_last; + int m_frame_counter = 0; SyncTrack m_sync_track; }; +struct AnimNodeInput { + AnimNode* m_node; + std::string m_input_name; +}; + struct NodeSocketAccessorBase { NodeSocketAccessorBase() {} virtual ~NodeSocketAccessorBase() {} @@ -515,12 +521,19 @@ struct AnimGraph { delete m_socket_accessor; } + void MarkActiveNodes(); + bool CheckNodeActive(int node_index) { + assert(node_index < m_nodes.size()); + return m_nodes[node_index]->m_frame_counter == m_frame_counter; + } void UpdateTime(float dt); void Evaluate(); + int m_frame_counter; AnimData m_local_transforms; + std::vector m_nodes; - std::vector > m_node_inputs; + std::vector > m_node_inputs; NodeSocketAccessorBase* m_socket_accessor; char* m_input_buffer = nullptr; char* m_output_buffer = nullptr; @@ -531,6 +544,22 @@ struct AnimGraph { void* GetOutput(const std::string& name) const; void* GetInput(const std::string& name) const; + AnimNode* getAnimNodeForInput( + size_t node_index, + const std::string& input_name) { + assert(node_index < m_nodes.size()); + assert(node_index < m_node_inputs.size()); + + std::vector& node_inputs = m_node_inputs[node_index]; + for (size_t i = 0, n = node_inputs.size(); i < n; i++) { + if (node_inputs[i].m_input_name == input_name) { + return node_inputs[i].m_node; + } + } + + return nullptr; + } + AnimNode* getAnimNode(const char* name) { for (size_t i = 0; i < m_nodes.size(); i++) { if (m_nodes[i]->m_name == name) { @@ -562,7 +591,21 @@ struct AnimGraph { node->m_name = node_resource.m_name; node->m_node_type_name = node_resource.m_type_name; result.m_nodes.push_back(node); - result.m_node_inputs.push_back(std::vector()); + + assert(node_resource.m_socket_accessor != nullptr); + result.m_node_inputs.push_back(std::vector()); + std::vector& node_inputs = result.m_node_inputs.back(); + for (int j = 0, n = node_resource.m_socket_accessor->m_inputs.size(); + j < n; + j++) { + const Socket& input_socket = + node_resource.m_socket_accessor->m_inputs[j]; + AnimNodeInput input; + input.m_node = nullptr; + input.m_input_name = input_socket.m_name; + + node_inputs.push_back(input); + } } // Prepare graph inputs @@ -688,7 +731,14 @@ struct AnimGraph { (*source_socket->m_value.ptr_ptr) = target_socket->m_value.ptr; size_t target_node_index = result.getAnimNodeIndex(target_node); - result.m_node_inputs[target_node_index].push_back(source_node); + + std::vector& node_inputs = + result.m_node_inputs[target_node_index]; + for (int j = 0, n = node_inputs.size(); j < n; j++) { + if (node_inputs[j].m_input_name == target_socket->m_name) { + node_inputs[j].m_node = source_node; + } + } if (target_node_accessor != result.m_socket_accessor) { delete target_node_accessor; @@ -703,6 +753,6 @@ struct AnimGraph { } }; -} +} // namespace AnimGraphCode #endif //ANIMTESTBED_ANIMGRAPHRESOURCE_H diff --git a/tests/AnimGraphResourceTests.cc b/tests/AnimGraphResourceTests.cc index a2d5614..919667f 100644 --- a/tests/AnimGraphResourceTests.cc +++ b/tests/AnimGraphResourceTests.cc @@ -5,6 +5,8 @@ #include "AnimGraphResource.h" #include "catch.hpp" +using namespace AnimGraphCode; + TEST_CASE("BasicGraph", "[AnimGraphResource]") { AnimGraphResource graph_resource; @@ -100,9 +102,10 @@ TEST_CASE("BasicGraph", "[AnimGraphResource]") { CHECK(graph.m_node_inputs[anim_sampler_index0].size() == 0); CHECK(graph.m_node_inputs[anim_sampler_index1].size() == 0); - CHECK(graph.m_node_inputs[blend_index].size() == 2); - CHECK(graph.m_node_inputs[blend_index][0] == anim_sampler_instance0); - CHECK(graph.m_node_inputs[blend_index][1] == anim_sampler_instance1); + CHECK(graph.m_node_inputs[blend_index].size() == 3); + CHECK(graph.m_node_inputs[blend_index][0].m_node == anim_sampler_instance0); + CHECK(graph.m_node_inputs[blend_index][1].m_node == anim_sampler_instance1); + CHECK(graph.m_node_inputs[blend_index][2].m_node == nullptr); } TEST_CASE("InputAttributeConversion", "[AnimGraphResource]") { @@ -324,12 +327,15 @@ TEST_CASE("GraphInputOutputConnectivity", "[AnimGraphResource]") { AnimData* graph_input0 = (AnimData*) anim_graph.GetInput("GraphAnimInput0"); REQUIRE(graph_input0 == &blend2_node->m_input0); + REQUIRE(anim_graph.m_nodes[1] == anim_graph.getAnimNodeForInput(blend2_node_index, "Input0")); AnimData* graph_input1 = (AnimData*) anim_graph.GetInput("GraphAnimInput1"); REQUIRE(graph_input1 == &blend2_node->m_input1); + REQUIRE(anim_graph.m_nodes[1] == anim_graph.getAnimNodeForInput(blend2_node_index, "Input1")); AnimData* graph_output = (AnimData*) anim_graph.GetOutput("GraphAnimOutput"); REQUIRE(graph_output == blend2_node->m_output); + REQUIRE(anim_graph.m_nodes[blend2_node_index] == anim_graph.getAnimNodeForInput(0, "GraphAnimOutput")); } } }