diff options
| -rw-r--r-- | examples3d/convex_decomposition3.rs | 14 | ||||
| -rw-r--r-- | src/geometry/collider.rs | 51 | ||||
| -rw-r--r-- | src/geometry/collider_shape.rs | 63 |
3 files changed, 117 insertions, 11 deletions
diff --git a/examples3d/convex_decomposition3.rs b/examples3d/convex_decomposition3.rs index abd2fe0..c06a450 100644 --- a/examples3d/convex_decomposition3.rs +++ b/examples3d/convex_decomposition3.rs @@ -45,7 +45,7 @@ pub fn init_world(testbed: &mut Testbed) { let deltas = na::one(); let mtl_path = Path::new(""); - let mut compound_parts = Vec::new(); + let mut shapes = Vec::new(); println!("Parsing and decomposing: {}", obj_path); let obj = obj::parse_file(&Path::new(&obj_path), &mtl_path, ""); @@ -81,13 +81,9 @@ pub fn init_world(testbed: &mut Testbed) { .into_iter() .map(|idx| [idx.x, idx.y, idx.z]) .collect(); - let vhacd = VHACD::decompose(¶ms, &vertices, &indices, true); - for (vertices, indices) in vhacd.compute_exact_convex_hulls(&vertices, &indices) { - if let Some(convex) = ColliderShape::convex_mesh(vertices, &indices) { - compound_parts.push(convex); - } - } + let decomposed_shape = ColliderShape::convex_decomposition(&vertices, &indices); + shapes.push(decomposed_shape); } // let compound = ColliderShape::compound(compound_parts); @@ -100,8 +96,8 @@ pub fn init_world(testbed: &mut Testbed) { let body = RigidBodyBuilder::new_dynamic().translation(x, y, z).build(); let handle = bodies.insert(body); - for part in &compound_parts { - let collider = ColliderBuilder::new(part.clone()).build(); + for shape in &shapes { + let collider = ColliderBuilder::new(shape.clone()).build(); colliders.insert(collider, handle, &mut bodies); } } diff --git a/src/geometry/collider.rs b/src/geometry/collider.rs index c5f53f7..232b246 100644 --- a/src/geometry/collider.rs +++ b/src/geometry/collider.rs @@ -1,6 +1,7 @@ +use crate::cdl::transformation::vhacd::VHACDParameters; use crate::dynamics::{CoefficientCombineRule, MassProperties, RigidBodyHandle}; use crate::geometry::{ColliderShape, InteractionGroups}; -use crate::math::{AngVector, Isometry, Point, Real, Rotation, Vector}; +use crate::math::{AngVector, Isometry, Point, Real, Rotation, Vector, DIM}; use cdl::bounding_volume::AABB; use cdl::shape::Shape; #[cfg(feature = "dim2")] @@ -299,6 +300,54 @@ impl ColliderBuilder { Self::new(ColliderShape::trimesh(vertices, indices)) } + /// Initializes a collider builder with a compound shape obtained from the decomposition of + /// the given trimesh (in 3D) or polyline (in 2D) into convex parts. + pub fn convex_decomposition(vertices: &[Point<Real>], indices: &[[u32; DIM]]) -> Self { + Self::new(ColliderShape::convex_decomposition(vertices, indices)) + } + + /// Initializes a collider builder with a compound shape obtained from the decomposition of + /// the given trimesh (in 3D) or polyline (in 2D) into convex parts dilated with round corners. + pub fn round_convex_decomposition( + vertices: &[Point<Real>], + indices: &[[u32; DIM]], + border_radius: Real, + ) -> Self { + Self::new(ColliderShape::round_convex_decomposition( + vertices, + indices, + border_radius, + )) + } + + /// Initializes a collider builder with a compound shape obtained from the decomposition of + /// the given trimesh (in 3D) or polyline (in 2D) into convex parts. + pub fn convex_decomposition_with_params( + vertices: &[Point<Real>], + indices: &[[u32; DIM]], + params: &VHACDParameters, + ) -> Self { + Self::new(ColliderShape::convex_decomposition_with_params( + vertices, indices, params, + )) + } + + /// Initializes a collider builder with a compound shape obtained from the decomposition of + /// the given trimesh (in 3D) or polyline (in 2D) into convex parts dilated with round corners. + pub fn round_convex_decomposition_with_params( + vertices: &[Point<Real>], + indices: &[[u32; DIM]], + params: &VHACDParameters, + border_radius: Real, + ) -> Self { + Self::new(ColliderShape::round_convex_decomposition_with_params( + vertices, + indices, + params, + border_radius, + )) + } + pub fn convex_hull(points: &[Point<Real>]) -> Option<Self> { ColliderShape::convex_hull(points).map(|cp| Self::new(cp)) } diff --git a/src/geometry/collider_shape.rs b/src/geometry/collider_shape.rs index 4777850..05067ef 100644 --- a/src/geometry/collider_shape.rs +++ b/src/geometry/collider_shape.rs @@ -1,4 +1,5 @@ -use crate::math::{Isometry, Point, Real, Vector}; +use crate::cdl::transformation::vhacd::{VHACDParameters, VHACD}; +use crate::math::{Isometry, Point, Real, Vector, DIM}; use cdl::shape::{ Ball, Capsule, Compound, Cuboid, HalfSpace, HeightField, RoundCuboid, RoundShape, RoundTriangle, Segment, Shape, ShapeType, TriMesh, Triangle, @@ -122,6 +123,66 @@ impl ColliderShape { ColliderShape(Arc::new(TriMesh::new(vertices, indices))) } + /// Initializes a compound shape obtained from the decomposition of the given trimesh (in 3D) or + /// polyline (in 2D) into convex parts. + pub fn convex_decomposition(vertices: &[Point<Real>], indices: &[[u32; DIM]]) -> Self { + Self::convex_decomposition_with_params(vertices, indices, &VHACDParameters::default()) + } + + /// Initializes a compound shape obtained from the decomposition of the given trimesh (in 3D) or + /// polyline (in 2D) into convex parts dilated with round corners. + pub fn round_convex_decomposition( + vertices: &[Point<Real>], + indices: &[[u32; DIM]], + border_radius: Real, + ) -> Self { + Self::round_convex_decomposition_with_params( + vertices, + indices, + &VHACDParameters::default(), + border_radius, + ) + } + + /// Initializes a compound shape obtained from the decomposition of the given trimesh (in 3D) or + /// polyline (in 2D) into convex parts. + pub fn convex_decomposition_with_params( + vertices: &[Point<Real>], + indices: &[[u32; DIM]], + params: &VHACDParameters, + ) -> Self { + let mut parts = vec![]; + let decomp = VHACD::decompose(params, &vertices, &indices, true); + + for (vertices, indices) in decomp.compute_exact_convex_hulls(&vertices, &indices) { + if let Some(convex) = Self::convex_mesh(vertices, &indices) { + parts.push((Isometry::identity(), convex)); + } + } + + Self::compound(parts) + } + + /// Initializes a compound shape obtained from the decomposition of the given trimesh (in 3D) or + /// polyline (in 2D) into convex parts dilated with round corners. + pub fn round_convex_decomposition_with_params( + vertices: &[Point<Real>], + indices: &[[u32; DIM]], + params: &VHACDParameters, + border_radius: Real, + ) -> Self { + let mut parts = vec![]; + let decomp = VHACD::decompose(params, &vertices, &indices, true); + + for (vertices, indices) in decomp.compute_exact_convex_hulls(&vertices, &indices) { + if let Some(convex) = Self::round_convex_mesh(vertices, &indices, border_radius) { + parts.push((Isometry::identity(), convex)); + } + } + + Self::compound(parts) + } + pub fn convex_hull(points: &[Point<Real>]) -> Option<Self> { #[cfg(feature = "dim2")] return ConvexPolygon::from_convex_hull(points).map(|ch| ColliderShape(Arc::new(ch))); |
