@@ -6,6 +6,59 @@ use crate::Vec3;
6
6
pub struct Ray {
7
7
/// The origin of the ray.
8
8
pub origin : Vec3 ,
9
- /// The direction of the ray.
9
+ /// A normalized vector representing the direction of the ray.
10
10
pub direction : Vec3 ,
11
11
}
12
+
13
+ impl Ray {
14
+ /// Returns the distance to the plane if the ray intersects it.
15
+ #[ inline]
16
+ pub fn intersect_plane ( & self , plane_origin : Vec3 , plane_normal : Vec3 ) -> Option < f32 > {
17
+ let denominator = plane_normal. dot ( self . direction ) ;
18
+ if denominator. abs ( ) > f32:: EPSILON {
19
+ let distance = ( plane_origin - self . origin ) . dot ( plane_normal) / denominator;
20
+ if distance >= f32:: EPSILON {
21
+ return Some ( distance) ;
22
+ }
23
+ }
24
+ None
25
+ }
26
+
27
+ /// Retrieve a point at the given distance along the ray.
28
+ #[ inline]
29
+ pub fn get_point ( & self , distance : f32 ) -> Vec3 {
30
+ self . origin + self . direction * distance
31
+ }
32
+ }
33
+
34
+ #[ cfg( test) ]
35
+ mod test {
36
+ use super :: * ;
37
+
38
+ #[ test]
39
+ fn intersects_plane ( ) {
40
+ let ray = Ray {
41
+ origin : Vec3 :: ZERO ,
42
+ direction : Vec3 :: Z ,
43
+ } ;
44
+
45
+ // Orthogonal, and test that plane_normal direction doesn't matter
46
+ assert_eq ! ( Some ( 1. ) , ray. intersect_plane( Vec3 :: Z , Vec3 :: Z ) ) ;
47
+ assert_eq ! ( Some ( 1. ) , ray. intersect_plane( Vec3 :: Z , Vec3 :: NEG_Z ) ) ;
48
+ assert_eq ! ( None , ray. intersect_plane( Vec3 :: NEG_Z , Vec3 :: Z ) ) ;
49
+ assert_eq ! ( None , ray. intersect_plane( Vec3 :: NEG_Z , Vec3 :: NEG_Z ) ) ;
50
+
51
+ // Diagonal
52
+ assert_eq ! ( Some ( 1. ) , ray. intersect_plane( Vec3 :: Z , Vec3 :: ONE ) ) ;
53
+ assert_eq ! ( None , ray. intersect_plane( Vec3 :: NEG_Z , Vec3 :: ONE ) ) ;
54
+
55
+ // Parralel
56
+ assert_eq ! ( None , ray. intersect_plane( Vec3 :: X , Vec3 :: X ) ) ;
57
+
58
+ // Parralel with simulated rounding error
59
+ assert_eq ! (
60
+ None ,
61
+ ray. intersect_plane( Vec3 :: X , Vec3 :: X + Vec3 :: Z * f32 :: EPSILON )
62
+ ) ;
63
+ }
64
+ }
0 commit comments