From 5e9441dd5e733e576f8e2fd27e66119ba6921196 Mon Sep 17 00:00:00 2001 From: yuni Date: Fri, 12 Jul 2024 15:32:45 +0200 Subject: [PATCH] abstract out orbit calculation into nature::pos_offset_for_orbiting_body() --- src/cmd.rs | 30 +++++++++--------------------- src/nature.rs | 26 ++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 21 deletions(-) diff --git a/src/cmd.rs b/src/cmd.rs index 020b9ff..e7bdb13 100644 --- a/src/cmd.rs +++ b/src/cmd.rs @@ -16,7 +16,6 @@ use bevy::pbr::{NotShadowCaster, NotShadowReceiver}; use bevy::prelude::*; use bevy_xpbd_3d::prelude::*; use regex::Regex; -use std::time::SystemTime; pub const ID_SPECIAL_PLAYERCAM: &str = "PLAYERCAMERA"; pub const ID_EARTH: &str = "earth"; @@ -811,30 +810,19 @@ fn spawn_entities( state.pos }; if let Some(r) = state.orbit_distance { - let mut phase_radians = 0.0f64; - if let Some(phase) = state.orbit_phase { - phase_radians += phase; - } - if let Some(id) = &state.orbit_object_id { - let mass = match id.as_str() { - "jupiter" => nature::JUPITER_MASS, - "sol" => nature::JUPITER_MASS, + let mass: Option = if let Some(id) = &state.orbit_object_id { + match id.as_str() { + "jupiter" => Some(nature::JUPITER_MASS), + "sol" => Some(nature::JUPITER_MASS), _ => { error!("Found no mass for object `{id}`"); 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( if state.is_sun { diff --git a/src/nature.rs b/src/nature.rs index 7071fc9..68e5601 100644 --- a/src/nature.rs +++ b/src/nature.rs @@ -11,6 +11,7 @@ // This module manages the messy, impure parts of our universe. use crate::prelude::*; +use std::time::SystemTime; pub const OXYGEN_USE_KG_PER_S: f32 = 1e-5; 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 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) 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(), ); } + +pub fn pos_offset_for_orbiting_body( + orbit_distance: f64, + orbited_mass: Option, + phase_offset: Option, +) -> 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); +}