diff --git a/src/actor.rs b/src/actor.rs index 2a6841d..96a2429 100644 --- a/src/actor.rs +++ b/src/actor.rs @@ -1131,33 +1131,46 @@ fn handle_atmosphere( mut settings: ResMut, q_atmosphere: Query<(&Position, Option<&LinearVelocity>, &HasAtmosphere)>, mut q_actor: Query< - (&Position, &mut LinearVelocity, Option<&mut HitPoints>, Option<&PlayerCamera>), + ( + &Position, + &mut LinearVelocity, + &Transform, + &Mass, + Option<&mut HitPoints>, + Option<&PlayerCamera>, + ), (With, Without), >, ) { let dt = time.delta_seconds() as f64; let mut reset_player_gauges = true; - for (pos, mut v, mut hp, player) in &mut q_actor { + for (pos, mut v, trans, mass, mut hp, player) in &mut q_actor { for (atmo_pos, atmo_v, atmo) in &q_atmosphere { let distance = atmo_pos.distance(pos.0); if distance < atmo.r_outer { - // height is between 0.0 (collides with planet) and 1.0 (outside of atmosphere) - let height = if distance < atmo.r_inner { - 0.0 - } else { - (distance - atmo.r_inner) / (atmo.r_outer - atmo.r_inner) - }; + let density = nature::jupiter_altitude_to_density(distance); + let pressure = nature::jupiter_altitude_to_pressure(distance); + let drag_coef = nature::DRAG_COEFFICIENT_SPHERE; + let radius = trans.scale.x as f64; + let area = PI * radius * radius; let dv = if let Some(atmo_v) = atmo_v { v.0 - atmo_v.0 } else { v.0 }; - let friction = dv * (1.0 - height).powf(16.0) * dt * 10.0; - v.0 -= friction; - let pressure = nature::jupiter_altitude_to_pressure(distance); + let drag_accel; + if dv == DVec3::ZERO { + drag_accel = DVec3::ZERO; + } else { + let speed = dv.length(); + let drag_force = nature::drag_force(density, speed, area, drag_coef); + drag_accel = -dv.normalize() * (drag_force / mass.0 * dt).clamp(0.0, speed); + v.0 += drag_accel; + } + if let Some(ref mut hp) = hp { if pressure > 1000.0 { hp.damage += f32::INFINITY; // better luck next time @@ -1166,9 +1179,9 @@ fn handle_atmosphere( } if player.is_some() { - let density = nature::jupiter_altitude_to_density(distance); settings.atmo_pressure = Some(pressure); settings.atmo_altitude = Some(distance - nature::JUPITER_RADIUS); + settings.atmo_drag = Some(drag_accel.length()); settings.atmo_density = Some(density); reset_player_gauges = false; } @@ -1190,5 +1203,6 @@ fn handle_atmosphere( settings.atmo_pressure = None; settings.atmo_altitude = None; settings.atmo_density = None; + settings.atmo_drag = None; } } diff --git a/src/hud.rs b/src/hud.rs index e16411d..05fd000 100644 --- a/src/hud.rs +++ b/src/hud.rs @@ -880,11 +880,14 @@ fn update_speedometer( if let Some(val) = settings.atmo_altitude { atmo += format!("alt: {}m\n", nature::readable_si(val)).as_str(); } + if let Some(val) = settings.atmo_pressure { + atmo += format!("p: {}bar\n", nature::readable_si(val as f64)).as_str(); + } if let Some(val) = settings.atmo_density { atmo += format!("dens: {}g/m³\n", nature::readable_si(val*1000.0)).as_str(); } - if let Some(val) = settings.atmo_pressure { - atmo += format!("p: {}bar\n", nature::readable_si(val as f64)).as_str(); + if let Some(val) = settings.atmo_drag { + atmo += format!("drag: {}m/s²\n", nature::readable_si(val)).as_str(); } speed_text.sections[0].value = atmo; diff --git a/src/nature.rs b/src/nature.rs index 57e9298..652f3d6 100644 --- a/src/nature.rs +++ b/src/nature.rs @@ -36,6 +36,8 @@ pub const EARTH_MASS: f64 = 5.972168e24; pub const JUPITER_ATMO_HEIGHT: f64 = 1_000_000.0; +pub const DRAG_COEFFICIENT_SPHERE: f64 = 0.47; // at Reynolds number 10e4 + // Arbitrary offset to time epoch, to generate more interesting orbital arrangements: pub const ORBIT_TIME_OFFSET: f64 = 614533234154.0; @@ -329,3 +331,7 @@ pub fn jupiter_altitude_to_density(altitude: f64) -> f64 { } return 25000.0 / (1.0 + (0.00000580528 * x + 361.44394).exp()); } + +pub fn drag_force(density: f64, speed: f64, area: f64, drag_coefficient: f64) -> f64 { + return 0.5 * density * speed * speed * area * drag_coefficient; +} diff --git a/src/var.rs b/src/var.rs index 4b48bf7..47d7a01 100644 --- a/src/var.rs +++ b/src/var.rs @@ -55,6 +55,7 @@ pub struct Settings { pub atmo_pressure: Option, pub atmo_density: Option, pub atmo_altitude: Option, + pub atmo_drag: Option, pub font_size_hud: f32, pub font_size_fps: f32, pub font_size_conversations: f32, @@ -206,6 +207,7 @@ impl Default for Settings { atmo_pressure: None, atmo_density: None, atmo_altitude: None, + atmo_drag: None, font_size_hud: 24.0, font_size_fps: 14.0, font_size_conversations: 32.0,