Merge pull request #75759 from TokageItLab/reimplement-grouped-statemachine

Rework for nested `AnimationNodeStateMachine`
This commit is contained in:
Rémi Verschelde
2023-04-24 16:44:21 +02:00
15 changed files with 1273 additions and 1158 deletions
+9 -9
View File
@@ -46,7 +46,7 @@ Variant AnimationNodeBlendSpace1D::get_parameter_default_value(const StringName
}
}
Ref<AnimationNode> AnimationNodeBlendSpace1D::get_child_by_name(const StringName &p_name) {
Ref<AnimationNode> AnimationNodeBlendSpace1D::get_child_by_name(const StringName &p_name) const {
return get_blend_point_node(p_name.operator String().to_int());
}
@@ -272,14 +272,14 @@ void AnimationNodeBlendSpace1D::_add_blend_point(int p_index, const Ref<Animatio
}
}
double AnimationNodeBlendSpace1D::process(double p_time, bool p_seek, bool p_is_external_seeking) {
double AnimationNodeBlendSpace1D::_process(double p_time, bool p_seek, bool p_is_external_seeking, bool p_test_only) {
if (blend_points_used == 0) {
return 0.0;
}
if (blend_points_used == 1) {
// only one point available, just play that animation
return blend_node(blend_points[0].name, blend_points[0].node, p_time, p_seek, p_is_external_seeking, 1.0, FILTER_IGNORE, true);
return blend_node(blend_points[0].name, blend_points[0].node, p_time, p_seek, p_is_external_seeking, 1.0, FILTER_IGNORE, true, p_test_only);
}
double blend_pos = get_parameter(blend_position);
@@ -341,10 +341,10 @@ double AnimationNodeBlendSpace1D::process(double p_time, bool p_seek, bool p_is_
for (int i = 0; i < blend_points_used; i++) {
if (i == point_lower || i == point_higher) {
double remaining = blend_node(blend_points[i].name, blend_points[i].node, p_time, p_seek, p_is_external_seeking, weights[i], FILTER_IGNORE, true);
double remaining = blend_node(blend_points[i].name, blend_points[i].node, p_time, p_seek, p_is_external_seeking, weights[i], FILTER_IGNORE, true, p_test_only);
max_time_remaining = MAX(max_time_remaining, remaining);
} else if (sync) {
blend_node(blend_points[i].name, blend_points[i].node, p_time, p_seek, p_is_external_seeking, 0, FILTER_IGNORE, true);
blend_node(blend_points[i].name, blend_points[i].node, p_time, p_seek, p_is_external_seeking, 0, FILTER_IGNORE, true, p_test_only);
}
}
} else {
@@ -369,22 +369,22 @@ double AnimationNodeBlendSpace1D::process(double p_time, bool p_seek, bool p_is_
na_n->set_backward(na_c->is_backward());
}
//see how much animation remains
from = cur_length_internal - blend_node(blend_points[cur_closest].name, blend_points[cur_closest].node, p_time, false, p_is_external_seeking, 0.0, FILTER_IGNORE, true);
from = cur_length_internal - blend_node(blend_points[cur_closest].name, blend_points[cur_closest].node, p_time, false, p_is_external_seeking, 0.0, FILTER_IGNORE, true, p_test_only);
}
max_time_remaining = blend_node(blend_points[new_closest].name, blend_points[new_closest].node, from, true, p_is_external_seeking, 1.0, FILTER_IGNORE, true);
max_time_remaining = blend_node(blend_points[new_closest].name, blend_points[new_closest].node, from, true, p_is_external_seeking, 1.0, FILTER_IGNORE, true, p_test_only);
cur_length_internal = from + max_time_remaining;
cur_closest = new_closest;
} else {
max_time_remaining = blend_node(blend_points[cur_closest].name, blend_points[cur_closest].node, p_time, p_seek, p_is_external_seeking, 1.0, FILTER_IGNORE, true);
max_time_remaining = blend_node(blend_points[cur_closest].name, blend_points[cur_closest].node, p_time, p_seek, p_is_external_seeking, 1.0, FILTER_IGNORE, true, p_test_only);
}
if (sync) {
for (int i = 0; i < blend_points_used; i++) {
if (i != cur_closest) {
blend_node(blend_points[i].name, blend_points[i].node, p_time, p_seek, p_is_external_seeking, 0, FILTER_IGNORE, true);
blend_node(blend_points[i].name, blend_points[i].node, p_time, p_seek, p_is_external_seeking, 0, FILTER_IGNORE, true, p_test_only);
}
}
}
+2 -2
View File
@@ -114,10 +114,10 @@ public:
void set_use_sync(bool p_sync);
bool is_using_sync() const;
double process(double p_time, bool p_seek, bool p_is_external_seeking) override;
virtual double _process(double p_time, bool p_seek, bool p_is_external_seeking, bool p_test_only = false) override;
String get_caption() const override;
Ref<AnimationNode> get_child_by_name(const StringName &p_name) override;
Ref<AnimationNode> get_child_by_name(const StringName &p_name) const override;
AnimationNodeBlendSpace1D();
~AnimationNodeBlendSpace1D();
+8 -8
View File
@@ -442,7 +442,7 @@ void AnimationNodeBlendSpace2D::_blend_triangle(const Vector2 &p_pos, const Vect
r_weights[2] = w;
}
double AnimationNodeBlendSpace2D::process(double p_time, bool p_seek, bool p_is_external_seeking) {
double AnimationNodeBlendSpace2D::_process(double p_time, bool p_seek, bool p_is_external_seeking, bool p_test_only) {
_update_triangles();
Vector2 blend_pos = get_parameter(blend_position);
@@ -512,7 +512,7 @@ double AnimationNodeBlendSpace2D::process(double p_time, bool p_seek, bool p_is_
for (int j = 0; j < 3; j++) {
if (i == triangle_points[j]) {
//blend with the given weight
double t = blend_node(blend_points[i].name, blend_points[i].node, p_time, p_seek, p_is_external_seeking, blend_weights[j], FILTER_IGNORE, true);
double t = blend_node(blend_points[i].name, blend_points[i].node, p_time, p_seek, p_is_external_seeking, blend_weights[j], FILTER_IGNORE, true, p_test_only);
if (first || t < mind) {
mind = t;
first = false;
@@ -523,7 +523,7 @@ double AnimationNodeBlendSpace2D::process(double p_time, bool p_seek, bool p_is_
}
if (sync && !found) {
blend_node(blend_points[i].name, blend_points[i].node, p_time, p_seek, p_is_external_seeking, 0, FILTER_IGNORE, true);
blend_node(blend_points[i].name, blend_points[i].node, p_time, p_seek, p_is_external_seeking, 0, FILTER_IGNORE, true, p_test_only);
}
}
} else {
@@ -548,22 +548,22 @@ double AnimationNodeBlendSpace2D::process(double p_time, bool p_seek, bool p_is_
na_n->set_backward(na_c->is_backward());
}
//see how much animation remains
from = cur_length_internal - blend_node(blend_points[cur_closest].name, blend_points[cur_closest].node, p_time, false, p_is_external_seeking, 0.0, FILTER_IGNORE, true);
from = cur_length_internal - blend_node(blend_points[cur_closest].name, blend_points[cur_closest].node, p_time, false, p_is_external_seeking, 0.0, FILTER_IGNORE, true, p_test_only);
}
mind = blend_node(blend_points[new_closest].name, blend_points[new_closest].node, from, true, p_is_external_seeking, 1.0, FILTER_IGNORE, true);
mind = blend_node(blend_points[new_closest].name, blend_points[new_closest].node, from, true, p_is_external_seeking, 1.0, FILTER_IGNORE, true, p_test_only);
cur_length_internal = from + mind;
cur_closest = new_closest;
} else {
mind = blend_node(blend_points[cur_closest].name, blend_points[cur_closest].node, p_time, p_seek, p_is_external_seeking, 1.0, FILTER_IGNORE, true);
mind = blend_node(blend_points[cur_closest].name, blend_points[cur_closest].node, p_time, p_seek, p_is_external_seeking, 1.0, FILTER_IGNORE, true, p_test_only);
}
if (sync) {
for (int i = 0; i < blend_points_used; i++) {
if (i != cur_closest) {
blend_node(blend_points[i].name, blend_points[i].node, p_time, p_seek, p_is_external_seeking, 0, FILTER_IGNORE, true);
blend_node(blend_points[i].name, blend_points[i].node, p_time, p_seek, p_is_external_seeking, 0, FILTER_IGNORE, true, p_test_only);
}
}
}
@@ -604,7 +604,7 @@ bool AnimationNodeBlendSpace2D::get_auto_triangles() const {
return auto_triangles;
}
Ref<AnimationNode> AnimationNodeBlendSpace2D::get_child_by_name(const StringName &p_name) {
Ref<AnimationNode> AnimationNodeBlendSpace2D::get_child_by_name(const StringName &p_name) const {
return get_blend_point_node(p_name.operator String().to_int());
}
+2 -2
View File
@@ -129,7 +129,7 @@ public:
void set_y_label(const String &p_label);
String get_y_label() const;
virtual double process(double p_time, bool p_seek, bool p_is_external_seeking) override;
virtual double _process(double p_time, bool p_seek, bool p_is_external_seeking, bool p_test_only = false) override;
virtual String get_caption() const override;
Vector2 get_closest_point(const Vector2 &p_point);
@@ -143,7 +143,7 @@ public:
void set_use_sync(bool p_sync);
bool is_using_sync() const;
virtual Ref<AnimationNode> get_child_by_name(const StringName &p_name) override;
virtual Ref<AnimationNode> get_child_by_name(const StringName &p_name) const override;
AnimationNodeBlendSpace2D();
~AnimationNodeBlendSpace2D();
+50 -45
View File
@@ -64,7 +64,7 @@ void AnimationNodeAnimation::_validate_property(PropertyInfo &p_property) const
}
}
double AnimationNodeAnimation::process(double p_time, bool p_seek, bool p_is_external_seeking) {
double AnimationNodeAnimation::_process(double p_time, bool p_seek, bool p_is_external_seeking, bool p_test_only) {
AnimationPlayer *ap = state->player;
ERR_FAIL_COND_V(!ap, 0);
@@ -99,6 +99,7 @@ double AnimationNodeAnimation::process(double p_time, bool p_seek, bool p_is_ext
step = p_time;
}
bool is_looping = false;
if (anim->get_loop_mode() == Animation::LOOP_PINGPONG) {
if (!Math::is_zero_approx(anim_size)) {
if (prev_time >= 0 && cur_time < 0) {
@@ -111,6 +112,7 @@ double AnimationNodeAnimation::process(double p_time, bool p_seek, bool p_is_ext
}
cur_time = Math::pingpong(cur_time, anim_size);
}
is_looping = true;
} else if (anim->get_loop_mode() == Animation::LOOP_LINEAR) {
if (!Math::is_zero_approx(anim_size)) {
if (prev_time >= 0 && cur_time < 0) {
@@ -122,6 +124,7 @@ double AnimationNodeAnimation::process(double p_time, bool p_seek, bool p_is_ext
cur_time = Math::fposmod(cur_time, anim_size);
}
backward = false;
is_looping = true;
} else {
if (cur_time < 0) {
step += cur_time;
@@ -159,14 +162,16 @@ double AnimationNodeAnimation::process(double p_time, bool p_seek, bool p_is_ext
}
}
if (play_mode == PLAY_MODE_FORWARD) {
blend_animation(animation, cur_time, step, p_seek, p_is_external_seeking, 1.0, looped_flag);
} else {
blend_animation(animation, anim_size - cur_time, -step, p_seek, p_is_external_seeking, 1.0, looped_flag);
if (!p_test_only) {
if (play_mode == PLAY_MODE_FORWARD) {
blend_animation(animation, cur_time, step, p_seek, p_is_external_seeking, 1.0, looped_flag);
} else {
blend_animation(animation, anim_size - cur_time, -step, p_seek, p_is_external_seeking, 1.0, looped_flag);
}
}
set_parameter(time, cur_time);
return anim_size - cur_time;
return is_looping ? HUGE_LENGTH : anim_size - cur_time;
}
String AnimationNodeAnimation::get_caption() const {
@@ -311,7 +316,7 @@ bool AnimationNodeOneShot::has_filter() const {
return true;
}
double AnimationNodeOneShot::process(double p_time, bool p_seek, bool p_is_external_seeking) {
double AnimationNodeOneShot::_process(double p_time, bool p_seek, bool p_is_external_seeking, bool p_test_only) {
OneShotRequest cur_request = static_cast<OneShotRequest>((int)get_parameter(request));
bool cur_active = get_parameter(active);
double cur_time = get_parameter(time);
@@ -324,7 +329,7 @@ double AnimationNodeOneShot::process(double p_time, bool p_seek, bool p_is_exter
if (cur_request == ONE_SHOT_REQUEST_ABORT) {
set_parameter(active, false);
set_parameter(time_to_restart, -1);
return blend_input(0, p_time, p_seek, p_is_external_seeking, 1.0, FILTER_IGNORE, sync);
return blend_input(0, p_time, p_seek, p_is_external_seeking, 1.0, FILTER_IGNORE, sync, p_test_only);
} else if (!do_start && !cur_active) {
if (cur_time_to_restart >= 0.0 && !p_seek) {
cur_time_to_restart -= p_time;
@@ -334,7 +339,7 @@ double AnimationNodeOneShot::process(double p_time, bool p_seek, bool p_is_exter
set_parameter(time_to_restart, cur_time_to_restart);
}
if (!do_start) {
return blend_input(0, p_time, p_seek, p_is_external_seeking, 1.0, FILTER_IGNORE, sync);
return blend_input(0, p_time, p_seek, p_is_external_seeking, 1.0, FILTER_IGNORE, sync, p_test_only);
}
}
@@ -370,11 +375,11 @@ double AnimationNodeOneShot::process(double p_time, bool p_seek, bool p_is_exter
double main_rem = 0.0;
if (mix == MIX_MODE_ADD) {
main_rem = blend_input(0, p_time, p_seek, p_is_external_seeking, 1.0, FILTER_IGNORE, sync);
main_rem = blend_input(0, p_time, p_seek, p_is_external_seeking, 1.0, FILTER_IGNORE, sync, p_test_only);
} else {
main_rem = blend_input(0, p_time, use_blend && p_seek, p_is_external_seeking, 1.0 - blend, FILTER_BLEND, sync); // Unlike below, processing this edge is a corner case.
main_rem = blend_input(0, p_time, use_blend && p_seek, p_is_external_seeking, 1.0 - blend, FILTER_BLEND, sync, p_test_only); // Unlike below, processing this edge is a corner case.
}
double os_rem = blend_input(1, os_seek ? cur_time : p_time, os_seek, p_is_external_seeking, Math::is_zero_approx(blend) ? CMP_EPSILON : blend, FILTER_PASS, true); // Blend values must be more than CMP_EPSILON to process discrete keys in edge.
double os_rem = blend_input(1, os_seek ? cur_time : p_time, os_seek, p_is_external_seeking, Math::is_zero_approx(blend) ? CMP_EPSILON : blend, FILTER_PASS, true, p_test_only); // Blend values must be more than CMP_EPSILON to process discrete keys in edge.
if (do_start) {
cur_remaining = os_rem;
@@ -459,10 +464,10 @@ bool AnimationNodeAdd2::has_filter() const {
return true;
}
double AnimationNodeAdd2::process(double p_time, bool p_seek, bool p_is_external_seeking) {
double AnimationNodeAdd2::_process(double p_time, bool p_seek, bool p_is_external_seeking, bool p_test_only) {
double amount = get_parameter(add_amount);
double rem0 = blend_input(0, p_time, p_seek, p_is_external_seeking, 1.0, FILTER_IGNORE, sync);
blend_input(1, p_time, p_seek, p_is_external_seeking, amount, FILTER_PASS, sync);
double rem0 = blend_input(0, p_time, p_seek, p_is_external_seeking, 1.0, FILTER_IGNORE, sync, p_test_only);
blend_input(1, p_time, p_seek, p_is_external_seeking, amount, FILTER_PASS, sync, p_test_only);
return rem0;
}
@@ -493,11 +498,11 @@ bool AnimationNodeAdd3::has_filter() const {
return true;
}
double AnimationNodeAdd3::process(double p_time, bool p_seek, bool p_is_external_seeking) {
double AnimationNodeAdd3::_process(double p_time, bool p_seek, bool p_is_external_seeking, bool p_test_only) {
double amount = get_parameter(add_amount);
blend_input(0, p_time, p_seek, p_is_external_seeking, MAX(0, -amount), FILTER_PASS, sync);
double rem0 = blend_input(1, p_time, p_seek, p_is_external_seeking, 1.0, FILTER_IGNORE, sync);
blend_input(2, p_time, p_seek, p_is_external_seeking, MAX(0, amount), FILTER_PASS, sync);
blend_input(0, p_time, p_seek, p_is_external_seeking, MAX(0, -amount), FILTER_PASS, sync, p_test_only);
double rem0 = blend_input(1, p_time, p_seek, p_is_external_seeking, 1.0, FILTER_IGNORE, sync, p_test_only);
blend_input(2, p_time, p_seek, p_is_external_seeking, MAX(0, amount), FILTER_PASS, sync, p_test_only);
return rem0;
}
@@ -525,11 +530,11 @@ String AnimationNodeBlend2::get_caption() const {
return "Blend2";
}
double AnimationNodeBlend2::process(double p_time, bool p_seek, bool p_is_external_seeking) {
double AnimationNodeBlend2::_process(double p_time, bool p_seek, bool p_is_external_seeking, bool p_test_only) {
double amount = get_parameter(blend_amount);
double rem0 = blend_input(0, p_time, p_seek, p_is_external_seeking, 1.0 - amount, FILTER_BLEND, sync);
double rem1 = blend_input(1, p_time, p_seek, p_is_external_seeking, amount, FILTER_PASS, sync);
double rem0 = blend_input(0, p_time, p_seek, p_is_external_seeking, 1.0 - amount, FILTER_BLEND, sync, p_test_only);
double rem1 = blend_input(1, p_time, p_seek, p_is_external_seeking, amount, FILTER_PASS, sync, p_test_only);
return amount > 0.5 ? rem1 : rem0; // Hacky but good enough.
}
@@ -560,11 +565,11 @@ String AnimationNodeBlend3::get_caption() const {
return "Blend3";
}
double AnimationNodeBlend3::process(double p_time, bool p_seek, bool p_is_external_seeking) {
double AnimationNodeBlend3::_process(double p_time, bool p_seek, bool p_is_external_seeking, bool p_test_only) {
double amount = get_parameter(blend_amount);
double rem0 = blend_input(0, p_time, p_seek, p_is_external_seeking, MAX(0, -amount), FILTER_IGNORE, sync);
double rem1 = blend_input(1, p_time, p_seek, p_is_external_seeking, 1.0 - ABS(amount), FILTER_IGNORE, sync);
double rem2 = blend_input(2, p_time, p_seek, p_is_external_seeking, MAX(0, amount), FILTER_IGNORE, sync);
double rem0 = blend_input(0, p_time, p_seek, p_is_external_seeking, MAX(0, -amount), FILTER_IGNORE, sync, p_test_only);
double rem1 = blend_input(1, p_time, p_seek, p_is_external_seeking, 1.0 - ABS(amount), FILTER_IGNORE, sync, p_test_only);
double rem2 = blend_input(2, p_time, p_seek, p_is_external_seeking, MAX(0, amount), FILTER_IGNORE, sync, p_test_only);
return amount > 0.5 ? rem2 : (amount < -0.5 ? rem0 : rem1); // Hacky but good enough.
}
@@ -592,12 +597,12 @@ String AnimationNodeTimeScale::get_caption() const {
return "TimeScale";
}
double AnimationNodeTimeScale::process(double p_time, bool p_seek, bool p_is_external_seeking) {
double AnimationNodeTimeScale::_process(double p_time, bool p_seek, bool p_is_external_seeking, bool p_test_only) {
double cur_scale = get_parameter(scale);
if (p_seek) {
return blend_input(0, p_time, true, p_is_external_seeking, 1.0, FILTER_IGNORE, true);
return blend_input(0, p_time, true, p_is_external_seeking, 1.0, FILTER_IGNORE, true, p_test_only);
} else {
return blend_input(0, p_time * cur_scale, false, p_is_external_seeking, 1.0, FILTER_IGNORE, true);
return blend_input(0, p_time * cur_scale, false, p_is_external_seeking, 1.0, FILTER_IGNORE, true, p_test_only);
}
}
@@ -622,16 +627,16 @@ String AnimationNodeTimeSeek::get_caption() const {
return "TimeSeek";
}
double AnimationNodeTimeSeek::process(double p_time, bool p_seek, bool p_is_external_seeking) {
double AnimationNodeTimeSeek::_process(double p_time, bool p_seek, bool p_is_external_seeking, bool p_test_only) {
double cur_seek_pos = get_parameter(seek_pos_request);
if (p_seek) {
return blend_input(0, p_time, true, p_is_external_seeking, 1.0, FILTER_IGNORE, true);
return blend_input(0, p_time, true, p_is_external_seeking, 1.0, FILTER_IGNORE, true, p_test_only);
} else if (cur_seek_pos >= 0) {
double ret = blend_input(0, cur_seek_pos, true, true, 1.0, FILTER_IGNORE, true);
double ret = blend_input(0, cur_seek_pos, true, true, 1.0, FILTER_IGNORE, true, p_test_only);
set_parameter(seek_pos_request, -1.0); // Reset.
return ret;
} else {
return blend_input(0, p_time, false, p_is_external_seeking, 1.0, FILTER_IGNORE, true);
return blend_input(0, p_time, false, p_is_external_seeking, 1.0, FILTER_IGNORE, true, p_test_only);
}
}
@@ -815,7 +820,7 @@ bool AnimationNodeTransition::is_allow_transition_to_self() const {
return allow_transition_to_self;
}
double AnimationNodeTransition::process(double p_time, bool p_seek, bool p_is_external_seeking) {
double AnimationNodeTransition::_process(double p_time, bool p_seek, bool p_is_external_seeking, bool p_test_only) {
String cur_transition_request = get_parameter(transition_request);
int cur_current_index = get_parameter(current_index);
int cur_prev_index = get_parameter(prev_index);
@@ -881,7 +886,7 @@ double AnimationNodeTransition::process(double p_time, bool p_seek, bool p_is_ex
// Special case for restart.
if (restart) {
set_parameter(time, 0);
return blend_input(cur_current_index, 0, true, p_is_external_seeking, 1.0, FILTER_IGNORE, true);
return blend_input(cur_current_index, 0, true, p_is_external_seeking, 1.0, FILTER_IGNORE, true, p_test_only);
}
if (switched) {
@@ -898,14 +903,14 @@ double AnimationNodeTransition::process(double p_time, bool p_seek, bool p_is_ex
if (sync) {
for (int i = 0; i < get_input_count(); i++) {
if (i != cur_current_index && i != cur_prev_index) {
blend_input(i, p_time, p_seek, p_is_external_seeking, 0, FILTER_IGNORE, true);
blend_input(i, p_time, p_seek, p_is_external_seeking, 0, FILTER_IGNORE, true, p_test_only);
}
}
}
if (cur_prev_index < 0) { // Process current animation, check for transition.
rem = blend_input(cur_current_index, p_time, p_seek, p_is_external_seeking, 1.0, FILTER_IGNORE, true);
rem = blend_input(cur_current_index, p_time, p_seek, p_is_external_seeking, 1.0, FILTER_IGNORE, true, p_test_only);
if (p_seek) {
cur_time = p_time;
@@ -935,12 +940,12 @@ double AnimationNodeTransition::process(double p_time, bool p_seek, bool p_is_ex
// Blend values must be more than CMP_EPSILON to process discrete keys in edge.
if (input_data[cur_current_index].reset && !p_seek && switched) { // Just switched, seek to start of current.
rem = blend_input(cur_current_index, 0, true, p_is_external_seeking, blend_inv, FILTER_IGNORE, true);
rem = blend_input(cur_current_index, 0, true, p_is_external_seeking, blend_inv, FILTER_IGNORE, true, p_test_only);
} else {
rem = blend_input(cur_current_index, p_time, p_seek, p_is_external_seeking, blend_inv, FILTER_IGNORE, true);
rem = blend_input(cur_current_index, p_time, p_seek, p_is_external_seeking, blend_inv, FILTER_IGNORE, true, p_test_only);
}
blend_input(cur_prev_index, p_time, use_blend && p_seek, p_is_external_seeking, blend, FILTER_IGNORE, true);
blend_input(cur_prev_index, p_time, use_blend && p_seek, p_is_external_seeking, blend, FILTER_IGNORE, true, p_test_only);
if (p_seek) {
cur_time = p_time;
} else {
@@ -999,8 +1004,8 @@ String AnimationNodeOutput::get_caption() const {
return "Output";
}
double AnimationNodeOutput::process(double p_time, bool p_seek, bool p_is_external_seeking) {
return blend_input(0, p_time, p_seek, p_is_external_seeking, 1.0, FILTER_IGNORE, true);
double AnimationNodeOutput::_process(double p_time, bool p_seek, bool p_is_external_seeking, bool p_test_only) {
return blend_input(0, p_time, p_seek, p_is_external_seeking, 1.0, FILTER_IGNORE, true, p_test_only);
}
AnimationNodeOutput::AnimationNodeOutput() {
@@ -1218,9 +1223,9 @@ String AnimationNodeBlendTree::get_caption() const {
return "BlendTree";
}
double AnimationNodeBlendTree::process(double p_time, bool p_seek, bool p_is_external_seeking) {
double AnimationNodeBlendTree::_process(double p_time, bool p_seek, bool p_is_external_seeking, bool p_test_only) {
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, p_is_external_seeking, 1.0, FILTER_IGNORE, true);
return _blend_node("output", nodes[SceneStringNames::get_singleton()->output].connections, this, output, p_time, p_seek, p_is_external_seeking, 1.0, FILTER_IGNORE, true, nullptr, p_test_only);
}
void AnimationNodeBlendTree::get_node_list(List<StringName> *r_list) {
@@ -1237,7 +1242,7 @@ Vector2 AnimationNodeBlendTree::get_graph_offset() const {
return graph_offset;
}
Ref<AnimationNode> AnimationNodeBlendTree::get_child_by_name(const StringName &p_name) {
Ref<AnimationNode> AnimationNodeBlendTree::get_child_by_name(const StringName &p_name) const {
return get_node(p_name);
}
+12 -12
View File
@@ -53,7 +53,7 @@ public:
static Vector<String> (*get_editable_animation_list)();
virtual String get_caption() const override;
virtual double process(double p_time, bool p_seek, bool p_is_external_seeking) override;
virtual double _process(double p_time, bool p_seek, bool p_is_external_seeking, bool p_test_only = false) override;
void set_animation(const StringName &p_name);
StringName get_animation() const;
@@ -150,7 +150,7 @@ public:
MixMode get_mix_mode() const;
virtual bool has_filter() const override;
virtual double process(double p_time, bool p_seek, bool p_is_external_seeking) override;
virtual double _process(double p_time, bool p_seek, bool p_is_external_seeking, bool p_test_only = false) override;
AnimationNodeOneShot();
};
@@ -173,7 +173,7 @@ public:
virtual String get_caption() const override;
virtual bool has_filter() const override;
virtual double process(double p_time, bool p_seek, bool p_is_external_seeking) override;
virtual double _process(double p_time, bool p_seek, bool p_is_external_seeking, bool p_test_only = false) override;
AnimationNodeAdd2();
};
@@ -193,7 +193,7 @@ public:
virtual String get_caption() const override;
virtual bool has_filter() const override;
virtual double process(double p_time, bool p_seek, bool p_is_external_seeking) override;
virtual double _process(double p_time, bool p_seek, bool p_is_external_seeking, bool p_test_only = false) override;
AnimationNodeAdd3();
};
@@ -211,7 +211,7 @@ public:
virtual Variant get_parameter_default_value(const StringName &p_parameter) const override;
virtual String get_caption() const override;
virtual double process(double p_time, bool p_seek, bool p_is_external_seeking) override;
virtual double _process(double p_time, bool p_seek, bool p_is_external_seeking, bool p_test_only = false) override;
virtual bool has_filter() const override;
AnimationNodeBlend2();
@@ -231,7 +231,7 @@ public:
virtual String get_caption() const override;
double process(double p_time, bool p_seek, bool p_is_external_seeking) override;
virtual double _process(double p_time, bool p_seek, bool p_is_external_seeking, bool p_test_only = false) override;
AnimationNodeBlend3();
};
@@ -249,7 +249,7 @@ public:
virtual String get_caption() const override;
double process(double p_time, bool p_seek, bool p_is_external_seeking) override;
virtual double _process(double p_time, bool p_seek, bool p_is_external_seeking, bool p_test_only = false) override;
AnimationNodeTimeScale();
};
@@ -268,7 +268,7 @@ public:
virtual String get_caption() const override;
double process(double p_time, bool p_seek, bool p_is_external_seeking) override;
virtual double _process(double p_time, bool p_seek, bool p_is_external_seeking, bool p_test_only = false) override;
AnimationNodeTimeSeek();
};
@@ -332,7 +332,7 @@ public:
void set_allow_transition_to_self(bool p_enable);
bool is_allow_transition_to_self() const;
double process(double p_time, bool p_seek, bool p_is_external_seeking) override;
virtual double _process(double p_time, bool p_seek, bool p_is_external_seeking, bool p_test_only = false) override;
AnimationNodeTransition();
};
@@ -342,7 +342,7 @@ class AnimationNodeOutput : public AnimationNode {
public:
virtual String get_caption() const override;
virtual double process(double p_time, bool p_seek, bool p_is_external_seeking) override;
virtual double _process(double p_time, bool p_seek, bool p_is_external_seeking, bool p_test_only = false) override;
AnimationNodeOutput();
};
@@ -414,14 +414,14 @@ public:
void get_node_connections(List<NodeConnection> *r_connections) const;
virtual String get_caption() const override;
virtual double process(double p_time, bool p_seek, bool p_is_external_seeking) override;
virtual double _process(double p_time, bool p_seek, bool p_is_external_seeking, bool p_test_only = false) 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) override;
virtual Ref<AnimationNode> get_child_by_name(const StringName &p_name) const override;
AnimationNodeBlendTree();
~AnimationNodeBlendTree();
File diff suppressed because it is too large Load Diff
+152 -86
View File
@@ -100,88 +100,23 @@ public:
VARIANT_ENUM_CAST(AnimationNodeStateMachineTransition::SwitchMode)
VARIANT_ENUM_CAST(AnimationNodeStateMachineTransition::AdvanceMode)
class AnimationNodeStateMachine;
class AnimationNodeStateMachinePlayback : public Resource {
GDCLASS(AnimationNodeStateMachinePlayback, Resource);
friend class AnimationNodeStateMachine;
struct AStarCost {
float distance = 0.0;
StringName prev;
};
struct Transition {
StringName from;
StringName to;
StringName next;
};
double len_fade_from = 0.0;
double pos_fade_from = 0.0;
double len_current = 0.0;
double pos_current = 0.0;
bool end_loop = false;
StringName current;
Transition current_transition;
Ref<Curve> current_curve;
bool force_auto_advance = false;
StringName fading_from;
float fading_time = 0.0;
float fading_pos = 0.0;
Vector<StringName> path;
bool playing = false;
StringName start_request;
StringName travel_request;
bool reset_request = false;
bool reset_request_on_teleport = false;
bool next_request = false;
bool stop_request = false;
bool _travel(AnimationNodeStateMachine *p_state_machine, const StringName &p_travel);
void _start(const StringName &p_state);
double _process(AnimationNodeStateMachine *p_state_machine, double p_time, bool p_seek, bool p_is_external_seeking);
double process(AnimationNodeStateMachine *p_state_machine, double p_time, bool p_seek, bool p_is_external_seeking);
bool _check_advance_condition(const Ref<AnimationNodeStateMachine> p_state_machine, const Ref<AnimationNodeStateMachineTransition> p_transition) const;
protected:
static void _bind_methods();
public:
void travel(const StringName &p_state, bool p_reset_on_teleport = true);
void start(const StringName &p_state, bool p_reset = true);
void next();
void stop();
bool is_playing() const;
StringName get_current_node() const;
StringName get_fading_from_node() const;
Vector<StringName> get_travel_path() const;
float get_current_play_pos() const;
float get_current_length() const;
float get_fade_from_play_pos() const;
float get_fade_from_length() const;
float get_fading_time() const;
float get_fading_pos() const;
AnimationNodeStateMachinePlayback();
};
class AnimationNodeStateMachinePlayback;
class AnimationNodeStateMachine : public AnimationRootNode {
GDCLASS(AnimationNodeStateMachine, AnimationRootNode);
public:
enum StateMachineType {
STATE_MACHINE_TYPE_ROOT,
STATE_MACHINE_TYPE_NESTED,
STATE_MACHINE_TYPE_GROUPED,
};
private:
friend class AnimationNodeStateMachinePlayback;
StateMachineType state_machine_type = STATE_MACHINE_TYPE_ROOT;
struct State {
Ref<AnimationRootNode> node;
Vector2 position;
@@ -189,28 +124,24 @@ private:
HashMap<StringName, State> states;
bool allow_transition_to_self = false;
bool reset_ends = false;
struct Transition {
StringName from;
StringName to;
StringName local_from;
StringName local_to;
Ref<AnimationNodeStateMachineTransition> transition;
};
Vector<Transition> transitions;
StringName playback = "playback";
StringName state_machine_name;
AnimationNodeStateMachine *prev_state_machine = nullptr;
bool updating_transitions = false;
Vector2 graph_offset;
void _remove_transition(const Ref<AnimationNodeStateMachineTransition> p_transition);
void _rename_transitions(const StringName &p_name, const StringName &p_new_name);
bool _can_connect(const StringName &p_name, Vector<AnimationNodeStateMachine *> p_parents = Vector<AnimationNodeStateMachine *>());
StringName _get_shortest_path(const StringName &p_path) const;
bool _can_connect(const StringName &p_name);
protected:
static void _bind_methods();
@@ -218,6 +149,8 @@ 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 _validate_property(PropertyInfo &p_property) const;
bool _check_advance_condition(const Ref<AnimationNodeStateMachine> p_state_machine, const Ref<AnimationNodeStateMachineTransition> p_transition) const;
virtual void _tree_changed() override;
@@ -232,6 +165,7 @@ public:
virtual void get_parameter_list(List<PropertyInfo> *r_list) const override;
virtual Variant get_parameter_default_value(const StringName &p_parameter) const override;
virtual bool is_parameter_read_only(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);
@@ -248,32 +182,164 @@ public:
virtual void get_child_nodes(List<ChildNode> *r_child_nodes) override;
bool has_transition(const StringName &p_from, const StringName &p_to) const;
bool has_local_transition(const StringName &p_from, const StringName &p_to) const;
bool has_transition_from(const StringName &p_from) const;
bool has_transition_to(const StringName &p_to) const;
int find_transition(const StringName &p_from, const StringName &p_to) const;
Vector<int> find_transition_from(const StringName &p_from) const;
Vector<int> find_transition_to(const StringName &p_to) const;
void add_transition(const StringName &p_from, const StringName &p_to, const Ref<AnimationNodeStateMachineTransition> &p_transition);
Ref<AnimationNodeStateMachineTransition> get_transition(int p_transition) const;
StringName get_transition_from(int p_transition) const;
StringName get_transition_to(int p_transition) const;
int get_transition_count() const;
bool is_transition_across_group(int p_transition) const;
void remove_transition_by_index(const int p_transition);
void remove_transition(const StringName &p_from, const StringName &p_to);
void set_state_machine_type(StateMachineType p_state_machine_type);
StateMachineType get_state_machine_type() const;
void set_allow_transition_to_self(bool p_enable);
bool is_allow_transition_to_self() const;
bool can_edit_node(const StringName &p_name) const;
void set_reset_ends(bool p_enable);
bool are_ends_reset() const;
AnimationNodeStateMachine *get_prev_state_machine() const;
bool can_edit_node(const StringName &p_name) const;
void set_graph_offset(const Vector2 &p_offset);
Vector2 get_graph_offset() const;
virtual double process(double p_time, bool p_seek, bool p_is_external_seeking) override;
virtual double _process(double p_time, bool p_seek, bool p_is_external_seeking, bool p_test_only = false) override;
virtual String get_caption() const override;
virtual Ref<AnimationNode> get_child_by_name(const StringName &p_name) override;
virtual Ref<AnimationNode> get_child_by_name(const StringName &p_name) const override;
AnimationNodeStateMachine();
};
VARIANT_ENUM_CAST(AnimationNodeStateMachine::StateMachineType);
class AnimationNodeStateMachinePlayback : public Resource {
GDCLASS(AnimationNodeStateMachinePlayback, Resource);
friend class AnimationNodeStateMachine;
struct AStarCost {
float distance = 0.0;
StringName prev;
};
struct TransitionInfo {
StringName from;
StringName to;
StringName next;
};
struct NextInfo {
StringName node;
double xfade;
Ref<Curve> curve;
AnimationNodeStateMachineTransition::SwitchMode switch_mode;
bool is_reset;
};
struct ChildStateMachineInfo {
Ref<AnimationNodeStateMachinePlayback> playback;
Vector<StringName> path;
bool is_reset = false;
};
Ref<AnimationNodeStateMachineTransition> default_transition;
String base_path;
double len_fade_from = 0.0;
double pos_fade_from = 0.0;
double len_current = 0.0;
double pos_current = 0.0;
StringName current;
Ref<Curve> current_curve;
Ref<AnimationNodeStateMachineTransition> group_start_transition;
Ref<AnimationNodeStateMachineTransition> group_end_transition;
StringName fading_from;
float fading_time = 0.0;
float fading_pos = 0.0;
Vector<StringName> path;
bool playing = false;
StringName start_request;
StringName travel_request;
bool reset_request = false;
bool reset_request_on_teleport = false;
bool _reset_request_for_fading_from = false;
bool next_request = false;
bool stop_request = false;
bool teleport_request = false;
bool is_grouped = false;
void _travel_main(const StringName &p_state, bool p_reset_on_teleport = true);
void _start_main(const StringName &p_state, bool p_reset = true);
void _next_main();
void _stop_main();
bool _make_travel_path(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine, bool p_is_allow_transition_to_self, Vector<StringName> &r_path, bool p_test_only);
String _validate_path(AnimationNodeStateMachine *p_state_machine, const String &p_path);
bool _travel(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine, bool p_is_allow_transition_to_self, bool p_test_only);
void _start(AnimationNodeStateMachine *p_state_machine);
void _clear_path_children(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine, bool p_test_only);
bool _travel_children(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine, const String &p_path, bool p_is_allow_transition_to_self, bool p_is_parent_same_state, bool p_test_only);
void _start_children(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine, const String &p_path, bool p_test_only);
double process(const String &p_base_path, AnimationNodeStateMachine *p_state_machine, double p_time, bool p_seek, bool p_is_external_seeking, bool p_test_only);
double _process(const String &p_base_path, AnimationNodeStateMachine *p_state_machine, double p_time, bool p_seek, bool p_is_external_seeking, bool p_test_only);
bool _check_advance_condition(const Ref<AnimationNodeStateMachine> p_state_machine, const Ref<AnimationNodeStateMachineTransition> p_transition) const;
bool _transition_to_next_recursive(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine, bool p_test_only);
NextInfo _find_next(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine) const;
Ref<AnimationNodeStateMachineTransition> _check_group_transition(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine, const AnimationNodeStateMachine::Transition &p_transition, Ref<AnimationNodeStateMachine> &r_state_machine, bool &r_bypass) const;
bool _can_transition_to_next(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine, NextInfo p_next, bool p_test_only);
void _set_current(AnimationNodeStateMachine *p_state_machine, const StringName &p_state);
void _set_grouped(bool p_is_grouped);
void _set_base_path(const String &p_base_path);
Ref<AnimationNodeStateMachinePlayback> _get_parent_playback(AnimationTree *p_tree) const;
Ref<AnimationNodeStateMachine> _get_parent_state_machine(AnimationTree *p_tree) const;
Ref<AnimationNodeStateMachineTransition> _get_group_start_transition() const;
Ref<AnimationNodeStateMachineTransition> _get_group_end_transition() const;
protected:
static void _bind_methods();
public:
void travel(const StringName &p_state, bool p_reset_on_teleport = true);
void start(const StringName &p_state, bool p_reset = true);
void next();
void stop();
bool is_playing() const;
bool is_end() const;
StringName get_current_node() const;
StringName get_fading_from_node() const;
Vector<StringName> get_travel_path() const;
float get_current_play_pos() const;
float get_current_length() const;
float get_fade_from_play_pos() const;
float get_fade_from_length() const;
float get_fading_time() const;
float get_fading_pos() const;
void clear_path();
void push_path(const StringName &p_state);
AnimationNodeStateMachinePlayback();
};
#endif // ANIMATION_NODE_STATE_MACHINE_H
+35 -15
View File
@@ -61,6 +61,9 @@ bool AnimationNode::is_parameter_read_only(const StringName &p_parameter) const
}
void AnimationNode::set_parameter(const StringName &p_name, const Variant &p_value) {
if (is_testing) {
return;
}
ERR_FAIL_COND(!state);
ERR_FAIL_COND(!state->tree->property_parent_map.has(base_path));
ERR_FAIL_COND(!state->tree->property_parent_map[base_path].has(p_name));
@@ -124,13 +127,13 @@ void AnimationNode::blend_animation(const StringName &p_animation, double p_time
state->animation_states.push_back(anim_state);
}
double AnimationNode::_pre_process(const StringName &p_base_path, AnimationNode *p_parent, State *p_state, double p_time, bool p_seek, bool p_is_external_seeking, const Vector<StringName> &p_connections) {
double AnimationNode::_pre_process(const StringName &p_base_path, AnimationNode *p_parent, State *p_state, double p_time, bool p_seek, bool p_is_external_seeking, const Vector<StringName> &p_connections, bool p_test_only) {
base_path = p_base_path;
parent = p_parent;
connections = p_connections;
state = p_state;
double t = process(p_time, p_seek, p_is_external_seeking);
double t = process(p_time, p_seek, p_is_external_seeking, p_test_only);
state = nullptr;
parent = nullptr;
@@ -154,7 +157,7 @@ void AnimationNode::make_invalid(const String &p_reason) {
state->invalid_reasons += String::utf8("") + p_reason;
}
double AnimationNode::blend_input(int p_input, double p_time, bool p_seek, bool p_is_external_seeking, real_t p_blend, FilterAction p_filter, bool p_sync) {
double AnimationNode::blend_input(int p_input, double p_time, bool p_seek, bool p_is_external_seeking, real_t p_blend, FilterAction p_filter, bool p_sync, bool p_test_only) {
ERR_FAIL_INDEX_V(p_input, inputs.size(), 0);
ERR_FAIL_COND_V(!state, 0);
@@ -173,7 +176,7 @@ double AnimationNode::blend_input(int p_input, double p_time, bool p_seek, bool
//inputs.write[p_input].last_pass = state->last_pass;
real_t activity = 0.0;
double ret = _blend_node(node_name, blend_tree->get_node_connection_array(node_name), nullptr, node, p_time, p_seek, p_is_external_seeking, p_blend, p_filter, p_sync, &activity);
double ret = _blend_node(node_name, blend_tree->get_node_connection_array(node_name), nullptr, node, p_time, p_seek, p_is_external_seeking, p_blend, p_filter, p_sync, &activity, p_test_only);
Vector<AnimationTree::Activity> *activity_ptr = state->tree->input_activity_map.getptr(base_path);
@@ -184,11 +187,11 @@ double AnimationNode::blend_input(int p_input, double p_time, bool p_seek, bool
return ret;
}
double AnimationNode::blend_node(const StringName &p_sub_path, Ref<AnimationNode> p_node, double p_time, bool p_seek, bool p_is_external_seeking, real_t p_blend, FilterAction p_filter, bool p_sync) {
return _blend_node(p_sub_path, Vector<StringName>(), this, p_node, p_time, p_seek, p_is_external_seeking, p_blend, p_filter, p_sync);
double AnimationNode::blend_node(const StringName &p_sub_path, Ref<AnimationNode> p_node, double p_time, bool p_seek, bool p_is_external_seeking, real_t p_blend, FilterAction p_filter, bool p_sync, bool p_test_only) {
return _blend_node(p_sub_path, Vector<StringName>(), this, p_node, p_time, p_seek, p_is_external_seeking, p_blend, p_filter, p_sync, nullptr, p_test_only);
}
double AnimationNode::_blend_node(const StringName &p_subpath, const Vector<StringName> &p_connections, AnimationNode *p_new_parent, Ref<AnimationNode> p_node, double p_time, bool p_seek, bool p_is_external_seeking, real_t p_blend, FilterAction p_filter, bool p_sync, real_t *r_max) {
double AnimationNode::_blend_node(const StringName &p_subpath, const Vector<StringName> &p_connections, AnimationNode *p_new_parent, Ref<AnimationNode> p_node, double p_time, bool p_seek, bool p_is_external_seeking, real_t p_blend, FilterAction p_filter, bool p_sync, real_t *r_max, bool p_test_only) {
ERR_FAIL_COND_V(!p_node.is_valid(), 0);
ERR_FAIL_COND_V(!state, 0);
@@ -298,9 +301,9 @@ double AnimationNode::_blend_node(const StringName &p_subpath, const Vector<Stri
// This process, which depends on p_sync is needed to process sync correctly in the case of
// that a synced AnimationNodeSync exists under the un-synced AnimationNodeSync.
if (!p_seek && !p_sync && !any_valid) {
return p_node->_pre_process(new_path, new_parent, state, 0, p_seek, p_is_external_seeking, p_connections);
return p_node->_pre_process(new_path, new_parent, state, 0, p_seek, p_is_external_seeking, p_connections, p_test_only);
}
return p_node->_pre_process(new_path, new_parent, state, p_time, p_seek, p_is_external_seeking, p_connections);
return p_node->_pre_process(new_path, new_parent, state, p_time, p_seek, p_is_external_seeking, p_connections, p_test_only);
}
String AnimationNode::get_caption() const {
@@ -354,9 +357,14 @@ int AnimationNode::find_input(const String &p_name) const {
return idx;
}
double AnimationNode::process(double p_time, bool p_seek, bool p_is_external_seeking) {
double AnimationNode::process(double p_time, bool p_seek, bool p_is_external_seeking, bool p_test_only) {
is_testing = p_test_only;
return _process(p_time, p_seek, p_is_external_seeking, p_test_only);
}
double AnimationNode::_process(double p_time, bool p_seek, bool p_is_external_seeking, bool p_test_only) {
double ret = 0;
GDVIRTUAL_CALL(_process, p_time, p_seek, p_is_external_seeking, ret);
GDVIRTUAL_CALL(_process, p_time, p_seek, p_is_external_seeking, p_test_only, ret);
return ret;
}
@@ -410,12 +418,24 @@ void AnimationNode::_validate_property(PropertyInfo &p_property) const {
}
}
Ref<AnimationNode> AnimationNode::get_child_by_name(const StringName &p_name) {
Ref<AnimationNode> AnimationNode::get_child_by_name(const StringName &p_name) const {
Ref<AnimationNode> ret;
GDVIRTUAL_CALL(_get_child_by_name, p_name, ret);
return ret;
}
Ref<AnimationNode> AnimationNode::find_node_by_path(const String &p_name) const {
Vector<String> split = p_name.split("/");
Ref<AnimationNode> ret = const_cast<AnimationNode *>(this);
for (int i = 0; i < split.size(); i++) {
ret = ret->get_child_by_name(split[i]);
if (!ret.is_valid()) {
break;
}
}
return ret;
}
void AnimationNode::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_input", "name"), &AnimationNode::add_input);
ClassDB::bind_method(D_METHOD("remove_input", "index"), &AnimationNode::remove_input);
@@ -434,8 +454,8 @@ void AnimationNode::_bind_methods() {
ClassDB::bind_method(D_METHOD("_get_filters"), &AnimationNode::_get_filters);
ClassDB::bind_method(D_METHOD("blend_animation", "animation", "time", "delta", "seeked", "is_external_seeking", "blend", "looped_flag"), &AnimationNode::blend_animation, DEFVAL(Animation::LOOPED_FLAG_NONE));
ClassDB::bind_method(D_METHOD("blend_node", "name", "node", "time", "seek", "is_external_seeking", "blend", "filter", "sync"), &AnimationNode::blend_node, DEFVAL(FILTER_IGNORE), DEFVAL(true));
ClassDB::bind_method(D_METHOD("blend_input", "input_index", "time", "seek", "is_external_seeking", "blend", "filter", "sync"), &AnimationNode::blend_input, DEFVAL(FILTER_IGNORE), DEFVAL(true));
ClassDB::bind_method(D_METHOD("blend_node", "name", "node", "time", "seek", "is_external_seeking", "blend", "filter", "sync", "test_only"), &AnimationNode::blend_node, DEFVAL(FILTER_IGNORE), DEFVAL(true), DEFVAL(false));
ClassDB::bind_method(D_METHOD("blend_input", "input_index", "time", "seek", "is_external_seeking", "blend", "filter", "sync", "test_only"), &AnimationNode::blend_input, DEFVAL(FILTER_IGNORE), DEFVAL(true), DEFVAL(false));
ClassDB::bind_method(D_METHOD("set_parameter", "name", "value"), &AnimationNode::set_parameter);
ClassDB::bind_method(D_METHOD("get_parameter", "name"), &AnimationNode::get_parameter);
@@ -448,7 +468,7 @@ void AnimationNode::_bind_methods() {
GDVIRTUAL_BIND(_get_child_by_name, "name");
GDVIRTUAL_BIND(_get_parameter_default_value, "parameter");
GDVIRTUAL_BIND(_is_parameter_read_only, "parameter");
GDVIRTUAL_BIND(_process, "time", "seek", "is_external_seeking");
GDVIRTUAL_BIND(_process, "time", "seek", "is_external_seeking", "test_only");
GDVIRTUAL_BIND(_get_caption);
GDVIRTUAL_BIND(_has_filter);
+14 -7
View File
@@ -37,6 +37,8 @@
#include "scene/resources/animation.h"
#include "scene/resources/audio_stream_polyphonic.h"
#define HUGE_LENGTH 31540000 // 31540000 seconds mean 1 year... is it too long? It must be longer than any Animation length and Transition xfade time to prevent time inversion.
class AnimationNodeBlendTree;
class AnimationNodeStartState;
class AnimationNodeEndState;
@@ -87,7 +89,9 @@ public:
Vector<real_t> blends;
State *state = nullptr;
double _pre_process(const StringName &p_base_path, AnimationNode *p_parent, State *p_state, double p_time, bool p_seek, bool p_is_external_seeking, const Vector<StringName> &p_connections);
bool is_testing = false;
double _pre_process(const StringName &p_base_path, AnimationNode *p_parent, State *p_state, double p_time, bool p_seek, bool p_is_external_seeking, const Vector<StringName> &p_connections, bool p_test_only = false);
//all this is temporary
StringName base_path;
@@ -100,12 +104,15 @@ public:
Array _get_filters() const;
void _set_filters(const Array &p_filters);
friend class AnimationNodeBlendTree;
double _blend_node(const StringName &p_subpath, const Vector<StringName> &p_connections, AnimationNode *p_new_parent, Ref<AnimationNode> p_node, double p_time, bool p_seek, bool p_is_external_seeking, real_t p_blend, FilterAction p_filter = FILTER_IGNORE, bool p_sync = true, real_t *r_max = nullptr);
double _blend_node(const StringName &p_subpath, const Vector<StringName> &p_connections, AnimationNode *p_new_parent, Ref<AnimationNode> p_node, double p_time, bool p_seek, bool p_is_external_seeking, real_t p_blend, FilterAction p_filter = FILTER_IGNORE, bool p_sync = true, real_t *r_max = nullptr, bool p_test_only = false);
protected:
virtual double _process(double p_time, bool p_seek, bool p_is_external_seeking, bool p_test_only = false);
double process(double p_time, bool p_seek, bool p_is_external_seeking, bool p_test_only = false);
void blend_animation(const StringName &p_animation, double p_time, double p_delta, bool p_seeked, bool p_is_external_seeking, real_t p_blend, Animation::LoopedFlag p_looped_flag = Animation::LOOPED_FLAG_NONE);
double blend_node(const StringName &p_sub_path, Ref<AnimationNode> p_node, double p_time, bool p_seek, bool p_is_external_seeking, real_t p_blend, FilterAction p_filter = FILTER_IGNORE, bool p_sync = true);
double blend_input(int p_input, double p_time, bool p_seek, bool p_is_external_seeking, real_t p_blend, FilterAction p_filter = FILTER_IGNORE, bool p_sync = true);
double blend_node(const StringName &p_sub_path, Ref<AnimationNode> p_node, double p_time, bool p_seek, bool p_is_external_seeking, real_t p_blend, FilterAction p_filter = FILTER_IGNORE, bool p_sync = true, bool p_test_only = false);
double blend_input(int p_input, double p_time, bool p_seek, bool p_is_external_seeking, real_t p_blend, FilterAction p_filter = FILTER_IGNORE, bool p_sync = true, bool p_test_only = false);
void make_invalid(const String &p_reason);
AnimationTree *get_animation_tree() const;
@@ -119,7 +126,7 @@ protected:
GDVIRTUAL1RC(Ref<AnimationNode>, _get_child_by_name, StringName)
GDVIRTUAL1RC(Variant, _get_parameter_default_value, StringName)
GDVIRTUAL1RC(bool, _is_parameter_read_only, StringName)
GDVIRTUAL3RC(double, _process, double, bool, bool)
GDVIRTUAL4RC(double, _process, double, bool, bool, bool)
GDVIRTUAL0RC(String, _get_caption)
GDVIRTUAL0RC(bool, _has_filter)
@@ -138,7 +145,6 @@ public:
virtual void get_child_nodes(List<ChildNode> *r_child_nodes);
virtual double process(double p_time, bool p_seek, bool p_is_external_seeking);
virtual String get_caption() const;
virtual bool add_input(const String &p_name);
@@ -156,7 +162,8 @@ public:
virtual bool has_filter() const;
virtual Ref<AnimationNode> get_child_by_name(const StringName &p_name);
virtual Ref<AnimationNode> get_child_by_name(const StringName &p_name) const;
Ref<AnimationNode> find_node_by_path(const String &p_name) const;
AnimationNode();
};