Skip to main content

terrain_forge/noise/
mod.rs

1//! Noise generation module with composable generators and modifiers
2
3mod fbm;
4mod modifiers;
5mod perlin;
6mod ridged;
7mod simplex;
8mod value;
9mod worley;
10
11pub use fbm::Fbm;
12pub use modifiers::*;
13pub use perlin::Perlin;
14pub use ridged::Ridged;
15pub use simplex::Simplex;
16pub use value::Value;
17pub use worley::Worley;
18
19/// Trait for noise sources that can be sampled at 2D coordinates.
20///
21/// # Examples
22///
23/// ```
24/// use terrain_forge::noise::{Perlin, NoiseSource, NoiseExt};
25///
26/// let noise = Perlin::new(42);
27/// let value = noise.sample(1.0, 2.0);
28/// assert!(value.is_finite());
29///
30/// let fbm = Perlin::new(42).fbm(4, 2.0, 0.5);
31/// let value = fbm.sample(1.0, 2.0);
32/// assert!(value.is_finite());
33/// ```
34pub trait NoiseSource {
35    /// Sample noise at 2D coordinates, returns value approximately in [-1, 1]
36    /// (may slightly exceed this range depending on the noise implementation)
37    fn sample(&self, x: f64, y: f64) -> f64;
38}
39
40/// Extension trait for composing noise sources
41pub trait NoiseExt: NoiseSource + Sized {
42    /// Scale output by a factor
43    fn scale(self, factor: f64) -> Scale<Self> {
44        Scale {
45            source: self,
46            factor,
47        }
48    }
49
50    /// Add offset to output
51    fn offset(self, amount: f64) -> Offset<Self> {
52        Offset {
53            source: self,
54            amount,
55        }
56    }
57
58    /// Clamp output to range
59    fn clamp(self, min: f64, max: f64) -> Clamp<Self> {
60        Clamp {
61            source: self,
62            min,
63            max,
64        }
65    }
66
67    /// Take absolute value
68    fn abs(self) -> Abs<Self> {
69        Abs { source: self }
70    }
71
72    /// Apply fractal brownian motion
73    fn fbm(self, octaves: u32, lacunarity: f64, persistence: f64) -> Fbm<Self> {
74        Fbm::new(self, octaves, lacunarity, persistence)
75    }
76
77    /// Blend this noise source with another, controlled by a third.
78    ///
79    /// The control source maps `[-1, 1]` to `[0, 1]` for interpolation:
80    /// control = -1 → 100% self, control = 1 → 100% other.
81    fn blend<B: NoiseSource, C: NoiseSource>(self, other: B, control: C) -> Blend<Self, B, C> {
82        Blend::new(self, other, control)
83    }
84}
85
86impl<T: NoiseSource> NoiseExt for T {}