1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
use fastnoise_lite::{FastNoiseLite, NoiseType};
use glam::{IVec2, Vec2};
use crate::{
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 {
config: WorldGeneratorConfig,
cave_noise: Option<FastNoiseLite>,
hardness_noise: Option<FastNoiseLite>,
}
impl WorldGenerator {
pub fn generate_chunk(&mut self, chunk_position: IVec2) -> Chunk {
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");
}
}
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: WorldGeneratorConfig) -> Self {
let mut wg = WorldGenerator {
config,
cave_noise: None,
hardness_noise: None,
};
wg.update_params(config);
wg
}
}
|