1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
use crate::{
config::PIXELS_TO_METRES,
sim::{
cell::{cell::Cell, materials::MaterialForm},
cell_sim::world::World,
lib::ray::AwDda,
particle_sim::particle::Particle,
},
};
pub mod particle;
pub struct ParticleManager {
pub particles: Vec<Particle>,
}
const PARTICLE_GRAVITY: f32 = 9.81 * PIXELS_TO_METRES;
impl ParticleManager {
pub fn particle_tick(&mut self, world: &mut World, 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(),
}
}
}
|