diff --git a/src/world.rs b/src/world.rs index 4cc67ff..851b2a8 100644 --- a/src/world.rs +++ b/src/world.rs @@ -7,8 +7,8 @@ use bevy_xpbd_3d::plugins::sync::SyncConfig; use std::f32::consts::PI; use std::f64::consts::PI as PI64; -const ASTEROID_UPDATE_INTERVAL: f32 = 0.1; // seconds -const ASTEROID_SIZE: f32 = 100.0; +const ASTEROID_UPDATE_INTERVAL: f32 = 1.0; // seconds +const ASTEROID_SIZE: f32 = 5000.0; const STARS_MAX_MAGNITUDE: f32 = 5.5; const CENTER_WORLD_ON_PLAYER: bool = true; @@ -68,7 +68,6 @@ impl Plugin for WorldPlugin { struct AsteroidData { entity: Option, is_spawned: bool, - spawned_once: bool, class: u8, size: f32, pos: DVec3, @@ -173,35 +172,47 @@ pub fn setup( fn generate_asteroids( mut db: ResMut, ) { - let maxdist = 30; - let maxdist_orthogonal = maxdist / 4; - let player_r: f64 = 220000e3; // sync this with defs.txt parameters - let player_phase: f64 = 0.66; // sync this with defs.txt parameters - let player_x: f64 = player_r * (player_phase * PI64 * 2.0).cos(); - let player_y: f64 = 0.0; - let player_z: f64 = player_r * (player_phase * PI64 * 2.0).sin(); - let offset: f64 = 500.0; - let dist: f64 = 8e3; - for i in -maxdist..maxdist { - for j in -maxdist_orthogonal..maxdist_orthogonal { - for k in -maxdist..maxdist { - let wobble: f64 = dist/2.0; - let (i, j, k) = (i as f64, j as f64, k as f64); + let phase_steps: i16 = 600; + let radius_steps: i16 = 1000; + let max_height_step: i16 = 6; // this one is inclusive for symmetry + let min_height_step: i16 = -max_height_step; + + let min_radius: f64 = 92e6; + let max_radius: f64 = 229e6; + let ring_thickness: f64 = 2.0e6; + + let height_step_factor: f64 = ring_thickness / 2.0 / (max_height_step as f64); + let max_phase_step_factor: f64 = 2.0 * PI64 / (phase_steps as f64); + let max_radius_factor: f64 = (max_radius - min_radius) / (radius_steps as f64); + let wobble: f64 = (ASTEROID_SIZE * 50.0).into(); + let mut count = 0; + for phase_step in 0..phase_steps { + let phase = max_phase_step_factor * phase_step as f64; + for radius_step in 0..radius_steps { + let radius = max_radius_factor * radius_step as f64 + min_radius; + for height_step in min_height_step..=max_height_step { + let height = height_step_factor * height_step as f64; + + let rand1 = (phase+radius).sin() + (height+radius).cos(); + let rand2 = (phase+height).sin() + (phase+radius).cos(); + let rand3 = (radius+height).sin() + (phase+height).cos(); + + let x = phase.sin() * radius + wobble * rand1; + let y = height + wobble * rand2; + let z = phase.cos() * radius + wobble * rand3; + db.0.push(AsteroidData { entity: None, is_spawned: false, - spawned_once: false, - pos: DVec3::new( - player_x + offset + dist * i + wobble * (j+k/PI64).sin() * (k+j/PI64).cos(), - player_y + offset + dist * j + wobble * (k+i/PI64).sin() * (i+k/PI64).cos(), - player_z + offset + dist * k + wobble * (i+j/PI64).sin() * (j+i/PI64).cos(), - ), + pos: DVec3::new(x, y, z), size: ASTEROID_SIZE, - class: (((i+j+k) as i32) % 2) as u8, + class: ((phase_step+radius_step+height_step) % 2) as u8, }); + count += 1; } } } + info!("Generated {count} asteroids"); } fn spawn_despawn_asteroids( @@ -226,7 +237,7 @@ fn spawn_despawn_asteroids( let mut despawned = 0; for asteroid in &mut db.0 { let dist = player.distance(asteroid.pos); - let should_spawn = dist < 50000.0; + let should_spawn = dist < 2000.0e3; if should_spawn == asteroid.is_spawned { continue; // Nothing to do } @@ -292,7 +303,6 @@ fn spawn_despawn_asteroids( } asteroid.entity = Some(entity_commands.id()); spawned += 1; - asteroid.spawned_once = true; asteroid.is_spawned = true; } if spawned != 0 || despawned != 0 {