extract core shape from the crown gear mesh generator

This commit is contained in:
numzero 2026-10-19 23:58:19 +03:00
parent daa7f413de
commit 5419c9c5f4

View File

@ -1,4 +1,4 @@
use std::f32::consts::PI;
use std::{f32::consts::PI, ops::Range};
use glam::{Mat3A, Vec3, vec3};
@ -20,6 +20,23 @@ pub struct CrownGearVisual {
pub base_thickness: f32,
}
impl CrownGearDesc {
pub fn to_shape(&self, part: Range<f32>, sides: usize) -> Vec<Vec3> {
let teeth = 2.0 * self.pitch_radius;
let mut ret = Vec::new();
ret.reserve_exact(sides);
for k in 0..sides {
let t0 = k as f32 / sides as f32;
let t = part.start + t0 * (part.end - part.start);
let rot = Mat3A::from_rotation_z(2.0 * PI * t);
let tooth = t * teeth;
let z = self.profile.y_from_tooth(tooth);
ret.push(rot * vec3(self.pitch_radius, 0.0, z));
}
ret
}
}
pub fn make_mesh_smooth(
desc: &CrownGearDesc,
visual: &CrownGearVisual,
@ -85,28 +102,26 @@ pub fn make_mesh_simple(
visual: &CrownGearVisual,
sides: usize,
) -> MeshIndexed<Vec3> {
let teeth = 2.0 * desc.pitch_radius;
let inner_scale = visual.inner_radius / desc.pitch_radius;
let outer_scale = visual.outer_radius / desc.pitch_radius;
let shape = desc.to_shape(0.0..1.0, sides);
assert_eq!(shape.len(), sides);
let mut mesh = MeshIndexed::new();
mesh.vertices.reserve_exact(4 * sides);
mesh.faces.reserve_exact(8 * sides);
for k in 0..sides {
let t = k as f32 / sides as f32;
let rot = Mat3A::from_rotation_z(2.0 * PI * t);
let tooth = t * teeth;
let y = desc.profile.y_from_tooth(tooth);
let vertex = |x, z| rot * vec3(x, 0.0, z);
for pt in shape {
let inner = inner_scale * pt;
let outer = outer_scale * pt;
mesh.vertices.extend([
vertex(visual.inner_radius, -visual.base_thickness),
vertex(visual.outer_radius, -visual.base_thickness),
vertex(visual.outer_radius, outer_scale * y),
vertex(visual.inner_radius, inner_scale * y),
inner.with_z(-visual.base_thickness),
outer.with_z(-visual.base_thickness),
outer,
inner,
]);
}
for k in 0..sides {
let base1 = 4 * k;
let base2 = 4 * ((k + 1) % sides);
for j1 in 0..4 {