2018-02-23 12:04:26 +01:00
|
|
|
//! Module containing the parser for material files from Wavefront OBJ (mtl files).
|
|
|
|
|
|
|
|
use std::path::PathBuf;
|
|
|
|
|
|
|
|
use parser::{Element, ParserError, LineParser};
|
2018-06-15 17:36:51 +02:00
|
|
|
use parser::obj::parse_values;
|
|
|
|
|
|
|
|
use math::vector::Vector3;
|
2018-02-23 12:04:26 +01:00
|
|
|
|
|
|
|
/// Wavefront material file format parser.
|
|
|
|
pub struct MtlParser {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
impl MtlParser {
|
|
|
|
|
|
|
|
/// Creates a MtlParser.
|
|
|
|
pub fn new() -> MtlParser {
|
|
|
|
MtlParser {
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
impl LineParser for MtlParser {
|
2018-06-15 17:36:51 +02:00
|
|
|
fn parse_line(&mut self, line_number: usize, line: &str, path: &str) -> Result<Element, ParserError> {
|
2018-02-23 12:04:26 +01:00
|
|
|
|
|
|
|
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())),
|
|
|
|
|
2018-06-15 17:36:51 +02:00
|
|
|
"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,
|
|
|
|
)))
|
|
|
|
},
|
|
|
|
|
2018-02-23 12:04:26 +01:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|