PlanesToFacesError

This commit is contained in:
Quaternions 2025-02-05 10:54:23 -08:00
parent 64fb36ec23
commit 6a085e42ba

@ -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();