Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Determine break_loop_at_end 1 frame earlier using prediction by delta #94858

Merged
merged 1 commit into from
Jul 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 2 additions & 7 deletions scene/animation/animation_blend_tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,15 +138,11 @@ AnimationNode::NodeTimeInfo AnimationNodeAnimation::_process(const AnimationMixe
bool p_seek = p_playback_info.seeked;
bool p_is_external_seeking = p_playback_info.is_external_seeking;

bool is_just_looped = false;

// 1. Progress for AnimationNode.
bool will_end = Animation::is_greater_or_equal_approx(cur_time + cur_delta, cur_len);
if (cur_loop_mode != Animation::LOOP_NONE) {
if (cur_loop_mode == Animation::LOOP_LINEAR) {
if (!Math::is_zero_approx(cur_len)) {
if (Animation::is_less_or_equal_approx(prev_time, cur_len) && Animation::is_greater_approx(cur_time, cur_len)) {
is_just_looped = true; // Don't break with negative timescale since remain will not be 0.
}
cur_time = Math::fposmod(cur_time, cur_len);
}
backward = false;
Expand All @@ -156,7 +152,6 @@ AnimationNode::NodeTimeInfo AnimationNodeAnimation::_process(const AnimationMixe
backward = !backward;
} else if (Animation::is_less_or_equal_approx(prev_time, cur_len) && Animation::is_greater_approx(cur_time, cur_len)) {
backward = !backward;
is_just_looped = true; // Don't break with negative timescale since remain will not be 0.
}
cur_time = Math::pingpong(cur_time, cur_len);
}
Expand Down Expand Up @@ -190,7 +185,7 @@ AnimationNode::NodeTimeInfo AnimationNodeAnimation::_process(const AnimationMixe
nti.position = cur_time;
nti.delta = cur_delta;
nti.loop_mode = cur_loop_mode;
nti.is_just_looped = is_just_looped;
nti.will_end = will_end;

// 3. Progress for Animation.
double prev_playback_time = prev_time + start_offset;
Expand Down
7 changes: 4 additions & 3 deletions scene/animation/animation_node_state_machine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -804,7 +804,7 @@ AnimationNode::NodeTimeInfo AnimationNodeStateMachinePlayback::_process(const St
pi.weight = 0;
current_nti = p_state_machine->blend_node(p_state_machine->states[current].node, current, pi, AnimationNode::FILTER_IGNORE, true, true);
// Don't process first node if not necessary, insteads process next node.
_transition_to_next_recursive(tree, p_state_machine, p_test_only);
_transition_to_next_recursive(tree, p_state_machine, p_delta, p_test_only);
}

// Check current node existence.
Expand Down Expand Up @@ -881,7 +881,7 @@ AnimationNode::NodeTimeInfo AnimationNodeStateMachinePlayback::_process(const St
}

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

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

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

AnimationMixer::PlaybackInfo pi;
pi.delta = p_delta;
NextInfo next;
Vector<StringName> transition_path;
transition_path.push_back(current);
Expand Down
2 changes: 1 addition & 1 deletion scene/animation/animation_node_state_machine.h
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ class AnimationNodeStateMachinePlayback : public Resource {
AnimationNode::NodeTimeInfo _process(const String &p_base_path, AnimationNodeStateMachine *p_state_machine, const AnimationMixer::PlaybackInfo p_playback_info, bool p_test_only);

bool _check_advance_condition(const Ref<AnimationNodeStateMachine> p_state_machine, const Ref<AnimationNodeStateMachineTransition> p_transition) const;
bool _transition_to_next_recursive(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine, bool p_test_only);
bool _transition_to_next_recursive(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine, double p_delta, bool p_test_only);
NextInfo _find_next(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine) const;
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;
bool _can_transition_to_next(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine, NextInfo p_next, bool p_test_only);
Expand Down
4 changes: 2 additions & 2 deletions scene/animation/animation_tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class AnimationNode : public Resource {

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

bool is_looping() {
Expand All @@ -84,7 +84,7 @@ class AnimationNode : public Resource {
if ((is_looping() && !p_break_loop) || is_infinity) {
return HUGE_LENGTH;
}
if (p_break_loop && is_just_looped) {
if (is_looping() && p_break_loop && will_end) {
return 0;
}
double remain = length - position;
Expand Down
Loading