diff --git a/lib/bsp_loader/src/brush.rs b/lib/bsp_loader/src/brush.rs index 45737b0..52bcabc 100644 --- a/lib/bsp_loader/src/brush.rs +++ b/lib/bsp_loader/src/brush.rs @@ -28,22 +28,21 @@ fn solve3(c0:&Face,c1:&Face,c2:&Face)->Option<Ratio<Vector3<Fixed<3,96>>,Fixed<3 } #[derive(Debug)] -pub enum BrushToMeshError{ - SliceBrushSides, - MissingPlane, - InvalidFaceCount{ - count:usize, - }, - InvalidPlanes, +pub enum PlanesToFacesError{ + InitFace1, + InitFace2, + InitIntersection, + FindNewIntersection, + EmptyFaces, } -impl std::fmt::Display for BrushToMeshError{ +impl std::fmt::Display for PlanesToFacesError{ fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{ write!(f,"{self:?}") } } -impl core::error::Error for BrushToMeshError{} +impl core::error::Error for PlanesToFacesError{} -fn planes_to_faces(face_list:std::collections::HashSet<Face>)->Option<Faces>{ +fn planes_to_faces(face_list:std::collections::HashSet<Face>)->Result<Faces,PlanesToFacesError>{ let mut faces=Vec::new(); // for each face, determine one edge at a time until you complete the face 'face: for face0 in &face_list{ @@ -58,7 +57,7 @@ fn planes_to_faces(face_list:std::collections::HashSet<Face>)->Option<Faces>{ // find the most perpendicular face to face0 let mut face1=face_list.iter().min_by_key(|&p|{ face0.normal.dot(p.normal).abs() - })?; + }).ok_or(PlanesToFacesError::InitFace1)?; // direction of edge formed by face0 x face1 let edge_dir=face0.normal.cross(face1.normal); @@ -67,9 +66,9 @@ fn planes_to_faces(face_list:std::collections::HashSet<Face>)->Option<Faces>{ let mut face2=face_list.iter().max_by_key(|&p|{ // find the best *oriented* face (no .abs()) edge_dir.dot(p.normal) - })?; + }).ok_or(PlanesToFacesError::InitFace2)?; - let mut intersection=solve3(face0,face1,face2)?; + let mut intersection=solve3(face0,face1,face2).ok_or(PlanesToFacesError::InitIntersection)?; // repeatedly update face0, face1 until all faces form part of the convex solid 'find: loop{ @@ -164,7 +163,7 @@ fn planes_to_faces(face_list:std::collections::HashSet<Face>)->Option<Faces>{ } Some((new_face,new_intersection,d_new_intersection)) - }).min_by_key(|&(_,_,d)|d)?; + }).min_by_key(|&(_,_,d)|d).ok_or(PlanesToFacesError::FindNewIntersection)?; // we looped back around to face1, we're done! if core::ptr::eq(face1,new_face){ @@ -179,14 +178,30 @@ fn planes_to_faces(face_list:std::collections::HashSet<Face>)->Option<Faces>{ } if faces.is_empty(){ - None + Err(PlanesToFacesError::EmptyFaces) }else{ - Some(Faces{ + Ok(Faces{ faces, }) } } +#[derive(Debug)] +pub enum BrushToMeshError{ + SliceBrushSides, + MissingPlane, + InvalidFaceCount{ + count:usize, + }, + InvalidPlanes(PlanesToFacesError), +} +impl std::fmt::Display for BrushToMeshError{ + fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{ + write!(f,"{self:?}") + } +} +impl core::error::Error for BrushToMeshError{} + pub fn brush_to_mesh(bsp:&vbsp::Bsp,brush:&vbsp::Brush)->Result<model::Mesh,BrushToMeshError>{ let brush_start_idx=brush.brush_side as usize; let sides_range=brush_start_idx..brush_start_idx+brush.num_brush_sides as usize; @@ -203,7 +218,7 @@ pub fn brush_to_mesh(bsp:&vbsp::Bsp,brush:&vbsp::Brush)->Result<model::Mesh,Brus return Err(BrushToMeshError::InvalidFaceCount{count:face_list.len()}); } - let faces=planes_to_faces(face_list).ok_or(BrushToMeshError::InvalidPlanes)?; + let faces=planes_to_faces(face_list).map_err(BrushToMeshError::InvalidPlanes)?; // generate the mesh let mut polygon_list=Vec::new();