bevy/crates/bevy_math/src
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
..
bounding Add scale_around_center method to BoundingVolume trait (#12142) 2024-03-11 21:48:25 +00:00
primitives Change Tetrahedron default origin to (0, 0, 0) (#12867) 2024-04-03 23:00:54 +00:00
rects Replace or document ignored doctests (#11040) 2024-01-01 16:50:56 +00:00
sampling Random sampling of directions and quaternions (#12857) 2024-04-04 23:13:00 +00:00
affine3.rs Automatic batching/instancing of draw commands (#9685) 2023-09-21 22:12:34 +00:00
aspect_ratio.rs Implement basic traits for AspectRatio (#12840) 2024-04-01 23:02:07 +00:00
common_traits.rs Remove VectorSpace impl on Quat (#12796) 2024-03-30 17:18:52 +00:00
cubic_splines.rs Move Point out of cubic splines module and expand it (#12747) 2024-03-28 13:40:26 +00:00
direction.rs Remove redundant imports (#12817) 2024-04-01 19:59:08 +00:00
float_ord.rs Move FloatOrd into bevy_math (#12732) 2024-03-27 18:30:11 +00:00
lib.rs Random sampling of directions and quaternions (#12857) 2024-04-04 23:13:00 +00:00
ray.rs Rename Direction2d/3d to Dir2/3 (#12189) 2024-02-28 22:48:43 +00:00
rotation2d.rs Add Rotation2d (#11658) 2024-03-11 19:11:57 +00:00