Merge pull request #75759 from TokageItLab/reimplement-grouped-statemachine
Rework for nested `AnimationNodeStateMachine`
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user