#![allow(unused)] use glam::DVec3; use once_cell::sync::Lazy; use std::sync::RwLock; use log::{debug}; use crate::config::{Body, Normalization}; pub type Position = DVec3; pub type Velocity = DVec3; pub type Acceleration = DVec3; pub type Mass = f64; pub type Time = f64; // Constants const EARTH_RADIUS: f64 = 6.378e6; //meters const EARTH_MASS: f64 = 5.972e24; //kg const EARTH_ORBITAL_VELOCITY: f64 = 2.9780e4; //m/s const AU: f64 = 1.49597870700e11; //meters const MOON_MASS: Mass = 7.34767309e22; // kg const MOON_ORBITAL_VELOCITY: f64 = 1.022e3; //m/s relative to earth const SUN_MASS: f64 = 1.989e30; //kg const SUN_RADIUS: f64 = 6.957e8; //meters const G: f64 = 6.67430e-11; // Default normalization constants const DEFAULT_R_0: f64 = EARTH_RADIUS; const DEFAULT_M_0: f64 = EARTH_MASS; // Global normalization context static NORMALIZATION: Lazy> = Lazy::new(|| { RwLock::new(NormalizationContext::default()) }); #[derive(Debug, Clone)] pub struct NormalizationContext { pub r_0: f64, pub m_0: f64, pub t_0: f64, } impl Default for NormalizationContext { fn default() -> Self { let r_0 = DEFAULT_R_0; let m_0 = DEFAULT_M_0; let t_0 = (r_0.powf(3.0) / (G * m_0)).sqrt(); debug!("Using default normalization: r_0 = {}, m_0 = {}, t_0 = {}", r_0, m_0, t_0); Self { r_0, m_0, t_0 } } } impl From<&Normalization> for NormalizationContext { fn from(norm: &Normalization) -> Self { Self { r_0: norm.r_0, m_0: norm.m_0, t_0: norm.t_0 } } } /// Set the global normalization context from a config normalization pub fn set_normalization(norm: &Normalization) { let mut context = NORMALIZATION.write().unwrap(); *context = NormalizationContext::from(norm); } /// Reset to default normalization pub fn reset_normalization() { let mut context = NORMALIZATION.write().unwrap(); *context = NormalizationContext::default(); } /// Get current normalization context pub fn get_normalization() -> NormalizationContext { NORMALIZATION.read().unwrap().clone() } #[inline] pub fn norm_pos(pos: Position) -> Position { let norm = get_normalization(); pos / norm.r_0 } #[inline] pub fn real_pos(pos: Position) -> Position { let norm = get_normalization(); pos * norm.r_0 } #[inline] pub fn norm_mass(mass: Mass) -> Mass { let norm = get_normalization(); mass / norm.m_0 } #[inline] pub fn real_mass(mass: Mass) -> Mass { let norm = get_normalization(); mass * norm.m_0 } #[inline] pub fn norm_time(time: Time) -> Time { let norm = get_normalization(); time / norm.t_0 } #[inline] pub fn real_time(time: Time) -> Time { let norm = get_normalization(); time * norm.t_0 } #[inline] pub fn norm_vel(vel: Velocity) -> Velocity { let norm = get_normalization(); vel / (norm.r_0 / norm.t_0) } #[inline] pub fn real_vel(vel: Velocity) -> Velocity { let norm = get_normalization(); vel * (norm.r_0 / norm.t_0) } #[inline] pub fn norm_acc(acc: Acceleration) -> Acceleration { let norm = get_normalization(); acc / (norm.r_0 / (norm.t_0 * norm.t_0)) } #[inline] pub fn real_acc(acc: Acceleration) -> Acceleration { let norm = get_normalization(); acc * (norm.r_0 / (norm.t_0 * norm.t_0)) } #[inline] pub fn norm_body(body: Body) -> Body { Body { name: body.name, mass: norm_mass(body.mass), position: norm_pos(body.position), velocity: norm_vel(body.velocity), acceleration: DVec3::ZERO, } } #[inline] pub fn real_body(body: &Body) -> Body { Body { name: body.name.clone(), mass: real_mass(body.mass), position: real_pos(body.position), velocity: real_vel(body.velocity), acceleration: DVec3::ZERO, } }