diff options
Diffstat (limited to 'scene/animation')
-rw-r--r-- | scene/animation/animation_blend_space_1d.cpp | 12 | ||||
-rw-r--r-- | scene/animation/animation_blend_space_1d.h | 18 | ||||
-rw-r--r-- | scene/animation/animation_blend_space_2d.cpp | 20 | ||||
-rw-r--r-- | scene/animation/animation_blend_space_2d.h | 30 | ||||
-rw-r--r-- | scene/animation/animation_blend_tree.cpp | 50 | ||||
-rw-r--r-- | scene/animation/animation_blend_tree.h | 71 | ||||
-rw-r--r-- | scene/animation/animation_cache.cpp | 7 | ||||
-rw-r--r-- | scene/animation/animation_cache.h | 30 | ||||
-rw-r--r-- | scene/animation/animation_node_state_machine.cpp | 38 | ||||
-rw-r--r-- | scene/animation/animation_node_state_machine.h | 38 | ||||
-rw-r--r-- | scene/animation/animation_player.cpp | 75 | ||||
-rw-r--r-- | scene/animation/animation_player.h | 79 | ||||
-rw-r--r-- | scene/animation/animation_tree.cpp | 63 | ||||
-rw-r--r-- | scene/animation/animation_tree.h | 96 | ||||
-rw-r--r-- | scene/animation/root_motion_view.cpp | 12 | ||||
-rw-r--r-- | scene/animation/root_motion_view.h | 16 | ||||
-rw-r--r-- | scene/animation/tween.cpp | 37 | ||||
-rw-r--r-- | scene/animation/tween.h | 45 |
18 files changed, 314 insertions, 423 deletions
diff --git a/scene/animation/animation_blend_space_1d.cpp b/scene/animation/animation_blend_space_1d.cpp index e426e98def..15f562242f 100644 --- a/scene/animation/animation_blend_space_1d.cpp +++ b/scene/animation/animation_blend_space_1d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -311,14 +311,6 @@ AnimationNodeBlendSpace1D::AnimationNodeBlendSpace1D() { for (int i = 0; i < MAX_BLEND_POINTS; i++) { blend_points[i].name = itos(i); } - blend_points_used = 0; - max_space = 1; - min_space = -1; - - snap = 0.1; - value_label = "value"; - - blend_position = "blend_position"; } AnimationNodeBlendSpace1D::~AnimationNodeBlendSpace1D() { diff --git a/scene/animation/animation_blend_space_1d.h b/scene/animation/animation_blend_space_1d.h index 816d3c9d4e..8886e6c679 100644 --- a/scene/animation/animation_blend_space_1d.h +++ b/scene/animation/animation_blend_space_1d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -43,24 +43,24 @@ class AnimationNodeBlendSpace1D : public AnimationRootNode { struct BlendPoint { StringName name; Ref<AnimationRootNode> node; - float position; + float position = 0.0; }; BlendPoint blend_points[MAX_BLEND_POINTS]; - int blend_points_used; + int blend_points_used = 0; - float max_space; - float min_space; + float max_space = 1.0; + float min_space = -1.0; - float snap; + float snap = 0.1; - String value_label; + String value_label = "value"; void _add_blend_point(int p_index, const Ref<AnimationRootNode> &p_node); void _tree_changed(); - StringName blend_position; + StringName blend_position = "blend_position"; protected: virtual void _validate_property(PropertyInfo &property) const override; diff --git a/scene/animation/animation_blend_space_2d.cpp b/scene/animation/animation_blend_space_2d.cpp index 5a42e2af7a..9c4bc107dd 100644 --- a/scene/animation/animation_blend_space_2d.cpp +++ b/scene/animation/animation_blend_space_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -437,7 +437,7 @@ float AnimationNodeBlendSpace2D::process(float p_time, bool p_seek) { Vector2 blend_pos = get_parameter(blend_position); int closest = get_parameter(this->closest); float length_internal = get_parameter(this->length_internal); - float mind = 0; //time of min distance point + float mind = 0.0; //time of min distance point if (blend_mode == BLEND_MODE_INTERPOLATED) { if (triangles.size() == 0) { @@ -529,7 +529,7 @@ float AnimationNodeBlendSpace2D::process(float p_time, bool p_seek) { } if (new_closest != closest && new_closest != -1) { - float from = 0; + float from = 0.0; if (blend_mode == BLEND_MODE_DISCRETE_CARRY && closest != -1) { //see how much animation remains from = blend_node(blend_points[closest].name, blend_points[closest].node, p_time, true, 0.0, FILTER_IGNORE, false) - length_internal; @@ -665,18 +665,6 @@ AnimationNodeBlendSpace2D::AnimationNodeBlendSpace2D() { for (int i = 0; i < MAX_BLEND_POINTS; i++) { blend_points[i].name = itos(i); } - auto_triangles = true; - blend_points_used = 0; - max_space = Vector2(1, 1); - min_space = Vector2(-1, -1); - snap = Vector2(0.1, 0.1); - x_label = "x"; - y_label = "y"; - trianges_dirty = false; - blend_position = "blend_position"; - closest = "closest"; - length_internal = "length_internal"; - blend_mode = BLEND_MODE_INTERPOLATED; } AnimationNodeBlendSpace2D::~AnimationNodeBlendSpace2D() { diff --git a/scene/animation/animation_blend_space_2d.h b/scene/animation/animation_blend_space_2d.h index 2aff678aad..65d09a550d 100644 --- a/scene/animation/animation_blend_space_2d.h +++ b/scene/animation/animation_blend_space_2d.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -55,23 +55,23 @@ protected: }; BlendPoint blend_points[MAX_BLEND_POINTS]; - int blend_points_used; + int blend_points_used = 0; struct BlendTriangle { - int points[3]; + int points[3] = {}; }; Vector<BlendTriangle> triangles; - StringName blend_position; - StringName closest; - StringName length_internal; - Vector2 max_space; - Vector2 min_space; - Vector2 snap; - String x_label; - String y_label; - BlendMode blend_mode; + StringName blend_position = "blend_position"; + StringName closest = "closest"; + StringName length_internal = "length_internal"; + Vector2 max_space = Vector2(1, 1); + Vector2 min_space = Vector2(-1, -1); + Vector2 snap = Vector2(0.1, 0.1); + String x_label = "x"; + String y_label = "y"; + BlendMode blend_mode = BLEND_MODE_INTERPOLATED; void _add_blend_point(int p_index, const Ref<AnimationRootNode> &p_node); void _set_triangles(const Vector<int> &p_triangles); @@ -79,8 +79,8 @@ protected: void _blend_triangle(const Vector2 &p_pos, const Vector2 *p_points, float *r_weights); - bool auto_triangles; - bool trianges_dirty; + bool auto_triangles = true; + bool trianges_dirty = false; void _update_triangles(); void _queue_auto_triangles(); diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp index 56995c0c13..79a1dc1ac0 100644 --- a/scene/animation/animation_blend_tree.cpp +++ b/scene/animation/animation_blend_tree.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -34,7 +34,6 @@ void AnimationNodeAnimation::set_animation(const StringName &p_name) { animation = p_name; - _change_notify("animation"); } StringName AnimationNodeAnimation::get_animation() const { @@ -125,9 +124,6 @@ void AnimationNodeAnimation::_bind_methods() { } AnimationNodeAnimation::AnimationNodeAnimation() { - last_version = 0; - skip = false; - time = "time"; } //////////////////////////////////////////////////////// @@ -346,21 +342,6 @@ void AnimationNodeOneShot::_bind_methods() { AnimationNodeOneShot::AnimationNodeOneShot() { add_input("in"); add_input("shot"); - - fade_in = 0.1; - fade_out = 0.1; - autorestart = false; - autorestart_delay = 1; - autorestart_random_delay = 0; - - mix = MIX_MODE_BLEND; - sync = false; - - active = "active"; - prev_active = "prev_active"; - time = "time"; - remaining = "remaining"; - time_to_restart = "time_to_restart"; } //////////////////////////////////////////////// @@ -405,10 +386,8 @@ void AnimationNodeAdd2::_bind_methods() { } AnimationNodeAdd2::AnimationNodeAdd2() { - add_amount = "add_amount"; add_input("in"); add_input("add"); - sync = false; } //////////////////////////////////////////////// @@ -454,11 +433,9 @@ void AnimationNodeAdd3::_bind_methods() { } AnimationNodeAdd3::AnimationNodeAdd3() { - add_amount = "add_amount"; add_input("-add"); add_input("in"); add_input("+add"); - sync = false; } ///////////////////////////////////////////// @@ -504,10 +481,8 @@ void AnimationNodeBlend2::_bind_methods() { } AnimationNodeBlend2::AnimationNodeBlend2() { - blend_amount = "blend_amount"; add_input("in"); add_input("blend"); - sync = false; } ////////////////////////////////////// @@ -583,7 +558,6 @@ void AnimationNodeTimeScale::_bind_methods() { } AnimationNodeTimeScale::AnimationNodeTimeScale() { - scale = "scale"; add_input("in"); } @@ -608,7 +582,6 @@ float AnimationNodeTimeSeek::process(float p_time, bool p_seek) { } else if (seek_pos >= 0) { float ret = blend_input(0, seek_pos, true, 1.0, FILTER_IGNORE, false); set_parameter(this->seek_pos, -1.0); //reset - _change_notify("seek_pos"); return ret; } else { return blend_input(0, p_time, false, 1.0, FILTER_IGNORE, false); @@ -620,7 +593,6 @@ void AnimationNodeTimeSeek::_bind_methods() { AnimationNodeTimeSeek::AnimationNodeTimeSeek() { add_input("in"); - seek_pos = "seek_position"; } ///////////////////////////////////////////////// @@ -728,7 +700,7 @@ float AnimationNodeTransition::process(float p_time, bool p_seek) { return 0; } - float rem = 0; + float rem = 0.0; if (prev < 0) { // process current animation, check for transition @@ -811,16 +783,7 @@ void AnimationNodeTransition::_bind_methods() { } AnimationNodeTransition::AnimationNodeTransition() { - prev_xfading = "prev_xfading"; - prev = "prev"; - time = "time"; - current = "current"; - prev_current = "prev_current"; - xfade = 0.0; - - enabled_inputs = 0; for (int i = 0; i < MAX_INPUTS; i++) { - inputs[i].auto_advance = false; inputs[i].name = "state " + itos(i); } } @@ -1158,6 +1121,13 @@ void AnimationNodeBlendTree::_get_property_list(List<PropertyInfo> *p_list) cons p_list->push_back(PropertyInfo(Variant::ARRAY, "node_connections", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); } +void AnimationNodeBlendTree::reset_state() { + graph_offset = Vector2(); + nodes.clear(); + emit_changed(); + emit_signal("tree_changed"); +} + void AnimationNodeBlendTree::_tree_changed() { emit_signal("tree_changed"); } diff --git a/scene/animation/animation_blend_tree.h b/scene/animation/animation_blend_tree.h index 7241a6bc13..d82658c8c2 100644 --- a/scene/animation/animation_blend_tree.h +++ b/scene/animation/animation_blend_tree.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -37,10 +37,10 @@ class AnimationNodeAnimation : public AnimationRootNode { GDCLASS(AnimationNodeAnimation, AnimationRootNode); StringName animation; - StringName time; + StringName time = "time"; - uint64_t last_version; - bool skip; + uint64_t last_version = 0; + bool skip = false; protected: void _validate_property(PropertyInfo &property) const override; @@ -71,26 +71,26 @@ public: }; private: - float fade_in; - float fade_out; + float fade_in = 0.1; + float fade_out = 0.1; - bool autorestart; - float autorestart_delay; - float autorestart_random_delay; - MixMode mix; + bool autorestart = false; + float autorestart_delay = 1.0; + float autorestart_random_delay = 0.0; + MixMode mix = MIX_MODE_BLEND; - bool sync; + bool sync = false; /* bool active; bool do_start; float time; float remaining;*/ - StringName active; - StringName prev_active; - StringName time; - StringName remaining; - StringName time_to_restart; + StringName active = "active"; + StringName prev_active = "prev_active"; + StringName time = "time"; + StringName remaining = "remaining"; + StringName time_to_restart = "time_to_restart"; protected: static void _bind_methods(); @@ -132,8 +132,8 @@ VARIANT_ENUM_CAST(AnimationNodeOneShot::MixMode) class AnimationNodeAdd2 : public AnimationNode { GDCLASS(AnimationNodeAdd2, AnimationNode); - StringName add_amount; - bool sync; + StringName add_amount = "add_amount"; + bool sync = false; protected: static void _bind_methods(); @@ -156,8 +156,8 @@ public: class AnimationNodeAdd3 : public AnimationNode { GDCLASS(AnimationNodeAdd3, AnimationNode); - StringName add_amount; - bool sync; + StringName add_amount = "add_amount"; + bool sync = false; protected: static void _bind_methods(); @@ -180,8 +180,8 @@ public: class AnimationNodeBlend2 : public AnimationNode { GDCLASS(AnimationNodeBlend2, AnimationNode); - StringName blend_amount; - bool sync; + StringName blend_amount = "blend_amount"; + bool sync = false; protected: static void _bind_methods(); @@ -225,7 +225,7 @@ public: class AnimationNodeTimeScale : public AnimationNode { GDCLASS(AnimationNodeTimeScale, AnimationNode); - StringName scale; + StringName scale = "scale"; protected: static void _bind_methods(); @@ -244,7 +244,7 @@ public: class AnimationNodeTimeSeek : public AnimationNode { GDCLASS(AnimationNodeTimeSeek, AnimationNode); - StringName seek_pos; + StringName seek_pos = "seek_position"; protected: static void _bind_methods(); @@ -268,12 +268,11 @@ class AnimationNodeTransition : public AnimationNode { }; struct InputData { String name; - bool auto_advance; - InputData() { auto_advance = false; } + bool auto_advance = false; }; InputData inputs[MAX_INPUTS]; - int enabled_inputs; + int enabled_inputs = 0; /* float prev_xfading; @@ -282,13 +281,13 @@ class AnimationNodeTransition : public AnimationNode { int current; int prev_current; */ - StringName prev_xfading; - StringName prev; - StringName time; - StringName current; - StringName prev_current; + StringName prev_xfading = "prev_xfading"; + StringName prev = "prev"; + StringName time = "time"; + StringName current = "current"; + StringName prev_current = "prev_current"; - float xfade; + float xfade = 0.0; void _update_inputs(); @@ -352,6 +351,8 @@ protected: bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List<PropertyInfo> *p_list) const; + virtual void reset_state() override; + public: enum ConnectionError { CONNECTION_OK, @@ -381,7 +382,7 @@ public: struct NodeConnection { StringName input_node; - int input_index; + int input_index = 0; StringName output_node; }; diff --git a/scene/animation/animation_cache.cpp b/scene/animation/animation_cache.cpp index abb2cf1b65..689acdd57b 100644 --- a/scene/animation/animation_cache.cpp +++ b/scene/animation/animation_cache.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -308,7 +308,4 @@ void AnimationCache::set_root(Node *p_root) { } AnimationCache::AnimationCache() { - root = nullptr; - cache_dirty = true; - cache_valid = false; } diff --git a/scene/animation/animation_cache.h b/scene/animation/animation_cache.h index feff1d364a..07c9d09ae0 100644 --- a/scene/animation/animation_cache.h +++ b/scene/animation/animation_cache.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -39,31 +39,23 @@ class AnimationCache : public Object { struct Path { RES resource; - Object *object; - Skeleton3D *skeleton; // haxor - Node *node; - Node3D *spatial; + Object *object = nullptr; + Skeleton3D *skeleton = nullptr; // haxor + Node *node = nullptr; + Node3D *spatial = nullptr; - int bone_idx; + int bone_idx = -1; Vector<StringName> subpath; - bool valid; - Path() { - object = nullptr; - skeleton = nullptr; - node = nullptr; - bone_idx = -1; - valid = false; - spatial = nullptr; - } + bool valid = false; }; Set<Node *> connected_nodes; Vector<Path> path_cache; - Node *root; + Node *root = nullptr; Ref<Animation> animation; - bool cache_dirty; - bool cache_valid; + bool cache_dirty = true; + bool cache_valid = false; void _node_exit_tree(Node *p_node); diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp index 36552c966d..d46f24752e 100644 --- a/scene/animation/animation_node_state_machine.cpp +++ b/scene/animation/animation_node_state_machine.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -130,11 +130,6 @@ void AnimationNodeStateMachineTransition::_bind_methods() { } AnimationNodeStateMachineTransition::AnimationNodeStateMachineTransition() { - switch_mode = SWITCH_MODE_IMMEDIATE; - auto_advance = false; - xfade = 0; - disabled = false; - priority = 1; } //////////////////////////////////////////////////////// @@ -322,7 +317,7 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_st // stopped, invalid state String node_name = start_request; start_request = StringName(); //clear start request - ERR_FAIL_V_MSG(0, "Can't travel to '" + node_name + "' if state machine is not playing."); + ERR_FAIL_V_MSG(0, "Can't travel to '" + node_name + "' if state machine is not playing. Maybe you need to enable Autoplay on Load for one of the nodes in your state machine or call .start() first?"); } } else { if (!_travel(p_state_machine, start_request)) { @@ -398,7 +393,7 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_st //find next StringName next; - float next_xfade = 0; + float next_xfade = 0.0; AnimationNodeStateMachineTransition::SwitchMode switch_mode = AnimationNodeStateMachineTransition::SWITCH_MODE_IMMEDIATE; if (path.size()) { @@ -495,21 +490,13 @@ void AnimationNodeStateMachinePlayback::_bind_methods() { ClassDB::bind_method(D_METHOD("stop"), &AnimationNodeStateMachinePlayback::stop); ClassDB::bind_method(D_METHOD("is_playing"), &AnimationNodeStateMachinePlayback::is_playing); ClassDB::bind_method(D_METHOD("get_current_node"), &AnimationNodeStateMachinePlayback::get_current_node); + ClassDB::bind_method(D_METHOD("get_current_play_position"), &AnimationNodeStateMachinePlayback::get_current_play_pos); + ClassDB::bind_method(D_METHOD("get_current_length"), &AnimationNodeStateMachinePlayback::get_current_length); ClassDB::bind_method(D_METHOD("get_travel_path"), &AnimationNodeStateMachinePlayback::get_travel_path); } AnimationNodeStateMachinePlayback::AnimationNodeStateMachinePlayback() { set_local_to_scene(true); //only one per instanced scene - - playing = false; - len_current = 0; - fading_time = 0; - stop_request = false; - len_total = 0.0; - pos_current = 0.0; - loops_current = 0; - fading_pos = 0.0; - start_request_travel = false; } /////////////////////////////////////////////////////// @@ -927,6 +914,18 @@ void AnimationNodeStateMachine::_get_property_list(List<PropertyInfo> *p_list) c p_list->push_back(PropertyInfo(Variant::VECTOR2, "graph_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); } +void AnimationNodeStateMachine::reset_state() { + states.clear(); + transitions.clear(); + playback = "playback"; + start_node = StringName(); + end_node = StringName(); + graph_offset = Vector2(); + + emit_changed(); + emit_signal("tree_changed"); +} + void AnimationNodeStateMachine::set_node_position(const StringName &p_name, const Vector2 &p_position) { ERR_FAIL_COND(!states.has(p_name)); states[p_name].position = p_position; @@ -973,5 +972,4 @@ void AnimationNodeStateMachine::_bind_methods() { } AnimationNodeStateMachine::AnimationNodeStateMachine() { - playback = "playback"; } diff --git a/scene/animation/animation_node_state_machine.h b/scene/animation/animation_node_state_machine.h index ae8975e940..9c1bca63c3 100644 --- a/scene/animation/animation_node_state_machine.h +++ b/scene/animation/animation_node_state_machine.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -44,13 +44,13 @@ public: }; private: - SwitchMode switch_mode; - bool auto_advance; + SwitchMode switch_mode = SWITCH_MODE_IMMEDIATE; + bool auto_advance = false; StringName advance_condition; StringName advance_condition_name; - float xfade; - bool disabled; - int priority; + float xfade = 0.0; + bool disabled = false; + int priority = 1; protected: static void _bind_methods(); @@ -89,28 +89,28 @@ class AnimationNodeStateMachinePlayback : public Resource { friend class AnimationNodeStateMachine; struct AStarCost { - float distance; + float distance = 0.0; StringName prev; }; - float len_total; + float len_total = 0.0; - float len_current; - float pos_current; - int loops_current; + float len_current = 0.0; + float pos_current = 0.0; + int loops_current = 0; StringName current; StringName fading_from; - float fading_time; - float fading_pos; + float fading_time = 0.0; + float fading_pos = 0.0; Vector<StringName> path; - bool playing; + bool playing = false; StringName start_request; - bool start_request_travel; - bool stop_request; + bool start_request_travel = false; + bool stop_request = false; bool _travel(AnimationNodeStateMachine *p_state_machine, const StringName &p_travel); @@ -154,7 +154,7 @@ private: Vector<Transition> transitions; - StringName playback; + StringName playback = "playback"; StringName start_node; StringName end_node; @@ -171,6 +171,8 @@ protected: bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List<PropertyInfo> *p_list) const; + virtual void reset_state() override; + public: virtual void get_parameter_list(List<PropertyInfo> *r_list) const override; virtual Variant get_parameter_default_value(const StringName &p_parameter) const override; diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index 159ccae130..0c1798a876 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -206,7 +206,7 @@ void AnimationPlayer::_notification(int p_what) { } } break; case NOTIFICATION_INTERNAL_PROCESS: { - if (animation_process_mode == ANIMATION_PROCESS_PHYSICS) { + if (process_callback == ANIMATION_PROCESS_PHYSICS) { break; } @@ -215,7 +215,7 @@ void AnimationPlayer::_notification(int p_what) { } } break; case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { - if (animation_process_mode == ANIMATION_PROCESS_IDLE) { + if (process_callback == ANIMATION_PROCESS_IDLE) { break; } @@ -229,13 +229,13 @@ void AnimationPlayer::_notification(int p_what) { } } -void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim) { +void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim, Node *p_root_override) { // Already cached? if (p_anim->node_cache.size() == p_anim->animation->get_track_count()) { return; } - Node *parent = get_node(root); + Node *parent = p_root_override ? p_root_override : get_node(root); ERR_FAIL_COND(!parent); @@ -605,7 +605,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float } if (p_seeked) { - //find whathever should be playing + //find whatever should be playing int idx = a->track_find_key(i, p_time); if (idx < 0) { continue; @@ -634,7 +634,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float nc->audio_playing = true; playing_caches.insert(nc); - if (len && end_ofs > 0) { //force a end at a time + if (len && end_ofs > 0) { //force an end at a time nc->audio_len = len - start_ofs - end_ofs; } else { nc->audio_len = 0; @@ -665,7 +665,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float nc->audio_playing = true; playing_caches.insert(nc); - if (len && end_ofs > 0) { //force a end at a time + if (len && end_ofs > 0) { //force an end at a time nc->audio_len = len - start_ofs - end_ofs; } else { nc->audio_len = 0; @@ -782,13 +782,13 @@ void AnimationPlayer::_animation_process_data(PlaybackData &cd, float p_delta, f delta = next_pos - cd.pos; // Fix delta (after determination of backwards because negative zero is lost here) if (&cd == &playback.current) { - if (!backwards && cd.pos <= len && next_pos == len /*&& playback.blend.empty()*/) { + 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 } - if (backwards && cd.pos >= 0 && next_pos == 0 /*&& playback.blend.empty()*/) { + 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 @@ -969,7 +969,7 @@ Error AnimationPlayer::add_animation(const StringName &p_name, const Ref<Animati } _ref_anim(p_animation); - _change_notify(); + notify_property_list_changed(); return OK; } @@ -981,7 +981,7 @@ void AnimationPlayer::remove_animation(const StringName &p_name) { animation_set.erase(p_name); clear_caches(); - _change_notify(); + notify_property_list_changed(); } void AnimationPlayer::_ref_anim(const Ref<Animation> &p_anim) { @@ -1039,7 +1039,7 @@ void AnimationPlayer::rename_animation(const StringName &p_name, const StringNam } clear_caches(); - _change_notify(); + notify_property_list_changed(); } bool AnimationPlayer::has_animation(const StringName &p_name) const { @@ -1132,7 +1132,7 @@ void AnimationPlayer::play(const StringName &p_name, float p_custom_blend, float Playback &c = playback; if (c.current.from) { - float blend_time = 0; + float blend_time = 0.0; // find if it can blend BlendKey bk; bk.from = c.current.from->name; @@ -1343,7 +1343,7 @@ void AnimationPlayer::_stop_playing_caches() { } void AnimationPlayer::_node_removed(Node *p_node) { - clear_caches(); // nodes contained here ar being removed, clear the caches + clear_caches(); // nodes contained here are being removed, clear the caches } void AnimationPlayer::clear_caches() { @@ -1403,8 +1403,8 @@ bool AnimationPlayer::is_reset_on_save_enabled() const { return reset_on_save; } -void AnimationPlayer::set_animation_process_mode(AnimationProcessMode p_mode) { - if (animation_process_mode == p_mode) { +void AnimationPlayer::set_process_callback(AnimationProcessCallback p_mode) { + if (process_callback == p_mode) { return; } @@ -1412,14 +1412,14 @@ void AnimationPlayer::set_animation_process_mode(AnimationProcessMode p_mode) { if (pr) { _set_process(false); } - animation_process_mode = p_mode; + process_callback = p_mode; if (pr) { _set_process(true); } } -AnimationPlayer::AnimationProcessMode AnimationPlayer::get_animation_process_mode() const { - return animation_process_mode; +AnimationPlayer::AnimationProcessCallback AnimationPlayer::get_process_callback() const { + return process_callback; } void AnimationPlayer::set_method_call_mode(AnimationMethodCallMode p_mode) { @@ -1435,7 +1435,7 @@ void AnimationPlayer::_set_process(bool p_process, bool p_force) { return; } - switch (animation_process_mode) { + switch (process_callback) { case ANIMATION_PROCESS_PHYSICS: set_physics_process_internal(p_process && active); break; @@ -1497,13 +1497,13 @@ void AnimationPlayer::get_argument_options(const StringName &p_function, int p_i } #ifdef TOOLS_ENABLED -Ref<AnimatedValuesBackup> AnimationPlayer::backup_animated_values() { +Ref<AnimatedValuesBackup> AnimationPlayer::backup_animated_values(Node *p_root_override) { Ref<AnimatedValuesBackup> backup; if (!playback.current.from) { return backup; } - _ensure_node_caches(playback.current.from); + _ensure_node_caches(playback.current.from, p_root_override); backup.instance(); for (int i = 0; i < playback.current.from->node_cache.size(); i++) { @@ -1560,10 +1560,11 @@ Ref<AnimatedValuesBackup> AnimationPlayer::apply_reset(bool p_user_initiated) { AnimationPlayer *aux_player = memnew(AnimationPlayer); EditorNode::get_singleton()->add_child(aux_player); - aux_player->set_root(aux_player->get_path_to(root_node)); aux_player->add_animation("RESET", reset_anim); aux_player->set_assigned_animation("RESET"); - Ref<AnimatedValuesBackup> old_values = aux_player->backup_animated_values(); + // Forcing the use of the original root because the scene where original player belongs may be not the active one + Node *root = get_node(get_root()); + Ref<AnimatedValuesBackup> old_values = aux_player->backup_animated_values(root); aux_player->seek(0.0f, true); aux_player->queue_delete(); @@ -1636,8 +1637,8 @@ void AnimationPlayer::_bind_methods() { ClassDB::bind_method(D_METHOD("clear_caches"), &AnimationPlayer::clear_caches); - ClassDB::bind_method(D_METHOD("set_animation_process_mode", "mode"), &AnimationPlayer::set_animation_process_mode); - ClassDB::bind_method(D_METHOD("get_animation_process_mode"), &AnimationPlayer::get_animation_process_mode); + ClassDB::bind_method(D_METHOD("set_process_callback", "mode"), &AnimationPlayer::set_process_callback); + ClassDB::bind_method(D_METHOD("get_process_callback"), &AnimationPlayer::get_process_callback); 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); @@ -1657,7 +1658,7 @@ void AnimationPlayer::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "current_animation_position", PROPERTY_HINT_NONE, "", 0), "", "get_current_animation_position"); ADD_GROUP("Playback Options", "playback_"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "playback_process_mode", PROPERTY_HINT_ENUM, "Physics,Idle,Manual"), "set_animation_process_mode", "get_animation_process_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "playback_process_mode", PROPERTY_HINT_ENUM, "Physics,Idle,Manual"), "set_process_callback", "get_process_callback"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "playback_default_blend_time", PROPERTY_HINT_RANGE, "0,4096,0.01"), "set_default_blend_time", "get_default_blend_time"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playback_active", PROPERTY_HINT_NONE, "", 0), "set_active", "is_active"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "playback_speed", PROPERTY_HINT_RANGE, "-64,64,0.01"), "set_speed_scale", "get_speed_scale"); @@ -1677,23 +1678,7 @@ void AnimationPlayer::_bind_methods() { } AnimationPlayer::AnimationPlayer() { - accum_pass = 1; - cache_update_size = 0; - cache_update_prop_size = 0; - cache_update_bezier_size = 0; - speed_scale = 1; - end_reached = false; - end_notify = false; - reset_on_save = true; - animation_process_mode = ANIMATION_PROCESS_IDLE; - method_call_mode = ANIMATION_METHOD_CALL_DEFERRED; - processing = false; - default_blend_time = 0; root = SceneStringNames::get_singleton()->path_pp; - playing = false; - active = true; - playback.seeked = false; - playback.started = false; } AnimationPlayer::~AnimationPlayer() { diff --git a/scene/animation/animation_player.h b/scene/animation/animation_player.h index 7f0d5630e1..2a1821c215 100644 --- a/scene/animation/animation_player.h +++ b/scene/animation/animation_player.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -41,9 +41,9 @@ class AnimatedValuesBackup : public Reference { GDCLASS(AnimatedValuesBackup, Reference); struct Entry { - Object *object; + Object *object = nullptr; Vector<StringName> subpath; // Unused if bone - int bone_idx; // -1 if not a bone + int bone_idx = -1; // -1 if not a bone Variant value; }; Vector<Entry> entries; @@ -64,7 +64,7 @@ class AnimationPlayer : public Node { OBJ_CATEGORY("Animation Nodes"); public: - enum AnimationProcessMode { + enum AnimationProcessCallback { ANIMATION_PROCESS_PHYSICS, ANIMATION_PROCESS_IDLE, ANIMATION_PROCESS_MANUAL, @@ -118,8 +118,6 @@ private: Variant value_accum; uint64_t accum_pass = 0; Variant capture; - - PropertyAnim() {} }; Map<StringName, PropertyAnim> property_anim; @@ -130,8 +128,6 @@ private: float bezier_accum = 0.0; Object *object = nullptr; uint64_t accum_pass = 0; - - BezierAnim() {} }; Map<StringName, BezierAnim> bezier_anim; @@ -141,7 +137,7 @@ private: struct TrackNodeCacheKey { ObjectID id; - int bone_idx; + int bone_idx = -1; inline bool operator<(const TrackNodeCacheKey &p_right) const { if (id == p_right.id) { @@ -155,16 +151,16 @@ private: Map<TrackNodeCacheKey, TrackNodeCache> node_cache_map; TrackNodeCache *cache_update[NODE_CACHE_UPDATE_MAX]; - int cache_update_size; + int cache_update_size = 0; TrackNodeCache::PropertyAnim *cache_update_prop[NODE_CACHE_UPDATE_MAX]; - int cache_update_prop_size; + int cache_update_prop_size = 0; TrackNodeCache::BezierAnim *cache_update_bezier[NODE_CACHE_UPDATE_MAX]; - int cache_update_bezier_size; + int cache_update_bezier_size = 0; Set<TrackNodeCache *> playing_caches; - uint64_t accum_pass; - float speed_scale; - float default_blend_time; + uint64_t accum_pass = 1; + float speed_scale = 1.0; + float default_blend_time = 0.0; struct AnimationData { String name; @@ -183,54 +179,43 @@ private: Map<BlendKey, float> blend_times; struct PlaybackData { - AnimationData *from; - float pos; - float speed_scale; - - PlaybackData() { - pos = 0; - speed_scale = 1.0; - from = nullptr; - } + AnimationData *from = nullptr; + float pos = 0.0; + float speed_scale = 1.0; }; struct Blend { PlaybackData data; - float blend_time; - float blend_left; - - Blend() { - blend_left = 0; - blend_time = 0; - } + float blend_time = 0.0; + float blend_left = 0.0; }; struct Playback { List<Blend> blend; PlaybackData current; StringName assigned; - bool seeked; - bool started; + bool seeked = false; + bool started = false; } playback; List<StringName> queued; - bool end_reached; - bool end_notify; + bool end_reached = false; + bool end_notify = false; String autoplay; - bool reset_on_save; - AnimationProcessMode animation_process_mode; - AnimationMethodCallMode method_call_mode; - bool processing; - bool active; + bool reset_on_save = true; + AnimationProcessCallback process_callback = ANIMATION_PROCESS_IDLE; + AnimationMethodCallMode method_call_mode = ANIMATION_METHOD_CALL_DEFERRED; + bool processing = false; + bool active = true; NodePath root; void _animation_process_animation(AnimationData *p_anim, float p_time, float 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); + void _ensure_node_caches(AnimationData *p_anim, Node *p_root_override = nullptr); void _animation_process_data(PlaybackData &cd, float p_delta, float p_blend, bool p_seeked, bool p_started); void _animation_process2(float p_delta, bool p_started); void _animation_update_transforms(); @@ -257,7 +242,7 @@ private: void _set_process(bool p_process, bool p_force = false); - bool playing; + bool playing = false; protected: bool _set(const StringName &p_name, const Variant &p_value); @@ -313,8 +298,8 @@ public: void set_reset_on_save_enabled(bool p_enabled); bool is_reset_on_save_enabled() const; - void set_animation_process_mode(AnimationProcessMode p_mode); - AnimationProcessMode get_animation_process_mode() const; + void set_process_callback(AnimationProcessCallback p_mode); + AnimationProcessCallback get_process_callback() const; void set_method_call_mode(AnimationMethodCallMode p_mode); AnimationMethodCallMode get_method_call_mode() const; @@ -334,7 +319,7 @@ public: void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const override; #ifdef TOOLS_ENABLED - Ref<AnimatedValuesBackup> backup_animated_values(); + Ref<AnimatedValuesBackup> backup_animated_values(Node *p_root_override = nullptr); Ref<AnimatedValuesBackup> apply_reset(bool p_user_initiated = false); bool can_apply_reset() const; #endif @@ -343,7 +328,7 @@ public: ~AnimationPlayer(); }; -VARIANT_ENUM_CAST(AnimationPlayer::AnimationProcessMode); +VARIANT_ENUM_CAST(AnimationPlayer::AnimationProcessCallback); VARIANT_ENUM_CAST(AnimationPlayer::AnimationMethodCallMode); #endif diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp index 2ef3ba87b2..4b4d3943c9 100644 --- a/scene/animation/animation_tree.cpp +++ b/scene/animation/animation_tree.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -40,7 +40,7 @@ void AnimationNode::get_parameter_list(List<PropertyInfo> *r_list) const { Array parameters = get_script_instance()->call("get_parameter_list"); for (int i = 0; i < parameters.size(); i++) { Dictionary d = parameters[i]; - ERR_CONTINUE(d.empty()); + ERR_CONTINUE(d.is_empty()); r_list->push_back(PropertyInfo::from_dict(d)); } } @@ -158,7 +158,7 @@ float AnimationNode::blend_input(int p_input, float p_time, bool p_seek, float p Ref<AnimationNode> node = blend_tree->get_node(node_name); //inputs.write[p_input].last_pass = state->last_pass; - float activity = 0; + float activity = 0.0; float ret = _blend_node(node_name, blend_tree->get_node_connection_array(node_name), nullptr, node, p_time, p_seek, p_blend, p_filter, p_optimize, &activity); Vector<AnimationTree::Activity> *activity_ptr = state->tree->input_activity_map.getptr(base_path); @@ -441,9 +441,6 @@ void AnimationNode::_bind_methods() { } AnimationNode::AnimationNode() { - state = nullptr; - parent = nullptr; - filter_enabled = false; } //////////////////// @@ -476,7 +473,7 @@ void AnimationTree::set_active(bool p_active) { active = p_active; started = active; - if (process_mode == ANIMATION_PROCESS_IDLE) { + if (process_callback == ANIMATION_PROCESS_IDLE) { set_process_internal(active); } else { set_physics_process_internal(active); @@ -497,8 +494,8 @@ bool AnimationTree::is_active() const { return active; } -void AnimationTree::set_process_mode(AnimationProcessMode p_mode) { - if (process_mode == p_mode) { +void AnimationTree::set_process_callback(AnimationProcessCallback p_mode) { + if (process_callback == p_mode) { return; } @@ -507,15 +504,15 @@ void AnimationTree::set_process_mode(AnimationProcessMode p_mode) { set_active(false); } - process_mode = p_mode; + process_callback = p_mode; if (was_active) { set_active(true); } } -AnimationTree::AnimationProcessMode AnimationTree::get_process_mode() const { - return process_mode; +AnimationTree::AnimationProcessCallback AnimationTree::get_process_callback() const { + return process_callback; } void AnimationTree::_node_removed(Node *p_node) { @@ -820,6 +817,7 @@ void AnimationTree::_process_graph(float p_delta) { Ref<Animation> a = as.animation; float time = as.time; float delta = as.delta; + float weight = as.blend; bool seeked = as.seeked; for (int i = 0; i < a->get_track_count(); i++) { @@ -839,7 +837,7 @@ void AnimationTree::_process_graph(float p_delta) { ERR_CONTINUE(blend_idx < 0 || blend_idx >= state.track_count); - float blend = (*as.track_blends)[blend_idx]; + float blend = (*as.track_blends)[blend_idx] * weight; if (blend < CMP_EPSILON) { continue; //nothing to blend @@ -1011,7 +1009,7 @@ void AnimationTree::_process_graph(float p_delta) { TrackCacheAudio *t = static_cast<TrackCacheAudio *>(track); if (seeked) { - //find whathever should be playing + //find whatever should be playing int idx = a->track_find_key(i, time); if (idx < 0) { continue; @@ -1040,7 +1038,7 @@ void AnimationTree::_process_graph(float p_delta) { t->playing = true; playing_caches.insert(t); - if (len && end_ofs > 0) { //force a end at a time + if (len && end_ofs > 0) { //force an end at a time t->len = len - start_ofs - end_ofs; } else { t->len = 0; @@ -1071,7 +1069,7 @@ void AnimationTree::_process_graph(float p_delta) { t->playing = true; playing_caches.insert(t); - if (len && end_ofs > 0) { //force a end at a time + if (len && end_ofs > 0) { //force an end at a time t->len = len - start_ofs - end_ofs; } else { t->len = 0; @@ -1236,11 +1234,11 @@ void AnimationTree::advance(float p_time) { } void AnimationTree::_notification(int p_what) { - if (active && p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS && process_mode == ANIMATION_PROCESS_PHYSICS) { + if (active && p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS && process_callback == ANIMATION_PROCESS_PHYSICS) { _process_graph(get_physics_process_delta_time()); } - if (active && p_what == NOTIFICATION_INTERNAL_PROCESS && process_mode == ANIMATION_PROCESS_IDLE) { + if (active && p_what == NOTIFICATION_INTERNAL_PROCESS && process_callback == ANIMATION_PROCESS_IDLE) { _process_graph(get_process_delta_time()); } @@ -1287,14 +1285,14 @@ String AnimationTree::get_configuration_warning() const { String warning = Node::get_configuration_warning(); if (!root.is_valid()) { - if (!warning.empty()) { + if (!warning.is_empty()) { warning += "\n\n"; } warning += TTR("No root AnimationNode for the graph is set."); } if (!has_node(animation_player)) { - if (!warning.empty()) { + if (!warning.is_empty()) { warning += "\n\n"; } warning += TTR("Path to an AnimationPlayer node containing animations is not set."); @@ -1302,12 +1300,12 @@ String AnimationTree::get_configuration_warning() const { AnimationPlayer *player = Object::cast_to<AnimationPlayer>(get_node(animation_player)); if (!player) { - if (!warning.empty()) { + if (!warning.is_empty()) { warning += "\n\n"; } warning += TTR("Path set for AnimationPlayer does not lead to an AnimationPlayer node."); } else if (!player->has_node(player->get_root())) { - if (!warning.empty()) { + if (!warning.is_empty()) { warning += "\n\n"; } warning += TTR("The AnimationPlayer root node is not a valid node."); @@ -1339,6 +1337,7 @@ void AnimationTree::_tree_changed() { } void AnimationTree::_update_properties_for_node(const String &p_base_path, Ref<AnimationNode> node) { + ERR_FAIL_COND(node.is_null()); if (!property_parent_map.has(p_base_path)) { property_parent_map[p_base_path] = HashMap<StringName, StringName>(); } @@ -1396,7 +1395,7 @@ void AnimationTree::_update_properties() { properties_dirty = false; - _change_notify(); + notify_property_list_changed(); } bool AnimationTree::_set(const StringName &p_name, const Variant &p_value) { @@ -1406,9 +1405,6 @@ bool AnimationTree::_set(const StringName &p_name, const Variant &p_value) { if (property_map.has(p_name)) { property_map[p_name] = p_value; -#ifdef TOOLS_ENABLED - _change_notify(p_name.operator String().utf8().get_data()); -#endif return true; } @@ -1476,8 +1472,8 @@ void AnimationTree::_bind_methods() { ClassDB::bind_method(D_METHOD("set_tree_root", "root"), &AnimationTree::set_tree_root); ClassDB::bind_method(D_METHOD("get_tree_root"), &AnimationTree::get_tree_root); - ClassDB::bind_method(D_METHOD("set_process_mode", "mode"), &AnimationTree::set_process_mode); - ClassDB::bind_method(D_METHOD("get_process_mode"), &AnimationTree::get_process_mode); + ClassDB::bind_method(D_METHOD("set_process_callback", "mode"), &AnimationTree::set_process_callback); + ClassDB::bind_method(D_METHOD("get_process_callback"), &AnimationTree::get_process_callback); ClassDB::bind_method(D_METHOD("set_animation_player", "root"), &AnimationTree::set_animation_player); ClassDB::bind_method(D_METHOD("get_animation_player"), &AnimationTree::get_animation_player); @@ -1496,7 +1492,7 @@ void AnimationTree::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "tree_root", PROPERTY_HINT_RESOURCE_TYPE, "AnimationRootNode"), "set_tree_root", "get_tree_root"); ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "anim_player", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "AnimationPlayer"), "set_animation_player", "get_animation_player"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "active"), "set_active", "is_active"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Physics,Idle,Manual"), "set_process_mode", "get_process_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "process_callback", PROPERTY_HINT_ENUM, "Physics,Idle,Manual"), "set_process_callback", "get_process_callback"); ADD_GROUP("Root Motion", "root_motion_"); ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "root_motion_track"), "set_root_motion_track", "get_root_motion_track"); @@ -1506,13 +1502,6 @@ void AnimationTree::_bind_methods() { } AnimationTree::AnimationTree() { - process_mode = ANIMATION_PROCESS_IDLE; - active = false; - cache_valid = false; - setup_pass = 1; - process_pass = 1; - started = true; - properties_dirty = true; } AnimationTree::~AnimationTree() { diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h index 166ca04f40..1c5aec26ab 100644 --- a/scene/animation/animation_tree.h +++ b/scene/animation/animation_tree.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -63,26 +63,26 @@ public: struct AnimationState { Ref<Animation> animation; - float time; - float delta; - const Vector<float> *track_blends; - float blend; - bool seeked; + float time = 0.0; + float delta = 0.0; + const Vector<float> *track_blends = nullptr; + float blend = 0.0; + bool seeked = false; }; struct State { - int track_count; + int track_count = 0; HashMap<NodePath, int> track_map; List<AnimationState> animation_states; - bool valid; - AnimationPlayer *player; - AnimationTree *tree; + bool valid = false; + AnimationPlayer *player = nullptr; + AnimationTree *tree = nullptr; String invalid_reasons; - uint64_t last_pass; + uint64_t last_pass = 0; }; Vector<float> blends; - State *state; + State *state = nullptr; float _pre_process(const StringName &p_base_path, AnimationNode *p_parent, State *p_state, float p_time, bool p_seek, const Vector<StringName> &p_connections); void _pre_update_animations(HashMap<NodePath, int> *track_map); @@ -90,10 +90,10 @@ public: //all this is temporary StringName base_path; Vector<StringName> connections; - AnimationNode *parent; + AnimationNode *parent = nullptr; HashMap<NodePath, bool> filter; - bool filter_enabled; + bool filter_enabled = false; Array _get_filters() const; void _set_filters(const Array &p_filters); @@ -163,7 +163,7 @@ class AnimationTree : public Node { GDCLASS(AnimationTree, Node); public: - enum AnimationProcessMode { + enum AnimationProcessCallback { ANIMATION_PROCESS_PHYSICS, ANIMATION_PROCESS_IDLE, ANIMATION_PROCESS_MANUAL, @@ -171,36 +171,29 @@ public: private: struct TrackCache { - bool root_motion; - uint64_t setup_pass; - uint64_t process_pass; - Animation::TrackType type; - Object *object; + bool root_motion = false; + uint64_t setup_pass = 0; + uint64_t process_pass = 0; + Animation::TrackType type = Animation::TrackType::TYPE_ANIMATION; + Object *object = nullptr; ObjectID object_id; TrackCache() { - root_motion = false; - setup_pass = 0; - process_pass = 0; - object = nullptr; } virtual ~TrackCache() {} }; struct TrackCacheTransform : public TrackCache { - Node3D *spatial; - Skeleton3D *skeleton; - int bone_idx; + Node3D *spatial = nullptr; + Skeleton3D *skeleton = nullptr; + int bone_idx = -1; Vector3 loc; Quat rot; - float rot_blend_accum; + float rot_blend_accum = 0.0; Vector3 scale; TrackCacheTransform() { type = Animation::TYPE_TRANSFORM; - spatial = nullptr; - bone_idx = -1; - skeleton = nullptr; } }; @@ -215,33 +208,28 @@ private: }; struct TrackCacheBezier : public TrackCache { - float value; + float value = 0.0; Vector<StringName> subpath; TrackCacheBezier() { type = Animation::TYPE_BEZIER; - value = 0; } }; struct TrackCacheAudio : public TrackCache { - bool playing; - float start; - float len; + bool playing = false; + float start = 0.0; + float len = 0.0; TrackCacheAudio() { type = Animation::TYPE_AUDIO; - playing = false; - start = 0; - len = 0; } }; struct TrackCacheAnimation : public TrackCache { - bool playing; + bool playing = false; TrackCacheAnimation() { type = Animation::TYPE_ANIMATION; - playing = false; } }; @@ -250,12 +238,12 @@ private: Ref<AnimationNode> root; - AnimationProcessMode process_mode; - bool active; + AnimationProcessCallback process_callback = ANIMATION_PROCESS_IDLE; + bool active = false; NodePath animation_player; AnimationNode::State state; - bool cache_valid; + bool cache_valid = false; void _node_removed(Node *p_node); void _caches_cleared(); @@ -263,16 +251,16 @@ private: bool _update_caches(AnimationPlayer *player); void _process_graph(float p_delta); - uint64_t setup_pass; - uint64_t process_pass; + uint64_t setup_pass = 1; + uint64_t process_pass = 1; - bool started; + bool started = true; NodePath root_motion_track; Transform root_motion_transform; friend class AnimationNode; - bool properties_dirty; + bool properties_dirty = true; void _tree_changed(); void _update_properties(); List<PropertyInfo> properties; @@ -280,8 +268,8 @@ private: HashMap<StringName, Variant> property_map; struct Activity { - uint64_t last_pass; - float activity; + uint64_t last_pass = 0; + float activity = 0.0; }; HashMap<StringName, Vector<Activity>> input_activity_map; @@ -306,8 +294,8 @@ public: void set_active(bool p_active); bool is_active() const; - void set_process_mode(AnimationProcessMode p_mode); - AnimationProcessMode get_process_mode() const; + void set_process_callback(AnimationProcessCallback p_mode); + AnimationProcessCallback get_process_callback() const; void set_animation_player(const NodePath &p_player); NodePath get_animation_player() const; @@ -332,6 +320,6 @@ public: ~AnimationTree(); }; -VARIANT_ENUM_CAST(AnimationTree::AnimationProcessMode) +VARIANT_ENUM_CAST(AnimationTree::AnimationProcessCallback) #endif // ANIMATION_GRAPH_PLAYER_H diff --git a/scene/animation/root_motion_view.cpp b/scene/animation/root_motion_view.cpp index cbf2e4a6ff..9ee1f32581 100644 --- a/scene/animation/root_motion_view.cpp +++ b/scene/animation/root_motion_view.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -89,12 +89,12 @@ void RootMotionView::_notification(int p_what) { AnimationTree *tree = Object::cast_to<AnimationTree>(node); if (tree && tree->is_active() && tree->get_root_motion_track() != NodePath()) { - if (is_processing_internal() && tree->get_process_mode() == AnimationTree::ANIMATION_PROCESS_PHYSICS) { + if (is_processing_internal() && tree->get_process_callback() == AnimationTree::ANIMATION_PROCESS_PHYSICS) { set_process_internal(false); set_physics_process_internal(true); } - if (is_physics_processing_internal() && tree->get_process_mode() == AnimationTree::ANIMATION_PROCESS_IDLE) { + if (is_physics_processing_internal() && tree->get_process_callback() == AnimationTree::ANIMATION_PROCESS_IDLE) { set_process_internal(true); set_physics_process_internal(false); } @@ -188,13 +188,9 @@ void RootMotionView::_bind_methods() { } RootMotionView::RootMotionView() { - zero_y = true; - radius = 10; - cell_size = 1; set_process_internal(true); immediate = RenderingServer::get_singleton()->immediate_create(); set_base(immediate); - color = Color(0.5, 0.5, 1.0); } RootMotionView::~RootMotionView() { diff --git a/scene/animation/root_motion_view.h b/scene/animation/root_motion_view.h index 77c51fe47a..afcff6137f 100644 --- a/scene/animation/root_motion_view.h +++ b/scene/animation/root_motion_view.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -39,12 +39,12 @@ class RootMotionView : public VisualInstance3D { public: RID immediate; NodePath path; - float cell_size; - float radius; - bool use_in_game; - Color color; - bool first; - bool zero_y; + float cell_size = 1.0; + float radius = 10.0; + bool use_in_game = false; + Color color = Color(0.5, 0.5, 1.0); + bool first = true; + bool zero_y = true; Transform accumulated; diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp index 1a2a97ada8..2030808724 100644 --- a/scene/animation/tween.cpp +++ b/scene/animation/tween.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -869,8 +869,21 @@ void Tween::start() { return; } + pending_update++; + for (List<InterpolateData>::Element *E = interpolates.front(); E; E = E->next()) { + InterpolateData &data = E->get(); + data.active = true; + } + pending_update--; + // We want to be activated set_active(true); + + // Don't resume from current position if stop_all() function has been used + if (was_stopped) { + seek(0); + } + was_stopped = false; } void Tween::reset(Object *p_object, StringName p_key) { @@ -939,7 +952,7 @@ void Tween::stop(Object *p_object, StringName p_key) { void Tween::stop_all() { // We no longer need to be active since all tweens have been stopped set_active(false); - + was_stopped = true; // For each interpolation... pending_update++; for (List<InterpolateData>::Element *E = interpolates.front(); E; E = E->next()) { @@ -1098,11 +1111,11 @@ void Tween::seek(real_t p_time) { real_t Tween::tell() const { // We want to grab the position of the furthest along tween pending_update++; - real_t pos = 0; + real_t pos = 0.0; // For each interpolation... for (const List<InterpolateData>::Element *E = interpolates.front(); E; E = E->next()) { - // Get the data and figure out if it's position is further along than the previous ones + // Get the data and figure out if its position is further along than the previous ones const InterpolateData &data = E->get(); if (data.elapsed > pos) { // Save it if so @@ -1122,7 +1135,7 @@ real_t Tween::get_runtime() const { pending_update++; // For each interpolation... - real_t runtime = 0; + real_t runtime = 0.0; for (const List<InterpolateData>::Element *E = interpolates.front(); E; E = E->next()) { // Get the tween data and see if it's runtime is greater than the previous tweens const InterpolateData &data = E->get(); @@ -1350,6 +1363,9 @@ void Tween::interpolate_property(Object *p_object, NodePath p_property, Variant return; } + // Check that the target object is valid + ERR_FAIL_COND_MSG(p_object == nullptr, vformat("The Tween \"%s\"'s target node is `null`. Is the node reference correct?", get_name())); + // Get the property from the node path p_property = p_property.get_as_property_path(); @@ -1378,6 +1394,9 @@ void Tween::interpolate_method(Object *p_object, StringName p_method, Variant p_ return; } + // Check that the target object is valid + ERR_FAIL_COND_MSG(p_object == nullptr, vformat("The Tween \"%s\"'s target node is `null`. Is the node reference correct?", get_name())); + // Convert any integers into REALs as they are better for interpolation if (p_initial_val.get_type() == Variant::INT) { p_initial_val = p_initial_val.operator real_t(); @@ -1789,12 +1808,6 @@ void Tween::targeting_method(Object *p_object, StringName p_method, Object *p_in } Tween::Tween() { - // Initialize tween attributes - tween_process_mode = TWEEN_PROCESS_IDLE; - repeat = false; - speed_scale = 1; - pending_update = 0; - uid = 0; } Tween::~Tween() { diff --git a/scene/animation/tween.h b/scene/animation/tween.h index 822fcf0b6f..142c0c65e0 100644 --- a/scene/animation/tween.h +++ b/scene/animation/tween.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -79,11 +79,11 @@ private: }; struct InterpolateData { - bool active; - InterpolateType type; - bool finish; - bool call_deferred; - real_t elapsed; + bool active = false; + InterpolateType type = INTER_CALLBACK; + bool finish = false; + bool call_deferred = false; + real_t elapsed = 0.0; ObjectID id; Vector<StringName> key; StringName concatenated_key; @@ -92,33 +92,28 @@ private: Variant final_val; ObjectID target_id; Vector<StringName> target_key; - real_t duration; - TransitionType trans_type; - EaseType ease_type; - real_t delay; - int args; + real_t duration = 0.0; + TransitionType trans_type = TransitionType::TRANS_BACK; + EaseType ease_type = EaseType::EASE_COUNT; + real_t delay = 0.0; + int args = 0; Variant arg[5]; - int uid; - InterpolateData() { - active = false; - finish = false; - call_deferred = false; - uid = 0; - } + int uid = 0; }; String autoplay; - TweenProcessMode tween_process_mode; - bool repeat; - float speed_scale; - mutable int pending_update; - int uid; + TweenProcessMode tween_process_mode = TWEEN_PROCESS_IDLE; + bool repeat = false; + float speed_scale = 1.0; + mutable int pending_update = 0; + int uid = 0; + bool was_stopped = false; List<InterpolateData> interpolates; struct PendingCommand { StringName key; - int args; + int args = 0; Variant arg[10]; }; List<PendingCommand> pending_commands; |