use noise::NoiseFn;
use num_traits::{AsPrimitive, ToPrimitive};
pub mod curl;
pub mod gabor;
pub mod img_noise;
pub mod sinusoid;
pub mod white;
pub use curl::*;
pub use gabor::*;
pub use img_noise::*;
pub use sinusoid::*;
pub use white::*;
#[derive(Debug, Clone, Copy)]
pub struct NoiseOpts {
pub width: f32,
pub height: f32,
pub x_scale: f32,
pub y_scale: f32,
pub z_scale: f32,
pub factor: f32,
}
impl NoiseOpts {
pub fn new(
width: f32,
height: f32,
x_scale: f32,
y_scale: f32,
z_scale: f32,
factor: f32,
) -> Self {
Self {
width,
height,
x_scale,
y_scale,
z_scale,
factor,
}
}
pub fn with_wh<T: AsPrimitive<f32>>(width: T, height: T) -> Self {
Self {
width: width.as_(),
height: height.as_(),
..Self::default()
}
}
pub fn width(self, width: f32) -> Self {
Self { width, ..self }
}
pub fn height(self, height: f32) -> Self {
Self { height, ..self }
}
pub fn factor(self, factor: f32) -> Self {
Self { factor, ..self }
}
pub fn x_scale(self, x_scale: f32) -> Self {
Self { x_scale, ..self }
}
pub fn y_scale(self, y_scale: f32) -> Self {
Self { y_scale, ..self }
}
pub fn z_scale(self, z_scale: f32) -> Self {
Self { z_scale, ..self }
}
pub fn xy_scales(self, scale: f32) -> Self {
Self {
x_scale: scale,
y_scale: scale,
..self
}
}
pub fn scales(self, scale: f32) -> Self {
Self {
x_scale: scale,
y_scale: scale,
z_scale: scale,
..self
}
}
}
impl Default for NoiseOpts {
fn default() -> Self {
Self {
width: 1.0,
height: 1.0,
x_scale: 1.0,
y_scale: 1.0,
z_scale: 1.0,
factor: 1.0,
}
}
}
fn get_f32<const N: usize>(nf: impl NoiseFn<f64, N>, point: [f32; N]) -> f32 {
let coords = point.iter().map(|p| p.to_f64());
let mut a: [f64; N] = [0.0; N];
for (i, c) in coords.enumerate() {
a[i] = c.unwrap();
}
nf.get(a) as f32
}
pub fn noise2d(nf: impl NoiseFn<f64, 2>, opts: &NoiseOpts, x: f32, y: f32) -> f32 {
opts.factor
* get_f32(
nf,
[
1.0 / opts.width * opts.x_scale * x,
1.0 / opts.height * opts.y_scale * y,
],
)
}
pub fn noise2d_01(nf: impl NoiseFn<f64, 2>, opts: &NoiseOpts, x: f32, y: f32) -> f32 {
0.5 * noise2d(&nf, opts, x, y) + 0.5
}
pub fn noise3d(nf: impl NoiseFn<f64, 3>, opts: &NoiseOpts, x: f32, y: f32, z: f32) -> f32 {
opts.factor
* get_f32(
nf,
[
1.0 / opts.width * opts.x_scale * x,
1.0 / opts.height * opts.y_scale * y,
opts.z_scale * z,
],
)
}
pub fn noise3d_01(nf: impl NoiseFn<f64, 3>, opts: &NoiseOpts, x: f32, y: f32, z: f32) -> f32 {
0.5 * noise3d(&nf, opts, x, y, z) + 0.5
}