Skip to content

Commit

Permalink
Merge pull request #46 from nixon-voxell/feature/sequence-builder
Browse files Browse the repository at this point in the history
Sequence builder
  • Loading branch information
nixon-voxell authored May 20, 2024
2 parents 10a1502 + 61b09da commit 474bc03
Show file tree
Hide file tree
Showing 8 changed files with 260 additions and 220 deletions.
85 changes: 65 additions & 20 deletions crates/motiongfx_core/src/action.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use bevy::prelude::*;
use crate::{
ease::{cubic, EaseFn},
f32lerp::F32Lerp,
prelude::MultiSequenceOrdering,
sequence::Sequence,
};

Expand Down Expand Up @@ -54,23 +55,7 @@ macro_rules! act {
};
}

#[macro_export]
macro_rules! play {
($commands:expr, $motion:expr,) => {
$crate::action::ActionBuilderExtension::play(&mut $commands, $motion)
};
($commands:expr, $($motion:expr,)+) => {
{
let commands = &mut $commands;
[
$($crate::action::ActionBuilderExtension::play(commands, ($motion))),+
]
}
};
}

pub use act;
pub use play;

/// Basic data structure to describe an animation action.
#[derive(Component, Clone, Copy)]
Expand Down Expand Up @@ -184,22 +169,69 @@ impl ActionMeta {
}
}

#[derive(Clone, Copy)]
pub struct Motion<T, U> {
pub action: Action<T, U>,
pub duration: f32,
}

pub trait ActionBuilderExtension {
fn play<T, U>(&mut self, motion: Motion<T, U>) -> Sequence
pub struct SequenceBuilder<'w, 's> {
commands: Commands<'w, 's>,
sequences: Vec<Sequence>,
}

impl<'a> SequenceBuilder<'a, 'a> {
/// Converts a [`Motion`] into a [`SequenceBuilder`].
pub fn add_motion<T, U>(mut self, motion: Motion<T, U>) -> Self
where
T: Send + Sync + 'static,
U: Send + Sync + 'static,
{
self.sequences.push(self.commands.play_motion(motion));
self
}

pub fn build(self) -> Vec<Sequence> {
self.sequences
}
}

impl MultiSequenceOrdering for SequenceBuilder<'_, '_> {
fn chain(self) -> Sequence {
self.sequences.chain()
}

fn all(self) -> Sequence {
self.sequences.all()
}

fn any(self) -> Sequence {
self.sequences.any()
}

fn flow(self, delay: f32) -> Sequence {
self.sequences.flow(delay)
}
}

pub trait SequenceBuilderExt<'w> {
/// Converts a [`Motion`] into a [`Sequence`].
fn play_motion<T, U>(&mut self, motion: Motion<T, U>) -> Sequence
where
T: Send + Sync + 'static,
U: Send + Sync + 'static;

/// Converts a [`Motion`] into a [`SequenceBuilder`].
fn add_motion<T, U>(&mut self, motion: Motion<T, U>) -> SequenceBuilder<'w, '_>
where
T: Send + Sync + 'static,
U: Send + Sync + 'static;

fn sleep(&mut self, duration: f32) -> Sequence;
}

impl ActionBuilderExtension for Commands<'_, '_> {
fn play<T, U>(&mut self, motion: Motion<T, U>) -> Sequence
impl<'w> SequenceBuilderExt<'w> for Commands<'w, '_> {
fn play_motion<T, U>(&mut self, motion: Motion<T, U>) -> Sequence
where
T: Send + Sync + 'static,
U: Send + Sync + 'static,
Expand All @@ -211,6 +243,19 @@ impl ActionBuilderExtension for Commands<'_, '_> {
Sequence::single(action_meta)
}

fn add_motion<T, U>(&mut self, motion: Motion<T, U>) -> SequenceBuilder<'w, '_>
where
T: Send + Sync + 'static,
U: Send + Sync + 'static,
{
let mut commands = self.reborrow();
let sequences = vec![commands.play_motion(motion)];
SequenceBuilder {
commands,
sequences,
}
}

fn sleep(&mut self, duration: f32) -> Sequence {
Sequence::empty(duration)
}
Expand Down
2 changes: 1 addition & 1 deletion crates/motiongfx_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub mod slide;

pub mod prelude {
pub use crate::{
action::{act, play, Action, ActionBuilderExtension},
action::{act, Action, SequenceBuilderExt},
color_palette::{ColorKey, ColorPalette},
cross_lerp::*,
ease,
Expand Down
17 changes: 14 additions & 3 deletions crates/motiongfx_core/src/motion/pbr_motion.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use bevy::prelude::*;
use bevy::{ecs::system::EntityCommands, prelude::*};

use super::AddNewAssetCommandExtension;

Expand Down Expand Up @@ -44,15 +44,15 @@ pub trait BuildPbrMotionExt {
) -> PbrMotion;
}

impl BuildPbrMotionExt for Commands<'_, '_> {
impl BuildPbrMotionExt for EntityCommands<'_> {
fn build_pbr(
&mut self,
transform: Transform,
mesh: Handle<Mesh>,
material: StandardMaterial,
) -> PbrMotion {
let id = self
.spawn(PbrBundle {
.insert(PbrBundle {
transform,
mesh,
..default()
Expand All @@ -67,3 +67,14 @@ impl BuildPbrMotionExt for Commands<'_, '_> {
}
}
}

impl BuildPbrMotionExt for Commands<'_, '_> {
fn build_pbr(
&mut self,
transform: Transform,
mesh: Handle<Mesh>,
material: StandardMaterial,
) -> PbrMotion {
self.spawn_empty().build_pbr(transform, mesh, material)
}
}
36 changes: 31 additions & 5 deletions crates/motiongfx_vello/src/motion/vector_motion.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use bevy::prelude::*;
use bevy::{ecs::system::EntityCommands, prelude::*};
use bevy_vello_graphics::prelude::*;
use motiongfx_core::motion::{transform_motion::TransformMotion, GetId};

Expand Down Expand Up @@ -61,10 +61,10 @@ pub trait BuildVectorMotionExt<T> {
) -> FSVectorMotion<T>;
}

impl<T: Component + Clone> BuildVectorMotionExt<T> for Commands<'_, '_> {
impl<T: Component + Clone> BuildVectorMotionExt<T> for EntityCommands<'_> {
fn build_fvector(&mut self, transform: Transform, vector: T, fill: Fill) -> FVectorMotion<T> {
let id = self
.spawn((transform, vector.clone(), fill.clone()))
.insert((transform, vector.clone(), fill.clone()))
.add_vello_scene()
.id();

Expand All @@ -83,7 +83,7 @@ impl<T: Component + Clone> BuildVectorMotionExt<T> for Commands<'_, '_> {
stroke: Stroke,
) -> SVectorMotion<T> {
let id = self
.spawn((transform, vector.clone(), stroke.clone()))
.insert((transform, vector.clone(), stroke.clone()))
.add_vello_scene()
.id();

Expand All @@ -103,7 +103,7 @@ impl<T: Component + Clone> BuildVectorMotionExt<T> for Commands<'_, '_> {
stroke: Stroke,
) -> FSVectorMotion<T> {
let id = self
.spawn((transform, vector.clone(), fill.clone(), stroke.clone()))
.insert((transform, vector.clone(), fill.clone(), stroke.clone()))
.add_vello_scene()
.id();

Expand All @@ -116,3 +116,29 @@ impl<T: Component + Clone> BuildVectorMotionExt<T> for Commands<'_, '_> {
}
}
}

impl<T: Component + Clone> BuildVectorMotionExt<T> for Commands<'_, '_> {
fn build_fvector(&mut self, transform: Transform, vector: T, fill: Fill) -> FVectorMotion<T> {
self.spawn_empty().build_fvector(transform, vector, fill)
}

fn build_svector(
&mut self,
transform: Transform,
vector: T,
stroke: Stroke,
) -> SVectorMotion<T> {
self.spawn_empty().build_svector(transform, vector, stroke)
}

fn build_fsvector(
&mut self,
transform: Transform,
vector: T,
fill: Fill,
stroke: Stroke,
) -> FSVectorMotion<T> {
self.spawn_empty()
.build_fsvector(transform, vector, fill, stroke)
}
}
26 changes: 13 additions & 13 deletions examples/easings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,12 @@ fn easings(mut commands: Commands, mut meshes: ResMut<Assets<Mesh>>) {
};

for i in 0..capacity {
let sphere = commands.build_pbr(
let sphere = commands.spawn(NotShadowCaster).build_pbr(
Transform::from_translation(Vec3::new(-5.0, (i as f32) - (capacity as f32) * 0.5, 0.0))
.with_scale(Vec3::ONE),
mesh_handle.clone(),
material.clone(),
);
commands.entity(sphere.id).insert(NotShadowCaster);
spheres.push(sphere);
}

Expand All @@ -56,18 +55,19 @@ fn easings(mut commands: Commands, mut meshes: ResMut<Assets<Mesh>>) {
.iter_mut()
.zip(easings)
.map(|(s, e)| {
play!(
commands,
s.to_translation_x(s.transform.translation.x + 10.0)
.with_ease(e)
.animate(4.0),
s.to_emissive(palette.get(ColorKey::Red) * 100.0)
.with_ease(e)
.animate(4.0),
)
.all()
commands
.add_motion(
s.to_translation_x(s.transform.translation.x + 10.0)
.with_ease(e)
.animate(4.0),
)
.add_motion(
s.to_emissive(palette.get(ColorKey::Red) * 100.0)
.animate(4.0),
)
.all()
})
.collect::<Vec<Sequence>>()
.collect::<Vec<_>>()
.all();

commands.spawn(SequencePlayerBundle {
Expand Down
39 changes: 21 additions & 18 deletions examples/hello_world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ fn hello_world(mut commands: Commands, mut meshes: ResMut<Assets<Mesh>>) {

for w in 0..WIDTH {
for h in 0..HEIGHT {
let cube = commands.build_pbr(
let cube = commands.spawn(NotShadowCaster).build_pbr(
Transform::from_translation(Vec3::new(
(w as f32) - (WIDTH as f32) * 0.5 - 1.0,
(h as f32) - (HEIGHT as f32) * 0.5,
Expand All @@ -41,7 +41,6 @@ fn hello_world(mut commands: Commands, mut meshes: ResMut<Assets<Mesh>>) {
mesh_handle.clone(),
material.clone(),
);
commands.entity(cube.id).insert(NotShadowCaster);
cubes.push(cube);
}
}
Expand All @@ -56,24 +55,28 @@ fn hello_world(mut commands: Commands, mut meshes: ResMut<Assets<Mesh>>) {

let circ_ease = ease::circ::ease_in_out;

let sequence = play!(
commands,
cube.to_scale(Vec3::splat(0.9))
let sequence = commands
.add_motion(
cube.to_scale(Vec3::splat(0.9))
.with_ease(circ_ease)
.animate(1.0),
)
.add_motion(
cube.to_translation_x(cube.transform.translation.x + 1.0)
.with_ease(circ_ease)
.animate(1.0),
)
.add_motion(
cube.to_rotation(Quat::from_euler(
EulerRot::XYZ,
0.0,
f32::to_radians(90.0),
0.0,
))
.with_ease(circ_ease)
.animate(1.0),
cube.to_translation_x(cube.transform.translation.x + 1.0)
.with_ease(circ_ease)
.animate(1.0),
cube.to_rotation(Quat::from_euler(
EulerRot::XYZ,
0.0,
f32::to_radians(90.0),
0.0,
))
.with_ease(circ_ease)
.animate(1.0),
)
.all();
)
.all();

cube_seqs.push(sequence);
}
Expand Down
Loading

0 comments on commit 474bc03

Please sign in to comment.