From 9bf1321f8f1d2e116f44c2461a53f302c4ef4171 Mon Sep 17 00:00:00 2001 From: Crozet Sébastien Date: Tue, 8 Dec 2020 17:31:49 +0100 Subject: Outsource the contact manifold, SAT, and some shapes. --- src/geometry/trimesh.rs | 63 +++++++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 26 deletions(-) (limited to 'src/geometry/trimesh.rs') diff --git a/src/geometry/trimesh.rs b/src/geometry/trimesh.rs index b4e8518..02a3b1c 100644 --- a/src/geometry/trimesh.rs +++ b/src/geometry/trimesh.rs @@ -1,16 +1,18 @@ -use crate::geometry::{PointProjection, Ray, RayIntersection, Triangle, WQuadtree}; +use crate::geometry::{ + Cuboid, HeightField, PointProjection, Ray, RayIntersection, Triangle, WQuadtree, +}; use crate::math::{Isometry, Point}; +use buckler::bounding_volume::AABB; +use buckler::query::{PointQuery, RayCast}; +use buckler::shape::FeatureId; use na::Point3; -use ncollide::bounding_volume::{HasBoundingVolume, AABB}; -use ncollide::query::{PointQuery, RayCast}; -use ncollide::shape::FeatureId; #[derive(Clone)] #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] /// A triangle mesh. pub struct Trimesh { wquadtree: WQuadtree, - aabb: AABB, + aabb: AABB, vertices: Vec>, indices: Vec>, } @@ -34,7 +36,7 @@ impl Trimesh { vertices[idx[1] as usize], vertices[idx[2] as usize], ) - .local_bounding_volume(); + .local_aabb(); (i, aabb) }); @@ -52,7 +54,7 @@ impl Trimesh { } /// Compute the axis-aligned bounding box of this triangle mesh. - pub fn aabb(&self, pos: &Isometry) -> AABB { + pub fn aabb(&self, pos: &Isometry) -> AABB { self.aabb.transform_by(pos) } @@ -106,15 +108,14 @@ impl Trimesh { } } -impl PointQuery for Trimesh { - fn project_point(&self, _m: &Isometry, _pt: &Point, _solid: bool) -> PointProjection { +impl PointQuery for Trimesh { + fn project_local_point(&self, _pt: &Point, _solid: bool) -> PointProjection { // TODO unimplemented!() } - fn project_point_with_feature( + fn project_local_point_and_get_feature( &self, - _m: &Isometry, _pt: &Point, ) -> (PointProjection, FeatureId) { // TODO @@ -123,10 +124,9 @@ impl PointQuery for Trimesh { } #[cfg(feature = "dim2")] -impl RayCast for Trimesh { - fn toi_and_normal_with_ray( +impl RayCast for Trimesh { + fn cast_local_ray_and_get_normal( &self, - _m: &Isometry, _ray: &Ray, _max_toi: f32, _solid: bool, @@ -142,24 +142,21 @@ impl RayCast for Trimesh { } #[cfg(feature = "dim3")] -impl RayCast for Trimesh { - fn toi_and_normal_with_ray( +impl RayCast for Trimesh { + fn cast_local_ray_and_get_normal( &self, - m: &Isometry, ray: &Ray, max_toi: f32, solid: bool, ) -> Option { // FIXME: do a best-first search. let mut intersections = Vec::new(); - let ls_ray = ray.inverse_transform_by(m); - self.wquadtree - .cast_ray(&ls_ray, max_toi, &mut intersections); + self.wquadtree.cast_ray(&ray, max_toi, &mut intersections); let mut best: Option = None; for inter in intersections { let tri = self.triangle(inter); - if let Some(inter) = tri.toi_and_normal_with_ray(m, ray, max_toi, solid) { + if let Some(inter) = tri.cast_local_ray_and_get_normal(ray, max_toi, solid) { if let Some(curr) = &mut best { if curr.toi > inter.toi { *curr = inter; @@ -173,16 +170,14 @@ impl RayCast for Trimesh { best } - fn intersects_ray(&self, m: &Isometry, ray: &Ray, max_toi: f32) -> bool { + fn intersects_local_ray(&self, ray: &Ray, max_toi: f32) -> bool { // FIXME: do a best-first search. let mut intersections = Vec::new(); - let ls_ray = ray.inverse_transform_by(m); - self.wquadtree - .cast_ray(&ls_ray, max_toi, &mut intersections); + self.wquadtree.cast_ray(&ray, max_toi, &mut intersections); for inter in intersections { let tri = self.triangle(inter); - if tri.intersects_ray(m, ray, max_toi) { + if tri.intersects_local_ray(ray, max_toi) { return true; } } @@ -190,3 +185,19 @@ impl RayCast for Trimesh { false } } + +#[cfg(feature = "dim3")] +impl From for Trimesh { + fn from(heightfield: HeightField) -> Self { + let (vtx, idx) = heightfield.to_trimesh(); + Trimesh::new(vtx, idx) + } +} + +#[cfg(feature = "dim3")] +impl From for Trimesh { + fn from(cuboid: Cuboid) -> Self { + let (vtx, idx) = cuboid.to_trimesh(); + Trimesh::new(vtx, idx) + } +} -- cgit From cc6d1b973002b4d366bc81ec6bf9e8240ad7b404 Mon Sep 17 00:00:00 2001 From: Crozet Sébastien Date: Mon, 14 Dec 2020 15:51:43 +0100 Subject: Outsource the Shape trait, wquadtree, and shape types. --- src/geometry/trimesh.rs | 203 ------------------------------------------------ 1 file changed, 203 deletions(-) delete mode 100644 src/geometry/trimesh.rs (limited to 'src/geometry/trimesh.rs') diff --git a/src/geometry/trimesh.rs b/src/geometry/trimesh.rs deleted file mode 100644 index 02a3b1c..0000000 --- a/src/geometry/trimesh.rs +++ /dev/null @@ -1,203 +0,0 @@ -use crate::geometry::{ - Cuboid, HeightField, PointProjection, Ray, RayIntersection, Triangle, WQuadtree, -}; -use crate::math::{Isometry, Point}; -use buckler::bounding_volume::AABB; -use buckler::query::{PointQuery, RayCast}; -use buckler::shape::FeatureId; -use na::Point3; - -#[derive(Clone)] -#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] -/// A triangle mesh. -pub struct Trimesh { - wquadtree: WQuadtree, - aabb: AABB, - vertices: Vec>, - indices: Vec>, -} - -impl Trimesh { - /// Creates a new triangle mesh from a vertex buffer and an index buffer. - pub fn new(vertices: Vec>, indices: Vec>) -> Self { - assert!( - vertices.len() > 1, - "A triangle mesh must contain at least one point." - ); - assert!( - indices.len() > 1, - "A triangle mesh must contain at least one triangle." - ); - - let aabb = AABB::from_points(&vertices); - let data = indices.iter().enumerate().map(|(i, idx)| { - let aabb = Triangle::new( - vertices[idx[0] as usize], - vertices[idx[1] as usize], - vertices[idx[2] as usize], - ) - .local_aabb(); - (i, aabb) - }); - - let mut wquadtree = WQuadtree::new(); - // NOTE: we apply no dilation factor because we won't - // update this tree dynamically. - wquadtree.clear_and_rebuild(data, 0.0); - - Self { - wquadtree, - aabb, - vertices, - indices, - } - } - - /// Compute the axis-aligned bounding box of this triangle mesh. - pub fn aabb(&self, pos: &Isometry) -> AABB { - self.aabb.transform_by(pos) - } - - pub(crate) fn waabbs(&self) -> &WQuadtree { - &self.wquadtree - } - - /// The number of triangles forming this mesh. - pub fn num_triangles(&self) -> usize { - self.indices.len() - } - - /// An iterator through all the triangles of this mesh. - pub fn triangles(&self) -> impl Iterator + '_ { - self.indices.iter().map(move |ids| { - Triangle::new( - self.vertices[ids.x as usize], - self.vertices[ids.y as usize], - self.vertices[ids.z as usize], - ) - }) - } - - /// Get the `i`-th triangle of this mesh. - pub fn triangle(&self, i: usize) -> Triangle { - let idx = self.indices[i]; - Triangle::new( - self.vertices[idx.x as usize], - self.vertices[idx.y as usize], - self.vertices[idx.z as usize], - ) - } - - /// The vertex buffer of this mesh. - pub fn vertices(&self) -> &[Point] { - &self.vertices[..] - } - - /// The index buffer of this mesh. - pub fn indices(&self) -> &[Point3] { - &self.indices - } - - /// A flat view of the index buffer of this mesh. - pub fn flat_indices(&self) -> &[u32] { - unsafe { - let len = self.indices.len() * 3; - let data = self.indices.as_ptr() as *const u32; - std::slice::from_raw_parts(data, len) - } - } -} - -impl PointQuery for Trimesh { - fn project_local_point(&self, _pt: &Point, _solid: bool) -> PointProjection { - // TODO - unimplemented!() - } - - fn project_local_point_and_get_feature( - &self, - _pt: &Point, - ) -> (PointProjection, FeatureId) { - // TODO - unimplemented!() - } -} - -#[cfg(feature = "dim2")] -impl RayCast for Trimesh { - fn cast_local_ray_and_get_normal( - &self, - _ray: &Ray, - _max_toi: f32, - _solid: bool, - ) -> Option { - // TODO - None - } - - fn intersects_ray(&self, _m: &Isometry, _ray: &Ray, _max_toi: f32) -> bool { - // TODO - false - } -} - -#[cfg(feature = "dim3")] -impl RayCast for Trimesh { - fn cast_local_ray_and_get_normal( - &self, - ray: &Ray, - max_toi: f32, - solid: bool, - ) -> Option { - // FIXME: do a best-first search. - let mut intersections = Vec::new(); - self.wquadtree.cast_ray(&ray, max_toi, &mut intersections); - let mut best: Option = None; - - for inter in intersections { - let tri = self.triangle(inter); - if let Some(inter) = tri.cast_local_ray_and_get_normal(ray, max_toi, solid) { - if let Some(curr) = &mut best { - if curr.toi > inter.toi { - *curr = inter; - } - } else { - best = Some(inter); - } - } - } - - best - } - - fn intersects_local_ray(&self, ray: &Ray, max_toi: f32) -> bool { - // FIXME: do a best-first search. - let mut intersections = Vec::new(); - self.wquadtree.cast_ray(&ray, max_toi, &mut intersections); - - for inter in intersections { - let tri = self.triangle(inter); - if tri.intersects_local_ray(ray, max_toi) { - return true; - } - } - - false - } -} - -#[cfg(feature = "dim3")] -impl From for Trimesh { - fn from(heightfield: HeightField) -> Self { - let (vtx, idx) = heightfield.to_trimesh(); - Trimesh::new(vtx, idx) - } -} - -#[cfg(feature = "dim3")] -impl From for Trimesh { - fn from(cuboid: Cuboid) -> Self { - let (vtx, idx) = cuboid.to_trimesh(); - Trimesh::new(vtx, idx) - } -} -- cgit