From b01acc2a888e59f66a2d4f6013fc5eacadd3c861 Mon Sep 17 00:00:00 2001 From: Martin Felis Date: Sun, 20 Feb 2022 15:57:19 +0100 Subject: [PATCH] Added marking of nodes active/inactive. --- src/AnimGraphResource.cc | 15 ++++++++- src/AnimGraphResource.h | 27 +++++++++++++--- tests/AnimGraphResourceTests.cc | 55 +++++++++++++++++++++++++++++++-- 3 files changed, 89 insertions(+), 8 deletions(-) diff --git a/src/AnimGraphResource.cc b/src/AnimGraphResource.cc index c591fdf..61f6112 100644 --- a/src/AnimGraphResource.cc +++ b/src/AnimGraphResource.cc @@ -389,7 +389,20 @@ void AnimGraph::UpdateOrderedNodes() { void AnimGraph::MarkActiveNodes() { m_frame_counter++; - // TODO: start from output and trigger updating of the frame counter. + int first_node_index = getAnimNodeIndex(m_ordered_nodes[0]); + m_ordered_nodes[0]->m_frame_counter = m_frame_counter; + m_ordered_nodes[0]->UpdateActiveInputFrameCounters(m_node_inputs[first_node_index]); + + for (size_t i = 1, n = m_ordered_nodes.size(); i < n; i++) { + AnimNode* node = m_ordered_nodes[i]; + if (CheckIsNodeActive(node)) { + int node_index = getAnimNodeIndex(node); + node->UpdateActiveInputFrameCounters(m_node_inputs[node_index]); + } else { + // Avoid active frame counter overrun. + node->m_frame_counter = m_frame_counter - 1; + } + } } void* AnimGraph::GetOutput(const std::string& name) const { diff --git a/src/AnimGraphResource.h b/src/AnimGraphResource.h index 5cc5e0e..8280b9c 100644 --- a/src/AnimGraphResource.h +++ b/src/AnimGraphResource.h @@ -319,6 +319,26 @@ struct Blend2Node : public AnimNode { AnimData* m_output = nullptr; float m_blend_weight = 0.f; bool m_sync_blend = false; + + + virtual void UpdateActiveInputFrameCounters (const std::vector& inputs) override { + for (size_t i = 0, n = inputs.size(); i < n; i++) { + AnimNode* input_node = inputs[i].m_node; + if (input_node == nullptr) { + continue; + } + + if (inputs[i].m_input_name == "Input0" && m_blend_weight < 0.999) { + input_node->m_frame_counter = m_frame_counter; + continue; + } + + if (inputs[i].m_input_name == "Input1" && m_blend_weight > 0.001) { + input_node->m_frame_counter = m_frame_counter; + continue; + } + } + } }; template <> @@ -532,14 +552,13 @@ struct AnimGraph { void UpdateOrderedNodes(); void MarkActiveNodes(); - bool CheckNodeActive(int node_index) { - assert(node_index < m_nodes.size()); - return m_nodes[node_index]->m_frame_counter == m_frame_counter; + bool CheckIsNodeActive(AnimNode* node) { + return node->m_frame_counter == m_frame_counter; } void UpdateTime(float dt); void Evaluate(); - int m_frame_counter; + int m_frame_counter = 0; AnimData m_local_transforms; std::vector m_nodes; diff --git a/tests/AnimGraphResourceTests.cc b/tests/AnimGraphResourceTests.cc index 73a50bb..570d9f9 100644 --- a/tests/AnimGraphResourceTests.cc +++ b/tests/AnimGraphResourceTests.cc @@ -439,9 +439,58 @@ TEST_CASE("GraphInputOutputConnectivity", "[AnimGraphResource]") { // // check ordering // - REQUIRE (anim_graph.getAnimNodeOrderIndex(blend2_node) < anim_graph.getAnimNodeOrderIndex(sampler_node)); - REQUIRE (anim_graph.getAnimNodeOrderIndex(blend2_node) < anim_graph.getAnimNodeOrderIndex(speed_scale_node)); - REQUIRE (anim_graph.getAnimNodeOrderIndex(speed_scale_node) < anim_graph.getAnimNodeOrderIndex(sampler_node)); + REQUIRE( + anim_graph.getAnimNodeOrderIndex(blend2_node) + < anim_graph.getAnimNodeOrderIndex(sampler_node)); + REQUIRE( + anim_graph.getAnimNodeOrderIndex(blend2_node) + < anim_graph.getAnimNodeOrderIndex(speed_scale_node)); + REQUIRE( + anim_graph.getAnimNodeOrderIndex(speed_scale_node) + < anim_graph.getAnimNodeOrderIndex(sampler_node)); + } + + WHEN("Instantiating graph") { + AnimGraph anim_graph = AnimGraph::createFromResource(graph_resource); + float* blend_weight_input = + reinterpret_cast(anim_graph.GetInput("GraphFloatInput")); + + Blend2Node* blend2_node = + dynamic_cast(anim_graph.m_nodes[blend2_node_index]); + SpeedScaleNode* speed_scale_node = dynamic_cast( + anim_graph.m_nodes[speed_scale_node_index]); + AnimSamplerNode* sampler_node = dynamic_cast( + anim_graph.m_nodes[sampler_node_index]); + + WHEN("Setting weight to 0. and marking nodes active.") { + *blend_weight_input = 0.; + anim_graph.MarkActiveNodes(); + + THEN("Speed scale and sampler node are inactive") { + REQUIRE(anim_graph.CheckIsNodeActive(speed_scale_node) == false); + REQUIRE(anim_graph.CheckIsNodeActive(sampler_node) == false); + } + } + + WHEN("Setting weight to 0. and marking nodes active") { + *blend_weight_input = 0.1; + anim_graph.MarkActiveNodes(); + + THEN("Speed scale and sampler nodes are active") { + REQUIRE(anim_graph.CheckIsNodeActive(speed_scale_node) == true); + REQUIRE(anim_graph.CheckIsNodeActive(sampler_node) == true); + } + } + + WHEN("Setting weight to 1. and marking nodes active") { + *blend_weight_input = 1.0; + anim_graph.MarkActiveNodes(); + + THEN("Speed scale and sampler nodes are active") { + REQUIRE(anim_graph.CheckIsNodeActive(speed_scale_node) == true); + REQUIRE(anim_graph.CheckIsNodeActive(sampler_node) == true); + } + } } } } \ No newline at end of file