Skip to main content

bevy_rapier2d/geometry/shape_views/
trimesh.rs

1use crate::geometry::Collider;
2use crate::math::{Rot, Vect};
3#[cfg(feature = "dim3")]
4use rapier::parry::shape::TriMeshPseudoNormals;
5use rapier::parry::shape::{
6    FeatureId, TopologyError, TriMesh, TriMeshBuilderError, TriMeshConnectedComponents,
7    TriMeshFlags, TriMeshTopology,
8};
9
10/// Read-only access to the properties of a triangle mesh.
11#[derive(Copy, Clone)]
12pub struct TriMeshView<'a> {
13    /// The raw shape from Rapier.
14    pub raw: &'a TriMesh,
15}
16
17macro_rules! impl_ref_methods(
18    ($View: ident) => {
19        impl<'a> $View<'a> {
20            /// The number of triangles forming this mesh.
21            pub fn num_triangles(&self) -> usize {
22                self.raw.num_triangles()
23            }
24
25            /// An iterator through all the triangles of this mesh.
26            pub fn triangles(&self) -> impl ExactSizeIterator<Item = (Vect, Vect, Vect)> + '_ {
27                self.raw
28                    .triangles()
29                    .map(|tri| (tri.a.into(), tri.b.into(), tri.c.into()))
30            }
31
32            /// Get the `i`-th triangle of this mesh.
33            pub fn triangle(&self, i: u32) -> (Vect, Vect, Vect) {
34                let tri = self.raw.triangle(i);
35                (tri.a.into(), tri.b.into(), tri.c.into())
36            }
37
38            /// The vertex buffer of this mesh.
39            pub fn vertices(&self) -> impl ExactSizeIterator<Item = Vect> + '_ {
40                self.raw.vertices().iter().map(|pt| (*pt).into())
41            }
42
43            /// The index buffer of this mesh.
44            pub fn indices(&self) -> &[[u32; 3]] {
45                self.raw.indices()
46            }
47
48            /// A flat view of the index buffer of this mesh.
49            pub fn flat_indices(&self) -> &[u32] {
50                self.raw.flat_indices()
51            }
52
53            /// The flags controlling the optional data associated to this mesh.
54            pub fn flags(&self) -> TriMeshFlags {
55                self.raw.flags()
56            }
57
58            /// The outward normal of the `i`-th triangle, or `None` if it is degenerate.
59            #[cfg(feature = "dim3")]
60            pub fn triangle_normal(&self, i: u32) -> Option<Vect> {
61                self.raw.triangle_normal(i)
62            }
63
64            /// Does the given feature (as returned by a ray-cast or point projection on one of
65            /// the triangles) identify the back face of that triangle?
66            pub fn is_backface(&self, feature: FeatureId) -> bool {
67                self.raw.is_backface(feature)
68            }
69
70            /// The half-edge topology of this mesh, if it was computed.
71            ///
72            /// This requires the [`TriMeshFlags::HALF_EDGE_TOPOLOGY`] flag.
73            pub fn topology(&self) -> Option<&TriMeshTopology> {
74                self.raw.topology()
75            }
76
77            /// The connected components of this mesh, if they were computed.
78            ///
79            /// This requires the [`TriMeshFlags::CONNECTED_COMPONENTS`] flag.
80            pub fn connected_components(&self) -> Option<&TriMeshConnectedComponents> {
81                self.raw.connected_components()
82            }
83
84            /// The number of connected components of this mesh, if they were computed.
85            pub fn num_connected_components(&self) -> Option<usize> {
86                self.raw
87                    .connected_components()
88                    .map(|cc| cc.num_connected_components())
89            }
90
91            /// Builds one triangle mesh collider per connected component of this mesh, each
92            /// built with the given `flags`.
93            ///
94            /// Returns `None` if the connected components were not computed.
95            pub fn connected_component_colliders(
96                &self,
97                flags: TriMeshFlags,
98            ) -> Option<Vec<Result<Collider, TriMeshBuilderError>>> {
99                self.raw.connected_component_meshes(flags).map(|meshes| {
100                    meshes
101                        .into_iter()
102                        .map(|mesh| mesh.map(|mesh| rapier::prelude::SharedShape::new(mesh).into()))
103                        .collect()
104                })
105            }
106
107            /// The vertex and edge pseudo-normals of this mesh, if they were computed.
108            ///
109            /// They are computed with the [`TriMeshFlags::ORIENTED`] or
110            /// [`TriMeshFlags::FIX_INTERNAL_EDGES`] flags.
111            #[cfg(feature = "dim3")]
112            pub fn pseudo_normals(&self) -> Option<&TriMeshPseudoNormals> {
113                self.raw.pseudo_normals()
114            }
115        }
116    }
117);
118
119impl_ref_methods!(TriMeshView);
120
121/// Read-write access to the properties of a triangle mesh.
122pub struct TriMeshViewMut<'a> {
123    /// The raw shape from Rapier.
124    pub raw: &'a mut TriMesh,
125}
126
127impl_ref_methods!(TriMeshViewMut);
128
129impl TriMeshViewMut<'_> {
130    /// Sets the flags of this triangle mesh, controlling its optional associated data.
131    pub fn set_flags(&mut self, flags: TriMeshFlags) -> Result<(), TopologyError> {
132        self.raw.set_flags(flags)
133    }
134
135    /// Replaces the vertex positions, keeping the index buffer and topology.
136    ///
137    /// The acceleration structure is refitted and the pseudo-normals (if any) are recomputed.
138    /// This is intended for meshes built with [`TriMeshFlags::DEFORMABLE`].
139    ///
140    /// # Panics
141    /// Panics if `vertices.len()` differs from the current number of vertices.
142    pub fn set_vertices(&mut self, vertices: &[Vect]) {
143        self.raw.set_vertices(vertices)
144    }
145
146    /// Modifies the vertex positions in place through `f`, then refits the acceleration
147    /// structure and recomputes the pseudo-normals (if any).
148    ///
149    /// This is intended for meshes built with [`TriMeshFlags::DEFORMABLE`].
150    pub fn update_vertices(&mut self, f: impl FnOnce(&mut [Vect])) {
151        self.raw.update_vertices(f)
152    }
153
154    /// Applies a rigid transformation to every vertex of this mesh.
155    pub fn transform_vertices(&mut self, translation: Vect, rotation: Rot) {
156        self.raw
157            .transform_vertices(&crate::utils::pose_from(translation, rotation))
158    }
159
160    /// Reverses the orientation of every triangle of this mesh.
161    pub fn reverse(&mut self) {
162        self.raw.reverse()
163    }
164}