Sfoglia il codice sorgente

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

Make `AnimationTree` / `AnimationPlayer` processes adopt to GDVIRTUAL
Rémi Verschelde 2 anni fa
parent
commit
44c0bfc94d

+ 11 - 0
doc/classes/AnimationPlayer.xml

@@ -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" />

+ 11 - 0
doc/classes/AnimationTree.xml

@@ -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" />

+ 19 - 8
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
@@ -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");

+ 2 - 0
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:

+ 36 - 25
scene/animation/animation_tree.cpp

@@ -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");

+ 2 - 0
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: