summaryrefslogtreecommitdiff
path: root/scene/animation/animation_blend_tree.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/animation/animation_blend_tree.cpp')
-rw-r--r--scene/animation/animation_blend_tree.cpp54
1 files changed, 35 insertions, 19 deletions
diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp
index 3fe46b380f..d3207c1a3d 100644
--- a/scene/animation/animation_blend_tree.cpp
+++ b/scene/animation/animation_blend_tree.cpp
@@ -350,29 +350,29 @@ double AnimationNodeOneShot::process(double p_time, bool p_seek, bool p_is_exter
set_parameter(active, true);
}
- real_t blend;
-
+ real_t blend = 1.0;
+ bool use_blend = sync;
if (cur_time < fade_in) {
if (fade_in > 0) {
+ use_blend = true;
blend = cur_time / fade_in;
} else {
- blend = 0;
+ blend = 0; // Should not happen.
}
} else if (!do_start && cur_remaining <= fade_out) {
+ use_blend = true;
if (fade_out > 0) {
blend = (cur_remaining / fade_out);
} else {
blend = 0;
}
- } else {
- blend = 1.0;
}
- double main_rem;
+ double main_rem = 0.0;
if (mix == MIX_MODE_ADD) {
main_rem = blend_input(0, p_time, p_seek, p_is_external_seeking, 1.0, FILTER_IGNORE, sync);
} else {
- main_rem = blend_input(0, p_time, p_seek, p_is_external_seeking, 1.0 - blend, FILTER_BLEND, sync); // Unlike below, processing this edge is a corner case.
+ main_rem = blend_input(0, p_time, use_blend && p_seek, p_is_external_seeking, 1.0 - blend, FILTER_BLEND, sync); // Unlike below, processing this edge is a corner case.
}
double os_rem = blend_input(1, os_seek ? cur_time : p_time, os_seek, p_is_external_seeking, Math::is_zero_approx(blend) ? CMP_EPSILON : blend, FILTER_PASS, true); // Blend values must be more than CMP_EPSILON to process discrete keys in edge.
@@ -825,6 +825,7 @@ double AnimationNodeTransition::process(double p_time, bool p_seek, bool p_is_ex
bool switched = false;
bool restart = false;
+ bool clear_remaining_fade = false;
if (pending_update) {
if (cur_current_index < 0 || cur_current_index >= get_input_count()) {
@@ -842,6 +843,10 @@ double AnimationNodeTransition::process(double p_time, bool p_seek, bool p_is_ex
pending_update = false;
}
+ if (p_time == 0 && p_seek && !p_is_external_seeking) {
+ clear_remaining_fade = true; // Reset occurs.
+ }
+
if (!cur_transition_request.is_empty()) {
int new_idx = find_input(cur_transition_request);
if (new_idx >= 0) {
@@ -849,10 +854,7 @@ double AnimationNodeTransition::process(double p_time, bool p_seek, bool p_is_ex
if (allow_transition_to_self) {
// Transition to same state.
restart = input_data[cur_current_index].reset;
- cur_prev_xfading = 0;
- set_parameter(prev_xfading, 0);
- cur_prev_index = -1;
- set_parameter(prev_index, -1);
+ clear_remaining_fade = true;
}
} else {
switched = true;
@@ -869,6 +871,13 @@ double AnimationNodeTransition::process(double p_time, bool p_seek, bool p_is_ex
set_parameter(transition_request, cur_transition_request);
}
+ if (clear_remaining_fade) {
+ cur_prev_xfading = 0;
+ set_parameter(prev_xfading, 0);
+ cur_prev_index = -1;
+ set_parameter(prev_index, -1);
+ }
+
// Special case for restart.
if (restart) {
set_parameter(time, 0);
@@ -910,24 +919,31 @@ double AnimationNodeTransition::process(double p_time, bool p_seek, bool p_is_ex
} else { // Cross-fading from prev to current.
- real_t blend = xfade_time == 0 ? 0 : (cur_prev_xfading / xfade_time);
- if (xfade_curve.is_valid()) {
- blend = xfade_curve->sample(blend);
+ real_t blend = 0.0;
+ real_t blend_inv = 1.0;
+ bool use_blend = sync;
+ if (xfade_time > 0) {
+ use_blend = true;
+ blend = cur_prev_xfading / xfade_time;
+ if (xfade_curve.is_valid()) {
+ blend = xfade_curve->sample(blend);
+ }
+ blend_inv = 1.0 - blend;
+ blend = Math::is_zero_approx(blend) ? CMP_EPSILON : blend;
+ blend_inv = Math::is_zero_approx(blend_inv) ? CMP_EPSILON : blend_inv;
}
// Blend values must be more than CMP_EPSILON to process discrete keys in edge.
- real_t blend_inv = 1.0 - blend;
if (input_data[cur_current_index].reset && !p_seek && switched) { // Just switched, seek to start of current.
- rem = blend_input(cur_current_index, 0, true, p_is_external_seeking, Math::is_zero_approx(blend_inv) ? CMP_EPSILON : blend_inv, FILTER_IGNORE, true);
+ rem = blend_input(cur_current_index, 0, true, p_is_external_seeking, blend_inv, FILTER_IGNORE, true);
} else {
- rem = blend_input(cur_current_index, p_time, p_seek, p_is_external_seeking, Math::is_zero_approx(blend_inv) ? CMP_EPSILON : blend_inv, FILTER_IGNORE, true);
+ rem = blend_input(cur_current_index, p_time, p_seek, p_is_external_seeking, blend_inv, FILTER_IGNORE, true);
}
+ blend_input(cur_prev_index, p_time, use_blend && p_seek, p_is_external_seeking, blend, FILTER_IGNORE, true);
if (p_seek) {
- blend_input(cur_prev_index, p_time, true, p_is_external_seeking, Math::is_zero_approx(blend) ? CMP_EPSILON : blend, FILTER_IGNORE, true);
cur_time = p_time;
} else {
- blend_input(cur_prev_index, p_time, false, p_is_external_seeking, Math::is_zero_approx(blend) ? CMP_EPSILON : blend, FILTER_IGNORE, true);
cur_time += p_time;
cur_prev_xfading -= p_time;
if (cur_prev_xfading < 0) {