wobj
Wavefront OBJ polygonal geometry and MTL material parser library.
Usage
To load an OBJ file:
fn main() -> Result<(), Box<dyn std::error::Error>> {
let bytes = std::fs::read("assets/cube.obj")?;
let obj = wobj::Obj::parse(&bytes)?;
for mesh in &obj.meshes() {
println!("Name: {:?}", mesh.name());
let (indicies, verticies) = mesh.triangulate()?;
}
Ok(())
}
To load a material:
fn main() -> Result<(), Box<dyn std::error::Error>> {
let bytes = std::fs::read("assets/cube.mtl")?;
let mtl = wobj::Mtl::parse(&bytes)?;
let material: Option<&wobj::Material> = mtl.get("CubeMaterial");
Ok(())
}
Since OBJ files can use a different MTL file for each material, if we want to
load all used materials without wasting work:
fn main() -> Result<(), Box<dyn std::error::Error>> {
let obj_path = std::path::Path::new("assets/cube.obj");
let parent_path = obj_path.parent().unwrap();
let obj = wobj::Obj::parse(&std::fs::read(obj_path)?)?;
let mut mtls = std::collections::HashMap::new();
for mesh in &obj.meshes() {
if let Some(mtllib) = mesh.mtllib()
&& let Some(material_name) = mesh.material()
{
if !mtls.contains_key(mtllib) {
let mtl_path = parent_path.join(mtllib);
let mtl = wobj::Mtl::parse(&std::fs::read(mtl_path)?)?;
mtls.insert(mtllib, mtl);
}
let material = mtls
.get(mtllib)
.and_then(|m| m.get(material_name))
.expect("Material not found");
println!("Material '{material_name}': {material:?}");
}
}
Ok(())
}
License
Licensed under either of
at your option.