diff options
| author | Kai Stevenson <kai@kaistevenson.com> | 2026-08-30 11:48:42 -0700 |
|---|---|---|
| committer | Kai Stevenson <kai@kaistevenson.com> | 2026-08-30 11:48:42 -0700 |
| commit | a0e3b22efb1d1a8b885717481061074459fe109f (patch) | |
| tree | 587165cfafc37bb204b3440f5ef7337b4bb5f65f /src | |
| parent | a57cb58602b323469861c0b06573c6e47db56f34 (diff) | |
dirt, stone
Diffstat (limited to 'src')
| -rw-r--r-- | src/camera.rs | 2 | ||||
| -rw-r--r-- | src/content/materials/mod.rs | 22 | ||||
| -rw-r--r-- | src/main.rs | 10 | ||||
| -rw-r--r-- | src/proc_gen/mod.rs | 101 | ||||
| -rw-r--r-- | src/renderer/ui.rs | 43 | ||||
| -rw-r--r-- | src/sim/cell_manager/manager.rs | 1 |
6 files changed, 143 insertions, 36 deletions
diff --git a/src/camera.rs b/src/camera.rs index 0fe9f22..f5e7c1c 100644 --- a/src/camera.rs +++ b/src/camera.rs @@ -85,7 +85,7 @@ impl Camera { pub fn new(screen_size: (i32, i32)) -> Self { Camera { - zoom: 0.15, + zoom: 0.20, centre: (0.0, 0.0), screen_size, } diff --git a/src/content/materials/mod.rs b/src/content/materials/mod.rs index f4a5ab5..11c0cca 100644 --- a/src/content/materials/mod.rs +++ b/src/content/materials/mod.rs @@ -12,6 +12,8 @@ pub mod powder; pub enum MaterialId { Void = 0, Sand, + Dirt, + Stone, Wood, Water, Fire, @@ -39,7 +41,7 @@ pub struct MaterialDef { pub sim_update: Option<fn(ctx: &mut UpdateCtx) -> PostUpdateAction>, } -static MATERIALS: [MaterialDef; 9] = [ +static MATERIALS: [MaterialDef; 11] = [ MaterialDef { name: "Void", color: (0x00, 0x00, 0x00, 0x00), @@ -56,6 +58,20 @@ static MATERIALS: [MaterialDef; 9] = [ sim_update: Some(powder::sim_update), }, MaterialDef { + name: "Dirt", + color: (0x2B, 0x20, 0x1C, 0xFF), + density: 55, + form: MaterialForm::Solid, + sim_update: None, + }, + MaterialDef { + name: "Stone", + color: (0x33, 0x30, 0x2F, 0xFF), + density: 115, + form: MaterialForm::Solid, + sim_update: None, + }, + MaterialDef { name: "Wood", color: (0x66, 0x39, 0x31, 0xFF), density: 60, @@ -109,9 +125,11 @@ static MATERIALS: [MaterialDef; 9] = [ ]; impl MaterialId { - pub const ALL: [MaterialId; 9] = [ + pub const ALL: [MaterialId; 11] = [ MaterialId::Void, MaterialId::Sand, + MaterialId::Dirt, + MaterialId::Stone, MaterialId::Wood, MaterialId::Water, MaterialId::Fire, diff --git a/src/main.rs b/src/main.rs index 0284aaf..63ed48f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -31,7 +31,7 @@ use crate::{ Input::{self}, InputManager, }, - proc_gen::WorldGenerator, + proc_gen::{WorldGenerator, WorldGeneratorConfig}, renderer::RendererState, sim::{entity::EntityDef, rb_manager::DebugRenderMode, sim_manager::SimManager}, vfx::VfxManager, @@ -50,8 +50,7 @@ struct Config { debug_render_mode: DebugRenderMode, // proc gen - proc_gen_seed: i32, - cave_noise_freq: f32, + world_generator_config: WorldGeneratorConfig, } struct Diagnostics { @@ -139,8 +138,7 @@ impl Default for App { debug_render: false, debug_render_mode: DebugRenderMode::default(), - proc_gen_seed: 10, - cave_noise_freq: 0.005, + world_generator_config: WorldGeneratorConfig::default(), }; Self { window: None, @@ -152,7 +150,7 @@ impl Default for App { vfx_manager: Some(VfxManager::new()), sim_manager: Some(SimManager::new()), - world_generator: Some(WorldGenerator::new(&config)), + world_generator: Some(WorldGenerator::new(config.world_generator_config)), last_render: Instant::now(), diff --git a/src/proc_gen/mod.rs b/src/proc_gen/mod.rs index 8c965fb..fb6a326 100644 --- a/src/proc_gen/mod.rs +++ b/src/proc_gen/mod.rs @@ -1,47 +1,100 @@ -use fastnoise_lite::FastNoiseLite; +use fastnoise_lite::{FastNoiseLite, NoiseType}; use glam::{IVec2, Vec2}; use crate::{ - Config, config::CHUNK_SIZE, content::materials::MaterialId, sim::{cell::Cell, cell_manager::chunk::Chunk}, }; +#[derive(Clone, Copy)] +pub struct WorldGeneratorConfig { + pub occupied_threshold: f32, + pub stone_threshold: f32, + pub proc_gen_seed: i32, + + pub cave_noise_freq: f32, + pub cave_noise_type: NoiseType, + pub hardness_noise_freq: f32, + pub hardness_noise_type: NoiseType, +} + +impl Default for WorldGeneratorConfig { + fn default() -> Self { + Self { + occupied_threshold: 0.05, + stone_threshold: 0.6, + proc_gen_seed: 10, + + cave_noise_freq: 0.005, + cave_noise_type: NoiseType::OpenSimplex2S, + hardness_noise_freq: 0.015, + hardness_noise_type: NoiseType::OpenSimplex2S, + } + } +} + pub struct WorldGenerator { - cave_noise: FastNoiseLite, + config: WorldGeneratorConfig, + cave_noise: Option<FastNoiseLite>, + hardness_noise: Option<FastNoiseLite>, } impl WorldGenerator { pub fn generate_chunk(&mut self, chunk_position: IVec2) -> Chunk { - let mut c = Chunk::void(); - let position = chunk_position * CHUNK_SIZE; - for x in 0..CHUNK_SIZE { - for y in 0..CHUNK_SIZE { - let cell_position = position.as_vec2() + Vec2::new(x as f32, y as f32); - let cnv = self - .cave_noise - .get_noise_2d(cell_position.x, cell_position.y); - if cnv < 0.5 { - c.set_cell_at_local_position( - x as u8, - y as u8, - Cell::from_material(MaterialId::Wood), - ); + if let Some(cave_noise) = &self.cave_noise + && let Some(hardness_noise) = &self.hardness_noise + { + let mut c = Chunk::void(); + let position = chunk_position * CHUNK_SIZE; + for x in 0..CHUNK_SIZE { + for y in 0..CHUNK_SIZE { + let cell_position = position.as_vec2() + Vec2::new(x as f32, y as f32); + let cnv = cave_noise.get_noise_2d(cell_position.x, cell_position.y); + let hnv = hardness_noise.get_noise_2d(cell_position.x, cell_position.y); + + let occupied = cnv < self.config.occupied_threshold; + if occupied { + let material = if hnv > self.config.stone_threshold { + MaterialId::Stone + } else { + MaterialId::Dirt + }; + c.set_cell_at_local_position( + x as u8, + y as u8, + Cell::from_material(material), + ); + } } } + c + } else { + panic!("Call update_params first"); } - c } - pub fn update_params(&mut self, config: &Config) { - self.cave_noise = FastNoiseLite::with_seed(config.proc_gen_seed + 50); - self.cave_noise.set_frequency(Some(config.cave_noise_freq)); + pub fn update_params(&mut self, config: WorldGeneratorConfig) { + let mut cave_noise = FastNoiseLite::with_seed(config.proc_gen_seed + 50); + cave_noise.set_frequency(Some(config.cave_noise_freq)); + cave_noise.set_noise_type(Some(config.cave_noise_type)); + + let mut hardness_noise = FastNoiseLite::with_seed(config.proc_gen_seed + 100); + hardness_noise.set_frequency(Some(config.hardness_noise_freq)); + hardness_noise.set_noise_type(Some(config.hardness_noise_type)); + + self.cave_noise = Some(cave_noise); + self.hardness_noise = Some(hardness_noise); + + self.config = config; } - pub fn new(config: &Config) -> Self { - let cave_noise = FastNoiseLite::with_seed(config.proc_gen_seed + 50); - let mut wg = WorldGenerator { cave_noise }; + pub fn new(config: WorldGeneratorConfig) -> Self { + let mut wg = WorldGenerator { + config, + cave_noise: None, + hardness_noise: None, + }; wg.update_params(config); wg } diff --git a/src/renderer/ui.rs b/src/renderer/ui.rs index 9af0113..98c916d 100644 --- a/src/renderer/ui.rs +++ b/src/renderer/ui.rs @@ -1,4 +1,5 @@ use egui::{Color32, Stroke, Ui, epaint::CircleShape}; +use fastnoise_lite::NoiseType; use glam::IVec2; use rapier2d::pipeline::QueryFilter; @@ -109,7 +110,7 @@ pub fn draw_egui<'a>( ui.add(egui::Slider::new(&mut camera.zoom, 0.0..=10.0).text("Zoom")); ui.heading("Proc gen"); if ui.button("Generate").clicked() { - world_generator.update_params(config); + world_generator.update_params(config.world_generator_config); for cx in -5..5 { for cy in -5..5 { let chunk = world_generator.generate_chunk(IVec2::new(cx, cy)); @@ -117,9 +118,45 @@ pub fn draw_egui<'a>( } } } - ui.add(egui::Slider::new(&mut config.proc_gen_seed, -100000..=100000).text("Seed")); + ui.add( + egui::Slider::new( + &mut config.world_generator_config.proc_gen_seed, + -100000..=100000, + ) + .text("Seed"), + ); + ui.add( + egui::Slider::new( + &mut config.world_generator_config.occupied_threshold, + 0.0..=1.0, + ) + .text("Occupation threshold"), + ); + ui.add( + egui::Slider::new( + &mut config.world_generator_config.stone_threshold, + 0.0..=1.0, + ) + .text("Stone threshold"), + ); + ui.label("Cave noise"); - ui.add(egui::Slider::new(&mut config.cave_noise_freq, 0.0..=1.0).text("Frequency")); + ui.add( + egui::Slider::new( + &mut config.world_generator_config.cave_noise_freq, + 0.0..=1.0, + ) + .text("Frequency"), + ); + + ui.label("Hardness noise"); + ui.add( + egui::Slider::new( + &mut config.world_generator_config.hardness_noise_freq, + 0.0..=1.0, + ) + .text("Frequency"), + ); ui.label(format!( "Mouse (world): x,y=({x}, {y})", diff --git a/src/sim/cell_manager/manager.rs b/src/sim/cell_manager/manager.rs index c8015f7..157499d 100644 --- a/src/sim/cell_manager/manager.rs +++ b/src/sim/cell_manager/manager.rs @@ -42,6 +42,7 @@ impl CellManager { // this is a temporary hack if !sleeping { self.chunks[idx].sleeping = false; + // remove this self.chunks[idx].collider_dirty_seqno = Some(0); } self.chunks[idx].needs_texture_update = true; |
