1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
use parry::bounding_volume;
use parry::math::{Isometry, Point, Real};
use parry::shape::{Cuboid, SharedShape, TriMeshFlags};
#[cfg(feature = "dim3")]
use parry::transformation::vhacd::VHACDParameters;
/*
*
* TODO: should all this be part of parry instead?
*
*/
/// Error that can be generated by the [`MeshConverter`].
#[derive(thiserror::Error, Debug)]
pub enum MeshConverterError {
/// The convex hull calculation carried out by the [`MeshConverter::ConvexHull`] failed.
#[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.
#[cfg(feature = "dim3")]
ConvexDecomposition,
/// The mesh is replaced by its convex decomposition with parameters specified to adjust
/// the convex decomposition algorithm.
#[cfg(feature = "dim3")]
ConvexDecompositionWithParams(VHACDParameters),
}
impl MeshConverter {
/// Applies the conversion rule described by this [`MeshConverter`] to build a shape from
/// the given vertex and index buffers.
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)?
}
#[cfg(feature = "dim3")]
MeshConverter::ConvexDecomposition => {
SharedShape::convex_decomposition(&vertices, &indices)
}
#[cfg(feature = "dim3")]
MeshConverter::ConvexDecompositionWithParams(params) => {
SharedShape::convex_decomposition_with_params(&vertices, &indices, params)
}
};
Ok((shape, transform))
}
}
|