doryen_extra/noise/
algorithms.rs

1/* BSD 3-Clause License
2 *
3 * Copyright © 2019, Alexander Krivács Schrøder <alexschrod@gmail.com>.
4 * Copyright © 2008-2019, Jice and the libtcod contributors.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright notice,
11 *    this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright notice,
14 *    this list of conditions and the following disclaimer in the documentation
15 *    and/or other materials provided with the distribution.
16 *
17 * 3. Neither the name of the copyright holder nor the names of its
18 *    contributors may be used to endorse or promote products derived from
19 *    this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33
34//! Noise generator algorithms.
35
36mod perlin;
37mod simplex;
38mod wavelet;
39
40pub use perlin::Perlin;
41pub use simplex::Simplex;
42pub use wavelet::Wavelet;
43
44use crate::noise::MAX_DIMENSIONS;
45use crate::random::algorithms::Algorithm as RandomAlgorithm;
46use crate::random::{Random, Rng};
47use ilyvion_util::multi_dimensional::Window2D;
48
49/// Noise algorithm trait.
50pub trait Algorithm {
51    /// Creates a new noise algorithm instance.
52    fn new<R: RandomAlgorithm>(dimensions: usize, initializer: AlgorithmInitializer<R>) -> Self;
53
54    /// Generates the noise value at the given coordinates.
55    fn generate(&self, f: &[f32]) -> f32;
56}
57
58/// Noise algorithm initializer.
59#[derive(Debug)]
60pub struct AlgorithmInitializer<R: RandomAlgorithm> {
61    random: Random<R>,
62}
63
64impl<R: RandomAlgorithm> AlgorithmInitializer<R> {
65    /// Create a new noise algorithm initializer instance.
66    pub fn new(random: Random<R>) -> Self {
67        Self { random }
68    }
69
70    /// Generate a map.
71    pub fn map(&mut self) -> [u8; 256] {
72        let mut map = [0; 256];
73        for i in 0_u8..=255 {
74            map[i as usize] = i;
75        }
76
77        for i in (0..255).rev() {
78            let j = self.random.get_i32(0, 255) as usize;
79            if i == j {
80                continue;
81            }
82            map.swap(i, j);
83        }
84
85        map
86    }
87
88    /// Generate a buffer.
89    pub fn buffer(&mut self, dimensions: usize) -> [f32; MAX_DIMENSIONS * 256] {
90        let mut buffer = [0.0; MAX_DIMENSIONS * 256];
91        let mut buffer_window = Window2D::new_mut_unchecked(&mut buffer, 256, MAX_DIMENSIONS);
92        for i in 0_u8..=255 {
93            for j in 0..dimensions {
94                buffer_window[i as usize][j] = self.random.get_f32(-0.5, 0.5);
95            }
96            Self::normalize(dimensions, &mut buffer_window[i as usize]);
97        }
98
99        buffer
100    }
101
102    fn normalize(dimensions: usize, f: &mut [f32]) {
103        let mut magnitude = 0.0;
104        for &i in f.iter().take(dimensions) {
105            magnitude += i * i;
106        }
107        magnitude = 1.0 / magnitude.sqrt();
108        for i in f.iter_mut().take(dimensions) {
109            *i *= magnitude;
110        }
111    }
112}