noise/noise_fns/transformers/
turbulence.rs1use crate::noise_fns::{Fbm, MultiFractal, NoiseFn, Seedable};
2
3#[derive(Clone, Debug)]
12pub struct Turbulence<Source, F>
13where
14 F: Default + Seedable,
15{
16 pub source: Source,
18
19 pub frequency: f64,
21
22 pub power: f64,
25
26 pub roughness: usize,
28
29 seed: u32,
30 x_distort_function: Fbm<F>,
31 y_distort_function: Fbm<F>,
32 z_distort_function: Fbm<F>,
33 u_distort_function: Fbm<F>,
34}
35
36impl<Source, F> Turbulence<Source, F>
37where
38 F: Default + Seedable,
39{
40 pub const DEFAULT_SEED: u32 = 0;
41 pub const DEFAULT_FREQUENCY: f64 = 1.0;
42 pub const DEFAULT_POWER: f64 = 1.0;
43 pub const DEFAULT_ROUGHNESS: usize = 3;
44
45 pub fn new(source: Source) -> Self {
46 Self {
47 source,
48 seed: Self::DEFAULT_SEED,
49 frequency: Self::DEFAULT_FREQUENCY,
50 power: Self::DEFAULT_POWER,
51 roughness: Self::DEFAULT_ROUGHNESS,
52 x_distort_function: Fbm::default()
53 .set_seed(Self::DEFAULT_SEED)
54 .set_octaves(Self::DEFAULT_ROUGHNESS)
55 .set_frequency(Self::DEFAULT_FREQUENCY),
56 y_distort_function: Fbm::default()
57 .set_seed(Self::DEFAULT_SEED + 1)
58 .set_octaves(Self::DEFAULT_ROUGHNESS)
59 .set_frequency(Self::DEFAULT_FREQUENCY),
60 z_distort_function: Fbm::default()
61 .set_seed(Self::DEFAULT_SEED + 2)
62 .set_octaves(Self::DEFAULT_ROUGHNESS)
63 .set_frequency(Self::DEFAULT_FREQUENCY),
64 u_distort_function: Fbm::default()
65 .set_seed(Self::DEFAULT_SEED + 3)
66 .set_octaves(Self::DEFAULT_ROUGHNESS)
67 .set_frequency(Self::DEFAULT_FREQUENCY),
68 }
69 }
70
71 pub fn set_frequency(self, frequency: f64) -> Self {
72 Self {
73 frequency,
74 x_distort_function: self.x_distort_function.set_frequency(frequency),
75 y_distort_function: self.y_distort_function.set_frequency(frequency),
76 z_distort_function: self.z_distort_function.set_frequency(frequency),
77 u_distort_function: self.u_distort_function.set_frequency(frequency),
78 ..self
79 }
80 }
81
82 pub fn set_power(self, power: f64) -> Self {
83 Self { power, ..self }
84 }
85
86 pub fn set_roughness(self, roughness: usize) -> Self {
87 Self {
88 roughness,
89 x_distort_function: self.x_distort_function.set_octaves(roughness),
90 y_distort_function: self.y_distort_function.set_octaves(roughness),
91 z_distort_function: self.z_distort_function.set_octaves(roughness),
92 u_distort_function: self.u_distort_function.set_octaves(roughness),
93 ..self
94 }
95 }
96}
97
98impl<Source, F> Seedable for Turbulence<Source, F>
99where
100 F: Default + Seedable,
101{
102 fn set_seed(self, seed: u32) -> Self {
103 Self {
104 seed,
105 x_distort_function: self.x_distort_function.set_seed(seed),
106 y_distort_function: self.y_distort_function.set_seed(seed + 1),
107 z_distort_function: self.z_distort_function.set_seed(seed + 2),
108 u_distort_function: self.u_distort_function.set_seed(seed + 3),
109 ..self
110 }
111 }
112
113 fn seed(&self) -> u32 {
114 self.seed
115 }
116}
117
118impl<Source, F> NoiseFn<f64, 2> for Turbulence<Source, F>
119where
120 Source: NoiseFn<f64, 2>,
121 F: Default + Seedable + NoiseFn<f64, 2>,
122{
123 fn get(&self, point: [f64; 2]) -> f64 {
124 let x0 = point[0] + 12414.0 / 65536.0;
128 let y0 = point[1] + 65124.0 / 65536.0;
129
130 let x1 = point[0] + 26519.0 / 65536.0;
131 let y1 = point[1] + 18128.0 / 65536.0;
132
133 let x_distort = point[0] + (self.x_distort_function.get([x0, y0]) * self.power);
134 let y_distort = point[1] + (self.y_distort_function.get([x1, y1]) * self.power);
135
136 self.source.get([x_distort, y_distort])
137 }
138}
139
140impl<Source, F> NoiseFn<f64, 3> for Turbulence<Source, F>
141where
142 Source: NoiseFn<f64, 3>,
143 F: Default + Seedable + NoiseFn<f64, 3>,
144{
145 fn get(&self, point: [f64; 3]) -> f64 {
146 let x0 = point[0] + 12414.0 / 65536.0;
150 let y0 = point[1] + 65124.0 / 65536.0;
151 let z0 = point[2] + 31337.0 / 65536.0;
152
153 let x1 = point[0] + 26519.0 / 65536.0;
154 let y1 = point[1] + 18128.0 / 65536.0;
155 let z1 = point[2] + 60943.0 / 65536.0;
156
157 let x2 = point[0] + 53820.0 / 65536.0;
158 let y2 = point[1] + 11213.0 / 65536.0;
159 let z2 = point[2] + 44845.0 / 65536.0;
160
161 let x_distort = point[0] + (self.x_distort_function.get([x0, y0, z0]) * self.power);
162 let y_distort = point[1] + (self.y_distort_function.get([x1, y1, z1]) * self.power);
163 let z_distort = point[2] + (self.z_distort_function.get([x2, y2, z2]) * self.power);
164
165 self.source.get([x_distort, y_distort, z_distort])
166 }
167}
168
169impl<Source, F> NoiseFn<f64, 4> for Turbulence<Source, F>
170where
171 Source: NoiseFn<f64, 4>,
172 F: Default + Seedable + NoiseFn<f64, 4>,
173{
174 fn get(&self, point: [f64; 4]) -> f64 {
175 let x0 = point[0] + 12414.0 / 65536.0;
179 let y0 = point[1] + 65124.0 / 65536.0;
180 let z0 = point[2] + 31337.0 / 65536.0;
181 let u0 = point[3] + 57948.0 / 65536.0;
182
183 let x1 = point[0] + 26519.0 / 65536.0;
184 let y1 = point[1] + 18128.0 / 65536.0;
185 let z1 = point[2] + 60943.0 / 65536.0;
186 let u1 = point[3] + 48513.0 / 65536.0;
187
188 let x2 = point[0] + 53820.0 / 65536.0;
189 let y2 = point[1] + 11213.0 / 65536.0;
190 let z2 = point[2] + 44845.0 / 65536.0;
191 let u2 = point[3] + 39357.0 / 65536.0;
192
193 let x3 = point[0] + 18128.0 / 65536.0;
194 let y3 = point[1] + 44845.0 / 65536.0;
195 let z3 = point[2] + 12414.0 / 65536.0;
196 let u3 = point[3] + 60943.0 / 65536.0;
197
198 let x_distort = point[0] + (self.x_distort_function.get([x0, y0, z0, u0]) * self.power);
199 let y_distort = point[1] + (self.y_distort_function.get([x1, y1, z1, u1]) * self.power);
200 let z_distort = point[2] + (self.z_distort_function.get([x2, y2, z2, u2]) * self.power);
201 let u_distort = point[3] + (self.u_distort_function.get([x3, y3, z3, u3]) * self.power);
202
203 self.source
204 .get([x_distort, y_distort, z_distort, u_distort])
205 }
206}