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 {}