generate a shell

This commit is contained in:
numzero 2026-07-20 14:04:48 +03:00
parent 5b8818a6b1
commit 342e2d25d2
3 changed files with 95 additions and 15 deletions

View File

@ -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);

View File

@ -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<Vec3>,
pub faces: Vec<[usize; 3]>,
pub faces: Vec<Face>,
}
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<Item = &'a mut Face>) {
for f in faces {
*f = [f[0], f[2], f[1]];
}
}
fn disc_faces(base: usize, sides: usize) -> Vec<Face> {
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<Face> {
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::<Vec3>::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
}

View File

@ -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 {