diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.rs | 6 | ||||
| -rw-r--r-- | src/solar_system.rs | 76 | ||||
| -rw-r--r-- | src/solar_system/orbit.rs | 58 | ||||
| -rw-r--r-- | src/tacmap.rs | 4 | ||||
| -rw-r--r-- | src/tacmap/camera.rs | 21 | ||||
| -rw-r--r-- | src/tacmap/orbit_render.rs | 2 | ||||
| -rw-r--r-- | src/timeman.rs | 9 |
7 files changed, 83 insertions, 93 deletions
diff --git a/src/main.rs b/src/main.rs index 4aeaa5e..fad750d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -87,11 +87,11 @@ impl GameState fn update( &mut self, - dt: Duration) + _dt: Duration) { let ticks = self.timeman.update(); ticks.iter().for_each(|time| { - solar_system::update_systems(self.solar_systems.iter_mut(), *time); + self.solar_systems.iter_mut().for_each(|system| { system.update(*time) }); }); } } @@ -111,7 +111,7 @@ impl ApplicationHandler for SystemicApp fn window_event( &mut self, event_loop: &ActiveEventLoop, - window_id: WindowId, + _window_id: WindowId, event: winit::event::WindowEvent, ) { let window = match &mut self.window { diff --git a/src/solar_system.rs b/src/solar_system.rs index c53f045..81567d0 100644 --- a/src/solar_system.rs +++ b/src/solar_system.rs @@ -2,7 +2,10 @@ pub mod orbit; pub mod ship; use serde::{Deserialize}; -use crate::{known_stars::*, solar_system::orbit::StaticOrbit, timeman::Second}; +use crate::known_stars::*; +use crate::solar_system::orbit::*; +use crate::solar_system::ship::*; +use crate::timeman::Second; use std::error::Error; const GRAVITATIONAL_CONSTANT: f64 = 6.67408e-20; @@ -48,16 +51,9 @@ pub struct SolarSystem { id: SystemId, name: String, + bodies: Vec<OrbitalBody>, -} - -pub fn update_systems( - solar_systems: std::slice::IterMut<'_, SolarSystem>, - time: Second) -{ - for system in solar_systems { - system.update(time); - } + ships: Vec<Ship> } impl SolarSystem @@ -107,6 +103,7 @@ impl SolarSystem id: id, name: bodies[0].name().clone(), bodies: bodies, + ships: vec![] }) } @@ -186,65 +183,16 @@ impl OrbitalBody None => return 0 } } - + pub fn calculate_orbit_at( &self, time: Second) - -> cgmath::Vector3<f64> + -> cgmath::Vector3<Kilometers> { - let orbit = match &self.orbit { - Some(v) => v, - None => return cgmath::vec3(0.0, 0.0, 0.0) - }; - - if orbit.parent.is_none() { - return cgmath::Vector3::<f64>::new(0.0, 0.0, 0.0); -} - - let eccentricity = orbit.eccentricity; - - let long_asc_node = orbit.long_asc_node; - let arg_periaps = orbit.long_periapsis - long_asc_node; - - let sma_cubed = orbit.semi_major_axis.powf(3.0); - let mean_motion = (self.sgp / sma_cubed).sqrt(); - - let mean_anomaly_epoch = orbit.mean_long - orbit.long_periapsis; - let mean_anomaly = mean_anomaly_epoch + (mean_motion * time as f64); - - //Find the eccentric anomaly via newton's method - let mut eccentric_anomaly = mean_anomaly; - for _ in 0..100 { - let (e_sin, e_cos) = eccentric_anomaly.sin_cos(); - let new_anomaly = eccentric_anomaly - - ( - (eccentric_anomaly - eccentricity * e_sin - mean_anomaly) / - (1.0 - eccentricity * e_cos) - ); - - let diff = eccentric_anomaly - new_anomaly; - eccentric_anomaly = new_anomaly; - if diff.abs() < 1e-6 { - break; - } + match &self.orbit { + Some(orbit) => orbit.calculate_position_at(self, time), + None => cgmath::vec3(0.0, 0.0, 0.0) } - - let true_anomaly = 2.0 * ( - ((1.0 + eccentricity) / (1.0 - eccentricity)).sqrt() - * (eccentric_anomaly / 2.0).tan() - ).atan(); - - let vw = true_anomaly + arg_periaps; - let (vw_sin, vw_cos) = vw.sin_cos(); - let (omega_sin, omega_cos) = long_asc_node.sin_cos(); - let (i_sin, i_cos) = orbit.inclination.sin_cos(); - - let r = orbit.semi_major_axis * (1.0 - eccentricity * eccentric_anomaly.cos()); - let x = r * (omega_cos * vw_cos - omega_sin * vw_sin * i_cos); - let y = r * i_sin * vw_sin; - let z = r * (omega_sin * vw_cos + omega_cos * vw_sin * i_cos); - - cgmath::Vector3::<f64>::new(x, y, z) } } diff --git a/src/solar_system/orbit.rs b/src/solar_system/orbit.rs index fe55e4f..b042bd3 100644 --- a/src/solar_system/orbit.rs +++ b/src/solar_system/orbit.rs @@ -20,10 +20,66 @@ impl StaticOrbit this_body: &OrbitalBody) -> Second { - ((self.semi_major_axis.powf(3.0) / this_body.sgp).sqrt() * std::f64::consts::TAU) as u64 + ((self.semi_major_axis.powf(3.0) / this_body.sgp).sqrt() * std::f64::consts::TAU) as Second } pub fn parent(&self) -> Option<BodyId> { self.parent } + + pub fn calculate_position_at( + &self, + this_body: &OrbitalBody, + time: Second) + -> cgmath::Vector3<f64> + { + if self.parent.is_none() { + return cgmath::Vector3::<f64>::new(0.0, 0.0, 0.0); + } + + let eccentricity = self.eccentricity; + + let long_asc_node = self.long_asc_node; + let arg_periaps = self.long_periapsis - long_asc_node; + + let sma_cubed = self.semi_major_axis.powf(3.0); + let mean_motion = (this_body.sgp / sma_cubed).sqrt(); + + let mean_anomaly_epoch = self.mean_long - self.long_periapsis; + let mean_anomaly = mean_anomaly_epoch + (mean_motion * time as f64); + + //Find the eccentric anomaly via newton's method + let mut eccentric_anomaly = mean_anomaly; + for _ in 0..100 { + let (e_sin, e_cos) = eccentric_anomaly.sin_cos(); + let new_anomaly = eccentric_anomaly - + ( + (eccentric_anomaly - eccentricity * e_sin - mean_anomaly) / + (1.0 - eccentricity * e_cos) + ); + + let diff = eccentric_anomaly - new_anomaly; + eccentric_anomaly = new_anomaly; + if diff.abs() < 1e-6 { + break; + } + } + + let true_anomaly = 2.0 * ( + ((1.0 + eccentricity) / (1.0 - eccentricity)).sqrt() + * (eccentric_anomaly / 2.0).tan() + ).atan(); + + let vw = true_anomaly + arg_periaps; + let (vw_sin, vw_cos) = vw.sin_cos(); + let (omega_sin, omega_cos) = long_asc_node.sin_cos(); + let (i_sin, i_cos) = self.inclination.sin_cos(); + + let r = self.semi_major_axis * (1.0 - eccentricity * eccentric_anomaly.cos()); + let x = r * (omega_cos * vw_cos - omega_sin * vw_sin * i_cos); + let y = r * i_sin * vw_sin; + let z = r * (omega_sin * vw_cos + omega_cos * vw_sin * i_cos); + + cgmath::Vector3::<f64>::new(x, y, z) + } } diff --git a/src/tacmap.rs b/src/tacmap.rs index 222363f..8d9e2c4 100644 --- a/src/tacmap.rs +++ b/src/tacmap.rs @@ -157,7 +157,7 @@ impl TacticalMap //Paint body labels let bodies = solar_system.bodies(); bodies.iter().for_each(|body| { - let scaled_radius = (2.0 * body.radius() * self.camera.get_scale()).max(16.0); + let scaled_radius = (screen_size.y * body.radius() * self.camera.get_scale()).max(16.0); let world_pos = solar_system.body_position(body); let local_pos = world_pos - self.camera.get_abs_position(); @@ -173,7 +173,7 @@ impl TacticalMap let screen_pos = egui::pos2( ((ndc_pos.x + 1.0) * 0.5) * screen_size.x, - (((-ndc_pos.y + 1.0) * 0.5) * screen_size.y) + scaled_radius); + (((-ndc_pos.y + 1.0) * 0.5) * screen_size.y) + (scaled_radius / clip_pos.w).max(16.0)); if clip_pos.z < 0.0 { return; } ui.put( diff --git a/src/tacmap/camera.rs b/src/tacmap/camera.rs index ada36ee..5efc24c 100644 --- a/src/tacmap/camera.rs +++ b/src/tacmap/camera.rs @@ -1,16 +1,12 @@ -use std::{cell::RefCell, time::Duration}; +use std::time::Duration; -use cgmath::{EuclideanSpace, InnerSpace, Point2, Point3, Rad, Vector2, Vector3, Vector4, Zero, perspective}; -use winit::{event::ElementState, keyboard::KeyCode}; +use cgmath::{InnerSpace, Point3, Rad, Vector2, Vector3, perspective}; +use winit::event::ElementState; +use winit::keyboard::KeyCode; -use crate::{GameState, solar_system::{self, Kilometers, SolarSystem}, ui, wgpuctx::WgpuCtx}; - -pub const OPENGL_TO_WGPU_MATRIX: cgmath::Matrix4<f32> = cgmath::Matrix4::from_cols( - Vector4::new(1.0, 0.0, 0.0, 0.0), - Vector4::new(0.0, 1.0, 0.0, 0.0), - Vector4::new(0.0, 0.0, 0.5, 0.0), - Vector4::new(0.0, 0.0, 0.5, 1.0) -); +use crate::solar_system::{self, BodyId, Kilometers, SolarSystem}; +use crate::ui; +use crate::wgpuctx::WgpuCtx; pub struct Camera { @@ -268,11 +264,8 @@ impl CameraController let dt = dt.as_secs_f32(); let speed = 1.0; - let current_radius = camera.rel_position.magnitude(); - let polar_diff = (self.position_pos_delta.z - self.position_neg_delta.z) * speed * dt; let azimuth_diff = (self.position_pos_delta.x - self.position_neg_delta.x) * speed * dt; - let dist_diff = (self.position_pos_delta.y - self.position_neg_delta.y) * speed * dt; let polar_final = camera.pitch.0 + polar_diff; let polar_cap = Into::<Rad<f32>>::into(cgmath::Deg(89.999)).0; diff --git a/src/tacmap/orbit_render.rs b/src/tacmap/orbit_render.rs index d79294e..a6a90d1 100644 --- a/src/tacmap/orbit_render.rs +++ b/src/tacmap/orbit_render.rs @@ -135,7 +135,7 @@ impl OrbitRenderer OrbitVertex::default();(num_points+1)*2]; for i in 0..num_points { let position = body.calculate_orbit_at( - (i as f64 * period_interval) as u64); + (i as f64 * period_interval) as Second); points[i*2].origin_id = body.get_orbits().unwrap() as _; points[i*2].position = [ diff --git a/src/timeman.rs b/src/timeman.rs index 64250ee..27d5450 100644 --- a/src/timeman.rs +++ b/src/timeman.rs @@ -1,11 +1,4 @@ -use std::cell::RefCell; -use std::time::Duration; -use std::{fmt::Display, string}; -use std::error::Error; - -use crate::GameState; - -pub type Second = u64; +pub type Second = i64; pub const MINUTE: Second = 60; pub const HOUR: Second = MINUTE * 60; |
