use std::fs::read_to_string; use std::path::{Path, PathBuf}; use crate::asset::{Assets, Submitter as AssetSubmitter}; use crate::material::asset::Map as MaterialAssetMap; use crate::model::{Materials, Spec}; #[derive(Debug, Clone)] #[non_exhaustive] pub struct Settings {} pub fn add_importers(assets: &mut Assets) { assets.set_importer(["obj"], import_wavefront_obj_asset); } fn import_wavefront_obj_asset( asset_submitter: &mut AssetSubmitter<'_>, path: &Path, _settings: Option<&'_ Settings>, ) -> Result<(), Error> { let obj = crate::file_format::wavefront::obj::parse( &read_to_string(path) .map_err(|err| Error::ReadFailed(err, path.to_path_buf()))?, )?; let mesh = obj.to_mesh()?; let mesh_asset = asset_submitter.submit_store_named("mesh", mesh); let mut material_asset_map_assets = Vec::with_capacity(obj.mtl_libs.iter().count()); for mtl_lib_path in &obj.mtl_libs { let mtl_lib_asset = asset_submitter.submit_load_other::(mtl_lib_path.as_path()); material_asset_map_assets.push(mtl_lib_asset); } asset_submitter.submit_store( Spec::builder() .mesh(mesh_asset) .materials(Materials::Maps(material_asset_map_assets)) .material_names( obj.unique_used_material_names .into_iter() .map(|material_name| material_name.into_string()), ) .build(), ); Ok(()) } #[derive(Debug, thiserror::Error)] enum Error { #[error("Failed to read file {}", .1.display())] ReadFailed(#[source] std::io::Error, PathBuf), #[error(transparent)] Other(#[from] crate::file_format::wavefront::obj::Error), }