parry3d/transformation/to_outline/
voxels_to_outline.rs

1use crate::bounding_volume::Aabb;
2use crate::math::{Point, Real};
3use crate::shape::{VoxelType, Voxels};
4use alloc::{vec, vec::Vec};
5
6impl Voxels {
7    /// Outlines this voxels shape as a set of polylines.
8    ///
9    /// The outline is such that only convex edges are output in the polyline.
10    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    /// Outlines this voxels shape using segments.
23    ///
24    /// The outline is such that only convex edges are output in the polyline.
25    pub fn iter_outline(&self, mut f: impl FnMut(Point<Real>, Point<Real>)) {
26        // TODO: move this as a new method: Voxels::to_outline?
27        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}