use crate::asset::{Assets, Handle as AssetHandle}; use crate::ecs::Component; use crate::material::Material; use crate::mesh::Mesh; pub mod asset; #[derive(Debug, Clone, Component)] #[non_exhaustive] pub struct Model { pub spec_asset: AssetHandle, } impl Model { pub fn new(asset_handle: AssetHandle) -> Self { Self { spec_asset: asset_handle } } } #[derive(Debug, Clone)] #[non_exhaustive] pub struct Spec { pub mesh_asset: Option>, pub materials: Vec, } impl Spec { pub fn builder() -> SpecBuilder { SpecBuilder::default() } pub fn find_first_material<'assets>( &'assets self, assets: &'assets Assets, ) -> MaterialSearchResult<'assets> { let Some(material_desc) = self.materials.first() else { return MaterialSearchResult::NoMaterials; }; if assets.get(&material_desc.asset).is_none() { tracing::trace!("Missing material asset"); return MaterialSearchResult::NotFound; } MaterialSearchResult::Found(&material_desc.asset) } } #[derive(Debug, Default, Clone)] pub struct SpecBuilder { mesh_asset: Option>, materials: Vec, } impl SpecBuilder { pub fn mesh(mut self, asset: AssetHandle) -> Self { self.mesh_asset = Some(asset); self } pub fn materials( mut self, materials: impl IntoIterator, ) -> Self { self.materials = materials.into_iter().collect(); self } #[tracing::instrument(skip_all)] pub fn build(self) -> Spec { Spec { mesh_asset: self.mesh_asset, materials: self.materials, } } } #[derive(Debug, Clone)] #[non_exhaustive] pub struct MaterialDescription { pub asset: AssetHandle, } impl MaterialDescription { pub fn new(asset: AssetHandle) -> Self { Self { asset } } } pub enum MaterialSearchResult<'a> { Found(&'a AssetHandle), NotFound, NoMaterials, }