1use crate::noise::algorithms::AlgorithmInitializer;
35use crate::noise::Algorithm;
36use crate::random::algorithms::Algorithm as RandomAlgorithm;
37use crate::util::FloorRem;
38
39use derivative::Derivative;
40
41#[derive(Clone, Copy, Derivative)]
43#[derivative(Debug)]
44pub struct Simplex {
45 dimensions: usize,
46 #[derivative(Debug = "ignore")]
47 map: [u8; 256],
48}
49
50impl Algorithm for Simplex {
51 fn new<R: RandomAlgorithm>(
52 dimensions: usize,
53 mut initializer: AlgorithmInitializer<R>,
54 ) -> Self {
55 Self {
56 dimensions,
57 map: initializer.map(),
58 }
59 }
60
61 fn generate(&self, f: &[f32]) -> f32 {
62 assert!(f.len() >= self.dimensions);
63
64 match self.dimensions {
65 1 => self.simplex_1d(f[0]),
66 2 => self.simplex_2d(f[0], f[1]),
67 3 => self.simplex_3d(f[0], f[1], f[2]),
68 4 => self.simplex_4d(f[0], f[1], f[2], f[3]),
69 _ => unreachable!(),
70 }
71 }
72}
73
74impl Simplex {
75 const SIMPLEX_SCALE: f32 = 0.5;
76 const SIMPLEX: [[f32; 4]; 64] = [
77 [0.0, 1.0, 2.0, 3.0],
78 [0.0, 1.0, 3.0, 2.0],
79 [0.0, 0.0, 0.0, 0.0],
80 [0.0, 2.0, 3.0, 1.0],
81 [0.0, 0.0, 0.0, 0.0],
82 [0.0, 0.0, 0.0, 0.0],
83 [0.0, 0.0, 0.0, 0.0],
84 [1.0, 2.0, 3.0, 0.0],
85 [0.0, 2.0, 1.0, 3.0],
86 [0.0, 0.0, 0.0, 0.0],
87 [0.0, 3.0, 1.0, 2.0],
88 [0.0, 3.0, 2.0, 1.0],
89 [0.0, 0.0, 0.0, 0.0],
90 [0.0, 0.0, 0.0, 0.0],
91 [0.0, 0.0, 0.0, 0.0],
92 [1.0, 3.0, 2.0, 0.0],
93 [0.0, 0.0, 0.0, 0.0],
94 [0.0, 0.0, 0.0, 0.0],
95 [0.0, 0.0, 0.0, 0.0],
96 [0.0, 0.0, 0.0, 0.0],
97 [0.0, 0.0, 0.0, 0.0],
98 [0.0, 0.0, 0.0, 0.0],
99 [0.0, 0.0, 0.0, 0.0],
100 [0.0, 0.0, 0.0, 0.0],
101 [1.0, 2.0, 0.0, 3.0],
102 [0.0, 0.0, 0.0, 0.0],
103 [1.0, 3.0, 0.0, 2.0],
104 [0.0, 0.0, 0.0, 0.0],
105 [0.0, 0.0, 0.0, 0.0],
106 [0.0, 0.0, 0.0, 0.0],
107 [2.0, 3.0, 0.0, 1.0],
108 [2.0, 3.0, 1.0, 0.0],
109 [1.0, 0.0, 2.0, 3.0],
110 [1.0, 0.0, 3.0, 2.0],
111 [0.0, 0.0, 0.0, 0.0],
112 [0.0, 0.0, 0.0, 0.0],
113 [0.0, 0.0, 0.0, 0.0],
114 [2.0, 0.0, 3.0, 1.0],
115 [0.0, 0.0, 0.0, 0.0],
116 [2.0, 1.0, 3.0, 0.0],
117 [0.0, 0.0, 0.0, 0.0],
118 [0.0, 0.0, 0.0, 0.0],
119 [0.0, 0.0, 0.0, 0.0],
120 [0.0, 0.0, 0.0, 0.0],
121 [0.0, 0.0, 0.0, 0.0],
122 [0.0, 0.0, 0.0, 0.0],
123 [0.0, 0.0, 0.0, 0.0],
124 [0.0, 0.0, 0.0, 0.0],
125 [2.0, 0.0, 1.0, 3.0],
126 [0.0, 0.0, 0.0, 0.0],
127 [0.0, 0.0, 0.0, 0.0],
128 [0.0, 0.0, 0.0, 0.0],
129 [3.0, 0.0, 1.0, 2.0],
130 [3.0, 0.0, 2.0, 1.0],
131 [0.0, 0.0, 0.0, 0.0],
132 [3.0, 1.0, 2.0, 0.0],
133 [2.0, 1.0, 0.0, 3.0],
134 [0.0, 0.0, 0.0, 0.0],
135 [0.0, 0.0, 0.0, 0.0],
136 [0.0, 0.0, 0.0, 0.0],
137 [3.0, 1.0, 0.0, 2.0],
138 [0.0, 0.0, 0.0, 0.0],
139 [3.0, 2.0, 0.0, 1.0],
140 [3.0, 2.0, 1.0, 0.0],
141 ];
142
143 fn simplex_1d(&self, f0: f32) -> f32 {
144 let i0 = (f0 * Self::SIMPLEX_SCALE).floor() as i32;
145 let i1 = i0 + 1;
146 let x0 = f0 * Self::SIMPLEX_SCALE - i0 as f32;
147 let x1 = x0 - 1.0;
148 let t0 = 1.0 - x0 * x0;
149 let t1 = 1.0 - x1 * x1;
150 let t0 = t0 * t0;
151 let t1 = t1 * t1;
152 let i0 = i32::from(self.map[(i0 & 0xFF) as usize]);
153 let mut n0 = Self::simplex_gradient_1d(i0, x0);
154 n0 *= t0 * t0;
155 let i1 = i32::from(self.map[(i1 & 0xFF) as usize]);
156 let mut n1 = Self::simplex_gradient_1d(i1, x1);
157 n1 *= t1 * t1;
158
159 0.25 * (n0 + n1)
160 }
161
162 #[allow(clippy::many_single_char_names)]
163 fn simplex_2d(&self, f0: f32, f1: f32) -> f32 {
164 const F2: f64 = 0.366_025_403;
165 const G2: f64 = 0.211_324_865;
166
167 let s = f64::from(f0 + f1) * F2 * f64::from(Self::SIMPLEX_SCALE);
168 let xs = f0 * Self::SIMPLEX_SCALE + s as f32;
169 let ys = f1 * Self::SIMPLEX_SCALE + s as f32;
170 let i = xs.floor() as i32;
171 let j = ys.floor() as i32;
172 let t = (f64::from(i) + f64::from(j)) * G2;
173 let xo = f64::from(i) - t;
174 let yo = f64::from(j) - t;
175 let x0 = f0 * Self::SIMPLEX_SCALE - xo as f32;
176 let y0 = f1 * Self::SIMPLEX_SCALE - yo as f32;
177 let ii = i.floor_modulo(256);
178 let jj = j.floor_modulo(256);
179 let (i1, j1) = if x0 > y0 { (1, 0) } else { (0, 1) };
180 let x1 = x0 - i1 as f32 + G2 as f32;
181 let y1 = y0 - j1 as f32 + G2 as f32;
182 let x2 = x0 - 1.0 + (2.0 * G2) as f32;
183 let y2 = y0 - 1.0 + (2.0 * G2) as f32;
184 let mut t0 = 0.5 - x0 * x0 - y0 * y0;
185
186 let n0 = if t0 < 0.0 {
187 0.0
188 } else {
189 let mut idx = (ii + i32::from(self.map[jj as usize])) & 0xFF;
190 t0 *= t0;
191 idx = i32::from(self.map[idx as usize]);
192 Self::simplex_gradient_2d(idx, x0, y0) * t0 * t0
193 };
194 let mut t1 = 0.5 - x1 * x1 - y1 * y1;
195 let n1 = if t1 < 0.0 {
196 0.0
197 } else {
198 let mut idx = (ii + i1 + i32::from(self.map[((jj + j1) & 0xFF) as usize])) & 0xFF;
199 t1 *= t1;
200 idx = i32::from(self.map[idx as usize]);
201 Self::simplex_gradient_2d(idx, x1, y1) * t1 * t1
202 };
203 let mut t2 = 0.5 - x2 * x2 - y2 * y2;
204 let n2 = if t2 < 0.0 {
205 0.0
206 } else {
207 let mut idx = (ii + 1 + i32::from(self.map[((jj + 1) & 0xFF) as usize])) & 0xFF;
208 t2 *= t2;
209 idx = i32::from(self.map[idx as usize]);
210 Self::simplex_gradient_2d(idx, x2, y2) * t2 * t2
211 };
212
213 40.0 * (n0 + n1 + n2)
214 }
215
216 #[allow(clippy::too_many_lines)]
217 #[allow(clippy::many_single_char_names)]
218 fn simplex_3d(&self, f0: f32, f1: f32, f2: f32) -> f32 {
219 const F3: f64 = 0.333_333_333;
220 const G3: f64 = 0.166_666_667;
221
222 let s = f64::from(f0 + f1 + f2) * F3 * f64::from(Self::SIMPLEX_SCALE);
223 let xs = f0 * Self::SIMPLEX_SCALE + s as f32;
224 let ys = f1 * Self::SIMPLEX_SCALE + s as f32;
225 let zs = f2 * Self::SIMPLEX_SCALE + s as f32;
226 let i = xs.floor() as i32;
227 let j = ys.floor() as i32;
228 let k = zs.floor() as i32;
229 let t = (f64::from(i) + f64::from(j) + f64::from(k)) * G3;
230 let xo = f64::from(i) - t;
231 let yo = f64::from(j) - t;
232 let zo = f64::from(k) - t;
233 let x0 = f0 * Self::SIMPLEX_SCALE - xo as f32;
234 let y0 = f1 * Self::SIMPLEX_SCALE - yo as f32;
235 let z0 = f2 * Self::SIMPLEX_SCALE - zo as f32;
236
237 let (i1, j1, k1, i2, j2, k2) = if x0 >= y0 {
238 if y0 >= z0 {
239 (1, 0, 0, 1, 1, 0)
240 } else if x0 >= z0 {
241 (1, 0, 0, 1, 0, 1)
242 } else {
243 (0, 0, 1, 1, 0, 1)
244 }
245 } else if y0 < z0 {
246 (0, 0, 1, 0, 1, 1)
247 } else if x0 < z0 {
248 (0, 1, 0, 0, 1, 1)
249 } else {
250 (0, 1, 0, 1, 1, 0)
251 };
252
253 let x1 = x0 - i1 as f32 + G3 as f32;
254 let y1 = y0 - j1 as f32 + G3 as f32;
255 let z1 = z0 - k1 as f32 + G3 as f32;
256 let x2 = x0 - i2 as f32 + 2.0 * G3 as f32;
257 let y2 = y0 - j2 as f32 + 2.0 * G3 as f32;
258 let z2 = z0 - k2 as f32 + 2.0 * G3 as f32;
259 let x3 = x0 - 1.0 + (3.0 * G3) as f32;
260 let y3 = y0 - 1.0 + (3.0 * G3) as f32;
261 let z3 = z0 - 1.0 + (3.0 * G3) as f32;
262 let ii = i.floor_modulo(256);
263 let jj = j.floor_modulo(256);
264 let kk = k.floor_modulo(256);
265
266 let mut t0 = 0.6 - x0 * x0 - y0 * y0 - z0 * z0;
267 let n0 = if t0 < 0.0 {
268 0.0
269 } else {
270 let idx = i32::from(
271 self.map[((ii
272 + i32::from(
273 self.map[((jj + i32::from(self.map[kk as usize])) & 0xFF) as usize],
274 ))
275 & 0xFF) as usize],
276 );
277 t0 *= t0;
278 Self::simplex_gradient_3d(idx, x0, y0, z0) * t0 * t0
279 };
280
281 let mut t1 = 0.6 - x1 * x1 - y1 * y1 - z1 * z1;
282 let n1 = if t1 < 0.0 {
283 0.0
284 } else {
285 let idx = i32::from(
286 self.map[((ii
287 + i1
288 + i32::from(
289 self.map[((jj + j1 + i32::from(self.map[((kk + k1) & 0xFF) as usize]))
290 & 0xFF) as usize],
291 ))
292 & 0xFF) as usize],
293 );
294 t1 *= t1;
295 Self::simplex_gradient_3d(idx, x1, y1, z1) * t1 * t1
296 };
297
298 let mut t2 = 0.6 - x2 * x2 - y2 * y2 - z2 * z2;
299 let n2 = if t2 < 0.0 {
300 0.0
301 } else {
302 let idx = i32::from(
303 self.map[((ii
304 + i2
305 + i32::from(
306 self.map[((jj + j2 + i32::from(self.map[((kk + k2) & 0xFF) as usize]))
307 & 0xFF) as usize],
308 ))
309 & 0xFF) as usize],
310 );
311 t2 *= t2;
312 Self::simplex_gradient_3d(idx, x2, y2, z2) * t2 * t2
313 };
314
315 let mut t3 = 0.6 - x3 * x3 - y3 * y3 - z3 * z3;
316 let n3 = if t3 < 0.0 {
317 0.0
318 } else {
319 let idx = i32::from(
320 self.map[((ii
321 + 1
322 + i32::from(
323 self.map[((jj + 1 + i32::from(self.map[((kk + 1) & 0xFF) as usize])) & 0xFF)
324 as usize],
325 ))
326 & 0xFF) as usize],
327 );
328 t3 *= t3;
329 Self::simplex_gradient_3d(idx, x3, y3, z3) * t3 * t3
330 };
331
332 32.0 * (n0 + n1 + n2 + n3)
333 }
334
335 #[allow(clippy::too_many_lines)]
336 #[allow(clippy::many_single_char_names)]
337 fn simplex_4d(&self, f0: f32, f1: f32, f2: f32, f3: f32) -> f32 {
338 const F4: f64 = 0.309_016_994;
339 const G4: f64 = 0.138_196_601;
340
341 let s = f64::from(f0 + f1 + f2 + f3) * F4 * f64::from(Self::SIMPLEX_SCALE);
342 let xs = f0 * Self::SIMPLEX_SCALE + s as f32;
343 let ys = f1 * Self::SIMPLEX_SCALE + s as f32;
344 let zs = f2 * Self::SIMPLEX_SCALE + s as f32;
345 let ws = f3 * Self::SIMPLEX_SCALE + s as f32;
346
347 let i = xs.floor() as i32;
348 let j = ys.floor() as i32;
349 let k = zs.floor() as i32;
350 let l = ws.floor() as i32;
351
352 let t = (f64::from(i) + f64::from(j) + f64::from(k) + f64::from(l)) * G4;
353 let xo = f64::from(i) - t;
354 let yo = f64::from(j) - t;
355 let zo = f64::from(k) - t;
356 let wo = f64::from(l) - t;
357
358 let x0 = f0 * Self::SIMPLEX_SCALE - xo as f32;
359 let y0 = f1 * Self::SIMPLEX_SCALE - yo as f32;
360 let z0 = f2 * Self::SIMPLEX_SCALE - zo as f32;
361 let w0 = f3 * Self::SIMPLEX_SCALE - wo as f32;
362
363 let c1 = if x0 > y0 { 32 } else { 0 };
364 let c2 = if x0 > z0 { 16 } else { 0 };
365 let c3 = if y0 > z0 { 8 } else { 0 };
366 let c4 = if x0 > w0 { 4 } else { 0 };
367 let c5 = if y0 > w0 { 2 } else { 0 };
368 let c6 = if z0 > w0 { 1 } else { 0 };
369 let c = c1 + c2 + c3 + c4 + c5 + c6;
370
371 let i1 = if Self::SIMPLEX[c][0] >= 3.0 { 1 } else { 0 };
372 let j1 = if Self::SIMPLEX[c][1] >= 3.0 { 1 } else { 0 };
373 let k1 = if Self::SIMPLEX[c][2] >= 3.0 { 1 } else { 0 };
374 let l1 = if Self::SIMPLEX[c][3] >= 3.0 { 1 } else { 0 };
375
376 let i2 = if Self::SIMPLEX[c][0] >= 2.0 { 1 } else { 0 };
377 let j2 = if Self::SIMPLEX[c][1] >= 2.0 { 1 } else { 0 };
378 let k2 = if Self::SIMPLEX[c][2] >= 2.0 { 1 } else { 0 };
379 let l2 = if Self::SIMPLEX[c][3] >= 2.0 { 1 } else { 0 };
380
381 let i3 = if Self::SIMPLEX[c][0] >= 1.0 { 1 } else { 0 };
382 let j3 = if Self::SIMPLEX[c][1] >= 1.0 { 1 } else { 0 };
383 let k3 = if Self::SIMPLEX[c][2] >= 1.0 { 1 } else { 0 };
384 let l3 = if Self::SIMPLEX[c][3] >= 1.0 { 1 } else { 0 };
385
386 let x1 = x0 - i1 as f32 + (G4) as f32;
387 let y1 = y0 - j1 as f32 + (G4) as f32;
388 let z1 = z0 - k1 as f32 + (G4) as f32;
389 let w1 = w0 - l1 as f32 + (G4) as f32;
390 let x2 = x0 - i2 as f32 + (2.0 * G4) as f32;
391 let y2 = y0 - j2 as f32 + (2.0 * G4) as f32;
392 let z2 = z0 - k2 as f32 + (2.0 * G4) as f32;
393 let w2 = w0 - l2 as f32 + (2.0 * G4) as f32;
394 let x3 = x0 - i3 as f32 + (3.0 * G4) as f32;
395 let y3 = y0 - j3 as f32 + (3.0 * G4) as f32;
396 let z3 = z0 - k3 as f32 + (3.0 * G4) as f32;
397 let w3 = w0 - l3 as f32 + (3.0 * G4) as f32;
398 let x4 = x0 - 1.0 + (4.0 * G4) as f32;
399 let y4 = y0 - 1.0 + (4.0 * G4) as f32;
400 let z4 = z0 - 1.0 + (4.0 * G4) as f32;
401 let w4 = w0 - 1.0 + (4.0 * G4) as f32;
402
403 let ii = i.floor_modulo(256);
404 let jj = j.floor_modulo(256);
405 let kk = k.floor_modulo(256);
406 let ll = l.floor_modulo(256);
407
408 let mut t0 = 0.6 - x0 * x0 - y0 * y0 - z0 * z0 - w0 * w0;
409 let n0 = if t0 < 0.0 {
410 0.0
411 } else {
412 let idx = i32::from(
413 self.map[((ii
414 + i32::from(
415 self.map[((jj
416 + i32::from(
417 self.map[((kk + i32::from(self.map[ll as usize])) & 0xFF) as usize],
418 ))
419 & 0xFF) as usize],
420 ))
421 & 0xFF) as usize],
422 );
423 t0 *= t0;
424 Self::simplex_gradient_4d(idx, x0, y0, z0, w0) * t0 * t0
425 };
426
427 let mut t1 = 0.6 - x1 * x1 - y1 * y1 - z1 * z1 - w1 * w1;
428 let n1 = if t1 < 0.0 {
429 0.0
430 } else {
431 let idx = i32::from(
432 self.map[((ii
433 + i1
434 + i32::from(
435 self.map[((jj
436 + j1
437 + i32::from(
438 self.map[((kk
439 + k1
440 + i32::from(self.map[((ll + l1) & 0xFF) as usize]))
441 & 0xFF) as usize],
442 ))
443 & 0xFF) as usize],
444 ))
445 & 0xFF) as usize],
446 );
447 t1 *= t1;
448 Self::simplex_gradient_4d(idx, x1, y1, z1, w1) * t1 * t1
449 };
450
451 let mut t2 = 0.6 - x2 * x2 - y2 * y2 - z2 * z2 - w2 * w2;
452 let n2 = if t2 < 0.0 {
453 0.0
454 } else {
455 let idx = i32::from(
456 self.map[((ii
457 + i2
458 + i32::from(
459 self.map[((jj
460 + j2
461 + i32::from(
462 self.map[((kk
463 + k2
464 + i32::from(self.map[((ll + l2) & 0xFF) as usize]))
465 & 0xFF) as usize],
466 ))
467 & 0xFF) as usize],
468 ))
469 & 0xFF) as usize],
470 );
471 t2 *= t2;
472 Self::simplex_gradient_4d(idx, x2, y2, z2, w2) * t2 * t2
473 };
474
475 let mut t3 = 0.6 - x3 * x3 - y3 * y3 - z3 * z3 - w3 * w3;
476 let n3 = if t3 < 0.0 {
477 0.0
478 } else {
479 let idx = i32::from(
480 self.map[((ii
481 + i3
482 + i32::from(
483 self.map[((jj
484 + j3
485 + i32::from(
486 self.map[((kk
487 + k3
488 + i32::from(self.map[((ll + l3) & 0xFF) as usize]))
489 & 0xFF) as usize],
490 ))
491 & 0xFF) as usize],
492 ))
493 & 0xFF) as usize],
494 );
495 t3 *= t3;
496 Self::simplex_gradient_4d(idx, x3, y3, z3, w3) * t3 * t3
497 };
498
499 let mut t4 = 0.6 - x4 * x4 - y4 * y4 - z4 * z4 - w4 * w4;
500 let n4 = if t4 < 0.0 {
501 0.0
502 } else {
503 let idx = i32::from(
504 self.map[((ii
505 + 1
506 + i32::from(
507 self.map[((jj
508 + 1
509 + i32::from(
510 self.map[((kk
511 + 1
512 + i32::from(self.map[((ll + 1) & 0xFF) as usize]))
513 & 0xFF) as usize],
514 ))
515 & 0xFF) as usize],
516 ))
517 & 0xFF) as usize],
518 );
519 t4 *= t4;
520 Self::simplex_gradient_4d(idx, x4, y4, z4, w4) * t4 * t4
521 };
522
523 27.0 * (n0 + n1 + n2 + n3 + n4)
524 }
525
526 fn simplex_gradient_1d(mut h: i32, x: f32) -> f32 {
527 h &= 0xF;
528 let mut grad = 1.0 + (h & 7) as f32;
529 if h & 8 == 8 {
530 grad = -grad;
531 }
532 grad * x
533 }
534
535 #[allow(clippy::many_single_char_names)]
536 fn simplex_gradient_2d(mut h: i32, x: f32, y: f32) -> f32 {
537 h &= 0x7;
538 let (u, v) = if h < 4 { (x, 2.0 * y) } else { (y, 2.0 * x) };
539 (if h & 1 == 1 { -u } else { u }) + (if h & 2 == 2 { -v } else { v })
540 }
541
542 #[allow(clippy::many_single_char_names)]
543 #[allow(unused_parens)] fn simplex_gradient_3d(mut h: i32, x: f32, y: f32, z: f32) -> f32 {
545 h &= 0xF;
546 let u = if h < 8 { x } else { y };
547 let v = if h < 4 {
548 y
549 } else if h == 12 || h == 14 {
550 x
551 } else {
552 z
553 };
554
555 (if h & 1 == 1 { -u } else { u } + if h & 2 == 2 { -v } else { v })
556 }
557
558 #[allow(clippy::many_single_char_names)]
559 #[allow(unused_parens)] fn simplex_gradient_4d(mut h: i32, x: f32, y: f32, z: f32, t: f32) -> f32 {
561 h &= 0x1F;
562 let u = if h < 24 { x } else { y };
563 let v = if h < 16 { y } else { z };
564 let w = if h < 8 { z } else { t };
565
566 (if h & 1 == 1 { -u } else { u }
567 + if h & 2 == 2 { -v } else { v }
568 + if h & 4 == 4 { -w } else { w })
569 }
570}