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;
// 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;

View file

@ -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 )

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 )
{
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 )

View file

@ -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++ )
{

View file

@ -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;

View file

@ -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))