diff options
Diffstat (limited to 'scene/animation/animation_blend_tree.cpp')
-rw-r--r-- | scene/animation/animation_blend_tree.cpp | 54 |
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) { |