1use approx::{AbsDiffEq, RelativeEq, UlpsEq};
2use nalgebra::{Isometry3, Point3, RealField, Reflection3, Unit, UnitQuaternion, Vector3};
3use simba::scalar::SubsetOf;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
10#[repr(C)]
11pub struct Plane<N: Copy + RealField> {
12 pub normal: Unit<Vector3<N>>,
14 pub bias: N,
16}
17
18impl<N: Copy + RealField> Plane<N> {
19 #[must_use]
50 pub fn new(normal: Unit<Vector3<N>>, distance: N) -> Self {
51 Self {
52 normal,
53 bias: -distance,
54 }
55 }
56 #[must_use]
58 pub fn with_point(normal: Unit<Vector3<N>>, point: &Point3<N>) -> Self {
59 Self::new(normal, normal.dot(&point.coords))
60 }
61 #[must_use]
63 pub fn distance(&self) -> N {
64 -self.bias
65 }
66 #[must_use]
68 pub fn distance_from(&self, point: &Point3<N>) -> N {
69 self.distance() - self.normal.dot(&point.coords)
70 }
71 #[must_use]
73 pub fn project_point(&self, point: &Point3<N>) -> Point3<N> {
74 self.project_vector(&point.coords).into()
75 }
76 #[must_use]
78 pub fn project_axis(&self, axis: &Unit<Vector3<N>>) -> Unit<Vector3<N>> {
79 Unit::new_normalize(self.project_vector(&axis.into_inner()))
80 }
81 #[must_use]
83 pub fn project_vector(&self, vector: &Vector3<N>) -> Vector3<N> {
84 vector - self.normal.into_inner() * (self.normal.dot(vector) + self.bias)
85 }
86 #[must_use]
88 pub fn angle_between(&self, a: &Vector3<N>, b: &Vector3<N>) -> N {
89 let angle = a.angle(b);
90 let axis = a.cross(b);
91 if self.normal.dot(&axis).is_sign_negative() {
92 -angle
93 } else {
94 angle
95 }
96 }
97 #[must_use]
99 pub fn rotate_by(self, rot: &UnitQuaternion<N>) -> Self {
100 Self {
101 normal: Unit::new_unchecked(rot.transform_vector(&self.normal)),
102 bias: self.bias,
103 }
104 }
105 #[must_use]
107 pub fn translate_by(self, vec: &Vector3<N>) -> Self {
108 Self {
109 normal: self.normal,
110 bias: self.bias - self.normal.dot(vec),
111 }
112 }
113 #[must_use]
138 pub fn transform_by(self, iso: &Isometry3<N>) -> Self {
139 self.rotate_by(&iso.rotation)
140 .translate_by(&iso.translation.vector)
141 }
142 #[must_use]
144 pub fn cast<M: Copy + RealField>(self) -> Plane<M>
145 where
146 N: SubsetOf<M>,
147 {
148 Plane {
149 normal: self.normal.cast(),
150 bias: self.bias.to_superset(),
151 }
152 }
153}
154
155impl<N: Copy + RealField> From<Reflection3<N>> for Plane<N> {
156 fn from(reflection: Reflection3<N>) -> Self {
157 Self::new(Unit::new_unchecked(*reflection.axis()), reflection.bias())
158 }
159}
160
161impl<N: Copy + RealField> From<Plane<N>> for Reflection3<N> {
162 fn from(plane: Plane<N>) -> Self {
163 Self::new(plane.normal, plane.distance())
164 }
165}
166
167impl<N: Copy + RealField + AbsDiffEq> AbsDiffEq for Plane<N>
168where
169 N::Epsilon: Copy,
170{
171 type Epsilon = N::Epsilon;
172
173 fn default_epsilon() -> N::Epsilon {
174 N::default_epsilon()
175 }
176
177 fn abs_diff_eq(&self, other: &Self, epsilon: N::Epsilon) -> bool {
178 self.normal.abs_diff_eq(&other.normal, epsilon)
179 && self.bias.abs_diff_eq(&other.bias, epsilon)
180 }
181}
182
183impl<N: Copy + RealField + RelativeEq> RelativeEq for Plane<N>
184where
185 N::Epsilon: Copy,
186{
187 fn default_max_relative() -> N::Epsilon {
188 N::default_max_relative()
189 }
190
191 fn relative_eq(&self, other: &Self, epsilon: N::Epsilon, max_relative: N::Epsilon) -> bool {
192 self.normal
193 .relative_eq(&other.normal, epsilon, max_relative)
194 && self.bias.relative_eq(&other.bias, epsilon, max_relative)
195 }
196}
197
198impl<N: Copy + RealField + UlpsEq> UlpsEq for Plane<N>
199where
200 N::Epsilon: Copy,
201{
202 fn default_max_ulps() -> u32 {
203 N::default_max_ulps()
204 }
205
206 fn ulps_eq(&self, other: &Self, epsilon: N::Epsilon, max_ulps: u32) -> bool {
207 self.normal.ulps_eq(&other.normal, epsilon, max_ulps)
208 && self.bias.ulps_eq(&other.bias, epsilon, max_ulps)
209 }
210}
211
212#[cfg(feature = "rkyv")]
213impl<N: Copy + RealField> rkyv::Archive for Plane<N> {
214 type Archived = Self;
215 type Resolver = ();
216
217 #[inline]
218 #[allow(unsafe_code)]
219 unsafe fn resolve(&self, _: usize, (): Self::Resolver, out: *mut Self::Archived) {
220 unsafe {
221 out.write(rkyv::to_archived!(*self as Self));
222 }
223 }
224}
225
226#[cfg(feature = "rkyv")]
227impl<Ser: rkyv::Fallible + ?Sized, N: Copy + RealField> rkyv::Serialize<Ser> for Plane<N> {
228 #[inline]
229 fn serialize(&self, _: &mut Ser) -> Result<Self::Resolver, Ser::Error> {
230 Ok(())
231 }
232}
233
234#[cfg(feature = "rkyv")]
235impl<De: rkyv::Fallible + ?Sized, N: Copy + RealField> rkyv::Deserialize<Self, De> for Plane<N> {
236 #[inline]
237 fn deserialize(&self, _: &mut De) -> Result<Self, De::Error> {
238 Ok(rkyv::from_archived!(*self))
239 }
240}