From 3c85a6ac41397cf95199933c6a93909bc070a844 Mon Sep 17 00:00:00 2001 From: Sébastien Crozet Date: Tue, 8 Sep 2020 21:18:17 +0200 Subject: Start implementing ray-casting. This adds a QueryPipeline structure responsible for scene queries. Currently this structure is able to perform a brute-force ray-cast. This commit also includes the beginning of implementation of a SIMD-based acceleration structure which will be used for these scene queries in the future. --- src/geometry/waabb.rs | 93 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 91 insertions(+), 2 deletions(-) (limited to 'src/geometry/waabb.rs') diff --git a/src/geometry/waabb.rs b/src/geometry/waabb.rs index c3853bc..702b5aa 100644 --- a/src/geometry/waabb.rs +++ b/src/geometry/waabb.rs @@ -1,15 +1,27 @@ #[cfg(feature = "serde-serialize")] use crate::math::DIM; -use crate::math::{Point, SimdBool, SimdFloat, SIMD_WIDTH}; +use crate::math::{Point, SIMD_WIDTH}; use ncollide::bounding_volume::AABB; -use simba::simd::{SimdPartialOrd, SimdValue}; +#[cfg(feature = "simd-is-enabled")] +use { + crate::math::{SimdBool, SimdFloat}, + simba::simd::{SimdPartialOrd, SimdValue}, +}; #[derive(Debug, Copy, Clone)] +#[cfg(feature = "simd-is-enabled")] pub(crate) struct WAABB { pub mins: Point, pub maxs: Point, } +#[derive(Debug, Copy, Clone)] +#[cfg(not(feature = "simd-is-enabled"))] +pub(crate) struct WAABB { + pub mins: [Point; SIMD_WIDTH], + pub maxs: [Point; SIMD_WIDTH], +} + #[cfg(feature = "serde-serialize")] impl serde::Serialize for WAABB { fn serialize(&self, serializer: S) -> Result @@ -18,16 +30,24 @@ impl serde::Serialize for WAABB { { use serde::ser::SerializeStruct; + #[cfg(feature = "simd-is-enabled")] let mins: Point<[f32; SIMD_WIDTH]> = Point::from( self.mins .coords .map(|e| array![|ii| e.extract(ii); SIMD_WIDTH]), ); + #[cfg(feature = "simd-is-enabled")] let maxs: Point<[f32; SIMD_WIDTH]> = Point::from( self.maxs .coords .map(|e| array![|ii| e.extract(ii); SIMD_WIDTH]), ); + + #[cfg(not(feature = "simd-is-enabled"))] + let mins = self.mins; + #[cfg(not(feature = "simd-is-enabled"))] + let maxs = self.maxs; + let mut waabb = serializer.serialize_struct("WAABB", 2)?; waabb.serialize_field("mins", &mins)?; waabb.serialize_field("maxs", &maxs)?; @@ -52,6 +72,7 @@ impl<'de> serde::Deserialize<'de> for WAABB { ) } + #[cfg(feature = "simd-is-enabled")] fn visit_seq(self, mut seq: A) -> Result where A: serde::de::SeqAccess<'de>, @@ -66,17 +87,36 @@ impl<'de> serde::Deserialize<'de> for WAABB { let maxs = Point::from(maxs.coords.map(|e| SimdFloat::from(e))); Ok(WAABB { mins, maxs }) } + + #[cfg(not(feature = "simd-is-enabled"))] + fn visit_seq(self, mut seq: A) -> Result + where + A: serde::de::SeqAccess<'de>, + { + let mins = seq + .next_element()? + .ok_or_else(|| serde::de::Error::invalid_length(0, &self))?; + let maxs = seq + .next_element()? + .ok_or_else(|| serde::de::Error::invalid_length(1, &self))?; + Ok(WAABB { mins, maxs }) + } } deserializer.deserialize_struct("WAABB", &["mins", "maxs"], Visitor {}) } } +#[cfg(feature = "simd-is-enabled")] impl WAABB { pub fn new(mins: Point, maxs: Point) -> Self { Self { mins, maxs } } + pub fn new_invalid() -> Self { + Self::splat(AABB::new_invalid()) + } + pub fn splat(aabb: AABB) -> Self { Self { mins: Point::splat(aabb.mins), @@ -103,6 +143,7 @@ impl WAABB { } } +#[cfg(feature = "simd-is-enabled")] impl From<[AABB; SIMD_WIDTH]> for WAABB { fn from(aabbs: [AABB; SIMD_WIDTH]) -> Self { let mins = array![|ii| aabbs[ii].mins; SIMD_WIDTH]; @@ -114,3 +155,51 @@ impl From<[AABB; SIMD_WIDTH]> for WAABB { } } } + +#[cfg(not(feature = "simd-is-enabled"))] +impl WAABB { + pub fn new_invalid() -> Self { + Self::splat(AABB::new_invalid()) + } + + pub fn splat(aabb: AABB) -> Self { + Self { + mins: [aabb.mins; SIMD_WIDTH], + maxs: [aabb.maxs; SIMD_WIDTH], + } + } + + #[cfg(feature = "dim2")] + pub fn intersects_lanewise(&self, other: &WAABB) -> [bool; SIMD_WIDTH] { + array![|ii| + self.mins[ii].x <= other.maxs[ii].x + && other.mins[ii].x <= self.maxs[ii].x + && self.mins[ii].y <= other.maxs[ii].y + && other.mins[ii].y <= self.maxs[ii].y + ; SIMD_WIDTH + ] + } + + #[cfg(feature = "dim3")] + pub fn intersects_lanewise(&self, other: &WAABB) -> [bool; SIMD_WIDTH] { + array![|ii| + self.mins[ii].x <= other.maxs[ii].x + && other.mins[ii].x <= self.maxs[ii].x + && self.mins[ii].y <= other.maxs[ii].y + && other.mins[ii].y <= self.maxs[ii].y + && self.mins[ii].z <= other.maxs[ii].z + && other.mins[ii].z <= self.maxs[ii].z + ; SIMD_WIDTH + ] + } +} + +#[cfg(not(feature = "simd-is-enabled"))] +impl From<[AABB; SIMD_WIDTH]> for WAABB { + fn from(aabbs: [AABB; SIMD_WIDTH]) -> Self { + let mins = array![|ii| aabbs[ii].mins; SIMD_WIDTH]; + let maxs = array![|ii| aabbs[ii].maxs; SIMD_WIDTH]; + + WAABB { mins, maxs } + } +} -- cgit