Skip to main content

bevy_rapier3d/geometry/shape_views/
heightfield.rs

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