Releases: mbrea-c/bevy_animation_graph
v0.5.0
Highlight
The migration to Bevy 0.14 replaces the transparent EntityPath
as the primary way to refer to bones with an opaque AnimationTargetId
, essentially a wrapper around an Uuid
. While this is good for performance, we still need a way to get the parent/children of a bone at animation graph run time: the solution for this was to introduce Skeleton
as a separate asset type.
Skeleton
s simply contain a mapping from AnimationTargetId
to EntityPath
, and store the bone hierarchy in a convenient format.
Defining skeleton assets is done simply by pointing it to the scene it represents, e.g.
(
source: Gltf(source: "models/character_rigged.glb", label: "Scene0"),
)
The asset loader will then load the scene and build the skeleton hierarchy at asset load time.
What's Changed
- Add more granular asset loading for the editor by @mbrea-c in #52
- Add padding node by @mbrea-c in #53
- Bevy 0.14 migration by @mbrea-c in #54
- Push version to 0.5 by @mbrea-c in #55
Full Changelog: v0.4.0...v0.5.0
v0.4.0
Highlights
Independent time signals, or the animate everything update
This is a foundational change that was important to lay the groundwork for animation state machines. Conceptually, the animation graph offers a way of describing a way of processing data that changes with time: when the animation player runs, it queries the graph using the time delta that has elapsed since the last frame. This delta then propagates backwards (i.e. left, if seen from the editor) in the graph as nodes receive it as input and use it to query the nodes upstream in the graph, possibly applying some transformation (e.g. the Speed
node will apply a speed multiplier to the time delta before querying its parent node).
However, in the previous version only animation pose data could change with time. That is, the backwards propagation of time deltas was inherently linked to the forward propagation of animation pose data. Other data, such as f32
, vec3
or other edges could not change with time (unless they were changed by gameplay logic and passed as graph input parameters, but that's orthogonal to this). This prevented legitimately useful constructs such as dynamic interpolation nodes between f32
or vec3
values, using for example a dampened spring-mass system to interpolate between the current and target values when the target can change dynamically. Such interpolation nodes would not output any animation pose data, but would need to receive a time delta in order to update the current value. Another example is event queues, which should be able to change over time (e.g. foot-down, foot-up events coming from an animation clip node): we wouldn't want to bundle this with animation pose data, because that would complicate the handling of events fed into the graph by gameplay logic (e.g., gameplay logic telling the graph that the character is now jumping via an event).
The solution we settled upon was to introduce separate time edges that control the backwards propagation of time deltas, and to stop considering animation pose data to be separate to other kinds of data. Now it's simple, "data" flows forward while "time" flows backwards. This is a bit unique among animation graph systems in popular engines and it does introduce some additional friction for simple operations (now you need to connect both a time and animation pose data edge rather than a single one) but it enables a lot of configurations that were difficult/impossible before. I'm looking forward to see how it works out.
So, if you just want to continue to use the graphs as usual what do you need to do now? Wherever there was a single pose input/output before, there will now be a time
and pose
separate pins, so you will need to connect them both:
Animation State Machines
This is a big one. There were certain things that were difficult to handle previously with the existing animation graph systems. For example, to switch between jumping and movement animations would require passing some sort of blend weight from the gameplay side of things. Now imagine you also have a aiming state and idle animations... you could end up managing an ad-hoc state machine in your gameplay logic, which would need to handle the transitions between states gracefully and without visual cuts. Ideally, the gameplay logic would indicate only which state the animation should go into via animation events fed into the graph, and the graph would handle states and transitions on its own. There might still be a state machine on the gameplay side, but only for gameplay state and it wouldn't care about animation states and transitions.
Well, this is exactly what we started to introduce here. State machines are represented as nodes within an animation graph. They have a separate editor tab with their own UI for editing. Each state is assigned an animation graph, and while that state is active the assigned animation graph will drive the output. Each transition is also assigned an animation graph, but this animation graph can query the respective assigned animation graphs for the transition's source and target states (e.g. to do blending). The transition animation graph is also fed data about the duration and elapsed percentage/time in the transition, which is useful for blending. Finally, the animation graph handling the transition is responsible for emitting events declaring the transition over.
AnimationGraphPlayer
now has a send_event
method to push an event into an event queue that will be made available to the graph in the user events
input pin: the Send events
editor tab is helpful in sending these events for testing/development, you can save event names so that they can be sent with one click.
Arbitrary inputs can be fed into a state machine node, and these inputs will be forwarded to all active states/transitions (a common application is forwarding character speed down to the state that handles locomotion animations).
Improve editor UI
The previous editor UI did the job, but was not very enjoyable to use. While there is still a lot to improve, a few things are better now:
- Nodes now show runtime information (duration, logical time)
- Active nodes are highlighted (i.e. nodes that were used in the current frame)
- Pins are divided into two colums (input and output columns) to improve readability at a glance.
- All inspectors have been condensed into a single tab.
Known issues/limitations
- Copy-paste is currently not working in the editor.
- There's no easy way to do global transitions, cancelling transitions, or stacking transitions when quickly switching between states. We're thinking of the best way to handle these.
Renaming the crate
Now that Bevy has a built-in animation graph feature, I'm thinking about renaming the crate to avoid confusion. I've got a few ideas but all suggestions are welcome :)
Changelog
v0.3.0
Highlights
- Update to Bevy 0.13 and egui 0.26
- Editor quality of life
- Preview Hierarchy tab displays all of the animated entities (all character bones) in the currently previewed animated scene as a tree.
- Clicking a bone from the Preview Hierarchy will copy its
EntityPath
to the clipboard and debug render the bone in the Preview Scene tab. - Some nodes display debug gizmos in the scene preview when selected in the editor
- Animation graph and animated scene asset selectors are now displayed as a tree
- Node overhauls
- Rotation node is now more configurable
- Input rotation can be in local (relative to parent bone), character (relative to root bone) or global space.
- The rotation can be either blended (with configurable weight) with the target bone's rotation, or composed with the target bone's rotation.
- A
chain_length
can be configured so that the rotation propagates to the bone's ancestors with decaying weight.
- FlipLR node is more configurable
- Detecting bones from the left/right sides is no longer a hardcoded "is there a .L or .R suffix" test, it can now be configured using regular expressions (arbitrary patterns before and after the left/right keys).
- Rotation node is now more configurable
- Ported support for step and cubic interpolation methods from
bevy_animation
. - Switched curve sampling to be done eagerly when sampling animations, rather than lazily. This slightly changed how chain and loop nodes work, but other than that it should not have any more visible effects if everything went well. Internally, however, a lot of complexity was removed from the codebase. The reasoning for the change and why it wasn't done like this from the beginning is explained in the PR #41
Changelog
- Link to the crate-help post from README by @mbrea-c in #32
- Parallelize animation players by @mbrea-c in #33
- Improve example default parameters by @mbrea-c in #36
- Add configuration to flip node by @mbrea-c in #37
- Enable manual dispatch of dry run workflow. by @mbrea-c in #38
- Rotation node overhaul, editor quality of life by @mbrea-c in #34
- Fix examples not responding to rotation keybinds by @mbrea-c in #40
- Sample curves eagerly by @mbrea-c in #41
- Update to Bevy 0.13 by @mbrea-c in #42
- Push version and add version table by @mbrea-c in #44
Full Changelog: v0.2.0...v0.3.0
v0.2.0
Key Changes
- Graph editor! There is now a visual graph editor that enables creation, editing and saving of animation graphs. It can live-preview an animated scene, but does not support editing animated scene and animation clip assets at the moment.
- Two bone inverse kinematics.
All changes
- Global and character space poses by @mbrea-c in #17
- fix: clip_node crashes if called before loading is finished by @mbrea-c in #18
- Inverse kinematics for two-bone chains by @mbrea-c in #19
- Preparations for graphical editor support by @mbrea-c in #21
- Convert repository to a workspace by @mbrea-c in #23
- Add editor prototype by @mbrea-c in #24
- Error propagation and handling by @mbrea-c in #26
- Graph editor bugfixes by @mbrea-c in #28
- Update documentation to reflect new editor changes by @mbrea-c in #29
- Release 0.2 by @mbrea-c in #31
Diff: v0.1.0...v0.2.0
v0.1.0
Highlights
AnimatedScene
assets allows assigning animation graphs to scenes and
provides an ergonomic API for spawning them and setting graph input parameters
from code.- Rotation node: Apply custom rotations to bones from a pose selected using a bone mask.
- New, simpler example using Bevy's fox.
- Documentation! You can now access documentation for this crate in docs.rs.
- Major refactor of graph design in order to simplify the node API and enable upcoming performance improvements.
- Many, many bugfixes :)
What's Changed
- Animated Scene Assets by @mbrea-c in #5
- Add CI pipeline by @mbrea-c in #8
- Address clippy errors by @mbrea-c in #10
- Enable
AnimationGraphPlayer
to pass parameters by @mbrea-c in #9 - Simplify graph architecture by @mbrea-c in #11
- Decouple dot output tool from dot and zathura commands by @mbrea-c in #12
- Added fox example by @mbrea-c in #13
- Further simplification of graph design, rotation modifier node by @mbrea-c in #14
- Add docs.rs documentation by @mbrea-c in #1
- Bump version to 0.11 by @mbrea-c in #16
Full Changelog: v0.1.0-alpha.4...v0.1.0
v0.1.0-alpha.4
Push version
v0.1.0-alpha.3
Last fixes before crates.io release:
- Added dual license
- Update Cargo.toml with missing fields
- Fixed error in
show_graph
commandline tool
v0.1.0-alpha.2
Changes:
- Fix computation graph short-circuiting when a valid cache is present
- Removed unnecessary dependencies
v0.1-alpha.1
First pre-release!
See the README file for an explanation of the current features.