diff --git a/src/AnimGraph/AnimGraphBlendTree.h b/src/AnimGraph/AnimGraphBlendTree.h index b37b509..492f156 100644 --- a/src/AnimGraph/AnimGraphBlendTree.h +++ b/src/AnimGraph/AnimGraphBlendTree.h @@ -189,65 +189,6 @@ struct AnimGraphBlendTree : public AnimNode { return nullptr; } - void* GetInputPtr(const std::string& name) const { - const std::vector graph_input_connections = - GetGraphInputConnections(); - for (const AnimGraphConnection& connection : graph_input_connections) { - if (connection.m_source_socket_name == name) { - return connection.m_socket.m_reference.ptr; - } - } - - return nullptr; - } - - void* GetOutputPtr(const std::string& name) const { - const std::vector graph_output_connections = - GetGraphOutputConnections(); - for (const AnimGraphConnection& connection : graph_output_connections) { - if (connection.m_source_socket_name == name) { - return connection.m_socket.m_reference.ptr; - } - } - - return nullptr; - } - - int getNodeEvalOrderIndex(const AnimNode* node) { - for (size_t i = 0, n = m_eval_ordered_nodes.size(); i < n; i++) { - if (m_eval_ordered_nodes[i] == node) { - return i; - } - } - - return -1; - } - const AnimNode* getAnimNodeForInput( - size_t node_index, - const std::string& input_name) const { - assert(node_index < m_nodes.size()); - - const std::vector& input_connection = - m_node_input_connections[node_index]; - for (size_t i = 0, n = input_connection.size(); i < n; i++) { - if (input_connection[i].m_target_socket_name == input_name) { - return input_connection[i].m_source_node; - } - } - - return nullptr; - } - - AnimNode* getAnimNode(const char* name) { - for (size_t i = 0; i < m_nodes.size(); i++) { - if (m_nodes[i]->m_name == name) { - return m_nodes[i]; - } - } - - return nullptr; - } - size_t GetAnimNodeIndex(const AnimNode* node) const { for (size_t i = 0; i < m_nodes.size(); i++) { if (m_nodes[i] == node) { diff --git a/src/AnimGraph/AnimGraphBlendTreeResource.cc b/src/AnimGraph/AnimGraphBlendTreeResource.cc deleted file mode 100644 index cf7e4f7..0000000 --- a/src/AnimGraph/AnimGraphBlendTreeResource.cc +++ /dev/null @@ -1,616 +0,0 @@ -// -// Created by martin on 04.02.22. -// - -#include -#include - -#include "3rdparty/json/json.hpp" - -#include "AnimGraphBlendTreeResource.h" -#include "AnimGraphNodes.h" - -using json = nlohmann::json; - -// -// Socket <-> json -// -std::string sSocketTypeToStr(SocketType pin_type) { - if (pin_type < SocketType::SocketTypeUndefined - || pin_type >= SocketType::SocketTypeLast) { - return "Unknown"; - } - - return SocketTypeNames[static_cast(pin_type)]; -} - -json sSocketToJson(const Socket& socket) { - json result; - result["name"] = socket.m_name; - result["type"] = sSocketTypeToStr(socket.m_type); - - if (socket.m_type == SocketType::SocketTypeString - && !socket.m_value_string.empty()) { - result["value"] = socket.m_value_string; - } else if (socket.m_value.flag) { - if (socket.m_type == SocketType::SocketTypeBool) { - result["value"] = socket.m_value.flag; - } else if (socket.m_type == SocketType::SocketTypeAnimation) { - } else if (socket.m_type == SocketType::SocketTypeInt) { - result["value"] = socket.m_value.int_value; - } else if (socket.m_type == SocketType::SocketTypeFloat) { - result["value"] = socket.m_value.float_value; - } else if (socket.m_type == SocketType::SocketTypeVec3) { - result["value"][0] = socket.m_value.vec3.v[0]; - result["value"][1] = socket.m_value.vec3.v[1]; - result["value"][2] = socket.m_value.vec3.v[2]; - } else if (socket.m_type == SocketType::SocketTypeQuat) { - result["value"][0] = socket.m_value.quat.v[0]; - result["value"][1] = socket.m_value.quat.v[1]; - result["value"][2] = socket.m_value.quat.v[2]; - result["value"][3] = socket.m_value.quat.v[3]; - } else { - std::cerr << "Invalid socket type '" << static_cast(socket.m_type) - << "'." << std::endl; - } - } - return result; -} - -Socket sJsonToSocket(const json& json_data) { - Socket result; - result.m_type = SocketType::SocketTypeUndefined; - result.m_reference.ptr = &result.m_value.int_value; - result.m_name = json_data["name"]; - - std::string type_string = json_data["type"]; - bool have_value = json_data.contains("value"); - - if (type_string == "Bool") { - result.m_type = SocketType::SocketTypeBool; - result.m_type_size = sizeof(bool); - result.m_reference.ptr = &result.m_value.int_value; - - if (have_value) { - result.m_value.flag = json_data["value"]; - } - } else if (type_string == "Animation") { - result.m_type = SocketType::SocketTypeAnimation; - result.m_type_size = sizeof(AnimData); - } else if (type_string == "Int") { - result.m_type = SocketType::SocketTypeInt; - result.m_type_size = sizeof(int); - if (have_value) { - result.m_value.int_value = json_data["value"]; - } - } else if (type_string == "Float") { - result.m_type = SocketType::SocketTypeFloat; - result.m_type_size = sizeof(float); - if (have_value) { - result.m_value.float_value = json_data["value"]; - } - } else if (type_string == "Vec3") { - result.m_type = SocketType::SocketTypeVec3; - result.m_type_size = sizeof(Vec3); - if (have_value) { - result.m_value.vec3.x = json_data["value"][0]; - result.m_value.vec3.y = json_data["value"][1]; - result.m_value.vec3.z = json_data["value"][2]; - } - } else if (type_string == "Quat") { - result.m_type = SocketType::SocketTypeQuat; - result.m_type_size = sizeof(Quat); - if (have_value) { - result.m_value.quat.x = json_data["value"][0]; - result.m_value.quat.y = json_data["value"][1]; - result.m_value.quat.z = json_data["value"][2]; - result.m_value.quat.w = json_data["value"][3]; - } - } else if (type_string == "String") { - result.m_type = SocketType::SocketTypeString; - result.m_type_size = sizeof(std::string); - if (have_value) { - result.m_value_string = json_data["value"]; - } - } else { - std::cerr << "Invalid socket type '" << type_string << "'." << std::endl; - } - - return result; -} - -// -// AnimGraphNode <-> json -// -json sAnimGraphNodeToJson( - const AnimNodeResource& node, - size_t node_index, - const std::vector& connections) { - json result; - - result["name"] = node.m_name; - result["type"] = "AnimNodeResource"; - result["node_type"] = node.m_type_name; - - for (size_t j = 0; j < 2; j++) { - result["position"][j] = node.m_position[j]; - } - - for (const auto & socket : node.m_socket_accessor->m_inputs) { - if (socket.m_type == SocketType::SocketTypeAnimation) { - continue; - } - - bool socket_connected = false; - for (const auto & connection : connections) { - if (connection.source_node_index == node_index - && connection.source_socket_name == socket.m_name) { - socket_connected = true; - break; - } - } - - if (!socket_connected) { - result["inputs"].push_back(sSocketToJson(socket)); - } - } - - for (auto & property : node.m_socket_accessor->m_properties) { - result["properties"][property.m_name] = sSocketToJson(property); - } - - return result; -} - -AnimNodeResource sAnimGraphNodeFromJson(const json& json_node, size_t node_index) { - AnimNodeResource result; - - result.m_name = json_node["name"]; - result.m_type_name = json_node["node_type"]; - result.m_position[0] = json_node["position"][0]; - result.m_position[1] = json_node["position"][1]; - - result.m_anim_node = AnimNodeFactory(result.m_type_name); - result.m_socket_accessor = - AnimNodeDescriptorFactory(result.m_type_name, result.m_anim_node); - - for (auto & property : result.m_socket_accessor->m_properties) { - property = sJsonToSocket(json_node["properties"][property.m_name]); - } - - if (node_index != 0 && node_index != 1 && json_node.contains("inputs")) { - for (size_t j = 0, n = json_node["inputs"].size(); j < n; j++) { - 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()); - if (input_socket == nullptr) { - std::cerr << "Could not find input socket with name " << input_name - << " for node type " << result.m_type_name << std::endl; - abort(); - } - *input_socket = sJsonToSocket(json_node["inputs"][j]); - } - } - - return result; -} - -// -// AnimGraphConnectionResource <-> Json -// -json sAnimGraphConnectionToJson( - const AnimGraphConnectionResource& connection) { - json result; - - result["type"] = "AnimGraphConnectionResource"; - - result["source_node_index"] = connection.source_node_index; - result["source_socket_name"] = connection.source_socket_name; - - result["target_node_index"] = connection.target_node_index; - result["target_socket_name"] = connection.target_socket_name; - - return result; -} - -AnimGraphConnectionResource sAnimGraphConnectionFromJson( - const json& json_node) { - AnimGraphConnectionResource connection; - - connection.source_node_index = json_node["source_node_index"]; - connection.source_socket_name = json_node["source_socket_name"]; - - connection.target_node_index = json_node["target_node_index"]; - connection.target_socket_name = json_node["target_socket_name"]; - - return connection; -} - -void AnimGraphBlendTreeResource::clear() { - m_name = ""; - - clearNodes(); - m_connections.clear(); - - initGraphConnectors(); -} - -void AnimGraphBlendTreeResource::clearNodes() { - for (auto & m_node : m_nodes) { - delete m_node.m_socket_accessor; - m_node.m_socket_accessor = nullptr; - delete m_node.m_anim_node; - m_node.m_anim_node = nullptr; - } - m_nodes.clear(); -} - -void AnimGraphBlendTreeResource::initGraphConnectors() { - m_nodes.push_back(AnimNodeResourceFactory("BlendTree")); - m_nodes[0].m_name = "Outputs"; - m_nodes.push_back(AnimNodeResourceFactory("BlendTree")); - m_nodes[1].m_name = "Inputs"; -} - -bool AnimGraphBlendTreeResource::saveToFile(const char* filename) const { - json result; - - result["name"] = m_name; - result["type"] = "AnimGraphResource"; - - for (size_t i = 0; i < m_nodes.size(); i++) { - const AnimNodeResource& node = m_nodes[i]; - result["nodes"][i] = sAnimGraphNodeToJson(node, i, m_connections); - } - - for (size_t i = 0; i < m_connections.size(); i++) { - const AnimGraphConnectionResource& connection = m_connections[i]; - result["connections"][i] = sAnimGraphConnectionToJson(connection); - } - - // Graph inputs and outputs - { - const AnimNodeResource& graph_output_node = m_nodes[0]; - const std::vector graph_inputs = - graph_output_node.m_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 = m_nodes[1]; - const std::vector graph_outputs = - graph_input_node.m_socket_accessor->m_outputs; - for (size_t i = 0; i < graph_outputs.size(); i++) { - result["nodes"][1]["outputs"][i] = sSocketToJson(graph_outputs[i]); - } - } - - std::ofstream output_file; - output_file.open(filename); - output_file << result.dump(4, ' ') << std::endl; - output_file.close(); - - return true; -} - -bool AnimGraphBlendTreeResource::loadFromFile(const char* filename) { - std::ifstream input_file; - input_file.open(filename); - std::stringstream buffer; - buffer << input_file.rdbuf(); - - json json_data = json::parse(buffer.str(), nullptr, false); - if (json_data.is_discarded()) { - std::cerr << "Error parsing json of file '" << filename << "'." - << std::endl; - } - - if (json_data["type"] != "AnimGraphResource") { - std::cerr - << "Invalid json object. Expected type 'AnimGraphResource' but got '" - << json_data["type"] << "'." << std::endl; - } - - clear(); - clearNodes(); - - m_name = json_data["name"]; - - // Load nodes - for (size_t i = 0, n = json_data["nodes"].size(); i < n; i++) { - const json& json_node = json_data["nodes"][i]; - if (json_node["type"] != "AnimNodeResource") { - std::cerr - << "Invalid json object. Expected type 'AnimNodeResource' but got '" - << json_node["type"] << "'." << std::endl; - return false; - } - - AnimNodeResource node = sAnimGraphNodeFromJson(json_node, i); - m_nodes.push_back(node); - } - - // Setup graph inputs and outputs - const json& graph_outputs = json_data["nodes"][0]["inputs"]; - for (const auto & graph_output : graph_outputs) { - AnimNodeResource& graph_node = m_nodes[0]; - graph_node.m_socket_accessor->m_inputs.push_back( - sJsonToSocket(graph_output)); - } - - const json& graph_inputs = json_data["nodes"][1]["outputs"]; - for (const auto & graph_input : graph_inputs) { - AnimNodeResource& graph_node = m_nodes[1]; - graph_node.m_socket_accessor->m_outputs.push_back( - sJsonToSocket(graph_input)); - } - - // Load connections - for (const auto & json_connection : json_data["connections"]) { - if (json_connection["type"] != "AnimGraphConnectionResource") { - std::cerr - << "Invalid json object. Expected type 'AnimGraphConnectionResource' " - "but got '" - << json_connection["type"] << "'." << std::endl; - return false; - } - - AnimGraphConnectionResource connection = - sAnimGraphConnectionFromJson(json_connection); - m_connections.push_back(connection); - } - - return true; -} - -void AnimGraphBlendTreeResource::createRuntimeNodeInstances(AnimGraph& instance) const { - for (int i = 0; i < m_nodes.size(); i++) { - const AnimNodeResource& node_resource = m_nodes[i]; - AnimNode* node = AnimNodeFactory(node_resource.m_type_name); - node->m_name = node_resource.m_name; - node->m_node_type_name = node_resource.m_type_name; - node->m_index = i; - instance.m_nodes.push_back(node); - - // runtime node connections - instance.m_node_input_connections.emplace_back(); - instance.m_node_output_connections.emplace_back(); - - } -} - -void AnimGraphBlendTreeResource::prepareGraphIOData(AnimGraph& instance) const { - instance.m_node_descriptor = - AnimNodeDescriptorFactory("BlendTree", instance.m_nodes[0]); - instance.m_node_descriptor->m_outputs = - m_nodes[1].m_socket_accessor->m_outputs; - instance.m_node_descriptor->m_inputs = m_nodes[0].m_socket_accessor->m_inputs; - - // - // graph inputs - // - int input_block_size = 0; - std::vector& graph_inputs = instance.getGraphInputs(); - for (int i = 0; i < graph_inputs.size(); i++) { - input_block_size += sizeof(void*); - } - - if (input_block_size > 0) { - instance.m_input_buffer = new char[input_block_size]; - memset(instance.m_input_buffer, 0, input_block_size); - } - - int input_block_offset = 0; - for (int i = 0; i < graph_inputs.size(); i++) { - graph_inputs[i].m_reference.ptr = - (void*)&instance.m_input_buffer[input_block_offset]; - instance.m_node_descriptor->m_outputs[i].m_reference.ptr = - &instance.m_input_buffer[input_block_offset]; - input_block_offset += sizeof(void*); - } - - // - // graph outputs - // - int output_block_size = 0; - std::vector& graph_outputs = instance.getGraphOutputs(); - for (int i = 0; i < graph_outputs.size(); i++) { - output_block_size += sizeof(void*); - } - - if (output_block_size > 0) { - instance.m_output_buffer = new char[output_block_size]; - memset(instance.m_output_buffer, 0, output_block_size); - } - - int output_block_offset = 0; - for (int i = 0; i < graph_outputs.size(); i++) { - instance.m_node_descriptor->m_inputs[i].m_reference.ptr = - &instance.m_output_buffer[output_block_offset]; - output_block_offset += sizeof(void*); - } - - // connections: make source and target sockets point to the same address in the connection data storage. - // TODO: instead of every connection, only create data blocks for the source sockets and make sure every source socket gets allocated once. - size_t connection_data_storage_size = 0; - for (const auto & connection : m_connections) { - const AnimNodeResource& source_node = m_nodes[connection.source_node_index]; - Socket* source_socket = source_node.m_socket_accessor->GetOutputSocket( - connection.source_socket_name.c_str()); - connection_data_storage_size += source_socket->m_type_size; - } - - if (connection_data_storage_size > 0) { - instance.m_connection_data_storage = new char[connection_data_storage_size]; - memset(instance.m_connection_data_storage, 0, connection_data_storage_size); - } - - std::vector instance_node_descriptors( - m_nodes.size(), - nullptr); - for (int i = 0; i < m_nodes.size(); i++) { - instance_node_descriptors[i] = AnimNodeDescriptorFactory( - m_nodes[i].m_type_name, - instance.m_nodes[i]); - } - - instance_node_descriptors[0]->m_inputs = instance.m_node_descriptor->m_inputs; - instance_node_descriptors[1]->m_outputs = - instance.m_node_descriptor->m_outputs; - - size_t connection_data_offset = 0; - for (const auto & connection : m_connections) { - NodeDescriptorBase* source_node_descriptor = - instance_node_descriptors[connection.source_node_index]; - NodeDescriptorBase* target_node_descriptor = - instance_node_descriptors[connection.target_node_index]; - - AnimNode* source_node = instance.m_nodes[connection.source_node_index]; - AnimNode* target_node = instance.m_nodes[connection.target_node_index]; - - Socket* source_socket = source_node_descriptor->GetOutputSocket( - connection.source_socket_name.c_str()); - Socket* target_socket = target_node_descriptor->GetInputSocket( - connection.target_socket_name.c_str()); - - AnimGraphConnection instance_connection; - instance_connection.m_source_node = source_node; - instance_connection.m_source_socket = *source_socket; - instance_connection.m_target_node = target_node; - instance_connection.m_target_socket = *target_socket; - instance.m_node_input_connections[connection.target_node_index].push_back( - instance_connection); - instance.m_node_output_connections[connection.source_node_index].push_back( - instance_connection); - - source_node_descriptor->SetOutputUnchecked( - connection.source_socket_name.c_str(), - &instance.m_connection_data_storage[connection_data_offset]); - - target_node_descriptor->SetInputUnchecked( - connection.target_socket_name.c_str(), - &instance.m_connection_data_storage[connection_data_offset]); - - if (source_socket->m_type == SocketType::SocketTypeAnimation) { - instance.m_animdata_blocks.push_back( - (AnimData*)(&instance - .m_connection_data_storage[connection_data_offset])); - } - - connection_data_offset += source_socket->m_type_size; - } - - // - // const node inputs - // - std::vector const_inputs = - getConstNodeInputs( instance_node_descriptors); - size_t const_node_inputs_buffer_size = 0; - for (auto & const_input : const_inputs) { - if (const_input->m_type == SocketType::SocketTypeString) { - // TODO: implement string const node input support - std::cerr << "Error: const inputs for strings not yet implemented!" - << std::endl; - abort(); - } - const_node_inputs_buffer_size += const_input->m_type_size; - } - - if (const_node_inputs_buffer_size > 0) { - instance.m_const_node_inputs = new char[const_node_inputs_buffer_size]; - memset(instance.m_const_node_inputs, '\0', const_node_inputs_buffer_size); - } - - size_t const_input_buffer_offset = 0; - for (auto & i : const_inputs) { - Socket* const_input = i; - - // TODO: implement string const node input support - assert(const_input->m_type != SocketType::SocketTypeString); - - *const_input->m_reference.ptr_ptr = - &instance.m_const_node_inputs[const_input_buffer_offset]; - memcpy (*const_input->m_reference.ptr_ptr, &const_input->m_value, i->m_type_size); - - const_input_buffer_offset += i->m_type_size; - } - - for (int i = 0; i < m_nodes.size(); i++) { - delete instance_node_descriptors[i]; - } -} - -void AnimGraphBlendTreeResource::setRuntimeNodeProperties(AnimGraph& instance) const { - for (int i = 2; i < m_nodes.size(); i++) { - const AnimNodeResource& node_resource = m_nodes[i]; - - NodeDescriptorBase* node_instance_accessor = AnimNodeDescriptorFactory( - node_resource.m_type_name, - instance.m_nodes[i]); - - std::vector& resource_properties = - node_resource.m_socket_accessor->m_properties; - for (const auto & property : resource_properties) { - const std::string& name = property.m_name; - - switch (property.m_type) { - case SocketType::SocketTypeBool: - node_instance_accessor->SetProperty( - name.c_str(), - property.m_value.flag); - break; - case SocketType::SocketTypeInt: - node_instance_accessor->SetProperty( - name.c_str(), - property.m_value.int_value); - break; - case SocketType::SocketTypeFloat: - node_instance_accessor->SetProperty( - name.c_str(), - property.m_value.float_value); - break; - case SocketType::SocketTypeVec3: - node_instance_accessor->SetProperty( - name.c_str(), - property.m_value.vec3); - break; - case SocketType::SocketTypeQuat: - node_instance_accessor->SetProperty( - name.c_str(), - property.m_value.quat); - break; - case SocketType::SocketTypeString: - node_instance_accessor->SetProperty( - name.c_str(), - property.m_value_string); - break; - default: - std::cerr << "Invalid socket type " - << static_cast(property.m_type) << std::endl; - } - } - - delete node_instance_accessor; - } -} - -std::vector AnimGraphBlendTreeResource::getConstNodeInputs( - std::vector& instance_node_descriptors) const { - std::vector result; - - for (size_t i = 0; i < m_nodes.size(); i++) { - for (size_t j = 0, num_inputs = instance_node_descriptors[i]->m_inputs.size(); - j < num_inputs; - j++) { - Socket& input = instance_node_descriptors[i]->m_inputs[j]; - - if (*input.m_reference.ptr_ptr == nullptr) { - memcpy(&input.m_value, &m_nodes[i].m_socket_accessor->m_inputs[j].m_value, sizeof(Socket::SocketValue)); - result.push_back(&input); - } - } - } - - return result; -} diff --git a/src/AnimGraph/AnimGraphBlendTreeResource.h b/src/AnimGraph/AnimGraphBlendTreeResource.h deleted file mode 100644 index 3715be0..0000000 --- a/src/AnimGraph/AnimGraphBlendTreeResource.h +++ /dev/null @@ -1,138 +0,0 @@ -// -// Created by martin on 04.02.22. -// - -#ifndef ANIMTESTBED_ANIMGRAPHBLENDTREERESOURCE_H -#define ANIMTESTBED_ANIMGRAPHBLENDTREERESOURCE_H - -#include -#include -#include -#include -#include -#include - -#include "AnimGraph.h" -#include "AnimGraphData.h" -#include "AnimGraphNodes.h" -#include "SyncTrack.h" - -struct AnimNode; - -struct AnimNodeResource { - std::string m_name; - std::string m_node_type_name; - AnimNode* m_anim_node = nullptr; - NodeDescriptorBase* m_socket_accessor = nullptr; - float m_position[2] = {0.f, 0.f}; -}; - - - -// -// AnimGraphResource -// -struct AnimGraphConnectionResource { - size_t source_node_index = -1; - std::string source_socket_name; - size_t target_node_index = -1; - std::string target_socket_name; -}; - -struct AnimGraphBlendTreeResource { - std::string m_name; - std::vector m_nodes; - std::vector m_connections; - - ~AnimGraphBlendTreeResource() { - for (auto & m_node : m_nodes) { - delete m_node.m_anim_node; - delete m_node.m_socket_accessor; - } - } - - AnimGraphBlendTreeResource() { clear(); } - - void clear(); - void clearNodes(); - void initGraphConnectors(); - bool saveToFile(const char* filename) const; - bool loadFromFile(const char* filename); - - AnimNodeResource& getGraphOutputNode() { return m_nodes[0]; } - AnimNodeResource& getGraphInputNode() { return m_nodes[1]; } - - size_t getNodeIndex(const AnimNodeResource& node_resource) const { - for (size_t i = 0, n = m_nodes.size(); i < n; i++) { - if (&m_nodes[i] == &node_resource) { - return i; - } - } - - return -1; - } - - size_t addNode(const AnimNodeResource &node_resource) { - m_nodes.push_back(node_resource); - return m_nodes.size() - 1; - } - - bool connectSockets( - const AnimNodeResource& source_node, - const std::string& source_socket_name, - const AnimNodeResource& target_node, - const std::string& target_socket_name) { - size_t source_node_index = getNodeIndex(source_node); - size_t target_node_index = getNodeIndex(target_node); - - if (source_node_index >= m_nodes.size() - || target_node_index >= m_nodes.size()) { - std::cerr << "Cannot connect nodes: could not find nodes." << std::endl; - return false; - } - - Socket* source_socket = - source_node.m_socket_accessor->GetOutputSocket(source_socket_name.c_str()); - Socket* target_socket = - target_node.m_socket_accessor->GetInputSocket(target_socket_name.c_str()); - - if (source_socket == nullptr || target_socket == nullptr) { - std::cerr << "Cannot connect nodes: could not find sockets." << std::endl; - return false; - } - - AnimGraphConnectionResource connection; - connection.source_node_index = source_node_index; - connection.source_socket_name = source_socket_name; - connection.target_node_index = target_node_index; - connection.target_socket_name = target_socket_name; - m_connections.push_back(connection); - - return true; - } - - bool isSocketConnected( - const AnimNodeResource& node, - const std::string& socket_name) { - size_t node_index = getNodeIndex(node); - for (const auto & connection : m_connections) { - if ((connection.source_node_index == node_index - && connection.source_socket_name == socket_name) - || ((connection.target_node_index == node_index) - && connection.target_socket_name == socket_name)) { - return true; - } - } - - return false; - } - - void createInstance(AnimGraph& result) const; - - void createRuntimeNodeInstances(AnimGraph& instance) const; - void prepareGraphIOData(AnimGraph& instance) const; - void setRuntimeNodeProperties(AnimGraph& instance) const; - std::vector getConstNodeInputs(std::vector& instance_node_descriptors) const; -}; - -#endif //ANIMTESTBED_ANIMGRAPHBLENDTREERESOURCE_H