summaryrefslogtreecommitdiff
path: root/scene/animation
diff options
context:
space:
mode:
Diffstat (limited to 'scene/animation')
-rw-r--r--scene/animation/SCsub2
-rw-r--r--scene/animation/animation_blend_space_1d.cpp26
-rw-r--r--scene/animation/animation_blend_space_1d.h14
-rw-r--r--scene/animation/animation_blend_space_2d.cpp77
-rw-r--r--scene/animation/animation_blend_space_2d.h14
-rw-r--r--scene/animation/animation_blend_tree.cpp178
-rw-r--r--scene/animation/animation_blend_tree.h96
-rw-r--r--scene/animation/animation_cache.cpp89
-rw-r--r--scene/animation/animation_cache.h18
-rw-r--r--scene/animation/animation_node_state_machine.cpp120
-rw-r--r--scene/animation/animation_node_state_machine.h15
-rw-r--r--scene/animation/animation_player.cpp426
-rw-r--r--scene/animation/animation_player.h105
-rw-r--r--scene/animation/animation_tree.cpp207
-rw-r--r--scene/animation/animation_tree.h34
-rw-r--r--scene/animation/animation_tree_player.cpp1866
-rw-r--r--scene/animation/animation_tree_player.h487
-rw-r--r--scene/animation/root_motion_view.cpp43
-rw-r--r--scene/animation/root_motion_view.h10
-rw-r--r--scene/animation/skeleton_ik.cpp588
-rw-r--r--scene/animation/skeleton_ik.h221
-rw-r--r--scene/animation/tween.cpp683
-rw-r--r--scene/animation/tween.h41
23 files changed, 989 insertions, 4371 deletions
diff --git a/scene/animation/SCsub b/scene/animation/SCsub
index b01e2fd54d..fc61250247 100644
--- a/scene/animation/SCsub
+++ b/scene/animation/SCsub
@@ -1,5 +1,5 @@
#!/usr/bin/env python
-Import('env')
+Import("env")
env.add_source_files(env.scene_sources, "*.cpp")
diff --git a/scene/animation/animation_blend_space_1d.cpp b/scene/animation/animation_blend_space_1d.cpp
index 0f55682427..e426e98def 100644
--- a/scene/animation/animation_blend_space_1d.cpp
+++ b/scene/animation/animation_blend_space_1d.cpp
@@ -31,8 +31,9 @@
#include "animation_blend_space_1d.h"
void AnimationNodeBlendSpace1D::get_parameter_list(List<PropertyInfo> *r_list) const {
- r_list->push_back(PropertyInfo(Variant::REAL, blend_position));
+ r_list->push_back(PropertyInfo(Variant::FLOAT, blend_position));
}
+
Variant AnimationNodeBlendSpace1D::get_parameter_default_value(const StringName &p_parameter) const {
return 0;
}
@@ -79,16 +80,14 @@ void AnimationNodeBlendSpace1D::_bind_methods() {
ClassDB::bind_method(D_METHOD("_add_blend_point", "index", "node"), &AnimationNodeBlendSpace1D::_add_blend_point);
- ClassDB::bind_method(D_METHOD("_tree_changed"), &AnimationNodeBlendSpace1D::_tree_changed);
-
for (int i = 0; i < MAX_BLEND_POINTS; i++) {
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "blend_point_" + itos(i) + "/node", PROPERTY_HINT_RESOURCE_TYPE, "AnimationRootNode", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_add_blend_point", "get_blend_point_node", i);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "blend_point_" + itos(i) + "/pos", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_blend_point_position", "get_blend_point_position", i);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "blend_point_" + itos(i) + "/pos", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_blend_point_position", "get_blend_point_position", i);
}
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "min_space", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_min_space", "get_min_space");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_space", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_max_space", "get_max_space");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "snap", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_snap", "get_snap");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "min_space", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_min_space", "get_min_space");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_space", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_max_space", "get_max_space");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "snap", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_snap", "get_snap");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "value_label", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_value_label", "get_value_label");
}
@@ -118,7 +117,7 @@ void AnimationNodeBlendSpace1D::add_blend_point(const Ref<AnimationRootNode> &p_
blend_points[p_at_index].node = p_node;
blend_points[p_at_index].position = p_position;
- blend_points[p_at_index].node->connect("tree_changed", this, "_tree_changed", varray(), CONNECT_REFERENCE_COUNTED);
+ blend_points[p_at_index].node->connect("tree_changed", callable_mp(this, &AnimationNodeBlendSpace1D::_tree_changed), varray(), CONNECT_REFERENCE_COUNTED);
blend_points_used++;
emit_signal("tree_changed");
@@ -135,11 +134,11 @@ void AnimationNodeBlendSpace1D::set_blend_point_node(int p_point, const Ref<Anim
ERR_FAIL_COND(p_node.is_null());
if (blend_points[p_point].node.is_valid()) {
- blend_points[p_point].node->disconnect("tree_changed", this, "_tree_changed");
+ blend_points[p_point].node->disconnect("tree_changed", callable_mp(this, &AnimationNodeBlendSpace1D::_tree_changed));
}
blend_points[p_point].node = p_node;
- blend_points[p_point].node->connect("tree_changed", this, "_tree_changed", varray(), CONNECT_REFERENCE_COUNTED);
+ blend_points[p_point].node->connect("tree_changed", callable_mp(this, &AnimationNodeBlendSpace1D::_tree_changed), varray(), CONNECT_REFERENCE_COUNTED);
emit_signal("tree_changed");
}
@@ -158,7 +157,7 @@ void AnimationNodeBlendSpace1D::remove_blend_point(int p_point) {
ERR_FAIL_INDEX(p_point, blend_points_used);
ERR_FAIL_COND(blend_points[p_point].node.is_null());
- blend_points[p_point].node->disconnect("tree_changed", this, "_tree_changed");
+ blend_points[p_point].node->disconnect("tree_changed", callable_mp(this, &AnimationNodeBlendSpace1D::_tree_changed));
for (int i = p_point; i < blend_points_used - 1; i++) {
blend_points[i] = blend_points[i + 1];
@@ -169,7 +168,6 @@ void AnimationNodeBlendSpace1D::remove_blend_point(int p_point) {
}
int AnimationNodeBlendSpace1D::get_blend_point_count() const {
-
return blend_points_used;
}
@@ -222,7 +220,6 @@ void AnimationNodeBlendSpace1D::_add_blend_point(int p_index, const Ref<Animatio
}
float AnimationNodeBlendSpace1D::process(float p_time, bool p_seek) {
-
if (blend_points_used == 0) {
return 0.0;
}
@@ -243,7 +240,6 @@ float AnimationNodeBlendSpace1D::process(float p_time, bool p_seek) {
// find the closest two points to blend between
for (int i = 0; i < blend_points_used; i++) {
-
float pos = blend_points[i].position;
if (pos <= blend_pos) {
@@ -278,7 +274,6 @@ float AnimationNodeBlendSpace1D::process(float p_time, bool p_seek) {
weights[point_lower] = 1.0;
} else {
-
// we are between two points.
// figure out weights, then blend the animations
@@ -313,7 +308,6 @@ String AnimationNodeBlendSpace1D::get_caption() const {
}
AnimationNodeBlendSpace1D::AnimationNodeBlendSpace1D() {
-
for (int i = 0; i < MAX_BLEND_POINTS; i++) {
blend_points[i].name = itos(i);
}
diff --git a/scene/animation/animation_blend_space_1d.h b/scene/animation/animation_blend_space_1d.h
index da3608e06d..816d3c9d4e 100644
--- a/scene/animation/animation_blend_space_1d.h
+++ b/scene/animation/animation_blend_space_1d.h
@@ -63,14 +63,14 @@ class AnimationNodeBlendSpace1D : public AnimationRootNode {
StringName blend_position;
protected:
- virtual void _validate_property(PropertyInfo &property) const;
+ virtual void _validate_property(PropertyInfo &property) const override;
static void _bind_methods();
public:
- virtual void get_parameter_list(List<PropertyInfo> *r_list) const;
- virtual Variant get_parameter_default_value(const StringName &p_parameter) const;
+ virtual void get_parameter_list(List<PropertyInfo> *r_list) const override;
+ virtual Variant get_parameter_default_value(const StringName &p_parameter) const override;
- virtual void get_child_nodes(List<ChildNode> *r_child_nodes);
+ virtual void get_child_nodes(List<ChildNode> *r_child_nodes) override;
void add_blend_point(const Ref<AnimationRootNode> &p_node, float p_position, int p_at_index = -1);
void set_blend_point_position(int p_point, float p_position);
@@ -93,10 +93,10 @@ public:
void set_value_label(const String &p_label);
String get_value_label() const;
- float process(float p_time, bool p_seek);
- String get_caption() const;
+ float process(float p_time, bool p_seek) override;
+ String get_caption() const override;
- Ref<AnimationNode> get_child_by_name(const StringName &p_name);
+ Ref<AnimationNode> get_child_by_name(const StringName &p_name) override;
AnimationNodeBlendSpace1D();
~AnimationNodeBlendSpace1D();
diff --git a/scene/animation/animation_blend_space_2d.cpp b/scene/animation/animation_blend_space_2d.cpp
index d749959377..5a42e2af7a 100644
--- a/scene/animation/animation_blend_space_2d.cpp
+++ b/scene/animation/animation_blend_space_2d.cpp
@@ -29,13 +29,15 @@
/*************************************************************************/
#include "animation_blend_space_2d.h"
-#include "core/math/delaunay.h"
+
+#include "core/math/geometry_2d.h"
void AnimationNodeBlendSpace2D::get_parameter_list(List<PropertyInfo> *r_list) const {
r_list->push_back(PropertyInfo(Variant::VECTOR2, blend_position));
r_list->push_back(PropertyInfo(Variant::INT, closest, PROPERTY_HINT_NONE, "", 0));
- r_list->push_back(PropertyInfo(Variant::REAL, length_internal, PROPERTY_HINT_NONE, "", 0));
+ r_list->push_back(PropertyInfo(Variant::FLOAT, length_internal, PROPERTY_HINT_NONE, "", 0));
}
+
Variant AnimationNodeBlendSpace2D::get_parameter_default_value(const StringName &p_parameter) const {
if (p_parameter == closest) {
return -1;
@@ -77,7 +79,7 @@ void AnimationNodeBlendSpace2D::add_blend_point(const Ref<AnimationRootNode> &p_
blend_points[p_at_index].node = p_node;
blend_points[p_at_index].position = p_position;
- blend_points[p_at_index].node->connect("tree_changed", this, "_tree_changed", varray(), CONNECT_REFERENCE_COUNTED);
+ blend_points[p_at_index].node->connect("tree_changed", callable_mp(this, &AnimationNodeBlendSpace2D::_tree_changed), varray(), CONNECT_REFERENCE_COUNTED);
blend_points_used++;
_queue_auto_triangles();
@@ -90,31 +92,35 @@ void AnimationNodeBlendSpace2D::set_blend_point_position(int p_point, const Vect
blend_points[p_point].position = p_position;
_queue_auto_triangles();
}
+
void AnimationNodeBlendSpace2D::set_blend_point_node(int p_point, const Ref<AnimationRootNode> &p_node) {
ERR_FAIL_INDEX(p_point, blend_points_used);
ERR_FAIL_COND(p_node.is_null());
if (blend_points[p_point].node.is_valid()) {
- blend_points[p_point].node->disconnect("tree_changed", this, "_tree_changed");
+ blend_points[p_point].node->disconnect("tree_changed", callable_mp(this, &AnimationNodeBlendSpace2D::_tree_changed));
}
blend_points[p_point].node = p_node;
- blend_points[p_point].node->connect("tree_changed", this, "_tree_changed", varray(), CONNECT_REFERENCE_COUNTED);
+ blend_points[p_point].node->connect("tree_changed", callable_mp(this, &AnimationNodeBlendSpace2D::_tree_changed), varray(), CONNECT_REFERENCE_COUNTED);
emit_signal("tree_changed");
}
+
Vector2 AnimationNodeBlendSpace2D::get_blend_point_position(int p_point) const {
ERR_FAIL_INDEX_V(p_point, blend_points_used, Vector2());
return blend_points[p_point].position;
}
+
Ref<AnimationRootNode> AnimationNodeBlendSpace2D::get_blend_point_node(int p_point) const {
ERR_FAIL_INDEX_V(p_point, blend_points_used, Ref<AnimationRootNode>());
return blend_points[p_point].node;
}
+
void AnimationNodeBlendSpace2D::remove_blend_point(int p_point) {
ERR_FAIL_INDEX(p_point, blend_points_used);
ERR_FAIL_COND(blend_points[p_point].node.is_null());
- blend_points[p_point].node->disconnect("tree_changed", this, "_tree_changed");
+ blend_points[p_point].node->disconnect("tree_changed", callable_mp(this, &AnimationNodeBlendSpace2D::_tree_changed));
for (int i = 0; i < triangles.size(); i++) {
bool erase = false;
@@ -141,12 +147,10 @@ void AnimationNodeBlendSpace2D::remove_blend_point(int p_point) {
}
int AnimationNodeBlendSpace2D::get_blend_point_count() const {
-
return blend_points_used;
}
bool AnimationNodeBlendSpace2D::has_triangle(int p_x, int p_y, int p_z) const {
-
ERR_FAIL_INDEX_V(p_x, blend_points_used, false);
ERR_FAIL_INDEX_V(p_y, blend_points_used, false);
ERR_FAIL_INDEX_V(p_z, blend_points_used, false);
@@ -167,15 +171,15 @@ bool AnimationNodeBlendSpace2D::has_triangle(int p_x, int p_y, int p_z) const {
break;
}
}
- if (all_equal)
+ if (all_equal) {
return true;
+ }
}
return false;
}
void AnimationNodeBlendSpace2D::add_triangle(int p_x, int p_y, int p_z, int p_at_index) {
-
ERR_FAIL_INDEX(p_x, blend_points_used);
ERR_FAIL_INDEX(p_y, blend_points_used);
ERR_FAIL_INDEX(p_z, blend_points_used);
@@ -207,14 +211,15 @@ void AnimationNodeBlendSpace2D::add_triangle(int p_x, int p_y, int p_z, int p_at
triangles.insert(p_at_index, t);
}
}
-int AnimationNodeBlendSpace2D::get_triangle_point(int p_triangle, int p_point) {
+int AnimationNodeBlendSpace2D::get_triangle_point(int p_triangle, int p_point) {
_update_triangles();
ERR_FAIL_INDEX_V(p_point, 3, -1);
ERR_FAIL_INDEX_V(p_triangle, triangles.size(), -1);
return triangles[p_triangle].points[p_point];
}
+
void AnimationNodeBlendSpace2D::remove_triangle(int p_triangle) {
ERR_FAIL_INDEX(p_triangle, triangles.size());
@@ -226,7 +231,6 @@ int AnimationNodeBlendSpace2D::get_triangle_count() const {
}
void AnimationNodeBlendSpace2D::set_min_space(const Vector2 &p_min) {
-
min_space = p_min;
if (min_space.x >= max_space.x) {
min_space.x = max_space.x - 1;
@@ -235,12 +239,12 @@ void AnimationNodeBlendSpace2D::set_min_space(const Vector2 &p_min) {
min_space.y = max_space.y - 1;
}
}
+
Vector2 AnimationNodeBlendSpace2D::get_min_space() const {
return min_space;
}
void AnimationNodeBlendSpace2D::set_max_space(const Vector2 &p_max) {
-
max_space = p_max;
if (max_space.x <= min_space.x) {
max_space.x = min_space.x + 1;
@@ -249,6 +253,7 @@ void AnimationNodeBlendSpace2D::set_max_space(const Vector2 &p_max) {
max_space.y = min_space.y + 1;
}
}
+
Vector2 AnimationNodeBlendSpace2D::get_max_space() const {
return max_space;
}
@@ -256,6 +261,7 @@ Vector2 AnimationNodeBlendSpace2D::get_max_space() const {
void AnimationNodeBlendSpace2D::set_snap(const Vector2 &p_snap) {
snap = p_snap;
}
+
Vector2 AnimationNodeBlendSpace2D::get_snap() const {
return snap;
}
@@ -263,6 +269,7 @@ Vector2 AnimationNodeBlendSpace2D::get_snap() const {
void AnimationNodeBlendSpace2D::set_x_label(const String &p_label) {
x_label = p_label;
}
+
String AnimationNodeBlendSpace2D::get_x_label() const {
return x_label;
}
@@ -270,6 +277,7 @@ String AnimationNodeBlendSpace2D::get_x_label() const {
void AnimationNodeBlendSpace2D::set_y_label(const String &p_label) {
y_label = p_label;
}
+
String AnimationNodeBlendSpace2D::get_y_label() const {
return y_label;
}
@@ -283,9 +291,9 @@ void AnimationNodeBlendSpace2D::_add_blend_point(int p_index, const Ref<Animatio
}
void AnimationNodeBlendSpace2D::_set_triangles(const Vector<int> &p_triangles) {
-
- if (auto_triangles)
+ if (auto_triangles) {
return;
+ }
ERR_FAIL_COND(p_triangles.size() % 3 != 0);
for (int i = 0; i < p_triangles.size(); i += 3) {
add_triangle(p_triangles[i + 0], p_triangles[i + 1], p_triangles[i + 2]);
@@ -293,10 +301,10 @@ void AnimationNodeBlendSpace2D::_set_triangles(const Vector<int> &p_triangles) {
}
Vector<int> AnimationNodeBlendSpace2D::_get_triangles() const {
-
Vector<int> t;
- if (auto_triangles && trianges_dirty)
+ if (auto_triangles && trianges_dirty) {
return t;
+ }
t.resize(triangles.size() * 3);
for (int i = 0; i < triangles.size(); i++) {
@@ -317,9 +325,9 @@ void AnimationNodeBlendSpace2D::_queue_auto_triangles() {
}
void AnimationNodeBlendSpace2D::_update_triangles() {
-
- if (!auto_triangles || !trianges_dirty)
+ if (!auto_triangles || !trianges_dirty) {
return;
+ }
trianges_dirty = false;
triangles.clear();
@@ -343,11 +351,11 @@ void AnimationNodeBlendSpace2D::_update_triangles() {
}
Vector2 AnimationNodeBlendSpace2D::get_closest_point(const Vector2 &p_point) {
-
_update_triangles();
- if (triangles.size() == 0)
+ if (triangles.size() == 0) {
return Vector2();
+ }
Vector2 best_point;
bool first = true;
@@ -358,8 +366,7 @@ Vector2 AnimationNodeBlendSpace2D::get_closest_point(const Vector2 &p_point) {
points[j] = get_blend_point_position(get_triangle_point(i, j));
}
- if (Geometry::is_point_in_triangle(p_point, points[0], points[1], points[2])) {
-
+ if (Geometry2D::is_point_in_triangle(p_point, points[0], points[1], points[2])) {
return p_point;
}
@@ -368,7 +375,7 @@ Vector2 AnimationNodeBlendSpace2D::get_closest_point(const Vector2 &p_point) {
points[j],
points[(j + 1) % 3]
};
- Vector2 closest = Geometry::get_closest_point_to_segment_2d(p_point, s);
+ Vector2 closest = Geometry2D::get_closest_point_to_segment(p_point, s);
if (first || closest.distance_to(p_point) < best_point.distance_to(p_point)) {
best_point = closest;
first = false;
@@ -380,7 +387,6 @@ Vector2 AnimationNodeBlendSpace2D::get_closest_point(const Vector2 &p_point) {
}
void AnimationNodeBlendSpace2D::_blend_triangle(const Vector2 &p_pos, const Vector2 *p_points, float *r_weights) {
-
if (p_pos.distance_squared_to(p_points[0]) < CMP_EPSILON2) {
r_weights[0] = 1;
r_weights[1] = 0;
@@ -426,7 +432,6 @@ void AnimationNodeBlendSpace2D::_blend_triangle(const Vector2 &p_pos, const Vect
}
float AnimationNodeBlendSpace2D::process(float p_time, bool p_seek) {
-
_update_triangles();
Vector2 blend_pos = get_parameter(blend_position);
@@ -435,9 +440,9 @@ float AnimationNodeBlendSpace2D::process(float p_time, bool p_seek) {
float mind = 0; //time of min distance point
if (blend_mode == BLEND_MODE_INTERPOLATED) {
-
- if (triangles.size() == 0)
+ if (triangles.size() == 0) {
return 0;
+ }
Vector2 best_point;
bool first = true;
@@ -450,8 +455,7 @@ float AnimationNodeBlendSpace2D::process(float p_time, bool p_seek) {
points[j] = get_blend_point_position(get_triangle_point(i, j));
}
- if (Geometry::is_point_in_triangle(blend_pos, points[0], points[1], points[2])) {
-
+ if (Geometry2D::is_point_in_triangle(blend_pos, points[0], points[1], points[2])) {
blend_triangle = i;
_blend_triangle(blend_pos, points, blend_weights);
break;
@@ -462,7 +466,7 @@ float AnimationNodeBlendSpace2D::process(float p_time, bool p_seek) {
points[j],
points[(j + 1) % 3]
};
- Vector2 closest2 = Geometry::get_closest_point_to_segment_2d(blend_pos, s);
+ Vector2 closest2 = Geometry2D::get_closest_point_to_segment(blend_pos, s);
if (first || closest2.distance_to(blend_pos) < best_point.distance_to(blend_pos)) {
best_point = closest2;
blend_triangle = i;
@@ -493,7 +497,6 @@ float AnimationNodeBlendSpace2D::process(float p_time, bool p_seek) {
first = true;
for (int i = 0; i < blend_points_used; i++) {
-
bool found = false;
for (int j = 0; j < 3; j++) {
if (i == triangle_points[j]) {
@@ -514,22 +517,18 @@ float AnimationNodeBlendSpace2D::process(float p_time, bool p_seek) {
}
}
} else {
-
int new_closest = -1;
float new_closest_dist = 1e20;
for (int i = 0; i < blend_points_used; i++) {
-
float d = blend_points[i].position.distance_squared_to(blend_pos);
if (d < new_closest_dist) {
-
new_closest = i;
new_closest_dist = d;
}
}
if (new_closest != closest && new_closest != -1) {
-
float from = 0;
if (blend_mode == BLEND_MODE_DISCRETE_CARRY && closest != -1) {
//see how much animation remains
@@ -556,7 +555,6 @@ String AnimationNodeBlendSpace2D::get_caption() const {
}
void AnimationNodeBlendSpace2D::_validate_property(PropertyInfo &property) const {
-
if (auto_triangles && property.name == "triangles") {
property.usage = 0;
}
@@ -600,7 +598,6 @@ AnimationNodeBlendSpace2D::BlendMode AnimationNodeBlendSpace2D::get_blend_mode()
}
void AnimationNodeBlendSpace2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("add_blend_point", "node", "pos", "at_index"), &AnimationNodeBlendSpace2D::add_blend_point, DEFVAL(-1));
ClassDB::bind_method(D_METHOD("set_blend_point_position", "point", "pos"), &AnimationNodeBlendSpace2D::set_blend_point_position);
ClassDB::bind_method(D_METHOD("get_blend_point_position", "point"), &AnimationNodeBlendSpace2D::get_blend_point_position);
@@ -640,7 +637,6 @@ void AnimationNodeBlendSpace2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_blend_mode", "mode"), &AnimationNodeBlendSpace2D::set_blend_mode);
ClassDB::bind_method(D_METHOD("get_blend_mode"), &AnimationNodeBlendSpace2D::get_blend_mode);
- ClassDB::bind_method(D_METHOD("_tree_changed"), &AnimationNodeBlendSpace2D::_tree_changed);
ClassDB::bind_method(D_METHOD("_update_triangles"), &AnimationNodeBlendSpace2D::_update_triangles);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_triangles", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_auto_triangles", "get_auto_triangles");
@@ -650,7 +646,7 @@ void AnimationNodeBlendSpace2D::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::VECTOR2, "blend_point_" + itos(i) + "/pos", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_blend_point_position", "get_blend_point_position", i);
}
- ADD_PROPERTY(PropertyInfo(Variant::POOL_INT_ARRAY, "triangles", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_triangles", "_get_triangles");
+ ADD_PROPERTY(PropertyInfo(Variant::PACKED_INT32_ARRAY, "triangles", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_triangles", "_get_triangles");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "min_space", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_min_space", "get_min_space");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "max_space", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_max_space", "get_max_space");
@@ -666,7 +662,6 @@ void AnimationNodeBlendSpace2D::_bind_methods() {
}
AnimationNodeBlendSpace2D::AnimationNodeBlendSpace2D() {
-
for (int i = 0; i < MAX_BLEND_POINTS; i++) {
blend_points[i].name = itos(i);
}
diff --git a/scene/animation/animation_blend_space_2d.h b/scene/animation/animation_blend_space_2d.h
index 7d197ef920..2aff678aad 100644
--- a/scene/animation/animation_blend_space_2d.h
+++ b/scene/animation/animation_blend_space_2d.h
@@ -88,14 +88,14 @@ protected:
void _tree_changed();
protected:
- virtual void _validate_property(PropertyInfo &property) const;
+ virtual void _validate_property(PropertyInfo &property) const override;
static void _bind_methods();
public:
- virtual void get_parameter_list(List<PropertyInfo> *r_list) const;
- virtual Variant get_parameter_default_value(const StringName &p_parameter) const;
+ virtual void get_parameter_list(List<PropertyInfo> *r_list) const override;
+ virtual Variant get_parameter_default_value(const StringName &p_parameter) const override;
- virtual void get_child_nodes(List<ChildNode> *r_child_nodes);
+ virtual void get_child_nodes(List<ChildNode> *r_child_nodes) override;
void add_blend_point(const Ref<AnimationRootNode> &p_node, const Vector2 &p_position, int p_at_index = -1);
void set_blend_point_position(int p_point, const Vector2 &p_position);
@@ -126,8 +126,8 @@ public:
void set_y_label(const String &p_label);
String get_y_label() const;
- virtual float process(float p_time, bool p_seek);
- virtual String get_caption() const;
+ virtual float process(float p_time, bool p_seek) override;
+ virtual String get_caption() const override;
Vector2 get_closest_point(const Vector2 &p_point);
@@ -137,7 +137,7 @@ public:
void set_blend_mode(BlendMode p_blend_mode);
BlendMode get_blend_mode() const;
- virtual Ref<AnimationNode> get_child_by_name(const StringName &p_name);
+ virtual Ref<AnimationNode> get_child_by_name(const StringName &p_name) override;
AnimationNodeBlendSpace2D();
~AnimationNodeBlendSpace2D();
diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp
index 5c284cb483..56995c0c13 100644
--- a/scene/animation/animation_blend_tree.cpp
+++ b/scene/animation/animation_blend_tree.cpp
@@ -41,18 +41,17 @@ StringName AnimationNodeAnimation::get_animation() const {
return animation;
}
-Vector<String> (*AnimationNodeAnimation::get_editable_animation_list)() = NULL;
+Vector<String> (*AnimationNodeAnimation::get_editable_animation_list)() = nullptr;
void AnimationNodeAnimation::get_parameter_list(List<PropertyInfo> *r_list) const {
- r_list->push_back(PropertyInfo(Variant::REAL, time, PROPERTY_HINT_NONE, "", 0));
+ r_list->push_back(PropertyInfo(Variant::FLOAT, time, PROPERTY_HINT_NONE, "", 0));
}
-void AnimationNodeAnimation::_validate_property(PropertyInfo &property) const {
+void AnimationNodeAnimation::_validate_property(PropertyInfo &property) const {
if (property.name == "animation" && get_editable_animation_list) {
Vector<String> names = get_editable_animation_list();
String anims;
for (int i = 0; i < names.size(); i++) {
-
if (i > 0) {
anims += ",";
}
@@ -66,14 +65,12 @@ void AnimationNodeAnimation::_validate_property(PropertyInfo &property) const {
}
float AnimationNodeAnimation::process(float p_time, bool p_seek) {
-
AnimationPlayer *ap = state->player;
ERR_FAIL_COND_V(!ap, 0);
float time = get_parameter(this->time);
if (!ap->has_animation(animation)) {
-
AnimationNodeBlendTree *tree = Object::cast_to<AnimationNodeBlendTree>(parent);
if (tree) {
String name = tree->get_node_name(Ref<AnimationNodeAnimation>(this));
@@ -101,13 +98,11 @@ float AnimationNodeAnimation::process(float p_time, bool p_seek) {
float anim_size = anim->get_length();
if (anim->has_loop()) {
-
if (anim_size) {
time = Math::fposmod(time, anim_size);
}
} else if (time > anim_size) {
-
time = anim_size;
}
@@ -126,7 +121,7 @@ void AnimationNodeAnimation::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_animation", "name"), &AnimationNodeAnimation::set_animation);
ClassDB::bind_method(D_METHOD("get_animation"), &AnimationNodeAnimation::get_animation);
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "animation"), "set_animation", "get_animation");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "animation"), "set_animation", "get_animation");
}
AnimationNodeAnimation::AnimationNodeAnimation() {
@@ -140,9 +135,9 @@ AnimationNodeAnimation::AnimationNodeAnimation() {
void AnimationNodeOneShot::get_parameter_list(List<PropertyInfo> *r_list) const {
r_list->push_back(PropertyInfo(Variant::BOOL, active));
r_list->push_back(PropertyInfo(Variant::BOOL, prev_active, PROPERTY_HINT_NONE, "", 0));
- r_list->push_back(PropertyInfo(Variant::REAL, time, PROPERTY_HINT_NONE, "", 0));
- r_list->push_back(PropertyInfo(Variant::REAL, remaining, PROPERTY_HINT_NONE, "", 0));
- r_list->push_back(PropertyInfo(Variant::REAL, time_to_restart, PROPERTY_HINT_NONE, "", 0));
+ r_list->push_back(PropertyInfo(Variant::FLOAT, time, PROPERTY_HINT_NONE, "", 0));
+ r_list->push_back(PropertyInfo(Variant::FLOAT, remaining, PROPERTY_HINT_NONE, "", 0));
+ r_list->push_back(PropertyInfo(Variant::FLOAT, time_to_restart, PROPERTY_HINT_NONE, "", 0));
}
Variant AnimationNodeOneShot::get_parameter_default_value(const StringName &p_parameter) const {
@@ -156,56 +151,50 @@ Variant AnimationNodeOneShot::get_parameter_default_value(const StringName &p_pa
}
void AnimationNodeOneShot::set_fadein_time(float p_time) {
-
fade_in = p_time;
}
void AnimationNodeOneShot::set_fadeout_time(float p_time) {
-
fade_out = p_time;
}
float AnimationNodeOneShot::get_fadein_time() const {
-
return fade_in;
}
-float AnimationNodeOneShot::get_fadeout_time() const {
+float AnimationNodeOneShot::get_fadeout_time() const {
return fade_out;
}
void AnimationNodeOneShot::set_autorestart(bool p_active) {
-
autorestart = p_active;
}
-void AnimationNodeOneShot::set_autorestart_delay(float p_time) {
+void AnimationNodeOneShot::set_autorestart_delay(float p_time) {
autorestart_delay = p_time;
}
-void AnimationNodeOneShot::set_autorestart_random_delay(float p_time) {
+void AnimationNodeOneShot::set_autorestart_random_delay(float p_time) {
autorestart_random_delay = p_time;
}
bool AnimationNodeOneShot::has_autorestart() const {
-
return autorestart;
}
-float AnimationNodeOneShot::get_autorestart_delay() const {
+float AnimationNodeOneShot::get_autorestart_delay() const {
return autorestart_delay;
}
-float AnimationNodeOneShot::get_autorestart_random_delay() const {
+float AnimationNodeOneShot::get_autorestart_random_delay() const {
return autorestart_random_delay;
}
void AnimationNodeOneShot::set_mix_mode(MixMode p_mix) {
-
mix = p_mix;
}
-AnimationNodeOneShot::MixMode AnimationNodeOneShot::get_mix_mode() const {
+AnimationNodeOneShot::MixMode AnimationNodeOneShot::get_mix_mode() const {
return mix;
}
@@ -218,7 +207,6 @@ bool AnimationNodeOneShot::has_filter() const {
}
float AnimationNodeOneShot::process(float p_time, bool p_seek) {
-
bool active = get_parameter(this->active);
bool prev_active = get_parameter(this->prev_active);
float time = get_parameter(this->time);
@@ -247,8 +235,9 @@ float AnimationNodeOneShot::process(float p_time, bool p_seek) {
bool os_seek = p_seek;
- if (p_seek)
+ if (p_seek) {
time = p_time;
+ }
bool do_start = !prev_active;
if (do_start) {
@@ -260,20 +249,21 @@ float AnimationNodeOneShot::process(float p_time, bool p_seek) {
float blend;
if (time < fade_in) {
-
- if (fade_in > 0)
+ if (fade_in > 0) {
blend = time / fade_in;
- else
+ } else {
blend = 0; //wtf
+ }
} else if (!do_start && remaining < fade_out) {
-
- if (fade_out)
+ if (fade_out) {
blend = (remaining / fade_out);
- else
+ } else {
blend = 1.0;
- } else
+ }
+ } else {
blend = 1.0;
+ }
float main_rem;
if (mix == MIX_MODE_ADD) {
@@ -306,18 +296,16 @@ float AnimationNodeOneShot::process(float p_time, bool p_seek) {
return MAX(main_rem, remaining);
}
-void AnimationNodeOneShot::set_use_sync(bool p_sync) {
+void AnimationNodeOneShot::set_use_sync(bool p_sync) {
sync = p_sync;
}
bool AnimationNodeOneShot::is_using_sync() const {
-
return sync;
}
void AnimationNodeOneShot::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_fadein_time", "time"), &AnimationNodeOneShot::set_fadein_time);
ClassDB::bind_method(D_METHOD("get_fadein_time"), &AnimationNodeOneShot::get_fadein_time);
@@ -339,14 +327,14 @@ void AnimationNodeOneShot::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_use_sync", "enable"), &AnimationNodeOneShot::set_use_sync);
ClassDB::bind_method(D_METHOD("is_using_sync"), &AnimationNodeOneShot::is_using_sync);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "fadein_time", PROPERTY_HINT_RANGE, "0,60,0.01,or_greater"), "set_fadein_time", "get_fadein_time");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "fadeout_time", PROPERTY_HINT_RANGE, "0,60,0.01,or_greater"), "set_fadeout_time", "get_fadeout_time");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fadein_time", PROPERTY_HINT_RANGE, "0,60,0.01,or_greater"), "set_fadein_time", "get_fadein_time");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fadeout_time", PROPERTY_HINT_RANGE, "0,60,0.01,or_greater"), "set_fadeout_time", "get_fadeout_time");
ADD_GROUP("autorestart_", "Auto Restart");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "autorestart"), "set_autorestart", "has_autorestart");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "autorestart_delay", PROPERTY_HINT_RANGE, "0,60,0.01,or_greater"), "set_autorestart_delay", "get_autorestart_delay");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "autorestart_random_delay", PROPERTY_HINT_RANGE, "0,60,0.01,or_greater"), "set_autorestart_random_delay", "get_autorestart_random_delay");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "autorestart_delay", PROPERTY_HINT_RANGE, "0,60,0.01,or_greater"), "set_autorestart_delay", "get_autorestart_delay");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "autorestart_random_delay", PROPERTY_HINT_RANGE, "0,60,0.01,or_greater"), "set_autorestart_random_delay", "get_autorestart_random_delay");
ADD_GROUP("", "");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sync"), "set_use_sync", "is_using_sync");
@@ -356,7 +344,6 @@ void AnimationNodeOneShot::_bind_methods() {
}
AnimationNodeOneShot::AnimationNodeOneShot() {
-
add_input("in");
add_input("shot");
@@ -379,8 +366,9 @@ AnimationNodeOneShot::AnimationNodeOneShot() {
////////////////////////////////////////////////
void AnimationNodeAdd2::get_parameter_list(List<PropertyInfo> *r_list) const {
- r_list->push_back(PropertyInfo(Variant::REAL, add_amount, PROPERTY_HINT_RANGE, "0,1,0.01"));
+ r_list->push_back(PropertyInfo(Variant::FLOAT, add_amount, PROPERTY_HINT_RANGE, "0,1,0.01"));
}
+
Variant AnimationNodeAdd2::get_parameter_default_value(const StringName &p_parameter) const {
return 0;
}
@@ -388,23 +376,20 @@ Variant AnimationNodeAdd2::get_parameter_default_value(const StringName &p_param
String AnimationNodeAdd2::get_caption() const {
return "Add2";
}
-void AnimationNodeAdd2::set_use_sync(bool p_sync) {
+void AnimationNodeAdd2::set_use_sync(bool p_sync) {
sync = p_sync;
}
bool AnimationNodeAdd2::is_using_sync() const {
-
return sync;
}
bool AnimationNodeAdd2::has_filter() const {
-
return true;
}
float AnimationNodeAdd2::process(float p_time, bool p_seek) {
-
float amount = get_parameter(add_amount);
float rem0 = blend_input(0, p_time, p_seek, 1.0, FILTER_IGNORE, !sync);
blend_input(1, p_time, p_seek, amount, FILTER_PASS, !sync);
@@ -413,7 +398,6 @@ float AnimationNodeAdd2::process(float p_time, bool p_seek) {
}
void AnimationNodeAdd2::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_use_sync", "enable"), &AnimationNodeAdd2::set_use_sync);
ClassDB::bind_method(D_METHOD("is_using_sync"), &AnimationNodeAdd2::is_using_sync);
@@ -421,7 +405,6 @@ void AnimationNodeAdd2::_bind_methods() {
}
AnimationNodeAdd2::AnimationNodeAdd2() {
-
add_amount = "add_amount";
add_input("in");
add_input("add");
@@ -431,8 +414,9 @@ AnimationNodeAdd2::AnimationNodeAdd2() {
////////////////////////////////////////////////
void AnimationNodeAdd3::get_parameter_list(List<PropertyInfo> *r_list) const {
- r_list->push_back(PropertyInfo(Variant::REAL, add_amount, PROPERTY_HINT_RANGE, "-1,1,0.01"));
+ r_list->push_back(PropertyInfo(Variant::FLOAT, add_amount, PROPERTY_HINT_RANGE, "-1,1,0.01"));
}
+
Variant AnimationNodeAdd3::get_parameter_default_value(const StringName &p_parameter) const {
return 0;
}
@@ -440,23 +424,20 @@ Variant AnimationNodeAdd3::get_parameter_default_value(const StringName &p_param
String AnimationNodeAdd3::get_caption() const {
return "Add3";
}
-void AnimationNodeAdd3::set_use_sync(bool p_sync) {
+void AnimationNodeAdd3::set_use_sync(bool p_sync) {
sync = p_sync;
}
bool AnimationNodeAdd3::is_using_sync() const {
-
return sync;
}
bool AnimationNodeAdd3::has_filter() const {
-
return true;
}
float AnimationNodeAdd3::process(float p_time, bool p_seek) {
-
float amount = get_parameter(add_amount);
blend_input(0, p_time, p_seek, MAX(0, -amount), FILTER_PASS, !sync);
float rem0 = blend_input(1, p_time, p_seek, 1.0, FILTER_IGNORE, !sync);
@@ -466,7 +447,6 @@ float AnimationNodeAdd3::process(float p_time, bool p_seek) {
}
void AnimationNodeAdd3::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_use_sync", "enable"), &AnimationNodeAdd3::set_use_sync);
ClassDB::bind_method(D_METHOD("is_using_sync"), &AnimationNodeAdd3::is_using_sync);
@@ -474,18 +454,19 @@ void AnimationNodeAdd3::_bind_methods() {
}
AnimationNodeAdd3::AnimationNodeAdd3() {
-
add_amount = "add_amount";
add_input("-add");
add_input("in");
add_input("+add");
sync = false;
}
+
/////////////////////////////////////////////
void AnimationNodeBlend2::get_parameter_list(List<PropertyInfo> *r_list) const {
- r_list->push_back(PropertyInfo(Variant::REAL, blend_amount, PROPERTY_HINT_RANGE, "0,1,0.01"));
+ r_list->push_back(PropertyInfo(Variant::FLOAT, blend_amount, PROPERTY_HINT_RANGE, "0,1,0.01"));
}
+
Variant AnimationNodeBlend2::get_parameter_default_value(const StringName &p_parameter) const {
return 0; //for blend amount
}
@@ -495,7 +476,6 @@ String AnimationNodeBlend2::get_caption() const {
}
float AnimationNodeBlend2::process(float p_time, bool p_seek) {
-
float amount = get_parameter(blend_amount);
float rem0 = blend_input(0, p_time, p_seek, 1.0 - amount, FILTER_BLEND, !sync);
@@ -505,26 +485,24 @@ float AnimationNodeBlend2::process(float p_time, bool p_seek) {
}
void AnimationNodeBlend2::set_use_sync(bool p_sync) {
-
sync = p_sync;
}
bool AnimationNodeBlend2::is_using_sync() const {
-
return sync;
}
bool AnimationNodeBlend2::has_filter() const {
-
return true;
}
-void AnimationNodeBlend2::_bind_methods() {
+void AnimationNodeBlend2::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_use_sync", "enable"), &AnimationNodeBlend2::set_use_sync);
ClassDB::bind_method(D_METHOD("is_using_sync"), &AnimationNodeBlend2::is_using_sync);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sync"), "set_use_sync", "is_using_sync");
}
+
AnimationNodeBlend2::AnimationNodeBlend2() {
blend_amount = "blend_amount";
add_input("in");
@@ -535,8 +513,9 @@ AnimationNodeBlend2::AnimationNodeBlend2() {
//////////////////////////////////////
void AnimationNodeBlend3::get_parameter_list(List<PropertyInfo> *r_list) const {
- r_list->push_back(PropertyInfo(Variant::REAL, blend_amount, PROPERTY_HINT_RANGE, "-1,1,0.01"));
+ r_list->push_back(PropertyInfo(Variant::FLOAT, blend_amount, PROPERTY_HINT_RANGE, "-1,1,0.01"));
}
+
Variant AnimationNodeBlend3::get_parameter_default_value(const StringName &p_parameter) const {
return 0; //for blend amount
}
@@ -546,17 +525,14 @@ String AnimationNodeBlend3::get_caption() const {
}
void AnimationNodeBlend3::set_use_sync(bool p_sync) {
-
sync = p_sync;
}
bool AnimationNodeBlend3::is_using_sync() const {
-
return sync;
}
float AnimationNodeBlend3::process(float p_time, bool p_seek) {
-
float amount = get_parameter(blend_amount);
float rem0 = blend_input(0, p_time, p_seek, MAX(0, -amount), FILTER_IGNORE, !sync);
float rem1 = blend_input(1, p_time, p_seek, 1.0 - ABS(amount), FILTER_IGNORE, !sync);
@@ -566,12 +542,12 @@ float AnimationNodeBlend3::process(float p_time, bool p_seek) {
}
void AnimationNodeBlend3::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_use_sync", "enable"), &AnimationNodeBlend3::set_use_sync);
ClassDB::bind_method(D_METHOD("is_using_sync"), &AnimationNodeBlend3::is_using_sync);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sync"), "set_use_sync", "is_using_sync");
}
+
AnimationNodeBlend3::AnimationNodeBlend3() {
blend_amount = "blend_amount";
add_input("-blend");
@@ -583,8 +559,9 @@ AnimationNodeBlend3::AnimationNodeBlend3() {
/////////////////////////////////
void AnimationNodeTimeScale::get_parameter_list(List<PropertyInfo> *r_list) const {
- r_list->push_back(PropertyInfo(Variant::REAL, scale, PROPERTY_HINT_RANGE, "0,32,0.01,or_greater"));
+ r_list->push_back(PropertyInfo(Variant::FLOAT, scale, PROPERTY_HINT_RANGE, "0,32,0.01,or_greater"));
}
+
Variant AnimationNodeTimeScale::get_parameter_default_value(const StringName &p_parameter) const {
return 1.0; //initial timescale
}
@@ -594,7 +571,6 @@ String AnimationNodeTimeScale::get_caption() const {
}
float AnimationNodeTimeScale::process(float p_time, bool p_seek) {
-
float scale = get_parameter(this->scale);
if (p_seek) {
return blend_input(0, p_time, true, 1.0, FILTER_IGNORE, false);
@@ -605,6 +581,7 @@ float AnimationNodeTimeScale::process(float p_time, bool p_seek) {
void AnimationNodeTimeScale::_bind_methods() {
}
+
AnimationNodeTimeScale::AnimationNodeTimeScale() {
scale = "scale";
add_input("in");
@@ -613,8 +590,9 @@ AnimationNodeTimeScale::AnimationNodeTimeScale() {
////////////////////////////////////
void AnimationNodeTimeSeek::get_parameter_list(List<PropertyInfo> *r_list) const {
- r_list->push_back(PropertyInfo(Variant::REAL, seek_pos, PROPERTY_HINT_RANGE, "-1,3600,0.01,or_greater"));
+ r_list->push_back(PropertyInfo(Variant::FLOAT, seek_pos, PROPERTY_HINT_RANGE, "-1,3600,0.01,or_greater"));
}
+
Variant AnimationNodeTimeSeek::get_parameter_default_value(const StringName &p_parameter) const {
return 1.0; //initial timescale
}
@@ -624,7 +602,6 @@ String AnimationNodeTimeSeek::get_caption() const {
}
float AnimationNodeTimeSeek::process(float p_time, bool p_seek) {
-
float seek_pos = get_parameter(this->seek_pos);
if (p_seek) {
return blend_input(0, p_time, true, 1.0, FILTER_IGNORE, false);
@@ -649,7 +626,6 @@ AnimationNodeTimeSeek::AnimationNodeTimeSeek() {
/////////////////////////////////////////////////
void AnimationNodeTransition::get_parameter_list(List<PropertyInfo> *r_list) const {
-
String anims;
for (int i = 0; i < enabled_inputs; i++) {
if (i > 0) {
@@ -661,9 +637,10 @@ void AnimationNodeTransition::get_parameter_list(List<PropertyInfo> *r_list) con
r_list->push_back(PropertyInfo(Variant::INT, current, PROPERTY_HINT_ENUM, anims));
r_list->push_back(PropertyInfo(Variant::INT, prev_current, PROPERTY_HINT_NONE, "", 0));
r_list->push_back(PropertyInfo(Variant::INT, prev, PROPERTY_HINT_NONE, "", 0));
- r_list->push_back(PropertyInfo(Variant::REAL, time, PROPERTY_HINT_NONE, "", 0));
- r_list->push_back(PropertyInfo(Variant::REAL, prev_xfading, PROPERTY_HINT_NONE, "", 0));
+ r_list->push_back(PropertyInfo(Variant::FLOAT, time, PROPERTY_HINT_NONE, "", 0));
+ r_list->push_back(PropertyInfo(Variant::FLOAT, prev_xfading, PROPERTY_HINT_NONE, "", 0));
}
+
Variant AnimationNodeTransition::get_parameter_default_value(const StringName &p_parameter) const {
if (p_parameter == time || p_parameter == prev_xfading) {
return 0.0;
@@ -728,7 +705,6 @@ float AnimationNodeTransition::get_cross_fade_time() const {
}
float AnimationNodeTransition::process(float p_time, bool p_seek) {
-
int current = get_parameter(this->current);
int prev = get_parameter(this->prev);
int prev_current = get_parameter(this->prev_current);
@@ -758,13 +734,13 @@ float AnimationNodeTransition::process(float p_time, bool p_seek) {
rem = blend_input(current, p_time, p_seek, 1.0, FILTER_IGNORE, false);
- if (p_seek)
+ if (p_seek) {
time = p_time;
- else
+ } else {
time += p_time;
+ }
if (inputs[current].auto_advance && rem <= xfade) {
-
set_parameter(this->current, (current + 1) % enabled_inputs);
}
@@ -776,7 +752,6 @@ float AnimationNodeTransition::process(float p_time, bool p_seek) {
rem = blend_input(current, 0, true, 1.0 - blend, FILTER_IGNORE, false);
} else {
-
rem = blend_input(current, p_time, p_seek, 1.0 - blend, FILTER_IGNORE, false);
}
@@ -800,7 +775,6 @@ float AnimationNodeTransition::process(float p_time, bool p_seek) {
}
void AnimationNodeTransition::_validate_property(PropertyInfo &property) const {
-
if (property.name.begins_with("input_")) {
String n = property.name.get_slicec('/', 0).get_slicec('_', 1);
if (n != "count") {
@@ -815,7 +789,6 @@ void AnimationNodeTransition::_validate_property(PropertyInfo &property) const {
}
void AnimationNodeTransition::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_enabled_inputs", "amount"), &AnimationNodeTransition::set_enabled_inputs);
ClassDB::bind_method(D_METHOD("get_enabled_inputs"), &AnimationNodeTransition::get_enabled_inputs);
@@ -829,7 +802,7 @@ void AnimationNodeTransition::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_cross_fade_time"), &AnimationNodeTransition::get_cross_fade_time);
ADD_PROPERTY(PropertyInfo(Variant::INT, "input_count", PROPERTY_HINT_RANGE, "0,64,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_enabled_inputs", "get_enabled_inputs");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "xfade_time", PROPERTY_HINT_RANGE, "0,120,0.01"), "set_cross_fade_time", "get_cross_fade_time");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "xfade_time", PROPERTY_HINT_RANGE, "0,120,0.01"), "set_cross_fade_time", "get_cross_fade_time");
for (int i = 0; i < MAX_INPUTS; i++) {
ADD_PROPERTYI(PropertyInfo(Variant::STRING, "input_" + itos(i) + "/name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "set_input_caption", "get_input_caption", i);
@@ -838,7 +811,6 @@ void AnimationNodeTransition::_bind_methods() {
}
AnimationNodeTransition::AnimationNodeTransition() {
-
prev_xfading = "prev_xfading";
prev = "prev";
time = "time";
@@ -869,7 +841,6 @@ AnimationNodeOutput::AnimationNodeOutput() {
///////////////////////////////////////////////////////
void AnimationNodeBlendTree::add_node(const StringName &p_name, Ref<AnimationNode> p_node, const Vector2 &p_position) {
-
ERR_FAIL_COND(nodes.has(p_name));
ERR_FAIL_COND(p_node.is_null());
ERR_FAIL_COND(p_name == SceneStringNames::get_singleton()->output);
@@ -884,12 +855,11 @@ void AnimationNodeBlendTree::add_node(const StringName &p_name, Ref<AnimationNod
emit_changed();
emit_signal("tree_changed");
- p_node->connect("tree_changed", this, "_tree_changed", varray(), CONNECT_REFERENCE_COUNTED);
- p_node->connect("changed", this, "_node_changed", varray(p_name), CONNECT_REFERENCE_COUNTED);
+ p_node->connect("tree_changed", callable_mp(this, &AnimationNodeBlendTree::_tree_changed), varray(), CONNECT_REFERENCE_COUNTED);
+ p_node->connect("changed", callable_mp(this, &AnimationNodeBlendTree::_node_changed), varray(p_name), CONNECT_REFERENCE_COUNTED);
}
Ref<AnimationNode> AnimationNodeBlendTree::get_node(const StringName &p_name) const {
-
ERR_FAIL_COND_V(!nodes.has(p_name), Ref<AnimationNode>());
return nodes[p_name].node;
@@ -935,20 +905,20 @@ void AnimationNodeBlendTree::get_child_nodes(List<ChildNode> *r_child_nodes) {
bool AnimationNodeBlendTree::has_node(const StringName &p_name) const {
return nodes.has(p_name);
}
-Vector<StringName> AnimationNodeBlendTree::get_node_connection_array(const StringName &p_name) const {
+Vector<StringName> AnimationNodeBlendTree::get_node_connection_array(const StringName &p_name) const {
ERR_FAIL_COND_V(!nodes.has(p_name), Vector<StringName>());
return nodes[p_name].connections;
}
-void AnimationNodeBlendTree::remove_node(const StringName &p_name) {
+void AnimationNodeBlendTree::remove_node(const StringName &p_name) {
ERR_FAIL_COND(!nodes.has(p_name));
ERR_FAIL_COND(p_name == SceneStringNames::get_singleton()->output); //can't delete output
{
Ref<AnimationNode> node = nodes[p_name].node;
- node->disconnect("tree_changed", this, "_tree_changed");
- node->disconnect("changed", this, "_node_changed");
+ node->disconnect("tree_changed", callable_mp(this, &AnimationNodeBlendTree::_tree_changed));
+ node->disconnect("changed", callable_mp(this, &AnimationNodeBlendTree::_node_changed));
}
nodes.erase(p_name);
@@ -967,20 +937,18 @@ void AnimationNodeBlendTree::remove_node(const StringName &p_name) {
}
void AnimationNodeBlendTree::rename_node(const StringName &p_name, const StringName &p_new_name) {
-
ERR_FAIL_COND(!nodes.has(p_name));
ERR_FAIL_COND(nodes.has(p_new_name));
ERR_FAIL_COND(p_name == SceneStringNames::get_singleton()->output);
ERR_FAIL_COND(p_new_name == SceneStringNames::get_singleton()->output);
- nodes[p_name].node->disconnect("changed", this, "_node_changed");
+ nodes[p_name].node->disconnect("changed", callable_mp(this, &AnimationNodeBlendTree::_node_changed));
nodes[p_new_name] = nodes[p_name];
nodes.erase(p_name);
//rename connections
for (Map<StringName, Node>::Element *E = nodes.front(); E; E = E->next()) {
-
for (int i = 0; i < E->get().connections.size(); i++) {
if (E->get().connections[i] == p_name) {
E->get().connections.write[i] = p_new_name;
@@ -988,13 +956,12 @@ void AnimationNodeBlendTree::rename_node(const StringName &p_name, const StringN
}
}
//connection must be done with new name
- nodes[p_new_name].node->connect("changed", this, "_node_changed", varray(p_new_name), CONNECT_REFERENCE_COUNTED);
+ nodes[p_new_name].node->connect("changed", callable_mp(this, &AnimationNodeBlendTree::_node_changed), varray(p_new_name), CONNECT_REFERENCE_COUNTED);
emit_signal("tree_changed");
}
void AnimationNodeBlendTree::connect_node(const StringName &p_input_node, int p_input_index, const StringName &p_output_node) {
-
ERR_FAIL_COND(!nodes.has(p_output_node));
ERR_FAIL_COND(!nodes.has(p_input_node));
ERR_FAIL_COND(p_output_node == SceneStringNames::get_singleton()->output);
@@ -1016,7 +983,6 @@ void AnimationNodeBlendTree::connect_node(const StringName &p_input_node, int p_
}
void AnimationNodeBlendTree::disconnect_node(const StringName &p_node, int p_input_index) {
-
ERR_FAIL_COND(!nodes.has(p_node));
Ref<AnimationNode> input = nodes[p_node].node;
@@ -1026,7 +992,6 @@ void AnimationNodeBlendTree::disconnect_node(const StringName &p_node, int p_inp
}
AnimationNodeBlendTree::ConnectionError AnimationNodeBlendTree::can_connect_node(const StringName &p_input_node, int p_input_index, const StringName &p_output_node) const {
-
if (!nodes.has(p_output_node) || p_output_node == SceneStringNames::get_singleton()->output) {
return CONNECTION_ERROR_NO_OUTPUT;
}
@@ -1061,7 +1026,6 @@ AnimationNodeBlendTree::ConnectionError AnimationNodeBlendTree::can_connect_node
}
void AnimationNodeBlendTree::get_node_connections(List<NodeConnection> *r_connections) const {
-
for (Map<StringName, Node>::Element *E = nodes.front(); E; E = E->next()) {
for (int i = 0; i < E->get().connections.size(); i++) {
StringName output = E->get().connections[i];
@@ -1081,25 +1045,21 @@ String AnimationNodeBlendTree::get_caption() const {
}
float AnimationNodeBlendTree::process(float p_time, bool p_seek) {
-
Ref<AnimationNodeOutput> output = nodes[SceneStringNames::get_singleton()->output].node;
return _blend_node("output", nodes[SceneStringNames::get_singleton()->output].connections, this, output, p_time, p_seek, 1.0);
}
void AnimationNodeBlendTree::get_node_list(List<StringName> *r_list) {
-
for (Map<StringName, Node>::Element *E = nodes.front(); E; E = E->next()) {
r_list->push_back(E->key());
}
}
void AnimationNodeBlendTree::set_graph_offset(const Vector2 &p_graph_offset) {
-
graph_offset = p_graph_offset;
}
Vector2 AnimationNodeBlendTree::get_graph_offset() const {
-
return graph_offset;
}
@@ -1108,10 +1068,8 @@ Ref<AnimationNode> AnimationNodeBlendTree::get_child_by_name(const StringName &p
}
bool AnimationNodeBlendTree::_set(const StringName &p_name, const Variant &p_value) {
-
String name = p_name;
if (name.begins_with("nodes/")) {
-
String node_name = name.get_slicec('/', 1);
String what = name.get_slicec('/', 2);
@@ -1124,14 +1082,12 @@ bool AnimationNodeBlendTree::_set(const StringName &p_name, const Variant &p_val
}
if (what == "position") {
-
if (nodes.has(node_name)) {
nodes[node_name].position = p_value;
}
return true;
}
} else if (name == "node_connections") {
-
Array conns = p_value;
ERR_FAIL_COND_V(conns.size() % 3 != 0, false);
@@ -1145,7 +1101,6 @@ bool AnimationNodeBlendTree::_set(const StringName &p_name, const Variant &p_val
}
bool AnimationNodeBlendTree::_get(const StringName &p_name, Variant &r_ret) const {
-
String name = p_name;
if (name.begins_with("nodes/")) {
String node_name = name.get_slicec('/', 1);
@@ -1159,7 +1114,6 @@ bool AnimationNodeBlendTree::_get(const StringName &p_name, Variant &r_ret) cons
}
if (what == "position") {
-
if (nodes.has(node_name)) {
r_ret = nodes[node_name].position;
return true;
@@ -1185,8 +1139,8 @@ bool AnimationNodeBlendTree::_get(const StringName &p_name, Variant &r_ret) cons
return false;
}
-void AnimationNodeBlendTree::_get_property_list(List<PropertyInfo> *p_list) const {
+void AnimationNodeBlendTree::_get_property_list(List<PropertyInfo> *p_list) const {
List<StringName> names;
for (Map<StringName, Node>::Element *E = nodes.front(); E; E = E->next()) {
names.push_back(E->key());
@@ -1209,13 +1163,11 @@ void AnimationNodeBlendTree::_tree_changed() {
}
void AnimationNodeBlendTree::_node_changed(const StringName &p_node) {
-
ERR_FAIL_COND(!nodes.has(p_node));
nodes[p_node].connections.resize(nodes[p_node].node->get_input_count());
}
void AnimationNodeBlendTree::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("add_node", "name", "node", "position"), &AnimationNodeBlendTree::add_node, DEFVAL(Vector2()));
ClassDB::bind_method(D_METHOD("get_node", "name"), &AnimationNodeBlendTree::get_node);
ClassDB::bind_method(D_METHOD("remove_node", "name"), &AnimationNodeBlendTree::remove_node);
@@ -1230,9 +1182,6 @@ void AnimationNodeBlendTree::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_graph_offset", "offset"), &AnimationNodeBlendTree::set_graph_offset);
ClassDB::bind_method(D_METHOD("get_graph_offset"), &AnimationNodeBlendTree::get_graph_offset);
- ClassDB::bind_method(D_METHOD("_tree_changed"), &AnimationNodeBlendTree::_tree_changed);
- ClassDB::bind_method(D_METHOD("_node_changed", "node"), &AnimationNodeBlendTree::_node_changed);
-
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "graph_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_graph_offset", "get_graph_offset");
BIND_CONSTANT(CONNECTION_OK);
@@ -1244,7 +1193,6 @@ void AnimationNodeBlendTree::_bind_methods() {
}
AnimationNodeBlendTree::AnimationNodeBlendTree() {
-
Ref<AnimationNodeOutput> output;
output.instance();
Node n;
diff --git a/scene/animation/animation_blend_tree.h b/scene/animation/animation_blend_tree.h
index 7ebe3f5444..7241a6bc13 100644
--- a/scene/animation/animation_blend_tree.h
+++ b/scene/animation/animation_blend_tree.h
@@ -34,7 +34,6 @@
#include "scene/animation/animation_tree.h"
class AnimationNodeAnimation : public AnimationRootNode {
-
GDCLASS(AnimationNodeAnimation, AnimationRootNode);
StringName animation;
@@ -44,17 +43,17 @@ class AnimationNodeAnimation : public AnimationRootNode {
bool skip;
protected:
- void _validate_property(PropertyInfo &property) const;
+ void _validate_property(PropertyInfo &property) const override;
static void _bind_methods();
public:
- void get_parameter_list(List<PropertyInfo> *r_list) const;
+ void get_parameter_list(List<PropertyInfo> *r_list) const override;
static Vector<String> (*get_editable_animation_list)();
- virtual String get_caption() const;
- virtual float process(float p_time, bool p_seek);
+ virtual String get_caption() const override;
+ virtual float process(float p_time, bool p_seek) override;
void set_animation(const StringName &p_name);
StringName get_animation() const;
@@ -97,10 +96,10 @@ protected:
static void _bind_methods();
public:
- virtual void get_parameter_list(List<PropertyInfo> *r_list) const;
- virtual Variant get_parameter_default_value(const StringName &p_parameter) const;
+ virtual void get_parameter_list(List<PropertyInfo> *r_list) const override;
+ virtual Variant get_parameter_default_value(const StringName &p_parameter) const override;
- virtual String get_caption() const;
+ virtual String get_caption() const override;
void set_fadein_time(float p_time);
void set_fadeout_time(float p_time);
@@ -122,8 +121,8 @@ public:
void set_use_sync(bool p_sync);
bool is_using_sync() const;
- virtual bool has_filter() const;
- virtual float process(float p_time, bool p_seek);
+ virtual bool has_filter() const override;
+ virtual float process(float p_time, bool p_seek) override;
AnimationNodeOneShot();
};
@@ -140,16 +139,16 @@ protected:
static void _bind_methods();
public:
- void get_parameter_list(List<PropertyInfo> *r_list) const;
- virtual Variant get_parameter_default_value(const StringName &p_parameter) const;
+ void get_parameter_list(List<PropertyInfo> *r_list) const override;
+ virtual Variant get_parameter_default_value(const StringName &p_parameter) const override;
- virtual String get_caption() const;
+ virtual String get_caption() const override;
void set_use_sync(bool p_sync);
bool is_using_sync() const;
- virtual bool has_filter() const;
- virtual float process(float p_time, bool p_seek);
+ virtual bool has_filter() const override;
+ virtual float process(float p_time, bool p_seek) override;
AnimationNodeAdd2();
};
@@ -164,16 +163,16 @@ protected:
static void _bind_methods();
public:
- void get_parameter_list(List<PropertyInfo> *r_list) const;
- virtual Variant get_parameter_default_value(const StringName &p_parameter) const;
+ void get_parameter_list(List<PropertyInfo> *r_list) const override;
+ virtual Variant get_parameter_default_value(const StringName &p_parameter) const override;
- virtual String get_caption() const;
+ virtual String get_caption() const override;
void set_use_sync(bool p_sync);
bool is_using_sync() const;
- virtual bool has_filter() const;
- virtual float process(float p_time, bool p_seek);
+ virtual bool has_filter() const override;
+ virtual float process(float p_time, bool p_seek) override;
AnimationNodeAdd3();
};
@@ -188,16 +187,16 @@ protected:
static void _bind_methods();
public:
- virtual void get_parameter_list(List<PropertyInfo> *r_list) const;
- virtual Variant get_parameter_default_value(const StringName &p_parameter) const;
+ virtual void get_parameter_list(List<PropertyInfo> *r_list) const override;
+ virtual Variant get_parameter_default_value(const StringName &p_parameter) const override;
- virtual String get_caption() const;
- virtual float process(float p_time, bool p_seek);
+ virtual String get_caption() const override;
+ virtual float process(float p_time, bool p_seek) override;
void set_use_sync(bool p_sync);
bool is_using_sync() const;
- virtual bool has_filter() const;
+ virtual bool has_filter() const override;
AnimationNodeBlend2();
};
@@ -211,15 +210,15 @@ protected:
static void _bind_methods();
public:
- virtual void get_parameter_list(List<PropertyInfo> *r_list) const;
- virtual Variant get_parameter_default_value(const StringName &p_parameter) const;
+ virtual void get_parameter_list(List<PropertyInfo> *r_list) const override;
+ virtual Variant get_parameter_default_value(const StringName &p_parameter) const override;
- virtual String get_caption() const;
+ virtual String get_caption() const override;
void set_use_sync(bool p_sync);
bool is_using_sync() const;
- float process(float p_time, bool p_seek);
+ float process(float p_time, bool p_seek) override;
AnimationNodeBlend3();
};
@@ -232,12 +231,12 @@ protected:
static void _bind_methods();
public:
- virtual void get_parameter_list(List<PropertyInfo> *r_list) const;
- virtual Variant get_parameter_default_value(const StringName &p_parameter) const;
+ virtual void get_parameter_list(List<PropertyInfo> *r_list) const override;
+ virtual Variant get_parameter_default_value(const StringName &p_parameter) const override;
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- float process(float p_time, bool p_seek);
+ float process(float p_time, bool p_seek) override;
AnimationNodeTimeScale();
};
@@ -251,12 +250,12 @@ protected:
static void _bind_methods();
public:
- virtual void get_parameter_list(List<PropertyInfo> *r_list) const;
- virtual Variant get_parameter_default_value(const StringName &p_parameter) const;
+ virtual void get_parameter_list(List<PropertyInfo> *r_list) const override;
+ virtual Variant get_parameter_default_value(const StringName &p_parameter) const override;
- virtual String get_caption() const;
+ virtual String get_caption() const override;
- float process(float p_time, bool p_seek);
+ float process(float p_time, bool p_seek) override;
AnimationNodeTimeSeek();
};
@@ -268,7 +267,6 @@ class AnimationNodeTransition : public AnimationNode {
MAX_INPUTS = 32
};
struct InputData {
-
String name;
bool auto_advance;
InputData() { auto_advance = false; }
@@ -296,13 +294,13 @@ class AnimationNodeTransition : public AnimationNode {
protected:
static void _bind_methods();
- void _validate_property(PropertyInfo &property) const;
+ void _validate_property(PropertyInfo &property) const override;
public:
- virtual void get_parameter_list(List<PropertyInfo> *r_list) const;
- virtual Variant get_parameter_default_value(const StringName &p_parameter) const;
+ virtual void get_parameter_list(List<PropertyInfo> *r_list) const override;
+ virtual Variant get_parameter_default_value(const StringName &p_parameter) const override;
- virtual String get_caption() const;
+ virtual String get_caption() const override;
void set_enabled_inputs(int p_inputs);
int get_enabled_inputs();
@@ -316,7 +314,7 @@ public:
void set_cross_fade_time(float p_fade);
float get_cross_fade_time() const;
- float process(float p_time, bool p_seek);
+ float process(float p_time, bool p_seek) override;
AnimationNodeTransition();
};
@@ -325,8 +323,8 @@ class AnimationNodeOutput : public AnimationNode {
GDCLASS(AnimationNodeOutput, AnimationNode);
public:
- virtual String get_caption() const;
- virtual float process(float p_time, bool p_seek);
+ virtual String get_caption() const override;
+ virtual float process(float p_time, bool p_seek) override;
AnimationNodeOutput();
};
@@ -376,7 +374,7 @@ public:
void set_node_position(const StringName &p_node, const Vector2 &p_position);
Vector2 get_node_position(const StringName &p_node) const;
- virtual void get_child_nodes(List<ChildNode> *r_child_nodes);
+ virtual void get_child_nodes(List<ChildNode> *r_child_nodes) override;
void connect_node(const StringName &p_input_node, int p_input_index, const StringName &p_output_node);
void disconnect_node(const StringName &p_node, int p_input_index);
@@ -390,15 +388,15 @@ public:
ConnectionError can_connect_node(const StringName &p_input_node, int p_input_index, const StringName &p_output_node) const;
void get_node_connections(List<NodeConnection> *r_connections) const;
- virtual String get_caption() const;
- virtual float process(float p_time, bool p_seek);
+ virtual String get_caption() const override;
+ virtual float process(float p_time, bool p_seek) override;
void get_node_list(List<StringName> *r_list);
void set_graph_offset(const Vector2 &p_graph_offset);
Vector2 get_graph_offset() const;
- virtual Ref<AnimationNode> get_child_by_name(const StringName &p_name);
+ virtual Ref<AnimationNode> get_child_by_name(const StringName &p_name) override;
AnimationNodeBlendTree();
~AnimationNodeBlendTree();
diff --git a/scene/animation/animation_cache.cpp b/scene/animation/animation_cache.cpp
index 8d1ffb43cc..abb2cf1b65 100644
--- a/scene/animation/animation_cache.cpp
+++ b/scene/animation/animation_cache.cpp
@@ -31,7 +31,6 @@
#include "animation_cache.h"
void AnimationCache::_node_exit_tree(Node *p_node) {
-
//it is one shot, so it disconnects upon arrival
ERR_FAIL_COND(!connected_nodes.has(p_node));
@@ -39,24 +38,21 @@ void AnimationCache::_node_exit_tree(Node *p_node) {
connected_nodes.erase(p_node);
for (int i = 0; i < path_cache.size(); i++) {
-
- if (path_cache[i].node != p_node)
+ if (path_cache[i].node != p_node) {
continue;
+ }
path_cache.write[i].valid = false; //invalidate path cache
}
}
void AnimationCache::_animation_changed() {
-
_clear_cache();
}
void AnimationCache::_clear_cache() {
-
while (connected_nodes.size()) {
-
- connected_nodes.front()->get()->disconnect("tree_exiting", this, "_node_exit_tree");
+ connected_nodes.front()->get()->disconnect("tree_exiting", callable_mp(this, &AnimationCache::_node_exit_tree));
connected_nodes.erase(connected_nodes.front());
}
path_cache.clear();
@@ -65,7 +61,6 @@ void AnimationCache::_clear_cache() {
}
void AnimationCache::_update_cache() {
-
cache_valid = false;
ERR_FAIL_COND(!root);
@@ -73,12 +68,10 @@ void AnimationCache::_update_cache() {
ERR_FAIL_COND(animation.is_null());
for (int i = 0; i < animation->get_track_count(); i++) {
-
NodePath np = animation->track_get_path(i);
Node *node = root->get_node(np);
if (!node) {
-
path_cache.push_back(Path());
ERR_CONTINUE_MSG(!node, "Invalid track path in animation '" + np + "'.");
}
@@ -88,27 +81,24 @@ void AnimationCache::_update_cache() {
Ref<Resource> res;
if (animation->track_get_type(i) == Animation::TYPE_TRANSFORM) {
-
if (np.get_subname_count() > 1) {
path_cache.push_back(Path());
ERR_CONTINUE_MSG(animation->track_get_type(i) == Animation::TYPE_TRANSFORM, "Transform tracks can't have a subpath '" + np + "'.");
}
- Spatial *sp = Object::cast_to<Spatial>(node);
+ Node3D *sp = Object::cast_to<Node3D>(node);
if (!sp) {
-
path_cache.push_back(Path());
- ERR_CONTINUE_MSG(!sp, "Transform track not of type Spatial '" + np + "'.");
+ ERR_CONTINUE_MSG(!sp, "Transform track not of type Node3D '" + np + "'.");
}
if (np.get_subname_count() == 1) {
StringName property = np.get_subname(0);
String ps = property;
- Skeleton *sk = Object::cast_to<Skeleton>(node);
+ Skeleton3D *sk = Object::cast_to<Skeleton3D>(node);
if (!sk) {
-
path_cache.push_back(Path());
ERR_CONTINUE_MSG(!sk, "Property defined in Transform track, but not a Skeleton! '" + np + "'.");
}
@@ -127,7 +117,6 @@ void AnimationCache::_update_cache() {
} else {
if (np.get_subname_count() > 0) {
-
RES res2;
Vector<StringName> leftover_subpath;
@@ -144,7 +133,6 @@ void AnimationCache::_update_cache() {
path.subpath = leftover_subpath;
} else {
-
path.node = node;
path.object = node;
path.subpath = np.get_subnames();
@@ -152,15 +140,12 @@ void AnimationCache::_update_cache() {
}
if (animation->track_get_type(i) == Animation::TYPE_VALUE) {
-
if (np.get_subname_count() == 0) {
-
path_cache.push_back(Path());
ERR_CONTINUE_MSG(np.get_subname_count() == 0, "Value Track lacks property: " + np + ".");
}
} else if (animation->track_get_type(i) == Animation::TYPE_METHOD) {
-
if (path.subpath.size() != 0) { // Trying to call a method of a non-resource
path_cache.push_back(Path());
@@ -174,7 +159,7 @@ void AnimationCache::_update_cache() {
if (!connected_nodes.has(path.node)) {
connected_nodes.insert(path.node);
- path.node->connect("tree_exiting", this, "_node_exit_tree", Node::make_binds(path.node), CONNECT_ONESHOT);
+ path.node->connect("tree_exiting", callable_mp(this, &AnimationCache::_node_exit_tree), Node::make_binds(path.node), CONNECT_ONESHOT);
}
}
@@ -183,15 +168,16 @@ void AnimationCache::_update_cache() {
}
void AnimationCache::set_track_transform(int p_idx, const Transform &p_transform) {
-
- if (cache_dirty)
+ if (cache_dirty) {
_update_cache();
+ }
ERR_FAIL_COND(!cache_valid);
ERR_FAIL_INDEX(p_idx, path_cache.size());
Path &p = path_cache.write[p_idx];
- if (!p.valid)
+ if (!p.valid) {
return;
+ }
ERR_FAIL_COND(!p.node);
ERR_FAIL_COND(!p.spatial);
@@ -204,49 +190,48 @@ void AnimationCache::set_track_transform(int p_idx, const Transform &p_transform
}
void AnimationCache::set_track_value(int p_idx, const Variant &p_value) {
-
- if (cache_dirty)
+ if (cache_dirty) {
_update_cache();
+ }
ERR_FAIL_COND(!cache_valid);
ERR_FAIL_INDEX(p_idx, path_cache.size());
Path &p = path_cache.write[p_idx];
- if (!p.valid)
+ if (!p.valid) {
return;
+ }
ERR_FAIL_COND(!p.object);
p.object->set_indexed(p.subpath, p_value);
}
-void AnimationCache::call_track(int p_idx, const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
-
- if (cache_dirty)
+void AnimationCache::call_track(int p_idx, const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
+ if (cache_dirty) {
_update_cache();
+ }
ERR_FAIL_COND(!cache_valid);
ERR_FAIL_INDEX(p_idx, path_cache.size());
Path &p = path_cache.write[p_idx];
- if (!p.valid)
+ if (!p.valid) {
return;
+ }
ERR_FAIL_COND(!p.object);
p.object->call(p_method, p_args, p_argcount, r_error);
}
void AnimationCache::set_all(float p_time, float p_delta) {
-
- if (cache_dirty)
+ if (cache_dirty) {
_update_cache();
+ }
ERR_FAIL_COND(!cache_valid);
int tc = animation->get_track_count();
for (int i = 0; i < tc; i++) {
-
switch (animation->track_get_type(i)) {
-
case Animation::TYPE_TRANSFORM: {
-
Vector3 loc, scale;
Quat rot;
animation->transform_track_interpolate(i, p_time, &loc, &rot, &scale);
@@ -257,17 +242,14 @@ void AnimationCache::set_all(float p_time, float p_delta) {
} break;
case Animation::TYPE_VALUE: {
-
if (animation->value_track_get_update_mode(i) == Animation::UPDATE_CONTINUOUS || (animation->value_track_get_update_mode(i) == Animation::UPDATE_DISCRETE && p_delta == 0)) {
Variant v = animation->value_track_interpolate(i, p_time);
set_track_value(i, v);
} else {
-
List<int> indices;
animation->value_track_get_key_indices(i, p_time, p_delta, &indices);
for (List<int>::Element *E = indices.front(); E; E = E->next()) {
-
Variant v = animation->track_get_key_value(i, E->get());
set_track_value(i, v);
}
@@ -275,25 +257,20 @@ void AnimationCache::set_all(float p_time, float p_delta) {
} break;
case Animation::TYPE_METHOD: {
-
List<int> indices;
animation->method_track_get_key_indices(i, p_time, p_delta, &indices);
for (List<int>::Element *E = indices.front(); E; E = E->next()) {
-
Vector<Variant> args = animation->method_track_get_params(i, E->get());
StringName name = animation->method_track_get_name(i, E->get());
- Variant::CallError err;
+ Callable::CallError err;
if (!args.size()) {
-
- call_track(i, name, NULL, 0, err);
+ call_track(i, name, nullptr, 0, err);
} else {
-
Vector<const Variant *> argptrs;
argptrs.resize(args.size());
for (int j = 0; j < args.size(); j++) {
-
argptrs.write[j] = &args.write[j];
}
@@ -309,33 +286,29 @@ void AnimationCache::set_all(float p_time, float p_delta) {
}
void AnimationCache::set_animation(const Ref<Animation> &p_animation) {
-
_clear_cache();
- if (animation.is_valid())
- animation->disconnect("changed", this, "_animation_changed");
+ if (animation.is_valid()) {
+ animation->disconnect("changed", callable_mp(this, &AnimationCache::_animation_changed));
+ }
animation = p_animation;
- if (animation.is_valid())
- animation->connect("changed", this, "_animation_changed");
+ if (animation.is_valid()) {
+ animation->connect("changed", callable_mp(this, &AnimationCache::_animation_changed));
+ }
}
void AnimationCache::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("_node_exit_tree"), &AnimationCache::_node_exit_tree);
- ClassDB::bind_method(D_METHOD("_animation_changed"), &AnimationCache::_animation_changed);
}
void AnimationCache::set_root(Node *p_root) {
-
_clear_cache();
root = p_root;
}
AnimationCache::AnimationCache() {
-
- root = NULL;
+ root = nullptr;
cache_dirty = true;
cache_valid = false;
}
diff --git a/scene/animation/animation_cache.h b/scene/animation/animation_cache.h
index 26ad9dfee5..feff1d364a 100644
--- a/scene/animation/animation_cache.h
+++ b/scene/animation/animation_cache.h
@@ -31,31 +31,29 @@
#ifndef ANIMATION_CACHE_H
#define ANIMATION_CACHE_H
-#include "scene/3d/skeleton.h"
+#include "scene/3d/skeleton_3d.h"
#include "scene/resources/animation.h"
class AnimationCache : public Object {
-
GDCLASS(AnimationCache, Object);
struct Path {
-
RES resource;
Object *object;
- Skeleton *skeleton; // haxor
+ Skeleton3D *skeleton; // haxor
Node *node;
- Spatial *spatial;
+ Node3D *spatial;
int bone_idx;
Vector<StringName> subpath;
bool valid;
Path() {
- object = NULL;
- skeleton = NULL;
- node = NULL;
+ object = nullptr;
+ skeleton = nullptr;
+ node = nullptr;
bone_idx = -1;
valid = false;
- spatial = NULL;
+ spatial = nullptr;
}
};
@@ -79,7 +77,7 @@ protected:
public:
void set_track_transform(int p_idx, const Transform &p_transform);
void set_track_value(int p_idx, const Variant &p_value);
- void call_track(int p_idx, const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error);
+ void call_track(int p_idx, const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error);
void set_all(float p_time, float p_delta = 0);
diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp
index 59d0d9e87f..17ce05f130 100644
--- a/scene/animation/animation_node_state_machine.cpp
+++ b/scene/animation/animation_node_state_machine.cpp
@@ -33,12 +33,10 @@
/////////////////////////////////////////////////
void AnimationNodeStateMachineTransition::set_switch_mode(SwitchMode p_mode) {
-
switch_mode = p_mode;
}
AnimationNodeStateMachineTransition::SwitchMode AnimationNodeStateMachineTransition::get_switch_mode() const {
-
return switch_mode;
}
@@ -71,7 +69,6 @@ StringName AnimationNodeStateMachineTransition::get_advance_condition_name() con
}
void AnimationNodeStateMachineTransition::set_xfade_time(float p_xfade) {
-
ERR_FAIL_COND(p_xfade < 0);
xfade = p_xfade;
emit_changed();
@@ -120,8 +117,8 @@ void AnimationNodeStateMachineTransition::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "switch_mode", PROPERTY_HINT_ENUM, "Immediate,Sync,AtEnd"), "set_switch_mode", "get_switch_mode");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_advance"), "set_auto_advance", "has_auto_advance");
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "advance_condition"), "set_advance_condition", "get_advance_condition");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "xfade_time", PROPERTY_HINT_RANGE, "0,240,0.01"), "set_xfade_time", "get_xfade_time");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "advance_condition"), "set_advance_condition", "get_advance_condition");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "xfade_time", PROPERTY_HINT_RANGE, "0,240,0.01"), "set_xfade_time", "get_xfade_time");
ADD_PROPERTY(PropertyInfo(Variant::INT, "priority", PROPERTY_HINT_RANGE, "0,32,1"), "set_priority", "get_priority");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disabled"), "set_disabled", "is_disabled");
@@ -133,7 +130,6 @@ void AnimationNodeStateMachineTransition::_bind_methods() {
}
AnimationNodeStateMachineTransition::AnimationNodeStateMachineTransition() {
-
switch_mode = SWITCH_MODE_IMMEDIATE;
auto_advance = false;
xfade = 0;
@@ -144,7 +140,6 @@ AnimationNodeStateMachineTransition::AnimationNodeStateMachineTransition() {
////////////////////////////////////////////////////////
void AnimationNodeStateMachinePlayback::travel(const StringName &p_state) {
-
start_request_travel = true;
start_request = p_state;
stop_request = false;
@@ -155,39 +150,45 @@ void AnimationNodeStateMachinePlayback::start(const StringName &p_state) {
start_request = p_state;
stop_request = false;
}
-void AnimationNodeStateMachinePlayback::stop() {
+void AnimationNodeStateMachinePlayback::stop() {
stop_request = true;
}
+
bool AnimationNodeStateMachinePlayback::is_playing() const {
return playing;
}
+
StringName AnimationNodeStateMachinePlayback::get_current_node() const {
return current;
}
+
StringName AnimationNodeStateMachinePlayback::get_blend_from_node() const {
return fading_from;
}
+
Vector<StringName> AnimationNodeStateMachinePlayback::get_travel_path() const {
return path;
}
+
float AnimationNodeStateMachinePlayback::get_current_play_pos() const {
return pos_current;
}
+
float AnimationNodeStateMachinePlayback::get_current_length() const {
return len_current;
}
bool AnimationNodeStateMachinePlayback::_travel(AnimationNodeStateMachine *p_state_machine, const StringName &p_travel) {
-
ERR_FAIL_COND_V(!playing, false);
ERR_FAIL_COND_V(!p_state_machine->states.has(p_travel), false);
ERR_FAIL_COND_V(!p_state_machine->states.has(current), false);
path.clear(); //a new one will be needed
- if (current == p_travel)
+ if (current == p_travel) {
return true; //nothing to do
+ }
loops_current = 0; // reset loops, so fade does not happen immediately
@@ -219,17 +220,15 @@ bool AnimationNodeStateMachinePlayback::_travel(AnimationNodeStateMachine *p_sta
//begin astar
bool found_route = false;
while (!found_route) {
-
if (open_list.size() == 0) {
return false; //no path found
}
//find the last cost transition
- List<int>::Element *least_cost_transition = NULL;
+ List<int>::Element *least_cost_transition = nullptr;
float least_cost = 1e20;
for (List<int>::Element *E = open_list.front(); E; E = E->next()) {
-
float cost = cost_map[p_state_machine->transitions[E->get()].to].distance;
cost += p_state_machine->states[p_state_machine->transitions[E->get()].to].position.distance_to(target_pos);
@@ -293,7 +292,6 @@ bool AnimationNodeStateMachinePlayback::_travel(AnimationNodeStateMachine *p_sta
}
float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_state_machine, float p_time, bool p_seek) {
-
//if not playing and it can restart, then restart
if (!playing && start_request == StringName()) {
if (!stop_request && p_state_machine->start_node) {
@@ -347,7 +345,6 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_st
bool do_start = (p_seek && p_time == 0) || play_start || current == StringName();
if (do_start) {
-
if (p_state_machine->start_node != StringName() && p_seek && p_time == 0) {
current = p_state_machine->start_node;
}
@@ -365,7 +362,6 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_st
float fade_blend = 1.0;
if (fading_from != StringName()) {
-
if (!p_state_machine->states.has(fading_from)) {
fading_from = StringName();
} else {
@@ -382,7 +378,6 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_st
float rem = p_state_machine->blend_node(current, p_state_machine->states[current].node, p_time, p_seek, fade_blend, AnimationNode::FILTER_IGNORE, false);
if (fading_from != StringName()) {
-
p_state_machine->blend_node(fading_from, p_state_machine->states[fading_from].node, p_time, p_seek, 1.0 - fade_blend, AnimationNode::FILTER_IGNORE, false);
}
@@ -407,7 +402,6 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_st
AnimationNodeStateMachineTransition::SwitchMode switch_mode = AnimationNodeStateMachineTransition::SWITCH_MODE_IMMEDIATE;
if (path.size()) {
-
for (int i = 0; i < p_state_machine->transitions.size(); i++) {
if (p_state_machine->transitions[i].from == current && p_state_machine->transitions[i].to == path[0]) {
next_xfade = p_state_machine->transitions[i].transition->get_xfade_time();
@@ -419,7 +413,6 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_st
float priority_best = 1e20;
int auto_advance_to = -1;
for (int i = 0; i < p_state_machine->transitions.size(); i++) {
-
bool auto_advance = false;
if (p_state_machine->transitions[i].transition->has_auto_advance()) {
auto_advance = true;
@@ -430,7 +423,6 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_st
}
if (p_state_machine->transitions[i].from == current && auto_advance) {
-
if (p_state_machine->transitions[i].transition->get_priority() <= priority_best) {
priority_best = p_state_machine->transitions[i].transition->get_priority();
auto_advance_to = i;
@@ -447,7 +439,6 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_st
//if next, see when to transition
if (next != StringName()) {
-
bool goto_next = false;
if (switch_mode == AnimationNodeStateMachineTransition::SWITCH_MODE_AT_END) {
@@ -492,7 +483,6 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_st
//compute time left for transitions by using the end node
if (p_state_machine->end_node != StringName() && p_state_machine->end_node != current) {
-
rem = p_state_machine->blend_node(p_state_machine->end_node, p_state_machine->states[p_state_machine->end_node].node, 0, true, 0, AnimationNode::FILTER_IGNORE, false);
}
@@ -500,7 +490,6 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_st
}
void AnimationNodeStateMachinePlayback::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("travel", "to_node"), &AnimationNodeStateMachinePlayback::travel);
ClassDB::bind_method(D_METHOD("start", "node"), &AnimationNodeStateMachinePlayback::start);
ClassDB::bind_method(D_METHOD("stop"), &AnimationNodeStateMachinePlayback::stop);
@@ -516,6 +505,11 @@ AnimationNodeStateMachinePlayback::AnimationNodeStateMachinePlayback() {
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;
}
///////////////////////////////////////////////////////
@@ -525,7 +519,7 @@ void AnimationNodeStateMachine::get_parameter_list(List<PropertyInfo> *r_list) c
List<StringName> advance_conditions;
for (int i = 0; i < transitions.size(); i++) {
StringName ac = transitions[i].transition->get_advance_condition_name();
- if (ac != StringName() && advance_conditions.find(ac) == NULL) {
+ if (ac != StringName() && advance_conditions.find(ac) == nullptr) {
advance_conditions.push_back(ac);
}
}
@@ -537,7 +531,6 @@ void AnimationNodeStateMachine::get_parameter_list(List<PropertyInfo> *r_list) c
}
Variant AnimationNodeStateMachine::get_parameter_default_value(const StringName &p_parameter) const {
-
if (p_parameter == playback) {
Ref<AnimationNodeStateMachinePlayback> p;
p.instance();
@@ -548,7 +541,6 @@ Variant AnimationNodeStateMachine::get_parameter_default_value(const StringName
}
void AnimationNodeStateMachine::add_node(const StringName &p_name, Ref<AnimationNode> p_node, const Vector2 &p_position) {
-
ERR_FAIL_COND(states.has(p_name));
ERR_FAIL_COND(p_node.is_null());
ERR_FAIL_COND(String(p_name).find("/") != -1);
@@ -562,11 +554,30 @@ void AnimationNodeStateMachine::add_node(const StringName &p_name, Ref<Animation
emit_changed();
emit_signal("tree_changed");
- p_node->connect("tree_changed", this, "_tree_changed", varray(), CONNECT_REFERENCE_COUNTED);
+ p_node->connect("tree_changed", callable_mp(this, &AnimationNodeStateMachine::_tree_changed), varray(), CONNECT_REFERENCE_COUNTED);
}
-Ref<AnimationNode> AnimationNodeStateMachine::get_node(const StringName &p_name) const {
+void AnimationNodeStateMachine::replace_node(const StringName &p_name, Ref<AnimationNode> p_node) {
+ ERR_FAIL_COND(states.has(p_name) == false);
+ ERR_FAIL_COND(p_node.is_null());
+ ERR_FAIL_COND(String(p_name).find("/") != -1);
+
+ {
+ Ref<AnimationNode> node = states[p_name].node;
+ if (node.is_valid()) {
+ node->disconnect_compat("tree_changed", this, "_tree_changed");
+ }
+ }
+
+ states[p_name].node = p_node;
+
+ emit_changed();
+ emit_signal("tree_changed");
+ p_node->connect_compat("tree_changed", this, "_tree_changed", varray(), CONNECT_REFERENCE_COUNTED);
+}
+
+Ref<AnimationNode> AnimationNodeStateMachine::get_node(const StringName &p_name) const {
ERR_FAIL_COND_V(!states.has(p_name), Ref<AnimationNode>());
return states[p_name].node;
@@ -602,8 +613,8 @@ void AnimationNodeStateMachine::get_child_nodes(List<ChildNode> *r_child_nodes)
bool AnimationNodeStateMachine::has_node(const StringName &p_name) const {
return states.has(p_name);
}
-void AnimationNodeStateMachine::remove_node(const StringName &p_name) {
+void AnimationNodeStateMachine::remove_node(const StringName &p_name) {
ERR_FAIL_COND(!states.has(p_name));
{
@@ -611,7 +622,7 @@ void AnimationNodeStateMachine::remove_node(const StringName &p_name) {
ERR_FAIL_COND(node.is_null());
- node->disconnect("tree_changed", this, "_tree_changed");
+ node->disconnect("tree_changed", callable_mp(this, &AnimationNodeStateMachine::_tree_changed));
}
states.erase(p_name);
@@ -619,7 +630,7 @@ void AnimationNodeStateMachine::remove_node(const StringName &p_name) {
for (int i = 0; i < transitions.size(); i++) {
if (transitions[i].from == p_name || transitions[i].to == p_name) {
- transitions.write[i].transition->disconnect("advance_condition_changed", this, "_tree_changed");
+ transitions.write[i].transition->disconnect("advance_condition_changed", callable_mp(this, &AnimationNodeStateMachine::_tree_changed));
transitions.remove(i);
i--;
}
@@ -642,7 +653,6 @@ void AnimationNodeStateMachine::remove_node(const StringName &p_name) {
}
void AnimationNodeStateMachine::rename_node(const StringName &p_name, const StringName &p_new_name) {
-
ERR_FAIL_COND(!states.has(p_name));
ERR_FAIL_COND(states.has(p_new_name));
@@ -676,7 +686,6 @@ void AnimationNodeStateMachine::rename_node(const StringName &p_name, const Stri
}
void AnimationNodeStateMachine::get_node_list(List<StringName> *r_nodes) const {
-
List<StringName> nodes;
for (Map<StringName, State>::Element *E = states.front(); E; E = E->next()) {
nodes.push_back(E->key());
@@ -689,25 +698,24 @@ void AnimationNodeStateMachine::get_node_list(List<StringName> *r_nodes) const {
}
bool AnimationNodeStateMachine::has_transition(const StringName &p_from, const StringName &p_to) const {
-
for (int i = 0; i < transitions.size(); i++) {
- if (transitions[i].from == p_from && transitions[i].to == p_to)
+ if (transitions[i].from == p_from && transitions[i].to == p_to) {
return true;
+ }
}
return false;
}
int AnimationNodeStateMachine::find_transition(const StringName &p_from, const StringName &p_to) const {
-
for (int i = 0; i < transitions.size(); i++) {
- if (transitions[i].from == p_from && transitions[i].to == p_to)
+ if (transitions[i].from == p_from && transitions[i].to == p_to) {
return i;
+ }
}
return -1;
}
void AnimationNodeStateMachine::add_transition(const StringName &p_from, const StringName &p_to, const Ref<AnimationNodeStateMachineTransition> &p_transition) {
-
ERR_FAIL_COND(p_from == p_to);
ERR_FAIL_COND(!states.has(p_from));
ERR_FAIL_COND(!states.has(p_to));
@@ -722,7 +730,7 @@ void AnimationNodeStateMachine::add_transition(const StringName &p_from, const S
tr.to = p_to;
tr.transition = p_transition;
- tr.transition->connect("advance_condition_changed", this, "_tree_changed", varray(), CONNECT_REFERENCE_COUNTED);
+ tr.transition->connect("advance_condition_changed", callable_mp(this, &AnimationNodeStateMachine::_tree_changed), varray(), CONNECT_REFERENCE_COUNTED);
transitions.push_back(tr);
}
@@ -731,26 +739,25 @@ Ref<AnimationNodeStateMachineTransition> AnimationNodeStateMachine::get_transiti
ERR_FAIL_INDEX_V(p_transition, transitions.size(), Ref<AnimationNodeStateMachineTransition>());
return transitions[p_transition].transition;
}
-StringName AnimationNodeStateMachine::get_transition_from(int p_transition) const {
+StringName AnimationNodeStateMachine::get_transition_from(int p_transition) const {
ERR_FAIL_INDEX_V(p_transition, transitions.size(), StringName());
return transitions[p_transition].from;
}
-StringName AnimationNodeStateMachine::get_transition_to(int p_transition) const {
+StringName AnimationNodeStateMachine::get_transition_to(int p_transition) const {
ERR_FAIL_INDEX_V(p_transition, transitions.size(), StringName());
return transitions[p_transition].to;
}
int AnimationNodeStateMachine::get_transition_count() const {
-
return transitions.size();
}
-void AnimationNodeStateMachine::remove_transition(const StringName &p_from, const StringName &p_to) {
+void AnimationNodeStateMachine::remove_transition(const StringName &p_from, const StringName &p_to) {
for (int i = 0; i < transitions.size(); i++) {
if (transitions[i].from == p_from && transitions[i].to == p_to) {
- transitions.write[i].transition->disconnect("advance_condition_changed", this, "_tree_changed");
+ transitions.write[i].transition->disconnect("advance_condition_changed", callable_mp(this, &AnimationNodeStateMachine::_tree_changed));
transitions.remove(i);
return;
}
@@ -762,9 +769,8 @@ void AnimationNodeStateMachine::remove_transition(const StringName &p_from, cons
}
void AnimationNodeStateMachine::remove_transition_by_index(int p_transition) {
-
ERR_FAIL_INDEX(p_transition, transitions.size());
- transitions.write[p_transition].transition->disconnect("advance_condition_changed", this, "_tree_changed");
+ transitions.write[p_transition].transition->disconnect("advance_condition_changed", callable_mp(this, &AnimationNodeStateMachine::_tree_changed));
transitions.remove(p_transition);
/*if (playing) {
path.clear();
@@ -772,24 +778,20 @@ void AnimationNodeStateMachine::remove_transition_by_index(int p_transition) {
}
void AnimationNodeStateMachine::set_start_node(const StringName &p_node) {
-
ERR_FAIL_COND(p_node != StringName() && !states.has(p_node));
start_node = p_node;
}
String AnimationNodeStateMachine::get_start_node() const {
-
return start_node;
}
void AnimationNodeStateMachine::set_end_node(const StringName &p_node) {
-
ERR_FAIL_COND(p_node != StringName() && !states.has(p_node));
end_node = p_node;
}
String AnimationNodeStateMachine::get_end_node() const {
-
return end_node;
}
@@ -802,7 +804,6 @@ Vector2 AnimationNodeStateMachine::get_graph_offset() const {
}
float AnimationNodeStateMachine::process(float p_time, bool p_seek) {
-
Ref<AnimationNodeStateMachinePlayback> playback = get_parameter(this->playback);
ERR_FAIL_COND_V(playback.is_null(), 0.0);
@@ -821,7 +822,6 @@ Ref<AnimationNode> AnimationNodeStateMachine::get_child_by_name(const StringName
}
bool AnimationNodeStateMachine::_set(const StringName &p_name, const Variant &p_value) {
-
String name = p_name;
if (name.begins_with("states/")) {
String node_name = name.get_slicec('/', 1);
@@ -836,14 +836,12 @@ bool AnimationNodeStateMachine::_set(const StringName &p_name, const Variant &p_
}
if (what == "position") {
-
if (states.has(node_name)) {
states[node_name].position = p_value;
}
return true;
}
} else if (name == "transitions") {
-
Array trans = p_value;
ERR_FAIL_COND_V(trans.size() % 3 != 0, false);
@@ -866,7 +864,6 @@ bool AnimationNodeStateMachine::_set(const StringName &p_name, const Variant &p_
}
bool AnimationNodeStateMachine::_get(const StringName &p_name, Variant &r_ret) const {
-
String name = p_name;
if (name.begins_with("states/")) {
String node_name = name.get_slicec('/', 1);
@@ -880,7 +877,6 @@ bool AnimationNodeStateMachine::_get(const StringName &p_name, Variant &r_ret) c
}
if (what == "position") {
-
if (states.has(node_name)) {
r_ret = states[node_name].position;
return true;
@@ -911,8 +907,8 @@ bool AnimationNodeStateMachine::_get(const StringName &p_name, Variant &r_ret) c
return false;
}
-void AnimationNodeStateMachine::_get_property_list(List<PropertyInfo> *p_list) const {
+void AnimationNodeStateMachine::_get_property_list(List<PropertyInfo> *p_list) const {
List<StringName> names;
for (Map<StringName, State>::Element *E = states.front(); E; E = E->next()) {
names.push_back(E->key());
@@ -926,8 +922,8 @@ void AnimationNodeStateMachine::_get_property_list(List<PropertyInfo> *p_list) c
}
p_list->push_back(PropertyInfo(Variant::ARRAY, "transitions", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
- p_list->push_back(PropertyInfo(Variant::STRING, "start_node", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
- p_list->push_back(PropertyInfo(Variant::STRING, "end_node", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::STRING_NAME, "start_node", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::STRING_NAME, "end_node", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
p_list->push_back(PropertyInfo(Variant::VECTOR2, "graph_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
}
@@ -937,7 +933,6 @@ void AnimationNodeStateMachine::set_node_position(const StringName &p_name, cons
}
Vector2 AnimationNodeStateMachine::get_node_position(const StringName &p_name) const {
-
ERR_FAIL_COND_V(!states.has(p_name), Vector2());
return states[p_name].position;
}
@@ -947,8 +942,8 @@ void AnimationNodeStateMachine::_tree_changed() {
}
void AnimationNodeStateMachine::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("add_node", "name", "node", "position"), &AnimationNodeStateMachine::add_node, DEFVAL(Vector2()));
+ ClassDB::bind_method(D_METHOD("replace_node", "name", "node"), &AnimationNodeStateMachine::replace_node);
ClassDB::bind_method(D_METHOD("get_node", "name"), &AnimationNodeStateMachine::get_node);
ClassDB::bind_method(D_METHOD("remove_node", "name"), &AnimationNodeStateMachine::remove_node);
ClassDB::bind_method(D_METHOD("rename_node", "name", "new_name"), &AnimationNodeStateMachine::rename_node);
@@ -975,11 +970,8 @@ void AnimationNodeStateMachine::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_graph_offset", "offset"), &AnimationNodeStateMachine::set_graph_offset);
ClassDB::bind_method(D_METHOD("get_graph_offset"), &AnimationNodeStateMachine::get_graph_offset);
-
- ClassDB::bind_method(D_METHOD("_tree_changed"), &AnimationNodeStateMachine::_tree_changed);
}
AnimationNodeStateMachine::AnimationNodeStateMachine() {
-
playback = "playback";
}
diff --git a/scene/animation/animation_node_state_machine.h b/scene/animation/animation_node_state_machine.h
index 55c9c3f00e..ae8975e940 100644
--- a/scene/animation/animation_node_state_machine.h
+++ b/scene/animation/animation_node_state_machine.h
@@ -134,7 +134,6 @@ public:
};
class AnimationNodeStateMachine : public AnimationRootNode {
-
GDCLASS(AnimationNodeStateMachine, AnimationRootNode);
private:
@@ -148,7 +147,6 @@ private:
Map<StringName, State> states;
struct Transition {
-
StringName from;
StringName to;
Ref<AnimationNodeStateMachineTransition> transition;
@@ -174,10 +172,11 @@ protected:
void _get_property_list(List<PropertyInfo> *p_list) const;
public:
- virtual void get_parameter_list(List<PropertyInfo> *r_list) const;
- virtual Variant get_parameter_default_value(const StringName &p_parameter) const;
+ virtual void get_parameter_list(List<PropertyInfo> *r_list) const override;
+ virtual Variant get_parameter_default_value(const StringName &p_parameter) const override;
void add_node(const StringName &p_name, Ref<AnimationNode> p_node, const Vector2 &p_position = Vector2());
+ void replace_node(const StringName &p_name, Ref<AnimationNode> p_node);
Ref<AnimationNode> get_node(const StringName &p_name) const;
void remove_node(const StringName &p_name);
void rename_node(const StringName &p_name, const StringName &p_new_name);
@@ -188,7 +187,7 @@ public:
void set_node_position(const StringName &p_name, const Vector2 &p_position);
Vector2 get_node_position(const StringName &p_name) const;
- virtual void get_child_nodes(List<ChildNode> *r_child_nodes);
+ virtual void get_child_nodes(List<ChildNode> *r_child_nodes) override;
bool has_transition(const StringName &p_from, const StringName &p_to) const;
int find_transition(const StringName &p_from, const StringName &p_to) const;
@@ -209,10 +208,10 @@ public:
void set_graph_offset(const Vector2 &p_offset);
Vector2 get_graph_offset() const;
- virtual float process(float p_time, bool p_seek);
- virtual String get_caption() const;
+ virtual float process(float p_time, bool p_seek) override;
+ virtual String get_caption() const override;
- virtual Ref<AnimationNode> get_child_by_name(const StringName &p_name);
+ virtual Ref<AnimationNode> get_child_by_name(const StringName &p_name) override;
AnimationNodeStateMachine();
};
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index 2bc9336b14..66c587e2d4 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -40,11 +40,10 @@
#include "scene/2d/skeleton_2d.h"
void AnimatedValuesBackup::update_skeletons() {
-
for (int i = 0; i < entries.size(); i++) {
if (entries[i].bone_idx != -1) {
// 3D bone
- Object::cast_to<Skeleton>(entries[i].object)->notification(Skeleton::NOTIFICATION_UPDATE_SKELETON);
+ Object::cast_to<Skeleton3D>(entries[i].object)->notification(Skeleton3D::NOTIFICATION_UPDATE_SKELETON);
} else {
Bone2D *bone = Object::cast_to<Bone2D>(entries[i].object);
if (bone && bone->skeleton) {
@@ -57,7 +56,6 @@ void AnimatedValuesBackup::update_skeletons() {
#endif
bool AnimationPlayer::_set(const StringName &p_name, const Variant &p_value) {
-
String name = p_name;
if (name.begins_with("playback/play")) { // bw compatibility
@@ -65,23 +63,19 @@ bool AnimationPlayer::_set(const StringName &p_name, const Variant &p_value) {
set_current_animation(p_value);
} else if (name.begins_with("anims/")) {
-
String which = name.get_slicec('/', 1);
add_animation(which, p_value);
} else if (name.begins_with("next/")) {
-
String which = name.get_slicec('/', 1);
animation_set_next(which, p_value);
} else if (p_name == SceneStringNames::get_singleton()->blend_times) {
-
Array array = p_value;
int len = array.size();
ERR_FAIL_COND_V(len % 3, false);
for (int i = 0; i < len / 3; i++) {
-
StringName from = array[i * 3 + 0];
StringName to = array[i * 3 + 1];
float time = array[i * 3 + 2];
@@ -89,14 +83,14 @@ bool AnimationPlayer::_set(const StringName &p_name, const Variant &p_value) {
set_blend_time(from, to, time);
}
- } else
+ } else {
return false;
+ }
return true;
}
bool AnimationPlayer::_get(const StringName &p_name, Variant &r_ret) const {
-
String name = p_name;
if (name == "playback/play") { // bw compatibility
@@ -104,41 +98,36 @@ bool AnimationPlayer::_get(const StringName &p_name, Variant &r_ret) const {
r_ret = get_current_animation();
} else if (name.begins_with("anims/")) {
-
String which = name.get_slicec('/', 1);
- r_ret = get_animation(which).get_ref_ptr();
+ r_ret = get_animation(which);
} else if (name.begins_with("next/")) {
-
String which = name.get_slicec('/', 1);
r_ret = animation_get_next(which);
} else if (name == "blend_times") {
-
Vector<BlendKey> keys;
for (Map<BlendKey, float>::Element *E = blend_times.front(); E; E = E->next()) {
-
keys.ordered_insert(E->key());
}
Array array;
for (int i = 0; i < keys.size(); i++) {
-
array.push_back(keys[i].from);
array.push_back(keys[i].to);
array.push_back(blend_times[keys[i]]);
}
r_ret = array;
- } else
+ } else {
return false;
+ }
return true;
}
void AnimationPlayer::_validate_property(PropertyInfo &property) const {
-
if (property.name == "current_animation") {
List<String> names;
@@ -149,9 +138,9 @@ void AnimationPlayer::_validate_property(PropertyInfo &property) const {
names.push_front("[stop]");
String hint;
for (List<String>::Element *E = names.front(); E; E = E->next()) {
-
- if (E != names.front())
+ if (E != names.front()) {
hint += ",";
+ }
hint += E->get();
}
@@ -160,14 +149,13 @@ void AnimationPlayer::_validate_property(PropertyInfo &property) const {
}
void AnimationPlayer::_get_property_list(List<PropertyInfo> *p_list) const {
-
List<PropertyInfo> anim_names;
for (Map<StringName, AnimationData>::Element *E = animation_set.front(); E; E = E->next()) {
-
anim_names.push_back(PropertyInfo(Variant::OBJECT, "anims/" + String(E->key()), PROPERTY_HINT_RESOURCE_TYPE, "Animation", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE));
- if (E->get().next != StringName())
+ if (E->get().next != StringName()) {
anim_names.push_back(PropertyInfo(Variant::STRING, "next/" + String(E->key()), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
+ }
}
anim_names.sort();
@@ -180,16 +168,12 @@ void AnimationPlayer::_get_property_list(List<PropertyInfo> *p_list) const {
}
void AnimationPlayer::advance(float p_time) {
-
_animation_process(p_time);
}
void AnimationPlayer::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_ENTER_TREE: {
-
if (!processing) {
//make sure that a previous process state was not saved
//only process if "processing" is set
@@ -200,39 +184,40 @@ void AnimationPlayer::_notification(int p_what) {
clear_caches();
} break;
case NOTIFICATION_READY: {
-
if (!Engine::get_singleton()->is_editor_hint() && animation_set.has(autoplay)) {
play(autoplay);
_animation_process(0);
}
} break;
case NOTIFICATION_INTERNAL_PROCESS: {
- if (animation_process_mode == ANIMATION_PROCESS_PHYSICS)
+ if (animation_process_mode == ANIMATION_PROCESS_PHYSICS) {
break;
+ }
- if (processing)
+ if (processing) {
_animation_process(get_process_delta_time());
+ }
} break;
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
-
- if (animation_process_mode == ANIMATION_PROCESS_IDLE)
+ if (animation_process_mode == ANIMATION_PROCESS_IDLE) {
break;
+ }
- if (processing)
+ if (processing) {
_animation_process(get_physics_process_delta_time());
+ }
} break;
case NOTIFICATION_EXIT_TREE: {
-
clear_caches();
} break;
}
}
void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim) {
-
// Already cached?
- if (p_anim->node_cache.size() == p_anim->animation->get_track_count())
+ if (p_anim->node_cache.size() == p_anim->animation->get_track_count()) {
return;
+ }
Node *parent = get_node(root);
@@ -243,36 +228,35 @@ void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim) {
p_anim->node_cache.resize(a->get_track_count());
for (int i = 0; i < a->get_track_count(); i++) {
-
- p_anim->node_cache.write[i] = NULL;
+ p_anim->node_cache.write[i] = nullptr;
RES resource;
Vector<StringName> leftover_path;
Node *child = parent->get_node_and_resource(a->track_get_path(i), resource, leftover_path);
ERR_CONTINUE_MSG(!child, "On Animation: '" + p_anim->name + "', couldn't resolve track: '" + String(a->track_get_path(i)) + "'."); // couldn't find the child node
- uint32_t id = resource.is_valid() ? resource->get_instance_id() : child->get_instance_id();
+ ObjectID id = resource.is_valid() ? resource->get_instance_id() : child->get_instance_id();
int bone_idx = -1;
- if (a->track_get_path(i).get_subname_count() == 1 && Object::cast_to<Skeleton>(child)) {
-
- Skeleton *sk = Object::cast_to<Skeleton>(child);
+ if (a->track_get_path(i).get_subname_count() == 1 && Object::cast_to<Skeleton3D>(child)) {
+ Skeleton3D *sk = Object::cast_to<Skeleton3D>(child);
bone_idx = sk->find_bone(a->track_get_path(i).get_subname(0));
if (bone_idx == -1) {
-
continue;
}
}
{
- if (!child->is_connected("tree_exiting", this, "_node_removed"))
- child->connect("tree_exiting", this, "_node_removed", make_binds(child), CONNECT_ONESHOT);
+ if (!child->is_connected("tree_exiting", callable_mp(this, &AnimationPlayer::_node_removed))) {
+ child->connect("tree_exiting", callable_mp(this, &AnimationPlayer::_node_removed), make_binds(child), CONNECT_ONESHOT);
+ }
}
TrackNodeCacheKey key;
key.id = id;
key.bone_idx = bone_idx;
- if (!node_cache_map.has(key))
+ if (!node_cache_map.has(key)) {
node_cache_map[key] = TrackNodeCache();
+ }
p_anim->node_cache.write[i] = &node_cache_map[key];
p_anim->node_cache[i]->path = a->track_get_path(i);
@@ -283,9 +267,9 @@ void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim) {
// special cases and caches for transform tracks
// cache spatial
- p_anim->node_cache[i]->spatial = Object::cast_to<Spatial>(child);
+ p_anim->node_cache[i]->spatial = Object::cast_to<Node3D>(child);
// cache skeleton
- p_anim->node_cache[i]->skeleton = Object::cast_to<Skeleton>(child);
+ p_anim->node_cache[i]->skeleton = Object::cast_to<Skeleton3D>(child);
if (p_anim->node_cache[i]->skeleton) {
if (a->track_get_path(i).get_subname_count() == 1) {
StringName bone_name = a->track_get_path(i).get_subname(0);
@@ -293,43 +277,39 @@ void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim) {
p_anim->node_cache[i]->bone_idx = p_anim->node_cache[i]->skeleton->find_bone(bone_name);
if (p_anim->node_cache[i]->bone_idx < 0) {
// broken track (nonexistent bone)
- p_anim->node_cache[i]->skeleton = NULL;
- p_anim->node_cache[i]->spatial = NULL;
+ p_anim->node_cache[i]->skeleton = nullptr;
+ p_anim->node_cache[i]->spatial = nullptr;
ERR_CONTINUE(p_anim->node_cache[i]->bone_idx < 0);
}
} else {
// no property, just use spatialnode
- p_anim->node_cache[i]->skeleton = NULL;
+ p_anim->node_cache[i]->skeleton = nullptr;
}
}
}
if (a->track_get_type(i) == Animation::TYPE_VALUE) {
-
if (!p_anim->node_cache[i]->property_anim.has(a->track_get_path(i).get_concatenated_subnames())) {
-
TrackNodeCache::PropertyAnim pa;
pa.subpath = leftover_path;
pa.object = resource.is_valid() ? (Object *)resource.ptr() : (Object *)child;
pa.special = SP_NONE;
pa.owner = p_anim->node_cache[i];
if (false && p_anim->node_cache[i]->node_2d) {
-
- if (leftover_path.size() == 1 && leftover_path[0] == SceneStringNames::get_singleton()->transform_pos)
+ if (leftover_path.size() == 1 && leftover_path[0] == SceneStringNames::get_singleton()->transform_pos) {
pa.special = SP_NODE2D_POS;
- else if (leftover_path.size() == 1 && leftover_path[0] == SceneStringNames::get_singleton()->transform_rot)
+ } else if (leftover_path.size() == 1 && leftover_path[0] == SceneStringNames::get_singleton()->transform_rot) {
pa.special = SP_NODE2D_ROT;
- else if (leftover_path.size() == 1 && leftover_path[0] == SceneStringNames::get_singleton()->transform_scale)
+ } else if (leftover_path.size() == 1 && leftover_path[0] == SceneStringNames::get_singleton()->transform_scale) {
pa.special = SP_NODE2D_SCALE;
+ }
}
p_anim->node_cache[i]->property_anim[a->track_get_path(i).get_concatenated_subnames()] = pa;
}
}
if (a->track_get_type(i) == Animation::TYPE_BEZIER && leftover_path.size()) {
-
if (!p_anim->node_cache[i]->bezier_anim.has(a->track_get_path(i).get_concatenated_subnames())) {
-
TrackNodeCache::BezierAnim ba;
ba.bezier_property = leftover_path;
ba.object = resource.is_valid() ? (Object *)resource.ptr() : (Object *)child;
@@ -342,7 +322,6 @@ void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim) {
}
void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float p_time, float p_delta, float p_interp, bool p_is_current, bool p_seeked, bool p_started) {
-
_ensure_node_caches(p_anim);
ERR_FAIL_COND(p_anim->node_cache.size() != p_anim->animation->get_track_count());
@@ -350,7 +329,6 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
bool can_call = is_inside_tree() && !Engine::get_singleton()->is_editor_hint();
for (int i = 0; i < a->get_track_count(); i++) {
-
// If an animation changes this animation (or it animates itself)
// we need to recreate our animation cache
if (p_anim->node_cache.size() != a->get_track_count()) {
@@ -359,21 +337,23 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
TrackNodeCache *nc = p_anim->node_cache[i];
- if (!nc)
+ if (!nc) {
continue; // no node cache for this track, skip it
+ }
- if (!a->track_is_enabled(i))
+ if (!a->track_is_enabled(i)) {
continue; // do nothing if the track is disabled
+ }
- if (a->track_get_key_count(i) == 0)
+ if (a->track_get_key_count(i) == 0) {
continue; // do nothing if track is empty
+ }
switch (a->track_get_type(i)) {
-
case Animation::TYPE_TRANSFORM: {
-
- if (!nc->spatial)
+ if (!nc->spatial) {
continue;
+ }
Vector3 loc;
Quat rot;
@@ -382,8 +362,9 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
Error err = a->transform_track_interpolate(i, p_time, &loc, &rot, &scale);
//ERR_CONTINUE(err!=OK); //used for testing, should be removed
- if (err != OK)
+ if (err != OK) {
continue;
+ }
if (nc->accum_pass != accum_pass) {
ERR_CONTINUE(cache_update_size >= NODE_CACHE_UPDATE_MAX);
@@ -394,17 +375,16 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
nc->scale_accum = scale;
} else {
-
- nc->loc_accum = nc->loc_accum.linear_interpolate(loc, p_interp);
+ nc->loc_accum = nc->loc_accum.lerp(loc, p_interp);
nc->rot_accum = nc->rot_accum.slerp(rot, p_interp);
- nc->scale_accum = nc->scale_accum.linear_interpolate(scale, p_interp);
+ nc->scale_accum = nc->scale_accum.lerp(scale, p_interp);
}
} break;
case Animation::TYPE_VALUE: {
-
- if (!nc->node)
+ if (!nc->node) {
continue;
+ }
//StringName property=a->track_get_path(i).get_property();
@@ -416,14 +396,14 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
Animation::UpdateMode update_mode = a->value_track_get_update_mode(i);
if (update_mode == Animation::UPDATE_CAPTURE) {
-
- if (p_started) {
+ if (p_started || pa->capture == Variant()) {
pa->capture = pa->object->get_indexed(pa->subpath);
}
int key_count = a->track_get_key_count(i);
- if (key_count == 0)
+ if (key_count == 0) {
continue; //eeh not worth it
+ }
float first_key_time = a->track_get_key_time(i, 0);
float transition = 1.0;
@@ -431,8 +411,9 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
if (first_key_time == 0.0) {
//ignore, use for transition
- if (key_count == 1)
+ if (key_count == 1) {
continue; //with one key we can't do anything
+ }
transition = a->track_get_key_transition(i, 0);
first_key_time = a->track_get_key_time(i, 1);
first_key = 1;
@@ -461,8 +442,9 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
Variant value = a->value_track_interpolate(i, p_time);
- if (value == Variant())
+ if (value == Variant()) {
continue;
+ }
//thanks to trigger mode, this should be solved now..
/*
@@ -479,21 +461,18 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
}
} else if (p_is_current && p_delta != 0) {
-
List<int> indices;
a->value_track_get_key_indices(i, p_time, p_delta, &indices);
for (List<int>::Element *F = indices.front(); F; F = F->next()) {
-
Variant value = a->track_get_key_value(i, F->get());
switch (pa->special) {
-
case SP_NONE: {
bool valid;
pa->object->set_indexed(pa->subpath, value, &valid); //you are not speshul
#ifdef DEBUG_ENABLED
if (!valid) {
- ERR_PRINTS("Failed setting track value '" + String(pa->owner->path) + "'. Check if property exists or the type of key is valid. Animation '" + a->get_name() + "' at node '" + get_path() + "'.");
+ ERR_PRINT("Failed setting track value '" + String(pa->owner->path) + "'. Check if property exists or the type of key is valid. Animation '" + a->get_name() + "' at node '" + get_path() + "'.");
}
#endif
@@ -501,7 +480,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
case SP_NODE2D_POS: {
#ifdef DEBUG_ENABLED
if (value.get_type() != Variant::VECTOR2) {
- ERR_PRINTS("Position key at time " + rtos(p_time) + " in Animation Track '" + String(pa->owner->path) + "' not of type Vector2(). Animation '" + a->get_name() + "' at node '" + get_path() + "'.");
+ ERR_PRINT("Position key at time " + rtos(p_time) + " in Animation Track '" + String(pa->owner->path) + "' not of type Vector2(). Animation '" + a->get_name() + "' at node '" + get_path() + "'.");
}
#endif
static_cast<Node2D *>(pa->object)->set_position(value);
@@ -509,7 +488,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
case SP_NODE2D_ROT: {
#ifdef DEBUG_ENABLED
if (value.is_num()) {
- ERR_PRINTS("Rotation key at time " + rtos(p_time) + " in Animation Track '" + String(pa->owner->path) + "' not numerical. Animation '" + a->get_name() + "' at node '" + get_path() + "'.");
+ ERR_PRINT("Rotation key at time " + rtos(p_time) + " in Animation Track '" + String(pa->owner->path) + "' not numerical. Animation '" + a->get_name() + "' at node '" + get_path() + "'.");
}
#endif
@@ -518,7 +497,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
case SP_NODE2D_SCALE: {
#ifdef DEBUG_ENABLED
if (value.get_type() != Variant::VECTOR2) {
- ERR_PRINTS("Scale key at time " + rtos(p_time) + " in Animation Track '" + String(pa->owner->path) + "' not of type Vector2()." + a->get_name() + "' at node '" + get_path() + "'.");
+ ERR_PRINT("Scale key at time " + rtos(p_time) + " in Animation Track '" + String(pa->owner->path) + "' not of type Vector2()." + a->get_name() + "' at node '" + get_path() + "'.");
}
#endif
@@ -530,21 +509,21 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
} break;
case Animation::TYPE_METHOD: {
-
- if (!nc->node)
+ if (!nc->node) {
continue;
+ }
if (p_delta == 0) {
continue;
}
- if (!p_is_current)
+ if (!p_is_current) {
break;
+ }
List<int> indices;
a->method_track_get_key_indices(i, p_time, p_delta, &indices);
for (List<int>::Element *E = indices.front(); E; E = E->next()) {
-
StringName method = a->method_track_get_name(i, E->get());
Vector<Variant> params = a->method_track_get_params(i, E->get());
@@ -553,7 +532,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
ERR_CONTINUE(s > VARIANT_ARG_MAX);
#ifdef DEBUG_ENABLED
if (!nc->node->has_method(method)) {
- ERR_PRINTS("Invalid method call '" + method + "'. '" + a->get_name() + "' at node '" + get_path() + "'.");
+ ERR_PRINT("Invalid method call '" + method + "'. '" + a->get_name() + "' at node '" + get_path() + "'.");
}
#endif
@@ -581,9 +560,9 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
} break;
case Animation::TYPE_BEZIER: {
-
- if (!nc->node)
+ if (!nc->node) {
continue;
+ }
Map<StringName, TrackNodeCache::BezierAnim>::Element *E = nc->bezier_anim.find(a->track_get_path(i).get_concatenated_subnames());
ERR_CONTINUE(!E); //should it continue, or create a new one?
@@ -602,9 +581,9 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
} break;
case Animation::TYPE_AUDIO: {
-
- if (!nc->node)
+ if (!nc->node) {
continue;
+ }
if (p_delta == 0) {
continue;
}
@@ -612,8 +591,9 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
if (p_seeked) {
//find whathever should be playing
int idx = a->track_find_key(i, p_time);
- if (idx < 0)
+ if (idx < 0) {
continue;
+ }
Ref<AudioStream> stream = a->audio_track_get_key_stream(i, idx);
if (!stream.is_valid()) {
@@ -678,7 +658,6 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
nc->audio_start = p_time;
}
} else if (nc->audio_playing) {
-
bool loop = a->has_loop();
bool stop = false;
@@ -704,22 +683,24 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
} break;
case Animation::TYPE_ANIMATION: {
-
AnimationPlayer *player = Object::cast_to<AnimationPlayer>(nc->node);
- if (!player)
+ if (!player) {
continue;
+ }
if (p_delta == 0 || p_seeked) {
//seek
int idx = a->track_find_key(i, p_time);
- if (idx < 0)
+ if (idx < 0) {
continue;
+ }
float pos = a->track_get_key_time(i, idx);
StringName anim_name = a->animation_track_get_key_animation(i, idx);
- if (String(anim_name) == "[stop]" || !player->has_animation(anim_name))
+ if (String(anim_name) == "[stop]" || !player->has_animation(anim_name)) {
continue;
+ }
Ref<Animation> anim = player->get_animation(anim_name);
@@ -749,7 +730,6 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
StringName anim_name = a->animation_track_get_key_animation(i, idx);
if (String(anim_name) == "[stop]" || !player->has_animation(anim_name)) {
-
if (playing_caches.has(nc)) {
playing_caches.erase(nc);
player->stop();
@@ -769,7 +749,6 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
}
void AnimationPlayer::_animation_process_data(PlaybackData &cd, float p_delta, float p_blend, bool p_seeked, bool p_started) {
-
float delta = p_delta * speed_scale * cd.speed_scale;
float next_pos = cd.pos + delta;
@@ -777,17 +756,16 @@ void AnimationPlayer::_animation_process_data(PlaybackData &cd, float p_delta, f
bool loop = cd.from->animation->has_loop();
if (!loop) {
-
- if (next_pos < 0)
+ if (next_pos < 0) {
next_pos = 0;
- else if (next_pos > len)
+ } else if (next_pos > len) {
next_pos = len;
+ }
// fix delta
delta = next_pos - cd.pos;
if (&cd == &playback.current) {
-
bool backwards = delta < 0;
if (!backwards && cd.pos <= len && next_pos == len /*&& playback.blend.empty()*/) {
@@ -804,7 +782,6 @@ void AnimationPlayer::_animation_process_data(PlaybackData &cd, float p_delta, f
}
} else {
-
float looped_next_pos = Math::fposmod(next_pos, len);
if (looped_next_pos == 0 && next_pos != 0) {
// Loop multiples of the length to it, rather than 0
@@ -819,8 +796,8 @@ void AnimationPlayer::_animation_process_data(PlaybackData &cd, float p_delta, f
_animation_process_animation(cd.from, cd.pos, delta, p_blend, &cd == &playback.current, p_seeked, p_started);
}
-void AnimationPlayer::_animation_process2(float p_delta, bool p_started) {
+void AnimationPlayer::_animation_process2(float p_delta, bool p_started) {
Playback &c = playback;
accum_pass++;
@@ -830,9 +807,8 @@ void AnimationPlayer::_animation_process2(float p_delta, bool p_started) {
c.seeked = false;
}
- List<Blend>::Element *prev = NULL;
+ List<Blend>::Element *prev = nullptr;
for (List<Blend>::Element *E = c.blend.back(); E; E = prev) {
-
Blend &b = E->get();
float blend = b.blend_left / b.blend_time;
_animation_process_data(b.data, p_delta, blend, false, false);
@@ -841,7 +817,6 @@ void AnimationPlayer::_animation_process2(float p_delta, bool p_started) {
prev = E->prev();
if (b.blend_left < 0) {
-
c.blend.erase(E);
}
}
@@ -851,7 +826,6 @@ void AnimationPlayer::_animation_update_transforms() {
{
Transform t;
for (int i = 0; i < cache_update_size; i++) {
-
TrackNodeCache *nc = cache_update[i];
ERR_CONTINUE(nc->accum_pass != accum_pass);
@@ -859,11 +833,9 @@ void AnimationPlayer::_animation_update_transforms() {
t.origin = nc->loc_accum;
t.basis.set_quat_scale(nc->rot_accum, nc->scale_accum);
if (nc->skeleton && nc->bone_idx >= 0) {
-
nc->skeleton->set_bone_pose(nc->bone_idx, t);
} else if (nc->spatial) {
-
nc->spatial->set_transform(t);
}
}
@@ -872,19 +844,17 @@ void AnimationPlayer::_animation_update_transforms() {
cache_update_size = 0;
for (int i = 0; i < cache_update_prop_size; i++) {
-
TrackNodeCache::PropertyAnim *pa = cache_update_prop[i];
ERR_CONTINUE(pa->accum_pass != accum_pass);
switch (pa->special) {
-
case SP_NONE: {
bool valid;
pa->object->set_indexed(pa->subpath, pa->value_accum, &valid); //you are not speshul
#ifdef DEBUG_ENABLED
if (!valid) {
- ERR_PRINTS("Failed setting key at time " + rtos(playback.current.pos) + " in Animation '" + get_current_animation() + "' at Node '" + get_path() + "', Track '" + String(pa->owner->path) + "'. Check if property exists or the type of key is right for the property");
+ ERR_PRINT("Failed setting key at time " + rtos(playback.current.pos) + " in Animation '" + get_current_animation() + "' at Node '" + get_path() + "', Track '" + String(pa->owner->path) + "'. Check if property exists or the type of key is right for the property");
}
#endif
@@ -892,7 +862,7 @@ void AnimationPlayer::_animation_update_transforms() {
case SP_NODE2D_POS: {
#ifdef DEBUG_ENABLED
if (pa->value_accum.get_type() != Variant::VECTOR2) {
- ERR_PRINTS("Position key at time " + rtos(playback.current.pos) + " in Animation '" + get_current_animation() + "' at Node '" + get_path() + "', Track '" + String(pa->owner->path) + "' not of type Vector2()");
+ ERR_PRINT("Position key at time " + rtos(playback.current.pos) + " in Animation '" + get_current_animation() + "' at Node '" + get_path() + "', Track '" + String(pa->owner->path) + "' not of type Vector2()");
}
#endif
static_cast<Node2D *>(pa->object)->set_position(pa->value_accum);
@@ -900,7 +870,7 @@ void AnimationPlayer::_animation_update_transforms() {
case SP_NODE2D_ROT: {
#ifdef DEBUG_ENABLED
if (pa->value_accum.is_num()) {
- ERR_PRINTS("Rotation key at time " + rtos(playback.current.pos) + " in Animation '" + get_current_animation() + "' at Node '" + get_path() + "', Track '" + String(pa->owner->path) + "' not numerical");
+ ERR_PRINT("Rotation key at time " + rtos(playback.current.pos) + " in Animation '" + get_current_animation() + "' at Node '" + get_path() + "', Track '" + String(pa->owner->path) + "' not numerical");
}
#endif
@@ -909,7 +879,7 @@ void AnimationPlayer::_animation_update_transforms() {
case SP_NODE2D_SCALE: {
#ifdef DEBUG_ENABLED
if (pa->value_accum.get_type() != Variant::VECTOR2) {
- ERR_PRINTS("Scale key at time " + rtos(playback.current.pos) + " in Animation '" + get_current_animation() + "' at Node '" + get_path() + "', Track '" + String(pa->owner->path) + "' not of type Vector2()");
+ ERR_PRINT("Scale key at time " + rtos(playback.current.pos) + " in Animation '" + get_current_animation() + "' at Node '" + get_path() + "', Track '" + String(pa->owner->path) + "' not of type Vector2()");
}
#endif
@@ -921,7 +891,6 @@ void AnimationPlayer::_animation_update_transforms() {
cache_update_prop_size = 0;
for (int i = 0; i < cache_update_bezier_size; i++) {
-
TrackNodeCache::BezierAnim *ba = cache_update_bezier[i];
ERR_CONTINUE(ba->accum_pass != accum_pass);
@@ -932,9 +901,7 @@ void AnimationPlayer::_animation_update_transforms() {
}
void AnimationPlayer::_animation_process(float p_delta) {
-
if (playback.current.from) {
-
end_reached = false;
end_notify = false;
_animation_process2(p_delta, playback.started);
@@ -950,14 +917,16 @@ void AnimationPlayer::_animation_process(float p_delta) {
play(queued.front()->get());
String new_name = playback.assigned;
queued.pop_front();
- if (end_notify)
+ if (end_notify) {
emit_signal(SceneStringNames::get_singleton()->animation_changed, old, new_name);
+ }
} else {
//stop();
playing = false;
_set_process(false);
- if (end_notify)
+ if (end_notify) {
emit_signal(SceneStringNames::get_singleton()->animation_finished, playback.assigned);
+ }
}
end_reached = false;
}
@@ -968,7 +937,6 @@ void AnimationPlayer::_animation_process(float p_delta) {
}
Error AnimationPlayer::add_animation(const StringName &p_name, const Ref<Animation> &p_animation) {
-
#ifdef DEBUG_ENABLED
ERR_FAIL_COND_V_MSG(String(p_name).find("/") != -1 || String(p_name).find(":") != -1 || String(p_name).find(",") != -1 || String(p_name).find("[") != -1, ERR_INVALID_PARAMETER, "Invalid animation name: " + String(p_name) + ".");
#endif
@@ -976,12 +944,10 @@ Error AnimationPlayer::add_animation(const StringName &p_name, const Ref<Animati
ERR_FAIL_COND_V(p_animation.is_null(), ERR_INVALID_PARAMETER);
if (animation_set.has(p_name)) {
-
_unref_anim(animation_set[p_name].animation);
animation_set[p_name].animation = p_animation;
clear_caches();
} else {
-
AnimationData ad;
ad.animation = p_animation;
ad.name = p_name;
@@ -994,7 +960,6 @@ Error AnimationPlayer::add_animation(const StringName &p_name, const Ref<Animati
}
void AnimationPlayer::remove_animation(const StringName &p_name) {
-
ERR_FAIL_COND(!animation_set.has(p_name));
stop();
@@ -1006,17 +971,14 @@ void AnimationPlayer::remove_animation(const StringName &p_name) {
}
void AnimationPlayer::_ref_anim(const Ref<Animation> &p_anim) {
-
- Ref<Animation>(p_anim)->connect(SceneStringNames::get_singleton()->tracks_changed, this, "_animation_changed", varray(), CONNECT_REFERENCE_COUNTED);
+ Ref<Animation>(p_anim)->connect(SceneStringNames::get_singleton()->tracks_changed, callable_mp(this, &AnimationPlayer::_animation_changed), varray(), CONNECT_REFERENCE_COUNTED);
}
void AnimationPlayer::_unref_anim(const Ref<Animation> &p_anim) {
-
- Ref<Animation>(p_anim)->disconnect(SceneStringNames::get_singleton()->tracks_changed, this, "_animation_changed");
+ Ref<Animation>(p_anim)->disconnect(SceneStringNames::get_singleton()->tracks_changed, callable_mp(this, &AnimationPlayer::_animation_changed));
}
void AnimationPlayer::rename_animation(const StringName &p_name, const StringName &p_new_name) {
-
ERR_FAIL_COND(!animation_set.has(p_name));
ERR_FAIL_COND(String(p_new_name).find("/") != -1 || String(p_new_name).find(":") != -1);
ERR_FAIL_COND(animation_set.has(p_new_name));
@@ -1030,7 +992,6 @@ void AnimationPlayer::rename_animation(const StringName &p_name, const StringNam
List<BlendKey> to_erase;
Map<BlendKey, float> to_insert;
for (Map<BlendKey, float>::Element *E = blend_times.front(); E; E = E->next()) {
-
BlendKey bk = E->key();
BlendKey new_bk = bk;
bool erase = false;
@@ -1050,7 +1011,6 @@ void AnimationPlayer::rename_animation(const StringName &p_name, const StringNam
}
while (to_erase.size()) {
-
blend_times.erase(to_erase.front()->get());
to_erase.pop_front();
}
@@ -1060,77 +1020,77 @@ void AnimationPlayer::rename_animation(const StringName &p_name, const StringNam
to_insert.erase(to_insert.front());
}
- if (autoplay == p_name)
+ if (autoplay == p_name) {
autoplay = p_new_name;
+ }
clear_caches();
_change_notify();
}
bool AnimationPlayer::has_animation(const StringName &p_name) const {
-
return animation_set.has(p_name);
}
-Ref<Animation> AnimationPlayer::get_animation(const StringName &p_name) const {
+Ref<Animation> AnimationPlayer::get_animation(const StringName &p_name) const {
ERR_FAIL_COND_V(!animation_set.has(p_name), Ref<Animation>());
const AnimationData &data = animation_set[p_name];
return data.animation;
}
-void AnimationPlayer::get_animation_list(List<StringName> *p_animations) const {
+void AnimationPlayer::get_animation_list(List<StringName> *p_animations) const {
List<String> anims;
for (Map<StringName, AnimationData>::Element *E = animation_set.front(); E; E = E->next()) {
-
anims.push_back(E->key());
}
anims.sort();
for (List<String>::Element *E = anims.front(); E; E = E->next()) {
-
p_animations->push_back(E->get());
}
}
void AnimationPlayer::set_blend_time(const StringName &p_animation1, const StringName &p_animation2, float p_time) {
-
+ ERR_FAIL_COND(!animation_set.has(p_animation1));
+ ERR_FAIL_COND(!animation_set.has(p_animation2));
ERR_FAIL_COND_MSG(p_time < 0, "Blend time cannot be smaller than 0.");
BlendKey bk;
bk.from = p_animation1;
bk.to = p_animation2;
- if (p_time == 0)
+ if (p_time == 0) {
blend_times.erase(bk);
- else
+ } else {
blend_times[bk] = p_time;
+ }
}
float AnimationPlayer::get_blend_time(const StringName &p_animation1, const StringName &p_animation2) const {
-
BlendKey bk;
bk.from = p_animation1;
bk.to = p_animation2;
- if (blend_times.has(bk))
+ if (blend_times.has(bk)) {
return blend_times[bk];
- else
+ } else {
return 0;
+ }
}
void AnimationPlayer::queue(const StringName &p_name) {
-
- if (!is_playing())
+ if (!is_playing()) {
play(p_name);
- else
+ } else {
queued.push_back(p_name);
+ }
}
-PoolVector<String> AnimationPlayer::get_queue() {
- PoolVector<String> ret;
+Vector<String> AnimationPlayer::get_queue() {
+ Vector<String> ret;
for (List<StringName>::Element *E = queued.front(); E; E = E->next()) {
ret.push_back(E->get());
}
@@ -1143,23 +1103,21 @@ void AnimationPlayer::clear_queue() {
}
void AnimationPlayer::play_backwards(const StringName &p_name, float p_custom_blend) {
-
play(p_name, p_custom_blend, -1, true);
}
void AnimationPlayer::play(const StringName &p_name, float p_custom_blend, float p_custom_scale, bool p_from_end) {
-
StringName name = p_name;
- if (String(name) == "")
+ if (String(name) == "") {
name = playback.assigned;
+ }
ERR_FAIL_COND_MSG(!animation_set.has(name), "Animation not found: " + name + ".");
Playback &c = playback;
if (c.current.from) {
-
float blend_time = 0;
// find if it can blend
BlendKey bk;
@@ -1169,30 +1127,25 @@ void AnimationPlayer::play(const StringName &p_name, float p_custom_blend, float
if (p_custom_blend >= 0) {
blend_time = p_custom_blend;
} else if (blend_times.has(bk)) {
-
blend_time = blend_times[bk];
} else {
-
bk.from = "*";
if (blend_times.has(bk)) {
-
blend_time = blend_times[bk];
} else {
-
bk.from = c.current.from->name;
bk.to = "*";
if (blend_times.has(bk)) {
-
blend_time = blend_times[bk];
}
}
}
- if (p_custom_blend < 0 && blend_time == 0 && default_blend_time)
+ if (p_custom_blend < 0 && blend_time == 0 && default_blend_time) {
blend_time = default_blend_time;
+ }
if (blend_time > 0) {
-
Blend b;
b.data = c.current;
b.blend_time = b.blend_left = blend_time;
@@ -1223,15 +1176,17 @@ void AnimationPlayer::play(const StringName &p_name, float p_custom_blend, float
c.seeked = false;
c.started = true;
- if (!end_reached)
+ if (!end_reached) {
queued.clear();
+ }
_set_process(true); // always process when starting an animation
playing = true;
emit_signal(SceneStringNames::get_singleton()->animation_started, c.assigned);
- if (is_inside_tree() && Engine::get_singleton()->is_editor_hint())
+ if (is_inside_tree() && Engine::get_singleton()->is_editor_hint()) {
return; // no next in this case
+ }
StringName next = animation_get_next(p_name);
if (next != StringName() && animation_set.has(next)) {
@@ -1240,25 +1195,10 @@ void AnimationPlayer::play(const StringName &p_name, float p_custom_blend, float
}
bool AnimationPlayer::is_playing() const {
-
return playing;
- /*
- if (playback.current.from==NULL)
- return false;
-
- float len=playback.current.from->animation->get_length();
- float pos = playback.current.pos;
- bool loop=playback.current.from->animation->has_loop();
- if (!loop && pos >= len) {
- return false;
- };
-
- return true;
- */
}
void AnimationPlayer::set_current_animation(const String &p_anim) {
-
if (p_anim == "[stop]" || p_anim == "") {
stop();
} else if (!is_playing() || playback.assigned != p_anim) {
@@ -1269,12 +1209,10 @@ void AnimationPlayer::set_current_animation(const String &p_anim) {
}
String AnimationPlayer::get_current_animation() const {
-
return (is_playing() ? playback.assigned : "");
}
void AnimationPlayer::set_assigned_animation(const String &p_anim) {
-
if (is_playing()) {
play(p_anim);
} else {
@@ -1286,17 +1224,15 @@ void AnimationPlayer::set_assigned_animation(const String &p_anim) {
}
String AnimationPlayer::get_assigned_animation() const {
-
return playback.assigned;
}
void AnimationPlayer::stop(bool p_reset) {
-
_stop_playing_caches();
Playback &c = playback;
c.blend.clear();
if (p_reset) {
- c.current.from = NULL;
+ c.current.from = nullptr;
c.current.speed_scale = 1;
c.current.pos = 0;
}
@@ -1306,15 +1242,14 @@ void AnimationPlayer::stop(bool p_reset) {
}
void AnimationPlayer::set_speed_scale(float p_speed) {
-
speed_scale = p_speed;
}
-float AnimationPlayer::get_speed_scale() const {
+float AnimationPlayer::get_speed_scale() const {
return speed_scale;
}
-float AnimationPlayer::get_playing_speed() const {
+float AnimationPlayer::get_playing_speed() const {
if (!playing) {
return 0;
}
@@ -1322,7 +1257,6 @@ float AnimationPlayer::get_playing_speed() const {
}
void AnimationPlayer::seek(float p_time, bool p_update) {
-
if (!playback.current.from) {
if (playback.assigned) {
ERR_FAIL_COND(!animation_set.has(playback.assigned));
@@ -1339,7 +1273,6 @@ void AnimationPlayer::seek(float p_time, bool p_update) {
}
void AnimationPlayer::seek_delta(float p_time, float p_delta) {
-
if (!playback.current.from) {
if (playback.assigned) {
ERR_FAIL_COND(!animation_set.has(playback.assigned));
@@ -1349,31 +1282,28 @@ void AnimationPlayer::seek_delta(float p_time, float p_delta) {
}
playback.current.pos = p_time - p_delta;
- if (speed_scale != 0.0)
+ if (speed_scale != 0.0) {
p_delta /= speed_scale;
+ }
_animation_process(p_delta);
//playback.current.pos=p_time;
}
bool AnimationPlayer::is_valid() const {
-
return (playback.current.from);
}
float AnimationPlayer::get_current_animation_position() const {
-
ERR_FAIL_COND_V(!playback.current.from, 0);
return playback.current.pos;
}
float AnimationPlayer::get_current_animation_length() const {
-
ERR_FAIL_COND_V(!playback.current.from, 0);
return playback.current.from->animation->get_length();
}
void AnimationPlayer::_animation_changed() {
-
clear_caches();
emit_signal("caches_cleared");
if (is_playing()) {
@@ -1382,16 +1312,15 @@ void AnimationPlayer::_animation_changed() {
}
void AnimationPlayer::_stop_playing_caches() {
-
for (Set<TrackNodeCache *>::Element *E = playing_caches.front(); E; E = E->next()) {
-
if (E->get()->node && E->get()->audio_playing) {
E->get()->node->call("stop");
}
if (E->get()->node && E->get()->animation_playing) {
AnimationPlayer *player = Object::cast_to<AnimationPlayer>(E->get()->node);
- if (!player)
+ if (!player) {
continue;
+ }
player->stop();
}
}
@@ -1400,18 +1329,15 @@ void AnimationPlayer::_stop_playing_caches() {
}
void AnimationPlayer::_node_removed(Node *p_node) {
-
clear_caches(); // nodes contained here ar being removed, clear the caches
}
void AnimationPlayer::clear_caches() {
-
_stop_playing_caches();
node_cache_map.clear();
for (Map<StringName, AnimationData>::Element *E = animation_set.front(); E; E = E->next()) {
-
E->get().node_cache.clear();
}
@@ -1421,121 +1347,116 @@ void AnimationPlayer::clear_caches() {
}
void AnimationPlayer::set_active(bool p_active) {
-
- if (active == p_active)
+ if (active == p_active) {
return;
+ }
active = p_active;
_set_process(processing, true);
}
bool AnimationPlayer::is_active() const {
-
return active;
}
StringName AnimationPlayer::find_animation(const Ref<Animation> &p_animation) const {
-
for (Map<StringName, AnimationData>::Element *E = animation_set.front(); E; E = E->next()) {
-
- if (E->get().animation == p_animation)
+ if (E->get().animation == p_animation) {
return E->key();
+ }
}
return "";
}
void AnimationPlayer::set_autoplay(const String &p_name) {
- if (is_inside_tree() && !Engine::get_singleton()->is_editor_hint())
+ if (is_inside_tree() && !Engine::get_singleton()->is_editor_hint()) {
WARN_PRINT("Setting autoplay after the node has been added to the scene has no effect.");
+ }
autoplay = p_name;
}
String AnimationPlayer::get_autoplay() const {
-
return autoplay;
}
void AnimationPlayer::set_animation_process_mode(AnimationProcessMode p_mode) {
-
- if (animation_process_mode == p_mode)
+ if (animation_process_mode == p_mode) {
return;
+ }
bool pr = processing;
- if (pr)
+ if (pr) {
_set_process(false);
+ }
animation_process_mode = p_mode;
- if (pr)
+ if (pr) {
_set_process(true);
+ }
}
AnimationPlayer::AnimationProcessMode AnimationPlayer::get_animation_process_mode() const {
-
return animation_process_mode;
}
void AnimationPlayer::set_method_call_mode(AnimationMethodCallMode p_mode) {
-
method_call_mode = p_mode;
}
AnimationPlayer::AnimationMethodCallMode AnimationPlayer::get_method_call_mode() const {
-
return method_call_mode;
}
void AnimationPlayer::_set_process(bool p_process, bool p_force) {
-
- if (processing == p_process && !p_force)
+ if (processing == p_process && !p_force) {
return;
+ }
switch (animation_process_mode) {
-
- case ANIMATION_PROCESS_PHYSICS: set_physics_process_internal(p_process && active); break;
- case ANIMATION_PROCESS_IDLE: set_process_internal(p_process && active); break;
- case ANIMATION_PROCESS_MANUAL: break;
+ case ANIMATION_PROCESS_PHYSICS:
+ set_physics_process_internal(p_process && active);
+ break;
+ case ANIMATION_PROCESS_IDLE:
+ set_process_internal(p_process && active);
+ break;
+ case ANIMATION_PROCESS_MANUAL:
+ break;
}
processing = p_process;
}
void AnimationPlayer::animation_set_next(const StringName &p_animation, const StringName &p_next) {
-
ERR_FAIL_COND(!animation_set.has(p_animation));
animation_set[p_animation].next = p_next;
}
StringName AnimationPlayer::animation_get_next(const StringName &p_animation) const {
-
- if (!animation_set.has(p_animation))
+ if (!animation_set.has(p_animation)) {
return StringName();
+ }
return animation_set[p_animation].next;
}
void AnimationPlayer::set_default_blend_time(float p_default) {
-
default_blend_time = p_default;
}
float AnimationPlayer::get_default_blend_time() const {
-
return default_blend_time;
}
void AnimationPlayer::set_root(const NodePath &p_root) {
-
root = p_root;
clear_caches();
}
NodePath AnimationPlayer::get_root() const {
-
return root;
}
void AnimationPlayer::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const {
-
#ifdef TOOLS_ENABLED
const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", 0) ? "'" : "\"";
#else
@@ -1543,11 +1464,10 @@ void AnimationPlayer::get_argument_options(const StringName &p_function, int p_i
#endif
String pf = p_function;
- if (p_function == "play" || p_function == "play_backwards" || p_function == "remove_animation" || p_function == "has_animation" || p_function == "queue") {
+ if (p_idx == 0 && (p_function == "play" || p_function == "play_backwards" || p_function == "remove_animation" || p_function == "has_animation" || p_function == "queue")) {
List<StringName> al;
get_animation_list(&al);
for (List<StringName>::Element *E = al.front(); E; E = E->next()) {
-
r_options->push_back(quote_style + String(E->get()) + quote_style);
}
}
@@ -1556,9 +1476,9 @@ void AnimationPlayer::get_argument_options(const StringName &p_function, int p_i
#ifdef TOOLS_ENABLED
AnimatedValuesBackup AnimationPlayer::backup_animated_values() {
-
- if (!playback.current.from)
+ if (!playback.current.from) {
return AnimatedValuesBackup();
+ }
_ensure_node_caches(playback.current.from);
@@ -1566,12 +1486,14 @@ AnimatedValuesBackup AnimationPlayer::backup_animated_values() {
for (int i = 0; i < playback.current.from->node_cache.size(); i++) {
TrackNodeCache *nc = playback.current.from->node_cache[i];
- if (!nc)
+ if (!nc) {
continue;
+ }
if (nc->skeleton) {
- if (nc->bone_idx == -1)
+ if (nc->bone_idx == -1) {
continue;
+ }
AnimatedValuesBackup::Entry entry;
entry.object = nc->skeleton;
@@ -1594,8 +1516,9 @@ AnimatedValuesBackup AnimationPlayer::backup_animated_values() {
bool valid;
entry.value = E->value().object->get_indexed(E->value().subpath, &valid);
entry.bone_idx = -1;
- if (valid)
+ if (valid) {
backup.entries.push_back(entry);
+ }
}
}
}
@@ -1605,24 +1528,18 @@ AnimatedValuesBackup AnimationPlayer::backup_animated_values() {
}
void AnimationPlayer::restore_animated_values(const AnimatedValuesBackup &p_backup) {
-
for (int i = 0; i < p_backup.entries.size(); i++) {
-
const AnimatedValuesBackup::Entry *entry = &p_backup.entries[i];
if (entry->bone_idx == -1) {
entry->object->set_indexed(entry->subpath, entry->value);
} else {
- Object::cast_to<Skeleton>(entry->object)->set_bone_pose(entry->bone_idx, entry->value);
+ Object::cast_to<Skeleton3D>(entry->object)->set_bone_pose(entry->bone_idx, entry->value);
}
}
}
#endif
void AnimationPlayer::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("_node_removed"), &AnimationPlayer::_node_removed);
- ClassDB::bind_method(D_METHOD("_animation_changed"), &AnimationPlayer::_animation_changed);
-
ClassDB::bind_method(D_METHOD("add_animation", "name", "animation"), &AnimationPlayer::add_animation);
ClassDB::bind_method(D_METHOD("remove_animation", "name"), &AnimationPlayer::remove_animation);
ClassDB::bind_method(D_METHOD("rename_animation", "name", "newname"), &AnimationPlayer::rename_animation);
@@ -1682,22 +1599,22 @@ void AnimationPlayer::_bind_methods() {
ClassDB::bind_method(D_METHOD("advance", "delta"), &AnimationPlayer::advance);
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "root_node"), "set_root", "get_root");
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "current_animation", PROPERTY_HINT_ENUM, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_ANIMATE_AS_TRIGGER), "set_current_animation", "get_current_animation");
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "assigned_animation", PROPERTY_HINT_NONE, "", 0), "set_assigned_animation", "get_assigned_animation");
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "autoplay", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_autoplay", "get_autoplay");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "current_animation_length", PROPERTY_HINT_NONE, "", 0), "", "get_current_animation_length");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "current_animation_position", PROPERTY_HINT_NONE, "", 0), "", "get_current_animation_position");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "current_animation", PROPERTY_HINT_ENUM, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_ANIMATE_AS_TRIGGER), "set_current_animation", "get_current_animation");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "assigned_animation", PROPERTY_HINT_NONE, "", 0), "set_assigned_animation", "get_assigned_animation");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "autoplay", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_autoplay", "get_autoplay");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "current_animation_length", PROPERTY_HINT_NONE, "", 0), "", "get_current_animation_length");
+ 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::REAL, "playback_default_blend_time", PROPERTY_HINT_RANGE, "0,4096,0.01"), "set_default_blend_time", "get_default_blend_time");
+ 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::REAL, "playback_speed", PROPERTY_HINT_RANGE, "-64,64,0.01"), "set_speed_scale", "get_speed_scale");
+ 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_SIGNAL(MethodInfo("animation_finished", PropertyInfo(Variant::STRING, "anim_name")));
- ADD_SIGNAL(MethodInfo("animation_changed", PropertyInfo(Variant::STRING, "old_name"), PropertyInfo(Variant::STRING, "new_name")));
- ADD_SIGNAL(MethodInfo("animation_started", PropertyInfo(Variant::STRING, "anim_name")));
+ 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")));
ADD_SIGNAL(MethodInfo("caches_cleared"));
BIND_ENUM_CONSTANT(ANIMATION_PROCESS_PHYSICS);
@@ -1709,7 +1626,6 @@ void AnimationPlayer::_bind_methods() {
}
AnimationPlayer::AnimationPlayer() {
-
accum_pass = 1;
cache_update_size = 0;
cache_update_prop_size = 0;
diff --git a/scene/animation/animation_player.h b/scene/animation/animation_player.h
index 06f762e63e..e1b9dffb1f 100644
--- a/scene/animation/animation_player.h
+++ b/scene/animation/animation_player.h
@@ -32,8 +32,8 @@
#define ANIMATION_PLAYER_H
#include "scene/2d/node_2d.h"
-#include "scene/3d/skeleton.h"
-#include "scene/3d/spatial.h"
+#include "scene/3d/node_3d.h"
+#include "scene/3d/skeleton_3d.h"
#include "scene/resources/animation.h"
#ifdef TOOLS_ENABLED
@@ -85,91 +85,66 @@ private:
};
struct TrackNodeCache {
-
NodePath path;
- uint32_t id;
+ uint32_t id = 0;
RES resource;
- Node *node;
- Spatial *spatial;
- Node2D *node_2d;
- Skeleton *skeleton;
- int bone_idx;
+ Node *node = nullptr;
+ Node3D *spatial = nullptr;
+ Node2D *node_2d = nullptr;
+ Skeleton3D *skeleton = nullptr;
+ int bone_idx = -1;
// accumulated transforms
Vector3 loc_accum;
Quat rot_accum;
Vector3 scale_accum;
- uint64_t accum_pass;
+ uint64_t accum_pass = 0;
- bool audio_playing;
- float audio_start;
- float audio_len;
+ bool audio_playing = false;
+ float audio_start = 0.0;
+ float audio_len = 0.0;
- bool animation_playing;
+ bool animation_playing = false;
struct PropertyAnim {
-
- TrackNodeCache *owner;
- SpecialProperty special; //small optimization
+ TrackNodeCache *owner = nullptr;
+ SpecialProperty special = SP_NONE; //small optimization
Vector<StringName> subpath;
- Object *object;
+ Object *object = nullptr;
Variant value_accum;
- uint64_t accum_pass;
+ uint64_t accum_pass = 0;
Variant capture;
- PropertyAnim() :
- owner(NULL),
- special(SP_NONE),
- object(NULL),
- accum_pass(0) {}
+ PropertyAnim() {}
};
Map<StringName, PropertyAnim> property_anim;
struct BezierAnim {
-
Vector<StringName> bezier_property;
- TrackNodeCache *owner;
- float bezier_accum;
- Object *object;
- uint64_t accum_pass;
-
- BezierAnim() :
- owner(NULL),
- bezier_accum(0.0),
- object(NULL),
- accum_pass(0) {}
+ TrackNodeCache *owner = nullptr;
+ float bezier_accum = 0.0;
+ Object *object = nullptr;
+ uint64_t accum_pass = 0;
+
+ BezierAnim() {}
};
Map<StringName, BezierAnim> bezier_anim;
- TrackNodeCache() :
- id(0),
- node(NULL),
- spatial(NULL),
- node_2d(NULL),
- skeleton(NULL),
- bone_idx(-1),
- accum_pass(0),
- audio_playing(false),
- audio_start(0.0),
- audio_len(0.0),
- animation_playing(false) {}
+ TrackNodeCache() {}
};
struct TrackNodeCacheKey {
-
- uint32_t id;
+ ObjectID id;
int bone_idx;
inline bool operator<(const TrackNodeCacheKey &p_right) const {
-
- if (id < p_right.id)
- return true;
- else if (id > p_right.id)
- return false;
- else
+ if (id == p_right.id) {
return bone_idx < p_right.bone_idx;
+ } else {
+ return id < p_right.id;
+ }
}
};
@@ -196,7 +171,6 @@ private:
Map<StringName, AnimationData> animation_set;
struct BlendKey {
-
StringName from;
StringName to;
bool operator<(const BlendKey &bk) const { return from == bk.from ? String(to) < String(bk.to) : String(from) < String(bk.from); }
@@ -205,35 +179,30 @@ private:
Map<BlendKey, float> blend_times;
struct PlaybackData {
-
AnimationData *from;
float pos;
float speed_scale;
PlaybackData() {
-
pos = 0;
speed_scale = 1.0;
- from = NULL;
+ from = nullptr;
}
};
struct Blend {
-
PlaybackData data;
float blend_time;
float blend_left;
Blend() {
-
blend_left = 0;
blend_time = 0;
}
};
struct Playback {
-
List<Blend> blend;
PlaybackData current;
StringName assigned;
@@ -266,13 +235,11 @@ private:
void _stop_playing_caches();
// bind helpers
- PoolVector<String> _get_animation_list() const {
-
+ Vector<String> _get_animation_list() const {
List<StringName> animations;
get_animation_list(&animations);
- PoolVector<String> ret;
+ Vector<String> ret;
while (animations.size()) {
-
ret.push_back(animations.front()->get());
animations.pop_front();
}
@@ -290,7 +257,7 @@ private:
protected:
bool _set(const StringName &p_name, const Variant &p_value);
bool _get(const StringName &p_name, Variant &r_ret) const;
- virtual void _validate_property(PropertyInfo &property) const;
+ virtual void _validate_property(PropertyInfo &property) const override;
void _get_property_list(List<PropertyInfo> *p_list) const;
void _notification(int p_what);
@@ -318,7 +285,7 @@ public:
void play(const StringName &p_name = StringName(), float p_custom_blend = -1, float p_custom_scale = 1.0, bool p_from_end = false);
void play_backwards(const StringName &p_name = StringName(), float p_custom_blend = -1);
void queue(const StringName &p_name);
- PoolVector<String> get_queue();
+ Vector<String> get_queue();
void clear_queue();
void stop(bool p_reset = true);
bool is_playing() const;
@@ -356,7 +323,7 @@ public:
void clear_caches(); ///< must be called by hand if an animation was modified after added
- void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const;
+ void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const override;
#ifdef TOOLS_ENABLED
// These may be interesting for games, but are too dangerous for general use
diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp
index 8b2d8861e7..466536db10 100644
--- a/scene/animation/animation_tree.cpp
+++ b/scene/animation/animation_tree.cpp
@@ -49,7 +49,7 @@ void AnimationNode::get_parameter_list(List<PropertyInfo> *r_list) const {
Variant AnimationNode::get_parameter_default_value(const StringName &p_parameter) const {
if (get_script_instance()) {
- return get_script_instance()->call("get_parameter_default_value");
+ return get_script_instance()->call("get_parameter_default_value", p_parameter);
}
return Variant();
}
@@ -73,7 +73,6 @@ Variant AnimationNode::get_parameter(const StringName &p_name) const {
}
void AnimationNode::get_child_nodes(List<ChildNode> *r_child_nodes) {
-
if (get_script_instance()) {
Dictionary cn = get_script_instance()->call("get_child_nodes");
List<Variant> keys;
@@ -88,14 +87,12 @@ void AnimationNode::get_child_nodes(List<ChildNode> *r_child_nodes) {
}
void AnimationNode::blend_animation(const StringName &p_animation, float p_time, float p_delta, bool p_seeked, float p_blend) {
-
ERR_FAIL_COND(!state);
ERR_FAIL_COND(!state->player->has_animation(p_animation));
Ref<Animation> animation = state->player->get_animation(p_animation);
if (animation.is_null()) {
-
AnimationNodeBlendTree *btree = Object::cast_to<AnimationNodeBlendTree>(parent);
if (btree) {
String name = btree->get_node_name(Ref<AnimationNodeAnimation>(this));
@@ -120,7 +117,6 @@ void AnimationNode::blend_animation(const StringName &p_animation, float p_time,
}
float AnimationNode::_pre_process(const StringName &p_base_path, AnimationNode *p_parent, State *p_state, float p_time, bool p_seek, const Vector<StringName> &p_connections) {
-
base_path = p_base_path;
parent = p_parent;
connections = p_connections;
@@ -128,8 +124,8 @@ float AnimationNode::_pre_process(const StringName &p_base_path, AnimationNode *
float t = process(p_time, p_seek);
- state = NULL;
- parent = NULL;
+ state = nullptr;
+ parent = nullptr;
base_path = StringName();
connections.clear();
@@ -164,7 +160,7 @@ float AnimationNode::blend_input(int p_input, float p_time, bool p_seek, float p
//inputs.write[p_input].last_pass = state->last_pass;
float activity = 0;
- float ret = _blend_node(node_name, blend_tree->get_node_connection_array(node_name), NULL, node, p_time, p_seek, p_blend, p_filter, p_optimize, &activity);
+ 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);
@@ -176,12 +172,10 @@ float AnimationNode::blend_input(int p_input, float p_time, bool p_seek, float p
}
float AnimationNode::blend_node(const StringName &p_sub_path, Ref<AnimationNode> p_node, float p_time, bool p_seek, float p_blend, FilterAction p_filter, bool p_optimize) {
-
return _blend_node(p_sub_path, Vector<StringName>(), this, p_node, p_time, p_seek, p_blend, p_filter, p_optimize);
}
float AnimationNode::_blend_node(const StringName &p_subpath, const Vector<StringName> &p_connections, AnimationNode *p_new_parent, Ref<AnimationNode> p_node, float p_time, bool p_seek, float p_blend, FilterAction p_filter, bool p_optimize, float *r_max) {
-
ERR_FAIL_COND_V(!p_node.is_valid(), 0);
ERR_FAIL_COND_V(!state, 0);
@@ -197,12 +191,11 @@ float AnimationNode::_blend_node(const StringName &p_subpath, const Vector<Strin
bool any_valid = false;
if (has_filter() && is_filter_enabled() && p_filter != FILTER_IGNORE) {
-
for (int i = 0; i < blend_count; i++) {
blendw[i] = 0.0; //all to zero by default
}
- const NodePath *K = NULL;
+ const NodePath *K = nullptr;
while ((K = filter.next(K))) {
if (!state->track_map.has(*K)) {
continue;
@@ -217,8 +210,9 @@ float AnimationNode::_blend_node(const StringName &p_subpath, const Vector<Strin
case FILTER_PASS: {
//values filtered pass, the rest don't
for (int i = 0; i < blend_count; i++) {
- if (blendw[i] == 0) //not filtered, does not pass
+ if (blendw[i] == 0) { //not filtered, does not pass
continue;
+ }
blendw[i] = blendr[i] * p_blend;
if (blendw[i] > CMP_EPSILON) {
@@ -228,12 +222,12 @@ float AnimationNode::_blend_node(const StringName &p_subpath, const Vector<Strin
} break;
case FILTER_STOP: {
-
//values filtered don't pass, the rest are blended
for (int i = 0; i < blend_count; i++) {
- if (blendw[i] > 0) //filtered, does not pass
+ if (blendw[i] > 0) { //filtered, does not pass
continue;
+ }
blendw[i] = blendr[i] * p_blend;
if (blendw[i] > CMP_EPSILON) {
@@ -243,7 +237,6 @@ float AnimationNode::_blend_node(const StringName &p_subpath, const Vector<Strin
} break;
case FILTER_BLEND: {
-
//filtered values are blended, the rest are passed without blending
for (int i = 0; i < blend_count; i++) {
@@ -262,7 +255,6 @@ float AnimationNode::_blend_node(const StringName &p_subpath, const Vector<Strin
}
} else {
for (int i = 0; i < blend_count; i++) {
-
//regular blend
blendw[i] = blendr[i] * p_blend;
if (blendw[i] > CMP_EPSILON) {
@@ -278,8 +270,9 @@ float AnimationNode::_blend_node(const StringName &p_subpath, const Vector<Strin
}
}
- if (!p_seek && p_optimize && !any_valid) //pointless to go on, all are zero
+ if (!p_seek && p_optimize && !any_valid) { //pointless to go on, all are zero
return 0;
+ }
String new_path;
AnimationNode *new_parent;
@@ -297,16 +290,15 @@ float AnimationNode::_blend_node(const StringName &p_subpath, const Vector<Strin
}
int AnimationNode::get_input_count() const {
-
return inputs.size();
}
+
String AnimationNode::get_input_name(int p_input) {
ERR_FAIL_INDEX_V(p_input, inputs.size(), String());
return inputs[p_input].name;
}
String AnimationNode::get_caption() const {
-
if (get_script_instance()) {
return get_script_instance()->call("get_caption");
}
@@ -316,7 +308,7 @@ String AnimationNode::get_caption() const {
void AnimationNode::add_input(const String &p_name) {
//root nodes can't add inputs
- ERR_FAIL_COND(Object::cast_to<AnimationRootNode>(this) != NULL);
+ ERR_FAIL_COND(Object::cast_to<AnimationRootNode>(this) != nullptr);
Input input;
ERR_FAIL_COND(p_name.find(".") != -1 || p_name.find("/") != -1);
input.name = p_name;
@@ -338,7 +330,6 @@ void AnimationNode::remove_input(int p_index) {
}
float AnimationNode::process(float p_time, bool p_seek) {
-
if (get_script_instance()) {
return get_script_instance()->call("process", p_time, p_seek);
}
@@ -371,10 +362,9 @@ bool AnimationNode::has_filter() const {
}
Array AnimationNode::_get_filters() const {
-
Array paths;
- const NodePath *K = NULL;
+ const NodePath *K = nullptr;
while ((K = filter.next(K))) {
paths.push_back(String(*K)); //use strings, so sorting is possible
}
@@ -382,6 +372,7 @@ Array AnimationNode::_get_filters() const {
return paths;
}
+
void AnimationNode::_set_filters(const Array &p_filters) {
filter.clear();
for (int i = 0; i < p_filters.size(); i++) {
@@ -397,13 +388,12 @@ void AnimationNode::_validate_property(PropertyInfo &property) const {
Ref<AnimationNode> AnimationNode::get_child_by_name(const StringName &p_name) {
if (get_script_instance()) {
- return get_script_instance()->call("get_child_by_name");
+ return get_script_instance()->call("get_child_by_name", p_name);
}
return Ref<AnimationNode>();
}
void AnimationNode::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_input_count"), &AnimationNode::get_input_count);
ClassDB::bind_method(D_METHOD("get_input_name", "input"), &AnimationNode::get_input_name);
@@ -433,13 +423,13 @@ void AnimationNode::_bind_methods() {
BIND_VMETHOD(MethodInfo(Variant::ARRAY, "get_parameter_list"));
BIND_VMETHOD(MethodInfo(Variant::OBJECT, "get_child_by_name", PropertyInfo(Variant::STRING, "name")));
{
- MethodInfo mi = MethodInfo(Variant::NIL, "get_parameter_default_value", PropertyInfo(Variant::STRING, "name"));
+ MethodInfo mi = MethodInfo(Variant::NIL, "get_parameter_default_value", PropertyInfo(Variant::STRING_NAME, "name"));
mi.return_val.usage = PROPERTY_USAGE_NIL_IS_VARIANT;
BIND_VMETHOD(mi);
}
- BIND_VMETHOD(MethodInfo("process", PropertyInfo(Variant::REAL, "time"), PropertyInfo(Variant::BOOL, "seek")));
+ BIND_VMETHOD(MethodInfo("process", PropertyInfo(Variant::FLOAT, "time"), PropertyInfo(Variant::BOOL, "seek")));
BIND_VMETHOD(MethodInfo(Variant::STRING, "get_caption"));
- BIND_VMETHOD(MethodInfo(Variant::STRING, "has_filter"));
+ BIND_VMETHOD(MethodInfo(Variant::BOOL, "has_filter"));
ADD_SIGNAL(MethodInfo("removed_from_graph"));
@@ -452,24 +442,22 @@ void AnimationNode::_bind_methods() {
}
AnimationNode::AnimationNode() {
-
- state = NULL;
- parent = NULL;
+ state = nullptr;
+ parent = nullptr;
filter_enabled = false;
}
////////////////////
void AnimationTree::set_tree_root(const Ref<AnimationNode> &p_root) {
-
if (root.is_valid()) {
- root->disconnect("tree_changed", this, "_tree_changed");
+ root->disconnect("tree_changed", callable_mp(this, &AnimationTree::_tree_changed));
}
root = p_root;
if (root.is_valid()) {
- root->connect("tree_changed", this, "_tree_changed");
+ root->connect("tree_changed", callable_mp(this, &AnimationTree::_tree_changed));
}
properties_dirty = true;
@@ -482,9 +470,9 @@ Ref<AnimationNode> AnimationTree::get_tree_root() const {
}
void AnimationTree::set_active(bool p_active) {
-
- if (active == p_active)
+ if (active == p_active) {
return;
+ }
active = p_active;
started = active;
@@ -492,13 +480,11 @@ void AnimationTree::set_active(bool p_active) {
if (process_mode == ANIMATION_PROCESS_IDLE) {
set_process_internal(active);
} else {
-
set_physics_process_internal(active);
}
if (!active && is_inside_tree()) {
for (Set<TrackCache *>::Element *E = playing_caches.front(); E; E = E->next()) {
-
if (ObjectDB::get_instance(E->get()->object_id)) {
E->get()->object->call("stop");
}
@@ -509,14 +495,13 @@ void AnimationTree::set_active(bool p_active) {
}
bool AnimationTree::is_active() const {
-
return active;
}
void AnimationTree::set_process_mode(AnimationProcessMode p_mode) {
-
- if (process_mode == p_mode)
+ if (process_mode == p_mode) {
return;
+ }
bool was_active = is_active();
if (was_active) {
@@ -539,7 +524,6 @@ void AnimationTree::_node_removed(Node *p_node) {
}
bool AnimationTree::_update_caches(AnimationPlayer *player) {
-
setup_pass++;
if (!player->has_node(player->get_root())) {
@@ -558,37 +542,35 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
NodePath path = anim->track_get_path(i);
Animation::TrackType track_type = anim->track_get_type(i);
- TrackCache *track = NULL;
+ TrackCache *track = nullptr;
if (track_cache.has(path)) {
track = track_cache.get(path);
}
//if not valid, delete track
- if (track && (track->type != track_type || ObjectDB::get_instance(track->object_id) == NULL)) {
+ if (track && (track->type != track_type || ObjectDB::get_instance(track->object_id) == nullptr)) {
playing_caches.erase(track);
memdelete(track);
track_cache.erase(path);
- track = NULL;
+ track = nullptr;
}
if (!track) {
-
RES resource;
Vector<StringName> leftover_path;
Node *child = parent->get_node_and_resource(path, resource, leftover_path);
if (!child) {
- ERR_PRINTS("AnimationTree: '" + String(E->get()) + "', couldn't resolve track: '" + String(path) + "'");
+ ERR_PRINT("AnimationTree: '" + String(E->get()) + "', couldn't resolve track: '" + String(path) + "'");
continue;
}
- if (!child->is_connected("tree_exited", this, "_node_removed")) {
- child->connect("tree_exited", this, "_node_removed", varray(child));
+ if (!child->is_connected("tree_exited", callable_mp(this, &AnimationTree::_node_removed))) {
+ child->connect("tree_exited", callable_mp(this, &AnimationTree::_node_removed), varray(child));
}
switch (track_type) {
case Animation::TYPE_VALUE: {
-
TrackCacheValue *track_value = memnew(TrackCacheValue);
if (resource.is_valid()) {
@@ -604,26 +586,23 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
} break;
case Animation::TYPE_TRANSFORM: {
-
- Spatial *spatial = Object::cast_to<Spatial>(child);
+ Node3D *spatial = Object::cast_to<Node3D>(child);
if (!spatial) {
- ERR_PRINTS("AnimationTree: '" + String(E->get()) + "', transform track does not point to spatial: '" + String(path) + "'");
+ ERR_PRINT("AnimationTree: '" + String(E->get()) + "', transform track does not point to spatial: '" + String(path) + "'");
continue;
}
TrackCacheTransform *track_xform = memnew(TrackCacheTransform);
track_xform->spatial = spatial;
- track_xform->skeleton = NULL;
+ track_xform->skeleton = nullptr;
track_xform->bone_idx = -1;
- if (path.get_subname_count() == 1 && Object::cast_to<Skeleton>(spatial)) {
-
- Skeleton *sk = Object::cast_to<Skeleton>(spatial);
+ if (path.get_subname_count() == 1 && Object::cast_to<Skeleton3D>(spatial)) {
+ Skeleton3D *sk = Object::cast_to<Skeleton3D>(spatial);
int bone_idx = sk->find_bone(path.get_subname(0));
if (bone_idx != -1) {
-
track_xform->skeleton = sk;
track_xform->bone_idx = bone_idx;
}
@@ -636,7 +615,6 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
} break;
case Animation::TYPE_METHOD: {
-
TrackCacheMethod *track_method = memnew(TrackCacheMethod);
if (resource.is_valid()) {
@@ -651,7 +629,6 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
} break;
case Animation::TYPE_BEZIER: {
-
TrackCacheBezier *track_bezier = memnew(TrackCacheBezier);
if (resource.is_valid()) {
@@ -666,7 +643,6 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
track = track_bezier;
} break;
case Animation::TYPE_AUDIO: {
-
TrackCacheAudio *track_audio = memnew(TrackCacheAudio);
track_audio->object = child;
@@ -676,7 +652,6 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
} break;
case Animation::TYPE_ANIMATION: {
-
TrackCacheAnimation *track_animation = memnew(TrackCacheAnimation);
track_animation->object = child;
@@ -700,7 +675,7 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
List<NodePath> to_delete;
- const NodePath *K = NULL;
+ const NodePath *K = nullptr;
while ((K = track_cache.next(K))) {
TrackCache *tc = track_cache[*K];
if (tc->setup_pass != setup_pass) {
@@ -717,7 +692,7 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
state.track_map.clear();
- K = NULL;
+ K = nullptr;
int idx = 0;
while ((K = track_cache.next(K))) {
state.track_map[*K] = idx;
@@ -732,8 +707,7 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
}
void AnimationTree::_clear_caches() {
-
- const NodePath *K = NULL;
+ const NodePath *K = nullptr;
while ((K = track_cache.next(K))) {
memdelete(track_cache[*K]);
}
@@ -744,7 +718,6 @@ void AnimationTree::_clear_caches() {
}
void AnimationTree::_process_graph(float p_delta) {
-
_update_properties(); //if properties need updating, update them
//check all tracks, see if they need modification
@@ -767,23 +740,22 @@ void AnimationTree::_process_graph(float p_delta) {
AnimationPlayer *player = Object::cast_to<AnimationPlayer>(get_node(animation_player));
- ObjectID current_animation_player = 0;
+ ObjectID current_animation_player;
if (player) {
current_animation_player = player->get_instance_id();
}
if (last_animation_player != current_animation_player) {
-
- if (last_animation_player) {
+ if (last_animation_player.is_valid()) {
Object *old_player = ObjectDB::get_instance(last_animation_player);
if (old_player) {
- old_player->disconnect("caches_cleared", this, "_clear_caches");
+ old_player->disconnect("caches_cleared", callable_mp(this, &AnimationTree::_clear_caches));
}
}
if (player) {
- player->connect("caches_cleared", this, "_clear_caches");
+ player->connect("caches_cleared", callable_mp(this, &AnimationTree::_clear_caches));
}
last_animation_player = current_animation_player;
@@ -826,14 +798,13 @@ void AnimationTree::_process_graph(float p_delta) {
//process
{
-
if (started) {
//if started, seek
- root->_pre_process(SceneStringNames::get_singleton()->parameters_base_path, NULL, &state, 0, true, Vector<StringName>());
+ root->_pre_process(SceneStringNames::get_singleton()->parameters_base_path, nullptr, &state, 0, true, Vector<StringName>());
started = false;
}
- root->_pre_process(SceneStringNames::get_singleton()->parameters_base_path, NULL, &state, p_delta, false, Vector<StringName>());
+ root->_pre_process(SceneStringNames::get_singleton()->parameters_base_path, nullptr, &state, p_delta, false, Vector<StringName>());
}
if (!state.valid) {
@@ -842,11 +813,9 @@ void AnimationTree::_process_graph(float p_delta) {
//apply value/transform/bezier blends to track caches and execute method/audio/animation tracks
{
-
bool can_call = is_inside_tree() && !Engine::get_singleton()->is_editor_hint();
for (List<AnimationNode::AnimationState>::Element *E = state.animation_states.front(); E; E = E->next()) {
-
const AnimationNode::AnimationState &as = E->get();
Ref<Animation> a = as.animation;
@@ -855,7 +824,6 @@ void AnimationTree::_process_graph(float p_delta) {
bool seeked = as.seeked;
for (int i = 0; i < a->get_track_count(); i++) {
-
NodePath path = a->track_get_path(i);
ERR_CONTINUE(!track_cache.has(path));
@@ -874,19 +842,16 @@ void AnimationTree::_process_graph(float p_delta) {
float blend = (*as.track_blends)[blend_idx];
- if (blend < CMP_EPSILON)
+ if (blend < CMP_EPSILON) {
continue; //nothing to blend
+ }
switch (track->type) {
-
case Animation::TYPE_TRANSFORM: {
-
TrackCacheTransform *t = static_cast<TrackCacheTransform *>(track);
if (track->root_motion) {
-
if (t->process_pass != process_pass) {
-
t->process_pass = process_pass;
t->loc = Vector3();
t->rot = Quat();
@@ -908,7 +873,6 @@ void AnimationTree::_process_graph(float p_delta) {
Vector3 scale[2];
if (prev_time > time) {
-
Error err = a->transform_track_interpolate(i, prev_time, &loc[0], &rot[0], &scale[0]);
if (err != OK) {
continue;
@@ -947,7 +911,6 @@ void AnimationTree::_process_graph(float p_delta) {
//ERR_CONTINUE(err!=OK); //used for testing, should be removed
if (t->process_pass != process_pass) {
-
t->process_pass = process_pass;
t->loc = loc;
t->rot = rot;
@@ -955,10 +918,11 @@ void AnimationTree::_process_graph(float p_delta) {
t->scale = scale;
}
- if (err != OK)
+ if (err != OK) {
continue;
+ }
- t->loc = t->loc.linear_interpolate(loc, blend);
+ t->loc = t->loc.lerp(loc, blend);
if (t->rot_blend_accum == 0) {
t->rot = rot;
t->rot_blend_accum = blend;
@@ -967,12 +931,11 @@ void AnimationTree::_process_graph(float p_delta) {
t->rot = rot.slerp(t->rot, t->rot_blend_accum / rot_total).normalized();
t->rot_blend_accum = rot_total;
}
- t->scale = t->scale.linear_interpolate(scale, blend);
+ t->scale = t->scale.lerp(scale, blend);
}
} break;
case Animation::TYPE_VALUE: {
-
TrackCacheValue *t = static_cast<TrackCacheValue *>(track);
Animation::UpdateMode update_mode = a->value_track_get_update_mode(i);
@@ -981,8 +944,9 @@ void AnimationTree::_process_graph(float p_delta) {
Variant value = a->value_track_interpolate(i, time);
- if (value == Variant())
+ if (value == Variant()) {
continue;
+ }
if (t->process_pass != process_pass) {
t->value = value;
@@ -992,12 +956,10 @@ void AnimationTree::_process_graph(float p_delta) {
Variant::interpolate(t->value, value, blend, t->value);
} else if (delta != 0) {
-
List<int> indices;
a->value_track_get_key_indices(i, time, delta, &indices);
for (List<int>::Element *F = indices.front(); F; F = F->next()) {
-
Variant value = a->track_get_key_value(i, F->get());
t->object->set_indexed(t->subpath, value);
}
@@ -1005,7 +967,6 @@ void AnimationTree::_process_graph(float p_delta) {
} break;
case Animation::TYPE_METHOD: {
-
if (delta == 0) {
continue;
}
@@ -1016,7 +977,6 @@ void AnimationTree::_process_graph(float p_delta) {
a->method_track_get_key_indices(i, time, delta, &indices);
for (List<int>::Element *F = indices.front(); F; F = F->next()) {
-
StringName method = a->method_track_get_name(i, F->get());
Vector<Variant> params = a->method_track_get_params(i, F->get());
@@ -1036,7 +996,6 @@ void AnimationTree::_process_graph(float p_delta) {
} break;
case Animation::TYPE_BEZIER: {
-
TrackCacheBezier *t = static_cast<TrackCacheBezier *>(track);
float bezier = a->bezier_track_interpolate(i, time);
@@ -1050,14 +1009,14 @@ void AnimationTree::_process_graph(float p_delta) {
} break;
case Animation::TYPE_AUDIO: {
-
TrackCacheAudio *t = static_cast<TrackCacheAudio *>(track);
if (seeked) {
//find whathever should be playing
int idx = a->track_find_key(i, time);
- if (idx < 0)
+ if (idx < 0) {
continue;
+ }
Ref<AudioStream> stream = a->audio_track_get_key_stream(i, idx);
if (!stream.is_valid()) {
@@ -1122,7 +1081,6 @@ void AnimationTree::_process_graph(float p_delta) {
t->start = time;
}
} else if (t->playing) {
-
bool loop = a->has_loop();
bool stop = false;
@@ -1154,25 +1112,27 @@ void AnimationTree::_process_graph(float p_delta) {
}
} break;
case Animation::TYPE_ANIMATION: {
-
TrackCacheAnimation *t = static_cast<TrackCacheAnimation *>(track);
AnimationPlayer *player2 = Object::cast_to<AnimationPlayer>(t->object);
- if (!player2)
+ if (!player2) {
continue;
+ }
if (delta == 0 || seeked) {
//seek
int idx = a->track_find_key(i, time);
- if (idx < 0)
+ if (idx < 0) {
continue;
+ }
float pos = a->track_get_key_time(i, idx);
StringName anim_name = a->animation_track_get_key_animation(i, idx);
- if (String(anim_name) == "[stop]" || !player2->has_animation(anim_name))
+ if (String(anim_name) == "[stop]" || !player2->has_animation(anim_name)) {
continue;
+ }
Ref<Animation> anim = player2->get_animation(anim_name);
@@ -1202,7 +1162,6 @@ void AnimationTree::_process_graph(float p_delta) {
StringName anim_name = a->animation_track_get_key_animation(i, idx);
if (String(anim_name) == "[stop]" || !player2->has_animation(anim_name)) {
-
if (playing_caches.has(t)) {
playing_caches.erase(t);
player2->stop();
@@ -1224,16 +1183,15 @@ void AnimationTree::_process_graph(float p_delta) {
{
// finally, set the tracks
- const NodePath *K = NULL;
+ const NodePath *K = nullptr;
while ((K = track_cache.next(K))) {
TrackCache *track = track_cache[*K];
- if (track->process_pass != process_pass)
+ if (track->process_pass != process_pass) {
continue; //not processed, ignore
+ }
switch (track->type) {
-
case Animation::TYPE_TRANSFORM: {
-
TrackCacheTransform *t = static_cast<TrackCacheTransform *>(track);
Transform xform;
@@ -1242,31 +1200,26 @@ void AnimationTree::_process_graph(float p_delta) {
xform.basis.set_quat_scale(t->rot, t->scale);
if (t->root_motion) {
-
root_motion_transform = xform;
if (t->skeleton && t->bone_idx >= 0) {
root_motion_transform = (t->skeleton->get_bone_rest(t->bone_idx) * root_motion_transform) * t->skeleton->get_bone_rest(t->bone_idx).affine_inverse();
}
} else if (t->skeleton && t->bone_idx >= 0) {
-
t->skeleton->set_bone_pose(t->bone_idx, xform);
} else {
-
t->spatial->set_transform(xform);
}
} break;
case Animation::TYPE_VALUE: {
-
TrackCacheValue *t = static_cast<TrackCacheValue *>(track);
t->object->set_indexed(t->subpath, t->value);
} break;
case Animation::TYPE_BEZIER: {
-
TrackCacheBezier *t = static_cast<TrackCacheBezier *>(track);
t->object->set_indexed(t->subpath, t->value);
@@ -1280,12 +1233,10 @@ void AnimationTree::_process_graph(float p_delta) {
}
void AnimationTree::advance(float p_time) {
-
_process_graph(p_time);
}
void AnimationTree::_notification(int p_what) {
-
if (active && p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS && process_mode == ANIMATION_PROCESS_PHYSICS) {
_process_graph(get_physics_process_delta_time());
}
@@ -1296,19 +1247,17 @@ void AnimationTree::_notification(int p_what) {
if (p_what == NOTIFICATION_EXIT_TREE) {
_clear_caches();
- if (last_animation_player) {
-
+ if (last_animation_player.is_valid()) {
Object *player = ObjectDB::get_instance(last_animation_player);
if (player) {
- player->disconnect("caches_cleared", this, "_clear_caches");
+ player->disconnect("caches_cleared", callable_mp(this, &AnimationTree::_clear_caches));
}
}
} else if (p_what == NOTIFICATION_ENTER_TREE) {
- if (last_animation_player) {
-
+ if (last_animation_player.is_valid()) {
Object *player = ObjectDB::get_instance(last_animation_player);
if (player) {
- player->connect("caches_cleared", this, "_clear_caches");
+ player->connect("caches_cleared", callable_mp(this, &AnimationTree::_clear_caches));
}
}
}
@@ -1324,11 +1273,10 @@ NodePath AnimationTree::get_animation_player() const {
}
bool AnimationTree::is_state_invalid() const {
-
return !state.valid;
}
-String AnimationTree::get_invalid_state_reason() const {
+String AnimationTree::get_invalid_state_reason() const {
return state.invalid_reasons;
}
@@ -1337,7 +1285,6 @@ uint64_t AnimationTree::get_last_process_pass() const {
}
String AnimationTree::get_configuration_warning() const {
-
String warning = Node::get_configuration_warning();
if (!root.is_valid()) {
@@ -1348,7 +1295,6 @@ String AnimationTree::get_configuration_warning() const {
}
if (!has_node(animation_player)) {
-
if (warning != String()) {
warning += "\n\n";
}
@@ -1402,13 +1348,11 @@ void AnimationTree::_tree_changed() {
}
void AnimationTree::_update_properties_for_node(const String &p_base_path, Ref<AnimationNode> node) {
-
if (!property_parent_map.has(p_base_path)) {
property_parent_map[p_base_path] = HashMap<StringName, StringName>();
}
if (node->get_input_count() && !input_activity_map.has(p_base_path)) {
-
Vector<Activity> activity;
for (int i = 0; i < node->get_input_count(); i++) {
Activity a;
@@ -1492,6 +1436,7 @@ bool AnimationTree::_get(const StringName &p_name, Variant &r_ret) const {
return false;
}
+
void AnimationTree::_get_property_list(List<PropertyInfo> *p_list) const {
if (properties_dirty) {
const_cast<AnimationTree *>(this)->_update_properties();
@@ -1503,7 +1448,6 @@ void AnimationTree::_get_property_list(List<PropertyInfo> *p_list) const {
}
void AnimationTree::rename_parameter(const String &p_base, const String &p_new_base) {
-
//rename values first
for (const List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) {
if (E->get().name.begins_with(p_base)) {
@@ -1518,7 +1462,6 @@ void AnimationTree::rename_parameter(const String &p_base, const String &p_new_b
}
float AnimationTree::get_connection_activity(const StringName &p_path, int p_connection) const {
-
if (!input_activity_map_get.has(p_path)) {
return 0;
}
@@ -1553,16 +1496,12 @@ void AnimationTree::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_root_motion_transform"), &AnimationTree::get_root_motion_transform);
- ClassDB::bind_method(D_METHOD("_tree_changed"), &AnimationTree::_tree_changed);
ClassDB::bind_method(D_METHOD("_update_properties"), &AnimationTree::_update_properties);
ClassDB::bind_method(D_METHOD("rename_parameter", "old_name", "new_name"), &AnimationTree::rename_parameter);
ClassDB::bind_method(D_METHOD("advance", "delta"), &AnimationTree::advance);
- ClassDB::bind_method(D_METHOD("_node_removed"), &AnimationTree::_node_removed);
- ClassDB::bind_method(D_METHOD("_clear_caches"), &AnimationTree::_clear_caches);
-
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");
@@ -1576,7 +1515,6 @@ void AnimationTree::_bind_methods() {
}
AnimationTree::AnimationTree() {
-
process_mode = ANIMATION_PROCESS_IDLE;
active = false;
cache_valid = false;
@@ -1584,7 +1522,6 @@ AnimationTree::AnimationTree() {
process_pass = 1;
started = true;
properties_dirty = true;
- last_animation_player = 0;
}
AnimationTree::~AnimationTree() {
diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h
index 0a8dc8109f..166ca04f40 100644
--- a/scene/animation/animation_tree.h
+++ b/scene/animation/animation_tree.h
@@ -32,8 +32,8 @@
#define ANIMATION_GRAPH_PLAYER_H
#include "animation_player.h"
-#include "scene/3d/skeleton.h"
-#include "scene/3d/spatial.h"
+#include "scene/3d/node_3d.h"
+#include "scene/3d/skeleton_3d.h"
#include "scene/resources/animation.h"
class AnimationNodeBlendTree;
@@ -52,7 +52,6 @@ public:
};
struct Input {
-
String name;
};
@@ -63,7 +62,6 @@ public:
friend class AnimationTree;
struct AnimationState {
-
Ref<Animation> animation;
float time;
float delta;
@@ -73,7 +71,6 @@ public:
};
struct State {
-
int track_count;
HashMap<NodePath, int> track_map;
List<AnimationState> animation_states;
@@ -101,7 +98,7 @@ public:
Array _get_filters() const;
void _set_filters(const Array &p_filters);
friend class AnimationNodeBlendTree;
- float _blend_node(const StringName &p_subpath, const Vector<StringName> &p_connections, AnimationNode *p_new_parent, Ref<AnimationNode> p_node, float p_time, bool p_seek, float p_blend, FilterAction p_filter = FILTER_IGNORE, bool p_optimize = true, float *r_max = NULL);
+ float _blend_node(const StringName &p_subpath, const Vector<StringName> &p_connections, AnimationNode *p_new_parent, Ref<AnimationNode> p_node, float p_time, bool p_seek, float p_blend, FilterAction p_filter = FILTER_IGNORE, bool p_optimize = true, float *r_max = nullptr);
protected:
void blend_animation(const StringName &p_animation, float p_time, float p_delta, bool p_seeked, float p_blend);
@@ -111,7 +108,7 @@ protected:
static void _bind_methods();
- void _validate_property(PropertyInfo &property) const;
+ void _validate_property(PropertyInfo &property) const override;
void _set_parent(Object *p_parent);
@@ -174,7 +171,6 @@ public:
private:
struct TrackCache {
-
bool root_motion;
uint64_t setup_pass;
uint64_t process_pass;
@@ -186,15 +182,14 @@ private:
root_motion = false;
setup_pass = 0;
process_pass = 0;
- object = NULL;
- object_id = 0;
+ object = nullptr;
}
virtual ~TrackCache() {}
};
struct TrackCacheTransform : public TrackCache {
- Spatial *spatial;
- Skeleton *skeleton;
+ Node3D *spatial;
+ Skeleton3D *skeleton;
int bone_idx;
Vector3 loc;
Quat rot;
@@ -203,26 +198,23 @@ private:
TrackCacheTransform() {
type = Animation::TYPE_TRANSFORM;
- spatial = NULL;
+ spatial = nullptr;
bone_idx = -1;
- skeleton = NULL;
+ skeleton = nullptr;
}
};
struct TrackCacheValue : public TrackCache {
-
Variant value;
Vector<StringName> subpath;
TrackCacheValue() { type = Animation::TYPE_VALUE; }
};
struct TrackCacheMethod : public TrackCache {
-
TrackCacheMethod() { type = Animation::TYPE_METHOD; }
};
struct TrackCacheBezier : public TrackCache {
-
float value;
Vector<StringName> subpath;
TrackCacheBezier() {
@@ -232,7 +224,6 @@ private:
};
struct TrackCacheAudio : public TrackCache {
-
bool playing;
float start;
float len;
@@ -246,7 +237,6 @@ private:
};
struct TrackCacheAnimation : public TrackCache {
-
bool playing;
TrackCacheAnimation() {
@@ -286,7 +276,7 @@ private:
void _tree_changed();
void _update_properties();
List<PropertyInfo> properties;
- HashMap<StringName, HashMap<StringName, StringName> > property_parent_map;
+ HashMap<StringName, HashMap<StringName, StringName>> property_parent_map;
HashMap<StringName, Variant> property_map;
struct Activity {
@@ -294,7 +284,7 @@ private:
float activity;
};
- HashMap<StringName, Vector<Activity> > input_activity_map;
+ HashMap<StringName, Vector<Activity>> input_activity_map;
HashMap<StringName, Vector<Activity> *> input_activity_map_get;
void _update_properties_for_node(const String &p_base_path, Ref<AnimationNode> node);
@@ -322,7 +312,7 @@ public:
void set_animation_player(const NodePath &p_player);
NodePath get_animation_player() const;
- virtual String get_configuration_warning() const;
+ virtual String get_configuration_warning() const override;
bool is_state_invalid() const;
String get_invalid_state_reason() const;
diff --git a/scene/animation/animation_tree_player.cpp b/scene/animation/animation_tree_player.cpp
deleted file mode 100644
index c7362391dc..0000000000
--- a/scene/animation/animation_tree_player.cpp
+++ /dev/null
@@ -1,1866 +0,0 @@
-/*************************************************************************/
-/* animation_tree_player.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 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 */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "animation_tree_player.h"
-#include "animation_player.h"
-
-#include "scene/scene_string_names.h"
-
-void AnimationTreePlayer::set_animation_process_mode(AnimationProcessMode p_mode) {
-
- if (animation_process_mode == p_mode)
- return;
-
- bool pr = processing;
- if (pr)
- _set_process(false);
- animation_process_mode = p_mode;
- if (pr)
- _set_process(true);
-}
-
-AnimationTreePlayer::AnimationProcessMode AnimationTreePlayer::get_animation_process_mode() const {
-
- return animation_process_mode;
-}
-
-void AnimationTreePlayer::_set_process(bool p_process, bool p_force) {
- if (processing == p_process && !p_force)
- return;
-
- switch (animation_process_mode) {
-
- case ANIMATION_PROCESS_PHYSICS: set_physics_process_internal(p_process && active); break;
- case ANIMATION_PROCESS_IDLE: set_process_internal(p_process && active); break;
- }
-
- processing = p_process;
-}
-
-bool AnimationTreePlayer::_set(const StringName &p_name, const Variant &p_value) {
-
- if (String(p_name) == "base_path") {
- set_base_path(p_value);
- return true;
- }
-
- if (String(p_name) == "master_player") {
- set_master_player(p_value);
- return true;
- }
-
- if (String(p_name) == SceneStringNames::get_singleton()->playback_active) {
- set_active(p_value);
- return true;
- }
-
- if (String(p_name) != "data")
- return false;
-
- Dictionary data = p_value;
-
- Array nodes = data.get_valid("nodes");
-
- for (int i = 0; i < nodes.size(); i++) {
-
- Dictionary node = nodes[i];
-
- StringName id = node.get_valid("id");
- Point2 pos = node.get_valid("position");
-
- NodeType nt = NODE_MAX;
- String type = node.get_valid("type");
-
- if (type == "output")
- nt = NODE_OUTPUT;
- else if (type == "animation")
- nt = NODE_ANIMATION;
- else if (type == "oneshot")
- nt = NODE_ONESHOT;
- else if (type == "mix")
- nt = NODE_MIX;
- else if (type == "blend2")
- nt = NODE_BLEND2;
- else if (type == "blend3")
- nt = NODE_BLEND3;
- else if (type == "blend4")
- nt = NODE_BLEND4;
- else if (type == "timescale")
- nt = NODE_TIMESCALE;
- else if (type == "timeseek")
- nt = NODE_TIMESEEK;
- else if (type == "transition")
- nt = NODE_TRANSITION;
-
- ERR_FAIL_COND_V(nt == NODE_MAX, false);
-
- if (nt != NODE_OUTPUT)
- add_node(nt, id);
- node_set_position(id, pos);
-
- switch (nt) {
- case NODE_OUTPUT: {
-
- } break;
- case NODE_ANIMATION: {
-
- if (node.has("from"))
- animation_node_set_master_animation(id, node.get_valid("from"));
- else
- animation_node_set_animation(id, node.get_valid("animation"));
- Array filters = node.get_valid("filter");
- for (int j = 0; j < filters.size(); j++) {
-
- animation_node_set_filter_path(id, filters[j], true);
- }
- } break;
- case NODE_ONESHOT: {
-
- oneshot_node_set_fadein_time(id, node.get_valid("fade_in"));
- oneshot_node_set_fadeout_time(id, node.get_valid("fade_out"));
- oneshot_node_set_mix_mode(id, node.get_valid("mix"));
- oneshot_node_set_autorestart(id, node.get_valid("autorestart"));
- oneshot_node_set_autorestart_delay(id, node.get_valid("autorestart_delay"));
- oneshot_node_set_autorestart_random_delay(id, node.get_valid("autorestart_random_delay"));
- Array filters = node.get_valid("filter");
- for (int j = 0; j < filters.size(); j++) {
-
- oneshot_node_set_filter_path(id, filters[j], true);
- }
-
- } break;
- case NODE_MIX: {
- mix_node_set_amount(id, node.get_valid("mix"));
- } break;
- case NODE_BLEND2: {
- blend2_node_set_amount(id, node.get_valid("blend"));
- Array filters = node.get_valid("filter");
- for (int j = 0; j < filters.size(); j++) {
-
- blend2_node_set_filter_path(id, filters[j], true);
- }
- } break;
- case NODE_BLEND3: {
- blend3_node_set_amount(id, node.get_valid("blend"));
- } break;
- case NODE_BLEND4: {
- blend4_node_set_amount(id, node.get_valid("blend"));
- } break;
- case NODE_TIMESCALE: {
- timescale_node_set_scale(id, node.get_valid("scale"));
- } break;
- case NODE_TIMESEEK: {
- } break;
- case NODE_TRANSITION: {
-
- transition_node_set_xfade_time(id, node.get_valid("xfade"));
-
- Array transitions = node.get_valid("transitions");
- transition_node_set_input_count(id, transitions.size());
-
- for (int x = 0; x < transitions.size(); x++) {
-
- Dictionary d = transitions[x];
- bool aa = d.get_valid("auto_advance");
- transition_node_set_input_auto_advance(id, x, aa);
- }
-
- } break;
- default: {
- };
- }
- }
-
- Array connections = data.get_valid("connections");
- ERR_FAIL_COND_V(connections.size() % 3, false);
-
- int cc = connections.size() / 3;
-
- for (int i = 0; i < cc; i++) {
-
- StringName src = connections[i * 3 + 0];
- StringName dst = connections[i * 3 + 1];
- int dst_in = connections[i * 3 + 2];
- connect_nodes(src, dst, dst_in);
- }
-
- set_active(data.get_valid("active"));
- set_master_player(data.get_valid("master"));
-
- return true;
-}
-
-bool AnimationTreePlayer::_get(const StringName &p_name, Variant &r_ret) const {
-
- if (String(p_name) == "base_path") {
- r_ret = base_path;
- return true;
- }
-
- if (String(p_name) == "master_player") {
- r_ret = master;
- return true;
- }
-
- if (String(p_name) == "playback/active") {
- r_ret = is_active();
- return true;
- }
-
- if (String(p_name) != "data")
- return false;
-
- Dictionary data;
-
- Array nodes;
-
- for (Map<StringName, NodeBase *>::Element *E = node_map.front(); E; E = E->next()) {
-
- NodeBase *n = node_map[E->key()];
-
- Dictionary node;
- node["id"] = E->key();
- node["position"] = n->pos;
-
- switch (n->type) {
- case NODE_OUTPUT: node["type"] = "output"; break;
- case NODE_ANIMATION: node["type"] = "animation"; break;
- case NODE_ONESHOT: node["type"] = "oneshot"; break;
- case NODE_MIX: node["type"] = "mix"; break;
- case NODE_BLEND2: node["type"] = "blend2"; break;
- case NODE_BLEND3: node["type"] = "blend3"; break;
- case NODE_BLEND4: node["type"] = "blend4"; break;
- case NODE_TIMESCALE: node["type"] = "timescale"; break;
- case NODE_TIMESEEK: node["type"] = "timeseek"; break;
- case NODE_TRANSITION: node["type"] = "transition"; break;
- default: node["type"] = ""; break;
- }
-
- switch (n->type) {
- case NODE_OUTPUT: {
-
- } break;
- case NODE_ANIMATION: {
- AnimationNode *an = static_cast<AnimationNode *>(n);
- if (master != NodePath() && an->from != "") {
- node["from"] = an->from;
- } else {
- node["animation"] = an->animation;
- }
- Array k;
- List<NodePath> keys;
- an->filter.get_key_list(&keys);
- k.resize(keys.size());
- int i = 0;
- for (List<NodePath>::Element *F = keys.front(); F; F = F->next()) {
- k[i++] = F->get();
- }
- node["filter"] = k;
- } break;
- case NODE_ONESHOT: {
- OneShotNode *osn = static_cast<OneShotNode *>(n);
- node["fade_in"] = osn->fade_in;
- node["fade_out"] = osn->fade_out;
- node["mix"] = osn->mix;
- node["autorestart"] = osn->autorestart;
- node["autorestart_delay"] = osn->autorestart_delay;
- node["autorestart_random_delay"] = osn->autorestart_random_delay;
-
- Array k;
- List<NodePath> keys;
- osn->filter.get_key_list(&keys);
- k.resize(keys.size());
- int i = 0;
- for (List<NodePath>::Element *F = keys.front(); F; F = F->next()) {
- k[i++] = F->get();
- }
- node["filter"] = k;
-
- } break;
- case NODE_MIX: {
- MixNode *mn = static_cast<MixNode *>(n);
- node["mix"] = mn->amount;
- } break;
- case NODE_BLEND2: {
- Blend2Node *bn = static_cast<Blend2Node *>(n);
- node["blend"] = bn->value;
- Array k;
- List<NodePath> keys;
- bn->filter.get_key_list(&keys);
- k.resize(keys.size());
- int i = 0;
- for (List<NodePath>::Element *F = keys.front(); F; F = F->next()) {
- k[i++] = F->get();
- }
- node["filter"] = k;
-
- } break;
- case NODE_BLEND3: {
- Blend3Node *bn = static_cast<Blend3Node *>(n);
- node["blend"] = bn->value;
- } break;
- case NODE_BLEND4: {
- Blend4Node *bn = static_cast<Blend4Node *>(n);
- node["blend"] = bn->value;
-
- } break;
- case NODE_TIMESCALE: {
- TimeScaleNode *tsn = static_cast<TimeScaleNode *>(n);
- node["scale"] = tsn->scale;
- } break;
- case NODE_TIMESEEK: {
- } break;
- case NODE_TRANSITION: {
-
- TransitionNode *tn = static_cast<TransitionNode *>(n);
- node["xfade"] = tn->xfade;
- Array transitions;
-
- for (int i = 0; i < tn->input_data.size(); i++) {
-
- Dictionary d;
- d["auto_advance"] = tn->input_data[i].auto_advance;
- transitions.push_back(d);
- }
-
- node["transitions"] = transitions;
-
- } break;
- default: {
- };
- }
-
- nodes.push_back(node);
- }
-
- data["nodes"] = nodes;
- //connectiosn
-
- List<Connection> connections;
- get_connection_list(&connections);
- Array connections_arr;
- connections_arr.resize(connections.size() * 3);
-
- int idx = 0;
- for (List<Connection>::Element *E = connections.front(); E; E = E->next()) {
-
- connections_arr.set(idx + 0, E->get().src_node);
- connections_arr.set(idx + 1, E->get().dst_node);
- connections_arr.set(idx + 2, E->get().dst_input);
-
- idx += 3;
- }
-
- data["connections"] = connections_arr;
- data["active"] = active;
- data["master"] = master;
-
- r_ret = data;
-
- return true;
-}
-
-void AnimationTreePlayer::_get_property_list(List<PropertyInfo> *p_list) const {
-
- p_list->push_back(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_NETWORK));
-}
-
-void AnimationTreePlayer::advance(float p_time) {
-
- _process_animation(p_time);
-}
-
-void AnimationTreePlayer::_notification(int p_what) {
-
- switch (p_what) {
-
- case NOTIFICATION_ENTER_TREE: {
-
- WARN_DEPRECATED_MSG("AnimationTreePlayer has been deprecated. Use AnimationTree instead.");
-
- if (!processing) {
- //make sure that a previous process state was not saved
- //only process if "processing" is set
- set_physics_process_internal(false);
- set_process_internal(false);
- }
- } break;
- case NOTIFICATION_READY: {
-
- dirty_caches = true;
- if (master != NodePath()) {
- _update_sources();
- }
- } break;
- case NOTIFICATION_INTERNAL_PROCESS: {
-
- if (animation_process_mode == ANIMATION_PROCESS_PHYSICS)
- break;
-
- if (processing)
- _process_animation(get_process_delta_time());
- } break;
- case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
-
- if (animation_process_mode == ANIMATION_PROCESS_IDLE)
- break;
-
- if (processing)
- _process_animation(get_physics_process_delta_time());
- } break;
- }
-}
-
-void AnimationTreePlayer::_compute_weights(float *p_fallback_weight, HashMap<NodePath, float> *p_weights, float p_coeff, const HashMap<NodePath, bool> *p_filter, float p_filtered_coeff) {
-
- if (p_filter != NULL) {
-
- List<NodePath> key_list;
- p_filter->get_key_list(&key_list);
-
- for (List<NodePath>::Element *E = key_list.front(); E; E = E->next()) {
-
- if ((*p_filter)[E->get()]) {
-
- if (p_weights->has(E->get())) {
- (*p_weights)[E->get()] *= p_filtered_coeff;
- } else {
- p_weights->set(E->get(), *p_fallback_weight * p_filtered_coeff);
- }
-
- } else if (p_weights->has(E->get())) {
- (*p_weights)[E->get()] *= p_coeff;
- }
- }
- }
-
- List<NodePath> key_list;
- p_weights->get_key_list(&key_list);
-
- for (List<NodePath>::Element *E = key_list.front(); E; E = E->next()) {
- if (p_filter == NULL || !p_filter->has(E->get())) {
- (*p_weights)[E->get()] *= p_coeff;
- }
- }
-
- *p_fallback_weight *= p_coeff;
-}
-
-float AnimationTreePlayer::_process_node(const StringName &p_node, AnimationNode **r_prev_anim, float p_time, bool p_seek, float p_fallback_weight, HashMap<NodePath, float> *p_weights) {
-
- ERR_FAIL_COND_V(!node_map.has(p_node), 0);
- NodeBase *nb = node_map[p_node];
-
- //transform to seconds...
-
- switch (nb->type) {
-
- case NODE_OUTPUT: {
-
- NodeOut *on = static_cast<NodeOut *>(nb);
- HashMap<NodePath, float> weights;
-
- return _process_node(on->inputs[0].node, r_prev_anim, p_time, p_seek, p_fallback_weight, &weights);
-
- } break;
- case NODE_ANIMATION: {
-
- AnimationNode *an = static_cast<AnimationNode *>(nb);
-
- float rem = 0;
- if (!an->animation.is_null()) {
-
- //float pos = an->time;
- //float delta = p_time;
-
- //const Animation *a = an->animation.operator->();
-
- if (p_seek) {
- an->time = p_time;
- an->step = 0;
- } else {
- an->time = MAX(0, an->time + p_time);
- an->step = p_time;
- }
-
- float anim_size = an->animation->get_length();
-
- if (an->animation->has_loop()) {
-
- if (anim_size)
- an->time = Math::fposmod(an->time, anim_size);
-
- } else if (an->time > anim_size) {
-
- an->time = anim_size;
- }
-
- an->skip = true;
-
- for (List<AnimationNode::TrackRef>::Element *E = an->tref.front(); E; E = E->next()) {
- NodePath track_path = an->animation->track_get_path(E->get().local_track);
- if (an->filter.has(track_path) && an->filter[track_path]) {
- E->get().weight = 0;
- } else {
- if (p_weights->has(track_path)) {
- float weight = (*p_weights)[track_path];
- E->get().weight = weight;
- } else {
- E->get().weight = p_fallback_weight;
- }
- }
- if (E->get().weight > CMP_EPSILON)
- an->skip = false;
- }
-
- rem = anim_size - an->time;
- }
-
- if (!(*r_prev_anim))
- active_list = an;
- else
- (*r_prev_anim)->next = an;
-
- an->next = NULL;
- *r_prev_anim = an;
-
- return rem;
-
- } break;
- case NODE_ONESHOT: {
-
- OneShotNode *osn = static_cast<OneShotNode *>(nb);
-
- if (!osn->active) {
- //make it as if this node doesn't exist, pass input 0 by.
- return _process_node(osn->inputs[0].node, r_prev_anim, p_time, p_seek, p_fallback_weight, p_weights);
- }
-
- bool os_seek = p_seek;
-
- if (p_seek)
- osn->time = p_time;
- if (osn->start) {
- osn->time = 0;
- os_seek = true;
- }
-
- float blend;
-
- if (osn->time < osn->fade_in) {
-
- if (osn->fade_in > 0)
- blend = osn->time / osn->fade_in;
- else
- blend = 0; //wtf
-
- } else if (!osn->start && osn->remaining < osn->fade_out) {
-
- if (osn->fade_out)
- blend = (osn->remaining / osn->fade_out);
- else
- blend = 1.0;
- } else
- blend = 1.0;
-
- float main_rem;
- float os_rem;
-
- HashMap<NodePath, float> os_weights(*p_weights);
- float os_fallback_weight = p_fallback_weight;
- _compute_weights(&p_fallback_weight, p_weights, osn->mix ? 1.0 : 1.0 - blend, &osn->filter, 1.0);
- _compute_weights(&os_fallback_weight, &os_weights, blend, &osn->filter, 0.0);
-
- main_rem = _process_node(osn->inputs[0].node, r_prev_anim, p_time, p_seek, p_fallback_weight, p_weights);
- os_rem = _process_node(osn->inputs[1].node, r_prev_anim, p_time, os_seek, os_fallback_weight, &os_weights);
-
- if (osn->start) {
- osn->remaining = os_rem;
- osn->start = false;
- }
-
- if (!p_seek) {
- osn->time += p_time;
- osn->remaining = os_rem;
- if (osn->remaining <= 0)
- osn->active = false;
- }
-
- return MAX(main_rem, osn->remaining);
- } break;
- case NODE_MIX: {
- MixNode *mn = static_cast<MixNode *>(nb);
-
- HashMap<NodePath, float> mn_weights(*p_weights);
- float mn_fallback_weight = p_fallback_weight;
- _compute_weights(&mn_fallback_weight, &mn_weights, mn->amount);
- float rem = _process_node(mn->inputs[0].node, r_prev_anim, p_time, p_seek, p_fallback_weight, p_weights);
- _process_node(mn->inputs[1].node, r_prev_anim, p_time, p_seek, mn_fallback_weight, &mn_weights);
- return rem;
-
- } break;
- case NODE_BLEND2: {
-
- Blend2Node *bn = static_cast<Blend2Node *>(nb);
-
- HashMap<NodePath, float> bn_weights(*p_weights);
- float bn_fallback_weight = p_fallback_weight;
- _compute_weights(&p_fallback_weight, p_weights, 1.0 - bn->value, &bn->filter, 1.0);
- _compute_weights(&bn_fallback_weight, &bn_weights, bn->value, &bn->filter, 0.0);
- float rem = _process_node(bn->inputs[0].node, r_prev_anim, p_time, p_seek, p_fallback_weight, p_weights);
- _process_node(bn->inputs[1].node, r_prev_anim, p_time, p_seek, bn_fallback_weight, &bn_weights);
-
- return rem;
- } break;
- case NODE_BLEND3: {
- Blend3Node *bn = static_cast<Blend3Node *>(nb);
-
- float rem;
- float blend, lower_blend, upper_blend;
- if (bn->value < 0) {
- lower_blend = -bn->value;
- blend = 1.0 - lower_blend;
- upper_blend = 0;
- } else {
- lower_blend = 0;
- blend = 1.0 - bn->value;
- upper_blend = bn->value;
- }
-
- HashMap<NodePath, float> upper_weights(*p_weights);
- float upper_fallback_weight = p_fallback_weight;
- HashMap<NodePath, float> lower_weights(*p_weights);
- float lower_fallback_weight = p_fallback_weight;
- _compute_weights(&upper_fallback_weight, &upper_weights, upper_blend);
- _compute_weights(&p_fallback_weight, p_weights, blend);
- _compute_weights(&lower_fallback_weight, &lower_weights, lower_blend);
-
- rem = _process_node(bn->inputs[1].node, r_prev_anim, p_time, p_seek, p_fallback_weight, p_weights);
- _process_node(bn->inputs[0].node, r_prev_anim, p_time, p_seek, lower_fallback_weight, &lower_weights);
- _process_node(bn->inputs[2].node, r_prev_anim, p_time, p_seek, upper_fallback_weight, &upper_weights);
-
- return rem;
- } break;
- case NODE_BLEND4: {
- Blend4Node *bn = static_cast<Blend4Node *>(nb);
-
- HashMap<NodePath, float> weights1(*p_weights);
- float fallback_weight1 = p_fallback_weight;
- HashMap<NodePath, float> weights2(*p_weights);
- float fallback_weight2 = p_fallback_weight;
- HashMap<NodePath, float> weights3(*p_weights);
- float fallback_weight3 = p_fallback_weight;
-
- _compute_weights(&p_fallback_weight, p_weights, 1.0 - bn->value.x);
- _compute_weights(&fallback_weight1, &weights1, bn->value.x);
- _compute_weights(&fallback_weight2, &weights2, 1.0 - bn->value.y);
- _compute_weights(&fallback_weight3, &weights3, bn->value.y);
-
- float rem = _process_node(bn->inputs[0].node, r_prev_anim, p_time, p_seek, p_fallback_weight, p_weights);
- _process_node(bn->inputs[1].node, r_prev_anim, p_time, p_seek, fallback_weight1, &weights1);
- float rem2 = _process_node(bn->inputs[2].node, r_prev_anim, p_time, p_seek, fallback_weight2, &weights2);
- _process_node(bn->inputs[3].node, r_prev_anim, p_time, p_seek, fallback_weight3, &weights3);
-
- return MAX(rem, rem2);
-
- } break;
- case NODE_TIMESCALE: {
- TimeScaleNode *tsn = static_cast<TimeScaleNode *>(nb);
- float rem;
- if (p_seek)
- rem = _process_node(tsn->inputs[0].node, r_prev_anim, p_time, true, p_fallback_weight, p_weights);
- else
- rem = _process_node(tsn->inputs[0].node, r_prev_anim, p_time * tsn->scale, false, p_fallback_weight, p_weights);
- if (tsn->scale == 0)
- return Math_INF;
- else
- return rem / tsn->scale;
-
- } break;
- case NODE_TIMESEEK: {
-
- TimeSeekNode *tsn = static_cast<TimeSeekNode *>(nb);
- if (tsn->seek_pos >= 0 && !p_seek) {
-
- p_time = tsn->seek_pos;
- p_seek = true;
- }
- tsn->seek_pos = -1;
-
- return _process_node(tsn->inputs[0].node, r_prev_anim, p_time, p_seek, p_fallback_weight, p_weights);
-
- } break;
- case NODE_TRANSITION: {
-
- TransitionNode *tn = static_cast<TransitionNode *>(nb);
- HashMap<NodePath, float> prev_weights(*p_weights);
- float prev_fallback_weight = p_fallback_weight;
-
- if (tn->prev < 0) { // process current animation, check for transition
-
- float rem = _process_node(tn->inputs[tn->current].node, r_prev_anim, p_time, p_seek, p_fallback_weight, p_weights);
- if (p_seek)
- tn->time = p_time;
- else
- tn->time += p_time;
-
- if (tn->input_data[tn->current].auto_advance && rem <= tn->xfade) {
-
- tn->set_current((tn->current + 1) % tn->inputs.size());
- }
-
- return rem;
- } else { // cross-fading from tn->prev to tn->current
-
- float blend = tn->xfade ? (tn->prev_xfading / tn->xfade) : 1;
-
- float rem;
-
- _compute_weights(&p_fallback_weight, p_weights, 1.0 - blend);
- _compute_weights(&prev_fallback_weight, &prev_weights, blend);
-
- if (!p_seek && tn->switched) { //just switched, seek to start of current
-
- rem = _process_node(tn->inputs[tn->current].node, r_prev_anim, 0, true, p_fallback_weight, p_weights);
- } else {
-
- rem = _process_node(tn->inputs[tn->current].node, r_prev_anim, p_time, p_seek, p_fallback_weight, p_weights);
- }
-
- tn->switched = false;
-
- if (p_seek) { // don't seek prev animation
- _process_node(tn->inputs[tn->prev].node, r_prev_anim, 0, false, prev_fallback_weight, &prev_weights);
- tn->time = p_time;
- } else {
- _process_node(tn->inputs[tn->prev].node, r_prev_anim, p_time, false, prev_fallback_weight, &prev_weights);
- tn->time += p_time;
- tn->prev_xfading -= p_time;
- if (tn->prev_xfading < 0) {
-
- tn->prev = -1;
- }
- }
-
- return rem;
- }
-
- } break;
- default: {
- }
- }
-
- return 0;
-}
-
-void AnimationTreePlayer::_process_animation(float p_delta) {
-
- if (last_error != CONNECT_OK)
- return;
-
- if (dirty_caches)
- _recompute_caches();
-
- active_list = NULL;
- AnimationNode *prev = NULL;
-
- if (reset_request) {
-
- _process_node(out_name, &prev, 0, true);
- reset_request = false;
- } else
- _process_node(out_name, &prev, p_delta);
-
- if (dirty_caches) {
- //some animation changed.. ignore this pass
- return;
- }
-
- //update the tracks..
-
- /* STEP 1 CLEAR TRACKS */
-
- for (TrackMap::Element *E = track_map.front(); E; E = E->next()) {
-
- Track &t = E->get();
-
- t.loc.zero();
- t.rot = Quat();
- t.scale.x = 0;
- t.scale.y = 0;
- t.scale.z = 0;
-
- t.value = t.object->get_indexed(t.subpath);
- t.value.zero();
-
- t.skip = false;
- }
-
- /* STEP 2 PROCESS ANIMATIONS */
-
- AnimationNode *anim_list = active_list;
- Quat empty_rot;
-
- while (anim_list) {
-
- if (!anim_list->animation.is_null() && !anim_list->skip) {
- //check if animation is meaningful
- Animation *a = anim_list->animation.operator->();
-
- for (List<AnimationNode::TrackRef>::Element *E = anim_list->tref.front(); E; E = E->next()) {
-
- AnimationNode::TrackRef &tr = E->get();
- if (tr.track == NULL || tr.local_track < 0 || tr.weight < CMP_EPSILON || !a->track_is_enabled(tr.local_track))
- continue;
-
- switch (a->track_get_type(tr.local_track)) {
- case Animation::TYPE_TRANSFORM: { ///< Transform a node or a bone.
-
- Vector3 loc;
- Quat rot;
- Vector3 scale;
- a->transform_track_interpolate(tr.local_track, anim_list->time, &loc, &rot, &scale);
-
- tr.track->loc += loc * tr.weight;
-
- scale.x -= 1.0;
- scale.y -= 1.0;
- scale.z -= 1.0;
- tr.track->scale += scale * tr.weight;
-
- tr.track->rot = tr.track->rot * empty_rot.slerp(rot, tr.weight);
-
- } break;
- case Animation::TYPE_VALUE: { ///< Set a value in a property, can be interpolated.
-
- if (a->value_track_get_update_mode(tr.local_track) == Animation::UPDATE_CONTINUOUS) {
- Variant value = a->value_track_interpolate(tr.local_track, anim_list->time);
- Variant::blend(tr.track->value, value, tr.weight, tr.track->value);
- } else {
- int index = a->track_find_key(tr.local_track, anim_list->time);
- tr.track->value = a->track_get_key_value(tr.local_track, index);
- }
- } break;
- case Animation::TYPE_METHOD: { ///< Call any method on a specific node.
-
- List<int> indices;
- a->method_track_get_key_indices(tr.local_track, anim_list->time, anim_list->step, &indices);
- for (List<int>::Element *F = indices.front(); F; F = F->next()) {
-
- StringName method = a->method_track_get_name(tr.local_track, F->get());
- Vector<Variant> args = a->method_track_get_params(tr.local_track, F->get());
- args.resize(VARIANT_ARG_MAX);
- tr.track->object->call(method, args[0], args[1], args[2], args[3], args[4]);
- }
- } break;
- default: {
- }
- }
- }
- }
-
- anim_list = anim_list->next;
- }
-
- /* STEP 3 APPLY TRACKS */
-
- for (TrackMap::Element *E = track_map.front(); E; E = E->next()) {
-
- Track &t = E->get();
-
- if (t.skip || !t.object)
- continue;
-
- if (t.subpath.size()) { // value track
- t.object->set_indexed(t.subpath, t.value);
- continue;
- }
-
- Transform xform;
- xform.origin = t.loc;
-
- t.scale.x += 1.0;
- t.scale.y += 1.0;
- t.scale.z += 1.0;
- xform.basis.set_quat_scale(t.rot, t.scale);
-
- if (t.bone_idx >= 0) {
- if (t.skeleton)
- t.skeleton->set_bone_pose(t.bone_idx, xform);
-
- } else if (t.spatial) {
-
- t.spatial->set_transform(xform);
- }
- }
-}
-
-void AnimationTreePlayer::add_node(NodeType p_type, const StringName &p_node) {
-
- ERR_FAIL_COND(p_type == NODE_OUTPUT);
- ERR_FAIL_COND(node_map.has(p_node));
-
- NodeBase *n = NULL;
-
- switch (p_type) {
-
- case NODE_ANIMATION: {
-
- n = memnew(AnimationNode);
- } break;
- case NODE_ONESHOT: {
-
- n = memnew(OneShotNode);
-
- } break;
- case NODE_MIX: {
- n = memnew(MixNode);
-
- } break;
- case NODE_BLEND2: {
- n = memnew(Blend2Node);
-
- } break;
- case NODE_BLEND3: {
- n = memnew(Blend3Node);
-
- } break;
- case NODE_BLEND4: {
- n = memnew(Blend4Node);
-
- } break;
- case NODE_TIMESCALE: {
- n = memnew(TimeScaleNode);
-
- } break;
- case NODE_TIMESEEK: {
- n = memnew(TimeSeekNode);
-
- } break;
- case NODE_TRANSITION: {
- n = memnew(TransitionNode);
-
- } break;
- default: {
- }
- }
-
- //n->name+=" "+itos(p_node);
- node_map[p_node] = n;
-}
-
-StringName AnimationTreePlayer::node_get_input_source(const StringName &p_node, int p_input) const {
-
- ERR_FAIL_COND_V(!node_map.has(p_node), StringName());
- ERR_FAIL_INDEX_V(p_input, node_map[p_node]->inputs.size(), StringName());
- return node_map[p_node]->inputs[p_input].node;
-}
-
-int AnimationTreePlayer::node_get_input_count(const StringName &p_node) const {
-
- ERR_FAIL_COND_V(!node_map.has(p_node), -1);
- return node_map[p_node]->inputs.size();
-}
-#define GET_NODE(m_type, m_cast) \
- ERR_FAIL_COND(!node_map.has(p_node)); \
- ERR_FAIL_COND_MSG(node_map[p_node]->type != m_type, "Invalid parameter for node type."); \
- m_cast *n = static_cast<m_cast *>(node_map[p_node]);
-
-void AnimationTreePlayer::animation_node_set_animation(const StringName &p_node, const Ref<Animation> &p_animation) {
-
- GET_NODE(NODE_ANIMATION, AnimationNode);
- n->animation = p_animation;
- dirty_caches = true;
-}
-
-void AnimationTreePlayer::animation_node_set_master_animation(const StringName &p_node, const String &p_master_animation) {
-
- GET_NODE(NODE_ANIMATION, AnimationNode);
- n->from = p_master_animation;
- dirty_caches = true;
- if (master != NodePath())
- _update_sources();
-}
-
-void AnimationTreePlayer::animation_node_set_filter_path(const StringName &p_node, const NodePath &p_track_path, bool p_filter) {
-
- GET_NODE(NODE_ANIMATION, AnimationNode);
-
- if (p_filter)
- n->filter[p_track_path] = true;
- else
- n->filter.erase(p_track_path);
-}
-
-void AnimationTreePlayer::animation_node_set_get_filtered_paths(const StringName &p_node, List<NodePath> *r_paths) const {
-
- GET_NODE(NODE_ANIMATION, AnimationNode);
-
- n->filter.get_key_list(r_paths);
-}
-
-void AnimationTreePlayer::oneshot_node_set_fadein_time(const StringName &p_node, float p_time) {
-
- GET_NODE(NODE_ONESHOT, OneShotNode);
- n->fade_in = p_time;
-}
-
-void AnimationTreePlayer::oneshot_node_set_fadeout_time(const StringName &p_node, float p_time) {
-
- GET_NODE(NODE_ONESHOT, OneShotNode);
- n->fade_out = p_time;
-}
-
-void AnimationTreePlayer::oneshot_node_set_mix_mode(const StringName &p_node, bool p_mix) {
-
- GET_NODE(NODE_ONESHOT, OneShotNode);
- n->mix = p_mix;
-}
-
-void AnimationTreePlayer::oneshot_node_set_autorestart(const StringName &p_node, bool p_active) {
-
- GET_NODE(NODE_ONESHOT, OneShotNode);
- n->autorestart = p_active;
-}
-
-void AnimationTreePlayer::oneshot_node_set_autorestart_delay(const StringName &p_node, float p_time) {
-
- GET_NODE(NODE_ONESHOT, OneShotNode);
- n->autorestart_delay = p_time;
-}
-void AnimationTreePlayer::oneshot_node_set_autorestart_random_delay(const StringName &p_node, float p_time) {
-
- GET_NODE(NODE_ONESHOT, OneShotNode);
- n->autorestart_random_delay = p_time;
-}
-
-void AnimationTreePlayer::oneshot_node_start(const StringName &p_node) {
-
- GET_NODE(NODE_ONESHOT, OneShotNode);
- n->active = true;
- n->start = true;
-}
-
-void AnimationTreePlayer::oneshot_node_stop(const StringName &p_node) {
-
- GET_NODE(NODE_ONESHOT, OneShotNode);
- n->active = false;
-}
-
-void AnimationTreePlayer::oneshot_node_set_filter_path(const StringName &p_node, const NodePath &p_filter, bool p_enable) {
-
- GET_NODE(NODE_ONESHOT, OneShotNode);
-
- if (p_enable)
- n->filter[p_filter] = true;
- else
- n->filter.erase(p_filter);
-}
-
-void AnimationTreePlayer::oneshot_node_set_get_filtered_paths(const StringName &p_node, List<NodePath> *r_paths) const {
-
- GET_NODE(NODE_ONESHOT, OneShotNode);
-
- n->filter.get_key_list(r_paths);
-}
-
-void AnimationTreePlayer::mix_node_set_amount(const StringName &p_node, float p_amount) {
-
- GET_NODE(NODE_MIX, MixNode);
- n->amount = p_amount;
-}
-
-void AnimationTreePlayer::blend2_node_set_amount(const StringName &p_node, float p_amount) {
-
- GET_NODE(NODE_BLEND2, Blend2Node);
- n->value = p_amount;
-}
-
-void AnimationTreePlayer::blend2_node_set_filter_path(const StringName &p_node, const NodePath &p_filter, bool p_enable) {
-
- GET_NODE(NODE_BLEND2, Blend2Node);
-
- if (p_enable)
- n->filter[p_filter] = true;
- else
- n->filter.erase(p_filter);
-}
-
-void AnimationTreePlayer::blend2_node_set_get_filtered_paths(const StringName &p_node, List<NodePath> *r_paths) const {
-
- GET_NODE(NODE_BLEND2, Blend2Node);
-
- n->filter.get_key_list(r_paths);
-}
-
-void AnimationTreePlayer::blend3_node_set_amount(const StringName &p_node, float p_amount) {
-
- GET_NODE(NODE_BLEND3, Blend3Node);
- n->value = p_amount;
-}
-void AnimationTreePlayer::blend4_node_set_amount(const StringName &p_node, const Vector2 &p_amount) {
-
- GET_NODE(NODE_BLEND4, Blend4Node);
- n->value = p_amount;
-}
-void AnimationTreePlayer::timescale_node_set_scale(const StringName &p_node, float p_scale) {
-
- GET_NODE(NODE_TIMESCALE, TimeScaleNode);
- n->scale = p_scale;
-}
-void AnimationTreePlayer::timeseek_node_seek(const StringName &p_node, float p_pos) {
-
- GET_NODE(NODE_TIMESEEK, TimeSeekNode);
- n->seek_pos = p_pos;
-}
-void AnimationTreePlayer::transition_node_set_input_count(const StringName &p_node, int p_inputs) {
-
- GET_NODE(NODE_TRANSITION, TransitionNode);
- ERR_FAIL_COND(p_inputs < 1);
-
- n->inputs.resize(p_inputs);
- n->input_data.resize(p_inputs);
-
- _clear_cycle_test();
-
- last_error = _cycle_test(out_name);
-}
-void AnimationTreePlayer::transition_node_set_input_auto_advance(const StringName &p_node, int p_input, bool p_auto_advance) {
-
- GET_NODE(NODE_TRANSITION, TransitionNode);
- ERR_FAIL_INDEX(p_input, n->input_data.size());
-
- n->input_data.write[p_input].auto_advance = p_auto_advance;
-}
-void AnimationTreePlayer::transition_node_set_xfade_time(const StringName &p_node, float p_time) {
-
- GET_NODE(NODE_TRANSITION, TransitionNode);
- n->xfade = p_time;
-}
-
-void AnimationTreePlayer::TransitionNode::set_current(int p_current) {
-
- ERR_FAIL_INDEX(p_current, inputs.size());
-
- if (current == p_current)
- return;
-
- prev = current;
- prev_xfading = xfade;
- prev_time = time;
- time = 0;
- current = p_current;
- switched = true;
-}
-
-void AnimationTreePlayer::transition_node_set_current(const StringName &p_node, int p_current) {
-
- GET_NODE(NODE_TRANSITION, TransitionNode);
- n->set_current(p_current);
-}
-
-void AnimationTreePlayer::node_set_position(const StringName &p_node, const Vector2 &p_pos) {
-
- ERR_FAIL_COND(!node_map.has(p_node));
- node_map[p_node]->pos = p_pos;
-}
-
-AnimationTreePlayer::NodeType AnimationTreePlayer::node_get_type(const StringName &p_node) const {
-
- ERR_FAIL_COND_V(!node_map.has(p_node), NODE_OUTPUT);
- return node_map[p_node]->type;
-}
-Point2 AnimationTreePlayer::node_get_position(const StringName &p_node) const {
-
- ERR_FAIL_COND_V(!node_map.has(p_node), Point2());
- return node_map[p_node]->pos;
-}
-
-#define GET_NODE_V(m_type, m_cast, m_ret) \
- ERR_FAIL_COND_V(!node_map.has(p_node), m_ret); \
- ERR_FAIL_COND_V_MSG(node_map[p_node]->type != m_type, m_ret, "Invalid parameter for node type."); \
- m_cast *n = static_cast<m_cast *>(node_map[p_node]);
-
-Ref<Animation> AnimationTreePlayer::animation_node_get_animation(const StringName &p_node) const {
-
- GET_NODE_V(NODE_ANIMATION, AnimationNode, Ref<Animation>());
- return n->animation;
-}
-
-String AnimationTreePlayer::animation_node_get_master_animation(const StringName &p_node) const {
-
- GET_NODE_V(NODE_ANIMATION, AnimationNode, String());
- return n->from;
-}
-
-float AnimationTreePlayer::animation_node_get_position(const StringName &p_node) const {
-
- GET_NODE_V(NODE_ANIMATION, AnimationNode, 0);
- return n->time;
-}
-
-bool AnimationTreePlayer::animation_node_is_path_filtered(const StringName &p_node, const NodePath &p_path) const {
-
- GET_NODE_V(NODE_ANIMATION, AnimationNode, 0);
- return n->filter.has(p_path);
-}
-
-float AnimationTreePlayer::oneshot_node_get_fadein_time(const StringName &p_node) const {
-
- GET_NODE_V(NODE_ONESHOT, OneShotNode, 0);
- return n->fade_in;
-}
-
-float AnimationTreePlayer::oneshot_node_get_fadeout_time(const StringName &p_node) const {
-
- GET_NODE_V(NODE_ONESHOT, OneShotNode, 0);
- return n->fade_out;
-}
-
-bool AnimationTreePlayer::oneshot_node_get_mix_mode(const StringName &p_node) const {
-
- GET_NODE_V(NODE_ONESHOT, OneShotNode, 0);
- return n->mix;
-}
-bool AnimationTreePlayer::oneshot_node_has_autorestart(const StringName &p_node) const {
-
- GET_NODE_V(NODE_ONESHOT, OneShotNode, 0);
- return n->autorestart;
-}
-float AnimationTreePlayer::oneshot_node_get_autorestart_delay(const StringName &p_node) const {
-
- GET_NODE_V(NODE_ONESHOT, OneShotNode, 0);
- return n->autorestart_delay;
-}
-float AnimationTreePlayer::oneshot_node_get_autorestart_random_delay(const StringName &p_node) const {
-
- GET_NODE_V(NODE_ONESHOT, OneShotNode, 0);
- return n->autorestart_random_delay;
-}
-
-bool AnimationTreePlayer::oneshot_node_is_active(const StringName &p_node) const {
-
- GET_NODE_V(NODE_ONESHOT, OneShotNode, 0);
- return n->active;
-}
-
-bool AnimationTreePlayer::oneshot_node_is_path_filtered(const StringName &p_node, const NodePath &p_path) const {
-
- GET_NODE_V(NODE_ONESHOT, OneShotNode, 0);
- return n->filter.has(p_path);
-}
-
-float AnimationTreePlayer::mix_node_get_amount(const StringName &p_node) const {
-
- GET_NODE_V(NODE_MIX, MixNode, 0);
- return n->amount;
-}
-float AnimationTreePlayer::blend2_node_get_amount(const StringName &p_node) const {
-
- GET_NODE_V(NODE_BLEND2, Blend2Node, 0);
- return n->value;
-}
-
-bool AnimationTreePlayer::blend2_node_is_path_filtered(const StringName &p_node, const NodePath &p_path) const {
-
- GET_NODE_V(NODE_BLEND2, Blend2Node, 0);
- return n->filter.has(p_path);
-}
-
-float AnimationTreePlayer::blend3_node_get_amount(const StringName &p_node) const {
-
- GET_NODE_V(NODE_BLEND3, Blend3Node, 0);
- return n->value;
-}
-Vector2 AnimationTreePlayer::blend4_node_get_amount(const StringName &p_node) const {
-
- GET_NODE_V(NODE_BLEND4, Blend4Node, Vector2());
- return n->value;
-}
-
-float AnimationTreePlayer::timescale_node_get_scale(const StringName &p_node) const {
-
- GET_NODE_V(NODE_TIMESCALE, TimeScaleNode, 0);
- return n->scale;
-}
-
-void AnimationTreePlayer::transition_node_delete_input(const StringName &p_node, int p_input) {
-
- GET_NODE(NODE_TRANSITION, TransitionNode);
- ERR_FAIL_INDEX(p_input, n->inputs.size());
-
- if (n->inputs.size() <= 1)
- return;
-
- n->inputs.remove(p_input);
- n->input_data.remove(p_input);
- last_error = _cycle_test(out_name);
-}
-
-int AnimationTreePlayer::transition_node_get_input_count(const StringName &p_node) const {
-
- GET_NODE_V(NODE_TRANSITION, TransitionNode, 0);
- return n->inputs.size();
-}
-
-bool AnimationTreePlayer::transition_node_has_input_auto_advance(const StringName &p_node, int p_input) const {
-
- GET_NODE_V(NODE_TRANSITION, TransitionNode, false);
- ERR_FAIL_INDEX_V(p_input, n->inputs.size(), false);
- return n->input_data[p_input].auto_advance;
-}
-float AnimationTreePlayer::transition_node_get_xfade_time(const StringName &p_node) const {
-
- GET_NODE_V(NODE_TRANSITION, TransitionNode, 0);
- return n->xfade;
-}
-
-int AnimationTreePlayer::transition_node_get_current(const StringName &p_node) const {
-
- GET_NODE_V(NODE_TRANSITION, TransitionNode, -1);
- return n->current;
-}
-
-/*misc */
-void AnimationTreePlayer::get_node_list(List<StringName> *p_node_list) const {
-
- for (Map<StringName, NodeBase *>::Element *E = node_map.front(); E; E = E->next()) {
-
- p_node_list->push_back(E->key());
- }
-}
-
-void AnimationTreePlayer::remove_node(const StringName &p_node) {
-
- ERR_FAIL_COND(!node_map.has(p_node));
- ERR_FAIL_COND_MSG(p_node == out_name, "Node 0 (output) can't be removed.");
-
- for (Map<StringName, NodeBase *>::Element *E = node_map.front(); E; E = E->next()) {
-
- NodeBase *nb = E->get();
- for (int i = 0; i < nb->inputs.size(); i++) {
-
- if (nb->inputs[i].node == p_node)
- nb->inputs.write[i].node = StringName();
- }
- }
-
- node_map.erase(p_node);
-
- _clear_cycle_test();
-
- // compute last error again, just in case
- last_error = _cycle_test(out_name);
- dirty_caches = true;
-}
-
-AnimationTreePlayer::ConnectError AnimationTreePlayer::_cycle_test(const StringName &p_at_node) {
-
- ERR_FAIL_COND_V(!node_map.has(p_at_node), CONNECT_INCOMPLETE);
-
- NodeBase *nb = node_map[p_at_node];
- if (nb->cycletest)
- return CONNECT_CYCLE;
-
- nb->cycletest = true;
-
- for (int i = 0; i < nb->inputs.size(); i++) {
- if (nb->inputs[i].node == StringName())
- return CONNECT_INCOMPLETE;
-
- ConnectError _err = _cycle_test(nb->inputs[i].node);
- if (_err)
- return _err;
- }
-
- return CONNECT_OK;
-}
-
-// Use this function to not alter next complete _cycle_test().
-void AnimationTreePlayer::_clear_cycle_test() {
- for (Map<StringName, NodeBase *>::Element *E = node_map.front(); E; E = E->next()) {
- NodeBase *nb = E->get();
- nb->cycletest = false;
- }
-}
-
-Error AnimationTreePlayer::connect_nodes(const StringName &p_src_node, const StringName &p_dst_node, int p_dst_input) {
-
- ERR_FAIL_COND_V(!node_map.has(p_src_node), ERR_INVALID_PARAMETER);
- ERR_FAIL_COND_V(!node_map.has(p_dst_node), ERR_INVALID_PARAMETER);
- ERR_FAIL_COND_V(p_src_node == p_dst_node, ERR_INVALID_PARAMETER);
-
- //NodeBase *src = node_map[p_src_node];
- NodeBase *dst = node_map[p_dst_node];
- ERR_FAIL_INDEX_V(p_dst_input, dst->inputs.size(), ERR_INVALID_PARAMETER);
-
- //int oldval = dst->inputs[p_dst_input].node;
-
- for (Map<StringName, NodeBase *>::Element *E = node_map.front(); E; E = E->next()) {
-
- NodeBase *nb = E->get();
- for (int i = 0; i < nb->inputs.size(); i++) {
-
- if (nb->inputs[i].node == p_src_node)
- nb->inputs.write[i].node = StringName();
- }
- }
-
- dst->inputs.write[p_dst_input].node = p_src_node;
-
- _clear_cycle_test();
-
- last_error = _cycle_test(out_name);
- if (last_error) {
-
- if (last_error == CONNECT_INCOMPLETE)
- return ERR_UNCONFIGURED;
- else if (last_error == CONNECT_CYCLE)
- return ERR_CYCLIC_LINK;
- }
- dirty_caches = true;
- return OK;
-}
-
-bool AnimationTreePlayer::are_nodes_connected(const StringName &p_src_node, const StringName &p_dst_node, int p_dst_input) const {
-
- ERR_FAIL_COND_V(!node_map.has(p_src_node), false);
- ERR_FAIL_COND_V(!node_map.has(p_dst_node), false);
- ERR_FAIL_COND_V(p_src_node == p_dst_node, false);
-
- NodeBase *dst = node_map[p_dst_node];
-
- return dst->inputs[p_dst_input].node == p_src_node;
-}
-
-void AnimationTreePlayer::disconnect_nodes(const StringName &p_node, int p_input) {
-
- ERR_FAIL_COND(!node_map.has(p_node));
-
- NodeBase *dst = node_map[p_node];
- ERR_FAIL_INDEX(p_input, dst->inputs.size());
- dst->inputs.write[p_input].node = StringName();
- last_error = CONNECT_INCOMPLETE;
- dirty_caches = true;
-}
-
-void AnimationTreePlayer::get_connection_list(List<Connection> *p_connections) const {
-
- for (Map<StringName, NodeBase *>::Element *E = node_map.front(); E; E = E->next()) {
-
- NodeBase *nb = E->get();
- for (int i = 0; i < nb->inputs.size(); i++) {
-
- if (nb->inputs[i].node != StringName()) {
- Connection c;
- c.src_node = nb->inputs[i].node;
- c.dst_node = E->key();
- c.dst_input = i;
- p_connections->push_back(c);
- }
- }
- }
-}
-
-AnimationTreePlayer::Track *AnimationTreePlayer::_find_track(const NodePath &p_path) {
-
- Node *parent = get_node(base_path);
- ERR_FAIL_COND_V(!parent, NULL);
-
- RES resource;
- Vector<StringName> leftover_path;
- Node *child = parent->get_node_and_resource(p_path, resource, leftover_path);
- if (!child) {
- String err = "Animation track references unknown Node: '" + String(p_path) + "'.";
- WARN_PRINT(err.ascii().get_data());
- return NULL;
- }
-
- ObjectID id = child->get_instance_id();
- int bone_idx = -1;
-
- if (p_path.get_subname_count()) {
-
- if (Object::cast_to<Skeleton>(child))
- bone_idx = Object::cast_to<Skeleton>(child)->find_bone(p_path.get_subname(0));
- }
-
- TrackKey key;
- key.id = id;
- key.bone_idx = bone_idx;
- key.subpath_concatenated = p_path.get_concatenated_subnames();
-
- if (!track_map.has(key)) {
-
- Track tr;
- tr.id = id;
- tr.object = resource.is_valid() ? (Object *)resource.ptr() : (Object *)child;
- tr.skeleton = Object::cast_to<Skeleton>(child);
- tr.spatial = Object::cast_to<Spatial>(child);
- tr.bone_idx = bone_idx;
- if (bone_idx == -1) tr.subpath = leftover_path;
-
- track_map[key] = tr;
- }
-
- return &track_map[key];
-}
-
-void AnimationTreePlayer::_recompute_caches() {
-
- track_map.clear();
- _recompute_caches(out_name);
- dirty_caches = false;
-}
-
-void AnimationTreePlayer::_recompute_caches(const StringName &p_node) {
-
- ERR_FAIL_COND(!node_map.has(p_node));
-
- NodeBase *nb = node_map[p_node];
-
- if (nb->type == NODE_ANIMATION) {
-
- AnimationNode *an = static_cast<AnimationNode *>(nb);
- an->tref.clear();
-
- if (!an->animation.is_null()) {
-
- Ref<Animation> a = an->animation;
-
- for (int i = 0; i < an->animation->get_track_count(); i++) {
-
- Track *tr = _find_track(a->track_get_path(i));
- if (!tr)
- continue;
-
- AnimationNode::TrackRef tref;
- tref.local_track = i;
- tref.track = tr;
- tref.weight = 0;
-
- an->tref.push_back(tref);
- }
- }
- }
-
- for (int i = 0; i < nb->inputs.size(); i++) {
-
- _recompute_caches(nb->inputs[i].node);
- }
-}
-
-void AnimationTreePlayer::recompute_caches() {
-
- dirty_caches = true;
-}
-
-/* playback */
-
-void AnimationTreePlayer::set_active(bool p_active) {
-
- if (active == p_active)
- return;
-
- active = p_active;
- processing = active;
- reset_request = p_active;
- _set_process(processing, true);
-}
-
-bool AnimationTreePlayer::is_active() const {
-
- return active;
-}
-
-AnimationTreePlayer::ConnectError AnimationTreePlayer::get_last_error() const {
-
- return last_error;
-}
-
-void AnimationTreePlayer::reset() {
-
- reset_request = true;
-}
-
-void AnimationTreePlayer::set_base_path(const NodePath &p_path) {
-
- base_path = p_path;
- recompute_caches();
-}
-
-NodePath AnimationTreePlayer::get_base_path() const {
-
- return base_path;
-}
-
-void AnimationTreePlayer::set_master_player(const NodePath &p_path) {
-
- if (p_path == master)
- return;
-
- master = p_path;
- _update_sources();
- recompute_caches();
-}
-
-NodePath AnimationTreePlayer::get_master_player() const {
-
- return master;
-}
-
-PoolVector<String> AnimationTreePlayer::_get_node_list() {
-
- List<StringName> nl;
- get_node_list(&nl);
- PoolVector<String> ret;
- ret.resize(nl.size());
- int idx = 0;
- for (List<StringName>::Element *E = nl.front(); E; E = E->next()) {
- ret.set(idx++, E->get());
- }
-
- return ret;
-}
-
-void AnimationTreePlayer::_update_sources() {
-
- if (master == NodePath())
- return;
- if (!is_inside_tree())
- return;
-
- Node *m = get_node(master);
- if (!m) {
- master = NodePath();
- ERR_FAIL_COND(!m);
- }
-
- AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(m);
-
- if (!ap) {
-
- master = NodePath();
- ERR_FAIL_COND(!ap);
- }
-
- for (Map<StringName, NodeBase *>::Element *E = node_map.front(); E; E = E->next()) {
-
- if (E->get()->type == NODE_ANIMATION) {
-
- AnimationNode *an = static_cast<AnimationNode *>(E->get());
-
- if (an->from != "") {
-
- an->animation = ap->get_animation(an->from);
- }
- }
- }
-}
-
-bool AnimationTreePlayer::node_exists(const StringName &p_name) const {
-
- return (node_map.has(p_name));
-}
-
-Error AnimationTreePlayer::node_rename(const StringName &p_node, const StringName &p_new_name) {
-
- if (p_new_name == p_node)
- return OK;
- ERR_FAIL_COND_V(!node_map.has(p_node), ERR_ALREADY_EXISTS);
- ERR_FAIL_COND_V(node_map.has(p_new_name), ERR_ALREADY_EXISTS);
- ERR_FAIL_COND_V(p_new_name == StringName(), ERR_INVALID_DATA);
- ERR_FAIL_COND_V(p_node == out_name, ERR_INVALID_DATA);
- ERR_FAIL_COND_V(p_new_name == out_name, ERR_INVALID_DATA);
-
- for (Map<StringName, NodeBase *>::Element *E = node_map.front(); E; E = E->next()) {
-
- NodeBase *nb = E->get();
- for (int i = 0; i < nb->inputs.size(); i++) {
-
- if (nb->inputs[i].node == p_node) {
- nb->inputs.write[i].node = p_new_name;
- }
- }
- }
-
- node_map[p_new_name] = node_map[p_node];
- node_map.erase(p_node);
-
- return OK;
-}
-
-String AnimationTreePlayer::get_configuration_warning() const {
-
- return TTR("This node has been deprecated. Use AnimationTree instead.");
-}
-
-void AnimationTreePlayer::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("add_node", "type", "id"), &AnimationTreePlayer::add_node);
-
- ClassDB::bind_method(D_METHOD("node_exists", "node"), &AnimationTreePlayer::node_exists);
- ClassDB::bind_method(D_METHOD("node_rename", "node", "new_name"), &AnimationTreePlayer::node_rename);
-
- ClassDB::bind_method(D_METHOD("node_get_type", "id"), &AnimationTreePlayer::node_get_type);
- ClassDB::bind_method(D_METHOD("node_get_input_count", "id"), &AnimationTreePlayer::node_get_input_count);
- ClassDB::bind_method(D_METHOD("node_get_input_source", "id", "idx"), &AnimationTreePlayer::node_get_input_source);
-
- ClassDB::bind_method(D_METHOD("animation_node_set_animation", "id", "animation"), &AnimationTreePlayer::animation_node_set_animation);
- ClassDB::bind_method(D_METHOD("animation_node_get_animation", "id"), &AnimationTreePlayer::animation_node_get_animation);
-
- ClassDB::bind_method(D_METHOD("animation_node_set_master_animation", "id", "source"), &AnimationTreePlayer::animation_node_set_master_animation);
- ClassDB::bind_method(D_METHOD("animation_node_get_master_animation", "id"), &AnimationTreePlayer::animation_node_get_master_animation);
- ClassDB::bind_method(D_METHOD("animation_node_get_position", "id"), &AnimationTreePlayer::animation_node_get_position);
- ClassDB::bind_method(D_METHOD("animation_node_set_filter_path", "id", "path", "enable"), &AnimationTreePlayer::animation_node_set_filter_path);
-
- ClassDB::bind_method(D_METHOD("oneshot_node_set_fadein_time", "id", "time_sec"), &AnimationTreePlayer::oneshot_node_set_fadein_time);
- ClassDB::bind_method(D_METHOD("oneshot_node_get_fadein_time", "id"), &AnimationTreePlayer::oneshot_node_get_fadein_time);
-
- ClassDB::bind_method(D_METHOD("oneshot_node_set_fadeout_time", "id", "time_sec"), &AnimationTreePlayer::oneshot_node_set_fadeout_time);
- ClassDB::bind_method(D_METHOD("oneshot_node_get_fadeout_time", "id"), &AnimationTreePlayer::oneshot_node_get_fadeout_time);
-
- ClassDB::bind_method(D_METHOD("oneshot_node_set_autorestart", "id", "enable"), &AnimationTreePlayer::oneshot_node_set_autorestart);
- ClassDB::bind_method(D_METHOD("oneshot_node_set_autorestart_delay", "id", "delay_sec"), &AnimationTreePlayer::oneshot_node_set_autorestart_delay);
- ClassDB::bind_method(D_METHOD("oneshot_node_set_autorestart_random_delay", "id", "rand_sec"), &AnimationTreePlayer::oneshot_node_set_autorestart_random_delay);
-
- ClassDB::bind_method(D_METHOD("oneshot_node_has_autorestart", "id"), &AnimationTreePlayer::oneshot_node_has_autorestart);
- ClassDB::bind_method(D_METHOD("oneshot_node_get_autorestart_delay", "id"), &AnimationTreePlayer::oneshot_node_get_autorestart_delay);
- ClassDB::bind_method(D_METHOD("oneshot_node_get_autorestart_random_delay", "id"), &AnimationTreePlayer::oneshot_node_get_autorestart_random_delay);
-
- ClassDB::bind_method(D_METHOD("oneshot_node_start", "id"), &AnimationTreePlayer::oneshot_node_start);
- ClassDB::bind_method(D_METHOD("oneshot_node_stop", "id"), &AnimationTreePlayer::oneshot_node_stop);
- ClassDB::bind_method(D_METHOD("oneshot_node_is_active", "id"), &AnimationTreePlayer::oneshot_node_is_active);
- ClassDB::bind_method(D_METHOD("oneshot_node_set_filter_path", "id", "path", "enable"), &AnimationTreePlayer::oneshot_node_set_filter_path);
-
- ClassDB::bind_method(D_METHOD("mix_node_set_amount", "id", "ratio"), &AnimationTreePlayer::mix_node_set_amount);
- ClassDB::bind_method(D_METHOD("mix_node_get_amount", "id"), &AnimationTreePlayer::mix_node_get_amount);
-
- ClassDB::bind_method(D_METHOD("blend2_node_set_amount", "id", "blend"), &AnimationTreePlayer::blend2_node_set_amount);
- ClassDB::bind_method(D_METHOD("blend2_node_get_amount", "id"), &AnimationTreePlayer::blend2_node_get_amount);
- ClassDB::bind_method(D_METHOD("blend2_node_set_filter_path", "id", "path", "enable"), &AnimationTreePlayer::blend2_node_set_filter_path);
-
- ClassDB::bind_method(D_METHOD("blend3_node_set_amount", "id", "blend"), &AnimationTreePlayer::blend3_node_set_amount);
- ClassDB::bind_method(D_METHOD("blend3_node_get_amount", "id"), &AnimationTreePlayer::blend3_node_get_amount);
-
- ClassDB::bind_method(D_METHOD("blend4_node_set_amount", "id", "blend"), &AnimationTreePlayer::blend4_node_set_amount);
- ClassDB::bind_method(D_METHOD("blend4_node_get_amount", "id"), &AnimationTreePlayer::blend4_node_get_amount);
-
- ClassDB::bind_method(D_METHOD("timescale_node_set_scale", "id", "scale"), &AnimationTreePlayer::timescale_node_set_scale);
- ClassDB::bind_method(D_METHOD("timescale_node_get_scale", "id"), &AnimationTreePlayer::timescale_node_get_scale);
-
- ClassDB::bind_method(D_METHOD("timeseek_node_seek", "id", "seconds"), &AnimationTreePlayer::timeseek_node_seek);
-
- ClassDB::bind_method(D_METHOD("transition_node_set_input_count", "id", "count"), &AnimationTreePlayer::transition_node_set_input_count);
- ClassDB::bind_method(D_METHOD("transition_node_get_input_count", "id"), &AnimationTreePlayer::transition_node_get_input_count);
- ClassDB::bind_method(D_METHOD("transition_node_delete_input", "id", "input_idx"), &AnimationTreePlayer::transition_node_delete_input);
-
- ClassDB::bind_method(D_METHOD("transition_node_set_input_auto_advance", "id", "input_idx", "enable"), &AnimationTreePlayer::transition_node_set_input_auto_advance);
- ClassDB::bind_method(D_METHOD("transition_node_has_input_auto_advance", "id", "input_idx"), &AnimationTreePlayer::transition_node_has_input_auto_advance);
-
- ClassDB::bind_method(D_METHOD("transition_node_set_xfade_time", "id", "time_sec"), &AnimationTreePlayer::transition_node_set_xfade_time);
- ClassDB::bind_method(D_METHOD("transition_node_get_xfade_time", "id"), &AnimationTreePlayer::transition_node_get_xfade_time);
-
- ClassDB::bind_method(D_METHOD("transition_node_set_current", "id", "input_idx"), &AnimationTreePlayer::transition_node_set_current);
- ClassDB::bind_method(D_METHOD("transition_node_get_current", "id"), &AnimationTreePlayer::transition_node_get_current);
-
- ClassDB::bind_method(D_METHOD("node_set_position", "id", "screen_position"), &AnimationTreePlayer::node_set_position);
- ClassDB::bind_method(D_METHOD("node_get_position", "id"), &AnimationTreePlayer::node_get_position);
-
- ClassDB::bind_method(D_METHOD("remove_node", "id"), &AnimationTreePlayer::remove_node);
- ClassDB::bind_method(D_METHOD("connect_nodes", "id", "dst_id", "dst_input_idx"), &AnimationTreePlayer::connect_nodes);
- ClassDB::bind_method(D_METHOD("are_nodes_connected", "id", "dst_id", "dst_input_idx"), &AnimationTreePlayer::are_nodes_connected);
- ClassDB::bind_method(D_METHOD("disconnect_nodes", "id", "dst_input_idx"), &AnimationTreePlayer::disconnect_nodes);
-
- ClassDB::bind_method(D_METHOD("set_active", "enabled"), &AnimationTreePlayer::set_active);
- ClassDB::bind_method(D_METHOD("is_active"), &AnimationTreePlayer::is_active);
-
- ClassDB::bind_method(D_METHOD("set_base_path", "path"), &AnimationTreePlayer::set_base_path);
- ClassDB::bind_method(D_METHOD("get_base_path"), &AnimationTreePlayer::get_base_path);
-
- ClassDB::bind_method(D_METHOD("set_master_player", "nodepath"), &AnimationTreePlayer::set_master_player);
- ClassDB::bind_method(D_METHOD("get_master_player"), &AnimationTreePlayer::get_master_player);
-
- ClassDB::bind_method(D_METHOD("get_node_list"), &AnimationTreePlayer::_get_node_list);
-
- ClassDB::bind_method(D_METHOD("set_animation_process_mode", "mode"), &AnimationTreePlayer::set_animation_process_mode);
- ClassDB::bind_method(D_METHOD("get_animation_process_mode"), &AnimationTreePlayer::get_animation_process_mode);
-
- ClassDB::bind_method(D_METHOD("advance", "delta"), &AnimationTreePlayer::advance);
-
- ClassDB::bind_method(D_METHOD("reset"), &AnimationTreePlayer::reset);
-
- ClassDB::bind_method(D_METHOD("recompute_caches"), &AnimationTreePlayer::recompute_caches);
-
- ADD_GROUP("Playback", "playback_");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "playback_process_mode", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_animation_process_mode", "get_animation_process_mode");
-
- ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "master_player", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "AnimationPlayer"), "set_master_player", "get_master_player");
- ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "base_path"), "set_base_path", "get_base_path");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "active"), "set_active", "is_active");
-
- BIND_ENUM_CONSTANT(NODE_OUTPUT);
- BIND_ENUM_CONSTANT(NODE_ANIMATION);
- BIND_ENUM_CONSTANT(NODE_ONESHOT);
- BIND_ENUM_CONSTANT(NODE_MIX);
- BIND_ENUM_CONSTANT(NODE_BLEND2);
- BIND_ENUM_CONSTANT(NODE_BLEND3);
- BIND_ENUM_CONSTANT(NODE_BLEND4);
- BIND_ENUM_CONSTANT(NODE_TIMESCALE);
- BIND_ENUM_CONSTANT(NODE_TIMESEEK);
- BIND_ENUM_CONSTANT(NODE_TRANSITION);
-
- BIND_ENUM_CONSTANT(ANIMATION_PROCESS_PHYSICS);
- BIND_ENUM_CONSTANT(ANIMATION_PROCESS_IDLE);
-}
-
-AnimationTreePlayer::AnimationTreePlayer() {
-
- active_list = NULL;
- out = memnew(NodeOut);
- out_name = "out";
- out->pos = Point2(40, 40);
- node_map.insert(out_name, out);
- animation_process_mode = ANIMATION_PROCESS_IDLE;
- processing = false;
- active = false;
- dirty_caches = true;
- reset_request = true;
- last_error = CONNECT_INCOMPLETE;
- base_path = String("..");
-}
-
-AnimationTreePlayer::~AnimationTreePlayer() {
-
- while (node_map.size()) {
- memdelete(node_map.front()->get());
- node_map.erase(node_map.front());
- }
-}
diff --git a/scene/animation/animation_tree_player.h b/scene/animation/animation_tree_player.h
deleted file mode 100644
index e1f6ce7b9c..0000000000
--- a/scene/animation/animation_tree_player.h
+++ /dev/null
@@ -1,487 +0,0 @@
-/*************************************************************************/
-/* animation_tree_player.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 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 */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef ANIMATION_TREE_PLAYER_H
-#define ANIMATION_TREE_PLAYER_H
-
-#include "animation_player.h"
-#include "scene/3d/skeleton.h"
-#include "scene/3d/spatial.h"
-#include "scene/resources/animation.h"
-
-class AnimationTreePlayer : public Node {
-
- GDCLASS(AnimationTreePlayer, Node);
- OBJ_CATEGORY("Animation Nodes");
-
-public:
- enum AnimationProcessMode {
- ANIMATION_PROCESS_PHYSICS,
- ANIMATION_PROCESS_IDLE,
- };
-
- enum NodeType {
-
- NODE_OUTPUT,
- NODE_ANIMATION,
- NODE_ONESHOT,
- NODE_MIX,
- NODE_BLEND2,
- NODE_BLEND3,
- NODE_BLEND4,
- NODE_TIMESCALE,
- NODE_TIMESEEK,
- NODE_TRANSITION,
-
- NODE_MAX,
- };
-
- enum ConnectError {
-
- CONNECT_OK,
- CONNECT_INCOMPLETE,
- CONNECT_CYCLE
- };
-
-private:
- enum {
-
- DISCONNECTED = -1,
- };
-
- struct TrackKey {
-
- uint32_t id;
- StringName subpath_concatenated;
- int bone_idx;
-
- inline bool operator<(const TrackKey &p_right) const {
-
- if (id == p_right.id) {
- if (bone_idx == p_right.bone_idx) {
- return subpath_concatenated < p_right.subpath_concatenated;
- } else
- return bone_idx < p_right.bone_idx;
- } else
- return id < p_right.id;
- }
- };
-
- struct Track {
- uint32_t id;
- Object *object;
- Spatial *spatial;
- Skeleton *skeleton;
- int bone_idx;
- Vector<StringName> subpath;
-
- Vector3 loc;
- Quat rot;
- Vector3 scale;
-
- Variant value;
-
- bool skip;
-
- Track() :
- id(0),
- object(NULL),
- spatial(NULL),
- skeleton(NULL),
- bone_idx(-1),
- skip(false) {}
- };
-
- typedef Map<TrackKey, Track> TrackMap;
-
- TrackMap track_map;
-
- struct Input {
-
- StringName node;
- //Input() { node=-1; }
- };
-
- struct NodeBase {
-
- bool cycletest;
-
- NodeType type;
- Point2 pos;
-
- Vector<Input> inputs;
-
- NodeBase() { cycletest = false; };
- virtual ~NodeBase() { cycletest = false; }
- };
-
- struct NodeOut : public NodeBase {
-
- NodeOut() {
- type = NODE_OUTPUT;
- inputs.resize(1);
- }
- };
-
- struct AnimationNode : public NodeBase {
-
- Ref<Animation> animation;
-
- struct TrackRef {
- int local_track;
- Track *track;
- float weight;
- };
-
- uint64_t last_version;
- List<TrackRef> tref;
- AnimationNode *next;
- float time;
- float step;
- String from;
- bool skip;
-
- HashMap<NodePath, bool> filter;
-
- AnimationNode() {
- type = NODE_ANIMATION;
- next = NULL;
- last_version = 0;
- skip = false;
- }
- };
-
- struct OneShotNode : public NodeBase {
-
- bool active;
- bool start;
- float fade_in;
- float fade_out;
-
- bool autorestart;
- float autorestart_delay;
- float autorestart_random_delay;
- bool mix;
-
- float time;
- float remaining;
- float autorestart_remaining;
-
- HashMap<NodePath, bool> filter;
-
- OneShotNode() {
- type = NODE_ONESHOT;
- fade_in = 0;
- fade_out = 0;
- inputs.resize(2);
- autorestart = false;
- autorestart_delay = 1;
- autorestart_remaining = 0;
- mix = false;
- active = false;
- start = false;
- }
- };
-
- struct MixNode : public NodeBase {
-
- float amount;
- MixNode() {
- type = NODE_MIX;
- inputs.resize(2);
- }
- };
-
- struct Blend2Node : public NodeBase {
-
- float value;
- HashMap<NodePath, bool> filter;
- Blend2Node() {
- type = NODE_BLEND2;
- value = 0;
- inputs.resize(2);
- }
- };
-
- struct Blend3Node : public NodeBase {
-
- float value;
- Blend3Node() {
- type = NODE_BLEND3;
- value = 0;
- inputs.resize(3);
- }
- };
-
- struct Blend4Node : public NodeBase {
-
- Point2 value;
- Blend4Node() {
- type = NODE_BLEND4;
- inputs.resize(4);
- }
- };
-
- struct TimeScaleNode : public NodeBase {
-
- float scale;
- TimeScaleNode() {
- type = NODE_TIMESCALE;
- scale = 1;
- inputs.resize(1);
- }
- };
-
- struct TimeSeekNode : public NodeBase {
-
- float seek_pos;
-
- TimeSeekNode() {
- type = NODE_TIMESEEK;
- inputs.resize(1);
- seek_pos = -1;
- }
- };
-
- struct TransitionNode : public NodeBase {
-
- struct InputData {
-
- bool auto_advance;
- InputData() { auto_advance = false; }
- };
-
- Vector<InputData> input_data;
-
- float prev_time;
- float prev_xfading;
- int prev;
- bool switched;
-
- float time;
- int current;
-
- float xfade;
-
- TransitionNode() {
- type = NODE_TRANSITION;
- xfade = 0;
- inputs.resize(1);
- input_data.resize(1);
- current = 0;
- prev = -1;
- prev_time = 0;
- prev_xfading = 0;
- switched = false;
- }
- void set_current(int p_current);
- };
-
- void _update_sources();
-
- StringName out_name;
- NodeOut *out;
-
- NodePath base_path;
- NodePath master;
-
- ConnectError last_error;
- AnimationNode *active_list;
- AnimationProcessMode animation_process_mode;
- bool processing;
- bool active;
- bool dirty_caches;
- Map<StringName, NodeBase *> node_map;
-
- // return time left to finish animation
- float _process_node(const StringName &p_node, AnimationNode **r_prev_anim, float p_time, bool p_seek = false, float p_fallback_weight = 1.0, HashMap<NodePath, float> *p_weights = NULL);
- void _process_animation(float p_delta);
- bool reset_request;
-
- ConnectError _cycle_test(const StringName &p_at_node);
- void _clear_cycle_test();
-
- Track *_find_track(const NodePath &p_path);
- void _recompute_caches();
- void _recompute_caches(const StringName &p_node);
- PoolVector<String> _get_node_list();
-
- void _compute_weights(float *p_fallback_weight, HashMap<NodePath, float> *p_weights, float p_coeff, const HashMap<NodePath, bool> *p_filter = NULL, float p_filtered_coeff = 0);
-
-protected:
- bool _set(const StringName &p_name, const Variant &p_value);
- bool _get(const StringName &p_name, Variant &r_ret) const;
- void _get_property_list(List<PropertyInfo> *p_list) const;
- void _notification(int p_what);
-
- static void _bind_methods();
-
-public:
- void add_node(NodeType p_type, const StringName &p_node); // nodes must be >0 node 0 is built-in (exit)
- bool node_exists(const StringName &p_name) const;
-
- Error node_rename(const StringName &p_node, const StringName &p_new_name);
- int node_get_input_count(const StringName &p_node) const;
- StringName node_get_input_source(const StringName &p_node, int p_input) const;
-
- String get_configuration_warning() const;
-
- /* ANIMATION NODE */
- void animation_node_set_animation(const StringName &p_node, const Ref<Animation> &p_animation);
- Ref<Animation> animation_node_get_animation(const StringName &p_node) const;
- void animation_node_set_master_animation(const StringName &p_node, const String &p_master_animation);
- String animation_node_get_master_animation(const StringName &p_node) const;
- float animation_node_get_position(const StringName &p_node) const;
-
- void animation_node_set_filter_path(const StringName &p_node, const NodePath &p_track_path, bool p_filter);
- void animation_node_set_get_filtered_paths(const StringName &p_node, List<NodePath> *r_paths) const;
- bool animation_node_is_path_filtered(const StringName &p_node, const NodePath &p_path) const;
-
- /* ONE SHOT NODE */
-
- void oneshot_node_set_fadein_time(const StringName &p_node, float p_time);
- void oneshot_node_set_fadeout_time(const StringName &p_node, float p_time);
-
- float oneshot_node_get_fadein_time(const StringName &p_node) const;
- float oneshot_node_get_fadeout_time(const StringName &p_node) const;
-
- void oneshot_node_set_autorestart(const StringName &p_node, bool p_active);
- void oneshot_node_set_autorestart_delay(const StringName &p_node, float p_time);
- void oneshot_node_set_autorestart_random_delay(const StringName &p_node, float p_time);
-
- bool oneshot_node_has_autorestart(const StringName &p_node) const;
- float oneshot_node_get_autorestart_delay(const StringName &p_node) const;
- float oneshot_node_get_autorestart_random_delay(const StringName &p_node) const;
-
- void oneshot_node_set_mix_mode(const StringName &p_node, bool p_mix);
- bool oneshot_node_get_mix_mode(const StringName &p_node) const;
-
- void oneshot_node_start(const StringName &p_node);
- void oneshot_node_stop(const StringName &p_node);
- bool oneshot_node_is_active(const StringName &p_node) const;
-
- void oneshot_node_set_filter_path(const StringName &p_node, const NodePath &p_filter, bool p_enable);
- void oneshot_node_set_get_filtered_paths(const StringName &p_node, List<NodePath> *r_paths) const;
- bool oneshot_node_is_path_filtered(const StringName &p_node, const NodePath &p_path) const;
-
- /* MIX/BLEND NODES */
-
- void mix_node_set_amount(const StringName &p_node, float p_amount);
- float mix_node_get_amount(const StringName &p_node) const;
-
- void blend2_node_set_amount(const StringName &p_node, float p_amount);
- float blend2_node_get_amount(const StringName &p_node) const;
- void blend2_node_set_filter_path(const StringName &p_node, const NodePath &p_filter, bool p_enable);
- void blend2_node_set_get_filtered_paths(const StringName &p_node, List<NodePath> *r_paths) const;
- bool blend2_node_is_path_filtered(const StringName &p_node, const NodePath &p_path) const;
-
- void blend3_node_set_amount(const StringName &p_node, float p_amount);
- float blend3_node_get_amount(const StringName &p_node) const;
-
- void blend4_node_set_amount(const StringName &p_node, const Point2 &p_amount);
- Point2 blend4_node_get_amount(const StringName &p_node) const;
-
- /* TIMESCALE/TIMESEEK NODES */
-
- void timescale_node_set_scale(const StringName &p_node, float p_scale);
- float timescale_node_get_scale(const StringName &p_node) const;
-
- void timeseek_node_seek(const StringName &p_node, float p_pos);
-
- /* TRANSITION NODE */
-
- void transition_node_set_input_count(const StringName &p_node, int p_inputs); // used for transition node
- int transition_node_get_input_count(const StringName &p_node) const;
- void transition_node_delete_input(const StringName &p_node, int p_input); // used for transition node
-
- void transition_node_set_input_auto_advance(const StringName &p_node, int p_input, bool p_auto_advance); // used for transition node
- bool transition_node_has_input_auto_advance(const StringName &p_node, int p_input) const;
-
- void transition_node_set_xfade_time(const StringName &p_node, float p_time); // used for transition node
- float transition_node_get_xfade_time(const StringName &p_node) const;
-
- void transition_node_set_current(const StringName &p_node, int p_current);
- int transition_node_get_current(const StringName &p_node) const;
-
- void node_set_position(const StringName &p_node, const Vector2 &p_pos); //for display
-
- /* GETS */
- Point2 node_get_position(const StringName &p_node) const; //for display
-
- NodeType node_get_type(const StringName &p_node) const;
-
- void get_node_list(List<StringName> *p_node_list) const;
- void remove_node(const StringName &p_node);
-
- Error connect_nodes(const StringName &p_src_node, const StringName &p_dst_node, int p_dst_input);
- bool are_nodes_connected(const StringName &p_src_node, const StringName &p_dst_node, int p_dst_input) const;
- void disconnect_nodes(const StringName &p_node, int p_input);
-
- void set_base_path(const NodePath &p_path);
- NodePath get_base_path() const;
-
- void set_master_player(const NodePath &p_path);
- NodePath get_master_player() const;
-
- struct Connection {
-
- StringName src_node;
- StringName dst_node;
- int dst_input;
- };
-
- void get_connection_list(List<Connection> *p_connections) const;
-
- /* playback */
-
- void set_active(bool p_active);
- bool is_active() const;
-
- void reset();
-
- void recompute_caches();
-
- ConnectError get_last_error() const;
-
- void set_animation_process_mode(AnimationProcessMode p_mode);
- AnimationProcessMode get_animation_process_mode() const;
-
- void _set_process(bool p_process, bool p_force = false);
-
- void advance(float p_time);
-
- AnimationTreePlayer();
- ~AnimationTreePlayer();
-};
-
-VARIANT_ENUM_CAST(AnimationTreePlayer::NodeType);
-VARIANT_ENUM_CAST(AnimationTreePlayer::AnimationProcessMode);
-
-#endif // ANIMATION_TREE_PLAYER_H
diff --git a/scene/animation/root_motion_view.cpp b/scene/animation/root_motion_view.cpp
index 32ceeb4dbf..cbf2e4a6ff 100644
--- a/scene/animation/root_motion_view.cpp
+++ b/scene/animation/root_motion_view.cpp
@@ -76,10 +76,8 @@ bool RootMotionView::get_zero_y() const {
}
void RootMotionView::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE) {
-
- VS::get_singleton()->immediate_set_material(immediate, SpatialMaterial::get_material_rid_for_2d(false, true, false, false, false));
+ RS::get_singleton()->immediate_set_material(immediate, StandardMaterial3D::get_material_rid_for_2d(false, true, false, false, false));
first = true;
}
@@ -87,7 +85,6 @@ void RootMotionView::_notification(int p_what) {
Transform transform;
if (has_node(path)) {
-
Node *node = get_node(path);
AnimationTree *tree = Object::cast_to<AnimationTree>(node);
@@ -122,14 +119,13 @@ void RootMotionView::_notification(int p_what) {
}
accumulated.origin.z = Math::fposmod(accumulated.origin.z, cell_size);
- VS::get_singleton()->immediate_clear(immediate);
+ RS::get_singleton()->immediate_clear(immediate);
int cells_in_radius = int((radius / cell_size) + 1.0);
- VS::get_singleton()->immediate_begin(immediate, VS::PRIMITIVE_LINES);
+ RS::get_singleton()->immediate_begin(immediate, RS::PRIMITIVE_LINES);
for (int i = -cells_in_radius; i < cells_in_radius; i++) {
for (int j = -cells_in_radius; j < cells_in_radius; j++) {
-
Vector3 from(i * cell_size, 0, j * cell_size);
Vector3 from_i((i + 1) * cell_size, 0, j * cell_size);
Vector3 from_j(i * cell_size, 0, (j + 1) * cell_size);
@@ -142,34 +138,33 @@ void RootMotionView::_notification(int p_what) {
c_i.a *= MAX(0, 1.0 - from_i.length() / radius);
c_j.a *= MAX(0, 1.0 - from_j.length() / radius);
- VS::get_singleton()->immediate_color(immediate, c);
- VS::get_singleton()->immediate_vertex(immediate, from);
+ RS::get_singleton()->immediate_color(immediate, c);
+ RS::get_singleton()->immediate_vertex(immediate, from);
- VS::get_singleton()->immediate_color(immediate, c_i);
- VS::get_singleton()->immediate_vertex(immediate, from_i);
+ RS::get_singleton()->immediate_color(immediate, c_i);
+ RS::get_singleton()->immediate_vertex(immediate, from_i);
- VS::get_singleton()->immediate_color(immediate, c);
- VS::get_singleton()->immediate_vertex(immediate, from);
+ RS::get_singleton()->immediate_color(immediate, c);
+ RS::get_singleton()->immediate_vertex(immediate, from);
- VS::get_singleton()->immediate_color(immediate, c_j);
- VS::get_singleton()->immediate_vertex(immediate, from_j);
+ RS::get_singleton()->immediate_color(immediate, c_j);
+ RS::get_singleton()->immediate_vertex(immediate, from_j);
}
}
- VS::get_singleton()->immediate_end(immediate);
+ RS::get_singleton()->immediate_end(immediate);
}
}
AABB RootMotionView::get_aabb() const {
-
return AABB(Vector3(-radius, 0, -radius), Vector3(radius * 2, 0.001, radius * 2));
}
-PoolVector<Face3> RootMotionView::get_faces(uint32_t p_usage_flags) const {
- return PoolVector<Face3>();
+
+Vector<Face3> RootMotionView::get_faces(uint32_t p_usage_flags) const {
+ return Vector<Face3>();
}
void RootMotionView::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_animation_path", "path"), &RootMotionView::set_animation_path);
ClassDB::bind_method(D_METHOD("get_animation_path"), &RootMotionView::get_animation_path);
@@ -187,8 +182,8 @@ void RootMotionView::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "animation_path", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "AnimationTree"), "set_animation_path", "get_animation_path");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "cell_size", PROPERTY_HINT_RANGE, "0.1,16,0.01,or_greater"), "set_cell_size", "get_cell_size");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "radius", PROPERTY_HINT_RANGE, "0.1,16,0.01,or_greater"), "set_radius", "get_radius");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "cell_size", PROPERTY_HINT_RANGE, "0.1,16,0.01,or_greater"), "set_cell_size", "get_cell_size");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.1,16,0.01,or_greater"), "set_radius", "get_radius");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "zero_y"), "set_zero_y", "get_zero_y");
}
@@ -197,12 +192,12 @@ RootMotionView::RootMotionView() {
radius = 10;
cell_size = 1;
set_process_internal(true);
- immediate = VisualServer::get_singleton()->immediate_create();
+ immediate = RenderingServer::get_singleton()->immediate_create();
set_base(immediate);
color = Color(0.5, 0.5, 1.0);
}
RootMotionView::~RootMotionView() {
set_base(RID());
- VisualServer::get_singleton()->free(immediate);
+ RenderingServer::get_singleton()->free(immediate);
}
diff --git a/scene/animation/root_motion_view.h b/scene/animation/root_motion_view.h
index 0a255cb5d2..77c51fe47a 100644
--- a/scene/animation/root_motion_view.h
+++ b/scene/animation/root_motion_view.h
@@ -31,10 +31,10 @@
#ifndef ROOT_MOTION_VIEW_H
#define ROOT_MOTION_VIEW_H
-#include "scene/3d/visual_instance.h"
+#include "scene/3d/visual_instance_3d.h"
-class RootMotionView : public VisualInstance {
- GDCLASS(RootMotionView, VisualInstance);
+class RootMotionView : public VisualInstance3D {
+ GDCLASS(RootMotionView, VisualInstance3D);
public:
RID immediate;
@@ -68,8 +68,8 @@ public:
void set_zero_y(bool p_zero_y);
bool get_zero_y() const;
- virtual AABB get_aabb() const;
- virtual PoolVector<Face3> get_faces(uint32_t p_usage_flags) const;
+ virtual AABB get_aabb() const override;
+ virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const override;
RootMotionView();
~RootMotionView();
diff --git a/scene/animation/skeleton_ik.cpp b/scene/animation/skeleton_ik.cpp
deleted file mode 100644
index 46028a9ce2..0000000000
--- a/scene/animation/skeleton_ik.cpp
+++ /dev/null
@@ -1,588 +0,0 @@
-/*************************************************************************/
-/* skeleton_ik.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 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 */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-/**
- * @author AndreaCatania
- */
-
-#include "skeleton_ik.h"
-
-#ifndef _3D_DISABLED
-
-FabrikInverseKinematic::ChainItem *FabrikInverseKinematic::ChainItem::find_child(const BoneId p_bone_id) {
- for (int i = children.size() - 1; 0 <= i; --i) {
- if (p_bone_id == children[i].bone) {
- return &children.write[i];
- }
- }
- return NULL;
-}
-
-FabrikInverseKinematic::ChainItem *FabrikInverseKinematic::ChainItem::add_child(const BoneId p_bone_id) {
- const int infant_child_id = children.size();
- children.resize(infant_child_id + 1);
- children.write[infant_child_id].bone = p_bone_id;
- children.write[infant_child_id].parent_item = this;
- return &children.write[infant_child_id];
-}
-
-/// Build a chain that starts from the root to tip
-bool FabrikInverseKinematic::build_chain(Task *p_task, bool p_force_simple_chain) {
-
- ERR_FAIL_COND_V(-1 == p_task->root_bone, false);
-
- Chain &chain(p_task->chain);
-
- chain.tips.resize(p_task->end_effectors.size());
- chain.chain_root.bone = p_task->root_bone;
- chain.chain_root.initial_transform = p_task->skeleton->get_bone_global_pose(chain.chain_root.bone);
- chain.chain_root.current_pos = chain.chain_root.initial_transform.origin;
- chain.chain_root.pb = p_task->skeleton->get_physical_bone(chain.chain_root.bone);
- chain.middle_chain_item = NULL;
-
- // Holds all IDs that are composing a single chain in reverse order
- Vector<BoneId> chain_ids;
- // This is used to know the chain size
- int sub_chain_size;
- // Resize only one time in order to fit all joints for performance reason
- chain_ids.resize(p_task->skeleton->get_bone_count());
-
- for (int x = p_task->end_effectors.size() - 1; 0 <= x; --x) {
-
- const EndEffector *ee(&p_task->end_effectors[x]);
- ERR_FAIL_COND_V(p_task->root_bone >= ee->tip_bone, false);
- ERR_FAIL_INDEX_V(ee->tip_bone, p_task->skeleton->get_bone_count(), false);
-
- sub_chain_size = 0;
- // Picks all IDs that composing a single chain in reverse order (except the root)
- BoneId chain_sub_tip(ee->tip_bone);
- while (chain_sub_tip > p_task->root_bone) {
-
- chain_ids.write[sub_chain_size++] = chain_sub_tip;
- chain_sub_tip = p_task->skeleton->get_bone_parent(chain_sub_tip);
- }
-
- BoneId middle_chain_item_id = (((float)sub_chain_size) * 0.5);
-
- // Build chain by reading chain ids in reverse order
- // For each chain item id will be created a ChainItem if doesn't exists
- ChainItem *sub_chain(&chain.chain_root);
- for (int i = sub_chain_size - 1; 0 <= i; --i) {
-
- ChainItem *child_ci(sub_chain->find_child(chain_ids[i]));
- if (!child_ci) {
-
- child_ci = sub_chain->add_child(chain_ids[i]);
-
- child_ci->pb = p_task->skeleton->get_physical_bone(child_ci->bone);
-
- child_ci->initial_transform = p_task->skeleton->get_bone_global_pose(child_ci->bone);
- child_ci->current_pos = child_ci->initial_transform.origin;
-
- if (child_ci->parent_item) {
- child_ci->length = (child_ci->current_pos - child_ci->parent_item->current_pos).length();
- }
- }
-
- sub_chain = child_ci;
-
- if (middle_chain_item_id == i) {
- chain.middle_chain_item = child_ci;
- }
- }
-
- if (!middle_chain_item_id)
- chain.middle_chain_item = NULL;
-
- // Initialize current tip
- chain.tips.write[x].chain_item = sub_chain;
- chain.tips.write[x].end_effector = ee;
-
- if (p_force_simple_chain) {
- // NOTE:
- // This is an "hack" that force to create only one tip per chain since the solver of multi tip (end effector)
- // is not yet created.
- // Remove this code when this is done
- break;
- }
- }
- return true;
-}
-
-void FabrikInverseKinematic::update_chain(const Skeleton *p_sk, ChainItem *p_chain_item) {
-
- if (!p_chain_item)
- return;
-
- p_chain_item->initial_transform = p_sk->get_bone_global_pose(p_chain_item->bone);
- p_chain_item->current_pos = p_chain_item->initial_transform.origin;
-
- for (int i = p_chain_item->children.size() - 1; 0 <= i; --i) {
- update_chain(p_sk, &p_chain_item->children.write[i]);
- }
-}
-
-void FabrikInverseKinematic::solve_simple(Task *p_task, bool p_solve_magnet) {
-
- real_t distance_to_goal(1e4);
- real_t previous_distance_to_goal(0);
- int can_solve(p_task->max_iterations);
- while (distance_to_goal > p_task->min_distance && Math::abs(previous_distance_to_goal - distance_to_goal) > 0.005 && can_solve) {
- previous_distance_to_goal = distance_to_goal;
- --can_solve;
-
- solve_simple_backwards(p_task->chain, p_solve_magnet);
- solve_simple_forwards(p_task->chain, p_solve_magnet);
-
- distance_to_goal = (p_task->chain.tips[0].chain_item->current_pos - p_task->chain.tips[0].end_effector->goal_transform.origin).length();
- }
-}
-
-void FabrikInverseKinematic::solve_simple_backwards(Chain &r_chain, bool p_solve_magnet) {
-
- if (p_solve_magnet && !r_chain.middle_chain_item) {
- return;
- }
-
- Vector3 goal;
- ChainItem *sub_chain_tip;
- if (p_solve_magnet) {
- goal = r_chain.magnet_position;
- sub_chain_tip = r_chain.middle_chain_item;
- } else {
- goal = r_chain.tips[0].end_effector->goal_transform.origin;
- sub_chain_tip = r_chain.tips[0].chain_item;
- }
-
- while (sub_chain_tip) {
- sub_chain_tip->current_pos = goal;
-
- if (sub_chain_tip->parent_item) {
- // Not yet in the chain root
- // So calculate next goal location
-
- const Vector3 look_parent((sub_chain_tip->parent_item->current_pos - sub_chain_tip->current_pos).normalized());
- goal = sub_chain_tip->current_pos + (look_parent * sub_chain_tip->length);
-
- // [TODO] Constraints goes here
- }
-
- sub_chain_tip = sub_chain_tip->parent_item;
- }
-}
-
-void FabrikInverseKinematic::solve_simple_forwards(Chain &r_chain, bool p_solve_magnet) {
-
- if (p_solve_magnet && !r_chain.middle_chain_item) {
- return;
- }
-
- ChainItem *sub_chain_root(&r_chain.chain_root);
- Vector3 origin(r_chain.chain_root.initial_transform.origin);
-
- while (sub_chain_root) { // Reach the tip
- sub_chain_root->current_pos = origin;
-
- if (!sub_chain_root->children.empty()) {
-
- ChainItem &child(sub_chain_root->children.write[0]);
-
- // Is not tip
- // So calculate next origin location
-
- // Look child
- sub_chain_root->current_ori = (child.current_pos - sub_chain_root->current_pos).normalized();
- origin = sub_chain_root->current_pos + (sub_chain_root->current_ori * child.length);
-
- // [TODO] Constraints goes here
-
- if (p_solve_magnet && sub_chain_root == r_chain.middle_chain_item) {
- // In case of magnet solving this is the tip
- sub_chain_root = NULL;
- } else {
- sub_chain_root = &child;
- }
- } else {
-
- // Is tip
- sub_chain_root = NULL;
- }
- }
-}
-
-FabrikInverseKinematic::Task *FabrikInverseKinematic::create_simple_task(Skeleton *p_sk, BoneId root_bone, BoneId tip_bone, const Transform &goal_transform) {
-
- FabrikInverseKinematic::EndEffector ee;
- ee.tip_bone = tip_bone;
-
- Task *task(memnew(Task));
- task->skeleton = p_sk;
- task->root_bone = root_bone;
- task->end_effectors.push_back(ee);
- task->goal_global_transform = goal_transform;
-
- if (!build_chain(task)) {
- free_task(task);
- return NULL;
- }
-
- return task;
-}
-
-void FabrikInverseKinematic::free_task(Task *p_task) {
- if (p_task)
- memdelete(p_task);
-}
-
-void FabrikInverseKinematic::set_goal(Task *p_task, const Transform &p_goal) {
- p_task->goal_global_transform = p_goal;
-}
-
-void FabrikInverseKinematic::make_goal(Task *p_task, const Transform &p_inverse_transf, real_t blending_delta) {
-
- if (blending_delta >= 0.99f) {
- // Update the end_effector (local transform) without blending
- p_task->end_effectors.write[0].goal_transform = p_inverse_transf * p_task->goal_global_transform;
- } else {
-
- // End effector in local transform
- const Transform end_effector_pose(p_task->skeleton->get_bone_global_pose(p_task->end_effectors.write[0].tip_bone));
-
- // Update the end_effector (local transform) by blending with current pose
- p_task->end_effectors.write[0].goal_transform = end_effector_pose.interpolate_with(p_inverse_transf * p_task->goal_global_transform, blending_delta);
- }
-}
-
-void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool override_tip_basis, bool p_use_magnet, const Vector3 &p_magnet_position) {
-
- if (blending_delta <= 0.01f) {
- return; // Skip solving
- }
-
- make_goal(p_task, p_task->skeleton->get_global_transform().affine_inverse().scaled(p_task->skeleton->get_global_transform().get_basis().get_scale()), blending_delta);
-
- update_chain(p_task->skeleton, &p_task->chain.chain_root);
-
- if (p_use_magnet && p_task->chain.middle_chain_item) {
- p_task->chain.magnet_position = p_task->chain.middle_chain_item->initial_transform.origin.linear_interpolate(p_magnet_position, blending_delta);
- solve_simple(p_task, true);
- }
- solve_simple(p_task, false);
-
- // Assign new bone position.
- ChainItem *ci(&p_task->chain.chain_root);
- while (ci) {
- Transform new_bone_pose(ci->initial_transform);
- new_bone_pose.origin = ci->current_pos;
-
- if (!ci->children.empty()) {
-
- /// Rotate basis
- const Vector3 initial_ori((ci->children[0].initial_transform.origin - ci->initial_transform.origin).normalized());
- const Vector3 rot_axis(initial_ori.cross(ci->current_ori).normalized());
-
- if (rot_axis[0] != 0 && rot_axis[1] != 0 && rot_axis[2] != 0) {
- const real_t rot_angle(Math::acos(CLAMP(initial_ori.dot(ci->current_ori), -1, 1)));
- new_bone_pose.basis.rotate(rot_axis, rot_angle);
- }
- } else {
- // Set target orientation to tip
- if (override_tip_basis)
- new_bone_pose.basis = p_task->chain.tips[0].end_effector->goal_transform.basis;
- else
- new_bone_pose.basis = new_bone_pose.basis * p_task->chain.tips[0].end_effector->goal_transform.basis;
- }
-
- p_task->skeleton->set_bone_global_pose_override(ci->bone, new_bone_pose, 1.0, true);
-
- if (!ci->children.empty())
- ci = &ci->children.write[0];
- else
- ci = NULL;
- }
-}
-
-void FabrikInverseKinematic::reset(Task *p_task) {
- ChainItem *ci(&p_task->chain.chain_root);
- while (ci) {
- p_task->skeleton->set_bone_global_pose_override(ci->bone, Transform(), 0);
- if (!ci->children.empty())
- ci = &ci->children.write[0];
- else
- ci = NULL;
- }
-}
-
-void SkeletonIK::_validate_property(PropertyInfo &property) const {
-
- if (property.name == "root_bone" || property.name == "tip_bone") {
-
- if (skeleton) {
-
- String names("--,");
- for (int i = 0; i < skeleton->get_bone_count(); i++) {
- if (i > 0)
- names += ",";
- names += skeleton->get_bone_name(i);
- }
-
- property.hint = PROPERTY_HINT_ENUM;
- property.hint_string = names;
- } else {
-
- property.hint = PROPERTY_HINT_NONE;
- property.hint_string = "";
- }
- }
-}
-
-void SkeletonIK::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("set_root_bone", "root_bone"), &SkeletonIK::set_root_bone);
- ClassDB::bind_method(D_METHOD("get_root_bone"), &SkeletonIK::get_root_bone);
-
- ClassDB::bind_method(D_METHOD("set_tip_bone", "tip_bone"), &SkeletonIK::set_tip_bone);
- ClassDB::bind_method(D_METHOD("get_tip_bone"), &SkeletonIK::get_tip_bone);
-
- ClassDB::bind_method(D_METHOD("set_interpolation", "interpolation"), &SkeletonIK::set_interpolation);
- ClassDB::bind_method(D_METHOD("get_interpolation"), &SkeletonIK::get_interpolation);
-
- ClassDB::bind_method(D_METHOD("set_target_transform", "target"), &SkeletonIK::set_target_transform);
- ClassDB::bind_method(D_METHOD("get_target_transform"), &SkeletonIK::get_target_transform);
-
- ClassDB::bind_method(D_METHOD("set_target_node", "node"), &SkeletonIK::set_target_node);
- ClassDB::bind_method(D_METHOD("get_target_node"), &SkeletonIK::get_target_node);
-
- ClassDB::bind_method(D_METHOD("set_override_tip_basis", "override"), &SkeletonIK::set_override_tip_basis);
- ClassDB::bind_method(D_METHOD("is_override_tip_basis"), &SkeletonIK::is_override_tip_basis);
-
- ClassDB::bind_method(D_METHOD("set_use_magnet", "use"), &SkeletonIK::set_use_magnet);
- ClassDB::bind_method(D_METHOD("is_using_magnet"), &SkeletonIK::is_using_magnet);
-
- ClassDB::bind_method(D_METHOD("set_magnet_position", "local_position"), &SkeletonIK::set_magnet_position);
- ClassDB::bind_method(D_METHOD("get_magnet_position"), &SkeletonIK::get_magnet_position);
-
- ClassDB::bind_method(D_METHOD("get_parent_skeleton"), &SkeletonIK::get_parent_skeleton);
- ClassDB::bind_method(D_METHOD("is_running"), &SkeletonIK::is_running);
-
- ClassDB::bind_method(D_METHOD("set_min_distance", "min_distance"), &SkeletonIK::set_min_distance);
- ClassDB::bind_method(D_METHOD("get_min_distance"), &SkeletonIK::get_min_distance);
-
- ClassDB::bind_method(D_METHOD("set_max_iterations", "iterations"), &SkeletonIK::set_max_iterations);
- ClassDB::bind_method(D_METHOD("get_max_iterations"), &SkeletonIK::get_max_iterations);
-
- ClassDB::bind_method(D_METHOD("start", "one_time"), &SkeletonIK::start, DEFVAL(false));
- ClassDB::bind_method(D_METHOD("stop"), &SkeletonIK::stop);
-
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "root_bone"), "set_root_bone", "get_root_bone");
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "tip_bone"), "set_tip_bone", "get_tip_bone");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "interpolation", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_interpolation", "get_interpolation");
- ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "target"), "set_target_transform", "get_target_transform");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "override_tip_basis"), "set_override_tip_basis", "is_override_tip_basis");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_magnet"), "set_use_magnet", "is_using_magnet");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "magnet"), "set_magnet_position", "get_magnet_position");
- ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "target_node"), "set_target_node", "get_target_node");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "min_distance"), "set_min_distance", "get_min_distance");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "max_iterations"), "set_max_iterations", "get_max_iterations");
-}
-
-void SkeletonIK::_notification(int p_what) {
- switch (p_what) {
- case NOTIFICATION_ENTER_TREE: {
- skeleton = Object::cast_to<Skeleton>(get_parent());
- set_process_priority(1);
- reload_chain();
- } break;
- case NOTIFICATION_INTERNAL_PROCESS: {
-
- if (target_node_override)
- reload_goal();
-
- _solve_chain();
-
- } break;
- case NOTIFICATION_EXIT_TREE: {
- reload_chain();
- } break;
- }
-}
-
-SkeletonIK::SkeletonIK() :
- interpolation(1),
- override_tip_basis(true),
- use_magnet(false),
- min_distance(0.01),
- max_iterations(10),
- skeleton(NULL),
- target_node_override(NULL),
- task(NULL) {
-}
-
-SkeletonIK::~SkeletonIK() {
- FabrikInverseKinematic::free_task(task);
- task = NULL;
-}
-
-void SkeletonIK::set_root_bone(const StringName &p_root_bone) {
- root_bone = p_root_bone;
- reload_chain();
-}
-
-StringName SkeletonIK::get_root_bone() const {
- return root_bone;
-}
-
-void SkeletonIK::set_tip_bone(const StringName &p_tip_bone) {
- tip_bone = p_tip_bone;
- reload_chain();
-}
-
-StringName SkeletonIK::get_tip_bone() const {
- return tip_bone;
-}
-
-void SkeletonIK::set_interpolation(real_t p_interpolation) {
- interpolation = p_interpolation;
-}
-
-real_t SkeletonIK::get_interpolation() const {
- return interpolation;
-}
-
-void SkeletonIK::set_target_transform(const Transform &p_target) {
- target = p_target;
- reload_goal();
-}
-
-const Transform &SkeletonIK::get_target_transform() const {
- return target;
-}
-
-void SkeletonIK::set_target_node(const NodePath &p_node) {
- target_node_path_override = p_node;
- target_node_override = NULL;
- reload_goal();
-}
-
-NodePath SkeletonIK::get_target_node() {
- return target_node_path_override;
-}
-
-void SkeletonIK::set_override_tip_basis(bool p_override) {
- override_tip_basis = p_override;
-}
-
-bool SkeletonIK::is_override_tip_basis() const {
- return override_tip_basis;
-}
-
-void SkeletonIK::set_use_magnet(bool p_use) {
- use_magnet = p_use;
-}
-
-bool SkeletonIK::is_using_magnet() const {
- return use_magnet;
-}
-
-void SkeletonIK::set_magnet_position(const Vector3 &p_local_position) {
- magnet_position = p_local_position;
-}
-
-const Vector3 &SkeletonIK::get_magnet_position() const {
- return magnet_position;
-}
-
-void SkeletonIK::set_min_distance(real_t p_min_distance) {
- min_distance = p_min_distance;
-}
-
-void SkeletonIK::set_max_iterations(int p_iterations) {
- max_iterations = p_iterations;
-}
-
-bool SkeletonIK::is_running() {
- return is_processing_internal();
-}
-
-void SkeletonIK::start(bool p_one_time) {
- if (p_one_time) {
- set_process_internal(false);
- _solve_chain();
- } else {
- set_process_internal(true);
- }
-}
-
-void SkeletonIK::stop() {
- set_process_internal(false);
- if (task)
- FabrikInverseKinematic::reset(task);
-}
-
-Transform SkeletonIK::_get_target_transform() {
-
- if (!target_node_override && !target_node_path_override.is_empty())
- target_node_override = Object::cast_to<Spatial>(get_node(target_node_path_override));
-
- if (target_node_override)
- return target_node_override->get_global_transform();
- else
- return target;
-}
-
-void SkeletonIK::reload_chain() {
-
- FabrikInverseKinematic::free_task(task);
- task = NULL;
-
- if (!skeleton)
- return;
-
- task = FabrikInverseKinematic::create_simple_task(skeleton, skeleton->find_bone(root_bone), skeleton->find_bone(tip_bone), _get_target_transform());
- if (task) {
- task->max_iterations = max_iterations;
- task->min_distance = min_distance;
- }
-}
-
-void SkeletonIK::reload_goal() {
- if (!task)
- return;
-
- FabrikInverseKinematic::set_goal(task, _get_target_transform());
-}
-
-void SkeletonIK::_solve_chain() {
- if (!task)
- return;
- FabrikInverseKinematic::solve(task, interpolation, override_tip_basis, use_magnet, magnet_position);
-}
-
-#endif // _3D_DISABLED
diff --git a/scene/animation/skeleton_ik.h b/scene/animation/skeleton_ik.h
deleted file mode 100644
index 8fc8a58b99..0000000000
--- a/scene/animation/skeleton_ik.h
+++ /dev/null
@@ -1,221 +0,0 @@
-/*************************************************************************/
-/* skeleton_ik.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 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 */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef SKELETON_IK_H
-#define SKELETON_IK_H
-
-#ifndef _3D_DISABLED
-
-/**
- * @author AndreaCatania
- */
-
-#include "core/math/transform.h"
-#include "scene/3d/skeleton.h"
-
-class FabrikInverseKinematic {
-
- struct EndEffector {
- BoneId tip_bone;
- Transform goal_transform;
- };
-
- struct ChainItem {
-
- Vector<ChainItem> children;
- ChainItem *parent_item;
-
- // Bone info
- BoneId bone;
- PhysicalBone *pb;
-
- real_t length;
- /// Positions relative to root bone
- Transform initial_transform;
- Vector3 current_pos;
- // Direction from this bone to child
- Vector3 current_ori;
-
- ChainItem() :
- parent_item(NULL),
- bone(-1),
- pb(NULL),
- length(0) {}
-
- ChainItem *find_child(const BoneId p_bone_id);
- ChainItem *add_child(const BoneId p_bone_id);
- };
-
- struct ChainTip {
- ChainItem *chain_item;
- const EndEffector *end_effector;
-
- ChainTip() :
- chain_item(NULL),
- end_effector(NULL) {}
-
- ChainTip(ChainItem *p_chain_item, const EndEffector *p_end_effector) :
- chain_item(p_chain_item),
- end_effector(p_end_effector) {}
-
- ChainTip(const ChainTip &p_other_ct) :
- chain_item(p_other_ct.chain_item),
- end_effector(p_other_ct.end_effector) {}
- };
-
- struct Chain {
- ChainItem chain_root;
- ChainItem *middle_chain_item;
- Vector<ChainTip> tips;
- Vector3 magnet_position;
- };
-
-public:
- struct Task : public RID_Data {
- RID self;
- Skeleton *skeleton;
-
- Chain chain;
-
- // Settings
- real_t min_distance;
- int max_iterations;
-
- // Bone data
- BoneId root_bone;
- Vector<EndEffector> end_effectors;
-
- Transform goal_global_transform;
-
- Task() :
- skeleton(NULL),
- min_distance(0.01),
- max_iterations(10),
- root_bone(-1) {}
- };
-
-private:
- /// Init a chain that starts from the root to tip
- static bool build_chain(Task *p_task, bool p_force_simple_chain = true);
-
- static void update_chain(const Skeleton *p_sk, ChainItem *p_chain_item);
-
- static void solve_simple(Task *p_task, bool p_solve_magnet);
- /// Special solvers that solve only chains with one end effector
- static void solve_simple_backwards(Chain &r_chain, bool p_solve_magnet);
- static void solve_simple_forwards(Chain &r_chain, bool p_solve_magnet);
-
-public:
- static Task *create_simple_task(Skeleton *p_sk, BoneId root_bone, BoneId tip_bone, const Transform &goal_transform);
- static void free_task(Task *p_task);
- // The goal of chain should be always in local space
- static void set_goal(Task *p_task, const Transform &p_goal);
- static void make_goal(Task *p_task, const Transform &p_inverse_transf, real_t blending_delta);
- static void solve(Task *p_task, real_t blending_delta, bool override_tip_basis, bool p_use_magnet, const Vector3 &p_magnet_position);
- static void reset(Task *p_task);
-};
-
-class SkeletonIK : public Node {
- GDCLASS(SkeletonIK, Node);
-
- StringName root_bone;
- StringName tip_bone;
- real_t interpolation;
- Transform target;
- NodePath target_node_path_override;
- bool override_tip_basis;
- bool use_magnet;
- Vector3 magnet_position;
-
- real_t min_distance;
- int max_iterations;
-
- Skeleton *skeleton;
- Spatial *target_node_override;
- FabrikInverseKinematic::Task *task;
-
-protected:
- virtual void
- _validate_property(PropertyInfo &property) const;
-
- static void _bind_methods();
- virtual void _notification(int p_what);
-
-public:
- SkeletonIK();
- virtual ~SkeletonIK();
-
- void set_root_bone(const StringName &p_root_bone);
- StringName get_root_bone() const;
-
- void set_tip_bone(const StringName &p_tip_bone);
- StringName get_tip_bone() const;
-
- void set_interpolation(real_t p_interpolation);
- real_t get_interpolation() const;
-
- void set_target_transform(const Transform &p_target);
- const Transform &get_target_transform() const;
-
- void set_target_node(const NodePath &p_node);
- NodePath get_target_node();
-
- void set_override_tip_basis(bool p_override);
- bool is_override_tip_basis() const;
-
- void set_use_magnet(bool p_use);
- bool is_using_magnet() const;
-
- void set_magnet_position(const Vector3 &p_local_position);
- const Vector3 &get_magnet_position() const;
-
- void set_min_distance(real_t p_min_distance);
- real_t get_min_distance() const { return min_distance; }
-
- void set_max_iterations(int p_iterations);
- int get_max_iterations() const { return max_iterations; }
-
- Skeleton *get_parent_skeleton() const { return skeleton; }
-
- bool is_running();
-
- void start(bool p_one_time = false);
- void stop();
-
-private:
- Transform _get_target_transform();
- void reload_chain();
- void reload_goal();
- void _solve_chain();
-};
-
-#endif // _3D_DISABLED
-
-#endif // SKELETON_IK_H
diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp
index 331a6c769c..bd4396d680 100644
--- a/scene/animation/tween.cpp
+++ b/scene/animation/tween.cpp
@@ -33,7 +33,6 @@
#include "core/method_bind_ext.gen.inc"
void Tween::_add_pending_command(StringName p_key, const Variant &p_arg1, const Variant &p_arg2, const Variant &p_arg3, const Variant &p_arg4, const Variant &p_arg5, const Variant &p_arg6, const Variant &p_arg7, const Variant &p_arg8, const Variant &p_arg9, const Variant &p_arg10) {
-
// Add a new pending command and reference it
pending_commands.push_back(PendingCommand());
PendingCommand &cmd = pending_commands.back()->get();
@@ -43,61 +42,69 @@ void Tween::_add_pending_command(StringName p_key, const Variant &p_arg1, const
// Determine command argument count
int &count = cmd.args;
- if (p_arg10.get_type() != Variant::NIL)
+ if (p_arg10.get_type() != Variant::NIL) {
count = 10;
- else if (p_arg9.get_type() != Variant::NIL)
+ } else if (p_arg9.get_type() != Variant::NIL) {
count = 9;
- else if (p_arg8.get_type() != Variant::NIL)
+ } else if (p_arg8.get_type() != Variant::NIL) {
count = 8;
- else if (p_arg7.get_type() != Variant::NIL)
+ } else if (p_arg7.get_type() != Variant::NIL) {
count = 7;
- else if (p_arg6.get_type() != Variant::NIL)
+ } else if (p_arg6.get_type() != Variant::NIL) {
count = 6;
- else if (p_arg5.get_type() != Variant::NIL)
+ } else if (p_arg5.get_type() != Variant::NIL) {
count = 5;
- else if (p_arg4.get_type() != Variant::NIL)
+ } else if (p_arg4.get_type() != Variant::NIL) {
count = 4;
- else if (p_arg3.get_type() != Variant::NIL)
+ } else if (p_arg3.get_type() != Variant::NIL) {
count = 3;
- else if (p_arg2.get_type() != Variant::NIL)
+ } else if (p_arg2.get_type() != Variant::NIL) {
count = 2;
- else if (p_arg1.get_type() != Variant::NIL)
+ } else if (p_arg1.get_type() != Variant::NIL) {
count = 1;
- else
+ } else {
count = 0;
+ }
// Add the specified arguments to the command
- // TODO: Make this a switch statement?
- if (count > 0)
+ if (count > 0) {
cmd.arg[0] = p_arg1;
- if (count > 1)
+ }
+ if (count > 1) {
cmd.arg[1] = p_arg2;
- if (count > 2)
+ }
+ if (count > 2) {
cmd.arg[2] = p_arg3;
- if (count > 3)
+ }
+ if (count > 3) {
cmd.arg[3] = p_arg4;
- if (count > 4)
+ }
+ if (count > 4) {
cmd.arg[4] = p_arg5;
- if (count > 5)
+ }
+ if (count > 5) {
cmd.arg[5] = p_arg6;
- if (count > 6)
+ }
+ if (count > 6) {
cmd.arg[6] = p_arg7;
- if (count > 7)
+ }
+ if (count > 7) {
cmd.arg[7] = p_arg8;
- if (count > 8)
+ }
+ if (count > 8) {
cmd.arg[8] = p_arg9;
- if (count > 9)
+ }
+ if (count > 9) {
cmd.arg[9] = p_arg10;
+ }
}
void Tween::_process_pending_commands() {
-
// For each pending command...
for (List<PendingCommand>::Element *E = pending_commands.front(); E; E = E->next()) {
-
// Get the command
PendingCommand &cmd = E->get();
- Variant::CallError err;
+ Callable::CallError err;
// Grab all of the arguments for the command
Variant *arg[10] = {
@@ -122,48 +129,51 @@ void Tween::_process_pending_commands() {
}
bool Tween::_set(const StringName &p_name, const Variant &p_value) {
-
// Set the correct attribute based on the given name
String name = p_name;
if (name == "playback/speed" || name == "speed") { // Backwards compatibility
set_speed_scale(p_value);
+ return true;
} else if (name == "playback/active") {
set_active(p_value);
+ return true;
} else if (name == "playback/repeat") {
set_repeat(p_value);
+ return true;
}
- return true;
+ return false;
}
bool Tween::_get(const StringName &p_name, Variant &r_ret) const {
-
// Get the correct attribute based on the given name
String name = p_name;
if (name == "playback/speed") { // Backwards compatibility
r_ret = speed_scale;
+ return true;
} else if (name == "playback/active") {
r_ret = is_active();
+ return true;
} else if (name == "playback/repeat") {
r_ret = is_repeat();
+ return true;
}
- return true;
+ return false;
}
void Tween::_get_property_list(List<PropertyInfo> *p_list) const {
// Add the property info for the Tween object
p_list->push_back(PropertyInfo(Variant::BOOL, "playback/active", PROPERTY_HINT_NONE, ""));
p_list->push_back(PropertyInfo(Variant::BOOL, "playback/repeat", PROPERTY_HINT_NONE, ""));
- p_list->push_back(PropertyInfo(Variant::REAL, "playback/speed", PROPERTY_HINT_RANGE, "-64,64,0.01"));
+ p_list->push_back(PropertyInfo(Variant::FLOAT, "playback/speed", PROPERTY_HINT_RANGE, "-64,64,0.01"));
}
void Tween::_notification(int p_what) {
// What notification did we receive?
switch (p_what) {
-
case NOTIFICATION_ENTER_TREE: {
// Are we not already active?
if (!is_active()) {
@@ -180,26 +190,30 @@ void Tween::_notification(int p_what) {
case NOTIFICATION_INTERNAL_PROCESS: {
// Are we processing during physics time?
- if (tween_process_mode == TWEEN_PROCESS_PHYSICS)
+ if (tween_process_mode == TWEEN_PROCESS_PHYSICS) {
// Do nothing since we aren't aligned with physics when we should be
break;
+ }
// Should we update?
- if (is_active())
+ if (is_active()) {
// Update the tweens
_tween_process(get_process_delta_time());
+ }
} break;
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
// Are we processing during 'regular' time?
- if (tween_process_mode == TWEEN_PROCESS_IDLE)
+ if (tween_process_mode == TWEEN_PROCESS_IDLE) {
// Do nothing since we would only process during idle time
break;
+ }
// Should we update?
- if (is_active())
+ if (is_active()) {
// Update the tweens
_tween_process(get_physics_process_delta_time());
+ }
} break;
case NOTIFICATION_EXIT_TREE: {
@@ -250,14 +264,14 @@ void Tween::_bind_methods() {
// Add the Tween signals
ADD_SIGNAL(MethodInfo("tween_started", PropertyInfo(Variant::OBJECT, "object"), PropertyInfo(Variant::NODE_PATH, "key")));
- ADD_SIGNAL(MethodInfo("tween_step", PropertyInfo(Variant::OBJECT, "object"), PropertyInfo(Variant::NODE_PATH, "key"), PropertyInfo(Variant::REAL, "elapsed"), PropertyInfo(Variant::OBJECT, "value")));
+ ADD_SIGNAL(MethodInfo("tween_step", PropertyInfo(Variant::OBJECT, "object"), PropertyInfo(Variant::NODE_PATH, "key"), PropertyInfo(Variant::FLOAT, "elapsed"), PropertyInfo(Variant::OBJECT, "value")));
ADD_SIGNAL(MethodInfo("tween_completed", PropertyInfo(Variant::OBJECT, "object"), PropertyInfo(Variant::NODE_PATH, "key")));
ADD_SIGNAL(MethodInfo("tween_all_completed"));
// Add the properties and tie them to the getters and setters
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "repeat"), "set_repeat", "is_repeat");
ADD_PROPERTY(PropertyInfo(Variant::INT, "playback_process_mode", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_tween_process_mode", "get_tween_process_mode");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "playback_speed", PROPERTY_HINT_RANGE, "-64,64,0.01"), "set_speed_scale", "get_speed_scale");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "playback_speed", PROPERTY_HINT_RANGE, "-64,64,0.01"), "set_speed_scale", "get_speed_scale");
// Bind Idle vs Physics process
BIND_ENUM_CONSTANT(TWEEN_PROCESS_PHYSICS);
@@ -284,7 +298,6 @@ void Tween::_bind_methods() {
}
Variant Tween::_get_initial_val(const InterpolateData &p_data) const {
-
// What type of data are we interpolating?
switch (p_data.type) {
case INTER_PROPERTY:
@@ -298,7 +311,7 @@ Variant Tween::_get_initial_val(const InterpolateData &p_data) const {
case TARGETING_METHOD: {
// Get the object that is being targeted
Object *object = ObjectDB::get_instance(p_data.target_id);
- ERR_FAIL_COND_V(object == NULL, p_data.initial_val);
+ ERR_FAIL_COND_V(object == nullptr, p_data.initial_val);
// Are we targeting a property or a method?
Variant initial_val;
@@ -309,9 +322,9 @@ Variant Tween::_get_initial_val(const InterpolateData &p_data) const {
ERR_FAIL_COND_V(!valid, p_data.initial_val);
} else {
// Call the method and get the initial value from it
- Variant::CallError error;
- initial_val = object->call(p_data.target_key[0], NULL, 0, error);
- ERR_FAIL_COND_V(error.error != Variant::CallError::CALL_OK, p_data.initial_val);
+ Callable::CallError error;
+ initial_val = object->call(p_data.target_key[0], nullptr, 0, error);
+ ERR_FAIL_COND_V(error.error != Callable::CallError::CALL_OK, p_data.initial_val);
}
return initial_val;
}
@@ -330,7 +343,7 @@ Variant Tween::_get_final_val(const InterpolateData &p_data) const {
case FOLLOW_METHOD: {
// Get the object that is being followed
Object *target = ObjectDB::get_instance(p_data.target_id);
- ERR_FAIL_COND_V(target == NULL, p_data.initial_val);
+ ERR_FAIL_COND_V(target == nullptr, p_data.initial_val);
// We want to figure out the final value
Variant final_val;
@@ -341,14 +354,16 @@ Variant Tween::_get_final_val(const InterpolateData &p_data) const {
ERR_FAIL_COND_V(!valid, p_data.initial_val);
} else {
// We're looking at a method. Call the method on the target object
- Variant::CallError error;
- final_val = target->call(p_data.target_key[0], NULL, 0, error);
- ERR_FAIL_COND_V(error.error != Variant::CallError::CALL_OK, p_data.initial_val);
+ Callable::CallError error;
+ final_val = target->call(p_data.target_key[0], nullptr, 0, error);
+ ERR_FAIL_COND_V(error.error != Callable::CallError::CALL_OK, p_data.initial_val);
}
- // If we're looking at an INT value, instead convert it to a REAL
+ // If we're looking at an INT value, instead convert it to a FLOAT
// This is better for interpolation
- if (final_val.get_type() == Variant::INT) final_val = final_val.operator real_t();
+ if (final_val.get_type() == Variant::INT) {
+ final_val = final_val.operator real_t();
+ }
return final_val;
}
@@ -360,7 +375,6 @@ Variant Tween::_get_final_val(const InterpolateData &p_data) const {
}
Variant &Tween::_get_delta_val(InterpolateData &p_data) {
-
// What kind of data are we interpolating?
switch (p_data.type) {
case INTER_PROPERTY:
@@ -372,7 +386,7 @@ Variant &Tween::_get_delta_val(InterpolateData &p_data) {
case FOLLOW_METHOD: {
// We're following an object, so grab that instance
Object *target = ObjectDB::get_instance(p_data.target_id);
- ERR_FAIL_COND_V(target == NULL, p_data.initial_val);
+ ERR_FAIL_COND_V(target == nullptr, p_data.initial_val);
// We want to figure out the final value
Variant final_val;
@@ -383,14 +397,16 @@ Variant &Tween::_get_delta_val(InterpolateData &p_data) {
ERR_FAIL_COND_V(!valid, p_data.initial_val);
} else {
// We're looking at a method. Call the method on the target object
- Variant::CallError error;
- final_val = target->call(p_data.target_key[0], NULL, 0, error);
- ERR_FAIL_COND_V(error.error != Variant::CallError::CALL_OK, p_data.initial_val);
+ Callable::CallError error;
+ final_val = target->call(p_data.target_key[0], nullptr, 0, error);
+ ERR_FAIL_COND_V(error.error != Callable::CallError::CALL_OK, p_data.initial_val);
}
- // If we're looking at an INT value, instead convert it to a REAL
+ // If we're looking at an INT value, instead convert it to a FLOAT
// This is better for interpolation
- if (final_val.get_type() == Variant::INT) final_val = final_val.operator real_t();
+ if (final_val.get_type() == Variant::INT) {
+ final_val = final_val.operator real_t();
+ }
// Calculate the delta based on the initial value and the final value
_calc_delta_val(p_data.initial_val, final_val, p_data.delta_val);
@@ -402,9 +418,11 @@ Variant &Tween::_get_delta_val(InterpolateData &p_data) {
// Grab the initial value from the data to calculate delta
Variant initial_val = _get_initial_val(p_data);
- // If we're looking at an INT value, instead convert it to a REAL
+ // If we're looking at an INT value, instead convert it to a FLOAT
// This is better for interpolation
- if (initial_val.get_type() == Variant::INT) initial_val = initial_val.operator real_t();
+ if (initial_val.get_type() == Variant::INT) {
+ initial_val = initial_val.operator real_t();
+ }
// Calculate the delta based on the initial value and the final value
_calc_delta_val(initial_val, p_data.final_val, p_data.delta_val);
@@ -430,7 +448,6 @@ Variant Tween::_run_equation(InterpolateData &p_data) {
// What type of data are we interpolating?
switch (initial_val.get_type()) {
-
case Variant::BOOL:
// Run the boolean specific equation (checking if it is at least 0.5)
result = (_run_equation(p_data.trans_type, p_data.ease_type, p_data.elapsed - p_data.delay, initial_val, delta_val, p_data.duration)) >= 0.5;
@@ -441,8 +458,8 @@ Variant Tween::_run_equation(InterpolateData &p_data) {
result = (int)_run_equation(p_data.trans_type, p_data.ease_type, p_data.elapsed - p_data.delay, (int)initial_val, (int)delta_val, p_data.duration);
break;
- case Variant::REAL:
- // Run the REAL specific equation
+ case Variant::FLOAT:
+ // Run the FLOAT specific equation
result = _run_equation(p_data.trans_type, p_data.ease_type, p_data.elapsed - p_data.delay, (real_t)initial_val, (real_t)delta_val, p_data.duration);
break;
@@ -459,6 +476,20 @@ Variant Tween::_run_equation(InterpolateData &p_data) {
result = r;
} break;
+ case Variant::RECT2: {
+ // Get the Rect2 for initial and delta value
+ Rect2 i = initial_val;
+ Rect2 d = delta_val;
+ Rect2 r;
+
+ // Execute the equation for the position and size of Rect2
+ APPLY_EQUATION(position.x);
+ APPLY_EQUATION(position.y);
+ APPLY_EQUATION(size.x);
+ APPLY_EQUATION(size.y);
+ result = r;
+ } break;
+
case Variant::VECTOR3: {
// Get vectors for initial and delta values
Vector3 i = initial_val;
@@ -473,26 +504,6 @@ Variant Tween::_run_equation(InterpolateData &p_data) {
result = r;
} break;
- case Variant::BASIS: {
- // Get the basis for initial and delta values
- Basis i = initial_val;
- Basis d = delta_val;
- Basis r;
-
- // Execute the equation on all the basis and mutate the r basis
- // This uses the custom APPLY_EQUATION macro defined above
- APPLY_EQUATION(elements[0][0]);
- APPLY_EQUATION(elements[0][1]);
- APPLY_EQUATION(elements[0][2]);
- APPLY_EQUATION(elements[1][0]);
- APPLY_EQUATION(elements[1][1]);
- APPLY_EQUATION(elements[1][2]);
- APPLY_EQUATION(elements[2][0]);
- APPLY_EQUATION(elements[2][1]);
- APPLY_EQUATION(elements[2][2]);
- result = r;
- } break;
-
case Variant::TRANSFORM2D: {
// Get the transforms for initial and delta values
Transform2D i = initial_val;
@@ -509,6 +520,7 @@ Variant Tween::_run_equation(InterpolateData &p_data) {
APPLY_EQUATION(elements[2][1]);
result = r;
} break;
+
case Variant::QUAT: {
// Get the quaternian for the initial and delta values
Quat i = initial_val;
@@ -523,6 +535,7 @@ Variant Tween::_run_equation(InterpolateData &p_data) {
APPLY_EQUATION(w);
result = r;
} break;
+
case Variant::AABB: {
// Get the AABB's for the initial and delta values
AABB i = initial_val;
@@ -539,6 +552,27 @@ Variant Tween::_run_equation(InterpolateData &p_data) {
APPLY_EQUATION(size.z);
result = r;
} break;
+
+ case Variant::BASIS: {
+ // Get the basis for initial and delta values
+ Basis i = initial_val;
+ Basis d = delta_val;
+ Basis r;
+
+ // Execute the equation on all the basis and mutate the r basis
+ // This uses the custom APPLY_EQUATION macro defined above
+ APPLY_EQUATION(elements[0][0]);
+ APPLY_EQUATION(elements[0][1]);
+ APPLY_EQUATION(elements[0][2]);
+ APPLY_EQUATION(elements[1][0]);
+ APPLY_EQUATION(elements[1][1]);
+ APPLY_EQUATION(elements[1][2]);
+ APPLY_EQUATION(elements[2][0]);
+ APPLY_EQUATION(elements[2][1]);
+ APPLY_EQUATION(elements[2][2]);
+ result = r;
+ } break;
+
case Variant::TRANSFORM: {
// Get the transforms for the initial and delta values
Transform i = initial_val;
@@ -561,6 +595,7 @@ Variant Tween::_run_equation(InterpolateData &p_data) {
APPLY_EQUATION(origin.z);
result = r;
} break;
+
case Variant::COLOR: {
// Get the Color for initial and delta value
Color i = initial_val;
@@ -575,6 +610,7 @@ Variant Tween::_run_equation(InterpolateData &p_data) {
APPLY_EQUATION(a);
result = r;
} break;
+
default: {
// If unknown, just return the initial value
result = initial_val;
@@ -586,14 +622,12 @@ Variant Tween::_run_equation(InterpolateData &p_data) {
}
bool Tween::_apply_tween_value(InterpolateData &p_data, Variant &value) {
-
// Get the object we want to apply the new value to
Object *object = ObjectDB::get_instance(p_data.id);
- ERR_FAIL_COND_V(object == NULL, false);
+ ERR_FAIL_COND_V(object == nullptr, false);
// What kind of data are we mutating?
switch (p_data.type) {
-
case INTER_PROPERTY:
case FOLLOW_PROPERTY:
case TARGETING_PROPERTY: {
@@ -607,7 +641,7 @@ bool Tween::_apply_tween_value(InterpolateData &p_data, Variant &value) {
case FOLLOW_METHOD:
case TARGETING_METHOD: {
// We want to call the method on the target object
- Variant::CallError error;
+ Callable::CallError error;
// Do we have a non-nil value passed in?
if (value.get_type() != Variant::NIL) {
@@ -616,11 +650,11 @@ bool Tween::_apply_tween_value(InterpolateData &p_data, Variant &value) {
object->call(p_data.key[0], (const Variant **)arg, 1, error);
} else {
// Don't pass any argument
- object->call(p_data.key[0], NULL, 0, error);
+ object->call(p_data.key[0], nullptr, 0, error);
}
// Did we get an error from the function call?
- return error.error == Variant::CallError::CALL_OK;
+ return error.error == Callable::CallError::CALL_OK;
}
case INTER_CALLBACK:
@@ -636,8 +670,9 @@ void Tween::_tween_process(float p_delta) {
_process_pending_commands();
// If the scale is 0, make no progress on the tweens
- if (speed_scale == 0)
+ if (speed_scale == 0) {
return;
+ }
// Update the delta and whether we are pending an update
p_delta *= speed_scale;
@@ -660,37 +695,39 @@ void Tween::_tween_process(float p_delta) {
}
// If we are all finished, we can reset all of the tweens
- if (repeats_finished)
+ if (repeats_finished) {
reset_all();
+ }
}
// Are all of the tweens complete?
- bool all_finished = true;
+ int any_unfinished = 0;
// For each tween we wish to interpolate...
for (List<InterpolateData>::Element *E = interpolates.front(); E; E = E->next()) {
-
// Get the data from it
InterpolateData &data = E->get();
- // Track if we hit one that isn't finished yet
- all_finished = all_finished && data.finish;
-
// Is the data not active or already finished? No need to go any further
- if (!data.active || data.finish)
+ if (!data.active || data.finish) {
continue;
+ }
+
+ // Track if we hit one that isn't finished yet
+ any_unfinished++;
// Get the target object for this interpolation
Object *object = ObjectDB::get_instance(data.id);
- if (object == NULL)
+ if (object == nullptr) {
continue;
+ }
// Are we still delaying this tween?
bool prev_delaying = data.elapsed <= data.delay;
data.elapsed += p_delta;
- if (data.elapsed < data.delay)
+ if (data.elapsed < data.delay) {
continue;
- else if (prev_delaying) {
+ } else if (prev_delaying) {
// We can apply the tween's value to the data and emit that the tween has started
_apply_tween_value(data, data.initial_val);
emit_signal("tween_started", object, NodePath(Vector<StringName>(), data.key, false));
@@ -732,7 +769,7 @@ void Tween::_tween_process(float p_delta) {
}
} else {
// Call the function directly with the arguments
- Variant::CallError error;
+ Callable::CallError error;
Variant *arg[5] = {
&data.arg[0],
&data.arg[1],
@@ -763,18 +800,17 @@ void Tween::_tween_process(float p_delta) {
emit_signal("tween_completed", object, NodePath(Vector<StringName>(), data.key, false));
// If we are not repeating the tween, remove it
- if (!repeat)
+ if (!repeat) {
call_deferred("_remove_by_uid", data.uid);
- } else if (!repeat) {
- // Check whether all tweens are finished
- all_finished = all_finished && data.finish;
+ any_unfinished--;
+ }
}
}
// One less update left to go
pending_update--;
// If all tweens are completed, we no longer need to be active
- if (all_finished) {
+ if (any_unfinished == 0) {
set_active(false);
emit_signal("tween_all_completed");
}
@@ -794,13 +830,18 @@ bool Tween::is_active() const {
void Tween::set_active(bool p_active) {
// Do nothing if it's the same active mode that we currently are
- if (is_active() == p_active)
+ if (is_active() == p_active) {
return;
+ }
// Depending on physics or idle, set processing
switch (tween_process_mode) {
- case TWEEN_PROCESS_IDLE: set_process_internal(p_active); break;
- case TWEEN_PROCESS_PHYSICS: set_physics_process_internal(p_active); break;
+ case TWEEN_PROCESS_IDLE:
+ set_process_internal(p_active);
+ break;
+ case TWEEN_PROCESS_PHYSICS:
+ set_physics_process_internal(p_active);
+ break;
}
}
@@ -820,31 +861,30 @@ float Tween::get_speed_scale() const {
return speed_scale;
}
-bool Tween::start() {
-
- ERR_FAIL_COND_V_MSG(!is_inside_tree(), false, "Tween was not added to the SceneTree!");
+void Tween::start() {
+ ERR_FAIL_COND_MSG(!is_inside_tree(), "Tween was not added to the SceneTree!");
// Are there any pending updates?
if (pending_update != 0) {
// Start the tweens after deferring
call_deferred("start");
- return true;
+ return;
}
// We want to be activated
set_active(true);
- return true;
}
-bool Tween::reset(Object *p_object, StringName p_key) {
+void Tween::reset(Object *p_object, StringName p_key) {
// Find all interpolations that use the same object and target string
pending_update++;
for (List<InterpolateData>::Element *E = interpolates.front(); E; E = E->next()) {
// Get the target object
InterpolateData &data = E->get();
Object *object = ObjectDB::get_instance(data.id);
- if (object == NULL)
+ if (object == nullptr) {
continue;
+ }
// Do we have the correct object and key?
if (object == p_object && (data.concatenated_key == p_key || p_key == "")) {
@@ -853,15 +893,15 @@ bool Tween::reset(Object *p_object, StringName p_key) {
data.finish = false;
// Also apply the initial state if there isn't a delay
- if (data.delay == 0)
+ if (data.delay == 0) {
_apply_tween_value(data, data.initial_val);
+ }
}
}
pending_update--;
- return true;
}
-bool Tween::reset_all() {
+void Tween::reset_all() {
// Go through all interpolations
pending_update++;
for (List<InterpolateData>::Element *E = interpolates.front(); E; E = E->next()) {
@@ -871,34 +911,34 @@ bool Tween::reset_all() {
data.finish = false;
// If there isn't a delay, apply the value to the object
- if (data.delay == 0)
+ if (data.delay == 0) {
_apply_tween_value(data, data.initial_val);
+ }
}
pending_update--;
- return true;
}
-bool Tween::stop(Object *p_object, StringName p_key) {
+void Tween::stop(Object *p_object, StringName p_key) {
// Find the tween that has the given target object and string key
pending_update++;
for (List<InterpolateData>::Element *E = interpolates.front(); E; E = E->next()) {
-
// Get the object the tween is targeting
InterpolateData &data = E->get();
Object *object = ObjectDB::get_instance(data.id);
- if (object == NULL)
+ if (object == nullptr) {
continue;
+ }
// Is this the correct object and does it have the given key?
- if (object == p_object && (data.concatenated_key == p_key || p_key == ""))
+ if (object == p_object && (data.concatenated_key == p_key || p_key == "")) {
// Disable the tween
data.active = false;
+ }
}
pending_update--;
- return true;
}
-bool Tween::stop_all() {
+void Tween::stop_all() {
// We no longer need to be active since all tweens have been stopped
set_active(false);
@@ -910,10 +950,9 @@ bool Tween::stop_all() {
data.active = false;
}
pending_update--;
- return true;
}
-bool Tween::resume(Object *p_object, StringName p_key) {
+void Tween::resume(Object *p_object, StringName p_key) {
// We need to be activated
// TODO: What if no tween is found??
set_active(true);
@@ -924,18 +963,19 @@ bool Tween::resume(Object *p_object, StringName p_key) {
// Grab the object
InterpolateData &data = E->get();
Object *object = ObjectDB::get_instance(data.id);
- if (object == NULL)
+ if (object == nullptr) {
continue;
+ }
// If the object and string key match, activate it
- if (object == p_object && (data.concatenated_key == p_key || p_key == ""))
+ if (object == p_object && (data.concatenated_key == p_key || p_key == "")) {
data.active = true;
+ }
}
pending_update--;
- return true;
}
-bool Tween::resume_all() {
+void Tween::resume_all() {
// Set ourselves active so we can process tweens
// TODO: What if there are no tweens? We get set to active for no reason!
set_active(true);
@@ -948,14 +988,13 @@ bool Tween::resume_all() {
data.active = true;
}
pending_update--;
- return true;
}
-bool Tween::remove(Object *p_object, StringName p_key) {
+void Tween::remove(Object *p_object, StringName p_key) {
// If we are still updating, call this function again later
if (pending_update != 0) {
call_deferred("remove", p_object, p_key);
- return true;
+ return;
}
// For each interpolation...
@@ -964,8 +1003,9 @@ bool Tween::remove(Object *p_object, StringName p_key) {
// Get the target object
InterpolateData &data = E->get();
Object *object = ObjectDB::get_instance(data.id);
- if (object == NULL)
+ if (object == nullptr) {
continue;
+ }
// If the target object and string key match, queue it for removal
if (object == p_object && (data.concatenated_key == p_key || p_key == "")) {
@@ -978,7 +1018,6 @@ bool Tween::remove(Object *p_object, StringName p_key) {
// Erase it
interpolates.erase(E->get());
}
- return true;
}
void Tween::_remove_by_uid(int uid) {
@@ -1008,11 +1047,11 @@ void Tween::_push_interpolate_data(InterpolateData &p_data) {
pending_update--;
}
-bool Tween::remove_all() {
+void Tween::remove_all() {
// If we are still updating, call this function again later
if (pending_update != 0) {
call_deferred("remove_all");
- return true;
+ return;
}
// We no longer need to be active
set_active(false);
@@ -1020,11 +1059,9 @@ bool Tween::remove_all() {
// Clear out all interpolations and reset the uid
interpolates.clear();
uid = 0;
-
- return true;
}
-bool Tween::seek(real_t p_time) {
+void Tween::seek(real_t p_time) {
// Go through each interpolation...
pending_update++;
for (List<InterpolateData>::Element *E = interpolates.front(); E; E = E->next()) {
@@ -1058,7 +1095,6 @@ bool Tween::seek(real_t p_time) {
_apply_tween_value(data, result);
}
pending_update--;
- return true;
}
real_t Tween::tell() const {
@@ -1070,9 +1106,10 @@ real_t Tween::tell() const {
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
const InterpolateData &data = E->get();
- if (data.elapsed > pos)
+ if (data.elapsed > pos) {
// Save it if so
pos = data.elapsed;
+ }
}
pending_update--;
return pos;
@@ -1092,9 +1129,10 @@ real_t Tween::get_runtime() const {
// Get the tween data and see if it's runtime is greater than the previous tweens
const InterpolateData &data = E->get();
real_t t = data.delay + data.duration;
- if (t > runtime)
+ if (t > runtime) {
// This is the longest running tween
runtime = t;
+ }
}
pending_update--;
@@ -1103,7 +1141,6 @@ real_t Tween::get_runtime() const {
}
bool Tween::_calc_delta_val(const Variant &p_initial_val, const Variant &p_final_val, Variant &p_delta_val) {
-
// Get the initial, final, and delta values
const Variant &initial_val = p_initial_val;
const Variant &final_val = p_final_val;
@@ -1111,7 +1148,6 @@ bool Tween::_calc_delta_val(const Variant &p_initial_val, const Variant &p_final
// What kind of data are we interpolating?
switch (initial_val.get_type()) {
-
case Variant::BOOL:
// We'll treat booleans just like integers
case Variant::INT:
@@ -1119,8 +1155,8 @@ bool Tween::_calc_delta_val(const Variant &p_initial_val, const Variant &p_final
delta_val = (int)final_val - (int)initial_val;
break;
- case Variant::REAL:
- // Convert to REAL and find the delta
+ case Variant::FLOAT:
+ // Convert to FLOAT and find the delta
delta_val = (real_t)final_val - (real_t)initial_val;
break;
@@ -1129,26 +1165,18 @@ bool Tween::_calc_delta_val(const Variant &p_initial_val, const Variant &p_final
delta_val = final_val.operator Vector2() - initial_val.operator Vector2();
break;
+ case Variant::RECT2: {
+ // Build a new Rect2 and use the new position and sizes to make a delta
+ Rect2 i = initial_val;
+ Rect2 f = final_val;
+ delta_val = Rect2(f.position - i.position, f.size - i.size);
+ } break;
+
case Variant::VECTOR3:
// Convert to Vectors and find the delta
delta_val = final_val.operator Vector3() - initial_val.operator Vector3();
break;
- case Variant::BASIS: {
- // Build a new basis which is the delta between the initial and final values
- Basis i = initial_val;
- Basis f = final_val;
- delta_val = Basis(f.elements[0][0] - i.elements[0][0],
- f.elements[0][1] - i.elements[0][1],
- f.elements[0][2] - i.elements[0][2],
- f.elements[1][0] - i.elements[1][0],
- f.elements[1][1] - i.elements[1][1],
- f.elements[1][2] - i.elements[1][2],
- f.elements[2][0] - i.elements[2][0],
- f.elements[2][1] - i.elements[2][1],
- f.elements[2][2] - i.elements[2][2]);
- } break;
-
case Variant::TRANSFORM2D: {
// Build a new transform which is the difference between the initial and final values
Transform2D i = initial_val;
@@ -1175,6 +1203,21 @@ bool Tween::_calc_delta_val(const Variant &p_initial_val, const Variant &p_final
delta_val = AABB(f.position - i.position, f.size - i.size);
} break;
+ case Variant::BASIS: {
+ // Build a new basis which is the delta between the initial and final values
+ Basis i = initial_val;
+ Basis f = final_val;
+ delta_val = Basis(f.elements[0][0] - i.elements[0][0],
+ f.elements[0][1] - i.elements[0][1],
+ f.elements[0][2] - i.elements[0][2],
+ f.elements[1][0] - i.elements[1][0],
+ f.elements[1][1] - i.elements[1][1],
+ f.elements[1][2] - i.elements[1][2],
+ f.elements[2][0] - i.elements[2][0],
+ f.elements[2][1] - i.elements[2][1],
+ f.elements[2][2] - i.elements[2][2]);
+ } break;
+
case Variant::TRANSFORM: {
// Build a new transform which is the difference between the initial and final values
Transform i = initial_val;
@@ -1203,16 +1246,39 @@ bool Tween::_calc_delta_val(const Variant &p_initial_val, const Variant &p_final
delta_val = Color(f.r - i.r, f.g - i.g, f.b - i.b, f.a - i.a);
} break;
- default:
- // TODO: Should move away from a 'magic string'?
- ERR_PRINT("Invalid param type, except(int/real/vector2/vector/matrix/matrix32/quat/aabb/transform/color)");
+ default: {
+ static Variant::Type supported_types[] = {
+ Variant::BOOL,
+ Variant::INT,
+ Variant::FLOAT,
+ Variant::VECTOR2,
+ Variant::RECT2,
+ Variant::VECTOR3,
+ Variant::TRANSFORM2D,
+ Variant::QUAT,
+ Variant::AABB,
+ Variant::BASIS,
+ Variant::TRANSFORM,
+ Variant::COLOR,
+ };
+
+ int length = *(&supported_types + 1) - supported_types;
+ String error_msg = "Invalid parameter type. Supported types are: ";
+ for (int i = 0; i < length; i++) {
+ if (i != 0) {
+ error_msg += ", ";
+ }
+ error_msg += Variant::get_type_name(supported_types[i]);
+ }
+ error_msg += ".";
+ ERR_PRINT(error_msg);
return false;
+ }
};
return true;
}
-bool Tween::_build_interpolation(InterpolateType p_interpolation_type, Object *p_object, NodePath *p_property, StringName *p_method, Variant p_initial_val, Variant p_final_val, real_t p_duration, TransitionType p_trans_type, EaseType p_ease_type, real_t p_delay) {
-
+void Tween::_build_interpolation(InterpolateType p_interpolation_type, Object *p_object, NodePath *p_property, StringName *p_method, Variant p_initial_val, Variant p_final_val, real_t p_duration, TransitionType p_trans_type, EaseType p_ease_type, real_t p_delay) {
// TODO: Add initialization+implementation for remaining interpolation types
// TODO: Fix this method's organization to take advantage of the type
@@ -1226,29 +1292,28 @@ bool Tween::_build_interpolation(InterpolateType p_interpolation_type, Object *p
// Validate and apply interpolation data
// Give it the object
- ERR_FAIL_COND_V_MSG(p_object == NULL, false, "Invalid object provided to Tween.");
- ERR_FAIL_COND_V_MSG(!ObjectDB::instance_validate(p_object), false, "Invalid object provided to Tween.");
+ ERR_FAIL_COND_MSG(p_object == nullptr, "Invalid object provided to Tween.");
data.id = p_object->get_instance_id();
// Validate the initial and final values
- ERR_FAIL_COND_V_MSG(p_initial_val.get_type() != p_final_val.get_type(), false, "Initial value type '" + Variant::get_type_name(p_initial_val.get_type()) + "' does not match final value type '" + Variant::get_type_name(p_final_val.get_type()) + "'.");
+ ERR_FAIL_COND_MSG(p_initial_val.get_type() != p_final_val.get_type(), "Initial value type '" + Variant::get_type_name(p_initial_val.get_type()) + "' does not match final value type '" + Variant::get_type_name(p_final_val.get_type()) + "'.");
data.initial_val = p_initial_val;
data.final_val = p_final_val;
// Check the Duration
- ERR_FAIL_COND_V_MSG(p_duration < 0, false, "Only non-negative duration values allowed in Tweens.");
+ ERR_FAIL_COND_MSG(p_duration < 0, "Only non-negative duration values allowed in Tweens.");
data.duration = p_duration;
// Tween Delay
- ERR_FAIL_COND_V_MSG(p_delay < 0, false, "Only non-negative delay values allowed in Tweens.");
+ ERR_FAIL_COND_MSG(p_delay < 0, "Only non-negative delay values allowed in Tweens.");
data.delay = p_delay;
// Transition type
- ERR_FAIL_COND_V_MSG(p_trans_type < 0 || p_trans_type >= TRANS_COUNT, false, "Invalid transition type provided to Tween.");
+ ERR_FAIL_COND_MSG(p_trans_type < 0 || p_trans_type >= TRANS_COUNT, "Invalid transition type provided to Tween.");
data.trans_type = p_trans_type;
// Easing type
- ERR_FAIL_COND_V_MSG(p_ease_type < 0 || p_ease_type >= EASE_COUNT, false, "Invalid easing type provided to Tween.");
+ ERR_FAIL_COND_MSG(p_ease_type < 0 || p_ease_type >= EASE_COUNT, "Invalid easing type provided to Tween.");
data.ease_type = p_ease_type;
// Is the property defined?
@@ -1256,7 +1321,7 @@ bool Tween::_build_interpolation(InterpolateType p_interpolation_type, Object *p
// Check that the object actually contains the given property
bool prop_valid = false;
p_object->get_indexed(p_property->get_subnames(), &prop_valid);
- ERR_FAIL_COND_V_MSG(!prop_valid, false, "Tween target object has no property named: " + p_property->get_concatenated_subnames() + ".");
+ ERR_FAIL_COND_MSG(!prop_valid, "Tween target object has no property named: " + p_property->get_concatenated_subnames() + ".");
data.key = p_property->get_subnames();
data.concatenated_key = p_property->get_concatenated_subnames();
@@ -1265,26 +1330,26 @@ bool Tween::_build_interpolation(InterpolateType p_interpolation_type, Object *p
// Is the method defined?
if (p_method) {
// Does the object even have the requested method?
- ERR_FAIL_COND_V_MSG(!p_object->has_method(*p_method), false, "Tween target object has no method named: " + *p_method + ".");
+ ERR_FAIL_COND_MSG(!p_object->has_method(*p_method), "Tween target object has no method named: " + *p_method + ".");
data.key.push_back(*p_method);
data.concatenated_key = *p_method;
}
// Is there not a valid delta?
- if (!_calc_delta_val(data.initial_val, data.final_val, data.delta_val))
- return false;
+ if (!_calc_delta_val(data.initial_val, data.final_val, data.delta_val)) {
+ return;
+ }
// Add this interpolation to the total
_push_interpolate_data(data);
- return true;
}
-bool Tween::interpolate_property(Object *p_object, NodePath p_property, Variant p_initial_val, Variant p_final_val, real_t p_duration, TransitionType p_trans_type, EaseType p_ease_type, real_t p_delay) {
+void Tween::interpolate_property(Object *p_object, NodePath p_property, Variant p_initial_val, Variant p_final_val, real_t p_duration, TransitionType p_trans_type, EaseType p_ease_type, real_t p_delay) {
// If we are busy updating, call this function again later
if (pending_update != 0) {
_add_pending_command("interpolate_property", p_object, p_property, p_initial_val, p_final_val, p_duration, p_trans_type, p_ease_type, p_delay);
- return true;
+ return;
}
// Get the property from the node path
@@ -1292,49 +1357,56 @@ bool Tween::interpolate_property(Object *p_object, NodePath p_property, Variant
// If no initial value given, grab the initial value from the object
// TODO: Is this documented? This is very useful and removes a lot of clutter from tweens!
- if (p_initial_val.get_type() == Variant::NIL) p_initial_val = p_object->get_indexed(p_property.get_subnames());
+ if (p_initial_val.get_type() == Variant::NIL) {
+ p_initial_val = p_object->get_indexed(p_property.get_subnames());
+ }
// 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();
- if (p_final_val.get_type() == Variant::INT) p_final_val = p_final_val.operator real_t();
+ if (p_initial_val.get_type() == Variant::INT) {
+ p_initial_val = p_initial_val.operator real_t();
+ }
+ if (p_final_val.get_type() == Variant::INT) {
+ p_final_val = p_final_val.operator real_t();
+ }
// Build the interpolation data
- bool result = _build_interpolation(INTER_PROPERTY, p_object, &p_property, NULL, p_initial_val, p_final_val, p_duration, p_trans_type, p_ease_type, p_delay);
- return result;
+ _build_interpolation(INTER_PROPERTY, p_object, &p_property, nullptr, p_initial_val, p_final_val, p_duration, p_trans_type, p_ease_type, p_delay);
}
-bool Tween::interpolate_method(Object *p_object, StringName p_method, Variant p_initial_val, Variant p_final_val, real_t p_duration, TransitionType p_trans_type, EaseType p_ease_type, real_t p_delay) {
+void Tween::interpolate_method(Object *p_object, StringName p_method, Variant p_initial_val, Variant p_final_val, real_t p_duration, TransitionType p_trans_type, EaseType p_ease_type, real_t p_delay) {
// If we are busy updating, call this function again later
if (pending_update != 0) {
_add_pending_command("interpolate_method", p_object, p_method, p_initial_val, p_final_val, p_duration, p_trans_type, p_ease_type, p_delay);
- return true;
+ return;
}
// 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();
- if (p_final_val.get_type() == Variant::INT) p_final_val = p_final_val.operator real_t();
+ if (p_initial_val.get_type() == Variant::INT) {
+ p_initial_val = p_initial_val.operator real_t();
+ }
+ if (p_final_val.get_type() == Variant::INT) {
+ p_final_val = p_final_val.operator real_t();
+ }
// Build the interpolation data
- bool result = _build_interpolation(INTER_METHOD, p_object, NULL, &p_method, p_initial_val, p_final_val, p_duration, p_trans_type, p_ease_type, p_delay);
- return result;
+ _build_interpolation(INTER_METHOD, p_object, nullptr, &p_method, p_initial_val, p_final_val, p_duration, p_trans_type, p_ease_type, p_delay);
}
-bool Tween::interpolate_callback(Object *p_object, real_t p_duration, String p_callback, VARIANT_ARG_DECLARE) {
+void Tween::interpolate_callback(Object *p_object, real_t p_duration, String p_callback, VARIANT_ARG_DECLARE) {
// If we are already updating, call this function again later
if (pending_update != 0) {
_add_pending_command("interpolate_callback", p_object, p_duration, p_callback, p_arg1, p_arg2, p_arg3, p_arg4, p_arg5);
- return true;
+ return;
}
// Check that the target object is valid
- ERR_FAIL_COND_V(p_object == NULL, false);
- ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_object), false);
+ ERR_FAIL_COND(p_object == nullptr);
// Duration cannot be negative
- ERR_FAIL_COND_V(p_duration < 0, false);
+ ERR_FAIL_COND(p_duration < 0);
// Check whether the object even has the callback
- ERR_FAIL_COND_V_MSG(!p_object->has_method(p_callback), false, "Object has no callback named: " + p_callback + ".");
+ ERR_FAIL_COND_MSG(!p_object->has_method(p_callback), "Object has no callback named: " + p_callback + ".");
// Build a new InterpolationData
InterpolateData data;
@@ -1353,18 +1425,19 @@ bool Tween::interpolate_callback(Object *p_object, real_t p_duration, String p_c
// Add arguments to the interpolation
int args = 0;
- if (p_arg5.get_type() != Variant::NIL)
+ if (p_arg5.get_type() != Variant::NIL) {
args = 5;
- else if (p_arg4.get_type() != Variant::NIL)
+ } else if (p_arg4.get_type() != Variant::NIL) {
args = 4;
- else if (p_arg3.get_type() != Variant::NIL)
+ } else if (p_arg3.get_type() != Variant::NIL) {
args = 3;
- else if (p_arg2.get_type() != Variant::NIL)
+ } else if (p_arg2.get_type() != Variant::NIL) {
args = 2;
- else if (p_arg1.get_type() != Variant::NIL)
+ } else if (p_arg1.get_type() != Variant::NIL) {
args = 1;
- else
+ } else {
args = 0;
+ }
data.args = args;
data.arg[0] = p_arg1;
@@ -1375,25 +1448,23 @@ bool Tween::interpolate_callback(Object *p_object, real_t p_duration, String p_c
// Add the new interpolation
_push_interpolate_data(data);
- return true;
}
-bool Tween::interpolate_deferred_callback(Object *p_object, real_t p_duration, String p_callback, VARIANT_ARG_DECLARE) {
+void Tween::interpolate_deferred_callback(Object *p_object, real_t p_duration, String p_callback, VARIANT_ARG_DECLARE) {
// If we are already updating, call this function again later
if (pending_update != 0) {
_add_pending_command("interpolate_deferred_callback", p_object, p_duration, p_callback, p_arg1, p_arg2, p_arg3, p_arg4, p_arg5);
- return true;
+ return;
}
// Check that the target object is valid
- ERR_FAIL_COND_V(p_object == NULL, false);
- ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_object), false);
+ ERR_FAIL_COND(p_object == nullptr);
// No negative durations allowed
- ERR_FAIL_COND_V(p_duration < 0, false);
+ ERR_FAIL_COND(p_duration < 0);
// Confirm the callback exists on the object
- ERR_FAIL_COND_V_MSG(!p_object->has_method(p_callback), false, "Object has no callback named: " + p_callback + ".");
+ ERR_FAIL_COND_MSG(!p_object->has_method(p_callback), "Object has no callback named: " + p_callback + ".");
// Create a new InterpolateData for the callback
InterpolateData data;
@@ -1412,18 +1483,19 @@ bool Tween::interpolate_deferred_callback(Object *p_object, real_t p_duration, S
// Collect arguments for the callback
int args = 0;
- if (p_arg5.get_type() != Variant::NIL)
+ if (p_arg5.get_type() != Variant::NIL) {
args = 5;
- else if (p_arg4.get_type() != Variant::NIL)
+ } else if (p_arg4.get_type() != Variant::NIL) {
args = 4;
- else if (p_arg3.get_type() != Variant::NIL)
+ } else if (p_arg3.get_type() != Variant::NIL) {
args = 3;
- else if (p_arg2.get_type() != Variant::NIL)
+ } else if (p_arg2.get_type() != Variant::NIL) {
args = 2;
- else if (p_arg1.get_type() != Variant::NIL)
+ } else if (p_arg1.get_type() != Variant::NIL) {
args = 1;
- else
+ } else {
args = 0;
+ }
data.args = args;
data.arg[0] = p_arg1;
@@ -1434,14 +1506,13 @@ bool Tween::interpolate_deferred_callback(Object *p_object, real_t p_duration, S
// Add the new interpolation
_push_interpolate_data(data);
- return true;
}
-bool Tween::follow_property(Object *p_object, NodePath p_property, Variant p_initial_val, Object *p_target, NodePath p_target_property, real_t p_duration, TransitionType p_trans_type, EaseType p_ease_type, real_t p_delay) {
+void Tween::follow_property(Object *p_object, NodePath p_property, Variant p_initial_val, Object *p_target, NodePath p_target_property, real_t p_duration, TransitionType p_trans_type, EaseType p_ease_type, real_t p_delay) {
// If we are already updating, call this function again later
if (pending_update != 0) {
_add_pending_command("follow_property", p_object, p_property, p_initial_val, p_target, p_target_property, p_duration, p_trans_type, p_ease_type, p_delay);
- return true;
+ return;
}
// Get the two properties from their paths
@@ -1450,41 +1521,45 @@ bool Tween::follow_property(Object *p_object, NodePath p_property, Variant p_ini
// If no initial value is given, grab it from the source object
// TODO: Is this documented? It's really helpful for decluttering tweens
- if (p_initial_val.get_type() == Variant::NIL) p_initial_val = p_object->get_indexed(p_property.get_subnames());
+ if (p_initial_val.get_type() == Variant::NIL) {
+ p_initial_val = p_object->get_indexed(p_property.get_subnames());
+ }
- // Convert initial INT values to REAL as they are better for interpolation
- if (p_initial_val.get_type() == Variant::INT) p_initial_val = p_initial_val.operator real_t();
+ // Convert initial INT values to FLOAT as they are better for interpolation
+ if (p_initial_val.get_type() == Variant::INT) {
+ p_initial_val = p_initial_val.operator real_t();
+ }
// Confirm the source and target objects are valid
- ERR_FAIL_COND_V(p_object == NULL, false);
- ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_object), false);
- ERR_FAIL_COND_V(p_target == NULL, false);
- ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_target), false);
+ ERR_FAIL_COND(p_object == nullptr);
+ ERR_FAIL_COND(p_target == nullptr);
// No negative durations
- ERR_FAIL_COND_V(p_duration < 0, false);
+ ERR_FAIL_COND(p_duration < 0);
// Ensure transition and easing types are valid
- ERR_FAIL_COND_V(p_trans_type < 0 || p_trans_type >= TRANS_COUNT, false);
- ERR_FAIL_COND_V(p_ease_type < 0 || p_ease_type >= EASE_COUNT, false);
+ ERR_FAIL_COND(p_trans_type < 0 || p_trans_type >= TRANS_COUNT);
+ ERR_FAIL_COND(p_ease_type < 0 || p_ease_type >= EASE_COUNT);
// No negative delays
- ERR_FAIL_COND_V(p_delay < 0, false);
+ ERR_FAIL_COND(p_delay < 0);
// Confirm the source and target objects have the desired properties
bool prop_valid = false;
p_object->get_indexed(p_property.get_subnames(), &prop_valid);
- ERR_FAIL_COND_V(!prop_valid, false);
+ ERR_FAIL_COND(!prop_valid);
bool target_prop_valid = false;
Variant target_val = p_target->get_indexed(p_target_property.get_subnames(), &target_prop_valid);
- ERR_FAIL_COND_V(!target_prop_valid, false);
+ ERR_FAIL_COND(!target_prop_valid);
- // Convert target INT to REAL since it is better for interpolation
- if (target_val.get_type() == Variant::INT) target_val = target_val.operator real_t();
+ // Convert target INT to FLOAT since it is better for interpolation
+ if (target_val.get_type() == Variant::INT) {
+ target_val = target_val.operator real_t();
+ }
// Verify that the target value and initial value are the same type
- ERR_FAIL_COND_V(target_val.get_type() != p_initial_val.get_type(), false);
+ ERR_FAIL_COND(target_val.get_type() != p_initial_val.get_type());
// Create a new InterpolateData
InterpolateData data;
@@ -1507,46 +1582,47 @@ bool Tween::follow_property(Object *p_object, NodePath p_property, Variant p_ini
// Add the interpolation
_push_interpolate_data(data);
- return true;
}
-bool Tween::follow_method(Object *p_object, StringName p_method, Variant p_initial_val, Object *p_target, StringName p_target_method, real_t p_duration, TransitionType p_trans_type, EaseType p_ease_type, real_t p_delay) {
+void Tween::follow_method(Object *p_object, StringName p_method, Variant p_initial_val, Object *p_target, StringName p_target_method, real_t p_duration, TransitionType p_trans_type, EaseType p_ease_type, real_t p_delay) {
// If we are currently updating, call this function again later
if (pending_update != 0) {
_add_pending_command("follow_method", p_object, p_method, p_initial_val, p_target, p_target_method, p_duration, p_trans_type, p_ease_type, p_delay);
- return true;
+ return;
+ }
+ // Convert initial INT values to FLOAT as they are better for interpolation
+ if (p_initial_val.get_type() == Variant::INT) {
+ p_initial_val = p_initial_val.operator real_t();
}
- // Convert initial INT values to REAL as they are better for interpolation
- if (p_initial_val.get_type() == Variant::INT) p_initial_val = p_initial_val.operator real_t();
// Verify the source and target objects are valid
- ERR_FAIL_COND_V(p_object == NULL, false);
- ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_object), false);
- ERR_FAIL_COND_V(p_target == NULL, false);
- ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_target), false);
+ ERR_FAIL_COND(p_object == nullptr);
+ ERR_FAIL_COND(p_target == nullptr);
// No negative durations
- ERR_FAIL_COND_V(p_duration < 0, false);
+ ERR_FAIL_COND(p_duration < 0);
// Ensure that the transition and ease types are valid
- ERR_FAIL_COND_V(p_trans_type < 0 || p_trans_type >= TRANS_COUNT, false);
- ERR_FAIL_COND_V(p_ease_type < 0 || p_ease_type >= EASE_COUNT, false);
+ ERR_FAIL_COND(p_trans_type < 0 || p_trans_type >= TRANS_COUNT);
+ ERR_FAIL_COND(p_ease_type < 0 || p_ease_type >= EASE_COUNT);
// No negative delays
- ERR_FAIL_COND_V(p_delay < 0, false);
+ ERR_FAIL_COND(p_delay < 0);
// Confirm both objects have the target methods
- ERR_FAIL_COND_V_MSG(!p_object->has_method(p_method), false, "Object has no method named: " + p_method + ".");
- ERR_FAIL_COND_V_MSG(!p_target->has_method(p_target_method), false, "Target has no method named: " + p_target_method + ".");
+ ERR_FAIL_COND_MSG(!p_object->has_method(p_method), "Object has no method named: " + p_method + ".");
+ ERR_FAIL_COND_MSG(!p_target->has_method(p_target_method), "Target has no method named: " + p_target_method + ".");
// Call the method to get the target value
- Variant::CallError error;
- Variant target_val = p_target->call(p_target_method, NULL, 0, error);
- ERR_FAIL_COND_V(error.error != Variant::CallError::CALL_OK, false);
+ Callable::CallError error;
+ Variant target_val = p_target->call(p_target_method, nullptr, 0, error);
+ ERR_FAIL_COND(error.error != Callable::CallError::CALL_OK);
- // Convert target INT values to REAL as they are better for interpolation
- if (target_val.get_type() == Variant::INT) target_val = target_val.operator real_t();
- ERR_FAIL_COND_V(target_val.get_type() != p_initial_val.get_type(), false);
+ // Convert target INT values to FLOAT as they are better for interpolation
+ if (target_val.get_type() == Variant::INT) {
+ target_val = target_val.operator real_t();
+ }
+ ERR_FAIL_COND(target_val.get_type() != p_initial_val.get_type());
// Make the new InterpolateData for the method follow
InterpolateData data;
@@ -1569,50 +1645,51 @@ bool Tween::follow_method(Object *p_object, StringName p_method, Variant p_initi
// Add the new interpolation
_push_interpolate_data(data);
- return true;
}
-bool Tween::targeting_property(Object *p_object, NodePath p_property, Object *p_initial, NodePath p_initial_property, Variant p_final_val, real_t p_duration, TransitionType p_trans_type, EaseType p_ease_type, real_t p_delay) {
+void Tween::targeting_property(Object *p_object, NodePath p_property, Object *p_initial, NodePath p_initial_property, Variant p_final_val, real_t p_duration, TransitionType p_trans_type, EaseType p_ease_type, real_t p_delay) {
// If we are currently updating, call this function again later
if (pending_update != 0) {
_add_pending_command("targeting_property", p_object, p_property, p_initial, p_initial_property, p_final_val, p_duration, p_trans_type, p_ease_type, p_delay);
- return true;
+ return;
}
// Grab the target property and the target property
p_property = p_property.get_as_property_path();
p_initial_property = p_initial_property.get_as_property_path();
- // Convert the initial INT values to REAL as they are better for Interpolation
- if (p_final_val.get_type() == Variant::INT) p_final_val = p_final_val.operator real_t();
+ // Convert the initial INT values to FLOAT as they are better for Interpolation
+ if (p_final_val.get_type() == Variant::INT) {
+ p_final_val = p_final_val.operator real_t();
+ }
// Verify both objects are valid
- ERR_FAIL_COND_V(p_object == NULL, false);
- ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_object), false);
- ERR_FAIL_COND_V(p_initial == NULL, false);
- ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_initial), false);
+ ERR_FAIL_COND(p_object == nullptr);
+ ERR_FAIL_COND(p_initial == nullptr);
// No negative durations
- ERR_FAIL_COND_V(p_duration < 0, false);
+ ERR_FAIL_COND(p_duration < 0);
// Ensure transition and easing types are valid
- ERR_FAIL_COND_V(p_trans_type < 0 || p_trans_type >= TRANS_COUNT, false);
- ERR_FAIL_COND_V(p_ease_type < 0 || p_ease_type >= EASE_COUNT, false);
+ ERR_FAIL_COND(p_trans_type < 0 || p_trans_type >= TRANS_COUNT);
+ ERR_FAIL_COND(p_ease_type < 0 || p_ease_type >= EASE_COUNT);
// No negative delays
- ERR_FAIL_COND_V(p_delay < 0, false);
+ ERR_FAIL_COND(p_delay < 0);
// Ensure the initial and target properties exist on their objects
bool prop_valid = false;
p_object->get_indexed(p_property.get_subnames(), &prop_valid);
- ERR_FAIL_COND_V(!prop_valid, false);
+ ERR_FAIL_COND(!prop_valid);
bool initial_prop_valid = false;
Variant initial_val = p_initial->get_indexed(p_initial_property.get_subnames(), &initial_prop_valid);
- ERR_FAIL_COND_V(!initial_prop_valid, false);
+ ERR_FAIL_COND(!initial_prop_valid);
- // Convert the initial INT value to REAL as it is better for interpolation
- if (initial_val.get_type() == Variant::INT) initial_val = initial_val.operator real_t();
- ERR_FAIL_COND_V(initial_val.get_type() != p_final_val.get_type(), false);
+ // Convert the initial INT value to FLOAT as it is better for interpolation
+ if (initial_val.get_type() == Variant::INT) {
+ initial_val = initial_val.operator real_t();
+ }
+ ERR_FAIL_COND(initial_val.get_type() != p_final_val.get_type());
// Build the InterpolateData object
InterpolateData data;
@@ -1635,52 +1712,54 @@ bool Tween::targeting_property(Object *p_object, NodePath p_property, Object *p_
data.delay = p_delay;
// Ensure there is a valid delta
- if (!_calc_delta_val(data.initial_val, data.final_val, data.delta_val))
- return false;
+ if (!_calc_delta_val(data.initial_val, data.final_val, data.delta_val)) {
+ return;
+ }
// Add the interpolation
_push_interpolate_data(data);
- return true;
}
-bool Tween::targeting_method(Object *p_object, StringName p_method, Object *p_initial, StringName p_initial_method, Variant p_final_val, real_t p_duration, TransitionType p_trans_type, EaseType p_ease_type, real_t p_delay) {
+void Tween::targeting_method(Object *p_object, StringName p_method, Object *p_initial, StringName p_initial_method, Variant p_final_val, real_t p_duration, TransitionType p_trans_type, EaseType p_ease_type, real_t p_delay) {
// If we are currently updating, call this function again later
if (pending_update != 0) {
_add_pending_command("targeting_method", p_object, p_method, p_initial, p_initial_method, p_final_val, p_duration, p_trans_type, p_ease_type, p_delay);
- return true;
+ return;
}
- // Convert final INT values to REAL as they are better for interpolation
- if (p_final_val.get_type() == Variant::INT) p_final_val = p_final_val.operator real_t();
+ // Convert final INT values to FLOAT as they are better for interpolation
+ if (p_final_val.get_type() == Variant::INT) {
+ p_final_val = p_final_val.operator real_t();
+ }
// Make sure the given objects are valid
- ERR_FAIL_COND_V(p_object == NULL, false);
- ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_object), false);
- ERR_FAIL_COND_V(p_initial == NULL, false);
- ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_initial), false);
+ ERR_FAIL_COND(p_object == nullptr);
+ ERR_FAIL_COND(p_initial == nullptr);
// No negative durations
- ERR_FAIL_COND_V(p_duration < 0, false);
+ ERR_FAIL_COND(p_duration < 0);
// Ensure transition and easing types are valid
- ERR_FAIL_COND_V(p_trans_type < 0 || p_trans_type >= TRANS_COUNT, false);
- ERR_FAIL_COND_V(p_ease_type < 0 || p_ease_type >= EASE_COUNT, false);
+ ERR_FAIL_COND(p_trans_type < 0 || p_trans_type >= TRANS_COUNT);
+ ERR_FAIL_COND(p_ease_type < 0 || p_ease_type >= EASE_COUNT);
// No negative delays
- ERR_FAIL_COND_V(p_delay < 0, false);
+ ERR_FAIL_COND(p_delay < 0);
// Make sure both objects have the given method
- ERR_FAIL_COND_V_MSG(!p_object->has_method(p_method), false, "Object has no method named: " + p_method + ".");
- ERR_FAIL_COND_V_MSG(!p_initial->has_method(p_initial_method), false, "Initial Object has no method named: " + p_initial_method + ".");
+ ERR_FAIL_COND_MSG(!p_object->has_method(p_method), "Object has no method named: " + p_method + ".");
+ ERR_FAIL_COND_MSG(!p_initial->has_method(p_initial_method), "Initial Object has no method named: " + p_initial_method + ".");
// Call the method to get the initial value
- Variant::CallError error;
- Variant initial_val = p_initial->call(p_initial_method, NULL, 0, error);
- ERR_FAIL_COND_V(error.error != Variant::CallError::CALL_OK, false);
+ Callable::CallError error;
+ Variant initial_val = p_initial->call(p_initial_method, nullptr, 0, error);
+ ERR_FAIL_COND(error.error != Callable::CallError::CALL_OK);
- // Convert initial INT values to REAL as they aer better for interpolation
- if (initial_val.get_type() == Variant::INT) initial_val = initial_val.operator real_t();
- ERR_FAIL_COND_V(initial_val.get_type() != p_final_val.get_type(), false);
+ // Convert initial INT values to FLOAT as they aer better for interpolation
+ if (initial_val.get_type() == Variant::INT) {
+ initial_val = initial_val.operator real_t();
+ }
+ ERR_FAIL_COND(initial_val.get_type() != p_final_val.get_type());
// Build the new InterpolateData object
InterpolateData data;
@@ -1703,12 +1782,12 @@ bool Tween::targeting_method(Object *p_object, StringName p_method, Object *p_in
data.delay = p_delay;
// Ensure there is a valid delta
- if (!_calc_delta_val(data.initial_val, data.final_val, data.delta_val))
- return false;
+ if (!_calc_delta_val(data.initial_val, data.final_val, data.delta_val)) {
+ return;
+ }
// Add the interpolation
_push_interpolate_data(data);
- return true;
}
Tween::Tween() {
diff --git a/scene/animation/tween.h b/scene/animation/tween.h
index f1218cd698..668870c526 100644
--- a/scene/animation/tween.h
+++ b/scene/animation/tween.h
@@ -34,7 +34,6 @@
#include "scene/main/node.h"
class Tween : public Node {
-
GDCLASS(Tween, Node);
public:
@@ -142,7 +141,7 @@ private:
void _tween_process(float p_delta);
void _remove_by_uid(int uid);
void _push_interpolate_data(InterpolateData &p_data);
- bool _build_interpolation(InterpolateType p_interpolation_type, Object *p_object, NodePath *p_property, StringName *p_method, Variant p_initial_val, Variant p_final_val, real_t p_duration, TransitionType p_trans_type, EaseType p_ease_type, real_t p_delay);
+ void _build_interpolation(InterpolateType p_interpolation_type, Object *p_object, NodePath *p_property, StringName *p_method, Variant p_initial_val, Variant p_final_val, real_t p_duration, TransitionType p_trans_type, EaseType p_ease_type, real_t p_delay);
protected:
bool _set(const StringName &p_name, const Variant &p_value);
@@ -165,28 +164,28 @@ public:
void set_speed_scale(float p_speed);
float get_speed_scale() const;
- bool start();
- bool reset(Object *p_object, StringName p_key);
- bool reset_all();
- bool stop(Object *p_object, StringName p_key);
- bool stop_all();
- bool resume(Object *p_object, StringName p_key);
- bool resume_all();
- bool remove(Object *p_object, StringName p_key);
- bool remove_all();
-
- bool seek(real_t p_time);
+ void start();
+ void reset(Object *p_object, StringName p_key);
+ void reset_all();
+ void stop(Object *p_object, StringName p_key);
+ void stop_all();
+ void resume(Object *p_object, StringName p_key);
+ void resume_all();
+ void remove(Object *p_object, StringName p_key);
+ void remove_all();
+
+ void seek(real_t p_time);
real_t tell() const;
real_t get_runtime() const;
- bool interpolate_property(Object *p_object, NodePath p_property, Variant p_initial_val, Variant p_final_val, real_t p_duration, TransitionType p_trans_type = TRANS_LINEAR, EaseType p_ease_type = EASE_IN_OUT, real_t p_delay = 0);
- bool interpolate_method(Object *p_object, StringName p_method, Variant p_initial_val, Variant p_final_val, real_t p_duration, TransitionType p_trans_type = TRANS_LINEAR, EaseType p_ease_type = EASE_IN_OUT, real_t p_delay = 0);
- bool interpolate_callback(Object *p_object, real_t p_duration, String p_callback, VARIANT_ARG_DECLARE);
- bool interpolate_deferred_callback(Object *p_object, real_t p_duration, String p_callback, VARIANT_ARG_DECLARE);
- bool follow_property(Object *p_object, NodePath p_property, Variant p_initial_val, Object *p_target, NodePath p_target_property, real_t p_duration, TransitionType p_trans_type = TRANS_LINEAR, EaseType p_ease_type = EASE_IN_OUT, real_t p_delay = 0);
- bool follow_method(Object *p_object, StringName p_method, Variant p_initial_val, Object *p_target, StringName p_target_method, real_t p_duration, TransitionType p_trans_type = TRANS_LINEAR, EaseType p_ease_type = EASE_IN_OUT, real_t p_delay = 0);
- bool targeting_property(Object *p_object, NodePath p_property, Object *p_initial, NodePath p_initial_property, Variant p_final_val, real_t p_duration, TransitionType p_trans_type = TRANS_LINEAR, EaseType p_ease_type = EASE_IN_OUT, real_t p_delay = 0);
- bool targeting_method(Object *p_object, StringName p_method, Object *p_initial, StringName p_initial_method, Variant p_final_val, real_t p_duration, TransitionType p_trans_type = TRANS_LINEAR, EaseType p_ease_type = EASE_IN_OUT, real_t p_delay = 0);
+ void interpolate_property(Object *p_object, NodePath p_property, Variant p_initial_val, Variant p_final_val, real_t p_duration, TransitionType p_trans_type = TRANS_LINEAR, EaseType p_ease_type = EASE_IN_OUT, real_t p_delay = 0);
+ void interpolate_method(Object *p_object, StringName p_method, Variant p_initial_val, Variant p_final_val, real_t p_duration, TransitionType p_trans_type = TRANS_LINEAR, EaseType p_ease_type = EASE_IN_OUT, real_t p_delay = 0);
+ void interpolate_callback(Object *p_object, real_t p_duration, String p_callback, VARIANT_ARG_DECLARE);
+ void interpolate_deferred_callback(Object *p_object, real_t p_duration, String p_callback, VARIANT_ARG_DECLARE);
+ void follow_property(Object *p_object, NodePath p_property, Variant p_initial_val, Object *p_target, NodePath p_target_property, real_t p_duration, TransitionType p_trans_type = TRANS_LINEAR, EaseType p_ease_type = EASE_IN_OUT, real_t p_delay = 0);
+ void follow_method(Object *p_object, StringName p_method, Variant p_initial_val, Object *p_target, StringName p_target_method, real_t p_duration, TransitionType p_trans_type = TRANS_LINEAR, EaseType p_ease_type = EASE_IN_OUT, real_t p_delay = 0);
+ void targeting_property(Object *p_object, NodePath p_property, Object *p_initial, NodePath p_initial_property, Variant p_final_val, real_t p_duration, TransitionType p_trans_type = TRANS_LINEAR, EaseType p_ease_type = EASE_IN_OUT, real_t p_delay = 0);
+ void targeting_method(Object *p_object, StringName p_method, Object *p_initial, StringName p_initial_method, Variant p_final_val, real_t p_duration, TransitionType p_trans_type = TRANS_LINEAR, EaseType p_ease_type = EASE_IN_OUT, real_t p_delay = 0);
Tween();
~Tween();