You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-12-01 16:38:31 +00:00
Merge pull request #113187 from TokageItLab/anim-map-revert
Revert: Fix AHashMap realloc cause AnimationPlayer crash
This commit is contained in:
@@ -164,11 +164,10 @@ void AnimationPlayer::_process_playback_data(PlaybackData &cd, double p_delta, f
|
||||
|
||||
double start = cd.get_start_time();
|
||||
double end = cd.get_end_time();
|
||||
AnimationData *p_from = &animation_set[cd.animation_name];
|
||||
|
||||
Animation::LoopedFlag looped_flag = Animation::LOOPED_FLAG_NONE;
|
||||
|
||||
switch (p_from->animation->get_loop_mode()) {
|
||||
switch (cd.from->animation->get_loop_mode()) {
|
||||
case Animation::LOOP_NONE: {
|
||||
if (Animation::is_less_approx(next_pos, start)) {
|
||||
next_pos = start;
|
||||
@@ -208,7 +207,7 @@ void AnimationPlayer::_process_playback_data(PlaybackData &cd, double p_delta, f
|
||||
|
||||
// End detection.
|
||||
if (p_is_current) {
|
||||
if (p_from->animation->get_loop_mode() == Animation::LOOP_NONE) {
|
||||
if (cd.from->animation->get_loop_mode() == Animation::LOOP_NONE) {
|
||||
if (!backwards && Animation::is_less_or_equal_approx(prev_pos, end) && Math::is_equal_approx(next_pos, end)) {
|
||||
// Playback finished.
|
||||
next_pos = end; // Snap to the edge.
|
||||
@@ -249,7 +248,7 @@ void AnimationPlayer::_process_playback_data(PlaybackData &cd, double p_delta, f
|
||||
pi.is_external_seeking = !p_internal_seeked && !p_started;
|
||||
pi.looped_flag = looped_flag;
|
||||
pi.weight = p_blend;
|
||||
make_animation_instance(cd.animation_name, pi);
|
||||
make_animation_instance(cd.from->name, pi);
|
||||
}
|
||||
|
||||
float AnimationPlayer::get_current_blend_amount() {
|
||||
@@ -301,13 +300,12 @@ void AnimationPlayer::_blend_playback_data(double p_delta, bool p_started) {
|
||||
}
|
||||
|
||||
bool AnimationPlayer::_blend_pre_process(double p_delta, int p_track_count, const AHashMap<NodePath, int> &p_track_map) {
|
||||
if (playback.current.animation_name.is_empty()) {
|
||||
if (!playback.current.from) {
|
||||
_set_process(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
AnimationData *p_from = &animation_set[playback.current.animation_name];
|
||||
tmp_from = p_from->animation->get_instance_id();
|
||||
tmp_from = playback.current.from->animation->get_instance_id();
|
||||
end_reached = false;
|
||||
end_notify = false;
|
||||
|
||||
@@ -318,10 +316,10 @@ bool AnimationPlayer::_blend_pre_process(double p_delta, int p_track_count, cons
|
||||
playback.started = false;
|
||||
}
|
||||
|
||||
String prev_animation_name = playback.current.animation_name;
|
||||
AnimationData *prev_from = playback.current.from;
|
||||
_blend_playback_data(p_delta, started);
|
||||
|
||||
if (prev_animation_name != playback.current.animation_name) {
|
||||
if (prev_from != playback.current.from) {
|
||||
return false; // Animation has been changed in the process (may be caused by method track), abort process.
|
||||
}
|
||||
|
||||
@@ -335,7 +333,7 @@ void AnimationPlayer::_blend_capture(double p_delta) {
|
||||
void AnimationPlayer::_blend_post_process() {
|
||||
if (end_reached) {
|
||||
// If the method track changes current animation, the animation is not finished.
|
||||
if (tmp_from == animation_set[playback.current.animation_name].animation->get_instance_id()) {
|
||||
if (tmp_from == playback.current.from->animation->get_instance_id()) {
|
||||
if (playback_queue.size()) {
|
||||
if (!finished_anim.is_empty()) {
|
||||
emit_signal(SceneStringName(animation_finished), finished_anim);
|
||||
@@ -435,10 +433,10 @@ void AnimationPlayer::play_section_with_markers(const StringName &p_name, const
|
||||
ERR_FAIL_COND_MSG(p_start_marker && p_end_marker && Animation::is_greater_approx(start_time, end_time), vformat("End marker %s is placed earlier than start marker %s in animation: %s.", p_end_marker, p_start_marker, name));
|
||||
|
||||
if (p_start_marker && Animation::is_less_approx(start_time, 0)) {
|
||||
WARN_PRINT_ED(vformat("Negative time start marker: %s is invalid in the section, so the start of the animation: %s is used instead.", p_start_marker, playback.current.animation_name));
|
||||
WARN_PRINT_ED(vformat("Negative time start marker: %s is invalid in the section, so the start of the animation: %s is used instead.", p_start_marker, playback.current.from->animation->get_name()));
|
||||
}
|
||||
if (p_end_marker && Animation::is_less_approx(end_time, 0)) {
|
||||
WARN_PRINT_ED(vformat("Negative time end marker: %s is invalid in the section, so the end of the animation: %s is used instead.", p_end_marker, playback.current.animation_name));
|
||||
WARN_PRINT_ED(vformat("Negative time end marker: %s is invalid in the section, so the end of the animation: %s is used instead.", p_end_marker, playback.current.from->animation->get_name()));
|
||||
}
|
||||
|
||||
play_section(name, start_time, end_time, p_custom_blend, p_custom_scale, p_from_end);
|
||||
@@ -457,11 +455,11 @@ void AnimationPlayer::play_section(const StringName &p_name, double p_start_time
|
||||
|
||||
Playback &c = playback;
|
||||
|
||||
if (!c.current.animation_name.is_empty()) {
|
||||
if (c.current.from) {
|
||||
double blend_time = 0.0;
|
||||
// Find if it can blend.
|
||||
BlendKey bk;
|
||||
bk.from = c.current.animation_name;
|
||||
bk.from = c.current.from->name;
|
||||
bk.to = name;
|
||||
|
||||
if (Animation::is_greater_or_equal_approx(p_custom_blend, 0)) {
|
||||
@@ -473,7 +471,7 @@ void AnimationPlayer::play_section(const StringName &p_name, double p_start_time
|
||||
if (blend_times.has(bk)) {
|
||||
blend_time = blend_times[bk];
|
||||
} else {
|
||||
bk.from = c.current.animation_name;
|
||||
bk.from = c.current.from->name;
|
||||
bk.to = "*";
|
||||
|
||||
if (blend_times.has(bk)) {
|
||||
@@ -500,8 +498,7 @@ void AnimationPlayer::play_section(const StringName &p_name, double p_start_time
|
||||
_clear_playing_caches();
|
||||
}
|
||||
|
||||
c.current.animation_name = name;
|
||||
c.current.animation_length = animation_set[name].animation->get_length();
|
||||
c.current.from = &animation_set[name];
|
||||
c.current.speed_scale = p_custom_scale;
|
||||
c.current.start_time = p_start_time;
|
||||
c.current.end_time = p_end_time;
|
||||
@@ -616,8 +613,7 @@ void AnimationPlayer::set_assigned_animation(const StringName &p_animation) {
|
||||
} else {
|
||||
ERR_FAIL_COND_MSG(!animation_set.has(p_animation), vformat("Animation not found: %s.", p_animation.operator String()));
|
||||
playback.current.pos = 0;
|
||||
playback.current.animation_name = p_animation;
|
||||
playback.current.animation_length = animation_set[p_animation].animation->get_length();
|
||||
playback.current.from = &animation_set[p_animation];
|
||||
playback.current.start_time = -1;
|
||||
playback.current.end_time = -1;
|
||||
playback.assigned = p_animation;
|
||||
@@ -662,13 +658,12 @@ void AnimationPlayer::seek_internal(double p_time, bool p_update, bool p_update_
|
||||
_check_immediately_after_start();
|
||||
|
||||
playback.current.pos = p_time;
|
||||
if (!playback.current.animation_name.is_empty()) {
|
||||
if (!playback.current.from) {
|
||||
if (playback.assigned) {
|
||||
ERR_FAIL_COND_MSG(!animation_set.has(playback.assigned), vformat("Animation not found: %s.", playback.assigned));
|
||||
playback.current.animation_name = playback.assigned;
|
||||
playback.current.animation_length = animation_set[playback.assigned].animation->get_length();
|
||||
playback.current.from = &animation_set[playback.assigned];
|
||||
}
|
||||
if (!playback.current.animation_name.is_empty()) {
|
||||
if (!playback.current.from) {
|
||||
return; // There is no animation.
|
||||
}
|
||||
}
|
||||
@@ -704,37 +699,37 @@ void AnimationPlayer::_check_immediately_after_start() {
|
||||
}
|
||||
|
||||
bool AnimationPlayer::is_valid() const {
|
||||
return (!playback.current.animation_name.is_empty());
|
||||
return (playback.current.from);
|
||||
}
|
||||
|
||||
double AnimationPlayer::get_current_animation_position() const {
|
||||
ERR_FAIL_COND_V_MSG(!playback.current.animation_name.is_empty(), 0, "AnimationPlayer has no current animation.");
|
||||
ERR_FAIL_NULL_V_MSG(playback.current.from, 0, "AnimationPlayer has no current animation.");
|
||||
return playback.current.pos;
|
||||
}
|
||||
|
||||
double AnimationPlayer::get_current_animation_length() const {
|
||||
ERR_FAIL_COND_V_MSG(!playback.current.animation_name.is_empty(), 0, "AnimationPlayer has no current animation.");
|
||||
return playback.current.animation_length;
|
||||
ERR_FAIL_NULL_V_MSG(playback.current.from, 0, "AnimationPlayer has no current animation.");
|
||||
return playback.current.from->animation->get_length();
|
||||
}
|
||||
|
||||
void AnimationPlayer::set_section_with_markers(const StringName &p_start_marker, const StringName &p_end_marker) {
|
||||
ERR_FAIL_COND_MSG(!playback.current.animation_name.is_empty(), "AnimationPlayer has no current animation.");
|
||||
ERR_FAIL_NULL_MSG(playback.current.from, "AnimationPlayer has no current animation.");
|
||||
ERR_FAIL_COND_MSG(p_start_marker == p_end_marker && p_start_marker, vformat("Start marker and end marker cannot be the same marker: %s.", p_start_marker));
|
||||
ERR_FAIL_COND_MSG(p_start_marker && !animation_set[playback.current.animation_name].animation->has_marker(p_start_marker), vformat("Marker %s not found in animation: %s.", p_start_marker, playback.current.animation_name));
|
||||
ERR_FAIL_COND_MSG(p_end_marker && !animation_set[playback.current.animation_name].animation->has_marker(p_end_marker), vformat("Marker %s not found in animation: %s.", p_end_marker, playback.current.animation_name));
|
||||
double start_time = p_start_marker ? animation_set[playback.current.animation_name].animation->get_marker_time(p_start_marker) : -1;
|
||||
double end_time = p_end_marker ? animation_set[playback.current.animation_name].animation->get_marker_time(p_end_marker) : -1;
|
||||
ERR_FAIL_COND_MSG(p_start_marker && !playback.current.from->animation->has_marker(p_start_marker), vformat("Marker %s not found in animation: %s.", p_start_marker, playback.current.from->animation->get_name()));
|
||||
ERR_FAIL_COND_MSG(p_end_marker && !playback.current.from->animation->has_marker(p_end_marker), vformat("Marker %s not found in animation: %s.", p_end_marker, playback.current.from->animation->get_name()));
|
||||
double start_time = p_start_marker ? playback.current.from->animation->get_marker_time(p_start_marker) : -1;
|
||||
double end_time = p_end_marker ? playback.current.from->animation->get_marker_time(p_end_marker) : -1;
|
||||
if (p_start_marker && Animation::is_less_approx(start_time, 0)) {
|
||||
WARN_PRINT_ONCE_ED(vformat("Marker %s time must be positive in animation: %s.", p_start_marker, playback.current.animation_name));
|
||||
WARN_PRINT_ONCE_ED(vformat("Marker %s time must be positive in animation: %s.", p_start_marker, playback.current.from->animation->get_name()));
|
||||
}
|
||||
if (p_end_marker && Animation::is_less_approx(end_time, 0)) {
|
||||
WARN_PRINT_ONCE_ED(vformat("Marker %s time must be positive in animation: %s.", p_end_marker, playback.current.animation_name));
|
||||
WARN_PRINT_ONCE_ED(vformat("Marker %s time must be positive in animation: %s.", p_end_marker, playback.current.from->animation->get_name()));
|
||||
}
|
||||
set_section(start_time, end_time);
|
||||
}
|
||||
|
||||
void AnimationPlayer::set_section(double p_start_time, double p_end_time) {
|
||||
ERR_FAIL_COND_MSG(!playback.current.animation_name.is_empty(), "AnimationPlayer has no current animation.");
|
||||
ERR_FAIL_NULL_MSG(playback.current.from, "AnimationPlayer has no current animation.");
|
||||
ERR_FAIL_COND_MSG(Animation::is_greater_or_equal_approx(p_start_time, 0) && Animation::is_greater_or_equal_approx(p_end_time, 0) && Animation::is_greater_or_equal_approx(p_start_time, p_end_time), vformat("Start time %f is greater than end time %f.", p_start_time, p_end_time));
|
||||
playback.current.start_time = p_start_time;
|
||||
playback.current.end_time = p_end_time;
|
||||
@@ -747,12 +742,12 @@ void AnimationPlayer::reset_section() {
|
||||
}
|
||||
|
||||
double AnimationPlayer::get_section_start_time() const {
|
||||
ERR_FAIL_COND_V_MSG(!playback.current.animation_name.is_empty(), playback.current.start_time, "AnimationPlayer has no current animation.");
|
||||
ERR_FAIL_NULL_V_MSG(playback.current.from, playback.current.start_time, "AnimationPlayer has no current animation.");
|
||||
return playback.current.get_start_time();
|
||||
}
|
||||
|
||||
double AnimationPlayer::get_section_end_time() const {
|
||||
ERR_FAIL_COND_V_MSG(!playback.current.animation_name.is_empty(), playback.current.end_time, "AnimationPlayer has no current animation.");
|
||||
ERR_FAIL_NULL_V_MSG(playback.current.from, playback.current.end_time, "AnimationPlayer has no current animation.");
|
||||
return playback.current.get_end_time();
|
||||
}
|
||||
|
||||
@@ -784,7 +779,7 @@ void AnimationPlayer::_stop_internal(bool p_reset, bool p_keep_state) {
|
||||
_clear_caches();
|
||||
Playback &c = playback;
|
||||
// c.blend.clear();
|
||||
double start = (!c.current.animation_name.is_empty()) ? playback.current.get_start_time() : 0;
|
||||
double start = c.current.from ? playback.current.get_start_time() : 0;
|
||||
if (p_reset) {
|
||||
c.blend.clear();
|
||||
if (p_keep_state) {
|
||||
@@ -794,7 +789,7 @@ void AnimationPlayer::_stop_internal(bool p_reset, bool p_keep_state) {
|
||||
seek_internal(start, true, true, true);
|
||||
is_stopping = false;
|
||||
}
|
||||
c.current.animation_name = String();
|
||||
c.current.from = nullptr;
|
||||
c.current.speed_scale = 1;
|
||||
emit_signal(SNAME("current_animation_changed"), "");
|
||||
}
|
||||
|
||||
@@ -65,21 +65,20 @@ private:
|
||||
bool is_stopping = false;
|
||||
|
||||
struct PlaybackData {
|
||||
String animation_name;
|
||||
int animation_length = 0;
|
||||
AnimationData *from = nullptr;
|
||||
double pos = 0.0;
|
||||
float speed_scale = 1.0;
|
||||
double start_time = 0.0;
|
||||
double end_time = 0.0;
|
||||
double get_start_time() const {
|
||||
if ((!animation_name.is_empty()) && (Animation::is_less_approx(start_time, 0) || Animation::is_greater_approx(start_time, animation_length))) {
|
||||
if (from && (Animation::is_less_approx(start_time, 0) || Animation::is_greater_approx(start_time, from->animation->get_length()))) {
|
||||
return 0;
|
||||
}
|
||||
return start_time;
|
||||
}
|
||||
double get_end_time() const {
|
||||
if ((!animation_name.is_empty()) && (Animation::is_less_approx(end_time, 0) || Animation::is_greater_approx(end_time, animation_length))) {
|
||||
return animation_length;
|
||||
if (from && (Animation::is_less_approx(end_time, 0) || Animation::is_greater_approx(end_time, from->animation->get_length()))) {
|
||||
return from->animation->get_length();
|
||||
}
|
||||
return end_time;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user