Remi123 / MotionMatching

Motion Matching for Godot 4.
MIT License
38 stars 3 forks source link

Aim for the first working version #5

Closed GeorgeS2019 closed 1 year ago

GeorgeS2019 commented 1 year ago
Remi123 commented 1 year ago

@GeorgeS2019 @CBerry22 @maximkulkin @SaracenOne

I can share my inputs on each subject.

AnimationTree

My plugin is outside AnimationTree for now, it's only a node that find the best poses and output the name and timestamp of the animation that best match it. For example, "WalkForward" at time 0.4. This is all my plugin output, but I do it every 0.2 seconds.

Once this is known I need to blend to the desired pose. I have a simple setup in the animationtree that blend between two poses, but basically all I need is a node that blend between the current pose, and the poses at my desired animation timestamp.

I value the fact that my setup is technically just a slightly more complex AnimationNode, as the user can use all the things that AnimationTree is able to output.

Inertialization vs active ragdoll.

I remembered that he had a Youtube channel, and looked back at the active ragdoll at this link. Quite frankly I'm impressed and I think it's possible to implement the blending using active ragdoll, but I have some reservation.

Issues 1

First of all, he is using two skeletons, one physical using PhysicalBone3D and the other that is playing the animation. The physical skeleton is trying to match the position of the equivalent bone in the normal rig using some spring calculation. It is indeed very similar to inertialization which is also derived from springs, although the calculation isn't the same but for this discussion it's similar enough.

With my plugin, the animated rig would simply go to the desired poses, wait 0.X seconds that is configurable, and continue playing the rest of the animation and the physical bones would simply catch up with the rest of the animation.

I'll try to make it so that there is only one skeleton, but I have to test it if is possible.

Issues 2

For my purpose, it is still a workaround a proper node that blend realistically between poses very often. My setup that switch between the current and desired poses would just be replaced by an active ragdoll setup that still needs maintenance, but now with double the skeletons.

Inertialization

I've discussed with Tokage about a solution to the inertialization. In essence, the real problem that I have to workaround is that I cannot create an AnimationNode that manipulate the Skeleton3D directly. The animationtree has it's own structure to represent a blend of all the nodes and I want to keep it that way.

My current solution would be to have a node similar to an AnimationNode, and once it receive the signal to switch to a desired pose, create a temporary animation with the current bones positions and rotations. I then smoothly transitions to the desired pose by manipulating the animations tracks's key values instead of the skeleton bones positions. The animationTree only see an Animation and I'm free to manipulate the values however I see fit. Once the transition is done I simply remove the temporary animation and play the desired one.

GeorgeS2019 commented 1 year ago

@Remi123 I just found out about significant progress in another branch.

When is the first working demo, not just the addon?

Remi123 commented 1 year ago

@GeorgeS2019

I've realized that I had lot of issues coming from my initial setup in my project, so I've started a new one and fixed most of the them. Basically stuff like skeletons's nodepath to their bones and bla bla bla. A bunch of bugs were fixed also. But here is the latest update :

The biggest challenge was inertialization, or the blend between poses. I happy to say I finally have it, but I wasn't able to make it part of an AnimationNode and integrate it with the AnimationTree. I've tried various approach, even creating per-skeleton animation and modifying the keys at runtime but it started messing with the cache of animationtree and the skeleton wasn't updating.

After talking with @TokageitLab and @fire, I was made aware that AnimationTree and AnimationPlayer are going throught a big refactoring, and since I was already trying to squeeze in this feature, I made the decision to delay implementing it in way that is compatible with the current setup, and just provide a class that inherit Skeleton3D and do the inertialization. I'll show the class to the implementers of AnimationTree so that they can decide how to integrate it if they want.

In the meantime there is an animationtree setup that can blend between poses but isn't as good as inertialization. I can include it in the demo and talk about it in the wiki, but I'll continue the development using my own Skeleton3D class.

Here a video of a inertialization test. Basically it's switching which animation it run every second, from a random time in the animation. The cool thing is that I can switch animation mid-switch. Still WIP ( first second isn't set I'll fix it later, and it float due to the skeleton weird rest pose.) july30.webm

A demo, while important, doesn't explain everything so it is more important to have a good wiki. I've started writing it but of course I've just started.

For now I'm using modified Mixamo animations with root motion analyze and play. Of course I can't distribute them so I made the whole plugin able to analyze any animation in an AnimationLibrary. I've talked with Fire and they have a setup to capture and record animations so my goal is to write a document saying what would be good for Motion Matching locomotion. If they want to share it it's great, the demo can include it but like I said before any animation can be used.

I've just used Kenney's character since they are free and CC0. With animation retargeting it become a non issues, which is already implemented in Godot. In fact my inertialization only look into the animation data, and only apply the motion_scale at the end.

I'm not exactly sure what you mean with this.