From 80433d5ed6e379476fbf1a084e5b0688fbd0ef32 Mon Sep 17 00:00:00 2001 From: numzero Date: Sat, 17 Oct 2026 23:04:31 +0300 Subject: [PATCH] refactor mesh construction --- src/crown_gear.rs | 123 +++++++++++----------------------------------- 1 file changed, 29 insertions(+), 94 deletions(-) diff --git a/src/crown_gear.rs b/src/crown_gear.rs index d3e1b6b..1cfe93a 100644 --- a/src/crown_gear.rs +++ b/src/crown_gear.rs @@ -1,6 +1,6 @@ use std::f32::consts::PI; -use glam::{Vec3, vec3}; +use glam::{Mat3A, Vec3, vec3}; use crate::{ profile::Profile, @@ -27,104 +27,39 @@ impl CrownGear { mesh.faces.reserve_exact(8 * sides); for k in 0..sides { let t = k as f32 / sides as f32; - let phi = 2.0 * PI * t; - let (s, c) = phi.sin_cos(); + let rot = Mat3A::from_rotation_z(2.0 * PI * t); + let tooth = t * teeth; let y = self.profile.y_from_tooth(tooth); - let eps = 1e-3; - let dy_dt = teeth - * (self.profile.y_from_tooth(tooth + eps) - self.profile.y_from_tooth(tooth - eps)) - / (2.0 * eps); - let v_radial = vec3(c * self.pitch_radius, s * self.pitch_radius, y); - let v_tan = vec3(-2.0 * PI * s, 2.0 * PI * c, dy_dt / self.pitch_radius); - let n_top = v_radial.cross(v_tan).normalize(); + let n_top = { + let eps = 1e-3; + let dy_dt = teeth + * (self.profile.y_from_tooth(tooth + eps) + - self.profile.y_from_tooth(tooth - eps)) + / (2.0 * eps); + vec3(-2.0 * PI * y, -dy_dt, 2.0 * PI * self.pitch_radius) + }; - let n_top = vec3( - s * dy_dt - 2.0 * PI * c * y, - -c * dy_dt - 2.0 * PI * s * y, - 2.0 * PI * self.pitch_radius, - ); - - // top - mesh.vertices.push(Vertex { - position: vec3( - c * self.outer_radius, - s * self.outer_radius, - outer_scale * y, - ), + let vertex = |x, z, n| Vertex { + position: rot * vec3(x, 0.0, z), color, - normal: n_top, - }); - mesh.vertices.push(Vertex { - position: vec3( - c * self.inner_radius, - s * self.inner_radius, - inner_scale * y, - ), - color, - normal: n_top, - }); - - // bottom - mesh.vertices.push(Vertex { - position: vec3( - c * self.inner_radius, - s * self.inner_radius, - -self.base_thickness, - ), - color, - normal: vec3(0.0, 0.0, -1.0), - }); - mesh.vertices.push(Vertex { - position: vec3( - c * self.outer_radius, - s * self.outer_radius, - -self.base_thickness, - ), - color, - normal: vec3(0.0, 0.0, -1.0), - }); - - // inner - mesh.vertices.push(Vertex { - position: vec3( - c * self.inner_radius, - s * self.inner_radius, - inner_scale * y, - ), - color, - normal: vec3(-c, -s, 0.0), - }); - mesh.vertices.push(Vertex { - position: vec3( - c * self.inner_radius, - s * self.inner_radius, - -self.base_thickness, - ), - color, - normal: vec3(-c, -s, 0.0), - }); - - // outer - mesh.vertices.push(Vertex { - position: vec3( - c * self.outer_radius, - s * self.outer_radius, - -self.base_thickness, - ), - color, - normal: vec3(c, s, 0.0), - }); - mesh.vertices.push(Vertex { - position: vec3( - c * self.outer_radius, - s * self.outer_radius, - outer_scale * y, - ), - color, - normal: vec3(c, s, 0.0), - }); + normal: n, + }; + mesh.vertices.extend([ + // top + vertex(self.outer_radius, outer_scale * y, n_top), + vertex(self.inner_radius, inner_scale * y, n_top), + // bottom + vertex(self.inner_radius, -self.base_thickness, -Vec3::Z), + vertex(self.outer_radius, -self.base_thickness, -Vec3::Z), + // inner + vertex(self.inner_radius, inner_scale * y, -Vec3::X), + vertex(self.inner_radius, -self.base_thickness, -Vec3::X), + // outer + vertex(self.outer_radius, -self.base_thickness, Vec3::X), + vertex(self.outer_radius, outer_scale * y, Vec3::X), + ]); let base1 = 8 * k; let base2 = 8 * ((k + 1) % sides);