mirror of
https://github.com/bevyengine/bevy
synced 2024-12-22 11:03:06 +00:00
0094bcbc07
*Additive blending* is an ubiquitous feature in game engines that allows animations to be concatenated instead of blended. The canonical use case is to allow a character to hold a weapon while performing arbitrary poses. For example, if you had a character that needed to be able to walk or run while attacking with a weapon, the typical workflow is to have an additive blend node that combines walking and running animation clips with an animation clip of one of the limbs performing a weapon attack animation. This commit adds support for additive blending to Bevy. It builds on top of the flexible infrastructure in #15589 and introduces a new type of node, the *add node*. Like blend nodes, add nodes combine the animations of their children according to their weights. Unlike blend nodes, however, add nodes don't normalize the weights to 1.0. The `animation_masks` example has been overhauled to demonstrate the use of additive blending in combination with masks. There are now controls to choose an animation clip for every limb of the fox individually. This patch also fixes a bug whereby masks were incorrectly accumulated with `insert()` during the graph threading phase, which could cause corruption of computed masks in some cases. Note that the `clip` field has been replaced with an `AnimationNodeType` enum, which breaks `animgraph.ron` files. The `Fox.animgraph.ron` asset has been updated to the new format. Closes #14395. ## Showcase https://github.com/user-attachments/assets/52dfe05f-fdb3-477a-9462-ec150f93df33 ## Migration Guide * The `animgraph.ron` format has changed to accommodate the new *additive blending* feature. You'll need to change `clip` fields to instances of the new `AnimationNodeType` enum.
41 lines
No EOL
1,019 B
Text
41 lines
No EOL
1,019 B
Text
(
|
|
graph: (
|
|
nodes: [
|
|
(
|
|
node_type: Blend,
|
|
mask: 0,
|
|
weight: 1.0,
|
|
),
|
|
(
|
|
node_type: Blend,
|
|
mask: 0,
|
|
weight: 1.0,
|
|
),
|
|
(
|
|
node_type: Clip(AssetPath("models/animated/Fox.glb#Animation0")),
|
|
mask: 0,
|
|
weight: 1.0,
|
|
),
|
|
(
|
|
node_type: Clip(AssetPath("models/animated/Fox.glb#Animation1")),
|
|
mask: 0,
|
|
weight: 1.0,
|
|
),
|
|
(
|
|
node_type: Clip(AssetPath("models/animated/Fox.glb#Animation2")),
|
|
mask: 0,
|
|
weight: 1.0,
|
|
),
|
|
],
|
|
node_holes: [],
|
|
edge_property: directed,
|
|
edges: [
|
|
Some((0, 1, ())),
|
|
Some((0, 2, ())),
|
|
Some((1, 3, ())),
|
|
Some((1, 4, ())),
|
|
],
|
|
),
|
|
root: 0,
|
|
mask_groups: {},
|
|
) |