use std::f32::consts::{FRAC_PI_2, PI};
use bevy::prelude::*;
use keyframe_animate::prelude::*;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugin(KeyframeAnimationPlugin)
.insert_resource(AmbientLight {
color: Color::WHITE,
brightness: 1.0,
})
.add_startup_system(setup)
.run();
}
fn setup(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
commands.spawn_bundle(PerspectiveCameraBundle {
transform: Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
..default()
});
let planet = Name::new("planet");
let orbit_controller = Name::new("orbit_controller");
let satellite = Name::new("satellite");
let mut animation = KeyframeAnimationClip::default();
animation.add_curve_to_path(
KeyframeEntityPath {
parts: vec![planet.clone()],
},
KeyframeVariableCurve {
options: Some(vec!["translation".to_string()]),
keyframe_timestamps: vec![0.0, 1.0, 2.0, 3.0, 4.0],
keyframes: Keyframe::translation(vec![
Vec3::new(1.0, 0.0, 1.0),
Vec3::new(-1.0, 0.0, 1.0),
Vec3::new(-1.0, 0.0, -1.0),
Vec3::new(1.0, 0.0, -1.0),
Vec3::new(1.0, 0.0, 1.0),
]),
},
);
animation.add_curve_to_path(
KeyframeEntityPath {
parts: vec![planet.clone(), orbit_controller.clone()],
},
KeyframeVariableCurve {
options: Some(vec!["rotation".to_string()]),
keyframe_timestamps: vec![0.0, 1.0, 2.0, 3.0, 4.0],
keyframes: Keyframe::rotation(vec![
Quat::from_axis_angle(Vec3::Y, 0.0),
Quat::from_axis_angle(Vec3::Y, FRAC_PI_2),
Quat::from_axis_angle(Vec3::Y, PI),
Quat::from_axis_angle(Vec3::Y, 3.0 * FRAC_PI_2),
Quat::from_axis_angle(Vec3::Y, 0.0),
]),
},
);
animation.add_curve_to_path(
KeyframeEntityPath {
parts: vec![planet.clone(), orbit_controller.clone(), satellite.clone()],
},
KeyframeVariableCurve {
options: Some(vec!["scale".to_string()]),
keyframe_timestamps: vec![0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0],
keyframes: Keyframe::scale(vec![
Vec3::splat(0.8),
Vec3::splat(1.2),
Vec3::splat(0.8),
Vec3::splat(1.2),
Vec3::splat(0.8),
Vec3::splat(1.2),
Vec3::splat(0.8),
Vec3::splat(1.2),
Vec3::splat(0.8),
]),
},
);
animation.add_curve_to_path(
KeyframeEntityPath {
parts: vec![planet.clone(), orbit_controller.clone(), satellite.clone()],
},
KeyframeVariableCurve {
options: Some(vec!["rotation".to_string()]),
keyframe_timestamps: vec![0.0, 1.0, 2.0, 3.0, 4.0],
keyframes: Keyframe::rotation(vec![
Quat::from_axis_angle(Vec3::Y, 0.0),
Quat::from_axis_angle(Vec3::Y, FRAC_PI_2),
Quat::from_axis_angle(Vec3::Y, PI),
Quat::from_axis_angle(Vec3::Y, 3.0 * FRAC_PI_2),
Quat::from_axis_angle(Vec3::Y, 0.0),
]),
},
);
let mut player = KeyframeAnimationPlayer::new(animation);
player.repeat();
commands
.spawn_bundle(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Icosphere::default())),
material: materials.add(Color::rgb(0.8, 0.7, 0.6).into()),
..default()
})
.insert_bundle((planet, player))
.with_children(|p| {
p.spawn_bundle(TransformBundle { ..default() })
.insert(orbit_controller)
.with_children(|p| {
p.spawn_bundle(PbrBundle {
transform: Transform::from_xyz(1.5, 0.0, 0.0),
mesh: meshes.add(Mesh::from(shape::Cube { size: 0.5 })),
material: materials.add(Color::rgb(0.3, 0.9, 0.3).into()),
..default()
})
.insert(satellite);
});
});
}