BlendTree input and output sockets can now be registered via the AnimGraphResource.

RefactorUnifiedBlendTreeStateMachineHandling
Martin Felis 2024-05-01 21:49:34 +02:00
parent b9789bd1e1
commit 698abbce4b
3 changed files with 94 additions and 17 deletions

View File

@ -161,7 +161,7 @@ struct Socket {
SocketValue m_value = {0}; SocketValue m_value = {0};
std::string m_value_string; std::string m_value_string;
union SocketReference { union SocketReference {
void* ptr; void* ptr = nullptr;
void** ptr_ptr; void** ptr_ptr;
}; };
SocketReference m_reference = {0}; SocketReference m_reference = {0};
@ -418,7 +418,7 @@ struct NodeDescriptorBase {
return socket->GetValue<T>(); return socket->GetValue<T>();
} }
virtual void UpdateFlags(){}; virtual void UpdateFlags() {};
protected: protected:
Socket* FindSocket(const char* name, std::vector<Socket>& sockets) { Socket* FindSocket(const char* name, std::vector<Socket>& sockets) {

View File

@ -276,6 +276,73 @@ struct AnimGraphResource : AnimNodeResource {
bool LoadFromFile(const char* filename); bool LoadFromFile(const char* filename);
void CreateBlendTreeInstance(AnimGraphBlendTree& result) const; void CreateBlendTreeInstance(AnimGraphBlendTree& result) const;
template <typename T>
bool RegisterBlendTreeInputSocket(const std::string& socket_name) {
Socket socket;
socket.m_name = socket_name;
socket.m_type = GetSocketType<T>();
socket.m_type_size = sizeof(T);
return RegisterBlendTreeInputSocket(socket);
}
bool RegisterBlendTreeInputSocket(const Socket& socket) {
AnimNodeResource* input_node = m_blend_tree_resource.GetGraphInputNode();
std::vector<Socket> input_sockets =
input_node->m_socket_accessor->m_outputs;
std::vector<Socket>::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;
});
if (iter != input_sockets.end()) {
std::cerr << "Error: cannot register input 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;
return true;
}
template <typename T>
bool RegisterBlendTreeOutputSocket(const std::string& socket_name) {
Socket socket;
socket.m_name = socket_name;
socket.m_type = GetSocketType<T>();
socket.m_type_size = sizeof(T);
return RegisterBlendTreeOutputSocket(socket);
}
bool RegisterBlendTreeOutputSocket(const Socket& socket) {
AnimNodeResource* output_node = m_blend_tree_resource.GetGraphOutputNode();
std::vector<Socket> output_sockets =
output_node->m_socket_accessor->m_inputs;
std::vector<Socket>::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;
});
if (iter != output_sockets.end()) {
return false;
}
output_node->m_socket_accessor->m_inputs.push_back(socket);
m_socket_accessor->m_outputs = output_node->m_socket_accessor->m_inputs;
return true;
}
void CreateStateMachineInstance(AnimGraphStateMachine& result) const; void CreateStateMachineInstance(AnimGraphStateMachine& result) const;
private: private:

View File

@ -304,21 +304,11 @@ class EmbeddedTreeBlend2GraphResource {
embedded_blend_tree_resource = &embedded_graph->m_blend_tree_resource; embedded_blend_tree_resource = &embedded_graph->m_blend_tree_resource;
// Embedded: outputs // Embedded: outputs
AnimNodeResource* embedded_outputs = embedded_graph->RegisterBlendTreeOutputSocket<AnimData>("AnimOutput");
embedded_blend_tree_resource->GetGraphOutputNode();
embedded_outputs->m_socket_accessor->RegisterInput<AnimData>(
"AnimOutput",
nullptr);
// Embedded: inputs // Embedded: inputs
AnimNodeResource* embedded_inputs = embedded_graph->RegisterBlendTreeInputSocket<AnimData>("AnimInput");
embedded_blend_tree_resource->GetGraphInputNode(); embedded_graph->RegisterBlendTreeInputSocket<float>("BlendWeight");
embedded_inputs->m_socket_accessor->RegisterOutput<AnimData>(
"AnimInput",
nullptr);
embedded_inputs->m_socket_accessor->RegisterOutput<float>(
"BlendWeight",
nullptr);
// Embedded nodes // Embedded nodes
embedded_blend2_node_index = embedded_blend_tree_resource->AddNode( embedded_blend2_node_index = embedded_blend_tree_resource->AddNode(
@ -343,7 +333,7 @@ class EmbeddedTreeBlend2GraphResource {
// Embedded: setup connections // Embedded: setup connections
REQUIRE(embedded_blend_tree_resource->ConnectSockets( REQUIRE(embedded_blend_tree_resource->ConnectSockets(
embedded_inputs, embedded_blend_tree_resource->GetGraphInputNode(),
"AnimInput", "AnimInput",
embedded_blend2_node_resource, embedded_blend2_node_resource,
"Input0")); "Input0"));
@ -358,7 +348,7 @@ class EmbeddedTreeBlend2GraphResource {
embedded_blend_tree_resource->GetGraphOutputNode(), embedded_blend_tree_resource->GetGraphOutputNode(),
"AnimOutput")); "AnimOutput"));
REQUIRE(embedded_blend_tree_resource->ConnectSockets( REQUIRE(embedded_blend_tree_resource->ConnectSockets(
embedded_inputs, embedded_blend_tree_resource->GetGraphInputNode(),
"BlendWeight", "BlendWeight",
embedded_blend2_node_resource, embedded_blend2_node_resource,
"Weight")); "Weight"));
@ -1342,3 +1332,23 @@ TEST_CASE_METHOD(
graph_context.freeAnimations(); graph_context.freeAnimations();
} }
TEST_CASE(
"Register AnimGraphResource Blendtree Sockets",
"[AnimGraphResource]") {
AnimNodeResource* blend_tree_anim_node_resource =
AnimNodeResourceFactory("BlendTree");
AnimGraphResource* blend_tree_graph_resource =
dynamic_cast<AnimGraphResource*>(blend_tree_anim_node_resource);
Socket socket;
socket.m_name = "FloatSocket";
socket.m_type = SocketType::SocketTypeFloat;
socket.m_reference.ptr = nullptr;
CHECK(blend_tree_graph_resource->RegisterBlendTreeInputSocket(socket));
CHECK(!blend_tree_graph_resource->RegisterBlendTreeInputSocket(socket));
CHECK(blend_tree_graph_resource->RegisterBlendTreeOutputSocket(socket));
CHECK(!blend_tree_graph_resource->RegisterBlendTreeOutputSocket(socket));
}