From 7466c0415415052cda55f02befb720d2a348b6c9 Mon Sep 17 00:00:00 2001 From: aura Date: Tue, 3 Mar 2026 23:35:50 +0100 Subject: smoother walls --- assets/maps/test.hmap | 41 ++++++++++++++++++++----- assets/maps/test3.hmap | 70 +++++++++++++++++++++++++++++++++++++++++++ src/game/physics/movement.cpp | 8 +---- src/game/world/trace.cpp | 38 ++++++++++++++++++----- src/util/vector.h | 1 + 5 files changed, 136 insertions(+), 22 deletions(-) create mode 100644 assets/maps/test3.hmap diff --git a/assets/maps/test.hmap b/assets/maps/test.hmap index df52de5..3d7db93 100644 --- a/assets/maps/test.hmap +++ b/assets/maps/test.hmap @@ -1,9 +1,9 @@ DEF map { I32 wallcount = 7; - I32 polycount = 2; + I32 polycount = 3; I32 propcount = 5; I32 spritecount = 1; - VEC3 startpos = { 84, 109, -39.75 }; + VEC3 startpos = { 124, 42, -39.75 }; F32 startang = 0; DEF props { DEF 0 { @@ -38,7 +38,7 @@ DEF map { } DEF 2 { VEC3 start = { 200, 200, -40 }; - VEC3 end = { 0, 200, 120 }; + VEC3 end = { 83, 200, 120 }; I32 propid = 2; } DEF 3 { @@ -96,22 +96,49 @@ DEF map { I32 type = 0; DEF vertices { DEF 0 { - VEC3 pos = { 188, 187, -7.5 }; + VEC3 pos = { 192, 124, -7.5 }; VEC2 uv = { 1, 0 }; CLR clr = { 1, 1, 1, 1 }; } DEF 1 { - VEC3 pos = { 6, 187, -7.5 }; + VEC3 pos = { 10, 124, -7.5 }; VEC2 uv = { 0, 0 }; CLR clr = { 1, 1, 1, 1 }; } DEF 2 { - VEC3 pos = { 6.79887, 133.711, -40 }; + VEC3 pos = { 10, 70, -40 }; VEC2 uv = { 0, 1 }; CLR clr = { 1, 1, 1, 1 }; } DEF 3 { - VEC3 pos = { 188.102, 133.711, -40 }; + VEC3 pos = { 192, 70, -40 }; + VEC2 uv = { 1, 1 }; + CLR clr = { 1, 1, 1, 1 }; + } + } + } + DEF 2 { + I32 vertcount = 4; + I32 propid = 0; + I32 type = 0; + DEF vertices { + DEF 0 { + VEC3 pos = { 192, 169, -40 }; + VEC2 uv = { 1, 0 }; + CLR clr = { 1, 1, 1, 1 }; + } + DEF 1 { + VEC3 pos = { 10, 169, -40 }; + VEC2 uv = { 0, 0 }; + CLR clr = { 1, 1, 1, 1 }; + } + DEF 2 { + VEC3 pos = { 10, 124, -7.5 }; + VEC2 uv = { 0, 1 }; + CLR clr = { 1, 1, 1, 1 }; + } + DEF 3 { + VEC3 pos = { 192, 124, -7.5 }; VEC2 uv = { 1, 1 }; CLR clr = { 1, 1, 1, 1 }; } diff --git a/assets/maps/test3.hmap b/assets/maps/test3.hmap new file mode 100644 index 0000000..e424ead --- /dev/null +++ b/assets/maps/test3.hmap @@ -0,0 +1,70 @@ +DEF map { + I32 wallcount = 4; + I32 polycount = 1; + I32 propcount = 2; + I32 spritecount = 0; + VEC3 startpos = { 246, 199, 0 }; + F32 startang = -0.372549; + DEF props { + DEF 0 { + CLR clr = { 1, 0, 1, 1 }; + } + DEF 1 { + CLR clr = { 1, 1, 1, 1 }; + STR tex[256] = "uvtest2.png"; + } + } + DEF walls { + DEF 0 { + VEC3 start = { 0, 0, -40 }; + VEC3 end = { 512, 0, 80 }; + I32 propid = 0; + } + DEF 1 { + VEC3 start = { 116, 165, -40 }; + VEC3 end = { 116, 293, 80 }; + I32 propid = 0; + } + DEF 2 { + VEC3 start = { 250, 183, -40 }; + VEC3 end = { 160, 96, 80 }; + I32 propid = 0; + } + DEF 3 { + VEC3 start = { 160, 96, -40 }; + VEC3 end = { 80, 96, 80 }; + I32 propid = 0; + } + } + DEF polygons { + DEF 0 { + I32 vertcount = 4; + I32 propid = 1; + I32 type = 0; + DEF vertices { + DEF 0 { + VEC3 pos = { 512, 512, -40 }; + VEC2 uv = { 1, 0 }; + CLR clr = { 1, 1, 1, 1 }; + } + DEF 1 { + VEC3 pos = { 0, 512, -40 }; + VEC2 uv = { 0, 0 }; + CLR clr = { 1, 1, 1, 1 }; + } + DEF 2 { + VEC3 pos = { -3.6704, -0.685966, -40 }; + VEC2 uv = { 0, 1 }; + CLR clr = { 1, 1, 1, 1 }; + } + DEF 3 { + VEC3 pos = { 512, 0, -40 }; + VEC2 uv = { 1, 1 }; + CLR clr = { 1, 1, 1, 1 }; + } + } + } + } + DEF sprites { + } +} diff --git a/src/game/physics/movement.cpp b/src/game/physics/movement.cpp index b2b2ffa..61b1cc4 100644 --- a/src/game/physics/movement.cpp +++ b/src/game/physics/movement.cpp @@ -257,7 +257,7 @@ F32 gmove_try_move( BSP_TRACE* t, VEC3* pos, VEC3* vel ) { F32 dot = vec_dot( *vel, t->normal ); *pos += wishmove * t->frac; // nudge player away from wall - *pos += t->normal * BSP_TRACE_EPSILON * 2.f; + *pos += t->normal * BSP_TRACE_EPSILON; // avoid clipping planes twice // in a rare edge case its possible to get stuck in the plane again after pushing away from it @@ -435,14 +435,11 @@ void gmove_step_move( VEC3 dest, BSP_TRACE* tr ) { VEC3 up = pos, down = pos; VEC3 upvel = vel, downvel = vel; - F32 groundn = 0.f; if( gmove->ground ) { VEC3 ground = pos; ground.z += 2.f; bsp_trace( tr, gmove->bsp, gmove->aabb, pos, ground ); - if( tr->hit ) - groundn = tr->normal.z; } // try moving forward first @@ -504,9 +501,6 @@ void gmove_step_move( VEC3 dest, BSP_TRACE* tr ) { gmove->pos += delta; if( tr->normal.z < 0.99f ) gmove->pos += tr->normal * BSP_TRACE_EPSILON * 2.f; - // hack : moving to a steeper slope, move up a bit to avoid getting stuck in the edge - if( gmove->ground && tr->normal.z < groundn ) - gmove->pos.z += BSP_TRACE_EPSILON; gmove->velocity = upvel; gmove->velocity.z = downvel.z; } diff --git a/src/game/world/trace.cpp b/src/game/world/trace.cpp index 61e3da4..d962ba3 100644 --- a/src/game/world/trace.cpp +++ b/src/game/world/trace.cpp @@ -190,9 +190,10 @@ inline U8 point_in_inflated_poly( for( U32 i = 0; i < c; ++i ) { VEC3 a = face->verts.data[i].pos; VEC3 b = face->verts.data[(i+1)%c].pos; - VEC3 in = vec_cross( norm, b - a ); + VEC3 e = b - a; + VEC3 in = vec_cross( norm, e ); F32 len = vec_len( in ); - if( len <= 0.00001f ) continue; + if( len <= 0.0001f ) continue; in *= (1.0f/ len); if( vec_dot( center - a, in ) < 0.0f ) in = in * -1.0f; @@ -201,6 +202,21 @@ inline U8 point_in_inflated_poly( F32 expand = aabb_support_radius( hull, in ); if( dist < -( expand - BSP_EDGE_TOLERANCE ) ) return 0; + + U8 isaxis = 0; + for( U32 i = 0; i < 3; ++i ) { + if( norm == vec3_axis[i] || norm == (vec3_axis[i] * -1.f) ) { + isaxis = 1; break; + } + } + + // for non-axis-aligned faces the point of contact is infinitely thin + // todo : this isnt foolproof, check for hit direction if it comes from up/down + // just ignore this, only apply to walls + if( !isaxis ) { + if( dist < BSP_EDGE_TOLERANCE ) + return 0; + } } return 1; } @@ -218,15 +234,20 @@ U8 bsp_trace_sweep_aabb_to_face( if( face->verts.size < 3 ) return 0; - VEC3 hullh = (hull.max - hull.min) * 0.5f; - AABB fhull = { face->mins - hullh, face->maxs + hullh }; + VEC3 hullv = hull.max - hull.min; + AABB fhull = { face->mins - hullv, face->maxs + hullv }; 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 = 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 ); + F32 ndir = vec_dot( norm, dir ); + + VEC3 dirn = vec_normalize( dir ); + F32 tdot = vec_dot( dirn, norm ); + if( tdot >= 0 ) // dont collide with rear side + return 0; if( fabsf( s0 ) <= radius + BSP_TRACE_EPSILON ) { if( aabb_contains_point( fhull, start ) && point_in_inflated_poly( start, face, hull, norm ) ) { @@ -247,7 +268,6 @@ U8 bsp_trace_sweep_aabb_to_face( F32 t_enter = (-radius - s0) / ndir; F32 t_exit = ( radius - s0) / ndir; if( t_enter > t_exit ) { F32 tmp=t_enter; t_enter=t_exit; t_exit=tmp; } - if( t_exit < 0.f - BSP_TRACE_EPSILON || t_enter > 1.f + BSP_TRACE_EPSILON ) return 0; @@ -319,9 +339,11 @@ 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 ); + + + F32 expand = aabb_support_radius( hull, n ); if( dist > BSP_TRACE_EPSILON ) { - F32 expand = aabb_support_radius( hull, vec_normalize( step - proj ) ); - if( dist < -(expand) || dist > expand ) + if( dist > expand - BSP_EDGE_TOLERANCE ) continue; } diff --git a/src/util/vector.h b/src/util/vector.h index 33409a7..a01689c 100644 --- a/src/util/vector.h +++ b/src/util/vector.h @@ -55,6 +55,7 @@ struct VEC3 { VEC3( const VEC2& v ) { x = v.x; y = v.y; z = 0.f; } bool operator==( const VEC3& v ) const { return ( x == v.x && y == v.y && z == v.z ); } + bool operator!=( const VEC3& v ) const { return !( x == v.x && y == v.y && z == v.z ); } VEC3& operator=( const VEC3& v ) { x = v.x; y = v.y; z = v.z; return *this; } F32& operator[]( I32 i ) { return ( (F32*)this )[i]; } F32 operator[]( I32 i ) const { return ( (F32*)this )[i]; } -- cgit v1.2.3