Added support of time updates for simple embedded graphs.

This commit is contained in:
Martin Felis
2024-04-01 12:33:23 +02:00
parent 0aebe44bd5
commit 76ea38f118
12 changed files with 392 additions and 198 deletions
+42 -28
View File
@@ -32,8 +32,12 @@ void AnimGraphBlendTree::UpdateOrderedNodesRecursive(int 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++) {
if (node_input_connections[i].m_crosses_hierarchy) {
continue;
}
int input_node_index =
GetAnimNodeIndex(node_input_connections.at(i).m_source_node);
GetAnimNodeIndex(node_input_connections[i].m_source_node);
if (input_node_index == 1) {
continue;
@@ -58,9 +62,11 @@ void AnimGraphBlendTree::UpdateOrderedNodesRecursive(int node_index) {
}
}
void AnimGraphBlendTree::MarkActiveInputs() {
void AnimGraphBlendTree::MarkActiveInputs(const std::vector<AnimGraphConnection>& input_connections) {
for (size_t i = 0, n = m_nodes.size(); i < n; i++) {
m_nodes[i]->m_state = AnimNodeEvalState::Deactivated;
if (m_nodes[i]->m_tick_number != m_tick_number) {
m_nodes[i]->m_state = AnimNodeEvalState::Deactivated;
}
}
const std::vector<AnimGraphConnection>& graph_output_inputs =
@@ -69,15 +75,16 @@ void AnimGraphBlendTree::MarkActiveInputs() {
const AnimGraphConnection& graph_input = graph_output_inputs[i];
AnimNode* node = graph_input.m_source_node;
if (node != nullptr) {
node->m_tick_number = m_tick_number;
node->m_state = AnimNodeEvalState::Activated;
}
}
for (size_t i = m_eval_ordered_nodes.size() - 1; i >= 0; i--) {
for (int i = m_eval_ordered_nodes.size() - 1; i >= 0; i--) {
AnimNode* node = m_eval_ordered_nodes[i];
if (checkIsNodeActive(node)) {
node->MarkActiveInputs();
if (CheckIsNodeActive(node)) {
size_t node_index = GetAnimNodeIndex(node);
node->MarkActiveInputs(m_node_input_connections[node_index]);
// Non-animation data inputs are always active.
for (size_t j = 0, nj = m_node_input_connections[node_index].size();
@@ -95,14 +102,14 @@ void AnimGraphBlendTree::MarkActiveInputs() {
}
}
void AnimGraphBlendTree::CalcSyncTrack() {
void AnimGraphBlendTree::CalcSyncTrack(const std::vector<AnimGraphConnection>& input_connections) {
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->CalcSyncTrack();
node->CalcSyncTrack(m_node_input_connections[GetAnimNodeIndex(node)]);
}
}
@@ -113,35 +120,21 @@ void AnimGraphBlendTree::UpdateTime(float time_last, float time_now) {
m_node_input_connections[0];
for (size_t i = 0, n = graph_output_inputs.size(); i < n; i++) {
AnimNode* node = graph_output_inputs[i].m_source_node;
if (node != nullptr) {
node->UpdateTime(node->m_time_now, node->m_time_now + dt);
if (node != nullptr && node->m_state != AnimNodeEvalState::TimeUpdated) {
node->UpdateTime(time_last, time_now);
}
}
for (size_t i = m_eval_ordered_nodes.size() - 1; i > 0; --i) {
for (int i = m_eval_ordered_nodes.size() - 1; i >= 0; --i) {
AnimNode* node = m_eval_ordered_nodes[i];
if (node->m_state != AnimNodeEvalState::TimeUpdated) {
continue;
}
size_t node_index = GetAnimNodeIndex(node);
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;
// Only propagate time updates via animation sockets.
if (input_node != nullptr
&& node_input_connections[i].m_target_socket.m_type
== SocketType::SocketTypeAnimation
&& input_node->m_state == AnimNodeEvalState::Activated) {
input_node->UpdateTime(node_time_last, node_time_now);
}
}
PropagateTimeToNodeInputs(node);
}
m_state = AnimNodeEvalState::TimeUpdated;
}
void AnimGraphBlendTree::Evaluate(AnimGraphContext& context) {
@@ -156,6 +149,27 @@ void AnimGraphBlendTree::Evaluate(AnimGraphContext& context) {
}
}
void AnimGraphBlendTree::PropagateTimeToNodeInputs(const AnimNode* node) {
size_t node_index = GetAnimNodeIndex(node);
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;
// Only propagate time updates via animation sockets.
if (input_node != nullptr
&& node_input_connections[i].m_target_socket.m_type
== SocketType::SocketTypeAnimation
&& input_node->m_state == AnimNodeEvalState::Activated) {
input_node->UpdateTime(node_time_last, node_time_now);
}
}
}
Socket* AnimGraphBlendTree::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];