ncollide3d/query/ray/
ray.rs1use crate::math::{Isometry, Point, Vector};
4use crate::shape::FeatureId;
5#[cfg(feature = "dim3")]
6use na::Point2;
7use na::RealField;
8
9#[derive(Debug, Clone, Copy)]
11pub struct Ray<N: RealField + Copy> {
12 pub origin: Point<N>,
14 pub dir: Vector<N>,
16}
17
18impl<N: RealField + Copy> Ray<N> {
19 pub fn new(origin: Point<N>, dir: Vector<N>) -> Ray<N> {
22 Ray {
23 origin: origin,
24 dir: dir,
25 }
26 }
27
28 #[inline]
30 pub fn transform_by(&self, m: &Isometry<N>) -> Self {
31 Self::new(m * self.origin, m * self.dir)
32 }
33
34 #[inline]
36 pub fn inverse_transform_by(&self, m: &Isometry<N>) -> Self {
37 Self::new(
38 m.inverse_transform_point(&self.origin),
39 m.inverse_transform_vector(&self.dir),
40 )
41 }
42
43 #[inline]
45 pub fn translate_by(&self, v: Vector<N>) -> Self {
46 Self::new(self.origin + v, self.dir)
47 }
48
49 #[inline]
53 pub fn point_at(&self, t: N) -> Point<N> {
54 self.origin + self.dir * t
55 }
56}
57
58#[derive(Copy, Clone, Debug)]
60#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
61pub struct RayIntersection<N: RealField + Copy> {
62 pub toi: N,
66
67 pub normal: Vector<N>,
72
73 pub feature: FeatureId,
75
76 #[cfg(feature = "dim3")]
79 pub uvs: Option<Point2<N>>,
80}
81
82impl<N: RealField + Copy> RayIntersection<N> {
83 #[inline]
84 #[cfg(feature = "dim3")]
86 pub fn new_with_uvs(
87 toi: N,
88 normal: Vector<N>,
89 feature: FeatureId,
90 uvs: Option<Point2<N>>,
91 ) -> RayIntersection<N> {
92 RayIntersection {
93 toi,
94 normal,
95 feature,
96 uvs,
97 }
98 }
99
100 #[inline]
101 #[cfg(feature = "dim3")]
103 pub fn new(toi: N, normal: Vector<N>, feature: FeatureId) -> RayIntersection<N> {
104 RayIntersection {
105 toi,
106 normal,
107 feature,
108 uvs: None,
109 }
110 }
111
112 #[inline]
113 #[cfg(feature = "dim2")]
115 pub fn new(toi: N, normal: Vector<N>, feature: FeatureId) -> RayIntersection<N> {
116 RayIntersection {
117 toi,
118 normal,
119 feature,
120 }
121 }
122}
123
124pub trait RayCast<N: RealField + Copy> {
126 fn toi_with_ray(&self, m: &Isometry<N>, ray: &Ray<N>, max_toi: N, solid: bool) -> Option<N> {
128 self.toi_and_normal_with_ray(m, ray, max_toi, solid)
129 .map(|inter| inter.toi)
130 }
131
132 fn toi_and_normal_with_ray(
134 &self,
135 m: &Isometry<N>,
136 ray: &Ray<N>,
137 max_toi: N,
138 solid: bool,
139 ) -> Option<RayIntersection<N>>;
140
141 #[cfg(feature = "dim3")]
144 #[inline]
145 fn toi_and_normal_and_uv_with_ray(
146 &self,
147 m: &Isometry<N>,
148 ray: &Ray<N>,
149 max_toi: N,
150 solid: bool,
151 ) -> Option<RayIntersection<N>> {
152 self.toi_and_normal_with_ray(m, ray, max_toi, solid)
153 }
154
155 #[inline]
157 fn intersects_ray(&self, m: &Isometry<N>, ray: &Ray<N>, max_toi: N) -> bool {
158 self.toi_with_ray(m, ray, max_toi, true).is_some()
159 }
160}