aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSébastien Crozet <sebcrozet@dimforge.com>2024-05-26 18:15:06 +0200
committerSébastien Crozet <sebastien@crozet.re>2024-06-09 12:09:58 +0200
commit9865d5836a18579d3edfc6bccb8dbc08a01e5a6b (patch)
treee9adc6c453229613db59eb65c219d4b2503aa9b3
parentd127af78168d43d8bd990fb120f221226b1fc010 (diff)
downloadrapier-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.rs17
-rw-r--r--src/geometry/mesh_converter.rs82
-rw-r--r--src/geometry/mod.rs7
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, &params)
+ }
+ };
+ 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;