Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update particles example to support multiple gravity centers based on mouse clicks #30

Merged
merged 1 commit into from
May 9, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 21 additions & 10 deletions examples/particles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ fn main() -> Result<()> {

struct Particles {
particles: Vec<Particle>,
gravity_center: Point,
gravity_centers: Vec<Point>,
}

impl Particles {
Expand All @@ -45,7 +45,7 @@ impl Particles {

Particles {
particles,
gravity_center: Point::new(0.0, 0.0),
gravity_centers: Vec::new(),
}
})
}
Expand Down Expand Up @@ -84,6 +84,10 @@ impl Game for Particles {
input::Event::CursorMoved { x, y } => {
input.cursor_position = Point::new(x, y);
}
input::Event::MouseInput {
button: input::MouseButton::Left,
state: input::ButtonState::Released,
} => input.points_clicked.push(input.cursor_position),
input::Event::KeyboardInput {
key_code,
state: input::ButtonState::Released,
Expand All @@ -95,7 +99,9 @@ impl Game for Particles {
}

fn interact(&mut self, input: &mut Input, view: &mut View, _gpu: &mut Gpu) {
self.gravity_center = input.cursor_position;
for point in &input.points_clicked {
self.gravity_centers.push(*point);
}

for key in &input.released_keys {
match key {
Expand All @@ -106,20 +112,23 @@ impl Game for Particles {
}
}

input.points_clicked.clear();
input.released_keys.clear();
}

fn update(&mut self, _view: &View, _window: &Window) {
let gravity_center = self.gravity_center.clone();
let gravity_centers = self.gravity_centers.clone();

// Update particles in parallel! <3 rayon
self.particles.par_iter_mut().for_each(move |particle| {
let distance = particle.position - gravity_center;

particle.acceleration = -((Self::G * Self::MASS)
* distance.normalize())
/ distance.norm_squared().max(1000.0);

particle.acceleration = gravity_centers
.par_iter()
.map(|gravity_center| {
let distance = particle.position - gravity_center;
-((Self::G * Self::MASS) * distance.normalize())
/ distance.norm_squared().max(1000.0)
})
.sum();
particle.velocity += particle.acceleration;
particle.position += particle.velocity;
});
Expand Down Expand Up @@ -287,13 +296,15 @@ impl View {

struct Input {
cursor_position: Point,
points_clicked: Vec<Point>,
released_keys: Vec<input::KeyCode>,
}

impl Input {
fn new() -> Input {
Input {
cursor_position: Point::new(0.0, 0.0),
points_clicked: Vec::new(),
released_keys: Vec::new(),
}
}
Expand Down