Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add animation node extension #99181

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

GuilhermeGSousa
Copy link
Contributor

@GuilhermeGSousa GuilhermeGSousa commented Nov 13, 2024

TODO:

  • Write docs

Bugsquad edit:

Fixes: godotengine/godot-proposals#11123

AnimationNode::NodeTimeInfo node_time_info;
};

class PlaybackInfoRC : public RefCounted {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same criticism of RC suffix as the last comment.

@TokageItLab
Copy link
Member

TokageItLab commented Nov 13, 2024

I have concerns about future compatibility breakdown if struct is implemented in GDScript. We will need to consider whether we need to rush.

@GuilhermeGSousa GuilhermeGSousa force-pushed the animation-node-extension branch 3 times, most recently from 61f3ab5 to b764317 Compare November 14, 2024 22:03
@GuilhermeGSousa
Copy link
Contributor Author

@TokageItLab what were your concerns? I don't have any strong opinions, I though this was the cleanest of the ways to do this but I'm open to suggestions!

@TokageItLab
Copy link
Member

TokageItLab commented Nov 15, 2024

More specifically, I am concerned that I guess that GDScript struct will not be implemented as refcounted (maybe it should be one of the Variant types) in the future.

In the discussion regarding the implementation of struct, there was mention of it being implemented as a similar to a typed Dictionary.

NodeTimeInfo is composed of several properties and a get_remain_time() method that returns a value based on them. It is like a combination of a typed Dictionary and a Callable, but both are built-in types in the variant, not extends RefCounted class.

So what you are trying to do should actually be one of the struct as one of the Variant types, not Refcounted.

Even if we rush to merge this with inheriting Refcounted because we don't have struct, we will still need to replace it with struct in the future. Then it is doubtful that we can migrate Refcounted into Variant since base classes are fundamentally different.

@GuilhermeGSousa
Copy link
Contributor Author

@TokageItLab are you suggesting waiting until structs are implemented? That might not be coming to the engine any time soon, and I wouldn't mind refactoring this code once it is available.

Another idea would be to do what the AudioStreamPlayback _mix method does and use pointers instead. That way it wouldn't be exposed to GDScript, and would be easy to convert to using structs once avaiable.

@TokageItLab
Copy link
Member

TokageItLab commented Nov 16, 2024

are you suggesting waiting until structs are implemented?

Right, that's the direction that should be most recommended. Insteads, you can use the custom module.

That might not be coming to the engine any time soon

Since the PR is already there #82198, you could help with that work and feedback to support it.

Then, it is fine to include that PR before this PR and mentions "- Prerequisite #82198" to the description of this PR


If we are in a hurry to implement something, we will need to expose NodeTimeInfo as some Variant type instead of RefCounted. RefCounted is referential, so compatibility will be hard broken in the future if there are scripts that reference the same NodeTimeInfo.

From a performance point of view, we should avoid this but you can use Dictionary in some cases, but there is a problem that the get_remain() method is not available. Or you can use a encoded PackedByteArray, or a Callable object to exchange information.

Strictly, these are also referential, but since they are Variant types, if a reference is broken, only the Initial value is passed, allowing for relatively safe compatibility breaking and migration.

@GuilhermeGSousa GuilhermeGSousa marked this pull request as ready for review November 16, 2024 17:18
@GuilhermeGSousa GuilhermeGSousa requested review from a team as code owners November 16, 2024 17:18
@GuilhermeGSousa
Copy link
Contributor Author

Hi @TokageItLab! I updated this PR before having read your comment! You make very valid points, and I think you might prefer these last changes I pushed, I'm no longer using ref counted objects and instead encoding the return value on a PackedFloat32Array, let me know what you think!

As for the struct PR, I do like the idea you suggested. I'm not familiar with the struct changes, but I can least help with feedback. Nonetheless, if possible I'd like to submit these changes first, and later refactor the return value to use a struct instead.

@TokageItLab
Copy link
Member

TokageItLab commented Nov 16, 2024

PackedFloat32Array looks fine than RefCounted.

This is not a blocking opinion of this PR in particular, but I have two more concerns (as above your comment, probably do you work in progress?)

  1. Shouldn't PlaybackInfo be an array so that it can be delivered as well?
  2. NodeTimeInfo has two methods: bool is_looping() and double get_remain(bool p_break_loop = false). Maybe you should implement it as a static method somewhere to be able to retrieve these information externally by passing an array as an argument.

@GuilhermeGSousa GuilhermeGSousa force-pushed the animation-node-extension branch 2 times, most recently from 8baefdb to 8c3c569 Compare November 17, 2024 15:53
@GuilhermeGSousa
Copy link
Contributor Author

@TokageItLab agree with all your comments, just updated the PR to include them.

@GuilhermeGSousa GuilhermeGSousa force-pushed the animation-node-extension branch 2 times, most recently from ea20df2 to 5a56fe1 Compare November 17, 2024 16:00
@fire
Copy link
Member

fire commented Nov 17, 2024

The documentation changed and requires to be generated with --doctool.

@fire
Copy link
Member

fire commented Nov 17, 2024

We want to add the experimental flag to this class, but I forgot the process—@AThousandShips and maybe others.

scene/register_scene_types.cpp Outdated Show resolved Hide resolved
Copy link
Member

@TokageItLab TokageItLab left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably unneeded.

scene/animation/animation_node_extension.h Outdated Show resolved Hide resolved
scene/animation/animation_node_extension.cpp Outdated Show resolved Hide resolved
Copy link
Member

@TokageItLab TokageItLab left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These must be implemented in the base class AnimationNode. BTW, process_state is also a struct, it will probably need to be a PackedArray if it is to be exposed.

However, since all we need is the tree and is_testing, I agree that we should expose those two as get methods to the AnimationNode class, but I think the AnimationTree should be returned as either NodePath or ObjectID, as it is unsafe to return the AnimationTree pointer directly.

scene/animation/animation_node_extension.cpp Outdated Show resolved Hide resolved
scene/animation/animation_node_extension.cpp Outdated Show resolved Hide resolved
scene/animation/animation_node_extension.h Outdated Show resolved Hide resolved
doc/classes/AnimationNodeExtension.xml Outdated Show resolved Hide resolved
doc/classes/AnimationNodeExtension.xml Outdated Show resolved Hide resolved
doc/classes/AnimationNodeExtension.xml Outdated Show resolved Hide resolved
doc/classes/AnimationNodeExtension.xml Outdated Show resolved Hide resolved
@GuilhermeGSousa GuilhermeGSousa force-pushed the animation-node-extension branch 2 times, most recently from 2b99218 to b17daf8 Compare November 25, 2024 13:07
@GuilhermeGSousa
Copy link
Contributor Author

GuilhermeGSousa commented Nov 25, 2024

Updated the PR. @TokageItLab I'm running into an issue, unless I'm missing something I don't think plugins can extend abstract native classes. I even tried making an abstract base class on the plugin before making the actual extended class in C++, but no luck.

godotengine/godot-proposals#5644

@TokageItLab
Copy link
Member

TokageItLab commented Nov 25, 2024

@GuilhermeGSousa It is the expected behavior that it cannot be called from the scene dock, but I assume it could be called if class_name is assigned (same with https://godotengine.org/article/design-of-the-skeleton-modifier-3d/#1-create-a-script). is there an error before the extending it with class_name is added?

@GuilhermeGSousa
Copy link
Contributor Author

GuilhermeGSousa commented Nov 25, 2024

@TokageItLab I meant to extend it in a GDExtension, in C++. As far as I can tell, it doesn't seem to be possible to register a class that inherits directly or indirectly from a native abstract class. Unless there's maybe an equivalent way of setting the "class_name" for a C++ class?

This is the error I run into at registration:

ERROR: Extension class 'MMAnimationNode' cannot extend native abstract class 'AnimationNodeExtension'.
   at: ClassDB::register_extension_class (core\object\class_db.cpp:2236)
Extension class 'MMAnimationNode' cannot extend native abstract class 'AnimationNodeExtension'.

@TokageItLab
Copy link
Member

TokageItLab commented Nov 25, 2024

How about GDREGISTER_VIRTUAL_CLASS instead of GDREGISTER_ABSTRACT_CLASS?

@GuilhermeGSousa
Copy link
Contributor Author

@TokageItLab that works great! I can extend the class and it can't be instantiated from the resources dialog window.

Copy link
Member

@TokageItLab TokageItLab left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, those API should be almost identical to the virtual function of the AnimationNode class provided in cpp, except for the struct format.

We don't know what struct will be in the future, but it is probably a Variant type, so it should be able to provide a migration path.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Approved, Waiting for Production
Development

Successfully merging this pull request may close these issues.

Add an AnimationNodeExtension node
6 participants