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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
use crate::modifiers::{Invert, Threshold};
use ansi_term::Colour::RGB;
use imgdata::color::{self, Color};
use log;
use noise::utils::{NoiseMap, NoiseMapBuilder, PlaneMapBuilder};
use noise::NoiseFn;
use std::collections::HashMap;
#[derive(Clone, Copy, Debug, Default)]
pub struct Resolution {
pub x: usize,
pub y: usize,
}
#[derive(Clone, Debug, Default)]
pub struct Char {
pub value: f64,
pub chr: char,
pub color: Option<String>,
}
#[derive(Clone, Debug, Default)]
pub struct ASCIIMapper {
pub chars: Vec<Char>,
pub lookup: HashMap<String, String>,
}
impl ASCIIMapper {
pub fn new(chars: Vec<Char>) -> Self {
let mut lookup = HashMap::new();
for Char { value, chr, color } in chars.iter() {
let mut chr_str = chr.to_string();
match color {
Some(color) => {
let c = color::from_hex(color.clone());
let [r, g, b] = c.rgb();
chr_str = RGB(r, g, b).paint(chr_str.as_str()).to_string();
}
None => (),
}
let k = format!("{:.2}", value);
log::debug!("Adding key, value: <{}, {}>", k, chr_str);
lookup.insert(k, chr_str);
}
return ASCIIMapper { chars, lookup };
}
}
#[derive(Clone, Copy, Debug, Default)]
pub struct LevelsOpts {
pub min: f64,
pub max: f64,
pub steps: u64,
}
impl LevelsOpts {
pub fn step(&self) -> f64 {
return (self.max - self.min) / (self.steps as f64);
}
}
#[derive(Clone, Debug, Default)]
pub struct Opts<'a> {
pub inverted: bool,
pub is_cave: bool,
pub is_image: bool,
pub is_ascii: bool,
pub ascii_mapper: ASCIIMapper,
pub levels: LevelsOpts,
pub log_level: &'a str,
pub noise_type: &'a str,
pub output: &'a str,
pub seed: u32,
pub res: Resolution,
pub res_str: &'a str,
pub threshold_cutoff: f64,
pub threshold_enabled: bool,
pub tiled: bool,
pub turbulence: bool,
}
pub struct Builder<'a> {
pub noise_fn: &'a dyn NoiseFn<[f64; 3]>,
pub opts: &'a Opts<'a>,
pub noise_map: NoiseMap,
}
impl<'a> Builder<'a> {
pub fn new(noise_fn: &'a dyn NoiseFn<[f64; 3]>, opts: &'a Opts) -> Self {
Self {
noise_fn,
opts,
noise_map: NoiseMap::new(0, 0),
}
}
fn build(&self, noise_fn: &'a dyn NoiseFn<[f64; 3]>) -> NoiseMap {
let noise_map = PlaneMapBuilder::new(noise_fn)
.set_size(self.opts.res.x, self.opts.res.y)
.set_is_seamless(self.opts.tiled)
.build();
return noise_map;
}
pub fn generate(&mut self) {
log::debug!("Generating ...");
if self.opts.threshold_enabled && self.opts.inverted {
let thresh = Threshold::new(self.noise_fn).set_cutoff(self.opts.threshold_cutoff);
let invert = Invert::new(&thresh);
self.noise_map = self.build(&invert);
} else if self.opts.inverted {
let invert = Invert::new(self.noise_fn);
self.noise_map = self.build(&invert);
} else if self.opts.threshold_enabled {
let thresh = Threshold::new(self.noise_fn).set_cutoff(self.opts.threshold_cutoff);
self.noise_map = self.build(&thresh);
} else {
self.noise_map = self.build(self.noise_fn);
}
}
}