parry3d/transformation/to_trimesh/
voxels_to_trimesh.rs

1use crate::bounding_volume::Aabb;
2use crate::math::{Point, Real};
3use crate::shape::Voxels;
4use alloc::{vec, vec::Vec};
5
6impl Voxels {
7    /// Computes an unoptimized mesh representation of this shape.
8    ///
9    /// Each free face of each voxel will result in two triangles. No effort is made to merge
10    /// adjacent triangles on large flat areas.
11    pub fn to_trimesh(&self) -> (Vec<Point<Real>>, Vec<[u32; 3]>) {
12        let aabb = Aabb::from_half_extents(Point::origin(), self.voxel_size() / 2.0);
13        let aabb_vtx = aabb.vertices();
14
15        let mut vtx = vec![];
16        let mut idx = vec![];
17        for vox in self.voxels() {
18            let mask = vox.state.free_faces();
19            for i in 0..6 {
20                if mask.bits() & (1 << i) != 0 {
21                    let fvid = Aabb::FACES_VERTEX_IDS[i];
22                    let base_id = vtx.len() as u32;
23                    vtx.push(vox.center + aabb_vtx[fvid.0].coords);
24                    vtx.push(vox.center + aabb_vtx[fvid.1].coords);
25                    vtx.push(vox.center + aabb_vtx[fvid.2].coords);
26                    vtx.push(vox.center + aabb_vtx[fvid.3].coords);
27
28                    if i % 2 == 0 {
29                        idx.push([base_id, base_id + 1, base_id + 2]);
30                        idx.push([base_id, base_id + 2, base_id + 3]);
31                    } else {
32                        idx.push([base_id, base_id + 2, base_id + 1]);
33                        idx.push([base_id, base_id + 3, base_id + 2]);
34                    }
35                }
36            }
37        }
38
39        (vtx, idx)
40    }
41}