use std::f32::consts::PI; use bevy::{ diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin}, math::Vec3A, prelude::*, }; use bevy_polyline::prelude::*; use lazy_static::*; use rand::{prelude::*, Rng}; use ringbuffer::{ConstGenericRingBuffer, RingBuffer}; const NUM_BODIES: usize = 512; const TRAIL_LENGTH: usize = 1024; const MINIMUM_ANGLE: f32 = 1.483_418_7; // == acos(5 degrees) fn main() { App::new() .insert_resource(ClearColor(Color::BLACK)) .insert_resource(Msaa::Sample4) .insert_resource(Simulation { scale: 1e6, ..Default::default() }) .add_plugins(DefaultPlugins) .add_plugins(PolylinePlugin) .add_systems(Startup, setup) .add_systems( Update, ((nbody_system, update_trails).chain(), rotator_system), ) .add_plugins(FrameTimeDiagnosticsPlugin) .add_plugins(LogDiagnosticsPlugin::default()) .run(); } fn setup( mut commands: Commands, mut polyline_materials: ResMut>, mut polylines: ResMut>, ) { let mut rng = StdRng::seed_from_u64(0); for _index in 0..NUM_BODIES { let r = rng.gen_range(2f32..800f32); let theta = rng.gen_range(0f32..2.0 * PI); let position = Vec3A::new( r * f32::cos(theta), rng.gen_range(-500f32..500f32), r * f32::sin(theta), ); let size = rng.gen_range(50f32..1000f32); commands.spawn(( Body { mass: size, position, velocity: position.cross(Vec3A::Y).normalize() * 0.00010, ..Default::default() }, Trail(ConstGenericRingBuffer::::new()), PolylineBundle { polyline: polylines.add(Polyline { vertices: Vec::with_capacity(TRAIL_LENGTH), }), material: polyline_materials.add(PolylineMaterial { width: (size * 0.1).powf(1.8), color: Color::hsl(rng.gen_range(0.0..360.0), 1.0, rng.gen_range(1.2..3.0)), perspective: true, ..Default::default() }), ..Default::default() }, )); } // camera commands.spawn(( Camera3dBundle { camera: Camera { hdr: true, ..default() }, tonemapping: bevy::core_pipeline::tonemapping::Tonemapping::TonyMcMapface, ..default() }, bevy::core_pipeline::bloom::BloomSettings { ..default() }, Rotates, )); } /// this component indicates what entities should rotate #[derive(Component)] struct Rotates; fn rotator_system(time: Res