glam_det 2.0.0

A simple and fast 3D math library for games and graphics.
Documentation
// Copyright (C) 2020-2025 glam-det authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

macro_rules! impl_vec_types {
    ($t:ty, $vec2:ident, $vec3:ident, $vec4:ident) => {
        impl Distribution<$vec2> for Standard {
            #[inline]
            fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $vec2 {
                rng.gen::<[$t; 2]>().into()
            }
        }

        impl Distribution<$vec3> for Standard {
            #[inline]
            fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $vec3 {
                rng.gen::<[$t; 3]>().into()
            }
        }

        impl Distribution<$vec4> for Standard {
            #[inline]
            fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $vec4 {
                rng.gen::<[$t; 4]>().into()
            }
        }

        #[test]
        fn test_vec2_rand() {
            use rand::{Rng, SeedableRng};
            use rand_xoshiro::Xoshiro256Plus;
            let mut rng1 = Xoshiro256Plus::seed_from_u64(0);
            let a: ($t, $t) = rng1.gen();
            let mut rng2 = Xoshiro256Plus::seed_from_u64(0);
            let b: $vec2 = rng2.gen();
            assert_eq!(a, b.into());
        }

        #[test]
        fn test_vec3_rand() {
            use rand::{Rng, SeedableRng};
            use rand_xoshiro::Xoshiro256Plus;
            let mut rng1 = Xoshiro256Plus::seed_from_u64(0);
            let a: ($t, $t, $t) = rng1.gen();
            let mut rng2 = Xoshiro256Plus::seed_from_u64(0);
            let b: $vec3 = rng2.gen();
            assert_eq!(a, b.into());
        }

        #[test]
        fn test_vec4_rand() {
            use rand::{Rng, SeedableRng};
            use rand_xoshiro::Xoshiro256Plus;
            let mut rng1 = Xoshiro256Plus::seed_from_u64(0);
            let a: ($t, $t, $t, $t) = rng1.gen();
            let mut rng2 = Xoshiro256Plus::seed_from_u64(0);
            let b: $vec4 = rng2.gen();
            assert_eq!(a, b.into());
        }
    };
}

macro_rules! impl_point_types {
    ($t:ty, $point2:ident, $point3:ident, $point4:ident) => {
        impl Distribution<$point2> for Standard {
            #[inline]
            fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $point2 {
                rng.gen::<[$t; 2]>().into()
            }
        }

        impl Distribution<$point3> for Standard {
            #[inline]
            fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $point3 {
                rng.gen::<[$t; 3]>().into()
            }
        }

        impl Distribution<$point4> for Standard {
            #[inline]
            fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $point4 {
                rng.gen::<[$t; 4]>().into()
            }
        }

        #[test]
        fn test_point2_rand() {
            use rand::{Rng, SeedableRng};
            use rand_xoshiro::Xoshiro256Plus;
            let mut rng1 = Xoshiro256Plus::seed_from_u64(0);
            let a: ($t, $t) = rng1.gen();
            let mut rng2 = Xoshiro256Plus::seed_from_u64(0);
            let b: $point2 = rng2.gen();
            assert_eq!(a, b.into());
        }

        #[test]
        fn test_point3_rand() {
            use rand::{Rng, SeedableRng};
            use rand_xoshiro::Xoshiro256Plus;
            let mut rng1 = Xoshiro256Plus::seed_from_u64(0);
            let a: ($t, $t, $t) = rng1.gen();
            let mut rng2 = Xoshiro256Plus::seed_from_u64(0);
            let b: $point3 = rng2.gen();
            assert_eq!(a, b.into());
        }

        #[test]
        fn test_point4_rand() {
            use rand::{Rng, SeedableRng};
            use rand_xoshiro::Xoshiro256Plus;
            let mut rng1 = Xoshiro256Plus::seed_from_u64(0);
            let a: ($t, $t, $t, $t) = rng1.gen();
            let mut rng2 = Xoshiro256Plus::seed_from_u64(0);
            let b: $point4 = rng2.gen();
            assert_eq!(a, b.into());
        }
    };
}

macro_rules! impl_float_types {
    ($t:ident, $mat2:ident, $mat3:ident, $mat4:ident, $quat:ident, $vec2:ident, $vec3:ident, $vec4:ident, $point2:ident, $point3:ident, $point4:ident) => {
        impl_vec_types!($t, $vec2, $vec3, $vec4);
        impl_point_types!($t, $point2, $point3, $point4);

        impl Distribution<$mat2> for Standard {
            #[inline]
            fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $mat2 {
                $mat2::from_cols_array(&rng.gen())
            }
        }

        impl Distribution<$mat3> for Standard {
            #[inline]
            fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $mat3 {
                $mat3::from_cols_array(&rng.gen())
            }
        }

        impl Distribution<$mat4> for Standard {
            #[inline]
            fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $mat4 {
                $mat4::from_cols_array(&rng.gen())
            }
        }

        impl Distribution<$quat> for Standard {
            #[inline]
            fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $quat {
                let yaw = -PI + rng.gen::<$t>() * 2.0 * PI;
                let pitch = -PI + rng.gen::<$t>() * 2.0 * PI;
                let roll = -PI + rng.gen::<$t>() * 2.0 * PI;
                $quat::from_euler(crate::EulerRot::YXZ, yaw, pitch, roll)
            }
        }

        #[test]
        fn test_mat2_rand() {
            use rand::{Rng, SeedableRng};
            use rand_xoshiro::Xoshiro256Plus;
            let mut rng1 = Xoshiro256Plus::seed_from_u64(0);
            let a = $mat2::from_cols_array(&rng1.gen::<[$t; 4]>());
            let mut rng2 = Xoshiro256Plus::seed_from_u64(0);
            let b = rng2.gen::<$mat2>();
            assert_eq!(a, b);
        }

        #[test]
        fn test_mat3_rand() {
            use rand::{Rng, SeedableRng};
            use rand_xoshiro::Xoshiro256Plus;
            let mut rng1 = Xoshiro256Plus::seed_from_u64(0);
            let a = $mat3::from_cols_array(&rng1.gen::<[$t; 9]>());
            let mut rng2 = Xoshiro256Plus::seed_from_u64(0);
            let b = rng2.gen::<$mat3>();
            assert_eq!(a, b);
        }

        #[test]
        fn test_mat4_rand() {
            use rand::{Rng, SeedableRng};
            use rand_xoshiro::Xoshiro256Plus;
            let mut rng1 = Xoshiro256Plus::seed_from_u64(0);
            let a = $mat4::from_cols_array(&rng1.gen::<[$t; 16]>());
            let mut rng2 = Xoshiro256Plus::seed_from_u64(0);
            let b = rng2.gen::<$mat4>();
            assert_eq!(a, b);
        }

        #[test]
        fn test_quat_rand() {
            use rand::{Rng, SeedableRng};
            use rand_xoshiro::Xoshiro256Plus;
            let mut rng1 = Xoshiro256Plus::seed_from_u64(0);
            let a: $quat = rng1.gen();
            assert!(a.is_normalized());
            let mut rng2 = Xoshiro256Plus::seed_from_u64(0);
            let b: $quat = rng2.gen();
            assert_eq!(a, b);
        }
    };
}

mod f32 {
    use crate::{Mat2, Mat3, Mat4, Point2, Point3, Point4, Quat, Vec2, Vec3, Vec3A, Vec4};
    use core::f32::consts::PI;
    use rand::{
        distributions::{Distribution, Standard},
        Rng,
    };

    impl_float_types!(f32, Mat2, Mat3, Mat4, Quat, Vec2, Vec3, Vec4, Point2, Point3, Point4);

    impl Distribution<Vec3A> for Standard {
        #[inline]
        fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Vec3A {
            rng.gen::<[f32; 3]>().into()
        }
    }

    #[test]
    fn test_vec3a_rand() {
        use rand::{Rng, SeedableRng};
        use rand_xoshiro::Xoshiro256Plus;
        let mut rng1 = Xoshiro256Plus::seed_from_u64(0);
        let a: (f32, f32, f32) = rng1.gen();
        let mut rng2 = Xoshiro256Plus::seed_from_u64(0);
        let b: Vec3A = rng2.gen();
        assert_eq!(a, b.into());
    }
}

mod f64 {
    use crate::{DMat2, DMat3, DMat4, DPoint2, DPoint3, DPoint4, DQuat, DVec2, DVec3, DVec4};
    use core::f64::consts::PI;
    use rand::{
        distributions::{Distribution, Standard},
        Rng,
    };

    impl_float_types!(
        f64, DMat2, DMat3, DMat4, DQuat, DVec2, DVec3, DVec4, DPoint2, DPoint3, DPoint4
    );
}

mod i32 {
    use crate::{IPoint2, IPoint3, IPoint4, IVec2, IVec3, IVec4};
    use rand::{
        distributions::{Distribution, Standard},
        Rng,
    };

    impl_vec_types!(i32, IVec2, IVec3, IVec4);
    impl_point_types!(i32, IPoint2, IPoint3, IPoint4);
}

mod u32 {
    use crate::{UPoint2, UPoint3, UPoint4, UVec2, UVec3, UVec4};
    use rand::{
        distributions::{Distribution, Standard},
        Rng,
    };

    impl_vec_types!(u32, UVec2, UVec3, UVec4);
    impl_point_types!(u32, UPoint2, UPoint3, UPoint4);
}