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>,
|
mut settings: ResMut<Settings>,
|
||||||
q_atmosphere: Query<(&Position, Option<&LinearVelocity>, &HasAtmosphere)>,
|
q_atmosphere: Query<(&Position, Option<&LinearVelocity>, &HasAtmosphere)>,
|
||||||
mut q_actor: Query<
|
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>),
|
(With<ExperiencesAtmosphere>, Without<HasAtmosphere>),
|
||||||
>,
|
>,
|
||||||
) {
|
) {
|
||||||
let dt = time.delta_seconds() as f64;
|
let dt = time.delta_seconds() as f64;
|
||||||
let mut reset_player_gauges = true;
|
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 {
|
for (atmo_pos, atmo_v, atmo) in &q_atmosphere {
|
||||||
let distance = atmo_pos.distance(pos.0);
|
let distance = atmo_pos.distance(pos.0);
|
||||||
if distance < atmo.r_outer {
|
if distance < atmo.r_outer {
|
||||||
// height is between 0.0 (collides with planet) and 1.0 (outside of atmosphere)
|
let density = nature::jupiter_altitude_to_density(distance);
|
||||||
let height = if distance < atmo.r_inner {
|
let pressure = nature::jupiter_altitude_to_pressure(distance);
|
||||||
0.0
|
let drag_coef = nature::DRAG_COEFFICIENT_SPHERE;
|
||||||
} else {
|
let radius = trans.scale.x as f64;
|
||||||
(distance - atmo.r_inner) / (atmo.r_outer - atmo.r_inner)
|
let area = PI * radius * radius;
|
||||||
};
|
|
||||||
|
|
||||||
let dv = if let Some(atmo_v) = atmo_v {
|
let dv = if let Some(atmo_v) = atmo_v {
|
||||||
v.0 - atmo_v.0
|
v.0 - atmo_v.0
|
||||||
} else {
|
} else {
|
||||||
v.0
|
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 let Some(ref mut hp) = hp {
|
||||||
if pressure > 1000.0 {
|
if pressure > 1000.0 {
|
||||||
hp.damage += f32::INFINITY; // better luck next time
|
hp.damage += f32::INFINITY; // better luck next time
|
||||||
|
@ -1166,9 +1179,9 @@ fn handle_atmosphere(
|
||||||
}
|
}
|
||||||
|
|
||||||
if player.is_some() {
|
if player.is_some() {
|
||||||
let density = nature::jupiter_altitude_to_density(distance);
|
|
||||||
settings.atmo_pressure = Some(pressure);
|
settings.atmo_pressure = Some(pressure);
|
||||||
settings.atmo_altitude = Some(distance - nature::JUPITER_RADIUS);
|
settings.atmo_altitude = Some(distance - nature::JUPITER_RADIUS);
|
||||||
|
settings.atmo_drag = Some(drag_accel.length());
|
||||||
settings.atmo_density = Some(density);
|
settings.atmo_density = Some(density);
|
||||||
reset_player_gauges = false;
|
reset_player_gauges = false;
|
||||||
}
|
}
|
||||||
|
@ -1190,5 +1203,6 @@ fn handle_atmosphere(
|
||||||
settings.atmo_pressure = None;
|
settings.atmo_pressure = None;
|
||||||
settings.atmo_altitude = None;
|
settings.atmo_altitude = None;
|
||||||
settings.atmo_density = None;
|
settings.atmo_density = None;
|
||||||
|
settings.atmo_drag = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -880,11 +880,14 @@ fn update_speedometer(
|
||||||
if let Some(val) = settings.atmo_altitude {
|
if let Some(val) = settings.atmo_altitude {
|
||||||
atmo += format!("alt: {}m\n", nature::readable_si(val)).as_str();
|
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 {
|
if let Some(val) = settings.atmo_density {
|
||||||
atmo += format!("dens: {}g/m³\n", nature::readable_si(val*1000.0)).as_str();
|
atmo += format!("dens: {}g/m³\n", nature::readable_si(val*1000.0)).as_str();
|
||||||
}
|
}
|
||||||
if let Some(val) = settings.atmo_pressure {
|
if let Some(val) = settings.atmo_drag {
|
||||||
atmo += format!("p: {}bar\n", nature::readable_si(val as f64)).as_str();
|
atmo += format!("drag: {}m/s²\n", nature::readable_si(val)).as_str();
|
||||||
}
|
}
|
||||||
speed_text.sections[0].value = atmo;
|
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 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:
|
// Arbitrary offset to time epoch, to generate more interesting orbital arrangements:
|
||||||
pub const ORBIT_TIME_OFFSET: f64 = 614533234154.0;
|
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());
|
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_pressure: Option<f64>,
|
||||||
pub atmo_density: Option<f64>,
|
pub atmo_density: Option<f64>,
|
||||||
pub atmo_altitude: Option<f64>,
|
pub atmo_altitude: Option<f64>,
|
||||||
|
pub atmo_drag: Option<f64>,
|
||||||
pub font_size_hud: f32,
|
pub font_size_hud: f32,
|
||||||
pub font_size_fps: f32,
|
pub font_size_fps: f32,
|
||||||
pub font_size_conversations: f32,
|
pub font_size_conversations: f32,
|
||||||
|
@ -206,6 +207,7 @@ impl Default for Settings {
|
||||||
atmo_pressure: None,
|
atmo_pressure: None,
|
||||||
atmo_density: None,
|
atmo_density: None,
|
||||||
atmo_altitude: None,
|
atmo_altitude: None,
|
||||||
|
atmo_drag: None,
|
||||||
font_size_hud: 24.0,
|
font_size_hud: 24.0,
|
||||||
font_size_fps: 14.0,
|
font_size_fps: 14.0,
|
||||||
font_size_conversations: 32.0,
|
font_size_conversations: 32.0,
|
||||||
|
|
Loading…
Reference in a new issue