From aada52a45b804f090e78382e0ef6f3a57b8c802a Mon Sep 17 00:00:00 2001 From: Amatsugu Date: Sun, 24 Mar 2024 21:41:50 -0400 Subject: [PATCH] idk what i'm doing --- engine/world_generation/src/data.rs | 26 ++++ engine/world_generation/src/heightmap.rs | 111 ++++++++++++++ engine/world_generation/src/lib.rs | 136 +----------------- engine/world_generation/src/mesh_generator.rs | 4 +- 4 files changed, 141 insertions(+), 136 deletions(-) create mode 100644 engine/world_generation/src/data.rs create mode 100644 engine/world_generation/src/heightmap.rs diff --git a/engine/world_generation/src/data.rs b/engine/world_generation/src/data.rs new file mode 100644 index 0000000..4ae8383 --- /dev/null +++ b/engine/world_generation/src/data.rs @@ -0,0 +1,26 @@ +pub struct GenerationConfig { + pub noise_scale: f64, + pub sea_level: f64, + pub layers: Vec, +} +pub struct GeneratorLayer { + pub strength: f64, + pub min_value: f64, + pub base_roughness: f64, + pub roughness: f64, + pub persistence: f64, + pub is_rigid: bool, + pub weight: f64, + pub weight_multi: f64, + pub layers: usize, + pub first_layer_mask: bool, +} +pub struct Chunk { + pub points: Vec, + pub size: usize, +} +pub struct Map { + pub chunks: Vec, + pub height: usize, + pub width: usize, +} \ No newline at end of file diff --git a/engine/world_generation/src/heightmap.rs b/engine/world_generation/src/heightmap.rs new file mode 100644 index 0000000..0540cd6 --- /dev/null +++ b/engine/world_generation/src/heightmap.rs @@ -0,0 +1,111 @@ +mod data; +use data::*; + +pub fn generate_heightmap( + height: usize, + width: usize, + cfg: &GenerationConfig, + seed: u32, +) -> Map { + let mut chunks: Vec = Vec::with_capacity(height * width); + for z in 0..height { + for x in 0..width { + chunks.push(generate_chunk(x as f64, z as f64, 32, cfg, seed)); + } + } + return Map { + chunks: chunks, + height: height, + width: width, + }; +} + +pub fn generate_chunk( + chunk_x: f64, + chunk_z: f64, + size: usize, + cfg: &GenerationConfig, + seed: u32, +) -> Chunk { + let mut result: Vec = Vec::with_capacity(size * size); + let noise = SuperSimplex::new(seed); + for z in 0..size { + for x in 0..size { + result.push(sample_point( + x as f64 + chunk_x * size as f64, + z as f64 + chunk_z * size as f64, + &cfg, + &noise, + )); + } + } + return Chunk { + points: result, + size: size, + }; +} + +fn sample_point(x: f64, z: f64, cfg: &GenerationConfig, noise: &SuperSimplex) -> f32 { + let x_s = x / cfg.noise_scale; + let z_s = z / cfg.noise_scale; + + let mut elevation: f64 = 0.; + let mut first_layer: f64 = 0.; + for i in 0..cfg.layers.len() { + let value: f64; + let layer = &cfg.layers[i]; + if layer.is_rigid { + value = sample_rigid(x_s, z_s, layer, noise); + } else { + value = sample_simple(x_s, z_s, layer, noise); + } + if i == 0 { + first_layer = value; + } + if layer.first_layer_mask { + elevation += mask(first_layer, value, cfg.sea_level); + } else { + elevation += value; + } + } + + return elevation as f32; +} + +fn mask(mask: f64, value: f64, sea_level: f64) -> f64 { + let m = (mask - sea_level).max(0.); + return value * m; +} + +fn sample_simple(x: f64, z: f64, cfg: &GeneratorLayer, noise: &SuperSimplex) -> f64 { + let mut freq: f64 = cfg.base_roughness; + let mut amp: f64 = 1.; + let mut value = 0.; + + for _ in 0..cfg.layers { + let v = noise.get([x * freq, z * freq]); + value += (v + 1.) * 0.5 * amp; + freq *= cfg.roughness; + amp *= cfg.persistence; + } + value -= cfg.min_value; + return value * cfg.strength; +} +fn sample_rigid(x: f64, z: f64, cfg: &GeneratorLayer, noise: &SuperSimplex) -> f64 { + let mut freq: f64 = cfg.base_roughness; + let mut amp: f64 = 1.; + let mut value = 0.; + let mut weight = 1.; + for _ in 0..cfg.layers { + let mut v = 1. - noise.get([x * freq, z * freq]).abs(); + v *= v; + v *= weight; + weight = v * cfg.weight_multi; + weight = weight.clamp(0., 1.); + value += v * amp; + freq *= cfg.roughness; + amp *= cfg.persistence; + } + value -= cfg.min_value; + return value * cfg.strength; +} \ No newline at end of file diff --git a/engine/world_generation/src/lib.rs b/engine/world_generation/src/lib.rs index 36637ae..54cdd4a 100644 --- a/engine/world_generation/src/lib.rs +++ b/engine/world_generation/src/lib.rs @@ -1,141 +1,9 @@ use noise::{NoiseFn, SuperSimplex}; - pub struct GenerationConfig { - pub noise_scale: f64, - pub sea_level: f64, - pub layers: Vec, - } - pub struct GeneratorLayer { - pub strength: f64, - pub min_value: f64, - pub base_roughness: f64, - pub roughness: f64, - pub persistence: f64, - pub is_rigid: bool, - pub weight: f64, - pub weight_multi: f64, - pub layers: usize, - pub first_layer_mask: bool, - } - pub struct Chunk { - pub points: Vec, - pub size: usize, - } - pub struct Map { - pub chunks: Vec, - pub height: usize, - pub width: usize, - } + - pub fn generate_heightmap( - height: usize, - width: usize, - cfg: &GenerationConfig, - seed: u32, - ) -> Map { - let mut chunks: Vec = Vec::with_capacity(height * width); - for z in 0..height { - for x in 0..width { - chunks.push(generate_chunk(x as f64, z as f64, 32, cfg, seed)); - } - } - return Map { - chunks: chunks, - height: height, - width: width, - }; - } - - pub fn generate_chunk( - chunk_x: f64, - chunk_z: f64, - size: usize, - cfg: &GenerationConfig, - seed: u32, - ) -> Chunk { - let mut result: Vec = Vec::with_capacity(size * size); - let noise = SuperSimplex::new(seed); - for z in 0..size { - for x in 0..size { - result.push(sample_point( - x as f64 + chunk_x * size as f64, - z as f64 + chunk_z * size as f64, - &cfg, - &noise, - )); - } - } - return Chunk { - points: result, - size: size, - }; - } - - fn sample_point(x: f64, z: f64, cfg: &GenerationConfig, noise: &SuperSimplex) -> f32 { - let x_s = x / cfg.noise_scale; - let z_s = z / cfg.noise_scale; - - let mut elevation: f64 = 0.; - let mut first_layer: f64 = 0.; - for i in 0..cfg.layers.len() { - let value: f64; - let layer = &cfg.layers[i]; - if layer.is_rigid { - value = sample_rigid(x_s, z_s, layer, noise); - } else { - value = sample_simple(x_s, z_s, layer, noise); - } - if i == 0 { - first_layer = value; - } - if layer.first_layer_mask { - elevation += mask(first_layer, value, cfg.sea_level); - } else { - elevation += value; - } - } - - return elevation as f32; - } - - fn mask(mask: f64, value: f64, sea_level: f64) -> f64 { - let m = (mask - sea_level).max(0.); - return value * m; - } - - fn sample_simple(x: f64, z: f64, cfg: &GeneratorLayer, noise: &SuperSimplex) -> f64 { - let mut freq: f64 = cfg.base_roughness; - let mut amp: f64 = 1.; - let mut value = 0.; - - for _ in 0..cfg.layers { - let v = noise.get([x * freq, z * freq]); - value += (v + 1.) * 0.5 * amp; - freq *= cfg.roughness; - amp *= cfg.persistence; - } - value -= cfg.min_value; - return value * cfg.strength; - } - fn sample_rigid(x: f64, z: f64, cfg: &GeneratorLayer, noise: &SuperSimplex) -> f64 { - let mut freq: f64 = cfg.base_roughness; - let mut amp: f64 = 1.; - let mut value = 0.; - let mut weight = 1.; - for _ in 0..cfg.layers { - let mut v = 1. - noise.get([x * freq, z * freq]).abs(); - v *= v; - v *= weight; - weight = v * cfg.weight_multi; - weight = weight.clamp(0., 1.); - value += v * amp; - freq *= cfg.roughness; - amp *= cfg.persistence; - } - value -= cfg.min_value; - return value * cfg.strength; - } + #[cfg(test)] mod tests { diff --git a/engine/world_generation/src/mesh_generator.rs b/engine/world_generation/src/mesh_generator.rs index d150344..2f7ed09 100644 --- a/engine/world_generation/src/mesh_generator.rs +++ b/engine/world_generation/src/mesh_generator.rs @@ -1,5 +1,5 @@ -mod lib; -use lib::Chunk; +mod data; +use data::Chunk; pub fn generate_chunk_mesh(chunk: &Chunk){