bevy_rapier2d/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()
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)
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, seg.b))
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.segment_at(i).map(|seg| (seg.a, seg.b))
54 }
55
56 /// Is the i-th segment of this heightfield removed?
57 pub fn is_segment_removed(&self, i: usize) -> bool {
58 self.raw.is_segment_removed(i)
59 }
60 }
61
62 #[cfg(feature = "dim3")]
63 impl<'a> $View<'a> {
64 /// The number of rows of this heightfield.
65 pub fn nrows(&self) -> usize {
66 self.raw.nrows()
67 }
68
69 /// The number of columns of this heightfield.
70 pub fn ncols(&self) -> usize {
71 self.raw.ncols()
72 }
73
74 /// The height at each cell endpoint.
75 pub fn heights(&self) -> &[Real] {
76 self.raw.heights().data()
77 }
78
79 /// The scale factor applied to this heightfield.
80 pub fn scale(&self) -> Vect {
81 self.raw.scale()
82 }
83
84 /// The width (extent along its local `x` axis) of each cell of this heightmap, including the scale factor.
85 pub fn cell_width(&self) -> Real {
86 self.raw.cell_width()
87 }
88
89 /// The height (extent along its local `z` axis) of each cell of this heightmap, including the scale factor.
90 pub fn cell_height(&self) -> Real {
91 self.raw.cell_height()
92 }
93
94 /// The width (extent along its local `x` axis) of each cell of this heightmap, excluding the scale factor.
95 pub fn unit_cell_width(&self) -> Real {
96 self.raw.unit_cell_width()
97 }
98
99 /// The height (extent along its local `z` axis) of each cell of this heightmap, excluding the scale factor.
100 pub fn unit_cell_height(&self) -> Real {
101 self.raw.unit_cell_height()
102 }
103
104 /// Index of the cell a point is on after vertical projection.
105 pub fn cell_at_point(&self, point: Vect) -> Option<(usize, usize)> {
106 self.raw.cell_at_point(point)
107 }
108
109 /// Iterator through all the triangles of this heightfield.
110 pub fn triangles(&self) -> impl Iterator<Item = (Vect, Vect, Vect)> + '_ {
111 self.raw.triangles().map(|tri| (tri.a, tri.b, tri.c))
112 }
113
114 /// The two triangles at the cell (i, j) of this heightfield.
115 ///
116 /// Returns `None` fore triangles that have been removed because of their user-defined status
117 /// flags (described by the `HeightFieldCellStatus` bitfield).
118 pub fn triangles_at(
119 &self,
120 i: usize,
121 j: usize,
122 ) -> (Option<(Vect, Vect, Vect)>, Option<(Vect, Vect, Vect)>) {
123 let (tri1, tri2) = self.raw.triangles_at(i, j);
124 (
125 tri1.map(|tri| (tri.a, tri.b, tri.c)),
126 tri2.map(|tri| (tri.a, tri.b, tri.c)),
127 )
128 }
129
130 /// The status of the `(i, j)`-th cell.
131 pub fn cell_status(&self, i: usize, j: usize) -> HeightFieldCellStatus {
132 self.raw.cell_status(i, j)
133 }
134
135 /// The statuses of all the cells of this heightfield, in column-major order.
136 pub fn cells_statuses(&self) -> &[HeightFieldCellStatus] {
137 self.raw.cells_statuses().data()
138 }
139 }
140 }
141);
142
143impl_ref_methods!(HeightFieldView);
144
145/// Read-write access to the properties of a heightfield.
146pub struct HeightFieldViewMut<'a> {
147 /// The raw shape from Rapier.
148 pub raw: &'a mut HeightField,
149}
150
151impl_ref_methods!(HeightFieldViewMut);
152
153#[cfg(feature = "dim2")]
154impl HeightFieldViewMut<'_> {
155 /// Sets whether or not the given cell of the heightfield is deleted.
156 pub fn set_segment_removed(&mut self, i: usize, removed: bool) {
157 self.raw.set_segment_removed(i, removed)
158 }
159}
160
161#[cfg(feature = "dim3")]
162impl HeightFieldViewMut<'_> {
163 /// Set the status of the `(i, j)`-th cell.
164 pub fn set_cell_status(&mut self, i: usize, j: usize, status: HeightFieldCellStatus) {
165 self.raw.set_cell_status(i, j, status)
166 }
167
168 /// The mutable statuses of all the cells of this heightfield.
169 pub fn cells_statuses_mut(&mut self) -> &mut [HeightFieldCellStatus] {
170 self.raw.cells_statuses_mut().data_mut()
171 }
172}