parry3d/transformation/to_outline/
ball_to_outline.rs

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