AnimTestbed/src/AnimGraph/AnimGraph.cc

147 lines
4.2 KiB
C++
Raw Normal View History

2022-03-25 11:46:44 +01:00
//
// Created by martin on 25.03.22.
//
#include "AnimGraph.h"
void AnimGraph::updateOrderedNodes() {
std::vector<int> node_index_stack;
node_index_stack.push_back(0);
m_eval_ordered_nodes.clear();
while (node_index_stack.size() > 0) {
std::vector<NodeInput>& node_inputs =
m_node_inputs[node_index_stack.back()];
node_index_stack.pop_back();
for (size_t i = 0, n = node_inputs.size(); i < n; i++) {
AnimNode* input_node = node_inputs[i].m_node;
if (input_node == nullptr) {
continue;
}
int input_node_index = input_node->m_index;
bool is_node_processed = false;
for (size_t j = 0, m = m_eval_ordered_nodes.size(); j < m; j++) {
if (m_eval_ordered_nodes[j] == input_node) {
is_node_processed = true;
break;
}
}
if (is_node_processed) {
continue;
}
m_eval_ordered_nodes.push_back(input_node);
node_index_stack.push_back(input_node_index);
}
}
}
void AnimGraph::markActiveNodes() {
for (size_t i = 0, n = m_nodes.size(); i < n; i++) {
m_nodes[i]->m_state = AnimNodeEvalState::Deactivated;
}
const std::vector<NodeInput> graph_output_inputs = m_node_inputs[0];
for (size_t i = 0, n = graph_output_inputs.size(); i < n; i++) {
const NodeInput& graph_input = graph_output_inputs[i];
AnimNode* node = graph_input.m_node;
if (node != nullptr) {
node->m_state = AnimNodeEvalState::Activated;
}
}
for (size_t i = 0, n = m_eval_ordered_nodes.size(); i < n; i++) {
AnimNode* node = m_eval_ordered_nodes[i];
if (checkIsNodeActive(node)) {
int node_index = node->m_index;
node->MarkActiveInputs(m_node_inputs[node_index]);
// Non-animation data inputs are always active.
for (size_t j = 0, nj = m_node_inputs[node_index].size(); j < nj; j++) {
const NodeInput& input = m_node_inputs[node_index][j];
if (input.m_node != nullptr && input.m_type != SocketType::SocketTypeAnimation) {
input.m_node->m_state = AnimNodeEvalState::Activated;
}
}
}
}
}
void AnimGraph::evalSyncTracks() {
for (size_t i = m_eval_ordered_nodes.size() - 1; i >= 0; i--) {
AnimNode* node = m_eval_ordered_nodes[i];
int node_index = node->m_index;
if (node->m_state == AnimNodeEvalState::Deactivated) {
continue;
}
node->CalcSyncTrack(m_node_inputs[node_index]);
}
}
void AnimGraph::updateTime(float dt) {
const std::vector<NodeInput> graph_output_inputs = m_node_inputs[0];
for (size_t i = 0, n = graph_output_inputs.size(); i < n; i++) {
AnimNode* node = m_eval_ordered_nodes[i];
if (node != nullptr) {
node->UpdateTime(node->m_time_now, node->m_time_now + dt);
}
}
for (size_t i = 0, n = m_eval_ordered_nodes.size(); i < n; i++) {
AnimNode* node = m_eval_ordered_nodes[i];
if (node->m_state != AnimNodeEvalState::TimeUpdated) {
continue;
}
int node_index = node->m_index;
const std::vector<NodeInput> node_inputs =
m_node_inputs[node_index];
float node_time_now = node->m_time_now;
float node_time_last = node->m_time_last;
for (size_t i = 0, n = node_inputs.size(); i < n; i++) {
AnimNode* input_node = node_inputs[i].m_node;
// Only propagate time updates via animation sockets.
if (input_node != nullptr
&& node_inputs[i].m_type == SocketType::SocketTypeAnimation
&& input_node->m_state == AnimNodeEvalState::Activated) {
input_node->UpdateTime(node_time_last, node_time_now);
}
}
}
}
void AnimGraph::evaluate() {
for (size_t i = m_eval_ordered_nodes.size() - 1; i >= 0; i--) {
AnimNode* node = m_eval_ordered_nodes[i];
if (node->m_state == AnimNodeEvalState::Deactivated) {
continue;
}
node->Evaluate();
}
}
void* AnimGraph::getOutput(const std::string& name) const {
Socket* socket = m_socket_accessor->FindInputSocket(name);
if (socket == nullptr) {
return nullptr;
}
return socket->m_value.ptr;
}
void* AnimGraph::getInput(const std::string& name) const {
Socket* socket = m_socket_accessor->FindOutputSocket(name);
if (socket == nullptr) {
return nullptr;
}
return *(socket->m_value.ptr_ptr);
}