terrain_forge/effects/
blend.rs1use crate::{Grid, Tile};
4
5pub fn threshold(values: &[Vec<f64>], grid: &mut Grid<Tile>, thresh: f64) {
6 let h = values.len().min(grid.height());
7 let w = values
8 .first()
9 .map(|r| r.len())
10 .unwrap_or(0)
11 .min(grid.width());
12
13 for (y, row) in values.iter().enumerate().take(h) {
14 for (x, &val) in row.iter().enumerate().take(w) {
15 grid.set(
16 x as i32,
17 y as i32,
18 if val > thresh {
19 Tile::Floor
20 } else {
21 Tile::Wall
22 },
23 );
24 }
25 }
26}
27
28pub fn gradient_blend(
29 base: &Grid<Tile>,
30 overlay: &Grid<Tile>,
31 output: &mut Grid<Tile>,
32 horizontal: bool,
33) {
34 let w = base.width().min(overlay.width()).min(output.width());
35 let h = base.height().min(overlay.height()).min(output.height());
36
37 for y in 0..h {
38 for x in 0..w {
39 let t = if horizontal {
40 x as f64 / w as f64
41 } else {
42 y as f64 / h as f64
43 };
44 let cell = if t > 0.5 {
45 overlay[(x, y)]
46 } else {
47 base[(x, y)]
48 };
49 output.set(x as i32, y as i32, cell);
50 }
51 }
52}
53
54pub fn radial_blend(
55 base: &Grid<Tile>,
56 overlay: &Grid<Tile>,
57 output: &mut Grid<Tile>,
58 inner_r: f64,
59 outer_r: f64,
60) {
61 let w = base.width().min(overlay.width()).min(output.width());
62 let h = base.height().min(overlay.height()).min(output.height());
63 let (cx, cy) = (w as f64 / 2.0, h as f64 / 2.0);
64
65 for y in 0..h {
66 for x in 0..w {
67 let dist = ((x as f64 - cx).powi(2) + (y as f64 - cy).powi(2)).sqrt();
68 let cell = if dist < inner_r {
69 base[(x, y)]
70 } else if dist > outer_r {
71 overlay[(x, y)]
72 } else if base[(x, y)].is_floor() || overlay[(x, y)].is_floor() {
73 Tile::Floor
74 } else {
75 Tile::Wall
76 };
77 output.set(x as i32, y as i32, cell);
78 }
79 }
80}