Simple graph output connection working.

This commit is contained in:
Martin Felis
2022-02-12 11:46:50 +01:00
parent c2ae0a11d2
commit 2b7cbe9d4c
2 changed files with 58 additions and 135 deletions
+44 -128
View File
@@ -5,6 +5,7 @@
#ifndef ANIMTESTBED_ANIMGRAPHRESOURCE_H
#define ANIMTESTBED_ANIMGRAPHRESOURCE_H
#include <cstring>
#include <iostream>
#include <map>
#include <string>
@@ -54,24 +55,13 @@ struct AnimNodeResource;
struct Socket {
std::string m_name;
SocketType m_type;
union Value {
bool* flag;
AnimData* anim_data;
float* real;
Vec3* vec3;
Quat* quat;
std::string* str;
SocketType m_type = SocketType::SocketTypeUndefined;
union SocketValue {
void* ptr;
bool** flag_ptr;
AnimData** anim_data_ptr;
float** real_ptr;
float** vec3_ptr;
float** quat_ptr;
std::string** str_ptr;
void** ptr_ptr;
};
Value m_value;
SocketValue m_value = {nullptr};
size_t m_type_size = 0;
};
struct AnimNode;
@@ -98,7 +88,7 @@ struct AnimNode {
};
struct NodeSocketAccessorBase {
NodeSocketAccessorBase(AnimNode* node) {}
NodeSocketAccessorBase() {}
virtual ~NodeSocketAccessorBase() {}
Socket* FindSocket(std::vector<Socket>& sockets, const std::string& name) {
@@ -164,137 +154,41 @@ struct NodeSocketAccessorBase {
sockets.push_back(Socket());
socket = &sockets[sockets.size() - 1];
socket->m_name = name;
socket->m_type_size = sizeof(T);
if constexpr (std::is_same<T, float>::value) {
socket->m_value.real = value_ptr;
socket->m_type = SocketType::SocketTypeFloat;
} else if constexpr (std::is_same<T, bool>::value) {
socket->m_value.flag = value_ptr;
socket->m_type = SocketType::SocketTypeBool;
} else if constexpr (std::is_same<T, Vec3>::value) {
socket->m_value.vec3 = value_ptr;
socket->m_type = SocketType::SocketTypeVec3;
} else if constexpr (std::is_same<T, Quat>::value) {
socket->m_value.quat = value_ptr;
socket->m_type = SocketType::SocketTypeQuat;
} else if constexpr (std::is_same<T, AnimData>::value) {
socket->m_value.anim_data = value_ptr;
socket->m_type = SocketType::SocketTypeAnimation;
} else if constexpr (std::is_same<T, std::string>::value) {
socket->m_value.str = value_ptr;
socket->m_type = SocketType::SocketTypeString;
} else if constexpr (std::is_same<T, float*>::value) {
socket->m_value.real_ptr = value_ptr;
socket->m_type = SocketType::SocketTypeFloat;
} else if constexpr (std::is_same<T, bool*>::value) {
socket->m_value.flag_ptr = value_ptr;
socket->m_type = SocketType::SocketTypeBool;
} else if constexpr (std::is_same<T, Vec3*>::value) {
socket->m_value.vec3_ptr = value_ptr;
socket->m_type = SocketType::SocketTypeVec3;
} else if constexpr (std::is_same<T, Quat*>::value) {
socket->m_value.quat_ptr = value_ptr;
socket->m_type = SocketType::SocketTypeQuat;
} else if constexpr (std::is_same<T, AnimData*>::value) {
socket->m_value.anim_data_ptr = value_ptr;
socket->m_type = SocketType::SocketTypeAnimation;
} else if constexpr (std::is_same<T, std::string*>::value) {
socket->m_value.str_ptr = value_ptr;
socket->m_type = SocketType::SocketTypeString;
} else {
std::cerr << "Cannot register socket, invalid type." << std::endl;
return false;
}
socket->m_value.ptr = value_ptr;
return true;
}
template <typename T>
bool SetSocketValue(
std::vector<Socket>& sockets,
const std::string& name,
T value) {
Socket* socket = FindSocket(sockets, name);
if (socket == nullptr) {
return false;
}
if constexpr (std::is_same<T, float>::value) {
(*socket->m_value.real) = value;
} else if constexpr (std::is_same<T, bool>::value) {
(*socket->m_value.flag) = value;
} else if constexpr (std::is_same<T, Vec3>::value) {
(*socket->m_value.vec3) = value;
} else if constexpr (std::is_same<T, Quat>::value) {
(*socket->m_value.vec3) = value;
} else if constexpr (std::is_same<T, AnimData>::value) {
(*socket->m_value.vec3) = value;
} else if constexpr (std::is_same<T, std::string>::value) {
(*socket->m_value.str) = value;
} else {
std::cerr << "Invalid type!" << std::endl;
return false;
}
return true;
}
template <typename T>
bool SetSocketRef(
std::vector<Socket>& sockets,
const std::string& name,
T* value) {
Socket* socket = FindSocket(sockets, name);
if (socket == nullptr) {
return false;
} else if constexpr (std::is_same<T, float>::value) {
(*socket->m_value.real_ptr) = value;
} else if constexpr (std::is_same<T, bool>::value) {
(*socket->m_value.flag_ptr) = value;
} else if constexpr (std::is_same<T, Vec3>::value) {
(*socket->m_value.vec3_ptr) = value;
} else if constexpr (std::is_same<T, Quat>::value) {
(*socket->m_value.quat_ptr) = value;
} else if constexpr (std::is_same<T, AnimData>::value) {
(*socket->m_value.anim_data_ptr) = value;
} else if constexpr (std::is_same<T, std::string>::value) {
(*socket->m_value.str_ptr) = value;
} else {
std::cerr << "Invalid type!" << std::endl;
return false;
}
return true;
}
template <typename T>
T* GetSocketValue(
std::vector<Socket>& sockets,
const std::string& name,
T* default_value) {
Socket* socket = FindSocket(sockets, name);
if (socket == nullptr) {
return default_value;
}
if constexpr (std::is_same<T, float>::value) {
return socket->m_value.real;
} else if constexpr (std::is_same<T, Vec3>::value) {
return socket->m_value.vec3;
} else if constexpr (std::is_same<T, bool>::value) {
return socket->m_value.flag;
} else if constexpr (std::is_same<T, Quat>::value) {
return socket->m_value.vec3;
} else if constexpr (std::is_same<T, AnimData>::value) {
return socket->m_value.anim_data;
} else if constexpr (std::is_same<T, std::string>::value) {
return socket->m_value.str;
}
std::cerr << "Invalid type!" << std::endl;
return nullptr;
}
template <typename T>
bool RegisterProperty(const std::string& name, T* value) {
return RegisterSocket(m_properties, name, value);
@@ -316,10 +210,6 @@ struct NodeSocketAccessorBase {
return RegisterSocket(m_inputs, name, value);
}
template <typename T>
bool SetInput(const std::string& name, T value) {
return SetSocketValue(m_inputs, name, value);
}
template <typename T>
T* GetInput(const std::string& name, T* value) {
return GetSocketValue(m_inputs, name, value);
}
@@ -337,10 +227,6 @@ struct NodeSocketAccessorBase {
bool RegisterOutput(const std::string& name, T** value) {
return RegisterSocket(m_outputs, name, value);
}
template <typename T>
bool SetOutputRef(const std::string& name, T* value) {
return SetSocketRef(m_outputs, name, value);
}
SocketType GetOutputType(const std::string& name) {
return GetSocketType(m_outputs, name);
}
@@ -372,7 +258,7 @@ struct BlendTreeNode : public AnimNode {};
template <>
struct NodeSocketAccessor<BlendTreeNode> : public NodeSocketAccessorBase {
NodeSocketAccessor(AnimNode* node_) : NodeSocketAccessorBase(node_) {}
NodeSocketAccessor(AnimNode* node_) {}
};
struct Blend2Node : public AnimNode {
@@ -385,7 +271,7 @@ struct Blend2Node : public AnimNode {
template <>
struct NodeSocketAccessor<Blend2Node> : public NodeSocketAccessorBase {
NodeSocketAccessor(AnimNode* node_) : NodeSocketAccessorBase(node_) {
NodeSocketAccessor(AnimNode* node_) {
Blend2Node* node = dynamic_cast<Blend2Node*>(node_);
RegisterInput("Input0", &node->m_input0);
RegisterInput("Input1", &node->m_input1);
@@ -405,7 +291,7 @@ struct SpeedScaleNode : public AnimNode {
template <>
struct NodeSocketAccessor<SpeedScaleNode> : public NodeSocketAccessorBase {
NodeSocketAccessor(AnimNode* node_) : NodeSocketAccessorBase(node_) {
NodeSocketAccessor(AnimNode* node_) {
SpeedScaleNode* node = dynamic_cast<SpeedScaleNode*>(node_);
RegisterInput("SpeedScale", &node->m_speed_scale);
RegisterInput("Input", &node->m_input);
@@ -421,7 +307,7 @@ struct AnimSamplerNode : public AnimNode {
template <>
struct NodeSocketAccessor<AnimSamplerNode> : public NodeSocketAccessorBase {
NodeSocketAccessor(AnimNode* node_) : NodeSocketAccessorBase(node_) {
NodeSocketAccessor(AnimNode* node_) {
AnimSamplerNode* node = dynamic_cast<AnimSamplerNode*>(node_);
RegisterOutput("Output", &node->m_output);
@@ -516,6 +402,9 @@ struct AnimGraph {
AnimData m_local_transforms;
std::vector<AnimNode*> m_nodes;
std::vector<std::vector<AnimNode*> > m_node_inputs;
NodeSocketAccessorBase* m_socket_accessor;
char* m_input_buffer = nullptr;
char* m_output_buffer = nullptr;
AnimNode* getAnimNode(const char* name) {
for (size_t i = 0; i < m_nodes.size(); i++) {
@@ -540,6 +429,8 @@ struct AnimGraph {
static AnimGraph createFromResource(const AnimGraphResource& resource) {
AnimGraph result;
// create nodes
for (int i = 0; i < resource.m_nodes.size(); i++) {
const AnimNodeResource& node_resource = resource.m_nodes[i];
AnimNode* node = AnimNodeFactory(node_resource.m_type_name.c_str());
@@ -549,6 +440,27 @@ struct AnimGraph {
result.m_node_inputs.push_back(std::vector<AnimNode*>());
}
// Prepare graph inputs
const AnimNodeResource& graph_node = resource.m_nodes[0];
result.m_socket_accessor = AnimNodeAccessorFactory("BlendTree", result.m_nodes[0]);
int input_block_size = 0;
const std::vector<Socket>& graph_inputs =
graph_node.m_socket_accessor->m_inputs;
for (int i = 0; i < graph_inputs.size(); i++) {
input_block_size += graph_inputs[i].m_type_size;
}
result.m_input_buffer = new char[input_block_size];
memset(result.m_input_buffer, 0, input_block_size);
int input_block_offset = 0;
for (int i = 0; i < graph_inputs.size(); i++) {
if (graph_inputs[i].m_type == SocketType::SocketTypeAnimation) {
result.m_socket_accessor->RegisterInput<AnimData>(graph_inputs[i].m_name, static_cast<AnimData*>( (void*) &result.m_input_buffer[input_block_offset]));
}
input_block_offset += graph_inputs[i].m_type_size;
}
// connect the nodes
for (int i = 0; i < resource.m_connections.size(); i++) {
const AnimGraphConnection& connection = resource.m_connections[i];
std::string source_node_type = "";
@@ -574,8 +486,12 @@ struct AnimGraph {
target_node = result.m_nodes[connection.m_target_node_index];
target_node_name = target_node->m_name;
target_node_type = target_node->m_node_type_name;
target_node_accessor =
AnimNodeAccessorFactory(target_node_type, target_node);
if (connection.m_target_node_index == 0) {
target_node_accessor = result.m_socket_accessor;
} else {
target_node_accessor =
AnimNodeAccessorFactory(target_node_type, target_node);
}
}
assert(source_node != nullptr);