| 
									
										
										
										
											2022-02-11 16:51:18 +01:00
										 |  |  | //
 | 
					
						
							|  |  |  | // Created by martin on 04.02.22.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-11 16:46:09 +02:00
										 |  |  | #include "ozz/base/io/archive.h"
 | 
					
						
							|  |  |  | #include "ozz/base/io/stream.h"
 | 
					
						
							|  |  |  | #include "ozz/base/log.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-25 11:46:44 +01:00
										 |  |  | #include "AnimGraph/AnimGraph.h"
 | 
					
						
							|  |  |  | #include "AnimGraph/AnimGraphEditor.h"
 | 
					
						
							| 
									
										
										
										
											2022-04-03 21:05:11 +02:00
										 |  |  | #include "AnimGraph/AnimGraphResource.h"
 | 
					
						
							| 
									
										
										
										
											2022-03-25 11:46:44 +01:00
										 |  |  | #include "catch.hpp"
 | 
					
						
							| 
									
										
										
										
											2022-02-19 00:25:51 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-11 16:46:09 +02:00
										 |  |  | bool load_skeleton (ozz::animation::Skeleton& skeleton, const char* filename) { | 
					
						
							|  |  |  |   assert(filename); | 
					
						
							|  |  |  |   ozz::io::File file(filename, "rb"); | 
					
						
							|  |  |  |   if (!file.opened()) { | 
					
						
							|  |  |  |     ozz::log::Err() << "Failed to open skeleton file " << filename << "." | 
					
						
							|  |  |  |                     << std::endl; | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   ozz::io::IArchive archive(&file); | 
					
						
							|  |  |  |   if (!archive.TestTag<ozz::animation::Skeleton>()) { | 
					
						
							|  |  |  |     ozz::log::Err() << "Failed to load skeleton instance from file " << filename | 
					
						
							|  |  |  |                     << "." << std::endl; | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Once the tag is validated, reading cannot fail.
 | 
					
						
							|  |  |  |   archive >> skeleton; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-11 16:51:18 +01:00
										 |  |  | TEST_CASE("BasicGraph", "[AnimGraphResource]") { | 
					
						
							|  |  |  |   AnimGraphResource graph_resource; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-12 10:14:26 +01:00
										 |  |  |   graph_resource.clear(); | 
					
						
							| 
									
										
										
										
											2022-02-11 16:51:18 +01:00
										 |  |  |   graph_resource.m_name = "WalkRunBlendGraph"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-12 10:14:26 +01:00
										 |  |  |   // Prepare graph inputs and outputs
 | 
					
						
							|  |  |  |   size_t walk_node_index = | 
					
						
							|  |  |  |       graph_resource.addNode(AnimNodeResourceFactory("AnimSampler")); | 
					
						
							|  |  |  |   size_t run_node_index = | 
					
						
							|  |  |  |       graph_resource.addNode(AnimNodeResourceFactory("AnimSampler")); | 
					
						
							|  |  |  |   size_t blend_node_index = | 
					
						
							|  |  |  |       graph_resource.addNode(AnimNodeResourceFactory("Blend2")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   AnimNodeResource& walk_node = graph_resource.m_nodes[walk_node_index]; | 
					
						
							| 
									
										
										
										
											2022-02-11 16:51:18 +01:00
										 |  |  |   walk_node.m_name = "WalkAnim"; | 
					
						
							| 
									
										
										
										
											2022-04-11 16:46:09 +02:00
										 |  |  |   walk_node.m_socket_accessor->SetPropertyValue("Filename", "data/walk.anim.ozz"); | 
					
						
							| 
									
										
										
										
											2022-02-12 10:14:26 +01:00
										 |  |  |   AnimNodeResource& run_node = graph_resource.m_nodes[run_node_index]; | 
					
						
							| 
									
										
										
										
											2022-04-11 16:46:09 +02:00
										 |  |  |   run_node.m_socket_accessor->SetPropertyValue("Filename", "data/run.anim.ozz"); | 
					
						
							| 
									
										
										
										
											2022-04-01 13:19:54 +02:00
										 |  |  |   run_node.m_name = "RunAnim"; | 
					
						
							| 
									
										
										
										
											2022-02-12 10:14:26 +01:00
										 |  |  |   AnimNodeResource& blend_node = graph_resource.m_nodes[blend_node_index]; | 
					
						
							| 
									
										
										
										
											2022-04-01 13:19:54 +02:00
										 |  |  |   blend_node.m_name = "BlendWalkRun"; | 
					
						
							| 
									
										
										
										
											2022-02-11 16:51:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-12 10:14:26 +01:00
										 |  |  |   AnimNodeResource& graph_node = graph_resource.m_nodes[0]; | 
					
						
							| 
									
										
										
										
											2022-02-12 11:46:50 +01:00
										 |  |  |   graph_node.m_socket_accessor->RegisterInput<AnimData>("GraphOutput", nullptr); | 
					
						
							| 
									
										
										
										
											2022-02-11 16:51:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-12 10:14:26 +01:00
										 |  |  |   REQUIRE(graph_node.m_socket_accessor->m_inputs.size() == 1); | 
					
						
							|  |  |  |   REQUIRE(blend_node.m_socket_accessor->GetInputIndex("Input0") == 0); | 
					
						
							|  |  |  |   REQUIRE(blend_node.m_socket_accessor->GetInputIndex("Input1") == 1); | 
					
						
							| 
									
										
										
										
											2022-02-11 16:51:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-11 16:46:09 +02:00
										 |  |  |   graph_resource.connectSockets(walk_node, "Output", blend_node, "Input0"); | 
					
						
							|  |  |  |   graph_resource.connectSockets(run_node, "Output", blend_node, "Input1"); | 
					
						
							|  |  |  |   graph_resource.connectSockets( | 
					
						
							|  |  |  |       blend_node, | 
					
						
							|  |  |  |       "Output", | 
					
						
							|  |  |  |       graph_resource.getGraphOutputNode(), | 
					
						
							|  |  |  |       "GraphOutput"); | 
					
						
							| 
									
										
										
										
											2022-02-11 16:51:18 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   graph_resource.saveToFile("WalkGraph.animgraph.json"); | 
					
						
							| 
									
										
										
										
											2022-04-11 16:46:09 +02:00
										 |  |  |   AnimGraphResource graph_resource_loaded; | 
					
						
							|  |  |  |   graph_resource_loaded.loadFromFile("WalkGraph.animgraph.json"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   AnimGraph graph = graph_resource_loaded.createInstance(); | 
					
						
							|  |  |  |   AnimGraphContext graph_context; | 
					
						
							|  |  |  |   graph_context.m_graph = &graph; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   ozz::animation::Skeleton skeleton; | 
					
						
							|  |  |  |   REQUIRE(load_skeleton(skeleton, "data/skeleton.ozz")); | 
					
						
							|  |  |  |   graph_context.m_skeleton = &skeleton; | 
					
						
							| 
									
										
										
										
											2022-02-11 16:51:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-11 16:46:09 +02:00
										 |  |  |   REQUIRE(graph.init(graph_context)); | 
					
						
							| 
									
										
										
										
											2022-02-11 16:51:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-14 22:37:19 +01:00
										 |  |  |   REQUIRE(graph.m_nodes.size() == 5); | 
					
						
							| 
									
										
										
										
											2022-02-12 11:46:50 +01:00
										 |  |  |   REQUIRE(graph.m_nodes[0]->m_node_type_name == "BlendTree"); | 
					
						
							| 
									
										
										
										
											2022-02-14 22:37:19 +01:00
										 |  |  |   REQUIRE(graph.m_nodes[1]->m_node_type_name == "BlendTree"); | 
					
						
							| 
									
										
										
										
											2022-02-12 11:46:50 +01:00
										 |  |  |   REQUIRE(graph.m_nodes[2]->m_node_type_name == "AnimSampler"); | 
					
						
							| 
									
										
										
										
											2022-02-14 22:37:19 +01:00
										 |  |  |   REQUIRE(graph.m_nodes[3]->m_node_type_name == "AnimSampler"); | 
					
						
							|  |  |  |   REQUIRE(graph.m_nodes[4]->m_node_type_name == "Blend2"); | 
					
						
							| 
									
										
										
										
											2022-02-11 16:51:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-12 11:46:50 +01:00
										 |  |  |   // connections within the graph
 | 
					
						
							| 
									
										
										
										
											2022-04-01 13:19:54 +02:00
										 |  |  |   AnimSamplerNode* anim_sampler_walk = | 
					
						
							| 
									
										
										
										
											2022-02-12 10:14:26 +01:00
										 |  |  |       dynamic_cast<AnimSamplerNode*>(graph.m_nodes[2]); | 
					
						
							| 
									
										
										
										
											2022-04-01 13:19:54 +02:00
										 |  |  |   AnimSamplerNode* anim_sampler_run = | 
					
						
							| 
									
										
										
										
											2022-02-14 22:37:19 +01:00
										 |  |  |       dynamic_cast<AnimSamplerNode*>(graph.m_nodes[3]); | 
					
						
							|  |  |  |   Blend2Node* blend2_instance = dynamic_cast<Blend2Node*>(graph.m_nodes[4]); | 
					
						
							| 
									
										
										
										
											2022-02-12 11:46:50 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // check node input dependencies
 | 
					
						
							| 
									
										
										
										
											2022-04-01 13:19:54 +02:00
										 |  |  |   size_t anim_sampler_index0 = anim_sampler_walk->m_index; | 
					
						
							|  |  |  |   size_t anim_sampler_index1 = anim_sampler_run->m_index; | 
					
						
							| 
									
										
										
										
											2022-02-24 22:55:40 +01:00
										 |  |  |   size_t blend_index = blend2_instance->m_index; | 
					
						
							| 
									
										
										
										
											2022-02-11 16:51:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-01 13:19:54 +02:00
										 |  |  |   REQUIRE(graph.m_node_input_connections[blend_index].size() == 2); | 
					
						
							| 
									
										
										
										
											2022-04-03 21:05:11 +02:00
										 |  |  |   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); | 
					
						
							| 
									
										
										
										
											2022-04-01 13:19:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   REQUIRE(graph.m_node_output_connections[anim_sampler_index0].size() == 1); | 
					
						
							| 
									
										
										
										
											2022-04-03 21:05:11 +02:00
										 |  |  |   CHECK( | 
					
						
							|  |  |  |       graph.m_node_output_connections[anim_sampler_index0][0].m_target_node | 
					
						
							|  |  |  |       == blend2_instance); | 
					
						
							| 
									
										
										
										
											2022-04-01 13:19:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   REQUIRE(graph.m_node_output_connections[anim_sampler_index1].size() == 1); | 
					
						
							| 
									
										
										
										
											2022-04-03 21:05:11 +02:00
										 |  |  |   CHECK( | 
					
						
							|  |  |  |       graph.m_node_output_connections[anim_sampler_index1][0].m_target_node | 
					
						
							|  |  |  |       == blend2_instance); | 
					
						
							| 
									
										
										
										
											2022-04-01 13:19:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-11 16:46:09 +02:00
										 |  |  |   // Ensure animation sampler nodes use the correct files
 | 
					
						
							|  |  |  |   REQUIRE(anim_sampler_walk->m_filename == "data/walk.anim.ozz"); | 
					
						
							|  |  |  |   REQUIRE(anim_sampler_walk->m_animation != nullptr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   REQUIRE(anim_sampler_run->m_filename == "data/run.anim.ozz"); | 
					
						
							|  |  |  |   REQUIRE(anim_sampler_run->m_animation != nullptr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   WHEN("Emulating Graph 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); | 
					
						
							|  |  |  |     const Socket* graph_output_socket = graph.getOutputSocket("GraphOutput"); | 
					
						
							|  |  |  |     CHECK(blend2_instance->o_output == (*graph_output_socket->m_reference.ptr_ptr)); | 
					
						
							|  |  |  |     AnimData* graph_output = | 
					
						
							|  |  |  |         static_cast<AnimData*>(*graph_output_socket->m_reference.ptr_ptr); | 
					
						
							|  |  |  |     graph.finishNodeEval(0); | 
					
						
							|  |  |  |     CHECK(blend2_instance->o_output == nullptr); | 
					
						
							|  |  |  |     CHECK(graph_output == (*graph_output_socket->m_reference.ptr_ptr)); | 
					
						
							|  |  |  |     CHECK(graph.m_anim_data_work_buffer.m_available_data.size() == 5); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2022-02-11 16:51:18 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST_CASE("InputAttributeConversion", "[AnimGraphResource]") { | 
					
						
							|  |  |  |   int node_id = 3321; | 
					
						
							|  |  |  |   int input_index = 221; | 
					
						
							|  |  |  |   int output_index = 125; | 
					
						
							|  |  |  |   int parsed_node_id; | 
					
						
							|  |  |  |   int parsed_input_index; | 
					
						
							|  |  |  |   int parsed_output_index; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   int attribute_id = GenerateInputAttributeId(node_id, input_index); | 
					
						
							|  |  |  |   SplitInputAttributeId(attribute_id, &parsed_node_id, &parsed_input_index); | 
					
						
							|  |  |  |   CHECK(node_id == parsed_node_id); | 
					
						
							|  |  |  |   CHECK(input_index == parsed_input_index); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   attribute_id = GenerateOutputAttributeId(node_id, output_index); | 
					
						
							|  |  |  |   SplitOutputAttributeId(attribute_id, &parsed_node_id, &parsed_output_index); | 
					
						
							|  |  |  |   CHECK(node_id == parsed_node_id); | 
					
						
							|  |  |  |   CHECK(output_index == parsed_output_index); | 
					
						
							| 
									
										
										
										
											2022-02-14 22:37:19 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-03 21:05:11 +02:00
										 |  |  | TEST_CASE("ResourceSaveLoadMathGraphInputs", "[AnimGraphResource]") { | 
					
						
							| 
									
										
										
										
											2022-02-14 22:37:19 +01:00
										 |  |  |   AnimGraphResource graph_resource_origin; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   graph_resource_origin.clear(); | 
					
						
							|  |  |  |   graph_resource_origin.m_name = "TestInputOutputGraph"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-11 11:40:53 +02:00
										 |  |  |   size_t float_to_vec3_node_index = graph_resource_origin.addNode( | 
					
						
							|  |  |  |       AnimNodeResourceFactory("MathFloatToVec3Node")); | 
					
						
							| 
									
										
										
										
											2022-04-03 21:05:11 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   AnimNodeResource& graph_output_node = | 
					
						
							|  |  |  |       graph_resource_origin.getGraphOutputNode(); | 
					
						
							| 
									
										
										
										
											2022-02-14 22:37:19 +01:00
										 |  |  |   graph_output_node.m_socket_accessor->RegisterInput<float>( | 
					
						
							| 
									
										
										
										
											2022-04-03 21:05:11 +02:00
										 |  |  |       "GraphFloatOutput", | 
					
						
							| 
									
										
										
										
											2022-02-14 22:37:19 +01:00
										 |  |  |       nullptr); | 
					
						
							| 
									
										
										
										
											2022-04-03 21:05:11 +02:00
										 |  |  |   graph_output_node.m_socket_accessor->RegisterInput<Vec3>( | 
					
						
							|  |  |  |       "GraphVec3Output", | 
					
						
							| 
									
										
										
										
											2022-02-14 22:37:19 +01:00
										 |  |  |       nullptr); | 
					
						
							| 
									
										
										
										
											2022-04-03 21:05:11 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   AnimNodeResource& graph_input_node = | 
					
						
							|  |  |  |       graph_resource_origin.getGraphInputNode(); | 
					
						
							| 
									
										
										
										
											2022-02-14 22:37:19 +01:00
										 |  |  |   graph_input_node.m_socket_accessor->RegisterOutput<float>( | 
					
						
							|  |  |  |       "GraphFloatInput", | 
					
						
							|  |  |  |       nullptr); | 
					
						
							| 
									
										
										
										
											2022-04-03 21:05:11 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Prepare graph inputs and outputs
 | 
					
						
							|  |  |  |   AnimNodeResource& float_to_vec3_node = | 
					
						
							|  |  |  |       graph_resource_origin.m_nodes[float_to_vec3_node_index]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   REQUIRE(graph_resource_origin.connectSockets( | 
					
						
							|  |  |  |       graph_input_node, | 
					
						
							|  |  |  |       "GraphFloatInput", | 
					
						
							|  |  |  |       graph_output_node, | 
					
						
							|  |  |  |       "GraphFloatOutput")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   REQUIRE(graph_resource_origin.connectSockets( | 
					
						
							|  |  |  |       graph_input_node, | 
					
						
							|  |  |  |       "GraphFloatInput", | 
					
						
							|  |  |  |       float_to_vec3_node, | 
					
						
							|  |  |  |       "Input0")); | 
					
						
							|  |  |  |   REQUIRE(graph_resource_origin.connectSockets( | 
					
						
							|  |  |  |       graph_input_node, | 
					
						
							|  |  |  |       "GraphFloatInput", | 
					
						
							|  |  |  |       float_to_vec3_node, | 
					
						
							|  |  |  |       "Input1")); | 
					
						
							|  |  |  |   REQUIRE(graph_resource_origin.connectSockets( | 
					
						
							|  |  |  |       graph_input_node, | 
					
						
							|  |  |  |       "GraphFloatInput", | 
					
						
							|  |  |  |       float_to_vec3_node, | 
					
						
							|  |  |  |       "Input2")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   REQUIRE(graph_resource_origin.connectSockets( | 
					
						
							|  |  |  |       float_to_vec3_node, | 
					
						
							|  |  |  |       "Output", | 
					
						
							|  |  |  |       graph_output_node, | 
					
						
							|  |  |  |       "GraphVec3Output")); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-14 22:37:19 +01:00
										 |  |  |   WHEN("Saving and loading graph resource") { | 
					
						
							|  |  |  |     const char* filename = "ResourceSaveLoadGraphInputs.json"; | 
					
						
							|  |  |  |     graph_resource_origin.saveToFile(filename); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     AnimGraphResource graph_resource_loaded; | 
					
						
							|  |  |  |     graph_resource_loaded.loadFromFile(filename); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const AnimNodeResource& graph_loaded_output_node = | 
					
						
							|  |  |  |         graph_resource_loaded.m_nodes[0]; | 
					
						
							|  |  |  |     const AnimNodeResource& graph_loaded_input_node = | 
					
						
							|  |  |  |         graph_resource_loaded.m_nodes[1]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     THEN("Graph inputs and outputs must be in loaded resource as well.") { | 
					
						
							|  |  |  |       REQUIRE( | 
					
						
							|  |  |  |           graph_output_node.m_socket_accessor->m_inputs.size() | 
					
						
							|  |  |  |           == graph_loaded_output_node.m_socket_accessor->m_inputs.size()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       REQUIRE( | 
					
						
							|  |  |  |           graph_input_node.m_socket_accessor->m_outputs.size() | 
					
						
							|  |  |  |           == graph_loaded_input_node.m_socket_accessor->m_outputs.size()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       REQUIRE( | 
					
						
							|  |  |  |           graph_loaded_input_node.m_socket_accessor->FindOutputSocket( | 
					
						
							|  |  |  |               "GraphFloatInput") | 
					
						
							|  |  |  |           != nullptr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       REQUIRE( | 
					
						
							|  |  |  |           graph_loaded_output_node.m_socket_accessor->FindInputSocket( | 
					
						
							| 
									
										
										
										
											2022-04-03 21:05:11 +02:00
										 |  |  |               "GraphFloatOutput") | 
					
						
							| 
									
										
										
										
											2022-02-14 22:37:19 +01:00
										 |  |  |           != nullptr); | 
					
						
							|  |  |  |       REQUIRE( | 
					
						
							|  |  |  |           graph_loaded_output_node.m_socket_accessor->FindInputSocket( | 
					
						
							| 
									
										
										
										
											2022-04-03 21:05:11 +02:00
										 |  |  |               "GraphVec3Output") | 
					
						
							| 
									
										
										
										
											2022-02-14 22:37:19 +01:00
										 |  |  |           != nullptr); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-03 21:05:11 +02:00
										 |  |  |       WHEN("Instantiating an AnimGraph") { | 
					
						
							|  |  |  |         AnimGraph anim_graph = graph_resource_loaded.createInstance(); | 
					
						
							| 
									
										
										
										
											2022-03-25 12:05:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-03 21:05:11 +02:00
										 |  |  |         REQUIRE(anim_graph.getInputSocket("GraphFloatInput") != nullptr); | 
					
						
							| 
									
										
										
										
											2022-04-11 11:40:53 +02:00
										 |  |  |         REQUIRE( | 
					
						
							|  |  |  |             anim_graph.getInputPtr("GraphFloatInput") | 
					
						
							|  |  |  |             == anim_graph.m_input_buffer); | 
					
						
							| 
									
										
										
										
											2022-04-03 21:05:11 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         float* graph_float_input = nullptr; | 
					
						
							| 
									
										
										
										
											2022-04-11 11:40:53 +02:00
										 |  |  |         graph_float_input = | 
					
						
							|  |  |  |             static_cast<float*>(anim_graph.getInputPtr("GraphFloatInput")); | 
					
						
							| 
									
										
										
										
											2022-04-03 21:05:11 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         *graph_float_input = 123.456f; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-11 11:40:53 +02:00
										 |  |  |         AND_WHEN("Evaluating Graph") { | 
					
						
							| 
									
										
										
										
											2022-04-11 16:46:09 +02:00
										 |  |  |           AnimGraphContext context = {&anim_graph, nullptr}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-11 11:40:53 +02:00
										 |  |  |           anim_graph.updateTime(0.f); | 
					
						
							| 
									
										
										
										
											2022-04-11 16:46:09 +02:00
										 |  |  |           anim_graph.evaluate(context); | 
					
						
							| 
									
										
										
										
											2022-04-11 11:40:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |           Socket* float_output_socket = | 
					
						
							|  |  |  |               anim_graph.getOutputSocket("GraphFloatOutput"); | 
					
						
							|  |  |  |           Socket* vec3_output_socket = | 
					
						
							|  |  |  |               anim_graph.getOutputSocket("GraphVec3Output"); | 
					
						
							|  |  |  |           Vec3& vec3_output = | 
					
						
							| 
									
										
										
										
											2022-04-11 16:46:09 +02:00
										 |  |  |               *static_cast<Vec3*>(vec3_output_socket->m_reference.ptr); | 
					
						
							| 
									
										
										
										
											2022-04-11 11:40:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |           THEN("output vector components equal the graph input vaulues") { | 
					
						
							|  |  |  |             CHECK(vec3_output[0] == *graph_float_input); | 
					
						
							|  |  |  |             CHECK(vec3_output[1] == *graph_float_input); | 
					
						
							|  |  |  |             CHECK(vec3_output[2] == *graph_float_input); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST_CASE("SimpleMathEvaluations", "[AnimGraphResource]") { | 
					
						
							|  |  |  |   AnimGraphResource graph_resource_origin; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   graph_resource_origin.clear(); | 
					
						
							|  |  |  |   graph_resource_origin.m_name = "TestInputOutputGraph"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   size_t math_add0_node_index = | 
					
						
							|  |  |  |       graph_resource_origin.addNode(AnimNodeResourceFactory("MathAddNode")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   size_t math_add1_node_index = | 
					
						
							|  |  |  |       graph_resource_origin.addNode(AnimNodeResourceFactory("MathAddNode")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   AnimNodeResource& graph_output_node = | 
					
						
							|  |  |  |       graph_resource_origin.getGraphOutputNode(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   graph_output_node.m_socket_accessor->RegisterInput<float>( | 
					
						
							|  |  |  |       "GraphFloat0Output", | 
					
						
							|  |  |  |       nullptr); | 
					
						
							|  |  |  |   graph_output_node.m_socket_accessor->RegisterInput<float>( | 
					
						
							|  |  |  |       "GraphFloat1Output", | 
					
						
							|  |  |  |       nullptr); | 
					
						
							|  |  |  |   graph_output_node.m_socket_accessor->RegisterInput<float>( | 
					
						
							|  |  |  |       "GraphFloat2Output", | 
					
						
							|  |  |  |       nullptr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   AnimNodeResource& graph_input_node = | 
					
						
							|  |  |  |       graph_resource_origin.getGraphInputNode(); | 
					
						
							|  |  |  |   graph_input_node.m_socket_accessor->RegisterOutput<float>( | 
					
						
							|  |  |  |       "GraphFloatInput", | 
					
						
							|  |  |  |       nullptr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Prepare graph inputs and outputs
 | 
					
						
							|  |  |  |   AnimNodeResource& math_add0_node = | 
					
						
							|  |  |  |       graph_resource_origin.m_nodes[math_add0_node_index]; | 
					
						
							|  |  |  |   AnimNodeResource& math_add1_node = | 
					
						
							|  |  |  |       graph_resource_origin.m_nodes[math_add1_node_index]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // direct output
 | 
					
						
							|  |  |  |   REQUIRE(graph_resource_origin.connectSockets( | 
					
						
							|  |  |  |       graph_input_node, | 
					
						
							|  |  |  |       "GraphFloatInput", | 
					
						
							|  |  |  |       graph_output_node, | 
					
						
							|  |  |  |       "GraphFloat0Output")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // add0 node
 | 
					
						
							|  |  |  |   REQUIRE(graph_resource_origin.connectSockets( | 
					
						
							|  |  |  |       graph_input_node, | 
					
						
							|  |  |  |       "GraphFloatInput", | 
					
						
							|  |  |  |       math_add0_node, | 
					
						
							|  |  |  |       "Input0")); | 
					
						
							| 
									
										
										
										
											2022-04-03 21:05:11 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-11 11:40:53 +02:00
										 |  |  |   REQUIRE(graph_resource_origin.connectSockets( | 
					
						
							|  |  |  |       graph_input_node, | 
					
						
							|  |  |  |       "GraphFloatInput", | 
					
						
							|  |  |  |       math_add0_node, | 
					
						
							|  |  |  |       "Input1")); | 
					
						
							| 
									
										
										
										
											2022-02-14 22:37:19 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-11 11:40:53 +02:00
										 |  |  |   REQUIRE(graph_resource_origin.connectSockets( | 
					
						
							|  |  |  |       math_add0_node, | 
					
						
							|  |  |  |       "Output", | 
					
						
							|  |  |  |       graph_output_node, | 
					
						
							|  |  |  |       "GraphFloat1Output")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // add1 node
 | 
					
						
							|  |  |  |   REQUIRE(graph_resource_origin.connectSockets( | 
					
						
							|  |  |  |       math_add0_node, | 
					
						
							|  |  |  |       "Output", | 
					
						
							|  |  |  |       math_add1_node, | 
					
						
							|  |  |  |       "Input0")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   REQUIRE(graph_resource_origin.connectSockets( | 
					
						
							|  |  |  |       graph_input_node, | 
					
						
							|  |  |  |       "GraphFloatInput", | 
					
						
							|  |  |  |       math_add1_node, | 
					
						
							|  |  |  |       "Input1")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   REQUIRE(graph_resource_origin.connectSockets( | 
					
						
							|  |  |  |       math_add1_node, | 
					
						
							|  |  |  |       "Output", | 
					
						
							|  |  |  |       graph_output_node, | 
					
						
							|  |  |  |       "GraphFloat2Output")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   WHEN("Saving and loading graph resource") { | 
					
						
							|  |  |  |     const char* filename = "ResourceSaveLoadGraphInputs.json"; | 
					
						
							|  |  |  |     graph_resource_origin.saveToFile(filename); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     AnimGraphResource graph_resource_loaded; | 
					
						
							|  |  |  |     graph_resource_loaded.loadFromFile(filename); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const AnimNodeResource& graph_loaded_output_node = | 
					
						
							|  |  |  |         graph_resource_loaded.m_nodes[0]; | 
					
						
							|  |  |  |     const AnimNodeResource& graph_loaded_input_node = | 
					
						
							|  |  |  |         graph_resource_loaded.m_nodes[1]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     WHEN("Instantiating an AnimGraph") { | 
					
						
							|  |  |  |       AnimGraph anim_graph = graph_resource_loaded.createInstance(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       REQUIRE(anim_graph.getInputSocket("GraphFloatInput") != nullptr); | 
					
						
							|  |  |  |       REQUIRE( | 
					
						
							|  |  |  |           anim_graph.getInputPtr("GraphFloatInput") | 
					
						
							|  |  |  |           == anim_graph.m_input_buffer); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       float* graph_float_input = nullptr; | 
					
						
							|  |  |  |       graph_float_input = | 
					
						
							|  |  |  |           static_cast<float*>(anim_graph.getInputPtr("GraphFloatInput")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       *graph_float_input = 123.456f; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       AND_WHEN("Evaluating Graph") { | 
					
						
							| 
									
										
										
										
											2022-04-11 16:46:09 +02:00
										 |  |  |         AnimGraphContext context = {&anim_graph, nullptr}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-11 11:40:53 +02:00
										 |  |  |         anim_graph.updateTime(0.f); | 
					
						
							| 
									
										
										
										
											2022-04-11 16:46:09 +02:00
										 |  |  |         anim_graph.evaluate(context); | 
					
						
							| 
									
										
										
										
											2022-04-03 21:05:11 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-11 11:40:53 +02:00
										 |  |  |         Socket* float0_output_socket = | 
					
						
							|  |  |  |             anim_graph.getOutputSocket("GraphFloat0Output"); | 
					
						
							|  |  |  |         Socket* float1_output_socket = | 
					
						
							|  |  |  |             anim_graph.getOutputSocket("GraphFloat1Output"); | 
					
						
							|  |  |  |         Socket* float2_output_socket = | 
					
						
							|  |  |  |             anim_graph.getOutputSocket("GraphFloat2Output"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         REQUIRE(float0_output_socket != nullptr); | 
					
						
							|  |  |  |         REQUIRE(float1_output_socket != nullptr); | 
					
						
							|  |  |  |         REQUIRE(float2_output_socket != nullptr); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-11 16:46:09 +02:00
										 |  |  |         float& float0_output = | 
					
						
							|  |  |  |             *static_cast<float*>(float0_output_socket->m_reference.ptr); | 
					
						
							|  |  |  |         float& float1_output = | 
					
						
							|  |  |  |             *static_cast<float*>(float1_output_socket->m_reference.ptr); | 
					
						
							|  |  |  |         float& float2_output = | 
					
						
							|  |  |  |             *static_cast<float*>(float2_output_socket->m_reference.ptr); | 
					
						
							| 
									
										
										
										
											2022-04-11 11:40:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         THEN("output vector components equal the graph input vaulues") { | 
					
						
							|  |  |  |           CHECK(float0_output == Approx(*graph_float_input)); | 
					
						
							|  |  |  |           CHECK(float1_output == Approx(*graph_float_input * 2.)); | 
					
						
							|  |  |  |           CHECK(float2_output == Approx(*graph_float_input * 3.)); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-04-03 21:05:11 +02:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2022-02-14 22:37:19 +01:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2022-04-03 21:05:11 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2022-02-14 22:37:19 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   WHEN("Connecting input to output and instantiating the graph") { | 
					
						
							|  |  |  |     AnimNodeResource& graph_output_node = graph_resource_origin.m_nodes[0]; | 
					
						
							|  |  |  |     AnimNodeResource& graph_input_node = graph_resource_origin.m_nodes[1]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     REQUIRE(graph_resource_origin.connectSockets( | 
					
						
							|  |  |  |         graph_input_node, | 
					
						
							|  |  |  |         "GraphAnimInput", | 
					
						
							|  |  |  |         graph_output_node, | 
					
						
							|  |  |  |         "GraphOutput")); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-25 12:05:56 +01:00
										 |  |  |     AnimGraph anim_graph = graph_resource_origin.createInstance(); | 
					
						
							| 
									
										
										
										
											2022-02-14 22:37:19 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-24 23:47:31 +01:00
										 |  |  |     void* graph_anim_input_ptr = anim_graph.getInput("GraphAnimInput"); | 
					
						
							|  |  |  |     void* graph_output_ptr = anim_graph.getOutput("GraphOutput"); | 
					
						
							| 
									
										
										
										
											2022-02-14 22:37:19 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     REQUIRE(graph_anim_input_ptr == graph_output_ptr); | 
					
						
							|  |  |  |     REQUIRE(graph_output_ptr == anim_graph.m_output_buffer); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     REQUIRE( | 
					
						
							| 
									
										
										
										
											2022-02-24 23:47:31 +01:00
										 |  |  |         anim_graph.getInput("GraphAnimInput") | 
					
						
							|  |  |  |         == anim_graph.getOutput("GraphOutput")); | 
					
						
							| 
									
										
										
										
											2022-02-14 22:37:19 +01:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST_CASE("GraphInputOutputConnectivity", "[AnimGraphResource]") { | 
					
						
							|  |  |  |   AnimGraphResource graph_resource; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   graph_resource.clear(); | 
					
						
							|  |  |  |   graph_resource.m_name = "TestGraphInputOutputConnectivity"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   AnimNodeResource& graph_output_node = graph_resource.m_nodes[0]; | 
					
						
							|  |  |  |   graph_output_node.m_socket_accessor->RegisterInput<float>( | 
					
						
							|  |  |  |       "GraphFloatOutput", | 
					
						
							|  |  |  |       nullptr); | 
					
						
							|  |  |  |   graph_output_node.m_socket_accessor->RegisterInput<AnimData>( | 
					
						
							|  |  |  |       "GraphAnimOutput", | 
					
						
							|  |  |  |       nullptr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   AnimNodeResource& graph_input_node = graph_resource.m_nodes[1]; | 
					
						
							|  |  |  |   graph_input_node.m_socket_accessor->RegisterOutput<float>( | 
					
						
							|  |  |  |       "GraphFloatInput", | 
					
						
							|  |  |  |       nullptr); | 
					
						
							| 
									
										
										
										
											2022-02-22 22:03:26 +01:00
										 |  |  |   graph_input_node.m_socket_accessor->RegisterOutput<float>( | 
					
						
							|  |  |  |       "SpeedScaleInput", | 
					
						
							|  |  |  |       nullptr); | 
					
						
							| 
									
										
										
										
											2022-02-14 22:37:19 +01:00
										 |  |  |   graph_input_node.m_socket_accessor->RegisterOutput<AnimData>( | 
					
						
							|  |  |  |       "GraphAnimInput0", | 
					
						
							|  |  |  |       nullptr); | 
					
						
							|  |  |  |   graph_input_node.m_socket_accessor->RegisterOutput<AnimData>( | 
					
						
							|  |  |  |       "GraphAnimInput1", | 
					
						
							|  |  |  |       nullptr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   WHEN("Connecting float input with float output") { | 
					
						
							|  |  |  |     REQUIRE(graph_resource.connectSockets( | 
					
						
							|  |  |  |         graph_resource.getGraphInputNode(), | 
					
						
							|  |  |  |         "GraphFloatInput", | 
					
						
							|  |  |  |         graph_resource.getGraphOutputNode(), | 
					
						
							|  |  |  |         "GraphFloatOutput")); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-25 12:05:56 +01:00
										 |  |  |     AnimGraph anim_graph = graph_resource.createInstance(); | 
					
						
							| 
									
										
										
										
											2022-02-14 22:37:19 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-19 12:16:57 +01:00
										 |  |  |     THEN("Writing to the input pointer changes the value of the output.") { | 
					
						
							| 
									
										
										
										
											2022-02-24 23:47:31 +01:00
										 |  |  |       float* float_input_ptr = (float*)anim_graph.getInput("GraphFloatInput"); | 
					
						
							| 
									
										
										
										
											2022-02-14 22:37:19 +01:00
										 |  |  |       REQUIRE(float_input_ptr != nullptr); | 
					
						
							|  |  |  |       *float_input_ptr = 23.123f; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       float* float_output_ptr = | 
					
						
							| 
									
										
										
										
											2022-02-24 23:47:31 +01:00
										 |  |  |           (float*)anim_graph.getOutput("GraphFloatOutput"); | 
					
						
							| 
									
										
										
										
											2022-02-14 22:37:19 +01:00
										 |  |  |       REQUIRE(float_output_ptr != nullptr); | 
					
						
							|  |  |  |       CHECK(*float_output_ptr == Approx(23.123f)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   WHEN("Connecting adding a Blend2 node") { | 
					
						
							| 
									
										
										
										
											2022-02-19 12:16:57 +01:00
										 |  |  |     size_t blend2_node_index = | 
					
						
							|  |  |  |         graph_resource.addNode(AnimNodeResourceFactory("Blend2")); | 
					
						
							|  |  |  |     AnimNodeResource& blend2_node_resource = | 
					
						
							|  |  |  |         graph_resource.m_nodes[blend2_node_index]; | 
					
						
							| 
									
										
										
										
											2022-02-14 22:37:19 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     REQUIRE(graph_resource.connectSockets( | 
					
						
							|  |  |  |         graph_resource.getGraphInputNode(), | 
					
						
							|  |  |  |         "GraphFloatInput", | 
					
						
							|  |  |  |         blend2_node_resource, | 
					
						
							|  |  |  |         "Weight")); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-19 12:16:57 +01:00
										 |  |  |     THEN("Connected float input points to the blend weight.") { | 
					
						
							| 
									
										
										
										
											2022-03-25 12:05:56 +01:00
										 |  |  |       AnimGraph anim_graph = graph_resource.createInstance(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-19 12:16:57 +01:00
										 |  |  |       Blend2Node* blend2_node = | 
					
						
							|  |  |  |           dynamic_cast<Blend2Node*>(anim_graph.m_nodes[blend2_node_index]); | 
					
						
							| 
									
										
										
										
											2022-02-14 22:37:19 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-19 12:16:57 +01:00
										 |  |  |       REQUIRE( | 
					
						
							| 
									
										
										
										
											2022-04-11 16:46:09 +02:00
										 |  |  |           *anim_graph.m_socket_accessor->m_outputs[0].m_reference.ptr_ptr | 
					
						
							| 
									
										
										
										
											2022-04-01 13:19:54 +02:00
										 |  |  |           == blend2_node->i_blend_weight); | 
					
						
							| 
									
										
										
										
											2022-02-24 23:47:31 +01:00
										 |  |  |       float* float_input_ptr = (float*)anim_graph.getInput("GraphFloatInput"); | 
					
						
							| 
									
										
										
										
											2022-04-01 13:19:54 +02:00
										 |  |  |       REQUIRE(float_input_ptr == blend2_node->i_blend_weight); | 
					
						
							| 
									
										
										
										
											2022-02-14 22:37:19 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-19 12:16:57 +01:00
										 |  |  |     WHEN( | 
					
						
							|  |  |  |         "Connecting AnimData inputs to blend2 node and blend2 output to graph " | 
					
						
							|  |  |  |         "output.") { | 
					
						
							| 
									
										
										
										
											2022-02-14 22:37:19 +01:00
										 |  |  |       REQUIRE(graph_resource.connectSockets( | 
					
						
							|  |  |  |           graph_resource.getGraphInputNode(), | 
					
						
							|  |  |  |           "GraphAnimInput0", | 
					
						
							|  |  |  |           blend2_node_resource, | 
					
						
							|  |  |  |           "Input0")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       REQUIRE(graph_resource.connectSockets( | 
					
						
							|  |  |  |           graph_resource.getGraphInputNode(), | 
					
						
							|  |  |  |           "GraphAnimInput1", | 
					
						
							|  |  |  |           blend2_node_resource, | 
					
						
							|  |  |  |           "Input1")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       REQUIRE(graph_resource.connectSockets( | 
					
						
							|  |  |  |           blend2_node_resource, | 
					
						
							|  |  |  |           "Output", | 
					
						
							|  |  |  |           graph_resource.getGraphOutputNode(), | 
					
						
							| 
									
										
										
										
											2022-02-19 12:16:57 +01:00
										 |  |  |           "GraphAnimOutput")); | 
					
						
							| 
									
										
										
										
											2022-02-14 22:37:19 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-19 12:16:57 +01:00
										 |  |  |       THEN( | 
					
						
							|  |  |  |           "AnimData from output gets blended and result is written to " | 
					
						
							|  |  |  |           "Output.") { | 
					
						
							| 
									
										
										
										
											2022-03-25 12:05:56 +01:00
										 |  |  |         AnimGraph anim_graph = graph_resource.createInstance(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-19 12:16:57 +01:00
										 |  |  |         Blend2Node* blend2_node = | 
					
						
							|  |  |  |             dynamic_cast<Blend2Node*>(anim_graph.m_nodes[blend2_node_index]); | 
					
						
							| 
									
										
										
										
											2022-02-14 22:37:19 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-19 12:16:57 +01:00
										 |  |  |         AnimData* graph_input0 = | 
					
						
							| 
									
										
										
										
											2022-02-24 23:47:31 +01:00
										 |  |  |             (AnimData*)anim_graph.getInput("GraphAnimInput0"); | 
					
						
							| 
									
										
										
										
											2022-04-01 13:19:54 +02:00
										 |  |  |         REQUIRE(graph_input0 == blend2_node->i_input0); | 
					
						
							| 
									
										
										
										
											2022-02-19 12:16:57 +01:00
										 |  |  |         REQUIRE( | 
					
						
							|  |  |  |             anim_graph.m_nodes[1] | 
					
						
							|  |  |  |             == anim_graph.getAnimNodeForInput(blend2_node_index, "Input0")); | 
					
						
							| 
									
										
										
										
											2022-02-14 22:37:19 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-19 12:16:57 +01:00
										 |  |  |         AnimData* graph_input1 = | 
					
						
							| 
									
										
										
										
											2022-02-24 23:47:31 +01:00
										 |  |  |             (AnimData*)anim_graph.getInput("GraphAnimInput1"); | 
					
						
							| 
									
										
										
										
											2022-04-01 13:19:54 +02:00
										 |  |  |         REQUIRE(graph_input1 == blend2_node->i_input1); | 
					
						
							| 
									
										
										
										
											2022-02-19 12:16:57 +01:00
										 |  |  |         REQUIRE( | 
					
						
							|  |  |  |             anim_graph.m_nodes[1] | 
					
						
							|  |  |  |             == anim_graph.getAnimNodeForInput(blend2_node_index, "Input1")); | 
					
						
							| 
									
										
										
										
											2022-02-14 22:37:19 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-19 12:16:57 +01:00
										 |  |  |         AnimData* graph_output = | 
					
						
							| 
									
										
										
										
											2022-02-24 23:47:31 +01:00
										 |  |  |             (AnimData*)anim_graph.getOutput("GraphAnimOutput"); | 
					
						
							| 
									
										
										
										
											2022-04-01 13:19:54 +02:00
										 |  |  |         REQUIRE(graph_output == blend2_node->o_output); | 
					
						
							| 
									
										
										
										
											2022-02-19 12:16:57 +01:00
										 |  |  |         REQUIRE( | 
					
						
							|  |  |  |             anim_graph.m_nodes[blend2_node_index] | 
					
						
							|  |  |  |             == anim_graph.getAnimNodeForInput(0, "GraphAnimOutput")); | 
					
						
							| 
									
										
										
										
											2022-02-14 22:37:19 +01:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2022-02-19 12:16:57 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   WHEN("Adding AnimSampler Nodes") { | 
					
						
							|  |  |  |     size_t blend2_node_index = | 
					
						
							|  |  |  |         graph_resource.addNode(AnimNodeResourceFactory("Blend2")); | 
					
						
							|  |  |  |     size_t sampler_node_index = | 
					
						
							|  |  |  |         graph_resource.addNode(AnimNodeResourceFactory("AnimSampler")); | 
					
						
							|  |  |  |     size_t speed_scale_node_index = | 
					
						
							|  |  |  |         graph_resource.addNode(AnimNodeResourceFactory("SpeedScale")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     AnimNodeResource& blend2_node_resource = | 
					
						
							|  |  |  |         graph_resource.m_nodes[blend2_node_index]; | 
					
						
							|  |  |  |     AnimNodeResource& sampler_node_resource = | 
					
						
							|  |  |  |         graph_resource.m_nodes[sampler_node_index]; | 
					
						
							|  |  |  |     AnimNodeResource& speed_scale_node_resource = | 
					
						
							|  |  |  |         graph_resource.m_nodes[speed_scale_node_index]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     REQUIRE(graph_resource.connectSockets( | 
					
						
							|  |  |  |         graph_resource.getGraphInputNode(), | 
					
						
							|  |  |  |         "GraphFloatInput", | 
					
						
							|  |  |  |         blend2_node_resource, | 
					
						
							|  |  |  |         "Weight")); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-22 22:03:26 +01:00
										 |  |  |     REQUIRE(graph_resource.connectSockets( | 
					
						
							|  |  |  |         graph_resource.getGraphInputNode(), | 
					
						
							|  |  |  |         "SpeedScaleInput", | 
					
						
							|  |  |  |         speed_scale_node_resource, | 
					
						
							|  |  |  |         "SpeedScale")); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-19 12:16:57 +01:00
										 |  |  |     REQUIRE(graph_resource.connectSockets( | 
					
						
							|  |  |  |         graph_resource.getGraphInputNode(), | 
					
						
							|  |  |  |         "GraphAnimInput0", | 
					
						
							|  |  |  |         blend2_node_resource, | 
					
						
							|  |  |  |         "Input0")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     REQUIRE(graph_resource.connectSockets( | 
					
						
							|  |  |  |         sampler_node_resource, | 
					
						
							|  |  |  |         "Output", | 
					
						
							|  |  |  |         speed_scale_node_resource, | 
					
						
							|  |  |  |         "Input")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     REQUIRE(graph_resource.connectSockets( | 
					
						
							|  |  |  |         speed_scale_node_resource, | 
					
						
							|  |  |  |         "Output", | 
					
						
							|  |  |  |         blend2_node_resource, | 
					
						
							|  |  |  |         "Input1")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     REQUIRE(graph_resource.connectSockets( | 
					
						
							|  |  |  |         blend2_node_resource, | 
					
						
							|  |  |  |         "Output", | 
					
						
							|  |  |  |         graph_resource.getGraphOutputNode(), | 
					
						
							|  |  |  |         "GraphAnimOutput")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     THEN("Data flow and node ordering must be correct.") { | 
					
						
							| 
									
										
										
										
											2022-03-25 12:05:56 +01:00
										 |  |  |       AnimGraph anim_graph = graph_resource.createInstance(); | 
					
						
							| 
									
										
										
										
											2022-02-19 12:16:57 +01:00
										 |  |  |       Blend2Node* blend2_node = | 
					
						
							|  |  |  |           dynamic_cast<Blend2Node*>(anim_graph.m_nodes[blend2_node_index]); | 
					
						
							|  |  |  |       SpeedScaleNode* speed_scale_node = dynamic_cast<SpeedScaleNode*>( | 
					
						
							|  |  |  |           anim_graph.m_nodes[speed_scale_node_index]); | 
					
						
							|  |  |  |       AnimSamplerNode* sampler_node = dynamic_cast<AnimSamplerNode*>( | 
					
						
							|  |  |  |           anim_graph.m_nodes[sampler_node_index]); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-19 12:18:54 +01:00
										 |  |  |       //
 | 
					
						
							|  |  |  |       // check connectivity
 | 
					
						
							|  |  |  |       //
 | 
					
						
							| 
									
										
										
										
											2022-02-19 12:16:57 +01:00
										 |  |  |       AnimData* graph_input0 = | 
					
						
							| 
									
										
										
										
											2022-02-24 23:47:31 +01:00
										 |  |  |           (AnimData*)anim_graph.getInput("GraphAnimInput0"); | 
					
						
							| 
									
										
										
										
											2022-04-01 13:19:54 +02:00
										 |  |  |       REQUIRE(graph_input0 == blend2_node->i_input0); | 
					
						
							| 
									
										
										
										
											2022-02-19 12:16:57 +01:00
										 |  |  |       REQUIRE( | 
					
						
							|  |  |  |           anim_graph.m_nodes[1] | 
					
						
							|  |  |  |           == anim_graph.getAnimNodeForInput(blend2_node_index, "Input0")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       AnimData* graph_input1 = | 
					
						
							| 
									
										
										
										
											2022-02-24 23:47:31 +01:00
										 |  |  |           (AnimData*)anim_graph.getInput("GraphAnimInput1"); | 
					
						
							| 
									
										
										
										
											2022-02-19 12:16:57 +01:00
										 |  |  |       REQUIRE(graph_input1 == nullptr); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-01 13:19:54 +02:00
										 |  |  |       REQUIRE(sampler_node->o_output == speed_scale_node->i_input); | 
					
						
							| 
									
										
										
										
											2022-02-19 12:16:57 +01:00
										 |  |  |       REQUIRE( | 
					
						
							|  |  |  |           sampler_node | 
					
						
							|  |  |  |           == anim_graph.getAnimNodeForInput(speed_scale_node_index, "Input")); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-11 16:46:09 +02:00
										 |  |  |       REQUIRE(speed_scale_node->o_output == blend2_node->i_input1); | 
					
						
							| 
									
										
										
										
											2022-02-19 12:16:57 +01:00
										 |  |  |       REQUIRE( | 
					
						
							|  |  |  |           speed_scale_node | 
					
						
							|  |  |  |           == anim_graph.getAnimNodeForInput(blend2_node_index, "Input1")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       AnimData* graph_output = | 
					
						
							| 
									
										
										
										
											2022-02-24 23:47:31 +01:00
										 |  |  |           (AnimData*)anim_graph.getOutput("GraphAnimOutput"); | 
					
						
							| 
									
										
										
										
											2022-04-01 13:19:54 +02:00
										 |  |  |       REQUIRE(graph_output == blend2_node->o_output); | 
					
						
							| 
									
										
										
										
											2022-02-19 12:16:57 +01:00
										 |  |  |       REQUIRE( | 
					
						
							|  |  |  |           anim_graph.m_nodes[blend2_node_index] | 
					
						
							|  |  |  |           == anim_graph.getAnimNodeForInput(0, "GraphAnimOutput")); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-19 12:18:54 +01:00
										 |  |  |       //
 | 
					
						
							|  |  |  |       // check ordering
 | 
					
						
							|  |  |  |       //
 | 
					
						
							| 
									
										
										
										
											2022-02-20 15:57:19 +01:00
										 |  |  |       REQUIRE( | 
					
						
							| 
									
										
										
										
											2022-02-22 22:03:26 +01:00
										 |  |  |           anim_graph.getNodeEvalOrderIndex(blend2_node) | 
					
						
							|  |  |  |           < anim_graph.getNodeEvalOrderIndex(sampler_node)); | 
					
						
							| 
									
										
										
										
											2022-02-20 15:57:19 +01:00
										 |  |  |       REQUIRE( | 
					
						
							| 
									
										
										
										
											2022-02-22 22:03:26 +01:00
										 |  |  |           anim_graph.getNodeEvalOrderIndex(blend2_node) | 
					
						
							|  |  |  |           < anim_graph.getNodeEvalOrderIndex(speed_scale_node)); | 
					
						
							| 
									
										
										
										
											2022-02-20 15:57:19 +01:00
										 |  |  |       REQUIRE( | 
					
						
							| 
									
										
										
										
											2022-02-22 22:03:26 +01:00
										 |  |  |           anim_graph.getNodeEvalOrderIndex(speed_scale_node) | 
					
						
							|  |  |  |           < anim_graph.getNodeEvalOrderIndex(sampler_node)); | 
					
						
							| 
									
										
										
										
											2022-02-20 15:57:19 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     WHEN("Instantiating graph") { | 
					
						
							| 
									
										
										
										
											2022-03-25 12:05:56 +01:00
										 |  |  |       AnimGraph anim_graph = graph_resource.createInstance(); | 
					
						
							| 
									
										
										
										
											2022-02-20 15:57:19 +01:00
										 |  |  |       float* blend_weight_input = | 
					
						
							| 
									
										
										
										
											2022-02-24 23:47:31 +01:00
										 |  |  |           reinterpret_cast<float*>(anim_graph.getInput("GraphFloatInput")); | 
					
						
							| 
									
										
										
										
											2022-02-20 15:57:19 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |       Blend2Node* blend2_node = | 
					
						
							|  |  |  |           dynamic_cast<Blend2Node*>(anim_graph.m_nodes[blend2_node_index]); | 
					
						
							|  |  |  |       SpeedScaleNode* speed_scale_node = dynamic_cast<SpeedScaleNode*>( | 
					
						
							|  |  |  |           anim_graph.m_nodes[speed_scale_node_index]); | 
					
						
							|  |  |  |       AnimSamplerNode* sampler_node = dynamic_cast<AnimSamplerNode*>( | 
					
						
							|  |  |  |           anim_graph.m_nodes[sampler_node_index]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       WHEN("Setting weight to 0. and marking nodes active.") { | 
					
						
							|  |  |  |         *blend_weight_input = 0.; | 
					
						
							| 
									
										
										
										
											2022-02-24 23:47:31 +01:00
										 |  |  |         anim_graph.markActiveNodes(); | 
					
						
							| 
									
										
										
										
											2022-02-20 15:57:19 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         THEN("Speed scale and sampler node are inactive") { | 
					
						
							| 
									
										
										
										
											2022-02-24 23:47:31 +01:00
										 |  |  |           REQUIRE(anim_graph.checkIsNodeActive(speed_scale_node) == false); | 
					
						
							|  |  |  |           REQUIRE(anim_graph.checkIsNodeActive(sampler_node) == false); | 
					
						
							| 
									
										
										
										
											2022-02-20 15:57:19 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       WHEN("Setting weight to 0. and marking nodes active") { | 
					
						
							|  |  |  |         *blend_weight_input = 0.1; | 
					
						
							| 
									
										
										
										
											2022-02-24 23:47:31 +01:00
										 |  |  |         anim_graph.markActiveNodes(); | 
					
						
							| 
									
										
										
										
											2022-02-20 15:57:19 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         THEN("Speed scale and sampler nodes are active") { | 
					
						
							| 
									
										
										
										
											2022-02-24 23:47:31 +01:00
										 |  |  |           REQUIRE(anim_graph.checkIsNodeActive(speed_scale_node) == true); | 
					
						
							|  |  |  |           REQUIRE(anim_graph.checkIsNodeActive(sampler_node) == true); | 
					
						
							| 
									
										
										
										
											2022-02-20 15:57:19 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       WHEN("Setting weight to 1. and marking nodes active") { | 
					
						
							|  |  |  |         *blend_weight_input = 1.0; | 
					
						
							| 
									
										
										
										
											2022-02-24 23:47:31 +01:00
										 |  |  |         anim_graph.markActiveNodes(); | 
					
						
							| 
									
										
										
										
											2022-02-20 15:57:19 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         THEN("Speed scale and sampler nodes are active") { | 
					
						
							| 
									
										
										
										
											2022-02-24 23:47:31 +01:00
										 |  |  |           REQUIRE(anim_graph.checkIsNodeActive(speed_scale_node) == true); | 
					
						
							|  |  |  |           REQUIRE(anim_graph.checkIsNodeActive(sampler_node) == true); | 
					
						
							| 
									
										
										
										
											2022-02-20 15:57:19 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2022-02-22 22:03:26 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |       WHEN("Updating time with dt = 0.3f and speed scale = 1.0f") { | 
					
						
							|  |  |  |         float* speed_scale_input = | 
					
						
							| 
									
										
										
										
											2022-02-24 23:47:31 +01:00
										 |  |  |             reinterpret_cast<float*>(anim_graph.getInput("SpeedScaleInput")); | 
					
						
							| 
									
										
										
										
											2022-02-22 22:03:26 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         *blend_weight_input = 0.1; | 
					
						
							|  |  |  |         *speed_scale_input = 1.0f; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-24 23:47:31 +01:00
										 |  |  |         anim_graph.markActiveNodes(); | 
					
						
							|  |  |  |         anim_graph.updateTime(0.3f); | 
					
						
							| 
									
										
										
										
											2022-02-22 22:03:26 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         THEN ("Anim sampler node time now must be 0.3f") { | 
					
						
							|  |  |  |           REQUIRE(sampler_node->m_time_now == Approx(0.3f)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       WHEN("Updating time with dt = 0.3f and speed scale = 1.3f") { | 
					
						
							|  |  |  |         float* speed_scale_input = | 
					
						
							| 
									
										
										
										
											2022-02-24 23:47:31 +01:00
										 |  |  |             reinterpret_cast<float*>(anim_graph.getInput("SpeedScaleInput")); | 
					
						
							| 
									
										
										
										
											2022-02-22 22:03:26 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         *blend_weight_input = 0.1; | 
					
						
							|  |  |  |         *speed_scale_input = 1.3f; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-24 23:47:31 +01:00
										 |  |  |         anim_graph.markActiveNodes(); | 
					
						
							|  |  |  |         anim_graph.updateTime(0.3f); | 
					
						
							| 
									
										
										
										
											2022-02-22 22:03:26 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         THEN ("Anim sampler node time now must be 0.39f") { | 
					
						
							|  |  |  |           REQUIRE(sampler_node->m_time_now == Approx(0.39f)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2022-02-19 12:16:57 +01:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2022-04-01 13:19:54 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  */ |