From ced8744ac9cf5f10840d66e050aad61b2c1f091e Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Wed, 8 Jan 2025 04:50:44 +0300 Subject: [PATCH] engine: split edge struct into two with 16-bit indicies and 32-bit indicies to support BSP2 format in runtime --- common/com_model.h | 18 +++++--- engine/common/mod_bmodel.c | 85 ++++++++++++++++++++++++++------------ ref/gl/gl_rsurf.c | 21 ++++++++-- ref/soft/r_bsp.c | 4 +- ref/soft/r_local.h | 2 +- ref/soft/r_rast.c | 12 +++--- 6 files changed, 96 insertions(+), 46 deletions(-) diff --git a/common/com_model.h b/common/com_model.h index 8539eb03..aea6d3fa 100644 --- a/common/com_model.h +++ b/common/com_model.h @@ -73,15 +73,16 @@ typedef struct mclipnode16_s } mclipnode16_t; // size is matched but representation is not -typedef struct +typedef struct medge32_s { -#ifdef SUPPORT_BSP2_FORMAT unsigned int v[2]; -#else +} medge32_t; + +typedef struct medge16_s +{ unsigned short v[2]; unsigned int cachededgeoffset; -#endif -} medge_t; +} medge16_t; typedef struct texture_s { @@ -347,7 +348,12 @@ typedef struct model_s mvertex_t *vertexes; int numedges; - medge_t *edges; + union + { + medge16_t *edges16; + medge32_t *edges32; + }; + int numnodes; mnode_t *nodes; diff --git a/engine/common/mod_bmodel.c b/engine/common/mod_bmodel.c index 03534e7f..a5261928 100644 --- a/engine/common/mod_bmodel.c +++ b/engine/common/mod_bmodel.c @@ -1264,22 +1264,35 @@ Mod_GetFaceContents determine face contents by name ================== */ -static mvertex_t *Mod_GetVertexByNumber( model_t *mod, int surfedge ) +static mvertex_t *Mod_GetVertexByNumber( model_t *mod, int surfedge, const dbspmodel_t *bmod ) { - int lindex; - medge_t *edge; + int lindex = mod->surfedges[surfedge]; - lindex = mod->surfedges[surfedge]; - - if( lindex > 0 ) + if( bmod->version == QBSP2_VERSION ) { - edge = &mod->edges[lindex]; - return &mod->vertexes[edge->v[0]]; + if( lindex > 0 ) + { + medge32_t *edge = &mod->edges32[lindex]; + return &mod->vertexes[edge->v[0]]; + } + else + { + medge32_t *edge = &mod->edges32[-lindex]; + return &mod->vertexes[edge->v[1]]; + } } else { - edge = &mod->edges[-lindex]; - return &mod->vertexes[edge->v[1]]; + if( lindex > 0 ) + { + medge16_t *edge = &mod->edges16[lindex]; + return &mod->vertexes[edge->v[0]]; + } + else + { + medge16_t *edge = &mod->edges16[-lindex]; + return &mod->vertexes[edge->v[1]]; + } } } @@ -1364,7 +1377,7 @@ Mod_CalcSurfaceExtents Fills in surf->texturemins[] and surf->extents[] ================= */ -static void Mod_CalcSurfaceExtents( model_t *mod, msurface_t *surf ) +static void Mod_CalcSurfaceExtents( model_t *mod, msurface_t *surf, const dbspmodel_t *bmod ) { // this place is VERY critical to precision // keep it as float, don't use double, because it causes issues with lightmap @@ -1391,8 +1404,16 @@ static void Mod_CalcSurfaceExtents( model_t *mod, msurface_t *surf ) if( e >= mod->numedges || e <= -mod->numedges ) Host_Error( "%s: bad edge\n", __func__ ); - if( e >= 0 ) v = &mod->vertexes[mod->edges[e].v[0]]; - else v = &mod->vertexes[mod->edges[-e].v[1]]; + if( bmod->version == QBSP2_VERSION ) + { + if( e >= 0 ) v = &mod->vertexes[mod->edges32[e].v[0]]; + else v = &mod->vertexes[mod->edges32[-e].v[1]]; + } + else + { + if( e >= 0 ) v = &mod->vertexes[mod->edges16[e].v[0]]; + else v = &mod->vertexes[mod->edges16[-e].v[1]]; + } for( j = 0; j < 2; j++ ) { @@ -1446,7 +1467,7 @@ Mod_CalcSurfaceBounds fills in surf->mins and surf->maxs ================= */ -static void Mod_CalcSurfaceBounds( model_t *mod, msurface_t *surf ) +static void Mod_CalcSurfaceBounds( model_t *mod, msurface_t *surf, const dbspmodel_t *bmod ) { int i, e; mvertex_t *v; @@ -1460,8 +1481,16 @@ static void Mod_CalcSurfaceBounds( model_t *mod, msurface_t *surf ) if( e >= mod->numedges || e <= -mod->numedges ) Host_Error( "%s: bad edge\n", __func__ ); - if( e >= 0 ) v = &mod->vertexes[mod->edges[e].v[0]]; - else v = &mod->vertexes[mod->edges[-e].v[1]]; + if( bmod->version == QBSP2_VERSION ) + { + if( e >= 0 ) v = &mod->vertexes[mod->edges32[e].v[0]]; + else v = &mod->vertexes[mod->edges32[-e].v[1]]; + } + else + { + if( e >= 0 ) v = &mod->vertexes[mod->edges16[e].v[0]]; + else v = &mod->vertexes[mod->edges16[-e].v[1]]; + } AddPointToBounds( v->position, surf->info->mins, surf->info->maxs ); } @@ -1473,7 +1502,7 @@ static void Mod_CalcSurfaceBounds( model_t *mod, msurface_t *surf ) Mod_CreateFaceBevels ================= */ -static void Mod_CreateFaceBevels( model_t *mod, msurface_t *surf ) +static void Mod_CreateFaceBevels( model_t *mod, msurface_t *surf, const dbspmodel_t *bmod ) { vec3_t delta, edgevec; byte *facebevel; @@ -1506,8 +1535,8 @@ static void Mod_CreateFaceBevels( model_t *mod, msurface_t *surf ) { mplane_t *dest = &fb->edges[i]; - v0 = Mod_GetVertexByNumber( mod, surf->firstedge + i ); - v1 = Mod_GetVertexByNumber( mod, surf->firstedge + (i + 1) % surf->numedges ); + v0 = Mod_GetVertexByNumber( mod, surf->firstedge + i, bmod ); + v1 = Mod_GetVertexByNumber( mod, surf->firstedge + (i + 1) % surf->numedges, bmod ); VectorSubtract( v1->position, v0->position, edgevec ); CrossProduct( faceNormal, edgevec, dest->normal ); VectorNormalize( dest->normal ); @@ -1521,7 +1550,7 @@ static void Mod_CreateFaceBevels( model_t *mod, msurface_t *surf ) // compute face radius for( i = 0; i < surf->numedges; i++ ) { - v0 = Mod_GetVertexByNumber( mod, surf->firstedge + i ); + v0 = Mod_GetVertexByNumber( mod, surf->firstedge + i, bmod ); VectorSubtract( v0->position, fb->origin, delta ); radius = DotProduct( delta, delta ); fb->radius = Q_max( radius, fb->radius ); @@ -2185,15 +2214,15 @@ Mod_LoadEdges */ static void Mod_LoadEdges( model_t *mod, dbspmodel_t *bmod ) { - medge_t *out; int i; - mod->edges = out = Mem_Malloc( mod->mempool, bmod->numedges * sizeof( medge_t )); mod->numedges = bmod->numedges; if( bmod->version == QBSP2_VERSION ) { - dedge32_t *in = (dedge32_t *)bmod->edges32; + dedge32_t *in = bmod->edges32; + medge32_t *out; + mod->edges32 = out = Mem_Malloc( mod->mempool, bmod->numedges * sizeof( *out )); for( i = 0; i < bmod->numedges; i++, in++, out++ ) { @@ -2203,7 +2232,9 @@ static void Mod_LoadEdges( model_t *mod, dbspmodel_t *bmod ) } else { - dedge_t *in = (dedge_t *)bmod->edges; + dedge_t *in = bmod->edges; + medge16_t *out; + mod->edges16 = out = Mem_Malloc( mod->mempool, bmod->numedges * sizeof( *out )); for( i = 0; i < bmod->numedges; i++, in++, out++ ) { @@ -2963,9 +2994,9 @@ static void Mod_LoadSurfaces( model_t *mod, dbspmodel_t *bmod ) if( FBitSet( out->texinfo->flags, TEX_SPECIAL )) SetBits( out->flags, SURF_DRAWTILED ); - Mod_CalcSurfaceBounds( mod, out ); - Mod_CalcSurfaceExtents( mod, out ); - Mod_CreateFaceBevels( mod, out ); + Mod_CalcSurfaceBounds( mod, out, bmod ); + Mod_CalcSurfaceExtents( mod, out, bmod ); + Mod_CreateFaceBevels( mod, out, bmod ); // grab the second sample to detect colored lighting if( test_lightsize > 0 && lightofs != -1 ) diff --git a/ref/gl/gl_rsurf.c b/ref/gl/gl_rsurf.c index 5d27e55a..20ea5dd8 100644 --- a/ref/gl/gl_rsurf.c +++ b/ref/gl/gl_rsurf.c @@ -125,12 +125,25 @@ static void R_TextureCoord( const vec3_t v, const msurface_t *surf, vec2_t coord static void R_GetEdgePosition( const model_t *mod, const msurface_t *fa, int i, vec3_t vec ) { const int lindex = mod->surfedges[fa->firstedge + i]; - const medge_t *pedges = mod->edges; - if( lindex > 0 ) - VectorCopy( mod->vertexes[pedges[lindex].v[0]].position, vec ); + if( tr.world->version == QBSP2_VERSION ) + { + const medge32_t *pedges = mod->edges32; + + if( lindex > 0 ) + VectorCopy( mod->vertexes[pedges[lindex].v[0]].position, vec ); + else + VectorCopy( mod->vertexes[pedges[-lindex].v[1]].position, vec ); + } else - VectorCopy( mod->vertexes[pedges[-lindex].v[1]].position, vec ); + { + const medge16_t *pedges = mod->edges16; + + if( lindex > 0 ) + VectorCopy( mod->vertexes[pedges[lindex].v[0]].position, vec ); + else + VectorCopy( mod->vertexes[pedges[-lindex].v[1]].position, vec ); + } } static void BoundPoly( int numverts, float *verts, vec3_t mins, vec3_t maxs ) diff --git a/ref/soft/r_bsp.c b/ref/soft/r_bsp.c index 4bc794aa..c3f649de 100644 --- a/ref/soft/r_bsp.c +++ b/ref/soft/r_bsp.c @@ -356,13 +356,13 @@ void R_DrawSolidClippedSubmodelPolygons( model_t *pmodel, mnode_t *topnode ) mplane_t *pplane; mvertex_t bverts[MAX_BMODEL_VERTS]; bedge_t bedges[MAX_BMODEL_EDGES], *pbedge; - medge_t *pedge, *pedges; + medge16_t *pedge, *pedges; // FIXME: use bounding-box-based frustum clipping info? psurf = &pmodel->surfaces[pmodel->firstmodelsurface]; numsurfaces = pmodel->nummodelsurfaces; - pedges = pmodel->edges; + pedges = pmodel->edges16; for( i = 0; i < numsurfaces; i++, psurf++ ) { diff --git a/ref/soft/r_local.h b/ref/soft/r_local.h index 687aa0b1..772e1c88 100644 --- a/ref/soft/r_local.h +++ b/ref/soft/r_local.h @@ -933,7 +933,7 @@ typedef struct edge_s unsigned short surfs[2]; struct edge_s *nextremove; float nearzi; - medge_t *owner; + medge16_t *owner; } edge_t; diff --git a/ref/soft/r_rast.c b/ref/soft/r_rast.c index 339ff0d7..3dff5d94 100644 --- a/ref/soft/r_rast.c +++ b/ref/soft/r_rast.c @@ -37,7 +37,7 @@ int c_faceclip; // numbe clipplane_t *entity_clipplanes; clipplane_t world_clipplanes[16]; -medge_t *r_pedge; +medge16_t *r_pedge; qboolean r_leftclipped, r_rightclipped; static qboolean makeleftedge, makerightedge; @@ -68,7 +68,7 @@ msurface_t *r_skyfaces; mplane_t r_skyplanes[6]; mtexinfo_t r_skytexinfo[6]; mvertex_t *r_skyverts; -medge_t *r_skyedges; +medge16_t *r_skyedges; int *r_skysurfedges; // I just copied this data from a box map... @@ -438,7 +438,7 @@ void R_RenderFace( msurface_t *fa, int clipflags ) mplane_t *pplane; float distinv; vec3_t p_normal; - medge_t *pedges, tedge; + medge16_t *pedges, tedge; clipplane_t *pclip; // translucent surfaces are not drawn by the edge renderer @@ -490,7 +490,7 @@ void R_RenderFace( msurface_t *fa, int clipflags ) r_nearzi = 0; r_nearzionly = false; makeleftedge = makerightedge = false; - pedges = RI.currentmodel->edges; + pedges = RI.currentmodel->edges16; r_lastvertvalid = false; for( i = 0; i < fa->numedges; i++ ) @@ -560,7 +560,7 @@ void R_RenderFace( msurface_t *fa, int clipflags ) else { // it's cached if the cached edge is valid and is owned - // by this medge_t + // by this medge16_t if((((uintptr_t)edge_p - (uintptr_t)r_edges ) > r_pedge->cachededgeoffset ) && (((edge_t *)((uintptr_t)r_edges @@ -651,7 +651,7 @@ void R_RenderBmodelFace( bedge_t *pedges, msurface_t *psurf ) mplane_t *pplane; float distinv; vec3_t p_normal; - medge_t tedge; + medge16_t tedge; clipplane_t *pclip; /*if (psurf->texinfo->flags & (SURF_TRANS33|SURF_TRANS66))