Skip to content

Commit f6cd6a4

Browse files
authored
Use Dir2/Dir3 instead of Vec2/Vec3 for Ray2d::new/Ray3d::new (#15735)
# Objective The `new` constructors for our ray types currently take a `Vec2`/`Vec3` instead of a `Dir2`/`Dir3`. This is confusing and footgunny for several reasons. - Which one of these is the direction? You can't see it from the type. ```rust let ray = Ray2d::new(Vec2::X, Vec2::X); ``` - Many engines allow unnormalized rays, and this can affect ray cast results by scaling the time of impact. However, in Bevy, rays are *always* normalized despite what the input argument in this case implies, and ray cast results are *not* scaled. ```rust // The true ray direction is still normalized, unlike what you'd expect. let ray = Ray2d::new(Vec2::X, Vec2::new(5.0, 0.0, 0.0))); ``` These cases are what the direction types are intended for, and we should use them as such. ## Solution Use `Dir2`/`Dir3` in the constructors. ```rust let ray = Ray2d::new(Vec2::X, Dir2::X); ``` We *could* also use `impl TryInto<DirN>`, which would allow both vectors and direction types, and then panic if the input is not normalized. This could be fine for ergonomics in some cases, but especially for rays, I think it's better to take an explicit direction type here. --- ## Migration Guide `Ray2d::new` and `Ray3d::new` now take a `Dir2` and `Dir3` instead of `Vec2` and `Vec3` respectively for the ray direction.
1 parent 82aa2e3 commit f6cd6a4

File tree

1 file changed

+6
-20
lines changed

1 file changed

+6
-20
lines changed

crates/bevy_math/src/ray.rs

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,9 @@ pub struct Ray2d {
2525

2626
impl Ray2d {
2727
/// Create a new `Ray2d` from a given origin and direction
28-
///
29-
/// # Panics
30-
///
31-
/// Panics if the given `direction` is zero (or very close to zero), or non-finite.
3228
#[inline]
33-
pub fn new(origin: Vec2, direction: Vec2) -> Self {
34-
Self {
35-
origin,
36-
direction: Dir2::new(direction).expect("ray direction must be nonzero and finite"),
37-
}
29+
pub const fn new(origin: Vec2, direction: Dir2) -> Self {
30+
Self { origin, direction }
3831
}
3932

4033
/// Get a point at a given distance along the ray
@@ -74,16 +67,9 @@ pub struct Ray3d {
7467

7568
impl Ray3d {
7669
/// Create a new `Ray3d` from a given origin and direction
77-
///
78-
/// # Panics
79-
///
80-
/// Panics if the given `direction` is zero (or very close to zero), or non-finite.
8170
#[inline]
82-
pub fn new(origin: Vec3, direction: Vec3) -> Self {
83-
Self {
84-
origin,
85-
direction: Dir3::new(direction).expect("ray direction must be nonzero and finite"),
86-
}
71+
pub const fn new(origin: Vec3, direction: Dir3) -> Self {
72+
Self { origin, direction }
8773
}
8874

8975
/// Get a point at a given distance along the ray
@@ -112,7 +98,7 @@ mod tests {
11298

11399
#[test]
114100
fn intersect_plane_2d() {
115-
let ray = Ray2d::new(Vec2::ZERO, Vec2::Y);
101+
let ray = Ray2d::new(Vec2::ZERO, Dir2::Y);
116102

117103
// Orthogonal, and test that an inverse plane_normal has the same result
118104
assert_eq!(
@@ -152,7 +138,7 @@ mod tests {
152138

153139
#[test]
154140
fn intersect_plane_3d() {
155-
let ray = Ray3d::new(Vec3::ZERO, Vec3::Z);
141+
let ray = Ray3d::new(Vec3::ZERO, Dir3::Z);
156142

157143
// Orthogonal, and test that an inverse plane_normal has the same result
158144
assert_eq!(

0 commit comments

Comments
 (0)