1#[cfg(feature = "nightly-simd")]
2use core::simd::{f32x2, f32x4};
3
4use crate::{Noise, Sample};
5
6pub(crate) trait Sealed {}
7
8macro_rules! r#if {
9 (if 2 == 2 { $($then:tt)* } else { $($else:tt)* }) => { $($then)* };
10 (if 2 == 3 { $($then:tt)* } else { $($else:tt)* }) => { $($else)* };
11 (if 2 == 4 { $($then:tt)* } else { $($else:tt)* }) => { $($else)* };
12 (if 3 == 2 { $($then:tt)* } else { $($else:tt)* }) => { $($else)* };
13 (if 3 == 3 { $($then:tt)* } else { $($else:tt)* }) => { $($then)* };
14 (if 3 == 4 { $($then:tt)* } else { $($else:tt)* }) => { $($else)* };
15 (if 4 == 2 { $($then:tt)* } else { $($else:tt)* }) => { $($else)* };
16 (if 4 == 3 { $($then:tt)* } else { $($else:tt)* }) => { $($else)* };
17 (if 4 == 4 { $($then:tt)* } else { $($else:tt)* }) => { $($then)* };
18}
19
20pub(crate) use r#if;
21
22macro_rules! impl_improves {
23 (
24 $(#[$trait_attrs:meta])*
25 trait $trait:ident {
26 $($trait_members:tt)*
27 }
28
29 $(
30 $(#[$improve_attrs:meta])*
31 $improve_struct:ident $improve_dim:tt $improve_fn:ident use $improve:ident $improve_a:ident;
32 )*
33 ) => {
34 $(#[$trait_attrs])*
35 #[expect(private_bounds)]
36 pub trait $trait: Sealed + Noise {
37 $(
38 $(#[$improve_attrs])*
39 fn $improve_fn(self) -> $improve_struct<Self>
40 where
41 Self: Sized,
42 {
43 $improve_struct(self)
44 }
45 )*
46
47 $($trait_members)*
48 }
49
50 $(
51 $(#[$improve_attrs])*
52 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
53 pub struct $improve_struct<OpenSimplexNoise>(pub OpenSimplexNoise);
54
55 impl<N> Noise for $improve_struct<N> {}
56
57 impl<N: OpenSimplexNoise> Sealed for $improve_struct<N> {}
58
59 impl<N: OpenSimplexNoise> $trait for $improve_struct<N> {
60 #[inline(always)]
61 fn raw_sample2(&self, point: [f32; 2], seed: i32) -> f32 {
62 self.0.raw_sample2(point, seed)
63 }
64
65 #[inline(always)]
66 #[cfg(feature = "nightly-simd")]
67 fn raw_sample2a(&self, point: f32x2, seed: i32) -> f32 {
68 self.0.raw_sample2a(point, seed)
69 }
70
71 #[inline(always)]
72 fn raw_sample3(&self, point: [f32; 3], seed: i32) -> f32 {
73 self.0.raw_sample3(point, seed)
74 }
75
76 #[inline(always)]
77 #[cfg(feature = "nightly-simd")]
78 fn raw_sample3a(&self, point: f32x4, seed: i32) -> f32 {
79 self.0.raw_sample3a(point, seed)
80 }
81
82 #[inline(always)]
83 fn raw_sample4(&self, point: [f32; 4], seed: i32) -> f32 {
84 self.0.raw_sample4(point, seed)
85 }
86
87 #[inline(always)]
88 #[cfg(feature = "nightly-simd")]
89 fn raw_sample4a(&self, point: f32x4, seed: i32) -> f32 {
90 self.0.raw_sample4a(point, seed)
91 }
92
93 #[inline(always)]
94 fn raw_improve2_x(&self, point: [f32; 2]) -> [f32; 2] {
95 self.0.raw_improve2_x(point)
96 }
97
98 #[inline(always)]
99 #[cfg(feature = "nightly-simd")]
100 fn raw_improve2a_x(&self, point: f32x2) -> f32x2 {
101 self.0.raw_improve2a_x(point)
102 }
103
104 #[inline(always)]
105 fn raw_improve3_xy(&self, point: [f32; 3]) -> [f32; 3] {
106 self.0.raw_improve3_xy(point)
107 }
108
109 #[inline(always)]
110 #[cfg(feature = "nightly-simd")]
111 fn raw_improve3a_xy(&self, point: f32x4) -> f32x4 {
112 self.0.raw_improve3a_xy(point)
113 }
114
115 #[inline(always)]
116 fn raw_improve3_xz(&self, point: [f32; 3]) -> [f32; 3] {
117 self.0.raw_improve3_xz(point)
118 }
119
120 #[inline(always)]
121 #[cfg(feature = "nightly-simd")]
122 fn raw_improve3a_xz(&self, point: f32x4) -> f32x4 {
123 self.0.raw_improve3a_xz(point)
124 }
125
126 #[doc(hidden)]
127 fn raw_improve4_xyz_xy(&self, point: [f32; 4]) -> [f32; 4] {
128 self.0.raw_improve4_xyz_xy(point)
129 }
130
131 #[doc(hidden)]
132 #[cfg(feature = "nightly-simd")]
133 fn raw_improve4a_xyz_xy(&self, point: f32x4) -> f32x4 {
134 self.0.raw_improve4a_xyz_xy(point)
135 }
136
137 #[doc(hidden)]
138 fn raw_improve4_xyz_xz(&self, point: [f32; 4]) -> [f32; 4] {
139 self.0.raw_improve4_xyz_xz(point)
140 }
141
142 #[doc(hidden)]
143 #[cfg(feature = "nightly-simd")]
144 fn raw_improve4a_xyz_xz(&self, point: f32x4) -> f32x4 {
145 self.0.raw_improve4a_xyz_xz(point)
146 }
147
148 #[doc(hidden)]
149 fn raw_improve4_xyz(&self, point: [f32; 4]) -> [f32; 4] {
150 self.0.raw_improve4_xyz(point)
151 }
152
153 #[doc(hidden)]
154 #[cfg(feature = "nightly-simd")]
155 fn raw_improve4a_xyz(&self, point: f32x4) -> f32x4 {
156 self.0.raw_improve4a_xyz(point)
157 }
158
159 #[doc(hidden)]
160 fn raw_improve4_xy_zw(&self, point: [f32; 4]) -> [f32; 4] {
161 self.0.raw_improve4_xy_zw(point)
162 }
163
164 #[doc(hidden)]
165 #[cfg(feature = "nightly-simd")]
166 fn raw_improve4a_xy_zw(&self, point: f32x4) -> f32x4 {
167 self.0.raw_improve4a_xy_zw(point)
168 }
169 }
170
171 $crate::open_simplex_2::r#if! {
172 if $improve_dim == 2 {
173 impl<N: OpenSimplexNoise> Sample<2> for $improve_struct<N> {
174 #[inline(always)]
175 fn sample_with_seed(&self, point: [f32; 2], seed: i32) -> f32 {
176 self.0.raw_sample2(self.0.$improve(point), seed)
177 }
178 }
179
180 #[cfg(feature = "nightly-simd")]
181 impl<N: OpenSimplexNoise> Sample<2, core::simd::f32x2> for $improve_struct<N> {
182 #[inline(always)]
183 fn sample_with_seed(&self, point: f32x2, seed: i32) -> f32 {
184 self.0.raw_sample2a(self.0.$improve_a(point), seed)
185 }
186 }
187 } else {
188 impl<N: Sample<2>> Sample<2> for $improve_struct<N> {
189 #[inline(always)]
190 fn sample_with_seed(&self, point: [f32; 2], seed: i32) -> f32 {
191 self.0.sample_with_seed(point, seed)
192 }
193 }
194
195 #[cfg(feature = "nightly-simd")]
196 impl<N: Sample<2, f32x2>> Sample<2, core::simd::f32x2> for $improve_struct<N> {
197 #[inline(always)]
198 fn sample_with_seed(&self, point: f32x2, seed: i32) -> f32 {
199 self.0.sample_with_seed(point, seed)
200 }
201 }
202 }
203 }
204
205 $crate::open_simplex_2::r#if! {
206 if $improve_dim == 3 {
207 impl<N: OpenSimplexNoise> Sample<3> for $improve_struct<N> {
208 #[inline(always)]
209 fn sample_with_seed(&self, point: [f32; 3], seed: i32) -> f32 {
210 self.0.raw_sample3(self.0.$improve(point), seed)
211 }
212 }
213
214 #[cfg(feature = "nightly-simd")]
215 impl<N: OpenSimplexNoise> Sample<3, f32x4> for $improve_struct<N> {
216 #[inline(always)]
217 fn sample_with_seed(&self, point: f32x4, seed: i32) -> f32 {
218 self.0.raw_sample3a(self.0.$improve_a(point), seed)
219 }
220 }
221 } else {
222 impl<N: Sample<3>> Sample<3> for $improve_struct<N> {
223 #[inline(always)]
224 fn sample_with_seed(&self, point: [f32; 3], seed: i32) -> f32 {
225 self.0.sample_with_seed(point, seed)
226 }
227 }
228
229 #[cfg(feature = "nightly-simd")]
230 impl<N: Sample<3, f32x4>> Sample<3, f32x4> for $improve_struct<N> {
231 #[inline(always)]
232 fn sample_with_seed(&self, point: f32x4, seed: i32) -> f32 {
233 self.0.sample_with_seed(point, seed)
234 }
235 }
236 }
237 }
238
239 $crate::open_simplex_2::r#if! {
240 if $improve_dim == 4 {
241 impl<N: OpenSimplexNoise> Sample<4> for $improve_struct<N> {
242 #[inline(always)]
243 fn sample_with_seed(&self, point: [f32; 4], seed: i32) -> f32 {
244 self.0.raw_sample4(self.0.$improve(point), seed)
245 }
246 }
247
248 #[cfg(feature = "nightly-simd")]
249 impl<N: OpenSimplexNoise> Sample<4, f32x4> for $improve_struct<N> {
250 #[inline(always)]
251 fn sample_with_seed(&self, point: f32x4, seed: i32) -> f32 {
252 self.0.raw_sample4a(self.0.$improve_a(point), seed)
253 }
254 }
255 } else {
256 impl<N: Sample<4>> Sample<4> for $improve_struct<N> {
257 #[inline(always)]
258 fn sample_with_seed(&self, point: [f32; 4], seed: i32) -> f32 {
259 self.0.sample_with_seed(point, seed)
260 }
261 }
262
263 #[cfg(feature = "nightly-simd")]
264 impl<N: Sample<4, f32x4>> Sample<4, f32x4> for $improve_struct<N> {
265 #[inline(always)]
266 fn sample_with_seed(&self, point: f32x4, seed: i32) -> f32 {
267 self.0.sample_with_seed(point, seed)
268 }
269 }
270 }
271 }
272 )*
273 };
274}
275
276impl_improves! {
277 trait OpenSimplexNoise {
279 #[doc(hidden)]
281 fn raw_sample2(&self, point: [f32; 2], seed: i32) -> f32;
282
283 #[doc(hidden)]
285 #[cfg(feature = "nightly-simd")]
286 fn raw_sample2a(&self, point: f32x2, seed: i32) -> f32;
287
288 #[doc(hidden)]
290 fn raw_sample3(&self, point: [f32; 3], seed: i32) -> f32;
291
292 #[doc(hidden)]
294 #[cfg(feature = "nightly-simd")]
295 fn raw_sample3a(&self, point: f32x4, seed: i32) -> f32;
296
297 #[doc(hidden)]
299 fn raw_sample4(&self, point: [f32; 4], seed: i32) -> f32;
300
301 #[doc(hidden)]
303 #[cfg(feature = "nightly-simd")]
304 fn raw_sample4a(&self, point: f32x4, seed: i32) -> f32;
305
306 #[doc(hidden)]
307 fn raw_improve2_x(&self, point: [f32; 2]) -> [f32; 2];
308
309 #[doc(hidden)]
310 #[cfg(feature = "nightly-simd")]
311 fn raw_improve2a_x(&self, point: f32x2) -> f32x2;
312
313 #[doc(hidden)]
314 fn raw_improve3_xy(&self, point: [f32; 3]) -> [f32; 3];
315
316 #[doc(hidden)]
317 #[cfg(feature = "nightly-simd")]
318 fn raw_improve3a_xy(&self, point: f32x4) -> f32x4;
319
320 #[doc(hidden)]
321 fn raw_improve3_xz(&self, point: [f32; 3]) -> [f32; 3];
322
323 #[doc(hidden)]
324 #[cfg(feature = "nightly-simd")]
325 fn raw_improve3a_xz(&self, point: f32x4) -> f32x4;
326
327 #[doc(hidden)]
328 fn raw_improve4_xyz(&self, point: [f32; 4]) -> [f32; 4];
329
330 #[doc(hidden)]
331 #[cfg(feature = "nightly-simd")]
332 fn raw_improve4a_xyz(&self, point: f32x4) -> f32x4;
333
334 #[doc(hidden)]
335 fn raw_improve4_xyz_xy(&self, point: [f32; 4]) -> [f32; 4];
336
337 #[doc(hidden)]
338 #[cfg(feature = "nightly-simd")]
339 fn raw_improve4a_xyz_xy(&self, point: f32x4) -> f32x4;
340
341 #[doc(hidden)]
342 fn raw_improve4_xyz_xz(&self, point: [f32; 4]) -> [f32; 4];
343
344 #[doc(hidden)]
345 #[cfg(feature = "nightly-simd")]
346 fn raw_improve4a_xyz_xz(&self, point: f32x4) -> f32x4;
347
348 #[doc(hidden)]
349 fn raw_improve4_xy_zw(&self, point: [f32; 4]) -> [f32; 4];
350
351 #[doc(hidden)]
352 #[cfg(feature = "nightly-simd")]
353 fn raw_improve4a_xy_zw(&self, point: f32x4) -> f32x4;
354 }
355
356 Improve2X 2 improve2_x use raw_improve2_x raw_improve2a_x;
363
364 Improve3Xy 3 improve3_xy use raw_improve3_xy raw_improve3a_xy;
370
371 Improve3Xz 3 improve3_xz use raw_improve3_xz raw_improve3a_xz;
377
378 Improve4Xyz 4 improve4_xyz use raw_improve4_xyz raw_improve4a_xyz;
384
385 Improve4XyzXy 4 improve4_xyz_xy use raw_improve4_xyz_xy raw_improve4a_xyz_xy;
391
392 Improve4XyzXz 4 improve4_xyz_xz use raw_improve4_xyz_xz raw_improve4a_xyz_xz;
398
399 Improve4XyZw 4 improve4_xy_zw use raw_improve4_xy_zw raw_improve4a_xy_zw;
405}
406
407macro_rules! impl_open_simplex_noise {
408 (234 $struct:ident) => {
409 impl $crate::Noise for $struct {}
410
411 impl $crate::Sample<2> for $struct {
412 #[inline(always)]
413 fn sample_with_seed(&self, point: [f32; 2], seed: i32) -> f32 {
414 self.raw_sample2(improve2(point), seed)
415 }
416 }
417
418 #[cfg(feature = "nightly-simd")]
419 impl $crate::Sample<2, core::simd::f32x2> for $struct {
420 #[inline(always)]
421 fn sample_with_seed(&self, point: core::simd::f32x2, seed: i32) -> f32 {
422 self.raw_sample2a(improve2a(point), seed)
423 }
424 }
425
426 impl $crate::Sample<3> for $struct {
427 #[inline(always)]
428 fn sample_with_seed(&self, point: [f32; 3], seed: i32) -> f32 {
429 self.raw_sample3(improve3(point), seed)
430 }
431 }
432
433 #[cfg(feature = "nightly-simd")]
434 impl $crate::Sample<3, core::simd::f32x4> for $struct {
435 #[inline(always)]
436 fn sample_with_seed(&self, point: core::simd::f32x4, seed: i32) -> f32 {
437 self.raw_sample3a(improve3a(point), seed)
438 }
439 }
440
441 impl $crate::Sample<4> for $struct {
442 #[inline(always)]
443 fn sample_with_seed(&self, point: [f32; 4], seed: i32) -> f32 {
444 self.raw_sample4(improve4(point), seed)
445 }
446 }
447
448 #[cfg(feature = "nightly-simd")]
449 impl $crate::Sample<4, core::simd::f32x4> for $struct {
450 #[inline(always)]
451 fn sample_with_seed(&self, point: core::simd::f32x4, seed: i32) -> f32 {
452 self.raw_sample4a(improve4a(point), seed)
453 }
454 }
455
456 impl $crate::open_simplex_2::Sealed for $struct {}
457 };
458}
459
460pub(crate) use impl_open_simplex_noise;