terrain_forge/effects/
morphology.rs1use crate::{Grid, Tile};
4
5pub fn erode(grid: &mut Grid<Tile>, iterations: usize) {
6 let (w, h) = (grid.width(), grid.height());
7 for _ in 0..iterations {
8 let snapshot: Vec<bool> = (0..w * h)
9 .map(|i| grid[(i % w, i / w)].is_floor())
10 .collect();
11 for y in 1..h - 1 {
12 for x in 1..w - 1 {
13 let idx = y * w + x;
14 if snapshot[idx] {
15 let has_wall = !snapshot[idx - 1]
16 || !snapshot[idx + 1]
17 || !snapshot[idx - w]
18 || !snapshot[idx + w];
19 if has_wall {
20 grid.set(x as i32, y as i32, Tile::Wall);
21 }
22 }
23 }
24 }
25 }
26}
27
28pub fn dilate(grid: &mut Grid<Tile>, iterations: usize) {
29 let (w, h) = (grid.width(), grid.height());
30 for _ in 0..iterations {
31 let snapshot: Vec<bool> = (0..w * h)
32 .map(|i| grid[(i % w, i / w)].is_floor())
33 .collect();
34 for y in 1..h - 1 {
35 for x in 1..w - 1 {
36 let idx = y * w + x;
37 if !snapshot[idx] {
38 let has_floor = snapshot[idx - 1]
39 || snapshot[idx + 1]
40 || snapshot[idx - w]
41 || snapshot[idx + w];
42 if has_floor {
43 grid.set(x as i32, y as i32, Tile::Floor);
44 }
45 }
46 }
47 }
48 }
49}
50
51pub fn open(grid: &mut Grid<Tile>, iterations: usize) {
52 erode(grid, iterations);
53 dilate(grid, iterations);
54}
55
56pub fn close(grid: &mut Grid<Tile>, iterations: usize) {
57 dilate(grid, iterations);
58 erode(grid, iterations);
59}