add a bevel gear blank
This commit is contained in:
parent
cfbd5a41c3
commit
f35ca37cae
110
src/bevel_gear.rs
Normal file
110
src/bevel_gear.rs
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
use std::f32::consts::PI;
|
||||
|
||||
use glam::{Mat3A, Vec2, Vec3, vec3};
|
||||
|
||||
use crate::{profile::Profile, render::mesh::MeshIndexed};
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct BevelGearDesc {
|
||||
pub profile: Profile,
|
||||
pub teeth: u32,
|
||||
pub cone_halfangle: f32,
|
||||
}
|
||||
|
||||
impl BevelGearDesc {
|
||||
pub fn cutter(&self) -> crate::crown_gear::CrownGearDesc {
|
||||
crate::crown_gear::CrownGearDesc {
|
||||
profile: Profile {
|
||||
addendum: self.profile.dedendum,
|
||||
dedendum: self.profile.addendum,
|
||||
pressure_angle: self.profile.pressure_angle,
|
||||
},
|
||||
pitch_radius: self.pitch_radius() / self.cone_halfangle.sin(),
|
||||
}
|
||||
}
|
||||
|
||||
fn pitch_radius(&self) -> f32 {
|
||||
0.5 * self.teeth as f32
|
||||
}
|
||||
|
||||
fn pitch_distance(&self) -> f32 {
|
||||
self.pitch_radius() / self.cone_halfangle.tan()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct BevelGearShape {
|
||||
points: Vec<f32>,
|
||||
}
|
||||
|
||||
impl BevelGearShape {
|
||||
fn new_raw(r: f32, n_points: usize) -> Self {
|
||||
BevelGearShape {
|
||||
points: vec![r; n_points],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_blank(desc: &BevelGearDesc, n_points: usize) -> Self {
|
||||
let r = 0.5 * desc.teeth as f32 + desc.profile.addendum + 0.1;
|
||||
Self::new_raw(r, n_points)
|
||||
}
|
||||
|
||||
pub fn to_points(&self) -> impl Iterator<Item = Vec2> {
|
||||
let angle = 2.0 * PI / self.points.len() as f32;
|
||||
self.points
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(move |(k, r)| Vec2::from_angle(k as f32 * angle) * r)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum BevelGearCap {
|
||||
Flat,
|
||||
Conical,
|
||||
Spherical,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct BevelGearVisual {
|
||||
pub inner_distance: f32,
|
||||
pub outer_distance: f32,
|
||||
}
|
||||
|
||||
pub fn make_mesh(
|
||||
desc: &BevelGearDesc,
|
||||
visual: &BevelGearVisual,
|
||||
shape: &BevelGearShape,
|
||||
) -> MeshIndexed<Vec3> {
|
||||
let inner_scale = visual.inner_distance / desc.pitch_distance();
|
||||
let outer_scale = visual.outer_distance / desc.pitch_distance();
|
||||
|
||||
let sides = shape.points.len();
|
||||
let mut mesh = MeshIndexed::new();
|
||||
mesh.vertices.reserve_exact(2 * sides + 2);
|
||||
mesh.faces.reserve_exact(4 * sides);
|
||||
for pt in shape.to_points() {
|
||||
let pt = vec3(pt.x, pt.y, desc.pitch_distance());
|
||||
mesh.vertices.extend([inner_scale * pt, outer_scale * pt]);
|
||||
}
|
||||
let caps = mesh.vertices.len();
|
||||
mesh.vertices.extend([
|
||||
vec3(0., 0., visual.inner_distance),
|
||||
vec3(0., 0., visual.outer_distance),
|
||||
]);
|
||||
for k in 0..sides {
|
||||
let base1 = 2 * k;
|
||||
let base2 = 2 * ((k + 1) % sides);
|
||||
mesh.faces.extend(
|
||||
[
|
||||
[base1, caps, base2],
|
||||
[base1, base2, base1 + 1],
|
||||
[base2 + 1, base1 + 1, base2],
|
||||
[base2 + 1, caps + 1, base1 + 1],
|
||||
]
|
||||
.map(|face| face.map(|index| u16::try_from(index).unwrap())),
|
||||
);
|
||||
}
|
||||
|
||||
mesh
|
||||
}
|
||||
22
src/lib.rs
22
src/lib.rs
|
|
@ -2,6 +2,7 @@ use std::error::Error;
|
|||
|
||||
use glam::{Mat4, UVec2, Vec3, Vec4, vec3, vec4};
|
||||
|
||||
mod bevel_gear;
|
||||
mod camera;
|
||||
mod crown_gear;
|
||||
mod profile;
|
||||
|
|
@ -80,6 +81,7 @@ impl Core {
|
|||
|
||||
let depth = Self::create_depth_buffer(&device, pixel_size);
|
||||
let mesh_pipeline = render::mesh::Pipeline::new(&device);
|
||||
|
||||
let crown_gear_mesh = crown_gear::make_mesh_simple(
|
||||
&crown_gear::CrownGearDesc {
|
||||
profile: Default::default(),
|
||||
|
|
@ -95,7 +97,25 @@ impl Core {
|
|||
.to_mesh()
|
||||
.to_standard_mesh(vec3(0.5, 0.5, 0.5))
|
||||
.into_indexed();
|
||||
let mesh_gray = render::mesh::GpuMeshIndexed::new(&device, &crown_gear_mesh);
|
||||
|
||||
let bevel_gear_desc = bevel_gear::BevelGearDesc {
|
||||
profile: Default::default(),
|
||||
teeth: 24,
|
||||
cone_halfangle: 0.5,
|
||||
};
|
||||
let bevel_gear_mesh = bevel_gear::make_mesh(
|
||||
&bevel_gear_desc,
|
||||
&bevel_gear::BevelGearVisual {
|
||||
inner_distance: 8.0,
|
||||
outer_distance: 12.0,
|
||||
},
|
||||
&bevel_gear::BevelGearShape::new_blank(&bevel_gear_desc, 60),
|
||||
)
|
||||
.to_mesh()
|
||||
.to_standard_mesh(vec3(0.5, 0.5, 0.5))
|
||||
.into_indexed();
|
||||
|
||||
let mesh_gray = render::mesh::GpuMeshIndexed::new(&device, &bevel_gear_mesh);
|
||||
|
||||
Self::configure_surface(&surface, &device, pixel_size);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user