refactor mesh construction

This commit is contained in:
numzero 2026-10-17 23:04:31 +03:00
parent 4fad56a7d1
commit 80433d5ed6

View File

@ -1,6 +1,6 @@
use std::f32::consts::PI; use std::f32::consts::PI;
use glam::{Vec3, vec3}; use glam::{Mat3A, Vec3, vec3};
use crate::{ use crate::{
profile::Profile, profile::Profile,
@ -27,104 +27,39 @@ impl CrownGear {
mesh.faces.reserve_exact(8 * sides); mesh.faces.reserve_exact(8 * sides);
for k in 0..sides { for k in 0..sides {
let t = k as f32 / sides as f32; let t = k as f32 / sides as f32;
let phi = 2.0 * PI * t; let rot = Mat3A::from_rotation_z(2.0 * PI * t);
let (s, c) = phi.sin_cos();
let tooth = t * teeth; let tooth = t * teeth;
let y = self.profile.y_from_tooth(tooth); 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 n_top = {
let v_tan = vec3(-2.0 * PI * s, 2.0 * PI * c, dy_dt / self.pitch_radius); let eps = 1e-3;
let n_top = v_radial.cross(v_tan).normalize(); 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( let vertex = |x, z, n| Vertex {
s * dy_dt - 2.0 * PI * c * y, position: rot * vec3(x, 0.0, z),
-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,
),
color, color,
normal: n_top, normal: n,
}); };
mesh.vertices.push(Vertex { mesh.vertices.extend([
position: vec3( // top
c * self.inner_radius, vertex(self.outer_radius, outer_scale * y, n_top),
s * self.inner_radius, vertex(self.inner_radius, inner_scale * y, n_top),
inner_scale * y, // bottom
), vertex(self.inner_radius, -self.base_thickness, -Vec3::Z),
color, vertex(self.outer_radius, -self.base_thickness, -Vec3::Z),
normal: n_top, // inner
}); vertex(self.inner_radius, inner_scale * y, -Vec3::X),
vertex(self.inner_radius, -self.base_thickness, -Vec3::X),
// bottom // outer
mesh.vertices.push(Vertex { vertex(self.outer_radius, -self.base_thickness, Vec3::X),
position: vec3( vertex(self.outer_radius, outer_scale * y, Vec3::X),
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),
});
let base1 = 8 * k; let base1 = 8 * k;
let base2 = 8 * ((k + 1) % sides); let base2 = 8 * ((k + 1) % sides);