From 6f7fefd9f5fe02aae2b42fa06e3924f6aa2d205e Mon Sep 17 00:00:00 2001 From: devil-ira Date: Thu, 6 Oct 2022 11:06:16 +0200 Subject: [PATCH 1/8] intersects_plane --- crates/bevy_math/src/ray.rs | 49 +++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/crates/bevy_math/src/ray.rs b/crates/bevy_math/src/ray.rs index cd1ec2b552d45..b33fdaad236b0 100644 --- a/crates/bevy_math/src/ray.rs +++ b/crates/bevy_math/src/ray.rs @@ -9,3 +9,52 @@ pub struct Ray { /// The direction of the ray. pub direction: Vec3, } + +impl Ray { + /// Returns true if this ray intersects the plane. + pub fn intersects_plane(&self, plane_origin: Vec3, plane_normal: Vec3) -> bool { + let denom = plane_normal.dot(self.direction); + if denom.abs() > f32::EPSILON { + let t = (plane_origin - self.origin).dot(plane_normal) / denom; + if t >= f32::EPSILON { + return true; + } + } + false + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn intersects_plane() { + let ray = Ray { + origin: Vec3::ZERO, + direction: Vec3::Z, + }; + + // Orthogonal + assert!(ray.intersects_plane(Vec3::Z, Vec3::Z)); + assert!(ray.intersects_plane(Vec3::Z, Vec3::NEG_Z)); + assert!(!ray.intersects_plane(Vec3::NEG_Z, Vec3::Z)); + assert!(!ray.intersects_plane(Vec3::NEG_Z, Vec3::NEG_Z)); + + // Diagonal + assert!(ray.intersects_plane(Vec3::Z, Vec3::ONE)); + assert!(ray.intersects_plane(Vec3::Z, Vec3::NEG_ONE)); + assert!(!ray.intersects_plane(Vec3::NEG_Z, Vec3::ONE)); + assert!(!ray.intersects_plane(Vec3::NEG_Z, Vec3::NEG_ONE)); + + // Parralel + assert!(!ray.intersects_plane(Vec3::X, Vec3::X)); + assert!(!ray.intersects_plane(Vec3::X, Vec3::NEG_X)); + assert!(!ray.intersects_plane(Vec3::NEG_X, Vec3::X)); + assert!(!ray.intersects_plane(Vec3::NEG_X, Vec3::NEG_X)); + + // Parralel with simulated rounding error + assert!(!ray.intersects_plane(Vec3::X, Vec3::X + Vec3::Z * f32::EPSILON)); + assert!(!ray.intersects_plane(Vec3::NEG_X, Vec3::X + Vec3::NEG_Z * f32::EPSILON)); + } +} From e9804b1351a88346346e6a7682b8a2f63c41d4ac Mon Sep 17 00:00:00 2001 From: devil-ira Date: Thu, 6 Oct 2022 11:12:09 +0200 Subject: [PATCH 2/8] get_point Co-authored-by: sark --- crates/bevy_math/src/ray.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/crates/bevy_math/src/ray.rs b/crates/bevy_math/src/ray.rs index b33fdaad236b0..218dec4db7220 100644 --- a/crates/bevy_math/src/ray.rs +++ b/crates/bevy_math/src/ray.rs @@ -22,6 +22,11 @@ impl Ray { } false } + + /// Retrieve a point at the given distance along the ray. + pub fn get_point(&self, distance: f32) -> Vec3 { + self.origin + self.direction * distance + } } #[cfg(test)] From 5507cbc3b996b46d1b929e53b0a169f117d4e33f Mon Sep 17 00:00:00 2001 From: devil-ira Date: Thu, 6 Oct 2022 11:24:34 +0200 Subject: [PATCH 3/8] simplify, fmt --- crates/bevy_math/src/ray.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/crates/bevy_math/src/ray.rs b/crates/bevy_math/src/ray.rs index 218dec4db7220..b123cfa5ff6de 100644 --- a/crates/bevy_math/src/ray.rs +++ b/crates/bevy_math/src/ray.rs @@ -16,13 +16,11 @@ impl Ray { let denom = plane_normal.dot(self.direction); if denom.abs() > f32::EPSILON { let t = (plane_origin - self.origin).dot(plane_normal) / denom; - if t >= f32::EPSILON { - return true; - } + return t >= f32::EPSILON; } false } - + /// Retrieve a point at the given distance along the ray. pub fn get_point(&self, distance: f32) -> Vec3 { self.origin + self.direction * distance @@ -51,7 +49,7 @@ mod test { assert!(ray.intersects_plane(Vec3::Z, Vec3::NEG_ONE)); assert!(!ray.intersects_plane(Vec3::NEG_Z, Vec3::ONE)); assert!(!ray.intersects_plane(Vec3::NEG_Z, Vec3::NEG_ONE)); - + // Parralel assert!(!ray.intersects_plane(Vec3::X, Vec3::X)); assert!(!ray.intersects_plane(Vec3::X, Vec3::NEG_X)); From ab5765ddd6c879d15691ff3942e0811f6094c4d8 Mon Sep 17 00:00:00 2001 From: devil-ira Date: Thu, 6 Oct 2022 11:30:14 +0200 Subject: [PATCH 4/8] doc --- crates/bevy_math/src/ray.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_math/src/ray.rs b/crates/bevy_math/src/ray.rs index b123cfa5ff6de..7e09e8f96da74 100644 --- a/crates/bevy_math/src/ray.rs +++ b/crates/bevy_math/src/ray.rs @@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize}; pub struct Ray { /// The origin of the ray. pub origin: Vec3, - /// The direction of the ray. + /// A normalized vector representing the direction of the ray. pub direction: Vec3, } From 34617437cb39705526fe9ff047d3cd8caaa225e4 Mon Sep 17 00:00:00 2001 From: devil-ira Date: Thu, 6 Oct 2022 12:20:08 +0200 Subject: [PATCH 5/8] return option --- crates/bevy_math/src/ray.rs | 44 +++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/crates/bevy_math/src/ray.rs b/crates/bevy_math/src/ray.rs index 7e09e8f96da74..2d1f61f8adbe9 100644 --- a/crates/bevy_math/src/ray.rs +++ b/crates/bevy_math/src/ray.rs @@ -11,14 +11,16 @@ pub struct Ray { } impl Ray { - /// Returns true if this ray intersects the plane. - pub fn intersects_plane(&self, plane_origin: Vec3, plane_normal: Vec3) -> bool { - let denom = plane_normal.dot(self.direction); - if denom.abs() > f32::EPSILON { - let t = (plane_origin - self.origin).dot(plane_normal) / denom; - return t >= f32::EPSILON; + /// Returns some distance to the plane if the ray intersects it. + pub fn intersect_plane(&self, plane_origin: Vec3, plane_normal: Vec3) -> Option { + let denominator = plane_normal.dot(self.direction); + if denominator.abs() > f32::EPSILON { + let distance = (plane_origin - self.origin).dot(plane_normal) / denominator; + if distance >= f32::EPSILON { + return Some(distance); + } } - false + None } /// Retrieve a point at the given distance along the ray. @@ -39,25 +41,25 @@ mod test { }; // Orthogonal - assert!(ray.intersects_plane(Vec3::Z, Vec3::Z)); - assert!(ray.intersects_plane(Vec3::Z, Vec3::NEG_Z)); - assert!(!ray.intersects_plane(Vec3::NEG_Z, Vec3::Z)); - assert!(!ray.intersects_plane(Vec3::NEG_Z, Vec3::NEG_Z)); + assert_eq!(Some(1.), ray.intersect_plane(Vec3::Z, Vec3::Z)); + assert_eq!(Some(1.), ray.intersect_plane(Vec3::Z, Vec3::NEG_Z)); + assert_eq!(None, ray.intersect_plane(Vec3::NEG_Z, Vec3::Z)); + assert_eq!(None, ray.intersect_plane(Vec3::NEG_Z, Vec3::NEG_Z)); // Diagonal - assert!(ray.intersects_plane(Vec3::Z, Vec3::ONE)); - assert!(ray.intersects_plane(Vec3::Z, Vec3::NEG_ONE)); - assert!(!ray.intersects_plane(Vec3::NEG_Z, Vec3::ONE)); - assert!(!ray.intersects_plane(Vec3::NEG_Z, Vec3::NEG_ONE)); + assert_eq!(Some(1.), ray.intersect_plane(Vec3::Z, Vec3::ONE)); + assert_eq!(Some(1.), ray.intersect_plane(Vec3::Z, Vec3::NEG_ONE)); + assert_eq!(None, ray.intersect_plane(Vec3::NEG_Z, Vec3::ONE)); + assert_eq!(None, ray.intersect_plane(Vec3::NEG_Z, Vec3::NEG_ONE)); // Parralel - assert!(!ray.intersects_plane(Vec3::X, Vec3::X)); - assert!(!ray.intersects_plane(Vec3::X, Vec3::NEG_X)); - assert!(!ray.intersects_plane(Vec3::NEG_X, Vec3::X)); - assert!(!ray.intersects_plane(Vec3::NEG_X, Vec3::NEG_X)); + assert_eq!(None, ray.intersect_plane(Vec3::X, Vec3::X)); + assert_eq!(None, ray.intersect_plane(Vec3::X, Vec3::NEG_X)); + assert_eq!(None, ray.intersect_plane(Vec3::NEG_X, Vec3::X)); + assert_eq!(None, ray.intersect_plane(Vec3::NEG_X, Vec3::NEG_X)); // Parralel with simulated rounding error - assert!(!ray.intersects_plane(Vec3::X, Vec3::X + Vec3::Z * f32::EPSILON)); - assert!(!ray.intersects_plane(Vec3::NEG_X, Vec3::X + Vec3::NEG_Z * f32::EPSILON)); + assert_eq!(None, ray.intersect_plane(Vec3::X, Vec3::X + Vec3::Z * f32::EPSILON)); + assert_eq!(None, ray.intersect_plane(Vec3::NEG_X, Vec3::X + Vec3::NEG_Z * f32::EPSILON)); } } From 20b6f33f120f9e4cb5005c5ad66561fa481e3486 Mon Sep 17 00:00:00 2001 From: devil-ira Date: Thu, 6 Oct 2022 12:35:50 +0200 Subject: [PATCH 6/8] inline --- crates/bevy_math/src/ray.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/bevy_math/src/ray.rs b/crates/bevy_math/src/ray.rs index 2d1f61f8adbe9..5c3e0f6b9cb8e 100644 --- a/crates/bevy_math/src/ray.rs +++ b/crates/bevy_math/src/ray.rs @@ -12,6 +12,7 @@ pub struct Ray { impl Ray { /// Returns some distance to the plane if the ray intersects it. + #[inline] pub fn intersect_plane(&self, plane_origin: Vec3, plane_normal: Vec3) -> Option { let denominator = plane_normal.dot(self.direction); if denominator.abs() > f32::EPSILON { @@ -24,6 +25,7 @@ impl Ray { } /// Retrieve a point at the given distance along the ray. + #[inline] pub fn get_point(&self, distance: f32) -> Vec3 { self.origin + self.direction * distance } From 2c83b9b9b00687a3d50f5b0ffba285ac3833bbaa Mon Sep 17 00:00:00 2001 From: devil-ira Date: Thu, 6 Oct 2022 12:45:47 +0200 Subject: [PATCH 7/8] reduce test --- crates/bevy_math/src/ray.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/crates/bevy_math/src/ray.rs b/crates/bevy_math/src/ray.rs index 5c3e0f6b9cb8e..240ba80e6126c 100644 --- a/crates/bevy_math/src/ray.rs +++ b/crates/bevy_math/src/ray.rs @@ -42,7 +42,7 @@ mod test { direction: Vec3::Z, }; - // Orthogonal + // Orthogonal, and test that plane_normal direction doesn't matter assert_eq!(Some(1.), ray.intersect_plane(Vec3::Z, Vec3::Z)); assert_eq!(Some(1.), ray.intersect_plane(Vec3::Z, Vec3::NEG_Z)); assert_eq!(None, ray.intersect_plane(Vec3::NEG_Z, Vec3::Z)); @@ -50,18 +50,12 @@ mod test { // Diagonal assert_eq!(Some(1.), ray.intersect_plane(Vec3::Z, Vec3::ONE)); - assert_eq!(Some(1.), ray.intersect_plane(Vec3::Z, Vec3::NEG_ONE)); assert_eq!(None, ray.intersect_plane(Vec3::NEG_Z, Vec3::ONE)); - assert_eq!(None, ray.intersect_plane(Vec3::NEG_Z, Vec3::NEG_ONE)); // Parralel assert_eq!(None, ray.intersect_plane(Vec3::X, Vec3::X)); - assert_eq!(None, ray.intersect_plane(Vec3::X, Vec3::NEG_X)); - assert_eq!(None, ray.intersect_plane(Vec3::NEG_X, Vec3::X)); - assert_eq!(None, ray.intersect_plane(Vec3::NEG_X, Vec3::NEG_X)); // Parralel with simulated rounding error assert_eq!(None, ray.intersect_plane(Vec3::X, Vec3::X + Vec3::Z * f32::EPSILON)); - assert_eq!(None, ray.intersect_plane(Vec3::NEG_X, Vec3::X + Vec3::NEG_Z * f32::EPSILON)); } } From 418dcc42318b7168a7ac109a19f778b67bc100c6 Mon Sep 17 00:00:00 2001 From: devil-ira Date: Thu, 6 Oct 2022 12:50:25 +0200 Subject: [PATCH 8/8] fmt --- crates/bevy_math/src/ray.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/crates/bevy_math/src/ray.rs b/crates/bevy_math/src/ray.rs index 240ba80e6126c..e7f031ad872f8 100644 --- a/crates/bevy_math/src/ray.rs +++ b/crates/bevy_math/src/ray.rs @@ -11,7 +11,7 @@ pub struct Ray { } impl Ray { - /// Returns some distance to the plane if the ray intersects it. + /// Returns the distance to the plane if the ray intersects it. #[inline] pub fn intersect_plane(&self, plane_origin: Vec3, plane_normal: Vec3) -> Option { let denominator = plane_normal.dot(self.direction); @@ -56,6 +56,9 @@ mod test { assert_eq!(None, ray.intersect_plane(Vec3::X, Vec3::X)); // Parralel with simulated rounding error - assert_eq!(None, ray.intersect_plane(Vec3::X, Vec3::X + Vec3::Z * f32::EPSILON)); + assert_eq!( + None, + ray.intersect_plane(Vec3::X, Vec3::X + Vec3::Z * f32::EPSILON) + ); } }