diff options
| author | aura <nw@moneybot.cc> | 2026-03-01 23:07:31 +0100 |
|---|---|---|
| committer | aura <nw@moneybot.cc> | 2026-03-01 23:07:31 +0100 |
| commit | b3a92fa1ffc565c2fc72b1a531cae09cbbc219bd (patch) | |
| tree | fe3d9d411a8de92c48f39e10456e485ec91cda93 /src/game/world/bsp.cpp | |
| parent | 71dd7fcccb45a54d85ae23a95a8a8905ed21fe15 (diff) | |
wip on adding edge normals
Diffstat (limited to 'src/game/world/bsp.cpp')
| -rw-r--r-- | src/game/world/bsp.cpp | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/src/game/world/bsp.cpp b/src/game/world/bsp.cpp index e163d6e..7c6b9ab 100644 --- a/src/game/world/bsp.cpp +++ b/src/game/world/bsp.cpp @@ -1,6 +1,7 @@ #include "bsp.h" #include "../../util/math.h" #include "map.h" +#include "trace.h" #include <climits> const F32 BSP_PORTAL_PLANE_SIZE = 64000.f; @@ -417,6 +418,110 @@ I32 bsp_build_nodes( return nidx; } +void bsp_gen_leaf_edges( BSP* bsp, I32 leaf_idx, LIST<BSP_EDGE>* out ) { + BSP_LEAF* leaf = &bsp->leaves.data[leaf_idx]; + + for( U32 facei = 0; facei < leaf->count; ++facei ) { + U32 faceidx = leaf->first + facei; + BSP_FACE* face = &bsp->faces.data[faceidx]; + + if( face->verts.size < 3 ) + continue; + + VEC3 facen = bsp_face_get_normal( face ); + VEC3 center{}; + for( U32 i = 0; i < face->verts.size; ++i ) + center = center + face->verts.data[i].pos; + center = center / face->verts.size; + + for( U32 i = 0; i < face->verts.size; ++i ) { + VEC3 a = face->verts[i].pos; + VEC3 b = face->verts[(i+1) % face->verts.size].pos; + VEC3 edge = b - a; + F32 elen = vec_len( edge ); + if( elen < 0.0001f ) + continue; + edge = edge * (1.f / elen); + + VEC3 edgen = vec_normalize( vec_cross( facen, edge ) ); + + if( vec_dot( edgen, center - a ) > 0.f ) + edgen = edgen * -1.f; + + if( fabsf( vec_dot( edgen, facen ) ) > 0.9999f ) + continue; + + BSP_EDGE bedge; + bedge.plane.normal = edgen; + bedge.plane.dist = vec_dot( edgen, a ); + bedge.face = faceidx; + bedge.v1 = a; + bedge.v2 = b; + bedge.avgc = 1; + out->push( bedge ); + } + } +} + +U8 bsp_edge_is_adjacent( BSP_EDGE* a, BSP_EDGE* b ) { + F32 t = BSP_EDGE_TOLERANCE; + F32 dv1 = vec_dist( a->v1, b->v1 ); + F32 dv2 = vec_dist( a->v2, b->v2 ); + + if( dv1 < t && dv2 < t ) + return 1; + + dv1 = vec_dist( a->v1, b->v2 ); + dv2 = vec_dist( a->v2, b->v1 ); + + if( dv1 < t && dv2 < t ) + return 1; + + return 0; +} + +LIST<BSP_EDGE> bsp_average_leaf_edges( BSP* bsp, LIST<BSP_EDGE>* edges ) { + LIST<BSP_EDGE> out{}; + for( U32 i = 0; i < edges->size; ++i ) { + BSP_EDGE a = edges->data[i]; + + for( U32 i2 = 0; i2 < out.size; ++i2 ) { + BSP_EDGE* b = &out.data[i2]; + if( bsp_edge_is_adjacent( &a, b ) ) { + VEC3 avg = vec_normalize( a.plane.normal + b->plane.normal * b->avgc ); + b->plane.normal = avg; + a.plane.normal = avg; + b->avgc++; + } + } + + a.avgc = 1; + out.push( a ); + } + + return out; +} + +void bsp_gen_leaf_edges( BSP* bsp ) { + LIST<BSP_EDGE> edges; + for( U32 i = 0; i < bsp->leaves.size; ++i ) + bsp_gen_leaf_edges( bsp, i, &edges ); + + edges = bsp_average_leaf_edges( bsp, &edges ); + edges.each( fn( BSP_EDGE* e ) { + U32 facei = e->face; + + bsp->leaves.each( fn( BSP_LEAF* l ) { + U32 starti = l->first; + U32 endi = l->first + l->count; + + if( facei >= starti && facei < endi ) + l->edges.push( *e ); + } ); + } ); +} + + inline void bsp_plane_basis( const VEC3& norm, VEC3* u, VEC3* v ) { VEC3 a = fabsf( norm.x ) > 0.9f ? VEC3{ 0, 1, 0 } : VEC3{ 1, 0, 0 }; *u = vec_normalize( vec_cross( a, norm ) ); @@ -727,6 +832,7 @@ BSP* bsp_build_map( WORLD_MAP* m ) { for( U32 i = 0; i < bsp->faces.size; ++i ) { bsp->faces.data[i].id = i; } + // bsp_gen_leaf_edges( bsp ); bsp_gen_render_vertices( bsp ); bsp_build_portals( bsp ); |
