From 1a515237afb7ad09353a65f5fbc6e98a7c29ce8e Mon Sep 17 00:00:00 2001 From: Kai Stevenson Date: Sat, 22 Aug 2026 15:00:35 -0700 Subject: sim manager refactor --- src/sim/particle_manager/mod.rs | 85 ++++++++++++++++++++++++++++++++++++ src/sim/particle_manager/particle.rs | 21 +++++++++ 2 files changed, 106 insertions(+) create mode 100644 src/sim/particle_manager/mod.rs create mode 100644 src/sim/particle_manager/particle.rs (limited to 'src/sim/particle_manager') diff --git a/src/sim/particle_manager/mod.rs b/src/sim/particle_manager/mod.rs new file mode 100644 index 0000000..e5e47eb --- /dev/null +++ b/src/sim/particle_manager/mod.rs @@ -0,0 +1,85 @@ +use crate::{ + config::PIXELS_TO_METRES, + sim::{ + cell::{cell::Cell, materials::MaterialForm}, + cell_manager::manager::CellManager, + lib::ray::AwDda, + particle_manager::particle::Particle, + }, +}; + +pub mod particle; + +pub struct ParticleManager { + pub particles: Vec, +} + +const PARTICLE_GRAVITY: f32 = 9.81 * PIXELS_TO_METRES; + +impl ParticleManager { + pub fn tick(&mut self, world: &mut CellManager, delta_time: f32) { + puffin::profile_function!(); + let mut i = 0; + 'outer: while i < self.particles.len() { + let p = &mut self.particles[i]; + + p.life -= delta_time; + if p.life <= 0.0 { + self.particles.swap_remove(i); + continue 'outer; + } + + p.velocity.y += PARTICLE_GRAVITY * delta_time; + let dt_velocity = p.velocity * delta_time; + + let mut dda = AwDda::new(p.position, p.position + dt_velocity); + + if let Some(mut prev) = dda.next() { + if let Some(cell) = world.get_cell_from_game_position(prev.x, prev.y) + && [ + MaterialForm::Solid, + MaterialForm::Powder, + MaterialForm::Liquid, + ] + .contains(&cell.material.def().form) + { + // the particle is already inside a collider, we should just kill it + self.particles.swap_remove(i); + continue 'outer; + } + + for next in dda { + if let Some(cell) = world.get_cell_from_game_position(next.x, next.y) + && [ + MaterialForm::Solid, + MaterialForm::Powder, + MaterialForm::Liquid, + ] + .contains(&cell.material.def().form) + { + // write ourselves to the board + world.set_cell_from_game_position( + prev.x, + prev.y, + Cell::from_material(p.material), + false, + ); + self.particles.swap_remove(i); + continue 'outer; + } + prev = next; + } + } + + // no collision, just move + p.position += dt_velocity; + i += 1; + } + } + + pub fn new() -> Self { + ParticleManager { + particles: Vec::new(), + } + } +} diff --git a/src/sim/particle_manager/particle.rs b/src/sim/particle_manager/particle.rs new file mode 100644 index 0000000..cc7dd28 --- /dev/null +++ b/src/sim/particle_manager/particle.rs @@ -0,0 +1,21 @@ +use glam::Vec2; + +use crate::sim::cell::materials::MaterialId; + +pub struct Particle { + pub position: Vec2, + pub velocity: Vec2, + pub material: MaterialId, + pub life: f32, +} + +impl Particle { + pub fn new(position: Vec2, velocity: Vec2, material: MaterialId, life: f32) -> Self { + Particle { + position, + velocity, + material, + life, + } + } +} -- cgit v1.3.1