diff options
Diffstat (limited to 'scene/animation')
-rw-r--r-- | scene/animation/animation_player.cpp | 45 | ||||
-rw-r--r-- | scene/animation/animation_player.h | 6 | ||||
-rw-r--r-- | scene/animation/animation_tree.cpp | 42 | ||||
-rw-r--r-- | scene/animation/animation_tree.h | 2 |
4 files changed, 93 insertions, 2 deletions
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index df6ef16b4f..76bf71387e 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -454,6 +454,23 @@ static void _call_object(Object *p_object, const StringName &p_method, const Vec } } +Variant AnimationPlayer::_post_process_key_value(const Ref<Animation> &p_anim, int p_track, Variant p_value, const Object *p_object, int p_object_idx) { + switch (p_anim->track_get_type(p_track)) { +#ifndef _3D_DISABLED + case Animation::TYPE_POSITION_3D: { + if (p_object_idx >= 0) { + const Skeleton3D *skel = Object::cast_to<Skeleton3D>(p_object); + return Vector3(p_value) * skel->get_motion_scale(); + } + return p_value; + } break; +#endif // _3D_DISABLED + default: { + } break; + } + return p_value; +} + 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) { _ensure_node_caches(p_anim); ERR_FAIL_COND(p_anim->node_cache.size() != p_anim->animation->get_track_count()); @@ -498,6 +515,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double if (err != OK) { continue; } + loc = _post_process_key_value(a, i, loc, nc->node_3d, nc->bone_idx); if (nc->accum_pass != accum_pass) { ERR_CONTINUE(cache_update_size >= NODE_CACHE_UPDATE_MAX); @@ -525,6 +543,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double if (err != OK) { continue; } + rot = _post_process_key_value(a, i, rot, nc->node_3d, nc->bone_idx); if (nc->accum_pass != accum_pass) { ERR_CONTINUE(cache_update_size >= NODE_CACHE_UPDATE_MAX); @@ -552,6 +571,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double if (err != OK) { continue; } + scale = _post_process_key_value(a, i, scale, nc->node_3d, nc->bone_idx); if (nc->accum_pass != accum_pass) { ERR_CONTINUE(cache_update_size >= NODE_CACHE_UPDATE_MAX); @@ -579,6 +599,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double if (err != OK) { continue; } + blend = _post_process_key_value(a, i, blend, nc->node_blend_shape, nc->blend_shape_idx); if (nc->accum_pass != accum_pass) { ERR_CONTINUE(cache_update_size >= NODE_CACHE_UPDATE_MAX); @@ -631,9 +652,9 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double if (p_time < first_key_time) { double c = Math::ease(p_time / first_key_time, transition); Variant first_value = a->track_get_key_value(i, first_key); + first_value = _post_process_key_value(a, i, first_value, nc->node); Variant interp_value; Variant::interpolate(pa->capture, first_value, c, interp_value); - if (pa->accum_pass != accum_pass) { ERR_CONTINUE(cache_update_prop_size >= NODE_CACHE_UPDATE_MAX); cache_update_prop[cache_update_prop_size++] = pa; @@ -653,6 +674,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double if (value == Variant()) { continue; } + value = _post_process_key_value(a, i, value, nc->node); if (pa->accum_pass != accum_pass) { ERR_CONTINUE(cache_update_prop_size >= NODE_CACHE_UPDATE_MAX); @@ -669,6 +691,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double for (int &F : indices) { Variant value = a->track_get_key_value(i, F); + value = _post_process_key_value(a, i, value, nc->node); switch (pa->special) { case SP_NONE: { bool valid; @@ -753,6 +776,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double TrackNodeCache::BezierAnim *ba = &E->value; real_t bezier = a->bezier_track_interpolate(i, p_time); + bezier = _post_process_key_value(a, i, bezier, nc->node); if (ba->accum_pass != accum_pass) { ERR_CONTINUE(cache_update_bezier_size >= NODE_CACHE_UPDATE_MAX); cache_update_bezier[cache_update_bezier_size++] = ba; @@ -1177,11 +1201,15 @@ void AnimationPlayer::_animation_process(double p_delta) { emit_signal(SceneStringNames::get_singleton()->animation_changed, old, new_name); } } else { - //stop(); playing = false; _set_process(false); if (end_notify) { emit_signal(SceneStringNames::get_singleton()->animation_finished, playback.assigned); + + if (movie_quit_on_finish && OS::get_singleton()->has_feature("movie")) { + print_line(vformat("Movie Maker mode is enabled. Quitting on animation finish as requested by: %s", get_path())); + get_tree()->quit(); + } } } end_reached = false; @@ -1868,6 +1896,14 @@ AnimationPlayer::AnimationMethodCallMode AnimationPlayer::get_method_call_mode() return method_call_mode; } +void AnimationPlayer::set_movie_quit_on_finish_enabled(bool p_enabled) { + movie_quit_on_finish = p_enabled; +} + +bool AnimationPlayer::is_movie_quit_on_finish_enabled() const { + return movie_quit_on_finish; +} + void AnimationPlayer::_set_process(bool p_process, bool p_force) { if (processing == p_process && !p_force) { return; @@ -2088,6 +2124,9 @@ void AnimationPlayer::_bind_methods() { ClassDB::bind_method(D_METHOD("set_method_call_mode", "mode"), &AnimationPlayer::set_method_call_mode); ClassDB::bind_method(D_METHOD("get_method_call_mode"), &AnimationPlayer::get_method_call_mode); + ClassDB::bind_method(D_METHOD("set_movie_quit_on_finish_enabled"), &AnimationPlayer::set_movie_quit_on_finish_enabled); + ClassDB::bind_method(D_METHOD("is_movie_quit_on_finish_enabled"), &AnimationPlayer::is_movie_quit_on_finish_enabled); + ClassDB::bind_method(D_METHOD("get_current_animation_position"), &AnimationPlayer::get_current_animation_position); ClassDB::bind_method(D_METHOD("get_current_animation_length"), &AnimationPlayer::get_current_animation_length); @@ -2109,6 +2148,8 @@ void AnimationPlayer::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "playback_speed", PROPERTY_HINT_RANGE, "-64,64,0.01"), "set_speed_scale", "get_speed_scale"); ADD_PROPERTY(PropertyInfo(Variant::INT, "method_call_mode", PROPERTY_HINT_ENUM, "Deferred,Immediate"), "set_method_call_mode", "get_method_call_mode"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "movie_quit_on_finish"), "set_movie_quit_on_finish_enabled", "is_movie_quit_on_finish_enabled"); + ADD_SIGNAL(MethodInfo("animation_finished", PropertyInfo(Variant::STRING_NAME, "anim_name"))); ADD_SIGNAL(MethodInfo("animation_changed", PropertyInfo(Variant::STRING_NAME, "old_name"), PropertyInfo(Variant::STRING_NAME, "new_name"))); ADD_SIGNAL(MethodInfo("animation_started", PropertyInfo(Variant::STRING_NAME, "anim_name"))); diff --git a/scene/animation/animation_player.h b/scene/animation/animation_player.h index 0d3ce5977e..b6d8dab1ed 100644 --- a/scene/animation/animation_player.h +++ b/scene/animation/animation_player.h @@ -262,6 +262,7 @@ private: bool reset_on_save = true; AnimationProcessCallback process_callback = ANIMATION_PROCESS_IDLE; AnimationMethodCallMode method_call_mode = ANIMATION_METHOD_CALL_DEFERRED; + bool movie_quit_on_finish = false; bool processing = false; bool active = true; @@ -316,6 +317,8 @@ protected: static void _bind_methods(); + virtual Variant _post_process_key_value(const Ref<Animation> &p_anim, int p_track, Variant p_value, const Object *p_object, int p_object_idx = -1); + public: StringName find_animation(const Ref<Animation> &p_animation) const; StringName find_animation_library(const Ref<Animation> &p_animation) const; @@ -371,6 +374,9 @@ public: void set_method_call_mode(AnimationMethodCallMode p_mode); AnimationMethodCallMode get_method_call_mode() const; + void set_movie_quit_on_finish_enabled(bool p_enabled); + bool is_movie_quit_on_finish_enabled() const; + void seek(double p_time, bool p_update = false); void seek_delta(double p_time, float p_delta); float get_current_animation_position() const; diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp index 4b80f571ae..b73fd6a24f 100644 --- a/scene/animation/animation_tree.cpp +++ b/scene/animation/animation_tree.cpp @@ -1054,7 +1054,9 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } + loc[0] = _post_process_key_value(a, i, loc[0], t->object, t->bone_idx); a->position_track_interpolate(i, (double)a->get_length(), &loc[1]); + loc[1] = _post_process_key_value(a, i, loc[1], t->object, t->bone_idx); t->loc += (loc[1] - loc[0]) * blend; prev_time = 0; } @@ -1064,7 +1066,9 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } + loc[0] = _post_process_key_value(a, i, loc[0], t->object, t->bone_idx); a->position_track_interpolate(i, 0, &loc[1]); + loc[1] = _post_process_key_value(a, i, loc[1], t->object, t->bone_idx); t->loc += (loc[1] - loc[0]) * blend; prev_time = (double)a->get_length(); } @@ -1074,8 +1078,10 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } + loc[0] = _post_process_key_value(a, i, loc[0], t->object, t->bone_idx); a->position_track_interpolate(i, time, &loc[1]); + loc[1] = _post_process_key_value(a, i, loc[1], t->object, t->bone_idx); t->loc += (loc[1] - loc[0]) * blend; prev_time = !backward ? 0 : (double)a->get_length(); @@ -1092,6 +1098,7 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } + loc = _post_process_key_value(a, i, loc, t->object, t->bone_idx); t->loc += (loc - t->init_loc) * blend; } @@ -1150,7 +1157,9 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } + rot[0] = _post_process_key_value(a, i, rot[0], t->object, t->bone_idx); a->rotation_track_interpolate(i, (double)a->get_length(), &rot[1]); + rot[1] = _post_process_key_value(a, i, rot[1], t->object, t->bone_idx); t->rot = (t->rot * Quaternion().slerp(rot[0].inverse() * rot[1], blend)).normalized(); prev_time = 0; } @@ -1160,6 +1169,7 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } + rot[0] = _post_process_key_value(a, i, rot[0], t->object, t->bone_idx); a->rotation_track_interpolate(i, 0, &rot[1]); t->rot = (t->rot * Quaternion().slerp(rot[0].inverse() * rot[1], blend)).normalized(); prev_time = (double)a->get_length(); @@ -1170,8 +1180,10 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } + rot[0] = _post_process_key_value(a, i, rot[0], t->object, t->bone_idx); a->rotation_track_interpolate(i, time, &rot[1]); + rot[1] = _post_process_key_value(a, i, rot[1], t->object, t->bone_idx); t->rot = (t->rot * Quaternion().slerp(rot[0].inverse() * rot[1], blend)).normalized(); prev_time = !backward ? 0 : (double)a->get_length(); @@ -1188,6 +1200,7 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } + rot = _post_process_key_value(a, i, rot, t->object, t->bone_idx); t->rot = (t->rot * Quaternion().slerp(t->init_rot.inverse() * rot, blend)).normalized(); } @@ -1246,8 +1259,10 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } + scale[0] = _post_process_key_value(a, i, scale[0], t->object, t->bone_idx); a->scale_track_interpolate(i, (double)a->get_length(), &scale[1]); t->scale += (scale[1] - scale[0]) * blend; + scale[1] = _post_process_key_value(a, i, scale[1], t->object, t->bone_idx); prev_time = 0; } } else { @@ -1256,7 +1271,9 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } + scale[0] = _post_process_key_value(a, i, scale[0], t->object, t->bone_idx); a->scale_track_interpolate(i, 0, &scale[1]); + scale[1] = _post_process_key_value(a, i, scale[1], t->object, t->bone_idx); t->scale += (scale[1] - scale[0]) * blend; prev_time = (double)a->get_length(); } @@ -1266,8 +1283,10 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } + scale[0] = _post_process_key_value(a, i, scale[0], t->object, t->bone_idx); a->scale_track_interpolate(i, time, &scale[1]); + scale[1] = _post_process_key_value(a, i, scale[1], t->object, t->bone_idx); t->scale += (scale[1] - scale[0]) * blend; prev_time = !backward ? 0 : (double)a->get_length(); @@ -1284,6 +1303,7 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } + scale = _post_process_key_value(a, i, scale, t->object, t->bone_idx); t->scale += (scale - t->init_scale) * blend; } @@ -1306,6 +1326,7 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } + value = _post_process_key_value(a, i, value, t->object, t->shape_index); t->value += (value - t->init_value) * blend; #endif // _3D_DISABLED @@ -1317,6 +1338,7 @@ void AnimationTree::_process_graph(double p_delta) { if (update_mode == Animation::UPDATE_CONTINUOUS || update_mode == Animation::UPDATE_CAPTURE) { Variant value = a->value_track_interpolate(i, time); + value = _post_process_key_value(a, i, value, t->object); if (value == Variant()) { continue; @@ -1344,12 +1366,14 @@ void AnimationTree::_process_graph(double p_delta) { continue; } Variant value = a->track_get_key_value(i, idx); + value = _post_process_key_value(a, i, value, t->object); t->object->set_indexed(t->subpath, value); } else { List<int> indices; a->value_track_get_key_indices(i, time, delta, &indices, pingponged); for (int &F : indices) { Variant value = a->track_get_key_value(i, F); + value = _post_process_key_value(a, i, value, t->object); t->object->set_indexed(t->subpath, value); } } @@ -1388,6 +1412,7 @@ void AnimationTree::_process_graph(double p_delta) { TrackCacheBezier *t = static_cast<TrackCacheBezier *>(track); real_t bezier = a->bezier_track_interpolate(i, time); + bezier = _post_process_key_value(a, i, bezier, t->object); if (t->process_pass != process_pass) { t->process_pass = process_pass; @@ -1663,6 +1688,23 @@ void AnimationTree::_process_graph(double p_delta) { } } +Variant AnimationTree::_post_process_key_value(const Ref<Animation> &p_anim, int p_track, Variant p_value, const Object *p_object, int p_object_idx) { + switch (p_anim->track_get_type(p_track)) { +#ifndef _3D_DISABLED + case Animation::TYPE_POSITION_3D: { + if (p_object_idx >= 0) { + const Skeleton3D *skel = Object::cast_to<Skeleton3D>(p_object); + return Vector3(p_value) * skel->get_motion_scale(); + } + return p_value; + } break; +#endif // _3D_DISABLED + default: { + } break; + } + return p_value; +} + void AnimationTree::advance(real_t p_time) { _process_graph(p_time); } diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h index d82fed9dc2..99851d140e 100644 --- a/scene/animation/animation_tree.h +++ b/scene/animation/animation_tree.h @@ -321,6 +321,8 @@ protected: void _notification(int p_what); static void _bind_methods(); + virtual Variant _post_process_key_value(const Ref<Animation> &p_anim, int p_track, Variant p_value, const Object *p_object, int p_object_idx = -1); + public: void set_tree_root(const Ref<AnimationNode> &p_root); Ref<AnimationNode> get_tree_root() const; |