chull_adapt/common/
convex_hull.rs1use glam_det::{Point3, UnitVec3, Vec3};
16
17pub struct ConvexHull {
18 pub points: Vec<Point3>,
19 pub bounding_planes: Vec<HalfPlane>,
20 pub face_indices_start: Vec<u32>,
21 pub face_vertex_indices: Vec<u32>,
22 pub center: Vec3,
23 pub volume: f32,
24 pub total_area: f32,
25 pub shift_center: Option<Vec3>,
31 pub debug: Option<ConvexHullDebugInfo>,
32}
33
34impl<'a> ConvexHull {
35 #[inline]
36 #[must_use]
37 pub fn get_vertex_indices(&self, face_index: usize) -> &[u32] {
38 let start = self.face_indices_start[face_index] as usize;
39 let next_index = face_index + 1;
40 let end = if next_index < self.face_indices_start.len() {
41 self.face_indices_start[next_index] as usize
42 } else {
43 self.face_vertex_indices.len()
44 };
45 &self.face_vertex_indices[start..end]
46 }
47
48 pub fn triangle_index_iter(&self) -> impl Iterator<Item = [usize; 3]> + '_ {
49 ConvexHullTriangleIndexIter::new(self)
50 }
51
52 pub fn face_iter(&'a self) -> impl Iterator<Item = &'a [u32]> {
53 ConvexHullFaceIter::new(self)
54 }
55}
56
57pub struct ConvexHullTriangleIndexIter<'a> {
59 hull: &'a ConvexHull,
60 face_index: usize,
61 sub_triangle_index: usize,
62}
63impl<'a> ConvexHullTriangleIndexIter<'a> {
64 #[inline]
65 #[must_use]
66 pub fn new(hull: &'a ConvexHull) -> Self {
67 Self {
68 hull,
69 face_index: 0,
70 sub_triangle_index: 2,
71 }
72 }
73}
74
75impl Iterator for ConvexHullTriangleIndexIter<'_> {
76 type Item = [usize; 3];
77
78 #[inline]
79 fn next(&mut self) -> Option<Self::Item> {
80 if self.face_index < self.hull.face_indices_start.len() {
81 let faces = self.hull.get_vertex_indices(self.face_index);
82 let mut triangle = [usize::MAX; 3];
83 triangle[0] = faces[0] as usize;
84 triangle[1] = faces[self.sub_triangle_index - 1] as usize;
85 triangle[2] = faces[self.sub_triangle_index] as usize;
86
87 self.sub_triangle_index += 1;
88 if self.sub_triangle_index == faces.len() {
89 self.face_index += 1;
90 self.sub_triangle_index = 2;
91 }
92 Some(triangle)
93 } else {
94 None
95 }
96 }
97}
98
99pub struct ConvexHullFaceIter<'a> {
100 hull: &'a ConvexHull,
101 face_index: usize,
102}
103impl<'a> ConvexHullFaceIter<'a> {
104 #[inline]
105 #[must_use]
106 pub fn new(hull: &'a ConvexHull) -> Self {
107 Self {
108 hull,
109 face_index: 0,
110 }
111 }
112}
113
114impl<'a> Iterator for ConvexHullFaceIter<'a> {
115 type Item = &'a [u32];
116
117 #[inline]
118 fn next(&mut self) -> Option<Self::Item> {
119 if self.face_index < self.hull.face_indices_start.len() {
120 let faces = self.hull.get_vertex_indices(self.face_index);
121 self.face_index += 1;
122 Some(faces)
123 } else {
124 None
125 }
126 }
127}
128
129pub struct HalfPlane {
135 pub center: Point3,
136 pub normal: UnitVec3,
137 pub offset: f32,
138}
139
140#[derive(Default)]
141pub struct ConvexHullDebugInfo {
142 pub neighbours_index: Vec<u32>,
143 pub neighbours_index_start: Vec<u32>,
146}
147
148#[derive(Default)]
149pub struct ConvexMesh {
150 pub vertices: Vec<Point3>,
151 pub triangles: Vec<u32>,
152}
153
154impl ConvexMesh {
155 #[must_use]
156 #[inline]
157 pub fn num_triangles(&self) -> u32 {
158 let triangles = self.triangles.len();
159 (triangles / 3) as u32
160 }
161
162 #[must_use]
163 #[inline]
164 pub fn num_vertices(&self) -> u32 {
165 self.vertices.len() as u32
166 }
167
168 #[must_use]
169 #[inline]
170 pub fn vertices(&self) -> &[Point3] {
171 &self.vertices
172 }
173
174 #[must_use]
175 #[inline]
176 pub fn triangles(&self) -> &[u32] {
177 &self.triangles
178 }
179}