diff options
author | Juan Linietsky <reduzio@gmail.com> | 2021-10-11 19:28:34 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-11 19:28:34 -0300 |
commit | f9aec342dcd51d65c5970dd395e3c7a66cac446c (patch) | |
tree | 9d5b542652e576f865abf0c97a37ee272210ae2e /scene | |
parent | 9ed4f8367b29204b89f9feaf86727b24396fb180 (diff) | |
parent | 610de0974db4feb7e50c9349a8a164b6bf0f36c8 (diff) |
Merge pull request #53687 from godotengine/revert-48332-implement-ping-pong
Revert "Implement reverse playback and ping-pong loop in AnimationPlayer and NodeAnimation"
Diffstat (limited to 'scene')
-rw-r--r-- | scene/animation/animation_blend_space_2d.cpp | 7 | ||||
-rw-r--r-- | scene/animation/animation_blend_tree.cpp | 79 | ||||
-rw-r--r-- | scene/animation/animation_blend_tree.h | 26 | ||||
-rw-r--r-- | scene/animation/animation_player.cpp | 135 | ||||
-rw-r--r-- | scene/animation/animation_player.h | 2 | ||||
-rw-r--r-- | scene/animation/animation_tree.cpp | 131 | ||||
-rw-r--r-- | scene/animation/animation_tree.h | 4 | ||||
-rw-r--r-- | scene/resources/animation.cpp | 539 | ||||
-rw-r--r-- | scene/resources/animation.h | 30 | ||||
-rw-r--r-- | scene/resources/audio_stream_sample.cpp | 6 | ||||
-rw-r--r-- | scene/resources/audio_stream_sample.h | 2 |
11 files changed, 300 insertions, 661 deletions
diff --git a/scene/animation/animation_blend_space_2d.cpp b/scene/animation/animation_blend_space_2d.cpp index 6c71be8363..145e7c605b 100644 --- a/scene/animation/animation_blend_space_2d.cpp +++ b/scene/animation/animation_blend_space_2d.cpp @@ -30,7 +30,6 @@ #include "animation_blend_space_2d.h" -#include "animation_blend_tree.h" #include "core/math/geometry_2d.h" void AnimationNodeBlendSpace2D::get_parameter_list(List<PropertyInfo> *r_list) const { @@ -532,12 +531,6 @@ double AnimationNodeBlendSpace2D::process(double p_time, bool p_seek) { if (new_closest != closest && new_closest != -1) { float from = 0.0; if (blend_mode == BLEND_MODE_DISCRETE_CARRY && closest != -1) { - //for ping-pong loop - Ref<AnimationNodeAnimation> na_c = static_cast<Ref<AnimationNodeAnimation>>(blend_points[closest].node); - Ref<AnimationNodeAnimation> na_n = static_cast<Ref<AnimationNodeAnimation>>(blend_points[new_closest].node); - if (!na_c.is_null() && !na_n.is_null()) { - na_n->set_backward(na_c->is_backward()); - } //see how much animation remains from = length_internal - blend_node(blend_points[closest].name, blend_points[closest].node, p_time, false, 0.0, FILTER_IGNORE, false); } diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp index 98830bd796..10a66386eb 100644 --- a/scene/animation/animation_blend_tree.cpp +++ b/scene/animation/animation_blend_tree.cpp @@ -30,7 +30,6 @@ #include "animation_blend_tree.h" -#include "scene/resources/animation.h" #include "scene/scene_string_names.h" void AnimationNodeAnimation::set_animation(const StringName &p_name) { @@ -84,55 +83,30 @@ double AnimationNodeAnimation::process(double p_time, bool p_seek) { } Ref<Animation> anim = ap->get_animation(animation); - double anim_size = (double)anim->get_length(); - double step = 0.0; - double prev_time = time; - int pingponged = 0; - bool current_backward = signbit(p_time); + + double step; if (p_seek) { - step = p_time - time; time = p_time; + step = 0; } else { - p_time *= backward ? -1.0 : 1.0; - if (!(time == anim_size && !current_backward) && !(time == 0 && current_backward)) { - time = time + p_time; - step = p_time; - } + time = MAX(0, time + p_time); + step = p_time; } - if (anim->get_loop_mode() == Animation::LoopMode::LOOP_PINGPONG) { + double anim_size = anim->get_length(); + + if (anim->has_loop()) { if (anim_size) { - if ((int)Math::floor(abs(time - prev_time) / anim_size) % 2 == 0) { - if (prev_time > 0 && time <= 0) { - backward = !backward; - pingponged = -1; - } - if (prev_time < anim_size && time >= anim_size) { - backward = !backward; - pingponged = 1; - } - } - time = Math::pingpong(time, anim_size); + time = Math::fposmod(time, anim_size); } - } else { - if (anim->get_loop_mode() == Animation::LoopMode::LOOP_LINEAR) { - if (anim_size) { - time = Math::fposmod(time, anim_size); - } - } else if (time < 0) { - time = 0; - } else if (time > anim_size) { - time = anim_size; - } - backward = false; - } - if (play_mode == PLAY_MODE_FORWARD) { - blend_animation(animation, time, step, p_seek, 1.0, pingponged); - } else { - blend_animation(animation, anim_size - time, -step, p_seek, 1.0, pingponged); + } else if (time > anim_size) { + time = anim_size; } + + blend_animation(animation, time, step, p_seek, 1.0); + set_parameter(this->time, time); return anim_size - time; @@ -142,34 +116,11 @@ String AnimationNodeAnimation::get_caption() const { return "Animation"; } -void AnimationNodeAnimation::set_play_mode(PlayMode p_play_mode) { - play_mode = p_play_mode; -} - -AnimationNodeAnimation::PlayMode AnimationNodeAnimation::get_play_mode() const { - return play_mode; -} - -void AnimationNodeAnimation::set_backward(bool p_backward) { - backward = p_backward; -} - -bool AnimationNodeAnimation::is_backward() const { - return backward; -} - void AnimationNodeAnimation::_bind_methods() { ClassDB::bind_method(D_METHOD("set_animation", "name"), &AnimationNodeAnimation::set_animation); ClassDB::bind_method(D_METHOD("get_animation"), &AnimationNodeAnimation::get_animation); - ClassDB::bind_method(D_METHOD("set_play_mode", "mode"), &AnimationNodeAnimation::set_play_mode); - ClassDB::bind_method(D_METHOD("get_play_mode"), &AnimationNodeAnimation::get_play_mode); - ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "animation"), "set_animation", "get_animation"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "play_mode", PROPERTY_HINT_ENUM, "Forward,Backward"), "set_play_mode", "get_play_mode"); - - BIND_ENUM_CONSTANT(PLAY_MODE_FORWARD); - BIND_ENUM_CONSTANT(PLAY_MODE_BACKWARD); } AnimationNodeAnimation::AnimationNodeAnimation() { @@ -582,7 +533,7 @@ AnimationNodeBlend3::AnimationNodeBlend3() { ///////////////////////////////// void AnimationNodeTimeScale::get_parameter_list(List<PropertyInfo> *r_list) const { - r_list->push_back(PropertyInfo(Variant::FLOAT, scale, PROPERTY_HINT_RANGE, "-32,32,0.01,or_lesser,or_greater")); + r_list->push_back(PropertyInfo(Variant::FLOAT, scale, PROPERTY_HINT_RANGE, "0,32,0.01,or_greater")); } Variant AnimationNodeTimeScale::get_parameter_default_value(const StringName &p_parameter) const { diff --git a/scene/animation/animation_blend_tree.h b/scene/animation/animation_blend_tree.h index e55dfb58ed..258443a999 100644 --- a/scene/animation/animation_blend_tree.h +++ b/scene/animation/animation_blend_tree.h @@ -42,12 +42,12 @@ class AnimationNodeAnimation : public AnimationRootNode { uint64_t last_version = 0; bool skip = false; -public: - enum PlayMode { - PLAY_MODE_FORWARD, - PLAY_MODE_BACKWARD - }; +protected: + void _validate_property(PropertyInfo &property) const override; + static void _bind_methods(); + +public: void get_parameter_list(List<PropertyInfo> *r_list) const override; static Vector<String> (*get_editable_animation_list)(); @@ -58,25 +58,9 @@ public: void set_animation(const StringName &p_name); StringName get_animation() const; - void set_play_mode(PlayMode p_play_mode); - PlayMode get_play_mode() const; - - void set_backward(bool p_backward); - bool is_backward() const; - AnimationNodeAnimation(); - -protected: - void _validate_property(PropertyInfo &property) const override; - static void _bind_methods(); - -private: - PlayMode play_mode = PLAY_MODE_FORWARD; - bool backward = false; }; -VARIANT_ENUM_CAST(AnimationNodeAnimation::PlayMode) - class AnimationNodeOneShot : public AnimationNode { GDCLASS(AnimationNodeOneShot, AnimationNode); diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index 8fd1602e8b..2c8c4ee788 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -340,13 +340,12 @@ void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim, Node *p_root_ov } } -void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double p_time, double p_delta, float p_interp, bool p_is_current, bool p_seeked, bool p_started, int p_pingponged) { +void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double p_time, double p_delta, float p_interp, bool p_is_current, bool p_seeked, bool p_started) { _ensure_node_caches(p_anim); ERR_FAIL_COND(p_anim->node_cache.size() != p_anim->animation->get_track_count()); Animation *a = p_anim->animation.operator->(); bool can_call = is_inside_tree() && !Engine::get_singleton()->is_editor_hint(); - bool backward = signbit(p_delta); for (int i = 0; i < a->get_track_count(); i++) { // If an animation changes this animation (or it animates itself) @@ -426,8 +425,8 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double continue; //eeh not worth it } - double first_key_time = a->track_get_key_time(i, 0); - double transition = 1.0; + float first_key_time = a->track_get_key_time(i, 0); + float transition = 1.0; int first_key = 0; if (first_key_time == 0.0) { @@ -435,13 +434,13 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double if (key_count == 1) { continue; //with one key we can't do anything } - transition = (double)a->track_get_key_transition(i, 0); + transition = a->track_get_key_transition(i, 0); first_key_time = a->track_get_key_time(i, 1); first_key = 1; } if (p_time < first_key_time) { - double c = Math::ease(p_time / first_key_time, transition); + float c = Math::ease(p_time / first_key_time, transition); Variant first_value = a->track_get_key_value(i, first_key); Variant interp_value; Variant::interpolate(pa->capture, first_value, c, interp_value); @@ -483,7 +482,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double } else if (p_is_current && p_delta != 0) { List<int> indices; - a->value_track_get_key_indices(i, p_time, p_delta, &indices, p_pingponged); + a->value_track_get_key_indices(i, p_time, p_delta, &indices); for (int &F : indices) { Variant value = a->track_get_key_value(i, F); @@ -542,7 +541,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double List<int> indices; - a->method_track_get_key_indices(i, p_time, p_delta, &indices, p_pingponged); + a->method_track_get_key_indices(i, p_time, p_delta, &indices); for (int &E : indices) { StringName method = a->method_track_get_name(i, E); @@ -597,7 +596,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double TrackNodeCache::BezierAnim *ba = &E->get(); - real_t bezier = a->bezier_track_interpolate(i, p_time); + float bezier = a->bezier_track_interpolate(i, p_time); if (ba->accum_pass != accum_pass) { ERR_CONTINUE(cache_update_bezier_size >= NODE_CACHE_UPDATE_MAX); cache_update_bezier[cache_update_bezier_size++] = ba; @@ -658,7 +657,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double } else { //find stuff to play List<int> to_play; - a->track_get_key_indices_in_range(i, p_time, p_delta, &to_play, p_pingponged); + a->track_get_key_indices_in_range(i, p_time, p_delta, &to_play); if (to_play.size()) { int idx = to_play.back()->get(); @@ -686,14 +685,12 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double nc->audio_start = p_time; } } else if (nc->audio_playing) { - bool loop = a->get_loop_mode() != Animation::LoopMode::LOOP_NONE; + bool loop = a->has_loop(); bool stop = false; - if (!loop) { - if ((p_time < nc->audio_start && !backward) || (p_time > nc->audio_start && backward)) { - stop = true; - } + if (!loop && p_time < nc->audio_start) { + stop = true; } else if (nc->audio_len > 0) { float len = nc->audio_start > p_time ? (a->get_length() - nc->audio_start) + p_time : p_time - nc->audio_start; @@ -734,23 +731,12 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double Ref<Animation> anim = player->get_animation(anim_name); - double at_anim_pos = 0.0; - - switch (anim->get_loop_mode()) { - case Animation::LoopMode::LOOP_NONE: { - at_anim_pos = MIN((double)anim->get_length(), p_time - pos); //seek to end - } break; - - case Animation::LoopMode::LOOP_LINEAR: { - at_anim_pos = Math::fposmod(p_time - pos, (double)anim->get_length()); //seek to loop - } break; + double at_anim_pos; - case Animation::LoopMode::LOOP_PINGPONG: { - at_anim_pos = Math::pingpong(p_time - pos, (double)anim->get_length()); - } break; - - default: - break; + if (anim->has_loop()) { + at_anim_pos = Math::fposmod(p_time - pos, (double)anim->get_length()); //seek to loop + } else { + at_anim_pos = MIN((double)anim->get_length(), p_time - pos); //seek to end } if (player->is_playing() || p_seeked) { @@ -765,7 +751,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double } else { //find stuff to play List<int> to_play; - a->track_get_key_indices_in_range(i, p_time, p_delta, &to_play, p_pingponged); + a->track_get_key_indices_in_range(i, p_time, p_delta, &to_play); if (to_play.size()) { int idx = to_play.back()->get(); @@ -795,73 +781,46 @@ void AnimationPlayer::_animation_process_data(PlaybackData &cd, double p_delta, double next_pos = cd.pos + delta; real_t len = cd.from->animation->get_length(); - int pingponged = 0; - - switch (cd.from->animation->get_loop_mode()) { - case Animation::LoopMode::LOOP_NONE: { - if (next_pos < 0) { - next_pos = 0; - } else if (next_pos > len) { - next_pos = len; - } + bool loop = cd.from->animation->has_loop(); - bool backwards = signbit(delta); // Negative zero means playing backwards too - delta = next_pos - cd.pos; // Fix delta (after determination of backwards because negative zero is lost here) + if (!loop) { + if (next_pos < 0) { + next_pos = 0; + } else if (next_pos > len) { + next_pos = len; + } - if (&cd == &playback.current) { - if (!backwards && cd.pos <= len && next_pos == len) { - //playback finished - end_reached = true; - end_notify = cd.pos < len; // Notify only if not already at the end - } + bool backwards = signbit(delta); // Negative zero means playing backwards too + delta = next_pos - cd.pos; // Fix delta (after determination of backwards because negative zero is lost here) - if (backwards && cd.pos >= 0 && next_pos == 0) { - //playback finished - end_reached = true; - end_notify = cd.pos > 0; // Notify only if not already at the beginning - } + if (&cd == &playback.current) { + if (!backwards && cd.pos <= len && next_pos == len) { + //playback finished + end_reached = true; + end_notify = cd.pos < len; // Notify only if not already at the end } - } break; - case Animation::LoopMode::LOOP_LINEAR: { - double looped_next_pos = Math::fposmod(next_pos, (double)len); - if (looped_next_pos == 0 && next_pos != 0) { - // Loop multiples of the length to it, rather than 0 - // so state at time=length is previewable in the editor - next_pos = len; - } else { - next_pos = looped_next_pos; + if (backwards && cd.pos >= 0 && next_pos == 0) { + //playback finished + end_reached = true; + end_notify = cd.pos > 0; // Notify only if not already at the beginning } - } break; - - case Animation::LoopMode::LOOP_PINGPONG: { - if ((int)Math::floor(abs(next_pos - cd.pos) / len) % 2 == 0) { - if (next_pos < 0 && cd.pos >= 0) { - cd.speed_scale *= -1.0; - pingponged = -1; - } - if (next_pos > len && cd.pos <= len) { - cd.speed_scale *= -1.0; - pingponged = 1; - } - } - double looped_next_pos = Math::pingpong(next_pos, (double)len); - if (looped_next_pos == 0 && next_pos != 0) { - // Loop multiples of the length to it, rather than 0 - // so state at time=length is previewable in the editor - next_pos = len; - } else { - next_pos = looped_next_pos; - } - } break; + } - default: - break; + } else { + double looped_next_pos = Math::fposmod(next_pos, (double)len); + if (looped_next_pos == 0 && next_pos != 0) { + // Loop multiples of the length to it, rather than 0 + // so state at time=length is previewable in the editor + next_pos = len; + } else { + next_pos = looped_next_pos; + } } cd.pos = next_pos; - _animation_process_animation(cd.from, cd.pos, delta, p_blend, &cd == &playback.current, p_seeked, p_started, pingponged); + _animation_process_animation(cd.from, cd.pos, delta, p_blend, &cd == &playback.current, p_seeked, p_started); } void AnimationPlayer::_animation_process2(double p_delta, bool p_started) { diff --git a/scene/animation/animation_player.h b/scene/animation/animation_player.h index df041de026..b693e29bdf 100644 --- a/scene/animation/animation_player.h +++ b/scene/animation/animation_player.h @@ -215,7 +215,7 @@ private: NodePath root; - void _animation_process_animation(AnimationData *p_anim, double p_time, double p_delta, float p_interp, bool p_is_current = true, bool p_seeked = false, bool p_started = false, int p_pingponged = 0); + void _animation_process_animation(AnimationData *p_anim, double p_time, double p_delta, float p_interp, bool p_is_current = true, bool p_seeked = false, bool p_started = false); void _ensure_node_caches(AnimationData *p_anim, Node *p_root_override = nullptr); void _animation_process_data(PlaybackData &cd, double p_delta, float p_blend, bool p_seeked, bool p_started); diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp index 7ea42e6df2..9ca8d478b1 100644 --- a/scene/animation/animation_tree.cpp +++ b/scene/animation/animation_tree.cpp @@ -32,7 +32,6 @@ #include "animation_blend_tree.h" #include "core/config/engine.h" -#include "scene/resources/animation.h" #include "scene/scene_string_names.h" #include "servers/audio/audio_stream.h" @@ -88,7 +87,7 @@ void AnimationNode::get_child_nodes(List<ChildNode> *r_child_nodes) { } } -void AnimationNode::blend_animation(const StringName &p_animation, real_t p_time, real_t p_delta, bool p_seeked, real_t p_blend, int p_pingponged) { +void AnimationNode::blend_animation(const StringName &p_animation, real_t p_time, real_t p_delta, bool p_seeked, real_t p_blend) { ERR_FAIL_COND(!state); ERR_FAIL_COND(!state->player->has_animation(p_animation)); @@ -114,7 +113,6 @@ void AnimationNode::blend_animation(const StringName &p_animation, real_t p_time anim_state.time = p_time; anim_state.animation = animation; anim_state.seeked = p_seeked; - anim_state.pingponged = p_pingponged; state->animation_states.push_back(anim_state); } @@ -420,7 +418,7 @@ void AnimationNode::_bind_methods() { ClassDB::bind_method(D_METHOD("_set_filters", "filters"), &AnimationNode::_set_filters); ClassDB::bind_method(D_METHOD("_get_filters"), &AnimationNode::_get_filters); - ClassDB::bind_method(D_METHOD("blend_animation", "animation", "time", "delta", "seeked", "blend", "pingponged"), &AnimationNode::blend_animation, DEFVAL(0)); + ClassDB::bind_method(D_METHOD("blend_animation", "animation", "time", "delta", "seeked", "blend"), &AnimationNode::blend_animation); ClassDB::bind_method(D_METHOD("blend_node", "name", "node", "time", "seek", "blend", "filter", "optimize"), &AnimationNode::blend_node, DEFVAL(FILTER_IGNORE), DEFVAL(true)); ClassDB::bind_method(D_METHOD("blend_input", "input_index", "time", "seek", "blend", "filter", "optimize"), &AnimationNode::blend_input, DEFVAL(FILTER_IGNORE), DEFVAL(true)); @@ -826,8 +824,6 @@ void AnimationTree::_process_graph(real_t p_delta) { double delta = as.delta; real_t weight = as.blend; bool seeked = as.seeked; - int pingponged = as.pingponged; - bool backward = signbit(delta); for (int i = 0; i < a->get_track_count(); i++) { NodePath path = a->track_get_path(i); @@ -866,38 +862,12 @@ void AnimationTree::_process_graph(real_t p_delta) { t->scale = Vector3(1, 1, 1); } - double prev_time = time - delta; - if (!backward) { - if (prev_time < 0) { - switch (a->get_loop_mode()) { - case Animation::LoopMode::LOOP_NONE: { - prev_time = 0; - } break; - case Animation::LoopMode::LOOP_LINEAR: { - prev_time = Math::fposmod(prev_time, (double)a->get_length()); - } break; - case Animation::LoopMode::LOOP_PINGPONG: { - prev_time = Math::pingpong(prev_time, (double)a->get_length()); - } break; - default: - break; - } - } - } else { - if (prev_time > a->get_length()) { - switch (a->get_loop_mode()) { - case Animation::LoopMode::LOOP_NONE: { - prev_time = (double)a->get_length(); - } break; - case Animation::LoopMode::LOOP_LINEAR: { - prev_time = Math::fposmod(prev_time, (double)a->get_length()); - } break; - case Animation::LoopMode::LOOP_PINGPONG: { - prev_time = Math::pingpong(prev_time, (double)a->get_length()); - } break; - default: - break; - } + real_t prev_time = time - delta; + if (prev_time < 0) { + if (!a->has_loop()) { + prev_time = 0; + } else { + prev_time = a->get_length() + prev_time; } } @@ -905,38 +875,20 @@ void AnimationTree::_process_graph(real_t p_delta) { Quaternion rot[2]; Vector3 scale[2]; - if (!backward) { - if (prev_time > time) { - Error err = a->transform_track_interpolate(i, prev_time, &loc[0], &rot[0], &scale[0]); - if (err != OK) { - continue; - } - - a->transform_track_interpolate(i, (double)a->get_length(), &loc[1], &rot[1], &scale[1]); - - t->loc += (loc[1] - loc[0]) * blend; - t->scale += (scale[1] - scale[0]) * blend; - Quaternion q = Quaternion().slerp(rot[0].normalized().inverse() * rot[1].normalized(), blend).normalized(); - t->rot = (t->rot * q).normalized(); - - prev_time = 0; + if (prev_time > time) { + Error err = a->transform_track_interpolate(i, prev_time, &loc[0], &rot[0], &scale[0]); + if (err != OK) { + continue; } - } else { - if (prev_time < time) { - Error err = a->transform_track_interpolate(i, prev_time, &loc[0], &rot[0], &scale[0]); - if (err != OK) { - continue; - } - a->transform_track_interpolate(i, 0, &loc[1], &rot[1], &scale[1]); + a->transform_track_interpolate(i, a->get_length(), &loc[1], &rot[1], &scale[1]); - t->loc += (loc[1] - loc[0]) * blend; - t->scale += (scale[1] - scale[0]) * blend; - Quaternion q = Quaternion().slerp(rot[0].normalized().inverse() * rot[1].normalized(), blend).normalized(); - t->rot = (t->rot * q).normalized(); + t->loc += (loc[1] - loc[0]) * blend; + t->scale += (scale[1] - scale[0]) * blend; + Quaternion q = Quaternion().slerp(rot[0].normalized().inverse() * rot[1].normalized(), blend).normalized(); + t->rot = (t->rot * q).normalized(); - prev_time = 0; - } + prev_time = 0; } Error err = a->transform_track_interpolate(i, prev_time, &loc[0], &rot[0], &scale[0]); @@ -951,7 +903,8 @@ void AnimationTree::_process_graph(real_t p_delta) { Quaternion q = Quaternion().slerp(rot[0].normalized().inverse() * rot[1].normalized(), blend).normalized(); t->rot = (t->rot * q).normalized(); - prev_time = !backward ? 0 : (double)a->get_length(); + prev_time = 0; + } else { Vector3 loc; Quaternion rot; @@ -1007,7 +960,7 @@ void AnimationTree::_process_graph(real_t p_delta) { } else { List<int> indices; - a->value_track_get_key_indices(i, time, delta, &indices, pingponged); + a->value_track_get_key_indices(i, time, delta, &indices); for (int &F : indices) { Variant value = a->track_get_key_value(i, F); @@ -1024,7 +977,7 @@ void AnimationTree::_process_graph(real_t p_delta) { List<int> indices; - a->method_track_get_key_indices(i, time, delta, &indices, pingponged); + a->method_track_get_key_indices(i, time, delta, &indices); for (int &F : indices) { StringName method = a->method_track_get_name(i, F); @@ -1107,7 +1060,7 @@ void AnimationTree::_process_graph(real_t p_delta) { } else { //find stuff to play List<int> to_play; - a->track_get_key_indices_in_range(i, time, delta, &to_play, pingponged); + a->track_get_key_indices_in_range(i, time, delta, &to_play); if (to_play.size()) { int idx = to_play.back()->get(); @@ -1135,20 +1088,12 @@ void AnimationTree::_process_graph(real_t p_delta) { t->start = time; } } else if (t->playing) { - bool loop = a->get_loop_mode() != Animation::LoopMode::LOOP_NONE; + bool loop = a->has_loop(); bool stop = false; - if (!loop) { - if (delta > 0) { - if (time < t->start) { - stop = true; - } - } else if (delta < 0) { - if (time > t->start) { - stop = true; - } - } + if (!loop && time < t->start) { + stop = true; } else if (t->len > 0) { real_t len = t->start > time ? (a->get_length() - t->start) + time : time - t->start; @@ -1182,7 +1127,7 @@ void AnimationTree::_process_graph(real_t p_delta) { continue; } - if (seeked) { + if (delta == 0 || seeked) { //seek int idx = a->track_find_key(i, time); if (idx < 0) { @@ -1198,20 +1143,12 @@ void AnimationTree::_process_graph(real_t p_delta) { Ref<Animation> anim = player2->get_animation(anim_name); - real_t at_anim_pos = 0.0; - - switch (anim->get_loop_mode()) { - case Animation::LoopMode::LOOP_NONE: { - at_anim_pos = MAX((double)anim->get_length(), time - pos); //seek to end - } break; - case Animation::LoopMode::LOOP_LINEAR: { - at_anim_pos = Math::fposmod(time - pos, (double)anim->get_length()); //seek to loop - } break; - case Animation::LoopMode::LOOP_PINGPONG: { - at_anim_pos = Math::pingpong(time - pos, (double)a->get_length()); - } break; - default: - break; + real_t at_anim_pos; + + if (anim->has_loop()) { + at_anim_pos = Math::fposmod(time - pos, (double)anim->get_length()); //seek to loop + } else { + at_anim_pos = MAX(anim->get_length(), time - pos); //seek to end } if (player2->is_playing() || seeked) { @@ -1226,7 +1163,7 @@ void AnimationTree::_process_graph(real_t p_delta) { } else { //find stuff to play List<int> to_play; - a->track_get_key_indices_in_range(i, time, delta, &to_play, pingponged); + a->track_get_key_indices_in_range(i, time, delta, &to_play); if (to_play.size()) { int idx = to_play.back()->get(); diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h index 7482de7ee1..1e0267682e 100644 --- a/scene/animation/animation_tree.h +++ b/scene/animation/animation_tree.h @@ -68,7 +68,6 @@ public: const Vector<real_t> *track_blends = nullptr; real_t blend = 0.0; bool seeked = false; - int pingponged = 0; }; struct State { @@ -102,10 +101,9 @@ public: real_t _blend_node(const StringName &p_subpath, const Vector<StringName> &p_connections, AnimationNode *p_new_parent, Ref<AnimationNode> p_node, real_t p_time, bool p_seek, real_t p_blend, FilterAction p_filter = FILTER_IGNORE, bool p_optimize = true, real_t *r_max = nullptr); protected: - void blend_animation(const StringName &p_animation, real_t p_time, real_t p_delta, bool p_seeked, real_t p_blend, int p_pingponged = 0); + void blend_animation(const StringName &p_animation, real_t p_time, real_t p_delta, bool p_seeked, real_t p_blend); real_t blend_node(const StringName &p_sub_path, Ref<AnimationNode> p_node, real_t p_time, bool p_seek, real_t p_blend, FilterAction p_filter = FILTER_IGNORE, bool p_optimize = true); real_t blend_input(int p_input, real_t p_time, bool p_seek, real_t p_blend, FilterAction p_filter = FILTER_IGNORE, bool p_optimize = true); - void make_invalid(const String &p_reason); static void _bind_methods(); diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp index 4382674470..b4eec2530b 100644 --- a/scene/resources/animation.cpp +++ b/scene/resources/animation.cpp @@ -309,8 +309,8 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const { if (name == "length") { r_ret = length; - } else if (name == "loop_mode") { - r_ret = loop_mode; + } else if (name == "loop") { + r_ret = loop; } else if (name == "step") { r_ret = step; } else if (name.begins_with("tracks/")) { @@ -1413,7 +1413,7 @@ void Animation::track_set_key_transition(int p_track, int p_key_idx, real_t p_tr } template <class K> -int Animation::_find(const Vector<K> &p_keys, double p_time, bool p_backward) const { +int Animation::_find(const Vector<K> &p_keys, double p_time) const { int len = p_keys.size(); if (len == 0) { return -2; @@ -1443,14 +1443,8 @@ int Animation::_find(const Vector<K> &p_keys, double p_time, bool p_backward) co } } - if (!p_backward) { - if (keys[middle].time > p_time) { - middle--; - } - } else { - if (keys[middle].time < p_time) { - middle++; - } + if (keys[middle].time > p_time) { + middle--; } return middle; @@ -1591,7 +1585,7 @@ real_t Animation::_cubic_interpolate(const real_t &p_pre_a, const real_t &p_a, c } template <class T> -T Animation::_interpolate(const Vector<TKey<T>> &p_keys, double p_time, InterpolationType p_interp, bool p_loop_wrap, bool *p_ok, bool p_backward) const { +T Animation::_interpolate(const Vector<TKey<T>> &p_keys, double p_time, InterpolationType p_interp, bool p_loop_wrap, bool *p_ok) const { int len = _find(p_keys, length) + 1; // try to find last key (there may be more past the end) if (len <= 0) { @@ -1609,7 +1603,7 @@ T Animation::_interpolate(const Vector<TKey<T>> &p_keys, double p_time, Interpol return p_keys[0].value; } - int idx = _find(p_keys, p_time, p_backward); + int idx = _find(p_keys, p_time); ERR_FAIL_COND_V(idx == -2, T()); @@ -1618,42 +1612,24 @@ T Animation::_interpolate(const Vector<TKey<T>> &p_keys, double p_time, Interpol real_t c = 0.0; // prepare for all cases of interpolation - if ((loop_mode == LOOP_LINEAR || loop_mode == LOOP_PINGPONG) && p_loop_wrap) { + if (loop && p_loop_wrap) { // loop - if (!p_backward) { - // no backward - if (idx >= 0) { - if (idx < len - 1) { - next = idx + 1; - real_t delta = p_keys[next].time - p_keys[idx].time; - real_t from = p_time - p_keys[idx].time; - - if (Math::is_zero_approx(delta)) { - c = 0; - } else { - c = from / delta; - } + if (idx >= 0) { + if ((idx + 1) < len) { + next = idx + 1; + real_t delta = p_keys[next].time - p_keys[idx].time; + real_t from = p_time - p_keys[idx].time; + + if (Math::is_zero_approx(delta)) { + c = 0; } else { - next = 0; - real_t delta = (length - p_keys[idx].time) + p_keys[next].time; - real_t from = p_time - p_keys[idx].time; - - if (Math::is_zero_approx(delta)) { - c = 0; - } else { - c = from / delta; - } + c = from / delta; } + } else { - // on loop, behind first key - idx = len - 1; next = 0; - real_t endtime = (length - p_keys[idx].time); - if (endtime < 0) { // may be keys past the end - endtime = 0; - } - real_t delta = endtime + p_keys[next].time; - real_t from = endtime + p_time; + real_t delta = (length - p_keys[idx].time) + p_keys[next].time; + real_t from = p_time - p_keys[idx].time; if (Math::is_zero_approx(delta)) { c = 0; @@ -1661,81 +1637,49 @@ T Animation::_interpolate(const Vector<TKey<T>> &p_keys, double p_time, Interpol c = from / delta; } } + } else { - // backward - if (idx <= len - 1) { - if (idx > 0) { - next = idx - 1; - real_t delta = (length - p_keys[next].time) - (length - p_keys[idx].time); - real_t from = (length - p_time) - (length - p_keys[idx].time); - - if (Math::is_zero_approx(delta)) - c = 0; - else - c = from / delta; - } else { - next = len - 1; - real_t delta = p_keys[idx].time + (length - p_keys[next].time); - real_t from = (length - p_time) - (length - p_keys[idx].time); - - if (Math::is_zero_approx(delta)) - c = 0; - else - c = from / delta; - } + // on loop, behind first key + idx = len - 1; + next = 0; + real_t endtime = (length - p_keys[idx].time); + if (endtime < 0) { // may be keys past the end + endtime = 0; + } + real_t delta = endtime + p_keys[next].time; + real_t from = endtime + p_time; + + if (Math::is_zero_approx(delta)) { + c = 0; } else { - // on loop, in front of last key - idx = 0; - next = len - 1; - real_t endtime = p_keys[idx].time; - if (endtime > length) // may be keys past the end - endtime = length; - real_t delta = p_keys[next].time - endtime; - real_t from = p_time - endtime; - - if (Math::is_zero_approx(delta)) - c = 0; - else - c = from / delta; + c = from / delta; } } + } else { // no loop - if (!p_backward) { - if (idx >= 0) { - if (idx < len - 1) { - next = idx + 1; - real_t delta = p_keys[next].time - p_keys[idx].time; - real_t from = p_time - p_keys[idx].time; - - if (Math::is_zero_approx(delta)) { - c = 0; - } else { - c = from / delta; - } + + if (idx >= 0) { + if ((idx + 1) < len) { + next = idx + 1; + real_t delta = p_keys[next].time - p_keys[idx].time; + real_t from = p_time - p_keys[idx].time; + + if (Math::is_zero_approx(delta)) { + c = 0; } else { - next = idx; + c = from / delta; } + } else { - idx = next = 0; + next = idx; } - } else { - if (idx <= len - 1) { - if (idx > 0) { - next = idx - 1; - real_t delta = (length - p_keys[next].time) - (length - p_keys[idx].time); - real_t from = (length - p_time) - (length - p_keys[idx].time); - - if (Math::is_zero_approx(delta)) { - c = 0; - } else { - c = from / delta; - } - } else { - next = idx; - } + } else { + // only allow extending first key to anim start if looping + if (loop) { + idx = next = 0; } else { - idx = next = len - 1; + result = false; } } } @@ -1785,7 +1729,7 @@ T Animation::_interpolate(const Vector<TKey<T>> &p_keys, double p_time, Interpol // do a barrel roll } -Error Animation::transform_track_interpolate(int p_track, double p_time, Vector3 *r_loc, Quaternion *r_rot, Vector3 *r_scale, bool p_backward) const { +Error Animation::transform_track_interpolate(int p_track, double p_time, Vector3 *r_loc, Quaternion *r_rot, Vector3 *r_scale) const { ERR_FAIL_INDEX_V(p_track, tracks.size(), ERR_INVALID_PARAMETER); Track *t = tracks[p_track]; ERR_FAIL_COND_V(t->type != TYPE_TRANSFORM3D, ERR_INVALID_PARAMETER); @@ -1794,7 +1738,7 @@ Error Animation::transform_track_interpolate(int p_track, double p_time, Vector3 bool ok = false; - TransformKey tk = _interpolate(tt->transforms, p_time, tt->interpolation, tt->loop_wrap, &ok, p_backward); + TransformKey tk = _interpolate(tt->transforms, p_time, tt->interpolation, tt->loop_wrap, &ok); if (!ok) { return ERR_UNAVAILABLE; @@ -1869,7 +1813,7 @@ void Animation::_value_track_get_key_indices_in_range(const ValueTrack *vt, doub } } -void Animation::value_track_get_key_indices(int p_track, double p_time, double p_delta, List<int> *p_indices, int p_pingponged) const { +void Animation::value_track_get_key_indices(int p_track, double p_time, double p_delta, List<int> *p_indices) const { ERR_FAIL_INDEX(p_track, tracks.size()); Track *t = tracks[p_track]; ERR_FAIL_COND(t->type != TYPE_VALUE); @@ -1883,50 +1827,30 @@ void Animation::value_track_get_key_indices(int p_track, double p_time, double p SWAP(from_time, to_time); } - switch (loop_mode) { - case LOOP_NONE: { - if (from_time < 0) { - from_time = 0; - } - if (from_time > length) { - from_time = length; - } - - if (to_time < 0) { - to_time = 0; - } - if (to_time > length) { - to_time = length; - } - } break; - case LOOP_LINEAR: { - from_time = Math::fposmod(from_time, length); - to_time = Math::fposmod(to_time, length); + if (loop) { + from_time = Math::fposmod(from_time, length); + to_time = Math::fposmod(to_time, length); - if (from_time > to_time) { - // handle loop by splitting - _value_track_get_key_indices_in_range(vt, from_time, length, p_indices); - _value_track_get_key_indices_in_range(vt, 0, to_time, p_indices); - return; - } - } break; - case LOOP_PINGPONG: { - from_time = Math::pingpong(from_time, length); - to_time = Math::pingpong(to_time, length); + if (from_time > to_time) { + // handle loop by splitting + _value_track_get_key_indices_in_range(vt, from_time, length, p_indices); + _value_track_get_key_indices_in_range(vt, 0, to_time, p_indices); + return; + } + } else { + if (from_time < 0) { + from_time = 0; + } + if (from_time > length) { + from_time = length; + } - if (p_pingponged == -1) { - // handle loop by splitting - _value_track_get_key_indices_in_range(vt, 0, from_time, p_indices); - _value_track_get_key_indices_in_range(vt, 0, to_time, p_indices); - return; - } - if (p_pingponged == 1) { - // handle loop by splitting - _value_track_get_key_indices_in_range(vt, from_time, length, p_indices); - _value_track_get_key_indices_in_range(vt, to_time, length, p_indices); - return; - } - } break; + if (to_time < 0) { + to_time = 0; + } + if (to_time > length) { + to_time = length; + } } _value_track_get_key_indices_in_range(vt, from_time, to_time, p_indices); @@ -1985,7 +1909,7 @@ void Animation::_track_get_key_indices_in_range(const Vector<T> &p_array, double } } -void Animation::track_get_key_indices_in_range(int p_track, double p_time, double p_delta, List<int> *p_indices, int p_pingponged) const { +void Animation::track_get_key_indices_in_range(int p_track, double p_time, double p_delta, List<int> *p_indices) const { ERR_FAIL_INDEX(p_track, tracks.size()); const Track *t = tracks[p_track]; @@ -1996,176 +1920,104 @@ void Animation::track_get_key_indices_in_range(int p_track, double p_time, doubl SWAP(from_time, to_time); } - switch (loop_mode) { - case LOOP_NONE: { - if (from_time < 0) { - from_time = 0; - } - if (from_time > length) { - from_time = length; - } + if (loop) { + if (from_time > length || from_time < 0) { + from_time = Math::fposmod(from_time, length); + } - if (to_time < 0) { - to_time = 0; - } - if (to_time > length) { - to_time = length; - } - } break; - case LOOP_LINEAR: { - if (from_time > length || from_time < 0) { - from_time = Math::fposmod(from_time, length); - } - if (to_time > length || to_time < 0) { - to_time = Math::fposmod(to_time, length); - } + if (to_time > length || to_time < 0) { + to_time = Math::fposmod(to_time, length); + } - if (from_time > to_time) { - // handle loop by splitting - switch (t->type) { - case TYPE_TRANSFORM3D: { - const TransformTrack *tt = static_cast<const TransformTrack *>(t); - _track_get_key_indices_in_range(tt->transforms, from_time, length, p_indices); - _track_get_key_indices_in_range(tt->transforms, 0, to_time, p_indices); - } break; - case TYPE_VALUE: { - const ValueTrack *vt = static_cast<const ValueTrack *>(t); - _track_get_key_indices_in_range(vt->values, from_time, length, p_indices); - _track_get_key_indices_in_range(vt->values, 0, to_time, p_indices); - } break; - case TYPE_METHOD: { - const MethodTrack *mt = static_cast<const MethodTrack *>(t); - _track_get_key_indices_in_range(mt->methods, from_time, length, p_indices); - _track_get_key_indices_in_range(mt->methods, 0, to_time, p_indices); - } break; - case TYPE_BEZIER: { - const BezierTrack *bz = static_cast<const BezierTrack *>(t); - _track_get_key_indices_in_range(bz->values, from_time, length, p_indices); - _track_get_key_indices_in_range(bz->values, 0, to_time, p_indices); - } break; - case TYPE_AUDIO: { - const AudioTrack *ad = static_cast<const AudioTrack *>(t); - _track_get_key_indices_in_range(ad->values, from_time, length, p_indices); - _track_get_key_indices_in_range(ad->values, 0, to_time, p_indices); - } break; - case TYPE_ANIMATION: { - const AnimationTrack *an = static_cast<const AnimationTrack *>(t); - _track_get_key_indices_in_range(an->values, from_time, length, p_indices); - _track_get_key_indices_in_range(an->values, 0, to_time, p_indices); - } break; - } - return; - } - } break; - case LOOP_PINGPONG: { - if (from_time > length || from_time < 0) { - from_time = Math::pingpong(from_time, length); - } - if (to_time > length || to_time < 0) { - to_time = Math::pingpong(to_time, length); + if (from_time > to_time) { + // handle loop by splitting + + switch (t->type) { + case TYPE_TRANSFORM3D: { + const TransformTrack *tt = static_cast<const TransformTrack *>(t); + _track_get_key_indices_in_range(tt->transforms, from_time, length, p_indices); + _track_get_key_indices_in_range(tt->transforms, 0, to_time, p_indices); + + } break; + case TYPE_VALUE: { + const ValueTrack *vt = static_cast<const ValueTrack *>(t); + _track_get_key_indices_in_range(vt->values, from_time, length, p_indices); + _track_get_key_indices_in_range(vt->values, 0, to_time, p_indices); + + } break; + case TYPE_METHOD: { + const MethodTrack *mt = static_cast<const MethodTrack *>(t); + _track_get_key_indices_in_range(mt->methods, from_time, length, p_indices); + _track_get_key_indices_in_range(mt->methods, 0, to_time, p_indices); + + } break; + case TYPE_BEZIER: { + const BezierTrack *bz = static_cast<const BezierTrack *>(t); + _track_get_key_indices_in_range(bz->values, from_time, length, p_indices); + _track_get_key_indices_in_range(bz->values, 0, to_time, p_indices); + + } break; + case TYPE_AUDIO: { + const AudioTrack *ad = static_cast<const AudioTrack *>(t); + _track_get_key_indices_in_range(ad->values, from_time, length, p_indices); + _track_get_key_indices_in_range(ad->values, 0, to_time, p_indices); + + } break; + case TYPE_ANIMATION: { + const AnimationTrack *an = static_cast<const AnimationTrack *>(t); + _track_get_key_indices_in_range(an->values, from_time, length, p_indices); + _track_get_key_indices_in_range(an->values, 0, to_time, p_indices); + + } break; } + return; + } + } else { + if (from_time < 0) { + from_time = 0; + } + if (from_time > length) { + from_time = length; + } - if ((int)Math::floor(abs(p_delta) / length) % 2 == 0) { - if (p_pingponged == -1) { - // handle loop by splitting - switch (t->type) { - case TYPE_TRANSFORM3D: { - const TransformTrack *tt = static_cast<const TransformTrack *>(t); - _track_get_key_indices_in_range(tt->transforms, 0, from_time, p_indices); - _track_get_key_indices_in_range(tt->transforms, 0, to_time, p_indices); - } break; - case TYPE_VALUE: { - const ValueTrack *vt = static_cast<const ValueTrack *>(t); - _track_get_key_indices_in_range(vt->values, 0, from_time, p_indices); - _track_get_key_indices_in_range(vt->values, 0, to_time, p_indices); - } break; - case TYPE_METHOD: { - const MethodTrack *mt = static_cast<const MethodTrack *>(t); - _track_get_key_indices_in_range(mt->methods, 0, from_time, p_indices); - _track_get_key_indices_in_range(mt->methods, 0, to_time, p_indices); - } break; - case TYPE_BEZIER: { - const BezierTrack *bz = static_cast<const BezierTrack *>(t); - _track_get_key_indices_in_range(bz->values, 0, from_time, p_indices); - _track_get_key_indices_in_range(bz->values, 0, to_time, p_indices); - } break; - case TYPE_AUDIO: { - const AudioTrack *ad = static_cast<const AudioTrack *>(t); - _track_get_key_indices_in_range(ad->values, 0, from_time, p_indices); - _track_get_key_indices_in_range(ad->values, 0, to_time, p_indices); - } break; - case TYPE_ANIMATION: { - const AnimationTrack *an = static_cast<const AnimationTrack *>(t); - _track_get_key_indices_in_range(an->values, 0, from_time, p_indices); - _track_get_key_indices_in_range(an->values, 0, to_time, p_indices); - } break; - } - return; - } - if (p_pingponged == 1) { - // handle loop by splitting - switch (t->type) { - case TYPE_TRANSFORM3D: { - const TransformTrack *tt = static_cast<const TransformTrack *>(t); - _track_get_key_indices_in_range(tt->transforms, from_time, length, p_indices); - _track_get_key_indices_in_range(tt->transforms, to_time, length, p_indices); - } break; - case TYPE_VALUE: { - const ValueTrack *vt = static_cast<const ValueTrack *>(t); - _track_get_key_indices_in_range(vt->values, from_time, length, p_indices); - _track_get_key_indices_in_range(vt->values, to_time, length, p_indices); - } break; - case TYPE_METHOD: { - const MethodTrack *mt = static_cast<const MethodTrack *>(t); - _track_get_key_indices_in_range(mt->methods, from_time, length, p_indices); - _track_get_key_indices_in_range(mt->methods, to_time, length, p_indices); - } break; - case TYPE_BEZIER: { - const BezierTrack *bz = static_cast<const BezierTrack *>(t); - _track_get_key_indices_in_range(bz->values, from_time, length, p_indices); - _track_get_key_indices_in_range(bz->values, to_time, length, p_indices); - } break; - case TYPE_AUDIO: { - const AudioTrack *ad = static_cast<const AudioTrack *>(t); - _track_get_key_indices_in_range(ad->values, from_time, length, p_indices); - _track_get_key_indices_in_range(ad->values, to_time, length, p_indices); - } break; - case TYPE_ANIMATION: { - const AnimationTrack *an = static_cast<const AnimationTrack *>(t); - _track_get_key_indices_in_range(an->values, from_time, length, p_indices); - _track_get_key_indices_in_range(an->values, to_time, length, p_indices); - } break; - } - return; - } - } - } break; + if (to_time < 0) { + to_time = 0; + } + if (to_time > length) { + to_time = length; + } } switch (t->type) { case TYPE_TRANSFORM3D: { const TransformTrack *tt = static_cast<const TransformTrack *>(t); _track_get_key_indices_in_range(tt->transforms, from_time, to_time, p_indices); + } break; case TYPE_VALUE: { const ValueTrack *vt = static_cast<const ValueTrack *>(t); _track_get_key_indices_in_range(vt->values, from_time, to_time, p_indices); + } break; case TYPE_METHOD: { const MethodTrack *mt = static_cast<const MethodTrack *>(t); _track_get_key_indices_in_range(mt->methods, from_time, to_time, p_indices); + } break; case TYPE_BEZIER: { const BezierTrack *bz = static_cast<const BezierTrack *>(t); _track_get_key_indices_in_range(bz->values, from_time, to_time, p_indices); + } break; case TYPE_AUDIO: { const AudioTrack *ad = static_cast<const AudioTrack *>(t); _track_get_key_indices_in_range(ad->values, from_time, to_time, p_indices); + } break; case TYPE_ANIMATION: { const AnimationTrack *an = static_cast<const AnimationTrack *>(t); _track_get_key_indices_in_range(an->values, from_time, to_time, p_indices); + } break; } } @@ -2203,7 +2055,7 @@ void Animation::_method_track_get_key_indices_in_range(const MethodTrack *mt, do } } -void Animation::method_track_get_key_indices(int p_track, double p_time, double p_delta, List<int> *p_indices, int p_pingponged) const { +void Animation::method_track_get_key_indices(int p_track, double p_time, double p_delta, List<int> *p_indices) const { ERR_FAIL_INDEX(p_track, tracks.size()); Track *t = tracks[p_track]; ERR_FAIL_COND(t->type != TYPE_METHOD); @@ -2217,58 +2069,35 @@ void Animation::method_track_get_key_indices(int p_track, double p_time, double SWAP(from_time, to_time); } - switch (loop_mode) { - case LOOP_NONE: { - if (from_time < 0) { - from_time = 0; - } - if (from_time > length) { - from_time = length; - } + if (loop) { + if (from_time > length || from_time < 0) { + from_time = Math::fposmod(from_time, length); + } - if (to_time < 0) { - to_time = 0; - } - if (to_time > length) { - to_time = length; - } - } break; - case LOOP_LINEAR: { - if (from_time > length || from_time < 0) { - from_time = Math::fposmod(from_time, length); - } - if (to_time > length || to_time < 0) { - to_time = Math::fposmod(to_time, length); - } + if (to_time > length || to_time < 0) { + to_time = Math::fposmod(to_time, length); + } - if (from_time > to_time) { - // handle loop by splitting - _method_track_get_key_indices_in_range(mt, from_time, length, p_indices); - _method_track_get_key_indices_in_range(mt, 0, to_time, p_indices); - return; - } - } break; - case LOOP_PINGPONG: { - if (from_time > length || from_time < 0) { - from_time = Math::pingpong(from_time, length); - } - if (to_time > length || to_time < 0) { - to_time = Math::pingpong(to_time, length); - } + if (from_time > to_time) { + // handle loop by splitting + _method_track_get_key_indices_in_range(mt, from_time, length, p_indices); + _method_track_get_key_indices_in_range(mt, 0, to_time, p_indices); + return; + } + } else { + if (from_time < 0) { + from_time = 0; + } + if (from_time > length) { + from_time = length; + } - if (p_pingponged == -1) { - _method_track_get_key_indices_in_range(mt, 0, from_time, p_indices); - _method_track_get_key_indices_in_range(mt, 0, to_time, p_indices); - return; - } - if (p_pingponged == 1) { - _method_track_get_key_indices_in_range(mt, from_time, length, p_indices); - _method_track_get_key_indices_in_range(mt, to_time, length, p_indices); - return; - } - } break; - default: - break; + if (to_time < 0) { + to_time = 0; + } + if (to_time > length) { + to_time = length; + } } _method_track_get_key_indices_in_range(mt, from_time, to_time, p_indices); @@ -2654,13 +2483,13 @@ real_t Animation::get_length() const { return length; } -void Animation::set_loop_mode(Animation::LoopMode p_loop_mode) { - loop_mode = p_loop_mode; +void Animation::set_loop(bool p_enabled) { + loop = p_enabled; emit_changed(); } -Animation::LoopMode Animation::get_loop_mode() const { - return loop_mode; +bool Animation::has_loop() const { + return loop; } void Animation::track_set_imported(int p_track, bool p_imported) { @@ -2799,7 +2628,7 @@ void Animation::_bind_methods() { ClassDB::bind_method(D_METHOD("track_set_interpolation_loop_wrap", "track_idx", "interpolation"), &Animation::track_set_interpolation_loop_wrap); ClassDB::bind_method(D_METHOD("track_get_interpolation_loop_wrap", "track_idx"), &Animation::track_get_interpolation_loop_wrap); - ClassDB::bind_method(D_METHOD("transform_track_interpolate", "track_idx", "time_sec", "is_backward"), &Animation::_transform_track_interpolate, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("transform_track_interpolate", "track_idx", "time_sec"), &Animation::_transform_track_interpolate); ClassDB::bind_method(D_METHOD("value_track_set_update_mode", "track_idx", "mode"), &Animation::value_track_set_update_mode); ClassDB::bind_method(D_METHOD("value_track_get_update_mode", "track_idx"), &Animation::value_track_get_update_mode); @@ -2837,8 +2666,8 @@ void Animation::_bind_methods() { ClassDB::bind_method(D_METHOD("set_length", "time_sec"), &Animation::set_length); ClassDB::bind_method(D_METHOD("get_length"), &Animation::get_length); - ClassDB::bind_method(D_METHOD("set_loop_mode", "loop_mode"), &Animation::set_loop_mode); - ClassDB::bind_method(D_METHOD("get_loop_mode"), &Animation::get_loop_mode); + ClassDB::bind_method(D_METHOD("set_loop", "enabled"), &Animation::set_loop); + ClassDB::bind_method(D_METHOD("has_loop"), &Animation::has_loop); ClassDB::bind_method(D_METHOD("set_step", "size_sec"), &Animation::set_step); ClassDB::bind_method(D_METHOD("get_step"), &Animation::get_step); @@ -2847,7 +2676,7 @@ void Animation::_bind_methods() { ClassDB::bind_method(D_METHOD("copy_track", "track_idx", "to_animation"), &Animation::copy_track); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "length", PROPERTY_HINT_RANGE, "0.001,99999,0.001"), "set_length", "get_length"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "loop_mode"), "set_loop_mode", "get_loop_mode"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "loop"), "set_loop", "has_loop"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "step", PROPERTY_HINT_RANGE, "0,4096,0.001"), "set_step", "get_step"); ADD_SIGNAL(MethodInfo("tracks_changed")); @@ -2867,10 +2696,6 @@ void Animation::_bind_methods() { BIND_ENUM_CONSTANT(UPDATE_DISCRETE); BIND_ENUM_CONSTANT(UPDATE_TRIGGER); BIND_ENUM_CONSTANT(UPDATE_CAPTURE); - - BIND_ENUM_CONSTANT(LOOP_NONE); - BIND_ENUM_CONSTANT(LOOP_LINEAR); - BIND_ENUM_CONSTANT(LOOP_PINGPONG); } void Animation::clear() { @@ -2878,7 +2703,7 @@ void Animation::clear() { memdelete(tracks[i]); } tracks.clear(); - loop_mode = LOOP_NONE; + loop = false; length = 1; emit_changed(); emit_signal(SceneStringNames::get_singleton()->tracks_changed); diff --git a/scene/resources/animation.h b/scene/resources/animation.h index 032b1a9277..9a410bd566 100644 --- a/scene/resources/animation.h +++ b/scene/resources/animation.h @@ -60,12 +60,7 @@ public: UPDATE_DISCRETE, UPDATE_TRIGGER, UPDATE_CAPTURE, - }; - enum LoopMode { - LOOP_NONE, - LOOP_LINEAR, - LOOP_PINGPONG, }; private: @@ -189,8 +184,7 @@ private: int _insert(double p_time, T &p_keys, const V &p_value); template <class K> - - inline int _find(const Vector<K> &p_keys, double p_time, bool p_backward = false) const; + inline int _find(const Vector<K> &p_keys, double p_time) const; _FORCE_INLINE_ Animation::TransformKey _interpolate(const Animation::TransformKey &p_a, const Animation::TransformKey &p_b, real_t p_c) const; @@ -206,7 +200,7 @@ private: _FORCE_INLINE_ real_t _cubic_interpolate(const real_t &p_pre_a, const real_t &p_a, const real_t &p_b, const real_t &p_post_b, real_t p_c) const; template <class T> - _FORCE_INLINE_ T _interpolate(const Vector<TKey<T>> &p_keys, double p_time, InterpolationType p_interp, bool p_loop_wrap, bool *p_ok, bool p_backward = false) const; + _FORCE_INLINE_ T _interpolate(const Vector<TKey<T>> &p_keys, double p_time, InterpolationType p_interp, bool p_loop_wrap, bool *p_ok) const; template <class T> _FORCE_INLINE_ void _track_get_key_indices_in_range(const Vector<T> &p_array, double from_time, double to_time, List<int> *p_indices) const; @@ -216,16 +210,15 @@ private: double length = 1.0; real_t step = 0.1; - LoopMode loop_mode = LOOP_NONE; - int pingponged = 0; + bool loop = false; // bind helpers private: - Array _transform_track_interpolate(int p_track, double p_time, bool p_backward = false) const { + Array _transform_track_interpolate(int p_track, double p_time) const { Vector3 loc; Quaternion rot; Vector3 scale; - transform_track_interpolate(p_track, p_time, &loc, &rot, &scale, p_backward); + transform_track_interpolate(p_track, p_time, &loc, &rot, &scale); Array ret; ret.push_back(loc); ret.push_back(rot); @@ -331,26 +324,26 @@ public: void track_set_interpolation_loop_wrap(int p_track, bool p_enable); bool track_get_interpolation_loop_wrap(int p_track) const; - Error transform_track_interpolate(int p_track, double p_time, Vector3 *r_loc, Quaternion *r_rot, Vector3 *r_scale, bool p_backward = false) const; + Error transform_track_interpolate(int p_track, double p_time, Vector3 *r_loc, Quaternion *r_rot, Vector3 *r_scale) const; Variant value_track_interpolate(int p_track, double p_time) const; - void value_track_get_key_indices(int p_track, double p_time, double p_delta, List<int> *p_indices, int p_pingponged = 0) const; + void value_track_get_key_indices(int p_track, double p_time, double p_delta, List<int> *p_indices) const; void value_track_set_update_mode(int p_track, UpdateMode p_mode); UpdateMode value_track_get_update_mode(int p_track) const; - void method_track_get_key_indices(int p_track, double p_time, double p_delta, List<int> *p_indices, int p_pingponged = 0) const; + void method_track_get_key_indices(int p_track, double p_time, double p_delta, List<int> *p_indices) const; Vector<Variant> method_track_get_params(int p_track, int p_key_idx) const; StringName method_track_get_name(int p_track, int p_key_idx) const; void copy_track(int p_track, Ref<Animation> p_to_animation); - void track_get_key_indices_in_range(int p_track, double p_time, double p_delta, List<int> *p_indices, int p_pingponged = 0) const; + void track_get_key_indices_in_range(int p_track, double p_time, double p_delta, List<int> *p_indices) const; void set_length(real_t p_length); real_t get_length() const; - void set_loop_mode(LoopMode p_loop_mode); - LoopMode get_loop_mode() const; + void set_loop(bool p_enabled); + bool has_loop() const; void set_step(real_t p_step); real_t get_step() const; @@ -366,6 +359,5 @@ public: VARIANT_ENUM_CAST(Animation::TrackType); VARIANT_ENUM_CAST(Animation::InterpolationType); VARIANT_ENUM_CAST(Animation::UpdateMode); -VARIANT_ENUM_CAST(Animation::LoopMode); #endif diff --git a/scene/resources/audio_stream_sample.cpp b/scene/resources/audio_stream_sample.cpp index c8a10e1c2a..d018103e64 100644 --- a/scene/resources/audio_stream_sample.cpp +++ b/scene/resources/audio_stream_sample.cpp @@ -299,7 +299,7 @@ int AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, int if (loop_format != AudioStreamSample::LOOP_DISABLED && offset < loop_begin_fp) { /* loopstart reached */ - if (loop_format == AudioStreamSample::LOOP_PINGPONG) { + if (loop_format == AudioStreamSample::LOOP_PING_PONG) { /* bounce ping pong */ offset = loop_begin_fp + (loop_begin_fp - offset); increment = -increment; @@ -320,7 +320,7 @@ int AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, int if (loop_format != AudioStreamSample::LOOP_DISABLED && offset >= loop_end_fp) { /* loopend reached */ - if (loop_format == AudioStreamSample::LOOP_PINGPONG) { + if (loop_format == AudioStreamSample::LOOP_PING_PONG) { /* bounce ping pong */ offset = loop_end_fp - (offset - loop_end_fp); increment = -increment; @@ -650,7 +650,7 @@ void AudioStreamSample::_bind_methods() { BIND_ENUM_CONSTANT(LOOP_DISABLED); BIND_ENUM_CONSTANT(LOOP_FORWARD); - BIND_ENUM_CONSTANT(LOOP_PINGPONG); + BIND_ENUM_CONSTANT(LOOP_PING_PONG); BIND_ENUM_CONSTANT(LOOP_BACKWARD); } diff --git a/scene/resources/audio_stream_sample.h b/scene/resources/audio_stream_sample.h index 0eb34be9bf..24198e3c98 100644 --- a/scene/resources/audio_stream_sample.h +++ b/scene/resources/audio_stream_sample.h @@ -92,7 +92,7 @@ public: enum LoopMode { LOOP_DISABLED, LOOP_FORWARD, - LOOP_PINGPONG, + LOOP_PING_PONG, LOOP_BACKWARD }; |