use std::fs::read_to_string; use std::path::{Path, PathBuf}; use crate::asset::{ Assets, Handle as AssetHandle, Label as AssetLabel, Submitter as AssetSubmitter, }; use crate::material::{LoadingTextureName, 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 { let asset_label = AssetLabel::from(parent_path.join(&ambient_map.path)); material_builder = material_builder .ambient_map(AssetHandle::invalid()) .loading_texture(LoadingTextureName::AmbientMap, asset_label); } if let Some(diffuse_map) = material.diffuse_map { let asset_label = AssetLabel::from(parent_path.join(&diffuse_map.path)); material_builder = material_builder .diffuse_map(AssetHandle::invalid()) .loading_texture(LoadingTextureName::DiffuseMap, asset_label); } if let Some(specular_map) = material.specular_map { let asset_label = AssetLabel::from(parent_path.join(&specular_map.path)); material_builder = material_builder .specular_map(AssetHandle::invalid()) .loading_texture(LoadingTextureName::SpecularMap, asset_label); } 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), }