Skip to content

Commit

Permalink
Fixes to animation graph evaluation (#15689)
Browse files Browse the repository at this point in the history
# Objective

Fix a couple of substantial errors found during the development of
#15665:
- `AnimationCurveEvaluator::add` was secretly unreachable. In other
words, additive blending never actually occurred.
- Weights from the animation graph nodes were ignored, and only
`ActiveAnimation`'s weights were used.

## Solution

Made additive blending reachable and included the graph node weight in
the weight of the stack elements appended in the curve application loop
of `animate_targets`.

## Testing

Tested on existing examples and on the new example added in #15665.
  • Loading branch information
mweatherley authored Oct 7, 2024
1 parent 280f77a commit d3657a0
Showing 1 changed file with 37 additions and 2 deletions.
39 changes: 37 additions & 2 deletions crates/bevy_animation/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1102,7 +1102,7 @@ pub fn animate_targets(
};

match animation_graph_node.node_type {
AnimationNodeType::Blend | AnimationNodeType::Add => {
AnimationNodeType::Blend => {
// This is a blend node.
for edge_index in threaded_animation_graph.sorted_edge_ranges
[animation_graph_node_index.index()]
Expand All @@ -1123,6 +1123,27 @@ pub fn animate_targets(
}
}

AnimationNodeType::Add => {
// This is an additive blend node.
for edge_index in threaded_animation_graph.sorted_edge_ranges
[animation_graph_node_index.index()]
.clone()
{
if let Err(err) = evaluation_state
.add_all(threaded_animation_graph.sorted_edges[edge_index as usize])
{
warn!("Failed to blend animation: {:?}", err);
}
}

if let Err(err) = evaluation_state.push_blend_register_all(
animation_graph_node.weight,
animation_graph_node_index,
) {
warn!("Animation blending failed: {:?}", err);
}
}

AnimationNodeType::Clip(ref animation_clip_handle) => {
// This is a clip node.
let Some(active_animation) = animation_player
Expand Down Expand Up @@ -1175,7 +1196,7 @@ pub fn animate_targets(
continue;
};

let weight = active_animation.weight;
let weight = active_animation.weight * animation_graph_node.weight;
let seek_time = active_animation.seek_time;

for curve in curves {
Expand Down Expand Up @@ -1323,6 +1344,20 @@ impl AnimationEvaluationState {
Ok(())
}

/// Calls [`AnimationCurveEvaluator::add`] on all curve evaluator types
/// that we've been building up for a single target.
///
/// The given `node_index` is the node that we're evaluating.
fn add_all(&mut self, node_index: AnimationNodeIndex) -> Result<(), AnimationEvaluationError> {
for curve_evaluator_type in self.current_curve_evaluator_types.keys() {
self.curve_evaluators
.get_mut(curve_evaluator_type)
.unwrap()
.add(node_index)?;
}
Ok(())
}

/// Calls [`AnimationCurveEvaluator::push_blend_register`] on all curve
/// evaluator types that we've been building up for a single target.
///
Expand Down

0 comments on commit d3657a0

Please sign in to comment.