use bytemuck::{Pod, Zeroable}; use rand::Rng; use wgpu::{VertexAttribute, VertexBufferLayout}; use std::{default, vec::Vec}; #[repr(C)] #[derive(Debug, Clone, Copy)] pub struct Pos([f32; 3]); #[repr(C)] #[derive(Debug, Clone, Copy)] pub struct Col([f32; 3]); impl Pos { pub fn new(x: f32, y: f32, z: f32) -> Self { Self([x, y, z]) } } unsafe impl Zeroable for Pos {} unsafe impl Pod for Pos {} impl Col { pub fn new(r: f32, g: f32, b: f32) -> Self { Self([r, g, b]) } pub fn random() -> Self { Self::new(rand::thread_rng().gen_range(0.0..=1.0), rand::thread_rng().gen_range(0.0..=1.0), rand::thread_rng().gen_range(0.0..=1.0)) } } unsafe impl Zeroable for Col {} unsafe impl Pod for Col {} #[repr(C)] #[derive(Debug, Clone, Copy)] pub struct Vertex { position: Pos, color: Col, } impl Vertex { pub fn new(position: Pos, color: Col) -> Self { Vertex { position: position, color: color } } pub fn desc() -> wgpu::VertexBufferLayout<'static> { wgpu::VertexBufferLayout { array_stride: std::mem::size_of::() as wgpu::BufferAddress, step_mode: wgpu::VertexStepMode::Vertex, attributes: &[VertexAttribute { format: wgpu::VertexFormat::Float32x3, offset: 0, shader_location: 0, }, VertexAttribute { format: wgpu::VertexFormat::Float32x3, offset: std::mem::size_of::<[f32; 3]>() as u64, shader_location: 1, }], } } } unsafe impl Zeroable for Vertex {} unsafe impl Pod for Vertex {} #[derive(Debug)] pub enum PolyError { NotEnoughSides, SidesAndTriangeNumberArentConsistant } #[repr(C)] pub struct Polygon{ triangles: Vec, n_sides: usize, } impl Polygon { pub fn new_from_center(center: Vertex, radius: f32, n_sides: usize) -> Self { //let theta = (360.0 / n_sides as f32).to_radians(); let mut vec_tris: Vec = Vec::with_capacity(n_sides); let center_x = center.position.0[0]; let center_y = center.position.0[1]; for v in 0..n_sides { let theta_current = (v as f32 / n_sides as f32) * 2.0 * std::f32::consts::PI; let theta_next = ((v+1) as f32 / n_sides as f32) * 2.0 * std::f32::consts::PI; let triangle = Triangle::new(Vertex::new(Pos::new((theta_current.cos() * radius) + center_x, (theta_current.sin() * radius) + center_y, 0.0), Col::random()), Vertex::new(Pos::new((theta_next.cos() * radius) + center_x, (theta_next.sin() * radius) + center_y, 0.0), Col::random()), center); vec_tris.push(triangle); }; Self::new_from_tris(vec_tris, n_sides).unwrap() } pub fn new_from_side(len_side: f32, n_sides: usize, color: Option) -> Self { todo!(); // let color = color.unwrap_or(Col::random()); // let theta = 360.0 / n_sides as f32; // let center = Pos::new( // // ((180.0 - theta) / 2.0).to_radians().cos() * radius, // // ((180.0 - theta) / 2.0).to_radians().sin() * radius, // (theta / 2.0).to_radians().cos() * radius, // (theta / 2.0).to_radians().sin() * radius, // 0.0 // ); // let nsides_poly = NSides::new(center, radius, n_sides, color).unwrap(); // nsides_poly.verts.polish_tris(nsides_poly.center, color) } fn new_from_tris(triangles: Vec, n_sides: usize) -> Result { if triangles.len() != n_sides { return Err(PolyError::SidesAndTriangeNumberArentConsistant) } Ok(Self { triangles, n_sides }) } pub fn get_tris(&self) -> Vec { self.triangles.clone() } pub fn uniform(&self) -> &[u8] { self.get_tris(); todo!() } } #[repr(C)] #[derive(Debug, Clone)] pub struct Triangle([Vertex; 3]); impl Triangle { pub fn new(vertex1: Vertex, vertex2: Vertex, vertex3: Vertex) -> Self { Self([vertex1, vertex2, vertex3]) } pub fn verts(&self) -> [Vertex; 3] { self.0 } } pub type VertexVector = Vec; trait VertexVectorMethods { fn polish_tris(&self, center_position: Pos, center_color: Col) -> Polygon; fn get_next(&self, index: usize) -> Vertex; } impl VertexVectorMethods for VertexVector { fn polish_tris(&self, center_position: Pos, center_color: Col) -> Polygon { let start_verts = self; let mut vec_tris = Vec::with_capacity(self.len()); for (vx, indx) in self.iter().zip(0..self.len()) { vec_tris.push(Triangle::new(vx.to_owned(), self.get_next(indx), Vertex { position: center_position, color: Col::random() })); }; Polygon::new_from_tris(vec_tris, self.len()).unwrap() } fn get_next(&self, index: usize) -> Vertex { if index != self.len()-1 { return self[index+1]; } else { return self[0]; } } } #[repr(C)] pub struct NSides { center: Pos, radius: f32, n_sides: usize, color: Col, verts: VertexVector } impl NSides { #[allow(private_interfaces)] pub fn new(center: Pos, radius: f32, n_sides: usize, color: Col) -> Result { if n_sides < 3 { return Err(PolyError::NotEnoughSides) } let verts = Self::calc_vertecies(n_sides, radius, color); return Ok(Self { center, radius, n_sides, color, verts, }) } pub fn get_verts(&self) -> VertexVector { self.verts.clone() } #[allow(private_interfaces)] fn calc_vertecies(n_sides: usize, radius: f32, color: Col) -> VertexVector{ let mut verts: Vec = Vec::with_capacity(n_sides); let float_sides = n_sides as f32; for x in 0..n_sides { let x = x as f32; let theta = (x / float_sides) * 2.0 * 3.14159265359; verts.push(Vertex::new(Pos::new(theta.cos() * radius, theta.sin() * radius, 0.0), color)); } verts } }