bevy/crates/bevy_math/src/lib.rs
Matty 3a7923ea92
Random sampling of directions and quaternions (#12857)
# Objective

Augment Bevy's random sampling capabilities by providing good tools for
producing random directions and rotations.

## Solution

The `rand` crate has a natural tool for providing `Distribution`s whose
output is a type that doesn't require any additional data to sample
values — namely,
[`Standard`](https://docs.rs/rand/latest/rand/distributions/struct.Standard.html).

Here, our existing `ShapeSample` implementations have been put to good
use in providing these, resulting in patterns like the following:
```rust
// Using thread-local rng
let random_direction1: Dir3 = random();

// Using an explicit rng
let random_direction2: Dir3 = rng.gen();

// Using an explicit rng coupled explicitly with Standard
let random_directions: Vec<Dir3> = rng.sample_iter(Standard).take(5).collect();
```

Furthermore, we have introduced a trait `FromRng` which provides sugar
for `rng.gen()` that is more namespace-friendly (in this author's
opinion):
```rust
let random_direction = Dir3::from_rng(rng);
```

The types this has been implemented for are `Dir2`, `Dir3`, `Dir3A`, and
`Quat`. Notably, `Quat` uses `glam`'s implementation rather than an
in-house one, and as a result, `bevy_math`'s "rand" feature now enables
that of `glam`.

---

## Changelog

- Created `standard` submodule in `sampling` to hold implementations and
other items related to the `Standard` distribution.
- "rand" feature of `bevy_math` now enables that of `glam`.

---

## Discussion

From a quick glance at `Quat`'s distribution implementation in `glam`, I
am a bit suspicious, since it is simple and doesn't match any algorithm
that I came across in my research. I will do a little more digging as a
follow-up to this and see if it's actually uniform (maybe even using
those tools I wrote — what a thrill).

As an aside, I'd also like to say that I think
[`Distribution`](https://docs.rs/rand/latest/rand/distributions/trait.Distribution.html)
is really, really good. It integrates with distributions provided
externally (e.g. in `rand` itself and its extensions) along with doing a
good job of isolating the source of randomness, so that output can be
reliably reproduced if need be. Finally, `Distribution::sample_iter` is
quite good for ergonomically acquiring lots of random values. At one
point I found myself writing traits to describe random sampling and
essentially reinvented this one. I just think it's good, and I think
it's worth centralizing around to a significant extent.
2024-04-04 23:13:00 +00:00

60 lines
1.7 KiB
Rust

#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![forbid(unsafe_code)]
#![doc(
html_logo_url = "https://bevyengine.org/assets/icon.png",
html_favicon_url = "https://bevyengine.org/assets/icon.png"
)]
//! Provides math types and functionality for the Bevy game engine.
//!
//! The commonly used types are vectors like [`Vec2`] and [`Vec3`],
//! matrices like [`Mat2`], [`Mat3`] and [`Mat4`] and orientation representations
//! like [`Quat`].
mod affine3;
mod aspect_ratio;
pub mod bounding;
mod common_traits;
pub mod cubic_splines;
mod direction;
mod float_ord;
pub mod primitives;
mod ray;
mod rects;
mod rotation2d;
#[cfg(feature = "rand")]
pub mod sampling;
pub use affine3::*;
pub use aspect_ratio::AspectRatio;
pub use common_traits::*;
pub use direction::*;
pub use float_ord::*;
pub use ray::{Ray2d, Ray3d};
pub use rects::*;
pub use rotation2d::Rotation2d;
#[cfg(feature = "rand")]
pub use sampling::{FromRng, ShapeSample};
/// The `bevy_math` prelude.
pub mod prelude {
#[doc(hidden)]
#[cfg(feature = "rand")]
pub use crate::sampling::{FromRng, ShapeSample};
#[doc(hidden)]
pub use crate::{
cubic_splines::{
CubicBSpline, CubicBezier, CubicCardinalSpline, CubicCurve, CubicGenerator,
CubicHermite, CubicNurbs, CubicNurbsError, CubicSegment, RationalCurve,
RationalGenerator, RationalSegment,
},
direction::{Dir2, Dir3, Dir3A},
primitives::*,
BVec2, BVec3, BVec4, EulerRot, FloatExt, IRect, IVec2, IVec3, IVec4, Mat2, Mat3, Mat4,
Quat, Ray2d, Ray3d, Rect, Rotation2d, URect, UVec2, UVec3, UVec4, Vec2, Vec2Swizzles, Vec3,
Vec3Swizzles, Vec4, Vec4Swizzles,
};
}
pub use glam::*;