aboutsummaryrefslogtreecommitdiff
path: root/src/geometry/waabb.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/geometry/waabb.rs')
-rw-r--r--src/geometry/waabb.rs217
1 files changed, 0 insertions, 217 deletions
diff --git a/src/geometry/waabb.rs b/src/geometry/waabb.rs
deleted file mode 100644
index 1ebf528..0000000
--- a/src/geometry/waabb.rs
+++ /dev/null
@@ -1,217 +0,0 @@
-use crate::geometry::Ray;
-use crate::math::{Point, Vector, DIM, SIMD_WIDTH};
-use crate::utils;
-use ncollide::bounding_volume::AABB;
-use num::{One, Zero};
-use {
- crate::math::{SimdBool, SimdFloat},
- simba::simd::{SimdPartialOrd, SimdValue},
-};
-
-#[derive(Debug, Copy, Clone)]
-pub(crate) struct WRay {
- pub origin: Point<SimdFloat>,
- pub dir: Vector<SimdFloat>,
-}
-
-impl WRay {
- pub fn splat(ray: Ray) -> Self {
- Self {
- origin: Point::splat(ray.origin),
- dir: Vector::splat(ray.dir),
- }
- }
-}
-
-#[derive(Debug, Copy, Clone)]
-pub(crate) struct WAABB {
- pub mins: Point<SimdFloat>,
- pub maxs: Point<SimdFloat>,
-}
-
-#[cfg(feature = "serde-serialize")]
-impl serde::Serialize for WAABB {
- fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- where
- S: serde::Serializer,
- {
- use serde::ser::SerializeStruct;
-
- let mins: Point<[f32; SIMD_WIDTH]> = Point::from(
- self.mins
- .coords
- .map(|e| array![|ii| e.extract(ii); SIMD_WIDTH]),
- );
- let maxs: Point<[f32; SIMD_WIDTH]> = Point::from(
- self.maxs
- .coords
- .map(|e| array![|ii| e.extract(ii); SIMD_WIDTH]),
- );
-
- let mut waabb = serializer.serialize_struct("WAABB", 2)?;
- waabb.serialize_field("mins", &mins)?;
- waabb.serialize_field("maxs", &maxs)?;
- waabb.end()
- }
-}
-
-#[cfg(feature = "serde-serialize")]
-impl<'de> serde::Deserialize<'de> for WAABB {
- fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
- where
- D: serde::Deserializer<'de>,
- {
- struct Visitor {};
- impl<'de> serde::de::Visitor<'de> for Visitor {
- type Value = WAABB;
- fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
- write!(
- formatter,
- "two arrays containing at least {} floats",
- SIMD_WIDTH * DIM * 2
- )
- }
-
- fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
- where
- A: serde::de::SeqAccess<'de>,
- {
- let mins: Point<[f32; SIMD_WIDTH]> = seq
- .next_element()?
- .ok_or_else(|| serde::de::Error::invalid_length(0, &self))?;
- let maxs: Point<[f32; SIMD_WIDTH]> = seq
- .next_element()?
- .ok_or_else(|| serde::de::Error::invalid_length(1, &self))?;
- let mins = Point::from(mins.coords.map(|e| SimdFloat::from(e)));
- let maxs = Point::from(maxs.coords.map(|e| SimdFloat::from(e)));
- Ok(WAABB { mins, maxs })
- }
- }
-
- deserializer.deserialize_struct("WAABB", &["mins", "maxs"], Visitor {})
- }
-}
-
-impl WAABB {
- pub fn new_invalid() -> Self {
- Self::splat(AABB::new_invalid())
- }
-
- pub fn splat(aabb: AABB<f32>) -> Self {
- Self {
- mins: Point::splat(aabb.mins),
- maxs: Point::splat(aabb.maxs),
- }
- }
-
- pub fn dilate_by_factor(&mut self, factor: SimdFloat) {
- // If some of the AABBs on this WAABB are invalid,
- // don't, dilate them.
- let is_valid = self.mins.x.simd_le(self.maxs.x);
- let factor = factor.select(is_valid, SimdFloat::zero());
-
- // NOTE: we multiply each by factor instead of doing
- // (maxs - mins) * factor. That's to avoid overflows (and
- // therefore NaNs if this WAABB contains some invalid
- // AABBs initialised with f32::MAX
- let dilation = self.maxs * factor - self.mins * factor;
- self.mins -= dilation;
- self.maxs += dilation;
- }
-
- pub fn replace(&mut self, i: usize, aabb: AABB<f32>) {
- self.mins.replace(i, aabb.mins);
- self.maxs.replace(i, aabb.maxs);
- }
-
- pub fn intersects_ray(&self, ray: &WRay, max_toi: SimdFloat) -> SimdBool {
- let _0 = SimdFloat::zero();
- let _1 = SimdFloat::one();
- let _infinity = SimdFloat::splat(f32::MAX);
-
- let mut hit = SimdBool::splat(true);
- let mut tmin = SimdFloat::zero();
- let mut tmax = max_toi;
-
- // TODO: could this be optimized more considering we really just need a boolean answer?
- for i in 0usize..DIM {
- let is_not_zero = ray.dir[i].simd_ne(_0);
- let is_zero_test =
- ray.origin[i].simd_ge(self.mins[i]) & ray.origin[i].simd_le(self.maxs[i]);
- let is_not_zero_test = {
- let denom = _1 / ray.dir[i];
- let mut inter_with_near_plane =
- ((self.mins[i] - ray.origin[i]) * denom).select(is_not_zero, -_infinity);
- let mut inter_with_far_plane =
- ((self.maxs[i] - ray.origin[i]) * denom).select(is_not_zero, _infinity);
-
- let gt = inter_with_near_plane.simd_gt(inter_with_far_plane);
- utils::simd_swap(gt, &mut inter_with_near_plane, &mut inter_with_far_plane);
-
- tmin = tmin.simd_max(inter_with_near_plane);
- tmax = tmax.simd_min(inter_with_far_plane);
-
- tmin.simd_le(tmax)
- };
-
- hit = hit & is_not_zero_test.select(is_not_zero, is_zero_test);
- }
-
- hit
- }
-
- #[cfg(feature = "dim2")]
- pub fn contains(&self, other: &WAABB) -> SimdBool {
- self.mins.x.simd_le(other.mins.x)
- & self.mins.y.simd_le(other.mins.y)
- & self.maxs.x.simd_ge(other.maxs.x)
- & self.maxs.y.simd_ge(other.maxs.y)
- }
-
- #[cfg(feature = "dim3")]
- pub fn contains(&self, other: &WAABB) -> SimdBool {
- self.mins.x.simd_le(other.mins.x)
- & self.mins.y.simd_le(other.mins.y)
- & self.mins.z.simd_le(other.mins.z)
- & self.maxs.x.simd_ge(other.maxs.x)
- & self.maxs.y.simd_ge(other.maxs.y)
- & self.maxs.z.simd_ge(other.maxs.z)
- }
-
- #[cfg(feature = "dim2")]
- pub fn intersects(&self, other: &WAABB) -> SimdBool {
- self.mins.x.simd_le(other.maxs.x)
- & other.mins.x.simd_le(self.maxs.x)
- & self.mins.y.simd_le(other.maxs.y)
- & other.mins.y.simd_le(self.maxs.y)
- }
-
- #[cfg(feature = "dim3")]
- pub fn intersects(&self, other: &WAABB) -> SimdBool {
- self.mins.x.simd_le(other.maxs.x)
- & other.mins.x.simd_le(self.maxs.x)
- & self.mins.y.simd_le(other.maxs.y)
- & other.mins.y.simd_le(self.maxs.y)
- & self.mins.z.simd_le(other.maxs.z)
- & other.mins.z.simd_le(self.maxs.z)
- }
-
- pub fn to_merged_aabb(&self) -> AABB<f32> {
- AABB::new(
- self.mins.coords.map(|e| e.simd_horizontal_min()).into(),
- self.maxs.coords.map(|e| e.simd_horizontal_max()).into(),
- )
- }
-}
-
-impl From<[AABB<f32>; SIMD_WIDTH]> for WAABB {
- fn from(aabbs: [AABB<f32>; SIMD_WIDTH]) -> Self {
- let mins = array![|ii| aabbs[ii].mins; SIMD_WIDTH];
- let maxs = array![|ii| aabbs[ii].maxs; SIMD_WIDTH];
-
- WAABB {
- mins: Point::from(mins),
- maxs: Point::from(maxs),
- }
- }
-}