#![cfg_attr(not(test), no_std)]
#![allow(
clippy::doc_markdown,
reason = "These rules should not apply to the readme."
)]
#![doc = include_str!("../README.md")]
pub mod cell_noise;
pub mod cells;
pub mod curves;
pub mod layering;
pub mod lengths;
pub mod math_noise;
pub mod misc_noise;
pub mod prelude;
pub mod rng;
use bevy_math::VectorSpace;
use rng::NoiseRng;
pub trait NoiseFunction<I> {
type Output;
fn evaluate(&self, input: I, seeds: &mut NoiseRng) -> Self::Output;
}
impl<I, T0: NoiseFunction<I>> NoiseFunction<I> for (T0,) {
type Output = T0::Output;
#[inline]
fn evaluate(&self, input: I, seeds: &mut NoiseRng) -> Self::Output {
self.0.evaluate(input, seeds)
}
}
macro_rules! impl_noise_function_tuple {
($($l:ident-$t:ident-$i:tt),*) => {
impl<
I,
T0: NoiseFunction<I>,
$($t: NoiseFunction<$l::Output>,)*
> NoiseFunction<I> for (T0, $($t,)*)
{
type Output = <impl_noise_function_tuple!(last $($t),*)>::Output;
#[inline]
fn evaluate(&self, input: I, seeds: &mut NoiseRng) -> Self::Output {
let input = self.0.evaluate(input, seeds);
$(let input = self.$i.evaluate(input, seeds);)*
input
}
}
};
(last $f:ident $(,)? ) => {
$f
};
(last $f:ident, $($items:ident),+ $(,)?) => {
impl_noise_function_tuple!(last $($items),+)
};
}
#[rustfmt::skip]
mod function_impls {
use super::*;
impl_noise_function_tuple!(T0-T1-1);
impl_noise_function_tuple!(T0-T1-1, T1-T2-2);
impl_noise_function_tuple!(T0-T1-1, T1-T2-2, T2-T3-3);
impl_noise_function_tuple!(T0-T1-1, T1-T2-2, T2-T3-3, T3-T4-4);
impl_noise_function_tuple!(T0-T1-1, T1-T2-2, T2-T3-3, T3-T4-4, T4-T5-5);
impl_noise_function_tuple!(T0-T1-1, T1-T2-2, T2-T3-3, T3-T4-4, T4-T5-5, T5-T6-6);
impl_noise_function_tuple!(T0-T1-1, T1-T2-2, T2-T3-3, T3-T4-4, T4-T5-5, T5-T6-6, T6-T7-7);
impl_noise_function_tuple!(T0-T1-1, T1-T2-2, T2-T3-3, T3-T4-4, T4-T5-5, T5-T6-6, T6-T7-7, T7-T8-8);
impl_noise_function_tuple!(T0-T1-1, T1-T2-2, T2-T3-3, T3-T4-4, T4-T5-5, T5-T6-6, T6-T7-7, T7-T8-8, T8-T9-9);
impl_noise_function_tuple!(T0-T1-1, T1-T2-2, T2-T3-3, T3-T4-4, T4-T5-5, T5-T6-6, T6-T7-7, T7-T8-8, T8-T9-9, T9-T10-10);
impl_noise_function_tuple!(T0-T1-1, T1-T2-2, T2-T3-3, T3-T4-4, T4-T5-5, T5-T6-6, T6-T7-7, T7-T8-8, T8-T9-9, T9-T10-10, T10-T11-11);
impl_noise_function_tuple!(T0-T1-1, T1-T2-2, T2-T3-3, T3-T4-4, T4-T5-5, T5-T6-6, T6-T7-7, T7-T8-8, T8-T9-9, T9-T10-10, T10-T11-11, T11-T12-12);
impl_noise_function_tuple!(T0-T1-1, T1-T2-2, T2-T3-3, T3-T4-4, T4-T5-5, T5-T6-6, T6-T7-7, T7-T8-8, T8-T9-9, T9-T10-10, T10-T11-11, T11-T12-12, T12-T13-13);
impl_noise_function_tuple!(T0-T1-1, T1-T2-2, T2-T3-3, T3-T4-4, T4-T5-5, T5-T6-6, T6-T7-7, T7-T8-8, T8-T9-9, T9-T10-10, T10-T11-11, T11-T12-12, T12-T13-13, T13-T14-14);
impl_noise_function_tuple!(T0-T1-1, T1-T2-2, T2-T3-3, T3-T4-4, T4-T5-5, T5-T6-6, T6-T7-7, T7-T8-8, T8-T9-9, T9-T10-10, T10-T11-11, T11-T12-12, T12-T13-13, T13-T14-14, T14-T15-15);
}
pub trait SeedableNoise {
fn set_seed(&mut self, seed: u32);
fn get_seed(&self) -> u32;
}
pub trait ScalableNoise {
fn set_frequency(&mut self, frequency: f32);
fn get_frequency(&self) -> f32;
fn set_period(&mut self, period: f32) {
self.set_frequency(1.0 / period);
}
fn get_period(&self) -> f32 {
1.0 / self.get_frequency()
}
}
pub trait Sampleable<I> {
type Result;
fn sample_raw(&self, loc: I) -> (Self::Result, NoiseRng);
#[inline]
fn sample_for<T>(&self, loc: I) -> T
where
Self: SampleableFor<I, T>,
{
self.sample(loc)
}
#[inline]
fn sample_dyn_for<T>(&self, loc: I) -> T
where
Self: DynamicSampleable<I, T>,
{
self.sample_dyn(loc)
}
}
pub trait SampleableFor<I, T> {
fn sample(&self, loc: I) -> T;
}
pub trait DynamicSampleable<I, T>: SampleableFor<I, T> {
fn sample_dyn(&self, loc: I) -> T {
self.sample(loc)
}
}
impl<T, I, N> DynamicSampleable<I, T> for N where N: SampleableFor<I, T> + Sampleable<I> {}
pub trait DynamicConfigurableSampleable<I, T>:
SeedableNoise + ScalableNoise + DynamicSampleable<I, T>
{
}
impl<I, T, N: SeedableNoise + ScalableNoise + DynamicSampleable<I, T>>
DynamicConfigurableSampleable<I, T> for N
{
}
#[derive(PartialEq, Clone, Copy)]
#[cfg_attr(feature = "bevy_reflect", derive(bevy_reflect::Reflect))]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
#[cfg_attr(feature = "debug", derive(Debug))]
pub struct Noise<N> {
pub noise: N,
pub seed: NoiseRng,
pub frequency: f32,
}
impl<N: Default> Default for Noise<N> {
fn default() -> Self {
Self {
noise: N::default(),
seed: NoiseRng(0),
frequency: 1.0,
}
}
}
impl<N> From<N> for Noise<N> {
fn from(value: N) -> Self {
Self {
noise: value,
seed: NoiseRng(0),
frequency: 1.0,
}
}
}
impl<I: VectorSpace<Scalar = f32>, N: NoiseFunction<I>> NoiseFunction<I> for Noise<N> {
type Output = N::Output;
#[inline]
fn evaluate(&self, input: I, seeds: &mut NoiseRng) -> Self::Output {
seeds.0 ^= self.seed.0;
self.noise.evaluate(input * self.frequency, seeds)
}
}
impl<N> ScalableNoise for Noise<N> {
fn set_frequency(&mut self, frequency: f32) {
self.frequency = frequency;
}
fn get_frequency(&self) -> f32 {
self.frequency
}
}
impl<N> SeedableNoise for Noise<N> {
fn set_seed(&mut self, seed: u32) {
self.seed = NoiseRng(seed);
}
fn get_seed(&self) -> u32 {
self.seed.0
}
}
impl<I: VectorSpace<Scalar = f32>, N: NoiseFunction<I>> Sampleable<I> for Noise<N> {
type Result = N::Output;
#[inline]
fn sample_raw(&self, loc: I) -> (Self::Result, NoiseRng) {
let mut seeds = self.seed;
let result = self.noise.evaluate(loc * self.frequency, &mut seeds);
(result, seeds)
}
}
impl<T, I: VectorSpace<Scalar = f32>, N: NoiseFunction<I, Output: Into<T>>> SampleableFor<I, T>
for Noise<N>
{
#[inline]
fn sample(&self, loc: I) -> T {
let (result, _rng) = self.sample_raw(loc);
result.into()
}
}
#[derive(PartialEq, Clone, Copy)]
#[cfg_attr(feature = "bevy_reflect", derive(bevy_reflect::Reflect))]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
#[cfg_attr(feature = "debug", derive(Debug))]
pub struct RawNoise<N> {
pub noise: N,
pub seed: NoiseRng,
}
impl<N: Default> Default for RawNoise<N> {
fn default() -> Self {
Self {
noise: N::default(),
seed: NoiseRng(0),
}
}
}
impl<N> From<N> for RawNoise<N> {
fn from(value: N) -> Self {
Self {
noise: value,
seed: NoiseRng(0),
}
}
}
impl<I, N: NoiseFunction<I>> NoiseFunction<I> for RawNoise<N> {
type Output = N::Output;
#[inline]
fn evaluate(&self, input: I, seeds: &mut NoiseRng) -> Self::Output {
seeds.0 ^= self.seed.0;
self.noise.evaluate(input, seeds)
}
}
impl<N> SeedableNoise for RawNoise<N> {
fn set_seed(&mut self, seed: u32) {
self.seed = NoiseRng(seed);
}
fn get_seed(&self) -> u32 {
self.seed.0
}
}
impl<I, N: NoiseFunction<I>> Sampleable<I> for RawNoise<N> {
type Result = N::Output;
#[inline]
fn sample_raw(&self, loc: I) -> (Self::Result, NoiseRng) {
let mut seeds = self.seed;
let result = self.noise.evaluate(loc, &mut seeds);
(result, seeds)
}
}
impl<T, I, N: NoiseFunction<I, Output: Into<T>>> SampleableFor<I, T> for RawNoise<N> {
#[inline]
fn sample(&self, loc: I) -> T {
let (result, _rng) = self.sample_raw(loc);
result.into()
}
}