use std::fs::read_to_string; use std::path::{Path, PathBuf}; use crate::asset::{Assets, Submitter as AssetSubmitter}; use crate::material::Material; /// Material asset import settings. #[derive(Debug)] #[non_exhaustive] pub struct Settings {} pub fn add_importers(assets: &mut Assets) { assets.set_importer::(import); } fn import( asset_submitter: &mut AssetSubmitter<'_>, path: &Path, _settings: Option<&'_ Settings>, ) -> Result<(), Error> { if path.extension().is_none_or(|ext| ext != "mtl") { return Err(Error::UnsupportedFileType); } let parent_path = path .parent() .ok_or_else(|| Error::InvalidPath(path.to_path_buf()))?; let named_materials = crate::file_format::wavefront::mtl::parse( &read_to_string(path) .map_err(|err| Error::ReadFailed(err, path.to_path_buf()))?, )?; for material in named_materials { let mut material_builder = Material::builder() .ambient(material.ambient) .diffuse(material.diffuse) .specular(material.specular) .shininess(material.shininess); if let Some(ambient_map) = material.ambient_map { material_builder = material_builder.ambient_map( asset_submitter.submit_load_other(parent_path.join(&ambient_map.path)), ); } if let Some(diffuse_map) = material.diffuse_map { material_builder = material_builder.diffuse_map( asset_submitter.submit_load_other(parent_path.join(&diffuse_map.path)), ); } if let Some(specular_map) = material.specular_map { material_builder = material_builder.specular_map( asset_submitter.submit_load_other(parent_path.join(&specular_map.path)), ); } asset_submitter.submit_store_named(material.name, material_builder.build()); } Ok(()) } #[derive(Debug, thiserror::Error)] enum Error { #[error("File type is unsupported")] UnsupportedFileType, #[error("Invalid path '{}'", .0.display())] InvalidPath(PathBuf), #[error("Failed to read file {}", .1.display())] ReadFailed(#[source] std::io::Error, PathBuf), #[error(transparent)] Other(#[from] crate::file_format::wavefront::mtl::Error), }