noise_functions/modifiers/
tileable.rs1use crate::{
2 math::{cos, sin},
3 Noise, Sample,
4};
5
6use core::f32::consts::{PI, TAU};
7
8#[cfg(feature = "nightly-simd")]
9use core::simd::{f32x2, f32x4};
10
11#[derive(Debug, Clone, Copy, PartialEq)]
15pub struct Tileable<Noise> {
16 pub noise: Noise,
17 width_div_pi: f32,
18 height_div_pi: f32,
19 tau_div_width: f32,
20 tau_div_height: f32,
21}
22
23impl<Noise> Tileable<Noise> {
24 pub const fn new(noise: Noise, width: f32, height: f32) -> Self {
25 Self {
26 noise,
27 width_div_pi: width / PI,
28 height_div_pi: height / PI,
29 tau_div_width: TAU / width,
30 tau_div_height: TAU / height,
31 }
32 }
33
34 fn map_point(&self, [x, y]: [f32; 2]) -> [f32; 4] {
35 let nx = cos(x * self.tau_div_width) * self.width_div_pi;
36 let ny = cos(y * self.tau_div_height) * self.height_div_pi;
37 let nz = sin(x * self.tau_div_width) * self.width_div_pi;
38 let nw = sin(y * self.tau_div_height) * self.height_div_pi;
39 [nx, ny, nz, nw]
40 }
41}
42
43impl<N> Noise for Tileable<N> {}
44
45impl<Noise> Sample<2> for Tileable<Noise>
46where
47 Noise: Sample<4>,
48{
49 fn sample_with_seed(&self, point: [f32; 2], seed: i32) -> f32 {
50 self.noise.sample_with_seed(self.map_point(point), seed)
51 }
52}
53
54#[cfg(feature = "nightly-simd")]
55impl<Noise> Sample<2, f32x2> for Tileable<Noise>
56where
57 Noise: Sample<4, f32x4>,
58{
59 fn sample_with_seed(&self, point: f32x2, seed: i32) -> f32 {
60 self.noise.sample_with_seed(self.map_point(point.into()).into(), seed)
61 }
62}