model-converter/src/parser/mtl.rs

82 lines
2.1 KiB
Rust

//! 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<Element, ParserError> {
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)
}
}
}