diff --git a/src/AnimGraph/AnimGraphData.h b/src/AnimGraph/AnimGraphData.h index cbf0385..3cff8da 100644 --- a/src/AnimGraph/AnimGraphData.h +++ b/src/AnimGraph/AnimGraphData.h @@ -269,6 +269,11 @@ struct AnimGraphConnection { bool m_crosses_hierarchy = false; }; +/** Maps socket names to actual memory locations of the corresponding sockets. + * + * This class is needed when instantiating a Blend Tree but also for the editor. + * It also acts as a virtual socket container for input and output sockets for Blend Trees. + */ struct NodeDescriptorBase { std::vector m_inputs; std::vector m_outputs; @@ -346,7 +351,7 @@ struct NodeDescriptorBase { *socket->m_reference.ptr_ptr = value_ptr; } - Socket* GetInputSocket(const char* name) { + Socket* GetInputSocket(const char* name) const { return FindSocket(name, m_inputs); } @@ -366,7 +371,7 @@ struct NodeDescriptorBase { *socket->m_reference.ptr_ptr = value_ptr; } - Socket* GetOutputSocket(const char* name) { + Socket* GetOutputSocket(const char* name) const { return FindSocket(name, m_outputs); } @@ -421,21 +426,11 @@ struct NodeDescriptorBase { virtual void UpdateFlags() {}; protected: - Socket* FindSocket(const char* name, std::vector& sockets) { - for (size_t i = 0, n = sockets.size(); i < n; i++) { - if (sockets[i].m_name == name) { - return &sockets[i]; - } - } - - return nullptr; - } - - const Socket* FindSocket(const char* name, const std::vector& sockets) + Socket* FindSocket(const char* name, const std::vector& sockets) const { for (size_t i = 0, n = sockets.size(); i < n; i++) { if (sockets[i].m_name == name) { - return &sockets[i]; + return const_cast(&sockets[i]); } } diff --git a/src/AnimGraph/AnimGraphEditor.cc b/src/AnimGraph/AnimGraphEditor.cc index fffc34e..ea3f0ff 100644 --- a/src/AnimGraph/AnimGraphEditor.cc +++ b/src/AnimGraph/AnimGraphEditor.cc @@ -185,11 +185,13 @@ void AnimGraphEditorRenderSidebar( } int num_properties = 0; - if (node_resource->m_socket_accessor != nullptr) { - num_properties = node_resource->m_socket_accessor->m_properties.size(); + if (node_resource->m_virtual_socket_accessor != nullptr) { + num_properties = + node_resource->m_virtual_socket_accessor->m_properties.size(); } for (int i = 0; i < num_properties; i++) { - Socket& property = node_resource->m_socket_accessor->m_properties[i]; + Socket& property = + node_resource->m_virtual_socket_accessor->m_properties[i]; if (property.m_type == SocketType::SocketTypeInt) { ImGui::InputInt( property.m_name.c_str(), @@ -228,7 +230,8 @@ void AnimGraphEditorRenderSidebar( ImGui::Text("Outputs"); // Graph outputs are the inputs of the output node! - std::vector& outputs = node_resource->m_socket_accessor->m_inputs; + std::vector& outputs = + node_resource->m_virtual_socket_accessor->m_inputs; std::vector::iterator iter = outputs.begin(); while (iter != outputs.end()) { @@ -264,7 +267,8 @@ void AnimGraphEditorRenderSidebar( ImGui::Text("Inputs"); // Graph inputs are the outputs of the input node! - std::vector& inputs = node_resource->m_socket_accessor->m_outputs; + std::vector& inputs = + node_resource->m_virtual_socket_accessor->m_outputs; std::vector::iterator iter = inputs.begin(); while (iter != inputs.end()) { @@ -273,7 +277,7 @@ void AnimGraphEditorRenderSidebar( if (NodeSocketEditor(input)) { AnimGraphResource* current_graph_resource = sEditorState.hierarchyStack[sEditorState.hierarchyStackIndex]; - current_graph_resource->m_socket_accessor->m_inputs = inputs; + current_graph_resource->m_virtual_socket_accessor->m_inputs = inputs; } if (ImGui::Button("X")) { RemoveBlendTreeConnectionsForSocket( @@ -302,7 +306,7 @@ void AnimGraphEditorClear() { } if (sEditorState.rootGraphResource) { - delete sEditorState.rootGraphResource->m_socket_accessor; + delete sEditorState.rootGraphResource->m_virtual_socket_accessor; } delete sEditorState.rootGraphResource; @@ -310,7 +314,8 @@ void AnimGraphEditorClear() { sEditorState.rootGraphResource->m_name = "Root"; sEditorState.rootGraphResource->m_graph_type_name = "BlendTree"; sEditorState.rootGraphResource->m_blend_tree_resource.InitGraphConnectors(); - sEditorState.rootGraphResource->m_socket_accessor = new NodeDescriptorBase; + sEditorState.rootGraphResource->m_virtual_socket_accessor = + new NodeDescriptorBase; sEditorState.hierarchyStack.clear(); sEditorState.hierarchyStack.push_back(sEditorState.rootGraphResource); @@ -462,7 +467,7 @@ void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context) { ->m_blend_tree_resource.GetNode( connection_resource->source_node_index); int source_socket_index = - source_node_resource->m_socket_accessor->GetOutputIndex( + source_node_resource->m_virtual_socket_accessor->GetOutputIndex( connection_resource->source_socket_name.c_str()); const AnimNodeResource* target_node_resource = @@ -470,7 +475,7 @@ void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context) { ->m_blend_tree_resource.GetNode( connection_resource->target_node_index); int target_socket_index = - target_node_resource->m_socket_accessor->GetInputIndex( + target_node_resource->m_virtual_socket_accessor->GetInputIndex( connection_resource->target_socket_name.c_str()); int source_socket_pin_id = NodeIndexAndSocketIndexToOutputPinId( @@ -504,7 +509,7 @@ void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context) { source_node = sEditorState.hierarchyStack[sEditorState.hierarchyStackIndex] ->m_blend_tree_resource.GetNode(source_node_index); - if (source_node->m_socket_accessor->m_outputs.size() + if (source_node->m_virtual_socket_accessor->m_outputs.size() < source_node_socket_index) { source_node_socket_index = -1; } else { @@ -530,7 +535,7 @@ void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context) { target_node = sEditorState.hierarchyStack[sEditorState.hierarchyStackIndex] ->m_blend_tree_resource.GetNode(target_node_index); - if (target_node->m_socket_accessor->m_inputs.size() + if (target_node->m_virtual_socket_accessor->m_inputs.size() < target_node_socket_index) { target_node_socket_index = -1; } else { diff --git a/src/AnimGraph/AnimGraphNodes.cc b/src/AnimGraph/AnimGraphNodes.cc index 4d4f321..1e63a2c 100644 --- a/src/AnimGraph/AnimGraphNodes.cc +++ b/src/AnimGraph/AnimGraphNodes.cc @@ -13,7 +13,7 @@ AnimNode* AnimNodeFactory(const std::string& name) { AnimNode* result = nullptr; - + if (name == "Blend2") { result = new Blend2Node; } else if (name == "SpeedScale") { @@ -72,6 +72,29 @@ NodeDescriptorBase* AnimNodeDescriptorFactory( return nullptr; } +NodeDescriptorBase* VirtualAnimNodeDescriptorFactory( + const std::string& node_type_name) { + AnimNode* temp_node = AnimNodeFactory(node_type_name); + NodeDescriptorBase* result = + AnimNodeDescriptorFactory(node_type_name.c_str(), temp_node); + + for (Socket& socket : result->m_inputs) { + socket.m_reference.ptr = nullptr; + } + + for (Socket& socket : result->m_outputs) { + socket.m_reference.ptr = nullptr; + } + + for (Socket& socket : result->m_properties) { + socket.m_reference.ptr = nullptr; + } + + delete temp_node; + + return result; +} + void Blend2Node::Evaluate(AnimGraphContext& context) { assert(i_input0 != nullptr); assert(i_input1 != nullptr); diff --git a/src/AnimGraph/AnimGraphNodes.h b/src/AnimGraph/AnimGraphNodes.h index 0f804b7..c76b568 100644 --- a/src/AnimGraph/AnimGraphNodes.h +++ b/src/AnimGraph/AnimGraphNodes.h @@ -240,4 +240,7 @@ NodeDescriptorBase* AnimNodeDescriptorFactory( const std::string& node_type_name, AnimNode* node); +NodeDescriptorBase* VirtualAnimNodeDescriptorFactory( + const std::string& node_type_name); + #endif //ANIMTESTBED_ANIMGRAPHNODES_H diff --git a/src/AnimGraph/AnimGraphResource.cc b/src/AnimGraph/AnimGraphResource.cc index 1949745..5d5c235 100644 --- a/src/AnimGraph/AnimGraphResource.cc +++ b/src/AnimGraph/AnimGraphResource.cc @@ -149,7 +149,7 @@ json sAnimGraphNodeToJson( if (node->m_node_type_name == "BlendTree") { } - for (const auto& socket : node->m_socket_accessor->m_inputs) { + for (const auto& socket : node->m_virtual_socket_accessor->m_inputs) { if (socket.m_type == SocketType::SocketTypeAnimation) { continue; } @@ -168,7 +168,7 @@ json sAnimGraphNodeToJson( } } - for (auto& property : node->m_socket_accessor->m_properties) { + for (auto& property : node->m_virtual_socket_accessor->m_properties) { result["properties"][property.m_name] = sSocketToJson(property); } @@ -193,11 +193,10 @@ AnimNodeResource* sAnimGraphNodeFromJson( result->m_position[0] = json_node["position"][0]; result->m_position[1] = json_node["position"][1]; - result->m_anim_node = AnimNodeFactory(result->m_node_type_name); - result->m_socket_accessor = - AnimNodeDescriptorFactory(result->m_node_type_name, result->m_anim_node); + result->m_virtual_socket_accessor = + VirtualAnimNodeDescriptorFactory(result->m_node_type_name); - for (auto& property : result->m_socket_accessor->m_properties) { + for (auto& property : result->m_virtual_socket_accessor->m_properties) { property = sJsonToSocket(json_node["properties"][property.m_name]); } @@ -206,7 +205,7 @@ AnimNodeResource* sAnimGraphNodeFromJson( assert(json_node["inputs"][j].contains("name")); std::string input_name = json_node["inputs"][j]["name"]; Socket* input_socket = - result->m_socket_accessor->GetInputSocket(input_name.c_str()); + result->m_virtual_socket_accessor->GetInputSocket(input_name.c_str()); if (input_socket == nullptr) { std::cerr << "Could not find input socket with name " << input_name << " for node type " << result->m_node_type_name << std::endl; @@ -285,14 +284,14 @@ static json sAnimGraphResourceBlendTreeToJson( { const AnimNodeResource* graph_output_node = blend_tree_resource.GetNode(0); const std::vector graph_inputs = - graph_output_node->m_socket_accessor->m_inputs; + graph_output_node->m_virtual_socket_accessor->m_inputs; for (size_t i = 0; i < graph_inputs.size(); i++) { result["nodes"][0]["inputs"][i] = sSocketToJson(graph_inputs[i]); } const AnimNodeResource* graph_input_node = blend_tree_resource.GetNode(1); const std::vector graph_outputs = - graph_input_node->m_socket_accessor->m_outputs; + graph_input_node->m_virtual_socket_accessor->m_outputs; for (size_t i = 0; i < graph_outputs.size(); i++) { result["nodes"][1]["outputs"][i] = sSocketToJson(graph_outputs[i]); } @@ -311,8 +310,8 @@ static bool sAnimGraphResourceBlendTreeFromJson( result_graph_resource->m_name = json_data["name"]; result_graph_resource->m_position[0] = json_data["position"][0]; result_graph_resource->m_position[1] = json_data["position"][1]; - assert(result_graph_resource->m_socket_accessor == nullptr); - result_graph_resource->m_socket_accessor = + assert(result_graph_resource->m_virtual_socket_accessor == nullptr); + result_graph_resource->m_virtual_socket_accessor = AnimNodeDescriptorFactory("BlendTree", nullptr); // Load nodes @@ -492,9 +491,9 @@ Socket* BlendTreeResource::GetNodeOutputSocket( const std::string& output_socket_name) const { Socket* output_socket = nullptr; - if (node->m_socket_accessor) { - output_socket = - node->m_socket_accessor->GetOutputSocket(output_socket_name.c_str()); + if (node->m_virtual_socket_accessor) { + output_socket = node->m_virtual_socket_accessor->GetOutputSocket( + output_socket_name.c_str()); } if (output_socket == nullptr && node->m_node_type_name == "BlendTree") { @@ -503,8 +502,7 @@ Socket* BlendTreeResource::GetNodeOutputSocket( const BlendTreeResource& blend_tree_resource = graph_resource->m_blend_tree_resource; output_socket = - blend_tree_resource.GetGraphOutputNode() - ->m_socket_accessor->GetInputSocket(output_socket_name.c_str()); + blend_tree_resource.GetGraphOutputSocket(output_socket_name.c_str()); } return output_socket; @@ -515,16 +513,16 @@ const Socket* BlendTreeResource::GetNodeOutputSocketByIndex( const size_t socket_output_index) const { const std::vector* output_sockets = nullptr; - if (node->m_socket_accessor) { - output_sockets = &node->m_socket_accessor->m_outputs; + if (node->m_virtual_socket_accessor) { + output_sockets = &node->m_virtual_socket_accessor->m_outputs; } else if (node->m_node_type_name == "BlendTree") { const AnimGraphResource* graph_resource = dynamic_cast(node); const BlendTreeResource& blend_tree_resource = graph_resource->m_blend_tree_resource; - output_sockets = - &blend_tree_resource.GetGraphOutputNode()->m_socket_accessor->m_outputs; + output_sockets = &blend_tree_resource.GetGraphOutputNode() + ->m_virtual_socket_accessor->m_outputs; } if (output_sockets != nullptr @@ -540,9 +538,9 @@ Socket* BlendTreeResource::GetNodeInputSocket( const std::string& input_socket_name) const { Socket* input_socket = nullptr; - if (node->m_socket_accessor) { - input_socket = - node->m_socket_accessor->GetInputSocket(input_socket_name.c_str()); + if (node->m_virtual_socket_accessor) { + input_socket = node->m_virtual_socket_accessor->GetInputSocket( + input_socket_name.c_str()); } if (input_socket == nullptr && node->m_node_type_name == "BlendTree") { @@ -551,8 +549,7 @@ Socket* BlendTreeResource::GetNodeInputSocket( const BlendTreeResource& blend_tree_resource = graph_resource->m_blend_tree_resource; input_socket = - blend_tree_resource.GetGraphInputNode() - ->m_socket_accessor->GetOutputSocket(input_socket_name.c_str()); + blend_tree_resource.GetGraphInputSocket(input_socket_name.c_str()); } return input_socket; @@ -563,16 +560,16 @@ const Socket* BlendTreeResource::GetNodeInputSocketByIndex( const size_t socket_input_index) const { const std::vector* output_sockets = nullptr; - if (node->m_socket_accessor) { - output_sockets = &node->m_socket_accessor->m_inputs; + if (node->m_virtual_socket_accessor) { + output_sockets = &node->m_virtual_socket_accessor->m_inputs; } else if (node->m_node_type_name == "BlendTree") { const AnimGraphResource* graph_resource = dynamic_cast(node); const BlendTreeResource& blend_tree_resource = graph_resource->m_blend_tree_resource; - output_sockets = - &blend_tree_resource.GetGraphOutputNode()->m_socket_accessor->m_outputs; + output_sockets = &blend_tree_resource.GetGraphOutputNode() + ->m_virtual_socket_accessor->m_outputs; } if (output_sockets != nullptr @@ -585,8 +582,8 @@ const Socket* BlendTreeResource::GetNodeInputSocketByIndex( std::vector BlendTreeResource::GetNodeOutputSockets( const AnimNodeResource* node) const { - if (node->m_socket_accessor) { - return node->m_socket_accessor->m_outputs; + if (node->m_virtual_socket_accessor) { + return node->m_virtual_socket_accessor->m_outputs; } if (node->m_node_type_name == "BlendTree") { @@ -595,7 +592,7 @@ std::vector BlendTreeResource::GetNodeOutputSockets( const BlendTreeResource& blend_tree_resource = graph_resource->m_blend_tree_resource; return blend_tree_resource.GetGraphOutputNode() - ->m_socket_accessor->m_inputs; + ->m_virtual_socket_accessor->m_inputs; } return std::vector(); @@ -603,8 +600,8 @@ std::vector BlendTreeResource::GetNodeOutputSockets( std::vector BlendTreeResource::GetNodeInputSockets( const AnimNodeResource* node) const { - if (node->m_socket_accessor) { - return node->m_socket_accessor->m_inputs; + if (node->m_virtual_socket_accessor) { + return node->m_virtual_socket_accessor->m_inputs; } if (node->m_node_type_name == "BlendTree") { @@ -613,7 +610,7 @@ std::vector BlendTreeResource::GetNodeInputSockets( const BlendTreeResource& blend_tree_resource = graph_resource->m_blend_tree_resource; return blend_tree_resource.GetGraphInputNode() - ->m_socket_accessor->m_outputs; + ->m_virtual_socket_accessor->m_outputs; } return std::vector(); @@ -863,9 +860,9 @@ void AnimGraphResource::CreateBlendTreeRuntimeNodeInstances( embedded_blend_tree_resource->CreateBlendTreeInstance( *embedded_blend_tree); - embedded_blend_tree_resource->m_socket_accessor->m_inputs = + embedded_blend_tree_resource->m_virtual_socket_accessor->m_inputs = embedded_blend_tree->m_node_descriptor->m_outputs; - embedded_blend_tree_resource->m_socket_accessor->m_outputs = + embedded_blend_tree_resource->m_virtual_socket_accessor->m_outputs = embedded_blend_tree->m_node_descriptor->m_inputs; } @@ -886,9 +883,11 @@ void AnimGraphResource::PrepareBlendTreeIOData( AnimNodeDescriptorFactory("BlendTree", instance.m_nodes[0]); instance.m_node_descriptor->m_outputs = - m_blend_tree_resource.GetNode(1)->m_socket_accessor->m_outputs; + m_blend_tree_resource.GetGraphInputNode() + ->m_virtual_socket_accessor->m_outputs; instance.m_node_descriptor->m_inputs = - m_blend_tree_resource.GetNode(0)->m_socket_accessor->m_inputs; + m_blend_tree_resource.GetGraphOutputNode() + ->m_virtual_socket_accessor->m_inputs; // // graph inputs @@ -942,8 +941,9 @@ void AnimGraphResource::PrepareBlendTreeIOData( m_blend_tree_resource.GetConnections()) { const AnimNodeResource* source_node = m_blend_tree_resource.GetNode(connection.source_node_index); - Socket* source_socket = source_node->m_socket_accessor->GetOutputSocket( - connection.source_socket_name.c_str()); + Socket* source_socket = + source_node->m_virtual_socket_accessor->GetOutputSocket( + connection.source_socket_name.c_str()); NodeSocketPair source_socket_pair{source_node, source_socket->m_name}; if (node_offset_map.find(source_socket_pair) == node_offset_map.end()) { @@ -974,9 +974,10 @@ void AnimGraphResource::CreateBlendTreeConnectionInstances( if (i > 1 && m_blend_tree_resource.GetNode(i)->m_node_type_name == "BlendTree") { instance_node_descriptors[i]->m_inputs = - m_blend_tree_resource.GetNode(i)->m_socket_accessor->m_inputs; + m_blend_tree_resource.GetNode(i)->m_virtual_socket_accessor->m_inputs; instance_node_descriptors[i]->m_outputs = - m_blend_tree_resource.GetNode(i)->m_socket_accessor->m_outputs; + m_blend_tree_resource.GetNode(i) + ->m_virtual_socket_accessor->m_outputs; } } @@ -1180,7 +1181,7 @@ void AnimGraphResource::SetRuntimeNodeProperties( result.m_nodes[i]); std::vector& resource_properties = - node_resource->m_socket_accessor->m_properties; + node_resource->m_virtual_socket_accessor->m_properties; for (const auto& property : resource_properties) { const std::string& name = property.m_name; diff --git a/src/AnimGraph/AnimGraphResource.h b/src/AnimGraph/AnimGraphResource.h index d6bddf2..b23e32c 100644 --- a/src/AnimGraph/AnimGraphResource.h +++ b/src/AnimGraph/AnimGraphResource.h @@ -12,12 +12,11 @@ struct AnimGraphBlendTree; struct AnimGraphStateMachine; struct AnimNodeResource { - virtual ~AnimNodeResource() = default; + virtual ~AnimNodeResource() { delete m_virtual_socket_accessor; }; std::string m_name; std::string m_node_type_name; - AnimNode* m_anim_node = nullptr; - NodeDescriptorBase* m_socket_accessor = nullptr; + NodeDescriptorBase* m_virtual_socket_accessor = nullptr; float m_position[2] = {0.f, 0.f}; }; @@ -57,9 +56,8 @@ struct BlendTreeResource { void CleanupNodes() { for (AnimNodeResource* node_resource : m_nodes) { - delete node_resource->m_anim_node; - delete node_resource->m_socket_accessor; - node_resource->m_socket_accessor = nullptr; + delete node_resource->m_virtual_socket_accessor; + node_resource->m_virtual_socket_accessor = nullptr; delete node_resource; } @@ -73,7 +71,7 @@ struct BlendTreeResource { AddNode(AnimNodeResourceFactory("BlendTreeSockets")); AnimNodeResource* input_node = GetGraphInputNode(); - output_node->m_name = "Inputs"; + input_node->m_name = "Inputs"; } [[nodiscard]] AnimNodeResource* GetGraphOutputNode() const { @@ -82,6 +80,14 @@ struct BlendTreeResource { [[nodiscard]] AnimNodeResource* GetGraphInputNode() const { return m_nodes[1]; } + Socket* GetGraphOutputSocket(const char* socket_name) const { + return GetGraphOutputNode()->m_virtual_socket_accessor->GetInputSocket( + socket_name); + } + Socket* GetGraphInputSocket(const char* socket_name) const { + return GetGraphInputNode()->m_virtual_socket_accessor->GetOutputSocket( + socket_name); + } int GetNodeIndex(const AnimNodeResource* node_resource) const { for (size_t i = 0, n = m_nodes.size(); i < n; i++) { @@ -192,7 +198,7 @@ struct BlendTreeResource { if (*input.m_reference.ptr_ptr == nullptr) { memcpy( &input.m_value, - &m_nodes[i]->m_socket_accessor->m_inputs[j].m_value, + &m_nodes[i]->m_virtual_socket_accessor->m_inputs[j].m_value, sizeof(Socket::SocketValue)); result.push_back(&input); } @@ -264,14 +270,7 @@ struct StateMachineResource { }; struct AnimGraphResource : AnimNodeResource { - virtual ~AnimGraphResource() { - Clear(); - - if (m_socket_accessor != nullptr) { - delete m_socket_accessor; - m_socket_accessor = nullptr; - } - }; + virtual ~AnimGraphResource() { Clear(); }; std::string m_graph_type_name; @@ -300,23 +299,18 @@ struct AnimGraphResource : AnimNodeResource { bool RegisterBlendTreeInputSocket(const Socket& socket) { AnimNodeResource* input_node = m_blend_tree_resource.GetGraphInputNode(); - std::vector input_sockets = - input_node->m_socket_accessor->m_outputs; - std::vector::const_iterator iter = std::find_if( - input_sockets.begin(), - input_sockets.end(), - [&socket](const Socket& input_socket) { - return socket.m_name == input_socket.m_name; - }); + Socket* input_socket = + m_blend_tree_resource.GetGraphInputSocket(socket.m_name.c_str()); - if (iter != input_sockets.end()) { - std::cerr << "Error: cannot register input socket as socket with name '" + if (input_socket != nullptr) { + std::cerr << "Error: cannot register output socket as socket with name '" << socket.m_name << "' already exists!" << std::endl; return false; } - input_node->m_socket_accessor->m_outputs.push_back(socket); - m_socket_accessor->m_inputs = input_node->m_socket_accessor->m_outputs; + input_node->m_virtual_socket_accessor->m_outputs.push_back(socket); + m_virtual_socket_accessor->m_inputs = + input_node->m_virtual_socket_accessor->m_outputs; return true; } @@ -334,21 +328,18 @@ struct AnimGraphResource : AnimNodeResource { bool RegisterBlendTreeOutputSocket(const Socket& socket) { AnimNodeResource* output_node = m_blend_tree_resource.GetGraphOutputNode(); - std::vector output_sockets = - output_node->m_socket_accessor->m_inputs; - std::vector::const_iterator iter = std::find_if( - output_sockets.begin(), - output_sockets.end(), - [&socket](const Socket& input_socket) { - return socket.m_name == input_socket.m_name; - }); + Socket* output_socket = + m_blend_tree_resource.GetGraphOutputSocket(socket.m_name.c_str()); - if (iter != output_sockets.end()) { + if (output_socket != nullptr) { + std::cerr << "Error: cannot register output socket as socket with name '" + << socket.m_name << "' already exists!" << std::endl; return false; } - output_node->m_socket_accessor->m_inputs.push_back(socket); - m_socket_accessor->m_outputs = output_node->m_socket_accessor->m_inputs; + output_node->m_virtual_socket_accessor->m_inputs.push_back(socket); + m_virtual_socket_accessor->m_outputs = + output_node->m_virtual_socket_accessor->m_inputs; return true; } @@ -385,15 +376,8 @@ static inline AnimNodeResource* AnimNodeResourceFactory( } result->m_node_type_name = node_type_name; - - if (node_type_name == "BlendTreeSockets") { - result->m_anim_node = AnimNodeFactory("BlendTree"); - result->m_socket_accessor = new NodeDescriptorBase(); - } else { - result->m_anim_node = AnimNodeFactory(node_type_name); - result->m_socket_accessor = - AnimNodeDescriptorFactory(node_type_name, result->m_anim_node); - } + result->m_virtual_socket_accessor = + VirtualAnimNodeDescriptorFactory(node_type_name); return result; } diff --git a/tests/AnimGraphResourceTests.cc b/tests/AnimGraphResourceTests.cc index e5822e6..3a60648 100644 --- a/tests/AnimGraphResourceTests.cc +++ b/tests/AnimGraphResourceTests.cc @@ -32,12 +32,12 @@ class SimpleAnimSamplerGraphResource { blend_tree_resource->AddNode(AnimNodeResourceFactory("AnimSampler")); walk_node = blend_tree_resource->GetNode(walk_node_index); walk_node->m_name = "WalkAnim"; - walk_node->m_socket_accessor->SetPropertyValue( + walk_node->m_virtual_socket_accessor->SetPropertyValue( "Filename", std::string("media/Walking-loop.ozz")); AnimNodeResource* graph_node = blend_tree_resource->GetGraphOutputNode(); - graph_node->m_socket_accessor->RegisterInput( + graph_node->m_virtual_socket_accessor->RegisterInput( "GraphOutput", nullptr); @@ -81,11 +81,11 @@ class Blend2GraphResource { walk_node = blend_tree_resource->GetNode(walk_node_index); walk_node->m_name = "WalkAnim"; - walk_node->m_socket_accessor->SetPropertyValue( + walk_node->m_virtual_socket_accessor->SetPropertyValue( "Filename", std::string("media/Walking-loop.ozz")); run_node = blend_tree_resource->GetNode(run_node_index); - run_node->m_socket_accessor->SetPropertyValue( + run_node->m_virtual_socket_accessor->SetPropertyValue( "Filename", std::string("media/Running0-loop.ozz")); run_node->m_name = "RunAnim"; @@ -93,14 +93,16 @@ class Blend2GraphResource { blend_node->m_name = "BlendWalkRun"; AnimNodeResource* graph_node = blend_tree_resource->GetGraphOutputNode(); - graph_node->m_socket_accessor->RegisterInput( + graph_node->m_virtual_socket_accessor->RegisterInput( "GraphOutput", nullptr); - 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); - blend_node->m_socket_accessor->SetInputValue("Weight", 0.123f); + REQUIRE(graph_node->m_virtual_socket_accessor->m_inputs.size() == 1); + REQUIRE( + blend_node->m_virtual_socket_accessor->GetInputIndex("Input0") == 0); + REQUIRE( + blend_node->m_virtual_socket_accessor->GetInputIndex("Input1") == 1); + blend_node->m_virtual_socket_accessor->SetInputValue("Weight", 0.123f); blend_tree_resource ->ConnectSockets(walk_node, "Output", blend_node, "Input0"); @@ -152,9 +154,8 @@ class EmbeddedBlendTreeGraphResource { // Setup parent outputs AnimNodeResource* parent_blend_tree_outputs = parent_blend_tree_resource->GetGraphOutputNode(); - parent_blend_tree_outputs->m_socket_accessor->RegisterInput( - "Output", - nullptr); + parent_blend_tree_outputs->m_virtual_socket_accessor + ->RegisterInput("Output", nullptr); // Parent AnimSampler walk_node_index = parent_blend_tree_resource->AddNode( @@ -162,7 +163,7 @@ class EmbeddedBlendTreeGraphResource { walk_node_resource = parent_blend_tree_resource->GetNode(walk_node_index); walk_node_resource->m_name = "WalkAnim"; - walk_node_resource->m_socket_accessor->SetPropertyValue( + walk_node_resource->m_virtual_socket_accessor->SetPropertyValue( "Filename", std::string("media/Walking-loop.ozz")); @@ -181,14 +182,14 @@ class EmbeddedBlendTreeGraphResource { // Embedded: outputs AnimNodeResource* embedded_outputs = embedded_blend_tree_resource->GetGraphOutputNode(); - embedded_outputs->m_socket_accessor->RegisterInput( + embedded_outputs->m_virtual_socket_accessor->RegisterInput( "AnimOutput", nullptr); // Embedded: inputs AnimNodeResource* embedded_inputs = embedded_blend_tree_resource->GetGraphInputNode(); - embedded_inputs->m_socket_accessor->RegisterOutput( + embedded_inputs->m_virtual_socket_accessor->RegisterOutput( "AnimInput", nullptr); @@ -197,7 +198,7 @@ class EmbeddedBlendTreeGraphResource { AnimNodeResourceFactory("SpeedScale")); AnimNodeResource* embedded_speed_scale_resource = embedded_blend_tree_resource->GetNode(embedded_speed_scale_index); - embedded_speed_scale_resource->m_socket_accessor->SetInputValue( + embedded_speed_scale_resource->m_virtual_socket_accessor->SetInputValue( "SpeedScale", 0.1f); @@ -270,14 +271,13 @@ class EmbeddedTreeBlend2GraphResource { // Setup parent outputs AnimNodeResource* parent_blend_tree_outputs = parent_blend_tree_resource->GetGraphOutputNode(); - parent_blend_tree_outputs->m_socket_accessor->RegisterInput( - "Output", - nullptr); + parent_blend_tree_outputs->m_virtual_socket_accessor + ->RegisterInput("Output", nullptr); // Setup parent inputs AnimNodeResource* parent_blend_tree_inputs = parent_blend_tree_resource->GetGraphInputNode(); - parent_blend_tree_inputs->m_socket_accessor->RegisterOutput( + parent_blend_tree_inputs->m_virtual_socket_accessor->RegisterOutput( "EmbeddedBlend2Weight", nullptr); @@ -287,7 +287,7 @@ class EmbeddedTreeBlend2GraphResource { walk_node_resource = parent_blend_tree_resource->GetNode(walk_node_index); walk_node_resource->m_name = "WalkAnim"; - walk_node_resource->m_socket_accessor->SetPropertyValue( + walk_node_resource->m_virtual_socket_accessor->SetPropertyValue( "Filename", std::string("media/Walking-loop.ozz")); @@ -320,14 +320,14 @@ class EmbeddedTreeBlend2GraphResource { // Configure node resources embedded_blend2_node_resource = embedded_blend_tree_resource->GetNode(embedded_blend2_node_index); - embedded_blend2_node_resource->m_socket_accessor->SetInputValue( + embedded_blend2_node_resource->m_virtual_socket_accessor->SetInputValue( "Weight", 0.1f); embedded_run_node_resource = embedded_blend_tree_resource->GetNode(embedded_run_node_index); embedded_run_node_resource->m_name = "RunAnim"; - embedded_run_node_resource->m_socket_accessor->SetPropertyValue( + embedded_run_node_resource->m_virtual_socket_accessor->SetPropertyValue( "Filename", std::string("media/RunningSlow-loop.ozz")); @@ -562,7 +562,7 @@ TEST_CASE("AnimSamplerSpeedScaleGraph", "[AnimGraphResource]") { AnimNodeResource* walk_node = blend_tree_resource.GetNode(walk_node_index); walk_node->m_name = "WalkAnim"; - walk_node->m_socket_accessor->SetPropertyValue( + walk_node->m_virtual_socket_accessor->SetPropertyValue( "Filename", std::string("media/Walking-loop.ozz")); @@ -570,12 +570,12 @@ TEST_CASE("AnimSamplerSpeedScaleGraph", "[AnimGraphResource]") { blend_tree_resource.GetNode(speed_scale_node_index); speed_scale_node->m_name = "SpeedScale"; float speed_scale_value = 1.35f; - speed_scale_node->m_socket_accessor->SetInputValue( + speed_scale_node->m_virtual_socket_accessor->SetInputValue( "SpeedScale", speed_scale_value); AnimNodeResource* graph_node = blend_tree_resource.GetGraphOutputNode(); - graph_node->m_socket_accessor->RegisterInput( + graph_node->m_virtual_socket_accessor->RegisterInput( "GraphOutput", nullptr); @@ -599,7 +599,7 @@ TEST_CASE("AnimSamplerSpeedScaleGraph", "[AnimGraphResource]") { Socket* speed_scale_resource_loaded_input = blend_tree_resource_loaded.GetNode(speed_scale_node_index) - ->m_socket_accessor->GetInputSocket("SpeedScale"); + ->m_virtual_socket_accessor->GetInputSocket("SpeedScale"); REQUIRE(speed_scale_resource_loaded_input != nullptr); REQUIRE_THAT( @@ -725,10 +725,10 @@ TEST_CASE_METHOD( const NodeDescriptor* blend2_node_descriptor_loaded = dynamic_cast*>( blend_tree_resource_loaded->GetNode(blend_node_index) - ->m_socket_accessor); + ->m_virtual_socket_accessor); REQUIRE_THAT( - blend_node->m_socket_accessor->GetInputValue("Weight"), + blend_node->m_virtual_socket_accessor->GetInputValue("Weight"), Catch::Matchers::WithinAbs( blend2_node_descriptor_loaded->GetInputValue("Weight"), 0.01)); @@ -852,16 +852,16 @@ TEST_CASE("ResourceSaveLoadMathGraphInputs", "[AnimGraphResource]") { AnimNodeResource* graph_output_node = blend_tree_resource.GetGraphOutputNode(); - graph_output_node->m_socket_accessor->RegisterInput( + graph_output_node->m_virtual_socket_accessor->RegisterInput( "GraphFloatOutput", nullptr); - graph_output_node->m_socket_accessor->RegisterInput( + graph_output_node->m_virtual_socket_accessor->RegisterInput( "GraphVec3Output", nullptr); AnimNodeResource* graph_input_node_resource = blend_tree_resource.GetGraphInputNode(); - graph_input_node_resource->m_socket_accessor->RegisterOutput( + graph_input_node_resource->m_virtual_socket_accessor->RegisterOutput( "GraphFloatInput", nullptr); @@ -914,24 +914,26 @@ TEST_CASE("ResourceSaveLoadMathGraphInputs", "[AnimGraphResource]") { 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()); + graph_output_node->m_virtual_socket_accessor->m_inputs.size() + == graph_loaded_output_node->m_virtual_socket_accessor->m_inputs + .size()); REQUIRE( - graph_input_node_resource->m_socket_accessor->m_outputs.size() - == graph_loaded_input_node->m_socket_accessor->m_outputs.size()); + graph_input_node_resource->m_virtual_socket_accessor->m_outputs.size() + == graph_loaded_input_node->m_virtual_socket_accessor->m_outputs + .size()); REQUIRE( - graph_loaded_input_node->m_socket_accessor->GetOutputSocket( + graph_loaded_input_node->m_virtual_socket_accessor->GetOutputSocket( "GraphFloatInput") != nullptr); REQUIRE( - graph_loaded_output_node->m_socket_accessor->GetInputSocket( + graph_loaded_output_node->m_virtual_socket_accessor->GetInputSocket( "GraphFloatOutput") != nullptr); REQUIRE( - graph_loaded_output_node->m_socket_accessor->GetInputSocket( + graph_loaded_output_node->m_virtual_socket_accessor->GetInputSocket( "GraphVec3Output") != nullptr); @@ -1012,18 +1014,18 @@ TEST_CASE("SimpleMathEvaluations", "[AnimGraphResource]") { AnimNodeResource* graph_output_node = blend_tree_resource.GetGraphOutputNode(); - graph_output_node->m_socket_accessor->RegisterInput( + graph_output_node->m_virtual_socket_accessor->RegisterInput( "GraphFloat0Output", nullptr); - graph_output_node->m_socket_accessor->RegisterInput( + graph_output_node->m_virtual_socket_accessor->RegisterInput( "GraphFloat1Output", nullptr); - graph_output_node->m_socket_accessor->RegisterInput( + graph_output_node->m_virtual_socket_accessor->RegisterInput( "GraphFloat2Output", nullptr); AnimNodeResource* graph_input_node = blend_tree_resource.GetGraphInputNode(); - graph_input_node->m_socket_accessor->RegisterOutput( + graph_input_node->m_virtual_socket_accessor->RegisterOutput( "GraphFloatInput", nullptr);