diff --git a/Cargo.toml b/Cargo.toml index bc8fe6a..55130f4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,10 +1,12 @@ [package] -name = "noise-engine" +name = "worldgen" version = "0.1.0" edition = "2024" [dependencies] noise = "0.9.0" +image = "0.25.5" +rayon = "1.10.0" [lib] -name = "noise_engine" +name = "worldgen" path = "src/lib.rs" diff --git a/README.md b/README.md index 4e3e9ef..2f0cc3f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# Noise-engine +# Worldgen -The **Noise-engine** module, implemented in Rust, serves as a specialized component for generating procedural noise functions integral to the **Cactus** Minecraft server. This project is tailored to address the computational and algorithmic requirements of Minecraft's world generation, with a concentrated focus on noise types essential for creating diverse and dynamic environments. +The **Worldgen** module, implemented in Rust, serves as a specialized component for generating procedural noise functions integral to the **Cactus** Minecraft server. This project is tailored to address the computational and algorithmic requirements of Minecraft's world generation, with a concentrated focus on noise types essential for creating diverse and dynamic environments. ## Features @@ -25,5 +25,3 @@ Given its specialized role as a server-integrated module, contributions from ext ## License This project is distributed under the terms of the [Mozilla Public License 2.0](LICENSE). - - diff --git a/big_noise_map.png b/big_noise_map.png new file mode 100644 index 0000000..ff37d9d Binary files /dev/null and b/big_noise_map.png differ diff --git a/src/lib.rs b/src/lib.rs index 1665399..453e9d0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -39,6 +39,19 @@ pub fn generate_normalized_noise_map( noise_map[x][z] = normalized_noise; } } - noise_map } + +#[cfg(test)] +mod tests { + use crate::generate_normalized_noise_map; + + #[test] + fn test_generate_normalized_noise_map() { + let noise_map = generate_normalized_noise_map(456, 0, 0, 0.1); + assert_eq!(noise_map.len(), 16); + for row in noise_map.iter() { + assert_eq!(row.len(), 16) + } + } +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..56b5d50 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,69 @@ +use image::{GrayImage, Luma}; +use rayon::prelude::*; +use worldgen::generate_normalized_noise_map; // Import rayon for parallel processing + +fn main() { + // Define parameters + let radius = 320; + let chunk_size = 16; + let num_chunks = 2 * radius + 1; // number of chunks per dimension (65 here) + let img_width = num_chunks * chunk_size; + let img_height = num_chunks * chunk_size; + + // Generate all chunk coordinates from -radius to +radius + let chunk_coords: Vec<(i32, i32)> = (-radius..=radius) + .flat_map(|cx| (-radius..=radius).map(move |cz| (cx, cz))) + .collect(); + + // Compute noise maps for each chunk in parallel using Rayon + let chunk_results: Vec<(i32, i32, [[f64; 16]; 16])> = chunk_coords + .into_par_iter() + .map(|(cx, cz)| { + let noise_map = generate_normalized_noise_map(42, cx, cz, 0.01); + (cx, cz, noise_map) + }) + .collect(); + + // Create the big image with the appropriate dimensions + let mut big_img: GrayImage = GrayImage::new(img_width as u32, img_height as u32); + + // Write each chunk's noise map into the global image at the corresponding position + for (cx, cz, noise_map) in chunk_results { + // Compute pixel offset: we shift de coordonnées de chunk pour obtenir des indices positifs + let offset_x = ((cx + radius) * chunk_size) as u32; + let offset_y = ((cz + radius) * chunk_size) as u32; + write_chunk_to_image(&mut big_img, offset_x, offset_y, noise_map); + } + + // Save the generated image to a file + big_img + .save("big_noise_map.png") + .expect("Failed to save image"); + println!("Image saved as big_noise_map.png"); +} + +/// Writes a 16x16 chunk noise map into the provided image at the specified offset. +/// Noise values are normalized from the range [-64, 324] to [0, 255]. +fn write_chunk_to_image( + img: &mut GrayImage, + offset_x: u32, + offset_y: u32, + noise_map: [[f64; 16]; 16], +) { + let min_val = -64.0; + let max_val = 324.0; + let scale = 255.0 / (max_val - min_val); + + // Iterate over each pixel in the 16x16 noise map + for (row_index, row) in noise_map.iter().enumerate() { + for (col_index, &value) in row.iter().enumerate() { + // Map noise value from [-64, 324] to [0, 255] + let pixel_value = (((value - min_val) * scale).round() as u8).min(255); + img.put_pixel( + offset_x + col_index as u32, + offset_y + row_index as u32, + Luma([pixel_value]), + ); + } + } +}