terrain_forge/effects/
blend.rs

1//! Blending effects
2
3use 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}