use std::f32::consts::PI; use glam::{Mat2, Vec3, vec2, vec3}; pub struct Mesh { pub vertices: Vec, pub faces: Vec<[usize; 3]>, } pub fn shell(shape: &crate::ShapeArgs) -> Mesh { let mut vertices = Vec::::new(); let mut faces = Vec::<[usize; 3]>::new(); let sides = shape.sides as usize; let layers = (shape.layers_up + shape.layers_down) as usize; let base_layer = shape.layers_down; let diameter = shape.base_diameter; let radius = diameter / 2.; let height = shape.height; let bottom_angle = (PI / sides as f32) * -(base_layer as f32); let top_angle = (PI / sides as f32) * (layers as f32 - base_layer as f32); let bottom_y = radius * bottom_angle.tan(); let top_y = radius * top_angle.tan(); let incline = height / (top_y - bottom_y); let elevation = -height / 2. - incline * bottom_y; for layer in 0..=layers { let angle = (PI / sides as f32) * (layer as f32 - base_layer as f32); let x = radius; let y = angle.tan() * x; let z = elevation + incline * y; for side in 0..sides { let angle = (2. * PI / sides as f32) * side as f32; let rot = Mat2::from_angle(angle); let xy = rot * vec2(x, y); let v = vec3(xy.x, xy.y, z); vertices.push(v); } } for layer in 0..layers { let base = sides * layer; for side in 0..sides { let index = |layer, offset| base + sides * layer + (side + offset) % sides; faces.push([index(0, 0), index(0, 1), index(1, 0)]); faces.push([index(0, 1), index(1, 1), index(1, 0)]); } } Mesh { vertices, faces } } 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]); } mesh }