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.cmple(high).all() {
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.cmple(high).all() {
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.cmple(high).all() {
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 test_uniform!(
486 new_inclusive,
487 <$t>::default(),
488 <$t>::default(),
489 $vec::default(),
490 $vec::default()
491 );
492
493 macro_rules! test_sample_uniform_sampler {
494 ($sampler_function_name:ident) => {
495 let v_int = test_vec_type_uniform!(
496 __repeat_code $t_count,
497 <$t as SampleUniform>::Sampler::$sampler_function_name(
498 <$t>::default(),
499 <$t>::MAX / $upper_range_divisor,
500 &mut int_rng,
501 ).unwrap()
502 );
503
504 let v_vec: $vec = <$vec as SampleUniform>::Sampler::$sampler_function_name(
505 $vec::default(),
506 $vec::MAX / $upper_range_divisor,
507 &mut vec_rng,
508 ).unwrap();
509 assert_eq!(v_int, v_vec.into());
510 };
511 }
512
513 test_sample_uniform_sampler!(sample_single);
514 test_sample_uniform_sampler!(sample_single_inclusive);
515 }
516 };
517}
518
519macro_rules! impl_int_types {
520 ($t:ty, $vec2:ident, $vec3:ident, $vec4:ident) => {
521 use rand::distr::uniform::UniformInt;
522
523 impl_vec_types!($t, $vec2, $vec3, $vec4, UniformInt, 1);
524 };
525}
526
527macro_rules! impl_float_types {
528 ($t:ident, $mat2:ident, $mat3:ident, $mat4:ident, $quat:ident, $vec2:ident, $vec3:ident, $vec4:ident) => {
529 use rand::distr::uniform::UniformFloat;
530
531 impl_vec_types!($t, $vec2, $vec3, $vec4, UniformFloat, 10.0);
532
533 impl Distribution<$mat2> for StandardUniform {
534 #[inline]
535 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $mat2 {
536 $mat2::from_cols_array(&rng.random())
537 }
538 }
539
540 impl Distribution<$mat3> for StandardUniform {
541 #[inline]
542 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $mat3 {
543 $mat3::from_cols_array(&rng.random())
544 }
545 }
546
547 impl Distribution<$mat4> for StandardUniform {
548 #[inline]
549 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $mat4 {
550 $mat4::from_cols_array(&rng.random())
551 }
552 }
553
554 impl Distribution<$quat> for StandardUniform {
555 #[inline]
556 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $quat {
557 let z = rng.random_range::<$t, _>(-1.0..=1.0);
558 let (y, x) = math::sin_cos(rng.random_range::<$t, _>(0.0..TAU));
559 let r = math::sqrt(1.0 - z * z);
560 let axis = $vec3::new(r * x, r * y, z);
561 let angle = rng.random_range::<$t, _>(0.0..TAU);
562 $quat::from_axis_angle(axis, angle)
563 }
564 }
565
566 #[test]
567 fn test_mat2_rand_standard() {
568 use rand::{Rng, SeedableRng};
569 use rand_xoshiro::Xoshiro256Plus;
570 let mut rng1 = Xoshiro256Plus::seed_from_u64(0);
571 let a = $mat2::from_cols_array(&rng1.random::<[$t; 4]>());
572 let mut rng2 = Xoshiro256Plus::seed_from_u64(0);
573 let b = rng2.random::<$mat2>();
574 assert_eq!(a, b);
575 }
576
577 #[test]
578 fn test_mat3_rand_standard() {
579 use rand::{Rng, SeedableRng};
580 use rand_xoshiro::Xoshiro256Plus;
581 let mut rng1 = Xoshiro256Plus::seed_from_u64(0);
582 let a = $mat3::from_cols_array(&rng1.random::<[$t; 9]>());
583 let mut rng2 = Xoshiro256Plus::seed_from_u64(0);
584 let b = rng2.random::<$mat3>();
585 assert_eq!(a, b);
586 }
587
588 #[test]
589 fn test_mat4_rand_standard() {
590 use rand::{Rng, SeedableRng};
591 use rand_xoshiro::Xoshiro256Plus;
592 let mut rng1 = Xoshiro256Plus::seed_from_u64(0);
593 let a = $mat4::from_cols_array(&rng1.random::<[$t; 16]>());
594 let mut rng2 = Xoshiro256Plus::seed_from_u64(0);
595 let b = rng2.random::<$mat4>();
596 assert_eq!(a, b);
597 }
598
599 #[test]
600 fn test_quat_rand_standard() {
601 use rand::{Rng, SeedableRng};
602 use rand_xoshiro::Xoshiro256Plus;
603 let mut rng1 = Xoshiro256Plus::seed_from_u64(0);
604 let a: $quat = rng1.random();
605 assert!(a.is_normalized());
606 let mut rng2 = Xoshiro256Plus::seed_from_u64(0);
607 let b: $quat = rng2.random();
608 assert_eq!(a, b);
609 }
610 };
611}
612
613#[derive(Clone, Copy, Debug, PartialEq)]
614pub struct UniformVec2<G> {
615 x_gen: G,
616 y_gen: G,
617}
618
619#[derive(Clone, Copy, Debug, PartialEq)]
620pub struct UniformVec3<G> {
621 x_gen: G,
622 y_gen: G,
623 z_gen: G,
624}
625
626#[derive(Clone, Copy, Debug, PartialEq)]
627pub struct UniformVec4<G> {
628 x_gen: G,
629 y_gen: G,
630 z_gen: G,
631 w_gen: G,
632}
633
634mod f32 {
635 use crate::f32::math;
636 use crate::{Mat2, Mat3, Mat4, Quat, Vec2, Vec3, Vec3A, Vec4};
637 use core::f32::consts::TAU;
638
639 impl_float_types!(f32, Mat2, Mat3, Mat4, Quat, Vec2, Vec3, Vec4);
640
641 impl Distribution<Vec3A> for StandardUniform {
642 #[inline]
643 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Vec3A {
644 rng.random::<[f32; 3]>().into()
645 }
646 }
647
648 #[test]
649 fn test_vec3a_rand_standard() {
650 use rand::{Rng, SeedableRng};
651 use rand_xoshiro::Xoshiro256Plus;
652 let mut rng1 = Xoshiro256Plus::seed_from_u64(0);
653 let a: (f32, f32, f32) = rng1.random();
654 let mut rng2 = Xoshiro256Plus::seed_from_u64(0);
655 let b: Vec3A = rng2.random();
656 assert_eq!(a, b.into());
657 }
658}
659
660mod f64 {
661 use crate::f64::math;
662 use crate::{DMat2, DMat3, DMat4, DQuat, DVec2, DVec3, DVec4};
663 use core::f64::consts::TAU;
664
665 impl_float_types!(f64, DMat2, DMat3, DMat4, DQuat, DVec2, DVec3, DVec4);
666}
667
668mod i8 {
669 use crate::{I8Vec2, I8Vec3, I8Vec4};
670
671 impl_int_types!(i8, I8Vec2, I8Vec3, I8Vec4);
672}
673
674mod i16 {
675 use crate::{I16Vec2, I16Vec3, I16Vec4};
676
677 impl_int_types!(i16, I16Vec2, I16Vec3, I16Vec4);
678}
679
680mod i32 {
681 use crate::{IVec2, IVec3, IVec4};
682
683 impl_int_types!(i32, IVec2, IVec3, IVec4);
684}
685
686mod i64 {
687 use crate::{I64Vec2, I64Vec3, I64Vec4};
688
689 impl_int_types!(i64, I64Vec2, I64Vec3, I64Vec4);
690}
691
692mod u8 {
693 use crate::{U8Vec2, U8Vec3, U8Vec4};
694
695 impl_int_types!(u8, U8Vec2, U8Vec3, U8Vec4);
696}
697
698mod u16 {
699 use crate::{U16Vec2, U16Vec3, U16Vec4};
700
701 impl_int_types!(u16, U16Vec2, U16Vec3, U16Vec4);
702}
703
704mod u32 {
705 use crate::{UVec2, UVec3, UVec4};
706
707 impl_int_types!(u32, UVec2, UVec3, UVec4);
708}
709
710mod u64 {
711 use crate::{U64Vec2, U64Vec3, U64Vec4};
712
713 impl_int_types!(u64, U64Vec2, U64Vec3, U64Vec4);
714}