#[cfg(test)]
mod tests {
#[test]
fn it_works() {
let result = 2 + 2;
assert_eq!(result, 4);
}
}
use bevy::{core::FixedTimestep, prelude::*};
use smooth_bevy_cameras::{
controllers::fps::{FpsCameraBundle, FpsCameraController, FpsCameraPlugin},
LookTransformPlugin,
};
mod components;
mod creation;
mod generation;
mod gravity;
pub mod utils;
pub use bevy::math::Vec3;
pub use generation::{Prefab, Prefab::*};
pub use utils::colors;
#[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)]
struct FixedUpdateStage;
pub struct Settings {
time_step: f32,
gravity_constant: f32,
particle_radius: f32,
camera_position: Vec3,
}
struct Systems(Vec<Prefab>);
pub struct Simulation {
time_step: f32,
gravity_constant: f32,
particle_radius: f32,
camera_position: Vec3,
background_color: Color,
systems: Vec<Prefab>,
}
impl Simulation {
pub fn new(
time_step: f32,
gravity_constant: f32,
particle_radius: f32,
camera_position: Vec3,
background_color: Color,
) -> Self {
Self {
time_step,
gravity_constant,
particle_radius,
camera_position,
background_color,
systems: vec![],
}
}
pub fn config(&mut self, systems: Vec<Prefab>) {
self.systems = systems;
}
pub fn run(&self) {
App::new()
.insert_resource(Msaa { samples: 4 })
.insert_resource(ClearColor(self.background_color))
.insert_resource(Settings {
time_step: self.time_step,
gravity_constant: self.gravity_constant,
particle_radius: self.particle_radius,
camera_position: self.camera_position,
})
.insert_resource(Systems(self.systems.clone()))
.add_plugins(DefaultPlugins)
.add_plugin(LookTransformPlugin)
.add_plugin(FpsCameraPlugin::default())
.add_startup_system(Self::setup)
.add_stage_after(
CoreStage::Update,
FixedUpdateStage,
SystemStage::parallel()
.with_run_criteria(FixedTimestep::step(self.time_step as f64))
.with_system(gravity::interact_bodies)
.with_system(gravity::interact_particles_with_bodies)
.with_system(gravity::integrate),
)
.run();
}
fn setup(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
settings: Res<Settings>,
systems: Res<Systems>,
) {
for syst in systems.0.iter() {
match syst {
Particle {
initial_position,
initial_velocity,
color,
} => {
creation::create_particle(
*initial_position,
*initial_velocity,
*color,
&mut commands,
&mut meshes,
&mut materials,
&settings,
);
}
Body {
mass,
radius,
initial_position,
initial_velocity,
color,
} => {
creation::create_body(
*mass,
*radius,
*color,
*initial_position,
*initial_velocity,
&mut commands,
&mut meshes,
&mut materials,
&settings,
);
}
Galaxy {
amount,
arms,
center_mass,
center_pos,
center_vel,
normal,
particle_color,
center_color,
} => {
creation::create_galaxy(
*amount,
*arms,
*center_mass,
*center_pos,
*center_vel,
*normal,
*particle_color,
*center_color,
&mut commands,
&mut meshes,
&mut materials,
&settings,
);
}
AsteroidBelt {
amount,
radius,
center_mass,
center_pos,
center_vel,
normal,
particle_color,
} => {
creation::create_asteroid_belt(
*amount,
*radius,
*center_mass,
*center_pos,
*center_vel,
*normal,
*particle_color,
&mut commands,
&mut meshes,
&mut materials,
&settings,
);
}
}
}
commands.insert_resource(AmbientLight {
color: Color::WHITE,
brightness: 0.5,
});
commands.spawn_bundle(FpsCameraBundle::new(
FpsCameraController::default(),
PerspectiveCameraBundle::default(),
settings.camera_position,
Vec3::new(0.0, 0.0, 0.0),
));
}
}