idk what i'm doing

This commit is contained in:
2024-03-24 21:41:50 -04:00
parent e9757a5371
commit aada52a45b
4 changed files with 141 additions and 136 deletions

View File

@@ -1,141 +1,9 @@
use noise::{NoiseFn, SuperSimplex};
pub struct GenerationConfig {
pub noise_scale: f64,
pub sea_level: f64,
pub layers: Vec<GeneratorLayer>,
}
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<f32>,
pub size: usize,
}
pub struct Map {
pub chunks: Vec<Chunk>,
pub height: usize,
pub width: usize,
}
pub fn generate_heightmap(
height: usize,
width: usize,
cfg: &GenerationConfig,
seed: u32,
) -> Map {
let mut chunks: Vec<Chunk> = 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<f32> = 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 {