AnimTestbed/src/AnimGraph/AnimGraph.h

192 lines
4.7 KiB
C
Raw Normal View History

2022-03-25 11:46:44 +01:00
//
// Created by martin on 25.03.22.
//
#ifndef ANIMTESTBED_ANIMGRAPH_H
#define ANIMTESTBED_ANIMGRAPH_H
2022-03-25 12:05:56 +01:00
#include "AnimGraphData.h"
#include "AnimGraphNodes.h"
2022-03-25 11:46:44 +01:00
struct AnimDataWorkBuffer {
2022-04-13 15:47:43 +02:00
struct AnimDataList {
AnimData* m_anim_data = nullptr;
AnimDataList* next = nullptr;
};
AnimDataList* m_anim_data_list = nullptr;
size_t m_num_allocations = 0;
~AnimDataWorkBuffer() {
AnimDataList* list_node = m_anim_data_list;
while (list_node != nullptr) {
AnimDataList* current_node = list_node;
list_node = list_node->next;
//delete current_node->m_anim_data;
current_node->m_anim_data = nullptr;
delete current_node;
}
}
2022-04-13 15:47:43 +02:00
AnimData* allocate(AnimGraphContext& graph_context) {
if (m_anim_data_list == nullptr) {
AnimData* result = new AnimData();
result->m_local_matrices.resize(graph_context.m_skeleton->num_soa_joints());
m_num_allocations++;
return result;
}
AnimData* result = m_anim_data_list->m_anim_data;
m_anim_data_list = m_anim_data_list->next;
delete m_anim_data_list;
return result;
}
2022-04-13 15:47:43 +02:00
void free(AnimData* anim_data) {
AnimDataList* list_node = new AnimDataList;
list_node->next = m_anim_data_list;
list_node->m_anim_data = anim_data;
m_anim_data_list = list_node;
}
2022-04-13 15:47:43 +02:00
size_t size() {
size_t result = 0;
AnimDataList* node = m_anim_data_list;
while (node != nullptr) {
result ++;
node = node->next;
}
return result;
}
};
2022-03-25 11:46:44 +01:00
//
// AnimGraph (Runtime)
//
struct AnimGraph {
AnimData m_local_transforms;
std::vector<AnimNode*> m_nodes;
std::vector<AnimNode*> m_eval_ordered_nodes;
std::vector<std::vector<AnimGraphConnection> > m_node_input_connections;
std::vector<std::vector<AnimGraphConnection> > m_node_output_connections;
2022-03-25 11:46:44 +01:00
NodeSocketAccessorBase* m_socket_accessor;
char* m_input_buffer = nullptr;
char* m_output_buffer = nullptr;
std::vector<Socket>& getGraphOutputs() { return m_socket_accessor->m_inputs; }
std::vector<Socket>& getGraphInputs() { return m_socket_accessor->m_outputs; }
2022-04-13 15:47:43 +02:00
AnimDataWorkBuffer m_anim_data_work_buffer;
2022-03-25 11:46:44 +01:00
~AnimGraph() {
delete[] m_input_buffer;
delete[] m_output_buffer;
for (int i = 0; i < m_nodes.size(); i++) {
delete m_nodes[i];
}
delete m_socket_accessor;
}
bool init(AnimGraphContext& context);
2022-03-25 11:46:44 +01:00
void updateOrderedNodes();
void updateOrderedNodesRecursive(int node_index);
2022-03-25 11:46:44 +01:00
void markActiveNodes();
bool checkIsNodeActive(AnimNode* node) {
return node->m_state != AnimNodeEvalState::Deactivated;
}
void evalInputNode();
2022-04-13 15:47:43 +02:00
void prepareNodeEval(AnimGraphContext& graph_context, size_t node_index);
void finishNodeEval(size_t node_index);
void evalOutputNode();
2022-03-25 11:46:44 +01:00
void evalSyncTracks();
void updateTime(float dt);
void evaluate(AnimGraphContext& context);
2022-03-25 11:46:44 +01:00
void reset() {
for (size_t i = 0, n = m_nodes.size(); i < n; i++) {
m_nodes[i]->m_time_now = 0.f;
m_nodes[i]->m_time_last = 0.f;
m_nodes[i]->m_state = AnimNodeEvalState::Undefined;
}
}
Socket* getInputSocket(const std::string& name);
Socket* getOutputSocket(const std::string& name);
2022-03-25 11:46:44 +01:00
const Socket* getInputSocket(const std::string& name) const;
const Socket* getOutputSocket(const std::string& name) const;
void* getInputPtr(const std::string& name) const {
const Socket* input_socket = getInputSocket(name);
if (input_socket != nullptr) {
return input_socket->m_reference.ptr;
}
return nullptr;
}
2022-04-13 15:47:43 +02:00
void* getOutputPtr(const std::string& name) const {
const Socket* input_socket = getOutputSocket(name);
if (input_socket != nullptr) {
return input_socket->m_reference.ptr;
}
return nullptr;
}
2022-03-25 11:46:44 +01:00
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 (
2022-03-25 11:46:44 +01:00
size_t node_index,
const std::string& input_name) const {
2022-03-25 11:46:44 +01:00
assert(node_index < m_nodes.size());
const std::vector<AnimGraphConnection>& 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.m_name == input_name) {
return input_connection[i].m_source_node;
2022-03-25 11:46:44 +01:00
}
}
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 (AnimNode* node) {
for (size_t i = 0; i < m_nodes.size(); i++) {
if (m_nodes[i] == node) {
return i;
}
}
return -1;
}
2022-03-25 11:46:44 +01:00
};
#endif //ANIMTESTBED_ANIMGRAPH_H