use std::collections::HashMap; use crate::Material; #[repr(C)] #[derive(Clone, Debug, PartialEq)] pub enum MeshIndices { //U8(Vec), U16(Vec), U32(Vec), } impl MeshIndices { pub fn len(&self) -> usize { match self { MeshIndices::U16(v) => v.len(), MeshIndices::U32(v) => v.len(), } } } /* impl From> for MeshIndices { fn from(value: Vec) -> Self { MeshIndices::U8(value) } } */ impl From> for MeshIndices { fn from(value: Vec) -> Self { MeshIndices::U16(value) } } impl From> for MeshIndices { fn from(value: Vec) -> Self { MeshIndices::U32(value) } } #[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: Figure out best way to store color data Joints, // TODO: Animation TexCoords, Weights, // TODO: Animation MorphTargets, // TODO: Animation /// Used during loading of the Mesh to process the materials taht it MaterialRef, Other(String), } #[derive(Clone, edict::Component)] pub struct Mesh { pub uuid: uuid::Uuid, pub attributes: HashMap, pub indices: Option, material: Option, } impl Default for Mesh { fn default() -> Self { Self { uuid: uuid::Uuid::new_v4(), attributes: Default::default(), indices: Default::default(), material: Default::default() } } } 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()) } pub fn material(&self) -> Material { self.material.clone().expect("This mesh is missing a material!") } pub fn set_material(&mut self, val: Material) { self.material = Some(val); } } #[derive(Clone, Default)] pub struct Model { pub meshes: Vec, //pub material } impl Model { pub fn new(meshes: Vec) -> Self { Self { meshes, } } }