151 lines
3.6 KiB
Rust
151 lines
3.6 KiB
Rust
use std::collections::HashMap;
|
|
|
|
use crate::Material;
|
|
|
|
#[repr(C)]
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub enum MeshIndices {
|
|
//U8(Vec<u8>),
|
|
U16(Vec<u16>),
|
|
U32(Vec<u32>),
|
|
}
|
|
|
|
impl MeshIndices {
|
|
pub fn len(&self) -> usize {
|
|
match self {
|
|
MeshIndices::U16(v) => v.len(),
|
|
MeshIndices::U32(v) => v.len(),
|
|
}
|
|
}
|
|
|
|
pub fn is_empty(&self) -> bool {
|
|
self.len() == 0
|
|
}
|
|
}
|
|
|
|
/* impl From<Vec<u8>> for MeshIndices {
|
|
fn from(value: Vec<u8>) -> Self {
|
|
MeshIndices::U8(value)
|
|
}
|
|
} */
|
|
|
|
impl From<Vec<u16>> for MeshIndices {
|
|
fn from(value: Vec<u16>) -> Self {
|
|
MeshIndices::U16(value)
|
|
}
|
|
}
|
|
|
|
impl From<Vec<u32>> for MeshIndices {
|
|
fn from(value: Vec<u32>) -> Self {
|
|
MeshIndices::U32(value)
|
|
}
|
|
}
|
|
|
|
#[repr(C)]
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub enum VertexAttributeData {
|
|
Vec2(Vec<glam::Vec2>),
|
|
Vec3(Vec<glam::Vec3>),
|
|
Vec4(Vec<glam::Vec4>),
|
|
}
|
|
|
|
impl VertexAttributeData {
|
|
/// Take self as a list of Vec2's
|
|
pub fn as_vec2(&self) -> &Vec<glam::Vec2> {
|
|
match self {
|
|
VertexAttributeData::Vec2(v) => v,
|
|
_ => panic!("Attempt to get {self:?} as `Vec2`"),
|
|
}
|
|
}
|
|
|
|
pub fn as_vec3(&self) -> &Vec<glam::Vec3> {
|
|
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<MeshVertexAttribute, VertexAttributeData>,
|
|
pub indices: Option<MeshIndices>,
|
|
material: Option<Material>,
|
|
}
|
|
|
|
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<glam::Vec3>> {
|
|
self.attributes.get(&MeshVertexAttribute::Position)
|
|
.map(|p| p.as_vec3())
|
|
}
|
|
|
|
pub fn add_position(&mut self, pos: Vec<glam::Vec3>) {
|
|
self.attributes.insert(MeshVertexAttribute::Position, VertexAttributeData::Vec3(pos));
|
|
}
|
|
|
|
/// Try to get the normals attribute of the Mesh
|
|
pub fn normals(&self) -> Option<&Vec<glam::Vec3>> {
|
|
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<glam::Vec2>> {
|
|
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<Mesh>,
|
|
//pub material
|
|
}
|
|
|
|
impl Model {
|
|
pub fn new(meshes: Vec<Mesh>) -> Self {
|
|
Self {
|
|
meshes,
|
|
}
|
|
}
|
|
} |