diff --git a/src/exporter/mod.rs b/src/exporter/mod.rs index 4f9244a..3161c68 100644 --- a/src/exporter/mod.rs +++ b/src/exporter/mod.rs @@ -49,5 +49,5 @@ pub trait ElementSerializer { /// Performs the serialization. /// /// Writes the serialization on the output and returns Err if an error occured. - fn serialize(&self, element: Element, output: &mut W) -> Result<(), ExportError>; + fn serialize(&self, element: Element, output: &mut W) -> Result; } diff --git a/src/exporter/obj.rs b/src/exporter/obj.rs index a33813b..167ce10 100644 --- a/src/exporter/obj.rs +++ b/src/exporter/obj.rs @@ -24,31 +24,31 @@ impl ObjElementSerializer { } /// Writes a face to a writable output. - pub fn write_face(&self, f: model::Face, output: &mut W) -> Result<(), ExportError> { + pub fn face_to_string(&self, f: model::Face) -> String { + if f.a.texture_coordinate.is_none() && f.a.normal.is_none() { // Only vertices - writeln!(output, "f {} {} {}", f.a.vertex + 1, f.b.vertex + 1, f.c.vertex + 1)?; + format!("f {} {} {}", f.a.vertex + 1, f.b.vertex + 1, f.c.vertex + 1) } else if f.a.normal.is_none() { // Vertices + tex coords - writeln!(output, "f {}/{} {}/{} {}/{}", + format!("f {}/{} {}/{} {}/{}", f.a.vertex + 1, f.a.texture_coordinate.unwrap() + 1, f.b.vertex + 1, f.b.texture_coordinate.unwrap() + 1, - f.c.vertex + 1, f.c.texture_coordinate.unwrap() + 1)?; + f.c.vertex + 1, f.c.texture_coordinate.unwrap() + 1) } else if f.a.texture_coordinate.is_none() { // Vertices + normals - writeln!(output, "f {}//{} {}//{} {}//{}", + format!("f {}//{} {}//{} {}//{}", f.a.vertex + 1, f.a.normal.unwrap() + 1, f.b.vertex + 1, f.b.normal.unwrap() + 1, - f.c.vertex + 1, f.c.normal.unwrap() + 1)?; + f.c.vertex + 1, f.c.normal.unwrap() + 1) } else { // All - writeln!(output, "f {}/{}/{} {}/{}/{} {}/{}/{}", + format!("f {}/{}/{} {}/{}/{} {}/{}/{}", f.a.vertex + 1, f.a.texture_coordinate.unwrap() + 1, f.a.normal.unwrap() + 1, f.b.vertex + 1, f.b.texture_coordinate.unwrap() + 1, f.b.normal.unwrap() + 1, - f.c.vertex + 1, f.c.texture_coordinate.unwrap() + 1, f.c.normal.unwrap() + 1)?; + f.c.vertex + 1, f.c.texture_coordinate.unwrap() + 1, f.c.normal.unwrap() + 1) } - Ok(()) } } @@ -67,17 +67,18 @@ impl ElementSerializer for ObjElementSerializer { /// let result = String::from_utf8(output).unwrap(); /// assert_eq!(result, "v 1 2 3\n"); /// ``` - fn serialize(&self, element: Element, output: &mut W) -> Result<(), ExportError> { + fn serialize(&self, element: Element, output: &mut W) -> Result { - match element { - Vertex(v) => writeln!(output, "v {} {} {}", v.x(), v.y(), v.z())?, - TextureCoordinate(vt) => writeln!(output, "vt {} {}", vt.x(), vt.y())?, - Normal(n) => writeln!(output, "vn {} {} {}", n.x(), n.y(), n.z())?, - Face(f) => self.write_face(f, output)?, - UseMaterial(ref n) => writeln!(output, "usemtl {}", n)?, - _ => (), - } + let string = match element { + Vertex(v) => format!("v {} {} {}", v.x(), v.y(), v.z()), + TextureCoordinate(vt) => format!("vt {} {}", vt.x(), vt.y()), + Normal(n) => format!("vn {} {} {}", n.x(), n.y(), n.z()), + Face(f) => self.face_to_string(f), + UseMaterial(ref n) => format!("usemtl {}", n), + _ => return Ok(0), + }; - Ok(()) + writeln!(output, "{}", string)?; + Ok(string.len() + 1) } } diff --git a/src/math/vector.rs b/src/math/vector.rs index de72689..699958f 100644 --- a/src/math/vector.rs +++ b/src/math/vector.rs @@ -112,6 +112,11 @@ macro_rules! make_vector { *self /= self.norm() } + /// Returns a new normalized vector. + pub fn normalized(&self) -> $name { + *self / self.norm() + } + } impl Add for $name { @@ -224,6 +229,7 @@ make_vector!(Vector3, 3, (T, T, T), (x, x_mut, 0), (y, y_mut, 1), (z, z_mut, 2)) make_vector!(Vector4, 4, (T, T, T, T), (x, x_mut, 0), (y, y_mut, 1), (z, z_mut, 2), (t, t_mut, 3)); impl Vector2 { + /// Returns a orthogonal vector to the one passed as parameter. pub fn orthogonal(&self) -> Vector2 { Vector2::new( self.y(), @@ -233,6 +239,7 @@ impl Vector2 { } impl Vector2 { + /// Returns a orthogonal vector to the one passed as parameter. pub fn orthogonal(&self) -> Vector2 { Vector2::new( self.y(), diff --git a/src/parser/mod.rs b/src/parser/mod.rs index c0d6981..ccb158b 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -175,6 +175,9 @@ pub trait Parser { self.priv_parse_into_model(model, path) } + /// Parses a file and adds its content to an already existing model. + /// + /// This is the method you should implement for you format parser. fn priv_parse_into_model(&mut self, model: &mut Model, path: &str) -> Result<(), ParserError>; } @@ -205,6 +208,8 @@ impl Parser for LP { use std::io::BufRead; for (num, line) in file.lines().enumerate() { + let num = num + 1; + if line.is_err() { return Err(ParserError::OtherError(path.to_owned())); }