#![cfg_attr(
feature = "document-features",
cfg_attr(doc, doc = ::document_features::document_features!())
)]
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(feature = "nightly-simd", feature(portable_simd))]
#![cfg_attr(feature = "nightly-const-fn-float", feature(const_fn_floating_point_arithmetic))]
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg_hide), doc(cfg_hide(no_global_oom_handling, feature = "nightly-const-fn-float")))]
#![allow(clippy::excessive_precision, clippy::needless_late_init, clippy::too_many_arguments)]
#[cfg(all(not(feature = "std"), not(feature = "libm")))]
compile_error!(r#"`noise-functions` crate: either the "std" or "libm" feature must be enabled"#);
#[cfg(feature = "alloc")]
extern crate alloc;
pub mod cellular;
pub mod fractal;
mod frequency;
mod lookup;
mod math;
mod noise_fn;
pub mod open_simplex_2;
mod sample;
mod scalar;
mod seeded;
#[cfg(feature = "nightly-simd")]
mod simd;
mod util;
#[doc(inline)]
pub use cellular::{CellDistance, CellDistanceSq, CellValue};
pub use frequency::Frequency;
pub use noise_fn::NoiseFn;
#[doc(inline)]
pub use open_simplex_2::{OpenSimplex2, OpenSimplex2s};
pub use sample::{Sample, Sample2, Sample3};
pub use seeded::Seeded;
#[cfg(feature = "nightly-simd")]
pub use sample::{Sample2a, Sample3a};
mod private_prelude {
pub(crate) use crate::fractal::*;
pub(crate) use crate::lookup::*;
pub(crate) use crate::math::*;
pub(crate) use crate::util::*;
pub(crate) use crate::*;
#[cfg(test)]
pub(crate) use crate::open_simplex_2::*;
#[cfg(test)]
pub(crate) use crate::cellular::*;
#[cfg(feature = "nightly-simd")]
pub(crate) use crate::simd::{PRIME_XY, PRIME_XYZ};
#[cfg(feature = "nightly-simd")]
pub(crate) use core::simd::{LaneCount, SimdElement, SupportedLaneCount};
#[cfg(feature = "nightly-simd")]
pub(crate) use core::simd::prelude::*;
#[cfg(feature = "nightly-simd")]
pub(crate) use core::simd::num::SimdFloat;
#[cfg(feature = "nightly-simd")]
pub(crate) use crate::simd::splat;
}
use crate::private_prelude::*;
const DEFAULT_JITTER_2D: f32 = 0.43701595;
const DEFAULT_JITTER_3D: f32 = 0.39614353;
macro_rules! impl_modifiers {
() => {
#[inline(always)]
pub const fn seed(self, seed: i32) -> Seeded<Self> {
Seeded { noise: self, seed }
}
#[inline(always)]
pub const fn frequency(self, frequency: f32) -> Frequency<Self> {
Frequency { noise: self, frequency }
}
cfg_const_feature_float! {
#[inline(always)]
pub fn fbm(self, octaves: u32, gain: f32, lacunarity: f32) -> Fbm<Self> {
Fbm {
noise: self,
octaves,
gain,
lacunarity,
fractal_bounding: fractal_bounding(octaves, gain),
}
}
}
cfg_const_feature_float! {
#[inline(always)]
pub fn ridged(self, octaves: u32, gain: f32, lacunarity: f32) -> Ridged<Self> {
Ridged {
noise: self,
octaves,
gain,
lacunarity,
fractal_bounding: fractal_bounding(octaves, gain),
}
}
}
cfg_const_feature_float! {
#[inline(always)]
pub fn ping_pong(self, octaves: u32, gain: f32, lacunarity: f32, strength: f32) -> PingPong<Self> {
PingPong {
noise: self,
octaves,
gain,
lacunarity,
fractal_bounding: fractal_bounding(octaves, gain),
strength,
}
}
}
};
}
pub(crate) use impl_modifiers;
macro_rules! cfg_const {
(
#[cfg_const($($tt:tt)*)]
$(#[$attr:meta])*
$vis:vis fn $ident:ident($($params:tt)*) $(-> $result:ty)? $body:block
) => {
#[cfg($($tt)*)]
$(#[$attr])*
$vis const fn $ident($($params)*) $(-> $result)? $body
#[cfg(not($($tt)*))]
$(#[$attr])*
$vis fn $ident($($params)*) $(-> $result)? $body
};
}
macro_rules! cfg_const_feature {
(
#[cfg_const_feature($feature:literal)]
$(#[$attr:meta])*
$vis:vis fn $ident:ident($($params:tt)*) $(-> $result:ty)? $body:block
) => {
$crate::cfg_const! {
#[cfg_const(feature = $feature)]
$(#[$attr])*
#[doc = concat!("*This function is `const` if the feature `", $feature, "` is enabled.*")]
$vis fn $ident($($params)*) $(-> $result)? $body
}
};
}
macro_rules! cfg_const_feature_float {
(
$(#[$attr:meta])*
$vis:vis fn $ident:ident($($params:tt)*) $(-> $result:ty)? $body:block
) => {
$crate::cfg_const_feature! {
#[cfg_const_feature("nightly-const-fn-float")]
$(#[$attr])*
$vis fn $ident($($params)*) $(-> $result)? $body
}
};
}
pub(crate) use cfg_const;
pub(crate) use cfg_const_feature;
pub(crate) use cfg_const_feature_float;
macro_rules! basic_noise {
($(#[$attr:meta])* $noise:ident in $noise_mod:ident) => {
$(#[$attr])*
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct $noise;
impl $noise {
impl_modifiers!();
}
impl Sample<2> for $noise {
#[inline(always)]
fn sample(&self, point: [f32; 2]) -> f32 {
crate::scalar::$noise_mod::gen2(point, 0)
}
}
impl Sample<2> for Seeded<$noise> {
#[inline(always)]
fn sample(&self, point: [f32; 2]) -> f32 {
crate::scalar::$noise_mod::gen2(point, self.seed)
}
}
impl Sample<2> for Seeded<&$noise> {
#[inline(always)]
fn sample(&self, point: [f32; 2]) -> f32 {
crate::scalar::$noise_mod::gen2(point, self.seed)
}
}
impl Sample<3> for $noise {
#[inline(always)]
fn sample(&self, point: [f32; 3]) -> f32 {
crate::scalar::$noise_mod::gen3(point, 0)
}
}
impl Sample<3> for Seeded<$noise> {
#[inline(always)]
fn sample(&self, point: [f32; 3]) -> f32 {
crate::scalar::$noise_mod::gen3(point, self.seed)
}
}
impl Sample<3> for Seeded<&$noise> {
#[inline(always)]
fn sample(&self, point: [f32; 3]) -> f32 {
crate::scalar::$noise_mod::gen3(point, self.seed)
}
}
#[cfg(feature = "nightly-simd")]
impl Sample<2, f32x2> for $noise {
#[inline(always)]
fn sample(&self, point: f32x2) -> f32 {
crate::simd::$noise_mod::gen2(point, 0)
}
}
#[cfg(feature = "nightly-simd")]
impl Sample<2, f32x2> for Seeded<$noise> {
#[inline(always)]
fn sample(&self, point: f32x2) -> f32 {
crate::simd::$noise_mod::gen2(point, self.seed)
}
}
#[cfg(feature = "nightly-simd")]
impl Sample<2, f32x2> for Seeded<&$noise> {
#[inline(always)]
fn sample(&self, point: f32x2) -> f32 {
crate::simd::$noise_mod::gen2(point, self.seed)
}
}
#[cfg(feature = "nightly-simd")]
impl Sample<3, f32x4> for $noise {
#[inline(always)]
fn sample(&self, point: f32x4) -> f32 {
crate::simd::$noise_mod::gen3(point, 0)
}
}
#[cfg(feature = "nightly-simd")]
impl Sample<3, f32x4> for Seeded<$noise> {
#[inline(always)]
fn sample(&self, point: f32x4) -> f32 {
crate::simd::$noise_mod::gen3(point, self.seed)
}
}
#[cfg(feature = "nightly-simd")]
impl Sample<3, f32x4> for Seeded<&$noise> {
#[inline(always)]
fn sample(&self, point: f32x4) -> f32 {
crate::simd::$noise_mod::gen3(point, self.seed)
}
}
};
}
pub(crate) use basic_noise;
basic_noise! {
Perlin in perlin
}
basic_noise! {
Value in value
}
basic_noise! {
ValueCubic in value_cubic
}
#[cfg(test)]
mod tests;