summaryrefslogtreecommitdiffstats
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/animation/animation_blend_tree.cpp24
-rw-r--r--scene/animation/animation_blend_tree.h5
-rw-r--r--scene/animation/animation_mixer.cpp37
-rw-r--r--scene/animation/animation_mixer.h1
-rw-r--r--scene/animation/animation_tree.cpp4
-rw-r--r--scene/animation/animation_tree.h2
-rw-r--r--scene/gui/text_edit.cpp4
7 files changed, 61 insertions, 16 deletions
diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp
index a2aef60417..e172286d05 100644
--- a/scene/animation/animation_blend_tree.cpp
+++ b/scene/animation/animation_blend_tree.cpp
@@ -93,7 +93,9 @@ AnimationNode::NodeTimeInfo AnimationNodeAnimation::process(const AnimationMixer
AnimationMixer::PlaybackInfo pi = p_playback_info;
if (p_playback_info.seeked) {
- pi.delta = get_node_time_info().position - p_playback_info.time;
+ if (p_playback_info.is_external_seeking) {
+ pi.delta = get_node_time_info().position - p_playback_info.time;
+ }
} else {
pi.time = get_node_time_info().position + (backward ? -p_playback_info.delta : p_playback_info.delta);
}
@@ -140,6 +142,12 @@ AnimationNode::NodeTimeInfo AnimationNodeAnimation::_process(const AnimationMixe
// 1. Progress for AnimationNode.
bool will_end = Animation::is_greater_or_equal_approx(cur_time + cur_delta, cur_len);
+ bool is_started = p_seek && !p_is_external_seeking && Math::is_zero_approx(cur_time);
+
+ // 1. Progress for AnimationNode.
+ if (is_started && advance_on_start) {
+ cur_time = cur_delta;
+ }
if (cur_loop_mode != Animation::LOOP_NONE) {
if (cur_loop_mode == Animation::LOOP_LINEAR) {
if (!Math::is_zero_approx(cur_len)) {
@@ -232,7 +240,7 @@ AnimationNode::NodeTimeInfo AnimationNodeAnimation::_process(const AnimationMixe
// 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 && Math::is_zero_approx(cur_playback_time)) {
+ if (is_started) {
process_state->tree->call_deferred(SNAME("emit_signal"), SceneStringName(animation_started), animation);
}
// Finished.
@@ -282,6 +290,14 @@ bool AnimationNodeAnimation::is_backward() const {
return backward;
}
+void AnimationNodeAnimation::set_advance_on_start(bool p_advance_on_start) {
+ advance_on_start = p_advance_on_start;
+}
+
+bool AnimationNodeAnimation::is_advance_on_start() const {
+ return advance_on_start;
+}
+
void AnimationNodeAnimation::set_use_custom_timeline(bool p_use_custom_timeline) {
use_custom_timeline = p_use_custom_timeline;
notify_property_list_changed();
@@ -331,6 +347,9 @@ void AnimationNodeAnimation::_bind_methods() {
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);
+ ClassDB::bind_method(D_METHOD("set_advance_on_start", "advance_on_start"), &AnimationNodeAnimation::set_advance_on_start);
+ ClassDB::bind_method(D_METHOD("is_advance_on_start"), &AnimationNodeAnimation::is_advance_on_start);
+
ClassDB::bind_method(D_METHOD("set_use_custom_timeline", "use_custom_timeline"), &AnimationNodeAnimation::set_use_custom_timeline);
ClassDB::bind_method(D_METHOD("is_using_custom_timeline"), &AnimationNodeAnimation::is_using_custom_timeline);
@@ -348,6 +367,7 @@ void AnimationNodeAnimation::_bind_methods() {
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");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "advance_on_start"), "set_advance_on_start", "is_advance_on_start");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_custom_timeline"), "set_use_custom_timeline", "is_using_custom_timeline");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "timeline_length", PROPERTY_HINT_RANGE, "0.001,60,0.001,or_greater,or_less,hide_slider,suffix:s"), "set_timeline_length", "get_timeline_length");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "stretch_time_scale"), "set_stretch_time_scale", "is_stretching_time_scale");
diff --git a/scene/animation/animation_blend_tree.h b/scene/animation/animation_blend_tree.h
index 2add35d009..5c912f0095 100644
--- a/scene/animation/animation_blend_tree.h
+++ b/scene/animation/animation_blend_tree.h
@@ -38,6 +38,8 @@ class AnimationNodeAnimation : public AnimationRootNode {
StringName animation;
+ bool advance_on_start = false;
+
bool use_custom_timeline = false;
double timeline_length = 1.0;
Animation::LoopMode loop_mode = Animation::LOOP_NONE;
@@ -72,6 +74,9 @@ public:
void set_backward(bool p_backward);
bool is_backward() const;
+ void set_advance_on_start(bool p_advance_on_start);
+ bool is_advance_on_start() const;
+
void set_use_custom_timeline(bool p_use_custom_timeline);
bool is_using_custom_timeline() const;
diff --git a/scene/animation/animation_mixer.cpp b/scene/animation/animation_mixer.cpp
index 0fa6810d23..b40c677f6e 100644
--- a/scene/animation/animation_mixer.cpp
+++ b/scene/animation/animation_mixer.cpp
@@ -600,6 +600,22 @@ void AnimationMixer::_init_root_motion_cache() {
root_motion_scale_accumulator = Vector3(1, 1, 1);
}
+void AnimationMixer::_create_track_num_to_track_cashe_for_animation(Ref<Animation> &p_animation) {
+ ERR_FAIL_COND(animation_track_num_to_track_cashe.has(p_animation));
+ LocalVector<TrackCache *> &track_num_to_track_cashe = animation_track_num_to_track_cashe.insert_new(p_animation, LocalVector<TrackCache *>())->value;
+ const Vector<Animation::Track *> &tracks = p_animation->get_tracks();
+
+ track_num_to_track_cashe.resize(tracks.size());
+ for (int i = 0; i < tracks.size(); i++) {
+ TrackCache **track_ptr = track_cache.getptr(tracks[i]->thash);
+ if (track_ptr == nullptr) {
+ track_num_to_track_cashe[i] = nullptr;
+ } else {
+ track_num_to_track_cashe[i] = *track_ptr;
+ }
+ }
+}
+
bool AnimationMixer::_update_caches() {
setup_pass++;
@@ -928,20 +944,9 @@ bool AnimationMixer::_update_caches() {
}
animation_track_num_to_track_cashe.clear();
- LocalVector<TrackCache *> track_num_to_track_cashe;
for (const StringName &E : sname_list) {
Ref<Animation> anim = get_animation(E);
- const Vector<Animation::Track *> tracks = anim->get_tracks();
- track_num_to_track_cashe.resize(tracks.size());
- for (int i = 0; i < tracks.size(); i++) {
- TrackCache **track_ptr = track_cache.getptr(tracks[i]->thash);
- if (track_ptr == nullptr) {
- track_num_to_track_cashe[i] = nullptr;
- } else {
- track_num_to_track_cashe[i] = *track_ptr;
- }
- }
- animation_track_num_to_track_cashe.insert(anim, track_num_to_track_cashe);
+ _create_track_num_to_track_cashe_for_animation(anim);
}
track_count = idx;
@@ -1074,6 +1079,9 @@ void AnimationMixer::blend_capture(double p_delta) {
capture_cache.remain -= p_delta * capture_cache.step;
if (Animation::is_less_or_equal_approx(capture_cache.remain, 0)) {
+ if (capture_cache.animation.is_valid()) {
+ animation_track_num_to_track_cashe.erase(capture_cache.animation);
+ }
capture_cache.clear();
return;
}
@@ -2205,6 +2213,9 @@ void AnimationMixer::capture(const StringName &p_name, double p_duration, Tween:
capture_cache.step = 1.0 / p_duration;
capture_cache.trans_type = p_trans_type;
capture_cache.ease_type = p_ease_type;
+ if (capture_cache.animation.is_valid()) {
+ animation_track_num_to_track_cashe.erase(capture_cache.animation);
+ }
capture_cache.animation.instantiate();
bool is_valid = false;
@@ -2228,6 +2239,8 @@ void AnimationMixer::capture(const StringName &p_name, double p_duration, Tween:
}
if (!is_valid) {
capture_cache.clear();
+ } else {
+ _create_track_num_to_track_cashe_for_animation(capture_cache.animation);
}
}
diff --git a/scene/animation/animation_mixer.h b/scene/animation/animation_mixer.h
index 1906146c56..3769fa268c 100644
--- a/scene/animation/animation_mixer.h
+++ b/scene/animation/animation_mixer.h
@@ -321,6 +321,7 @@ protected:
void _clear_playing_caches();
void _init_root_motion_cache();
bool _update_caches();
+ void _create_track_num_to_track_cashe_for_animation(Ref<Animation> &p_animation);
/* ---- Audio ---- */
AudioServer::PlaybackType playback_type;
diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp
index d676e2acf4..f2871cda79 100644
--- a/scene/animation/animation_tree.cpp
+++ b/scene/animation/animation_tree.cpp
@@ -371,7 +371,9 @@ AnimationNode::NodeTimeInfo AnimationNode::process(const AnimationMixer::Playbac
AnimationMixer::PlaybackInfo pi = p_playback_info;
if (p_playback_info.seeked) {
- pi.delta = get_node_time_info().position - p_playback_info.time;
+ if (p_playback_info.is_external_seeking) {
+ pi.delta = get_node_time_info().position - p_playback_info.time;
+ }
} else {
pi.time = get_node_time_info().position + p_playback_info.delta;
}
diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h
index eb25a8db1b..5a2a822ff0 100644
--- a/scene/animation/animation_tree.h
+++ b/scene/animation/animation_tree.h
@@ -91,7 +91,7 @@ public:
if (Math::is_zero_approx(remain)) {
return 0;
}
- return length - position;
+ return remain;
}
};
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 699277ba41..05e9b84bfa 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -7310,6 +7310,10 @@ void TextEdit::_paste_internal(int p_caret) {
}
String clipboard = DisplayServer::get_singleton()->clipboard_get();
+ if (clipboard.is_empty()) {
+ // Nothing to paste.
+ return;
+ }
// Paste a full line. Ignore '\r' characters that may have been added to the clipboard by the OS.
if (get_caret_count() == 1 && !has_selection(0) && !cut_copy_line.is_empty() && cut_copy_line == clipboard.replace("\r", "")) {