diff options
| author | Sébastien Crozet <sebcrozet@dimforge.com> | 2024-05-26 18:15:06 +0200 |
|---|---|---|
| committer | Sébastien Crozet <sebastien@crozet.re> | 2024-06-09 12:09:58 +0200 |
| commit | 9865d5836a18579d3edfc6bccb8dbc08a01e5a6b (patch) | |
| tree | e9adc6c453229613db59eb65c219d4b2503aa9b3 | |
| parent | d127af78168d43d8bd990fb120f221226b1fc010 (diff) | |
| download | rapier-9865d5836a18579d3edfc6bccb8dbc08a01e5a6b.tar.gz rapier-9865d5836a18579d3edfc6bccb8dbc08a01e5a6b.tar.bz2 rapier-9865d5836a18579d3edfc6bccb8dbc08a01e5a6b.zip | |
feat: add MeshConverter and Colliders::converted_trimesh for building a collider with a shape computed form mesh buffers
| -rw-r--r-- | src/geometry/collider.rs | 17 | ||||
| -rw-r--r-- | src/geometry/mesh_converter.rs | 82 | ||||
| -rw-r--r-- | src/geometry/mod.rs | 7 |
3 files changed, 102 insertions, 4 deletions
diff --git a/src/geometry/collider.rs b/src/geometry/collider.rs index c58548e..d72e098 100644 --- a/src/geometry/collider.rs +++ b/src/geometry/collider.rs @@ -2,7 +2,7 @@ use crate::dynamics::{CoefficientCombineRule, MassProperties, RigidBodyHandle}; use crate::geometry::{ ActiveCollisionTypes, BroadPhaseProxyIndex, ColliderBroadPhaseData, ColliderChanges, ColliderFlags, ColliderMassProps, ColliderMaterial, ColliderParent, ColliderPosition, - ColliderShape, ColliderType, InteractionGroups, SharedShape, + ColliderShape, ColliderType, InteractionGroups, MeshConverter, MeshConverterError, SharedShape, }; use crate::math::{AngVector, Isometry, Point, Real, Rotation, Vector, DIM}; use crate::parry::transformation::vhacd::VHACDParameters; @@ -698,6 +698,21 @@ impl ColliderBuilder { Self::new(SharedShape::trimesh_with_flags(vertices, indices, flags)) } + /// Initializes a collider builder with a shape converted from the given triangle mesh index + /// and vertex buffer. + /// + /// All the conversion variants could be achieved with other constructors of [`ColliderBuilder`] + /// but having this specified by an enum can occasionally be easier or more flexible (determined + /// at runtime). + pub fn converted_trimesh( + vertices: Vec<Point<Real>>, + indices: Vec<[u32; 3]>, + converter: MeshConverter, + ) -> Result<Self, MeshConverterError> { + let (shape, pose) = converter.convert(vertices, indices)?; + Ok(Self::new(shape).position(pose)) + } + /// 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 { diff --git a/src/geometry/mesh_converter.rs b/src/geometry/mesh_converter.rs new file mode 100644 index 0000000..e2f515a --- /dev/null +++ b/src/geometry/mesh_converter.rs @@ -0,0 +1,82 @@ +use parry::bounding_volume; +use parry::math::{Isometry, Point, Real}; +use parry::shape::{Cuboid, SharedShape, TriMeshFlags}; +use parry::transformation::vhacd::VHACDParameters; + +/* + * + * TODO: should all this be part of parry instead? + * + */ + +#[derive(thiserror::Error, Debug)] +pub enum MeshConverterError { + #[error("convex-hull computation failed")] + ConvexHullFailed, +} + +/// Determines how meshes (generally when loaded from a file) are converted into Rapier colliders. +// TODO: implement Copy once we add a Copy implementation for VHACDParameters. +#[derive(Clone, Debug, PartialEq, Default)] +pub enum MeshConverter { + /// The mesh is loaded as-is without any particular processing. + #[default] + TriMesh, + /// The mesh is loaded with the specified flags. + TriMeshWithFlags(TriMeshFlags), + /// The mesh is replaced by its Oriented Bounding Box (represented as + /// a rotated cuboid). + /// + /// With this option, the mesh’s index buffer is ignored. + Obb, + /// The mesh is replaced by its AABB. + /// + /// With this option, the mesh’s index buffer is ignored. + Aabb, + /// The mesh is replaced by its convex-hull. + /// + /// With this option, the mesh’s index buffer is ignored. + ConvexHull, + /// The mesh is replaced by its convex decomposition. + ConvexDecomposition, + /// The mesh is replaced by its convex decomposition with parameters specified to adjust + /// the convex decomposition algorithm. + ConvexDecompositionWithParams(VHACDParameters), +} + +impl MeshConverter { + pub fn convert( + &self, + vertices: Vec<Point<Real>>, + indices: Vec<[u32; 3]>, + ) -> Result<(SharedShape, Isometry<Real>), MeshConverterError> { + let mut transform = Isometry::identity(); + let shape = match self { + MeshConverter::TriMesh => SharedShape::trimesh(vertices, indices), + MeshConverter::TriMeshWithFlags(flags) => { + SharedShape::trimesh_with_flags(vertices, indices, *flags) + } + MeshConverter::Obb => { + let (pose, cuboid) = parry::utils::obb(&vertices); + transform = pose; + SharedShape::new(cuboid) + } + MeshConverter::Aabb => { + let aabb = bounding_volume::details::local_point_cloud_aabb(&vertices); + let cuboid = Cuboid::new(aabb.half_extents()); + transform = Isometry::from(aabb.center().coords); + SharedShape::new(cuboid) + } + MeshConverter::ConvexHull => { + SharedShape::convex_hull(&vertices).ok_or(MeshConverterError::ConvexHullFailed)? + } + MeshConverter::ConvexDecomposition => { + SharedShape::convex_decomposition(&vertices, &indices) + } + MeshConverter::ConvexDecompositionWithParams(params) => { + SharedShape::convex_decomposition_with_params(&vertices, &indices, ¶ms) + } + }; + Ok((shape, transform)) + } +} diff --git a/src/geometry/mod.rs b/src/geometry/mod.rs index 1eaad79..e7f0da7 100644 --- a/src/geometry/mod.rs +++ b/src/geometry/mod.rs @@ -2,7 +2,9 @@ pub use self::broad_phase::BroadPhase; pub use self::broad_phase_multi_sap::{BroadPhaseMultiSap, BroadPhasePairEvent, ColliderPair}; +pub use self::collider::{Collider, ColliderBuilder}; pub use self::collider_components::*; +pub use self::collider_set::ColliderSet; pub use self::contact_pair::{ ContactData, ContactManifoldData, ContactPair, IntersectionPair, SolverContact, SolverFlags, }; @@ -10,11 +12,9 @@ pub use self::interaction_graph::{ ColliderGraphIndex, InteractionGraph, RigidBodyGraphIndex, TemporaryInteractionIndex, }; pub use self::interaction_groups::{Group, InteractionGroups}; +pub use self::mesh_converter::{MeshConverter, MeshConverterError}; pub use self::narrow_phase::NarrowPhase; -pub use self::collider::{Collider, ColliderBuilder}; -pub use self::collider_set::ColliderSet; - pub use parry::bounding_volume::BoundingVolume; pub use parry::query::{PointQuery, PointQueryWithLocation, RayCast, TrackedContact}; pub use parry::shape::SharedShape; @@ -207,3 +207,4 @@ mod broad_phase; mod broad_phase_qbvh; mod collider; mod collider_set; +mod mesh_converter; |
