bevyengine / bevy

A refreshingly simple data-driven game engine built in Rust
https://bevyengine.org
Apache License 2.0
36.11k stars 3.56k forks source link

Animation API #91

Closed cart closed 2 years ago

cart commented 4 years ago

Animation permeates almost everything in gamedev. First, we should add a general purpose code-first animation system. Then later we can add a property-based timeline system that can be saved to a config file and visualized / edited in the Bevy Editor.

JonahPlusPlus commented 4 years ago

I think a good place to start would be interpolation. The minterpolate crate provides a nice set of functions for interpolation. It shouldn't be hard to add an interface for it, and could be later expanded to the timeline system you have in mind.

JonahPlusPlus commented 4 years ago

Looking at minterpolate and interpolation, minterpolate provides more interpolation functions and a common interface between them, which is nice when swapping out functions on the fly.

However, it adds the mint crate, which is unnecessary unless using multiple math crates. It is possible to make a fork and remove the mint sections, or ask the author to make it a crate feature, however the last update was 2 years ago, so it might not be maintained.

But the benefit of using it would be that animations sets can easily be added. The only drawbacks I could think of is that it might be a hassle when working in an animation set where the interpolation function differs between values.

Fortunately, both issues could be fixed by implementing all the features and more into the bevy_animation crate. The mint types could be removed, and a new MixedFunction variant could be added to the IterpolationFunction enum. TheMixedFunction could be constructed to take any number of interpolation functions and ranges, including more MixedFunctions, allowing the interpolation function to change over the entire set.

Hope this wasn't too long, it's just great to see such a great project.

JonahPlusPlus commented 4 years ago

Looking into glam-rs, it also uses the mint crate. It probably doesn't need to be removed.

kirawi commented 3 years ago

Relatively, how far down on the roadmap is this?

razaamir commented 3 years ago

Matrix in real life. Lady in red is a purple watch on my wrist

On Wed, Nov 11, 2020 at 9:09 AM Kirawi notifications@github.com wrote:

Relatively, how far down on the roadmap is this?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/bevyengine/bevy/issues/91#issuecomment-725177085, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHGK5TEBDODZQEV5YV6UG2TSPIFA3ANCNFSM4PU73PZA .

-- Raza Amir

DrewRidley commented 3 years ago

I am quite new to Bevy but perhaps this might be useful.

https://github.com/openrr/k

Inverse and Forward kinematics library for rust that seems stable, well documented, and pretty fast from my initial benchmarking. Let me know what you think.

alice-i-cecile commented 3 years ago

We have a solid start on this in #1429 and another starting point to look at in #482.

EvoTeamDevelop commented 3 years ago

Maybe it would be easier to integration already existing solutions like https://rive.app/ I know that Defold game engine also is in the middle of its integration.

Type1J commented 3 years ago

The crates mentioned, so far, seem to lack sequences, easing, or keeps the easing functions built-in, while user defined functions are second class.

I haven't seen a mention of keyframe, yet. As animation foundations go, keyframe is pretty complete. I could see a UI in an editor being built using it as a foundation with seperate tracks, etc. functioning pretty well.

It also brings in mint, but given mint's purpose (being a common set of types for 3D linear algebra for interop with various crates and engines), I don't believe that to be a problem.

I'm not familiar with Rive, but I believe keyframe would ease the import of Rive assets, as well, given its capabilities.

Please take a look at keyframe. I invite persuasion to use another crate, if you find it superior.

parasyte commented 2 years ago

I think one of the troubles with keyframe is that it owns its easing functions. Working with easings/interpolation on their own means one of two things will happen:

Honestly this is a small concern, because it's a tiny crate. But I'm calling it out because I would personally never search for an interpolation crate with keywords like keyframe or sequence, so I would land in the latter case.

Type1J commented 2 years ago

Actually, it doesn't own them. That was a major concern of mine, and one of the reasons that I landed on this library for a few projects. It has a trait defined as:

pub trait EasingFunction {
    /// For an X position on the curve, calculate the Y position.
    /// 0.0-1.0 is start and end on both axes but values can go out of bounds.
    ///
    /// # Note
    ///
    /// Because this method has a `&self` argument this trait can be used to both implement a "static" curve function (e.g. a linear interpolation)
    /// or a "dynamic" curve function (e.g. a bezier curve with user defined inputs).
    ///
    /// Since a static curve function will have zero size the size of a `dyn EasingFunction` will be the same size as a vtable.
    /// This also means you can specify a static curve function with only the name of the type (e.g. `ease(EaseInOut, 0.0, 1.0, 0.5)`).
    fn y(&self, x: f64) -> f64;
}

You can pass it any type that implements this trait.

parasyte commented 2 years ago

I was talking about the actual implementations. I understand that one can implement any conceivable interpolation function and use it with the trait. That wasn't the concern I raised.

lygamac commented 2 years ago

Just curious about how is going to be the final design of the animation system in code. I really like the code-first concept, as editor-based animations are less flexible.

Will the design be similar to Godot's animation API (deprecated, now it seems to be an editor resource)? Such design is based on functions, and it's really difficult to manipulate and understand through the code in a big project. Rather, it's meant to be used in an editor.

Is it possible to achieve a nested function list feature like in Lua? I made up this example:

animation_list = {
    { "anim1", "path_to_animation"},
    { "anim2", "path_to_animation"},
    -- ... etc
}

animation_player(function(s)
    node = animation.states {
        fade_time = 0.3,
        states = {
            state1 = "path_to_animation",
            state2 = animation.blend {
                blend1 = "path_to_animation",
                blend2 = animation.states {states = animation_list}
                -- etc
            },
        },
    }
    end)

Which is literary a code-based node tree to a Godot equivalent: image

cart commented 2 years ago

Closing in favor of #4026