summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/editor/view2d.cpp24
-rw-r--r--src/game/physics/movement.cpp10
-rw-r--r--src/game/world/bsp.cpp2
-rw-r--r--src/game/world/bsp.h18
-rw-r--r--src/game/world/bsp_draw.cpp3
-rw-r--r--src/game/world/trace.cpp116
-rw-r--r--src/game/world/trace.h2
7 files changed, 103 insertions, 72 deletions
diff --git a/src/editor/view2d.cpp b/src/editor/view2d.cpp
index b68846e..c1ef5ea 100644
--- a/src/editor/view2d.cpp
+++ b/src/editor/view2d.cpp
@@ -630,13 +630,23 @@ void gui_editor_2dview_draw_sprites( GUI_EDITOR_2DVIEW* view, I32 x, I32 y ) {
gui_draw_rect( pos.x - w/2 - 1, pos.y - h/2 - 1, w + 2, h + 2, CLR::WHITE( 0.5f ) );
}
- gl_2d_textured_frect(
- _gui.gl2d_font,
- { (F32)((I32)pos.x - w/2), (F32)((I32)pos.y - h/2) },
- { (F32)w, (F32)h },
- s->tex,
- s->clr
- );
+ else {
+ gl_2d_frect(
+ _gui.gl2d,
+ { (F32)((I32)pos.x - w/2), (F32)((I32)pos.y - h/2) },
+ { (F32)w, (F32)h },
+ s->clr
+ );
+ }
+ if( s->tex ) {
+ gl_2d_textured_frect(
+ _gui.gl2d_font,
+ { (F32)((I32)pos.x - w/2), (F32)((I32)pos.y - h/2) },
+ { (F32)w, (F32)h },
+ s->tex,
+ s->clr
+ );
+ }
} );
}
diff --git a/src/game/physics/movement.cpp b/src/game/physics/movement.cpp
index 9f1a7dd..d689096 100644
--- a/src/game/physics/movement.cpp
+++ b/src/game/physics/movement.cpp
@@ -154,7 +154,7 @@ U8 gmove_touch_ground_quadrants( BSP_TRACE* tr, VEC3 start, VEC3 end ) {
void gmove_categorize_pos() {
gmove->pl->surf_friction = 1.f;
F32 offset = 2.f;
- BSP_TRACE tr{};
+ BSP_TRACE tr{ .hitmask = HG_MOVEMENT };
VEC3 point = gmove->pos;
point.z -= offset;
@@ -282,7 +282,7 @@ F32 gmove_try_move( BSP_TRACE* t, VEC3* pos, VEC3* vel ) {
}
void gmove_check_stuck( VEC3* in_pos ) {
- BSP_TRACE t;
+ BSP_TRACE t{ .hitmask = HG_MOVEMENT };
VEC3 pos = *in_pos;
U32 i;
if( vec_len( gmove->unstuck_vel ) < 0.f )
@@ -417,7 +417,7 @@ void gmove_friction() {
}
void gmove_stay_on_ground() {
- BSP_TRACE tr{};
+ BSP_TRACE tr{ .hitmask = HG_MOVEMENT };
VEC3 start = gmove->pos;
VEC3 end = gmove->pos;
@@ -547,7 +547,7 @@ void gmove_walk_move() {
VEC3 dest = gmove->pos + gmove->velocity * TICK_INTERVAL;
- BSP_TRACE tr{};
+ BSP_TRACE tr{ .hitmask = HG_MOVEMENT };
bsp_trace( &tr, gmove->bsp, gmove->aabb, gmove->pos, dest );
defer( gmove_stay_on_ground() );
@@ -582,7 +582,7 @@ void gmove_air_move() {
gmove_airaccelerate( wishdir, speed, var_getf( mv_airaccelerate ) );
- BSP_TRACE tr{};
+ BSP_TRACE tr{ .hitmask = HG_MOVEMENT };
gmove_try_move( &tr, &gmove->pos, &gmove->velocity );
gmove_check_stuck( &gmove->pos );
}
diff --git a/src/game/world/bsp.cpp b/src/game/world/bsp.cpp
index 4894d1c..f5fb0e9 100644
--- a/src/game/world/bsp.cpp
+++ b/src/game/world/bsp.cpp
@@ -168,6 +168,7 @@ LIST<BSP_FACE> bsp_map_faces_from_walls( WORLD_MAP* map ) {
f.verts.push( vertices[1] );
f.verts.push( vertices[0] );
f.verts.push( vertices[3] );
+ f.hitmask = HM_WORLD;
ret.push( f );
};
@@ -188,6 +189,7 @@ LIST<BSP_FACE> bsp_map_faces_from_planes( WORLD_MAP* map ) {
f.verts.push( *start );
f.verts.push( *last );
f.verts.push( p->vertices[i] );
+ f.hitmask = HM_WORLD;
ret.push( f );
last = &p->vertices[i];
diff --git a/src/game/world/bsp.h b/src/game/world/bsp.h
index fa06696..ac72e14 100644
--- a/src/game/world/bsp.h
+++ b/src/game/world/bsp.h
@@ -25,6 +25,23 @@ enum BspSide_t {
BSP_SIDE_SPAN = 8,
};
+enum HitMask_t {
+ HM_NONE = 0,
+ HM_WORLD = 1 << 1,
+ HM_PROP = 1 << 2,
+ HM_ENTITY = 1 << 3,
+ HM_PLAYER = 1 << 4,
+ HM_ANY = 0xffffffff
+};
+
+enum HitGroup_t {
+ HG_NONE = 0,
+ HG_MOVEMENT = HM_WORLD | HM_PROP,
+ HG_BULLET = HM_WORLD | HM_PROP | HM_ENTITY,
+ HG_SOLID = HM_WORLD | HM_PROP | HM_ENTITY,
+ HG_ANY = 0xffffffff
+};
+
struct BSP_FACE {
I32 propid;
I32 id;
@@ -32,6 +49,7 @@ struct BSP_FACE {
LIST<VERTEX3D> render_verts{};
VEC3 mins;
VEC3 maxs;
+ U32 hitmask;
};
struct BSP_NODE {
diff --git a/src/game/world/bsp_draw.cpp b/src/game/world/bsp_draw.cpp
index 30e6731..3f5b067 100644
--- a/src/game/world/bsp_draw.cpp
+++ b/src/game/world/bsp_draw.cpp
@@ -2,6 +2,7 @@
#include "../../game.h"
#include "../../render/gl_3d.h"
#include "../objlist.h"
+#include "bsp.h"
#include "map.h"
#include "trace.h"
@@ -70,7 +71,7 @@ void bsp_draw_sprites( BSP* bsp, GAME_DATA* game ) {
LIST<MAP_SPRITE>* sprites = &game->state.map->sprites;
for( U32 i = 0; i < sprites->size; ++i ) {
MAP_SPRITE* sprite = &sprites->data[i];
- BSP_TRACE t;
+ BSP_TRACE t{ .hitmask = HG_SOLID };
t.in_start = player_get_view_pos( objl->pl );
t.in_end = sprite->pos;
diff --git a/src/game/world/trace.cpp b/src/game/world/trace.cpp
index b1f91a3..893c679 100644
--- a/src/game/world/trace.cpp
+++ b/src/game/world/trace.cpp
@@ -3,13 +3,23 @@
#include "bsp.h"
#include "map.h"
+U8 bsp_trace_should_hit_face( BSP_TRACE* tr, BSP_FACE* face ) {
+ if( face->propid == MAPPROP_SKYBOX )
+ return 0;
+ if( !(face->hitmask & tr->hitmask) )
+ return 0;
+
+ return 1;
+}
+
// i have no idea how this works tbh i pasted this
// todo : backface culling (return 0 if d < BSP_TRACE_EPSILON)
-U8 bsp_segment_intersects_tri(
+U8 bsp_trace_intersects_face(
const VEC3& va, const VEC3& vb,
const VEC3& v0, const VEC3& v1, const VEC3& v2,
F32* fract,
- VEC2* out_uv = 0
+ VEC2* out_uv = 0,
+ I32 leaf_idx = 0
) {
VEC3 dir = vb - va;
VEC3 e1 = v1 - v0,
@@ -17,9 +27,10 @@ U8 bsp_segment_intersects_tri(
VEC3 p = vec_cross( dir, e2 );
F32 d = vec_dot( e1, p );
+ if( d < 0 )
+ d *= -1.0f;
- if( fabsf( d ) < BSP_TRACE_EPSILON ) {
- // parallel
+ if( fabsf( d ) <= BSP_NORM_EPSILON ) {
return 0;
}
@@ -52,7 +63,7 @@ U8 bsp_segment_intersects_tri(
return 1;
}
-U8 bsp_trace_leaf_segment( BSP_TRACE* trace, BSP* bsp, I32 leafidx, const VEC3& va, const VEC3& vb ) {
+U8 bsp_trace_leaf( BSP_TRACE* trace, BSP* bsp, I32 leafidx, const VEC3& start, const VEC3& end ) {
BSP_LEAF* leaf = &bsp->leaves.data[leafidx];
U8 didhit = 0;
F32 best = FLT_MAX;
@@ -60,6 +71,9 @@ U8 bsp_trace_leaf_segment( BSP_TRACE* trace, BSP* bsp, I32 leafidx, const VEC3&
for( U32 i = 0; i < leaf->count; ++i ) {
BSP_FACE* face = &bsp->faces.data[leaf->first + i];
+ if( !bsp_trace_should_hit_face( trace, face ) )
+ continue;
+
// shouldnt happen
if( face->verts.size < 3 )
continue;
@@ -69,19 +83,17 @@ U8 bsp_trace_leaf_segment( BSP_TRACE* trace, BSP* bsp, I32 leafidx, const VEC3&
VEC3 v1 = face->verts[t0].pos;
VEC3 v2 = face->verts[t0 + 1].pos;
- // todo : skip func for props
-
F32 t;
VEC2 uv;
- if( !bsp_segment_intersects_tri( va, vb, v0, v1, v2, &t, &uv ) )
+ if( !bsp_trace_intersects_face( start, end, v0, v1, v2, &t, &uv, leafidx ) )
continue;
if( t < best ) {
best = t;
trace->hit = didhit = 1;
trace->frac = t;
- trace->point = va + (vb - va) * t;
+ trace->point = start + (end - start) * t;
trace->normal = vec_normalize( vec_cross( v1 - v0, v2 - v0 ) );
trace->propid = face->propid;
trace->leafid = leafidx;
@@ -93,43 +105,38 @@ U8 bsp_trace_leaf_segment( BSP_TRACE* trace, BSP* bsp, I32 leafidx, const VEC3&
return didhit;
}
-U8 bsp_trace_segment( BSP_TRACE* trace, BSP* bsp, I32 nodeidx, const VEC3& va, const VEC3& vb ) {
+U8 bsp_trace( BSP_TRACE* trace, BSP* bsp, I32 nodeidx, const VEC3& start, const VEC3& end ) {
if( bsp_is_leaf( nodeidx ) ) {
I32 i = bsp_leaf_index( nodeidx );
- return bsp_trace_leaf_segment( trace, bsp, i, va, vb );
+ return bsp_trace_leaf( trace, bsp, i, start, end );
}
BSP_NODE* node = &bsp->nodes.data[nodeidx];
- F32 da = bsp_plane_dist( node->plane, va );
- F32 db = bsp_plane_dist( node->plane, vb );
+ F32 da = bsp_plane_dist( node->plane, start );
+ F32 db = bsp_plane_dist( node->plane, end );
if( da > BSP_TRACE_EPSILON && db > BSP_TRACE_EPSILON )
- return bsp_trace_segment( trace, bsp, node->front, va, vb );
+ return bsp_trace( trace, bsp, node->front, start, end );
if( da < -BSP_TRACE_EPSILON && db < -BSP_TRACE_EPSILON )
- return bsp_trace_segment( trace, bsp, node->back, va, vb );
+ return bsp_trace( trace, bsp, node->back, start, end );
- VEC3 dir = vb - va;
+ VEC3 dir = end - start;
F32 denom = vec_dot( node->plane.normal, dir );
I32 near = (da >= 0.f) ? node->front : node->back;
I32 far = (da >= 0.f) ? node->back : node->front;
if( fabsf( denom ) < BSP_TRACE_EPSILON ) {
- if( bsp_trace_segment( trace, bsp, near, va, vb ) )
+ if( bsp_trace( trace, bsp, near, start, end ) )
return 1;
- return bsp_trace_segment( trace, bsp, far, va, vb );
+ return bsp_trace( trace, bsp, far, start, end );
}
- F32 t = (node->plane.dist - vec_dot( node->plane.normal, va ) ) / denom;
+ F32 t = (node->plane.dist - vec_dot( node->plane.normal, start ) ) / denom;
t = m_clamp( t, 0.f, 1.f );
- VEC3 iplane = va + dir * t;
- if( bsp_trace_segment( trace, bsp, near, va, iplane ) )
+ if( bsp_trace( trace, bsp, near, start, end ) )
return 1;
- if( t <= BSP_TRACE_EPSILON || t >= 1.0f - BSP_TRACE_EPSILON ) {
- return bsp_trace_segment( trace, bsp, far, iplane, vb );
- }
-
- return bsp_trace_segment( trace, bsp, far, iplane, vb );
+ return bsp_trace( trace, bsp, far, start, end );
}
// nudge the trace ends slightly to prevent exact-coplanar infinite recursion.
@@ -170,7 +177,7 @@ U8 bsp_trace( BSP_TRACE* trace, BSP* bsp ) {
VEC3 start = trace->in_start;
VEC3 end = trace->in_end;
- return bsp_trace_segment( trace, bsp, bsp->root, start, end );
+ return bsp_trace( trace, bsp, bsp->root, start, end );
}
F32 hull_proj_radius( const AABB& hull, VEC3 dir ) {
@@ -225,10 +232,6 @@ inline U8 point_in_inflated_poly(
++axis;
}
- if( axis == 3 )
- continue;
-
-
if( !axis ) { // project closest hull corner onto plane
VEC3 diag = in;
diag *= -1;
@@ -252,8 +255,6 @@ U8 bsp_trace_sweep_aabb_to_face(
BSP_TRACE* trace,
const AABB& hull,
BSP_FACE* face,
- const VEC3& start,
- const VEC3& end,
U32 face_idx
) {
if( face->verts.size < 3 )
@@ -275,11 +276,11 @@ U8 bsp_trace_sweep_aabb_to_face(
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 ) ) {
+ if( aabb_contains_point( fhullh, trace->in_start ) && point_in_inflated_poly( trace->in_start, face, hull, norm ) ) {
trace->hit = 1;
trace->frac = 0.f;
trace->startsolid = 1;
- trace->point = start;
+ trace->point = trace->in_start;
trace->normal = norm;
trace->propid = face->propid;
trace->faceid = face_idx;
@@ -315,8 +316,6 @@ U8 bsp_trace_sweep_aabb_to_leaf_edges(
BSP* bsp,
BSP_TRACE* trace,
const AABB& hull,
- const VEC3& start,
- const VEC3& end,
I32 leaf_idx,
F32* in_best
) {
@@ -331,8 +330,8 @@ U8 bsp_trace_sweep_aabb_to_leaf_edges(
BSP_EDGE* e = &leaf->edges[i];
BSP_FACE* f = &bsp->faces.data[e->face];
- if( f->propid == MAPPROP_SKYBOX )
- continue;
+ if( !bsp_trace_should_hit_face( trace, f ) )
+ continue;
VEC3 n = e->plane.normal;
F32 d = e->plane.dist;
@@ -407,8 +406,6 @@ U8 bsp_trace_sweep_aabb_to_leaf(
BSP* bsp,
BSP_TRACE* trace,
const AABB& hull,
- const VEC3& start,
- const VEC3& end,
I32 leaf_idx
) {
BSP_LEAF* leaf = &bsp->leaves.data[leaf_idx];
@@ -422,11 +419,11 @@ U8 bsp_trace_sweep_aabb_to_leaf(
U32 face_idx = leaf->first + i;
BSP_FACE* f = &bsp->faces.data[face_idx];
- if( f->propid == MAPPROP_SKYBOX )
+ if( !bsp_trace_should_hit_face( trace, f ) )
continue;
BSP_TRACE tr = *trace;
- if( !bsp_trace_sweep_aabb_to_face( &tr, hull, f, start, end, face_idx ) )
+ if( !bsp_trace_sweep_aabb_to_face( &tr, hull, f, face_idx ) )
continue;
if( tr.frac < best ) {
@@ -438,7 +435,7 @@ 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 );
+ U8 ehit = bsp_trace_sweep_aabb_to_leaf_edges( bsp, &edgehit, hull, leaf_idx, &best );
if( hit || ehit ) {
if( ehit && !hit )
*trace = edgehit;
@@ -461,13 +458,13 @@ U8 bsp_trace_sweep_aabb(
BSP_TRACE* trace,
BSP* bsp,
const AABB& hull,
- const VEC3& start,
- const VEC3& end,
I32 node_idx
) {
+ VEC3 start = trace->in_start;
+ VEC3 end = trace->in_end;
if( bsp_is_leaf( node_idx ) ) {
I32 i = bsp_leaf_index( node_idx );
- return bsp_trace_sweep_aabb_to_leaf( bsp, trace, hull, start, end, i );
+ return bsp_trace_sweep_aabb_to_leaf( bsp, trace, hull, i );
}
BSP_NODE* node = &bsp->nodes.data[node_idx];
@@ -479,10 +476,10 @@ U8 bsp_trace_sweep_aabb(
F32 offset = aabb_support_radius( hull, n );
if( s_dist > offset && e_dist > offset )
- return bsp_trace_sweep_aabb( trace, bsp, hull, start, end, node->front );
+ return bsp_trace_sweep_aabb( trace, bsp, hull, node->front );
if( s_dist < -offset && e_dist < -offset )
- return bsp_trace_sweep_aabb( trace, bsp, hull, start, end, node->back );
+ return bsp_trace_sweep_aabb( trace, bsp, hull, node->back );
VEC3 dir = end - start;
F32 denom = ( e_dist - s_dist );
@@ -490,9 +487,9 @@ U8 bsp_trace_sweep_aabb(
if( fabsf(denom) < BSP_TRACE_EPSILON ) {
I32 near = (s_dist >= 0.f) ? node->front : node->back;
I32 far = (s_dist >= 0.f) ? node->back : node->front;
- if( bsp_trace_sweep_aabb( trace, bsp, hull, start, end, near ) )
+ if( bsp_trace_sweep_aabb( trace, bsp, hull, near ) )
return 1;
- return bsp_trace_sweep_aabb( trace, bsp, hull, start, end, far );
+ return bsp_trace_sweep_aabb( trace, bsp, hull, far );
}
F32 tin = ( offset - s_dist) / denom;
@@ -508,8 +505,8 @@ U8 bsp_trace_sweep_aabb(
BSP_TRACE tr_near = *trace;
BSP_TRACE tr_far = *trace;
- U8 hit_near = bsp_trace_sweep_aabb( &tr_near, bsp, hull, start, end, near );
- U8 hit_far = bsp_trace_sweep_aabb( &tr_far , bsp, hull, start, end, far );
+ U8 hit_near = bsp_trace_sweep_aabb( &tr_near, bsp, hull, near );
+ U8 hit_far = bsp_trace_sweep_aabb( &tr_far , bsp, hull, far );
if( hit_near && hit_far ) {
*trace = (tr_near.frac <= tr_far.frac) ? tr_near : tr_far;
@@ -522,10 +519,11 @@ U8 bsp_trace_sweep_aabb(
if( tin <= BSP_TRACE_EPSILON || tin >= 1.f - BSP_TRACE_EPSILON ) {
F32 nudge = (denom >= 0.f ? 1.f : -1.f) * BSP_TRACE_EPSILON;
VEC3 nudged = start + dir * nudge;
- return bsp_trace_sweep_aabb( trace, bsp, hull, nudged, end, far );
+ trace->in_start = nudged;
+ return bsp_trace_sweep_aabb( trace, bsp, hull, far );
}
- return bsp_trace_sweep_aabb(trace, bsp, hull, start, end, far );
+ return bsp_trace_sweep_aabb(trace, bsp, hull, far );
}
U8 bsp_trace( BSP_TRACE* trace, BSP* bsp, AABB hull ) {
@@ -545,13 +543,13 @@ U8 bsp_trace( BSP_TRACE* trace, BSP* bsp, AABB hull ) {
trace->in_start += off;
trace->in_end += off;
- U8 ret = bsp_trace_sweep_aabb( trace, bsp, hull, trace->in_start, trace->in_end, bsp->root );
+ U8 ret = bsp_trace_sweep_aabb( trace, bsp, hull, bsp->root );
- trace->in_start -= off;
- trace->in_end -= off;
+ trace->in_start = start;
+ trace->in_end = end;
if( !ret )
- trace->point = trace->in_end;
+ trace->point = end;
else
trace->point -= off;
diff --git a/src/game/world/trace.h b/src/game/world/trace.h
index d04ed6b..31ed28c 100644
--- a/src/game/world/trace.h
+++ b/src/game/world/trace.h
@@ -11,6 +11,8 @@ struct BSP_TRACE {
VEC3 in_start;
VEC3 in_end;
+ U32 hitmask = HM_ANY;
+
U8 hit;
F32 frac;
VEC3 point;