use crate::{asset::Asset, math::*, render::Vertex}; use wgpu::{Buffer, Device}; use zerocopy::AsBytes; pub enum MeshType { Cube, Plane { size: f32, }, Quad { north_west: Vec2, north_east: Vec2, south_west: Vec2, south_east: Vec2, }, } pub struct Mesh { pub vertices: Vec, pub indices: Vec, pub vertex_buffer: Option, pub index_buffer: Option, } impl Mesh { pub fn setup_buffers(&mut self, device: &Device) { if let None = self.vertex_buffer { self.vertex_buffer = Some( device.create_buffer_with_data(self.vertices.as_bytes(), wgpu::BufferUsage::VERTEX), ); } if let None = self.index_buffer { self.index_buffer = Some( device.create_buffer_with_data(self.indices.as_bytes(), wgpu::BufferUsage::INDEX), ); } } } impl Asset for Mesh { fn load(descriptor: MeshType) -> Self { let (vertices, indices) = match descriptor { MeshType::Cube => create_cube(), MeshType::Plane { size } => create_plane(size), MeshType::Quad { north_west, north_east, south_west, south_east, } => create_quad(north_west, north_east, south_west, south_east), }; Mesh { vertices, indices, vertex_buffer: None, index_buffer: None, } } } pub fn create_quad( north_west: Vec2, north_east: Vec2, south_west: Vec2, south_east: Vec2, ) -> (Vec, Vec) { let vertex_data = [ Vertex::from(([south_west.x(), south_west.y(), 0.0], [0.0, 0.0, 1.0])), Vertex::from(([north_west.x(), north_west.y(), 0.0], [0.0, 0.0, 1.0])), Vertex::from(([north_east.x(), north_east.y(), 0.0], [0.0, 0.0, 1.0])), Vertex::from(([south_east.x(), south_east.y(), 0.0], [0.0, 0.0, 1.0])), ]; let index_data: &[u16] = &[0, 2, 1, 0, 3, 2]; return (vertex_data.to_vec(), index_data.to_vec()); } pub fn create_cube() -> (Vec, Vec) { let vertex_data = [ // top (0, 0, 1) Vertex::from(([-1, -1, 1], [0, 0, 1])), Vertex::from(([1, -1, 1], [0, 0, 1])), Vertex::from(([1, 1, 1], [0, 0, 1])), Vertex::from(([-1, 1, 1], [0, 0, 1])), // bottom (0, 0, -1) Vertex::from(([-1, 1, -1], [0, 0, -1])), Vertex::from(([1, 1, -1], [0, 0, -1])), Vertex::from(([1, -1, -1], [0, 0, -1])), Vertex::from(([-1, -1, -1], [0, 0, -1])), // right (1, 0, 0) Vertex::from(([1, -1, -1], [1, 0, 0])), Vertex::from(([1, 1, -1], [1, 0, 0])), Vertex::from(([1, 1, 1], [1, 0, 0])), Vertex::from(([1, -1, 1], [1, 0, 0])), // left (-1, 0, 0) Vertex::from(([-1, -1, 1], [-1, 0, 0])), Vertex::from(([-1, 1, 1], [-1, 0, 0])), Vertex::from(([-1, 1, -1], [-1, 0, 0])), Vertex::from(([-1, -1, -1], [-1, 0, 0])), // front (0, 1, 0) Vertex::from(([1, 1, -1], [0, 1, 0])), Vertex::from(([-1, 1, -1], [0, 1, 0])), Vertex::from(([-1, 1, 1], [0, 1, 0])), Vertex::from(([1, 1, 1], [0, 1, 0])), // back (0, -1, 0) Vertex::from(([1, -1, 1], [0, -1, 0])), Vertex::from(([-1, -1, 1], [0, -1, 0])), Vertex::from(([-1, -1, -1], [0, -1, 0])), Vertex::from(([1, -1, -1], [0, -1, 0])), ]; let index_data: &[u16] = &[ 0, 1, 2, 2, 3, 0, // top 4, 5, 6, 6, 7, 4, // bottom 8, 9, 10, 10, 11, 8, // right 12, 13, 14, 14, 15, 12, // left 16, 17, 18, 18, 19, 16, // front 20, 21, 22, 22, 23, 20, // back ]; (vertex_data.to_vec(), index_data.to_vec()) } pub fn create_plane(size: f32) -> (Vec, Vec) { let size_over_2 = size / 2.0; create_quad( vec2(-size_over_2, size_over_2), vec2(size_over_2, size_over_2), vec2(-size_over_2, -size_over_2), vec2(size_over_2, -size_over_2), ) }