diff --git a/strafe-client/src/face_crawler.rs b/strafe-client/src/face_crawler.rs
index 06405750..4b2fab44 100644
--- a/strafe-client/src/face_crawler.rs
+++ b/strafe-client/src/face_crawler.rs
@@ -12,6 +12,20 @@ pub enum CrawlResult<M:MeshQuery>{
 	Miss(FEV<M>),
 	Hit(M::Face,GigaTime),
 }
+impl<M:MeshQuery> CrawlResult<M>{
+	pub fn hit(self)->Option<(M::Face,GigaTime)>{
+		match self{
+			CrawlResult::Miss(_)=>None,
+			CrawlResult::Hit(face,time)=>Some((face,time)),
+		}
+	}
+	pub fn miss(self)->Option<FEV<M>>{
+		match self{
+			CrawlResult::Miss(fev)=>Some(fev),
+			CrawlResult::Hit(_,_)=>None,
+		}
+	}
+}
 
 impl<F:Copy,M:MeshQuery<Normal=Vector3<F>,Offset=Fixed<4,128>>> FEV<M>
 	where
diff --git a/strafe-client/src/model_physics.rs b/strafe-client/src/model_physics.rs
index 57f9ec36..a8c15774 100644
--- a/strafe-client/src/model_physics.rs
+++ b/strafe-client/src/model_physics.rs
@@ -726,19 +726,13 @@ impl MinkowskiMesh<'_>{
 			infinity_body.acceleration=vec3::ZERO;
 			//crawl in from negative infinity along a tangent line to get the closest fev
 			// TODO: change crawl_fev args to delta time? Optional values?
-			match infinity_fev.crawl(self,&infinity_body,Time::MIN/4,start_time){
-				crate::face_crawler::CrawlResult::Miss(fev)=>Some(fev),
-				crate::face_crawler::CrawlResult::Hit(_,_)=>None,
-			}
+			infinity_fev.crawl(self,&infinity_body,Time::MIN/4,start_time).miss()
 		})
 	}
 	pub fn predict_collision_in(&self,relative_body:&Body,start_time:Time,time_limit:Time)->Option<(MinkowskiFace,GigaTime)>{
 		self.closest_fev_not_inside(relative_body.clone(),start_time).map_or(None,|fev|{
 			//continue forwards along the body parabola
-			match fev.crawl(self,relative_body,start_time,time_limit){
-				crate::face_crawler::CrawlResult::Miss(_)=>None,
-				crate::face_crawler::CrawlResult::Hit(face,time)=>Some((face,time)),
-			}
+			fev.crawl(self,relative_body,start_time,time_limit).hit()
 		})
 	}
 	pub fn predict_collision_out(&self,relative_body:&Body,start_time:Time,time_limit:Time)->Option<(MinkowskiFace,GigaTime)>{
@@ -746,10 +740,9 @@ impl MinkowskiMesh<'_>{
 		let infinity_body=-relative_body.clone();
 		self.closest_fev_not_inside(infinity_body,-time_limit).map_or(None,|fev|{
 			//continue backwards along the body parabola
-			match fev.crawl(self,&infinity_body,-time_limit,-start_time){
-				crate::face_crawler::CrawlResult::Miss(_)=>None,
-				crate::face_crawler::CrawlResult::Hit(face,time)=>Some((face,-time)),//no need to test -time<time_limit because of the first step
-			}
+			fev.crawl(self,&infinity_body,-time_limit,-start_time).hit()
+				//no need to test -time<time_limit because of the first step
+				.map(|(face,time)|(face,-time))
 		})
 	}
 	pub fn predict_collision_face_out(&self,relative_body:&Body,start_time:Time,time_limit:Time,contact_face_id:MinkowskiFace)->Option<(MinkowskiEdge,GigaTime)>{
@@ -785,10 +778,7 @@ impl MinkowskiMesh<'_>{
 	}
 	fn infinity_in(&self,infinity_body:Body)->Option<(MinkowskiFace,GigaTime)>{
 		let infinity_fev=self.infinity_fev(-infinity_body.velocity,infinity_body.position);
-		match infinity_fev.crawl(self,&infinity_body,Time::MIN/4,infinity_body.time){
-			crate::face_crawler::CrawlResult::Miss(_)=>None,
-			crate::face_crawler::CrawlResult::Hit(face,time)=>Some((face,time)),
-		}
+		infinity_fev.crawl(self,&infinity_body,Time::MIN/4,infinity_body.time).hit()
 	}
 	pub fn is_point_in_mesh(&self,point:Planar64Vec3)->bool{
 		let infinity_body=Body::new(point,vec3::Y,vec3::ZERO,Time::ZERO);