From 342e2d25d2da23134dd0781f07c28e267254be38 Mon Sep 17 00:00:00 2001 From: numzero Date: Mon, 20 Jul 2026 14:04:48 +0300 Subject: [PATCH] generate a shell --- src/lib.rs | 2 +- src/mesh.rs | 105 +++++++++++++++++++++++++++++++++++++++++++------- src/render.rs | 3 +- 3 files changed, 95 insertions(+), 15 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 7b1eed6..01eba7b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -96,7 +96,7 @@ impl Core { } fn render(&self, output: &wgpu::Texture, args: &RedrawArgs) { - let mesh = mesh::generate(&args.shape); + let mesh = mesh::cup(&args.shape); let mesh = faceted_mesh(&mesh); let mesh = render::Mesh::new(&self.device, &mesh); diff --git a/src/mesh.rs b/src/mesh.rs index f76145d..a9ba76a 100644 --- a/src/mesh.rs +++ b/src/mesh.rs @@ -1,15 +1,58 @@ use std::f32::consts::PI; -use glam::{Mat2, Vec3, vec2, vec3}; +use glam::{Mat2, Vec3, Vec3Swizzles, vec2, vec3}; +pub type Face = [usize; 3]; + +#[derive(Clone)] pub struct Mesh { pub vertices: Vec, - pub faces: Vec<[usize; 3]>, + pub faces: Vec, +} + +impl Mesh { + pub fn flip(&mut self) { + flip_faces(&mut self.faces); + } + + pub fn append(&mut self, other: &Mesh) { + let base = self.vertices.len(); + self.vertices.extend(&other.vertices); + self.faces.reserve(other.faces.len()); + for face in &other.faces { + self.faces.push(face.map(|index| base + index)); + } + } +} + +fn flip_faces<'a>(faces: impl IntoIterator) { + for f in faces { + *f = [f[0], f[2], f[1]]; + } +} + +fn disc_faces(base: usize, sides: usize) -> Vec { + let mut faces = Vec::new(); + for side in 0..(sides - 2) { + faces.push([base + sides - 1, base + side, base + side + 1]); + } + faces +} + +fn ring_faces(base1: usize, base2: usize, sides: usize) -> Vec { + let mut faces = Vec::new(); + for side in 0..sides { + let i1 = side; + let i2 = (side + 1) % sides; + faces.push([base1 + i1, base1 + i2, base2 + i1]); + faces.push([base1 + i2, base2 + i2, base2 + i1]); + } + faces } pub fn shell(shape: &crate::ShapeArgs) -> Mesh { - let mut vertices = Vec::::new(); - let mut faces = Vec::<[usize; 3]>::new(); + let mut vertices = Vec::new(); + let mut faces = Vec::new(); let sides = shape.sides as usize; let layers = (shape.layers_up + shape.layers_down) as usize; @@ -50,15 +93,51 @@ pub fn shell(shape: &crate::ShapeArgs) -> Mesh { } pub fn solid(shape: &crate::ShapeArgs) -> Mesh { - let mut mesh = shell(shape); let sides = shape.sides as usize; - for side in 0..(sides - 2) { - mesh.faces.push([sides - 1, side + 1, side]); - } - let base = mesh.vertices.len() - sides; - for side in 0..(sides - 2) { - mesh.faces - .push([base + sides - 1, base + side, base + side + 1]); - } + + let mut mesh = shell(shape); + + let mut bottom = disc_faces(0, sides); + flip_faces(&mut bottom); + mesh.faces.extend(bottom); + + let top = disc_faces(mesh.vertices.len() - sides, sides); + mesh.faces.extend(top); + + mesh +} + +pub fn cup(shape: &crate::ShapeArgs) -> Mesh { + let sides = shape.sides as usize; + let thickness = 1.6; + + let mut outer = shell(shape); + let shell_vs = outer.vertices.len(); + + let mut inner = outer.clone(); + inner.flip(); + for v in &mut inner.vertices { + let hor = v.xy(); + let (dir, len) = hor.normalize_and_length(); + assert!(len > thickness); + *v = v.with_xy(dir * (len - thickness)); + } + for i in 0..sides { + inner.vertices[i].z += thickness; + } + + let bottom_inner = disc_faces(0, sides); + inner.faces.extend(bottom_inner); + + let mut bottom_outer = disc_faces(0, sides); + flip_faces(&mut bottom_outer); + outer.faces.extend(bottom_outer); + + let mut mesh = outer; + mesh.append(&inner); + + let top_ring = ring_faces(shell_vs - sides, 2 * shell_vs - sides, sides); + mesh.faces.extend(top_ring); + mesh } diff --git a/src/render.rs b/src/render.rs index f05f96e..f267bd3 100644 --- a/src/render.rs +++ b/src/render.rs @@ -88,7 +88,8 @@ impl Pipeline { }, primitive: wgpu::PrimitiveState { topology: wgpu::PrimitiveTopology::TriangleList, - // cull_mode: Some(wgpu::Face::Front), + front_face: wgpu::FrontFace::Cw, + cull_mode: Some(wgpu::Face::Back), ..Default::default() }, depth_stencil: Some(wgpu::DepthStencilState {