From 881bc60ab34e88ece7f07ddf8740630d69632565 Mon Sep 17 00:00:00 2001 From: Quaternions <krakow20@gmail.com> Date: Thu, 13 Mar 2025 17:31:44 -0700 Subject: [PATCH] bsp_loader: truncate vertex precision to 16 bits The physics algorithm expects vertices to align exactly with faces. Since the face normal is calculated via the cross product of vertex positions, this allows the face normals to be exact with respect to the vertex positions. --- lib/bsp_loader/src/brush.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/bsp_loader/src/brush.rs b/lib/bsp_loader/src/brush.rs index a7ce6e1..d06c4a8 100644 --- a/lib/bsp_loader/src/brush.rs +++ b/lib/bsp_loader/src/brush.rs @@ -138,7 +138,15 @@ fn planes_to_faces(face_list:std::collections::HashSet<Face>)->Result<Faces,Plan loop{ // push point onto vertices // problem: this may push a vertex that does not fit in the fixed point range and is thus meaningless - face.push(intersection.divide().narrow_1().unwrap()); + // + // physics bug 2 originates from vertices being imprecise? + // + // Mask off the most precise 16 bits so that + // when face normals are calculated from + // the remaining 16 fractional bits + // they never exceed 32 bits of precision. + const MASK:Planar64=Planar64::raw(!((1<<16)-1)); + face.push(intersection.divide().narrow_1().unwrap().map(|c|c&MASK)); // we looped back around to face1, we're done! if core::ptr::eq(face1,face2){