use std::f32::consts::TAU; use bevy::prelude::*; use rand::prelude::*; use crate::geometry::PLANET_RADIUS; pub const LIGHT_RANGE: f32 = 50.0; #[derive(Component)] struct AnimatedCyberLight { axis: Vec3, rate: f32, } #[derive(Component)] pub(crate) struct AnimateCyberLightWireframe; fn spawn_lights( mut commands: Commands, mut meshes: ResMut>, mut materials: ResMut>, ) { let pink_light = PointLight { intensity: 1_00.0, range: LIGHT_RANGE, color: Color::PINK, radius: 1.0, shadows_enabled: true, ..Default::default() }; let blue_light = PointLight { intensity: 1_000.0, range: LIGHT_RANGE, color: Color::BLUE, radius: 1.0, shadows_enabled: true, ..Default::default() }; commands.insert_resource(AmbientLight { color: Color::WHITE, brightness: 0.32, }); let rng = &mut thread_rng(); // spawn 200 orbiting bisexual lights for _ in 0..255 { let hue = rng.gen_range(260.0..320.0); let saturation = rng.gen_range(0.85..0.99); let lightness = rng.gen_range(0.3..0.7); let color = Color::hsl(hue, saturation, lightness); let axis = crate::random_sphere_vec(rng); let angle = rng.gen_range(0.0..TAU); let rate: f32 = rng.gen_range(7.0..10.0); let rate = rate.to_radians(); let rotation = Quat::from_axis_angle(axis, angle); let altitude = PLANET_RADIUS + rng.gen_range(8.0..20.0); let perp = axis.any_orthonormal_vector(); let translation = perp * altitude; let transform = Transform::from_translation(translation); let intensity = rng.gen_range(500.0..900.0); let radius = rng.gen::() * 2.5; // why can't this infer the gen type? let point_light = PointLight { intensity, range: LIGHT_RANGE, color, radius, shadows_enabled: true, ..Default::default() }; commands .spawn_bundle(( AnimatedCyberLight { axis, rate }, Transform::from_rotation(rotation), GlobalTransform::default(), )) .with_children(|parent| { parent .spawn_bundle(PointLightBundle { transform, point_light, ..Default::default() }) .with_children(|builder| { builder .spawn_bundle(PbrBundle { mesh: meshes.add(Mesh::from(shape::Icosphere { radius, subdivisions: 1, })), material: materials.add(StandardMaterial { base_color: color, emissive: color, ..Default::default() }), ..Default::default() }) .insert(AnimateCyberLightWireframe); }); // mesh child }); // light child } // up light commands .spawn_bundle(PointLightBundle { transform: Transform::from_xyz(0.0, PLANET_RADIUS + 30.0, 0.0), point_light: pink_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, -PLANET_RADIUS - 30.0, 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 orbit_lights(time: Res