use bevy::prelude::*;
use bevy_midi_params::{MidiParams, MidiParamsPlugin};
#[derive(Resource, MidiParams)]
struct MeshController {
#[midi(16, 0..4)]
pub mesh_index: i32,
pub prev_mesh_index: usize,
#[midi(20)] #[midi(21)] #[midi(22)] #[midi(23)] pub mesh_color: LinearRgba,
#[midi(24, -5.0..5.0)] #[midi(25, -5.0..5.0)] #[midi(26, -5.0..5.0)] pub position_offset: Vec3,
#[midi(58)]
pub visible: bool,
#[midi(19, 0.0..10.0)]
pub rotation_speed: f32,
}
impl Default for MeshController {
fn default() -> Self {
Self {
mesh_index: 0,
prev_mesh_index: 0,
mesh_color: LinearRgba::rgb(1.0, 0.5, 0.3),
position_offset: Vec3::ZERO,
visible: true,
rotation_speed: 1.0,
}
}
}
#[derive(Component)]
struct MeshDisplay {
meshes: Vec<Handle<Mesh>>,
}
#[derive(Component)]
struct RotatingMesh;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(MidiParamsPlugin::default().with_controller("midi mix")) .init_resource::<MeshController>() .add_systems(Startup, setup)
.add_systems(Update, (update_mesh_display, rotate_mesh))
.run();
}
fn setup(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
commands.spawn((
Camera3d::default(),
Transform::from_xyz(0.0, 5.0, 10.0).looking_at(Vec3::ZERO, Vec3::Y),
));
commands.spawn((
DirectionalLight {
illuminance: 10_000.0,
shadows_enabled: true,
..default()
},
Transform::from_rotation(Quat::from_euler(EulerRot::XYZ, -0.5, -0.5, 0.0)),
));
let mesh_handles = vec![
meshes.add(Cuboid::new(2.0, 2.0, 2.0)),
meshes.add(Sphere::new(1.5).mesh().ico(5).unwrap()),
meshes.add(Cylinder::new(1.0, 2.0)),
meshes.add(Torus::new(1.0, 0.5)),
meshes.add(Capsule3d::new(0.5, 2.0)),
];
commands.spawn((
Mesh3d(mesh_handles[0].clone()),
MeshMaterial3d(materials.add(StandardMaterial {
base_color: Color::LinearRgba(LinearRgba::rgb(1.0, 0.5, 0.3)),
..default()
})),
Transform::from_xyz(0.0, 0.0, 0.0),
MeshDisplay {
meshes: mesh_handles,
},
RotatingMesh,
));
}
fn update_mesh_display(
mut controller: ResMut<MeshController>,
mut query: Query<(
&mut Mesh3d,
&mut Transform,
&mut Visibility,
&MeshMaterial3d<StandardMaterial>,
&MeshDisplay,
)>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
for (mut mesh, mut transform, mut visibility, mat_handle, display) in &mut query {
let index = (controller.mesh_index as usize) % display.meshes.len();
if controller.prev_mesh_index != index {
mesh.0 = display.meshes[index].clone();
controller.prev_mesh_index = index;
}
transform.translation = controller.position_offset;
*visibility = if controller.visible {
Visibility::Visible
} else {
Visibility::Hidden
};
if let Some(material) = materials.get_mut(&mat_handle.0) {
material.base_color = Color::LinearRgba(controller.mesh_color);
}
}
}
fn rotate_mesh(
time: Res<Time>,
controller: Res<MeshController>,
mut query: Query<&mut Transform, With<RotatingMesh>>,
) {
for mut transform in &mut query {
transform.rotate_y(controller.rotation_speed * time.delta_secs());
}
}