//! Module containing the parser for material files from Wavefront OBJ (mtl files). use std::path::PathBuf; use parser::{Element, ParserError, LineParser}; use parser::obj::parse_values; use math::vector::Vector3; /// Wavefront material file format parser. pub struct MtlParser { } impl MtlParser { /// Creates a MtlParser. pub fn new() -> MtlParser { MtlParser { } } } impl LineParser for MtlParser { fn parse_line(&mut self, line_number: usize, line: &str, path: &str) -> Result { let mut root = PathBuf::from(path); root.pop(); let mut split = line.split_whitespace(); if let Some(first) = split.nth(0) { let first = first.trim(); match first { // Ignore comments "#" => Ok(Element::None), // Starts a new material "newmtl" => Ok(Element::NewMaterial(split.nth(0).unwrap().to_owned())), "Kd" => { let values = parse_values(line_number, line, path, 3)?; Ok(Element::Diffuse(Vector3::new( values[0] as f32, values[1] as f32, values[2] as f32, ))) }, map if map.starts_with("map_") => { let mut full_path = root.clone(); full_path.push(split.nth(0).unwrap().to_owned()); Ok(Element::Texture(first.to_owned(), full_path.to_str().unwrap().to_owned())) }, // The keyword is not empty and unexpected // We don't do this : we simply return an unknown material instruction // key if key.len() != 0 => { // Err(ParserError::UnexpectedKeyword(path.to_owned(), line_number, key.to_owned())) // }, // Empty string "" => Ok(Element::None), // Unknown instruction _ => Ok(Element::UnknownMaterialInstruction(line.to_owned())), } } else { Ok(Element::None) } } }