bevy/crates/bevy_animation/Cargo.toml

48 lines
1.6 KiB
TOML
Raw Normal View History

[package]
name = "bevy_animation"
version = "0.15.0-dev"
edition = "2021"
description = "Provides animation functionality for Bevy Engine"
homepage = "https://bevyengine.org"
repository = "https://github.com/bevyengine/bevy"
license = "MIT OR Apache-2.0"
keywords = ["bevy"]
[dependencies]
# bevy
Add Support for Triggering Events via `AnimationEvent`s (#15538) # Objective Add support for events that can be triggered from animation clips. This is useful when you need something to happen at a specific time in an animation. For example, playing a sound every time a characters feet hits the ground when walking. Closes #15494 ## Solution Added a new field to `AnimationClip`: `events`, which contains a list of `AnimationEvent`s. These are automatically triggered in `animate_targets` and `trigger_untargeted_animation_events`. ## Testing Added a couple of tests and example (`animation_events.rs`) to make sure events are triggered when expected. --- ## Showcase `Events` need to also implement `AnimationEvent` and `Reflect` to be used with animations. ```rust #[derive(Event, AnimationEvent, Reflect)] struct SomeEvent; ``` Events can be added to an `AnimationClip` by specifying a time and event. ```rust // trigger an event after 1.0 second animation_clip.add_event(1.0, SomeEvent); ``` And optionally, providing a target id. ```rust let id = AnimationTargetId::from_iter(["shoulder", "arm", "hand"]); animation_clip.add_event_to_target(id, 1.0, HandEvent); ``` I modified the `animated_fox` example to show off the feature. ![CleanShot 2024-10-05 at 02 41 57](https://github.com/user-attachments/assets/0bb47db7-24f9-4504-88f1-40e375b89b1b) --------- Co-authored-by: Matty <weatherleymatthew@gmail.com> Co-authored-by: Chris Biscardi <chris@christopherbiscardi.com> Co-authored-by: François Mockers <francois.mockers@vleue.com>
2024-10-06 10:03:05 +00:00
bevy_animation_derive = { path = "derive", version = "0.15.0-dev" }
bevy_app = { path = "../bevy_app", version = "0.15.0-dev" }
bevy_asset = { path = "../bevy_asset", version = "0.15.0-dev" }
bevy_color = { path = "../bevy_color", version = "0.15.0-dev" }
bevy_core = { path = "../bevy_core", version = "0.15.0-dev" }
bevy_derive = { path = "../bevy_derive", version = "0.15.0-dev" }
bevy_log = { path = "../bevy_log", version = "0.15.0-dev" }
bevy_math = { path = "../bevy_math", version = "0.15.0-dev" }
bevy_reflect = { path = "../bevy_reflect", version = "0.15.0-dev", features = [
"bevy",
Implement the `AnimationGraph`, allowing for multiple animations to be blended together. (#11989) This is an implementation of RFC #51: https://github.com/bevyengine/rfcs/blob/main/rfcs/51-animation-composition.md Note that the implementation strategy is different from the one outlined in that RFC, because two-phase animation has now landed. # Objective Bevy needs animation blending. The RFC for this is [RFC 51]. ## Solution This is an implementation of the RFC. Note that the implementation strategy is different from the one outlined there, because two-phase animation has now landed. This is just a draft to get the conversation started. Currently we're missing a few things: - [x] A fully-fleshed-out mechanism for transitions - [x] A serialization format for `AnimationGraph`s - [x] Examples are broken, other than `animated_fox` - [x] Documentation --- ## Changelog ### Added * The `AnimationPlayer` has been reworked to support blending multiple animations together through an `AnimationGraph`, and as such will no longer function unless a `Handle<AnimationGraph>` has been added to the entity containing the player. See [RFC 51] for more details. * Transition functionality has moved from the `AnimationPlayer` to a new component, `AnimationTransitions`, which works in tandem with the `AnimationGraph`. ## Migration Guide * `AnimationPlayer`s can no longer play animations by themselves and need to be paired with a `Handle<AnimationGraph>`. Code that was using `AnimationPlayer` to play animations will need to create an `AnimationGraph` asset first, add a node for the clip (or clips) you want to play, and then supply the index of that node to the `AnimationPlayer`'s `play` method. * The `AnimationPlayer::play_with_transition()` method has been removed and replaced with the `AnimationTransitions` component. If you were previously using `AnimationPlayer::play_with_transition()`, add all animations that you were playing to the `AnimationGraph`, and create an `AnimationTransitions` component to manage the blending between them. [RFC 51]: https://github.com/bevyengine/rfcs/blob/main/rfcs/51-animation-composition.md --------- Co-authored-by: Rob Parrett <robparrett@gmail.com>
2024-03-07 20:22:42 +00:00
"petgraph",
] }
bevy_render = { path = "../bevy_render", version = "0.15.0-dev" }
bevy_time = { path = "../bevy_time", version = "0.15.0-dev" }
bevy_utils = { path = "../bevy_utils", version = "0.15.0-dev" }
bevy_ecs = { path = "../bevy_ecs", version = "0.15.0-dev" }
bevy_transform = { path = "../bevy_transform", version = "0.15.0-dev" }
bevy_hierarchy = { path = "../bevy_hierarchy", version = "0.15.0-dev" }
Rework animation to be done in two phases. (#11707) # Objective Bevy's animation system currently does tree traversals based on `Name` that aren't necessary. Not only do they require in unsafe code because tree traversals are awkward with parallelism, but they are also somewhat slow, brittle, and complex, which manifested itself as way too many queries in #11670. # Solution Divide animation into two phases: animation *advancement* and animation *evaluation*, which run after one another. *Advancement* operates on the `AnimationPlayer` and sets the current animation time to match the game time. *Evaluation* operates on all animation bones in the scene in parallel and sets the transforms and/or morph weights based on the time and the clip. To do this, we introduce a new component, `AnimationTarget`, which the asset loader places on every bone. It contains the ID of the entity containing the `AnimationPlayer`, as well as a UUID that identifies which bone in the animation the target corresponds to. In the case of glTF, the UUID is derived from the full path name to the bone. The rule that `AnimationTarget`s are descendants of the entity containing `AnimationPlayer` is now just a convention, not a requirement; this allows us to eliminate the unsafe code. # Migration guide * `AnimationClip` now uses UUIDs instead of hierarchical paths based on the `Name` component to refer to bones. This has several consequences: - A new component, `AnimationTarget`, should be placed on each bone that you wish to animate, in order to specify its UUID and the associated `AnimationPlayer`. The glTF loader automatically creates these components as necessary, so most uses of glTF rigs shouldn't need to change. - Moving a bone around the tree, or renaming it, no longer prevents an `AnimationPlayer` from affecting it. - Dynamically changing the `AnimationPlayer` component will likely require manual updating of the `AnimationTarget` components. * Entities with `AnimationPlayer` components may now possess descendants that also have `AnimationPlayer` components. They may not, however, animate the same bones. * As they aren't specific to `TypeId`s, `bevy_reflect::utility::NoOpTypeIdHash` and `bevy_reflect::utility::NoOpTypeIdHasher` have been renamed to `bevy_reflect::utility::NoOpHash` and `bevy_reflect::utility::NoOpHasher` respectively.
2024-02-19 14:59:54 +00:00
# other
Implement the `AnimationGraph`, allowing for multiple animations to be blended together. (#11989) This is an implementation of RFC #51: https://github.com/bevyengine/rfcs/blob/main/rfcs/51-animation-composition.md Note that the implementation strategy is different from the one outlined in that RFC, because two-phase animation has now landed. # Objective Bevy needs animation blending. The RFC for this is [RFC 51]. ## Solution This is an implementation of the RFC. Note that the implementation strategy is different from the one outlined there, because two-phase animation has now landed. This is just a draft to get the conversation started. Currently we're missing a few things: - [x] A fully-fleshed-out mechanism for transitions - [x] A serialization format for `AnimationGraph`s - [x] Examples are broken, other than `animated_fox` - [x] Documentation --- ## Changelog ### Added * The `AnimationPlayer` has been reworked to support blending multiple animations together through an `AnimationGraph`, and as such will no longer function unless a `Handle<AnimationGraph>` has been added to the entity containing the player. See [RFC 51] for more details. * Transition functionality has moved from the `AnimationPlayer` to a new component, `AnimationTransitions`, which works in tandem with the `AnimationGraph`. ## Migration Guide * `AnimationPlayer`s can no longer play animations by themselves and need to be paired with a `Handle<AnimationGraph>`. Code that was using `AnimationPlayer` to play animations will need to create an `AnimationGraph` asset first, add a node for the clip (or clips) you want to play, and then supply the index of that node to the `AnimationPlayer`'s `play` method. * The `AnimationPlayer::play_with_transition()` method has been removed and replaced with the `AnimationTransitions` component. If you were previously using `AnimationPlayer::play_with_transition()`, add all animations that you were playing to the `AnimationGraph`, and create an `AnimationTransitions` component to manage the blending between them. [RFC 51]: https://github.com/bevyengine/rfcs/blob/main/rfcs/51-animation-composition.md --------- Co-authored-by: Rob Parrett <robparrett@gmail.com>
2024-03-07 20:22:42 +00:00
petgraph = { version = "0.6", features = ["serde-1"] }
ron = "0.8"
serde = "1"
blake3 = { version = "1.0" }
Implement the `AnimationGraph`, allowing for multiple animations to be blended together. (#11989) This is an implementation of RFC #51: https://github.com/bevyengine/rfcs/blob/main/rfcs/51-animation-composition.md Note that the implementation strategy is different from the one outlined in that RFC, because two-phase animation has now landed. # Objective Bevy needs animation blending. The RFC for this is [RFC 51]. ## Solution This is an implementation of the RFC. Note that the implementation strategy is different from the one outlined there, because two-phase animation has now landed. This is just a draft to get the conversation started. Currently we're missing a few things: - [x] A fully-fleshed-out mechanism for transitions - [x] A serialization format for `AnimationGraph`s - [x] Examples are broken, other than `animated_fox` - [x] Documentation --- ## Changelog ### Added * The `AnimationPlayer` has been reworked to support blending multiple animations together through an `AnimationGraph`, and as such will no longer function unless a `Handle<AnimationGraph>` has been added to the entity containing the player. See [RFC 51] for more details. * Transition functionality has moved from the `AnimationPlayer` to a new component, `AnimationTransitions`, which works in tandem with the `AnimationGraph`. ## Migration Guide * `AnimationPlayer`s can no longer play animations by themselves and need to be paired with a `Handle<AnimationGraph>`. Code that was using `AnimationPlayer` to play animations will need to create an `AnimationGraph` asset first, add a node for the clip (or clips) you want to play, and then supply the index of that node to the `AnimationPlayer`'s `play` method. * The `AnimationPlayer::play_with_transition()` method has been removed and replaced with the `AnimationTransitions` component. If you were previously using `AnimationPlayer::play_with_transition()`, add all animations that you were playing to the `AnimationGraph`, and create an `AnimationTransitions` component to manage the blending between them. [RFC 51]: https://github.com/bevyengine/rfcs/blob/main/rfcs/51-animation-composition.md --------- Co-authored-by: Rob Parrett <robparrett@gmail.com>
2024-03-07 20:22:42 +00:00
thiserror = "1"
thread_local = "1"
uuid = { version = "1.7", features = ["v4"] }
Impose a more sensible ordering for animation graph evaluation. (#15589) This is an updated version of #15530. Review comments were addressed. This commit changes the animation graph evaluation to be operate in a more sensible order and updates the semantics of blend nodes to conform to [the animation composition RFC]. Prior to this patch, a node graph like this: ``` ┌─────┐ │ │ │ 1 │ │ │ └──┬──┘ │ ┌───────┴───────┐ │ │ ▼ ▼ ┌─────┐ ┌─────┐ │ │ │ │ │ 2 │ │ 3 │ │ │ │ │ └──┬──┘ └──┬──┘ │ │ ┌───┴───┐ ┌───┴───┐ │ │ │ │ ▼ ▼ ▼ ▼ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ │ │ │ │ │ │ │ │ │ 4 │ │ 6 │ │ 5 │ │ 7 │ │ │ │ │ │ │ │ │ └─────┘ └─────┘ └─────┘ └─────┘ ``` Would be evaluated as (((4 ⊕ 5) ⊕ 6) ⊕ 7), with the blend (lerp/slerp) operation notated as ⊕. As quaternion multiplication isn't commutative, this is very counterintuitive and will especially lead to trouble with the forthcoming additive blending feature (#15198). This patch fixes the issue by changing the evaluation order to postorder, with children of a node evaluated in ascending order by node index. To do so, this patch revamps `AnimationCurve` to be based on an *evaluation stack* and a *blend register*. During target evaluation, the graph evaluator traverses the graph in postorder. When encountering a clip node, the evaluator pushes the possibly-interpolated value onto the evaluation stack. When encountering a blend node, the evaluator pops values off the stack into the blend register, accumulating weights as appropriate. When the graph is completely evaluated, the top element on the stack is *committed* to the property of the component. A new system, the *graph threading* system, is added in order to cache the sorted postorder traversal to avoid the overhead of sorting children at animation evaluation time. Mask evaluation has been moved to this system so that the graph only has to be traversed at most once per frame. Unlike the `ActiveAnimation` list, the *threaded graph* is cached from frame to frame and only has to be regenerated when the animation graph asset changes. This patch currently regresses the `animate_target` performance in `many_foxes` by around 50%, resulting in an FPS loss of about 2-3 FPS. I'd argue that this is an acceptable price to pay for a much more intuitive system. In the future, we can mitigate the regression with a fast path that avoids consulting the graph if only one animation is playing. However, in the interest of keeping this patch simple, I didn't do so here. [the animation composition RFC]: https://github.com/bevyengine/rfcs/blob/main/rfcs/51-animation-composition.md # Objective - Describe the objective or issue this PR addresses. - If you're fixing a specific issue, say "Fixes #X". ## Solution - Describe the solution used to achieve the objective above. ## Testing - Did you test these changes? If so, how? - Are there any parts that need more testing? - How can other people (reviewers) test your changes? Is there anything specific they need to know? - If relevant, what platforms did you test these changes on, and are there any important ones you can't test? --- ## Showcase > This section is optional. If this PR does not include a visual change or does not add a new feature, you can delete this section. - Help others understand the result of this PR by showcasing your awesome work! - If this PR adds a new feature or public API, consider adding a brief pseudo-code snippet of it in action - If this PR includes a visual change, consider adding a screenshot, GIF, or video - If you want, you could even include a before/after comparison! - If the Migration Guide adequately covers the changes, you can delete this section While a showcase should aim to be brief and digestible, you can use a toggleable section to save space on longer showcases: <details> <summary>Click to view showcase</summary> ```rust println!("My super cool code."); ``` </details> ## Migration Guide > This section is optional. If there are no breaking changes, you can delete this section. - If this PR is a breaking change (relative to the last release of Bevy), describe how a user might need to migrate their code to support these changes - Simply adding new functionality is not a breaking change. - Fixing behavior that was definitely a bug, rather than a questionable design choice is not a breaking change. --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-10-03 00:36:42 +00:00
smallvec = "1"
Rework animation to be done in two phases. (#11707) # Objective Bevy's animation system currently does tree traversals based on `Name` that aren't necessary. Not only do they require in unsafe code because tree traversals are awkward with parallelism, but they are also somewhat slow, brittle, and complex, which manifested itself as way too many queries in #11670. # Solution Divide animation into two phases: animation *advancement* and animation *evaluation*, which run after one another. *Advancement* operates on the `AnimationPlayer` and sets the current animation time to match the game time. *Evaluation* operates on all animation bones in the scene in parallel and sets the transforms and/or morph weights based on the time and the clip. To do this, we introduce a new component, `AnimationTarget`, which the asset loader places on every bone. It contains the ID of the entity containing the `AnimationPlayer`, as well as a UUID that identifies which bone in the animation the target corresponds to. In the case of glTF, the UUID is derived from the full path name to the bone. The rule that `AnimationTarget`s are descendants of the entity containing `AnimationPlayer` is now just a convention, not a requirement; this allows us to eliminate the unsafe code. # Migration guide * `AnimationClip` now uses UUIDs instead of hierarchical paths based on the `Name` component to refer to bones. This has several consequences: - A new component, `AnimationTarget`, should be placed on each bone that you wish to animate, in order to specify its UUID and the associated `AnimationPlayer`. The glTF loader automatically creates these components as necessary, so most uses of glTF rigs shouldn't need to change. - Moving a bone around the tree, or renaming it, no longer prevents an `AnimationPlayer` from affecting it. - Dynamically changing the `AnimationPlayer` component will likely require manual updating of the `AnimationTarget` components. * Entities with `AnimationPlayer` components may now possess descendants that also have `AnimationPlayer` components. They may not, however, animate the same bones. * As they aren't specific to `TypeId`s, `bevy_reflect::utility::NoOpTypeIdHash` and `bevy_reflect::utility::NoOpTypeIdHasher` have been renamed to `bevy_reflect::utility::NoOpHash` and `bevy_reflect::utility::NoOpHasher` respectively.
2024-02-19 14:59:54 +00:00
[lints]
workspace = true
[package.metadata.docs.rs]
rustdoc-args = ["-Zunstable-options", "--generate-link-to-definition"]
all-features = true