diff --git a/src/lib.rs b/src/lib.rs index ffc9deef..ba74ca9b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,9 +3,9 @@ //! # Example //! //! ```rust -//! use noise::{NoiseFn, Perlin, Seedable}; +//! use noise::{NoiseFn, Perlin, Seedable, DEFAULT_SEED}; //! -//! let perlin = Perlin::new(1); +//! let perlin = Perlin::new(DEFAULT_SEED); //! let val = perlin.get([42.4, 37.7, 2.8]); //! ``` diff --git a/src/noise_fns.rs b/src/noise_fns.rs index 03e6a599..3b499d52 100644 --- a/src/noise_fns.rs +++ b/src/noise_fns.rs @@ -50,8 +50,14 @@ where /// Trait for functions that require a seed before generating their values pub trait Seedable { /// Set the seed for the function implementing the `Seedable` trait - fn set_seed(self, seed: u32) -> Self; + fn set_seed(self, seed: Seed) -> Self; /// Getter to retrieve the seed from the function - fn seed(&self) -> u32; + fn seed(&self) -> Seed; } + +pub type Seed = [u8; 16]; + +pub const DEFAULT_SEED: Seed = [ + 0x4f, 0x09, 0xd6, 0x9f, 0x62, 0x9b, 0x09, 0x0c, 0x0c, 0x49, 0x09, 0xfe, 0x6f, 0x1d, 0x4a, 0x38, +]; diff --git a/src/noise_fns/generators/fractals.rs b/src/noise_fns/generators/fractals.rs index 159e4d88..1fd0eeeb 100644 --- a/src/noise_fns/generators/fractals.rs +++ b/src/noise_fns/generators/fractals.rs @@ -7,7 +7,7 @@ mod fbm; mod hybridmulti; mod ridgedmulti; -use crate::Seedable; +use crate::{Seed, Seedable}; /// Trait for `MultiFractal` functions pub trait MultiFractal { @@ -20,14 +20,16 @@ pub trait MultiFractal { fn set_persistence(self, persistence: f64) -> Self; } -fn build_sources(seed: u32, octaves: usize) -> Vec +fn build_sources(seed: Seed, octaves: usize) -> Vec where Source: Default + Seedable, { let mut sources = Vec::with_capacity(octaves); for x in 0..octaves { let source = Source::default(); - sources.push(source.set_seed(seed + x as u32)); + let mut seed = seed; + seed[0] += x as u8; + sources.push(source.set_seed(seed)); } sources } diff --git a/src/noise_fns/generators/fractals/basicmulti.rs b/src/noise_fns/generators/fractals/basicmulti.rs index 69d8ab62..a63a6517 100644 --- a/src/noise_fns/generators/fractals/basicmulti.rs +++ b/src/noise_fns/generators/fractals/basicmulti.rs @@ -1,6 +1,7 @@ use crate::{ math::vectors::*, - noise_fns::{MultiFractal, NoiseFn, Seedable}, + noise_fns::{MultiFractal, NoiseFn, Seedable, DEFAULT_SEED}, + Seed, }; use alloc::vec::Vec; @@ -44,7 +45,8 @@ pub struct BasicMulti { /// persistence produces "rougher" noise. pub persistence: f64, - seed: u32, + seed: Seed, + sources: Vec, scale_factor: f64, } @@ -53,14 +55,13 @@ impl BasicMulti where T: Default + Seedable, { - pub const DEFAULT_SEED: u32 = 0; pub const DEFAULT_OCTAVES: usize = 6; pub const DEFAULT_FREQUENCY: f64 = 2.0; pub const DEFAULT_LACUNARITY: f64 = core::f64::consts::PI * 2.0 / 3.0; pub const DEFAULT_PERSISTENCE: f64 = 0.5; pub const MAX_OCTAVES: usize = 32; - pub fn new(seed: u32) -> Self { + pub fn new(seed: Seed) -> Self { Self { seed, octaves: Self::DEFAULT_OCTAVES, @@ -92,7 +93,7 @@ where T: Default + Seedable, { fn default() -> Self { - Self::new(Self::DEFAULT_SEED) + Self::new(DEFAULT_SEED) } } @@ -135,7 +136,7 @@ impl Seedable for BasicMulti where T: Default + Seedable, { - fn set_seed(self, seed: u32) -> Self { + fn set_seed(self, seed: Seed) -> Self { if self.seed == seed { return self; } @@ -147,7 +148,7 @@ where } } - fn seed(&self) -> u32 { + fn seed(&self) -> Seed { self.seed } } diff --git a/src/noise_fns/generators/fractals/billow.rs b/src/noise_fns/generators/fractals/billow.rs index d72df0b3..a93288df 100644 --- a/src/noise_fns/generators/fractals/billow.rs +++ b/src/noise_fns/generators/fractals/billow.rs @@ -1,6 +1,7 @@ use crate::{ math::{scale_shift, vectors::*}, - noise_fns::{MultiFractal, NoiseFn, Seedable}, + noise_fns::{MultiFractal, NoiseFn, Seedable, DEFAULT_SEED}, + Seed, }; use alloc::vec::Vec; @@ -41,7 +42,8 @@ pub struct Billow { /// persistence produces "rougher" noise. pub persistence: f64, - seed: u32, + seed: Seed, + sources: Vec, scale_factor: f64, } @@ -50,14 +52,13 @@ impl Billow where T: Default + Seedable, { - pub const DEFAULT_SEED: u32 = 0; pub const DEFAULT_OCTAVE_COUNT: usize = 6; pub const DEFAULT_FREQUENCY: f64 = 1.0; pub const DEFAULT_LACUNARITY: f64 = core::f64::consts::PI * 2.0 / 3.0; pub const DEFAULT_PERSISTENCE: f64 = 0.5; pub const MAX_OCTAVES: usize = 32; - pub fn new(seed: u32) -> Self { + pub fn new(seed: Seed) -> Self { Self { seed, octaves: Self::DEFAULT_OCTAVE_COUNT, @@ -88,7 +89,7 @@ where T: Default + Seedable, { fn default() -> Self { - Self::new(Self::DEFAULT_SEED) + Self::new(DEFAULT_SEED) } } @@ -131,7 +132,7 @@ impl Seedable for Billow where T: Default + Seedable, { - fn set_seed(self, seed: u32) -> Self { + fn set_seed(self, seed: Seed) -> Self { if self.seed == seed { return self; } @@ -143,7 +144,7 @@ where } } - fn seed(&self) -> u32 { + fn seed(&self) -> Seed { self.seed } } diff --git a/src/noise_fns/generators/fractals/fbm.rs b/src/noise_fns/generators/fractals/fbm.rs index 12238143..2f9c0190 100644 --- a/src/noise_fns/generators/fractals/fbm.rs +++ b/src/noise_fns/generators/fractals/fbm.rs @@ -1,6 +1,7 @@ use crate::{ math::vectors::*, - noise_fns::{MultiFractal, NoiseFn, Seedable}, + noise_fns::{MultiFractal, NoiseFn, Seedable, DEFAULT_SEED}, + Seed, }; use alloc::vec::Vec; @@ -50,7 +51,7 @@ pub struct Fbm { /// persistence produces "rougher" noise. pub persistence: f64, - seed: u32, + seed: Seed, sources: Vec, scale_factor: f64, } @@ -59,14 +60,13 @@ impl Fbm where T: Default + Seedable, { - pub const DEFAULT_SEED: u32 = 0; pub const DEFAULT_OCTAVE_COUNT: usize = 6; pub const DEFAULT_FREQUENCY: f64 = 1.0; pub const DEFAULT_LACUNARITY: f64 = core::f64::consts::PI * 2.0 / 3.0; pub const DEFAULT_PERSISTENCE: f64 = 0.5; pub const MAX_OCTAVES: usize = 32; - pub fn new(seed: u32) -> Self { + pub fn new(seed: Seed) -> Self { Self { seed, octaves: Self::DEFAULT_OCTAVE_COUNT, @@ -97,7 +97,7 @@ where T: Default + Seedable, { fn default() -> Self { - Self::new(Self::DEFAULT_SEED) + Self::new(DEFAULT_SEED) } } @@ -140,7 +140,7 @@ impl Seedable for Fbm where T: Default + Seedable, { - fn set_seed(self, seed: u32) -> Self { + fn set_seed(self, seed: Seed) -> Self { if self.seed == seed { return self; } @@ -152,7 +152,7 @@ where } } - fn seed(&self) -> u32 { + fn seed(&self) -> Seed { self.seed } } diff --git a/src/noise_fns/generators/fractals/hybridmulti.rs b/src/noise_fns/generators/fractals/hybridmulti.rs index 70db30c4..82498cd3 100644 --- a/src/noise_fns/generators/fractals/hybridmulti.rs +++ b/src/noise_fns/generators/fractals/hybridmulti.rs @@ -1,6 +1,7 @@ use crate::{ math::vectors::*, - noise_fns::{MultiFractal, NoiseFn, Seedable}, + noise_fns::{MultiFractal, NoiseFn, Seedable, DEFAULT_SEED}, + Seed, }; use alloc::vec::Vec; @@ -38,7 +39,7 @@ pub struct HybridMulti { /// persistence produces "rougher" noise. pub persistence: f64, - seed: u32, + seed: Seed, sources: Vec, scale_factor: f64, } @@ -47,14 +48,13 @@ impl HybridMulti where T: Default + Seedable, { - pub const DEFAULT_SEED: u32 = 0; pub const DEFAULT_OCTAVES: usize = 6; pub const DEFAULT_FREQUENCY: f64 = 2.0; pub const DEFAULT_LACUNARITY: f64 = core::f64::consts::PI * 2.0 / 3.0; pub const DEFAULT_PERSISTENCE: f64 = 0.25; pub const MAX_OCTAVES: usize = 32; - pub fn new(seed: u32) -> Self { + pub fn new(seed: Seed) -> Self { Self { seed, octaves: Self::DEFAULT_OCTAVES, @@ -100,7 +100,7 @@ where T: Default + Seedable, { fn default() -> Self { - Self::new(Self::DEFAULT_SEED) + Self::new(DEFAULT_SEED) } } @@ -143,7 +143,7 @@ impl Seedable for HybridMulti where T: Default + Seedable, { - fn set_seed(self, seed: u32) -> Self { + fn set_seed(self, seed: Seed) -> Self { if self.seed == seed { return self; } @@ -155,7 +155,7 @@ where } } - fn seed(&self) -> u32 { + fn seed(&self) -> Seed { self.seed } } diff --git a/src/noise_fns/generators/fractals/ridgedmulti.rs b/src/noise_fns/generators/fractals/ridgedmulti.rs index 158be7fc..e816ff4e 100644 --- a/src/noise_fns/generators/fractals/ridgedmulti.rs +++ b/src/noise_fns/generators/fractals/ridgedmulti.rs @@ -1,6 +1,7 @@ use crate::{ math::vectors::*, - noise_fns::{MultiFractal, NoiseFn, Seedable}, + noise_fns::{MultiFractal, NoiseFn, Seedable, DEFAULT_SEED}, + Seed, }; use alloc::vec::Vec; @@ -56,7 +57,8 @@ pub struct RidgedMulti { /// half the height of the previous. pub attenuation: f64, - seed: u32, + seed: Seed, + sources: Vec, scale_factor: f64, } @@ -65,7 +67,6 @@ impl RidgedMulti where T: Default + Seedable, { - pub const DEFAULT_SEED: u32 = 0; pub const DEFAULT_OCTAVE_COUNT: usize = 6; pub const DEFAULT_FREQUENCY: f64 = 1.0; pub const DEFAULT_LACUNARITY: f64 = core::f64::consts::PI * 2.0 / 3.0; @@ -73,7 +74,7 @@ where pub const DEFAULT_ATTENUATION: f64 = 2.0; pub const MAX_OCTAVES: usize = 32; - pub fn new(seed: u32) -> Self { + pub fn new(seed: Seed) -> Self { Self { seed, octaves: Self::DEFAULT_OCTAVE_COUNT, @@ -130,7 +131,7 @@ where T: Default + Seedable, { fn default() -> Self { - Self::new(Self::DEFAULT_SEED) + Self::new(DEFAULT_SEED) } } @@ -173,7 +174,7 @@ impl Seedable for RidgedMulti where T: Default + Seedable, { - fn set_seed(self, seed: u32) -> Self { + fn set_seed(self, seed: Seed) -> Self { if self.seed == seed { return self; } @@ -185,7 +186,7 @@ where } } - fn seed(&self) -> u32 { + fn seed(&self) -> Seed { self.seed } } diff --git a/src/noise_fns/generators/open_simplex.rs b/src/noise_fns/generators/open_simplex.rs index 83ed222a..f6dc9406 100644 --- a/src/noise_fns/generators/open_simplex.rs +++ b/src/noise_fns/generators/open_simplex.rs @@ -2,52 +2,53 @@ //! Instead, these functions use the `OpenSimplex` algorithm, as detailed here: //! +use rand::{Rng, SeedableRng}; +use rand_xorshift::XorShiftRng; + use crate::{ core::open_simplex::{open_simplex_2d, open_simplex_3d, open_simplex_4d}, - noise_fns::{NoiseFn, Seedable}, + noise_fns::{NoiseFn, Seedable, DEFAULT_SEED}, permutationtable::PermutationTable, + Seed, }; /// Noise function that outputs 2/3/4-dimensional Open Simplex noise. #[derive(Clone, Copy, Debug)] pub struct OpenSimplex { - seed: u32, + seed: Seed, perm_table: PermutationTable, } impl OpenSimplex { - const DEFAULT_SEED: u32 = 0; + pub fn new(seed: Seed) -> Self { + let mut rng = XorShiftRng::from_seed(seed); - pub fn new(seed: u32) -> Self { Self { seed, - perm_table: PermutationTable::new(seed), + perm_table: rng.gen(), } } } impl Default for OpenSimplex { fn default() -> Self { - Self::new(Self::DEFAULT_SEED) + Self::new(DEFAULT_SEED) } } impl Seedable for OpenSimplex { /// Sets the seed value for Open Simplex noise - fn set_seed(self, seed: u32) -> Self { + fn set_seed(self, seed: Seed) -> Self { // If the new seed is the same as the current seed, just return self. if self.seed == seed { return self; } // Otherwise, regenerate the permutation table based on the new seed. - Self { - seed, - perm_table: PermutationTable::new(seed), - } + Self::new(seed) } - fn seed(&self) -> u32 { + fn seed(&self) -> Seed { self.seed } } diff --git a/src/noise_fns/generators/perlin.rs b/src/noise_fns/generators/perlin.rs index 0904107e..76bf27a3 100644 --- a/src/noise_fns/generators/perlin.rs +++ b/src/noise_fns/generators/perlin.rs @@ -1,49 +1,57 @@ +use rand::{Rng, SeedableRng}; +use rand_xorshift::XorShiftRng; + use crate::{ core::perlin::*, - noise_fns::{NoiseFn, Seedable}, + noise_fns::{NoiseFn, Seedable, DEFAULT_SEED}, permutationtable::PermutationTable, + Seed, }; /// Noise function that outputs 1/2/3/4-dimensional Perlin noise. #[derive(Clone, Copy, Debug)] pub struct Perlin { - seed: u32, + seed: Seed, perm_table: PermutationTable, } impl Perlin { pub const DEFAULT_SEED: u32 = 0; - pub fn new(seed: u32) -> Self { + pub fn new(seed: Seed) -> Self { + let mut rng = XorShiftRng::from_seed(seed); + Self { seed, - perm_table: PermutationTable::new(seed), + perm_table: rng.gen(), } } } impl Default for Perlin { fn default() -> Self { - Self::new(Self::DEFAULT_SEED) + Self::new(DEFAULT_SEED) } } impl Seedable for Perlin { /// Sets the seed value for Perlin noise - fn set_seed(self, seed: u32) -> Self { + fn set_seed(self, seed: Seed) -> Self { // If the new seed is the same as the current seed, just return self. if self.seed == seed { return self; } // Otherwise, regenerate the permutation table based on the new seed. + let mut rng = XorShiftRng::from_seed(seed); + Self { seed, - perm_table: PermutationTable::new(seed), + perm_table: rng.gen(), } } - fn seed(&self) -> u32 { + fn seed(&self) -> Seed { self.seed } } diff --git a/src/noise_fns/generators/perlin_surflet.rs b/src/noise_fns/generators/perlin_surflet.rs index d0c946d1..591c0550 100644 --- a/src/noise_fns/generators/perlin_surflet.rs +++ b/src/noise_fns/generators/perlin_surflet.rs @@ -1,7 +1,11 @@ +use rand::{Rng, SeedableRng}; +use rand_xorshift::XorShiftRng; + use crate::{ core::perlin_surflet::*, - noise_fns::{NoiseFn, Seedable}, + noise_fns::{NoiseFn, Seedable, DEFAULT_SEED}, permutationtable::PermutationTable, + Seed, }; /// Noise function that outputs 2/3/4-dimensional Perlin noise. @@ -10,43 +14,40 @@ use crate::{ /// calculate the values at a point using wavelets instead of interpolated gradients. #[derive(Clone, Copy, Debug)] pub struct PerlinSurflet { - seed: u32, + seed: Seed, perm_table: PermutationTable, } impl PerlinSurflet { - pub const DEFAULT_SEED: u32 = 0; + pub fn new(seed: Seed) -> Self { + let mut rng = XorShiftRng::from_seed(seed); - pub fn new(seed: u32) -> Self { Self { seed, - perm_table: PermutationTable::new(seed), + perm_table: rng.gen(), } } } impl Default for PerlinSurflet { fn default() -> Self { - Self::new(Self::DEFAULT_SEED) + Self::new(DEFAULT_SEED) } } impl Seedable for PerlinSurflet { /// Sets the seed value for Perlin noise - fn set_seed(self, seed: u32) -> Self { + fn set_seed(self, seed: Seed) -> Self { // If the new seed is the same as the current seed, just return self. if self.seed == seed { return self; } // Otherwise, regenerate the permutation table based on the new seed. - Self { - seed, - perm_table: PermutationTable::new(seed), - } + Self::new(seed) } - fn seed(&self) -> u32 { + fn seed(&self) -> Seed { self.seed } } diff --git a/src/noise_fns/generators/simplex.rs b/src/noise_fns/generators/simplex.rs index 61a5194e..ef5aee94 100644 --- a/src/noise_fns/generators/simplex.rs +++ b/src/noise_fns/generators/simplex.rs @@ -1,50 +1,51 @@ +use rand::{Rng, SeedableRng}; +use rand_xorshift::XorShiftRng; + use crate::{ core::simplex::*, - noise_fns::{NoiseFn, Seedable}, + noise_fns::{NoiseFn, Seedable, DEFAULT_SEED}, permutationtable::PermutationTable, + Seed, }; /// Noise function that outputs N-dimensional Simplex noise. /// #[derive(Clone, Copy, Debug)] pub struct Simplex { - seed: u32, + seed: Seed, hasher: PermutationTable, } impl Simplex { - pub const DEFAULT_SEED: u32 = 0; + pub fn new(seed: Seed) -> Self { + let mut rng = XorShiftRng::from_seed(seed); - pub fn new(seed: u32) -> Self { Simplex { seed, - hasher: PermutationTable::new(seed), + hasher: rng.gen(), } } } impl Default for Simplex { fn default() -> Self { - Self::new(Self::DEFAULT_SEED) + Self::new(DEFAULT_SEED) } } impl Seedable for Simplex { /// Sets the seed value for Simplex noise - fn set_seed(self, seed: u32) -> Self { + fn set_seed(self, seed: Seed) -> Self { // If the new seed is the same as the current seed, just return self. if self.seed == seed { return self; } // Otherwise, regenerate the permutation table based on the new seed. - Simplex { - seed, - hasher: PermutationTable::new(seed), - } + Simplex::new(seed) } - fn seed(&self) -> u32 { + fn seed(&self) -> Seed { self.seed } } diff --git a/src/noise_fns/generators/super_simplex.rs b/src/noise_fns/generators/super_simplex.rs index f265148f..3def0322 100644 --- a/src/noise_fns/generators/super_simplex.rs +++ b/src/noise_fns/generators/super_simplex.rs @@ -1,49 +1,49 @@ +use rand::{Rng, SeedableRng}; +use rand_xorshift::XorShiftRng; + use crate::{ core::super_simplex::*, - noise_fns::{NoiseFn, Seedable}, + noise_fns::{NoiseFn, Seedable, DEFAULT_SEED}, permutationtable::PermutationTable, + Seed, }; /// Noise function that outputs 2/3-dimensional Super Simplex noise. #[derive(Clone, Copy, Debug)] pub struct SuperSimplex { - seed: u32, + seed: Seed, perm_table: PermutationTable, } impl SuperSimplex { - pub const DEFAULT_SEED: u32 = 0; - - pub fn new(seed: u32) -> Self { + pub fn new(seed: Seed) -> Self { + let mut rng = XorShiftRng::from_seed(seed); Self { seed, - perm_table: PermutationTable::new(seed), + perm_table: rng.gen(), } } } impl Default for SuperSimplex { fn default() -> Self { - Self::new(Self::DEFAULT_SEED) + Self::new(DEFAULT_SEED) } } impl Seedable for SuperSimplex { /// Sets the seed value for Super Simplex noise - fn set_seed(self, seed: u32) -> Self { + fn set_seed(self, seed: Seed) -> Self { // If the new seed is the same as the current seed, just return self. if self.seed == seed { return self; } // Otherwise, regenerate the permutation table based on the new seed. - Self { - seed, - perm_table: PermutationTable::new(seed), - } + Self::new(seed) } - fn seed(&self) -> u32 { + fn seed(&self) -> Seed { self.seed } } diff --git a/src/noise_fns/generators/value.rs b/src/noise_fns/generators/value.rs index 8d401bfc..474b4197 100644 --- a/src/noise_fns/generators/value.rs +++ b/src/noise_fns/generators/value.rs @@ -1,49 +1,50 @@ +use rand::{Rng, SeedableRng}; +use rand_xorshift::XorShiftRng; + use crate::{ core::value::{value_2d, value_3d, value_4d}, - noise_fns::{NoiseFn, Seedable}, + noise_fns::{NoiseFn, Seedable, DEFAULT_SEED}, permutationtable::PermutationTable, + Seed, }; /// Noise function that outputs 2/3/4-dimensional Value noise. #[derive(Clone, Copy, Debug)] pub struct Value { - seed: u32, + seed: Seed, perm_table: PermutationTable, } impl Value { - pub const DEFAULT_SEED: u32 = 0; + pub fn new(seed: Seed) -> Self { + let mut rng = XorShiftRng::from_seed(seed); - pub fn new(seed: u32) -> Self { Self { seed, - perm_table: PermutationTable::new(seed), + perm_table: rng.gen(), } } } impl Default for Value { fn default() -> Self { - Self::new(Self::DEFAULT_SEED) + Self::new(DEFAULT_SEED) } } impl Seedable for Value { /// Sets the seed value for Value noise - fn set_seed(self, seed: u32) -> Self { + fn set_seed(self, seed: Seed) -> Self { // If the new seed is the same as the current seed, just return self. if self.seed == seed { return self; } // Otherwise, regenerate the permutation table based on the new seed. - Self { - seed, - perm_table: PermutationTable::new(seed), - } + Self::new(seed) } - fn seed(&self) -> u32 { + fn seed(&self) -> Seed { self.seed } } diff --git a/src/noise_fns/generators/worley.rs b/src/noise_fns/generators/worley.rs index be7589f1..a33d25ee 100644 --- a/src/noise_fns/generators/worley.rs +++ b/src/noise_fns/generators/worley.rs @@ -1,10 +1,13 @@ use crate::{ core::worley::*, math::vectors::*, - noise_fns::{NoiseFn, Seedable}, + noise_fns::{NoiseFn, Seedable, DEFAULT_SEED}, permutationtable::PermutationTable, + Seed, }; use alloc::rc::Rc; +use rand::{Rng, SeedableRng}; +use rand_xorshift::XorShiftRng; /// Noise function that outputs Worley noise. #[derive(Clone)] @@ -20,19 +23,20 @@ pub struct Worley { /// Frequency of the seed points. pub frequency: f64, - seed: u32, + seed: Seed, perm_table: PermutationTable, } type DistanceFunction = dyn Fn(&[f64], &[f64]) -> f64; impl Worley { - pub const DEFAULT_SEED: u32 = 0; pub const DEFAULT_FREQUENCY: f64 = 1.0; - pub fn new(seed: u32) -> Self { + pub fn new(seed: Seed) -> Self { + let mut rng = XorShiftRng::from_seed(seed); + Self { - perm_table: PermutationTable::new(seed), + perm_table: rng.gen(), seed, distance_function: Rc::new(distance_functions::euclidean), return_type: ReturnType::Value, @@ -68,27 +72,29 @@ impl Worley { impl Default for Worley { fn default() -> Self { - Self::new(0) + Self::new(DEFAULT_SEED) } } impl Seedable for Worley { /// Sets the seed value used by the Worley cells. - fn set_seed(self, seed: u32) -> Self { + fn set_seed(self, seed: Seed) -> Self { // If the new seed is the same as the current seed, just return self. if self.seed == seed { return self; } // Otherwise, regenerate the permutation table based on the new seed. + let mut rng = XorShiftRng::from_seed(seed); + Self { - perm_table: PermutationTable::new(seed), + perm_table: rng.gen(), seed, ..self } } - fn seed(&self) -> u32 { + fn seed(&self) -> Seed { self.seed } } diff --git a/src/noise_fns/transformers/turbulence.rs b/src/noise_fns/transformers/turbulence.rs index 0d6d16ce..a61cf582 100644 --- a/src/noise_fns/transformers/turbulence.rs +++ b/src/noise_fns/transformers/turbulence.rs @@ -1,4 +1,10 @@ -use crate::noise_fns::{Fbm, MultiFractal, NoiseFn, Seedable}; +use rand::{Rng, SeedableRng}; +use rand_xorshift::XorShiftRng; + +use crate::{ + noise_fns::{Fbm, MultiFractal, NoiseFn, Seedable, DEFAULT_SEED}, + Seed, +}; /// Noise function that randomly displaces the input value before returning the /// output value from the source function. @@ -26,7 +32,8 @@ where /// Affects the roughness of the turbulence. Higher values are rougher. pub roughness: usize, - seed: u32, + seed: Seed, + x_distort_function: Fbm, y_distort_function: Fbm, z_distort_function: Fbm, @@ -37,32 +44,37 @@ impl Turbulence where F: Default + Seedable, { - pub const DEFAULT_SEED: u32 = 0; pub const DEFAULT_FREQUENCY: f64 = 1.0; pub const DEFAULT_POWER: f64 = 1.0; pub const DEFAULT_ROUGHNESS: usize = 3; pub fn new(source: Source) -> Self { + Self::new_with_seed(source, DEFAULT_SEED) + } + + pub fn new_with_seed(source: Source, seed: Seed) -> Self { + let mut rng = XorShiftRng::from_seed(seed); + Self { source, - seed: Self::DEFAULT_SEED, + seed: DEFAULT_SEED, frequency: Self::DEFAULT_FREQUENCY, power: Self::DEFAULT_POWER, roughness: Self::DEFAULT_ROUGHNESS, x_distort_function: Fbm::default() - .set_seed(Self::DEFAULT_SEED) + .set_seed(rng.gen()) .set_octaves(Self::DEFAULT_ROUGHNESS) .set_frequency(Self::DEFAULT_FREQUENCY), y_distort_function: Fbm::default() - .set_seed(Self::DEFAULT_SEED + 1) + .set_seed(rng.gen()) .set_octaves(Self::DEFAULT_ROUGHNESS) .set_frequency(Self::DEFAULT_FREQUENCY), z_distort_function: Fbm::default() - .set_seed(Self::DEFAULT_SEED + 2) + .set_seed(rng.gen()) .set_octaves(Self::DEFAULT_ROUGHNESS) .set_frequency(Self::DEFAULT_FREQUENCY), u_distort_function: Fbm::default() - .set_seed(Self::DEFAULT_SEED + 3) + .set_seed(rng.gen()) .set_octaves(Self::DEFAULT_ROUGHNESS) .set_frequency(Self::DEFAULT_FREQUENCY), } @@ -99,18 +111,20 @@ impl Seedable for Turbulence where F: Default + Seedable, { - fn set_seed(self, seed: u32) -> Self { + fn set_seed(self, seed: Seed) -> Self { + let mut rng = XorShiftRng::from_seed(seed); + Self { seed, - x_distort_function: self.x_distort_function.set_seed(seed), - y_distort_function: self.y_distort_function.set_seed(seed + 1), - z_distort_function: self.z_distort_function.set_seed(seed + 2), - u_distort_function: self.u_distort_function.set_seed(seed + 3), + x_distort_function: self.x_distort_function.set_seed(rng.gen()), + y_distort_function: self.y_distort_function.set_seed(rng.gen()), + z_distort_function: self.z_distort_function.set_seed(rng.gen()), + u_distort_function: self.u_distort_function.set_seed(rng.gen()), ..self } } - fn seed(&self) -> u32 { + fn seed(&self) -> Seed { self.seed } }