Skip to content
38 changes: 32 additions & 6 deletions crates/bevy_math/src/ray.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,21 @@ pub struct Ray2d {
}

impl Ray2d {
/// Create a new `Ray2d` from a given origin and direction
/// Creates a new `Ray2d` from a given origin and direction
#[inline]
pub const fn new(origin: Vec2, direction: Dir2) -> Self {
Self { origin, direction }
}

/// Get a point at a given distance along the ray
/// Returns the point at a given distance along the ray.
#[inline]
pub fn get_point(&self, distance: f32) -> Vec2 {
self.origin + *self.direction * distance
}

/// Get the distance to a plane if the ray intersects it
/// Returns the distance to a plane if the ray intersects it.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should mention the new method here too :)

///
/// Use [`Ray2d::plane_intersection_point`] to get the intersection point directly.
#[inline]
pub fn intersect_plane(&self, plane_origin: Vec2, plane: Plane2d) -> Option<f32> {
let denominator = plane.normal.dot(*self.direction);
Expand All @@ -53,6 +55,15 @@ impl Ray2d {
}
None
}

/// Returns the intersection point with a plane, if it exists.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These docs should call out that it's a combination of the other two methods.

///
/// Calls [`Ray2d::get_point`] on the result of [`Ray2d::intersect_plane`].
#[inline]
pub fn plane_intersection_point(&self, plane_origin: Vec2, plane: Plane2d) -> Option<Vec2> {
self.intersect_plane(plane_origin, plane)
.map(|distance| self.get_point(distance))
}
}

/// An infinite half-line starting at `origin` and going in `direction` in 3D space.
Expand All @@ -75,19 +86,21 @@ pub struct Ray3d {
}

impl Ray3d {
/// Create a new `Ray3d` from a given origin and direction
/// Creates a new `Ray3d` from a given origin and direction
#[inline]
pub const fn new(origin: Vec3, direction: Dir3) -> Self {
Self { origin, direction }
}

/// Get a point at a given distance along the ray
/// Returns the point at a given distance along the ray
#[inline]
pub fn get_point(&self, distance: f32) -> Vec3 {
self.origin + *self.direction * distance
}

/// Get the distance to a plane if the ray intersects it
/// Returns the distance to a plane if the ray intersects it
///
/// Use [`Ray3d::plane_intersection_point`] to get the intersection point directly.
#[inline]
pub fn intersect_plane(&self, plane_origin: Vec3, plane: InfinitePlane3d) -> Option<f32> {
let denominator = plane.normal.dot(*self.direction);
Expand All @@ -99,6 +112,19 @@ impl Ray3d {
}
None
}

/// Returns the intersection point of the ray with a plane, if it exists.
///
/// Calls [`Ray3d::get_point`] on the result of [`Ray3d::intersect_plane`].
#[inline]
pub fn plane_intersection_point(
&self,
plane_origin: Vec3,
plane: InfinitePlane3d,
) -> Option<Vec3> {
self.intersect_plane(plane_origin, plane)
.map(|distance| self.get_point(distance))
}
}

#[cfg(test)]
Expand Down
7 changes: 2 additions & 5 deletions examples/3d/3d_viewport_to_world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,9 @@ fn draw_cursor(
if let Some(cursor_position) = window.cursor_position()
// Calculate a ray pointing from the camera into the world based on the cursor's position.
&& let Ok(ray) = camera.viewport_to_world(camera_transform, cursor_position)
// Calculate if and at what distance the ray is hitting the ground plane.
&& let Some(distance) =
ray.intersect_plane(ground.translation(), InfinitePlane3d::new(ground.up()))
// Calculate if and where the ray is hitting the ground plane.
&& let Some(point) = ray.plane_intersection_point(ground.translation(), InfinitePlane3d::new(ground.up()))
{
let point = ray.get_point(distance);

// Draw a circle just above the ground plane at that position.
gizmos.circle(
Isometry3d::new(
Expand Down
6 changes: 3 additions & 3 deletions examples/3d/irradiance_volumes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -466,11 +466,11 @@ fn handle_mouse_clicks(
let Ok(ray) = camera.viewport_to_world(camera_transform, mouse_position) else {
return;
};
let Some(ray_distance) = ray.intersect_plane(Vec3::ZERO, InfinitePlane3d::new(Vec3::Y)) else {
let Some(plane_intersection) =
ray.plane_intersection_point(Vec3::ZERO, InfinitePlane3d::new(Vec3::Y))
else {
return;
};
let plane_intersection = ray.origin + ray.direction.normalize() * ray_distance;

// Move all the main objects.
for mut transform in main_objects.iter_mut() {
transform.translation = vec3(
Expand Down