use na::{ self, Isometry2, Isometry3, Matrix2, Matrix3, Matrix4, Point2, Point3, Point4, RealField, Vector2, Vector3, Vector4, }; use ncollide3d::bounding_volume::{BoundingSphere, AABB}; use ncollide3d::query::Ray; use ncollide3d::shape::{Ball, Capsule, Cone, ConvexHull, Cuboid, Cylinder, Segment, Triangle}; use rand::distributions::{Distribution, Standard}; use rand::Rng; pub trait DefaultGen { fn generate(rng: &mut R) -> Self; } pub fn generate(rng: &mut R) -> T { DefaultGen::generate(rng) } macro_rules! impl_rand_default_gen ( ($t: ty) => { impl DefaultGen for $t { fn generate(rng: &mut R) -> $t { rng.gen::<$t>() } } } ); impl_rand_default_gen!(Vector2); impl_rand_default_gen!(Vector3); impl_rand_default_gen!(Vector4); impl_rand_default_gen!(Point2); impl_rand_default_gen!(Point3); impl_rand_default_gen!(Point4); impl_rand_default_gen!(Matrix2); impl_rand_default_gen!(Matrix3); impl_rand_default_gen!(Matrix4); impl_rand_default_gen!(Isometry2); impl_rand_default_gen!(Isometry3); impl_rand_default_gen!(Vector2); impl_rand_default_gen!(Vector3); impl_rand_default_gen!(Vector4); impl_rand_default_gen!(Point2); impl_rand_default_gen!(Point3); impl_rand_default_gen!(Point4); impl_rand_default_gen!(Matrix2); impl_rand_default_gen!(Matrix3); impl_rand_default_gen!(Matrix4); impl_rand_default_gen!(Isometry2); impl_rand_default_gen!(Isometry3); impl_rand_default_gen!(f32); impl_rand_default_gen!(f64); impl_rand_default_gen!(bool); impl DefaultGen for Ball where Standard: Distribution, { fn generate(rng: &mut R) -> Ball { Ball::new(rng.gen::().abs()) } } impl DefaultGen for Cuboid where Standard: Distribution>, { fn generate(rng: &mut R) -> Cuboid { Cuboid::new(rng.gen::>().abs()) } } impl DefaultGen for Capsule where Standard: Distribution, { fn generate(rng: &mut R) -> Capsule { Capsule::new(rng.gen::().abs(), rng.gen::().abs()) } } impl DefaultGen for Cone where Standard: Distribution, { fn generate(rng: &mut R) -> Cone { Cone::new(rng.gen::().abs(), rng.gen::().abs()) } } impl DefaultGen for Cylinder where Standard: Distribution, { fn generate(rng: &mut R) -> Cylinder { Cylinder::new(rng.gen::().abs(), rng.gen::().abs()) } } impl DefaultGen for Segment where Standard: Distribution>, { fn generate(rng: &mut R) -> Segment { Segment::new(rng.gen(), rng.gen()) } } impl DefaultGen for Triangle where Standard: Distribution>, { fn generate(rng: &mut R) -> Triangle { Triangle::new(rng.gen(), rng.gen(), rng.gen()) } } impl DefaultGen for ConvexHull where Standard: Distribution>, { fn generate(rng: &mut R) -> ConvexHull { // It is recommended to have at most 100 points. // Otherwise, a smarter structure like the DK hierarchy would be needed. let pts: Vec<_> = (0..100).map(|_| rng.gen()).collect(); ConvexHull::try_from_points(&pts).unwrap() } } impl DefaultGen for Ray where Standard: Distribution>, { fn generate(rng: &mut R) -> Ray { // The generate ray will always point to the origin. let shift = rng.gen::>() * na::convert::<_, N>(10.0f64); Ray::new(Point3::origin() + shift, -shift) } } impl DefaultGen for AABB where Standard: Distribution>, { fn generate(rng: &mut R) -> AABB { // an AABB centered at the origin. let half_extents = rng.gen::>().abs(); AABB::new( Point3::origin() + (-half_extents), Point3::origin() + half_extents, ) } } impl DefaultGen for BoundingSphere where Standard: Distribution, { fn generate(rng: &mut R) -> BoundingSphere { // a bounding sphere centered at the origin. BoundingSphere::new(Point3::origin(), rng.gen::().abs()) } }