engine: split edge struct into two with 16-bit indicies and 32-bit indicies to support BSP2 format in runtime

This commit is contained in:
Alibek Omarov 2025-01-08 04:50:44 +03:00
parent 734c07ddab
commit ced8744ac9
6 changed files with 96 additions and 46 deletions

View file

@ -73,15 +73,16 @@ typedef struct mclipnode16_s
} mclipnode16_t; } mclipnode16_t;
// size is matched but representation is not // size is matched but representation is not
typedef struct typedef struct medge32_s
{ {
#ifdef SUPPORT_BSP2_FORMAT
unsigned int v[2]; unsigned int v[2];
#else } medge32_t;
typedef struct medge16_s
{
unsigned short v[2]; unsigned short v[2];
unsigned int cachededgeoffset; unsigned int cachededgeoffset;
#endif } medge16_t;
} medge_t;
typedef struct texture_s typedef struct texture_s
{ {
@ -347,7 +348,12 @@ typedef struct model_s
mvertex_t *vertexes; mvertex_t *vertexes;
int numedges; int numedges;
medge_t *edges; union
{
medge16_t *edges16;
medge32_t *edges32;
};
int numnodes; int numnodes;
mnode_t *nodes; mnode_t *nodes;

View file

@ -1264,23 +1264,36 @@ Mod_GetFaceContents
determine face contents by name 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; int lindex = mod->surfedges[surfedge];
medge_t *edge;
lindex = mod->surfedges[surfedge];
if( bmod->version == QBSP2_VERSION )
{
if( lindex > 0 ) if( lindex > 0 )
{ {
edge = &mod->edges[lindex]; medge32_t *edge = &mod->edges32[lindex];
return &mod->vertexes[edge->v[0]]; return &mod->vertexes[edge->v[0]];
} }
else else
{ {
edge = &mod->edges[-lindex]; medge32_t *edge = &mod->edges32[-lindex];
return &mod->vertexes[edge->v[1]]; return &mod->vertexes[edge->v[1]];
} }
}
else
{
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[] 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 // this place is VERY critical to precision
// keep it as float, don't use double, because it causes issues with lightmap // 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 ) if( e >= mod->numedges || e <= -mod->numedges )
Host_Error( "%s: bad edge\n", __func__ ); Host_Error( "%s: bad edge\n", __func__ );
if( e >= 0 ) v = &mod->vertexes[mod->edges[e].v[0]]; if( bmod->version == QBSP2_VERSION )
else v = &mod->vertexes[mod->edges[-e].v[1]]; {
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++ ) for( j = 0; j < 2; j++ )
{ {
@ -1446,7 +1467,7 @@ Mod_CalcSurfaceBounds
fills in surf->mins and surf->maxs 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; int i, e;
mvertex_t *v; mvertex_t *v;
@ -1460,8 +1481,16 @@ static void Mod_CalcSurfaceBounds( model_t *mod, msurface_t *surf )
if( e >= mod->numedges || e <= -mod->numedges ) if( e >= mod->numedges || e <= -mod->numedges )
Host_Error( "%s: bad edge\n", __func__ ); Host_Error( "%s: bad edge\n", __func__ );
if( e >= 0 ) v = &mod->vertexes[mod->edges[e].v[0]]; if( bmod->version == QBSP2_VERSION )
else v = &mod->vertexes[mod->edges[-e].v[1]]; {
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 ); 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 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; vec3_t delta, edgevec;
byte *facebevel; byte *facebevel;
@ -1506,8 +1535,8 @@ static void Mod_CreateFaceBevels( model_t *mod, msurface_t *surf )
{ {
mplane_t *dest = &fb->edges[i]; mplane_t *dest = &fb->edges[i];
v0 = Mod_GetVertexByNumber( mod, surf->firstedge + i ); v0 = Mod_GetVertexByNumber( mod, surf->firstedge + i, bmod );
v1 = Mod_GetVertexByNumber( mod, surf->firstedge + (i + 1) % surf->numedges ); v1 = Mod_GetVertexByNumber( mod, surf->firstedge + (i + 1) % surf->numedges, bmod );
VectorSubtract( v1->position, v0->position, edgevec ); VectorSubtract( v1->position, v0->position, edgevec );
CrossProduct( faceNormal, edgevec, dest->normal ); CrossProduct( faceNormal, edgevec, dest->normal );
VectorNormalize( dest->normal ); VectorNormalize( dest->normal );
@ -1521,7 +1550,7 @@ static void Mod_CreateFaceBevels( model_t *mod, msurface_t *surf )
// compute face radius // compute face radius
for( i = 0; i < surf->numedges; i++ ) 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 ); VectorSubtract( v0->position, fb->origin, delta );
radius = DotProduct( delta, delta ); radius = DotProduct( delta, delta );
fb->radius = Q_max( radius, fb->radius ); fb->radius = Q_max( radius, fb->radius );
@ -2185,15 +2214,15 @@ Mod_LoadEdges
*/ */
static void Mod_LoadEdges( model_t *mod, dbspmodel_t *bmod ) static void Mod_LoadEdges( model_t *mod, dbspmodel_t *bmod )
{ {
medge_t *out;
int i; int i;
mod->edges = out = Mem_Malloc( mod->mempool, bmod->numedges * sizeof( medge_t ));
mod->numedges = bmod->numedges; mod->numedges = bmod->numedges;
if( bmod->version == QBSP2_VERSION ) 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++ ) for( i = 0; i < bmod->numedges; i++, in++, out++ )
{ {
@ -2203,7 +2232,9 @@ static void Mod_LoadEdges( model_t *mod, dbspmodel_t *bmod )
} }
else 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++ ) 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 )) if( FBitSet( out->texinfo->flags, TEX_SPECIAL ))
SetBits( out->flags, SURF_DRAWTILED ); SetBits( out->flags, SURF_DRAWTILED );
Mod_CalcSurfaceBounds( mod, out ); Mod_CalcSurfaceBounds( mod, out, bmod );
Mod_CalcSurfaceExtents( mod, out ); Mod_CalcSurfaceExtents( mod, out, bmod );
Mod_CreateFaceBevels( mod, out ); Mod_CreateFaceBevels( mod, out, bmod );
// grab the second sample to detect colored lighting // grab the second sample to detect colored lighting
if( test_lightsize > 0 && lightofs != -1 ) if( test_lightsize > 0 && lightofs != -1 )

View file

@ -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 ) 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 int lindex = mod->surfedges[fa->firstedge + i];
const medge_t *pedges = mod->edges;
if( tr.world->version == QBSP2_VERSION )
{
const medge32_t *pedges = mod->edges32;
if( lindex > 0 ) if( lindex > 0 )
VectorCopy( mod->vertexes[pedges[lindex].v[0]].position, vec ); VectorCopy( mod->vertexes[pedges[lindex].v[0]].position, vec );
else else
VectorCopy( mod->vertexes[pedges[-lindex].v[1]].position, vec ); VectorCopy( mod->vertexes[pedges[-lindex].v[1]].position, vec );
}
else
{
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 ) static void BoundPoly( int numverts, float *verts, vec3_t mins, vec3_t maxs )

View file

@ -356,13 +356,13 @@ void R_DrawSolidClippedSubmodelPolygons( model_t *pmodel, mnode_t *topnode )
mplane_t *pplane; mplane_t *pplane;
mvertex_t bverts[MAX_BMODEL_VERTS]; mvertex_t bverts[MAX_BMODEL_VERTS];
bedge_t bedges[MAX_BMODEL_EDGES], *pbedge; bedge_t bedges[MAX_BMODEL_EDGES], *pbedge;
medge_t *pedge, *pedges; medge16_t *pedge, *pedges;
// FIXME: use bounding-box-based frustum clipping info? // FIXME: use bounding-box-based frustum clipping info?
psurf = &pmodel->surfaces[pmodel->firstmodelsurface]; psurf = &pmodel->surfaces[pmodel->firstmodelsurface];
numsurfaces = pmodel->nummodelsurfaces; numsurfaces = pmodel->nummodelsurfaces;
pedges = pmodel->edges; pedges = pmodel->edges16;
for( i = 0; i < numsurfaces; i++, psurf++ ) for( i = 0; i < numsurfaces; i++, psurf++ )
{ {

View file

@ -933,7 +933,7 @@ typedef struct edge_s
unsigned short surfs[2]; unsigned short surfs[2];
struct edge_s *nextremove; struct edge_s *nextremove;
float nearzi; float nearzi;
medge_t *owner; medge16_t *owner;
} edge_t; } edge_t;

View file

@ -37,7 +37,7 @@ int c_faceclip; // numbe
clipplane_t *entity_clipplanes; clipplane_t *entity_clipplanes;
clipplane_t world_clipplanes[16]; clipplane_t world_clipplanes[16];
medge_t *r_pedge; medge16_t *r_pedge;
qboolean r_leftclipped, r_rightclipped; qboolean r_leftclipped, r_rightclipped;
static qboolean makeleftedge, makerightedge; static qboolean makeleftedge, makerightedge;
@ -68,7 +68,7 @@ msurface_t *r_skyfaces;
mplane_t r_skyplanes[6]; mplane_t r_skyplanes[6];
mtexinfo_t r_skytexinfo[6]; mtexinfo_t r_skytexinfo[6];
mvertex_t *r_skyverts; mvertex_t *r_skyverts;
medge_t *r_skyedges; medge16_t *r_skyedges;
int *r_skysurfedges; int *r_skysurfedges;
// I just copied this data from a box map... // I just copied this data from a box map...
@ -438,7 +438,7 @@ void R_RenderFace( msurface_t *fa, int clipflags )
mplane_t *pplane; mplane_t *pplane;
float distinv; float distinv;
vec3_t p_normal; vec3_t p_normal;
medge_t *pedges, tedge; medge16_t *pedges, tedge;
clipplane_t *pclip; clipplane_t *pclip;
// translucent surfaces are not drawn by the edge renderer // 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_nearzi = 0;
r_nearzionly = false; r_nearzionly = false;
makeleftedge = makerightedge = false; makeleftedge = makerightedge = false;
pedges = RI.currentmodel->edges; pedges = RI.currentmodel->edges16;
r_lastvertvalid = false; r_lastvertvalid = false;
for( i = 0; i < fa->numedges; i++ ) for( i = 0; i < fa->numedges; i++ )
@ -560,7 +560,7 @@ void R_RenderFace( msurface_t *fa, int clipflags )
else else
{ {
// it's cached if the cached edge is valid and is owned // 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 ) if((((uintptr_t)edge_p - (uintptr_t)r_edges )
> r_pedge->cachededgeoffset ) > r_pedge->cachededgeoffset )
&& (((edge_t *)((uintptr_t)r_edges && (((edge_t *)((uintptr_t)r_edges
@ -651,7 +651,7 @@ void R_RenderBmodelFace( bedge_t *pedges, msurface_t *psurf )
mplane_t *pplane; mplane_t *pplane;
float distinv; float distinv;
vec3_t p_normal; vec3_t p_normal;
medge_t tedge; medge16_t tedge;
clipplane_t *pclip; clipplane_t *pclip;
/*if (psurf->texinfo->flags & (SURF_TRANS33|SURF_TRANS66)) /*if (psurf->texinfo->flags & (SURF_TRANS33|SURF_TRANS66))