use fastnoise_lite::{FastNoiseLite, FractalType}; use godot::classes::class_macros::private::virtuals::Os::Vector3i; use crate::chunk::{Chunk, chunk::CHUNK_SIZE}; pub struct SimpleSurfaceGenerator { noise: FastNoiseLite, surface_height: u32, } impl SimpleSurfaceGenerator { pub fn new(seed: i32, frequency: f32, surface_height: u32) -> Self { let mut noise = FastNoiseLite::new(); noise.frequency = frequency; noise.noise_type = fastnoise_lite::NoiseType::OpenSimplex2; noise.seed = seed; noise.set_fractal_type(Some(FractalType::Ridged)); noise.set_fractal_octaves(Some(4)); Self { noise, surface_height, } } #[inline] pub fn normalize_value(value: f32) -> f32 { (value + 1.0) * 0.5 // [0, value] } } impl SimpleSurfaceGenerator { fn generate(&self, column: &mut Chunk) { let size_x = CHUNK_SIZE; let size_z = CHUNK_SIZE; let base_x = column.world_position.0 * size_x; let base_z = column.world_position.1 * size_z; let freq = 1.0 / 32.0; let column_height = CHUNK_SIZE * self.surface_height as i32; for x in 0..CHUNK_SIZE { for z in 0..CHUNK_SIZE { // world coordinates of this column let world_x = base_x + x; let world_z = base_z + z; let noise = self .noise .get_noise_2d(world_x as f32 * freq, world_z as f32 * freq); let noise = Self::normalize_value(noise); let height = (noise.powi(2) * column_height as f32) as i32; for y in 1..=height { column.set_voxel(Vector3i::new(world_x, y, world_z), true); } } } } fn sample_voxel(&self, pos: Vector3i) -> bool { let freq = 1.0 / 32.0; let noise = self .noise .get_noise_2d(pos.x as f32 * freq, pos.z as f32 * freq); let noise = Self::normalize_value(noise); let column_height = CHUNK_SIZE * self.surface_height as i32; let height = (noise.powi(2) * column_height as f32) as i32; pos.y <= height } }