use std::collections::HashMap; #[repr(C)] #[derive(Copy, Clone, Debug)] pub struct Vertex { pub position: glam::Vec3, pub tex_coords: glam::Vec2 } impl Vertex { pub fn new(position: glam::Vec3, tex_coords: glam::Vec2) -> Self { Self { position, tex_coords, } } } #[repr(C)] #[derive(Clone, Debug, PartialEq)] pub enum VertexAttributeData { Vec2(Vec), Vec3(Vec), Vec4(Vec), } impl VertexAttributeData { /// Take self as a list of Vec2's pub fn as_vec2(&self) -> &Vec { match self { VertexAttributeData::Vec2(v) => v, _ => panic!("Attempt to get {self:?} as `Vec2`"), } } pub fn as_vec3(&self) -> &Vec { match self { VertexAttributeData::Vec3(v) => v, _ => panic!("Attempt to get {self:?} as `Vec3`"), } } } #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub enum MeshVertexAttribute { Position, Normals, Tangents, // Colors, // TODO: Store data in VertexAttributeData Joints, // TODO: Animation TexCoords, Weights, // TODO: Animation MorphTargets, // TODO: Animation Other(String), } #[derive(Clone, Default)] pub struct Mesh { pub attributes: HashMap, pub indices: Option>, } impl Mesh { pub fn add_attribute(&mut self, attribute: MeshVertexAttribute, data: VertexAttributeData) { self.attributes.insert(attribute, data); } /// Try to get the position attribute of the Mesh pub fn position(&self) -> Option<&Vec> { self.attributes.get(&MeshVertexAttribute::Position) .map(|p| p.as_vec3()) } pub fn add_position(&mut self, pos: Vec) { self.attributes.insert(MeshVertexAttribute::Position, VertexAttributeData::Vec3(pos)); } /// Try to get the normals attribute of the Mesh pub fn normals(&self) -> Option<&Vec> { self.attributes.get(&MeshVertexAttribute::Normals) .map(|p| p.as_vec3()) } /// Try to get the texture coordinates attribute of the Mesh pub fn tex_coords(&self) -> Option<&Vec> { self.attributes.get(&MeshVertexAttribute::TexCoords) .map(|p| p.as_vec2()) } } #[derive(Clone, Default)] pub struct Model { pub meshes: Vec, //pub material } impl Model { pub fn new(meshes: Vec) -> Self { Self { meshes, } } }