This repository has been archived by the owner on Aug 29, 2023. It is now read-only.
/
nbody.rs
78 lines (70 loc) · 1.99 KB
/
nbody.rs
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
use crate::G;
use bevy::math::Vec3;
use bevy::prelude::*;
use heron::{should_run, Acceleration};
use particular::prelude::*;
#[particle(3)]
pub struct Body {
position: Vec3,
mu: f32,
entity: Entity,
}
impl Body {
pub fn new(position: Vec3, mu: f32, entity: Entity) -> Self {
Self {
position,
mu,
entity,
}
}
}
#[derive(Component)]
pub enum PointMass {
HasGravity { mass: f32 },
AffectedByGravity,
}
pub struct ParticularPlugin;
impl Plugin for ParticularPlugin {
fn build(&self, app: &mut bevy::prelude::App) {
app.insert_resource(ParticleSet::<Body>::new())
.add_system_set_to_stage(
CoreStage::PreUpdate,
SystemSet::new()
.with_run_criteria(should_run)
.with_system(sync_particle_set),
)
.add_system_set_to_stage(
CoreStage::Update,
SystemSet::new()
.with_run_criteria(should_run)
.with_system(accelerate_particles),
);
}
}
fn sync_particle_set(
mut particle_set: ResMut<ParticleSet<Body>>,
query: Query<(Entity, &GlobalTransform, &PointMass)>,
) {
*particle_set = ParticleSet::new();
query.for_each(|(entity, tranform, point_mass)| {
let position = tranform.translation();
match point_mass {
PointMass::HasGravity { mass } => {
particle_set.add_massive(Body::new(position, mass * G, entity))
}
PointMass::AffectedByGravity => {
particle_set.add_massless(Body::new(position, 0.0, entity))
}
};
})
}
fn accelerate_particles(
mut particle_set: ResMut<ParticleSet<Body>>,
mut query: Query<&mut Acceleration, With<PointMass>>,
) {
for (gravity, body) in particle_set.result() {
if let Ok(mut acceleration) = query.get_mut(body.entity) {
acceleration.linear = gravity;
}
}
}