From e3e67b0c6fb3810f863ef3006759199a437536a7 Mon Sep 17 00:00:00 2001 From: hut Date: Tue, 2 Apr 2024 05:12:53 +0200 Subject: [PATCH] on-the-fly asteroid generation --- src/world.rs | 253 +++++++++++++++++++++++++-------------------------- 1 file changed, 125 insertions(+), 128 deletions(-) diff --git a/src/world.rs b/src/world.rs index 851b2a8..b437d9b 100644 --- a/src/world.rs +++ b/src/world.rs @@ -1,18 +1,20 @@ use crate::{actor, nature, settings, hud}; use bevy::prelude::*; use bevy::render::render_resource::{AsBindGroup, ShaderRef}; -use bevy::math::DVec3; +use bevy::math::{DVec3, I64Vec3}; use bevy_xpbd_3d::prelude::*; use bevy_xpbd_3d::plugins::sync::SyncConfig; +use std::collections::HashMap; use std::f32::consts::PI; -use std::f64::consts::PI as PI64; const ASTEROID_UPDATE_INTERVAL: f32 = 1.0; // seconds -const ASTEROID_SIZE: f32 = 5000.0; +const ASTEROID_SIZE_FACTOR: f32 = 5.0; const STARS_MAX_MAGNITUDE: f32 = 5.5; const CENTER_WORLD_ON_PLAYER: bool = true; -const ASTEROIDS_ARE_SPHERES: bool = false; + +const ASTEROID_SPAWN_STEP: f64 = 500.0; +const ASTEROID_VIEW_RADIUS: f64 = 1000.0; const ASSET_ASTEROID1: &str = "models/asteroid.glb#Scene0"; const ASSET_ASTEROID2: &str = "models/asteroid2.glb#Scene0"; @@ -35,7 +37,6 @@ pub struct WorldPlugin; impl Plugin for WorldPlugin { fn build(&self, app: &mut App) { app.add_systems(Startup, setup); - app.add_systems(Startup, generate_asteroids); app.add_systems(Update, handle_cheats); app.add_systems(PostUpdate, handle_despawn); app.add_systems(Update, spawn_despawn_asteroids); @@ -46,6 +47,7 @@ impl Plugin for WorldPlugin { app.insert_resource(AsteroidUpdateTimer( Timer::from_seconds(ASTEROID_UPDATE_INTERVAL, TimerMode::Repeating))); app.insert_resource(AsteroidDatabase(Vec::new())); + app.insert_resource(ActiveAsteroids(HashMap::new())); app.add_event::(); if CENTER_WORLD_ON_PLAYER { @@ -62,19 +64,20 @@ impl Plugin for WorldPlugin { #[derive(Resource)] struct AsteroidUpdateTimer(Timer); #[derive(Resource)] struct AsteroidDatabase(Vec); +#[derive(Resource)] struct ActiveAsteroids(HashMap); #[derive(Component)] struct Asteroid; struct AsteroidData { - entity: Option, - is_spawned: bool, - class: u8, - size: f32, - pos: DVec3, + entity: Entity, + //viewdistance: f64, } #[derive(Event)] -pub struct DespawnEvent(Entity); +pub struct DespawnEvent { + entity: Entity, + origin: I64Vec3, +} #[derive(Asset, TypePath, AsBindGroup, Debug, Clone)] pub struct RingMaterial { @@ -169,141 +172,133 @@ pub fn setup( )); } -fn generate_asteroids( - mut db: ResMut, -) { - 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, - pos: DVec3::new(x, y, z), - size: ASTEROID_SIZE, - class: ((phase_step+radius_step+height_step) % 2) as u8, - }); - count += 1; - } - } - } - info!("Generated {count} asteroids"); -} - fn spawn_despawn_asteroids( time: Res