New evaluation scheme.

- Animation Data are always referenced via a pointer in nodes.
- Animation Data storage pointers are injected from graph when node is evaluated.
- Node value outputs always stored in node.
- Node value inputs always referenced via pointer. References are created when instantiating the graph.
This commit is contained in:
Martin Felis
2022-04-01 13:19:54 +02:00
parent abddbea62b
commit 08ae84fcb4
8 changed files with 559 additions and 431 deletions
+69 -52
View File
@@ -25,9 +25,9 @@ TEST_CASE("BasicGraph", "[AnimGraphResource]") {
AnimNodeResource& walk_node = graph_resource.m_nodes[walk_node_index];
walk_node.m_name = "WalkAnim";
AnimNodeResource& run_node = graph_resource.m_nodes[run_node_index];
walk_node.m_name = "RunAnim";
run_node.m_name = "RunAnim";
AnimNodeResource& blend_node = graph_resource.m_nodes[blend_node_index];
walk_node.m_name = "BlendWalkRun";
blend_node.m_name = "BlendWalkRun";
AnimNodeResource& graph_node = graph_resource.m_nodes[0];
graph_node.m_socket_accessor->RegisterInput<AnimData>("GraphOutput", nullptr);
@@ -36,31 +36,25 @@ TEST_CASE("BasicGraph", "[AnimGraphResource]") {
REQUIRE(blend_node.m_socket_accessor->GetInputIndex("Input0") == 0);
REQUIRE(blend_node.m_socket_accessor->GetInputIndex("Input1") == 1);
AnimGraphConnection walk_to_blend;
walk_to_blend.m_source_node = &walk_node;
walk_to_blend.m_source_socket =
walk_node.m_socket_accessor->FindOutputSocket("Output");
walk_to_blend.m_target_node = &blend_node;
walk_to_blend.m_target_socket =
blend_node.m_socket_accessor->FindInputSocket("Input0");
AnimGraphConnectionResource walk_to_blend;
walk_to_blend.source_node_index = walk_node_index;
walk_to_blend.source_socket_name = "Output";
walk_to_blend.target_node_index = blend_node_index;
walk_to_blend.target_socket_name = "Input0";
graph_resource.m_connections.push_back(walk_to_blend);
AnimGraphConnection run_to_blend;
run_to_blend.m_source_node = &run_node;
run_to_blend.m_source_socket =
run_node.m_socket_accessor->FindOutputSocket("Output");
run_to_blend.m_target_node = &blend_node;
run_to_blend.m_target_socket =
blend_node.m_socket_accessor->FindInputSocket("Input1");
AnimGraphConnectionResource run_to_blend;
run_to_blend.source_node_index = run_node_index;
run_to_blend.source_socket_name = "Output";
run_to_blend.target_node_index = blend_node_index;
run_to_blend.target_socket_name = "Input1";
graph_resource.m_connections.push_back(run_to_blend);
AnimGraphConnection blend_to_output;
blend_to_output.m_source_node = &blend_node;
blend_to_output.m_source_socket =
blend_node.m_socket_accessor->FindOutputSocket("Output");
blend_to_output.m_target_node = &graph_resource.m_nodes[0];
blend_to_output.m_target_socket =
graph_node.m_socket_accessor->FindInputSocket("GraphOutput");
AnimGraphConnectionResource blend_to_output;
blend_to_output.source_node_index = blend_node_index;
blend_to_output.source_socket_name = "Output";
blend_to_output.target_node_index = 0;
blend_to_output.target_socket_name = "GraphOutput";
graph_resource.m_connections.push_back(blend_to_output);
graph_resource.saveToFile("WalkGraph.animgraph.json");
@@ -75,34 +69,55 @@ TEST_CASE("BasicGraph", "[AnimGraphResource]") {
REQUIRE(graph.m_nodes[4]->m_node_type_name == "Blend2");
// connections within the graph
AnimSamplerNode* anim_sampler_instance0 =
AnimSamplerNode* anim_sampler_walk =
dynamic_cast<AnimSamplerNode*>(graph.m_nodes[2]);
AnimSamplerNode* anim_sampler_instance1 =
AnimSamplerNode* anim_sampler_run =
dynamic_cast<AnimSamplerNode*>(graph.m_nodes[3]);
Blend2Node* blend2_instance = dynamic_cast<Blend2Node*>(graph.m_nodes[4]);
CHECK(anim_sampler_instance0->m_output == &blend2_instance->m_input0);
CHECK(anim_sampler_instance1->m_output == &blend2_instance->m_input1);
// connections from graph to the graph node
CHECK(graph.m_socket_accessor->m_inputs.size() == 1);
CHECK(graph.m_socket_accessor->FindInputSocket("GraphOutput"));
CHECK(
reinterpret_cast<char*>(blend2_instance->m_output)
== graph.getOutput("GraphOutput"));
// check node input dependencies
size_t anim_sampler_index0 = anim_sampler_instance0->m_index;
size_t anim_sampler_index1 = anim_sampler_instance1->m_index;
size_t anim_sampler_index0 = anim_sampler_walk->m_index;
size_t anim_sampler_index1 = anim_sampler_run->m_index;
size_t blend_index = blend2_instance->m_index;
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() == 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);
REQUIRE(graph.m_node_input_connections[blend_index].size() == 2);
CHECK(graph.m_node_input_connections[blend_index][0].m_source_node == anim_sampler_walk);
CHECK(graph.m_node_input_connections[blend_index][1].m_source_node == anim_sampler_run);
REQUIRE(graph.m_node_output_connections[anim_sampler_index0].size() == 1);
CHECK(graph.m_node_output_connections[anim_sampler_index0][0].m_target_node == blend2_instance);
REQUIRE(graph.m_node_output_connections[anim_sampler_index1].size() == 1);
CHECK(graph.m_node_output_connections[anim_sampler_index1][0].m_target_node == blend2_instance);
// Emulate evaluation
CHECK(graph.m_anim_data_work_buffer.m_available_data.size() == 5);
graph.prepareNodeEval(walk_node_index);
graph.finishNodeEval(walk_node_index);
CHECK(graph.m_anim_data_work_buffer.m_available_data.size() == 4);
graph.prepareNodeEval(run_node_index);
graph.finishNodeEval(run_node_index);
CHECK(graph.m_anim_data_work_buffer.m_available_data.size() == 3);
graph.prepareNodeEval(blend_node_index);
CHECK(blend2_instance->i_input0 == anim_sampler_walk->o_output);
CHECK(blend2_instance->i_input1 == anim_sampler_run->o_output);
CHECK(graph.m_anim_data_work_buffer.m_available_data.size() == 2);
graph.finishNodeEval(blend_node_index);
CHECK(anim_sampler_walk->o_output == nullptr);
CHECK(anim_sampler_run->o_output == nullptr);
CHECK(graph.m_anim_data_work_buffer.m_available_data.size() == 4);
graph.prepareNodeEval(0);
Socket* graph_output_socket = graph.getOutputSocket("GraphOutput");
CHECK(blend2_instance->o_output == (*graph_output_socket->m_value.ptr_ptr));
AnimData* graph_output = static_cast<AnimData*>(*graph_output_socket->m_value.ptr_ptr);
graph.finishNodeEval(0);
CHECK(blend2_instance->o_output == nullptr);
CHECK(graph_output == (*graph_output_socket->m_value.ptr_ptr));
CHECK(graph.m_anim_data_work_buffer.m_available_data.size() == 5);
}
/*
TEST_CASE("InputAttributeConversion", "[AnimGraphResource]") {
int node_id = 3321;
int input_index = 221;
@@ -299,9 +314,9 @@ TEST_CASE("GraphInputOutputConnectivity", "[AnimGraphResource]") {
REQUIRE(
*anim_graph.m_socket_accessor->m_outputs[0].m_value.ptr_ptr
== &blend2_node->m_blend_weight);
== blend2_node->i_blend_weight);
float* float_input_ptr = (float*)anim_graph.getInput("GraphFloatInput");
REQUIRE(float_input_ptr == &blend2_node->m_blend_weight);
REQUIRE(float_input_ptr == blend2_node->i_blend_weight);
}
WHEN(
@@ -335,21 +350,21 @@ TEST_CASE("GraphInputOutputConnectivity", "[AnimGraphResource]") {
AnimData* graph_input0 =
(AnimData*)anim_graph.getInput("GraphAnimInput0");
REQUIRE(graph_input0 == &blend2_node->m_input0);
REQUIRE(graph_input0 == blend2_node->i_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(graph_input1 == blend2_node->i_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(graph_output == blend2_node->o_output);
REQUIRE(
anim_graph.m_nodes[blend2_node_index]
== anim_graph.getAnimNodeForInput(0, "GraphAnimOutput"));
@@ -422,7 +437,7 @@ TEST_CASE("GraphInputOutputConnectivity", "[AnimGraphResource]") {
//
AnimData* graph_input0 =
(AnimData*)anim_graph.getInput("GraphAnimInput0");
REQUIRE(graph_input0 == &blend2_node->m_input0);
REQUIRE(graph_input0 == blend2_node->i_input0);
REQUIRE(
anim_graph.m_nodes[1]
== anim_graph.getAnimNodeForInput(blend2_node_index, "Input0"));
@@ -431,19 +446,19 @@ TEST_CASE("GraphInputOutputConnectivity", "[AnimGraphResource]") {
(AnimData*)anim_graph.getInput("GraphAnimInput1");
REQUIRE(graph_input1 == nullptr);
REQUIRE(sampler_node->m_output == &speed_scale_node->m_input);
REQUIRE(sampler_node->o_output == speed_scale_node->i_input);
REQUIRE(
sampler_node
== anim_graph.getAnimNodeForInput(speed_scale_node_index, "Input"));
REQUIRE(speed_scale_node->m_output == &blend2_node->m_input1);
REQUIRE(speed_scale_node->i_output == blend2_node->i_input1);
REQUIRE(
speed_scale_node
== anim_graph.getAnimNodeForInput(blend2_node_index, "Input1"));
AnimData* graph_output =
(AnimData*)anim_graph.getOutput("GraphAnimOutput");
REQUIRE(graph_output == blend2_node->m_output);
REQUIRE(graph_output == blend2_node->o_output);
REQUIRE(
anim_graph.m_nodes[blend2_node_index]
== anim_graph.getAnimNodeForInput(0, "GraphAnimOutput"));
@@ -535,4 +550,6 @@ TEST_CASE("GraphInputOutputConnectivity", "[AnimGraphResource]") {
}
}
}
}
}
*/