parry3d/transformation/to_outline/
voxels_to_outline.rs1use crate::bounding_volume::Aabb;
2use crate::math::{Point, Real};
3use crate::shape::{VoxelType, Voxels};
4use alloc::{vec, vec::Vec};
5
6impl Voxels {
7 pub fn to_outline(&self) -> (Vec<Point<Real>>, Vec<[u32; 2]>) {
11 let mut points = vec![];
12 self.iter_outline(|a, b| {
13 points.push(a);
14 points.push(b);
15 });
16 let indices = (0..points.len() as u32 / 2)
17 .map(|i| [i * 2, i * 2 + 1])
18 .collect();
19 (points, indices)
20 }
21
22 pub fn iter_outline(&self, mut f: impl FnMut(Point<Real>, Point<Real>)) {
26 let radius = self.voxel_size() / 2.0;
28 let aabb = Aabb::from_half_extents(Point::origin(), radius);
29 let vtx = aabb.vertices();
30
31 for vox in self.voxels() {
32 match vox.state.voxel_type() {
33 VoxelType::Vertex => {
34 let mask = vox.state.feature_mask();
35
36 for edge in Aabb::EDGES_VERTEX_IDS {
37 if mask & (1 << edge.0) != 0 || mask & (1 << edge.1) != 0 {
38 f(
39 vox.center + vtx[edge.0].coords,
40 vox.center + vtx[edge.1].coords,
41 );
42 }
43 }
44 }
45 VoxelType::Edge => {
46 let vtx = aabb.vertices();
47 let mask = vox.state.feature_mask();
48
49 for (i, edge) in Aabb::EDGES_VERTEX_IDS.iter().enumerate() {
50 if mask & (1 << i) != 0 {
51 f(
52 vox.center + vtx[edge.0].coords,
53 vox.center + vtx[edge.1].coords,
54 );
55 }
56 }
57 }
58 _ => {}
59 }
60 }
61 }
62}