aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples3d/convex_decomposition3.rs14
-rw-r--r--src/geometry/collider.rs51
-rw-r--r--src/geometry/collider_shape.rs63
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(&params, &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)));