add crown gear
This commit is contained in:
parent
1732e2f6fc
commit
232720a78a
84
src/crown_gear.rs
Normal file
84
src/crown_gear.rs
Normal file
|
|
@ -0,0 +1,84 @@
|
||||||
|
use std::f32::consts::PI;
|
||||||
|
|
||||||
|
use glam::{Vec3, vec3};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
profile::Profile,
|
||||||
|
render::mesh::{CpuMeshIndexed, Vertex},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct CrownGear {
|
||||||
|
pub profile: Profile,
|
||||||
|
pub pitch_radius: f32,
|
||||||
|
|
||||||
|
pub inner_radius: f32,
|
||||||
|
pub outer_radius: f32,
|
||||||
|
pub base_thickness: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CrownGear {
|
||||||
|
pub fn make_mesh(&self, sides: usize, color: Vec3) -> CpuMeshIndexed {
|
||||||
|
let teeth = 2.0 * self.pitch_radius;
|
||||||
|
let inner_scale = self.inner_radius / self.pitch_radius;
|
||||||
|
let outer_scale = self.outer_radius / self.pitch_radius;
|
||||||
|
|
||||||
|
let mut mesh = CpuMeshIndexed::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 phi = 2.0 * PI * t;
|
||||||
|
let (s, c) = phi.sin_cos();
|
||||||
|
let tooth = t * teeth;
|
||||||
|
let y = self.profile.y_from_tooth(tooth);
|
||||||
|
mesh.vertices.push(Vertex {
|
||||||
|
position: vec3(
|
||||||
|
c * self.inner_radius,
|
||||||
|
s * self.inner_radius,
|
||||||
|
-self.base_thickness,
|
||||||
|
),
|
||||||
|
color,
|
||||||
|
normal: Vec3::ZERO, // FIXME calculate the normal
|
||||||
|
});
|
||||||
|
mesh.vertices.push(Vertex {
|
||||||
|
position: vec3(
|
||||||
|
c * self.outer_radius,
|
||||||
|
s * self.outer_radius,
|
||||||
|
-self.base_thickness,
|
||||||
|
),
|
||||||
|
color,
|
||||||
|
normal: Vec3::ZERO, // FIXME calculate the normal
|
||||||
|
});
|
||||||
|
mesh.vertices.push(Vertex {
|
||||||
|
position: vec3(
|
||||||
|
c * self.outer_radius,
|
||||||
|
s * self.outer_radius,
|
||||||
|
outer_scale * y,
|
||||||
|
),
|
||||||
|
color,
|
||||||
|
normal: Vec3::ZERO, // FIXME calculate the normal
|
||||||
|
});
|
||||||
|
mesh.vertices.push(Vertex {
|
||||||
|
position: vec3(
|
||||||
|
c * self.inner_radius,
|
||||||
|
s * self.inner_radius,
|
||||||
|
inner_scale * y,
|
||||||
|
),
|
||||||
|
color,
|
||||||
|
normal: Vec3::ZERO, // FIXME calculate the normal
|
||||||
|
});
|
||||||
|
let base1 = 4 * k;
|
||||||
|
let base2 = 4 * ((k + 1) % sides);
|
||||||
|
for j1 in 0..4 {
|
||||||
|
let j2 = (j1 + 1) % 4;
|
||||||
|
mesh.faces.push(
|
||||||
|
[base1 + j1, base2 + j1, base1 + j2].map(|index| index.try_into().unwrap()),
|
||||||
|
);
|
||||||
|
mesh.faces.push(
|
||||||
|
[base2 + j2, base1 + j2, base2 + j1].map(|index| index.try_into().unwrap()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mesh
|
||||||
|
}
|
||||||
|
}
|
||||||
41
src/lib.rs
41
src/lib.rs
|
|
@ -3,6 +3,7 @@ use std::error::Error;
|
||||||
use glam::{Mat4, UVec2, Vec3, Vec4, vec3, vec4};
|
use glam::{Mat4, UVec2, Vec3, Vec4, vec3, vec4};
|
||||||
|
|
||||||
mod camera;
|
mod camera;
|
||||||
|
mod crown_gear;
|
||||||
mod profile;
|
mod profile;
|
||||||
mod render;
|
mod render;
|
||||||
|
|
||||||
|
|
@ -40,38 +41,10 @@ pub struct Core {
|
||||||
surface: wgpu::Surface<'static>,
|
surface: wgpu::Surface<'static>,
|
||||||
|
|
||||||
mesh_pipeline: render::mesh::Pipeline,
|
mesh_pipeline: render::mesh::Pipeline,
|
||||||
mesh_color: render::mesh::GpuMeshIndexed,
|
|
||||||
mesh_gray: render::mesh::GpuMeshIndexed,
|
mesh_gray: render::mesh::GpuMeshIndexed,
|
||||||
depth: wgpu::Texture,
|
depth: wgpu::Texture,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cube(a: f32, b: f32) -> render::mesh::CpuMeshIndexed {
|
|
||||||
let gray_level = (b + a) / 2.;
|
|
||||||
let gray = Vec3::splat(gray_level);
|
|
||||||
let color_level = (b - a) / 2.;
|
|
||||||
let mut mesh = render::mesh::CpuMeshIndexed::default();
|
|
||||||
for (u, v, w) in [
|
|
||||||
(Vec3::X, Vec3::Y, Vec3::Z),
|
|
||||||
(Vec3::Y, Vec3::Z, Vec3::X),
|
|
||||||
(Vec3::Z, Vec3::X, Vec3::Y),
|
|
||||||
] {
|
|
||||||
for m in [1., -1.] {
|
|
||||||
let base = mesh.vertices.len() as u16;
|
|
||||||
for offset in [m * v + u, m * v - u, -m * v - u, -m * v + u] {
|
|
||||||
let vertex = render::mesh::Vertex {
|
|
||||||
position: (m * w + offset),
|
|
||||||
color: gray + color_level * m * w,
|
|
||||||
normal: m * w,
|
|
||||||
};
|
|
||||||
mesh.vertices.push(vertex);
|
|
||||||
}
|
|
||||||
mesh.faces.push([base, base + 1, base + 2]);
|
|
||||||
mesh.faces.push([base, base + 2, base + 3]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mesh
|
|
||||||
}
|
|
||||||
|
|
||||||
fn srgb_to_linear(color: Vec3) -> Vec3 {
|
fn srgb_to_linear(color: Vec3) -> Vec3 {
|
||||||
color.map(|x| {
|
color.map(|x| {
|
||||||
if x > 0.04045 {
|
if x > 0.04045 {
|
||||||
|
|
@ -107,8 +80,15 @@ 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 mesh_color = render::mesh::GpuMeshIndexed::new(&device, &cube(0.2, 0.8));
|
let crown_gear_mesh = crown_gear::CrownGear {
|
||||||
let mesh_gray = render::mesh::GpuMeshIndexed::new(&device, &cube(0.7, 0.7));
|
profile: Default::default(),
|
||||||
|
pitch_radius: 24.0,
|
||||||
|
inner_radius: 16.0,
|
||||||
|
outer_radius: 30.0,
|
||||||
|
base_thickness: 2.0,
|
||||||
|
}
|
||||||
|
.make_mesh(600, vec3(0.5, 0.5, 0.5));
|
||||||
|
let mesh_gray = render::mesh::GpuMeshIndexed::new(&device, &crown_gear_mesh);
|
||||||
|
|
||||||
Self::configure_surface(&surface, &device, pixel_size);
|
Self::configure_surface(&surface, &device, pixel_size);
|
||||||
|
|
||||||
|
|
@ -117,7 +97,6 @@ impl Core {
|
||||||
queue,
|
queue,
|
||||||
surface,
|
surface,
|
||||||
mesh_pipeline,
|
mesh_pipeline,
|
||||||
mesh_color,
|
|
||||||
mesh_gray,
|
mesh_gray,
|
||||||
depth,
|
depth,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,12 @@ pub struct CpuMeshIndexed {
|
||||||
pub faces: Vec<[u16; 3]>,
|
pub faces: Vec<[u16; 3]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl CpuMeshIndexed {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct GpuMesh {
|
pub struct GpuMesh {
|
||||||
vertices: wgpu::Buffer,
|
vertices: wgpu::Buffer,
|
||||||
vertex_count: u32,
|
vertex_count: u32,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user