Merge pull request #71682 from TokageItLab/gdvirtual-anim-node

Make `AnimationTree` / `AnimationPlayer` processes adopt to GDVIRTUAL
This commit is contained in:
Rémi Verschelde 2023-01-26 16:01:17 +01:00
commit 44c0bfc94d
No known key found for this signature in database
GPG Key ID: C3336907360768E1
6 changed files with 81 additions and 33 deletions

View File

@ -15,6 +15,17 @@
<link title="Third Person Shooter Demo">https://godotengine.org/asset-library/asset/678</link>
</tutorials>
<methods>
<method name="_post_process_key_value" qualifiers="virtual const">
<return type="Variant" />
<param index="0" name="animation" type="Animation" />
<param index="1" name="track" type="int" />
<param index="2" name="value" type="Variant" />
<param index="3" name="object" type="Object" />
<param index="4" name="object_idx" type="int" />
<description>
A virtual function for processing after key getting during playback.
</description>
</method>
<method name="add_animation_library">
<return type="int" enum="Error" />
<param index="0" name="name" type="StringName" />

View File

@ -12,6 +12,17 @@
<link title="Third Person Shooter Demo">https://godotengine.org/asset-library/asset/678</link>
</tutorials>
<methods>
<method name="_post_process_key_value" qualifiers="virtual const">
<return type="Variant" />
<param index="0" name="animation" type="Animation" />
<param index="1" name="track" type="int" />
<param index="2" name="value" type="Variant" />
<param index="3" name="object" type="Object" />
<param index="4" name="object_idx" type="int" />
<description>
A virtual function for processing after key getting during playback.
</description>
</method>
<method name="advance">
<return type="void" />
<param index="0" name="delta" type="float" />

View File

@ -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
@ -514,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);
@ -542,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);
@ -570,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);
@ -598,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);
@ -651,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);
@ -672,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);
@ -703,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;
@ -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;
@ -2194,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");

View File

@ -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:

View File

@ -1105,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;
}
@ -1117,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();
}
@ -1129,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();
@ -1143,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;
}
@ -1196,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;
}
@ -1208,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();
@ -1219,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();
@ -1233,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();
}
@ -1286,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 {
@ -1298,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();
}
@ -1310,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();
@ -1324,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;
}
@ -1342,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
@ -1354,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;
@ -1394,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);
}
}
@ -1438,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;
@ -1701,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
@ -2035,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");

View File

@ -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: