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

Add approximate comparing static methods to Animation and make Animation code use them #94554

Merged
merged 1 commit into from
Jul 24, 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
57 changes: 29 additions & 28 deletions scene/animation/animation_blend_tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,40 +144,40 @@ AnimationNode::NodeTimeInfo AnimationNodeAnimation::_process(const AnimationMixe
if (cur_loop_mode != Animation::LOOP_NONE) {
if (cur_loop_mode == Animation::LOOP_LINEAR) {
if (!Math::is_zero_approx(cur_len)) {
if (prev_time <= cur_len && cur_time > 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;
} else {
if (!Math::is_zero_approx(cur_len)) {
if (prev_time >= 0 && cur_time < 0) {
if (Animation::is_greater_or_equal_approx(prev_time, 0) && Animation::is_less_approx(cur_time, 0)) {
backward = !backward;
} else if (prev_time <= cur_len && cur_time > cur_len) {
} 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);
}
}
} else {
if (cur_time < 0) {
if (Animation::is_less_approx(cur_time, 0)) {
cur_delta += cur_time;
cur_time = 0;
} else if (cur_time > cur_len) {
} else if (Animation::is_greater_approx(cur_time, cur_len)) {
cur_delta += cur_time - cur_len;
cur_time = cur_len;
}
backward = false;
// If ended, don't progress AnimationNode. So set delta to 0.
if (!Math::is_zero_approx(cur_delta)) {
if (play_mode == PLAY_MODE_FORWARD) {
if (prev_time >= cur_len) {
if (Animation::is_greater_or_equal_approx(prev_time, cur_len)) {
cur_delta = 0;
}
} else {
if (prev_time <= 0) {
if (Animation::is_less_or_equal_approx(prev_time, 0)) {
cur_delta = 0;
}
}
Expand All @@ -197,50 +197,51 @@ AnimationNode::NodeTimeInfo AnimationNodeAnimation::_process(const AnimationMixe
double cur_playback_time = cur_time + start_offset;
if (stretch_time_scale) {
double mlt = anim_size / cur_len;
prev_playback_time *= mlt;
cur_playback_time *= mlt;
cur_delta *= mlt;
}
if (cur_loop_mode == Animation::LOOP_LINEAR) {
if (!Math::is_zero_approx(anim_size)) {
prev_playback_time = Math::fposmod(prev_playback_time, anim_size);
cur_playback_time = Math::fposmod(cur_playback_time, anim_size);
if (prev_playback_time >= 0 && cur_playback_time < 0) {
if (Animation::is_greater_or_equal_approx(prev_playback_time, 0) && Animation::is_less_approx(cur_playback_time, 0)) {
looped_flag = node_backward ? Animation::LOOPED_FLAG_END : Animation::LOOPED_FLAG_START;
}
if (prev_playback_time <= anim_size && cur_playback_time > anim_size) {
if (Animation::is_less_or_equal_approx(prev_playback_time, anim_size) && Animation::is_greater_approx(cur_playback_time, anim_size)) {
looped_flag = node_backward ? Animation::LOOPED_FLAG_START : Animation::LOOPED_FLAG_END;
}
}
} else if (cur_loop_mode == Animation::LOOP_PINGPONG) {
if (!Math::is_zero_approx(anim_size)) {
if (Math::fposmod(cur_playback_time, anim_size * 2.0) >= anim_size) {
if (Animation::is_greater_or_equal_approx(Math::fposmod(cur_playback_time, anim_size * 2.0), anim_size)) {
cur_delta = -cur_delta; // Needed for retrieving discrete keys correctly.
}
prev_playback_time = Math::pingpong(prev_playback_time, anim_size);
cur_playback_time = Math::pingpong(cur_playback_time, anim_size);
if (prev_playback_time >= 0 && cur_playback_time < 0) {
if (Animation::is_greater_or_equal_approx(prev_playback_time, 0) && Animation::is_less_approx(cur_playback_time, 0)) {
looped_flag = node_backward ? Animation::LOOPED_FLAG_END : Animation::LOOPED_FLAG_START;
}
if (prev_playback_time <= anim_size && cur_playback_time > anim_size) {
if (Animation::is_less_or_equal_approx(prev_playback_time, anim_size) && Animation::is_greater_approx(cur_playback_time, anim_size)) {
looped_flag = node_backward ? Animation::LOOPED_FLAG_START : Animation::LOOPED_FLAG_END;
}
}
} else {
if (cur_playback_time < 0) {
if (Animation::is_less_approx(cur_playback_time, 0)) {
cur_playback_time = 0;
} else if (cur_playback_time > anim_size) {
} else if (Animation::is_greater_approx(cur_playback_time, anim_size)) {
cur_playback_time = anim_size;
}

// Emit start & finish signal. Internally, the detections are the same for backward.
// We should use call_deferred since the track keys are still being processed.
if (process_state->tree && !p_test_only) {
// AnimationTree uses seek to 0 "internally" to process the first key of the animation, which is used as the start detection.
if (p_seek && !p_is_external_seeking && cur_playback_time == 0) {
if (p_seek && !p_is_external_seeking && Math::is_zero_approx(cur_playback_time)) {
process_state->tree->call_deferred(SNAME("emit_signal"), SceneStringName(animation_started), animation);
}
// Finished.
if (prev_time + start_offset < anim_size && cur_playback_time >= anim_size) {
if (Animation::is_less_approx(prev_playback_time, anim_size) && Animation::is_greater_or_equal_approx(cur_playback_time, anim_size)) {
process_state->tree->call_deferred(SNAME("emit_signal"), SceneStringName(animation_finished), animation);
}
}
Expand Down Expand Up @@ -522,7 +523,7 @@ AnimationNode::NodeTimeInfo AnimationNodeOneShot::_process(const AnimationMixer:
bool p_seek = p_playback_info.seeked;
bool p_is_external_seeking = p_playback_info.is_external_seeking;

if (p_time == 0 && p_seek && !p_is_external_seeking) {
if (Math::is_zero_approx(p_time) && p_seek && !p_is_external_seeking) {
clear_remaining_fade = true; // Reset occurs.
}

Expand All @@ -545,9 +546,9 @@ AnimationNode::NodeTimeInfo AnimationNodeOneShot::_process(const AnimationMixer:
set_parameter(internal_active, false);
set_parameter(time_to_restart, -1);
} else if (!do_start && !cur_active) {
if (cur_time_to_restart >= 0.0 && !p_seek) {
if (Animation::is_greater_or_equal_approx(cur_time_to_restart, 0) && !p_seek) {
cur_time_to_restart -= abs_delta;
if (cur_time_to_restart < 0) {
if (Animation::is_less_approx(cur_time_to_restart, 0)) {
do_start = true; // Restart.
}
set_parameter(time_to_restart, cur_time_to_restart);
Expand Down Expand Up @@ -590,8 +591,8 @@ AnimationNode::NodeTimeInfo AnimationNodeOneShot::_process(const AnimationMixer:
real_t blend = 1.0;
bool use_blend = sync;

if (cur_fade_in_remaining > 0) {
if (fade_in > 0) {
if (Animation::is_greater_approx(cur_fade_in_remaining, 0)) {
if (Animation::is_greater_approx(fade_in, 0)) {
use_blend = true;
blend = (fade_in - cur_fade_in_remaining) / fade_in;
if (fade_in_curve.is_valid()) {
Expand All @@ -604,7 +605,7 @@ AnimationNode::NodeTimeInfo AnimationNodeOneShot::_process(const AnimationMixer:

if (is_fading_out) {
use_blend = true;
if (fade_out > 0) {
if (Animation::is_greater_approx(fade_out, 0)) {
blend = cur_fade_out_remaining / fade_out;
if (fade_out_curve.is_valid()) {
blend = 1.0 - fade_out_curve->sample(1.0 - blend);
Expand Down Expand Up @@ -636,15 +637,15 @@ AnimationNode::NodeTimeInfo AnimationNodeOneShot::_process(const AnimationMixer:

NodeTimeInfo os_nti = blend_input(1, pi, FILTER_PASS, true, p_test_only); // Blend values must be more than CMP_EPSILON to process discrete keys in edge.

if (cur_fade_in_remaining <= 0 && !do_start && !is_fading_out && os_nti.get_remain(break_loop_at_end) <= fade_out) {
if (Animation::is_less_or_equal_approx(cur_fade_in_remaining, 0) && !do_start && !is_fading_out && Animation::is_less_or_equal_approx(os_nti.get_remain(break_loop_at_end), fade_out)) {
is_fading_out = true;
cur_fade_out_remaining = os_nti.get_remain(break_loop_at_end);
cur_fade_in_remaining = 0;
set_parameter(internal_active, false);
}

if (!p_seek) {
if (os_nti.get_remain(break_loop_at_end) <= 0 || (is_fading_out && cur_fade_out_remaining <= 0)) {
if (Animation::is_less_or_equal_approx(os_nti.get_remain(break_loop_at_end), 0) || (is_fading_out && Animation::is_less_or_equal_approx(cur_fade_out_remaining, 0))) {
set_parameter(internal_active, false);
set_parameter(active, false);
if (auto_restart) {
Expand Down Expand Up @@ -1007,7 +1008,7 @@ AnimationNode::NodeTimeInfo AnimationNodeTimeSeek::_process(const AnimationMixer

AnimationMixer::PlaybackInfo pi = p_playback_info;
pi.weight = 1.0;
if (cur_seek_pos >= 0) {
if (Animation::is_greater_or_equal_approx(cur_seek_pos, 0)) {
pi.time = cur_seek_pos;
pi.seeked = true;
pi.is_external_seeking = true;
Expand Down Expand Up @@ -1252,7 +1253,7 @@ AnimationNode::NodeTimeInfo AnimationNodeTransition::_process(const AnimationMix
bool p_seek = p_playback_info.seeked;
bool p_is_external_seeking = p_playback_info.is_external_seeking;

if (p_time == 0 && p_seek && !p_is_external_seeking) {
if (Math::is_zero_approx(p_time) && p_seek && !p_is_external_seeking) {
clear_remaining_fade = true; // Reset occurs.
}

Expand Down Expand Up @@ -1317,7 +1318,7 @@ AnimationNode::NodeTimeInfo AnimationNodeTransition::_process(const AnimationMix
if (cur_prev_index < 0) { // Process current animation, check for transition.
pi.weight = 1.0;
cur_nti = blend_input(cur_current_index, pi, FILTER_IGNORE, true, p_test_only);
if (input_data[cur_current_index].auto_advance && cur_nti.get_remain(input_data[cur_current_index].break_loop_at_end) <= xfade_time) {
if (input_data[cur_current_index].auto_advance && Animation::is_less_or_equal_approx(cur_nti.get_remain(input_data[cur_current_index].break_loop_at_end), xfade_time)) {
set_parameter(transition_request, get_input_name((cur_current_index + 1) % get_input_count()));
}
} else { // Cross-fading from prev to current.
Expand Down Expand Up @@ -1349,7 +1350,7 @@ AnimationNode::NodeTimeInfo AnimationNodeTransition::_process(const AnimationMix
pi.weight = blend;
blend_input(cur_prev_index, pi, FILTER_IGNORE, true, p_test_only);
if (!p_seek) {
if (cur_prev_xfading <= 0) {
if (Animation::is_less_or_equal_approx(cur_prev_xfading, 0)) {
set_parameter(prev_index, -1);
}
cur_prev_xfading -= Math::abs(p_playback_info.delta);
Expand Down
42 changes: 21 additions & 21 deletions scene/animation/animation_mixer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1049,7 +1049,7 @@ void AnimationMixer::blend_capture(double p_delta) {
}

capture_cache.remain -= p_delta * capture_cache.step;
if (capture_cache.remain <= 0.0) {
if (Animation::is_less_or_equal_approx(capture_cache.remain, 0)) {
capture_cache.clear();
return;
}
Expand Down Expand Up @@ -1156,7 +1156,7 @@ void AnimationMixer::_blend_process(double p_delta, bool p_update_only) {
if (track->root_motion && calc_root) {
double prev_time = time - delta;
if (!backward) {
if (prev_time < 0) {
if (Animation::is_less_approx(prev_time, 0)) {
switch (a->get_loop_mode()) {
case Animation::LOOP_NONE: {
prev_time = 0;
Expand All @@ -1172,7 +1172,7 @@ void AnimationMixer::_blend_process(double p_delta, bool p_update_only) {
}
}
} else {
if (prev_time > a->get_length()) {
if (Animation::is_greater_approx(prev_time, (double)a->get_length())) {
switch (a->get_loop_mode()) {
case Animation::LOOP_NONE: {
prev_time = (double)a->get_length();
Expand All @@ -1190,7 +1190,7 @@ void AnimationMixer::_blend_process(double p_delta, bool p_update_only) {
}
Vector3 loc[2];
if (!backward) {
if (prev_time > time) {
if (Animation::is_greater_approx(prev_time, time)) {
Error err = a->try_position_track_interpolate(i, prev_time, &loc[0]);
if (err != OK) {
continue;
Expand All @@ -1202,7 +1202,7 @@ void AnimationMixer::_blend_process(double p_delta, bool p_update_only) {
prev_time = 0;
}
} else {
if (prev_time < time) {
if (Animation::is_less_approx(prev_time, time)) {
Error err = a->try_position_track_interpolate(i, prev_time, &loc[0]);
if (err != OK) {
continue;
Expand Down Expand Up @@ -1244,7 +1244,7 @@ void AnimationMixer::_blend_process(double p_delta, bool p_update_only) {
if (track->root_motion && calc_root) {
double prev_time = time - delta;
if (!backward) {
if (prev_time < 0) {
if (Animation::is_less_approx(prev_time, 0)) {
switch (a->get_loop_mode()) {
case Animation::LOOP_NONE: {
prev_time = 0;
Expand All @@ -1260,7 +1260,7 @@ void AnimationMixer::_blend_process(double p_delta, bool p_update_only) {
}
}
} else {
if (prev_time > a->get_length()) {
if (Animation::is_greater_approx(prev_time, (double)a->get_length())) {
switch (a->get_loop_mode()) {
case Animation::LOOP_NONE: {
prev_time = (double)a->get_length();
Expand All @@ -1278,7 +1278,7 @@ void AnimationMixer::_blend_process(double p_delta, bool p_update_only) {
}
Quaternion rot[2];
if (!backward) {
if (prev_time > time) {
if (Animation::is_greater_approx(prev_time, time)) {
Error err = a->try_rotation_track_interpolate(i, prev_time, &rot[0]);
if (err != OK) {
continue;
Expand All @@ -1290,7 +1290,7 @@ void AnimationMixer::_blend_process(double p_delta, bool p_update_only) {
prev_time = 0;
}
} else {
if (prev_time < time) {
if (Animation::is_less_approx(prev_time, time)) {
Error err = a->try_rotation_track_interpolate(i, prev_time, &rot[0]);
if (err != OK) {
continue;
Expand Down Expand Up @@ -1331,7 +1331,7 @@ void AnimationMixer::_blend_process(double p_delta, bool p_update_only) {
if (track->root_motion && calc_root) {
double prev_time = time - delta;
if (!backward) {
if (prev_time < 0) {
if (Animation::is_less_approx(prev_time, 0)) {
switch (a->get_loop_mode()) {
case Animation::LOOP_NONE: {
prev_time = 0;
Expand All @@ -1347,7 +1347,7 @@ void AnimationMixer::_blend_process(double p_delta, bool p_update_only) {
}
}
} else {
if (prev_time > a->get_length()) {
if (Animation::is_greater_approx(prev_time, (double)a->get_length())) {
switch (a->get_loop_mode()) {
case Animation::LOOP_NONE: {
prev_time = (double)a->get_length();
Expand All @@ -1365,7 +1365,7 @@ void AnimationMixer::_blend_process(double p_delta, bool p_update_only) {
}
Vector3 scale[2];
if (!backward) {
if (prev_time > time) {
if (Animation::is_greater_approx(prev_time, time)) {
Error err = a->try_scale_track_interpolate(i, prev_time, &scale[0]);
if (err != OK) {
continue;
Expand All @@ -1377,7 +1377,7 @@ void AnimationMixer::_blend_process(double p_delta, bool p_update_only) {
prev_time = 0;
}
} else {
if (prev_time < time) {
if (Animation::is_less_approx(prev_time, time)) {
Error err = a->try_scale_track_interpolate(i, prev_time, &scale[0]);
if (err != OK) {
continue;
Expand Down Expand Up @@ -1635,7 +1635,7 @@ void AnimationMixer::_blend_process(double p_delta, bool p_update_only) {
PlayingAudioStreamInfo pasi;
pasi.index = t->audio_stream_playback->play_stream(stream, start_ofs, 0, 1.0, t->playback_type, t->bus);
pasi.start = time;
if (len && end_ofs > 0) { // Force an end at a time.
if (len && Animation::is_greater_approx(end_ofs, 0)) { // Force an end at a time.
pasi.len = len - start_ofs - end_ofs;
} else {
pasi.len = 0;
Expand Down Expand Up @@ -1671,7 +1671,7 @@ void AnimationMixer::_blend_process(double p_delta, bool p_update_only) {
double at_anim_pos = 0.0;
switch (anim->get_loop_mode()) {
case Animation::LOOP_NONE: {
if (!is_external_seeking && ((!backward && time >= pos + (double)anim->get_length()) || (backward && time <= pos))) {
if (!is_external_seeking && ((!backward && Animation::is_greater_or_equal_approx(time, pos + (double)anim->get_length())) || (backward && Animation::is_less_or_equal_approx(time, pos)))) {
continue; // Do nothing if current time is outside of length when started.
}
at_anim_pos = MIN((double)anim->get_length(), time - pos); // Seek to end.
Expand Down Expand Up @@ -1841,23 +1841,23 @@ void AnimationMixer::_blend_apply() {
}
if (!track_info.loop) {
if (!track_info.backward) {
if (track_info.time < pasi.start) {
if (Animation::is_less_approx(track_info.time, pasi.start)) {
stop = true;
}
} else if (track_info.backward) {
if (track_info.time > pasi.start) {
if (Animation::is_greater_approx(track_info.time, pasi.start)) {
stop = true;
}
}
}
if (pasi.len > 0) {
if (Animation::is_greater_approx(pasi.len, 0)) {
double len = 0.0;
if (!track_info.backward) {
len = pasi.start > track_info.time ? (track_info.length - pasi.start) + track_info.time : track_info.time - pasi.start;
len = Animation::is_greater_approx(pasi.start, track_info.time) ? (track_info.length - pasi.start) + track_info.time : track_info.time - pasi.start;
} else {
len = pasi.start < track_info.time ? (track_info.length - track_info.time) + pasi.start : pasi.start - track_info.time;
len = Animation::is_less_approx(pasi.start, track_info.time) ? (track_info.length - track_info.time) + pasi.start : pasi.start - track_info.time;
}
if (len > pasi.len) {
if (Animation::is_greater_approx(len, pasi.len)) {
stop = true;
}
}
Expand Down
Loading
Loading