1mod math;
2
3use bevy::prelude::*;
4
5pub mod prelude {
6 pub use super::{Mass, Orbit, OrbitPlugin};
7}
8
9pub struct OrbitPlugin;
10
11impl Plugin for OrbitPlugin {
12 fn build(&self, app: &mut App) {
13 app.add_system_to_stage(
14 CoreStage::PostUpdate,
15 calculate_orbits.before(bevy::transform::transform_propagate_system),
16 );
17 }
18}
19
20#[derive(Component)]
21pub struct Orbit {
22 pub semi_major_axis: f32,
23 pub eccentricity: f32,
24 pub argument_of_periapsis: f32,
25 pub initial_mean_anomaly: f32,
26}
27
28#[derive(Component)]
29pub struct Mass {
30 pub mass: f32,
31}
32
33pub fn calculate_orbits(
34 time: Res<Time>,
35 masses: Query<&Mass>,
36 mut orbits: Query<(&Orbit, &mut Transform, Option<&Parent>)>,
37) {
38 for (orbit, mut transform, maybe_parent) in orbits.iter_mut() {
39 if orbit.semi_major_axis == 0.0 {
40 transform.translation = Vec3::ZERO;
41 continue;
42 }
43
44 let Some(parent) = maybe_parent else {
45 transform.translation = Vec3::ZERO;
46 continue;
47 };
48
49 let Some(parent_mass) = masses.get_component::<Mass>(parent.get()).ok() else {
50 warn!("Parent entity {parent:?} is missing Mass component");
51 continue;
52 };
53
54 let pos = math::calculate_position_at_time(
55 orbit.semi_major_axis,
56 orbit.eccentricity,
57 orbit.argument_of_periapsis,
58 orbit.initial_mean_anomaly,
59 parent_mass.mass,
60 time.elapsed_seconds(),
61 );
62 transform.translation = Vec3::from(pos);
63 }
64}