summaryrefslogtreecommitdiff
path: root/scene/animation
diff options
context:
space:
mode:
Diffstat (limited to 'scene/animation')
-rw-r--r--scene/animation/animation_node_state_machine.cpp32
-rw-r--r--scene/animation/animation_node_state_machine.h9
-rw-r--r--scene/animation/animation_player.cpp49
-rw-r--r--scene/animation/animation_player.h2
-rw-r--r--scene/animation/animation_tree.cpp78
-rw-r--r--scene/animation/animation_tree.h2
6 files changed, 120 insertions, 52 deletions
diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp
index 02f1e9f9a6..7fb831b3b2 100644
--- a/scene/animation/animation_node_state_machine.cpp
+++ b/scene/animation/animation_node_state_machine.cpp
@@ -228,6 +228,22 @@ float AnimationNodeStateMachinePlayback::get_current_length() const {
return len_current;
}
+float AnimationNodeStateMachinePlayback::get_fade_from_play_pos() const {
+ return pos_fade_from;
+}
+
+float AnimationNodeStateMachinePlayback::get_fade_from_length() const {
+ return len_fade_from;
+}
+
+float AnimationNodeStateMachinePlayback::get_fading_time() const {
+ return fading_time;
+}
+
+float AnimationNodeStateMachinePlayback::get_fading_pos() const {
+ return fading_pos;
+}
+
bool AnimationNodeStateMachinePlayback::_travel(AnimationNodeStateMachine *p_state_machine, const StringName &p_travel) {
ERR_FAIL_COND_V(!playing, false);
ERR_FAIL_COND_V(!p_state_machine->states.has(p_travel), false);
@@ -466,7 +482,17 @@ double AnimationNodeStateMachinePlayback::_process(AnimationNodeStateMachine *p_
if (fading_from != StringName()) {
double fade_blend_inv = 1.0 - fade_blend;
- p_state_machine->blend_node(fading_from, p_state_machine->states[fading_from].node, p_time, p_seek, p_is_external_seeking, Math::is_zero_approx(fade_blend_inv) ? CMP_EPSILON : fade_blend_inv, AnimationNode::FILTER_IGNORE, true); // Blend values must be more than CMP_EPSILON to process discrete keys in edge.
+ float fading_from_rem = 0.0;
+ fading_from_rem = p_state_machine->blend_node(fading_from, p_state_machine->states[fading_from].node, p_time, p_seek, p_is_external_seeking, Math::is_zero_approx(fade_blend_inv) ? CMP_EPSILON : fade_blend_inv, AnimationNode::FILTER_IGNORE, true); // Blend values must be more than CMP_EPSILON to process discrete keys in edge.
+ //guess playback position
+ if (fading_from_rem > len_fade_from) { // weird but ok
+ len_fade_from = fading_from_rem;
+ }
+
+ { //advance and loop check
+ float next_pos = len_fade_from - fading_from_rem;
+ pos_fade_from = next_pos; //looped
+ }
if (fade_blend >= 1.0) {
fading_from = StringName();
}
@@ -633,6 +659,8 @@ double AnimationNodeStateMachinePlayback::_process(AnimationNodeStateMachine *p_
}
current = next;
+ pos_fade_from = pos_current;
+ len_fade_from = len_current;
if (reset_request) {
len_current = p_state_machine->blend_node(current, p_state_machine->states[current].node, 0, true, p_is_external_seeking, CMP_EPSILON, AnimationNode::FILTER_IGNORE, true); // Process next node's first key in here.
@@ -716,7 +744,7 @@ AnimationNodeStateMachinePlayback::AnimationNodeStateMachinePlayback() {
///////////////////////////////////////////////////////
void AnimationNodeStateMachine::get_parameter_list(List<PropertyInfo> *r_list) const {
- r_list->push_back(PropertyInfo(Variant::OBJECT, playback, PROPERTY_HINT_RESOURCE_TYPE, "AnimationNodeStateMachinePlayback", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE));
+ r_list->push_back(PropertyInfo(Variant::OBJECT, playback, PROPERTY_HINT_RESOURCE_TYPE, "AnimationNodeStateMachinePlayback", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_ALWAYS_DUPLICATE));
List<StringName> advance_conditions;
for (int i = 0; i < transitions.size(); i++) {
StringName ac = transitions[i].transition->get_advance_condition_name();
diff --git a/scene/animation/animation_node_state_machine.h b/scene/animation/animation_node_state_machine.h
index 1b4e010a06..cf4d850aa6 100644
--- a/scene/animation/animation_node_state_machine.h
+++ b/scene/animation/animation_node_state_machine.h
@@ -118,6 +118,9 @@ class AnimationNodeStateMachinePlayback : public Resource {
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;
@@ -164,6 +167,12 @@ public:
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();
};
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index 047997ca09..77d82990d1 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -451,6 +451,15 @@ static void _call_object(Object *p_object, const StringName &p_method, const Vec
}
}
+Variant AnimationPlayer::post_process_key_value(const Ref<Animation> &p_anim, int p_track, Variant p_value, const Object *p_object, int p_object_idx) {
+ Variant res;
+ if (GDVIRTUAL_CALL(_post_process_key_value, p_anim, p_track, p_value, const_cast<Object *>(p_object), p_object_idx, res)) {
+ return res;
+ }
+
+ return _post_process_key_value(p_anim, p_track, p_value, p_object, p_object_idx);
+}
+
Variant AnimationPlayer::_post_process_key_value(const Ref<Animation> &p_anim, int p_track, Variant p_value, const Object *p_object, int p_object_idx) {
switch (p_anim->track_get_type(p_track)) {
#ifndef _3D_DISABLED
@@ -473,7 +482,9 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double
ERR_FAIL_COND(p_anim->node_cache.size() != p_anim->animation->get_track_count());
Animation *a = p_anim->animation.operator->();
+#ifdef TOOLS_ENABLED
bool can_call = is_inside_tree() && !Engine::get_singleton()->is_editor_hint();
+#endif // TOOLS_ENABLED
bool backward = signbit(p_delta);
for (int i = 0; i < a->get_track_count(); i++) {
@@ -512,7 +523,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double
if (err != OK) {
continue;
}
- loc = _post_process_key_value(a, i, loc, nc->node_3d, nc->bone_idx);
+ loc = post_process_key_value(a, i, loc, nc->node_3d, nc->bone_idx);
if (nc->accum_pass != accum_pass) {
ERR_CONTINUE(cache_update_size >= NODE_CACHE_UPDATE_MAX);
@@ -540,7 +551,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double
if (err != OK) {
continue;
}
- rot = _post_process_key_value(a, i, rot, nc->node_3d, nc->bone_idx);
+ rot = post_process_key_value(a, i, rot, nc->node_3d, nc->bone_idx);
if (nc->accum_pass != accum_pass) {
ERR_CONTINUE(cache_update_size >= NODE_CACHE_UPDATE_MAX);
@@ -568,7 +579,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double
if (err != OK) {
continue;
}
- scale = _post_process_key_value(a, i, scale, nc->node_3d, nc->bone_idx);
+ scale = post_process_key_value(a, i, scale, nc->node_3d, nc->bone_idx);
if (nc->accum_pass != accum_pass) {
ERR_CONTINUE(cache_update_size >= NODE_CACHE_UPDATE_MAX);
@@ -596,7 +607,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double
if (err != OK) {
continue;
}
- blend = _post_process_key_value(a, i, blend, nc->node_blend_shape, nc->blend_shape_idx);
+ blend = post_process_key_value(a, i, blend, nc->node_blend_shape, nc->blend_shape_idx);
if (nc->accum_pass != accum_pass) {
ERR_CONTINUE(cache_update_size >= NODE_CACHE_UPDATE_MAX);
@@ -649,7 +660,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double
if (p_time < first_key_time) {
double c = Math::ease(p_time / first_key_time, transition);
Variant first_value = a->track_get_key_value(i, first_key);
- first_value = _post_process_key_value(a, i, first_value, nc->node);
+ first_value = post_process_key_value(a, i, first_value, nc->node);
Variant interp_value = Animation::interpolate_variant(pa->capture, first_value, c);
if (pa->accum_pass != accum_pass) {
ERR_CONTINUE(cache_update_prop_size >= NODE_CACHE_UPDATE_MAX);
@@ -670,7 +681,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double
if (value == Variant()) {
continue;
}
- value = _post_process_key_value(a, i, value, nc->node);
+ value = post_process_key_value(a, i, value, nc->node);
if (pa->accum_pass != accum_pass) {
ERR_CONTINUE(cache_update_prop_size >= NODE_CACHE_UPDATE_MAX);
@@ -701,7 +712,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double
for (int &F : indices) {
Variant value = a->track_get_key_value(i, F);
- value = _post_process_key_value(a, i, value, nc->node);
+ value = post_process_key_value(a, i, value, nc->node);
switch (pa->special) {
case SP_NONE: {
bool valid;
@@ -745,11 +756,13 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double
} break;
case Animation::TYPE_METHOD: {
- if (!nc->node || is_stopping) {
+#ifdef TOOLS_ENABLED
+ if (!can_call) {
continue;
}
- if (!p_is_current) {
- break;
+#endif // TOOLS_ENABLED
+ if (!p_is_current || !nc->node || is_stopping) {
+ continue;
}
List<int> indices;
@@ -772,16 +785,12 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double
for (int &E : indices) {
StringName method = a->method_track_get_name(i, E);
Vector<Variant> params = a->method_track_get_params(i, E);
-
#ifdef DEBUG_ENABLED
if (!nc->node->has_method(method)) {
ERR_PRINT("Invalid method call '" + method + "'. '" + a->get_name() + "' at node '" + get_path() + "'.");
}
#endif
-
- if (can_call) {
- _call_object(nc->node, method, params, method_call_mode == ANIMATION_METHOD_CALL_DEFERRED);
- }
+ _call_object(nc->node, method, params, method_call_mode == ANIMATION_METHOD_CALL_DEFERRED);
}
} break;
@@ -796,7 +805,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double
TrackNodeCache::BezierAnim *ba = &E->value;
real_t bezier = a->bezier_track_interpolate(i, p_time);
- bezier = _post_process_key_value(a, i, bezier, nc->node);
+ bezier = post_process_key_value(a, i, bezier, nc->node);
if (ba->accum_pass != accum_pass) {
ERR_CONTINUE(cache_update_bezier_size >= NODE_CACHE_UPDATE_MAX);
cache_update_bezier[cache_update_bezier_size++] = ba;
@@ -813,7 +822,11 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double
}
if (p_seeked) {
- //find whatever should be playing
+#ifdef TOOLS_ENABLED
+ if (!can_call) {
+ continue; // To avoid spamming the preview in editor.
+ }
+#endif // TOOLS_ENABLED
int idx = a->track_find_key(i, p_time);
if (idx < 0) {
continue;
@@ -2190,6 +2203,8 @@ void AnimationPlayer::_bind_methods() {
ClassDB::bind_method(D_METHOD("seek", "seconds", "update"), &AnimationPlayer::seek, DEFVAL(false));
ClassDB::bind_method(D_METHOD("advance", "delta"), &AnimationPlayer::advance);
+ GDVIRTUAL_BIND(_post_process_key_value, "animation", "track", "value", "object", "object_idx");
+
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "root_node"), "set_root", "get_root");
ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "current_animation", PROPERTY_HINT_ENUM, "", PROPERTY_USAGE_EDITOR), "set_current_animation", "get_current_animation");
ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "assigned_animation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_assigned_animation", "get_assigned_animation");
diff --git a/scene/animation/animation_player.h b/scene/animation/animation_player.h
index 7e7d12f982..2901c43dcf 100644
--- a/scene/animation/animation_player.h
+++ b/scene/animation/animation_player.h
@@ -317,6 +317,8 @@ protected:
static void _bind_methods();
+ GDVIRTUAL5RC(Variant, _post_process_key_value, Ref<Animation>, int, Variant, Object *, int);
+ Variant post_process_key_value(const Ref<Animation> &p_anim, int p_track, Variant p_value, const Object *p_object, int p_object_idx = -1);
virtual Variant _post_process_key_value(const Ref<Animation> &p_anim, int p_track, Variant p_value, const Object *p_object, int p_object_idx = -1);
public:
diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp
index 077a5696bb..a2a1a0aaef 100644
--- a/scene/animation/animation_tree.cpp
+++ b/scene/animation/animation_tree.cpp
@@ -1015,8 +1015,9 @@ void AnimationTree::_process_graph(double p_delta) {
// Apply value/transform/blend/bezier blends to track caches and execute method/audio/animation tracks.
{
+#ifdef TOOLS_ENABLED
bool can_call = is_inside_tree() && !Engine::get_singleton()->is_editor_hint();
-
+#endif // TOOLS_ENABLED
for (const AnimationNode::AnimationState &as : state.animation_states) {
Ref<Animation> a = as.animation;
double time = as.time;
@@ -1104,9 +1105,9 @@ void AnimationTree::_process_graph(double p_delta) {
if (err != OK) {
continue;
}
- loc[0] = _post_process_key_value(a, i, loc[0], t->object, t->bone_idx);
+ loc[0] = post_process_key_value(a, i, loc[0], t->object, t->bone_idx);
a->position_track_interpolate(i, (double)a->get_length(), &loc[1]);
- loc[1] = _post_process_key_value(a, i, loc[1], t->object, t->bone_idx);
+ loc[1] = post_process_key_value(a, i, loc[1], t->object, t->bone_idx);
t->loc += (loc[1] - loc[0]) * blend;
prev_time = 0;
}
@@ -1116,9 +1117,9 @@ void AnimationTree::_process_graph(double p_delta) {
if (err != OK) {
continue;
}
- loc[0] = _post_process_key_value(a, i, loc[0], t->object, t->bone_idx);
+ loc[0] = post_process_key_value(a, i, loc[0], t->object, t->bone_idx);
a->position_track_interpolate(i, 0, &loc[1]);
- loc[1] = _post_process_key_value(a, i, loc[1], t->object, t->bone_idx);
+ loc[1] = post_process_key_value(a, i, loc[1], t->object, t->bone_idx);
t->loc += (loc[1] - loc[0]) * blend;
prev_time = (double)a->get_length();
}
@@ -1128,10 +1129,10 @@ void AnimationTree::_process_graph(double p_delta) {
if (err != OK) {
continue;
}
- loc[0] = _post_process_key_value(a, i, loc[0], t->object, t->bone_idx);
+ loc[0] = post_process_key_value(a, i, loc[0], t->object, t->bone_idx);
a->position_track_interpolate(i, time, &loc[1]);
- loc[1] = _post_process_key_value(a, i, loc[1], t->object, t->bone_idx);
+ loc[1] = post_process_key_value(a, i, loc[1], t->object, t->bone_idx);
t->loc += (loc[1] - loc[0]) * blend;
prev_time = !backward ? 0 : (double)a->get_length();
@@ -1142,7 +1143,7 @@ void AnimationTree::_process_graph(double p_delta) {
if (err != OK) {
continue;
}
- loc = _post_process_key_value(a, i, loc, t->object, t->bone_idx);
+ loc = post_process_key_value(a, i, loc, t->object, t->bone_idx);
t->loc += (loc - t->init_loc) * blend;
}
@@ -1195,9 +1196,9 @@ void AnimationTree::_process_graph(double p_delta) {
if (err != OK) {
continue;
}
- rot[0] = _post_process_key_value(a, i, rot[0], t->object, t->bone_idx);
+ rot[0] = post_process_key_value(a, i, rot[0], t->object, t->bone_idx);
a->rotation_track_interpolate(i, (double)a->get_length(), &rot[1]);
- rot[1] = _post_process_key_value(a, i, rot[1], t->object, t->bone_idx);
+ rot[1] = post_process_key_value(a, i, rot[1], t->object, t->bone_idx);
t->rot = (t->rot * Quaternion().slerp(rot[0].inverse() * rot[1], blend)).normalized();
prev_time = 0;
}
@@ -1207,7 +1208,7 @@ void AnimationTree::_process_graph(double p_delta) {
if (err != OK) {
continue;
}
- rot[0] = _post_process_key_value(a, i, rot[0], t->object, t->bone_idx);
+ rot[0] = post_process_key_value(a, i, rot[0], t->object, t->bone_idx);
a->rotation_track_interpolate(i, 0, &rot[1]);
t->rot = (t->rot * Quaternion().slerp(rot[0].inverse() * rot[1], blend)).normalized();
prev_time = (double)a->get_length();
@@ -1218,10 +1219,10 @@ void AnimationTree::_process_graph(double p_delta) {
if (err != OK) {
continue;
}
- rot[0] = _post_process_key_value(a, i, rot[0], t->object, t->bone_idx);
+ rot[0] = post_process_key_value(a, i, rot[0], t->object, t->bone_idx);
a->rotation_track_interpolate(i, time, &rot[1]);
- rot[1] = _post_process_key_value(a, i, rot[1], t->object, t->bone_idx);
+ rot[1] = post_process_key_value(a, i, rot[1], t->object, t->bone_idx);
t->rot = (t->rot * Quaternion().slerp(rot[0].inverse() * rot[1], blend)).normalized();
prev_time = !backward ? 0 : (double)a->get_length();
@@ -1232,7 +1233,7 @@ void AnimationTree::_process_graph(double p_delta) {
if (err != OK) {
continue;
}
- rot = _post_process_key_value(a, i, rot, t->object, t->bone_idx);
+ rot = post_process_key_value(a, i, rot, t->object, t->bone_idx);
t->rot = (t->rot * Quaternion().slerp(t->init_rot.inverse() * rot, blend)).normalized();
}
@@ -1285,10 +1286,10 @@ void AnimationTree::_process_graph(double p_delta) {
if (err != OK) {
continue;
}
- scale[0] = _post_process_key_value(a, i, scale[0], t->object, t->bone_idx);
+ scale[0] = post_process_key_value(a, i, scale[0], t->object, t->bone_idx);
a->scale_track_interpolate(i, (double)a->get_length(), &scale[1]);
t->scale += (scale[1] - scale[0]) * blend;
- scale[1] = _post_process_key_value(a, i, scale[1], t->object, t->bone_idx);
+ scale[1] = post_process_key_value(a, i, scale[1], t->object, t->bone_idx);
prev_time = 0;
}
} else {
@@ -1297,9 +1298,9 @@ void AnimationTree::_process_graph(double p_delta) {
if (err != OK) {
continue;
}
- scale[0] = _post_process_key_value(a, i, scale[0], t->object, t->bone_idx);
+ scale[0] = post_process_key_value(a, i, scale[0], t->object, t->bone_idx);
a->scale_track_interpolate(i, 0, &scale[1]);
- scale[1] = _post_process_key_value(a, i, scale[1], t->object, t->bone_idx);
+ scale[1] = post_process_key_value(a, i, scale[1], t->object, t->bone_idx);
t->scale += (scale[1] - scale[0]) * blend;
prev_time = (double)a->get_length();
}
@@ -1309,10 +1310,10 @@ void AnimationTree::_process_graph(double p_delta) {
if (err != OK) {
continue;
}
- scale[0] = _post_process_key_value(a, i, scale[0], t->object, t->bone_idx);
+ scale[0] = post_process_key_value(a, i, scale[0], t->object, t->bone_idx);
a->scale_track_interpolate(i, time, &scale[1]);
- scale[1] = _post_process_key_value(a, i, scale[1], t->object, t->bone_idx);
+ scale[1] = post_process_key_value(a, i, scale[1], t->object, t->bone_idx);
t->scale += (scale[1] - scale[0]) * blend;
prev_time = !backward ? 0 : (double)a->get_length();
@@ -1323,7 +1324,7 @@ void AnimationTree::_process_graph(double p_delta) {
if (err != OK) {
continue;
}
- scale = _post_process_key_value(a, i, scale, t->object, t->bone_idx);
+ scale = post_process_key_value(a, i, scale, t->object, t->bone_idx);
t->scale += (scale - t->init_scale) * blend;
}
@@ -1341,7 +1342,7 @@ void AnimationTree::_process_graph(double p_delta) {
if (err != OK) {
continue;
}
- value = _post_process_key_value(a, i, value, t->object, t->shape_index);
+ value = post_process_key_value(a, i, value, t->object, t->shape_index);
t->value += (value - t->init_value) * blend;
#endif // _3D_DISABLED
@@ -1353,7 +1354,7 @@ void AnimationTree::_process_graph(double p_delta) {
if (update_mode == Animation::UPDATE_CONTINUOUS || update_mode == Animation::UPDATE_CAPTURE) {
Variant value = a->value_track_interpolate(i, time);
- value = _post_process_key_value(a, i, value, t->object);
+ value = post_process_key_value(a, i, value, t->object);
if (value == Variant()) {
continue;
@@ -1393,14 +1394,14 @@ void AnimationTree::_process_graph(double p_delta) {
continue;
}
Variant value = a->track_get_key_value(i, idx);
- value = _post_process_key_value(a, i, value, t->object);
+ value = post_process_key_value(a, i, value, t->object);
t->object->set_indexed(t->subpath, value);
} else {
List<int> indices;
a->track_get_key_indices_in_range(i, time, delta, &indices, looped_flag);
for (int &F : indices) {
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);
t->object->set_indexed(t->subpath, value);
}
}
@@ -1408,6 +1409,11 @@ void AnimationTree::_process_graph(double p_delta) {
} break;
case Animation::TYPE_METHOD: {
+#ifdef TOOLS_ENABLED
+ if (!can_call) {
+ return;
+ }
+#endif // TOOLS_ENABLED
TrackCacheMethod *t = static_cast<TrackCacheMethod *>(track);
if (seeked) {
@@ -1417,18 +1423,14 @@ void AnimationTree::_process_graph(double p_delta) {
}
StringName method = a->method_track_get_name(i, idx);
Vector<Variant> params = a->method_track_get_params(i, idx);
- if (can_call) {
- _call_object(t->object, method, params, false);
- }
+ _call_object(t->object, method, params, false);
} else {
List<int> indices;
a->track_get_key_indices_in_range(i, time, delta, &indices, looped_flag);
for (int &F : indices) {
StringName method = a->method_track_get_name(i, F);
Vector<Variant> params = a->method_track_get_params(i, F);
- if (can_call) {
- _call_object(t->object, method, params, true);
- }
+ _call_object(t->object, method, params, true);
}
}
} break;
@@ -1436,7 +1438,7 @@ void AnimationTree::_process_graph(double p_delta) {
TrackCacheBezier *t = static_cast<TrackCacheBezier *>(track);
real_t bezier = a->bezier_track_interpolate(i, time);
- bezier = _post_process_key_value(a, i, bezier, t->object);
+ bezier = post_process_key_value(a, i, bezier, t->object);
t->value += (bezier - t->init_value) * blend;
} break;
@@ -1444,7 +1446,6 @@ void AnimationTree::_process_graph(double p_delta) {
TrackCacheAudio *t = static_cast<TrackCacheAudio *>(track);
if (seeked) {
- //find whatever should be playing
int idx = a->track_find_key(i, time, is_external_seeking ? Animation::FIND_MODE_NEAREST : Animation::FIND_MODE_EXACT);
if (idx < 0) {
continue;
@@ -1700,6 +1701,15 @@ void AnimationTree::_process_graph(double p_delta) {
}
}
+Variant AnimationTree::post_process_key_value(const Ref<Animation> &p_anim, int p_track, Variant p_value, const Object *p_object, int p_object_idx) {
+ Variant res;
+ if (GDVIRTUAL_CALL(_post_process_key_value, p_anim, p_track, p_value, const_cast<Object *>(p_object), p_object_idx, res)) {
+ return res;
+ }
+
+ return _post_process_key_value(p_anim, p_track, p_value, p_object, p_object_idx);
+}
+
Variant AnimationTree::_post_process_key_value(const Ref<Animation> &p_anim, int p_track, Variant p_value, const Object *p_object, int p_object_idx) {
switch (p_anim->track_get_type(p_track)) {
#ifndef _3D_DISABLED
@@ -2034,6 +2044,8 @@ void AnimationTree::_bind_methods() {
ClassDB::bind_method(D_METHOD("advance", "delta"), &AnimationTree::advance);
+ GDVIRTUAL_BIND(_post_process_key_value, "animation", "track", "value", "object", "object_idx");
+
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "tree_root", PROPERTY_HINT_RESOURCE_TYPE, "AnimationRootNode"), "set_tree_root", "get_tree_root");
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "anim_player", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "AnimationPlayer"), "set_animation_player", "get_animation_player");
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "advance_expression_base_node", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Node"), "set_advance_expression_base_node", "get_advance_expression_base_node");
diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h
index 52d3e1bd41..ab538feb58 100644
--- a/scene/animation/animation_tree.h
+++ b/scene/animation/animation_tree.h
@@ -328,6 +328,8 @@ protected:
void _notification(int p_what);
static void _bind_methods();
+ GDVIRTUAL5RC(Variant, _post_process_key_value, Ref<Animation>, int, Variant, Object *, int);
+ Variant post_process_key_value(const Ref<Animation> &p_anim, int p_track, Variant p_value, const Object *p_object, int p_object_idx = -1);
virtual Variant _post_process_key_value(const Ref<Animation> &p_anim, int p_track, Variant p_value, const Object *p_object, int p_object_idx = -1);
public: