outfly/src/nature.rs
2024-04-14 22:34:12 +02:00

109 lines
4.2 KiB
Rust

// This stuff here, this stuff is messy. Nobody wants to deal with this,
// nobody cares how it works, but I guess we need it as an ingredient for
// the universe *sigh* so here we go.
pub const OXYGEN_USE_KG_PER_S: f32 = 1e-5;
pub const OXY_S: f32 = OXYGEN_USE_KG_PER_S;
pub const OXY_M: f32 = OXYGEN_USE_KG_PER_S * 60.0;
pub const OXY_H: f32 = OXYGEN_USE_KG_PER_S * 60.0 * 60.0;
pub const OXY_D: f32 = OXYGEN_USE_KG_PER_S * 60.0 * 60.0 * 24.0;
pub const LIGHTYEAR2METER: f64 = 9_460_730_472_580_800.0;
pub const PARSEC2METER: f64 = 3.0857e16;
pub const DIST_JUPTER_SUN: f64 = 778479.0e6;
pub const EARTH_GRAVITY: f32 = 9.81;
// Each star's values: (x, y, z, magnitude, color index, distance, name)
pub const STARS: &[(f32, f32, f32, f32, f32, f32, &str)] = &include!("data/stars.in");
pub fn star_color_index_to_rgb(color_index: f32) -> (f32, f32, f32) {
let temperature = 4600.0 * ((1.0 / (0.92 * color_index + 1.7)) + (1.0 / (0.92 * color_index + 0.62)));
let (red, green, blue) = if temperature <= 6600.0 {
let red = 255.0;
let green = 99.4708025861 * (temperature / 100.0).ln() - 161.1195681661;
let blue = if temperature <= 2000.0 {
0.0
} else {
138.5177312231 * ((temperature / 100.0) - 10.0).ln() - 305.0447927307
};
(red, green, blue)
} else {
let red = 329.698727446 * ((temperature / 100.0 - 60.0).powf(-0.1332047592));
let green = 288.1221695283 * ((temperature / 100.0 - 60.0).powf(-0.0755148492));
let blue = 255.0;
(red, green, blue)
};
let clamp = |x: f32| -> f32 { (x / 255.0).max(0.0).min(1.0) };
return (clamp(red), clamp(green), clamp(blue))
}
fn smooth_edge(start: f32, end: f32, value: f32) -> f32 {
let x: f32 = (value - start) / (end - start);
return 4.0 * x * x * (1.0 - x * x);
}
pub fn ring_density(radius: f32) -> f32 {
// NOTE: Keep this in sync with assets/shaders/jupiters_rings.wgsl
// Input: distance to center of jupiter in million meters
// Output: relative brightness of the ring
let halo_inner: f32 = 92.0;
let halo_outer: f32 = 122.5;
let main_inner: f32 = 122.5;
let main_outer: f32 = 129.0;
let amalthea_inner: f32 = 129.0;
let amalthea_outer: f32 = 182.0;
let thebe_inner: f32 = 129.0;
let thebe_outer: f32 = 229.0;
let metis_notch_center: f32 = 128.0;
let metis_notch_width: f32 = 0.6;
let halo_brightness: f32 = 0.75;
let main_brightness: f32 = 1.0;
let almathea_brightness: f32 = 0.5;
let thebe_brightness: f32 = 0.5;
let mut density: f32 = 0.0;
if radius >= halo_inner && radius <= halo_outer {
density = halo_brightness * smooth_edge(halo_inner, halo_outer, radius);
} else if radius >= main_inner && radius <= main_outer {
let mut metis_notch_effect: f32 = 1.0;
if radius > metis_notch_center - metis_notch_width * 0.5 && radius < metis_notch_center + metis_notch_width * 0.5 {
metis_notch_effect = 0.5 * (1.0 - smooth_edge(metis_notch_center - metis_notch_width * 0.5, metis_notch_center + metis_notch_width * 0.5, radius));
}
density = main_brightness * metis_notch_effect * smooth_edge(main_inner, main_outer, radius);
} else {
if radius >= amalthea_inner && radius <= amalthea_outer {
density = almathea_brightness * smooth_edge(amalthea_inner, amalthea_outer, radius);
}
if radius >= thebe_inner && radius <= thebe_outer {
density += thebe_brightness * smooth_edge(thebe_inner, thebe_outer, radius);
}
}
return density;
}
pub fn readable_distance(distance: f64) -> String {
let abs_distance = distance.abs();
if abs_distance > LIGHTYEAR2METER * 0.01 {
let lightyears = distance / LIGHTYEAR2METER;
return format!("{lightyears:.2} ly");
}
if abs_distance >= 1.0e10 {
let gigameters = distance * 1.0e-9;
return format!("{gigameters:.1}Gm");
}
if abs_distance >= 1.0e7 {
let megameters = distance * 1.0e-6;
return format!("{megameters:.1}Mm");
}
if abs_distance >= 1.0e4 {
let kilometers = distance * 1.0e-3;
return format!("{kilometers:.1}km");
}
return format!("{distance:.1}m");
}