1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
use crate::noise_fns::NoiseFn;
/// Noise function that uses multiple source functions to displace each coordinate
/// of the input value before returning the output value from the `source` function.
pub struct Displace<Source, XDisplace, YDisplace, ZDisplace, UDisplace> {
/// Source function that outputs a value
pub source: Source,
/// Displacement function that displaces the _x_ coordinate of the input
/// value.
pub x_displace: XDisplace,
/// Displacement function that displaces the _y_ coordinate of the input
/// value.
pub y_displace: YDisplace,
/// Displacement function that displaces the _z_ coordinate of the input
/// value. Only needed for 3d or higher noise.
pub z_displace: ZDisplace,
/// Displacement function that displaces the _u_ coordinate of the input
/// value. Only needed for 4d or higher noise.
pub u_displace: UDisplace,
}
impl<Source, XDisplace, YDisplace, ZDisplace, UDisplace>
Displace<Source, XDisplace, YDisplace, ZDisplace, UDisplace>
{
pub fn new(
source: Source,
x_displace: XDisplace,
y_displace: YDisplace,
z_displace: ZDisplace,
u_displace: UDisplace,
) -> Self {
Self {
source,
x_displace,
y_displace,
z_displace,
u_displace,
}
}
}
impl<Source, XDisplace, YDisplace, ZDisplace, UDisplace> NoiseFn<[f64; 2]>
for Displace<Source, XDisplace, YDisplace, ZDisplace, UDisplace>
where
Source: NoiseFn<[f64; 2]>,
XDisplace: NoiseFn<[f64; 2]>,
YDisplace: NoiseFn<[f64; 2]>,
{
fn get(&self, point: [f64; 2]) -> f64 {
// Get the output values from the displacement functions and add them to
// the corresponding coordinate in the input value. Since this is a 2d
// function, we only need the x_displace and y_displace functions.
let x = point[0] + self.x_displace.get(point);
let y = point[1] + self.y_displace.get(point);
// get the output value using the offset input value instead of the
// original input value.
self.source.get([x, y])
}
}
impl<Source, XDisplace, YDisplace, ZDisplace, UDisplace> NoiseFn<[f64; 3]>
for Displace<Source, XDisplace, YDisplace, ZDisplace, UDisplace>
where
Source: NoiseFn<[f64; 3]>,
XDisplace: NoiseFn<[f64; 3]>,
YDisplace: NoiseFn<[f64; 3]>,
ZDisplace: NoiseFn<[f64; 3]>,
{
fn get(&self, point: [f64; 3]) -> f64 {
// Get the output values from the displacement functions and add them to
// the corresponding coordinate in the input value. Since this is a 3d
// function, we only need the x_displace, y_displace, and z_displace
// functions. Also, panic if there is no z_displace function defined.
let x = point[0] + self.x_displace.get(point);
let y = point[1] + self.y_displace.get(point);
let z = point[2] + self.z_displace.get(point);
// get the output value using the offset input value instead of the
// original input value.
self.source.get([x, y, z])
}
}
impl<Source, XDisplace, YDisplace, ZDisplace, UDisplace> NoiseFn<[f64; 4]>
for Displace<Source, XDisplace, YDisplace, ZDisplace, UDisplace>
where
Source: NoiseFn<[f64; 4]>,
XDisplace: NoiseFn<[f64; 4]>,
YDisplace: NoiseFn<[f64; 4]>,
ZDisplace: NoiseFn<[f64; 4]>,
UDisplace: NoiseFn<[f64; 4]>,
{
fn get(&self, point: [f64; 4]) -> f64 {
// Get the output values from the displacement functions and add them to
// the corresponding coordinate in the input value. Since this is a 4d
// function, we need all of the displace functions. Panic if there is no z-
// or u-displace function defined.
let x = point[0] + self.x_displace.get(point);
let y = point[1] + self.y_displace.get(point);
let z = point[2] + self.z_displace.get(point);
let u = point[3] + self.u_displace.get(point);
// get the output value using the offset input value instead of the
// original input value.
self.source.get([x, y, z, u])
}
}