summaryrefslogtreecommitdiff
path: root/src/game/world/trace.cpp
diff options
context:
space:
mode:
authoraura <nw@moneybot.cc>2026-03-03 16:16:06 +0100
committeraura <nw@moneybot.cc>2026-03-03 16:16:06 +0100
commite57cac01b0a4eb764185e8eca9396a25b83f34d3 (patch)
tree37847002df4bdb984903362e9fa1134038f92d0e /src/game/world/trace.cpp
parentb3a92fa1ffc565c2fc72b1a531cae09cbbc219bd (diff)
edge planes )))bsp-edges
Diffstat (limited to 'src/game/world/trace.cpp')
-rw-r--r--src/game/world/trace.cpp66
1 files changed, 48 insertions, 18 deletions
diff --git a/src/game/world/trace.cpp b/src/game/world/trace.cpp
index 6d1e8db..61e3da4 100644
--- a/src/game/world/trace.cpp
+++ b/src/game/world/trace.cpp
@@ -218,16 +218,18 @@ U8 bsp_trace_sweep_aabb_to_face(
if( face->verts.size < 3 )
return 0;
- VEC3 norm = bsp_face_get_normal( face );
- F32 d = vec_dot( norm, face->verts[0].pos );
- F32 radius = aabb_support_radius( hull, norm );
+ VEC3 hullh = (hull.max - hull.min) * 0.5f;
+ AABB fhull = { face->mins - hullh, face->maxs + hullh };
+ VEC3 norm = bsp_face_get_normal( face );
+ F32 d = vec_dot( norm, face->verts[0].pos );
+ F32 radius = aabb_support_radius( hull, norm );
- VEC3 dir = end - start;
+ VEC3 dir = trace->in_end - trace->in_start;
F32 s0 = vec_dot( norm, trace->in_start ) - d;
F32 ndir = vec_dot( norm, trace->in_end - trace->in_start );
if( fabsf( s0 ) <= radius + BSP_TRACE_EPSILON ) {
- if( point_in_inflated_poly( start, face, hull, norm ) ) {
+ if( aabb_contains_point( fhull, start ) && point_in_inflated_poly( start, face, hull, norm ) ) {
trace->hit = 1;
trace->frac = 0.f;
trace->startsolid = 1;
@@ -250,7 +252,10 @@ U8 bsp_trace_sweep_aabb_to_face(
return 0;
F32 t = m_clamp( t_enter, 0.f, 1.f );
- VEC3 step = start + dir * t;
+ VEC3 step = trace->in_start + dir * t;
+
+ if( !aabb_contains_point( fhull, step ) )
+ return 0;
if( !point_in_inflated_poly( step, face, hull, norm ) )
return 0;
@@ -276,7 +281,7 @@ U8 bsp_trace_sweep_aabb_to_leaf_edges(
BSP_LEAF* leaf = &bsp->leaves.data[leaf_idx];
U8 hit = 0;
F32 best = *in_best;
-
+
BSP_TRACE besthit = *trace;
for( U32 i = 0; i < leaf->edges.size; ++i ) {
BSP_EDGE* e = &leaf->edges[i];
@@ -294,15 +299,31 @@ U8 bsp_trace_sweep_aabb_to_leaf_edges(
if( ndir >= 0.f ) continue;
if( s0 < -(r + BSP_TRACE_EPSILON) ) continue;
-
- F32 t = (-r - s0) / ndir;
- if( t < 0.f || t > 1.f ) continue;
- t = m_clamp( t, 0.f, 1.f );
+
+ F32 t_enter = ( r - s0) / ndir;
+ F32 t_exit = (-r - s0) / ndir;
+ if( t_enter > t_exit ) { F32 tmp = t_enter; t_enter = t_exit; t_exit = tmp; }
+
+ if( t_exit < -BSP_TRACE_EPSILON || t_enter > 1.f + BSP_TRACE_EPSILON )
+ continue;
+ F32 t = m_clamp( t_enter, 0.f, 1.f );
VEC3 step = start + (end - start) * t;
- if( !point_in_inflated_poly( step, f, hull, n ) )
+ VEC3 edir = e->v2 - e->v1;
+ F32 elen = vec_len( edir );
+ if( elen < 0.001f )
continue;
+ edir *= (1.f / elen);
+
+ F32 along = vec_dot( step - e->v1, edir );
+ VEC3 proj = e->v1 + edir * m_clamp( along, 0.f, elen );
+ F32 dist = vec_dist( proj, step );
+ if( dist > BSP_TRACE_EPSILON ) {
+ F32 expand = aabb_support_radius( hull, vec_normalize( step - proj ) );
+ if( dist < -(expand) || dist > expand )
+ continue;
+ }
if( t < best ) {
best = t;
@@ -338,6 +359,7 @@ U8 bsp_trace_sweep_aabb_to_leaf(
F32 best = FLT_MAX;
BSP_TRACE besthit = *trace;
+ BSP_TRACE edgehit = *trace;
for( U32 i = 0; i < leaf->count; ++i ) {
U32 face_idx = leaf->first + i;
@@ -358,14 +380,22 @@ U8 bsp_trace_sweep_aabb_to_leaf(
}
}
- U8 ehit = bsp_trace_sweep_aabb_to_leaf_edges( bsp, trace, hull, start, end, leaf_idx, &best );
- if( !hit ) hit = ehit;
-
- if( hit ) {
- *trace = besthit;
+ U8 ehit = bsp_trace_sweep_aabb_to_leaf_edges( bsp, &edgehit, hull, start, end, leaf_idx, &best );
+
+ if( hit || ehit ) {
+ if( ehit && !hit )
+ *trace = edgehit;
+ else if( !ehit && hit )
+ *trace = besthit;
+ else if( edgehit.frac < besthit.frac )
+ *trace = edgehit;
+ else
+ *trace = besthit;
trace->hit = 1;
+ return 1;
}
- return hit;
+
+ return 0;
}
U8 bsp_trace_sweep_aabb(