use bevy::prelude::*; use cyber_rider::flycam::{MovementSettings, PlayerPlugin, PLANET_RADIUS}; /* stolen with neither shame nor pity from git@github.com:sburris0/bevy_flycam.git, b90f6fc, which is copyright 2020 Spencer Burris */ const LIGHT_RANGE: f32 = PLANET_RADIUS * 2.2; const LIGHT_DIST: f32 = PLANET_RADIUS * 1.2; fn main() { App::new() .insert_resource(Msaa { samples: 4 }) .add_plugins(DefaultPlugins) .add_plugin(PlayerPlugin) .insert_resource(MovementSettings { sensitivity: 0.3, // default: 1.0 accel: 20.0, // default: 40.0 drag: 0.1, // default: 0.05 gravity: 10.0, // default: 10.0 }) .add_startup_system(setup.label("world")) .add_startup_system(disable_cursor.after("world")) .add_system(animate_lights) .add_system(bevy::input::system::exit_on_esc_system) .run(); } fn disable_cursor(mut windows: ResMut) { let window = windows.get_primary_mut().unwrap(); window.set_cursor_lock_mode(false); window.set_cursor_visibility(true); } #[derive(Component)] struct Animate; fn setup( mut commands: Commands, mut meshes: ResMut>, mut materials: ResMut>, ) { let red_light = PointLight { intensity: 5_000.0, range: LIGHT_RANGE, color: Color::RED, ..Default::default() }; let blue_light = PointLight { intensity: 5_000.0, range: LIGHT_RANGE, color: Color::BLUE, ..Default::default() }; let purple_light = PointLight { intensity: 5_000.0, range: LIGHT_RANGE, color: Color::PURPLE, ..Default::default() }; commands.insert_resource(AmbientLight { color: Color::WHITE, brightness: 0.12, }); // world commands.spawn_bundle(PbrBundle { mesh: meshes.add(Mesh::from(shape::Icosphere { radius: PLANET_RADIUS, subdivisions: 6, })), material: materials.add(StandardMaterial { base_color: Color::GRAY, metallic: 0.7, perceptual_roughness: 0.5, ..Default::default() }), ..Default::default() }); // east light commands .spawn_bundle(PointLightBundle { transform: Transform::from_xyz(LIGHT_DIST, 0.0, 0.0), point_light: purple_light, ..Default::default() }) .with_children(|builder| { builder.spawn_bundle(PbrBundle { mesh: meshes.add(Mesh::from(shape::UVSphere { radius: 10.0, ..Default::default() })), material: materials.add(StandardMaterial { base_color: Color::PURPLE, emissive: Color::rgba_linear(50.0, 0.0, 50.0, 0.0), ..Default::default() }), ..Default::default() }); }) .insert(Animate); // west light commands .spawn_bundle(PointLightBundle { transform: Transform::from_xyz(-LIGHT_DIST, 0.0, 0.0), point_light: purple_light, ..Default::default() }) .with_children(|builder| { builder.spawn_bundle(PbrBundle { mesh: meshes.add(Mesh::from(shape::UVSphere { radius: 10.0, ..Default::default() })), material: materials.add(StandardMaterial { base_color: Color::PURPLE, emissive: Color::rgba_linear(50.0, 0.0, 50.0, 0.0), ..Default::default() }), ..Default::default() }); }) .insert(Animate); // north light commands .spawn_bundle(PointLightBundle { transform: Transform::from_xyz(0.0, 0.0, LIGHT_DIST), point_light: purple_light, ..Default::default() }) .with_children(|builder| { builder.spawn_bundle(PbrBundle { mesh: meshes.add(Mesh::from(shape::UVSphere { radius: 10.0, ..Default::default() })), material: materials.add(StandardMaterial { base_color: Color::PURPLE, emissive: Color::rgba_linear(50.0, 0.0, 50.0, 0.0), ..Default::default() }), ..Default::default() }); }) .insert(Animate); // south light commands .spawn_bundle(PointLightBundle { transform: Transform::from_xyz(0.0, 0.0, -LIGHT_DIST), point_light: purple_light, ..Default::default() }) .with_children(|builder| { builder.spawn_bundle(PbrBundle { mesh: meshes.add(Mesh::from(shape::UVSphere { radius: 10.0, ..Default::default() })), material: materials.add(StandardMaterial { base_color: Color::PURPLE, emissive: Color::rgba_linear(50.0, 0.0, 50.0, 0.0), ..Default::default() }), ..Default::default() }); }) .insert(Animate); // up light commands .spawn_bundle(PointLightBundle { transform: Transform::from_xyz(0.0, LIGHT_DIST, 0.0), point_light: red_light, ..Default::default() }) .with_children(|builder| { builder.spawn_bundle(PbrBundle { mesh: meshes.add(Mesh::from(shape::Icosphere { radius: 10.0, subdivisions: 2, })), material: materials.add(StandardMaterial { base_color: Color::RED, emissive: Color::rgba_linear(100.0, 0.0, 0.0, 0.0), ..Default::default() }), ..Default::default() }); }); // down light commands .spawn_bundle(PointLightBundle { transform: Transform::from_xyz(0.0, -LIGHT_DIST, 0.0), point_light: blue_light, ..Default::default() }) .with_children(|builder| { builder.spawn_bundle(PbrBundle { mesh: meshes.add(Mesh::from(shape::Icosphere { radius: 10.0, subdivisions: 2, })), material: materials.add(StandardMaterial { base_color: Color::BLUE, emissive: Color::rgba_linear(0.0, 0.0, 100.0, 0.0), ..Default::default() }), ..Default::default() }); }); } fn animate_lights(mut query: Query<&mut Transform, (With, With)>) { for mut transform in query.iter_mut() { let translation = &transform.translation; let x = translation.x; let y = translation.y; let z = if translation.z.abs() < 0.1 { translation.z + 0.15 } else { translation.z }; // 10 degrees == 0.174533 radians let anim_rate = 0.174533 / 5.0; let theta = z.atan2(x) + anim_rate; let x_new = LIGHT_DIST * theta.cos(); let z_new = LIGHT_DIST * theta.sin(); *transform = Transform::from_xyz(x_new, y, z_new); } }