parry3d/transformation/to_outline/
ball_to_outline.rs1use crate::math::{Pose, Real, RealField, Vector};
2use crate::shape::Ball;
3use crate::transformation::utils;
4use alloc::vec::Vec;
5
6impl Ball {
7 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
42pub(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}