summaryrefslogtreecommitdiff
path: root/src/game/world/bsp.cpp
diff options
context:
space:
mode:
authoraura <nw@moneybot.cc>2026-03-01 23:07:31 +0100
committeraura <nw@moneybot.cc>2026-03-01 23:07:31 +0100
commitb3a92fa1ffc565c2fc72b1a531cae09cbbc219bd (patch)
treefe3d9d411a8de92c48f39e10456e485ec91cda93 /src/game/world/bsp.cpp
parent71dd7fcccb45a54d85ae23a95a8a8905ed21fe15 (diff)
wip on adding edge normals
Diffstat (limited to 'src/game/world/bsp.cpp')
-rw-r--r--src/game/world/bsp.cpp106
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 );