Skip to content

Commit 7aba10b

Browse files
committed
Merge pull request #94858 from TokageItLab/early-break-loop-at-end
Determine `break_loop_at_end` 1 frame earlier using prediction by delta
2 parents c15242b + 4de79fe commit 7aba10b

File tree

4 files changed

+9
-13
lines changed

4 files changed

+9
-13
lines changed

scene/animation/animation_blend_tree.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -138,15 +138,11 @@ AnimationNode::NodeTimeInfo AnimationNodeAnimation::_process(const AnimationMixe
138138
bool p_seek = p_playback_info.seeked;
139139
bool p_is_external_seeking = p_playback_info.is_external_seeking;
140140

141-
bool is_just_looped = false;
142-
143141
// 1. Progress for AnimationNode.
142+
bool will_end = Animation::is_greater_or_equal_approx(cur_time + cur_delta, cur_len);
144143
if (cur_loop_mode != Animation::LOOP_NONE) {
145144
if (cur_loop_mode == Animation::LOOP_LINEAR) {
146145
if (!Math::is_zero_approx(cur_len)) {
147-
if (Animation::is_less_or_equal_approx(prev_time, cur_len) && Animation::is_greater_approx(cur_time, cur_len)) {
148-
is_just_looped = true; // Don't break with negative timescale since remain will not be 0.
149-
}
150146
cur_time = Math::fposmod(cur_time, cur_len);
151147
}
152148
backward = false;
@@ -156,7 +152,6 @@ AnimationNode::NodeTimeInfo AnimationNodeAnimation::_process(const AnimationMixe
156152
backward = !backward;
157153
} else if (Animation::is_less_or_equal_approx(prev_time, cur_len) && Animation::is_greater_approx(cur_time, cur_len)) {
158154
backward = !backward;
159-
is_just_looped = true; // Don't break with negative timescale since remain will not be 0.
160155
}
161156
cur_time = Math::pingpong(cur_time, cur_len);
162157
}
@@ -190,7 +185,7 @@ AnimationNode::NodeTimeInfo AnimationNodeAnimation::_process(const AnimationMixe
190185
nti.position = cur_time;
191186
nti.delta = cur_delta;
192187
nti.loop_mode = cur_loop_mode;
193-
nti.is_just_looped = is_just_looped;
188+
nti.will_end = will_end;
194189

195190
// 3. Progress for Animation.
196191
double prev_playback_time = prev_time + start_offset;

scene/animation/animation_node_state_machine.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -804,7 +804,7 @@ AnimationNode::NodeTimeInfo AnimationNodeStateMachinePlayback::_process(const St
804804
pi.weight = 0;
805805
current_nti = p_state_machine->blend_node(p_state_machine->states[current].node, current, pi, AnimationNode::FILTER_IGNORE, true, true);
806806
// Don't process first node if not necessary, insteads process next node.
807-
_transition_to_next_recursive(tree, p_state_machine, p_test_only);
807+
_transition_to_next_recursive(tree, p_state_machine, p_delta, p_test_only);
808808
}
809809

810810
// Check current node existence.
@@ -881,7 +881,7 @@ AnimationNode::NodeTimeInfo AnimationNodeStateMachinePlayback::_process(const St
881881
}
882882

883883
// Find next and see when to transition.
884-
bool will_end = _transition_to_next_recursive(tree, p_state_machine, p_test_only) || current == AnimationNodeStateMachine::END_NODE;
884+
bool will_end = _transition_to_next_recursive(tree, p_state_machine, p_delta, p_test_only) || current == AnimationNodeStateMachine::END_NODE;
885885

886886
// Predict remaining time.
887887
if (will_end || ((p_state_machine->get_state_machine_type() == AnimationNodeStateMachine::STATE_MACHINE_TYPE_NESTED) && !p_state_machine->has_transition_from(current))) {
@@ -899,10 +899,11 @@ AnimationNode::NodeTimeInfo AnimationNodeStateMachinePlayback::_process(const St
899899
return current_nti;
900900
}
901901

902-
bool AnimationNodeStateMachinePlayback::_transition_to_next_recursive(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine, bool p_test_only) {
902+
bool AnimationNodeStateMachinePlayback::_transition_to_next_recursive(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine, double p_delta, bool p_test_only) {
903903
_reset_request_for_fading_from = false;
904904

905905
AnimationMixer::PlaybackInfo pi;
906+
pi.delta = p_delta;
906907
NextInfo next;
907908
Vector<StringName> transition_path;
908909
transition_path.push_back(current);

scene/animation/animation_node_state_machine.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ class AnimationNodeStateMachinePlayback : public Resource {
306306
AnimationNode::NodeTimeInfo _process(const String &p_base_path, AnimationNodeStateMachine *p_state_machine, const AnimationMixer::PlaybackInfo p_playback_info, bool p_test_only);
307307

308308
bool _check_advance_condition(const Ref<AnimationNodeStateMachine> p_state_machine, const Ref<AnimationNodeStateMachineTransition> p_transition) const;
309-
bool _transition_to_next_recursive(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine, bool p_test_only);
309+
bool _transition_to_next_recursive(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine, double p_delta, bool p_test_only);
310310
NextInfo _find_next(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine) const;
311311
Ref<AnimationNodeStateMachineTransition> _check_group_transition(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine, const AnimationNodeStateMachine::Transition &p_transition, Ref<AnimationNodeStateMachine> &r_state_machine, bool &r_bypass) const;
312312
bool _can_transition_to_next(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine, NextInfo p_next, bool p_test_only);

scene/animation/animation_tree.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ class AnimationNode : public Resource {
7474

7575
// Needs internally to estimate remain time, the previous frame values are not retained.
7676
Animation::LoopMode loop_mode = Animation::LOOP_NONE;
77-
bool is_just_looped = false; // For breaking loop, it is true when just looped.
77+
bool will_end = false; // For breaking loop, it is true when just looped.
7878
bool is_infinity = false; // For unpredictable state machine's end.
7979

8080
bool is_looping() {
@@ -84,7 +84,7 @@ class AnimationNode : public Resource {
8484
if ((is_looping() && !p_break_loop) || is_infinity) {
8585
return HUGE_LENGTH;
8686
}
87-
if (p_break_loop && is_just_looped) {
87+
if (is_looping() && p_break_loop && will_end) {
8888
return 0;
8989
}
9090
double remain = length - position;

0 commit comments

Comments
 (0)