aboutsummaryrefslogtreecommitdiff
path: root/src/geometry/waabb.rs
diff options
context:
space:
mode:
authorSébastien Crozet <developer@crozet.re>2020-08-25 22:10:25 +0200
committerSébastien Crozet <developer@crozet.re>2020-08-25 22:10:25 +0200
commit754a48b7ff6d8c58b1ee08651e60112900b60455 (patch)
tree7d777a6c003f1f5d8f8d24f533f35a95a88957fe /src/geometry/waabb.rs
downloadrapier-0.1.0.tar.gz
rapier-0.1.0.tar.bz2
rapier-0.1.0.zip
First public release of Rapier.v0.1.0
Diffstat (limited to 'src/geometry/waabb.rs')
-rw-r--r--src/geometry/waabb.rs116
1 files changed, 116 insertions, 0 deletions
diff --git a/src/geometry/waabb.rs b/src/geometry/waabb.rs
new file mode 100644
index 0000000..c3853bc
--- /dev/null
+++ b/src/geometry/waabb.rs
@@ -0,0 +1,116 @@
+#[cfg(feature = "serde-serialize")]
+use crate::math::DIM;
+use crate::math::{Point, SimdBool, SimdFloat, SIMD_WIDTH};
+use ncollide::bounding_volume::AABB;
+use simba::simd::{SimdPartialOrd, SimdValue};
+
+#[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(mins: Point<SimdFloat>, maxs: Point<SimdFloat>) -> Self {
+ Self { mins, maxs }
+ }
+
+ pub fn splat(aabb: AABB<f32>) -> Self {
+ Self {
+ mins: Point::splat(aabb.mins),
+ maxs: Point::splat(aabb.maxs),
+ }
+ }
+
+ #[cfg(feature = "dim2")]
+ pub fn intersects_lanewise(&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_lanewise(&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)
+ }
+}
+
+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),
+ }
+ }
+}