diff --git a/lib/bsp_loader/src/brush.rs b/lib/bsp_loader/src/brush.rs
index a14a9b2..2eed980 100644
--- a/lib/bsp_loader/src/brush.rs
+++ b/lib/bsp_loader/src/brush.rs
@@ -34,6 +34,7 @@ pub enum BrushToMeshError{
 	InvalidFaceCount{
 		count:usize,
 	},
+	InvalidPlanes,
 }
 impl std::fmt::Display for BrushToMeshError{
 	fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
@@ -43,6 +44,7 @@ impl std::fmt::Display for BrushToMeshError{
 impl core::error::Error for BrushToMeshError{}
 
 fn planes_to_faces(face_list:Vec<Face>)->Option<Faces>{
+	let mut faces=Vec::new();
 	// for each face, determine one edge at a time until you complete the face
 	let mut dedup=std::collections::HashSet::new();
 	'face: for face0 in &face_list{
@@ -136,33 +138,58 @@ fn planes_to_faces(face_list:Vec<Face>)->Option<Faces>{
 		}
 
 		// === follow edges around face ===
-		// Note that we chose face2 so that the faces create a particular winding order.
+		// Note that we chose face2 such that the 3 faces create a particular winding order.
 		// If we choose a consistent face to follow (face1, face2) it will always wind with a consistent chirality
 
+		// keep looping until we meet this face again
+		let face1=face1;
+		let mut face=Vec::new();
 		loop{
+			// push point onto vertices
+			face.push(intersection.divide().fix_1());
+
 			// the measure
 			let edge_dir=face0.normal.cross(face1.normal);
 
 			// the dot product to beat
 			let d_intersection=edge_dir.dot(intersection.num)/intersection.den;
 
-			for new_face in &face_list{
-				if core::ptr::eq(face0,new_face){
-					continue;
+			// find the next face moving clockwise around face0
+			let (new_face,new_intersection,_)=face_list.iter().filter_map(|new_face|{
+				// ignore faces we've seen before
+				if core::ptr::eq(face0,new_face)
+				  |core::ptr::eq(face2,new_face){
+					return None;
 				}
-				if core::ptr::eq(face1,new_face){
-					continue;
-				}
-				if core::ptr::eq(face2,new_face){
-					continue;
-				}
-				if let Some(new_intersection)=solve3(new_face,face1,face2){
+				let new_intersection=solve3(face0,face2,new_face)?;
+
+				// the d value must be larger
+				let d_new_intersection=edge_dir.dot(new_intersection.num)/new_intersection.den;
+				if d_new_intersection.le_ratio(d_intersection){
+					return None;
 				}
+				Some((new_face,new_intersection,d_new_intersection))
+			}).min_by_key(|&(_,_,d)|d)?;
+
+			// we looped back around to face1, we're done!
+			if core::ptr::eq(face1,new_face){
+				break;
 			}
+
+			face2=new_face;
+			intersection=new_intersection;
 		}
+
+		faces.push(face);
 	}
 
-	None
+	if faces.is_empty(){
+		None
+	}else{
+		Some(Faces{
+			faces,
+		})
+	}
 }
 
 pub fn brush_to_mesh(bsp:&vbsp::Bsp,brush:&vbsp::Brush)->Result<model::Mesh,BrushToMeshError>{
@@ -181,7 +208,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)?;
+	let faces=planes_to_faces(face_list).ok_or(BrushToMeshError::InvalidPlanes)?;
 
 	// generate the mesh
 	let mut polygon_list=Vec::new();