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.first().map(|r| r.len()).unwrap_or(0).min(grid.width());
8
9 for (y, row) in values.iter().enumerate().take(h) {
10 for (x, &val) in row.iter().enumerate().take(w) {
11 grid.set(x as i32, y as i32, if val > thresh { Tile::Floor } else { Tile::Wall });
12 }
13 }
14}
15
16pub fn gradient_blend(base: &Grid<Tile>, overlay: &Grid<Tile>, output: &mut Grid<Tile>, horizontal: bool) {
17 let w = base.width().min(overlay.width()).min(output.width());
18 let h = base.height().min(overlay.height()).min(output.height());
19
20 for y in 0..h {
21 for x in 0..w {
22 let t = if horizontal { x as f64 / w as f64 } else { y as f64 / h as f64 };
23 let cell = if t > 0.5 { overlay[(x, y)] } else { base[(x, y)] };
24 output.set(x as i32, y as i32, cell);
25 }
26 }
27}
28
29pub fn radial_blend(base: &Grid<Tile>, overlay: &Grid<Tile>, output: &mut Grid<Tile>, inner_r: f64, outer_r: f64) {
30 let w = base.width().min(overlay.width()).min(output.width());
31 let h = base.height().min(overlay.height()).min(output.height());
32 let (cx, cy) = (w as f64 / 2.0, h as f64 / 2.0);
33
34 for y in 0..h {
35 for x in 0..w {
36 let dist = ((x as f64 - cx).powi(2) + (y as f64 - cy).powi(2)).sqrt();
37 let cell = if dist < inner_r {
38 base[(x, y)]
39 } else if dist > outer_r {
40 overlay[(x, y)]
41 } else if base[(x, y)].is_floor() || overlay[(x, y)].is_floor() {
42 Tile::Floor
43 } else {
44 Tile::Wall
45 };
46 output.set(x as i32, y as i32, cell);
47 }
48 }
49}