1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
use crate::bounding_volume::AABB;
use crate::math::Real;
use crate::shape::Cuboid;
use crate::transformation::utils;
use na::{self, Point3};

impl AABB {
    /// Discretize the boundary of this AABB as a triangle-mesh.
    pub fn to_trimesh(&self) -> (Vec<Point3<Real>>, Vec<[u32; 3]>) {
        let center = self.center();
        let half_extents = self.half_extents();
        let mut cube_mesh = Cuboid::new(half_extents).to_trimesh();
        cube_mesh.0.iter_mut().for_each(|p| *p += center.coords);
        cube_mesh
    }
}

impl Cuboid {
    /// Discretize the boundary of this cuboid as a triangle-mesh.
    pub fn to_trimesh(&self) -> (Vec<Point3<Real>>, Vec<[u32; 3]>) {
        let (vtx, idx) = unit_cuboid();
        (utils::scaled(vtx, self.half_extents * 2.0), idx)
    }
}

/**
 * Generates a cuboid shape with a split index buffer.
 *
 * The cuboid is centered at the origin, and has its half extents set to 0.5.
 */
fn unit_cuboid() -> (Vec<Point3<Real>>, Vec<[u32; 3]>) {
    let mut coords = Vec::with_capacity(8);
    let mut faces = Vec::with_capacity(12);

    coords.push(Point3::new(-0.5, -0.5, 0.5));
    coords.push(Point3::new(-0.5, -0.5, -0.5));
    coords.push(Point3::new(0.5, -0.5, -0.5));
    coords.push(Point3::new(0.5, -0.5, 0.5));
    coords.push(Point3::new(-0.5, 0.5, 0.5));
    coords.push(Point3::new(-0.5, 0.5, -0.5));
    coords.push(Point3::new(0.5, 0.5, -0.5));
    coords.push(Point3::new(0.5, 0.5, 0.5));

    faces.push([4, 5, 0]);
    faces.push([5, 1, 0]);

    faces.push([5, 6, 1]);
    faces.push([6, 2, 1]);

    faces.push([6, 7, 3]);
    faces.push([2, 6, 3]);

    faces.push([7, 4, 0]);
    faces.push([3, 7, 0]);

    faces.push([0, 1, 2]);
    faces.push([3, 0, 2]);

    faces.push([7, 6, 5]);
    faces.push([4, 7, 5]);

    (coords, faces)
}