From 4e564326d0a302e27bf773eee9b1bdb88dfda884 Mon Sep 17 00:00:00 2001 From: HampusM Date: Wed, 15 Jan 2025 19:45:08 +0100 Subject: fix(engine): make Mesh indices produced by Obj::to_mesh useful --- engine/src/file_format/wavefront/obj.rs | 49 +++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 21 deletions(-) (limited to 'engine/src/file_format') diff --git a/engine/src/file_format/wavefront/obj.rs b/engine/src/file_format/wavefront/obj.rs index 88e6580..6ca11c2 100644 --- a/engine/src/file_format/wavefront/obj.rs +++ b/engine/src/file_format/wavefront/obj.rs @@ -2,6 +2,7 @@ //! //! File format documentation: +use std::collections::HashMap; use std::fs::read_to_string; use std::path::PathBuf; @@ -82,26 +83,32 @@ impl Obj /// - A face index does not fit in a [`u32`] pub fn to_mesh(&self) -> Result { - let vertices = self - .faces - .iter() - .flat_map(|face| face.vertices.clone()) - .map(|face_vertex| face_vertex.to_vertex(self)) - .collect::, Error>>()?; - - Ok(Mesh::new( - vertices, - Some( - self.faces - .iter() - .flat_map(|face| face.vertices.clone()) - .enumerate() - .map(|(index, _)| { - u32::try_from(index).map_err(|_| Error::FaceIndexTooBig(index)) - }) - .collect::, _>>()?, - ), - )) + let mut vertices = Vec::::with_capacity(self.faces.len() * 3); + let mut indices = Vec::::with_capacity(self.faces.len() * 3); + + let mut added_face_vertices = + HashMap::::with_capacity(self.faces.len() * 3); + + for face in &self.faces { + for face_vertex in &face.vertices { + if let Some(index) = added_face_vertices.get(&face_vertex) { + indices.push(*index); + + continue; + } + + vertices.push(face_vertex.to_vertex(self)?); + + let vertex_index = u32::try_from(vertices.len() - 1) + .map_err(|_| Error::FaceIndexTooBig(vertices.len() - 1))?; + + indices.push(vertex_index); + + added_face_vertices.insert(face_vertex.clone(), vertex_index); + } + } + + Ok(Mesh::new(vertices, Some(indices))) } /// Reads and parses the material libraries of this `Obj`. @@ -142,7 +149,7 @@ pub struct Face pub material_name: Option, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct FaceVertex { pub position: u32, -- cgit v1.2.3-18-g5258