parry2d/transformation/to_polyline/
voxels_to_polyline.rs

1use crate::bounding_volume::Aabb;
2use crate::math::{Point, Real};
3use crate::shape::{VoxelType, Voxels};
4use alloc::{vec, vec::Vec};
5use na::{self, Point2};
6
7impl Voxels {
8    /// Converts the outlines of this set of voxels as a polyline.
9    pub fn to_polyline(&self) -> (Vec<Point2<Real>>, Vec<[u32; 2]>) {
10        let mut points = vec![];
11        self.iter_outline(|a, b| {
12            points.push(a);
13            points.push(b);
14        });
15        let indices = (0..points.len() as u32 / 2)
16            .map(|i| [i * 2, i * 2 + 1])
17            .collect();
18        (points, indices)
19    }
20
21    /// Outlines this voxels shape with segments.
22    pub fn iter_outline(&self, mut f: impl FnMut(Point<Real>, Point<Real>)) {
23        // TODO: move this as a new method: Voxels::to_outline?
24        let radius = self.voxel_size() / 2.0;
25        let aabb = Aabb::from_half_extents(Point::origin(), radius);
26        let vtx = aabb.vertices();
27
28        for vox in self.voxels() {
29            match vox.state.voxel_type() {
30                VoxelType::Vertex => {
31                    let mask = vox.state.feature_mask();
32
33                    for edge in Aabb::FACES_VERTEX_IDS {
34                        if mask & (1 << edge.0) != 0 || mask & (1 << edge.1) != 0 {
35                            f(
36                                vox.center + vtx[edge.0].coords,
37                                vox.center + vtx[edge.1].coords,
38                            );
39                        }
40                    }
41                }
42                VoxelType::Face => {
43                    let vtx = aabb.vertices();
44                    let mask = vox.state.feature_mask();
45
46                    for (i, edge) in Aabb::FACES_VERTEX_IDS.iter().enumerate() {
47                        if mask & (1 << i) != 0 {
48                            f(
49                                vox.center + vtx[edge.0].coords,
50                                vox.center + vtx[edge.1].coords,
51                            );
52                        }
53                    }
54                }
55                _ => {}
56            }
57        }
58    }
59}