parry3d/transformation/to_trimesh/
cylinder_to_trimesh.rs

1use crate::math::Real;
2use crate::shape::Cylinder;
3use crate::transformation::utils;
4use alloc::vec::Vec;
5use na::{self, Point3, RealField, Vector3};
6
7impl Cylinder {
8    /// Discretize the boundary of this cylinder as a triangle-mesh.
9    pub fn to_trimesh(&self, nsubdiv: u32) -> (Vec<Point3<Real>>, Vec<[u32; 3]>) {
10        let diameter = self.radius * 2.0;
11        let height = self.half_height * 2.0;
12        let scale = Vector3::new(diameter, height, diameter);
13        let (vtx, idx) = unit_cylinder(nsubdiv);
14        (utils::scaled(vtx, scale), idx)
15    }
16}
17
18/// Generates a cylinder with unit height and diameter.
19fn unit_cylinder(nsubdiv: u32) -> (Vec<Point3<Real>>, Vec<[u32; 3]>) {
20    let two_pi = Real::two_pi();
21    let invsubdiv = 1.0 / (nsubdiv as Real);
22    let dtheta = two_pi * invsubdiv;
23    let mut coords = Vec::new();
24    let mut indices = Vec::new();
25
26    utils::push_circle(
27        na::convert(0.5),
28        nsubdiv,
29        dtheta,
30        na::convert(-0.5),
31        &mut coords,
32    );
33
34    utils::push_circle(
35        na::convert(0.5),
36        nsubdiv,
37        dtheta,
38        na::convert(0.5),
39        &mut coords,
40    );
41
42    utils::push_ring_indices(0, nsubdiv, nsubdiv, &mut indices);
43    utils::push_filled_circle_indices(0, nsubdiv, &mut indices);
44    utils::push_filled_circle_indices(nsubdiv, nsubdiv, &mut indices);
45
46    let len = indices.len();
47    let bottom_start_id = len - (nsubdiv as usize - 2);
48    utils::reverse_clockwising(&mut indices[bottom_start_id..]);
49
50    (coords, indices)
51}