summaryrefslogtreecommitdiff
path: root/src/game/world/trace.cpp
diff options
context:
space:
mode:
authoraura <nw@moneybot.cc>2026-03-04 18:58:21 +0100
committeraura <nw@moneybot.cc>2026-03-04 18:58:21 +0100
commit73045b6642348c8d2fd8b45cae305bbf0344d444 (patch)
tree9898f64cc14f4e95b147e0fab4b9004e41109780 /src/game/world/trace.cpp
parentfc12cd41c56bc123f01bc073b703fb151dfde814 (diff)
more collision improv
Diffstat (limited to 'src/game/world/trace.cpp')
-rw-r--r--src/game/world/trace.cpp44
1 files changed, 22 insertions, 22 deletions
diff --git a/src/game/world/trace.cpp b/src/game/world/trace.cpp
index 1d32afe..25c0477 100644
--- a/src/game/world/trace.cpp
+++ b/src/game/world/trace.cpp
@@ -226,9 +226,7 @@ U8 bsp_trace_sweep_aabb_to_face(
if( face->verts.size < 3 )
return 0;
- VEC3 hullv = hull.max - hull.min;
- AABB fhull = { face->mins - hullv, face->maxs + hullv };
- AABB fhullh = { face->mins - hullv * 0.5f, face->maxs + hullv * 0.5f };
+
VEC3 norm = bsp_face_get_normal( face );
F32 d = vec_dot( norm, face->verts[0].pos );
F32 radius = aabb_support_radius( hull, norm );
@@ -237,19 +235,19 @@ U8 bsp_trace_sweep_aabb_to_face(
F32 s0 = vec_dot( norm, trace->in_start ) - d;
F32 ndir = vec_dot( norm, dir );
- F32 tdot = vec_dot( dir, norm );
- if( tdot >= 0 ) // dont collide with rear side
+ if( ndir >= 0 ) // dont collide with rear side
return 0;
+ VEC3 hullv = hull.max - hull.min;
+ for( U32 i = 0; i < 3; ++i ) hullv[i] += BSP_EDGE_TOLERANCE;
+ AABB fhullh = { face->mins - hullv * 0.5f, face->maxs + hullv * 0.5f };
+
if( fabsf( s0 ) <= radius + BSP_TRACE_EPSILON ) {
if( aabb_contains_point( fhullh, start ) && point_in_inflated_poly( start, face, hull, norm ) ) {
trace->hit = 1;
trace->frac = 0.f;
trace->startsolid = 1;
trace->point = start;
- trace->point.x = m_clamp( trace->point.x, fhullh.min.x, fhullh.max.x );
- trace->point.y = m_clamp( trace->point.y, fhullh.min.y, fhullh.max.y );
- trace->point.z = m_clamp( trace->point.z, fhullh.min.z, fhullh.max.z );
trace->normal = norm;
trace->propid = face->propid;
trace->faceid = face_idx;
@@ -266,16 +264,12 @@ U8 bsp_trace_sweep_aabb_to_face(
F32 t = m_clamp( t_enter, 0.f, 1.f );
VEC3 step = trace->in_start + dir * t;
- if( !aabb_contains_point( fhull, step ) )
+ if( !aabb_contains_point( fhullh, step ) )
return 0;
if( !point_in_inflated_poly( step, face, hull, norm ) )
return 0;
- step.x = m_clamp( step.x, fhullh.min.x, fhullh.max.x );
- step.y = m_clamp( step.y, fhullh.min.y, fhullh.max.y );
- step.z = m_clamp( step.z, fhullh.min.z, fhullh.max.z );
-
trace->hit = 1;
trace->frac = t;
trace->point = step;
@@ -320,7 +314,7 @@ U8 bsp_trace_sweep_aabb_to_leaf_edges(
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 )
+ if( t_exit < 0.f || t_enter > 1.f )
continue;
F32 t = m_clamp( t_enter, 0.f, 1.f );
@@ -335,12 +329,15 @@ U8 bsp_trace_sweep_aabb_to_leaf_edges(
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 );
+ VEC3 ec = vec_cross( edir, n );
+ F32 nlen = vec_len( ec );
+ if( nlen < 0.001f )
+ continue;
+ ec *= (1.f / nlen);
- F32 expand = aabb_support_radius( hull, n );
- if( dist > BSP_TRACE_EPSILON ) {
- if( dist > expand - BSP_EDGE_TOLERANCE )
- continue;
- }
+ F32 expand = aabb_support_radius( hull, ec );
+ if( dist - expand > r * 0.5f )
+ continue;
if( t < best ) {
best = t;
@@ -397,17 +394,20 @@ U8 bsp_trace_sweep_aabb_to_leaf(
}
}
+ best = FLT_MAX;
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 )
+ else if( edgehit.frac <= besthit.frac + BSP_TRACE_EPSILON )
*trace = edgehit;
- else
+ else {
*trace = besthit;
+ if( edgehit.normal.z > besthit.normal.z )
+ trace->normal.z = edgehit.normal.z;
+ }
trace->hit = 1;
return 1;
}