Simple graph output connection working.
This commit is contained in:
+44
-128
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user