Skip to main content

worldgen/noise/perlin/
mod.rs

1//////////////////////////////////////////////////////////////////////////////
2//  File: rust-worldgen/noise/perlin/mod.rs
3//////////////////////////////////////////////////////////////////////////////
4//  Copyright 2015 Samuel Sleight
5//
6//  Licensed under the Apache License, Version 2.0 (the "License");
7//  you may not use this file except in compliance with the License.
8//  You may obtain a copy of the License at
9//
10//      http://www.apache.org/licenses/LICENSE-2.0
11//
12//  Unless required by applicable law or agreed to in writing, software
13//  distributed under the License is distributed on an "AS IS" BASIS,
14//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15//  See the License for the specific language governing permissions and
16//  limitations under the License.
17//////////////////////////////////////////////////////////////////////////////
18
19//! A provider of perlin noise.
20//!
21//! Perlin noise is generated by combining a number of different values
22//! of coherent noise (known as octaves).
23//!
24//! The perlin noise source has a number of different properties that can
25//! be customised: the number of octaves, and the frequency, persistence,
26//! and lacunarity of the noise.
27
28use std::default::Default;
29
30use super::NoiseProvider;
31use super::coherent::CoherentNoise;
32
33pub use self::property::{Octaves, Frequency, Persistence, Lacunarity};
34use self::property::Property;
35
36mod property;
37
38/// The perlin noise source
39///
40/// # Example
41///
42/// ```
43/// # use worldgen::noise::perlin::{PerlinNoise, Octaves};
44/// # use worldgen::noise::NoiseProvider;
45/// let noise = PerlinNoise::new()
46///     .set(Octaves::of(5));
47///
48/// let value = noise.generate(1.5, 2.5, 15);
49/// ```
50#[derive(Default, Debug, Copy, Clone)]
51pub struct PerlinNoise {
52    octaves: Octaves,
53    freq: Frequency,
54    pers: Persistence,
55    lacu: Lacunarity
56}
57
58impl PerlinNoise {
59    /// Construct the default perlin source.
60    ///
61    /// The default values are:
62    ///
63    /// ```text
64    /// octaves = 8
65    /// frequency = 1.0
66    /// persistence = 0.5
67    /// lacunarity = 2.0
68    /// ```
69    pub fn new() -> PerlinNoise {
70        Default::default()
71    }
72
73    /// Set a property on the noise source.
74    pub fn set<T: Property>(self, property: T) -> PerlinNoise {
75        property.set_to(self)
76    }
77
78    fn set_octaves(self, octaves: Octaves) -> PerlinNoise {
79        PerlinNoise {
80            octaves,
81            ..self
82        }
83    }
84
85    fn set_frequency(self, freq: Frequency) -> PerlinNoise {
86        PerlinNoise {
87            freq,
88            ..self
89        }
90    }
91
92    fn set_persistence(self, pers: Persistence) -> PerlinNoise {
93        PerlinNoise {
94            pers,
95            ..self
96        }
97    }
98
99    fn set_lacunarity(self, lacu: Lacunarity) -> PerlinNoise {
100        PerlinNoise {
101            lacu,
102            ..self
103        }
104    }
105}
106
107impl NoiseProvider for PerlinNoise {
108    fn generate(&self, x: f64, y: f64, seed: u64) -> f64 {
109        let mut x = x * self.freq.value;
110        let mut y = y * self.freq.value;
111        let mut pers = 1.0f64;
112
113        (0 .. self.octaves.value).fold(0.0, |value, octave| {
114            let seed = seed + octave as u64;
115            let value = value + CoherentNoise.generate(x, y, seed) * pers;
116
117            x *= self.lacu.value;
118            y *= self.lacu.value;
119            pers *= self.pers.value;
120
121            value
122        })
123    }
124}