atmosphere: implement drag
This commit is contained in:
parent
bbbf9c839b
commit
ac522eb130
38
src/actor.rs
38
src/actor.rs
|
@ -1131,33 +1131,46 @@ fn handle_atmosphere(
|
|||
mut settings: ResMut<Settings>,
|
||||
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<ExperiencesAtmosphere>, Without<HasAtmosphere>),
|
||||
>,
|
||||
) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -55,6 +55,7 @@ pub struct Settings {
|
|||
pub atmo_pressure: Option<f64>,
|
||||
pub atmo_density: Option<f64>,
|
||||
pub atmo_altitude: Option<f64>,
|
||||
pub atmo_drag: Option<f64>,
|
||||
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,
|
||||
|
|
Loading…
Reference in a new issue