bevy_rapier3d/geometry/shape_views/
heightfield.rs

1use crate::math::{Real, Vect};
2use rapier::parry::shape::HeightField;
3pub use rapier::parry::shape::HeightFieldCellStatus;
4
5/// Read-only access to the properties of a heightfield.
6#[derive(Copy, Clone)]
7pub struct HeightFieldView<'a> {
8    /// The raw shape from Rapier.
9    pub raw: &'a HeightField,
10}
11
12macro_rules! impl_ref_methods(
13    ($View: ident) => {
14        #[cfg(feature = "dim2")]
15        impl<'a> $View<'a> {
16            /// The number of cells of this heightfield.
17            pub fn num_cells(&self) -> usize {
18                self.raw.num_cells()
19            }
20
21            /// The height at each cell endpoint.
22            pub fn heights(&self) -> &[Real] {
23                self.raw.heights().as_slice()
24            }
25
26            /// The scale factor applied to this heightfield.
27            pub fn scale(&self) -> Vect {
28                (*self.raw.scale()).into()
29            }
30
31            /// The width of a single cell of this heightfield.
32            pub fn cell_width(&self) -> Real {
33                self.raw.cell_width()
34            }
35
36            /// The width of a single cell of this heightfield, without taking the scale factor into account.
37            pub fn unit_cell_width(&self) -> Real {
38                self.raw.unit_cell_width()
39            }
40
41            /// Index of the cell a point is on after vertical projection.
42            pub fn cell_at_point(&self, point: Vect) -> Option<usize> {
43                self.raw.cell_at_point(&point.into())
44            }
45
46            /// Iterator through all the segments of this heightfield.
47            pub fn segments(&self) -> impl Iterator<Item = (Vect, Vect)> + '_ {
48                self.raw.segments().map(|seg| (seg.a.into(), seg.b.into()))
49            }
50
51            /// The i-th segment of the heightfield if it has not been removed.
52            pub fn segment_at(&self, i: usize) -> Option<(Vect, Vect)> {
53                self.raw
54                    .segment_at(i)
55                    .map(|seg| (seg.a.into(), seg.b.into()))
56            }
57
58            /// Is the i-th segment of this heightfield removed?
59            pub fn is_segment_removed(&self, i: usize) -> bool {
60                self.raw.is_segment_removed(i)
61            }
62        }
63
64        #[cfg(feature = "dim3")]
65        impl<'a> $View<'a> {
66            /// The number of rows of this heightfield.
67            pub fn nrows(&self) -> usize {
68                self.raw.nrows()
69            }
70
71            /// The number of columns of this heightfield.
72            pub fn ncols(&self) -> usize {
73                self.raw.ncols()
74            }
75
76            /// The height at each cell endpoint.
77            pub fn heights(&self) -> &[Real] {
78                self.raw.heights().as_slice()
79            }
80
81            /// The scale factor applied to this heightfield.
82            pub fn scale(&self) -> Vect {
83                (*self.raw.scale()).into()
84            }
85
86            /// The width (extent along its local `x` axis) of each cell of this heightmap, including the scale factor.
87            pub fn cell_width(&self) -> Real {
88                self.raw.cell_width()
89            }
90
91            /// The height (extent along its local `z` axis) of each cell of this heightmap, including the scale factor.
92            pub fn cell_height(&self) -> Real {
93                self.raw.cell_height()
94            }
95
96            /// The width (extent along its local `x` axis) of each cell of this heightmap, excluding the scale factor.
97            pub fn unit_cell_width(&self) -> Real {
98                self.raw.unit_cell_width()
99            }
100
101            /// The height (extent along its local `z` axis) of each cell of this heightmap, excluding the scale factor.
102            pub fn unit_cell_height(&self) -> Real {
103                self.raw.unit_cell_height()
104            }
105
106            /// Index of the cell a point is on after vertical projection.
107            pub fn cell_at_point(&self, point: Vect) -> Option<(usize, usize)> {
108                self.raw.cell_at_point(&point.into())
109            }
110
111            /// Iterator through all the triangles of this heightfield.
112            pub fn triangles(&self) -> impl Iterator<Item = (Vect, Vect, Vect)> + '_ {
113                self.raw
114                    .triangles()
115                    .map(|tri| (tri.a.into(), tri.b.into(), tri.c.into()))
116            }
117
118            /// The two triangles at the cell (i, j) of this heightfield.
119            ///
120            /// Returns `None` fore triangles that have been removed because of their user-defined status
121            /// flags (described by the `HeightFieldCellStatus` bitfield).
122            pub fn triangles_at(
123                &self,
124                i: usize,
125                j: usize,
126            ) -> (Option<(Vect, Vect, Vect)>, Option<(Vect, Vect, Vect)>) {
127                let (tri1, tri2) = self.raw.triangles_at(i, j);
128                (
129                    tri1.map(|tri| (tri.a.into(), tri.b.into(), tri.c.into())),
130                    tri2.map(|tri| (tri.a.into(), tri.b.into(), tri.c.into())),
131                )
132            }
133
134            /// The status of the `(i, j)`-th cell.
135            pub fn cell_status(&self, i: usize, j: usize) -> HeightFieldCellStatus {
136                self.raw.cell_status(i, j)
137            }
138
139            /// The statuses of all the cells of this heightfield, in column-major order.
140            pub fn cells_statuses(&self) -> &[HeightFieldCellStatus] {
141                self.raw.cells_statuses().as_slice()
142            }
143        }
144    }
145);
146
147impl_ref_methods!(HeightFieldView);
148
149/// Read-write access to the properties of a heightfield.
150pub struct HeightFieldViewMut<'a> {
151    /// The raw shape from Rapier.
152    pub raw: &'a mut HeightField,
153}
154
155impl_ref_methods!(HeightFieldViewMut);
156
157#[cfg(feature = "dim2")]
158impl HeightFieldViewMut<'_> {
159    /// Sets whether or not the given cell of the heightfield is deleted.
160    pub fn set_segment_removed(&mut self, i: usize, removed: bool) {
161        self.raw.set_segment_removed(i, removed)
162    }
163}
164
165#[cfg(feature = "dim3")]
166impl HeightFieldViewMut<'_> {
167    /// Set the status of the `(i, j)`-th cell.
168    pub fn set_cell_status(&mut self, i: usize, j: usize, status: HeightFieldCellStatus) {
169        self.raw.set_cell_status(i, j, status)
170    }
171
172    /// The mutable statuses of all the cells of this heightfield.
173    pub fn cells_statuses_mut(&mut self) -> &mut [HeightFieldCellStatus] {
174        self.raw.cells_statuses_mut().as_mut_slice()
175    }
176}