base asteroid density on actual ring density
This commit is contained in:
parent
be55433376
commit
591db70d08
|
@ -7,7 +7,7 @@
|
||||||
@group(2) @binding(1) var<uniform> jupiter_radius: f32;
|
@group(2) @binding(1) var<uniform> jupiter_radius: f32;
|
||||||
|
|
||||||
const jupiter_radius_Mm: f32 = 71.492;
|
const jupiter_radius_Mm: f32 = 71.492;
|
||||||
const brightness = 0.05;
|
const brightness = 0.025;
|
||||||
|
|
||||||
fn smooth_edge(start: f32, end: f32, value: f32) -> f32 {
|
fn smooth_edge(start: f32, end: f32, value: f32) -> f32 {
|
||||||
var x: f32 = (value - start) / (end - start);
|
var x: f32 = (value - start) / (end - start);
|
||||||
|
@ -15,6 +15,9 @@ fn smooth_edge(start: f32, end: f32, value: f32) -> f32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ring_density(radius: f32) -> f32 {
|
fn ring_density(radius: f32) -> f32 {
|
||||||
|
// NOTE: Keep this in sync with src/nature.rs::ring_density
|
||||||
|
// Input: distance to center of jupiter in million meters
|
||||||
|
// Output: relative brightness of the ring
|
||||||
let halo_inner: f32 = 92.0;
|
let halo_inner: f32 = 92.0;
|
||||||
let halo_outer: f32 = 122.5;
|
let halo_outer: f32 = 122.5;
|
||||||
let main_inner: f32 = 122.5;
|
let main_inner: f32 = 122.5;
|
||||||
|
@ -26,13 +29,10 @@ fn ring_density(radius: f32) -> f32 {
|
||||||
let metis_notch_center: f32 = 128.0;
|
let metis_notch_center: f32 = 128.0;
|
||||||
let metis_notch_width: f32 = 0.6;
|
let metis_notch_width: f32 = 0.6;
|
||||||
|
|
||||||
let halo_brightness: f32 = 0.3;
|
let halo_brightness: f32 = 0.75;
|
||||||
let main_brightness: f32 = 0.4;
|
let main_brightness: f32 = 1.0;
|
||||||
let almathea_brightness: f32 = 0.2;
|
let almathea_brightness: f32 = 0.5;
|
||||||
let thebe_brightness: f32 = 0.2;
|
let thebe_brightness: f32 = 0.5;
|
||||||
|
|
||||||
let inner_smooth_factor: f32 = 2.0; // Smooth inner edges
|
|
||||||
let outer_smooth_factor: f32 = 1.5; // Rougher outer edges
|
|
||||||
|
|
||||||
var density: f32 = 0.0;
|
var density: f32 = 0.0;
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ actor 0 0 0 jupiter
|
||||||
rotationz -0.28
|
rotationz -0.28
|
||||||
angularmomentum 30 30 30
|
angularmomentum 30 30 30
|
||||||
|
|
||||||
actor 0 0 0 suit
|
actor 0 593051 0 suit
|
||||||
relativeto jupiter
|
relativeto jupiter
|
||||||
orbit 220000e3 0.66
|
orbit 220000e3 0.66
|
||||||
player yes
|
player yes
|
||||||
|
|
28
src/hud.rs
28
src/hud.rs
|
@ -218,6 +218,24 @@ fn setup(
|
||||||
..default()
|
..default()
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
TextSection::new(
|
||||||
|
"\n位置 ",
|
||||||
|
TextStyle {
|
||||||
|
font: asset_server.load(FONT),
|
||||||
|
font_size: settings.font_size_hud,
|
||||||
|
color: Color::GRAY,
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
),
|
||||||
|
TextSection::new(
|
||||||
|
"",
|
||||||
|
TextStyle {
|
||||||
|
font: asset_server.load(FONT),
|
||||||
|
font_size: settings.font_size_hud,
|
||||||
|
color: Color::GRAY,
|
||||||
|
..default()
|
||||||
|
}
|
||||||
|
),
|
||||||
TextSection::new(
|
TextSection::new(
|
||||||
"\nSuit Integrity ",
|
"\nSuit Integrity ",
|
||||||
TextStyle {
|
TextStyle {
|
||||||
|
@ -368,7 +386,7 @@ fn update(
|
||||||
time: Res<Time>,
|
time: Res<Time>,
|
||||||
mut log: ResMut<Log>,
|
mut log: ResMut<Log>,
|
||||||
player: Query<(&actor::Suit, &actor::LifeForm), With<actor::Player>>,
|
player: Query<(&actor::Suit, &actor::LifeForm), With<actor::Player>>,
|
||||||
q_camera: Query<&LinearVelocity, With<actor::PlayerCamera>>,
|
q_camera: Query<(&Position, &LinearVelocity), With<actor::PlayerCamera>>,
|
||||||
mut timer: ResMut<FPSUpdateTimer>,
|
mut timer: ResMut<FPSUpdateTimer>,
|
||||||
mut query: Query<&mut Text, With<GaugesText>>,
|
mut query: Query<&mut Text, With<GaugesText>>,
|
||||||
q_choices: Query<&ChoiceAvailable>,
|
q_choices: Query<&ChoiceAvailable>,
|
||||||
|
@ -382,7 +400,7 @@ fn update(
|
||||||
let player = player.get_single();
|
let player = player.get_single();
|
||||||
if player.is_ok() && q_camera_result.is_ok() {
|
if player.is_ok() && q_camera_result.is_ok() {
|
||||||
let (suit, lifeform) = player.unwrap();
|
let (suit, lifeform) = player.unwrap();
|
||||||
let cam_v = q_camera_result.unwrap();
|
let (pos, cam_v) = q_camera_result.unwrap();
|
||||||
for mut text in &mut query {
|
for mut text in &mut query {
|
||||||
if let Some(fps) = diagnostics.get(&FrameTimeDiagnosticsPlugin::FPS) {
|
if let Some(fps) = diagnostics.get(&FrameTimeDiagnosticsPlugin::FPS) {
|
||||||
if let Some(value) = fps.smoothed() {
|
if let Some(value) = fps.smoothed() {
|
||||||
|
@ -407,11 +425,13 @@ fn update(
|
||||||
text.sections[7].value = format!("{adrenaline:.0}pg/mL");
|
text.sections[7].value = format!("{adrenaline:.0}pg/mL");
|
||||||
let all_actors = query_all_actors.iter().len();
|
let all_actors = query_all_actors.iter().len();
|
||||||
text.sections[9].value = format!("{all_actors:.0}");
|
text.sections[9].value = format!("{all_actors:.0}");
|
||||||
|
let (x, y, z) = (pos.x, pos.y, pos.z);
|
||||||
|
text.sections[11].value = format!("{x:.0}|{z:.0}|{y:.0}");
|
||||||
let integrity = suit.integrity * 100.0;
|
let integrity = suit.integrity * 100.0;
|
||||||
text.sections[11].value = format!("{integrity:.0}%");
|
text.sections[13].value = format!("{integrity:.0}%");
|
||||||
let speed = cam_v.length();
|
let speed = cam_v.length();
|
||||||
let kmh = speed * 60.0 * 60.0 / 1000.0;
|
let kmh = speed * 60.0 * 60.0 / 1000.0;
|
||||||
text.sections[13].value = format!("{speed:.0}m/s | {kmh:.0}km/h");
|
text.sections[15].value = format!("{speed:.0}m/s | {kmh:.0}km/h");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,53 @@ pub fn star_color_index_to_rgb(color_index: f32) -> (f32, f32, f32) {
|
||||||
return (clamp(red), clamp(green), clamp(blue))
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
// The "STARS" constant was autogenerated by "genrate_starchart.py" using data
|
// The "STARS" constant was autogenerated by "genrate_starchart.py" using data
|
||||||
// from the HYG database: https://github.com/astronexus/HYG-Database/tree/main/hyg
|
// from the HYG database: https://github.com/astronexus/HYG-Database/tree/main/hyg
|
||||||
// License: CC BY-SA 4.0: https://creativecommons.org/licenses/by-sa/4.0/
|
// License: CC BY-SA 4.0: https://creativecommons.org/licenses/by-sa/4.0/
|
||||||
|
|
39
src/world.rs
39
src/world.rs
|
@ -9,7 +9,8 @@ use std::f32::consts::PI;
|
||||||
use fastrand;
|
use fastrand;
|
||||||
|
|
||||||
const ASTEROID_UPDATE_INTERVAL: f32 = 0.1; // seconds
|
const ASTEROID_UPDATE_INTERVAL: f32 = 0.1; // seconds
|
||||||
const ASTEROID_SIZE_FACTOR: f32 = 3.0;
|
const ASTEROID_SIZE_FACTOR: f32 = 10.0;
|
||||||
|
const RING_THICKNESS: f64 = 8.0e6;
|
||||||
const STARS_MAX_MAGNITUDE: f32 = 5.5;
|
const STARS_MAX_MAGNITUDE: f32 = 5.5;
|
||||||
|
|
||||||
const CENTER_WORLD_ON_PLAYER: bool = true;
|
const CENTER_WORLD_ON_PLAYER: bool = true;
|
||||||
|
@ -167,9 +168,9 @@ pub fn setup(
|
||||||
}),
|
}),
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
Position::from_xyz(0.0, -10000.0, 0.0),
|
Position::from_xyz(0.0, 0.0, 0.0),
|
||||||
//Rotation::from(Quat::IDENTITY),
|
Rotation::from(Quat::IDENTITY),
|
||||||
Rotation::from(Quat::from_rotation_x(-0.3f32.to_radians())),
|
//Rotation::from(Quat::from_rotation_x(-0.3f32.to_radians())),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,6 +242,20 @@ fn spawn_despawn_asteroids(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Density based on the radius alone
|
||||||
|
let radius_plane = (player.x * player.x + player.z * player.z).sqrt();
|
||||||
|
let density_r = nature::ring_density((radius_plane / 1e6) as f32);
|
||||||
|
if density_r < 0.001 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Density based on radius and the vertical distance to the ring
|
||||||
|
let normalized_distance = player.y / (RING_THICKNESS / 2.0);
|
||||||
|
let density = density_r * (-4.0 * normalized_distance.powf(2.0)).exp() as f32;
|
||||||
|
dbg!(normalized_distance, density_r, density);
|
||||||
|
if density < 0.001 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let mut rng = fastrand::Rng::new();
|
let mut rng = fastrand::Rng::new();
|
||||||
for x in -stepmax..=stepmax {
|
for x in -stepmax..=stepmax {
|
||||||
for y in -stepmax..=stepmax {
|
for y in -stepmax..=stepmax {
|
||||||
|
@ -264,15 +279,21 @@ fn spawn_despawn_asteroids(
|
||||||
rng.seed(seed);
|
rng.seed(seed);
|
||||||
|
|
||||||
let rand_s = rng.f32();
|
let rand_s = rng.f32();
|
||||||
let size: f32 = (rand_s + 1e-6).powf(-0.5) as f32; // -> between ~1 and 1000
|
let size_raw: f32 = (rand_s + 1e-4).powf(-0.5) as f32; // -> between ~1 and 100
|
||||||
|
let size_density = size_raw * density;
|
||||||
|
|
||||||
if rand_s > 0.7 {
|
if size_density < 0.3 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if size_raw < 20.0 {
|
||||||
let dist = player_cell.as_dvec3().distance(origin.as_dvec3());
|
let dist = player_cell.as_dvec3().distance(origin.as_dvec3());
|
||||||
if dist > 4.0 {
|
if dist > 6.0 {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
dbg!(size_density, dist);
|
||||||
spawned_near += 1;
|
spawned_near += 1;
|
||||||
}
|
}
|
||||||
|
let size: f32 = ASTEROID_SIZE_FACTOR * size_density;
|
||||||
|
|
||||||
let rand_x = rng.f64();
|
let rand_x = rng.f64();
|
||||||
let rand_y = rng.f64();
|
let rand_y = rng.f64();
|
||||||
|
@ -306,7 +327,7 @@ fn spawn_despawn_asteroids(
|
||||||
entity_commands.insert(SceneBundle {
|
entity_commands.insert(SceneBundle {
|
||||||
scene: asset_server.load(asset),
|
scene: asset_server.load(asset),
|
||||||
transform: Transform {
|
transform: Transform {
|
||||||
scale: Vec3::splat(ASTEROID_SIZE_FACTOR * size),
|
scale: Vec3::splat(size),
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
..default()
|
..default()
|
||||||
|
@ -320,7 +341,7 @@ fn spawn_despawn_asteroids(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if spawned != 0 || despawned != 0 {
|
if spawned != 0 || despawned != 0 {
|
||||||
log.notice(format!("spawned: {spawned} (near: {spawned_near}), despawned: {despawned}"));
|
//log.notice(format!("spawned: {spawned} (near: {spawned_near}), despawned: {despawned}"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue