parry3d/transformation/to_outline/
ball_to_outline.rs

1use crate::math::{Isometry, Point, Real, Vector};
2use crate::shape::Ball;
3use crate::transformation::utils;
4use alloc::vec::Vec;
5use na::{self, Point3, RealField};
6
7impl Ball {
8    /// Outlines this ball’s shape using polylines.
9    pub fn to_outline(&self, nsubdiv: u32) -> (Vec<Point3<Real>>, Vec<[u32; 2]>) {
10        let diameter = self.radius * 2.0;
11        let (vtx, idx) = unit_sphere_outline(nsubdiv);
12        (utils::scaled(vtx, Vector::repeat(diameter)), idx)
13    }
14}
15
16fn unit_sphere_outline(nsubdiv: u32) -> (Vec<Point3<Real>>, Vec<[u32; 2]>) {
17    let two_pi = Real::two_pi();
18    let dtheta = two_pi / (nsubdiv as Real);
19    let mut coords = Vec::new();
20    let mut indices = Vec::new();
21
22    utils::push_circle(0.5, nsubdiv, dtheta, 0.0, &mut coords);
23    utils::push_circle(0.5, nsubdiv, dtheta, 0.0, &mut coords);
24    utils::push_circle(0.5, nsubdiv, dtheta, 0.0, &mut coords);
25
26    let n = nsubdiv as usize;
27    utils::transform(
28        &mut coords[n..n * 2],
29        Isometry::rotation(Vector::x() * Real::frac_pi_2()),
30    );
31    utils::transform(
32        &mut coords[n * 2..n * 3],
33        Isometry::rotation(Vector::z() * Real::frac_pi_2()),
34    );
35
36    utils::push_circle_outline_indices(&mut indices, 0..nsubdiv);
37    utils::push_circle_outline_indices(&mut indices, nsubdiv..nsubdiv * 2);
38    utils::push_circle_outline_indices(&mut indices, nsubdiv * 2..nsubdiv * 3);
39
40    (coords, indices)
41}
42
43/// Creates an hemisphere with a radius of 0.5.
44pub(crate) fn push_unit_hemisphere_outline(
45    nsubdiv: u32,
46    pts: &mut Vec<Point<Real>>,
47    idx: &mut Vec<[u32; 2]>,
48) {
49    let base_idx = pts.len() as u32;
50    let dtheta = Real::pi() / (nsubdiv as Real);
51    let npoints = nsubdiv + 1;
52
53    utils::push_circle(0.5, npoints, dtheta, 0.0, pts);
54    utils::push_circle(0.5, npoints, dtheta, 0.0, pts);
55
56    let n = npoints as usize;
57    utils::transform(
58        &mut pts[base_idx as usize..base_idx as usize + n],
59        Isometry::rotation(Vector::x() * -Real::frac_pi_2()),
60    );
61    utils::transform(
62        &mut pts[base_idx as usize + n..base_idx as usize + n * 2],
63        Isometry::rotation(Vector::z() * Real::frac_pi_2())
64            * Isometry::rotation(Vector::y() * Real::frac_pi_2()),
65    );
66
67    utils::push_open_circle_outline_indices(idx, base_idx..base_idx + npoints);
68    utils::push_open_circle_outline_indices(idx, base_idx + npoints..base_idx + npoints * 2);
69}