From 510aef07a89244f52656b3a1c9c9fa656331fe48 Mon Sep 17 00:00:00 2001
From: Quaternions <krakow20@gmail.com>
Date: Tue, 18 Feb 2025 13:53:56 -0800
Subject: [PATCH] wip wip

---
 engine/physics/src/physics.rs | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/engine/physics/src/physics.rs b/engine/physics/src/physics.rs
index fc14ad6..34b3d67 100644
--- a/engine/physics/src/physics.rs
+++ b/engine/physics/src/physics.rs
@@ -1,4 +1,5 @@
 use std::collections::{HashMap,HashSet};
+use crate::model::DirectedEdge;
 use crate::model::{self as model_physics,PhysicsMesh,PhysicsMeshTransform,TransformedMesh,MeshQuery,PhysicsMeshId,PhysicsSubmeshId};
 use strafesnet_common::bvh;
 use strafesnet_common::map;
@@ -983,8 +984,22 @@ impl PhysicsData{
 	pub fn trace_ray(&self,ray:strafesnet_common::bvh::Ray)->Option<ModelId>{
 		let (time,convex_mesh_id)=self.bvh.sample_ray(&ray,Time::ZERO,Time::MAX,|&model,ray|{
 			let mesh=self.models.mesh(model);
-			// TODO: ray tracing lol
-			None
+			// brute force trace every face
+			mesh.faces().filter_map(|face_id|{
+				let (n,d)=mesh.face_nd(face_id);
+				// trace ray onto face
+				// n.(o+d*t)==n.p
+				// n.o + n.d * t == n.p
+				// t == (n.p - n.o)/n.d
+				let t=(d-n.dot(ray.origin))/n.dot(ray.direction);
+				// check if point of intersection is behind face edges
+				let p=ray.extrapolate(t);
+				mesh.face_edges(face_id).iter().all(|&directed_edge_id|{
+					let edge_n=mesh.directed_edge_n(directed_edge_id);
+					let &[vert0,vert1]=mesh.edge_verts(directed_edge_id.as_undirected()).as_ref();
+					(n.cross(edge_n)*2).dot(p.num)/p.den<mesh.vert(vert0)+mesh.vert(vert1)
+				}).then(||t.into())
+			}).min()
 		})?;
 		Some(convex_mesh_id.model_id.into())
 	}