AnimTestbed/src/AnimGraph/AnimGraph.cc

288 lines
9.0 KiB
C++
Raw Normal View History

2022-03-25 11:46:44 +01:00
//
// Created by martin on 25.03.22.
//
#include "AnimGraph.h"
#include <cstring>
bool AnimGraph::init(AnimGraphContext& context) {
for (size_t i = 2; i < m_nodes.size(); i++) {
if (!m_nodes[i]->Init(context)) {
return false;
}
}
2022-04-13 15:47:43 +02:00
std::vector<AnimGraphConnection>& graph_outputs = m_node_input_connections[0];
for (size_t i = 0, n = graph_outputs.size(); i < n; i++) {
AnimGraphConnection& connection = graph_outputs[i];
if (connection.m_target_socket.m_type == SocketType::SocketTypeAnimation) {
AnimData* graph_anim_output =
static_cast<AnimData*>(connection.m_target_socket.m_reference.ptr);
assert(graph_anim_output != nullptr);
graph_anim_output->m_local_matrices.resize(
context.m_skeleton->num_soa_joints());
}
}
return true;
}
2022-03-25 11:46:44 +01:00
void AnimGraph::updateOrderedNodes() {
m_eval_ordered_nodes.clear();
updateOrderedNodesRecursive(0);
}
2022-03-25 11:46:44 +01:00
void AnimGraph::updateOrderedNodesRecursive(int node_index) {
AnimNode* node = m_nodes[node_index];
const std::vector<AnimGraphConnection> node_input_connections =
m_node_input_connections[node_index];
for (size_t i = 0, n = node_input_connections.size(); i < n; i++) {
int input_node_index =
getAnimNodeIndex(node_input_connections[i].m_source_node);
if (input_node_index == 1) {
continue;
}
updateOrderedNodesRecursive(input_node_index);
2022-03-25 11:46:44 +01:00
}
if (node_index != 0) {
m_eval_ordered_nodes.push_back(node);
}
2022-03-25 11:46:44 +01:00
}
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<AnimGraphConnection>& graph_output_inputs =
m_node_input_connections[0];
2022-03-25 11:46:44 +01:00
for (size_t i = 0, n = graph_output_inputs.size(); i < n; i++) {
const AnimGraphConnection& graph_input = graph_output_inputs[i];
AnimNode* node = graph_input.m_source_node;
2022-03-25 11:46:44 +01:00
if (node != nullptr) {
node->m_state = AnimNodeEvalState::Activated;
}
}
2022-04-13 15:47:43 +02:00
for (size_t i = m_eval_ordered_nodes.size() - 1; i > 0; i--) {
2022-03-25 11:46:44 +01:00
AnimNode* node = m_eval_ordered_nodes[i];
if (checkIsNodeActive(node)) {
int node_index = node->m_index;
node->MarkActiveInputs(m_node_input_connections[node_index]);
2022-03-25 11:46:44 +01:00
// Non-animation data inputs are always active.
for (size_t j = 0, nj = m_node_input_connections[node_index].size();
j < nj;
j++) {
const AnimGraphConnection& input =
m_node_input_connections[node_index][j];
if (input.m_source_node != nullptr
&& input.m_target_socket.m_type
!= SocketType::SocketTypeAnimation) {
input.m_source_node->m_state = AnimNodeEvalState::Activated;
2022-03-25 11:46:44 +01:00
}
}
}
}
}
2022-04-13 15:47:43 +02:00
void AnimGraph::prepareNodeEval(
AnimGraphContext& graph_context,
size_t node_index) {
for (size_t i = 0, n = m_node_output_connections[node_index].size(); i < n;
i++) {
AnimGraphConnection& output_connection =
m_node_output_connections[node_index][i];
if (output_connection.m_source_socket.m_type
!= SocketType::SocketTypeAnimation) {
continue;
}
2022-04-13 15:47:43 +02:00
assert (*output_connection.m_source_socket.m_reference.ptr_ptr == nullptr);
(*output_connection.m_source_socket.m_reference.ptr_ptr) =
2022-04-13 15:47:43 +02:00
m_anim_data_work_buffer.allocate(graph_context);
}
for (size_t i = 0, n = m_node_input_connections[node_index].size(); i < n;
i++) {
AnimGraphConnection& input_connection =
m_node_input_connections[node_index][i];
if (input_connection.m_source_socket.m_type
!= SocketType::SocketTypeAnimation) {
continue;
}
(*input_connection.m_target_socket.m_reference.ptr_ptr) =
(*input_connection.m_source_socket.m_reference.ptr_ptr);
}
}
void AnimGraph::finishNodeEval(size_t node_index) {
for (size_t i = 0, n = m_node_input_connections[node_index].size(); i < n;
i++) {
AnimGraphConnection& input_connection =
m_node_input_connections[node_index][i];
if (input_connection.m_source_socket.m_type
!= SocketType::SocketTypeAnimation) {
continue;
}
2022-04-13 15:47:43 +02:00
m_anim_data_work_buffer.free(static_cast<AnimData*>(
input_connection.m_source_socket.m_reference.ptr));
(*input_connection.m_source_socket.m_reference.ptr_ptr) = nullptr;
}
}
void AnimGraph::evalInputNode() {
for (size_t i = 0, n = m_node_output_connections[1].size(); i < n; i++) {
AnimGraphConnection& graph_input_connection =
m_node_output_connections[1][i];
if (graph_input_connection.m_source_socket.m_type
!= SocketType::SocketTypeAnimation) {
memcpy(
*graph_input_connection.m_target_socket.m_reference.ptr_ptr,
graph_input_connection.m_source_socket.m_reference.ptr,
sizeof(void*));
printf("bla");
} else {
// TODO: how to deal with anim data outputs?
}
}
}
void AnimGraph::evalOutputNode() {
for (size_t i = 0, n = m_node_input_connections[0].size(); i < n; i++) {
AnimGraphConnection& graph_output_connection =
m_node_input_connections[0][i];
if (graph_output_connection.m_source_socket.m_type
!= SocketType::SocketTypeAnimation) {
memcpy(
graph_output_connection.m_target_socket.m_reference.ptr,
graph_output_connection.m_source_socket.m_reference.ptr,
graph_output_connection.m_target_socket.m_type_size);
} else {
2022-04-13 15:47:43 +02:00
AnimData* source_data = static_cast<AnimData*>(
*graph_output_connection.m_source_socket.m_reference.ptr_ptr);
AnimData* target_data = static_cast<AnimData*>(
graph_output_connection.m_target_socket.m_reference.ptr);
target_data->m_local_matrices = source_data->m_local_matrices;
}
}
}
2022-03-25 11:46:44 +01:00
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_input_connections[node_index]);
2022-03-25 11:46:44 +01:00
}
}
void AnimGraph::updateTime(float dt) {
const std::vector<AnimGraphConnection>& graph_output_inputs =
m_node_input_connections[0];
2022-03-25 11:46:44 +01:00
for (size_t i = 0, n = graph_output_inputs.size(); i < n; i++) {
AnimNode* node = graph_output_inputs[i].m_source_node;
2022-03-25 11:46:44 +01:00
if (node != nullptr) {
node->UpdateTime(node->m_time_now, node->m_time_now + dt);
}
}
for (size_t i = m_eval_ordered_nodes.size() - 1; i > 0; --i) {
2022-03-25 11:46:44 +01:00
AnimNode* node = m_eval_ordered_nodes[i];
if (node->m_state != AnimNodeEvalState::TimeUpdated) {
continue;
}
int node_index = node->m_index;
float node_time_now = node->m_time_now;
float node_time_last = node->m_time_last;
const std::vector<AnimGraphConnection>& node_input_connections =
m_node_input_connections[node_index];
for (size_t i = 0, n = node_input_connections.size(); i < n; i++) {
AnimNode* input_node = node_input_connections[i].m_source_node;
2022-03-25 11:46:44 +01:00
// Only propagate time updates via animation sockets.
if (input_node != nullptr
&& node_input_connections[i].m_target_socket.m_type
== SocketType::SocketTypeAnimation
2022-03-25 11:46:44 +01:00
&& input_node->m_state == AnimNodeEvalState::Activated) {
input_node->UpdateTime(node_time_last, node_time_now);
}
}
}
}
void AnimGraph::evaluate(AnimGraphContext& context) {
for (int i = 0, n = m_eval_ordered_nodes.size(); i < n; i++) {
2022-03-25 11:46:44 +01:00
AnimNode* node = m_eval_ordered_nodes[i];
2022-03-25 11:46:44 +01:00
if (node->m_state == AnimNodeEvalState::Deactivated) {
continue;
}
2022-04-13 15:47:43 +02:00
prepareNodeEval(context, node->m_index);
node->Evaluate(context);
finishNodeEval(node->m_index);
2022-03-25 11:46:44 +01:00
}
2022-04-11 11:40:53 +02:00
evalOutputNode();
2022-03-25 11:46:44 +01:00
}
Socket* AnimGraph::getInputSocket(const std::string& name) {
for (size_t i = 0, n = m_node_output_connections[1].size(); i < n; i++) {
AnimGraphConnection& connection = m_node_output_connections[1][i];
if (connection.m_source_socket.m_name == name) {
return &connection.m_source_socket;
}
2022-03-25 11:46:44 +01:00
}
return nullptr;
2022-03-25 11:46:44 +01:00
}
Socket* AnimGraph::getOutputSocket(const std::string& name) {
for (size_t i = 0, n = m_node_input_connections[0].size(); i < n; i++) {
AnimGraphConnection& connection = m_node_input_connections[0][i];
if (connection.m_target_socket.m_name == name) {
return &connection.m_target_socket;
}
2022-03-25 11:46:44 +01:00
}
return nullptr;
}
const Socket* AnimGraph::getInputSocket(const std::string& name) const {
for (size_t i = 0, n = m_node_output_connections[1].size(); i < n; i++) {
const AnimGraphConnection& connection = m_node_output_connections[1][i];
if (connection.m_source_socket.m_name == name) {
return &connection.m_source_socket;
}
}
return nullptr;
}
const Socket* AnimGraph::getOutputSocket(const std::string& name) const {
for (size_t i = 0, n = m_node_input_connections[0].size(); i < n; i++) {
const AnimGraphConnection& connection = m_node_input_connections[0][i];
if (connection.m_target_socket.m_name == name) {
return &connection.m_target_socket;
}
}
return nullptr;
2022-03-25 11:46:44 +01:00
}