abstract out orbit calculation into nature::pos_offset_for_orbiting_body()

This commit is contained in:
yuni 2024-07-12 15:32:45 +02:00
parent 90c89fc3f3
commit 5e9441dd5e
2 changed files with 35 additions and 21 deletions

View file

@ -16,7 +16,6 @@ use bevy::pbr::{NotShadowCaster, NotShadowReceiver};
use bevy::prelude::*; use bevy::prelude::*;
use bevy_xpbd_3d::prelude::*; use bevy_xpbd_3d::prelude::*;
use regex::Regex; use regex::Regex;
use std::time::SystemTime;
pub const ID_SPECIAL_PLAYERCAM: &str = "PLAYERCAMERA"; pub const ID_SPECIAL_PLAYERCAM: &str = "PLAYERCAMERA";
pub const ID_EARTH: &str = "earth"; pub const ID_EARTH: &str = "earth";
@ -811,30 +810,19 @@ fn spawn_entities(
state.pos state.pos
}; };
if let Some(r) = state.orbit_distance { if let Some(r) = state.orbit_distance {
let mut phase_radians = 0.0f64; let mass: Option<f64> = if let Some(id) = &state.orbit_object_id {
if let Some(phase) = state.orbit_phase { match id.as_str() {
phase_radians += phase; "jupiter" => Some(nature::JUPITER_MASS),
} "sol" => Some(nature::JUPITER_MASS),
if let Some(id) = &state.orbit_object_id {
let mass = match id.as_str() {
"jupiter" => nature::JUPITER_MASS,
"sol" => nature::JUPITER_MASS,
_ => { _ => {
error!("Found no mass for object `{id}`"); error!("Found no mass for object `{id}`");
continue; continue;
} }
};
let orbital_period = nature::simple_orbital_period(mass, r);
phase_radians +=
if let Ok(epoch) = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) {
let now = epoch.as_secs_f64() + 614533234154.0; // random
PI * 2.0 * (now % orbital_period) / orbital_period
} else {
error!("Can't determine current time `{id}`");
0.0
};
} }
absolute_pos += nature::phase_dist_to_coords(-phase_radians, r); } else {
None
};
absolute_pos += nature::pos_offset_for_orbiting_body(r, mass, state.orbit_phase);
} }
let scale = Vec3::splat( let scale = Vec3::splat(
if state.is_sun { if state.is_sun {

View file

@ -11,6 +11,7 @@
// This module manages the messy, impure parts of our universe. // This module manages the messy, impure parts of our universe.
use crate::prelude::*; use crate::prelude::*;
use std::time::SystemTime;
pub const OXYGEN_USE_KG_PER_S: f32 = 1e-5; pub const OXYGEN_USE_KG_PER_S: f32 = 1e-5;
pub const OXY_S: f32 = OXYGEN_USE_KG_PER_S; pub const OXY_S: f32 = OXYGEN_USE_KG_PER_S;
@ -33,6 +34,9 @@ pub const SOL_MASS: f64 = 1.9885e30;
pub const JUPITER_MASS: f64 = 1.8982e27; pub const JUPITER_MASS: f64 = 1.8982e27;
pub const EARTH_MASS: f64 = 5.972168e24; pub const EARTH_MASS: f64 = 5.972168e24;
// Arbitrary offset to time epoch, to generate more interesting orbital arrangements:
pub const ORBIT_TIME_OFFSET: f64 = 614533234154.0;
// Each star's values: (x, y, z, magnitude, color index, distance, name) // Each star's values: (x, y, z, magnitude, color index, distance, name)
pub const STARS: &[(f32, f32, f32, f32, f32, f32, &str)] = &include!("data/stars.in"); pub const STARS: &[(f32, f32, f32, f32, f32, f32, &str)] = &include!("data/stars.in");
@ -204,3 +208,25 @@ pub fn phase_dist_to_coords(phase_radians: f64, distance: f64) -> DVec3 {
distance * phase_radians.sin(), distance * phase_radians.sin(),
); );
} }
pub fn pos_offset_for_orbiting_body(
orbit_distance: f64,
orbited_mass: Option<f64>,
phase_offset: Option<f64>,
) -> DVec3 {
let r = orbit_distance;
let mut phase_radians = 0.0f64;
if let Some(phase_offset) = phase_offset {
phase_radians += phase_offset
}
if let Some(mass) = orbited_mass {
if let Ok(epoch) = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) {
let orbital_period = simple_orbital_period(mass, r);
let now = epoch.as_secs_f64() + ORBIT_TIME_OFFSET;
phase_radians += PI * 2.0 * (now % orbital_period) / orbital_period;
} else {
eprintln!("WARNING: Can't determine current time in calculate_position_offset_for_orbiting_body().");
}
}
return phase_dist_to_coords(-phase_radians, r);
}