Refactor process of AnimationTree for end of animation
This commit is contained in:
parent
0b2dc0f017
commit
c1ec99f0e1
@ -251,15 +251,6 @@
|
|||||||
Returns the amount of tracks in the animation.
|
Returns the amount of tracks in the animation.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="method_track_get_key_indices" qualifiers="const">
|
|
||||||
<return type="PackedInt32Array" />
|
|
||||||
<param index="0" name="track_idx" type="int" />
|
|
||||||
<param index="1" name="time_sec" type="float" />
|
|
||||||
<param index="2" name="delta" type="float" />
|
|
||||||
<description>
|
|
||||||
Returns all the key indices of a method track, given a position and delta time.
|
|
||||||
</description>
|
|
||||||
</method>
|
|
||||||
<method name="method_track_get_name" qualifiers="const">
|
<method name="method_track_get_name" qualifiers="const">
|
||||||
<return type="StringName" />
|
<return type="StringName" />
|
||||||
<param index="0" name="track_idx" type="int" />
|
<param index="0" name="track_idx" type="int" />
|
||||||
@ -523,15 +514,6 @@
|
|||||||
Swaps the track [param track_idx]'s index position with the track [param with_idx].
|
Swaps the track [param track_idx]'s index position with the track [param with_idx].
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="value_track_get_key_indices" qualifiers="const">
|
|
||||||
<return type="PackedInt32Array" />
|
|
||||||
<param index="0" name="track_idx" type="int" />
|
|
||||||
<param index="1" name="time_sec" type="float" />
|
|
||||||
<param index="2" name="delta" type="float" />
|
|
||||||
<description>
|
|
||||||
Returns all the key indices of a value track, given a position and delta time.
|
|
||||||
</description>
|
|
||||||
</method>
|
|
||||||
<method name="value_track_get_update_mode" qualifiers="const">
|
<method name="value_track_get_update_mode" qualifiers="const">
|
||||||
<return type="int" enum="Animation.UpdateMode" />
|
<return type="int" enum="Animation.UpdateMode" />
|
||||||
<param index="0" name="track_idx" type="int" />
|
<param index="0" name="track_idx" type="int" />
|
||||||
|
@ -53,7 +53,7 @@
|
|||||||
<return type="float" />
|
<return type="float" />
|
||||||
<param index="0" name="time" type="float" />
|
<param index="0" name="time" type="float" />
|
||||||
<param index="1" name="seek" type="bool" />
|
<param index="1" name="seek" type="bool" />
|
||||||
<param index="2" name="seek_root" type="bool" />
|
<param index="2" name="is_external_seeking" type="bool" />
|
||||||
<description>
|
<description>
|
||||||
When inheriting from [AnimationRootNode], implement this virtual method to run some code when this node is processed. The [param time] parameter is a relative delta, unless [param seek] is [code]true[/code], in which case it is absolute.
|
When inheriting from [AnimationRootNode], implement this virtual method to run some code when this node is processed. The [param time] parameter is a relative delta, unless [param seek] is [code]true[/code], in which case it is absolute.
|
||||||
Here, call the [method blend_input], [method blend_node] or [method blend_animation] functions. You can also use [method get_parameter] and [method set_parameter] to modify local memory.
|
Here, call the [method blend_input], [method blend_node] or [method blend_animation] functions. You can also use [method get_parameter] and [method set_parameter] to modify local memory.
|
||||||
@ -73,7 +73,7 @@
|
|||||||
<param index="1" name="time" type="float" />
|
<param index="1" name="time" type="float" />
|
||||||
<param index="2" name="delta" type="float" />
|
<param index="2" name="delta" type="float" />
|
||||||
<param index="3" name="seeked" type="bool" />
|
<param index="3" name="seeked" type="bool" />
|
||||||
<param index="4" name="seek_root" type="bool" />
|
<param index="4" name="is_external_seeking" type="bool" />
|
||||||
<param index="5" name="blend" type="float" />
|
<param index="5" name="blend" type="float" />
|
||||||
<param index="6" name="pingponged" type="int" default="0" />
|
<param index="6" name="pingponged" type="int" default="0" />
|
||||||
<description>
|
<description>
|
||||||
@ -85,7 +85,7 @@
|
|||||||
<param index="0" name="input_index" type="int" />
|
<param index="0" name="input_index" type="int" />
|
||||||
<param index="1" name="time" type="float" />
|
<param index="1" name="time" type="float" />
|
||||||
<param index="2" name="seek" type="bool" />
|
<param index="2" name="seek" type="bool" />
|
||||||
<param index="3" name="seek_root" type="bool" />
|
<param index="3" name="is_external_seeking" type="bool" />
|
||||||
<param index="4" name="blend" type="float" />
|
<param index="4" name="blend" type="float" />
|
||||||
<param index="5" name="filter" type="int" enum="AnimationNode.FilterAction" default="0" />
|
<param index="5" name="filter" type="int" enum="AnimationNode.FilterAction" default="0" />
|
||||||
<param index="6" name="sync" type="bool" default="true" />
|
<param index="6" name="sync" type="bool" default="true" />
|
||||||
@ -99,7 +99,7 @@
|
|||||||
<param index="1" name="node" type="AnimationNode" />
|
<param index="1" name="node" type="AnimationNode" />
|
||||||
<param index="2" name="time" type="float" />
|
<param index="2" name="time" type="float" />
|
||||||
<param index="3" name="seek" type="bool" />
|
<param index="3" name="seek" type="bool" />
|
||||||
<param index="4" name="seek_root" type="bool" />
|
<param index="4" name="is_external_seeking" type="bool" />
|
||||||
<param index="5" name="blend" type="float" />
|
<param index="5" name="blend" type="float" />
|
||||||
<param index="6" name="filter" type="int" enum="AnimationNode.FilterAction" default="0" />
|
<param index="6" name="filter" type="int" enum="AnimationNode.FilterAction" default="0" />
|
||||||
<param index="7" name="sync" type="bool" default="true" />
|
<param index="7" name="sync" type="bool" default="true" />
|
||||||
|
@ -230,14 +230,14 @@ void AnimationNodeBlendSpace1D::_add_blend_point(int p_index, const Ref<Animatio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double AnimationNodeBlendSpace1D::process(double p_time, bool p_seek, bool p_seek_root) {
|
double AnimationNodeBlendSpace1D::process(double p_time, bool p_seek, bool p_is_external_seeking) {
|
||||||
if (blend_points_used == 0) {
|
if (blend_points_used == 0) {
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blend_points_used == 1) {
|
if (blend_points_used == 1) {
|
||||||
// only one point available, just play that animation
|
// only one point available, just play that animation
|
||||||
return blend_node(blend_points[0].name, blend_points[0].node, p_time, p_seek, p_seek_root, 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
double blend_pos = get_parameter(blend_position);
|
double blend_pos = get_parameter(blend_position);
|
||||||
@ -307,10 +307,10 @@ double AnimationNodeBlendSpace1D::process(double p_time, bool p_seek, bool p_see
|
|||||||
|
|
||||||
for (int i = 0; i < blend_points_used; i++) {
|
for (int i = 0; i < blend_points_used; i++) {
|
||||||
if (i == point_lower || i == point_higher) {
|
if (i == point_lower || i == point_higher) {
|
||||||
double remaining = blend_node(blend_points[i].name, blend_points[i].node, p_time, p_seek, p_seek_root, 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);
|
||||||
max_time_remaining = MAX(max_time_remaining, remaining);
|
max_time_remaining = MAX(max_time_remaining, remaining);
|
||||||
} else if (sync) {
|
} else if (sync) {
|
||||||
blend_node(blend_points[i].name, blend_points[i].node, p_time, p_seek, p_seek_root, 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ public:
|
|||||||
void set_use_sync(bool p_sync);
|
void set_use_sync(bool p_sync);
|
||||||
bool is_using_sync() const;
|
bool is_using_sync() const;
|
||||||
|
|
||||||
double process(double p_time, bool p_seek, bool p_seek_root) override;
|
double process(double p_time, bool p_seek, bool p_is_external_seeking) override;
|
||||||
String get_caption() const 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) override;
|
||||||
|
@ -432,7 +432,7 @@ void AnimationNodeBlendSpace2D::_blend_triangle(const Vector2 &p_pos, const Vect
|
|||||||
r_weights[2] = w;
|
r_weights[2] = w;
|
||||||
}
|
}
|
||||||
|
|
||||||
double AnimationNodeBlendSpace2D::process(double p_time, bool p_seek, bool p_seek_root) {
|
double AnimationNodeBlendSpace2D::process(double p_time, bool p_seek, bool p_is_external_seeking) {
|
||||||
_update_triangles();
|
_update_triangles();
|
||||||
|
|
||||||
Vector2 blend_pos = get_parameter(blend_position);
|
Vector2 blend_pos = get_parameter(blend_position);
|
||||||
@ -502,7 +502,7 @@ double AnimationNodeBlendSpace2D::process(double p_time, bool p_seek, bool p_see
|
|||||||
for (int j = 0; j < 3; j++) {
|
for (int j = 0; j < 3; j++) {
|
||||||
if (i == triangle_points[j]) {
|
if (i == triangle_points[j]) {
|
||||||
//blend with the given weight
|
//blend with the given weight
|
||||||
double t = blend_node(blend_points[i].name, blend_points[i].node, p_time, p_seek, p_seek_root, 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);
|
||||||
if (first || t < mind) {
|
if (first || t < mind) {
|
||||||
mind = t;
|
mind = t;
|
||||||
first = false;
|
first = false;
|
||||||
@ -513,7 +513,7 @@ double AnimationNodeBlendSpace2D::process(double p_time, bool p_seek, bool p_see
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sync && !found) {
|
if (sync && !found) {
|
||||||
blend_node(blend_points[i].name, blend_points[i].node, p_time, p_seek, p_seek_root, 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -538,22 +538,22 @@ double AnimationNodeBlendSpace2D::process(double p_time, bool p_seek, bool p_see
|
|||||||
na_n->set_backward(na_c->is_backward());
|
na_n->set_backward(na_c->is_backward());
|
||||||
}
|
}
|
||||||
//see how much animation remains
|
//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_seek_root, 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
mind = blend_node(blend_points[new_closest].name, blend_points[new_closest].node, from, true, p_seek_root, 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);
|
||||||
cur_length_internal = from + mind;
|
cur_length_internal = from + mind;
|
||||||
|
|
||||||
cur_closest = new_closest;
|
cur_closest = new_closest;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
mind = blend_node(blend_points[cur_closest].name, blend_points[cur_closest].node, p_time, p_seek, p_seek_root, 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sync) {
|
if (sync) {
|
||||||
for (int i = 0; i < blend_points_used; i++) {
|
for (int i = 0; i < blend_points_used; i++) {
|
||||||
if (i != cur_closest) {
|
if (i != cur_closest) {
|
||||||
blend_node(blend_points[i].name, blend_points[i].node, p_time, p_seek, p_seek_root, 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,7 +128,7 @@ public:
|
|||||||
void set_y_label(const String &p_label);
|
void set_y_label(const String &p_label);
|
||||||
String get_y_label() const;
|
String get_y_label() const;
|
||||||
|
|
||||||
virtual double process(double p_time, bool p_seek, bool p_seek_root) override;
|
virtual double process(double p_time, bool p_seek, bool p_is_external_seeking) override;
|
||||||
virtual String get_caption() const override;
|
virtual String get_caption() const override;
|
||||||
|
|
||||||
Vector2 get_closest_point(const Vector2 &p_point);
|
Vector2 get_closest_point(const Vector2 &p_point);
|
||||||
|
@ -64,7 +64,7 @@ void AnimationNodeAnimation::_validate_property(PropertyInfo &p_property) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double AnimationNodeAnimation::process(double p_time, bool p_seek, bool p_seek_root) {
|
double AnimationNodeAnimation::process(double p_time, bool p_seek, bool p_is_external_seeking) {
|
||||||
AnimationPlayer *ap = state->player;
|
AnimationPlayer *ap = state->player;
|
||||||
ERR_FAIL_COND_V(!ap, 0);
|
ERR_FAIL_COND_V(!ap, 0);
|
||||||
|
|
||||||
@ -115,12 +115,13 @@ double AnimationNodeAnimation::process(double p_time, bool p_seek, bool p_seek_r
|
|||||||
}
|
}
|
||||||
cur_time = Math::pingpong(cur_time, anim_size);
|
cur_time = Math::pingpong(cur_time, anim_size);
|
||||||
}
|
}
|
||||||
|
} else if (anim->get_loop_mode() == Animation::LOOP_LINEAR) {
|
||||||
|
if (!Math::is_zero_approx(anim_size)) {
|
||||||
|
cur_time = Math::fposmod(cur_time, anim_size);
|
||||||
|
}
|
||||||
|
backward = false;
|
||||||
} else {
|
} else {
|
||||||
if (anim->get_loop_mode() == Animation::LOOP_LINEAR) {
|
if (cur_time < 0) {
|
||||||
if (!Math::is_zero_approx(anim_size)) {
|
|
||||||
cur_time = Math::fposmod(cur_time, anim_size);
|
|
||||||
}
|
|
||||||
} else if (cur_time < 0) {
|
|
||||||
step += cur_time;
|
step += cur_time;
|
||||||
cur_time = 0;
|
cur_time = 0;
|
||||||
} else if (cur_time > anim_size) {
|
} else if (cur_time > anim_size) {
|
||||||
@ -128,12 +129,25 @@ double AnimationNodeAnimation::process(double p_time, bool p_seek, bool p_seek_r
|
|||||||
cur_time = anim_size;
|
cur_time = anim_size;
|
||||||
}
|
}
|
||||||
backward = false;
|
backward = false;
|
||||||
|
|
||||||
|
// If ended, don't progress animation. So set delta to 0.
|
||||||
|
if (p_time > 0) {
|
||||||
|
if (play_mode == PLAY_MODE_FORWARD) {
|
||||||
|
if (prev_time >= anim_size) {
|
||||||
|
step = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (prev_time <= 0) {
|
||||||
|
step = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (play_mode == PLAY_MODE_FORWARD) {
|
if (play_mode == PLAY_MODE_FORWARD) {
|
||||||
blend_animation(animation, cur_time, step, p_seek, p_seek_root, 1.0, pingponged);
|
blend_animation(animation, cur_time, step, p_seek, p_is_external_seeking, 1.0, pingponged);
|
||||||
} else {
|
} else {
|
||||||
blend_animation(animation, anim_size - cur_time, -step, p_seek, p_seek_root, 1.0, pingponged);
|
blend_animation(animation, anim_size - cur_time, -step, p_seek, p_is_external_seeking, 1.0, pingponged);
|
||||||
}
|
}
|
||||||
set_parameter(time, cur_time);
|
set_parameter(time, cur_time);
|
||||||
|
|
||||||
@ -273,7 +287,7 @@ bool AnimationNodeOneShot::has_filter() const {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
double AnimationNodeOneShot::process(double p_time, bool p_seek, bool p_seek_root) {
|
double AnimationNodeOneShot::process(double p_time, bool p_seek, bool p_is_external_seeking) {
|
||||||
bool cur_active = get_parameter(active);
|
bool cur_active = get_parameter(active);
|
||||||
bool cur_prev_active = get_parameter(prev_active);
|
bool cur_prev_active = get_parameter(prev_active);
|
||||||
double cur_time = get_parameter(time);
|
double cur_time = get_parameter(time);
|
||||||
@ -296,7 +310,7 @@ double AnimationNodeOneShot::process(double p_time, bool p_seek, bool p_seek_roo
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!cur_active) {
|
if (!cur_active) {
|
||||||
return blend_input(0, p_time, p_seek, p_seek_root, 1.0, FILTER_IGNORE, sync);
|
return blend_input(0, p_time, p_seek, p_is_external_seeking, 1.0, FILTER_IGNORE, sync);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -333,12 +347,12 @@ double AnimationNodeOneShot::process(double p_time, bool p_seek, bool p_seek_roo
|
|||||||
|
|
||||||
double main_rem;
|
double main_rem;
|
||||||
if (mix == MIX_MODE_ADD) {
|
if (mix == MIX_MODE_ADD) {
|
||||||
main_rem = blend_input(0, p_time, p_seek, p_seek_root, 1.0, FILTER_IGNORE, sync);
|
main_rem = blend_input(0, p_time, p_seek, p_is_external_seeking, 1.0, FILTER_IGNORE, sync);
|
||||||
} else {
|
} else {
|
||||||
main_rem = blend_input(0, p_time, p_seek, p_seek_root, 1.0 - blend, FILTER_BLEND, sync);
|
main_rem = blend_input(0, p_time, p_seek, p_is_external_seeking, 1.0 - blend, FILTER_BLEND, sync);
|
||||||
}
|
}
|
||||||
|
|
||||||
double os_rem = blend_input(1, os_seek ? cur_time : p_time, os_seek, p_seek_root, blend, FILTER_PASS, true);
|
double os_rem = blend_input(1, os_seek ? cur_time : p_time, os_seek, p_is_external_seeking, blend, FILTER_PASS, true);
|
||||||
|
|
||||||
if (do_start) {
|
if (do_start) {
|
||||||
cur_remaining = os_rem;
|
cur_remaining = os_rem;
|
||||||
@ -420,10 +434,10 @@ bool AnimationNodeAdd2::has_filter() const {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
double AnimationNodeAdd2::process(double p_time, bool p_seek, bool p_seek_root) {
|
double AnimationNodeAdd2::process(double p_time, bool p_seek, bool p_is_external_seeking) {
|
||||||
double amount = get_parameter(add_amount);
|
double amount = get_parameter(add_amount);
|
||||||
double rem0 = blend_input(0, p_time, p_seek, p_seek_root, 1.0, FILTER_IGNORE, sync);
|
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_seek_root, amount, FILTER_PASS, sync);
|
blend_input(1, p_time, p_seek, p_is_external_seeking, amount, FILTER_PASS, sync);
|
||||||
|
|
||||||
return rem0;
|
return rem0;
|
||||||
}
|
}
|
||||||
@ -454,11 +468,11 @@ bool AnimationNodeAdd3::has_filter() const {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
double AnimationNodeAdd3::process(double p_time, bool p_seek, bool p_seek_root) {
|
double AnimationNodeAdd3::process(double p_time, bool p_seek, bool p_is_external_seeking) {
|
||||||
double amount = get_parameter(add_amount);
|
double amount = get_parameter(add_amount);
|
||||||
blend_input(0, p_time, p_seek, p_seek_root, MAX(0, -amount), FILTER_PASS, sync);
|
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_seek_root, 1.0, FILTER_IGNORE, 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_seek_root, MAX(0, amount), FILTER_PASS, sync);
|
blend_input(2, p_time, p_seek, p_is_external_seeking, MAX(0, amount), FILTER_PASS, sync);
|
||||||
|
|
||||||
return rem0;
|
return rem0;
|
||||||
}
|
}
|
||||||
@ -486,11 +500,11 @@ String AnimationNodeBlend2::get_caption() const {
|
|||||||
return "Blend2";
|
return "Blend2";
|
||||||
}
|
}
|
||||||
|
|
||||||
double AnimationNodeBlend2::process(double p_time, bool p_seek, bool p_seek_root) {
|
double AnimationNodeBlend2::process(double p_time, bool p_seek, bool p_is_external_seeking) {
|
||||||
double amount = get_parameter(blend_amount);
|
double amount = get_parameter(blend_amount);
|
||||||
|
|
||||||
double rem0 = blend_input(0, p_time, p_seek, p_seek_root, 1.0 - amount, FILTER_BLEND, sync);
|
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_seek_root, amount, FILTER_PASS, sync);
|
double rem1 = blend_input(1, p_time, p_seek, p_is_external_seeking, amount, FILTER_PASS, sync);
|
||||||
|
|
||||||
return amount > 0.5 ? rem1 : rem0; //hacky but good enough
|
return amount > 0.5 ? rem1 : rem0; //hacky but good enough
|
||||||
}
|
}
|
||||||
@ -521,11 +535,11 @@ String AnimationNodeBlend3::get_caption() const {
|
|||||||
return "Blend3";
|
return "Blend3";
|
||||||
}
|
}
|
||||||
|
|
||||||
double AnimationNodeBlend3::process(double p_time, bool p_seek, bool p_seek_root) {
|
double AnimationNodeBlend3::process(double p_time, bool p_seek, bool p_is_external_seeking) {
|
||||||
double amount = get_parameter(blend_amount);
|
double amount = get_parameter(blend_amount);
|
||||||
double rem0 = blend_input(0, p_time, p_seek, p_seek_root, 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);
|
||||||
double rem1 = blend_input(1, p_time, p_seek, p_seek_root, 1.0 - ABS(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_seek_root, MAX(0, amount), FILTER_IGNORE, sync);
|
double rem2 = blend_input(2, p_time, p_seek, p_is_external_seeking, MAX(0, amount), FILTER_IGNORE, sync);
|
||||||
|
|
||||||
return amount > 0.5 ? rem2 : (amount < -0.5 ? rem0 : rem1); //hacky but good enough
|
return amount > 0.5 ? rem2 : (amount < -0.5 ? rem0 : rem1); //hacky but good enough
|
||||||
}
|
}
|
||||||
@ -553,12 +567,12 @@ String AnimationNodeTimeScale::get_caption() const {
|
|||||||
return "TimeScale";
|
return "TimeScale";
|
||||||
}
|
}
|
||||||
|
|
||||||
double AnimationNodeTimeScale::process(double p_time, bool p_seek, bool p_seek_root) {
|
double AnimationNodeTimeScale::process(double p_time, bool p_seek, bool p_is_external_seeking) {
|
||||||
double cur_scale = get_parameter(scale);
|
double cur_scale = get_parameter(scale);
|
||||||
if (p_seek) {
|
if (p_seek) {
|
||||||
return blend_input(0, p_time, true, p_seek_root, 1.0, FILTER_IGNORE, true);
|
return blend_input(0, p_time, true, p_is_external_seeking, 1.0, FILTER_IGNORE, true);
|
||||||
} else {
|
} else {
|
||||||
return blend_input(0, p_time * cur_scale, false, p_seek_root, 1.0, FILTER_IGNORE, true);
|
return blend_input(0, p_time * cur_scale, false, p_is_external_seeking, 1.0, FILTER_IGNORE, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -583,16 +597,16 @@ String AnimationNodeTimeSeek::get_caption() const {
|
|||||||
return "Seek";
|
return "Seek";
|
||||||
}
|
}
|
||||||
|
|
||||||
double AnimationNodeTimeSeek::process(double p_time, bool p_seek, bool p_seek_root) {
|
double AnimationNodeTimeSeek::process(double p_time, bool p_seek, bool p_is_external_seeking) {
|
||||||
double cur_seek_pos = get_parameter(seek_pos);
|
double cur_seek_pos = get_parameter(seek_pos);
|
||||||
if (p_seek) {
|
if (p_seek) {
|
||||||
return blend_input(0, p_time, true, p_seek_root, 1.0, FILTER_IGNORE, true);
|
return blend_input(0, p_time, true, p_is_external_seeking, 1.0, FILTER_IGNORE, true);
|
||||||
} else if (cur_seek_pos >= 0) {
|
} 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);
|
||||||
set_parameter(seek_pos, -1.0); //reset
|
set_parameter(seek_pos, -1.0); //reset
|
||||||
return ret;
|
return ret;
|
||||||
} else {
|
} else {
|
||||||
return blend_input(0, p_time, false, p_seek_root, 1.0, FILTER_IGNORE, true);
|
return blend_input(0, p_time, false, p_is_external_seeking, 1.0, FILTER_IGNORE, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -700,7 +714,7 @@ bool AnimationNodeTransition::is_from_start() const {
|
|||||||
return from_start;
|
return from_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
double AnimationNodeTransition::process(double p_time, bool p_seek, bool p_seek_root) {
|
double AnimationNodeTransition::process(double p_time, bool p_seek, bool p_is_external_seeking) {
|
||||||
int cur_current = get_parameter(current);
|
int cur_current = get_parameter(current);
|
||||||
int cur_prev = get_parameter(prev);
|
int cur_prev = get_parameter(prev);
|
||||||
int cur_prev_current = get_parameter(prev_current);
|
int cur_prev_current = get_parameter(prev_current);
|
||||||
@ -729,14 +743,14 @@ double AnimationNodeTransition::process(double p_time, bool p_seek, bool p_seek_
|
|||||||
if (sync) {
|
if (sync) {
|
||||||
for (int i = 0; i < enabled_inputs; i++) {
|
for (int i = 0; i < enabled_inputs; i++) {
|
||||||
if (i != cur_current && i != cur_prev) {
|
if (i != cur_current && i != cur_prev) {
|
||||||
blend_input(i, p_time, p_seek, p_seek_root, 0, FILTER_IGNORE, true);
|
blend_input(i, p_time, p_seek, p_is_external_seeking, 0, FILTER_IGNORE, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cur_prev < 0) { // process current animation, check for transition
|
if (cur_prev < 0) { // process current animation, check for transition
|
||||||
|
|
||||||
rem = blend_input(cur_current, p_time, p_seek, p_seek_root, 1.0, FILTER_IGNORE, true);
|
rem = blend_input(cur_current, p_time, p_seek, p_is_external_seeking, 1.0, FILTER_IGNORE, true);
|
||||||
|
|
||||||
if (p_seek) {
|
if (p_seek) {
|
||||||
cur_time = p_time;
|
cur_time = p_time;
|
||||||
@ -756,17 +770,16 @@ double AnimationNodeTransition::process(double p_time, bool p_seek, bool p_seek_
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (from_start && !p_seek && switched) { //just switched, seek to start of current
|
if (from_start && !p_seek && switched) { //just switched, seek to start of current
|
||||||
|
rem = blend_input(cur_current, 0, true, p_is_external_seeking, 1.0 - blend, FILTER_IGNORE, true);
|
||||||
rem = blend_input(cur_current, 0, true, p_seek_root, 1.0 - blend, FILTER_IGNORE, true);
|
|
||||||
} else {
|
} else {
|
||||||
rem = blend_input(cur_current, p_time, p_seek, p_seek_root, 1.0 - blend, FILTER_IGNORE, true);
|
rem = blend_input(cur_current, p_time, p_seek, p_is_external_seeking, 1.0 - blend, FILTER_IGNORE, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_seek) {
|
if (p_seek) {
|
||||||
blend_input(cur_prev, p_time, true, p_seek_root, blend, FILTER_IGNORE, true);
|
blend_input(cur_prev, p_time, true, p_is_external_seeking, blend, FILTER_IGNORE, true);
|
||||||
cur_time = p_time;
|
cur_time = p_time;
|
||||||
} else {
|
} else {
|
||||||
blend_input(cur_prev, p_time, false, p_seek_root, blend, FILTER_IGNORE, true);
|
blend_input(cur_prev, p_time, false, p_is_external_seeking, blend, FILTER_IGNORE, true);
|
||||||
cur_time += p_time;
|
cur_time += p_time;
|
||||||
cur_prev_xfading -= p_time;
|
cur_prev_xfading -= p_time;
|
||||||
if (cur_prev_xfading < 0) {
|
if (cur_prev_xfading < 0) {
|
||||||
@ -835,8 +848,8 @@ String AnimationNodeOutput::get_caption() const {
|
|||||||
return "Output";
|
return "Output";
|
||||||
}
|
}
|
||||||
|
|
||||||
double AnimationNodeOutput::process(double p_time, bool p_seek, bool p_seek_root) {
|
double AnimationNodeOutput::process(double p_time, bool p_seek, bool p_is_external_seeking) {
|
||||||
return blend_input(0, p_time, p_seek, p_seek_root, 1.0, FILTER_IGNORE, true);
|
return blend_input(0, p_time, p_seek, p_is_external_seeking, 1.0, FILTER_IGNORE, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimationNodeOutput::AnimationNodeOutput() {
|
AnimationNodeOutput::AnimationNodeOutput() {
|
||||||
@ -1048,9 +1061,9 @@ String AnimationNodeBlendTree::get_caption() const {
|
|||||||
return "BlendTree";
|
return "BlendTree";
|
||||||
}
|
}
|
||||||
|
|
||||||
double AnimationNodeBlendTree::process(double p_time, bool p_seek, bool p_seek_root) {
|
double AnimationNodeBlendTree::process(double p_time, bool p_seek, bool p_is_external_seeking) {
|
||||||
Ref<AnimationNodeOutput> output = nodes[SceneStringNames::get_singleton()->output].node;
|
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_seek_root, 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimationNodeBlendTree::get_node_list(List<StringName> *r_list) {
|
void AnimationNodeBlendTree::get_node_list(List<StringName> *r_list) {
|
||||||
|
@ -53,7 +53,7 @@ public:
|
|||||||
static Vector<String> (*get_editable_animation_list)();
|
static Vector<String> (*get_editable_animation_list)();
|
||||||
|
|
||||||
virtual String get_caption() const override;
|
virtual String get_caption() const override;
|
||||||
virtual double process(double p_time, bool p_seek, bool p_seek_root) override;
|
virtual double process(double p_time, bool p_seek, bool p_is_external_seeking) override;
|
||||||
|
|
||||||
void set_animation(const StringName &p_name);
|
void set_animation(const StringName &p_name);
|
||||||
StringName get_animation() const;
|
StringName get_animation() const;
|
||||||
@ -72,7 +72,7 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
PlayMode play_mode = PLAY_MODE_FORWARD;
|
PlayMode play_mode = PLAY_MODE_FORWARD;
|
||||||
bool backward = false;
|
bool backward = false; // Only used by pingpong animation.
|
||||||
};
|
};
|
||||||
|
|
||||||
VARIANT_ENUM_CAST(AnimationNodeAnimation::PlayMode)
|
VARIANT_ENUM_CAST(AnimationNodeAnimation::PlayMode)
|
||||||
@ -148,7 +148,7 @@ public:
|
|||||||
MixMode get_mix_mode() const;
|
MixMode get_mix_mode() const;
|
||||||
|
|
||||||
virtual bool has_filter() const override;
|
virtual bool has_filter() const override;
|
||||||
virtual double process(double p_time, bool p_seek, bool p_seek_root) override;
|
virtual double process(double p_time, bool p_seek, bool p_is_external_seeking) override;
|
||||||
|
|
||||||
AnimationNodeOneShot();
|
AnimationNodeOneShot();
|
||||||
};
|
};
|
||||||
@ -170,7 +170,7 @@ public:
|
|||||||
virtual String get_caption() const override;
|
virtual String get_caption() const override;
|
||||||
|
|
||||||
virtual bool has_filter() const override;
|
virtual bool has_filter() const override;
|
||||||
virtual double process(double p_time, bool p_seek, bool p_seek_root) override;
|
virtual double process(double p_time, bool p_seek, bool p_is_external_seeking) override;
|
||||||
|
|
||||||
AnimationNodeAdd2();
|
AnimationNodeAdd2();
|
||||||
};
|
};
|
||||||
@ -190,7 +190,7 @@ public:
|
|||||||
virtual String get_caption() const override;
|
virtual String get_caption() const override;
|
||||||
|
|
||||||
virtual bool has_filter() const override;
|
virtual bool has_filter() const override;
|
||||||
virtual double process(double p_time, bool p_seek, bool p_seek_root) override;
|
virtual double process(double p_time, bool p_seek, bool p_is_external_seeking) override;
|
||||||
|
|
||||||
AnimationNodeAdd3();
|
AnimationNodeAdd3();
|
||||||
};
|
};
|
||||||
@ -208,7 +208,7 @@ public:
|
|||||||
virtual Variant get_parameter_default_value(const StringName &p_parameter) const override;
|
virtual Variant get_parameter_default_value(const StringName &p_parameter) const override;
|
||||||
|
|
||||||
virtual String get_caption() const override;
|
virtual String get_caption() const override;
|
||||||
virtual double process(double p_time, bool p_seek, bool p_seek_root) override;
|
virtual double process(double p_time, bool p_seek, bool p_is_external_seeking) override;
|
||||||
|
|
||||||
virtual bool has_filter() const override;
|
virtual bool has_filter() const override;
|
||||||
AnimationNodeBlend2();
|
AnimationNodeBlend2();
|
||||||
@ -228,7 +228,7 @@ public:
|
|||||||
|
|
||||||
virtual String get_caption() const override;
|
virtual String get_caption() const override;
|
||||||
|
|
||||||
double process(double p_time, bool p_seek, bool p_seek_root) override;
|
double process(double p_time, bool p_seek, bool p_is_external_seeking) override;
|
||||||
AnimationNodeBlend3();
|
AnimationNodeBlend3();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -246,7 +246,7 @@ public:
|
|||||||
|
|
||||||
virtual String get_caption() const override;
|
virtual String get_caption() const override;
|
||||||
|
|
||||||
double process(double p_time, bool p_seek, bool p_seek_root) override;
|
double process(double p_time, bool p_seek, bool p_is_external_seeking) override;
|
||||||
|
|
||||||
AnimationNodeTimeScale();
|
AnimationNodeTimeScale();
|
||||||
};
|
};
|
||||||
@ -265,7 +265,7 @@ public:
|
|||||||
|
|
||||||
virtual String get_caption() const override;
|
virtual String get_caption() const override;
|
||||||
|
|
||||||
double process(double p_time, bool p_seek, bool p_seek_root) override;
|
double process(double p_time, bool p_seek, bool p_is_external_seeking) override;
|
||||||
|
|
||||||
AnimationNodeTimeSeek();
|
AnimationNodeTimeSeek();
|
||||||
};
|
};
|
||||||
@ -331,7 +331,7 @@ public:
|
|||||||
void set_from_start(bool p_from_start);
|
void set_from_start(bool p_from_start);
|
||||||
bool is_from_start() const;
|
bool is_from_start() const;
|
||||||
|
|
||||||
double process(double p_time, bool p_seek, bool p_seek_root) override;
|
double process(double p_time, bool p_seek, bool p_is_external_seeking) override;
|
||||||
|
|
||||||
AnimationNodeTransition();
|
AnimationNodeTransition();
|
||||||
};
|
};
|
||||||
@ -341,7 +341,7 @@ class AnimationNodeOutput : public AnimationNode {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
virtual String get_caption() const override;
|
virtual String get_caption() const override;
|
||||||
virtual double process(double p_time, bool p_seek, bool p_seek_root) override;
|
virtual double process(double p_time, bool p_seek, bool p_is_external_seeking) override;
|
||||||
AnimationNodeOutput();
|
AnimationNodeOutput();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -410,7 +410,7 @@ public:
|
|||||||
void get_node_connections(List<NodeConnection> *r_connections) const;
|
void get_node_connections(List<NodeConnection> *r_connections) const;
|
||||||
|
|
||||||
virtual String get_caption() const override;
|
virtual String get_caption() const override;
|
||||||
virtual double process(double p_time, bool p_seek, bool p_seek_root) override;
|
virtual double process(double p_time, bool p_seek, bool p_is_external_seeking) override;
|
||||||
|
|
||||||
void get_node_list(List<StringName> *r_list);
|
void get_node_list(List<StringName> *r_list);
|
||||||
|
|
||||||
|
@ -332,11 +332,11 @@ bool AnimationNodeStateMachinePlayback::_travel(AnimationNodeStateMachine *p_sta
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
double AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_state_machine, double p_time, bool p_seek, bool p_seek_root) {
|
double AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_state_machine, double p_time, bool p_seek, bool p_is_external_seeking) {
|
||||||
if (p_time == -1) {
|
if (p_time == -1) {
|
||||||
Ref<AnimationNodeStateMachine> anodesm = p_state_machine->states[current].node;
|
Ref<AnimationNodeStateMachine> anodesm = p_state_machine->states[current].node;
|
||||||
if (anodesm.is_valid()) {
|
if (anodesm.is_valid()) {
|
||||||
p_state_machine->blend_node(current, p_state_machine->states[current].node, -1, p_seek, p_seek_root, 0, AnimationNode::FILTER_IGNORE, true);
|
p_state_machine->blend_node(current, p_state_machine->states[current].node, -1, p_seek, p_is_external_seeking, 0, AnimationNode::FILTER_IGNORE, true);
|
||||||
}
|
}
|
||||||
playing = false;
|
playing = false;
|
||||||
return 0;
|
return 0;
|
||||||
@ -405,7 +405,7 @@ double AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_s
|
|||||||
current = p_state_machine->start_node;
|
current = p_state_machine->start_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
len_current = p_state_machine->blend_node(current, p_state_machine->states[current].node, 0, true, p_seek_root, 1.0, AnimationNode::FILTER_IGNORE, true);
|
len_current = p_state_machine->blend_node(current, p_state_machine->states[current].node, 0, true, p_is_external_seeking, 1.0, AnimationNode::FILTER_IGNORE, true);
|
||||||
pos_current = 0;
|
pos_current = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -433,10 +433,10 @@ double AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_s
|
|||||||
if (current_curve.is_valid()) {
|
if (current_curve.is_valid()) {
|
||||||
fade_blend = current_curve->sample(fade_blend);
|
fade_blend = current_curve->sample(fade_blend);
|
||||||
}
|
}
|
||||||
float rem = p_state_machine->blend_node(current, p_state_machine->states[current].node, p_time, p_seek, p_seek_root, fade_blend, AnimationNode::FILTER_IGNORE, true);
|
float rem = p_state_machine->blend_node(current, p_state_machine->states[current].node, p_time, p_seek, p_is_external_seeking, fade_blend, AnimationNode::FILTER_IGNORE, true);
|
||||||
|
|
||||||
if (fading_from != StringName()) {
|
if (fading_from != StringName()) {
|
||||||
p_state_machine->blend_node(fading_from, p_state_machine->states[fading_from].node, p_time, p_seek, p_seek_root, 1.0 - fade_blend, AnimationNode::FILTER_IGNORE, true);
|
p_state_machine->blend_node(fading_from, p_state_machine->states[fading_from].node, p_time, p_seek, p_is_external_seeking, 1.0 - fade_blend, AnimationNode::FILTER_IGNORE, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
//guess playback position
|
//guess playback position
|
||||||
@ -593,19 +593,19 @@ double AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_s
|
|||||||
{ // if the current node is a state machine, update the "playing" variable to false by passing -1 in p_time
|
{ // if the current node is a state machine, update the "playing" variable to false by passing -1 in p_time
|
||||||
Ref<AnimationNodeStateMachine> anodesm = p_state_machine->states[current].node;
|
Ref<AnimationNodeStateMachine> anodesm = p_state_machine->states[current].node;
|
||||||
if (anodesm.is_valid()) {
|
if (anodesm.is_valid()) {
|
||||||
p_state_machine->blend_node(current, p_state_machine->states[current].node, -1, p_seek, p_seek_root, 0, AnimationNode::FILTER_IGNORE, true);
|
p_state_machine->blend_node(current, p_state_machine->states[current].node, -1, p_seek, p_is_external_seeking, 0, AnimationNode::FILTER_IGNORE, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
current = next;
|
current = next;
|
||||||
|
|
||||||
if (switch_mode == AnimationNodeStateMachineTransition::SWITCH_MODE_SYNC) {
|
if (switch_mode == AnimationNodeStateMachineTransition::SWITCH_MODE_SYNC) {
|
||||||
len_current = p_state_machine->blend_node(current, p_state_machine->states[current].node, 0, true, p_seek_root, 0, AnimationNode::FILTER_IGNORE, true);
|
len_current = p_state_machine->blend_node(current, p_state_machine->states[current].node, 0, true, p_is_external_seeking, 0, AnimationNode::FILTER_IGNORE, true);
|
||||||
pos_current = MIN(pos_current, len_current);
|
pos_current = MIN(pos_current, len_current);
|
||||||
p_state_machine->blend_node(current, p_state_machine->states[current].node, pos_current, true, p_seek_root, 0, AnimationNode::FILTER_IGNORE, true);
|
p_state_machine->blend_node(current, p_state_machine->states[current].node, pos_current, true, p_is_external_seeking, 0, AnimationNode::FILTER_IGNORE, true);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
len_current = p_state_machine->blend_node(current, p_state_machine->states[current].node, 0, true, p_seek_root, 0, AnimationNode::FILTER_IGNORE, true);
|
len_current = p_state_machine->blend_node(current, p_state_machine->states[current].node, 0, true, p_is_external_seeking, 0, AnimationNode::FILTER_IGNORE, true);
|
||||||
pos_current = 0;
|
pos_current = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1133,11 +1133,11 @@ Vector2 AnimationNodeStateMachine::get_graph_offset() const {
|
|||||||
return graph_offset;
|
return graph_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
double AnimationNodeStateMachine::process(double p_time, bool p_seek, bool p_seek_root) {
|
double AnimationNodeStateMachine::process(double p_time, bool p_seek, bool p_is_external_seeking) {
|
||||||
Ref<AnimationNodeStateMachinePlayback> playback_new = get_parameter(playback);
|
Ref<AnimationNodeStateMachinePlayback> playback_new = get_parameter(playback);
|
||||||
ERR_FAIL_COND_V(playback_new.is_null(), 0.0);
|
ERR_FAIL_COND_V(playback_new.is_null(), 0.0);
|
||||||
|
|
||||||
return playback_new->process(this, p_time, p_seek, p_seek_root);
|
return playback_new->process(this, p_time, p_seek, p_is_external_seeking);
|
||||||
}
|
}
|
||||||
|
|
||||||
String AnimationNodeStateMachine::get_caption() const {
|
String AnimationNodeStateMachine::get_caption() const {
|
||||||
|
@ -133,7 +133,7 @@ class AnimationNodeStateMachinePlayback : public Resource {
|
|||||||
|
|
||||||
bool _travel(AnimationNodeStateMachine *p_state_machine, const StringName &p_travel);
|
bool _travel(AnimationNodeStateMachine *p_state_machine, const StringName &p_travel);
|
||||||
|
|
||||||
double process(AnimationNodeStateMachine *p_state_machine, double p_time, bool p_seek, bool p_seek_root);
|
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;
|
bool _check_advance_condition(const Ref<AnimationNodeStateMachine> p_state_machine, const Ref<AnimationNodeStateMachineTransition> p_transition) const;
|
||||||
|
|
||||||
@ -239,7 +239,7 @@ public:
|
|||||||
void set_graph_offset(const Vector2 &p_offset);
|
void set_graph_offset(const Vector2 &p_offset);
|
||||||
Vector2 get_graph_offset() const;
|
Vector2 get_graph_offset() const;
|
||||||
|
|
||||||
virtual double process(double p_time, bool p_seek, bool p_seek_root) override;
|
virtual double process(double p_time, bool p_seek, bool p_is_external_seeking) override;
|
||||||
virtual String get_caption() const 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) override;
|
||||||
|
@ -683,7 +683,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double
|
|||||||
|
|
||||||
} else if (p_is_current && p_delta != 0) {
|
} else if (p_is_current && p_delta != 0) {
|
||||||
List<int> indices;
|
List<int> indices;
|
||||||
a->value_track_get_key_indices(i, p_time, p_delta, &indices, p_pingponged);
|
a->track_get_key_indices_in_range(i, p_time, p_delta, &indices, p_pingponged);
|
||||||
|
|
||||||
for (int &F : indices) {
|
for (int &F : indices) {
|
||||||
Variant value = a->track_get_key_value(i, F);
|
Variant value = a->track_get_key_value(i, F);
|
||||||
@ -742,8 +742,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double
|
|||||||
}
|
}
|
||||||
|
|
||||||
List<int> indices;
|
List<int> indices;
|
||||||
|
a->track_get_key_indices_in_range(i, p_time, p_delta, &indices, p_pingponged);
|
||||||
a->method_track_get_key_indices(i, p_time, p_delta, &indices, p_pingponged);
|
|
||||||
|
|
||||||
for (int &E : indices) {
|
for (int &E : indices) {
|
||||||
StringName method = a->method_track_get_name(i, E);
|
StringName method = a->method_track_get_name(i, E);
|
||||||
|
@ -86,7 +86,7 @@ void AnimationNode::get_child_nodes(List<ChildNode> *r_child_nodes) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimationNode::blend_animation(const StringName &p_animation, double p_time, double p_delta, bool p_seeked, bool p_seek_root, real_t p_blend, int p_pingponged) {
|
void AnimationNode::blend_animation(const StringName &p_animation, double p_time, double p_delta, bool p_seeked, bool p_is_external_seeking, real_t p_blend, int p_pingponged) {
|
||||||
ERR_FAIL_COND(!state);
|
ERR_FAIL_COND(!state);
|
||||||
ERR_FAIL_COND(!state->player->has_animation(p_animation));
|
ERR_FAIL_COND(!state->player->has_animation(p_animation));
|
||||||
|
|
||||||
@ -113,18 +113,18 @@ void AnimationNode::blend_animation(const StringName &p_animation, double p_time
|
|||||||
anim_state.animation = animation;
|
anim_state.animation = animation;
|
||||||
anim_state.seeked = p_seeked;
|
anim_state.seeked = p_seeked;
|
||||||
anim_state.pingponged = p_pingponged;
|
anim_state.pingponged = p_pingponged;
|
||||||
anim_state.seek_root = p_seek_root;
|
anim_state.is_external_seeking = p_is_external_seeking;
|
||||||
|
|
||||||
state->animation_states.push_back(anim_state);
|
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_seek_root, 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) {
|
||||||
base_path = p_base_path;
|
base_path = p_base_path;
|
||||||
parent = p_parent;
|
parent = p_parent;
|
||||||
connections = p_connections;
|
connections = p_connections;
|
||||||
state = p_state;
|
state = p_state;
|
||||||
|
|
||||||
double t = process(p_time, p_seek, p_seek_root);
|
double t = process(p_time, p_seek, p_is_external_seeking);
|
||||||
|
|
||||||
state = nullptr;
|
state = nullptr;
|
||||||
parent = nullptr;
|
parent = nullptr;
|
||||||
@ -148,7 +148,7 @@ void AnimationNode::make_invalid(const String &p_reason) {
|
|||||||
state->invalid_reasons += String::utf8("• ") + p_reason;
|
state->invalid_reasons += String::utf8("• ") + p_reason;
|
||||||
}
|
}
|
||||||
|
|
||||||
double AnimationNode::blend_input(int p_input, double p_time, bool p_seek, bool p_seek_root, 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) {
|
||||||
ERR_FAIL_INDEX_V(p_input, inputs.size(), 0);
|
ERR_FAIL_INDEX_V(p_input, inputs.size(), 0);
|
||||||
ERR_FAIL_COND_V(!state, 0);
|
ERR_FAIL_COND_V(!state, 0);
|
||||||
|
|
||||||
@ -167,7 +167,7 @@ double AnimationNode::blend_input(int p_input, double p_time, bool p_seek, bool
|
|||||||
|
|
||||||
//inputs.write[p_input].last_pass = state->last_pass;
|
//inputs.write[p_input].last_pass = state->last_pass;
|
||||||
real_t activity = 0.0;
|
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_seek_root, 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);
|
||||||
|
|
||||||
Vector<AnimationTree::Activity> *activity_ptr = state->tree->input_activity_map.getptr(base_path);
|
Vector<AnimationTree::Activity> *activity_ptr = state->tree->input_activity_map.getptr(base_path);
|
||||||
|
|
||||||
@ -178,11 +178,11 @@ double AnimationNode::blend_input(int p_input, double p_time, bool p_seek, bool
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
double AnimationNode::blend_node(const StringName &p_sub_path, Ref<AnimationNode> p_node, double p_time, bool p_seek, bool p_seek_root, real_t p_blend, FilterAction p_filter, bool 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) {
|
||||||
return _blend_node(p_sub_path, Vector<StringName>(), this, p_node, p_time, p_seek, p_seek_root, p_blend, p_filter, 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_subpath, const Vector<StringName> &p_connections, AnimationNode *p_new_parent, Ref<AnimationNode> p_node, double p_time, bool p_seek, bool p_seek_root, 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) {
|
||||||
ERR_FAIL_COND_V(!p_node.is_valid(), 0);
|
ERR_FAIL_COND_V(!p_node.is_valid(), 0);
|
||||||
ERR_FAIL_COND_V(!state, 0);
|
ERR_FAIL_COND_V(!state, 0);
|
||||||
|
|
||||||
@ -292,9 +292,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
|
// 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.
|
// that a synced AnimationNodeSync exists under the un-synced AnimationNodeSync.
|
||||||
if (!p_seek && !p_sync && !any_valid) {
|
if (!p_seek && !p_sync && !any_valid) {
|
||||||
return p_node->_pre_process(new_path, new_parent, state, 0, p_seek, p_seek_root, p_connections);
|
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, p_time, p_seek, p_seek_root, p_connections);
|
return p_node->_pre_process(new_path, new_parent, state, p_time, p_seek, p_is_external_seeking, p_connections);
|
||||||
}
|
}
|
||||||
|
|
||||||
int AnimationNode::get_input_count() const {
|
int AnimationNode::get_input_count() const {
|
||||||
@ -335,9 +335,9 @@ void AnimationNode::remove_input(int p_index) {
|
|||||||
emit_changed();
|
emit_changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
double AnimationNode::process(double p_time, bool p_seek, bool p_seek_root) {
|
double AnimationNode::process(double p_time, bool p_seek, bool p_is_external_seeking) {
|
||||||
double ret = 0;
|
double ret = 0;
|
||||||
GDVIRTUAL_CALL(_process, p_time, p_seek, p_seek_root, ret);
|
GDVIRTUAL_CALL(_process, p_time, p_seek, p_is_external_seeking, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -413,9 +413,9 @@ void AnimationNode::_bind_methods() {
|
|||||||
ClassDB::bind_method(D_METHOD("_set_filters", "filters"), &AnimationNode::_set_filters);
|
ClassDB::bind_method(D_METHOD("_set_filters", "filters"), &AnimationNode::_set_filters);
|
||||||
ClassDB::bind_method(D_METHOD("_get_filters"), &AnimationNode::_get_filters);
|
ClassDB::bind_method(D_METHOD("_get_filters"), &AnimationNode::_get_filters);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("blend_animation", "animation", "time", "delta", "seeked", "seek_root", "blend", "pingponged"), &AnimationNode::blend_animation, DEFVAL(0));
|
ClassDB::bind_method(D_METHOD("blend_animation", "animation", "time", "delta", "seeked", "is_external_seeking", "blend", "pingponged"), &AnimationNode::blend_animation, DEFVAL(0));
|
||||||
ClassDB::bind_method(D_METHOD("blend_node", "name", "node", "time", "seek", "seek_root", "blend", "filter", "sync"), &AnimationNode::blend_node, DEFVAL(FILTER_IGNORE), DEFVAL(true));
|
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", "seek_root", "blend", "filter", "sync"), &AnimationNode::blend_input, 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("set_parameter", "name", "value"), &AnimationNode::set_parameter);
|
ClassDB::bind_method(D_METHOD("set_parameter", "name", "value"), &AnimationNode::set_parameter);
|
||||||
ClassDB::bind_method(D_METHOD("get_parameter", "name"), &AnimationNode::get_parameter);
|
ClassDB::bind_method(D_METHOD("get_parameter", "name"), &AnimationNode::get_parameter);
|
||||||
@ -427,7 +427,7 @@ void AnimationNode::_bind_methods() {
|
|||||||
GDVIRTUAL_BIND(_get_parameter_list);
|
GDVIRTUAL_BIND(_get_parameter_list);
|
||||||
GDVIRTUAL_BIND(_get_child_by_name, "name");
|
GDVIRTUAL_BIND(_get_child_by_name, "name");
|
||||||
GDVIRTUAL_BIND(_get_parameter_default_value, "parameter");
|
GDVIRTUAL_BIND(_get_parameter_default_value, "parameter");
|
||||||
GDVIRTUAL_BIND(_process, "time", "seek", "seek_root");
|
GDVIRTUAL_BIND(_process, "time", "seek", "is_external_seeking");
|
||||||
GDVIRTUAL_BIND(_get_caption);
|
GDVIRTUAL_BIND(_get_caption);
|
||||||
GDVIRTUAL_BIND(_has_filter);
|
GDVIRTUAL_BIND(_has_filter);
|
||||||
|
|
||||||
@ -1007,9 +1007,10 @@ void AnimationTree::_process_graph(double p_delta) {
|
|||||||
real_t weight = as.blend;
|
real_t weight = as.blend;
|
||||||
bool seeked = as.seeked;
|
bool seeked = as.seeked;
|
||||||
int pingponged = as.pingponged;
|
int pingponged = as.pingponged;
|
||||||
|
bool is_external_seeking = as.is_external_seeking;
|
||||||
#ifndef _3D_DISABLED
|
#ifndef _3D_DISABLED
|
||||||
bool backward = signbit(delta); // This flag is required only for the root motion since it calculates the difference between the previous and current frames.
|
bool backward = signbit(delta); // This flag is required only for the root motion since it calculates the difference between the previous and current frames.
|
||||||
bool calc_root = !seeked || as.seek_root;
|
bool calc_root = !seeked || is_external_seeking;
|
||||||
#endif // _3D_DISABLED
|
#endif // _3D_DISABLED
|
||||||
|
|
||||||
for (int i = 0; i < a->get_track_count(); i++) {
|
for (int i = 0; i < a->get_track_count(); i++) {
|
||||||
@ -1368,7 +1369,7 @@ void AnimationTree::_process_graph(double p_delta) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (seeked) {
|
if (seeked) {
|
||||||
int idx = a->track_find_key(i, time);
|
int idx = a->track_find_key(i, time, !is_external_seeking);
|
||||||
if (idx < 0) {
|
if (idx < 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1377,7 +1378,7 @@ void AnimationTree::_process_graph(double p_delta) {
|
|||||||
t->object->set_indexed(t->subpath, value);
|
t->object->set_indexed(t->subpath, value);
|
||||||
} else {
|
} else {
|
||||||
List<int> indices;
|
List<int> indices;
|
||||||
a->value_track_get_key_indices(i, time, delta, &indices, pingponged);
|
a->track_get_key_indices_in_range(i, time, delta, &indices, pingponged);
|
||||||
for (int &F : indices) {
|
for (int &F : indices) {
|
||||||
Variant value = a->track_get_key_value(i, F);
|
Variant value = a->track_get_key_value(i, F);
|
||||||
value = _post_process_key_value(a, i, value, t->object);
|
value = _post_process_key_value(a, i, value, t->object);
|
||||||
@ -1391,7 +1392,7 @@ void AnimationTree::_process_graph(double p_delta) {
|
|||||||
TrackCacheMethod *t = static_cast<TrackCacheMethod *>(track);
|
TrackCacheMethod *t = static_cast<TrackCacheMethod *>(track);
|
||||||
|
|
||||||
if (seeked) {
|
if (seeked) {
|
||||||
int idx = a->track_find_key(i, time);
|
int idx = a->track_find_key(i, time, !is_external_seeking);
|
||||||
if (idx < 0) {
|
if (idx < 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1402,7 +1403,7 @@ void AnimationTree::_process_graph(double p_delta) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
List<int> indices;
|
List<int> indices;
|
||||||
a->method_track_get_key_indices(i, time, delta, &indices, pingponged);
|
a->track_get_key_indices_in_range(i, time, delta, &indices, pingponged);
|
||||||
for (int &F : indices) {
|
for (int &F : indices) {
|
||||||
StringName method = a->method_track_get_name(i, F);
|
StringName method = a->method_track_get_name(i, F);
|
||||||
Vector<Variant> params = a->method_track_get_params(i, F);
|
Vector<Variant> params = a->method_track_get_params(i, F);
|
||||||
@ -1425,7 +1426,7 @@ void AnimationTree::_process_graph(double p_delta) {
|
|||||||
|
|
||||||
if (seeked) {
|
if (seeked) {
|
||||||
//find whatever should be playing
|
//find whatever should be playing
|
||||||
int idx = a->track_find_key(i, time);
|
int idx = a->track_find_key(i, time, !is_external_seeking);
|
||||||
if (idx < 0) {
|
if (idx < 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1538,7 +1539,7 @@ void AnimationTree::_process_graph(double p_delta) {
|
|||||||
|
|
||||||
if (seeked) {
|
if (seeked) {
|
||||||
//seek
|
//seek
|
||||||
int idx = a->track_find_key(i, time);
|
int idx = a->track_find_key(i, time, !is_external_seeking);
|
||||||
if (idx < 0) {
|
if (idx < 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ public:
|
|||||||
const Vector<real_t> *track_blends = nullptr;
|
const Vector<real_t> *track_blends = nullptr;
|
||||||
real_t blend = 0.0;
|
real_t blend = 0.0;
|
||||||
bool seeked = false;
|
bool seeked = false;
|
||||||
bool seek_root = false;
|
bool is_external_seeking = false;
|
||||||
int pingponged = 0;
|
int pingponged = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -86,7 +86,7 @@ public:
|
|||||||
Vector<real_t> blends;
|
Vector<real_t> blends;
|
||||||
State *state = nullptr;
|
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_seek_root, const Vector<StringName> &p_connections);
|
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);
|
||||||
|
|
||||||
//all this is temporary
|
//all this is temporary
|
||||||
StringName base_path;
|
StringName base_path;
|
||||||
@ -99,12 +99,12 @@ public:
|
|||||||
Array _get_filters() const;
|
Array _get_filters() const;
|
||||||
void _set_filters(const Array &p_filters);
|
void _set_filters(const Array &p_filters);
|
||||||
friend class AnimationNodeBlendTree;
|
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_seek_root, 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);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void blend_animation(const StringName &p_animation, double p_time, double p_delta, bool p_seeked, bool p_seek_root, real_t p_blend, int p_pingponged = 0);
|
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, int p_pingponged = 0);
|
||||||
double blend_node(const StringName &p_sub_path, Ref<AnimationNode> p_node, double p_time, bool p_seek, bool p_seek_root, 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);
|
||||||
double blend_input(int p_input, double p_time, bool p_seek, bool p_seek_root, 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);
|
||||||
|
|
||||||
void make_invalid(const String &p_reason);
|
void make_invalid(const String &p_reason);
|
||||||
AnimationTree *get_animation_tree() const;
|
AnimationTree *get_animation_tree() const;
|
||||||
@ -135,7 +135,7 @@ public:
|
|||||||
|
|
||||||
virtual void get_child_nodes(List<ChildNode> *r_child_nodes);
|
virtual void get_child_nodes(List<ChildNode> *r_child_nodes);
|
||||||
|
|
||||||
virtual double process(double p_time, bool p_seek, bool p_seek_root);
|
virtual double process(double p_time, bool p_seek, bool p_is_external_seeking);
|
||||||
virtual String get_caption() const;
|
virtual String get_caption() const;
|
||||||
|
|
||||||
int get_input_count() const;
|
int get_input_count() const;
|
||||||
|
@ -2705,106 +2705,6 @@ Variant Animation::value_track_interpolate(int p_track, double p_time) const {
|
|||||||
return Variant();
|
return Variant();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Animation::_value_track_get_key_indices_in_range(const ValueTrack *vt, double from_time, double to_time, List<int> *p_indices) const {
|
|
||||||
if (from_time != length && to_time == length) {
|
|
||||||
to_time = length + CMP_EPSILON; //include a little more if at the end
|
|
||||||
}
|
|
||||||
int to = _find(vt->values, to_time);
|
|
||||||
|
|
||||||
if (to >= 0 && from_time == to_time && vt->values[to].time == from_time) {
|
|
||||||
//find exact (0 delta), return if found
|
|
||||||
p_indices->push_back(to);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// can't really send the events == time, will be sent in the next frame.
|
|
||||||
// if event>=len then it will probably never be requested by the anim player.
|
|
||||||
|
|
||||||
if (to >= 0 && vt->values[to].time >= to_time) {
|
|
||||||
to--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (to < 0) {
|
|
||||||
return; // not bother
|
|
||||||
}
|
|
||||||
|
|
||||||
int from = _find(vt->values, from_time);
|
|
||||||
|
|
||||||
// position in the right first event.+
|
|
||||||
if (from < 0 || vt->values[from].time < from_time) {
|
|
||||||
from++;
|
|
||||||
}
|
|
||||||
|
|
||||||
int max = vt->values.size();
|
|
||||||
|
|
||||||
for (int i = from; i <= to; i++) {
|
|
||||||
ERR_CONTINUE(i < 0 || i >= max); // shouldn't happen
|
|
||||||
p_indices->push_back(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Animation::value_track_get_key_indices(int p_track, double p_time, double p_delta, List<int> *p_indices, int p_pingponged) const {
|
|
||||||
ERR_FAIL_INDEX(p_track, tracks.size());
|
|
||||||
Track *t = tracks[p_track];
|
|
||||||
ERR_FAIL_COND(t->type != TYPE_VALUE);
|
|
||||||
|
|
||||||
ValueTrack *vt = static_cast<ValueTrack *>(t);
|
|
||||||
|
|
||||||
double from_time = p_time - p_delta;
|
|
||||||
double to_time = p_time;
|
|
||||||
|
|
||||||
if (from_time > to_time) {
|
|
||||||
SWAP(from_time, to_time);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (loop_mode) {
|
|
||||||
case LOOP_NONE: {
|
|
||||||
if (from_time < 0) {
|
|
||||||
from_time = 0;
|
|
||||||
}
|
|
||||||
if (from_time > length) {
|
|
||||||
from_time = length;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (to_time < 0) {
|
|
||||||
to_time = 0;
|
|
||||||
}
|
|
||||||
if (to_time > length) {
|
|
||||||
to_time = length;
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
case LOOP_LINEAR: {
|
|
||||||
from_time = Math::fposmod(from_time, length);
|
|
||||||
to_time = Math::fposmod(to_time, length);
|
|
||||||
|
|
||||||
if (from_time > to_time) {
|
|
||||||
// handle loop by splitting
|
|
||||||
_value_track_get_key_indices_in_range(vt, from_time, length, p_indices);
|
|
||||||
_value_track_get_key_indices_in_range(vt, 0, to_time, p_indices);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
case LOOP_PINGPONG: {
|
|
||||||
from_time = Math::pingpong(from_time, length);
|
|
||||||
to_time = Math::pingpong(to_time, length);
|
|
||||||
|
|
||||||
if (p_pingponged == -1) {
|
|
||||||
// handle loop by splitting
|
|
||||||
_value_track_get_key_indices_in_range(vt, 0, from_time, p_indices);
|
|
||||||
_value_track_get_key_indices_in_range(vt, 0, to_time, p_indices);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (p_pingponged == 1) {
|
|
||||||
// handle loop by splitting
|
|
||||||
_value_track_get_key_indices_in_range(vt, from_time, length, p_indices);
|
|
||||||
_value_track_get_key_indices_in_range(vt, to_time, length, p_indices);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
|
|
||||||
_value_track_get_key_indices_in_range(vt, from_time, to_time, p_indices);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Animation::value_track_set_update_mode(int p_track, UpdateMode p_mode) {
|
void Animation::value_track_set_update_mode(int p_track, UpdateMode p_mode) {
|
||||||
ERR_FAIL_INDEX(p_track, tracks.size());
|
ERR_FAIL_INDEX(p_track, tracks.size());
|
||||||
Track *t = tracks[p_track];
|
Track *t = tracks[p_track];
|
||||||
@ -2827,7 +2727,7 @@ Animation::UpdateMode Animation::value_track_get_update_mode(int p_track) const
|
|||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void Animation::_track_get_key_indices_in_range(const Vector<T> &p_array, double from_time, double to_time, List<int> *p_indices) const {
|
void Animation::_track_get_key_indices_in_range(const Vector<T> &p_array, double from_time, double to_time, List<int> *p_indices) const {
|
||||||
if (from_time != length && to_time == length) {
|
if (to_time == length) {
|
||||||
to_time = length + CMP_EPSILON; //include a little more if at the end
|
to_time = length + CMP_EPSILON; //include a little more if at the end
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2861,6 +2761,11 @@ void Animation::_track_get_key_indices_in_range(const Vector<T> &p_array, double
|
|||||||
|
|
||||||
void Animation::track_get_key_indices_in_range(int p_track, double p_time, double p_delta, List<int> *p_indices, int p_pingponged) const {
|
void Animation::track_get_key_indices_in_range(int p_track, double p_time, double p_delta, List<int> *p_indices, int p_pingponged) const {
|
||||||
ERR_FAIL_INDEX(p_track, tracks.size());
|
ERR_FAIL_INDEX(p_track, tracks.size());
|
||||||
|
|
||||||
|
if (p_delta == 0) {
|
||||||
|
return; // Prevent to get key continuously.
|
||||||
|
}
|
||||||
|
|
||||||
const Track *t = tracks[p_track];
|
const Track *t = tracks[p_track];
|
||||||
|
|
||||||
double from_time = p_time - p_delta;
|
double from_time = p_time - p_delta;
|
||||||
@ -2977,86 +2882,88 @@ void Animation::track_get_key_indices_in_range(int p_track, double p_time, doubl
|
|||||||
if ((int)Math::floor(abs(p_delta) / length) % 2 == 0) {
|
if ((int)Math::floor(abs(p_delta) / length) % 2 == 0) {
|
||||||
if (p_pingponged == -1) {
|
if (p_pingponged == -1) {
|
||||||
// handle loop by splitting
|
// handle loop by splitting
|
||||||
|
to_time = MAX(CMP_EPSILON, to_time); // To avoid overlapping keys at the turnaround point, one of the point will needs to be shifted slightly.
|
||||||
switch (t->type) {
|
switch (t->type) {
|
||||||
case TYPE_POSITION_3D: {
|
case TYPE_POSITION_3D: {
|
||||||
const PositionTrack *tt = static_cast<const PositionTrack *>(t);
|
const PositionTrack *tt = static_cast<const PositionTrack *>(t);
|
||||||
if (tt->compressed_track >= 0) {
|
if (tt->compressed_track >= 0) {
|
||||||
_get_compressed_key_indices_in_range<3>(tt->compressed_track, 0, from_time, p_indices);
|
_get_compressed_key_indices_in_range<3>(tt->compressed_track, 0, from_time, p_indices);
|
||||||
_get_compressed_key_indices_in_range<3>(tt->compressed_track, 0, to_time, p_indices);
|
_get_compressed_key_indices_in_range<3>(tt->compressed_track, CMP_EPSILON, to_time, p_indices);
|
||||||
} else {
|
} else {
|
||||||
_track_get_key_indices_in_range(tt->positions, 0, from_time, p_indices);
|
_track_get_key_indices_in_range(tt->positions, 0, from_time, p_indices);
|
||||||
_track_get_key_indices_in_range(tt->positions, 0, to_time, p_indices);
|
_track_get_key_indices_in_range(tt->positions, CMP_EPSILON, to_time, p_indices);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case TYPE_ROTATION_3D: {
|
case TYPE_ROTATION_3D: {
|
||||||
const RotationTrack *rt = static_cast<const RotationTrack *>(t);
|
const RotationTrack *rt = static_cast<const RotationTrack *>(t);
|
||||||
if (rt->compressed_track >= 0) {
|
if (rt->compressed_track >= 0) {
|
||||||
_get_compressed_key_indices_in_range<3>(rt->compressed_track, 0, from_time, p_indices);
|
_get_compressed_key_indices_in_range<3>(rt->compressed_track, 0, from_time, p_indices);
|
||||||
_get_compressed_key_indices_in_range<3>(rt->compressed_track, 0, to_time, p_indices);
|
_get_compressed_key_indices_in_range<3>(rt->compressed_track, CMP_EPSILON, to_time, p_indices);
|
||||||
} else {
|
} else {
|
||||||
_track_get_key_indices_in_range(rt->rotations, 0, from_time, p_indices);
|
_track_get_key_indices_in_range(rt->rotations, 0, from_time, p_indices);
|
||||||
_track_get_key_indices_in_range(rt->rotations, 0, to_time, p_indices);
|
_track_get_key_indices_in_range(rt->rotations, CMP_EPSILON, to_time, p_indices);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case TYPE_SCALE_3D: {
|
case TYPE_SCALE_3D: {
|
||||||
const ScaleTrack *st = static_cast<const ScaleTrack *>(t);
|
const ScaleTrack *st = static_cast<const ScaleTrack *>(t);
|
||||||
if (st->compressed_track >= 0) {
|
if (st->compressed_track >= 0) {
|
||||||
_get_compressed_key_indices_in_range<3>(st->compressed_track, 0, from_time, p_indices);
|
_get_compressed_key_indices_in_range<3>(st->compressed_track, 0, from_time, p_indices);
|
||||||
_get_compressed_key_indices_in_range<3>(st->compressed_track, 0, to_time, p_indices);
|
_get_compressed_key_indices_in_range<3>(st->compressed_track, CMP_EPSILON, to_time, p_indices);
|
||||||
} else {
|
} else {
|
||||||
_track_get_key_indices_in_range(st->scales, 0, from_time, p_indices);
|
_track_get_key_indices_in_range(st->scales, 0, from_time, p_indices);
|
||||||
_track_get_key_indices_in_range(st->scales, 0, to_time, p_indices);
|
_track_get_key_indices_in_range(st->scales, CMP_EPSILON, to_time, p_indices);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case TYPE_BLEND_SHAPE: {
|
case TYPE_BLEND_SHAPE: {
|
||||||
const BlendShapeTrack *bst = static_cast<const BlendShapeTrack *>(t);
|
const BlendShapeTrack *bst = static_cast<const BlendShapeTrack *>(t);
|
||||||
if (bst->compressed_track >= 0) {
|
if (bst->compressed_track >= 0) {
|
||||||
_get_compressed_key_indices_in_range<1>(bst->compressed_track, 0, from_time, p_indices);
|
_get_compressed_key_indices_in_range<1>(bst->compressed_track, 0, from_time, p_indices);
|
||||||
_get_compressed_key_indices_in_range<1>(bst->compressed_track, 0, to_time, p_indices);
|
_get_compressed_key_indices_in_range<1>(bst->compressed_track, CMP_EPSILON, to_time, p_indices);
|
||||||
} else {
|
} else {
|
||||||
_track_get_key_indices_in_range(bst->blend_shapes, 0, from_time, p_indices);
|
_track_get_key_indices_in_range(bst->blend_shapes, 0, from_time, p_indices);
|
||||||
_track_get_key_indices_in_range(bst->blend_shapes, 0, to_time, p_indices);
|
_track_get_key_indices_in_range(bst->blend_shapes, CMP_EPSILON, to_time, p_indices);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case TYPE_VALUE: {
|
case TYPE_VALUE: {
|
||||||
const ValueTrack *vt = static_cast<const ValueTrack *>(t);
|
const ValueTrack *vt = static_cast<const ValueTrack *>(t);
|
||||||
_track_get_key_indices_in_range(vt->values, 0, from_time, p_indices);
|
_track_get_key_indices_in_range(vt->values, 0, from_time, p_indices);
|
||||||
_track_get_key_indices_in_range(vt->values, 0, to_time, p_indices);
|
_track_get_key_indices_in_range(vt->values, CMP_EPSILON, to_time, p_indices);
|
||||||
} break;
|
} break;
|
||||||
case TYPE_METHOD: {
|
case TYPE_METHOD: {
|
||||||
const MethodTrack *mt = static_cast<const MethodTrack *>(t);
|
const MethodTrack *mt = static_cast<const MethodTrack *>(t);
|
||||||
_track_get_key_indices_in_range(mt->methods, 0, from_time, p_indices);
|
_track_get_key_indices_in_range(mt->methods, 0, from_time, p_indices);
|
||||||
_track_get_key_indices_in_range(mt->methods, 0, to_time, p_indices);
|
_track_get_key_indices_in_range(mt->methods, CMP_EPSILON, to_time, p_indices);
|
||||||
} break;
|
} break;
|
||||||
case TYPE_BEZIER: {
|
case TYPE_BEZIER: {
|
||||||
const BezierTrack *bz = static_cast<const BezierTrack *>(t);
|
const BezierTrack *bz = static_cast<const BezierTrack *>(t);
|
||||||
_track_get_key_indices_in_range(bz->values, 0, from_time, p_indices);
|
_track_get_key_indices_in_range(bz->values, 0, from_time, p_indices);
|
||||||
_track_get_key_indices_in_range(bz->values, 0, to_time, p_indices);
|
_track_get_key_indices_in_range(bz->values, CMP_EPSILON, to_time, p_indices);
|
||||||
} break;
|
} break;
|
||||||
case TYPE_AUDIO: {
|
case TYPE_AUDIO: {
|
||||||
const AudioTrack *ad = static_cast<const AudioTrack *>(t);
|
const AudioTrack *ad = static_cast<const AudioTrack *>(t);
|
||||||
_track_get_key_indices_in_range(ad->values, 0, from_time, p_indices);
|
_track_get_key_indices_in_range(ad->values, 0, from_time, p_indices);
|
||||||
_track_get_key_indices_in_range(ad->values, 0, to_time, p_indices);
|
_track_get_key_indices_in_range(ad->values, CMP_EPSILON, to_time, p_indices);
|
||||||
} break;
|
} break;
|
||||||
case TYPE_ANIMATION: {
|
case TYPE_ANIMATION: {
|
||||||
const AnimationTrack *an = static_cast<const AnimationTrack *>(t);
|
const AnimationTrack *an = static_cast<const AnimationTrack *>(t);
|
||||||
_track_get_key_indices_in_range(an->values, 0, from_time, p_indices);
|
_track_get_key_indices_in_range(an->values, 0, from_time, p_indices);
|
||||||
_track_get_key_indices_in_range(an->values, 0, to_time, p_indices);
|
_track_get_key_indices_in_range(an->values, CMP_EPSILON, to_time, p_indices);
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (p_pingponged == 1) {
|
if (p_pingponged == 1) {
|
||||||
// handle loop by splitting
|
// handle loop by splitting
|
||||||
|
to_time = MIN(length - CMP_EPSILON, to_time);
|
||||||
switch (t->type) {
|
switch (t->type) {
|
||||||
case TYPE_POSITION_3D: {
|
case TYPE_POSITION_3D: {
|
||||||
const PositionTrack *tt = static_cast<const PositionTrack *>(t);
|
const PositionTrack *tt = static_cast<const PositionTrack *>(t);
|
||||||
if (tt->compressed_track >= 0) {
|
if (tt->compressed_track >= 0) {
|
||||||
_get_compressed_key_indices_in_range<3>(tt->compressed_track, from_time, length, p_indices);
|
_get_compressed_key_indices_in_range<3>(tt->compressed_track, from_time, length, p_indices);
|
||||||
_get_compressed_key_indices_in_range<3>(tt->compressed_track, to_time, length, p_indices);
|
_get_compressed_key_indices_in_range<3>(tt->compressed_track, to_time, length - CMP_EPSILON, p_indices);
|
||||||
} else {
|
} else {
|
||||||
_track_get_key_indices_in_range(tt->positions, from_time, length, p_indices);
|
_track_get_key_indices_in_range(tt->positions, from_time, length, p_indices);
|
||||||
_track_get_key_indices_in_range(tt->positions, to_time, length, p_indices);
|
_track_get_key_indices_in_range(tt->positions, to_time, length - CMP_EPSILON, p_indices);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case TYPE_ROTATION_3D: {
|
case TYPE_ROTATION_3D: {
|
||||||
@ -3066,7 +2973,7 @@ void Animation::track_get_key_indices_in_range(int p_track, double p_time, doubl
|
|||||||
_get_compressed_key_indices_in_range<3>(rt->compressed_track, to_time, length, p_indices);
|
_get_compressed_key_indices_in_range<3>(rt->compressed_track, to_time, length, p_indices);
|
||||||
} else {
|
} else {
|
||||||
_track_get_key_indices_in_range(rt->rotations, from_time, length, p_indices);
|
_track_get_key_indices_in_range(rt->rotations, from_time, length, p_indices);
|
||||||
_track_get_key_indices_in_range(rt->rotations, to_time, length, p_indices);
|
_track_get_key_indices_in_range(rt->rotations, to_time, length - CMP_EPSILON, p_indices);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case TYPE_SCALE_3D: {
|
case TYPE_SCALE_3D: {
|
||||||
@ -3076,43 +2983,43 @@ void Animation::track_get_key_indices_in_range(int p_track, double p_time, doubl
|
|||||||
_get_compressed_key_indices_in_range<3>(st->compressed_track, to_time, length, p_indices);
|
_get_compressed_key_indices_in_range<3>(st->compressed_track, to_time, length, p_indices);
|
||||||
} else {
|
} else {
|
||||||
_track_get_key_indices_in_range(st->scales, from_time, length, p_indices);
|
_track_get_key_indices_in_range(st->scales, from_time, length, p_indices);
|
||||||
_track_get_key_indices_in_range(st->scales, to_time, length, p_indices);
|
_track_get_key_indices_in_range(st->scales, to_time, length - CMP_EPSILON, p_indices);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case TYPE_BLEND_SHAPE: {
|
case TYPE_BLEND_SHAPE: {
|
||||||
const BlendShapeTrack *bst = static_cast<const BlendShapeTrack *>(t);
|
const BlendShapeTrack *bst = static_cast<const BlendShapeTrack *>(t);
|
||||||
if (bst->compressed_track >= 0) {
|
if (bst->compressed_track >= 0) {
|
||||||
_get_compressed_key_indices_in_range<1>(bst->compressed_track, from_time, length, p_indices);
|
_get_compressed_key_indices_in_range<1>(bst->compressed_track, from_time, length, p_indices);
|
||||||
_get_compressed_key_indices_in_range<1>(bst->compressed_track, to_time, length, p_indices);
|
_get_compressed_key_indices_in_range<1>(bst->compressed_track, to_time, length - CMP_EPSILON, p_indices);
|
||||||
} else {
|
} else {
|
||||||
_track_get_key_indices_in_range(bst->blend_shapes, from_time, length, p_indices);
|
_track_get_key_indices_in_range(bst->blend_shapes, from_time, length, p_indices);
|
||||||
_track_get_key_indices_in_range(bst->blend_shapes, to_time, length, p_indices);
|
_track_get_key_indices_in_range(bst->blend_shapes, to_time, length - CMP_EPSILON, p_indices);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case TYPE_VALUE: {
|
case TYPE_VALUE: {
|
||||||
const ValueTrack *vt = static_cast<const ValueTrack *>(t);
|
const ValueTrack *vt = static_cast<const ValueTrack *>(t);
|
||||||
_track_get_key_indices_in_range(vt->values, from_time, length, p_indices);
|
_track_get_key_indices_in_range(vt->values, from_time, length, p_indices);
|
||||||
_track_get_key_indices_in_range(vt->values, to_time, length, p_indices);
|
_track_get_key_indices_in_range(vt->values, to_time, length - CMP_EPSILON, p_indices);
|
||||||
} break;
|
} break;
|
||||||
case TYPE_METHOD: {
|
case TYPE_METHOD: {
|
||||||
const MethodTrack *mt = static_cast<const MethodTrack *>(t);
|
const MethodTrack *mt = static_cast<const MethodTrack *>(t);
|
||||||
_track_get_key_indices_in_range(mt->methods, from_time, length, p_indices);
|
_track_get_key_indices_in_range(mt->methods, from_time, length, p_indices);
|
||||||
_track_get_key_indices_in_range(mt->methods, to_time, length, p_indices);
|
_track_get_key_indices_in_range(mt->methods, to_time, length - CMP_EPSILON, p_indices);
|
||||||
} break;
|
} break;
|
||||||
case TYPE_BEZIER: {
|
case TYPE_BEZIER: {
|
||||||
const BezierTrack *bz = static_cast<const BezierTrack *>(t);
|
const BezierTrack *bz = static_cast<const BezierTrack *>(t);
|
||||||
_track_get_key_indices_in_range(bz->values, from_time, length, p_indices);
|
_track_get_key_indices_in_range(bz->values, from_time, length, p_indices);
|
||||||
_track_get_key_indices_in_range(bz->values, to_time, length, p_indices);
|
_track_get_key_indices_in_range(bz->values, to_time, length - CMP_EPSILON, p_indices);
|
||||||
} break;
|
} break;
|
||||||
case TYPE_AUDIO: {
|
case TYPE_AUDIO: {
|
||||||
const AudioTrack *ad = static_cast<const AudioTrack *>(t);
|
const AudioTrack *ad = static_cast<const AudioTrack *>(t);
|
||||||
_track_get_key_indices_in_range(ad->values, from_time, length, p_indices);
|
_track_get_key_indices_in_range(ad->values, from_time, length, p_indices);
|
||||||
_track_get_key_indices_in_range(ad->values, to_time, length, p_indices);
|
_track_get_key_indices_in_range(ad->values, to_time, length - CMP_EPSILON, p_indices);
|
||||||
} break;
|
} break;
|
||||||
case TYPE_ANIMATION: {
|
case TYPE_ANIMATION: {
|
||||||
const AnimationTrack *an = static_cast<const AnimationTrack *>(t);
|
const AnimationTrack *an = static_cast<const AnimationTrack *>(t);
|
||||||
_track_get_key_indices_in_range(an->values, from_time, length, p_indices);
|
_track_get_key_indices_in_range(an->values, from_time, length, p_indices);
|
||||||
_track_get_key_indices_in_range(an->values, to_time, length, p_indices);
|
_track_get_key_indices_in_range(an->values, to_time, length - CMP_EPSILON, p_indices);
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -3177,110 +3084,6 @@ void Animation::track_get_key_indices_in_range(int p_track, double p_time, doubl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Animation::_method_track_get_key_indices_in_range(const MethodTrack *mt, double from_time, double to_time, List<int> *p_indices) const {
|
|
||||||
if (from_time != length && to_time == length) {
|
|
||||||
to_time = length + CMP_EPSILON; //include a little more if at the end
|
|
||||||
}
|
|
||||||
|
|
||||||
int to = _find(mt->methods, to_time);
|
|
||||||
|
|
||||||
// can't really send the events == time, will be sent in the next frame.
|
|
||||||
// if event>=len then it will probably never be requested by the anim player.
|
|
||||||
|
|
||||||
if (to >= 0 && mt->methods[to].time >= to_time) {
|
|
||||||
to--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (to < 0) {
|
|
||||||
return; // not bother
|
|
||||||
}
|
|
||||||
|
|
||||||
int from = _find(mt->methods, from_time);
|
|
||||||
|
|
||||||
// position in the right first event.+
|
|
||||||
if (from < 0 || mt->methods[from].time < from_time) {
|
|
||||||
from++;
|
|
||||||
}
|
|
||||||
|
|
||||||
int max = mt->methods.size();
|
|
||||||
|
|
||||||
for (int i = from; i <= to; i++) {
|
|
||||||
ERR_CONTINUE(i < 0 || i >= max); // shouldn't happen
|
|
||||||
p_indices->push_back(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Animation::method_track_get_key_indices(int p_track, double p_time, double p_delta, List<int> *p_indices, int p_pingponged) const {
|
|
||||||
ERR_FAIL_INDEX(p_track, tracks.size());
|
|
||||||
Track *t = tracks[p_track];
|
|
||||||
ERR_FAIL_COND(t->type != TYPE_METHOD);
|
|
||||||
|
|
||||||
MethodTrack *mt = static_cast<MethodTrack *>(t);
|
|
||||||
|
|
||||||
double from_time = p_time - p_delta;
|
|
||||||
double to_time = p_time;
|
|
||||||
|
|
||||||
if (from_time > to_time) {
|
|
||||||
SWAP(from_time, to_time);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (loop_mode) {
|
|
||||||
case LOOP_NONE: {
|
|
||||||
if (from_time < 0) {
|
|
||||||
from_time = 0;
|
|
||||||
}
|
|
||||||
if (from_time > length) {
|
|
||||||
from_time = length;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (to_time < 0) {
|
|
||||||
to_time = 0;
|
|
||||||
}
|
|
||||||
if (to_time > length) {
|
|
||||||
to_time = length;
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
case LOOP_LINEAR: {
|
|
||||||
if (from_time > length || from_time < 0) {
|
|
||||||
from_time = Math::fposmod(from_time, length);
|
|
||||||
}
|
|
||||||
if (to_time > length || to_time < 0) {
|
|
||||||
to_time = Math::fposmod(to_time, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (from_time > to_time) {
|
|
||||||
// handle loop by splitting
|
|
||||||
_method_track_get_key_indices_in_range(mt, from_time, length, p_indices);
|
|
||||||
_method_track_get_key_indices_in_range(mt, 0, to_time, p_indices);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
case LOOP_PINGPONG: {
|
|
||||||
if (from_time > length || from_time < 0) {
|
|
||||||
from_time = Math::pingpong(from_time, length);
|
|
||||||
}
|
|
||||||
if (to_time > length || to_time < 0) {
|
|
||||||
to_time = Math::pingpong(to_time, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p_pingponged == -1) {
|
|
||||||
_method_track_get_key_indices_in_range(mt, 0, from_time, p_indices);
|
|
||||||
_method_track_get_key_indices_in_range(mt, 0, to_time, p_indices);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (p_pingponged == 1) {
|
|
||||||
_method_track_get_key_indices_in_range(mt, from_time, length, p_indices);
|
|
||||||
_method_track_get_key_indices_in_range(mt, to_time, length, p_indices);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
_method_track_get_key_indices_in_range(mt, from_time, to_time, p_indices);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector<Variant> Animation::method_track_get_params(int p_track, int p_key_idx) const {
|
Vector<Variant> Animation::method_track_get_params(int p_track, int p_key_idx) const {
|
||||||
ERR_FAIL_INDEX_V(p_track, tracks.size(), Vector<Variant>());
|
ERR_FAIL_INDEX_V(p_track, tracks.size(), Vector<Variant>());
|
||||||
Track *t = tracks[p_track];
|
Track *t = tracks[p_track];
|
||||||
@ -3941,10 +3744,8 @@ void Animation::_bind_methods() {
|
|||||||
ClassDB::bind_method(D_METHOD("value_track_set_update_mode", "track_idx", "mode"), &Animation::value_track_set_update_mode);
|
ClassDB::bind_method(D_METHOD("value_track_set_update_mode", "track_idx", "mode"), &Animation::value_track_set_update_mode);
|
||||||
ClassDB::bind_method(D_METHOD("value_track_get_update_mode", "track_idx"), &Animation::value_track_get_update_mode);
|
ClassDB::bind_method(D_METHOD("value_track_get_update_mode", "track_idx"), &Animation::value_track_get_update_mode);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("value_track_get_key_indices", "track_idx", "time_sec", "delta"), &Animation::_value_track_get_key_indices);
|
|
||||||
ClassDB::bind_method(D_METHOD("value_track_interpolate", "track_idx", "time_sec"), &Animation::value_track_interpolate);
|
ClassDB::bind_method(D_METHOD("value_track_interpolate", "track_idx", "time_sec"), &Animation::value_track_interpolate);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("method_track_get_key_indices", "track_idx", "time_sec", "delta"), &Animation::_method_track_get_key_indices);
|
|
||||||
ClassDB::bind_method(D_METHOD("method_track_get_name", "track_idx", "key_idx"), &Animation::method_track_get_name);
|
ClassDB::bind_method(D_METHOD("method_track_get_name", "track_idx", "key_idx"), &Animation::method_track_get_name);
|
||||||
ClassDB::bind_method(D_METHOD("method_track_get_params", "track_idx", "key_idx"), &Animation::method_track_get_params);
|
ClassDB::bind_method(D_METHOD("method_track_get_params", "track_idx", "key_idx"), &Animation::method_track_get_params);
|
||||||
|
|
||||||
|
@ -252,9 +252,6 @@ private:
|
|||||||
template <class T>
|
template <class T>
|
||||||
_FORCE_INLINE_ void _track_get_key_indices_in_range(const Vector<T> &p_array, double from_time, double to_time, List<int> *p_indices) const;
|
_FORCE_INLINE_ void _track_get_key_indices_in_range(const Vector<T> &p_array, double from_time, double to_time, List<int> *p_indices) const;
|
||||||
|
|
||||||
_FORCE_INLINE_ void _value_track_get_key_indices_in_range(const ValueTrack *vt, double from_time, double to_time, List<int> *p_indices) const;
|
|
||||||
_FORCE_INLINE_ void _method_track_get_key_indices_in_range(const MethodTrack *mt, double from_time, double to_time, List<int> *p_indices) const;
|
|
||||||
|
|
||||||
double length = 1.0;
|
double length = 1.0;
|
||||||
real_t step = 0.1;
|
real_t step = 0.1;
|
||||||
LoopMode loop_mode = LOOP_NONE;
|
LoopMode loop_mode = LOOP_NONE;
|
||||||
@ -345,27 +342,6 @@ private:
|
|||||||
|
|
||||||
// bind helpers
|
// bind helpers
|
||||||
private:
|
private:
|
||||||
Vector<int> _value_track_get_key_indices(int p_track, double p_time, double p_delta) const {
|
|
||||||
List<int> idxs;
|
|
||||||
value_track_get_key_indices(p_track, p_time, p_delta, &idxs);
|
|
||||||
Vector<int> idxr;
|
|
||||||
|
|
||||||
for (int &E : idxs) {
|
|
||||||
idxr.push_back(E);
|
|
||||||
}
|
|
||||||
return idxr;
|
|
||||||
}
|
|
||||||
Vector<int> _method_track_get_key_indices(int p_track, double p_time, double p_delta) const {
|
|
||||||
List<int> idxs;
|
|
||||||
method_track_get_key_indices(p_track, p_time, p_delta, &idxs);
|
|
||||||
Vector<int> idxr;
|
|
||||||
|
|
||||||
for (int &E : idxs) {
|
|
||||||
idxr.push_back(E);
|
|
||||||
}
|
|
||||||
return idxr;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool _float_track_optimize_key(const TKey<float> t0, const TKey<float> t1, const TKey<float> t2, real_t p_allowed_velocity_err, real_t p_allowed_precision_error);
|
bool _float_track_optimize_key(const TKey<float> t0, const TKey<float> t1, const TKey<float> t2, real_t p_allowed_velocity_err, real_t p_allowed_precision_error);
|
||||||
bool _vector2_track_optimize_key(const TKey<Vector2> t0, const TKey<Vector2> t1, const TKey<Vector2> t2, real_t p_alowed_velocity_err, real_t p_allowed_angular_error, real_t p_allowed_precision_error);
|
bool _vector2_track_optimize_key(const TKey<Vector2> t0, const TKey<Vector2> t1, const TKey<Vector2> t2, real_t p_alowed_velocity_err, real_t p_allowed_angular_error, real_t p_allowed_precision_error);
|
||||||
bool _vector3_track_optimize_key(const TKey<Vector3> t0, const TKey<Vector3> t1, const TKey<Vector3> t2, real_t p_alowed_velocity_err, real_t p_allowed_angular_error, real_t p_allowed_precision_error);
|
bool _vector3_track_optimize_key(const TKey<Vector3> t0, const TKey<Vector3> t1, const TKey<Vector3> t2, real_t p_alowed_velocity_err, real_t p_allowed_angular_error, real_t p_allowed_precision_error);
|
||||||
@ -470,11 +446,9 @@ public:
|
|||||||
bool track_get_interpolation_loop_wrap(int p_track) const;
|
bool track_get_interpolation_loop_wrap(int p_track) const;
|
||||||
|
|
||||||
Variant value_track_interpolate(int p_track, double p_time) const;
|
Variant value_track_interpolate(int p_track, double p_time) const;
|
||||||
void value_track_get_key_indices(int p_track, double p_time, double p_delta, List<int> *p_indices, int p_pingponged = 0) const;
|
|
||||||
void value_track_set_update_mode(int p_track, UpdateMode p_mode);
|
void value_track_set_update_mode(int p_track, UpdateMode p_mode);
|
||||||
UpdateMode value_track_get_update_mode(int p_track) const;
|
UpdateMode value_track_get_update_mode(int p_track) const;
|
||||||
|
|
||||||
void method_track_get_key_indices(int p_track, double p_time, double p_delta, List<int> *p_indices, int p_pingponged = 0) const;
|
|
||||||
Vector<Variant> method_track_get_params(int p_track, int p_key_idx) const;
|
Vector<Variant> method_track_get_params(int p_track, int p_key_idx) const;
|
||||||
StringName method_track_get_name(int p_track, int p_key_idx) const;
|
StringName method_track_get_name(int p_track, int p_key_idx) const;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user