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};
|
use glam::{Mat4, UVec2, Vec3, Vec4, vec3, vec4};
|
||||||
|
|
||||||
|
mod bevel_gear;
|
||||||
mod camera;
|
mod camera;
|
||||||
mod crown_gear;
|
mod crown_gear;
|
||||||
mod profile;
|
mod profile;
|
||||||
|
|
@ -80,6 +81,7 @@ impl Core {
|
||||||
|
|
||||||
let depth = Self::create_depth_buffer(&device, pixel_size);
|
let depth = Self::create_depth_buffer(&device, pixel_size);
|
||||||
let mesh_pipeline = render::mesh::Pipeline::new(&device);
|
let mesh_pipeline = render::mesh::Pipeline::new(&device);
|
||||||
|
|
||||||
let crown_gear_mesh = crown_gear::make_mesh_simple(
|
let crown_gear_mesh = crown_gear::make_mesh_simple(
|
||||||
&crown_gear::CrownGearDesc {
|
&crown_gear::CrownGearDesc {
|
||||||
profile: Default::default(),
|
profile: Default::default(),
|
||||||
|
|
@ -95,7 +97,25 @@ impl Core {
|
||||||
.to_mesh()
|
.to_mesh()
|
||||||
.to_standard_mesh(vec3(0.5, 0.5, 0.5))
|
.to_standard_mesh(vec3(0.5, 0.5, 0.5))
|
||||||
.into_indexed();
|
.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);
|
Self::configure_surface(&surface, &device, pixel_size);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user