use crate::timeman; use super::*; pub type BodyId = usize; pub const BODY_TICK_DURATION: Second = timeman::DAY; pub struct OrbitalBody { id: BodyId, name: String, mass: Kilograms, radius: Kilometers, sgp: f64, orbit: Option, rel_pos: Option<(i64, cgmath::Vector3)> } impl StaticOrbiter for OrbitalBody { fn orbit(&self) -> Option<&StaticOrbit> { self.orbit.as_ref() } fn sgp(&self) -> f64 { self.sgp } } impl OrbitalBody { pub const TICK_DURATION: Second = BODY_TICK_DURATION; pub fn new_from_record( id: BodyId, record: CSVOrbitalBody) -> Self { Self { id: id, name: record.name, mass: record.mass, radius: record.radius, sgp: record.sgp, orbit: match record.orbits { Some(parent) => Some(StaticOrbit::new( parent, record.eccentricity, record.inclination, record.long_asc_node, record.long_periapsis, record.mean_long, record.semi_major_axis )), None => None }, rel_pos: None } } pub fn id(&self) -> BodyId { self.id } pub fn name(&self) -> &String { &self.name } pub fn radius(&self) -> f32 { self.radius as f32 } pub fn mass(&self) -> Kilograms { self.mass } pub fn sgp(&self) -> f64 { self.sgp } pub fn relative_position( &self, time: Second) -> cgmath::Vector3 { let time = time - (time % BODY_TICK_DURATION); self.calculate_orbit_at(time) } pub fn absolute_position( &self, solar_system: &SolarSystem, time: Second) -> cgmath::Vector3 { match &self.orbit { Some(orbit) => { let parent_pos = solar_system.bodies()[orbit.parent()].absolute_position(solar_system, time); parent_pos + self.relative_position(time) }, None => self.relative_position(time) } } pub fn get_orbit(&self) -> &Option { &self.orbit } pub fn orbital_period( &self ) -> Second { match &self.orbit { Some(v) => v.period(self), None => return 0 } } pub fn calculate_orbit_at( &self, time: Second) -> cgmath::Vector3 { match &self.orbit { Some(orbit) => orbit.calculate_position_at(self, time), None => cgmath::vec3(0.0, 0.0, 0.0) } } }