1macro_rules! impl_vec_types {
2 (
3 $t:ty,
4 $vec2:ident,
5 $vec3:ident,
6 $vec4:ident,
7 $uniform:ident,
8 $upper_range_multiplier:expr
9 ) => {
10 use super::{UniformVec2, UniformVec3, UniformVec4};
11 use rand::{
12 distr::{
13 uniform::{Error as UniformError, SampleBorrow, SampleUniform, UniformSampler},
14 Distribution, StandardUniform,
15 },
16 Rng,
17 };
18
19 impl Distribution<$vec2> for StandardUniform {
20 #[inline]
21 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $vec2 {
22 rng.random::<[$t; 2]>().into()
23 }
24 }
25
26 impl SampleUniform for $vec2 {
27 type Sampler = UniformVec2<$uniform<$t>>;
28 }
29
30 impl UniformSampler for UniformVec2<$uniform<$t>> {
31 type X = $vec2;
32
33 fn new<B1, B2>(low_b: B1, high_b: B2) -> Result<Self, UniformError>
34 where
35 B1: SampleBorrow<Self::X> + Sized,
36 B2: SampleBorrow<Self::X> + Sized,
37 {
38 let low = *low_b.borrow();
39 let high = *high_b.borrow();
40
41 if low.x >= high.x || low.y >= high.y {
42 return Err(UniformError::EmptyRange);
43 }
44
45 Ok(Self {
46 x_gen: $uniform::new(low.x, high.x)?,
47 y_gen: $uniform::new(low.y, high.y)?,
48 })
49 }
50
51 fn new_inclusive<B1, B2>(low_b: B1, high_b: B2) -> Result<Self, UniformError>
52 where
53 B1: SampleBorrow<Self::X> + Sized,
54 B2: SampleBorrow<Self::X> + Sized,
55 {
56 let low = *low_b.borrow();
57 let high = *high_b.borrow();
58
59 if low.x >= high.x || low.y >= high.y {
60 return Err(UniformError::EmptyRange);
61 }
62
63 Ok(Self {
64 x_gen: $uniform::new_inclusive(low.x, high.x)?,
65 y_gen: $uniform::new_inclusive(low.y, high.y)?,
66 })
67 }
68
69 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X {
70 Self::X::from([self.x_gen.sample(rng), self.y_gen.sample(rng)])
71 }
72
73 fn sample_single<R: Rng + ?Sized, B1, B2>(
74 low_b: B1,
75 high_b: B2,
76 rng: &mut R,
77 ) -> Result<Self::X, UniformError>
78 where
79 B1: SampleBorrow<Self::X> + Sized,
80 B2: SampleBorrow<Self::X> + Sized,
81 {
82 let low = *low_b.borrow();
83 let high = *high_b.borrow();
84
85 if low.x >= high.x || low.y >= high.y {
86 return Err(UniformError::EmptyRange);
87 }
88
89 Ok(Self::X::from([
90 $uniform::<$t>::sample_single(low.x, high.x, rng)?,
91 $uniform::<$t>::sample_single(low.y, high.y, rng)?,
92 ]))
93 }
94
95 fn sample_single_inclusive<R: Rng + ?Sized, B1, B2>(
96 low_b: B1,
97 high_b: B2,
98 rng: &mut R,
99 ) -> Result<Self::X, UniformError>
100 where
101 B1: SampleBorrow<Self::X> + Sized,
102 B2: SampleBorrow<Self::X> + Sized,
103 {
104 let low = *low_b.borrow();
105 let high = *high_b.borrow();
106
107 if low.x >= high.x || low.y >= high.y {
108 return Err(UniformError::EmptyRange);
109 }
110
111 Ok(Self::X::from([
112 $uniform::<$t>::sample_single_inclusive(low.x, high.x, rng)?,
113 $uniform::<$t>::sample_single_inclusive(low.y, high.y, rng)?,
114 ]))
115 }
116 }
117
118 impl Distribution<$vec3> for StandardUniform {
119 #[inline]
120 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $vec3 {
121 rng.random::<[$t; 3]>().into()
122 }
123 }
124
125 impl SampleUniform for $vec3 {
126 type Sampler = UniformVec3<$uniform<$t>>;
127 }
128
129 impl UniformSampler for UniformVec3<$uniform<$t>> {
130 type X = $vec3;
131
132 fn new<B1, B2>(low_b: B1, high_b: B2) -> Result<Self, UniformError>
133 where
134 B1: SampleBorrow<Self::X> + Sized,
135 B2: SampleBorrow<Self::X> + Sized,
136 {
137 let low = *low_b.borrow();
138 let high = *high_b.borrow();
139
140 if low.x >= high.x || low.y >= high.y || low.z >= high.z {
141 return Err(UniformError::EmptyRange);
142 }
143
144 Ok(Self {
145 x_gen: $uniform::new(low.x, high.x)?,
146 y_gen: $uniform::new(low.y, high.y)?,
147 z_gen: $uniform::new(low.z, high.z)?,
148 })
149 }
150
151 fn new_inclusive<B1, B2>(low_b: B1, high_b: B2) -> Result<Self, UniformError>
152 where
153 B1: SampleBorrow<Self::X> + Sized,
154 B2: SampleBorrow<Self::X> + Sized,
155 {
156 let low = *low_b.borrow();
157 let high = *high_b.borrow();
158
159 if low.x >= high.x || low.y >= high.y || low.z >= high.z {
160 return Err(UniformError::EmptyRange);
161 }
162
163 Ok(Self {
164 x_gen: $uniform::new_inclusive(low.x, high.x)?,
165 y_gen: $uniform::new_inclusive(low.y, high.y)?,
166 z_gen: $uniform::new_inclusive(low.z, high.z)?,
167 })
168 }
169
170 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X {
171 Self::X::from([
172 self.x_gen.sample(rng),
173 self.y_gen.sample(rng),
174 self.z_gen.sample(rng),
175 ])
176 }
177
178 fn sample_single<R: Rng + ?Sized, B1, B2>(
179 low_b: B1,
180 high_b: B2,
181 rng: &mut R,
182 ) -> Result<Self::X, UniformError>
183 where
184 B1: SampleBorrow<Self::X> + Sized,
185 B2: SampleBorrow<Self::X> + Sized,
186 {
187 let low = *low_b.borrow();
188 let high = *high_b.borrow();
189
190 if low.x >= high.x || low.y >= high.y || low.z >= high.z {
191 return Err(UniformError::EmptyRange);
192 }
193
194 Ok(Self::X::from([
195 $uniform::<$t>::sample_single(low.x, high.x, rng)?,
196 $uniform::<$t>::sample_single(low.y, high.y, rng)?,
197 $uniform::<$t>::sample_single(low.z, high.z, rng)?,
198 ]))
199 }
200
201 fn sample_single_inclusive<R: Rng + ?Sized, B1, B2>(
202 low_b: B1,
203 high_b: B2,
204 rng: &mut R,
205 ) -> Result<Self::X, UniformError>
206 where
207 B1: SampleBorrow<Self::X> + Sized,
208 B2: SampleBorrow<Self::X> + Sized,
209 {
210 let low = *low_b.borrow();
211 let high = *high_b.borrow();
212
213 if low.x >= high.x || low.y >= high.y || low.z >= high.z {
214 return Err(UniformError::EmptyRange);
215 }
216
217 Ok(Self::X::from([
218 $uniform::<$t>::sample_single_inclusive(low.x, high.x, rng)?,
219 $uniform::<$t>::sample_single_inclusive(low.y, high.y, rng)?,
220 $uniform::<$t>::sample_single_inclusive(low.z, high.z, rng)?,
221 ]))
222 }
223 }
224
225 impl Distribution<$vec4> for StandardUniform {
226 #[inline]
227 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $vec4 {
228 rng.random::<[$t; 4]>().into()
229 }
230 }
231
232 impl SampleUniform for $vec4 {
233 type Sampler = UniformVec4<$uniform<$t>>;
234 }
235
236 impl UniformSampler for UniformVec4<$uniform<$t>> {
237 type X = $vec4;
238
239 fn new<B1, B2>(low_b: B1, high_b: B2) -> Result<Self, UniformError>
240 where
241 B1: SampleBorrow<Self::X> + Sized,
242 B2: SampleBorrow<Self::X> + Sized,
243 {
244 let low = *low_b.borrow();
245 let high = *high_b.borrow();
246
247 if low.x >= high.x || low.y >= high.y || low.z >= high.z || low.w >= high.w {
248 return Err(UniformError::EmptyRange);
249 }
250
251 Ok(Self {
252 x_gen: $uniform::new(low.x, high.x)?,
253 y_gen: $uniform::new(low.y, high.y)?,
254 z_gen: $uniform::new(low.z, high.z)?,
255 w_gen: $uniform::new(low.w, high.w)?,
256 })
257 }
258
259 fn new_inclusive<B1, B2>(low_b: B1, high_b: B2) -> Result<Self, UniformError>
260 where
261 B1: SampleBorrow<Self::X> + Sized,
262 B2: SampleBorrow<Self::X> + Sized,
263 {
264 let low = *low_b.borrow();
265 let high = *high_b.borrow();
266
267 if low.x >= high.x || low.y >= high.y || low.z >= high.z || low.w >= high.w {
268 return Err(UniformError::EmptyRange);
269 }
270
271 Ok(Self {
272 x_gen: $uniform::new_inclusive(low.x, high.x)?,
273 y_gen: $uniform::new_inclusive(low.y, high.y)?,
274 z_gen: $uniform::new_inclusive(low.z, high.z)?,
275 w_gen: $uniform::new_inclusive(low.w, high.w)?,
276 })
277 }
278
279 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X {
280 Self::X::from([
281 self.x_gen.sample(rng),
282 self.y_gen.sample(rng),
283 self.z_gen.sample(rng),
284 self.w_gen.sample(rng),
285 ])
286 }
287
288 fn sample_single<R: Rng + ?Sized, B1, B2>(
289 low_b: B1,
290 high_b: B2,
291 rng: &mut R,
292 ) -> Result<Self::X, UniformError>
293 where
294 B1: SampleBorrow<Self::X> + Sized,
295 B2: SampleBorrow<Self::X> + Sized,
296 {
297 let low = *low_b.borrow();
298 let high = *high_b.borrow();
299
300 if low.x >= high.x || low.y >= high.y || low.z >= high.z || low.w >= high.w {
301 return Err(UniformError::EmptyRange);
302 }
303
304 Ok(Self::X::from([
305 $uniform::<$t>::sample_single(low.x, high.x, rng)?,
306 $uniform::<$t>::sample_single(low.y, high.y, rng)?,
307 $uniform::<$t>::sample_single(low.z, high.z, rng)?,
308 $uniform::<$t>::sample_single(low.w, high.w, rng)?,
309 ]))
310 }
311
312 fn sample_single_inclusive<R: Rng + ?Sized, B1, B2>(
313 low_b: B1,
314 high_b: B2,
315 rng: &mut R,
316 ) -> Result<Self::X, UniformError>
317 where
318 B1: SampleBorrow<Self::X> + Sized,
319 B2: SampleBorrow<Self::X> + Sized,
320 {
321 let low = *low_b.borrow();
322 let high = *high_b.borrow();
323
324 if low.x >= high.x || low.y >= high.y || low.z >= high.z || low.w >= high.w {
325 return Err(UniformError::EmptyRange);
326 }
327
328 Ok(Self::X::from([
329 $uniform::<$t>::sample_single_inclusive(low.x, high.x, rng)?,
330 $uniform::<$t>::sample_single_inclusive(low.y, high.y, rng)?,
331 $uniform::<$t>::sample_single_inclusive(low.z, high.z, rng)?,
332 $uniform::<$t>::sample_single_inclusive(low.w, high.w, rng)?,
333 ]))
334 }
335 }
336
337 #[test]
338 fn test_vec2_rand_standard() {
339 use rand::{Rng, SeedableRng};
340 use rand_xoshiro::Xoshiro256Plus;
341 let mut rng1 = Xoshiro256Plus::seed_from_u64(0);
342 let a: ($t, $t) = rng1.random();
343 let mut rng2 = Xoshiro256Plus::seed_from_u64(0);
344 let b: $vec2 = rng2.random();
345 assert_eq!(a, b.into());
346 }
347
348 #[test]
349 fn test_vec3_rand_standard() {
350 use rand::{Rng, SeedableRng};
351 use rand_xoshiro::Xoshiro256Plus;
352 let mut rng1 = Xoshiro256Plus::seed_from_u64(0);
353 let a: ($t, $t, $t) = rng1.random();
354 let mut rng2 = Xoshiro256Plus::seed_from_u64(0);
355 let b: $vec3 = rng2.random();
356 assert_eq!(a, b.into());
357 }
358
359 #[test]
360 fn test_vec4_rand_standard() {
361 use rand::{Rng, SeedableRng};
362 use rand_xoshiro::Xoshiro256Plus;
363 let mut rng1 = Xoshiro256Plus::seed_from_u64(0);
364 let a: ($t, $t, $t, $t) = rng1.random();
365 let mut rng2 = Xoshiro256Plus::seed_from_u64(0);
366 let b: $vec4 = rng2.random();
367 assert_eq!(a, b.into());
368 }
369
370 test_vec_type_uniform!(
371 test_vec2_rand_uniform_equality,
372 $vec2,
373 $t,
374 2,
375 $upper_range_multiplier
376 );
377
378 test_vec_type_uniform!(
379 test_vec3_rand_uniform_equality,
380 $vec3,
381 $t,
382 3,
383 $upper_range_multiplier
384 );
385
386 test_vec_type_uniform!(
387 test_vec4_rand_uniform_equality,
388 $vec4,
389 $t,
390 4,
391 $upper_range_multiplier
392 );
393 };
394}
395
396macro_rules! test_vec_type_uniform {
397 (__repeat_code 2, $code:expr) => {
401 ($code, $code)
402 };
403 (__repeat_code 3, $code:expr) => {
404 ($code, $code, $code)
405 };
406 (__repeat_code 4, $code:expr) => {
407 ($code, $code, $code, $code)
408 };
409 (
410 $equality_test_name:ident,
411 $vec:ident,
412 $t:ty,
413 $t_count:tt,
414 $upper_range_divisor:expr
415 ) => {
416 #[test]
420 fn $equality_test_name() {
421 use rand::{distr::Uniform, Rng, SeedableRng};
422 use rand_xoshiro::Xoshiro256Plus;
423
424 let mut int_rng = Xoshiro256Plus::seed_from_u64(0);
425 let mut vec_rng = Xoshiro256Plus::seed_from_u64(0);
426
427 macro_rules! test_uniform {
428 (
429 __single_test,
430 $uniform_function_name:ident,
431 $t_low:expr,
432 $t_high:expr,
433 $vec_low:expr,
434 $vec_high:expr
435 ) => {
436 let int_u = Uniform::$uniform_function_name($t_low, $t_high).unwrap();
437 let vec_u = Uniform::$uniform_function_name($vec_low, $vec_high).unwrap();
438
439 let v_int = test_vec_type_uniform!(
440 __repeat_code $t_count,
441 int_rng.sample(int_u)
442 );
443 let v_vec: $vec = vec_rng.sample(vec_u);
444 assert_eq!(v_int, v_vec.into());
445 };
446 (
447 $uniform_function_name:ident,
448 $t_low:expr,
449 $t_high:expr,
450 $vec_low:expr,
451 $vec_high:expr
452 ) => {
453 test_uniform!(
454 __single_test,
455 $uniform_function_name,
456 $t_low, $t_high,
457 $vec_low, $vec_high
458 );
459
460 test_uniform!(
461 __single_test,
462 $uniform_function_name,
463 &$t_low, &$t_high,
464 &$vec_low, &$vec_high
465 );
466 };
467 }
468
469 test_uniform!(
470 new,
471 <$t>::default(),
472 <$t>::MAX / $upper_range_divisor,
473 $vec::default(),
474 $vec::MAX / $upper_range_divisor
475 );
476
477 test_uniform!(
478 new_inclusive,
479 <$t>::default(),
480 <$t>::MAX / $upper_range_divisor,
481 $vec::default(),
482 $vec::MAX / $upper_range_divisor
483 );
484
485 macro_rules! test_sample_uniform_sampler {
486 ($sampler_function_name:ident) => {
487 let v_int = test_vec_type_uniform!(
488 __repeat_code $t_count,
489 <$t as SampleUniform>::Sampler::$sampler_function_name(
490 <$t>::default(),
491 <$t>::MAX / $upper_range_divisor,
492 &mut int_rng,
493 ).unwrap()
494 );
495
496 let v_vec: $vec = <$vec as SampleUniform>::Sampler::$sampler_function_name(
497 $vec::default(),
498 $vec::MAX / $upper_range_divisor,
499 &mut vec_rng,
500 ).unwrap();
501 assert_eq!(v_int, v_vec.into());
502 };
503 }
504
505 test_sample_uniform_sampler!(sample_single);
506 test_sample_uniform_sampler!(sample_single_inclusive);
507 }
508 };
509}
510
511macro_rules! impl_int_types {
512 ($t:ty, $vec2:ident, $vec3:ident, $vec4:ident) => {
513 use rand::distr::uniform::UniformInt;
514
515 impl_vec_types!($t, $vec2, $vec3, $vec4, UniformInt, 1);
516 };
517}
518
519macro_rules! impl_float_types {
520 ($t:ident, $mat2:ident, $mat3:ident, $mat4:ident, $quat:ident, $vec2:ident, $vec3:ident, $vec4:ident) => {
521 use rand::distr::uniform::UniformFloat;
522
523 impl_vec_types!($t, $vec2, $vec3, $vec4, UniformFloat, 10.0);
524
525 impl Distribution<$mat2> for StandardUniform {
526 #[inline]
527 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $mat2 {
528 $mat2::from_cols_array(&rng.random())
529 }
530 }
531
532 impl Distribution<$mat3> for StandardUniform {
533 #[inline]
534 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $mat3 {
535 $mat3::from_cols_array(&rng.random())
536 }
537 }
538
539 impl Distribution<$mat4> for StandardUniform {
540 #[inline]
541 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $mat4 {
542 $mat4::from_cols_array(&rng.random())
543 }
544 }
545
546 impl Distribution<$quat> for StandardUniform {
547 #[inline]
548 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $quat {
549 let z = rng.random_range::<$t, _>(-1.0..=1.0);
550 let (y, x) = math::sin_cos(rng.random_range::<$t, _>(0.0..TAU));
551 let r = math::sqrt(1.0 - z * z);
552 let axis = $vec3::new(r * x, r * y, z);
553 let angle = rng.random_range::<$t, _>(0.0..TAU);
554 $quat::from_axis_angle(axis, angle)
555 }
556 }
557
558 #[test]
559 fn test_mat2_rand_standard() {
560 use rand::{Rng, SeedableRng};
561 use rand_xoshiro::Xoshiro256Plus;
562 let mut rng1 = Xoshiro256Plus::seed_from_u64(0);
563 let a = $mat2::from_cols_array(&rng1.random::<[$t; 4]>());
564 let mut rng2 = Xoshiro256Plus::seed_from_u64(0);
565 let b = rng2.random::<$mat2>();
566 assert_eq!(a, b);
567 }
568
569 #[test]
570 fn test_mat3_rand_standard() {
571 use rand::{Rng, SeedableRng};
572 use rand_xoshiro::Xoshiro256Plus;
573 let mut rng1 = Xoshiro256Plus::seed_from_u64(0);
574 let a = $mat3::from_cols_array(&rng1.random::<[$t; 9]>());
575 let mut rng2 = Xoshiro256Plus::seed_from_u64(0);
576 let b = rng2.random::<$mat3>();
577 assert_eq!(a, b);
578 }
579
580 #[test]
581 fn test_mat4_rand_standard() {
582 use rand::{Rng, SeedableRng};
583 use rand_xoshiro::Xoshiro256Plus;
584 let mut rng1 = Xoshiro256Plus::seed_from_u64(0);
585 let a = $mat4::from_cols_array(&rng1.random::<[$t; 16]>());
586 let mut rng2 = Xoshiro256Plus::seed_from_u64(0);
587 let b = rng2.random::<$mat4>();
588 assert_eq!(a, b);
589 }
590
591 #[test]
592 fn test_quat_rand_standard() {
593 use rand::{Rng, SeedableRng};
594 use rand_xoshiro::Xoshiro256Plus;
595 let mut rng1 = Xoshiro256Plus::seed_from_u64(0);
596 let a: $quat = rng1.random();
597 assert!(a.is_normalized());
598 let mut rng2 = Xoshiro256Plus::seed_from_u64(0);
599 let b: $quat = rng2.random();
600 assert_eq!(a, b);
601 }
602 };
603}
604
605#[derive(Clone, Copy, Debug, PartialEq)]
606pub struct UniformVec2<G> {
607 x_gen: G,
608 y_gen: G,
609}
610
611#[derive(Clone, Copy, Debug, PartialEq)]
612pub struct UniformVec3<G> {
613 x_gen: G,
614 y_gen: G,
615 z_gen: G,
616}
617
618#[derive(Clone, Copy, Debug, PartialEq)]
619pub struct UniformVec4<G> {
620 x_gen: G,
621 y_gen: G,
622 z_gen: G,
623 w_gen: G,
624}
625
626mod f32 {
627 use crate::f32::math;
628 use crate::{Mat2, Mat3, Mat4, Quat, Vec2, Vec3, Vec3A, Vec4};
629 use core::f32::consts::TAU;
630
631 impl_float_types!(f32, Mat2, Mat3, Mat4, Quat, Vec2, Vec3, Vec4);
632
633 impl Distribution<Vec3A> for StandardUniform {
634 #[inline]
635 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Vec3A {
636 rng.random::<[f32; 3]>().into()
637 }
638 }
639
640 #[test]
641 fn test_vec3a_rand_standard() {
642 use rand::{Rng, SeedableRng};
643 use rand_xoshiro::Xoshiro256Plus;
644 let mut rng1 = Xoshiro256Plus::seed_from_u64(0);
645 let a: (f32, f32, f32) = rng1.random();
646 let mut rng2 = Xoshiro256Plus::seed_from_u64(0);
647 let b: Vec3A = rng2.random();
648 assert_eq!(a, b.into());
649 }
650}
651
652mod f64 {
653 use crate::f64::math;
654 use crate::{DMat2, DMat3, DMat4, DQuat, DVec2, DVec3, DVec4};
655 use core::f64::consts::TAU;
656
657 impl_float_types!(f64, DMat2, DMat3, DMat4, DQuat, DVec2, DVec3, DVec4);
658}
659
660mod i8 {
661 use crate::{I8Vec2, I8Vec3, I8Vec4};
662
663 impl_int_types!(i8, I8Vec2, I8Vec3, I8Vec4);
664}
665
666mod i16 {
667 use crate::{I16Vec2, I16Vec3, I16Vec4};
668
669 impl_int_types!(i16, I16Vec2, I16Vec3, I16Vec4);
670}
671
672mod i32 {
673 use crate::{IVec2, IVec3, IVec4};
674
675 impl_int_types!(i32, IVec2, IVec3, IVec4);
676}
677
678mod i64 {
679 use crate::{I64Vec2, I64Vec3, I64Vec4};
680
681 impl_int_types!(i64, I64Vec2, I64Vec3, I64Vec4);
682}
683
684mod u8 {
685 use crate::{U8Vec2, U8Vec3, U8Vec4};
686
687 impl_int_types!(u8, U8Vec2, U8Vec3, U8Vec4);
688}
689
690mod u16 {
691 use crate::{U16Vec2, U16Vec3, U16Vec4};
692
693 impl_int_types!(u16, U16Vec2, U16Vec3, U16Vec4);
694}
695
696mod u32 {
697 use crate::{UVec2, UVec3, UVec4};
698
699 impl_int_types!(u32, UVec2, UVec3, UVec4);
700}
701
702mod u64 {
703 use crate::{U64Vec2, U64Vec3, U64Vec4};
704
705 impl_int_types!(u64, U64Vec2, U64Vec3, U64Vec4);
706}