diff options
Diffstat (limited to 'engine')
-rw-r--r-- | engine/src/file_format/wavefront/obj.rs | 174 |
1 files changed, 86 insertions, 88 deletions
diff --git a/engine/src/file_format/wavefront/obj.rs b/engine/src/file_format/wavefront/obj.rs index d60b41d..884229c 100644 --- a/engine/src/file_format/wavefront/obj.rs +++ b/engine/src/file_format/wavefront/obj.rs @@ -14,14 +14,6 @@ use crate::util::try_option; use crate::vector::{Vec2, Vec3}; use crate::vertex::{Builder as VertexBuilder, Vertex}; -/// The output from parsing the content of a Wavefront `.obj` using [`parse`]. -#[derive(Debug)] -#[non_exhaustive] -pub struct Obj -{ - pub mesh: Mesh, -} - /// Parses the content of a Wavefront `.obj`. /// /// # Errors @@ -107,26 +99,40 @@ pub fn parse(obj_content: &str) -> Result<Obj, Error> }) .collect::<Result<Vec<[FaceVertex; 3]>, _>>()?; - let vertices = faces - .iter() - .flatten() - .map(|face_vertex| { - face_vertex_to_vertex( - face_vertex, - Data { - vertex_positions: &vertex_positions, - texture_positions: &texture_positions, - vertex_normals: &vertex_normals, - }, - ) - }) - .collect::<Result<Vec<_>, Error>>()?; - Ok(Obj { - mesh: Mesh::new( + vertex_positions, + vertex_normals, + texture_positions, + faces, + }) +} + +/// The output from parsing the content of a Wavefront `.obj` using [`parse`]. +#[derive(Debug)] +#[non_exhaustive] +pub struct Obj +{ + pub vertex_positions: Vec<Vec3<f32>>, + pub vertex_normals: Vec<Vec3<f32>>, + pub texture_positions: Vec<Vec2<f32>>, + pub faces: Vec<[FaceVertex; 3]>, +} + +impl Obj +{ + pub fn to_mesh(&self) -> Result<Mesh, Error> + { + let vertices = self + .faces + .iter() + .flatten() + .map(|face_vertex| face_vertex.to_vertex(self)) + .collect::<Result<Vec<_>, Error>>()?; + + Ok(Mesh::new( vertices, Some( - faces + self.faces .iter() .flatten() .enumerate() @@ -135,55 +141,67 @@ pub fn parse(obj_content: &str) -> Result<Obj, Error> }) .collect::<Result<Vec<_>, _>>()?, ), - ), - }) + )) + } } -struct Data<'a> +#[derive(Debug)] +pub struct FaceVertex { - vertex_positions: &'a [Vec3<f32>], - texture_positions: &'a [Vec2<f32>], - vertex_normals: &'a [Vec3<f32>], + pub position: u32, + pub texture: Option<u32>, + pub normal: Option<u32>, } -fn face_vertex_to_vertex(face_vertex: &FaceVertex, data: Data) -> Result<Vertex, Error> +impl FaceVertex { - let vertex_pos = *data - .vertex_positions - .get(face_vertex.position as usize - 1) - .ok_or(Error::FaceVertexPositionNotFound { - vertex_pos_index: face_vertex.position, - })?; - - let face_vertex_texture = face_vertex - .texture - .ok_or(Error::NoFaceVertexTextureNotSupported)?; - - let texture_pos = *data - .texture_positions - .get(face_vertex_texture as usize - 1) - .ok_or(Error::FaceTexturePositionNotFound { - texture_pos_index: face_vertex_texture, - })?; - - let face_vertex_normal = face_vertex - .normal - .ok_or(Error::NoFaceVertexNormalNotSupported)?; - - let vertex_normal = *data - .vertex_normals - .get(face_vertex_normal as usize - 1) - .ok_or(Error::FaceVertexNormalNotFound { - vertex_normal_index: face_vertex_normal, - })?; - - Ok(VertexBuilder::new() - .pos(vertex_pos) - .color(Color::WHITE_F32) - .texture_coords(texture_pos) - .normal(vertex_normal) - .build() - .unwrap()) + /// Tries to convert this face vertex into a [`Vertex`]. + pub fn to_vertex(&self, obj: &Obj) -> Result<Vertex, Error> + { + let vertex_pos = *obj.vertex_positions.get(self.position as usize - 1).ok_or( + Error::FaceVertexPositionNotFound { vertex_pos_index: self.position }, + )?; + + let face_vertex_texture = + self.texture.ok_or(Error::NoFaceVertexTextureNotSupported)?; + + let texture_pos = *obj + .texture_positions + .get(face_vertex_texture as usize - 1) + .ok_or(Error::FaceTexturePositionNotFound { + texture_pos_index: face_vertex_texture, + })?; + + let face_vertex_normal = + self.normal.ok_or(Error::NoFaceVertexNormalNotSupported)?; + + let vertex_normal = *obj + .vertex_normals + .get(face_vertex_normal as usize - 1) + .ok_or(Error::FaceVertexNormalNotFound { + vertex_normal_index: face_vertex_normal, + })?; + + Ok(VertexBuilder::new() + .pos(vertex_pos) + .color(Color::WHITE_F32) + .texture_coords(texture_pos) + .normal(vertex_normal) + .build() + .unwrap()) + } +} + +impl From<Triplet> for FaceVertex +{ + fn from(triplet: Triplet) -> Self + { + Self { + position: triplet.0, + texture: triplet.1, + normal: triplet.2, + } + } } #[derive(Debug, thiserror::Error)] @@ -248,23 +266,3 @@ keyword! { F, } } - -#[derive(Debug)] -struct FaceVertex -{ - position: u32, - texture: Option<u32>, - normal: Option<u32>, -} - -impl From<Triplet> for FaceVertex -{ - fn from(triplet: Triplet) -> Self - { - Self { - position: triplet.0, - texture: triplet.1, - normal: triplet.2, - } - } -} |